From 5197360f9e09449ac7249a98fbde36a3608e059c Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 18 May 2020 19:03:21 +0200 Subject: [PATCH 001/242] mtd: rawnand: mtk: Convert the driver to exec_op() Let's convert the driver to exec_op() to have one less driver relying on the legacy interface. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200518170321.321697-1-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/mtk_nand.c | 116 +++++++++++++++++++------------- 1 file changed, 71 insertions(+), 45 deletions(-) diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c index c1a6e31aabb8..ca8457626d53 100644 --- a/drivers/mtd/nand/raw/mtk_nand.c +++ b/drivers/mtd/nand/raw/mtk_nand.c @@ -387,44 +387,6 @@ static int mtk_nfc_hw_runtime_config(struct mtd_info *mtd) return 0; } -static void mtk_nfc_select_chip(struct nand_chip *nand, int chip) -{ - struct mtk_nfc *nfc = nand_get_controller_data(nand); - struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(nand); - - if (chip < 0) - return; - - mtk_nfc_hw_runtime_config(nand_to_mtd(nand)); - - nfi_writel(nfc, mtk_nand->sels[chip], NFI_CSEL); -} - -static int mtk_nfc_dev_ready(struct nand_chip *nand) -{ - struct mtk_nfc *nfc = nand_get_controller_data(nand); - - if (nfi_readl(nfc, NFI_STA) & STA_BUSY) - return 0; - - return 1; -} - -static void mtk_nfc_cmd_ctrl(struct nand_chip *chip, int dat, - unsigned int ctrl) -{ - struct mtk_nfc *nfc = nand_get_controller_data(chip); - - if (ctrl & NAND_ALE) { - mtk_nfc_send_address(nfc, dat); - } else if (ctrl & NAND_CLE) { - mtk_nfc_hw_reset(nfc); - - nfi_writew(nfc, CNFG_OP_CUST, NFI_CNFG); - mtk_nfc_send_command(nfc, dat); - } -} - static inline void mtk_nfc_wait_ioready(struct mtk_nfc *nfc) { int rc; @@ -501,6 +463,74 @@ static void mtk_nfc_write_buf(struct nand_chip *chip, const u8 *buf, int len) mtk_nfc_write_byte(chip, buf[i]); } +static int mtk_nfc_exec_instr(struct nand_chip *chip, + const struct nand_op_instr *instr) +{ + struct mtk_nfc *nfc = nand_get_controller_data(chip); + unsigned int i; + u32 status; + + switch (instr->type) { + case NAND_OP_CMD_INSTR: + mtk_nfc_send_command(nfc, instr->ctx.cmd.opcode); + return 0; + case NAND_OP_ADDR_INSTR: + for (i = 0; i < instr->ctx.addr.naddrs; i++) + mtk_nfc_send_address(nfc, instr->ctx.addr.addrs[i]); + return 0; + case NAND_OP_DATA_IN_INSTR: + mtk_nfc_read_buf(chip, instr->ctx.data.buf.in, + instr->ctx.data.len); + return 0; + case NAND_OP_DATA_OUT_INSTR: + mtk_nfc_write_buf(chip, instr->ctx.data.buf.out, + instr->ctx.data.len); + return 0; + case NAND_OP_WAITRDY_INSTR: + return readl_poll_timeout(nfc->regs + NFI_STA, status, + status & STA_BUSY, 20, + instr->ctx.waitrdy.timeout_ms); + default: + break; + } + + return -EINVAL; +} + +static void mtk_nfc_select_target(struct nand_chip *nand, unsigned int cs) +{ + struct mtk_nfc *nfc = nand_get_controller_data(nand); + struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(nand); + + mtk_nfc_hw_runtime_config(nand_to_mtd(nand)); + + nfi_writel(nfc, mtk_nand->sels[cs], NFI_CSEL); +} + +static int mtk_nfc_exec_op(struct nand_chip *chip, + const struct nand_operation *op, + bool check_only) +{ + struct mtk_nfc *nfc = nand_get_controller_data(chip); + unsigned int i; + int ret = 0; + + if (check_only) + return 0; + + mtk_nfc_hw_reset(nfc); + nfi_writew(nfc, CNFG_OP_CUST, NFI_CNFG); + mtk_nfc_select_target(chip, op->cs); + + for (i = 0; i < op->ninstrs; i++) { + ret = mtk_nfc_exec_instr(chip, &op->instrs[i]); + if (ret) + break; + } + + return ret; +} + static int mtk_nfc_setup_data_interface(struct nand_chip *chip, int csline, const struct nand_data_interface *conf) { @@ -803,6 +833,7 @@ static int mtk_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, u32 reg; int ret; + mtk_nfc_select_target(chip, chip->cur_cs); nand_prog_page_begin_op(chip, page, 0, NULL, 0); if (!raw) { @@ -920,6 +951,7 @@ static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, u8 *buf; int rc; + mtk_nfc_select_target(chip, chip->cur_cs); start = data_offs / chip->ecc.size; end = DIV_ROUND_UP(data_offs + readlen, chip->ecc.size); @@ -1326,6 +1358,7 @@ static int mtk_nfc_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops mtk_nfc_controller_ops = { .attach_chip = mtk_nfc_attach_chip, .setup_data_interface = mtk_nfc_setup_data_interface, + .exec_op = mtk_nfc_exec_op, }; static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc, @@ -1381,13 +1414,6 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc, nand_set_controller_data(nand, nfc); nand->options |= NAND_USES_DMA | NAND_SUBPAGE_READ; - nand->legacy.dev_ready = mtk_nfc_dev_ready; - nand->legacy.select_chip = mtk_nfc_select_chip; - nand->legacy.write_byte = mtk_nfc_write_byte; - nand->legacy.write_buf = mtk_nfc_write_buf; - nand->legacy.read_byte = mtk_nfc_read_byte; - nand->legacy.read_buf = mtk_nfc_read_buf; - nand->legacy.cmd_ctrl = mtk_nfc_cmd_ctrl; /* set default mode in case dt entry is missing */ nand->ecc.mode = NAND_ECC_HW; From bcad94d7b7c13b123ed4ded86544667cfbfb1aa7 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sun, 7 Jun 2020 19:42:43 +0200 Subject: [PATCH 002/242] pinctrl: ingenic: Add NAND FRE/FWE pins for JZ4740 Add the FRE/FWE pins for the JZ4740. These pins must be in function #0 for the NAND to work. The reason it worked before was because the bootloader did set these pins to the correct function beforehand. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20200607174243.2361664-1-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 6a8d44504f94..1da72438d680 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -124,6 +124,7 @@ static int jz4740_nand_cs1_pins[] = { 0x39, }; static int jz4740_nand_cs2_pins[] = { 0x3a, }; static int jz4740_nand_cs3_pins[] = { 0x3b, }; static int jz4740_nand_cs4_pins[] = { 0x3c, }; +static int jz4740_nand_fre_fwe_pins[] = { 0x5c, 0x5d, }; static int jz4740_pwm_pwm0_pins[] = { 0x77, }; static int jz4740_pwm_pwm1_pins[] = { 0x78, }; static int jz4740_pwm_pwm2_pins[] = { 0x79, }; @@ -146,6 +147,7 @@ static int jz4740_nand_cs1_funcs[] = { 0, }; static int jz4740_nand_cs2_funcs[] = { 0, }; static int jz4740_nand_cs3_funcs[] = { 0, }; static int jz4740_nand_cs4_funcs[] = { 0, }; +static int jz4740_nand_fre_fwe_funcs[] = { 0, 0, }; static int jz4740_pwm_pwm0_funcs[] = { 0, }; static int jz4740_pwm_pwm1_funcs[] = { 0, }; static int jz4740_pwm_pwm2_funcs[] = { 0, }; @@ -178,6 +180,7 @@ static const struct group_desc jz4740_groups[] = { INGENIC_PIN_GROUP("nand-cs2", jz4740_nand_cs2), INGENIC_PIN_GROUP("nand-cs3", jz4740_nand_cs3), INGENIC_PIN_GROUP("nand-cs4", jz4740_nand_cs4), + INGENIC_PIN_GROUP("nand-fre-fwe", jz4740_nand_fre_fwe), INGENIC_PIN_GROUP("pwm0", jz4740_pwm_pwm0), INGENIC_PIN_GROUP("pwm1", jz4740_pwm_pwm1), INGENIC_PIN_GROUP("pwm2", jz4740_pwm_pwm2), @@ -195,7 +198,7 @@ static const char *jz4740_lcd_groups[] = { "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-18bit-tft", "lcd-no-pins", }; static const char *jz4740_nand_groups[] = { - "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4", + "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4", "nand-fre-fwe", }; static const char *jz4740_pwm0_groups[] = { "pwm0", }; static const char *jz4740_pwm1_groups[] = { "pwm1", }; From f46fe79ff1b65692a65266a5bec6dbe2bf7fc70f Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Mon, 8 Jun 2020 14:51:43 +0200 Subject: [PATCH 003/242] pinctrl-single: fix pcs_parse_pinconf() return value This patch causes pcs_parse_pinconf() to return -ENOTSUPP when no pinctrl_map is added. The current behavior is to return 0 when !PCS_HAS_PINCONF or !nconfs. Thus pcs_parse_one_pinctrl_entry() incorrectly assumes that a map was added and sets num_maps = 2. Analysis: ========= The function pcs_parse_one_pinctrl_entry() calls pcs_parse_pinconf() if PCS_HAS_PINCONF is enabled. The function pcs_parse_pinconf() returns 0 to indicate there was no error and num_maps is then set to 2: 980 static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, 981 struct device_node *np, 982 struct pinctrl_map **map, 983 unsigned *num_maps, 984 const char **pgnames) 985 { 1053 (*map)->type = PIN_MAP_TYPE_MUX_GROUP; 1054 (*map)->data.mux.group = np->name; 1055 (*map)->data.mux.function = np->name; 1056 1057 if (PCS_HAS_PINCONF && function) { 1058 res = pcs_parse_pinconf(pcs, np, function, map); 1059 if (res) 1060 goto free_pingroups; 1061 *num_maps = 2; 1062 } else { 1063 *num_maps = 1; 1064 } However, pcs_parse_pinconf() will also return 0 if !PCS_HAS_PINCONF or !nconfs. I believe these conditions should indicate that no map was added by returning -ENOTSUPP. Otherwise pcs_parse_one_pinctrl_entry() will set num_maps = 2 even though no maps were successfully added, as it does not reach "m++" on line 940: 895 static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, 896 struct pcs_function *func, 897 struct pinctrl_map **map) 898 899 { 900 struct pinctrl_map *m = *map; 917 /* If pinconf isn't supported, don't parse properties in below. */ 918 if (!PCS_HAS_PINCONF) 919 return 0; 920 921 /* cacluate how much properties are supported in current node */ 922 for (i = 0; i < ARRAY_SIZE(prop2); i++) { 923 if (of_find_property(np, prop2[i].name, NULL)) 924 nconfs++; 925 } 926 for (i = 0; i < ARRAY_SIZE(prop4); i++) { 927 if (of_find_property(np, prop4[i].name, NULL)) 928 nconfs++; 929 } 930 if (!nconfs) 919 return 0; 932 933 func->conf = devm_kcalloc(pcs->dev, 934 nconfs, sizeof(struct pcs_conf_vals), 935 GFP_KERNEL); 936 if (!func->conf) 937 return -ENOMEM; 938 func->nconfs = nconfs; 939 conf = &(func->conf[0]); 940 m++; This situtation will cause a boot failure [0] on the BeagleBone Black (AM3358) when am33xx_pinmux node in arch/arm/boot/dts/am33xx-l4.dtsi has compatible = "pinconf-single" instead of "pinctrl-single". The patch fixes this issue by returning -ENOSUPP when !PCS_HAS_PINCONF or !nconfs, so that pcs_parse_one_pinctrl_entry() will know that no map was added. Logic is also added to pcs_parse_one_pinctrl_entry() to distinguish between -ENOSUPP and other errors. In the case of -ENOSUPP, num_maps is set to 1 as it is valid for pinconf to be enabled and a given pin group to not any pinconf properties. [0] https://lore.kernel.org/linux-omap/20200529175544.GA3766151@x1/ Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") Signed-off-by: Drew Fustini Acked-by: Tony Lindgren Link: https://lore.kernel.org/r/20200608125143.GA2789203@x1 Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 1e0614daee9b..a9d511982780 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -916,7 +916,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, /* If pinconf isn't supported, don't parse properties in below. */ if (!PCS_HAS_PINCONF) - return 0; + return -ENOTSUPP; /* cacluate how much properties are supported in current node */ for (i = 0; i < ARRAY_SIZE(prop2); i++) { @@ -928,7 +928,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, nconfs++; } if (!nconfs) - return 0; + return -ENOTSUPP; func->conf = devm_kcalloc(pcs->dev, nconfs, sizeof(struct pcs_conf_vals), @@ -1056,9 +1056,12 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, if (PCS_HAS_PINCONF && function) { res = pcs_parse_pinconf(pcs, np, function, map); - if (res) + if (res == 0) + *num_maps = 2; + else if (res == -ENOTSUPP) + *num_maps = 1; + else goto free_pingroups; - *num_maps = 2; } else { *num_maps = 1; } From b5fc06a10e7aea88c9a9efd4547a3aee44138e3e Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Fri, 12 Jun 2020 14:06:09 +0200 Subject: [PATCH 004/242] pinctrl: ingenic: Add ingenic,jz4725b-gpio compatible string Add a compatible string to support the GPIO chips on the JZ4725B SoC. There was already a compatible string for the pinctrl node, but not for the individual GPIO chip nodes. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20200612120609.12730-1-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 1da72438d680..fc0d10411aa9 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -2295,6 +2295,7 @@ static const struct regmap_config ingenic_pinctrl_regmap_config = { static const struct of_device_id ingenic_gpio_of_match[] __initconst = { { .compatible = "ingenic,jz4740-gpio", }, + { .compatible = "ingenic,jz4725b-gpio", }, { .compatible = "ingenic,jz4760-gpio", }, { .compatible = "ingenic,jz4770-gpio", }, { .compatible = "ingenic,jz4780-gpio", }, From d888229ef2fbc9557cbf953fa8e2687550f5308b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 15 Jun 2020 14:54:06 +0200 Subject: [PATCH 005/242] pinctrl: stm32: don't print an error on probe deferral during clock get Change STM32 pinctrl driver to not print an error trace when probe is deferred due to clock resource. Probe defer issue (for clocks) could occur during bank registering when some banks have already been registered. In this case banks already registered should be released. To not waste time in this case, it is better to check first if all clocks are available before registering banks. Signed-off-by: Etienne Carriere Signed-off-by: Alexandre Torgue Link: https://lore.kernel.org/r/20200615125407.27632-2-alexandre.torgue@st.com Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index a657cd829ce6..c15460ef2307 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1217,12 +1217,6 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, if (IS_ERR(bank->base)) return PTR_ERR(bank->base); - bank->clk = of_clk_get_by_name(np, NULL); - if (IS_ERR(bank->clk)) { - dev_err(dev, "failed to get clk (%ld)\n", PTR_ERR(bank->clk)); - return PTR_ERR(bank->clk); - } - err = clk_prepare(bank->clk); if (err) { dev_err(dev, "failed to prepare clk (%d)\n", err); @@ -1517,6 +1511,23 @@ int stm32_pctl_probe(struct platform_device *pdev) if (!pctl->banks) return -ENOMEM; + i = 0; + for_each_available_child_of_node(np, child) { + struct stm32_gpio_bank *bank = &pctl->banks[i]; + + if (of_property_read_bool(child, "gpio-controller")) { + bank->clk = of_clk_get_by_name(child, NULL); + if (IS_ERR(bank->clk)) { + if (PTR_ERR(bank->clk) != -EPROBE_DEFER) + dev_err(dev, + "failed to get clk (%ld)\n", + PTR_ERR(bank->clk)); + return PTR_ERR(bank->clk); + } + i++; + } + } + for_each_available_child_of_node(np, child) { if (of_property_read_bool(child, "gpio-controller")) { ret = stm32_gpiolib_register_bank(pctl, child); From 2254e77665d5af6186781319d8bc109ba03008c1 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 15 Jun 2020 14:54:07 +0200 Subject: [PATCH 006/242] pinctrl: stm32: defer probe if reset resource is not yet ready Defer probe when pin controller reset is defined in the system resources but not yet probed. Signed-off-by: Etienne Carriere Signed-off-by: Alexandre Torgue Link: https://lore.kernel.org/r/20200615125407.27632-3-alexandre.torgue@st.com Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index c15460ef2307..162535e7c94d 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -84,6 +84,7 @@ struct stm32_pinctrl_group { struct stm32_gpio_bank { void __iomem *base; struct clk *clk; + struct reset_control *rstc; spinlock_t lock; struct gpio_chip gpio_chip; struct pinctrl_gpio_range range; @@ -1202,13 +1203,11 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct of_phandle_args args; struct device *dev = pctl->dev; struct resource res; - struct reset_control *rstc; int npins = STM32_GPIO_PINS_PER_BANK; int bank_nr, err; - rstc = of_reset_control_get_exclusive(np, NULL); - if (!IS_ERR(rstc)) - reset_control_deassert(rstc); + if (!IS_ERR(bank->rstc)) + reset_control_deassert(bank->rstc); if (of_address_to_resource(np, 0, &res)) return -ENODEV; @@ -1516,6 +1515,11 @@ int stm32_pctl_probe(struct platform_device *pdev) struct stm32_gpio_bank *bank = &pctl->banks[i]; if (of_property_read_bool(child, "gpio-controller")) { + bank->rstc = of_reset_control_get_exclusive(child, + NULL); + if (PTR_ERR(bank->rstc) == -EPROBE_DEFER) + return -EPROBE_DEFER; + bank->clk = of_clk_get_by_name(child, NULL); if (IS_ERR(bank->clk)) { if (PTR_ERR(bank->clk) != -EPROBE_DEFER) From d9665bb82269f0f2bc18b73f074754e452bb3767 Mon Sep 17 00:00:00 2001 From: Alexandre Torgue Date: Mon, 15 Jun 2020 14:59:50 +0200 Subject: [PATCH 007/242] pinctrl: stm32: return proper error code in pin_config_set ".pin_config_set" or ".pin_config_group_set" can be called with a configuration not supported (i.e. PIN_CONFIG_PERSIST_STATE). In this case, it is more suitable to return -ENOTSUPP instead of -EINVAL. Signed-off-by: Alexandre Torgue Link: https://lore.kernel.org/r/20200615125951.28008-2-alexandre.torgue@st.com Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 162535e7c94d..cdf6b01d1956 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1085,7 +1085,7 @@ static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, ret = stm32_pmx_gpio_set_direction(pctldev, range, pin, false); break; default: - ret = -EINVAL; + ret = -ENOTSUPP; } return ret; From b1a05ba9ae8cf6592e1d1f3e7b03bf8e5863f75f Mon Sep 17 00:00:00 2001 From: Alexandre Torgue Date: Mon, 15 Jun 2020 14:59:51 +0200 Subject: [PATCH 008/242] pinctrl: stm32: add possibility to configure pins individually Adds the possibility to configure a single pin through the gpiolib (i.e: to set PULL_UP/PULL_DOWN config). Mutex behavior is slightly changed to avoid a deadlock when pin_config_set is called (in this case pctldev->mutex is already taken). Signed-off-by: Alexandre Torgue Link: https://lore.kernel.org/r/20200615125951.28008-3-alexandre.torgue@st.com Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index cdf6b01d1956..faf2660298f5 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -303,6 +303,7 @@ static const struct gpio_chip stm32_gpio_template = { .direction_output = stm32_gpio_direction_output, .to_irq = stm32_gpio_to_irq, .get_direction = stm32_gpio_get_direction, + .set_config = gpiochip_generic_config, }; static void stm32_gpio_irq_trigger(struct irq_data *d) @@ -1052,7 +1053,7 @@ static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, struct stm32_gpio_bank *bank; int offset, ret = 0; - range = pinctrl_find_gpio_range_from_pin(pctldev, pin); + range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin); if (!range) { dev_err(pctl->dev, "No gpio range defined.\n"); return -EINVAL; @@ -1110,9 +1111,11 @@ static int stm32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, int i, ret; for (i = 0; i < num_configs; i++) { + mutex_lock(&pctldev->mutex); ret = stm32_pconf_parse_conf(pctldev, g->pin, pinconf_to_config_param(configs[i]), pinconf_to_config_argument(configs[i])); + mutex_unlock(&pctldev->mutex); if (ret < 0) return ret; @@ -1122,6 +1125,22 @@ static int stm32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, return 0; } +static int stm32_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + int i, ret; + + for (i = 0; i < num_configs; i++) { + ret = stm32_pconf_parse_conf(pctldev, pin, + pinconf_to_config_param(configs[i]), + pinconf_to_config_argument(configs[i])); + if (ret < 0) + return ret; + } + + return 0; +} + static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned int pin) @@ -1187,10 +1206,10 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev, } } - static const struct pinconf_ops stm32_pconf_ops = { .pin_config_group_get = stm32_pconf_group_get, .pin_config_group_set = stm32_pconf_group_set, + .pin_config_set = stm32_pconf_set, .pin_config_dbg_show = stm32_pconf_dbg_show, }; From 4e7293e3a2a367d0935925988acfd941549ce489 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:44 +0300 Subject: [PATCH 009/242] pinctrl: cherryview: Introduce chv_readl() helper There are plenty of places where we call readl(chv_padreg(pctrl, offset, ...)); Replace them with newly introduced chv_readl() helper chv_readl(pctrl, offset, ...); Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 71 +++++++++++----------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 8e3953a223d0..afff7c0fc33f 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -610,6 +610,11 @@ static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, return pctrl->regs + offset + reg; } +static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset) +{ + return readl(chv_padreg(pctrl, pin, offset)); +} + static void chv_writel(u32 value, void __iomem *reg) { writel(value, reg); @@ -620,10 +625,7 @@ static void chv_writel(u32 value, void __iomem *reg) /* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */ static bool chv_pad_locked(struct chv_pinctrl *pctrl, unsigned int offset) { - void __iomem *reg; - - reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); - return readl(reg) & CHV_PADCTRL1_CFGLOCK; + return chv_readl(pctrl, offset, CHV_PADCTRL1) & CHV_PADCTRL1_CFGLOCK; } static int chv_get_groups_count(struct pinctrl_dev *pctldev) @@ -661,8 +663,8 @@ static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); - ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1)); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); + ctrl1 = chv_readl(pctrl, offset, CHV_PADCTRL1); locked = chv_pad_locked(pctrl, offset); raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -758,7 +760,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, mode &= ~PINMODE_INVERT_OE; reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); - value = readl(reg); + value = chv_readl(pctrl, pin, CHV_PADCTRL0); /* Disable GPIO mode */ value &= ~CHV_PADCTRL0_GPIOEN; /* Set to desired mode */ @@ -768,7 +770,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, /* Update for invert_oe */ reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); - value = readl(reg) & ~CHV_PADCTRL1_INVRXTX_MASK; + value = chv_readl(pctrl, pin, CHV_PADCTRL1) & ~CHV_PADCTRL1_INVRXTX_MASK; if (invert_oe) value |= CHV_PADCTRL1_INVRXTX_TXENABLE; chv_writel(value, reg); @@ -789,7 +791,7 @@ static void chv_gpio_clear_triggering(struct chv_pinctrl *pctrl, u32 value; reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); - value = readl(reg); + value = chv_readl(pctrl, offset, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; chv_writel(value, reg); @@ -807,7 +809,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, raw_spin_lock_irqsave(&chv_lock, flags); if (chv_pad_locked(pctrl, offset)) { - value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); + value = chv_readl(pctrl, offset, CHV_PADCTRL0); if (!(value & CHV_PADCTRL0_GPIOEN)) { /* Locked so cannot enable */ raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -828,7 +830,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, chv_gpio_clear_triggering(pctrl, offset); reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); - value = readl(reg); + value = chv_readl(pctrl, offset, CHV_PADCTRL0); /* * If the pin is in HiZ mode (both TX and RX buffers are @@ -877,7 +879,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK; + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0) & ~CHV_PADCTRL0_GPIOCFG_MASK; if (input) ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; else @@ -910,8 +912,8 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, u32 term; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); - ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1)); + ctrl0 = chv_readl(pctrl, pin, CHV_PADCTRL0); + ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); raw_spin_unlock_irqrestore(&chv_lock, flags); term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT; @@ -987,7 +989,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, u32 ctrl0, pull; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(reg); + ctrl0 = chv_readl(pctrl, pin, CHV_PADCTRL0); switch (param) { case PIN_CONFIG_BIAS_DISABLE: @@ -1053,7 +1055,7 @@ static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, u32 ctrl1; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl1 = readl(reg); + ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); if (enable) ctrl1 |= CHV_PADCTRL1_ODEN; @@ -1175,7 +1177,7 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned int offset) u32 ctrl0, cfg; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); raw_spin_unlock_irqrestore(&chv_lock, flags); cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; @@ -1196,7 +1198,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) raw_spin_lock_irqsave(&chv_lock, flags); reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); - ctrl0 = readl(reg); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); if (value) ctrl0 |= CHV_PADCTRL0_GPIOTXSTATE; @@ -1215,7 +1217,7 @@ static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) unsigned long flags; raw_spin_lock_irqsave(&chv_lock, flags); - ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); + ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); raw_spin_unlock_irqrestore(&chv_lock, flags); direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; @@ -1259,7 +1261,7 @@ static void chv_gpio_irq_ack(struct irq_data *d) raw_spin_lock(&chv_lock); - intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT); @@ -1277,7 +1279,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) raw_spin_lock_irqsave(&chv_lock, flags); - intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; @@ -1322,11 +1324,11 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) u32 intsel, value; raw_spin_lock_irqsave(&chv_lock, flags); - intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + intsel = chv_readl(pctrl, pin, CHV_PADCTRL0); intsel &= CHV_PADCTRL0_INTSEL_MASK; intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; - value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1)); + value = chv_readl(pctrl, pin, CHV_PADCTRL1); if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL) handler = handle_level_irq; else @@ -1369,7 +1371,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) if (!chv_pad_locked(pctrl, pin)) { void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); - value = readl(reg); + value = chv_readl(pctrl, pin, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; @@ -1389,7 +1391,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) chv_writel(value, reg); } - value = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); + value = chv_readl(pctrl, pin, CHV_PADCTRL0); value &= CHV_PADCTRL0_INTSEL_MASK; value >>= CHV_PADCTRL0_INTSEL_SHIFT; @@ -1487,7 +1489,7 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, desc = &community->pins[i]; - intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0)); + intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); intsel &= CHV_PADCTRL0_INTSEL_MASK; intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; @@ -1721,7 +1723,6 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) for (i = 0; i < pctrl->community->npins; i++) { const struct pinctrl_pin_desc *desc; struct chv_pin_context *ctx; - void __iomem *reg; desc = &pctrl->community->pins[i]; if (chv_pad_locked(pctrl, desc->number)) @@ -1729,11 +1730,10 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) ctx = &pctrl->saved_pin_context[i]; - reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL0); - ctx->padctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIORXSTATE; + ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); + ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; - reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL1); - ctx->padctrl1 = readl(reg); + ctx->padctrl1 = chv_readl(pctrl, desc->number, CHV_PADCTRL1); } raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -1770,19 +1770,20 @@ static int chv_pinctrl_resume_noirq(struct device *dev) /* Only restore if our saved state differs from the current */ reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL0); - val = readl(reg) & ~CHV_PADCTRL0_GPIORXSTATE; + val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); + val &= ~CHV_PADCTRL0_GPIORXSTATE; if (ctx->padctrl0 != val) { chv_writel(ctx->padctrl0, reg); dev_dbg(pctrl->dev, "restored pin %2u ctrl0 0x%08x\n", - desc->number, readl(reg)); + desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL0)); } reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL1); - val = readl(reg); + val = chv_readl(pctrl, desc->number, CHV_PADCTRL1); if (ctx->padctrl1 != val) { chv_writel(ctx->padctrl1, reg); dev_dbg(pctrl->dev, "restored pin %2u ctrl1 0x%08x\n", - desc->number, readl(reg)); + desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL1)); } } From 99fd6512278e08a0fb264e3b83eccbbf0ff30967 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:45 +0300 Subject: [PATCH 010/242] pinctrl: cherryview: Introduce helpers to IO with common registers Pin control device and effectively the single community in it has a set of common registers. It's good to have a helpers to IO on them. Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 39 ++++++++++++++-------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index afff7c0fc33f..28ed2f3b42a1 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -598,6 +598,20 @@ static const struct chv_community *chv_communities[] = { */ static DEFINE_RAW_SPINLOCK(chv_lock); +static u32 chv_pctrl_readl(struct chv_pinctrl *pctrl, unsigned int offset) +{ + return readl(pctrl->regs + offset); +} + +static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 value) +{ + void __iomem *reg = pctrl->regs + offset; + + /* Write and simple read back to confirm the bus transferring done */ + writel(value, reg); + readl(reg); +} + static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, unsigned int reg) { @@ -1264,7 +1278,7 @@ static void chv_gpio_irq_ack(struct irq_data *d) intr_line = chv_readl(pctrl, pin, CHV_PADCTRL0); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; - chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT); + chv_pctrl_writel(pctrl, CHV_INTSTAT, BIT(intr_line)); raw_spin_unlock(&chv_lock); } @@ -1283,12 +1297,12 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; - value = readl(pctrl->regs + CHV_INTMASK); + value = chv_pctrl_readl(pctrl, CHV_INTMASK); if (mask) value &= ~BIT(intr_line); else value |= BIT(intr_line); - chv_writel(value, pctrl->regs + CHV_INTMASK); + chv_pctrl_writel(pctrl, CHV_INTMASK, value); raw_spin_unlock_irqrestore(&chv_lock, flags); } @@ -1419,7 +1433,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) chained_irq_enter(chip, desc); raw_spin_lock_irqsave(&chv_lock, flags); - pending = readl(pctrl->regs + CHV_INTSTAT); + pending = chv_pctrl_readl(pctrl, CHV_INTSTAT); raw_spin_unlock_irqrestore(&chv_lock, flags); for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) { @@ -1514,12 +1528,11 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip) * Mask all interrupts the community is able to generate * but leave the ones that can only generate GPEs unmasked. */ - chv_writel(GENMASK(31, pctrl->community->nirqs), - pctrl->regs + CHV_INTMASK); + chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, pctrl->community->nirqs)); } /* Clear all interrupts */ - chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); + chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); return 0; } @@ -1618,9 +1631,9 @@ static acpi_status chv_pinctrl_mmio_access_handler(u32 function, raw_spin_lock_irqsave(&chv_lock, flags); if (function == ACPI_WRITE) - chv_writel((u32)(*value), pctrl->regs + (u32)address); + chv_pctrl_writel(pctrl, address, *value); else if (function == ACPI_READ) - *value = readl(pctrl->regs + (u32)address); + *value = chv_pctrl_readl(pctrl, address); else ret = AE_BAD_PARAMETER; @@ -1718,7 +1731,7 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) raw_spin_lock_irqsave(&chv_lock, flags); - pctrl->saved_intmask = readl(pctrl->regs + CHV_INTMASK); + pctrl->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); for (i = 0; i < pctrl->community->npins; i++) { const struct pinctrl_pin_desc *desc; @@ -1754,7 +1767,7 @@ static int chv_pinctrl_resume_noirq(struct device *dev) * registers because we don't know in which state BIOS left them * upon exiting suspend. */ - chv_writel(0, pctrl->regs + CHV_INTMASK); + chv_pctrl_writel(pctrl, CHV_INTMASK, 0x0000); for (i = 0; i < pctrl->community->npins; i++) { const struct pinctrl_pin_desc *desc; @@ -1791,8 +1804,8 @@ static int chv_pinctrl_resume_noirq(struct device *dev) * Now that all pins are restored to known state, we can restore * the interrupt mask register as well. */ - chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); - chv_writel(pctrl->saved_intmask, pctrl->regs + CHV_INTMASK); + chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); + chv_pctrl_writel(pctrl, CHV_INTMASK, pctrl->saved_intmask); raw_spin_unlock_irqrestore(&chv_lock, flags); From bfc8a4baec9377b3fdd2bbeafaf5a7f2c95b1151 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:46 +0300 Subject: [PATCH 011/242] pinctrl: cherryview: Convert chv_writel() to use chv_padreg() chv_writel() is now solely used for cases where we write data to the PAD registers. In order to simplify callers, calculate register address inside chv_writel(). Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 48 ++++++++-------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 28ed2f3b42a1..1fc46dfb880e 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -629,10 +629,12 @@ static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int o return readl(chv_padreg(pctrl, pin, offset)); } -static void chv_writel(u32 value, void __iomem *reg) +static void chv_writel(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset, u32 value) { + void __iomem *reg = chv_padreg(pctrl, pin, offset); + + /* Write and simple read back to confirm the bus transferring done */ writel(value, reg); - /* simple readback to confirm the bus transferring done */ readl(reg); } @@ -758,7 +760,6 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, for (i = 0; i < grp->npins; i++) { int pin = grp->pins[i]; - void __iomem *reg; unsigned int mode; bool invert_oe; u32 value; @@ -773,21 +774,19 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, invert_oe = mode & PINMODE_INVERT_OE; mode &= ~PINMODE_INVERT_OE; - reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); value = chv_readl(pctrl, pin, CHV_PADCTRL0); /* Disable GPIO mode */ value &= ~CHV_PADCTRL0_GPIOEN; /* Set to desired mode */ value &= ~CHV_PADCTRL0_PMODE_MASK; value |= mode << CHV_PADCTRL0_PMODE_SHIFT; - chv_writel(value, reg); + chv_writel(pctrl, pin, CHV_PADCTRL0, value); /* Update for invert_oe */ - reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); value = chv_readl(pctrl, pin, CHV_PADCTRL1) & ~CHV_PADCTRL1_INVRXTX_MASK; if (invert_oe) value |= CHV_PADCTRL1_INVRXTX_TXENABLE; - chv_writel(value, reg); + chv_writel(pctrl, pin, CHV_PADCTRL1, value); dev_dbg(pctrl->dev, "configured pin %u mode %u OE %sinverted\n", pin, mode, invert_oe ? "" : "not "); @@ -801,14 +800,12 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, static void chv_gpio_clear_triggering(struct chv_pinctrl *pctrl, unsigned int offset) { - void __iomem *reg; u32 value; - reg = chv_padreg(pctrl, offset, CHV_PADCTRL1); value = chv_readl(pctrl, offset, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; - chv_writel(value, reg); + chv_writel(pctrl, offset, CHV_PADCTRL1, value); } static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, @@ -817,7 +814,6 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); unsigned long flags; - void __iomem *reg; u32 value; raw_spin_lock_irqsave(&chv_lock, flags); @@ -843,7 +839,6 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, /* Disable interrupt generation */ chv_gpio_clear_triggering(pctrl, offset); - reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); value = chv_readl(pctrl, offset, CHV_PADCTRL0); /* @@ -853,13 +848,12 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, if ((value & CHV_PADCTRL0_GPIOCFG_MASK) == (CHV_PADCTRL0_GPIOCFG_HIZ << CHV_PADCTRL0_GPIOCFG_SHIFT)) { value &= ~CHV_PADCTRL0_GPIOCFG_MASK; - value |= CHV_PADCTRL0_GPIOCFG_GPI << - CHV_PADCTRL0_GPIOCFG_SHIFT; + value |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; } /* Switch to a GPIO mode */ value |= CHV_PADCTRL0_GPIOEN; - chv_writel(value, reg); + chv_writel(pctrl, offset, CHV_PADCTRL0, value); } raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -887,7 +881,6 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, unsigned int offset, bool input) { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - void __iomem *reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); unsigned long flags; u32 ctrl0; @@ -898,7 +891,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; else ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT; - chv_writel(ctrl0, reg); + chv_writel(pctrl, offset, CHV_PADCTRL0, ctrl0); raw_spin_unlock_irqrestore(&chv_lock, flags); @@ -998,7 +991,6 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, enum pin_config_param param, u32 arg) { - void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); unsigned long flags; u32 ctrl0, pull; @@ -1055,7 +1047,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, return -EINVAL; } - chv_writel(ctrl0, reg); + chv_writel(pctrl, pin, CHV_PADCTRL0, ctrl0); raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; @@ -1064,7 +1056,6 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned int pin, static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, bool enable) { - void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); unsigned long flags; u32 ctrl1; @@ -1076,7 +1067,7 @@ static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, else ctrl1 &= ~CHV_PADCTRL1_ODEN; - chv_writel(ctrl1, reg); + chv_writel(pctrl, pin, CHV_PADCTRL1, ctrl1); raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; @@ -1206,12 +1197,10 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); unsigned long flags; - void __iomem *reg; u32 ctrl0; raw_spin_lock_irqsave(&chv_lock, flags); - reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); if (value) @@ -1219,7 +1208,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) else ctrl0 &= ~CHV_PADCTRL0_GPIOTXSTATE; - chv_writel(ctrl0, reg); + chv_writel(pctrl, offset, CHV_PADCTRL0, ctrl0); raw_spin_unlock_irqrestore(&chv_lock, flags); } @@ -1383,8 +1372,6 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) * Driver programs the IntWakeCfg bits and save the mapping. */ if (!chv_pad_locked(pctrl, pin)) { - void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); - value = chv_readl(pctrl, pin, CHV_PADCTRL1); value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; value &= ~CHV_PADCTRL1_INVRXTX_MASK; @@ -1402,7 +1389,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) value |= CHV_PADCTRL1_INVRXTX_RXDATA; } - chv_writel(value, reg); + chv_writel(pctrl, pin, CHV_PADCTRL1, value); } value = chv_readl(pctrl, pin, CHV_PADCTRL0); @@ -1772,7 +1759,6 @@ static int chv_pinctrl_resume_noirq(struct device *dev) for (i = 0; i < pctrl->community->npins; i++) { const struct pinctrl_pin_desc *desc; const struct chv_pin_context *ctx; - void __iomem *reg; u32 val; desc = &pctrl->community->pins[i]; @@ -1782,19 +1768,17 @@ static int chv_pinctrl_resume_noirq(struct device *dev) ctx = &pctrl->saved_pin_context[i]; /* Only restore if our saved state differs from the current */ - reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL0); val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); val &= ~CHV_PADCTRL0_GPIORXSTATE; if (ctx->padctrl0 != val) { - chv_writel(ctx->padctrl0, reg); + chv_writel(pctrl, desc->number, CHV_PADCTRL0, ctx->padctrl0); dev_dbg(pctrl->dev, "restored pin %2u ctrl0 0x%08x\n", desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL0)); } - reg = chv_padreg(pctrl, desc->number, CHV_PADCTRL1); val = chv_readl(pctrl, desc->number, CHV_PADCTRL1); if (ctx->padctrl1 != val) { - chv_writel(ctx->padctrl1, reg); + chv_writel(pctrl, desc->number, CHV_PADCTRL1, ctx->padctrl1); dev_dbg(pctrl->dev, "restored pin %2u ctrl1 0x%08x\n", desc->number, chv_readl(pctrl, desc->number, CHV_PADCTRL1)); } From 42fecd55c772549b88ec10841b7f4ab2330c44b5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:47 +0300 Subject: [PATCH 012/242] pinctrl: intel: Allow drivers to define total amount of IRQs per community Some of the pin control devices may not be capable to generate IRQ per each pin in the community. Allow individual drivers to define total amount of IRQs per community. Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index cc78c483518f..0f01ef3fdfdd 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -103,6 +103,7 @@ enum { * @gpps: Pad groups if the controller has variable size pad groups * @ngpps: Number of pad groups in this community * @pad_map: Optional non-linear mapping of the pads + * @nirqs: Optional total number of IRQs this community can generate * @regs: Community specific common registers (reserved for core driver) * @pad_regs: Community specific pad registers (reserved for core driver) * @@ -127,6 +128,7 @@ struct intel_community { const struct intel_padgroup *gpps; size_t ngpps; const unsigned int *pad_map; + unsigned short nirqs; /* Reserved for the core driver */ void __iomem *regs; From c8f8f65ea8ebc50aba7ab9741b3d0343ddf63d7f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:48 +0300 Subject: [PATCH 013/242] pinctrl: intel: Allow drivers to define ACPI address space ID Individual drivers may install ACPI OpRegion handlers based on address space ID which differs from community to community. Add special field in the struct intel_community for that purpose. Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index 0f01ef3fdfdd..4e17308d33e9 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -104,6 +104,7 @@ enum { * @ngpps: Number of pad groups in this community * @pad_map: Optional non-linear mapping of the pads * @nirqs: Optional total number of IRQs this community can generate + * @acpi_space_id: Optional address space ID for ACPI OpRegion handler * @regs: Community specific common registers (reserved for core driver) * @pad_regs: Community specific pad registers (reserved for core driver) * @@ -129,6 +130,7 @@ struct intel_community { size_t ngpps; const unsigned int *pad_map; unsigned short nirqs; + unsigned short acpi_space_id; /* Reserved for the core driver */ void __iomem *regs; From 293428f93260d45f712a2d9f895bc0def0b34a3d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 9 Jun 2020 21:24:49 +0300 Subject: [PATCH 014/242] pinctrl: cherryview: Re-use data structures from pinctrl-intel.h (part 3) We have some data structures duplicated across the drivers. Let's deduplicate them by using struct intel_pinctrl_soc_data, struct intel_community and struct intel_pinctrl_context that are being provided by pinctrl-intel.h. Signed-off-by: Andy Shevchenko Acked-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 268 +++++++++++---------- 1 file changed, 138 insertions(+), 130 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 1fc46dfb880e..9ef246145bde 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -2,7 +2,7 @@ /* * Cherryview/Braswell pinctrl driver * - * Copyright (C) 2014, Intel Corporation + * Copyright (C) 2014, 2020 Intel Corporation * Author: Mika Westerberg * * This driver is based on the original Cherryview GPIO driver by @@ -67,35 +67,7 @@ #define CHV_PADCTRL1_INTWAKECFG_BOTH 3 #define CHV_PADCTRL1_INTWAKECFG_LEVEL 4 -/** - * struct chv_community - A community specific configuration - * @uid: ACPI _UID used to match the community - * @pins: All pins in this community - * @npins: Number of pins - * @groups: All groups in this community - * @ngroups: Number of groups - * @functions: All functions in this community - * @nfunctions: Number of functions - * @gpps: Pad groups - * @ngpps: Number of pad groups in this community - * @nirqs: Total number of IRQs this community can generate - * @acpi_space_id: An address space ID for ACPI OpRegion handler - */ -struct chv_community { - const char *uid; - const struct pinctrl_pin_desc *pins; - size_t npins; - const struct intel_pingroup *groups; - size_t ngroups; - const struct intel_function *functions; - size_t nfunctions; - const struct intel_padgroup *gpps; - size_t ngpps; - size_t nirqs; - acpi_adr_space_type acpi_space_id; -}; - -struct chv_pin_context { +struct intel_pad_context { u32 padctrl0; u32 padctrl1; }; @@ -107,13 +79,13 @@ struct chv_pin_context { * @pctldev: Pointer to the pin controller device * @chip: GPIO chip in this pin controller * @irqchip: IRQ chip in this pin controller - * @regs: MMIO registers + * @soc: Community specific pin configuration data + * @communities: All communities in this pin controller + * @ncommunities: Number of communities in this pin controller + * @context: Configuration saved over system sleep * @irq: Our parent irq - * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO - * offset (in GPIO number space) - * @community: Community this pinctrl instance represents + * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space) * @saved_intmask: Interrupt mask saved for system sleep - * @saved_pin_context: Pointer to a context of the pins saved for system sleep * * The first group in @groups is expected to contain all pins that can be * used as GPIOs. @@ -124,24 +96,34 @@ struct chv_pinctrl { struct pinctrl_dev *pctldev; struct gpio_chip chip; struct irq_chip irqchip; - void __iomem *regs; - unsigned int irq; + const struct intel_pinctrl_soc_data *soc; + struct intel_community *communities; + size_t ncommunities; + struct intel_pinctrl_context context; + int irq; + unsigned int intr_lines[16]; - const struct chv_community *community; u32 saved_intmask; - struct chv_pin_context *saved_pin_context; }; #define PINMODE_INVERT_OE BIT(15) #define PINMODE(m, i) ((m) | ((i) * PINMODE_INVERT_OE)) -#define CHV_GPP(start, end) \ +#define CHV_GPP(start, end) \ { \ .base = (start), \ .size = (end) - (start) + 1, \ } +#define CHV_COMMUNITY(g, i, a) \ + { \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + .nirqs = (i), \ + .acpi_space_id = (a), \ + } + static const struct pinctrl_pin_desc southwest_pins[] = { PINCTRL_PIN(0, "FST_SPI_D2"), PINCTRL_PIN(1, "FST_SPI_D0"), @@ -303,7 +285,15 @@ static const struct intel_padgroup southwest_gpps[] = { CHV_GPP(90, 97), }; -static const struct chv_community southwest_community = { +/* + * Southwest community can generate GPIO interrupts only for the first 8 + * interrupts. The upper half (8-15) can only be used to trigger GPEs. + */ +static const struct intel_community southwest_communities[] = { + CHV_COMMUNITY(southwest_gpps, 8, 0x91), +}; + +static const struct intel_pinctrl_soc_data southwest_soc_data = { .uid = "1", .pins = southwest_pins, .npins = ARRAY_SIZE(southwest_pins), @@ -311,15 +301,8 @@ static const struct chv_community southwest_community = { .ngroups = ARRAY_SIZE(southwest_groups), .functions = southwest_functions, .nfunctions = ARRAY_SIZE(southwest_functions), - .gpps = southwest_gpps, - .ngpps = ARRAY_SIZE(southwest_gpps), - /* - * Southwest community can generate GPIO interrupts only for the - * first 8 interrupts. The upper half (8-15) can only be used to - * trigger GPEs. - */ - .nirqs = 8, - .acpi_space_id = 0x91, + .communities = southwest_communities, + .ncommunities = ARRAY_SIZE(southwest_communities), }; static const struct pinctrl_pin_desc north_pins[] = { @@ -396,19 +379,20 @@ static const struct intel_padgroup north_gpps[] = { CHV_GPP(60, 72), }; -static const struct chv_community north_community = { +/* + * North community can generate GPIO interrupts only for the first 8 + * interrupts. The upper half (8-15) can only be used to trigger GPEs. + */ +static const struct intel_community north_communities[] = { + CHV_COMMUNITY(north_gpps, 8, 0x92), +}; + +static const struct intel_pinctrl_soc_data north_soc_data = { .uid = "2", .pins = north_pins, .npins = ARRAY_SIZE(north_pins), - .gpps = north_gpps, - .ngpps = ARRAY_SIZE(north_gpps), - /* - * North community can generate GPIO interrupts only for the first - * 8 interrupts. The upper half (8-15) can only be used to trigger - * GPEs. - */ - .nirqs = 8, - .acpi_space_id = 0x92, + .communities = north_communities, + .ncommunities = ARRAY_SIZE(north_communities), }; static const struct pinctrl_pin_desc east_pins[] = { @@ -444,14 +428,16 @@ static const struct intel_padgroup east_gpps[] = { CHV_GPP(15, 26), }; -static const struct chv_community east_community = { +static const struct intel_community east_communities[] = { + CHV_COMMUNITY(east_gpps, 16, 0x93), +}; + +static const struct intel_pinctrl_soc_data east_soc_data = { .uid = "3", .pins = east_pins, .npins = ARRAY_SIZE(east_pins), - .gpps = east_gpps, - .ngpps = ARRAY_SIZE(east_gpps), - .nirqs = 16, - .acpi_space_id = 0x93, + .communities = east_communities, + .ncommunities = ARRAY_SIZE(east_communities), }; static const struct pinctrl_pin_desc southeast_pins[] = { @@ -566,7 +552,11 @@ static const struct intel_padgroup southeast_gpps[] = { CHV_GPP(75, 85), }; -static const struct chv_community southeast_community = { +static const struct intel_community southeast_communities[] = { + CHV_COMMUNITY(southeast_gpps, 16, 0x94), +}; + +static const struct intel_pinctrl_soc_data southeast_soc_data = { .uid = "4", .pins = southeast_pins, .npins = ARRAY_SIZE(southeast_pins), @@ -574,17 +564,16 @@ static const struct chv_community southeast_community = { .ngroups = ARRAY_SIZE(southeast_groups), .functions = southeast_functions, .nfunctions = ARRAY_SIZE(southeast_functions), - .gpps = southeast_gpps, - .ngpps = ARRAY_SIZE(southeast_gpps), - .nirqs = 16, - .acpi_space_id = 0x94, + .communities = southeast_communities, + .ncommunities = ARRAY_SIZE(southeast_communities), }; -static const struct chv_community *chv_communities[] = { - &southwest_community, - &north_community, - &east_community, - &southeast_community, +static const struct intel_pinctrl_soc_data *chv_soc_data[] = { + &southwest_soc_data, + &north_soc_data, + &east_soc_data, + &southeast_soc_data, + NULL }; /* @@ -600,12 +589,15 @@ static DEFINE_RAW_SPINLOCK(chv_lock); static u32 chv_pctrl_readl(struct chv_pinctrl *pctrl, unsigned int offset) { - return readl(pctrl->regs + offset); + const struct intel_community *community = &pctrl->communities[0]; + + return readl(community->regs + offset); } static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 value) { - void __iomem *reg = pctrl->regs + offset; + const struct intel_community *community = &pctrl->communities[0]; + void __iomem *reg = community->regs + offset; /* Write and simple read back to confirm the bus transferring done */ writel(value, reg); @@ -615,13 +607,13 @@ static void chv_pctrl_writel(struct chv_pinctrl *pctrl, unsigned int offset, u32 static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned int offset, unsigned int reg) { + const struct intel_community *community = &pctrl->communities[0]; unsigned int family_no = offset / MAX_FAMILY_PAD_GPIO_NO; unsigned int pad_no = offset % MAX_FAMILY_PAD_GPIO_NO; - offset = FAMILY_PAD_REGS_OFF + FAMILY_PAD_REGS_SIZE * family_no + - GPIO_REGS_SIZE * pad_no; + offset = FAMILY_PAD_REGS_SIZE * family_no + GPIO_REGS_SIZE * pad_no; - return pctrl->regs + offset + reg; + return community->pad_regs + offset + reg; } static u32 chv_readl(struct chv_pinctrl *pctrl, unsigned int pin, unsigned int offset) @@ -648,7 +640,7 @@ static int chv_get_groups_count(struct pinctrl_dev *pctldev) { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->community->ngroups; + return pctrl->soc->ngroups; } static const char *chv_get_group_name(struct pinctrl_dev *pctldev, @@ -656,7 +648,7 @@ static const char *chv_get_group_name(struct pinctrl_dev *pctldev, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->community->groups[group].name; + return pctrl->soc->groups[group].name; } static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, @@ -664,8 +656,8 @@ static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - *pins = pctrl->community->groups[group].pins; - *npins = pctrl->community->groups[group].npins; + *pins = pctrl->soc->groups[group].pins; + *npins = pctrl->soc->groups[group].npins; return 0; } @@ -713,7 +705,7 @@ static int chv_get_functions_count(struct pinctrl_dev *pctldev) { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->community->nfunctions; + return pctrl->soc->nfunctions; } static const char *chv_get_function_name(struct pinctrl_dev *pctldev, @@ -721,7 +713,7 @@ static const char *chv_get_function_name(struct pinctrl_dev *pctldev, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - return pctrl->community->functions[function].name; + return pctrl->soc->functions[function].name; } static int chv_get_function_groups(struct pinctrl_dev *pctldev, @@ -731,8 +723,8 @@ static int chv_get_function_groups(struct pinctrl_dev *pctldev, { struct chv_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - *groups = pctrl->community->functions[function].groups; - *ngroups = pctrl->community->functions[function].ngroups; + *groups = pctrl->soc->functions[function].groups; + *ngroups = pctrl->soc->functions[function].ngroups; return 0; } @@ -744,7 +736,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned long flags; int i; - grp = &pctrl->community->groups[group]; + grp = &pctrl->soc->groups[group]; raw_spin_lock_irqsave(&chv_lock, flags); @@ -1412,6 +1404,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) { struct gpio_chip *gc = irq_desc_get_handler_data(desc); struct chv_pinctrl *pctrl = gpiochip_get_data(gc); + const struct intel_community *community = &pctrl->communities[0]; struct irq_chip *chip = irq_desc_get_chip(desc); unsigned long pending; unsigned long flags; @@ -1423,7 +1416,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) pending = chv_pctrl_readl(pctrl, CHV_INTSTAT); raw_spin_unlock_irqrestore(&chv_lock, flags); - for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) { + for_each_set_bit(intr_line, &pending, community->nirqs) { unsigned int irq, offset; offset = pctrl->intr_lines[intr_line]; @@ -1480,15 +1473,15 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, unsigned int ngpios) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); - const struct chv_community *community = pctrl->community; + const struct intel_community *community = &pctrl->communities[0]; int i; /* Do not add GPIOs that can only generate GPEs to the IRQ domain */ - for (i = 0; i < community->npins; i++) { + for (i = 0; i < pctrl->soc->npins; i++) { const struct pinctrl_pin_desc *desc; u32 intsel; - desc = &community->pins[i]; + desc = &pctrl->soc->pins[i]; intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); intsel &= CHV_PADCTRL0_INTSEL_MASK; @@ -1502,6 +1495,7 @@ static void chv_init_irq_valid_mask(struct gpio_chip *chip, static int chv_gpio_irq_init_hw(struct gpio_chip *chip) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); + const struct intel_community *community = &pctrl->communities[0]; /* * The same set of machines in chv_no_valid_mask[] have incorrectly @@ -1515,7 +1509,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip) * Mask all interrupts the community is able to generate * but leave the ones that can only generate GPEs unmasked. */ - chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, pctrl->community->nirqs)); + chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, community->nirqs)); } /* Clear all interrupts */ @@ -1527,7 +1521,7 @@ static int chv_gpio_irq_init_hw(struct gpio_chip *chip) static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) { struct chv_pinctrl *pctrl = gpiochip_get_data(chip); - const struct chv_community *community = pctrl->community; + const struct intel_community *community = &pctrl->communities[0]; const struct intel_padgroup *gpp; int ret, i; @@ -1547,15 +1541,15 @@ static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) { + const struct intel_community *community = &pctrl->communities[0]; const struct intel_padgroup *gpp; struct gpio_chip *chip = &pctrl->chip; bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); - const struct chv_community *community = pctrl->community; int ret, i, irq_base; *chip = chv_gpio_chip; - chip->ngpio = community->pins[community->npins - 1].number + 1; + chip->ngpio = pctrl->soc->pins[pctrl->soc->npins - 1].number + 1; chip->label = dev_name(pctrl->dev); chip->add_pin_ranges = chv_gpio_add_pin_ranges; chip->parent = pctrl->dev; @@ -1581,7 +1575,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) chip->irq.init_valid_mask = chv_init_irq_valid_mask; } else { irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, - community->npins, NUMA_NO_NODE); + pctrl->soc->npins, NUMA_NO_NODE); if (irq_base < 0) { dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); return irq_base; @@ -1631,6 +1625,10 @@ static acpi_status chv_pinctrl_mmio_access_handler(u32 function, static int chv_pinctrl_probe(struct platform_device *pdev) { + const struct intel_pinctrl_soc_data *soc_data = NULL; + const struct intel_pinctrl_soc_data **soc_table; + struct intel_community *community; + struct device *dev = &pdev->dev; struct chv_pinctrl *pctrl; struct acpi_device *adev; acpi_status status; @@ -1640,40 +1638,53 @@ static int chv_pinctrl_probe(struct platform_device *pdev) if (!adev) return -ENODEV; - pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); + soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(dev); + for (i = 0; soc_table[i]; i++) { + if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) { + soc_data = soc_table[i]; + break; + } + } + if (!soc_data) + return -ENODEV; + + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); if (!pctrl) return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(chv_communities); i++) - if (!strcmp(adev->pnp.unique_id, chv_communities[i]->uid)) { - pctrl->community = chv_communities[i]; - break; - } - if (i == ARRAY_SIZE(chv_communities)) - return -ENODEV; - pctrl->dev = &pdev->dev; + pctrl->soc = soc_data; + + pctrl->ncommunities = pctrl->soc->ncommunities; + pctrl->communities = devm_kmemdup(dev, pctrl->soc->communities, + pctrl->ncommunities * sizeof(*pctrl->communities), + GFP_KERNEL); + if (!pctrl->communities) + return -ENOMEM; + + community = &pctrl->communities[0]; + community->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(community->regs)) + return PTR_ERR(community->regs); + + community->pad_regs = community->regs + FAMILY_PAD_REGS_OFF; #ifdef CONFIG_PM_SLEEP - pctrl->saved_pin_context = devm_kcalloc(pctrl->dev, - pctrl->community->npins, sizeof(*pctrl->saved_pin_context), - GFP_KERNEL); - if (!pctrl->saved_pin_context) + pctrl->context.pads = devm_kcalloc(dev, pctrl->soc->npins, + sizeof(*pctrl->context.pads), + GFP_KERNEL); + if (!pctrl->context.pads) return -ENOMEM; #endif - pctrl->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(pctrl->regs)) - return PTR_ERR(pctrl->regs); - irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; pctrl->pctldesc = chv_pinctrl_desc; pctrl->pctldesc.name = dev_name(&pdev->dev); - pctrl->pctldesc.pins = pctrl->community->pins; - pctrl->pctldesc.npins = pctrl->community->npins; + pctrl->pctldesc.pins = pctrl->soc->pins; + pctrl->pctldesc.npins = pctrl->soc->npins; pctrl->pctldev = devm_pinctrl_register(&pdev->dev, &pctrl->pctldesc, pctrl); @@ -1687,7 +1698,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev) return ret; status = acpi_install_address_space_handler(adev->handle, - pctrl->community->acpi_space_id, + community->acpi_space_id, chv_pinctrl_mmio_access_handler, NULL, pctrl); if (ACPI_FAILURE(status)) @@ -1701,9 +1712,10 @@ static int chv_pinctrl_probe(struct platform_device *pdev) static int chv_pinctrl_remove(struct platform_device *pdev) { struct chv_pinctrl *pctrl = platform_get_drvdata(pdev); + const struct intel_community *community = &pctrl->communities[0]; acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev), - pctrl->community->acpi_space_id, + community->acpi_space_id, chv_pinctrl_mmio_access_handler); return 0; @@ -1720,16 +1732,14 @@ static int chv_pinctrl_suspend_noirq(struct device *dev) pctrl->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); - for (i = 0; i < pctrl->community->npins; i++) { + for (i = 0; i < pctrl->soc->npins; i++) { const struct pinctrl_pin_desc *desc; - struct chv_pin_context *ctx; + struct intel_pad_context *ctx = &pctrl->context.pads[i]; - desc = &pctrl->community->pins[i]; + desc = &pctrl->soc->pins[i]; if (chv_pad_locked(pctrl, desc->number)) continue; - ctx = &pctrl->saved_pin_context[i]; - ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; @@ -1756,17 +1766,15 @@ static int chv_pinctrl_resume_noirq(struct device *dev) */ chv_pctrl_writel(pctrl, CHV_INTMASK, 0x0000); - for (i = 0; i < pctrl->community->npins; i++) { + for (i = 0; i < pctrl->soc->npins; i++) { const struct pinctrl_pin_desc *desc; - const struct chv_pin_context *ctx; + struct intel_pad_context *ctx = &pctrl->context.pads[i]; u32 val; - desc = &pctrl->community->pins[i]; + desc = &pctrl->soc->pins[i]; if (chv_pad_locked(pctrl, desc->number)) continue; - ctx = &pctrl->saved_pin_context[i]; - /* Only restore if our saved state differs from the current */ val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); val &= ~CHV_PADCTRL0_GPIORXSTATE; @@ -1803,7 +1811,7 @@ static const struct dev_pm_ops chv_pinctrl_pm_ops = { }; static const struct acpi_device_id chv_pinctrl_acpi_match[] = { - { "INT33FF" }, + { "INT33FF", (kernel_ulong_t)chv_soc_data }, { } }; MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match); From af7e3eeb84e27fcfd1f46a80f111c8c72c206776 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:54 +0300 Subject: [PATCH 015/242] pinctrl: intel: Disable input and output buffer when switching to GPIO It's possible scenario that pin has been in different mode, while the respective GPIO register has a leftover output buffer enabled. In such case when we request GPIO it will switch to GPIO mode, and thus to output with unknown value, followed by switching to input mode. This can produce a glitch on the pin. Disable input and output buffer when switching to GPIO to avoid potential glitches. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 6a274e20d926..9df5a0c0d416 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -435,11 +435,20 @@ static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) { u32 value; + value = readl(padcfg0); + /* Put the pad into GPIO mode */ - value = readl(padcfg0) & ~PADCFG0_PMODE_MASK; + value &= ~PADCFG0_PMODE_MASK; + value |= PADCFG0_PMODE_GPIO; + + /* Disable input and output buffers */ + value &= ~PADCFG0_GPIORXDIS; + value &= ~PADCFG0_GPIOTXDIS; + /* Disable SCI/SMI/NMI generation */ value &= ~(PADCFG0_GPIROUTIOXAPIC | PADCFG0_GPIROUTSCI); value &= ~(PADCFG0_GPIROUTSMI | PADCFG0_GPIROUTNMI); + writel(value, padcfg0); } @@ -1036,6 +1045,9 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned int type) intel_gpio_set_gpio_mode(reg); + /* Disable TX buffer and enable RX (this will be input) */ + __intel_gpio_set_direction(reg, true); + value = readl(reg); value &= ~(PADCFG0_RXEVCFG_MASK | PADCFG0_RXINV); From f62cdde5483957fc28249a9fc691e892e6b38e85 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:55 +0300 Subject: [PATCH 016/242] pinctrl: intel: Reduce scope of the lock In some cases lock covers unneeded calls and operations. Reduce scope of the lock in such cases. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 9df5a0c0d416..d0b658ba2136 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -460,6 +460,8 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, void __iomem *padcfg0; unsigned long flags; + padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); + raw_spin_lock_irqsave(&pctrl->lock, flags); if (!intel_pad_owned_by_host(pctrl, pin)) { @@ -472,8 +474,6 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, return 0; } - padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); - /* * If pin is already configured in GPIO mode, we assume that * firmware provides correct settings. In such case we avoid @@ -503,11 +503,10 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev, void __iomem *padcfg0; unsigned long flags; - raw_spin_lock_irqsave(&pctrl->lock, flags); - padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); - __intel_gpio_set_direction(padcfg0, input); + raw_spin_lock_irqsave(&pctrl->lock, flags); + __intel_gpio_set_direction(padcfg0, input); raw_spin_unlock_irqrestore(&pctrl->lock, flags); return 0; @@ -622,10 +621,11 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, int ret = 0; u32 value; - raw_spin_lock_irqsave(&pctrl->lock, flags); - community = intel_get_community(pctrl, pin); padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); + + raw_spin_lock_irqsave(&pctrl->lock, flags); + value = readl(padcfg1); switch (param) { From 86851bbce1a332b0658519386041fe430f4e9e39 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:56 +0300 Subject: [PATCH 017/242] pinctrl: intel: Make use of IRQ_RETVAL() Instead of using bitwise operations against returned values, which is a bit fragile, convert IRQ handler to count amount of GPIO groups, where at least one interrupt happened, and convert it to returned value by IRQ_RETVAL() macro. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index d0b658ba2136..e05273a00ff2 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1093,12 +1093,12 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) return 0; } -static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, - const struct intel_community *community) +static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, + const struct intel_community *community) { struct gpio_chip *gc = &pctrl->chip; - irqreturn_t ret = IRQ_NONE; - int gpp; + unsigned int gpp; + int ret = 0; for (gpp = 0; gpp < community->ngpps; gpp++) { const struct intel_padgroup *padgrp = &community->gpps[gpp]; @@ -1118,9 +1118,9 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, irq = irq_find_mapping(gc->irq.domain, padgrp->gpio_base + gpp_offset); generic_handle_irq(irq); - - ret |= IRQ_HANDLED; } + + ret += pending ? 1 : 0; } return ret; @@ -1130,16 +1130,16 @@ static irqreturn_t intel_gpio_irq(int irq, void *data) { const struct intel_community *community; struct intel_pinctrl *pctrl = data; - irqreturn_t ret = IRQ_NONE; - int i; + unsigned int i; + int ret = 0; /* Need to check all communities for pending interrupts */ for (i = 0; i < pctrl->ncommunities; i++) { community = &pctrl->communities[i]; - ret |= intel_gpio_community_irq_handler(pctrl, community); + ret += intel_gpio_community_irq_handler(pctrl, community); } - return ret; + return IRQ_RETVAL(ret); } static int intel_gpio_add_community_ranges(struct intel_pinctrl *pctrl, From bb2f43d49b72c8497dba53a44fc41bea03d4ab9e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:57 +0300 Subject: [PATCH 018/242] pinctrl: intel: Get rid of redundant 'else' in intel_config_set_debounce() In a code like if (...) { ... goto label; } else { ... } the 'else' keyword is redundant. Get rid of it for better readability. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index e05273a00ff2..76b1b899a389 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -719,12 +719,12 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, if (v < 3 || v > 15) { ret = -EINVAL; goto exit_unlock; - } else { - /* Enable glitch filter and debouncer */ - value0 |= PADCFG0_PREGFRXSEL; - value2 |= v << PADCFG2_DEBOUNCE_SHIFT; - value2 |= PADCFG2_DEBEN; } + + /* Enable glitch filter and debouncer */ + value0 |= PADCFG0_PREGFRXSEL; + value2 |= v << PADCFG2_DEBOUNCE_SHIFT; + value2 |= PADCFG2_DEBEN; } writel(value0, padcfg0); From 8fff0427d1b2b47469496dbcf3f846dab0cccc7b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:58 +0300 Subject: [PATCH 019/242] pinctrl: intel: Drop the only label in the code for consistency Drop the only label in the code, i.e. in intel_config_set_debounce(), for consistency with the rest. In entire driver we use multipoint return. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 76b1b899a389..2bcda48ea29a 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -695,7 +695,6 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, void __iomem *padcfg0, *padcfg2; unsigned long flags; u32 value0, value2; - int ret = 0; padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); if (!padcfg2) @@ -717,8 +716,8 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, v = order_base_2(debounce * NSEC_PER_USEC / DEBOUNCE_PERIOD_NSEC); if (v < 3 || v > 15) { - ret = -EINVAL; - goto exit_unlock; + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + return -EINVAL; } /* Enable glitch filter and debouncer */ @@ -730,10 +729,9 @@ static int intel_config_set_debounce(struct intel_pinctrl *pctrl, writel(value0, padcfg0); writel(value2, padcfg2); -exit_unlock: raw_spin_unlock_irqrestore(&pctrl->lock, flags); - return ret; + return 0; } static int intel_config_set(struct pinctrl_dev *pctldev, unsigned int pin, From 81ab5542d7978f41a2b41c0f325b45980a478c6f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:49:59 +0300 Subject: [PATCH 020/242] pinctrl: intel: Split intel_config_get() to three functions Split intel_config_get() to three functions, i.e. intel_config_get() and two helpers intel_config_get_pull() and intel_config_get_debounce() to be symmetrical with intel_config_set*(). Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 97 ++++++++++++++++++--------- 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 2bcda48ea29a..d6ef012f2cc4 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -521,20 +521,17 @@ static const struct pinmux_ops intel_pinmux_ops = { .gpio_set_direction = intel_gpio_set_direction, }; -static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *config) +static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, + enum pin_config_param param, u32 *arg) { - struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); - enum pin_config_param param = pinconf_to_config_param(*config); const struct intel_community *community; + void __iomem *padcfg1; u32 value, term; - u32 arg = 0; - - if (!intel_pad_owned_by_host(pctrl, pin)) - return -ENOTSUPP; community = intel_get_community(pctrl, pin); - value = readl(intel_get_padcfg(pctrl, pin, PADCFG1)); + padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); + value = readl(padcfg1); + term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT; switch (param) { @@ -549,16 +546,16 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, switch (term) { case PADCFG1_TERM_1K: - arg = 1000; + *arg = 1000; break; case PADCFG1_TERM_2K: - arg = 2000; + *arg = 2000; break; case PADCFG1_TERM_5K: - arg = 5000; + *arg = 5000; break; case PADCFG1_TERM_20K: - arg = 20000; + *arg = 20000; break; } @@ -572,36 +569,72 @@ static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, case PADCFG1_TERM_1K: if (!(community->features & PINCTRL_FEATURE_1K_PD)) return -EINVAL; - arg = 1000; + *arg = 1000; break; case PADCFG1_TERM_5K: - arg = 5000; + *arg = 5000; break; case PADCFG1_TERM_20K: - arg = 20000; + *arg = 20000; break; } break; - case PIN_CONFIG_INPUT_DEBOUNCE: { - void __iomem *padcfg2; - u32 v; - - padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); - if (!padcfg2) - return -ENOTSUPP; - - v = readl(padcfg2); - if (!(v & PADCFG2_DEBEN)) - return -EINVAL; - - v = (v & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT; - arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC; - - break; + default: + return -EINVAL; } + return 0; +} + +static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int pin, + enum pin_config_param param, u32 *arg) +{ + void __iomem *padcfg2; + unsigned long v; + u32 value2; + + padcfg2 = intel_get_padcfg(pctrl, pin, PADCFG2); + if (!padcfg2) + return -ENOTSUPP; + + value2 = readl(padcfg2); + if (!(value2 & PADCFG2_DEBEN)) + return -EINVAL; + + v = (value2 & PADCFG2_DEBOUNCE_MASK) >> PADCFG2_DEBOUNCE_SHIFT; + *arg = BIT(v) * DEBOUNCE_PERIOD_NSEC / NSEC_PER_USEC; + + return 0; +} + +static int intel_config_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + u32 arg = 0; + int ret; + + if (!intel_pad_owned_by_host(pctrl, pin)) + return -ENOTSUPP; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = intel_config_get_pull(pctrl, pin, param, &arg); + if (ret) + return ret; + break; + + case PIN_CONFIG_INPUT_DEBOUNCE: + ret = intel_config_get_debounce(pctrl, pin, param, &arg); + if (ret) + return ret; + break; + default: return -ENOTSUPP; } From e64fbfa51e8fc4eeca2d2bbf0d31a30a15734229 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:50:00 +0300 Subject: [PATCH 021/242] pinctrl: intel: Protect IO in few call backs by lock Protect IO in intel_gpio_get_direction(), intel_gpio_community_irq_handler(), intel_config_get_debounce() and intel_config_get_pull() by lock. Even for simple readl() we better serialize IO to avoid potential problems. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index d6ef012f2cc4..35c88fcb75a2 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -526,11 +526,15 @@ static int intel_config_get_pull(struct intel_pinctrl *pctrl, unsigned int pin, { const struct intel_community *community; void __iomem *padcfg1; + unsigned long flags; u32 value, term; community = intel_get_community(pctrl, pin); padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); + + raw_spin_lock_irqsave(&pctrl->lock, flags); value = readl(padcfg1); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); term = (value & PADCFG1_TERM_MASK) >> PADCFG1_TERM_SHIFT; @@ -592,6 +596,7 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p enum pin_config_param param, u32 *arg) { void __iomem *padcfg2; + unsigned long flags; unsigned long v; u32 value2; @@ -599,7 +604,9 @@ static int intel_config_get_debounce(struct intel_pinctrl *pctrl, unsigned int p if (!padcfg2) return -ENOTSUPP; + raw_spin_lock_irqsave(&pctrl->lock, flags); value2 = readl(padcfg2); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); if (!(value2 & PADCFG2_DEBEN)) return -EINVAL; @@ -934,6 +941,7 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned int offset, static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct intel_pinctrl *pctrl = gpiochip_get_data(chip); + unsigned long flags; void __iomem *reg; u32 padcfg0; int pin; @@ -946,8 +954,9 @@ static int intel_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) if (!reg) return -EINVAL; + raw_spin_lock_irqsave(&pctrl->lock, flags); padcfg0 = readl(reg); - + raw_spin_unlock_irqrestore(&pctrl->lock, flags); if (padcfg0 & PADCFG0_PMODE_MASK) return -EINVAL; @@ -1134,12 +1143,17 @@ static int intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, for (gpp = 0; gpp < community->ngpps; gpp++) { const struct intel_padgroup *padgrp = &community->gpps[gpp]; unsigned long pending, enabled, gpp_offset; + unsigned long flags; + + raw_spin_lock_irqsave(&pctrl->lock, flags); pending = readl(community->regs + community->is_offset + padgrp->reg_num * 4); enabled = readl(community->regs + community->ie_offset + padgrp->reg_num * 4); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + /* Only interrupts that are enabled */ pending &= enabled; From d1bfd0229ec4deb53e61f95c050b524152fd0d9e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 10 Jun 2020 21:14:49 +0300 Subject: [PATCH 022/242] pinctrl: intel: Make use of for_each_requested_gpio_in_range() Make use of for_each_requested_gpio_in_range() instead of home grown analogue. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 35c88fcb75a2..b64997b303e0 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1628,19 +1628,6 @@ static void intel_gpio_irq_init(struct intel_pinctrl *pctrl) } } -static u32 -intel_gpio_is_requested(struct gpio_chip *chip, int base, unsigned int size) -{ - u32 requested = 0; - unsigned int i; - - for (i = 0; i < size; i++) - if (gpiochip_is_requested(chip, base + i)) - requested |= BIT(i); - - return requested; -} - static bool intel_gpio_update_reg(void __iomem *reg, u32 mask, u32 value) { u32 curr, updated; @@ -1661,12 +1648,16 @@ static void intel_restore_hostown(struct intel_pinctrl *pctrl, unsigned int c, const struct intel_community *community = &pctrl->communities[c]; const struct intel_padgroup *padgrp = &community->gpps[gpp]; struct device *dev = pctrl->dev; - u32 requested; + const char *dummy; + u32 requested = 0; + unsigned int i; if (padgrp->gpio_base == INTEL_GPIO_BASE_NOMAP) return; - requested = intel_gpio_is_requested(&pctrl->chip, padgrp->gpio_base, padgrp->size); + for_each_requested_gpio_in_range(&pctrl->chip, i, padgrp->gpio_base, padgrp->size, dummy) + requested |= BIT(i); + if (!intel_gpio_update_reg(base + gpp * 4, requested, saved)) return; From f3e7d2812247342c415c76ba75fd79df57ee2a74 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 10 Jun 2020 21:14:49 +0300 Subject: [PATCH 023/242] pinctrl: lynxpoint: Make use of for_each_requested_gpio() Make use of for_each_requested_gpio() instead of home grown analogue. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index a45b8f2182fd..2a3af998b91c 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -919,16 +919,17 @@ static int lp_gpio_runtime_resume(struct device *dev) static int lp_gpio_resume(struct device *dev) { struct intel_pinctrl *lg = dev_get_drvdata(dev); + struct gpio_chip *chip = &lg->chip; + const char *dummy; void __iomem *reg; int i; /* on some hardware suspend clears input sensing, re-enable it here */ - for (i = 0; i < lg->chip.ngpio; i++) { - if (gpiochip_is_requested(&lg->chip, i) != NULL) { - reg = lp_gpio_reg(&lg->chip, i, LP_CONFIG2); - iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); - } + for_each_requested_gpio(chip, i, dummy) { + reg = lp_gpio_reg(chip, i, LP_CONFIG2); + iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); } + return 0; } From 0472567ba86469eb9faabc917f4c3084c08cf0c2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 15 Jun 2020 17:30:15 +0300 Subject: [PATCH 024/242] pinctrl: lynxpoint: Introduce helpers to enable or disable input Introduce couple of helpers to enable or disable input. i.e. lp_gpio_enable_input() and lp_gpio_disable_input(). Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 2a3af998b91c..003d795528e8 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -386,6 +386,16 @@ static int lp_pinmux_set_mux(struct pinctrl_dev *pctldev, return 0; } +static void lp_gpio_enable_input(void __iomem *reg) +{ + iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); +} + +static void lp_gpio_disable_input(void __iomem *reg) +{ + iowrite32(ioread32(reg) | GPINDIS_BIT, reg); +} + static int lp_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int pin) @@ -411,7 +421,7 @@ static int lp_gpio_request_enable(struct pinctrl_dev *pctldev, } /* Enable input sensing */ - iowrite32(ioread32(conf2) & ~GPINDIS_BIT, conf2); + lp_gpio_enable_input(conf2); raw_spin_unlock_irqrestore(&lg->lock, flags); @@ -429,7 +439,7 @@ static void lp_gpio_disable_free(struct pinctrl_dev *pctldev, raw_spin_lock_irqsave(&lg->lock, flags); /* Disable input sensing */ - iowrite32(ioread32(conf2) | GPINDIS_BIT, conf2); + lp_gpio_disable_input(conf2); raw_spin_unlock_irqrestore(&lg->lock, flags); @@ -921,14 +931,11 @@ static int lp_gpio_resume(struct device *dev) struct intel_pinctrl *lg = dev_get_drvdata(dev); struct gpio_chip *chip = &lg->chip; const char *dummy; - void __iomem *reg; int i; /* on some hardware suspend clears input sensing, re-enable it here */ - for_each_requested_gpio(chip, i, dummy) { - reg = lp_gpio_reg(chip, i, LP_CONFIG2); - iowrite32(ioread32(reg) & ~GPINDIS_BIT, reg); - } + for_each_requested_gpio(chip, i, dummy) + lp_gpio_enable_input(lp_gpio_reg(chip, i, LP_CONFIG2)); return 0; } From e359a6f03ba3b35bc573c3993173a273041e4bc1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:50:05 +0300 Subject: [PATCH 025/242] pinctrl: lynxpoint: Drop no-op ACPI_PTR() call Since we dependent on ACPI, there is no need to use ACPI_PTR() which is a no-op in this case. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-lynxpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 003d795528e8..96589d01fe35 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -959,7 +959,7 @@ static struct platform_driver lp_gpio_driver = { .driver = { .name = "lp_gpio", .pm = &lp_gpio_pm_ops, - .acpi_match_table = ACPI_PTR(lynxpoint_gpio_acpi_match), + .acpi_match_table = lynxpoint_gpio_acpi_match, }, }; From e87daf0bd83cb82576940d0a6e0e48b01d18c939 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 12 Jun 2020 17:50:06 +0300 Subject: [PATCH 026/242] pinctrl: baytrail: Drop no-op ACPI_PTR() call Since we dependent on ACPI, there is no need to use ACPI_PTR() which is a no-op in this case. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-baytrail.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 0ff7c55173da..e3ceb3dfeabe 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1757,9 +1757,8 @@ static struct platform_driver byt_gpio_driver = { .driver = { .name = "byt_gpio", .pm = &byt_gpio_pm_ops, + .acpi_match_table = byt_gpio_acpi_match, .suppress_bind_attrs = true, - - .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match), }, }; From 156abe2961601d60a8c2a60c6dc8dd6ce7adcdaf Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 6 Jun 2020 11:31:50 +0200 Subject: [PATCH 027/242] pinctrl: baytrail: Fix pin being driven low for a while on gpiod_get(..., GPIOD_OUT_HIGH) The pins on the Bay Trail SoC have separate input-buffer and output-buffer enable bits and a read of the level bit of the value register will always return the value from the input-buffer. The BIOS of a device may configure a pin in output-only mode, only enabling the output buffer, and write 1 to the level bit to drive the pin high. This 1 written to the level bit will be stored inside the data-latch of the output buffer. But a subsequent read of the value register will return 0 for the level bit because the input-buffer is disabled. This causes a read-modify-write as done by byt_gpio_set_direction() to write 0 to the level bit, driving the pin low! Before this commit byt_gpio_direction_output() relied on pinctrl_gpio_direction_output() to set the direction, followed by a call to byt_gpio_set() to apply the selected value. This causes the pin to go low between the pinctrl_gpio_direction_output() and byt_gpio_set() calls. Change byt_gpio_direction_output() to directly make the register modifications itself instead. Replacing the 2 subsequent writes to the value register with a single write. Note that the pinctrl code does not keep track internally of the direction, so not going through pinctrl_gpio_direction_output() is not an issue. This issue was noticed on a Trekstor SurfTab Twin 10.1. When the panel is already on at boot (no external monitor connected), then the i915 driver does a gpiod_get(..., GPIOD_OUT_HIGH) for the panel-enable GPIO. The temporarily going low of that GPIO was causing the panel to reset itself after which it would not show an image until it was turned off and back on again (until a full modeset was done on it). This commit fixes this. This commit also updates the byt_gpio_direction_input() to use direct register accesses instead of going through pinctrl_gpio_direction_input(), to keep it consistent with byt_gpio_direction_output(). Note for backporting, this commit depends on: commit e2b74419e5cc ("pinctrl: baytrail: Replace WARN with dev_info_once when setting direct-irq pin to output") Cc: stable@vger.kernel.org Fixes: 86e3ef812fe3 ("pinctrl: baytrail: Update gpio chip operations") Signed-off-by: Hans de Goede Acked-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 67 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index e3ceb3dfeabe..a917a2df520e 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -800,6 +800,21 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, pm_runtime_put(vg->dev); } +static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg, + unsigned int offset) +{ + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + + /* + * Before making any direction modifications, do a check if gpio is set + * for direct IRQ. On Bay Trail, setting GPIO to output does not make + * sense, so let's at least inform the caller before they shoot + * themselves in the foot. + */ + if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) + dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); +} + static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, struct pinctrl_gpio_range *range, unsigned int offset, @@ -807,7 +822,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, { struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); - void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); unsigned long flags; u32 value; @@ -817,14 +831,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, value &= ~BYT_DIR_MASK; if (input) value |= BYT_OUTPUT_EN; - else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) - /* - * Before making any direction modifications, do a check if gpio - * is set for direct IRQ. On baytrail, setting GPIO to output - * does not make sense, so let's at least inform the caller before - * they shoot themselves in the foot. - */ - dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); + else + byt_gpio_direct_irq_check(vg, offset); writel(value, val_reg); @@ -1165,19 +1173,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - return pinctrl_gpio_direction_input(chip->base + offset); + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 reg; + + raw_spin_lock_irqsave(&byt_lock, flags); + + reg = readl(val_reg); + reg &= ~BYT_DIR_MASK; + reg |= BYT_OUTPUT_EN; + writel(reg, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; } +/* + * Note despite the temptation this MUST NOT be converted into a call to + * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this + * MUST be done as a single BYT_VAL_REG register write. + * See the commit message of the commit adding this comment for details. + */ static int byt_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - int ret = pinctrl_gpio_direction_output(chip->base + offset); + struct intel_pinctrl *vg = gpiochip_get_data(chip); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 reg; - if (ret) - return ret; + raw_spin_lock_irqsave(&byt_lock, flags); - byt_gpio_set(chip, offset, value); + byt_gpio_direct_irq_check(vg, offset); + reg = readl(val_reg); + reg &= ~BYT_DIR_MASK; + if (value) + reg |= BYT_LEVEL; + else + reg &= ~BYT_LEVEL; + + writel(reg, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } From b3b4f8dffd38c2ec08d7eadaa57147a0ff6e3714 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 5 Jun 2020 23:23:14 +0300 Subject: [PATCH 028/242] pinctrl: sh-pfc: r8a77980: Add RPC pins, groups, and functions Add the RPC pins/groups/functions to the R8A77980 PFC driver. They can be used if an Octal-SPI flash or HyperFlash is connected. Based on the patch by Dmitry Shifrin . Signed-off-by: Sergei Shtylyov Link: https://lore.kernel.org/r/fd089d37-95bb-4ec9-282f-e04d7e5195e4@cogentembedded.com Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/pfc-r8a77980.c | 76 +++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c index 14fe4032a52d..1055f9853404 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c @@ -1710,6 +1710,64 @@ static const unsigned int qspi1_data4_mux[] = { QSPI1_IO2_MARK, QSPI1_IO3_MARK }; +/* - RPC -------------------------------------------------------------------- */ +static const unsigned int rpc_clk1_pins[] = { + /* Octal-SPI flash: C/SCLK */ + RCAR_GP_PIN(5, 0), +}; +static const unsigned int rpc_clk1_mux[] = { + QSPI0_SPCLK_MARK, +}; +static const unsigned int rpc_clk2_pins[] = { + /* HyperFlash: CK, CK# */ + RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 6), +}; +static const unsigned int rpc_clk2_mux[] = { + QSPI0_SPCLK_MARK, QSPI1_SPCLK_MARK, +}; +static const unsigned int rpc_ctrl_pins[] = { + /* Octal-SPI flash: S#/CS, DQS */ + /* HyperFlash: CS#, RDS */ + RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 11), +}; +static const unsigned int rpc_ctrl_mux[] = { + QSPI0_SSL_MARK, QSPI1_SSL_MARK, +}; +static const unsigned int rpc_data_pins[] = { + /* DQ[0:7] */ + RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2), + RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 4), + RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8), + RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 10), +}; +static const unsigned int rpc_data_mux[] = { + QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, + QSPI0_IO2_MARK, QSPI0_IO3_MARK, + QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, + QSPI1_IO2_MARK, QSPI1_IO3_MARK, +}; +static const unsigned int rpc_reset_pins[] = { + /* RPC_RESET# */ + RCAR_GP_PIN(5, 12), +}; +static const unsigned int rpc_reset_mux[] = { + RPC_RESET_N_MARK, +}; +static const unsigned int rpc_int_pins[] = { + /* RPC_INT# */ + RCAR_GP_PIN(5, 14), +}; +static const unsigned int rpc_int_mux[] = { + RPC_INT_N_MARK, +}; +static const unsigned int rpc_wp_pins[] = { + /* RPC_WP# */ + RCAR_GP_PIN(5, 13), +}; +static const unsigned int rpc_wp_mux[] = { + RPC_WP_N_MARK, +}; + /* - SCIF0 ------------------------------------------------------------------ */ static const unsigned int scif0_data_pins[] = { /* RX0, TX0 */ @@ -2126,6 +2184,13 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(qspi1_ctrl), SH_PFC_PIN_GROUP(qspi1_data2), SH_PFC_PIN_GROUP(qspi1_data4), + SH_PFC_PIN_GROUP(rpc_clk1), + SH_PFC_PIN_GROUP(rpc_clk2), + SH_PFC_PIN_GROUP(rpc_ctrl), + SH_PFC_PIN_GROUP(rpc_data), + SH_PFC_PIN_GROUP(rpc_reset), + SH_PFC_PIN_GROUP(rpc_int), + SH_PFC_PIN_GROUP(rpc_wp), SH_PFC_PIN_GROUP(scif0_data), SH_PFC_PIN_GROUP(scif0_clk), SH_PFC_PIN_GROUP(scif0_ctrl), @@ -2362,6 +2427,16 @@ static const char * const qspi1_groups[] = { "qspi1_data4", }; +static const char * const rpc_groups[] = { + "rpc_clk1", + "rpc_clk2", + "rpc_ctrl", + "rpc_data", + "rpc_reset", + "rpc_int", + "rpc_wp", +}; + static const char * const scif0_groups[] = { "scif0_data", "scif0_clk", @@ -2460,6 +2535,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(pwm4), SH_PFC_FUNCTION(qspi0), SH_PFC_FUNCTION(qspi1), + SH_PFC_FUNCTION(rpc), SH_PFC_FUNCTION(scif0), SH_PFC_FUNCTION(scif1), SH_PFC_FUNCTION(scif3), From b2fc9b4eb1d79c03fd78e50b810c2ea27178e1e3 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 19 Jun 2020 20:54:32 +0300 Subject: [PATCH 029/242] pinctrl: sh-pfc: r8a77970: Add RPC pins, groups, and functions Add the RPC pins/groups/functions to the R8A77970 PFC driver. They can be used if an Octal-SPI flash or HyperFlash is connected. Based on the patch by Dmitry Shifrin . Signed-off-by: Sergei Shtylyov Link: https://lore.kernel.org/r/3982785f-4fca-96f9-2b6a-a0d1828cb0ad@cogentembedded.com Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/pfc-r8a77970.c | 76 +++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c index 25e27b6bee89..9f7d9c9238fc 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c @@ -1416,6 +1416,64 @@ static const unsigned int qspi1_data4_mux[] = { QSPI1_IO2_MARK, QSPI1_IO3_MARK }; +/* - RPC -------------------------------------------------------------------- */ +static const unsigned int rpc_clk1_pins[] = { + /* Octal-SPI flash: C/SCLK */ + RCAR_GP_PIN(5, 0), +}; +static const unsigned int rpc_clk1_mux[] = { + QSPI0_SPCLK_MARK, +}; +static const unsigned int rpc_clk2_pins[] = { + /* HyperFlash: CK, CK# */ + RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 6), +}; +static const unsigned int rpc_clk2_mux[] = { + QSPI0_SPCLK_MARK, QSPI1_SPCLK_MARK, +}; +static const unsigned int rpc_ctrl_pins[] = { + /* Octal-SPI flash: S#/CS, DQS */ + /* HyperFlash: CS#, RDS */ + RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 11), +}; +static const unsigned int rpc_ctrl_mux[] = { + QSPI0_SSL_MARK, QSPI1_SSL_MARK, +}; +static const unsigned int rpc_data_pins[] = { + /* DQ[0:7] */ + RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2), + RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 4), + RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8), + RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 10), +}; +static const unsigned int rpc_data_mux[] = { + QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK, + QSPI0_IO2_MARK, QSPI0_IO3_MARK, + QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK, + QSPI1_IO2_MARK, QSPI1_IO3_MARK, +}; +static const unsigned int rpc_reset_pins[] = { + /* RPC_RESET# */ + RCAR_GP_PIN(5, 12), +}; +static const unsigned int rpc_reset_mux[] = { + RPC_RESET_N_MARK, +}; +static const unsigned int rpc_int_pins[] = { + /* RPC_INT# */ + RCAR_GP_PIN(5, 14), +}; +static const unsigned int rpc_int_mux[] = { + RPC_INT_N_MARK, +}; +static const unsigned int rpc_wp_pins[] = { + /* RPC_WP# */ + RCAR_GP_PIN(5, 13), +}; +static const unsigned int rpc_wp_mux[] = { + RPC_WP_N_MARK, +}; + /* - SCIF Clock ------------------------------------------------------------- */ static const unsigned int scif_clk_a_pins[] = { /* SCIF_CLK */ @@ -1750,6 +1808,13 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(qspi1_ctrl), SH_PFC_PIN_GROUP(qspi1_data2), SH_PFC_PIN_GROUP(qspi1_data4), + SH_PFC_PIN_GROUP(rpc_clk1), + SH_PFC_PIN_GROUP(rpc_clk2), + SH_PFC_PIN_GROUP(rpc_ctrl), + SH_PFC_PIN_GROUP(rpc_data), + SH_PFC_PIN_GROUP(rpc_reset), + SH_PFC_PIN_GROUP(rpc_int), + SH_PFC_PIN_GROUP(rpc_wp), SH_PFC_PIN_GROUP(scif_clk_a), SH_PFC_PIN_GROUP(scif_clk_b), SH_PFC_PIN_GROUP(scif0_data), @@ -1954,6 +2019,16 @@ static const char * const qspi1_groups[] = { "qspi1_data4", }; +static const char * const rpc_groups[] = { + "rpc_clk1", + "rpc_clk2", + "rpc_ctrl", + "rpc_data", + "rpc_reset", + "rpc_int", + "rpc_wp", +}; + static const char * const scif_clk_groups[] = { "scif_clk_a", "scif_clk_b", @@ -2039,6 +2114,7 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(pwm4), SH_PFC_FUNCTION(qspi0), SH_PFC_FUNCTION(qspi1), + SH_PFC_FUNCTION(rpc), SH_PFC_FUNCTION(scif_clk), SH_PFC_FUNCTION(scif0), SH_PFC_FUNCTION(scif1), From 503a02b72d457f18eccf58296f9b50df6666d7fc Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 22 Jun 2020 18:56:15 +0300 Subject: [PATCH 030/242] pinctrl: merrifield: Update pin names in accordance with official list Some of the pin names were provided officially to the customers in different spelling. We update pin names in accordance with the official list. Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-merrifield.c | 46 +++++++++++----------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 04ca8ae95df8..2c213714df30 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -135,7 +135,7 @@ static const struct pinctrl_pin_desc mrfld_pins[] = { PINCTRL_PIN(43, "GP83_SD_D3"), PINCTRL_PIN(44, "GP84_SD_LS_CLK_FB"), PINCTRL_PIN(45, "GP85_SD_LS_CMD_DIR"), - PINCTRL_PIN(46, "GP86_SD_LVL_D_DIR"), + PINCTRL_PIN(46, "GP86_SD_LS_D_DIR"), PINCTRL_PIN(47, "GP88_SD_LS_SEL"), PINCTRL_PIN(48, "GP87_SD_PD"), PINCTRL_PIN(49, "GP89_SD_WP"), @@ -171,28 +171,28 @@ static const struct pinctrl_pin_desc mrfld_pins[] = { PINCTRL_PIN(77, "GP42_I2S_2_RXD"), PINCTRL_PIN(78, "GP43_I2S_2_TXD"), /* Family 6: GP SSP (22 pins) */ - PINCTRL_PIN(79, "GP120_SPI_3_CLK"), - PINCTRL_PIN(80, "GP121_SPI_3_SS"), - PINCTRL_PIN(81, "GP122_SPI_3_RXD"), - PINCTRL_PIN(82, "GP123_SPI_3_TXD"), - PINCTRL_PIN(83, "GP102_SPI_4_CLK"), - PINCTRL_PIN(84, "GP103_SPI_4_SS_0"), - PINCTRL_PIN(85, "GP104_SPI_4_SS_1"), - PINCTRL_PIN(86, "GP105_SPI_4_SS_2"), - PINCTRL_PIN(87, "GP106_SPI_4_SS_3"), - PINCTRL_PIN(88, "GP107_SPI_4_RXD"), - PINCTRL_PIN(89, "GP108_SPI_4_TXD"), - PINCTRL_PIN(90, "GP109_SPI_5_CLK"), - PINCTRL_PIN(91, "GP110_SPI_5_SS_0"), - PINCTRL_PIN(92, "GP111_SPI_5_SS_1"), - PINCTRL_PIN(93, "GP112_SPI_5_SS_2"), - PINCTRL_PIN(94, "GP113_SPI_5_SS_3"), - PINCTRL_PIN(95, "GP114_SPI_5_RXD"), - PINCTRL_PIN(96, "GP115_SPI_5_TXD"), - PINCTRL_PIN(97, "GP116_SPI_6_CLK"), - PINCTRL_PIN(98, "GP117_SPI_6_SS"), - PINCTRL_PIN(99, "GP118_SPI_6_RXD"), - PINCTRL_PIN(100, "GP119_SPI_6_TXD"), + PINCTRL_PIN(79, "GP120_SPI_0_CLK"), + PINCTRL_PIN(80, "GP121_SPI_0_SS"), + PINCTRL_PIN(81, "GP122_SPI_0_RXD"), + PINCTRL_PIN(82, "GP123_SPI_0_TXD"), + PINCTRL_PIN(83, "GP102_SPI_1_CLK"), + PINCTRL_PIN(84, "GP103_SPI_1_SS0"), + PINCTRL_PIN(85, "GP104_SPI_1_SS1"), + PINCTRL_PIN(86, "GP105_SPI_1_SS2"), + PINCTRL_PIN(87, "GP106_SPI_1_SS3"), + PINCTRL_PIN(88, "GP107_SPI_1_RXD"), + PINCTRL_PIN(89, "GP108_SPI_1_TXD"), + PINCTRL_PIN(90, "GP109_SPI_2_CLK"), + PINCTRL_PIN(91, "GP110_SPI_2_SS0"), + PINCTRL_PIN(92, "GP111_SPI_2_SS1"), + PINCTRL_PIN(93, "GP112_SPI_2_SS2"), + PINCTRL_PIN(94, "GP113_SPI_2_SS3"), + PINCTRL_PIN(95, "GP114_SPI_2_RXD"), + PINCTRL_PIN(96, "GP115_SPI_2_TXD"), + PINCTRL_PIN(97, "GP116_SPI_3_CLK"), + PINCTRL_PIN(98, "GP117_SPI_3_SS"), + PINCTRL_PIN(99, "GP118_SPI_3_RXD"), + PINCTRL_PIN(100, "GP119_SPI_3_TXD"), /* Family 7: I2C (14 pins) */ PINCTRL_PIN(101, "GP19_I2C_1_SCL"), PINCTRL_PIN(102, "GP20_I2C_1_SDA"), From 90d6bf481a5d0c32112925f3ecc640b9145f77d8 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 18 May 2020 19:09:12 +0200 Subject: [PATCH 031/242] mtd: rawnand: tango: Convert the driver to exec_op() Let's convert the driver to exec_op() to have one less driver relying on the legacy interface. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200518170912.328988-1-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/tango_nand.c | 145 ++++++++++++++++++------------ 1 file changed, 89 insertions(+), 56 deletions(-) diff --git a/drivers/mtd/nand/raw/tango_nand.c b/drivers/mtd/nand/raw/tango_nand.c index 246871e01027..b3a0d08f1733 100644 --- a/drivers/mtd/nand/raw/tango_nand.c +++ b/drivers/mtd/nand/raw/tango_nand.c @@ -113,53 +113,11 @@ struct tango_chip { #define TIMING(t0, t1, t2, t3) ((t0) << 24 | (t1) << 16 | (t2) << 8 | (t3)) -static void tango_cmd_ctrl(struct nand_chip *chip, int dat, unsigned int ctrl) -{ - struct tango_chip *tchip = to_tango_chip(chip); - - if (ctrl & NAND_CLE) - writeb_relaxed(dat, tchip->base + PBUS_CMD); - - if (ctrl & NAND_ALE) - writeb_relaxed(dat, tchip->base + PBUS_ADDR); -} - -static int tango_dev_ready(struct nand_chip *chip) -{ - struct tango_nfc *nfc = to_tango_nfc(chip->controller); - - return readl_relaxed(nfc->pbus_base + PBUS_CS_CTRL) & PBUS_IORDY; -} - -static u8 tango_read_byte(struct nand_chip *chip) -{ - struct tango_chip *tchip = to_tango_chip(chip); - - return readb_relaxed(tchip->base + PBUS_DATA); -} - -static void tango_read_buf(struct nand_chip *chip, u8 *buf, int len) -{ - struct tango_chip *tchip = to_tango_chip(chip); - - ioread8_rep(tchip->base + PBUS_DATA, buf, len); -} - -static void tango_write_buf(struct nand_chip *chip, const u8 *buf, int len) -{ - struct tango_chip *tchip = to_tango_chip(chip); - - iowrite8_rep(tchip->base + PBUS_DATA, buf, len); -} - -static void tango_select_chip(struct nand_chip *chip, int idx) +static void tango_select_target(struct nand_chip *chip, unsigned int cs) { struct tango_nfc *nfc = to_tango_nfc(chip->controller); struct tango_chip *tchip = to_tango_chip(chip); - if (idx < 0) - return; /* No "chip unselect" function */ - writel_relaxed(tchip->timing1, nfc->reg_base + NFC_TIMING1); writel_relaxed(tchip->timing2, nfc->reg_base + NFC_TIMING2); writel_relaxed(tchip->xfer_cfg, nfc->reg_base + NFC_XFER_CFG); @@ -168,6 +126,69 @@ static void tango_select_chip(struct nand_chip *chip, int idx) writel_relaxed(tchip->bb_cfg, nfc->reg_base + NFC_BB_CFG); } +static int tango_waitrdy(struct nand_chip *chip, unsigned int timeout_ms) +{ + struct tango_nfc *nfc = to_tango_nfc(chip->controller); + u32 status; + + return readl_relaxed_poll_timeout(nfc->pbus_base + PBUS_CS_CTRL, + status, status & PBUS_IORDY, 20, + timeout_ms); +} + +static int tango_exec_instr(struct nand_chip *chip, + const struct nand_op_instr *instr) +{ + struct tango_chip *tchip = to_tango_chip(chip); + unsigned int i; + + switch (instr->type) { + case NAND_OP_CMD_INSTR: + writeb_relaxed(instr->ctx.cmd.opcode, tchip->base + PBUS_CMD); + return 0; + case NAND_OP_ADDR_INSTR: + for (i = 0; i < instr->ctx.addr.naddrs; i++) + writeb_relaxed(instr->ctx.addr.addrs[i], + tchip->base + PBUS_ADDR); + return 0; + case NAND_OP_DATA_IN_INSTR: + ioread8_rep(tchip->base + PBUS_DATA, instr->ctx.data.buf.in, + instr->ctx.data.len); + return 0; + case NAND_OP_DATA_OUT_INSTR: + iowrite8_rep(tchip->base + PBUS_DATA, instr->ctx.data.buf.out, + instr->ctx.data.len); + return 0; + case NAND_OP_WAITRDY_INSTR: + return tango_waitrdy(chip, + instr->ctx.waitrdy.timeout_ms); + default: + break; + } + + return -EINVAL; +} + +static int tango_exec_op(struct nand_chip *chip, + const struct nand_operation *op, + bool check_only) +{ + unsigned int i; + int ret = 0; + + if (check_only) + return 0; + + tango_select_target(chip, op->cs); + for (i = 0; i < op->ninstrs; i++) { + ret = tango_exec_instr(chip, &op->instrs[i]); + if (ret) + break; + } + + return ret; +} + /* * The controller does not check for bitflips in erased pages, * therefore software must check instead. @@ -279,6 +300,7 @@ static int tango_read_page(struct nand_chip *chip, u8 *buf, struct tango_nfc *nfc = to_tango_nfc(chip->controller); int err, res, len = mtd->writesize; + tango_select_target(chip, chip->cur_cs); if (oob_required) chip->ecc.read_oob(chip, page); @@ -300,22 +322,30 @@ static int tango_write_page(struct nand_chip *chip, const u8 *buf, { struct mtd_info *mtd = nand_to_mtd(chip); struct tango_nfc *nfc = to_tango_nfc(chip->controller); - int err, status, len = mtd->writesize; + const struct nand_sdr_timings *timings; + int err, len = mtd->writesize; + u8 status; /* Calling tango_write_oob() would send PAGEPROG twice */ if (oob_required) return -ENOTSUPP; + tango_select_target(chip, chip->cur_cs); writel_relaxed(0xffffffff, nfc->mem_base + METADATA); err = do_dma(nfc, DMA_TO_DEVICE, NFC_WRITE, buf, len, page); if (err) return err; - status = chip->legacy.waitfunc(chip); - if (status & NAND_STATUS_FAIL) - return -EIO; + timings = nand_get_sdr_timings(&chip->data_interface); + err = tango_waitrdy(chip, PSEC_TO_MSEC(timings->tR_max)); + if (err) + return err; - return 0; + err = nand_status_op(chip, &status); + if (err) + return err; + + return (status & NAND_STATUS_FAIL) ? -EIO : 0; } static void aux_read(struct nand_chip *chip, u8 **buf, int len, int *pos) @@ -326,7 +356,9 @@ static void aux_read(struct nand_chip *chip, u8 **buf, int len, int *pos) /* skip over "len" bytes */ nand_change_read_column_op(chip, *pos, NULL, 0, false); } else { - tango_read_buf(chip, *buf, len); + struct tango_chip *tchip = to_tango_chip(chip); + + ioread8_rep(tchip->base + PBUS_DATA, *buf, len); *buf += len; } } @@ -339,7 +371,9 @@ static void aux_write(struct nand_chip *chip, const u8 **buf, int len, int *pos) /* skip over "len" bytes */ nand_change_write_column_op(chip, *pos, NULL, 0, false); } else { - tango_write_buf(chip, *buf, len); + struct tango_chip *tchip = to_tango_chip(chip); + + iowrite8_rep(tchip->base + PBUS_DATA, *buf, len); *buf += len; } } @@ -420,6 +454,7 @@ static void raw_write(struct nand_chip *chip, const u8 *buf, const u8 *oob) static int tango_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_required, int page) { + tango_select_target(chip, chip->cur_cs); nand_read_page_op(chip, page, 0, NULL, 0); raw_read(chip, buf, chip->oob_poi); return 0; @@ -428,6 +463,7 @@ static int tango_read_page_raw(struct nand_chip *chip, u8 *buf, static int tango_write_page_raw(struct nand_chip *chip, const u8 *buf, int oob_required, int page) { + tango_select_target(chip, chip->cur_cs); nand_prog_page_begin_op(chip, page, 0, NULL, 0); raw_write(chip, buf, chip->oob_poi); return nand_prog_page_end_op(chip); @@ -435,6 +471,7 @@ static int tango_write_page_raw(struct nand_chip *chip, const u8 *buf, static int tango_read_oob(struct nand_chip *chip, int page) { + tango_select_target(chip, chip->cur_cs); nand_read_page_op(chip, page, 0, NULL, 0); raw_read(chip, NULL, chip->oob_poi); return 0; @@ -442,6 +479,7 @@ static int tango_read_oob(struct nand_chip *chip, int page) static int tango_write_oob(struct nand_chip *chip, int page) { + tango_select_target(chip, chip->cur_cs); nand_prog_page_begin_op(chip, page, 0, NULL, 0); raw_write(chip, NULL, chip->oob_poi); return nand_prog_page_end_op(chip); @@ -528,6 +566,7 @@ static int tango_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops tango_controller_ops = { .attach_chip = tango_attach_chip, .setup_data_interface = tango_set_timings, + .exec_op = tango_exec_op, }; static int chip_init(struct device *dev, struct device_node *np) @@ -562,12 +601,6 @@ static int chip_init(struct device *dev, struct device_node *np) ecc = &chip->ecc; mtd = nand_to_mtd(chip); - chip->legacy.read_byte = tango_read_byte; - chip->legacy.write_buf = tango_write_buf; - chip->legacy.read_buf = tango_read_buf; - chip->legacy.select_chip = tango_select_chip; - chip->legacy.cmd_ctrl = tango_cmd_ctrl; - chip->legacy.dev_ready = tango_dev_ready; chip->options = NAND_USES_DMA | NAND_NO_SUBPAGE_WRITE | NAND_WAIT_TCCS; From ba9f316986502471b160470e5e27a5e5a2ccadaf Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 20 May 2020 01:24:52 +0200 Subject: [PATCH 032/242] dt-bindings: mtd: nand: Document the generic rb-gpios property A few drivers use this property to describe GPIO pins used to sample the NAND Ready/Busy state. Let's make it part of the generic binding doc. Signed-off-by: Boris Brezillon Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200519232454.374081-2-boris.brezillon@collabora.com --- Documentation/devicetree/bindings/mtd/nand-controller.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml index cde7c4d79efe..40fc5b0b2b8c 100644 --- a/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -114,6 +114,13 @@ patternProperties: description: Contains the native Ready/Busy IDs. + rb-gpios: + description: + Contains one or more GPIO descriptor (the numper of descriptor + depends on the number of R/B pins exposed by the flash) for the + Ready/Busy pins. Active state refers to the NAND ready state and + should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted. + required: - reg From 33d226f504ed72cba3a2b42bbe2a993b3d6d9548 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 02:25:06 +0200 Subject: [PATCH 033/242] mtd: nand: Move nand_device forward declaration to the top This structure might be used earlier in this file, let's move the forward declaration at the top. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529002517.3546-10-miquel.raynal@bootlin.com --- include/linux/mtd/nand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 0c7483843a32..a1f38c778d0e 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -12,6 +12,8 @@ #include +struct nand_device; + /** * struct nand_memory_organization - Memory organization structure * @bits_per_cell: number of bits per NAND cell @@ -133,8 +135,6 @@ struct nand_bbt { unsigned long *cache; }; -struct nand_device; - /** * struct nand_ops - NAND operations * @erase: erase a specific block. No need to check if the block is bad before From deedeb60e812b464c18a9902984eb3f643efcae9 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 02:25:07 +0200 Subject: [PATCH 034/242] mtd: nand: Add an extra level in the Kconfig hierarchy Use an extra level in Kconfig for all NAND related entries. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529002517.3546-11-miquel.raynal@bootlin.com --- drivers/mtd/nand/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index a5d8a211cb8a..c1a45b071165 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -1,7 +1,12 @@ # SPDX-License-Identifier: GPL-2.0-only + +menu "NAND" + config MTD_NAND_CORE tristate source "drivers/mtd/nand/onenand/Kconfig" source "drivers/mtd/nand/raw/Kconfig" source "drivers/mtd/nand/spi/Kconfig" + +endmenu From 6232095cc57cd096f126fa23c227a20a1669cc4f Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 02:25:08 +0200 Subject: [PATCH 035/242] mtd: nand: Drop useless 'depends on' in Kconfig Both OneNAND and raw NAND bits can't be compiled if MTD is disabled because of the if/endif logic in drivers/mtd/Kconfig. There is no need for an extra "depends on MTD" in their respective Kconfig files. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529002517.3546-12-miquel.raynal@bootlin.com --- drivers/mtd/nand/onenand/Kconfig | 1 - drivers/mtd/nand/raw/Kconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/mtd/nand/onenand/Kconfig b/drivers/mtd/nand/onenand/Kconfig index 572b8fe69abb..1a0e65bc246e 100644 --- a/drivers/mtd/nand/onenand/Kconfig +++ b/drivers/mtd/nand/onenand/Kconfig @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig MTD_ONENAND tristate "OneNAND Device Support" - depends on MTD depends on HAS_IOMEM help This enables support for accessing all type of OneNAND flash diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 113f61052269..85280e327bfe 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -12,7 +12,6 @@ config MTD_NAND_ECC_SW_HAMMING_SMC menuconfig MTD_RAW_NAND tristate "Raw/Parallel NAND Device Support" - depends on MTD select MTD_NAND_CORE select MTD_NAND_ECC_SW_HAMMING help From 85f54c5588885cc3b5be4a07498dd0755de9f5cf Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 02:25:10 +0200 Subject: [PATCH 036/242] mtd: nand: Rename a core structure Prepare the migration to a generic ECC engine by renaming the nand_ecc_req structure into nand_ecc_props. This structure will be the base of a wider 'nand_ecc' structure. In nand_device, these properties are still named "eccreq" even if "eccprops" might be more descriptive. This is just a transition step, this field is being replaced very soon by a much wider structure. The impact of renaming this field would be huge compared to its interest. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529002517.3546-14-miquel.raynal@bootlin.com --- include/linux/mtd/nand.h | 8 ++++---- include/linux/mtd/spinand.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index a1f38c778d0e..af99041ceaa9 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -116,11 +116,11 @@ struct nand_page_io_req { }; /** - * struct nand_ecc_req - NAND ECC requirements + * struct nand_ecc_props - NAND ECC properties * @strength: ECC strength - * @step_size: ECC step/block size + * @step_size: Number of bytes per step */ -struct nand_ecc_req { +struct nand_ecc_props { unsigned int strength; unsigned int step_size; }; @@ -179,7 +179,7 @@ struct nand_ops { struct nand_device { struct mtd_info mtd; struct nand_memory_organization memorg; - struct nand_ecc_req eccreq; + struct nand_ecc_props eccreq; struct nand_row_converter rowconv; struct nand_bbt bbt; const struct nand_ops *ops; diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 1077c45721ff..7b78c4ba9b3e 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -309,7 +309,7 @@ struct spinand_info { struct spinand_devid devid; u32 flags; struct nand_memory_organization memorg; - struct nand_ecc_req eccreq; + struct nand_ecc_props eccreq; struct spinand_ecc_info eccinfo; struct { const struct spinand_op_variants *read_cache; From c4cabc08d09e4b107b685e08bdec8a38a91089d8 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:12:55 +0200 Subject: [PATCH 037/242] mtd: rawnand: Use unsigned types for nand_chip unsigned values page_shift, phys_erase_shift, bbt_erase_shift, chip_shift, pagemask, subpagesize and badblockbits are all positive values, so declare them as unsigned. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-2-miquel.raynal@bootlin.com --- include/linux/mtd/rawnand.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 65b1c1c18b41..830f2d08937f 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1110,11 +1110,11 @@ struct nand_chip { unsigned int options; unsigned int bbt_options; - int page_shift; - int phys_erase_shift; - int bbt_erase_shift; - int chip_shift; - int pagemask; + unsigned int page_shift; + unsigned int phys_erase_shift; + unsigned int bbt_erase_shift; + unsigned int chip_shift; + unsigned int pagemask; u8 *data_buf; struct { @@ -1122,10 +1122,10 @@ struct nand_chip { int page; } pagecache; - int subpagesize; + unsigned int subpagesize; int onfi_timing_mode_default; unsigned int badblockpos; - int badblockbits; + unsigned int badblockbits; struct nand_id id; struct nand_parameters parameters; From d1f3837a507d73746f9e2118fad20ee5e57e86cc Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:12:56 +0200 Subject: [PATCH 038/242] mtd: rawnand: Only use u8 instead of uint8_t in nand_chip structure Mechanical change to avoid using old types. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-3-miquel.raynal@bootlin.com --- include/linux/mtd/rawnand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 830f2d08937f..cea137778224 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1141,13 +1141,13 @@ struct nand_chip { int (*suspend)(struct nand_chip *chip); void (*resume)(struct nand_chip *chip); - uint8_t *oob_poi; + u8 *oob_poi; struct nand_controller *controller; struct nand_ecc_ctrl ecc; unsigned long buf_align; - uint8_t *bbt; + u8 *bbt; struct nand_bbt_descr *bbt_td; struct nand_bbt_descr *bbt_md; From 8e8b2706e15d16443b1ea61a6f994c08ec5b9486 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:12:57 +0200 Subject: [PATCH 039/242] mtd: rawnand: Create a nand_chip operations structure And move nand_chip hooks there. While moving entries from one structure to the other, adapt the documentation style. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-4-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_base.c | 20 ++++++++--------- drivers/mtd/nand/raw/nand_hynix.c | 2 +- drivers/mtd/nand/raw/nand_macronix.c | 10 ++++----- drivers/mtd/nand/raw/nand_micron.c | 2 +- include/linux/mtd/rawnand.h | 32 ++++++++++++++++------------ 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 45124dbb1835..d9cb71e7c0ed 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -3215,10 +3215,10 @@ static int nand_setup_read_retry(struct nand_chip *chip, int retry_mode) if (retry_mode >= chip->read_retries) return -EINVAL; - if (!chip->setup_read_retry) + if (!chip->ops.setup_read_retry) return -EOPNOTSUPP; - return chip->setup_read_retry(chip, retry_mode); + return chip->ops.setup_read_retry(chip, retry_mode); } static void nand_wait_readrdy(struct nand_chip *chip) @@ -4462,8 +4462,8 @@ static int nand_suspend(struct mtd_info *mtd) int ret = 0; mutex_lock(&chip->lock); - if (chip->suspend) - ret = chip->suspend(chip); + if (chip->ops.suspend) + ret = chip->ops.suspend(chip); if (!ret) chip->suspended = 1; mutex_unlock(&chip->lock); @@ -4481,8 +4481,8 @@ static void nand_resume(struct mtd_info *mtd) mutex_lock(&chip->lock); if (chip->suspended) { - if (chip->resume) - chip->resume(chip); + if (chip->ops.resume) + chip->ops.resume(chip); chip->suspended = 0; } else { pr_err("%s called for a chip which is not in suspended state\n", @@ -4511,10 +4511,10 @@ static int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct nand_chip *chip = mtd_to_nand(mtd); - if (!chip->lock_area) + if (!chip->ops.lock_area) return -ENOTSUPP; - return chip->lock_area(chip, ofs, len); + return chip->ops.lock_area(chip, ofs, len); } /** @@ -4527,10 +4527,10 @@ static int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct nand_chip *chip = mtd_to_nand(mtd); - if (!chip->unlock_area) + if (!chip->ops.unlock_area) return -ENOTSUPP; - return chip->unlock_area(chip, ofs, len); + return chip->ops.unlock_area(chip, ofs, len); } /* Set default functions */ diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c index 7caedaa5b9e5..7d1be53f27f3 100644 --- a/drivers/mtd/nand/raw/nand_hynix.c +++ b/drivers/mtd/nand/raw/nand_hynix.c @@ -337,7 +337,7 @@ static int hynix_mlc_1xnm_rr_init(struct nand_chip *chip, rr->nregs = nregs; rr->regs = hynix_1xnm_mlc_read_retry_regs; hynix->read_retry = rr; - chip->setup_read_retry = hynix_nand_setup_read_retry; + chip->ops.setup_read_retry = hynix_nand_setup_read_retry; chip->read_retries = nmodes; out: diff --git a/drivers/mtd/nand/raw/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c index 09c254c97b5c..1472f925f386 100644 --- a/drivers/mtd/nand/raw/nand_macronix.c +++ b/drivers/mtd/nand/raw/nand_macronix.c @@ -130,7 +130,7 @@ static void macronix_nand_onfi_init(struct nand_chip *chip) return; chip->read_retries = MACRONIX_NUM_READ_RETRY_MODES; - chip->setup_read_retry = macronix_nand_setup_read_retry; + chip->ops.setup_read_retry = macronix_nand_setup_read_retry; if (p->supports_set_get_features) { bitmap_set(p->set_feature_list, @@ -242,8 +242,8 @@ static void macronix_nand_block_protection_support(struct nand_chip *chip) bitmap_set(chip->parameters.set_feature_list, ONFI_FEATURE_ADDR_MXIC_PROTECTION, 1); - chip->lock_area = mxic_nand_lock; - chip->unlock_area = mxic_nand_unlock; + chip->ops.lock_area = mxic_nand_lock; + chip->ops.unlock_area = mxic_nand_unlock; } static int nand_power_down_op(struct nand_chip *chip) @@ -312,8 +312,8 @@ static void macronix_nand_deep_power_down_support(struct nand_chip *chip) if (i < 0) return; - chip->suspend = mxic_nand_suspend; - chip->resume = mxic_nand_resume; + chip->ops.suspend = mxic_nand_suspend; + chip->ops.resume = mxic_nand_resume; } static int macronix_nand_init(struct nand_chip *chip) diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c index 3589b4fce0d4..4385092a9325 100644 --- a/drivers/mtd/nand/raw/nand_micron.c +++ b/drivers/mtd/nand/raw/nand_micron.c @@ -84,7 +84,7 @@ static int micron_nand_onfi_init(struct nand_chip *chip) struct nand_onfi_vendor_micron *micron = (void *)p->onfi->vendor; chip->read_retries = micron->read_retry_options; - chip->setup_read_retry = micron_nand_setup_read_retry; + chip->ops.setup_read_retry = micron_nand_setup_read_retry; } if (p->supports_set_get_features) { diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index cea137778224..7f9be95ca8dc 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1027,16 +1027,31 @@ struct nand_legacy { struct nand_controller dummy_controller; }; +/** + * struct nand_chip_ops - NAND chip operations + * @suspend: Suspend operation + * @resume: Resume operation + * @lock_area: Lock operation + * @unlock_area: Unlock operation + * @setup_read_retry: Set the read-retry mode (mostly needed for MLC NANDs) + */ +struct nand_chip_ops { + int (*suspend)(struct nand_chip *chip); + void (*resume)(struct nand_chip *chip); + int (*lock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len); + int (*unlock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len); + int (*setup_read_retry)(struct nand_chip *chip, int retry_mode); +}; + /** * struct nand_chip - NAND Private Flash Chip Data * @base: Inherit from the generic NAND device + * @ops: NAND chip operations * @legacy: All legacy fields/hooks. If you develop a new driver, * don't even try to use any of these fields/hooks, and if * you're modifying an existing driver that is using those * fields/hooks, you should consider reworking the driver * avoid using them. - * @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for - * setting the read-retry mode. Mostly needed for MLC NAND. * @ecc: [BOARDSPECIFIC] ECC control structure * @buf_align: minimum buffer alignment required by a platform * @oob_poi: "poison value buffer," used for laying out OOB data @@ -1081,8 +1096,6 @@ struct nand_legacy { * @lock: lock protecting the suspended field. Also used to * serialize accesses to the NAND device. * @suspended: set to 1 when the device is suspended, 0 when it's not. - * @suspend: [REPLACEABLE] specific NAND device suspend operation - * @resume: [REPLACEABLE] specific NAND device resume operation * @bbt: [INTERN] bad block table pointer * @bbt_td: [REPLACEABLE] bad block table descriptor for flash * lookup. @@ -1096,17 +1109,13 @@ struct nand_legacy { * @manufacturer: [INTERN] Contains manufacturer information * @manufacturer.desc: [INTERN] Contains manufacturer's description * @manufacturer.priv: [INTERN] Contains manufacturer private information - * @lock_area: [REPLACEABLE] specific NAND chip lock operation - * @unlock_area: [REPLACEABLE] specific NAND chip unlock operation */ struct nand_chip { struct nand_device base; - + struct nand_chip_ops ops; struct nand_legacy legacy; - int (*setup_read_retry)(struct nand_chip *chip, int retry_mode); - unsigned int options; unsigned int bbt_options; @@ -1138,8 +1147,6 @@ struct nand_chip { struct mutex lock; unsigned int suspended : 1; - int (*suspend)(struct nand_chip *chip); - void (*resume)(struct nand_chip *chip); u8 *oob_poi; struct nand_controller *controller; @@ -1159,9 +1166,6 @@ struct nand_chip { const struct nand_manufacturer *desc; void *priv; } manufacturer; - - int (*lock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len); - int (*unlock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len); }; extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops; From 271de009b7c0c1c15f63491a352ab08835462977 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:12:58 +0200 Subject: [PATCH 040/242] mtd: rawnand: Rename the manufacturer structure It is currently called nand_manufacturer but could actually be called nand_manufacturer_desc, like its instances, so that the former name is left unused for now. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-5-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/internals.h | 6 +++--- drivers/mtd/nand/raw/nand_base.c | 14 +++++++------- drivers/mtd/nand/raw/nand_ids.c | 16 ++++++++-------- include/linux/mtd/rawnand.h | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index 03866b0aadea..a518acfd9b3f 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -53,12 +53,12 @@ struct nand_manufacturer_ops { }; /** - * struct nand_manufacturer - NAND Flash Manufacturer structure + * struct nand_manufacturer_desc - NAND Flash Manufacturer descriptor * @name: Manufacturer name * @id: manufacturer ID code of device. * @ops: manufacturer operations */ -struct nand_manufacturer { +struct nand_manufacturer_desc { int id; char *name; const struct nand_manufacturer_ops *ops; @@ -79,7 +79,7 @@ extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops; extern const struct mtd_pairing_scheme dist3_pairing_scheme; /* Core functions */ -const struct nand_manufacturer *nand_get_manufacturer(u8 id); +const struct nand_manufacturer_desc *nand_get_manufacturer_desc(u8 id); int nand_bbm_get_next_page(struct nand_chip *chip, int page); int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs); int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index d9cb71e7c0ed..534ee75d0f2b 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4810,9 +4810,9 @@ static void nand_manufacturer_cleanup(struct nand_chip *chip) } static const char * -nand_manufacturer_name(const struct nand_manufacturer *manufacturer) +nand_manufacturer_name(const struct nand_manufacturer_desc *manufacturer_desc) { - return manufacturer ? manufacturer->name : "Unknown"; + return manufacturer_desc ? manufacturer_desc->name : "Unknown"; } /* @@ -4820,7 +4820,7 @@ nand_manufacturer_name(const struct nand_manufacturer *manufacturer) */ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) { - const struct nand_manufacturer *manufacturer; + const struct nand_manufacturer_desc *manufacturer_desc; struct mtd_info *mtd = nand_to_mtd(chip); struct nand_memory_organization *memorg; int busw, ret; @@ -4877,8 +4877,8 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data)); /* Try to identify manufacturer */ - manufacturer = nand_get_manufacturer(maf_id); - chip->manufacturer.desc = manufacturer; + manufacturer_desc = nand_get_manufacturer_desc(maf_id); + chip->manufacturer.desc = manufacturer_desc; if (!type) type = nand_flash_ids; @@ -4957,7 +4957,7 @@ ident_done: */ pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", maf_id, dev_id); - pr_info("%s %s\n", nand_manufacturer_name(manufacturer), + pr_info("%s %s\n", nand_manufacturer_name(manufacturer_desc), mtd->name); pr_warn("bus width %d instead of %d bits\n", busw ? 16 : 8, (chip->options & NAND_BUSWIDTH_16) ? 16 : 8); @@ -4992,7 +4992,7 @@ ident_done: pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", maf_id, dev_id); - pr_info("%s %s\n", nand_manufacturer_name(manufacturer), + pr_info("%s %s\n", nand_manufacturer_name(manufacturer_desc), chip->parameters.model); pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", (int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index ba27902fc54b..e0dbc2e316c7 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -166,7 +166,7 @@ struct nand_flash_dev nand_flash_ids[] = { }; /* Manufacturer IDs */ -static const struct nand_manufacturer nand_manufacturers[] = { +static const struct nand_manufacturer_desc nand_manufacturer_descs[] = { {NAND_MFR_AMD, "AMD/Spansion", &amd_nand_manuf_ops}, {NAND_MFR_ATO, "ATO"}, {NAND_MFR_EON, "Eon"}, @@ -186,20 +186,20 @@ static const struct nand_manufacturer nand_manufacturers[] = { }; /** - * nand_get_manufacturer - Get manufacturer information from the manufacturer - * ID + * nand_get_manufacturer_desc - Get manufacturer information from the + * manufacturer ID * @id: manufacturer ID * - * Returns a pointer a nand_manufacturer object if the manufacturer is defined + * Returns a nand_manufacturer_desc object if the manufacturer is defined * in the NAND manufacturers database, NULL otherwise. */ -const struct nand_manufacturer *nand_get_manufacturer(u8 id) +const struct nand_manufacturer_desc *nand_get_manufacturer_desc(u8 id) { int i; - for (i = 0; i < ARRAY_SIZE(nand_manufacturers); i++) - if (nand_manufacturers[i].id == id) - return &nand_manufacturers[i]; + for (i = 0; i < ARRAY_SIZE(nand_manufacturer_descs); i++) + if (nand_manufacturer_descs[i].id == id) + return &nand_manufacturer_descs[i]; return NULL; } diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 7f9be95ca8dc..860d3c1020ef 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1163,7 +1163,7 @@ struct nand_chip { void *priv; struct { - const struct nand_manufacturer *desc; + const struct nand_manufacturer_desc *desc; void *priv; } manufacturer; }; From 36017af430e6b2fad0b2ee5476103706160f1379 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:12:59 +0200 Subject: [PATCH 041/242] mtd: rawnand: Declare the nand_manufacturer structure out of nand_chip Now that struct nand_manufacturer type is free, use it to store the nand_manufacturer_desc and the manufacturer's private data. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-6-miquel.raynal@bootlin.com --- include/linux/mtd/rawnand.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 860d3c1020ef..a3dfa36a9fd5 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1043,10 +1043,21 @@ struct nand_chip_ops { int (*setup_read_retry)(struct nand_chip *chip, int retry_mode); }; +/** + * struct nand_manufacturer - NAND manufacturer structure + * @desc: The manufacturer description + * @priv: Private information for the manufacturer driver + */ +struct nand_manufacturer { + const struct nand_manufacturer_desc *desc; + void *priv; +}; + /** * struct nand_chip - NAND Private Flash Chip Data * @base: Inherit from the generic NAND device * @ops: NAND chip operations + * @manufacturer: Manufacturer information * @legacy: All legacy fields/hooks. If you develop a new driver, * don't even try to use any of these fields/hooks, and if * you're modifying an existing driver that is using those @@ -1106,13 +1117,11 @@ struct nand_chip_ops { * structure which is shared among multiple independent * devices. * @priv: [OPTIONAL] pointer to private chip data - * @manufacturer: [INTERN] Contains manufacturer information - * @manufacturer.desc: [INTERN] Contains manufacturer's description - * @manufacturer.priv: [INTERN] Contains manufacturer private information */ struct nand_chip { struct nand_device base; + struct nand_manufacturer manufacturer; struct nand_chip_ops ops; struct nand_legacy legacy; @@ -1161,11 +1170,6 @@ struct nand_chip { struct nand_bbt_descr *badblock_pattern; void *priv; - - struct { - const struct nand_manufacturer_desc *desc; - void *priv; - } manufacturer; }; extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops; From a63674c7cfe62221e05ba73107d9e15d73ff8bbd Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:00 +0200 Subject: [PATCH 042/242] mtd: rawnand: Reorganize the nand_chip structure Reorder fields in this structure and pack entries by theme: * The main descriptive structures * The data interface details * Bad block information * The device layout * Extra buffers matching the device layout * Internal values * External objects like the ECC controller, the ECC engine and a private data pointer. While at it, adapt the documentation style. I changed on purpose the description of @oob_poi which was weird. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-7-miquel.raynal@bootlin.com --- include/linux/mtd/rawnand.h | 174 +++++++++++++++++------------------- 1 file changed, 80 insertions(+), 94 deletions(-) diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index a3dfa36a9fd5..544ec8736793 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1055,120 +1055,106 @@ struct nand_manufacturer { /** * struct nand_chip - NAND Private Flash Chip Data - * @base: Inherit from the generic NAND device - * @ops: NAND chip operations - * @manufacturer: Manufacturer information - * @legacy: All legacy fields/hooks. If you develop a new driver, - * don't even try to use any of these fields/hooks, and if - * you're modifying an existing driver that is using those - * fields/hooks, you should consider reworking the driver - * avoid using them. - * @ecc: [BOARDSPECIFIC] ECC control structure - * @buf_align: minimum buffer alignment required by a platform - * @oob_poi: "poison value buffer," used for laying out OOB data - * before writing - * @page_shift: [INTERN] number of address bits in a page (column - * address bits). - * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock - * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry - * @chip_shift: [INTERN] number of address bits in one chip - * @options: [BOARDSPECIFIC] various chip options. They can partly - * be set to inform nand_scan about special functionality. - * See the defines for further explanation. - * @bbt_options: [INTERN] bad block specific options. All options used - * here must come from bbm.h. By default, these options - * will be copied to the appropriate nand_bbt_descr's. - * @badblockpos: [INTERN] position of the bad block marker in the oob - * area. - * @badblockbits: [INTERN] minimum number of set bits in a good block's - * bad block marker position; i.e., BBM == 11110111b is - * not bad when badblockbits == 7 - * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is - * set to the actually used ONFI mode if the chip is - * ONFI compliant or deduced from the datasheet if - * the NAND chip is not ONFI compliant. - * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 - * @data_buf: [INTERN] buffer for data, size is (page size + oobsize). - * @pagecache: Structure containing page cache related fields - * @pagecache.bitflips: Number of bitflips of the cached page - * @pagecache.page: Page number currently in the cache. -1 means no page is - * currently cached - * @subpagesize: [INTERN] holds the subpagesize - * @id: [INTERN] holds NAND ID - * @parameters: [INTERN] holds generic parameters under an easily - * readable form. - * @data_interface: [INTERN] NAND interface timing information - * @cur_cs: currently selected target. -1 means no target selected, - * otherwise we should always have cur_cs >= 0 && - * cur_cs < nanddev_ntargets(). NAND Controller drivers - * should not modify this value, but they're allowed to - * read it. - * @read_retries: [INTERN] the number of read retry modes supported - * @lock: lock protecting the suspended field. Also used to - * serialize accesses to the NAND device. - * @suspended: set to 1 when the device is suspended, 0 when it's not. - * @bbt: [INTERN] bad block table pointer - * @bbt_td: [REPLACEABLE] bad block table descriptor for flash - * lookup. - * @bbt_md: [REPLACEABLE] bad block table mirror descriptor - * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial - * bad block scan. - * @controller: [REPLACEABLE] a pointer to a hardware controller - * structure which is shared among multiple independent - * devices. - * @priv: [OPTIONAL] pointer to private chip data + * @base: Inherit from the generic NAND device + * @id: Holds NAND ID + * @parameters: Holds generic parameters under an easily readable form + * @manufacturer: Manufacturer information + * @ops: NAND chip operations + * @legacy: All legacy fields/hooks. If you develop a new driver, don't even try + * to use any of these fields/hooks, and if you're modifying an + * existing driver that is using those fields/hooks, you should + * consider reworking the driver and avoid using them. + * @options: Various chip options. They can partly be set to inform nand_scan + * about special functionality. See the defines for further + * explanation. + * @onfi_timing_mode_default: Default ONFI timing mode. This field is set to the + * actually used ONFI mode if the chip is ONFI + * compliant or deduced from the datasheet otherwise + * @data_interface: NAND interface timing information + * @bbt_erase_shift: Number of address bits in a bbt entry + * @bbt_options: Bad block table specific options. All options used here must + * come from bbm.h. By default, these options will be copied to + * the appropriate nand_bbt_descr's. + * @badblockpos: Bad block marker position in the oob area + * @badblockbits: Minimum number of set bits in a good block's bad block marker + * position; i.e., BBM = 11110111b is good when badblockbits = 7 + * @bbt_td: Bad block table descriptor for flash lookup + * @bbt_md: Bad block table mirror descriptor + * @badblock_pattern: Bad block scan pattern used for initial bad block scan + * @bbt: Bad block table pointer + * @page_shift: Number of address bits in a page (column address bits) + * @phys_erase_shift: Number of address bits in a physical eraseblock + * @chip_shift: Number of address bits in one chip + * @pagemask: Page number mask = number of (pages / chip) - 1 + * @subpagesize: Holds the subpagesize + * @data_buf: Buffer for data, size is (page size + oobsize) + * @oob_poi: pointer on the OOB area covered by data_buf + * @pagecache: Structure containing page cache related fields + * @pagecache.bitflips: Number of bitflips of the cached page + * @pagecache.page: Page number currently in the cache. -1 means no page is + * currently cached + * @buf_align: Minimum buffer alignment required by a platform + * @lock: Lock protecting the suspended field. Also used to serialize accesses + * to the NAND device + * @suspended: Set to 1 when the device is suspended, 0 when it's not + * @cur_cs: Currently selected target. -1 means no target selected, otherwise we + * should always have cur_cs >= 0 && cur_cs < nanddev_ntargets(). + * NAND Controller drivers should not modify this value, but they're + * allowed to read it. + * @read_retries: The number of read retry modes supported + * @controller: The hardware controller structure which is shared among multiple + * independent devices + * @ecc: The ECC controller structure + * @priv: Chip private data */ - struct nand_chip { struct nand_device base; + struct nand_id id; + struct nand_parameters parameters; struct nand_manufacturer manufacturer; struct nand_chip_ops ops; struct nand_legacy legacy; - unsigned int options; - unsigned int bbt_options; + /* Data interface */ + int onfi_timing_mode_default; + struct nand_data_interface data_interface; + + /* Bad block information */ + unsigned int bbt_erase_shift; + unsigned int bbt_options; + unsigned int badblockpos; + unsigned int badblockbits; + struct nand_bbt_descr *bbt_td; + struct nand_bbt_descr *bbt_md; + struct nand_bbt_descr *badblock_pattern; + u8 *bbt; + + /* Device internal layout */ unsigned int page_shift; unsigned int phys_erase_shift; - unsigned int bbt_erase_shift; unsigned int chip_shift; unsigned int pagemask; - u8 *data_buf; + unsigned int subpagesize; + /* Buffers */ + u8 *data_buf; + u8 *oob_poi; struct { unsigned int bitflips; int page; } pagecache; - - unsigned int subpagesize; - int onfi_timing_mode_default; - unsigned int badblockpos; - unsigned int badblockbits; - - struct nand_id id; - struct nand_parameters parameters; - - struct nand_data_interface data_interface; - - int cur_cs; - - int read_retries; - - struct mutex lock; - unsigned int suspended : 1; - - u8 *oob_poi; - struct nand_controller *controller; - - struct nand_ecc_ctrl ecc; unsigned long buf_align; - u8 *bbt; - struct nand_bbt_descr *bbt_td; - struct nand_bbt_descr *bbt_md; - - struct nand_bbt_descr *badblock_pattern; + /* Internals */ + struct mutex lock; + unsigned int suspended : 1; + int cur_cs; + int read_retries; + /* Externals */ + struct nand_controller *controller; + struct nand_ecc_ctrl ecc; void *priv; }; From 6ef10df37e7dd99a5a16228fabcc3a5141585b66 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:01 +0200 Subject: [PATCH 043/242] mtd: rawnand: Compare the actual timing values Avoid relying just on the default timing mode to discriminate if the data interface must be restored. This field should only be used at initialization time by legacy chips statically defined. Do a memcmp() instead. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-8-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 534ee75d0f2b..3526c2a50bbe 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -2512,7 +2512,8 @@ int nand_reset(struct nand_chip *chip, int chipnr) * nand_setup_data_interface() uses ->set/get_features() which would * fail anyway as the parameter page is not available yet. */ - if (!chip->onfi_timing_mode_default) + if (!memcmp(&chip->data_interface, &saved_data_intf, + sizeof(saved_data_intf))) return 0; chip->data_interface = saved_data_intf; From fe7f7b0846bdcc53a3d3e83fea67f988ab5145d8 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:02 +0200 Subject: [PATCH 044/242] mtd: rawnand: Use the data interface mode entry when relevant The data interface setup does not care about the default timing mode but cares about the actual timing mode at the time of the call of this helper. Use this entry instead and let chip->default_timing_mode only be used at initialization time. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-9-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_base.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 3526c2a50bbe..6e06ccf61aeb 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -951,9 +951,8 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) */ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr) { - u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { - chip->onfi_timing_mode_default, - }; + u8 mode = chip->data_interface.timings.mode; + u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { mode, }; int ret; if (!nand_has_setup_data_iface(chip)) @@ -987,9 +986,9 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr) if (ret) goto err_reset_chip; - if (tmode_param[0] != chip->onfi_timing_mode_default) { + if (tmode_param[0] != mode) { pr_warn("timing mode %d not acknowledged by the NAND chip\n", - chip->onfi_timing_mode_default); + mode); goto err_reset_chip; } From adcf98b2d87429dfbc114666a8be6f2b36f5d898 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:03 +0200 Subject: [PATCH 045/242] mtd: rawnand: Rename nand_has_setup_data_iface() This is really a NAND controller hook so call it nand_controller_can_setup_data_iface(), which makes much more sense. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-10-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/internals.h | 2 +- drivers/mtd/nand/raw/nand_base.c | 6 +++--- drivers/mtd/nand/raw/nand_legacy.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index a518acfd9b3f..a5e2cec7e301 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -130,7 +130,7 @@ static inline int nand_exec_op(struct nand_chip *chip, return chip->controller->ops->exec_op(chip, op, false); } -static inline bool nand_has_setup_data_iface(struct nand_chip *chip) +static inline bool nand_controller_can_setup_data_iface(struct nand_chip *chip) { if (!chip->controller || !chip->controller->ops || !chip->controller->ops->setup_data_interface) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 6e06ccf61aeb..2a477ce81165 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -910,7 +910,7 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) { int ret; - if (!nand_has_setup_data_iface(chip)) + if (!nand_controller_can_setup_data_iface(chip)) return 0; /* @@ -955,7 +955,7 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr) u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { mode, }; int ret; - if (!nand_has_setup_data_iface(chip)) + if (!nand_controller_can_setup_data_iface(chip)) return 0; /* Change the mode on the chip side (if supported by the NAND chip) */ @@ -1025,7 +1025,7 @@ static int nand_init_data_interface(struct nand_chip *chip) { int modes, mode, ret; - if (!nand_has_setup_data_iface(chip)) + if (!nand_controller_can_setup_data_iface(chip)) return 0; /* diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c index d64791c06a97..848403dcae03 100644 --- a/drivers/mtd/nand/raw/nand_legacy.c +++ b/drivers/mtd/nand/raw/nand_legacy.c @@ -365,7 +365,7 @@ static void nand_ccs_delay(struct nand_chip *chip) * Wait tCCS_min if it is correctly defined, otherwise wait 500ns * (which should be safe for all NANDs). */ - if (nand_has_setup_data_iface(chip)) + if (nand_controller_can_setup_data_iface(chip)) ndelay(chip->data_interface.timings.sdr.tCCS_min / 1000); else ndelay(500); From 8d69a80f541db0f58ebe92801bedbf17199738bd Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:04 +0200 Subject: [PATCH 046/242] mtd: rawnand: Fix nand_setup_data_interface() description This is a copy/paste error and belongs to nand_init_data_interface() description. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-11-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_base.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 2a477ce81165..01e788e0d010 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -941,11 +941,8 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) * @chip: The NAND chip * @chipnr: Internal die id * - * Find and configure the best data interface and NAND timings supported by - * the chip and the driver. - * First tries to retrieve supported timing modes from ONFI information, - * and if the NAND chip does not support ONFI, relies on the - * ->onfi_timing_mode_default specified in the nand_ids table. + * Configure what has been reported to be the best data interface and NAND + * timings supported by the chip and the driver. * * Returns 0 for success or negative error code otherwise. */ From 5e179a532a9954883685748b60081e75b33f0d32 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:05 +0200 Subject: [PATCH 047/242] mtd: rawnand: Rename nand_init_data_interface() This name is a bit misleading, what we do in this helper is trying to find the best SDR timings supported by the controller and the chip. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-12-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_base.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 01e788e0d010..1d9cf02d164b 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -1005,7 +1005,7 @@ err_reset_chip: } /** - * nand_init_data_interface - find the best data interface and timings + * nand_choose_data_interface - find the best data interface and timings * @chip: The NAND chip * * Find the best data interface and NAND timings supported by the chip @@ -1018,7 +1018,7 @@ err_reset_chip: * * Returns 0 for success or negative error code otherwise. */ -static int nand_init_data_interface(struct nand_chip *chip) +static int nand_choose_data_interface(struct nand_chip *chip) { int modes, mode, ret; @@ -5969,8 +5969,8 @@ static int nand_scan_tail(struct nand_chip *chip) if (!mtd->bitflip_threshold) mtd->bitflip_threshold = DIV_ROUND_UP(mtd->ecc_strength * 3, 4); - /* Initialize the ->data_interface field. */ - ret = nand_init_data_interface(chip); + /* Find the fastest data interface for this chip */ + ret = nand_choose_data_interface(chip); if (ret) goto err_nanddev_cleanup; From 844cc46460095023365345bfe61a0f195f9cb66e Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:06 +0200 Subject: [PATCH 048/242] mtd: rawnand: timings: Update onfi_fill_data_interface() kernel doc Describe all parameters and drop the legacy [NAND Interface] prefix. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-13-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_timings.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index 36d21be3dfe5..a73d934e86f9 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -274,9 +274,10 @@ static const struct nand_data_interface onfi_sdr_timings[] = { }; /** - * onfi_fill_data_interface - [NAND Interface] Initialize a data interface from - * given ONFI mode - * @mode: The ONFI timing mode + * onfi_fill_data_interface - Initialize a data interface from a given ONFI mode + * @chip: The NAND chip + * @type: The data interface type + * @timing_mode: The ONFI timing mode */ int onfi_fill_data_interface(struct nand_chip *chip, enum nand_data_interface_type type, From 623c0141f560800c4fc7a7502654994633791d36 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:07 +0200 Subject: [PATCH 049/242] mtd: rawnand: timings: Provide onfi_fill_data_interface() with a data interface Right now the core uses onfi_fill_data_interface() to initialize the nand_data_interface object embedded in nand_chip, but we are about to allocate this object dynamically and let manufacturer drivers provide their own interface config. Let's patch the onfi_fill_data_interface() so it can initialize an interface config that's not the one currently attached to the nand_chip. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-14-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/internals.h | 1 + drivers/mtd/nand/raw/nand_base.c | 7 ++++--- drivers/mtd/nand/raw/nand_timings.c | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index a5e2cec7e301..0f74509abc4c 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -85,6 +85,7 @@ int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs); int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, int allowbbt); int onfi_fill_data_interface(struct nand_chip *chip, + struct nand_data_interface *iface, enum nand_data_interface_type type, int timing_mode); int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param); diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 1d9cf02d164b..b4de85794e07 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -927,7 +927,7 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) * timings to timing mode 0. */ - onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0); + onfi_fill_data_interface(chip, &chip->data_interface, NAND_SDR_IFACE, 0); ret = chip->controller->ops->setup_data_interface(chip, chipnr, &chip->data_interface); if (ret) @@ -1040,7 +1040,8 @@ static int nand_choose_data_interface(struct nand_chip *chip) } for (mode = fls(modes) - 1; mode >= 0; mode--) { - ret = onfi_fill_data_interface(chip, NAND_SDR_IFACE, mode); + ret = onfi_fill_data_interface(chip, &chip->data_interface, + NAND_SDR_IFACE, mode); if (ret) continue; @@ -5182,7 +5183,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, mutex_init(&chip->lock); /* Enforce the right timings for reset/detection */ - onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0); + onfi_fill_data_interface(chip, &chip->data_interface, NAND_SDR_IFACE, 0); ret = nand_dt_init(chip); if (ret) diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index a73d934e86f9..ce6bb87db2e8 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -276,14 +276,15 @@ static const struct nand_data_interface onfi_sdr_timings[] = { /** * onfi_fill_data_interface - Initialize a data interface from a given ONFI mode * @chip: The NAND chip + * @iface: The data interface to fill * @type: The data interface type * @timing_mode: The ONFI timing mode */ int onfi_fill_data_interface(struct nand_chip *chip, + struct nand_data_interface *iface, enum nand_data_interface_type type, int timing_mode) { - struct nand_data_interface *iface = &chip->data_interface; struct onfi_params *onfi = chip->parameters.onfi; if (type != NAND_SDR_IFACE) From fcaab3b26d2534ec9f227810975ad220823ac578 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:08 +0200 Subject: [PATCH 050/242] mtd: rawnand: timings: onfi_fill_data_interface timing mode is unsigned Turn this argument into an unsigned int, as it cannot be signed. This also spares a check. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-15-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/internals.h | 2 +- drivers/mtd/nand/raw/nand_timings.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index 0f74509abc4c..bd10ec92f04a 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -87,7 +87,7 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, int onfi_fill_data_interface(struct nand_chip *chip, struct nand_data_interface *iface, enum nand_data_interface_type type, - int timing_mode); + unsigned int timing_mode); int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param); int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param); int nand_read_page_raw_notsupp(struct nand_chip *chip, u8 *buf, diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index ce6bb87db2e8..08dc381349fa 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -283,14 +283,14 @@ static const struct nand_data_interface onfi_sdr_timings[] = { int onfi_fill_data_interface(struct nand_chip *chip, struct nand_data_interface *iface, enum nand_data_interface_type type, - int timing_mode) + unsigned int timing_mode) { struct onfi_params *onfi = chip->parameters.onfi; if (type != NAND_SDR_IFACE) return -EINVAL; - if (timing_mode < 0 || timing_mode >= ARRAY_SIZE(onfi_sdr_timings)) + if (timing_mode >= ARRAY_SIZE(onfi_sdr_timings)) return -EINVAL; *iface = onfi_sdr_timings[timing_mode]; From 98d6979aa898239ec2faa10467c338a808e1287e Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:09 +0200 Subject: [PATCH 051/242] mtd: rawnand: timings: Add a helper to find the closest ONFI mode Vendors are allowed to provide their own set of timings. In this case, we provide a way to derive the "closest" timing mode so that, if the NAND controller does not support tweaking these parameters, it will be able to configure itself anyway. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-16-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/internals.h | 2 ++ drivers/mtd/nand/raw/nand_timings.c | 47 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index bd10ec92f04a..f851ed210d70 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -88,6 +88,8 @@ int onfi_fill_data_interface(struct nand_chip *chip, struct nand_data_interface *iface, enum nand_data_interface_type type, unsigned int timing_mode); +unsigned int +onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings); int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param); int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param); int nand_read_page_raw_notsupp(struct nand_chip *chip, u8 *buf, diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index 08dc381349fa..b089f2dc5f23 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -273,6 +273,53 @@ static const struct nand_data_interface onfi_sdr_timings[] = { }, }; +/** + * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a + * set of timings + * @spec_timings: the timings to challenge + */ +unsigned int +onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings) +{ + const struct nand_sdr_timings *onfi_timings; + int mode; + + for (mode = ARRAY_SIZE(onfi_sdr_timings) - 1; mode > 0; mode--) { + onfi_timings = &onfi_sdr_timings[mode].timings.sdr; + + if (spec_timings->tCCS_min <= onfi_timings->tCCS_min && + spec_timings->tADL_min <= onfi_timings->tADL_min && + spec_timings->tALH_min <= onfi_timings->tALH_min && + spec_timings->tALS_min <= onfi_timings->tALS_min && + spec_timings->tAR_min <= onfi_timings->tAR_min && + spec_timings->tCEH_min <= onfi_timings->tCEH_min && + spec_timings->tCH_min <= onfi_timings->tCH_min && + spec_timings->tCLH_min <= onfi_timings->tCLH_min && + spec_timings->tCLR_min <= onfi_timings->tCLR_min && + spec_timings->tCLS_min <= onfi_timings->tCLS_min && + spec_timings->tCOH_min <= onfi_timings->tCOH_min && + spec_timings->tCS_min <= onfi_timings->tCS_min && + spec_timings->tDH_min <= onfi_timings->tDH_min && + spec_timings->tDS_min <= onfi_timings->tDS_min && + spec_timings->tIR_min <= onfi_timings->tIR_min && + spec_timings->tRC_min <= onfi_timings->tRC_min && + spec_timings->tREH_min <= onfi_timings->tREH_min && + spec_timings->tRHOH_min <= onfi_timings->tRHOH_min && + spec_timings->tRHW_min <= onfi_timings->tRHW_min && + spec_timings->tRLOH_min <= onfi_timings->tRLOH_min && + spec_timings->tRP_min <= onfi_timings->tRP_min && + spec_timings->tRR_min <= onfi_timings->tRR_min && + spec_timings->tWC_min <= onfi_timings->tWC_min && + spec_timings->tWH_min <= onfi_timings->tWH_min && + spec_timings->tWHR_min <= onfi_timings->tWHR_min && + spec_timings->tWP_min <= onfi_timings->tWP_min && + spec_timings->tWW_min <= onfi_timings->tWW_min) + return mode; + } + + return 0; +} + /** * onfi_fill_data_interface - Initialize a data interface from a given ONFI mode * @chip: The NAND chip From 173d548b64e14d3d1f22191cc0092c47631a18db Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:10 +0200 Subject: [PATCH 052/242] mtd: rawnand: timings: Avoid redefining tR_max and tCCS_min These two values are already hardcoded in the default ONFI timing structure, no need to redefine them here. Plus, we want to be able to reference timing mode 0 easily and reliably, without extra computation, so we get rid of the extra assignations. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-17-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_timings.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index b089f2dc5f23..54c7a1a8b038 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -369,9 +369,6 @@ int onfi_fill_data_interface(struct nand_chip *chip, /* microseconds -> picoseconds */ timings->tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX; timings->tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX; - - timings->tR_max = 200000000; - timings->tCCS_min = 500000; } return 0; From d1bfe1e31932822ee90fc6b4cdeae785f70b3650 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:11 +0200 Subject: [PATCH 053/242] mtd: rawnand: timings: Use default values for tPROG_max and tBERS_max The ONFI parameter page of a chip might define more fine grained tPROG_max and tBERS_max. When we do not have this information, we default to the highest possible values (they are maxima anyway). There is no point setting these fields at runtime, so explicitly move these defaults to the main ONFI SDR timings structure. This way, we will also be able to return a pointer to mode 0 directly when we will create a default reset configuration. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-18-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_timings.c | 31 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index 54c7a1a8b038..efff3583c549 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -12,6 +12,13 @@ #define ONFI_DYN_TIMING_MAX U16_MAX +/* + * For non-ONFI chips we use the highest possible value for tPROG and tBERS. + * tR and tCCS will take the default values precised in the ONFI specification + * for timing mode 0, respectively 200us and 500ns. + * + * These four values are tweaked to be more accurate in the case of ONFI chips. + */ static const struct nand_data_interface onfi_sdr_timings[] = { /* Mode 0 */ { @@ -20,6 +27,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { .timings.sdr = { .tCCS_min = 500000, .tR_max = 200000000, + .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, + .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, .tADL_min = 400000, .tALH_min = 20000, .tALS_min = 50000, @@ -63,6 +72,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { .timings.sdr = { .tCCS_min = 500000, .tR_max = 200000000, + .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, + .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, .tADL_min = 400000, .tALH_min = 10000, .tALS_min = 25000, @@ -106,6 +117,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { .timings.sdr = { .tCCS_min = 500000, .tR_max = 200000000, + .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, + .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, .tADL_min = 400000, .tALH_min = 10000, .tALS_min = 15000, @@ -149,6 +162,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { .timings.sdr = { .tCCS_min = 500000, .tR_max = 200000000, + .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, + .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, .tADL_min = 400000, .tALH_min = 5000, .tALS_min = 10000, @@ -192,6 +207,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { .timings.sdr = { .tCCS_min = 500000, .tR_max = 200000000, + .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, + .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, .tADL_min = 400000, .tALH_min = 5000, .tALS_min = 10000, @@ -235,6 +252,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { .timings.sdr = { .tCCS_min = 500000, .tR_max = 200000000, + .tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX, + .tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX, .tADL_min = 400000, .tALH_min = 5000, .tALS_min = 10000, @@ -357,18 +376,6 @@ int onfi_fill_data_interface(struct nand_chip *chip, /* nanoseconds -> picoseconds */ timings->tCCS_min = 1000UL * onfi->tCCS; - } else { - struct nand_sdr_timings *timings = &iface->timings.sdr; - /* - * For non-ONFI chips we use the highest possible value for - * tPROG and tBERS. tR and tCCS will take the default values - * precised in the ONFI specification for timing mode 0, - * respectively 200us and 500ns. - */ - - /* microseconds -> picoseconds */ - timings->tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX; - timings->tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX; } return 0; From e0160cd41fb81fde9ee4612a7ea2dfd631de2638 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:12 +0200 Subject: [PATCH 054/242] mtd: rawnand: Hide the chip->data_interface indirection As a preparation for allocating the data interface structure dynamically (and rename it), let's avoid accessing chip->data_interface directly. Instead, we introduce a helper, nand_get_interface_config(), and use it to retrieve the current data interface configuration out of a nand_chip object. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-19-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/marvell_nand.c | 9 ++++--- drivers/mtd/nand/raw/meson_nand.c | 8 +++--- drivers/mtd/nand/raw/nand_base.c | 34 +++++++++++++------------- drivers/mtd/nand/raw/nand_legacy.c | 5 +++- drivers/mtd/nand/raw/nand_toshiba.c | 2 +- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 2 +- drivers/mtd/nand/raw/tango_nand.c | 2 +- include/linux/mtd/rawnand.h | 11 +++++++++ 8 files changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 260a0430313e..df859889e4eb 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -1096,6 +1096,8 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, const u8 *oob_buf, bool raw, int page) { + const struct nand_sdr_timings *sdr = + nand_get_sdr_timings(nand_get_interface_config(chip)); struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip); struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout; @@ -1141,7 +1143,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip, return ret; ret = marvell_nfc_wait_op(chip, - PSEC_TO_MSEC(chip->data_interface.timings.sdr.tPROG_max)); + PSEC_TO_MSEC(sdr->tPROG_max)); return ret; } @@ -1562,6 +1564,8 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip, const u8 *buf, int oob_required, int page) { + const struct nand_sdr_timings *sdr = + nand_get_sdr_timings(nand_get_interface_config(chip)); struct mtd_info *mtd = nand_to_mtd(chip); const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout; const u8 *data = buf; @@ -1598,8 +1602,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip, marvell_nfc_wait_ndrun(chip); } - ret = marvell_nfc_wait_op(chip, - PSEC_TO_MSEC(chip->data_interface.timings.sdr.tPROG_max)); + ret = marvell_nfc_wait_op(chip, PSEC_TO_MSEC(sdr->tPROG_max)); marvell_nfc_disable_hw_ecc(chip); diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index 3f376471f3f7..580b7be0719f 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -573,10 +573,10 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len) static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, int page, bool in) { + const struct nand_sdr_timings *sdr = + nand_get_sdr_timings(nand_get_interface_config(nand)); struct mtd_info *mtd = nand_to_mtd(nand); struct meson_nfc *nfc = nand_get_controller_data(nand); - const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&nand->data_interface); u32 *addrs = nfc->cmdfifo.rw.addrs; u32 cs = nfc->param.chip_select; u32 cmd0, cmd_num, row_start; @@ -626,9 +626,9 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, static int meson_nfc_write_page_sub(struct nand_chip *nand, int page, int raw) { - struct mtd_info *mtd = nand_to_mtd(nand); const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&nand->data_interface); + nand_get_sdr_timings(nand_get_interface_config(nand)); + struct mtd_info *mtd = nand_to_mtd(nand); struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); struct meson_nfc *nfc = nand_get_controller_data(nand); int data_len, info_len; diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index b4de85794e07..7d393e1d0252 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -773,7 +773,7 @@ int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) return -ENOTSUPP; /* Wait tWB before polling the STATUS reg. */ - timings = nand_get_sdr_timings(&chip->data_interface); + timings = nand_get_sdr_timings(nand_get_interface_config(chip)); ndelay(PSEC_TO_NSEC(timings->tWB_max)); ret = nand_status_op(chip, NULL); @@ -1119,9 +1119,9 @@ static int nand_sp_exec_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, void *buf, unsigned int len) { - struct mtd_info *mtd = nand_to_mtd(chip); const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); + struct mtd_info *mtd = nand_to_mtd(chip); u8 addrs[4]; struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_READ0, 0), @@ -1163,7 +1163,7 @@ static int nand_lp_exec_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int len) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); u8 addrs[5]; struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_READ0, 0), @@ -1260,7 +1260,7 @@ int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf, if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_PARAM, 0), NAND_OP_ADDR(1, &page, PSEC_TO_NSEC(sdr->tWB_max)), @@ -1315,7 +1315,7 @@ int nand_change_read_column_op(struct nand_chip *chip, if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); u8 addrs[2] = {}; struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_RNDOUT, 0), @@ -1389,9 +1389,9 @@ static int nand_exec_prog_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, const void *buf, unsigned int len, bool prog) { - struct mtd_info *mtd = nand_to_mtd(chip); const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); + struct mtd_info *mtd = nand_to_mtd(chip); u8 addrs[5] = {}; struct nand_op_instr instrs[] = { /* @@ -1514,7 +1514,7 @@ int nand_prog_page_end_op(struct nand_chip *chip) if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_PAGEPROG, PSEC_TO_NSEC(sdr->tWB_max)), @@ -1621,7 +1621,7 @@ int nand_change_write_column_op(struct nand_chip *chip, if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); u8 addrs[2]; struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_RNDIN, 0), @@ -1676,7 +1676,7 @@ int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf, if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_READID, 0), NAND_OP_ADDR(1, &addr, PSEC_TO_NSEC(sdr->tADL_min)), @@ -1715,7 +1715,7 @@ int nand_status_op(struct nand_chip *chip, u8 *status) { if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_STATUS, PSEC_TO_NSEC(sdr->tADL_min)), @@ -1784,7 +1784,7 @@ int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock) if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); u8 addrs[3] = { page, page >> 8, page >> 16 }; struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_ERASE1, 0), @@ -1843,7 +1843,7 @@ static int nand_set_features_op(struct nand_chip *chip, u8 feature, if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_SET_FEATURES, 0), NAND_OP_ADDR(1, &feature, PSEC_TO_NSEC(sdr->tADL_min)), @@ -1890,7 +1890,7 @@ static int nand_get_features_op(struct nand_chip *chip, u8 feature, if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_GET_FEATURES, 0), NAND_OP_ADDR(1, &feature, PSEC_TO_NSEC(sdr->tWB_max)), @@ -1947,7 +1947,7 @@ int nand_reset_op(struct nand_chip *chip) { if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); struct nand_op_instr instrs[] = { NAND_OP_CMD(NAND_CMD_RESET, PSEC_TO_NSEC(sdr->tWB_max)), NAND_OP_WAIT_RDY(PSEC_TO_MSEC(sdr->tRST_max), 0), @@ -3226,7 +3226,7 @@ static void nand_wait_readrdy(struct nand_chip *chip) if (!(chip->options & NAND_NEED_READRDY)) return; - sdr = nand_get_sdr_timings(&chip->data_interface); + sdr = nand_get_sdr_timings(nand_get_interface_config(chip)); WARN_ON(nand_wait_rdy_op(chip, PSEC_TO_MSEC(sdr->tR_max), 0)); } diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c index 848403dcae03..fe769762e1d8 100644 --- a/drivers/mtd/nand/raw/nand_legacy.c +++ b/drivers/mtd/nand/raw/nand_legacy.c @@ -354,6 +354,9 @@ static void nand_command(struct nand_chip *chip, unsigned int command, static void nand_ccs_delay(struct nand_chip *chip) { + const struct nand_sdr_timings *sdr = + nand_get_sdr_timings(nand_get_interface_config(chip)); + /* * The controller already takes care of waiting for tCCS when the RNDIN * or RNDOUT command is sent, return directly. @@ -366,7 +369,7 @@ static void nand_ccs_delay(struct nand_chip *chip) * (which should be safe for all NANDs). */ if (nand_controller_can_setup_data_iface(chip)) - ndelay(chip->data_interface.timings.sdr.tCCS_min / 1000); + ndelay(sdr->tCCS_min / 1000); else ndelay(500); } diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index ae069905d7e4..333037bdca41 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -33,7 +33,7 @@ static int toshiba_nand_benand_read_eccstatus_op(struct nand_chip *chip, if (nand_has_exec_op(chip)) { const struct nand_sdr_timings *sdr = - nand_get_sdr_timings(&chip->data_interface); + nand_get_sdr_timings(nand_get_interface_config(chip)); struct nand_op_instr instrs[] = { NAND_OP_CMD(TOSHIBA_NAND_CMD_ECC_STATUS_READ, PSEC_TO_NSEC(sdr->tADL_min)), diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index 65c9d17b25a3..7320c0fc19ec 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -1308,7 +1308,7 @@ static int stm32_fmc2_nfc_waitrdy(struct nand_chip *chip, dev_warn(nfc->dev, "Waitrdy timeout\n"); /* Wait tWB before R/B# signal is low */ - timings = nand_get_sdr_timings(&chip->data_interface); + timings = nand_get_sdr_timings(nand_get_interface_config(chip)); ndelay(PSEC_TO_NSEC(timings->tWB_max)); /* R/B# signal is low, clear high level flag */ diff --git a/drivers/mtd/nand/raw/tango_nand.c b/drivers/mtd/nand/raw/tango_nand.c index b3a0d08f1733..648dc7e77f6a 100644 --- a/drivers/mtd/nand/raw/tango_nand.c +++ b/drivers/mtd/nand/raw/tango_nand.c @@ -336,7 +336,7 @@ static int tango_write_page(struct nand_chip *chip, const u8 *buf, if (err) return err; - timings = nand_get_sdr_timings(&chip->data_interface); + timings = nand_get_sdr_timings(nand_get_interface_config(chip)); err = tango_waitrdy(chip, PSEC_TO_MSEC(timings->tR_max)); if (err) return err; diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 544ec8736793..0852df941130 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1203,6 +1203,17 @@ static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) return mtd_get_of_node(nand_to_mtd(chip)); } +/** + * nand_get_interface_config - Retrieve the current interface configuration + * of a NAND chip + * @chip: The NAND chip + */ +static inline const struct nand_data_interface * +nand_get_interface_config(struct nand_chip *chip) +{ + return &chip->data_interface; +} + /* * A helper for defining older NAND chips where the second ID byte fully * defined the chip, including the geometry (chip size, eraseblock size, page From 4c46667b3d67253604ee42840917844548c86657 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:13 +0200 Subject: [PATCH 055/242] mtd: rawnand: s/data_interface/interface_config/ The name/suffix data_interface is a bit misleading in that the field or functions actually represent a configuration that can be applied by the controller/chip. Let's rename all fields/functions/hooks that are worth renaming. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal --- drivers/mtd/nand/raw/ams-delta.c | 6 +- drivers/mtd/nand/raw/arasan-nand-controller.c | 6 +- drivers/mtd/nand/raw/atmel/nand-controller.c | 34 ++++----- .../mtd/nand/raw/cadence-nand-controller.c | 6 +- drivers/mtd/nand/raw/denali.c | 8 +-- drivers/mtd/nand/raw/fsmc_nand.c | 6 +- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 6 +- drivers/mtd/nand/raw/internals.h | 12 ++-- drivers/mtd/nand/raw/marvell_nand.c | 9 ++- drivers/mtd/nand/raw/meson_nand.c | 6 +- drivers/mtd/nand/raw/mtk_nand.c | 6 +- drivers/mtd/nand/raw/mxc_nand.c | 20 +++--- drivers/mtd/nand/raw/mxic_nand.c | 6 +- drivers/mtd/nand/raw/nand_base.c | 69 ++++++++++--------- drivers/mtd/nand/raw/nand_legacy.c | 2 +- drivers/mtd/nand/raw/nand_timings.c | 17 ++--- drivers/mtd/nand/raw/s3c2410.c | 6 +- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 4 +- drivers/mtd/nand/raw/sunxi_nand.c | 6 +- drivers/mtd/nand/raw/tango_nand.c | 4 +- drivers/mtd/nand/raw/tegra_nand.c | 6 +- include/linux/mtd/rawnand.h | 33 +++++---- 22 files changed, 139 insertions(+), 139 deletions(-) diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c index 3711e7a0436c..fdba155416d2 100644 --- a/drivers/mtd/nand/raw/ams-delta.c +++ b/drivers/mtd/nand/raw/ams-delta.c @@ -191,8 +191,8 @@ static int gpio_nand_exec_op(struct nand_chip *this, return ret; } -static int gpio_nand_setup_data_interface(struct nand_chip *this, int csline, - const struct nand_data_interface *cf) +static int gpio_nand_setup_interface(struct nand_chip *this, int csline, + const struct nand_interface_config *cf) { struct gpio_nand *priv = nand_get_controller_data(this); const struct nand_sdr_timings *sdr = nand_get_sdr_timings(cf); @@ -217,7 +217,7 @@ static int gpio_nand_setup_data_interface(struct nand_chip *this, int csline, static const struct nand_controller_ops gpio_nand_ops = { .exec_op = gpio_nand_exec_op, - .setup_data_interface = gpio_nand_setup_data_interface, + .setup_interface = gpio_nand_setup_interface, }; /* diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c index 7141dcccba3c..12c643e97c85 100644 --- a/drivers/mtd/nand/raw/arasan-nand-controller.c +++ b/drivers/mtd/nand/raw/arasan-nand-controller.c @@ -854,8 +854,8 @@ static int anfc_exec_op(struct nand_chip *chip, return nand_op_parser_exec_op(chip, &anfc_op_parser, op, check_only); } -static int anfc_setup_data_interface(struct nand_chip *chip, int target, - const struct nand_data_interface *conf) +static int anfc_setup_interface(struct nand_chip *chip, int target, + const struct nand_interface_config *conf) { struct anand *anand = to_anand(chip); struct arasan_nfc *nfc = to_anfc(chip->controller); @@ -1083,7 +1083,7 @@ static void anfc_detach_chip(struct nand_chip *chip) static const struct nand_controller_ops anfc_ops = { .exec_op = anfc_exec_op, - .setup_data_interface = anfc_setup_data_interface, + .setup_interface = anfc_setup_interface, .attach_chip = anfc_attach_chip, .detach_chip = anfc_detach_chip, }; diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index 46a3724a788e..c9818f548d07 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -200,8 +200,8 @@ struct atmel_nand_controller_ops { void (*nand_init)(struct atmel_nand_controller *nc, struct atmel_nand *nand); int (*ecc_init)(struct nand_chip *chip); - int (*setup_data_interface)(struct atmel_nand *nand, int csline, - const struct nand_data_interface *conf); + int (*setup_interface)(struct atmel_nand *nand, int csline, + const struct nand_interface_config *conf); }; struct atmel_nand_controller_caps { @@ -1168,7 +1168,7 @@ static int atmel_hsmc_nand_ecc_init(struct nand_chip *chip) } static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand, - const struct nand_data_interface *conf, + const struct nand_interface_config *conf, struct atmel_smc_cs_conf *smcconf) { u32 ncycles, totalcycles, timeps, mckperiodps; @@ -1397,9 +1397,9 @@ static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand, return 0; } -static int atmel_smc_nand_setup_data_interface(struct atmel_nand *nand, +static int atmel_smc_nand_setup_interface(struct atmel_nand *nand, int csline, - const struct nand_data_interface *conf) + const struct nand_interface_config *conf) { struct atmel_nand_controller *nc; struct atmel_smc_cs_conf smcconf; @@ -1422,9 +1422,9 @@ static int atmel_smc_nand_setup_data_interface(struct atmel_nand *nand, return 0; } -static int atmel_hsmc_nand_setup_data_interface(struct atmel_nand *nand, +static int atmel_hsmc_nand_setup_interface(struct atmel_nand *nand, int csline, - const struct nand_data_interface *conf) + const struct nand_interface_config *conf) { struct atmel_hsmc_nand_controller *nc; struct atmel_smc_cs_conf smcconf; @@ -1452,8 +1452,8 @@ static int atmel_hsmc_nand_setup_data_interface(struct atmel_nand *nand, return 0; } -static int atmel_nand_setup_data_interface(struct nand_chip *chip, int csline, - const struct nand_data_interface *conf) +static int atmel_nand_setup_interface(struct nand_chip *chip, int csline, + const struct nand_interface_config *conf) { struct atmel_nand *nand = to_atmel_nand(chip); struct atmel_nand_controller *nc; @@ -1464,7 +1464,7 @@ static int atmel_nand_setup_data_interface(struct nand_chip *chip, int csline, (csline < 0 && csline != NAND_DATA_IFACE_CHECK_ONLY)) return -EINVAL; - return nc->caps->ops->setup_data_interface(nand, csline, conf); + return nc->caps->ops->setup_interface(nand, csline, conf); } static void atmel_nand_init(struct atmel_nand_controller *nc, @@ -1483,7 +1483,7 @@ static void atmel_nand_init(struct atmel_nand_controller *nc, chip->legacy.write_buf = atmel_nand_write_buf; chip->legacy.select_chip = atmel_nand_select_chip; - if (!nc->mck || !nc->caps->ops->setup_data_interface) + if (!nc->mck || !nc->caps->ops->setup_interface) chip->options |= NAND_KEEP_TIMINGS; /* Some NANDs require a longer delay than the default one (20us). */ @@ -1956,7 +1956,7 @@ static int atmel_nand_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops atmel_nand_controller_ops = { .attach_chip = atmel_nand_attach_chip, - .setup_data_interface = atmel_nand_setup_data_interface, + .setup_interface = atmel_nand_setup_interface, }; static int atmel_nand_controller_init(struct atmel_nand_controller *nc, @@ -2318,7 +2318,7 @@ static const struct atmel_nand_controller_ops atmel_hsmc_nc_ops = { .remove = atmel_hsmc_nand_controller_remove, .ecc_init = atmel_hsmc_nand_ecc_init, .nand_init = atmel_hsmc_nand_init, - .setup_data_interface = atmel_hsmc_nand_setup_data_interface, + .setup_interface = atmel_hsmc_nand_setup_interface, }; static const struct atmel_nand_controller_caps atmel_sama5_nc_caps = { @@ -2375,10 +2375,10 @@ atmel_smc_nand_controller_remove(struct atmel_nand_controller *nc) /* * The SMC reg layout of at91rm9200 is completely different which prevents us - * from re-using atmel_smc_nand_setup_data_interface() for the - * ->setup_data_interface() hook. + * from re-using atmel_smc_nand_setup_interface() for the + * ->setup_interface() hook. * At this point, there's no support for the at91rm9200 SMC IP, so we leave - * ->setup_data_interface() unassigned. + * ->setup_interface() unassigned. */ static const struct atmel_nand_controller_ops at91rm9200_nc_ops = { .probe = atmel_smc_nand_controller_probe, @@ -2399,7 +2399,7 @@ static const struct atmel_nand_controller_ops atmel_smc_nc_ops = { .remove = atmel_smc_nand_controller_remove, .ecc_init = atmel_nand_ecc_init, .nand_init = atmel_smc_nand_init, - .setup_data_interface = atmel_smc_nand_setup_data_interface, + .setup_interface = atmel_smc_nand_setup_interface, }; static const struct atmel_nand_controller_caps atmel_sam9260_nc_caps = { diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c index c405722adfe1..574cbd3446e5 100644 --- a/drivers/mtd/nand/raw/cadence-nand-controller.c +++ b/drivers/mtd/nand/raw/cadence-nand-controller.c @@ -2303,8 +2303,8 @@ static inline u32 calc_tdvw(u32 trp_cnt, u32 clk_period, u32 trhoh_min, } static int -cadence_nand_setup_data_interface(struct nand_chip *chip, int chipnr, - const struct nand_data_interface *conf) +cadence_nand_setup_interface(struct nand_chip *chip, int chipnr, + const struct nand_interface_config *conf) { const struct nand_sdr_timings *sdr; struct cdns_nand_ctrl *cdns_ctrl = to_cdns_nand_ctrl(chip->controller); @@ -2690,7 +2690,7 @@ static int cadence_nand_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops cadence_nand_controller_ops = { .attach_chip = cadence_nand_attach_chip, .exec_op = cadence_nand_exec_op, - .setup_data_interface = cadence_nand_setup_data_interface, + .setup_interface = cadence_nand_setup_interface, }; static int cadence_nand_chip_init(struct cdns_nand_ctrl *cdns_ctrl, diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 4e6e1578aa2d..9d99dade95ce 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -761,8 +761,8 @@ static int denali_write_page(struct nand_chip *chip, const u8 *buf, return denali_page_xfer(chip, (void *)buf, mtd->writesize, page, true); } -static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, - const struct nand_data_interface *conf) +static int denali_setup_interface(struct nand_chip *chip, int chipnr, + const struct nand_interface_config *conf) { static const unsigned int data_setup_on_host = 10000; struct denali_controller *denali = to_denali_controller(chip); @@ -1173,7 +1173,7 @@ static int denali_exec_op(struct nand_chip *chip, static const struct nand_controller_ops denali_controller_ops = { .attach_chip = denali_attach_chip, .exec_op = denali_exec_op, - .setup_data_interface = denali_setup_data_interface, + .setup_interface = denali_setup_interface, }; int denali_chip_init(struct denali_controller *denali, @@ -1230,7 +1230,7 @@ int denali_chip_init(struct denali_controller *denali, chip->buf_align = 16; } - /* clk rate info is needed for setup_data_interface */ + /* clk rate info is needed for setup_interface */ if (!denali->clk_rate || !denali->clk_x_rate) chip->options |= NAND_KEEP_TIMINGS; diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c index 3909752b14c5..92ddc41d0ff0 100644 --- a/drivers/mtd/nand/raw/fsmc_nand.c +++ b/drivers/mtd/nand/raw/fsmc_nand.c @@ -327,8 +327,8 @@ static int fsmc_calc_timings(struct fsmc_nand_data *host, return 0; } -static int fsmc_setup_data_interface(struct nand_chip *nand, int csline, - const struct nand_data_interface *conf) +static int fsmc_setup_interface(struct nand_chip *nand, int csline, + const struct nand_interface_config *conf) { struct fsmc_nand_data *host = nand_to_fsmc(nand); struct fsmc_nand_timings tims; @@ -951,7 +951,7 @@ static int fsmc_nand_attach_chip(struct nand_chip *nand) static const struct nand_controller_ops fsmc_nand_controller_ops = { .attach_chip = fsmc_nand_attach_chip, .exec_op = fsmc_exec_op, - .setup_data_interface = fsmc_setup_data_interface, + .setup_interface = fsmc_setup_interface, }; /** diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index 061a8ddda275..5d4aee46cc55 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -736,8 +736,8 @@ static void gpmi_nfc_apply_timings(struct gpmi_nand_data *this) udelay(dll_wait_time_us); } -static int gpmi_setup_data_interface(struct nand_chip *chip, int chipnr, - const struct nand_data_interface *conf) +static int gpmi_setup_interface(struct nand_chip *chip, int chipnr, + const struct nand_interface_config *conf) { struct gpmi_nand_data *this = nand_get_controller_data(chip); const struct nand_sdr_timings *sdr; @@ -2400,7 +2400,7 @@ unmap: static const struct nand_controller_ops gpmi_nand_controller_ops = { .attach_chip = gpmi_nand_attach_chip, - .setup_data_interface = gpmi_setup_data_interface, + .setup_interface = gpmi_setup_interface, .exec_op = gpmi_nfc_exec_op, }; diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index f851ed210d70..114c63a6a349 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -84,10 +84,10 @@ int nand_bbm_get_next_page(struct nand_chip *chip, int page); int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs); int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, int allowbbt); -int onfi_fill_data_interface(struct nand_chip *chip, - struct nand_data_interface *iface, - enum nand_data_interface_type type, - unsigned int timing_mode); +int onfi_fill_interface_config(struct nand_chip *chip, + struct nand_interface_config *iface, + enum nand_interface_type type, + unsigned int timing_mode); unsigned int onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings); int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param); @@ -133,10 +133,10 @@ static inline int nand_exec_op(struct nand_chip *chip, return chip->controller->ops->exec_op(chip, op, false); } -static inline bool nand_controller_can_setup_data_iface(struct nand_chip *chip) +static inline bool nand_controller_can_setup_interface(struct nand_chip *chip) { if (!chip->controller || !chip->controller->ops || - !chip->controller->ops->setup_data_interface) + !chip->controller->ops->setup_interface) return false; if (chip->options & NAND_KEEP_TIMINGS) diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index df859889e4eb..8482d3bd8b1f 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -2308,9 +2308,8 @@ static struct nand_bbt_descr bbt_mirror_descr = { .pattern = bbt_mirror_pattern }; -static int marvell_nfc_setup_data_interface(struct nand_chip *chip, int chipnr, - const struct nand_data_interface - *conf) +static int marvell_nfc_setup_interface(struct nand_chip *chip, int chipnr, + const struct nand_interface_config *conf) { struct marvell_nand_chip *marvell_nand = to_marvell_nand(chip); struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); @@ -2511,7 +2510,7 @@ static int marvell_nand_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops marvell_nand_controller_ops = { .attach_chip = marvell_nand_attach_chip, .exec_op = marvell_nfc_exec_op, - .setup_data_interface = marvell_nfc_setup_data_interface, + .setup_interface = marvell_nfc_setup_interface, }; static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc, @@ -2647,7 +2646,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc, /* * Save a reference value for timing registers before - * ->setup_data_interface() is called. + * ->setup_interface() is called. */ marvell_nand->ndtr0 = readl_relaxed(nfc->regs + NDTR0); marvell_nand->ndtr1 = readl_relaxed(nfc->regs + NDTR1); diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index 580b7be0719f..0e5829a2b54f 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -1097,8 +1097,8 @@ static int meson_chip_buffer_init(struct nand_chip *nand) } static -int meson_nfc_setup_data_interface(struct nand_chip *nand, int csline, - const struct nand_data_interface *conf) +int meson_nfc_setup_interface(struct nand_chip *nand, int csline, + const struct nand_interface_config *conf) { struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); const struct nand_sdr_timings *timings; @@ -1222,7 +1222,7 @@ static int meson_nand_attach_chip(struct nand_chip *nand) static const struct nand_controller_ops meson_nand_controller_ops = { .attach_chip = meson_nand_attach_chip, .detach_chip = meson_nand_detach_chip, - .setup_data_interface = meson_nfc_setup_data_interface, + .setup_interface = meson_nfc_setup_interface, .exec_op = meson_nfc_exec_op, }; diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c index ca8457626d53..ad1b55dab211 100644 --- a/drivers/mtd/nand/raw/mtk_nand.c +++ b/drivers/mtd/nand/raw/mtk_nand.c @@ -531,8 +531,8 @@ static int mtk_nfc_exec_op(struct nand_chip *chip, return ret; } -static int mtk_nfc_setup_data_interface(struct nand_chip *chip, int csline, - const struct nand_data_interface *conf) +static int mtk_nfc_setup_interface(struct nand_chip *chip, int csline, + const struct nand_interface_config *conf) { struct mtk_nfc *nfc = nand_get_controller_data(chip); const struct nand_sdr_timings *timings; @@ -1357,7 +1357,7 @@ static int mtk_nfc_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops mtk_nfc_controller_ops = { .attach_chip = mtk_nfc_attach_chip, - .setup_data_interface = mtk_nfc_setup_data_interface, + .setup_interface = mtk_nfc_setup_interface, .exec_op = mtk_nfc_exec_op, }; diff --git a/drivers/mtd/nand/raw/mxc_nand.c b/drivers/mtd/nand/raw/mxc_nand.c index 09dacb83cb5a..07c41e8bae2d 100644 --- a/drivers/mtd/nand/raw/mxc_nand.c +++ b/drivers/mtd/nand/raw/mxc_nand.c @@ -137,8 +137,8 @@ struct mxc_nand_devtype_data { u32 (*get_ecc_status)(struct mxc_nand_host *); const struct mtd_ooblayout_ops *ooblayout; void (*select_chip)(struct nand_chip *chip, int cs); - int (*setup_data_interface)(struct nand_chip *chip, int csline, - const struct nand_data_interface *conf); + int (*setup_interface)(struct nand_chip *chip, int csline, + const struct nand_interface_config *conf); void (*enable_hwecc)(struct nand_chip *chip, bool enable); /* @@ -1139,8 +1139,8 @@ static void preset_v1(struct mtd_info *mtd) writew(0x4, NFC_V1_V2_WRPROT); } -static int mxc_nand_v2_setup_data_interface(struct nand_chip *chip, int csline, - const struct nand_data_interface *conf) +static int mxc_nand_v2_setup_interface(struct nand_chip *chip, int csline, + const struct nand_interface_config *conf) { struct mxc_nand_host *host = nand_get_controller_data(chip); int tRC_min_ns, tRC_ps, ret; @@ -1521,7 +1521,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { .get_ecc_status = get_ecc_status_v2, .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v2, - .setup_data_interface = mxc_nand_v2_setup_data_interface, + .setup_interface = mxc_nand_v2_setup_interface, .enable_hwecc = mxc_nand_enable_hwecc_v1_v2, .irqpending_quirk = 0, .needs_ip = 0, @@ -1738,17 +1738,17 @@ static int mxcnd_attach_chip(struct nand_chip *chip) return 0; } -static int mxcnd_setup_data_interface(struct nand_chip *chip, int chipnr, - const struct nand_data_interface *conf) +static int mxcnd_setup_interface(struct nand_chip *chip, int chipnr, + const struct nand_interface_config *conf) { struct mxc_nand_host *host = nand_get_controller_data(chip); - return host->devtype_data->setup_data_interface(chip, chipnr, conf); + return host->devtype_data->setup_interface(chip, chipnr, conf); } static const struct nand_controller_ops mxcnd_controller_ops = { .attach_chip = mxcnd_attach_chip, - .setup_data_interface = mxcnd_setup_data_interface, + .setup_interface = mxcnd_setup_interface, }; static int mxcnd_probe(struct platform_device *pdev) @@ -1809,7 +1809,7 @@ static int mxcnd_probe(struct platform_device *pdev) if (err < 0) return err; - if (!host->devtype_data->setup_data_interface) + if (!host->devtype_data->setup_interface) this->options |= NAND_KEEP_TIMINGS; if (host->devtype_data->needs_ip) { diff --git a/drivers/mtd/nand/raw/mxic_nand.c b/drivers/mtd/nand/raw/mxic_nand.c index 57f36721f4c6..d66b5b0971fa 100644 --- a/drivers/mtd/nand/raw/mxic_nand.c +++ b/drivers/mtd/nand/raw/mxic_nand.c @@ -451,8 +451,8 @@ static int mxic_nfc_exec_op(struct nand_chip *chip, return ret; } -static int mxic_nfc_setup_data_interface(struct nand_chip *chip, int chipnr, - const struct nand_data_interface *conf) +static int mxic_nfc_setup_interface(struct nand_chip *chip, int chipnr, + const struct nand_interface_config *conf) { struct mxic_nand_ctlr *nfc = nand_get_controller_data(chip); const struct nand_sdr_timings *sdr; @@ -480,7 +480,7 @@ static int mxic_nfc_setup_data_interface(struct nand_chip *chip, int chipnr, static const struct nand_controller_ops mxic_nand_controller_ops = { .exec_op = mxic_nfc_exec_op, - .setup_data_interface = mxic_nfc_setup_data_interface, + .setup_interface = mxic_nfc_setup_interface, }; static int mxic_nfc_probe(struct platform_device *pdev) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 7d393e1d0252..4fa18fb68d62 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -898,7 +898,7 @@ static bool nand_supports_set_features(struct nand_chip *chip, int addr) } /** - * nand_reset_data_interface - Reset data interface and timings + * nand_reset_interface - Reset data interface and timings * @chip: The NAND chip * @chipnr: Internal die id * @@ -906,11 +906,12 @@ static bool nand_supports_set_features(struct nand_chip *chip, int addr) * * Returns 0 for success or negative error code otherwise. */ -static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) +static int nand_reset_interface(struct nand_chip *chip, int chipnr) { + const struct nand_controller_ops *ops = chip->controller->ops; int ret; - if (!nand_controller_can_setup_data_iface(chip)) + if (!nand_controller_can_setup_interface(chip)) return 0; /* @@ -927,9 +928,9 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) * timings to timing mode 0. */ - onfi_fill_data_interface(chip, &chip->data_interface, NAND_SDR_IFACE, 0); - ret = chip->controller->ops->setup_data_interface(chip, chipnr, - &chip->data_interface); + onfi_fill_interface_config(chip, &chip->interface_config, + NAND_SDR_IFACE, 0); + ret = ops->setup_interface(chip, chipnr, &chip->interface_config); if (ret) pr_err("Failed to configure data interface to SDR timing mode 0\n"); @@ -937,7 +938,7 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) } /** - * nand_setup_data_interface - Setup the best data interface and timings + * nand_setup_interface - Setup the best data interface and timings * @chip: The NAND chip * @chipnr: Internal die id * @@ -946,13 +947,13 @@ static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) * * Returns 0 for success or negative error code otherwise. */ -static int nand_setup_data_interface(struct nand_chip *chip, int chipnr) +static int nand_setup_interface(struct nand_chip *chip, int chipnr) { - u8 mode = chip->data_interface.timings.mode; + u8 mode = chip->interface_config.timings.mode; u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { mode, }; int ret; - if (!nand_controller_can_setup_data_iface(chip)) + if (!nand_controller_can_setup_interface(chip)) return 0; /* Change the mode on the chip side (if supported by the NAND chip) */ @@ -966,8 +967,8 @@ static int nand_setup_data_interface(struct nand_chip *chip, int chipnr) } /* Change the mode on the controller side */ - ret = chip->controller->ops->setup_data_interface(chip, chipnr, - &chip->data_interface); + ret = chip->controller->ops->setup_interface(chip, chipnr, + &chip->interface_config); if (ret) return ret; @@ -996,7 +997,7 @@ err_reset_chip: * Fallback to mode 0 if the chip explicitly did not ack the chosen * timing mode. */ - nand_reset_data_interface(chip, chipnr); + nand_reset_interface(chip, chipnr); nand_select_target(chip, chipnr); nand_reset_op(chip); nand_deselect_target(chip); @@ -1005,7 +1006,7 @@ err_reset_chip: } /** - * nand_choose_data_interface - find the best data interface and timings + * nand_choose_interface_config - find the best data interface and timings * @chip: The NAND chip * * Find the best data interface and NAND timings supported by the chip @@ -1013,16 +1014,16 @@ err_reset_chip: * First tries to retrieve supported timing modes from ONFI information, * and if the NAND chip does not support ONFI, relies on the * ->onfi_timing_mode_default specified in the nand_ids table. After this - * function nand_chip->data_interface is initialized with the best timing mode + * function nand_chip->interface_ is initialized with the best timing mode * available. * * Returns 0 for success or negative error code otherwise. */ -static int nand_choose_data_interface(struct nand_chip *chip) +static int nand_choose_interface_config(struct nand_chip *chip) { int modes, mode, ret; - if (!nand_controller_can_setup_data_iface(chip)) + if (!nand_controller_can_setup_interface(chip)) return 0; /* @@ -1040,8 +1041,8 @@ static int nand_choose_data_interface(struct nand_chip *chip) } for (mode = fls(modes) - 1; mode >= 0; mode--) { - ret = onfi_fill_data_interface(chip, &chip->data_interface, - NAND_SDR_IFACE, mode); + ret = onfi_fill_interface_config(chip, &chip->interface_config, + NAND_SDR_IFACE, mode); if (ret) continue; @@ -1049,9 +1050,9 @@ static int nand_choose_data_interface(struct nand_chip *chip) * Pass NAND_DATA_IFACE_CHECK_ONLY to only check if the * controller supports the requested timings. */ - ret = chip->controller->ops->setup_data_interface(chip, + ret = chip->controller->ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY, - &chip->data_interface); + &chip->interface_config); if (!ret) { chip->onfi_timing_mode_default = mode; break; @@ -2477,17 +2478,17 @@ EXPORT_SYMBOL_GPL(nand_subop_get_data_len); * @chipnr: Internal die id * * Save the timings data structure, then apply SDR timings mode 0 (see - * nand_reset_data_interface for details), do the reset operation, and - * apply back the previous timings. + * nand_reset_interface for details), do the reset operation, and apply + * back the previous timings. * * Returns 0 on success, a negative error code otherwise. */ int nand_reset(struct nand_chip *chip, int chipnr) { - struct nand_data_interface saved_data_intf = chip->data_interface; + struct nand_interface_config saved_intf_config = chip->interface_config; int ret; - ret = nand_reset_data_interface(chip, chipnr); + ret = nand_reset_interface(chip, chipnr); if (ret) return ret; @@ -2503,18 +2504,18 @@ int nand_reset(struct nand_chip *chip, int chipnr) return ret; /* - * A nand_reset_data_interface() put both the NAND chip and the NAND + * A nand_reset_interface() put both the NAND chip and the NAND * controller in timings mode 0. If the default mode for this chip is * also 0, no need to proceed to the change again. Plus, at probe time, - * nand_setup_data_interface() uses ->set/get_features() which would + * nand_setup_interface() uses ->set/get_features() which would * fail anyway as the parameter page is not available yet. */ - if (!memcmp(&chip->data_interface, &saved_data_intf, - sizeof(saved_data_intf))) + if (!memcmp(&chip->interface_config, &saved_intf_config, + sizeof(saved_intf_config))) return 0; - chip->data_interface = saved_data_intf; - ret = nand_setup_data_interface(chip, chipnr); + chip->interface_config = saved_intf_config; + ret = nand_setup_interface(chip, chipnr); if (ret) return ret; @@ -5183,7 +5184,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, mutex_init(&chip->lock); /* Enforce the right timings for reset/detection */ - onfi_fill_data_interface(chip, &chip->data_interface, NAND_SDR_IFACE, 0); + onfi_fill_interface_config(chip, &chip->interface_config, NAND_SDR_IFACE, 0); ret = nand_dt_init(chip); if (ret) @@ -5971,13 +5972,13 @@ static int nand_scan_tail(struct nand_chip *chip) mtd->bitflip_threshold = DIV_ROUND_UP(mtd->ecc_strength * 3, 4); /* Find the fastest data interface for this chip */ - ret = nand_choose_data_interface(chip); + ret = nand_choose_interface_config(chip); if (ret) goto err_nanddev_cleanup; /* Enter fastest possible mode on all dies. */ for (i = 0; i < nanddev_ntargets(&chip->base); i++) { - ret = nand_setup_data_interface(chip, i); + ret = nand_setup_interface(chip, i); if (ret) goto err_nanddev_cleanup; } diff --git a/drivers/mtd/nand/raw/nand_legacy.c b/drivers/mtd/nand/raw/nand_legacy.c index fe769762e1d8..2bcc03714432 100644 --- a/drivers/mtd/nand/raw/nand_legacy.c +++ b/drivers/mtd/nand/raw/nand_legacy.c @@ -368,7 +368,7 @@ static void nand_ccs_delay(struct nand_chip *chip) * Wait tCCS_min if it is correctly defined, otherwise wait 500ns * (which should be safe for all NANDs). */ - if (nand_controller_can_setup_data_iface(chip)) + if (nand_controller_can_setup_interface(chip)) ndelay(sdr->tCCS_min / 1000); else ndelay(500); diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index efff3583c549..bf05b4bceaa0 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -19,7 +19,7 @@ * * These four values are tweaked to be more accurate in the case of ONFI chips. */ -static const struct nand_data_interface onfi_sdr_timings[] = { +static const struct nand_interface_config onfi_sdr_timings[] = { /* Mode 0 */ { .type = NAND_SDR_IFACE, @@ -340,16 +340,17 @@ onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings) } /** - * onfi_fill_data_interface - Initialize a data interface from a given ONFI mode + * onfi_fill_interface_config - Initialize an interface config from a given + * ONFI mode * @chip: The NAND chip - * @iface: The data interface to fill - * @type: The data interface type + * @iface: The interface configuration to fill + * @type: The interface type * @timing_mode: The ONFI timing mode */ -int onfi_fill_data_interface(struct nand_chip *chip, - struct nand_data_interface *iface, - enum nand_data_interface_type type, - unsigned int timing_mode) +int onfi_fill_interface_config(struct nand_chip *chip, + struct nand_interface_config *iface, + enum nand_interface_type type, + unsigned int timing_mode) { struct onfi_params *onfi = chip->parameters.onfi; diff --git a/drivers/mtd/nand/raw/s3c2410.c b/drivers/mtd/nand/raw/s3c2410.c index f86dff311464..f121a3ae294c 100644 --- a/drivers/mtd/nand/raw/s3c2410.c +++ b/drivers/mtd/nand/raw/s3c2410.c @@ -808,8 +808,8 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, return -ENODEV; } -static int s3c2410_nand_setup_data_interface(struct nand_chip *chip, int csline, - const struct nand_data_interface *conf) +static int s3c2410_nand_setup_interface(struct nand_chip *chip, int csline, + const struct nand_interface_config *conf) { struct mtd_info *mtd = nand_to_mtd(chip); struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); @@ -999,7 +999,7 @@ static int s3c2410_nand_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops s3c24xx_nand_controller_ops = { .attach_chip = s3c2410_nand_attach_chip, - .setup_data_interface = s3c2410_nand_setup_data_interface, + .setup_interface = s3c2410_nand_setup_interface, }; static const struct of_device_id s3c24xx_nand_dt_ids[] = { diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index 7320c0fc19ec..a4140af43ed4 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -1546,7 +1546,7 @@ static void stm32_fmc2_nfc_calc_timings(struct nand_chip *chip, } static int stm32_fmc2_nfc_setup_interface(struct nand_chip *chip, int chipnr, - const struct nand_data_interface *conf) + const struct nand_interface_config *conf) { const struct nand_sdr_timings *sdrt; @@ -1764,7 +1764,7 @@ static int stm32_fmc2_nfc_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops stm32_fmc2_nfc_controller_ops = { .attach_chip = stm32_fmc2_nfc_attach_chip, .exec_op = stm32_fmc2_nfc_exec_op, - .setup_data_interface = stm32_fmc2_nfc_setup_interface, + .setup_interface = stm32_fmc2_nfc_setup_interface, }; static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index ffbc1651fadc..9c50c2b965e1 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1376,8 +1376,8 @@ static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration, #define sunxi_nand_lookup_timing(l, p, c) \ _sunxi_nand_lookup_timing(l, ARRAY_SIZE(l), p, c) -static int sunxi_nfc_setup_data_interface(struct nand_chip *nand, int csline, - const struct nand_data_interface *conf) +static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, + const struct nand_interface_config *conf) { struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); @@ -1920,7 +1920,7 @@ static int sunxi_nfc_exec_op(struct nand_chip *nand, static const struct nand_controller_ops sunxi_nand_controller_ops = { .attach_chip = sunxi_nand_attach_chip, - .setup_data_interface = sunxi_nfc_setup_data_interface, + .setup_interface = sunxi_nfc_setup_interface, .exec_op = sunxi_nfc_exec_op, }; diff --git a/drivers/mtd/nand/raw/tango_nand.c b/drivers/mtd/nand/raw/tango_nand.c index 648dc7e77f6a..bdb965ae7a4a 100644 --- a/drivers/mtd/nand/raw/tango_nand.c +++ b/drivers/mtd/nand/raw/tango_nand.c @@ -515,7 +515,7 @@ static u32 to_ticks(int kHz, int ps) } static int tango_set_timings(struct nand_chip *chip, int csline, - const struct nand_data_interface *conf) + const struct nand_interface_config *conf) { const struct nand_sdr_timings *sdr = nand_get_sdr_timings(conf); struct tango_nfc *nfc = to_tango_nfc(chip->controller); @@ -565,7 +565,7 @@ static int tango_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops tango_controller_ops = { .attach_chip = tango_attach_chip, - .setup_data_interface = tango_set_timings, + .setup_interface = tango_set_timings, .exec_op = tango_exec_op, }; diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c index f9d046b2cd3b..6b6212ffa01c 100644 --- a/drivers/mtd/nand/raw/tegra_nand.c +++ b/drivers/mtd/nand/raw/tegra_nand.c @@ -813,8 +813,8 @@ static void tegra_nand_setup_timing(struct tegra_nand_controller *ctrl, writel_relaxed(reg, ctrl->regs + TIMING_2); } -static int tegra_nand_setup_data_interface(struct nand_chip *chip, int csline, - const struct nand_data_interface *conf) +static int tegra_nand_setup_interface(struct nand_chip *chip, int csline, + const struct nand_interface_config *conf) { struct tegra_nand_controller *ctrl = to_tegra_ctrl(chip->controller); const struct nand_sdr_timings *timings; @@ -1053,7 +1053,7 @@ static int tegra_nand_attach_chip(struct nand_chip *chip) static const struct nand_controller_ops tegra_nand_controller_ops = { .attach_chip = &tegra_nand_attach_chip, .exec_op = tegra_nand_exec_op, - .setup_data_interface = tegra_nand_setup_data_interface, + .setup_interface = tegra_nand_setup_interface, }; static int tegra_nand_chips_init(struct device *dev, diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 0852df941130..2ca56eef0f07 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -492,22 +492,22 @@ struct nand_sdr_timings { }; /** - * enum nand_data_interface_type - NAND interface timing type + * enum nand_interface_type - NAND interface type * @NAND_SDR_IFACE: Single Data Rate interface */ -enum nand_data_interface_type { +enum nand_interface_type { NAND_SDR_IFACE, }; /** - * struct nand_data_interface - NAND interface timing + * struct nand_interface_config - NAND interface timing * @type: type of the timing * @timings: The timing information * @timings.mode: Timing mode as defined in the specification * @timings.sdr: Use it when @type is %NAND_SDR_IFACE. */ -struct nand_data_interface { - enum nand_data_interface_type type; +struct nand_interface_config { + enum nand_interface_type type; struct nand_timings { unsigned int mode; union { @@ -521,7 +521,7 @@ struct nand_data_interface { * @conf: The data interface */ static inline const struct nand_sdr_timings * -nand_get_sdr_timings(const struct nand_data_interface *conf) +nand_get_sdr_timings(const struct nand_interface_config *conf) { if (conf->type != NAND_SDR_IFACE) return ERR_PTR(-EINVAL); @@ -944,11 +944,10 @@ static inline void nand_op_trace(const char *prefix, * This method replaces chip->legacy.cmdfunc(), * chip->legacy.{read,write}_{buf,byte,word}(), * chip->legacy.dev_ready() and chip->legacy.waifunc(). - * @setup_data_interface: setup the data interface and timing. If - * chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this - * means the configuration should not be applied but - * only checked. - * This hook is optional. + * @setup_interface: setup the data interface and timing. If chipnr is set to + * %NAND_DATA_IFACE_CHECK_ONLY this means the configuration + * should not be applied but only checked. + * This hook is optional. */ struct nand_controller_ops { int (*attach_chip)(struct nand_chip *chip); @@ -956,8 +955,8 @@ struct nand_controller_ops { int (*exec_op)(struct nand_chip *chip, const struct nand_operation *op, bool check_only); - int (*setup_data_interface)(struct nand_chip *chip, int chipnr, - const struct nand_data_interface *conf); + int (*setup_interface)(struct nand_chip *chip, int chipnr, + const struct nand_interface_config *conf); }; /** @@ -1070,7 +1069,7 @@ struct nand_manufacturer { * @onfi_timing_mode_default: Default ONFI timing mode. This field is set to the * actually used ONFI mode if the chip is ONFI * compliant or deduced from the datasheet otherwise - * @data_interface: NAND interface timing information + * @interface_config: NAND interface timing information * @bbt_erase_shift: Number of address bits in a bbt entry * @bbt_options: Bad block table specific options. All options used here must * come from bbm.h. By default, these options will be copied to @@ -1118,7 +1117,7 @@ struct nand_chip { /* Data interface */ int onfi_timing_mode_default; - struct nand_data_interface data_interface; + struct nand_interface_config interface_config; /* Bad block information */ unsigned int bbt_erase_shift; @@ -1208,10 +1207,10 @@ static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) * of a NAND chip * @chip: The NAND chip */ -static inline const struct nand_data_interface * +static inline const struct nand_interface_config * nand_get_interface_config(struct nand_chip *chip) { - return &chip->data_interface; + return &chip->interface_config; } /* From 42a9ad050e6f1f6e909e2117e7a99f54f5336939 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:14 +0200 Subject: [PATCH 056/242] mtd: rawnand: timings: Make onfi_fill_interface_config() a void helper Warn the user if the parameters are wrong but basically it would mean there is a serious issue in the NAND core. So no need to ever check its output, let's make this helper return void. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-21-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/internals.h | 8 ++++---- drivers/mtd/nand/raw/nand_base.c | 6 ++---- drivers/mtd/nand/raw/nand_timings.c | 18 ++++++++---------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index 114c63a6a349..63c5af436901 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -84,10 +84,10 @@ int nand_bbm_get_next_page(struct nand_chip *chip, int page); int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs); int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, int allowbbt); -int onfi_fill_interface_config(struct nand_chip *chip, - struct nand_interface_config *iface, - enum nand_interface_type type, - unsigned int timing_mode); +void onfi_fill_interface_config(struct nand_chip *chip, + struct nand_interface_config *iface, + enum nand_interface_type type, + unsigned int timing_mode); unsigned int onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings); int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param); diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 4fa18fb68d62..3bfd71d589cf 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -1041,10 +1041,8 @@ static int nand_choose_interface_config(struct nand_chip *chip) } for (mode = fls(modes) - 1; mode >= 0; mode--) { - ret = onfi_fill_interface_config(chip, &chip->interface_config, - NAND_SDR_IFACE, mode); - if (ret) - continue; + onfi_fill_interface_config(chip, &chip->interface_config, + NAND_SDR_IFACE, mode); /* * Pass NAND_DATA_IFACE_CHECK_ONLY to only check if the diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index bf05b4bceaa0..1e22006c79ba 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -347,18 +347,18 @@ onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings) * @type: The interface type * @timing_mode: The ONFI timing mode */ -int onfi_fill_interface_config(struct nand_chip *chip, - struct nand_interface_config *iface, - enum nand_interface_type type, - unsigned int timing_mode) +void onfi_fill_interface_config(struct nand_chip *chip, + struct nand_interface_config *iface, + enum nand_interface_type type, + unsigned int timing_mode) { struct onfi_params *onfi = chip->parameters.onfi; - if (type != NAND_SDR_IFACE) - return -EINVAL; + if (WARN_ON(type != NAND_SDR_IFACE)) + return; - if (timing_mode >= ARRAY_SIZE(onfi_sdr_timings)) - return -EINVAL; + if (WARN_ON(timing_mode >= ARRAY_SIZE(onfi_sdr_timings))) + return; *iface = onfi_sdr_timings[timing_mode]; @@ -378,6 +378,4 @@ int onfi_fill_interface_config(struct nand_chip *chip, /* nanoseconds -> picoseconds */ timings->tCCS_min = 1000UL * onfi->tCCS; } - - return 0; } From b5b39f640c1f5621ed4ff6418e74ee35ff5d988e Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:15 +0200 Subject: [PATCH 057/242] mtd: rawnand: Introduce nand_choose_best_sdr_timings() Extract the logic out of nand_choose_interface_config() to create a public helper that can be reused by manufacturer drivers. Add the possibility to provide a specific set of timings. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-22-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/internals.h | 3 + drivers/mtd/nand/raw/nand_base.c | 94 ++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 36 deletions(-) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index 63c5af436901..5ebfbb89e572 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -90,6 +90,9 @@ void onfi_fill_interface_config(struct nand_chip *chip, unsigned int timing_mode); unsigned int onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings); +int nand_choose_best_sdr_timings(struct nand_chip *chip, + struct nand_interface_config *iface, + struct nand_sdr_timings *spec_timings); int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param); int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param); int nand_read_page_raw_notsupp(struct nand_chip *chip, u8 *buf, diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 3bfd71d589cf..742d099df5c6 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -1005,6 +1005,62 @@ err_reset_chip: return ret; } +/** + * nand_choose_best_sdr_timings - Pick up the best SDR timings that both the + * NAND controller and the NAND chip support + * @chip: the NAND chip + * @iface: the interface configuration (can eventually be updated) + * @spec_timings: specific timings, when not fitting the ONFI specification + * + * If specific timings are provided, use them. Otherwise, try to retrieve + * supported timing modes from ONFI information. Finally, if the NAND chip does + * not follow the ONFI specification, rely on the ->default_timing_mode + * specified in the nand_ids table. + */ +int nand_choose_best_sdr_timings(struct nand_chip *chip, + struct nand_interface_config *iface, + struct nand_sdr_timings *spec_timings) +{ + const struct nand_controller_ops *ops = chip->controller->ops; + int best_mode = 0, mode, ret; + + iface->type = NAND_SDR_IFACE; + + if (spec_timings) { + iface->timings.sdr = *spec_timings; + iface->timings.mode = onfi_find_closest_sdr_mode(spec_timings); + + /* Verify the controller supports the requested interface */ + ret = ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY, + iface); + if (!ret) + return ret; + + /* Fallback to slower modes */ + best_mode = iface->timings.mode; + } else { + if (chip->parameters.onfi) { + unsigned int onfi_modes; + + onfi_modes = chip->parameters.onfi->async_timing_mode; + best_mode = fls(onfi_modes) - 1; + } else { + best_mode = chip->onfi_timing_mode_default; + } + } + + for (mode = best_mode; mode >= 0; mode--) { + onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, mode); + + ret = ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY, + iface); + if (!ret) + return 0; + } + + return 0; +} + /** * nand_choose_interface_config - find the best data interface and timings * @chip: The NAND chip @@ -1016,48 +1072,14 @@ err_reset_chip: * ->onfi_timing_mode_default specified in the nand_ids table. After this * function nand_chip->interface_ is initialized with the best timing mode * available. - * - * Returns 0 for success or negative error code otherwise. */ static int nand_choose_interface_config(struct nand_chip *chip) { - int modes, mode, ret; - if (!nand_controller_can_setup_interface(chip)) return 0; - /* - * First try to identify the best timings from ONFI parameters and - * if the NAND does not support ONFI, fallback to the default ONFI - * timing mode. - */ - if (chip->parameters.onfi) { - modes = chip->parameters.onfi->async_timing_mode; - } else { - if (!chip->onfi_timing_mode_default) - return 0; - - modes = GENMASK(chip->onfi_timing_mode_default, 0); - } - - for (mode = fls(modes) - 1; mode >= 0; mode--) { - onfi_fill_interface_config(chip, &chip->interface_config, - NAND_SDR_IFACE, mode); - - /* - * Pass NAND_DATA_IFACE_CHECK_ONLY to only check if the - * controller supports the requested timings. - */ - ret = chip->controller->ops->setup_interface(chip, - NAND_DATA_IFACE_CHECK_ONLY, - &chip->interface_config); - if (!ret) { - chip->onfi_timing_mode_default = mode; - break; - } - } - - return 0; + return nand_choose_best_sdr_timings(chip, &chip->interface_config, + NULL); } /** From 26d014f0400e5ff54cc80c8329e3adbd74db1e04 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:16 +0200 Subject: [PATCH 058/242] mtd: rawnand: Add the ->choose_interface_config() hook This hook can be overloaded by NAND manufacturer drivers to propose alternative timings when not following the main standards. In this case, the manufacturer drivers is responsible for choosing the best interface configuration that fits both the controller and chip capabilities. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-23-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_base.c | 17 +++++++++++------ include/linux/mtd/rawnand.h | 3 +++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 742d099df5c6..2f4eba1a1082 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -1066,18 +1066,23 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip, * @chip: The NAND chip * * Find the best data interface and NAND timings supported by the chip - * and the driver. - * First tries to retrieve supported timing modes from ONFI information, - * and if the NAND chip does not support ONFI, relies on the - * ->onfi_timing_mode_default specified in the nand_ids table. After this - * function nand_chip->interface_ is initialized with the best timing mode - * available. + * and the driver. Eventually let the NAND manufacturer driver propose his own + * set of timings. + * + * After this function nand_chip->interface_config is initialized with the best + * timing mode available. + * + * Returns 0 for success or negative error code otherwise. */ static int nand_choose_interface_config(struct nand_chip *chip) { if (!nand_controller_can_setup_interface(chip)) return 0; + if (chip->ops.choose_interface_config) + return chip->ops.choose_interface_config(chip, + &chip->interface_config); + return nand_choose_best_sdr_timings(chip, &chip->interface_config, NULL); } diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 2ca56eef0f07..316a02189da1 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1033,6 +1033,7 @@ struct nand_legacy { * @lock_area: Lock operation * @unlock_area: Unlock operation * @setup_read_retry: Set the read-retry mode (mostly needed for MLC NANDs) + * @choose_interface_config: Choose the best interface configuration */ struct nand_chip_ops { int (*suspend)(struct nand_chip *chip); @@ -1040,6 +1041,8 @@ struct nand_chip_ops { int (*lock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len); int (*unlock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len); int (*setup_read_retry)(struct nand_chip *chip, int retry_mode); + int (*choose_interface_config)(struct nand_chip *chip, + struct nand_interface_config *iface); }; /** From 2f36bae11234b5a9ca018bc44fff0e847cacc33c Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:17 +0200 Subject: [PATCH 059/242] mtd: rawnand: toshiba: Implement ->choose_interface_config() for TC58TEG5DCLTA00 Implement this hook for the tc58teg5dclta00 NAND chip and stop setting ->default_timing_mode. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-24-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_toshiba.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index 333037bdca41..d23bb4322062 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -194,11 +194,21 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) } } +static int +tc58teg5dclta00_choose_interface_config(struct nand_chip *chip, + struct nand_interface_config *iface) +{ + onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 5); + + return nand_choose_best_sdr_timings(chip, iface, NULL); +} + static int tc58teg5dclta00_init(struct nand_chip *chip) { struct mtd_info *mtd = nand_to_mtd(chip); - chip->onfi_timing_mode_default = 5; + chip->ops.choose_interface_config = + &tc58teg5dclta00_choose_interface_config; chip->options |= NAND_NEED_SCRAMBLING; mtd_set_pairing_scheme(mtd, &dist3_pairing_scheme); From 0d0245b99552aa8c5c67d34ab7b4f0fd4d174444 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:18 +0200 Subject: [PATCH 060/242] mtd: rawnand: toshiba: Implement ->choose_interface_config() for TC58NVG0S3E This chip supports ONFI SDR timing mode 2, implement the new hook to advertize it. Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-25-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_ids.c | 3 +-- drivers/mtd/nand/raw/nand_toshiba.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index e0dbc2e316c7..c729a8bc895d 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -28,8 +28,7 @@ struct nand_flash_dev nand_flash_ids[] = { */ {"TC58NVG0S3E 1G 3.3V 8-bit", { .id = {0x98, 0xd1, 0x90, 0x15, 0x76, 0x14, 0x01, 0x00} }, - SZ_2K, SZ_128, SZ_128K, 0, 8, 64, NAND_ECC_INFO(1, SZ_512), - 2 }, + SZ_2K, SZ_128, SZ_128K, 0, 8, 64, NAND_ECC_INFO(1, SZ_512), }, {"TC58NVG2S0F 4G 3.3V 8-bit", { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, SZ_4K, SZ_512, SZ_256K, 0, 8, 224, NAND_ECC_INFO(4, SZ_512) }, diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index d23bb4322062..6d53f9b7a817 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -203,6 +203,15 @@ tc58teg5dclta00_choose_interface_config(struct nand_chip *chip, return nand_choose_best_sdr_timings(chip, iface, NULL); } +static int +tc58nvg0s3e_choose_interface_config(struct nand_chip *chip, + struct nand_interface_config *iface) +{ + onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 2); + + return nand_choose_best_sdr_timings(chip, iface, NULL); +} + static int tc58teg5dclta00_init(struct nand_chip *chip) { struct mtd_info *mtd = nand_to_mtd(chip); @@ -215,6 +224,14 @@ static int tc58teg5dclta00_init(struct nand_chip *chip) return 0; } +static int tc58nvg0s3e_init(struct nand_chip *chip) +{ + chip->ops.choose_interface_config = + &tc58nvg0s3e_choose_interface_config; + + return 0; +} + static int toshiba_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) @@ -227,6 +244,9 @@ static int toshiba_nand_init(struct nand_chip *chip) if (!strcmp("TC58TEG5DCLTA00", chip->parameters.model)) tc58teg5dclta00_init(chip); + if (!strncmp("TC58NVG0S3E", chip->parameters.model, + sizeof("TC58NVG0S3E") - 1)) + tc58nvg0s3e_init(chip); return 0; } From 246a06ff13277349a09ea4dd46f516185e13d01d Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:19 +0200 Subject: [PATCH 061/242] mtd: rawnand: hynix: Implement ->choose_interface_config() for H27UCG8T2ATR-BC This chip supports ONFI SDR timing mode 4, implement the new hook to advertize it. Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-26-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_hynix.c | 14 ++++++++++++++ drivers/mtd/nand/raw/nand_ids.c | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c index 7d1be53f27f3..6d08eb834456 100644 --- a/drivers/mtd/nand/raw/nand_hynix.c +++ b/drivers/mtd/nand/raw/nand_hynix.c @@ -673,6 +673,15 @@ static void hynix_nand_cleanup(struct nand_chip *chip) nand_set_manufacturer_data(chip, NULL); } +static int +h27ucg8t2atrbc_choose_interface_config(struct nand_chip *chip, + struct nand_interface_config *iface) +{ + onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 4); + + return nand_choose_best_sdr_timings(chip, iface, NULL); +} + static int hynix_nand_init(struct nand_chip *chip) { struct hynix_nand *hynix; @@ -689,6 +698,11 @@ static int hynix_nand_init(struct nand_chip *chip) nand_set_manufacturer_data(chip, hynix); + if (!strncmp("H27UCG8T2ATR-BC", chip->parameters.model, + sizeof("H27UCG8T2ATR-BC") - 1)) + chip->ops.choose_interface_config = + h27ucg8t2atrbc_choose_interface_config; + ret = hynix_nand_rr_init(chip); if (ret) hynix_nand_cleanup(chip); diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index c729a8bc895d..3b890d55703d 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -50,7 +50,7 @@ struct nand_flash_dev nand_flash_ids[] = { {"H27UCG8T2ATR-BC 64G 3.3V 8-bit", { .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} }, SZ_8K, SZ_8K, SZ_2M, NAND_NEED_SCRAMBLING, 6, 640, - NAND_ECC_INFO(40, SZ_1K), 4 }, + NAND_ECC_INFO(40, SZ_1K) }, LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS), LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS), From 6d469f863772946e9ebd26068f7c9a609ab128d3 Mon Sep 17 00:00:00 2001 From: Rickard x Andersson Date: Fri, 29 May 2020 13:13:20 +0200 Subject: [PATCH 062/242] mtd: rawnand: toshiba: Choose the interface configuration for TH58NVG2S3HBAI4 The Kioxia/Toshiba TH58NVG2S3HBAI4 NAND memory is not ONFI compliant. The timings of the NAND chip memory are quite close to ONFI mode 4 but is breaking that spec. By providing our own set of timings, erase block read speed is increased from 6910 kiB/s to 13490 kiB/s and erase block write speed is increased from 3350 kiB/s to 4410 kiB/s. Tested on IMX6SX which has a NAND controller supporting EDO mode. Signed-off-by: Rickard x Andersson Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-27-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_ids.c | 3 +++ drivers/mtd/nand/raw/nand_toshiba.c | 38 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index 3b890d55703d..b9945791a9d7 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -51,6 +51,9 @@ struct nand_flash_dev nand_flash_ids[] = { { .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} }, SZ_8K, SZ_8K, SZ_2M, NAND_NEED_SCRAMBLING, 6, 640, NAND_ECC_INFO(40, SZ_1K) }, + {"TH58NVG2S3HBAI4 4G 3.3V 8-bit", + { .id = {0x98, 0xdc, 0x91, 0x15, 0x76} }, + SZ_2K, SZ_512, SZ_128K, 0, 5, 128, NAND_ECC_INFO(8, SZ_512) }, LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS), LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS), diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index 6d53f9b7a817..f746c19f3b2c 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -212,6 +212,33 @@ tc58nvg0s3e_choose_interface_config(struct nand_chip *chip, return nand_choose_best_sdr_timings(chip, iface, NULL); } +static int +th58nvg2s3hbai4_choose_interface_config(struct nand_chip *chip, + struct nand_interface_config *iface) +{ + struct nand_sdr_timings *sdr = &iface->timings.sdr; + + /* Start with timings from the closest timing mode, mode 4. */ + onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 4); + + /* Patch timings that differ from mode 4. */ + sdr->tALS_min = 12000; + sdr->tCHZ_max = 20000; + sdr->tCLS_min = 12000; + sdr->tCOH_min = 0; + sdr->tDS_min = 12000; + sdr->tRHOH_min = 25000; + sdr->tRHW_min = 30000; + sdr->tRHZ_max = 60000; + sdr->tWHR_min = 60000; + + /* Patch timings not part of onfi timing mode. */ + sdr->tPROG_max = 700000000; + sdr->tBERS_max = 5000000000; + + return nand_choose_best_sdr_timings(chip, iface, sdr); +} + static int tc58teg5dclta00_init(struct nand_chip *chip) { struct mtd_info *mtd = nand_to_mtd(chip); @@ -232,6 +259,14 @@ static int tc58nvg0s3e_init(struct nand_chip *chip) return 0; } +static int th58nvg2s3hbai4_init(struct nand_chip *chip) +{ + chip->ops.choose_interface_config = + &th58nvg2s3hbai4_choose_interface_config; + + return 0; +} + static int toshiba_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) @@ -247,6 +282,9 @@ static int toshiba_nand_init(struct nand_chip *chip) if (!strncmp("TC58NVG0S3E", chip->parameters.model, sizeof("TC58NVG0S3E") - 1)) tc58nvg0s3e_init(chip); + if (!strncmp("TH58NVG2S3HBAI4", chip->parameters.model, + sizeof("TH58NVG2S3HBAI4") - 1)) + th58nvg2s3hbai4_init(chip); return 0; } From a69ad11168dca68b3f0adc6882422f4a2e2cb050 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:21 +0200 Subject: [PATCH 063/242] mtd: rawnand: Get rid of the default ONFI timing mode The ->choose_interface() hook is here for manufacturer drivers to provide a better timing interface than the default one, this field is not needed anymore. Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-28-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/nand_base.c | 19 ++++--------------- include/linux/mtd/rawnand.h | 9 --------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 2f4eba1a1082..753328f106c1 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -1012,10 +1012,8 @@ err_reset_chip: * @iface: the interface configuration (can eventually be updated) * @spec_timings: specific timings, when not fitting the ONFI specification * - * If specific timings are provided, use them. Otherwise, try to retrieve - * supported timing modes from ONFI information. Finally, if the NAND chip does - * not follow the ONFI specification, rely on the ->default_timing_mode - * specified in the nand_ids table. + * If specific timings are provided, use them. Otherwise, retrieve supported + * timing modes from ONFI information. */ int nand_choose_best_sdr_timings(struct nand_chip *chip, struct nand_interface_config *iface, @@ -1038,15 +1036,8 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip, /* Fallback to slower modes */ best_mode = iface->timings.mode; - } else { - if (chip->parameters.onfi) { - unsigned int onfi_modes; - - onfi_modes = chip->parameters.onfi->async_timing_mode; - best_mode = fls(onfi_modes) - 1; - } else { - best_mode = chip->onfi_timing_mode_default; - } + } else if (chip->parameters.onfi) { + best_mode = fls(chip->parameters.onfi->async_timing_mode) - 1; } for (mode = best_mode; mode >= 0; mode--) { @@ -4767,8 +4758,6 @@ static bool find_full_id_nand(struct nand_chip *chip, chip->options |= type->options; chip->base.eccreq.strength = NAND_ECC_STRENGTH(type); chip->base.eccreq.step_size = NAND_ECC_STEP(type); - chip->onfi_timing_mode_default = - type->onfi_timing_mode_default; chip->parameters.model = kstrdup(type->name, GFP_KERNEL); if (!chip->parameters.model) diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 316a02189da1..a2427c67d38b 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1069,9 +1069,6 @@ struct nand_manufacturer { * @options: Various chip options. They can partly be set to inform nand_scan * about special functionality. See the defines for further * explanation. - * @onfi_timing_mode_default: Default ONFI timing mode. This field is set to the - * actually used ONFI mode if the chip is ONFI - * compliant or deduced from the datasheet otherwise * @interface_config: NAND interface timing information * @bbt_erase_shift: Number of address bits in a bbt entry * @bbt_options: Bad block table specific options. All options used here must @@ -1119,7 +1116,6 @@ struct nand_chip { unsigned int options; /* Data interface */ - int onfi_timing_mode_default; struct nand_interface_config interface_config; /* Bad block information */ @@ -1268,10 +1264,6 @@ nand_get_interface_config(struct nand_chip *chip) * @ecc_step_ds in nand_chip{}, also from the datasheet. * For example, the "4bit ECC for each 512Byte" can be set with * NAND_ECC_INFO(4, 512). - * @onfi_timing_mode_default: the default ONFI timing mode entered after a NAND - * reset. Should be deduced from timings described - * in the datasheet. - * */ struct nand_flash_dev { char *name; @@ -1292,7 +1284,6 @@ struct nand_flash_dev { uint16_t strength_ds; uint16_t step_ds; } ecc; - int onfi_timing_mode_default; }; int nand_create_bbt(struct nand_chip *chip); From 35b6bcc970f759d4a86d6221d09ca28ea20467c8 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 29 May 2020 13:13:22 +0200 Subject: [PATCH 064/242] mtd: rawnand: Allocate the interface configurations dynamically Instead of manipulating the statically allocated structure and copy timings around, allocate one at identification time and save it in the nand_chip structure once it has been initialized. All NAND chips using the same interface configuration during reset and startup, we define a helper to retrieve a single reset interface configuration object, shared across all NAND chips. We use a second pointer to always have a reference on the currently applied interface configuration, which may either point to the "best interface configuration" or to the "default reset interface configuration". Signed-off-by: Miquel Raynal Reviewed-by: Boris Brezillon Link: https://lore.kernel.org/linux-mtd/20200529111322.7184-29-miquel.raynal@bootlin.com --- drivers/mtd/nand/raw/internals.h | 1 + drivers/mtd/nand/raw/nand_base.c | 86 ++++++++++++++++++----------- drivers/mtd/nand/raw/nand_timings.c | 6 ++ include/linux/mtd/rawnand.h | 11 +++- 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index 5ebfbb89e572..012876e14317 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -93,6 +93,7 @@ onfi_find_closest_sdr_mode(const struct nand_sdr_timings *spec_timings); int nand_choose_best_sdr_timings(struct nand_chip *chip, struct nand_interface_config *iface, struct nand_sdr_timings *spec_timings); +const struct nand_interface_config *nand_get_reset_interface_config(void); int nand_get_features(struct nand_chip *chip, int addr, u8 *subfeature_param); int nand_set_features(struct nand_chip *chip, int addr, u8 *subfeature_param); int nand_read_page_raw_notsupp(struct nand_chip *chip, u8 *buf, diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 753328f106c1..0c768cb88f96 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -928,9 +928,9 @@ static int nand_reset_interface(struct nand_chip *chip, int chipnr) * timings to timing mode 0. */ - onfi_fill_interface_config(chip, &chip->interface_config, - NAND_SDR_IFACE, 0); - ret = ops->setup_interface(chip, chipnr, &chip->interface_config); + chip->current_interface_config = nand_get_reset_interface_config(); + ret = ops->setup_interface(chip, chipnr, + chip->current_interface_config); if (ret) pr_err("Failed to configure data interface to SDR timing mode 0\n"); @@ -949,13 +949,25 @@ static int nand_reset_interface(struct nand_chip *chip, int chipnr) */ static int nand_setup_interface(struct nand_chip *chip, int chipnr) { - u8 mode = chip->interface_config.timings.mode; - u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { mode, }; + const struct nand_controller_ops *ops = chip->controller->ops; + u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = { }; int ret; if (!nand_controller_can_setup_interface(chip)) return 0; + /* + * A nand_reset_interface() put both the NAND chip and the NAND + * controller in timings mode 0. If the default mode for this chip is + * also 0, no need to proceed to the change again. Plus, at probe time, + * nand_setup_interface() uses ->set/get_features() which would + * fail anyway as the parameter page is not available yet. + */ + if (!chip->best_interface_config) + return 0; + + tmode_param[0] = chip->best_interface_config->timings.mode; + /* Change the mode on the chip side (if supported by the NAND chip) */ if (nand_supports_set_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE)) { nand_select_target(chip, chipnr); @@ -967,14 +979,13 @@ static int nand_setup_interface(struct nand_chip *chip, int chipnr) } /* Change the mode on the controller side */ - ret = chip->controller->ops->setup_interface(chip, chipnr, - &chip->interface_config); + ret = ops->setup_interface(chip, chipnr, chip->best_interface_config); if (ret) return ret; /* Check the mode has been accepted by the chip, if supported */ if (!nand_supports_get_features(chip, ONFI_FEATURE_ADDR_TIMING_MODE)) - return 0; + goto update_interface_config; memset(tmode_param, 0, ONFI_SUBFEATURE_PARAM_LEN); nand_select_target(chip, chipnr); @@ -984,12 +995,15 @@ static int nand_setup_interface(struct nand_chip *chip, int chipnr) if (ret) goto err_reset_chip; - if (tmode_param[0] != mode) { + if (tmode_param[0] != chip->best_interface_config->timings.mode) { pr_warn("timing mode %d not acknowledged by the NAND chip\n", - mode); + chip->best_interface_config->timings.mode); goto err_reset_chip; } +update_interface_config: + chip->current_interface_config = chip->best_interface_config; + return 0; err_reset_chip: @@ -1031,8 +1045,10 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip, /* Verify the controller supports the requested interface */ ret = ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY, iface); - if (!ret) + if (!ret) { + chip->best_interface_config = iface; return ret; + } /* Fallback to slower modes */ best_mode = iface->timings.mode; @@ -1046,9 +1062,11 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip, ret = ops->setup_interface(chip, NAND_DATA_IFACE_CHECK_ONLY, iface); if (!ret) - return 0; + break; } + chip->best_interface_config = iface; + return 0; } @@ -1067,15 +1085,25 @@ int nand_choose_best_sdr_timings(struct nand_chip *chip, */ static int nand_choose_interface_config(struct nand_chip *chip) { + struct nand_interface_config *iface; + int ret; + if (!nand_controller_can_setup_interface(chip)) return 0; - if (chip->ops.choose_interface_config) - return chip->ops.choose_interface_config(chip, - &chip->interface_config); + iface = kzalloc(sizeof(*iface), GFP_KERNEL); + if (!iface) + return -ENOMEM; - return nand_choose_best_sdr_timings(chip, &chip->interface_config, - NULL); + if (chip->ops.choose_interface_config) + ret = chip->ops.choose_interface_config(chip, iface); + else + ret = nand_choose_best_sdr_timings(chip, iface, NULL); + + if (ret) + kfree(iface); + + return ret; } /** @@ -2501,7 +2529,6 @@ EXPORT_SYMBOL_GPL(nand_subop_get_data_len); */ int nand_reset(struct nand_chip *chip, int chipnr) { - struct nand_interface_config saved_intf_config = chip->interface_config; int ret; ret = nand_reset_interface(chip, chipnr); @@ -2519,18 +2546,6 @@ int nand_reset(struct nand_chip *chip, int chipnr) if (ret) return ret; - /* - * A nand_reset_interface() put both the NAND chip and the NAND - * controller in timings mode 0. If the default mode for this chip is - * also 0, no need to proceed to the change again. Plus, at probe time, - * nand_setup_interface() uses ->set/get_features() which would - * fail anyway as the parameter page is not available yet. - */ - if (!memcmp(&chip->interface_config, &saved_intf_config, - sizeof(saved_intf_config))) - return 0; - - chip->interface_config = saved_intf_config; ret = nand_setup_interface(chip, chipnr); if (ret) return ret; @@ -5198,7 +5213,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, mutex_init(&chip->lock); /* Enforce the right timings for reset/detection */ - onfi_fill_interface_config(chip, &chip->interface_config, NAND_SDR_IFACE, 0); + chip->current_interface_config = nand_get_reset_interface_config(); ret = nand_dt_init(chip); if (ret) @@ -5994,7 +6009,7 @@ static int nand_scan_tail(struct nand_chip *chip) for (i = 0; i < nanddev_ntargets(&chip->base); i++) { ret = nand_setup_interface(chip, i); if (ret) - goto err_nanddev_cleanup; + goto err_free_interface_config; } /* Check, if we should skip the bad block table scan */ @@ -6004,10 +6019,12 @@ static int nand_scan_tail(struct nand_chip *chip) /* Build bad block table */ ret = nand_create_bbt(chip); if (ret) - goto err_nanddev_cleanup; + goto err_free_interface_config; return 0; +err_free_interface_config: + kfree(chip->best_interface_config); err_nanddev_cleanup: nanddev_cleanup(&chip->base); @@ -6101,6 +6118,9 @@ void nand_cleanup(struct nand_chip *chip) & NAND_BBT_DYNAMICSTRUCT) kfree(chip->badblock_pattern); + /* Free the data interface */ + kfree(chip->best_interface_config); + /* Free manufacturer priv data. */ nand_manufacturer_cleanup(chip); diff --git a/drivers/mtd/nand/raw/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index 1e22006c79ba..94d832646487 100644 --- a/drivers/mtd/nand/raw/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c @@ -292,6 +292,12 @@ static const struct nand_interface_config onfi_sdr_timings[] = { }, }; +/* All NAND chips share the same reset data interface: SDR mode 0 */ +const struct nand_interface_config *nand_get_reset_interface_config(void) +{ + return &onfi_sdr_timings[0]; +} + /** * onfi_find_closest_sdr_mode - Derive the closest ONFI SDR timing mode given a * set of timings diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index a2427c67d38b..a725b620aca2 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1069,7 +1069,11 @@ struct nand_manufacturer { * @options: Various chip options. They can partly be set to inform nand_scan * about special functionality. See the defines for further * explanation. - * @interface_config: NAND interface timing information + * @current_interface_config: The currently used NAND interface configuration + * @best_interface_config: The best NAND interface configuration which fits both + * the NAND chip and NAND controller constraints. If + * unset, the default reset interface configuration must + * be used. * @bbt_erase_shift: Number of address bits in a bbt entry * @bbt_options: Bad block table specific options. All options used here must * come from bbm.h. By default, these options will be copied to @@ -1116,7 +1120,8 @@ struct nand_chip { unsigned int options; /* Data interface */ - struct nand_interface_config interface_config; + const struct nand_interface_config *current_interface_config; + struct nand_interface_config *best_interface_config; /* Bad block information */ unsigned int bbt_erase_shift; @@ -1209,7 +1214,7 @@ static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) static inline const struct nand_interface_config * nand_get_interface_config(struct nand_chip *chip) { - return &chip->interface_config; + return chip->current_interface_config; } /* From ccc49eff77bee2885447a032948959a134029fe3 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:13 +0200 Subject: [PATCH 065/242] mtd: rawnand: fsl_upm: Remove unused mtd var The mtd var in fun_wait_rnb() is now unused, let's get rid of it and fix the warning resulting from this unused var. Fixes: 50a487e7719c ("mtd: rawnand: Pass a nand_chip object to chip->dev_ready()") Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-2-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index 627deb26db51..76d1032cd35e 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -62,7 +62,6 @@ static int fun_chip_ready(struct nand_chip *chip) static void fun_wait_rnb(struct fsl_upm_nand *fun) { if (fun->rnb_gpio[fun->mchip_number] >= 0) { - struct mtd_info *mtd = nand_to_mtd(&fun->chip); int cnt = 1000000; while (--cnt && !fun_chip_ready(&fun->chip)) From 5290833c10b9f997de16f5bd158efcde3f96db54 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:14 +0200 Subject: [PATCH 066/242] mtd: rawnand: fsl_upm: Get rid of the unused fsl_upm_nand.parts field fsl_upm_nand.parts is unused, let's get rid of it. Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-3-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index 76d1032cd35e..6eba2f4a2f5a 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -29,7 +29,6 @@ struct fsl_upm_nand { struct device *dev; struct nand_chip chip; int last_ctrl; - struct mtd_partition *parts; struct fsl_upm upm; uint8_t upm_addr_offset; uint8_t upm_cmd_offset; From f760bf29f8676b67fda766d3cf1dbc2fe79829e6 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:15 +0200 Subject: [PATCH 067/242] mtd: rawnand: fsl_upm: Allocate the fsl_upm_nand object using devm_kzalloc() This simplifies the init error path and remove function. Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-4-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index 6eba2f4a2f5a..9cf79c62ef22 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -205,36 +205,34 @@ static int fun_probe(struct platform_device *ofdev) int size; int i; - fun = kzalloc(sizeof(*fun), GFP_KERNEL); + fun = devm_kzalloc(&ofdev->dev, sizeof(*fun), GFP_KERNEL); if (!fun) return -ENOMEM; ret = of_address_to_resource(ofdev->dev.of_node, 0, &io_res); if (ret) { dev_err(&ofdev->dev, "can't get IO base\n"); - goto err1; + return ret; } ret = fsl_upm_find(io_res.start, &fun->upm); if (ret) { dev_err(&ofdev->dev, "can't find UPM\n"); - goto err1; + return ret; } prop = of_get_property(ofdev->dev.of_node, "fsl,upm-addr-offset", &size); if (!prop || size != sizeof(uint32_t)) { dev_err(&ofdev->dev, "can't get UPM address offset\n"); - ret = -EINVAL; - goto err1; + return -EINVAL; } fun->upm_addr_offset = *prop; prop = of_get_property(ofdev->dev.of_node, "fsl,upm-cmd-offset", &size); if (!prop || size != sizeof(uint32_t)) { dev_err(&ofdev->dev, "can't get UPM command offset\n"); - ret = -EINVAL; - goto err1; + return -EINVAL; } fun->upm_cmd_offset = *prop; @@ -244,7 +242,7 @@ static int fun_probe(struct platform_device *ofdev) fun->mchip_count = size / sizeof(uint32_t); if (fun->mchip_count >= NAND_MAX_CHIPS) { dev_err(&ofdev->dev, "too much multiple chips\n"); - goto err1; + return -EINVAL; } for (i = 0; i < fun->mchip_count; i++) fun->mchip_offsets[i] = be32_to_cpu(prop[i]); @@ -306,8 +304,6 @@ err2: break; gpio_free(fun->rnb_gpio[i]); } -err1: - kfree(fun); return ret; } @@ -330,8 +326,6 @@ static int fun_remove(struct platform_device *ofdev) gpio_free(fun->rnb_gpio[i]); } - kfree(fun); - return 0; } From 0016648cdc45eea00bd585ccb4b2596784f60615 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:16 +0200 Subject: [PATCH 068/242] mtd: rawnand: fsl_upm: Use devm_kasprintf() to allocate the MTD name This simplifies the init() error path and the remove() handler. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-5-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index 9cf79c62ef22..a3e3a968891d 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -176,8 +176,9 @@ static int fun_chip_init(struct fsl_upm_nand *fun, return -ENODEV; nand_set_flash_node(&fun->chip, flash_np); - mtd->name = kasprintf(GFP_KERNEL, "0x%llx.%pOFn", (u64)io_res->start, - flash_np); + mtd->name = devm_kasprintf(fun->dev, GFP_KERNEL, "0x%llx.%pOFn", + (u64)io_res->start, + flash_np); if (!mtd->name) { ret = -ENOMEM; goto err; @@ -190,8 +191,6 @@ static int fun_chip_init(struct fsl_upm_nand *fun, ret = mtd_device_register(mtd, NULL, 0); err: of_node_put(flash_np); - if (ret) - kfree(mtd->name); return ret; } @@ -318,7 +317,6 @@ static int fun_remove(struct platform_device *ofdev) ret = mtd_device_unregister(mtd); WARN_ON(ret); nand_cleanup(chip); - kfree(mtd->name); for (i = 0; i < fun->mchip_count; i++) { if (fun->rnb_gpio[i] < 0) From 58c5a0e04dfceb1c64c84553bc909d1aa39a3bd5 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:17 +0200 Subject: [PATCH 069/242] mtd: rawnand: fsl_upm: Use platform_get_resource() + devm_ioremap_resource() Replace the of_address_to_resource() + devm_ioremap() calls by platform_get_resource() + devm_ioremap_resource() ones which allows us to get rid of one error message since devm_ioremap_resource() already takes care of that. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-6-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index a3e3a968891d..54851e9ea784 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -197,7 +196,7 @@ err: static int fun_probe(struct platform_device *ofdev) { struct fsl_upm_nand *fun; - struct resource io_res; + struct resource *io_res; const __be32 *prop; int rnb_gpio; int ret; @@ -208,13 +207,12 @@ static int fun_probe(struct platform_device *ofdev) if (!fun) return -ENOMEM; - ret = of_address_to_resource(ofdev->dev.of_node, 0, &io_res); - if (ret) { - dev_err(&ofdev->dev, "can't get IO base\n"); - return ret; - } + io_res = platform_get_resource(ofdev, IORESOURCE_MEM, 0); + fun->io_base = devm_ioremap_resource(&ofdev->dev, io_res); + if (IS_ERR(fun->io_base)) + return PTR_ERR(fun->io_base); - ret = fsl_upm_find(io_res.start, &fun->upm); + ret = fsl_upm_find(io_res->start, &fun->upm); if (ret) { dev_err(&ofdev->dev, "can't find UPM\n"); return ret; @@ -280,17 +278,10 @@ static int fun_probe(struct platform_device *ofdev) fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN | FSL_UPM_WAIT_WRITE_BYTE; - fun->io_base = devm_ioremap(&ofdev->dev, io_res.start, - resource_size(&io_res)); - if (!fun->io_base) { - ret = -ENOMEM; - goto err2; - } - fun->dev = &ofdev->dev; fun->last_ctrl = NAND_CLE; - ret = fun_chip_init(fun, ofdev->dev.of_node, &io_res); + ret = fun_chip_init(fun, ofdev->dev.of_node, io_res); if (ret) goto err2; From a50895bbdbd433173c698c4a2321b0f02ff19ba1 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:18 +0200 Subject: [PATCH 070/242] mtd: rawnand: fsl_upm: Use gpio descriptors The integer-based GPIO ids are now deprecated in favor of the GPIO desc API. The PPC platforms have already been converted to GPIOLIB, so let's use gpio descs in the NAND driver too. While at it, we use devm_gpiod_get_index_optional() so we can get rid of the manual gpio desc release done in the init error path and in the remove function. Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-7-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 44 ++++++++-------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index 54851e9ea784..977b7aad419b 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -32,7 +31,7 @@ struct fsl_upm_nand { uint8_t upm_addr_offset; uint8_t upm_cmd_offset; void __iomem *io_base; - int rnb_gpio[NAND_MAX_CHIPS]; + struct gpio_desc *rnb_gpio[NAND_MAX_CHIPS]; uint32_t mchip_offsets[NAND_MAX_CHIPS]; uint32_t mchip_count; uint32_t mchip_number; @@ -50,7 +49,7 @@ static int fun_chip_ready(struct nand_chip *chip) { struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); - if (gpio_get_value(fun->rnb_gpio[fun->mchip_number])) + if (gpiod_get_value(fun->rnb_gpio[fun->mchip_number])) return 1; dev_vdbg(fun->dev, "busy\n"); @@ -165,7 +164,7 @@ static int fun_chip_init(struct fsl_upm_nand *fun, if (fun->mchip_count > 1) fun->chip.legacy.select_chip = fun_select_chip; - if (fun->rnb_gpio[0] >= 0) + if (!fun->rnb_gpio[0]) fun->chip.legacy.dev_ready = fun_chip_ready; mtd->dev.parent = fun->dev; @@ -198,7 +197,6 @@ static int fun_probe(struct platform_device *ofdev) struct fsl_upm_nand *fun; struct resource *io_res; const __be32 *prop; - int rnb_gpio; int ret; int size; int i; @@ -248,20 +246,12 @@ static int fun_probe(struct platform_device *ofdev) } for (i = 0; i < fun->mchip_count; i++) { - fun->rnb_gpio[i] = -1; - rnb_gpio = of_get_gpio(ofdev->dev.of_node, i); - if (rnb_gpio >= 0) { - ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev)); - if (ret) { - dev_err(&ofdev->dev, - "can't request RNB gpio #%d\n", i); - goto err2; - } - gpio_direction_input(rnb_gpio); - fun->rnb_gpio[i] = rnb_gpio; - } else if (rnb_gpio == -EINVAL) { + fun->rnb_gpio[i] = devm_gpiod_get_index_optional(&ofdev->dev, + NULL, i, + GPIOD_IN); + if (IS_ERR(fun->rnb_gpio[i])) { dev_err(&ofdev->dev, "RNB gpio #%d is invalid\n", i); - goto err2; + return PTR_ERR(fun->rnb_gpio[i]); } } @@ -283,19 +273,11 @@ static int fun_probe(struct platform_device *ofdev) ret = fun_chip_init(fun, ofdev->dev.of_node, io_res); if (ret) - goto err2; + return ret; dev_set_drvdata(&ofdev->dev, fun); return 0; -err2: - for (i = 0; i < fun->mchip_count; i++) { - if (fun->rnb_gpio[i] < 0) - break; - gpio_free(fun->rnb_gpio[i]); - } - - return ret; } static int fun_remove(struct platform_device *ofdev) @@ -303,18 +285,12 @@ static int fun_remove(struct platform_device *ofdev) struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); struct nand_chip *chip = &fun->chip; struct mtd_info *mtd = nand_to_mtd(chip); - int ret, i; + int ret; ret = mtd_device_unregister(mtd); WARN_ON(ret); nand_cleanup(chip); - for (i = 0; i < fun->mchip_count; i++) { - if (fun->rnb_gpio[i] < 0) - break; - gpio_free(fun->rnb_gpio[i]); - } - return 0; } From abc846afda664b7f229f32b40bbef738c3511801 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:19 +0200 Subject: [PATCH 071/242] mtd: rawnand: fsl_upm: Inherit from nand_controller Explicitly inherit from nand_controller instead of relying on the nand_chip.legacy.dummy_controller field. Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-8-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index 977b7aad419b..9a63e36825d8 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -24,6 +24,7 @@ #define FSL_UPM_WAIT_WRITE_BUFFER 0x4 struct fsl_upm_nand { + struct nand_controller base; struct device *dev; struct nand_chip chip; int last_ctrl; @@ -167,6 +168,7 @@ static int fun_chip_init(struct fsl_upm_nand *fun, if (!fun->rnb_gpio[0]) fun->chip.legacy.dev_ready = fun_chip_ready; + fun->chip.controller = &fun->base; mtd->dev.parent = fun->dev; flash_np = of_get_next_child(upm_np, NULL); @@ -268,6 +270,7 @@ static int fun_probe(struct platform_device *ofdev) fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN | FSL_UPM_WAIT_WRITE_BYTE; + nand_controller_init(&fun->base); fun->dev = &ofdev->dev; fun->last_ctrl = NAND_CLE; From 54309d65776755bcdb9dcf3744cd764fc1e254ea Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:20 +0200 Subject: [PATCH 072/242] mtd: rawnand: fsl_upm: Implement exec_op() Implement exec_op() so we can get rid of the legacy interface implementation. Signed-off-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-9-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 86 ++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index 9a63e36825d8..03ca20930274 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -194,6 +194,91 @@ err: return ret; } +static int func_exec_instr(struct nand_chip *chip, + const struct nand_op_instr *instr) +{ + struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); + u32 mar, reg_offs = fun->mchip_offsets[fun->mchip_number]; + unsigned int i; + const u8 *out; + u8 *in; + + switch (instr->type) { + case NAND_OP_CMD_INSTR: + fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); + mar = (instr->ctx.cmd.opcode << (32 - fun->upm.width)) | + reg_offs; + fsl_upm_run_pattern(&fun->upm, fun->io_base + reg_offs, mar); + fsl_upm_end_pattern(&fun->upm); + return 0; + + case NAND_OP_ADDR_INSTR: + fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); + for (i = 0; i < instr->ctx.addr.naddrs; i++) { + mar = (instr->ctx.addr.addrs[i] << (32 - fun->upm.width)) | + reg_offs; + fsl_upm_run_pattern(&fun->upm, fun->io_base + reg_offs, mar); + } + fsl_upm_end_pattern(&fun->upm); + return 0; + + case NAND_OP_DATA_IN_INSTR: + in = instr->ctx.data.buf.in; + for (i = 0; i < instr->ctx.data.len; i++) + in[i] = in_8(fun->io_base + reg_offs); + return 0; + + case NAND_OP_DATA_OUT_INSTR: + out = instr->ctx.data.buf.out; + for (i = 0; i < instr->ctx.data.len; i++) + out_8(fun->io_base + reg_offs, out[i]); + return 0; + + case NAND_OP_WAITRDY_INSTR: + if (!fun->rnb_gpio[fun->mchip_number]) + return nand_soft_waitrdy(chip, instr->ctx.waitrdy.timeout_ms); + + return nand_gpio_waitrdy(chip, fun->rnb_gpio[fun->mchip_number], + instr->ctx.waitrdy.timeout_ms); + + default: + return -EINVAL; + } + + return 0; +} + +static int fun_exec_op(struct nand_chip *chip, const struct nand_operation *op, + bool check_only) +{ + struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); + unsigned int i; + int ret; + + if (op->cs > NAND_MAX_CHIPS) + return -EINVAL; + + if (check_only) + return 0; + + fun->mchip_number = op->cs; + + for (i = 0; i < op->ninstrs; i++) { + ret = func_exec_instr(chip, &op->instrs[i]); + if (ret) + return ret; + + if (op->instrs[i].delay_ns) + ndelay(op->instrs[i].delay_ns); + } + + return 0; +} + +static const struct nand_controller_ops fun_ops = { + .exec_op = fun_exec_op, +}; + static int fun_probe(struct platform_device *ofdev) { struct fsl_upm_nand *fun; @@ -271,6 +356,7 @@ static int fun_probe(struct platform_device *ofdev) FSL_UPM_WAIT_WRITE_BYTE; nand_controller_init(&fun->base); + fun->base.ops = &fun_ops; fun->dev = &ofdev->dev; fun->last_ctrl = NAND_CLE; From 8fac41ebe2895fccf4bc40347f1638fe845d4936 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:21 +0200 Subject: [PATCH 073/242] mtd: rawnand: fsl_upm: Get rid of the legacy interface implementation Now that the driver implements exec_op(), we can get rid of the legacy interface implementation. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-10-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/fsl_upm.c | 133 --------------------------------- 1 file changed, 133 deletions(-) diff --git a/drivers/mtd/nand/raw/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index 03ca20930274..197850aeb261 100644 --- a/drivers/mtd/nand/raw/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c @@ -19,15 +19,10 @@ #include #include -#define FSL_UPM_WAIT_RUN_PATTERN 0x1 -#define FSL_UPM_WAIT_WRITE_BYTE 0x2 -#define FSL_UPM_WAIT_WRITE_BUFFER 0x4 - struct fsl_upm_nand { struct nand_controller base; struct device *dev; struct nand_chip chip; - int last_ctrl; struct fsl_upm upm; uint8_t upm_addr_offset; uint8_t upm_cmd_offset; @@ -36,8 +31,6 @@ struct fsl_upm_nand { uint32_t mchip_offsets[NAND_MAX_CHIPS]; uint32_t mchip_count; uint32_t mchip_number; - int chip_delay; - uint32_t wait_flags; }; static inline struct fsl_upm_nand *to_fsl_upm_nand(struct mtd_info *mtdinfo) @@ -46,105 +39,6 @@ static inline struct fsl_upm_nand *to_fsl_upm_nand(struct mtd_info *mtdinfo) chip); } -static int fun_chip_ready(struct nand_chip *chip) -{ - struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); - - if (gpiod_get_value(fun->rnb_gpio[fun->mchip_number])) - return 1; - - dev_vdbg(fun->dev, "busy\n"); - return 0; -} - -static void fun_wait_rnb(struct fsl_upm_nand *fun) -{ - if (fun->rnb_gpio[fun->mchip_number] >= 0) { - int cnt = 1000000; - - while (--cnt && !fun_chip_ready(&fun->chip)) - cpu_relax(); - if (!cnt) - dev_err(fun->dev, "tired waiting for RNB\n"); - } else { - ndelay(100); - } -} - -static void fun_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl) -{ - struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); - u32 mar; - - if (!(ctrl & fun->last_ctrl)) { - fsl_upm_end_pattern(&fun->upm); - - if (cmd == NAND_CMD_NONE) - return; - - fun->last_ctrl = ctrl & (NAND_ALE | NAND_CLE); - } - - if (ctrl & NAND_CTRL_CHANGE) { - if (ctrl & NAND_ALE) - fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); - else if (ctrl & NAND_CLE) - fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); - } - - mar = (cmd << (32 - fun->upm.width)) | - fun->mchip_offsets[fun->mchip_number]; - fsl_upm_run_pattern(&fun->upm, chip->legacy.IO_ADDR_R, mar); - - if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN) - fun_wait_rnb(fun); -} - -static void fun_select_chip(struct nand_chip *chip, int mchip_nr) -{ - struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); - - if (mchip_nr == -1) { - chip->legacy.cmd_ctrl(chip, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); - } else if (mchip_nr >= 0 && mchip_nr < NAND_MAX_CHIPS) { - fun->mchip_number = mchip_nr; - chip->legacy.IO_ADDR_R = fun->io_base + fun->mchip_offsets[mchip_nr]; - chip->legacy.IO_ADDR_W = chip->legacy.IO_ADDR_R; - } else { - BUG(); - } -} - -static uint8_t fun_read_byte(struct nand_chip *chip) -{ - struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); - - return in_8(fun->chip.legacy.IO_ADDR_R); -} - -static void fun_read_buf(struct nand_chip *chip, uint8_t *buf, int len) -{ - struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); - int i; - - for (i = 0; i < len; i++) - buf[i] = in_8(fun->chip.legacy.IO_ADDR_R); -} - -static void fun_write_buf(struct nand_chip *chip, const uint8_t *buf, int len) -{ - struct fsl_upm_nand *fun = to_fsl_upm_nand(nand_to_mtd(chip)); - int i; - - for (i = 0; i < len; i++) { - out_8(fun->chip.legacy.IO_ADDR_W, buf[i]); - if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE) - fun_wait_rnb(fun); - } - if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER) - fun_wait_rnb(fun); -} - static int fun_chip_init(struct fsl_upm_nand *fun, const struct device_node *upm_np, const struct resource *io_res) @@ -153,21 +47,8 @@ static int fun_chip_init(struct fsl_upm_nand *fun, int ret; struct device_node *flash_np; - fun->chip.legacy.IO_ADDR_R = fun->io_base; - fun->chip.legacy.IO_ADDR_W = fun->io_base; - fun->chip.legacy.cmd_ctrl = fun_cmd_ctrl; - fun->chip.legacy.chip_delay = fun->chip_delay; - fun->chip.legacy.read_byte = fun_read_byte; - fun->chip.legacy.read_buf = fun_read_buf; - fun->chip.legacy.write_buf = fun_write_buf; fun->chip.ecc.mode = NAND_ECC_SOFT; fun->chip.ecc.algo = NAND_ECC_HAMMING; - if (fun->mchip_count > 1) - fun->chip.legacy.select_chip = fun_select_chip; - - if (!fun->rnb_gpio[0]) - fun->chip.legacy.dev_ready = fun_chip_ready; - fun->chip.controller = &fun->base; mtd->dev.parent = fun->dev; @@ -342,23 +223,9 @@ static int fun_probe(struct platform_device *ofdev) } } - prop = of_get_property(ofdev->dev.of_node, "chip-delay", NULL); - if (prop) - fun->chip_delay = be32_to_cpup(prop); - else - fun->chip_delay = 50; - - prop = of_get_property(ofdev->dev.of_node, "fsl,upm-wait-flags", &size); - if (prop && size == sizeof(uint32_t)) - fun->wait_flags = be32_to_cpup(prop); - else - fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN | - FSL_UPM_WAIT_WRITE_BYTE; - nand_controller_init(&fun->base); fun->base.ops = &fun_ops; fun->dev = &ofdev->dev; - fun->last_ctrl = NAND_CLE; ret = fun_chip_init(fun, ofdev->dev.of_node, io_res); if (ret) From b4c719685491983628155c5c8b677332709c4c6f Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 17:07:44 +0200 Subject: [PATCH 074/242] mtd: rawnand: gpio: Inherit from nand_controller Inherit from nand_controller so we don't rely on the nand_chip.legacy.dummy_controller field. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603150746.1423257-2-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/gpio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/nand/raw/gpio.c b/drivers/mtd/nand/raw/gpio.c index 938077e5c6a9..33828fb20a13 100644 --- a/drivers/mtd/nand/raw/gpio.c +++ b/drivers/mtd/nand/raw/gpio.c @@ -27,6 +27,7 @@ #include struct gpiomtd { + struct nand_controller base; void __iomem *io_sync; struct nand_chip nand_chip; struct gpio_nand_platdata plat; @@ -273,6 +274,7 @@ static int gpio_nand_probe(struct platform_device *pdev) if (gpiomtd->rdy) chip->legacy.dev_ready = gpio_nand_devready; + nand_controller_init(&gpiomtd->base); nand_set_flash_node(chip, pdev->dev.of_node); chip->legacy.IO_ADDR_W = chip->legacy.IO_ADDR_R; chip->ecc.mode = NAND_ECC_SOFT; @@ -280,6 +282,7 @@ static int gpio_nand_probe(struct platform_device *pdev) chip->options = gpiomtd->plat.options; chip->legacy.chip_delay = gpiomtd->plat.chip_delay; chip->legacy.cmd_ctrl = gpio_nand_cmd_ctrl; + chip->controller = &gpiomtd->base; mtd = nand_to_mtd(chip); mtd->dev.parent = dev; From 22b27a675d714499848d4f389082eb0d959a7b34 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 17:07:45 +0200 Subject: [PATCH 075/242] mtd: rawnand: gpio: Implement exec_op() Implement exec_op() so we can get rid of the legacy interface implementation. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603150746.1423257-3-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/gpio.c | 104 ++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/gpio.c b/drivers/mtd/nand/raw/gpio.c index 33828fb20a13..115998011192 100644 --- a/drivers/mtd/nand/raw/gpio.c +++ b/drivers/mtd/nand/raw/gpio.c @@ -25,9 +25,11 @@ #include #include #include +#include struct gpiomtd { struct nand_controller base; + void __iomem *io; void __iomem *io_sync; struct nand_chip nand_chip; struct gpio_nand_platdata plat; @@ -98,6 +100,99 @@ static int gpio_nand_devready(struct nand_chip *chip) return gpiod_get_value(gpiomtd->rdy); } +static int gpio_nand_exec_instr(struct nand_chip *chip, + const struct nand_op_instr *instr) +{ + struct gpiomtd *gpiomtd = gpio_nand_getpriv(nand_to_mtd(chip)); + unsigned int i; + + switch (instr->type) { + case NAND_OP_CMD_INSTR: + gpio_nand_dosync(gpiomtd); + gpiod_set_value(gpiomtd->cle, 1); + gpio_nand_dosync(gpiomtd); + writeb(instr->ctx.cmd.opcode, gpiomtd->io); + gpio_nand_dosync(gpiomtd); + gpiod_set_value(gpiomtd->cle, 0); + return 0; + + case NAND_OP_ADDR_INSTR: + gpio_nand_dosync(gpiomtd); + gpiod_set_value(gpiomtd->ale, 1); + gpio_nand_dosync(gpiomtd); + for (i = 0; i < instr->ctx.addr.naddrs; i++) + writeb(instr->ctx.addr.addrs[i], gpiomtd->io); + gpio_nand_dosync(gpiomtd); + gpiod_set_value(gpiomtd->ale, 0); + return 0; + + case NAND_OP_DATA_IN_INSTR: + gpio_nand_dosync(gpiomtd); + if ((chip->options & NAND_BUSWIDTH_16) && + !instr->ctx.data.force_8bit) + ioread16_rep(gpiomtd->io, instr->ctx.data.buf.in, + instr->ctx.data.len / 2); + else + ioread8_rep(gpiomtd->io, instr->ctx.data.buf.in, + instr->ctx.data.len); + return 0; + + case NAND_OP_DATA_OUT_INSTR: + gpio_nand_dosync(gpiomtd); + if ((chip->options & NAND_BUSWIDTH_16) && + !instr->ctx.data.force_8bit) + iowrite16_rep(gpiomtd->io, instr->ctx.data.buf.out, + instr->ctx.data.len / 2); + else + iowrite8_rep(gpiomtd->io, instr->ctx.data.buf.out, + instr->ctx.data.len); + return 0; + + case NAND_OP_WAITRDY_INSTR: + if (!gpiomtd->rdy) + return nand_soft_waitrdy(chip, instr->ctx.waitrdy.timeout_ms); + + return nand_gpio_waitrdy(chip, gpiomtd->rdy, + instr->ctx.waitrdy.timeout_ms); + + default: + return -EINVAL; + } + + return 0; +} + +static int gpio_nand_exec_op(struct nand_chip *chip, + const struct nand_operation *op, + bool check_only) +{ + struct gpiomtd *gpiomtd = gpio_nand_getpriv(nand_to_mtd(chip)); + unsigned int i; + int ret = 0; + + if (check_only) + return 0; + + gpio_nand_dosync(gpiomtd); + gpiod_set_value(gpiomtd->nce, 0); + for (i = 0; i < op->ninstrs; i++) { + ret = gpio_nand_exec_instr(chip, &op->instrs[i]); + if (ret) + break; + + if (op->instrs[i].delay_ns) + ndelay(op->instrs[i].delay_ns); + } + gpio_nand_dosync(gpiomtd); + gpiod_set_value(gpiomtd->nce, 1); + + return ret; +} + +static const struct nand_controller_ops gpio_nand_ops = { + .exec_op = gpio_nand_exec_op, +}; + #ifdef CONFIG_OF static const struct of_device_id gpio_nand_id_table[] = { { .compatible = "gpio-control-nand" }, @@ -226,9 +321,9 @@ static int gpio_nand_probe(struct platform_device *pdev) chip = &gpiomtd->nand_chip; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - chip->legacy.IO_ADDR_R = devm_ioremap_resource(dev, res); - if (IS_ERR(chip->legacy.IO_ADDR_R)) - return PTR_ERR(chip->legacy.IO_ADDR_R); + gpiomtd->io = devm_ioremap_resource(dev, res); + if (IS_ERR(gpiomtd->io)) + return PTR_ERR(gpiomtd->io); res = gpio_nand_get_io_sync(pdev); if (res) { @@ -275,7 +370,10 @@ static int gpio_nand_probe(struct platform_device *pdev) chip->legacy.dev_ready = gpio_nand_devready; nand_controller_init(&gpiomtd->base); + gpiomtd->base.ops = &gpio_nand_ops; + nand_set_flash_node(chip, pdev->dev.of_node); + chip->legacy.IO_ADDR_R = gpiomtd->io; chip->legacy.IO_ADDR_W = chip->legacy.IO_ADDR_R; chip->ecc.mode = NAND_ECC_SOFT; chip->ecc.algo = NAND_ECC_HAMMING; From df66c27101ff279dc2e8cc2ced7191029495f194 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 17:07:46 +0200 Subject: [PATCH 076/242] mtd: rawnand: gpio: Get rid of the legacy interface implementation Now that exec_op() is implemented, we can get rid of the legacy interface implementation. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603150746.1423257-4-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/gpio.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/drivers/mtd/nand/raw/gpio.c b/drivers/mtd/nand/raw/gpio.c index 115998011192..3bd847ccc3f3 100644 --- a/drivers/mtd/nand/raw/gpio.c +++ b/drivers/mtd/nand/raw/gpio.c @@ -72,34 +72,6 @@ static void gpio_nand_dosync(struct gpiomtd *gpiomtd) static inline void gpio_nand_dosync(struct gpiomtd *gpiomtd) {} #endif -static void gpio_nand_cmd_ctrl(struct nand_chip *chip, int cmd, - unsigned int ctrl) -{ - struct gpiomtd *gpiomtd = gpio_nand_getpriv(nand_to_mtd(chip)); - - gpio_nand_dosync(gpiomtd); - - if (ctrl & NAND_CTRL_CHANGE) { - if (gpiomtd->nce) - gpiod_set_value(gpiomtd->nce, !(ctrl & NAND_NCE)); - gpiod_set_value(gpiomtd->cle, !!(ctrl & NAND_CLE)); - gpiod_set_value(gpiomtd->ale, !!(ctrl & NAND_ALE)); - gpio_nand_dosync(gpiomtd); - } - if (cmd == NAND_CMD_NONE) - return; - - writeb(cmd, gpiomtd->nand_chip.legacy.IO_ADDR_W); - gpio_nand_dosync(gpiomtd); -} - -static int gpio_nand_devready(struct nand_chip *chip) -{ - struct gpiomtd *gpiomtd = gpio_nand_getpriv(nand_to_mtd(chip)); - - return gpiod_get_value(gpiomtd->rdy); -} - static int gpio_nand_exec_instr(struct nand_chip *chip, const struct nand_op_instr *instr) { @@ -365,21 +337,14 @@ static int gpio_nand_probe(struct platform_device *pdev) ret = PTR_ERR(gpiomtd->rdy); goto out_ce; } - /* Using RDY pin */ - if (gpiomtd->rdy) - chip->legacy.dev_ready = gpio_nand_devready; nand_controller_init(&gpiomtd->base); gpiomtd->base.ops = &gpio_nand_ops; nand_set_flash_node(chip, pdev->dev.of_node); - chip->legacy.IO_ADDR_R = gpiomtd->io; - chip->legacy.IO_ADDR_W = chip->legacy.IO_ADDR_R; chip->ecc.mode = NAND_ECC_SOFT; chip->ecc.algo = NAND_ECC_HAMMING; chip->options = gpiomtd->plat.options; - chip->legacy.chip_delay = gpiomtd->plat.chip_delay; - chip->legacy.cmd_ctrl = gpio_nand_cmd_ctrl; chip->controller = &gpiomtd->base; mtd = nand_to_mtd(chip); From 735bf220b11fe003d4236d430db0c7131babf468 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 9 Jun 2020 13:45:57 +0100 Subject: [PATCH 077/242] mtd: rawnand: trivial spelling The word 'descriptor' is misspelled throughout the tree. Fix it up accordingly: decriptors -> descriptors Signed-off-by: Kieran Bingham Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200609124610.3445662-5-kieran.bingham+renesas@ideasonboard.com --- drivers/mtd/nand/raw/mxc_nand.c | 2 +- drivers/mtd/nand/raw/nand_bbt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/mxc_nand.c b/drivers/mtd/nand/raw/mxc_nand.c index 07c41e8bae2d..a043d76b48cb 100644 --- a/drivers/mtd/nand/raw/mxc_nand.c +++ b/drivers/mtd/nand/raw/mxc_nand.c @@ -1432,7 +1432,7 @@ static int mxc_nand_get_features(struct nand_chip *chip, int addr, } /* - * The generic flash bbt decriptors overlap with our ecc + * The generic flash bbt descriptors overlap with our ecc * hardware, so define some i.MX specific ones. */ static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' }; diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index 96045d60471e..344a24fd2ca8 100644 --- a/drivers/mtd/nand/raw/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c @@ -1226,7 +1226,7 @@ static int nand_scan_bbt(struct nand_chip *this, struct nand_bbt_descr *bd) return -ENOMEM; /* - * If no primary table decriptor is given, scan the device to build a + * If no primary table descriptor is given, scan the device to build a * memory based bad block table. */ if (!td) { From 443440cc4a901af462239d286cd10721aa1c7dfc Mon Sep 17 00:00:00 2001 From: Sivaprakash Murugesan Date: Fri, 12 Jun 2020 13:28:15 +0530 Subject: [PATCH 078/242] mtd: rawnand: qcom: avoid write to unavailable register SFLASHC_BURST_CFG is only available on older ipq NAND platforms, this register has been removed when the NAND controller got implemented in the qpic controller. Avoid writing this register on devices which are based on qpic NAND controller. Fixes: dce84760b09f ("mtd: nand: qcom: Support for IPQ8074 QPIC NAND controller") Cc: stable@vger.kernel.org Signed-off-by: Sivaprakash Murugesan Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/1591948696-16015-2-git-send-email-sivaprak@codeaurora.org --- drivers/mtd/nand/raw/qcom_nandc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index f1daf330951b..78b5f211598c 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -459,11 +459,13 @@ struct qcom_nand_host { * among different NAND controllers. * @ecc_modes - ecc mode for NAND * @is_bam - whether NAND controller is using BAM + * @is_qpic - whether NAND CTRL is part of qpic IP * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset */ struct qcom_nandc_props { u32 ecc_modes; bool is_bam; + bool is_qpic; u32 dev_cmd_reg_start; }; @@ -2774,7 +2776,8 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc) u32 nand_ctrl; /* kill onenand */ - nandc_write(nandc, SFLASHC_BURST_CFG, 0); + if (!nandc->props->is_qpic) + nandc_write(nandc, SFLASHC_BURST_CFG, 0); nandc_write(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD), NAND_DEV_CMD_VLD_VAL); @@ -3035,12 +3038,14 @@ static const struct qcom_nandc_props ipq806x_nandc_props = { static const struct qcom_nandc_props ipq4019_nandc_props = { .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT), .is_bam = true, + .is_qpic = true, .dev_cmd_reg_start = 0x0, }; static const struct qcom_nandc_props ipq8074_nandc_props = { .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT), .is_bam = true, + .is_qpic = true, .dev_cmd_reg_start = 0x7000, }; From cb272395dceef1652247dad08a50ed4153ffbd43 Mon Sep 17 00:00:00 2001 From: Sivaprakash Murugesan Date: Fri, 12 Jun 2020 13:28:16 +0530 Subject: [PATCH 079/242] mtd: rawnand: qcom: set BAM mode only if not set already BAM is DMA controller on QCOM ipq platforms, BAM mode on NAND driver is set by writing BAM_MODE_EN bit on NAND_CTRL register. NAND_CTRL is an operational register and in BAM mode operational registers are read only. So, before enabling BAM mode by writing the NAND_CTRL register, check if BAM mode was already enabled by the bootloader, and enable BAM mode only if it is not enabled already. Signed-off-by: Sivaprakash Murugesan Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/1591948696-16015-3-git-send-email-sivaprak@codeaurora.org --- drivers/mtd/nand/raw/qcom_nandc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 78b5f211598c..bd7a7251429b 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -2784,7 +2784,16 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc) /* enable ADM or BAM DMA */ if (nandc->props->is_bam) { nand_ctrl = nandc_read(nandc, NAND_CTRL); - nandc_write(nandc, NAND_CTRL, nand_ctrl | BAM_MODE_EN); + + /* + *NAND_CTRL is an operational registers, and CPU + * access to operational registers are read only + * in BAM mode. So update the NAND_CTRL register + * only if it is not in BAM mode. In most cases BAM + * mode will be enabled in bootloader + */ + if (!(nand_ctrl & BAM_MODE_EN)) + nandc_write(nandc, NAND_CTRL, nand_ctrl | BAM_MODE_EN); } else { nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN); } From bee3ab8bdd3b13faf08e5b6e0218f59b0a49fcc3 Mon Sep 17 00:00:00 2001 From: Kamal Dasu Date: Fri, 12 Jun 2020 17:29:01 -0400 Subject: [PATCH 080/242] mtd: rawnand: brcmnand: Don't default to edu transfer When flash-dma is absent do not default to using flash-edu. Make sure flash-edu is enabled before setting EDU transfer function. Fixes: a5d53ad26a8b ("mtd: rawnand: brcmnand: Add support for flash-edu for dma transfers") Signed-off-by: Kamal Dasu Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200612212902.21347-2-kdasu.kdev@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 44068e9eea03..ac934a715a19 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -3023,8 +3023,9 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (ret < 0) goto err; - /* set edu transfer function to call */ - ctrl->dma_trans = brcmnand_edu_trans; + if (has_edu(ctrl)) + /* set edu transfer function to call */ + ctrl->dma_trans = brcmnand_edu_trans; } /* Disable automatic device ID config, direct addressing */ From 4551e78ad98add1f16b70cf286d5aad3ce7bcd4c Mon Sep 17 00:00:00 2001 From: Kamal Dasu Date: Fri, 12 Jun 2020 17:29:02 -0400 Subject: [PATCH 081/242] mtd: rawnand: brcmnand: ECC error handling on EDU transfers Implement ECC correctable and uncorrectable error handling for EDU reads. If ECC correctable bitflips are encountered on EDU transfer, read page again using PIO. This is needed due to a NAND controller limitation where corrected data is not transferred to the DMA buffer on ECC error. This applies to ECC correctable errors that are reported by the controller hardware based on set number of bitflips threshold in the controller threshold register, bitflips below the threshold are corrected silently and are not reported by the controller hardware. Fixes: a5d53ad26a8b ("mtd: rawnand: brcmnand: Add support for flash-edu for dma transfers") Signed-off-by: Kamal Dasu Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200612212902.21347-3-kdasu.kdev@gmail.com --- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index ac934a715a19..a4033d32a710 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -1918,6 +1918,22 @@ static int brcmnand_edu_trans(struct brcmnand_host *host, u64 addr, u32 *buf, edu_writel(ctrl, EDU_STOP, 0); /* force stop */ edu_readl(ctrl, EDU_STOP); + if (!ret && edu_cmd == EDU_CMD_READ) { + u64 err_addr = 0; + + /* + * check for ECC errors here, subpage ECC errors are + * retained in ECC error address register + */ + err_addr = brcmnand_get_uncorrecc_addr(ctrl); + if (!err_addr) { + err_addr = brcmnand_get_correcc_addr(ctrl); + if (err_addr) + ret = -EUCLEAN; + } else + ret = -EBADMSG; + } + return ret; } @@ -2124,6 +2140,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, u64 err_addr = 0; int err; bool retry = true; + bool edu_err = false; dev_dbg(ctrl->dev, "read %llx -> %p\n", (unsigned long long)addr, buf); @@ -2141,6 +2158,10 @@ try_dmaread: else return -EIO; } + + if (has_edu(ctrl) && err_addr) + edu_err = true; + } else { if (oob) memset(oob, 0x99, mtd->oobsize); @@ -2188,6 +2209,11 @@ try_dmaread: if (mtd_is_bitflip(err)) { unsigned int corrected = brcmnand_count_corrected(ctrl); + /* in case of EDU correctable error we read again using PIO */ + if (edu_err) + err = brcmnand_read_by_pio(mtd, chip, addr, trans, buf, + oob, &err_addr); + dev_dbg(ctrl->dev, "corrected error at 0x%llx\n", (unsigned long long)err_addr); mtd->ecc_stats.corrected += corrected; From 91e81150d38842b58133ce1a5d70c88e8f1cf7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Mon, 15 Jun 2020 11:17:40 +0200 Subject: [PATCH 082/242] mtd: parsers: bcm63xx: simplify CFE detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of trying to parse CFE version string, which is customized by some vendors, let's just check that "CFE1" was passed on argument 3. Signed-off-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski Reviewed-by: Florian Fainelli Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200615091740.2958303-1-noltari@gmail.com --- drivers/mtd/parsers/bcm63xxpart.c | 32 ++++++++++++------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/drivers/mtd/parsers/bcm63xxpart.c b/drivers/mtd/parsers/bcm63xxpart.c index 78f90c6c18fd..b15bdadaedb5 100644 --- a/drivers/mtd/parsers/bcm63xxpart.c +++ b/drivers/mtd/parsers/bcm63xxpart.c @@ -22,6 +22,11 @@ #include #include +#ifdef CONFIG_MIPS +#include +#include +#endif /* CONFIG_MIPS */ + #define BCM963XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ #define BCM963XX_CFE_MAGIC_OFFSET 0x4e0 @@ -32,28 +37,15 @@ #define STR_NULL_TERMINATE(x) \ do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0) -static int bcm63xx_detect_cfe(struct mtd_info *master) +static inline int bcm63xx_detect_cfe(void) { - char buf[9]; - int ret; - size_t retlen; + int ret = 0; - ret = mtd_read(master, BCM963XX_CFE_VERSION_OFFSET, 5, &retlen, - (void *)buf); - buf[retlen] = 0; +#ifdef CONFIG_MIPS + ret = (fw_arg3 == CFE_EPTSEAL); +#endif /* CONFIG_MIPS */ - if (ret) - return ret; - - if (strncmp("cfe-v", buf, 5) == 0) - return 0; - - /* very old CFE's do not have the cfe-v string, so check for magic */ - ret = mtd_read(master, BCM963XX_CFE_MAGIC_OFFSET, 8, &retlen, - (void *)buf); - buf[retlen] = 0; - - return strncmp("CFE1CFE1", buf, 8); + return ret; } static int bcm63xx_read_nvram(struct mtd_info *master, @@ -138,7 +130,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, struct bcm963xx_nvram *nvram = NULL; int ret; - if (bcm63xx_detect_cfe(master)) + if (!bcm63xx_detect_cfe()) return -EINVAL; nvram = vzalloc(sizeof(*nvram)); From fef95b7211deb80c19ebfcdd5208ec7b80b40cbf Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 15 Jun 2020 18:57:48 +0300 Subject: [PATCH 083/242] mtd: spi-nor: intel-spi: Add support for Intel Emmitsburg SPI serial flash Intel Emmitsburg has the same SPI serial flash controller as Lewisburg. Add Emmitsburg PCI ID to the driver list of supported devices. Signed-off-by: Mika Westerberg Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200615155748.920-1-mika.westerberg@linux.intel.com --- drivers/mtd/spi-nor/controllers/intel-spi-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c index 81329f680bec..c19f1035cc02 100644 --- a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c +++ b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c @@ -68,6 +68,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x1bca), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info }, From a0eec15673222ef52655fc6a5da0008c501aebdc Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 24 Jun 2020 22:21:03 +0300 Subject: [PATCH 084/242] mtd: spi-nor: intel-spi: Add support for Intel Tiger Lake-H SPI serial flash Intel Tiger Lake-H has the same SPI serial flash controller as Cannon Lake. Add Tiger Lake-H PCI ID to the driver list of supported devices. Signed-off-by: Mika Westerberg Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200624192103.78770-1-mika.westerberg@linux.intel.com --- drivers/mtd/spi-nor/controllers/intel-spi-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c index c19f1035cc02..c72aa1ab71ad 100644 --- a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c +++ b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c @@ -70,6 +70,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x1bca), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x43a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x4b24), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0xa0a4), (unsigned long)&bxt_info }, From 169efc3bf4dde79a8e15d71f45f1150bec46b663 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 4 Jun 2020 12:28:07 +0300 Subject: [PATCH 085/242] =?UTF-8?q?pinctrl:=20merrifield:=20Add=20I=C2=B2S?= =?UTF-8?q?=20bus=202=20pins=20to=20groups=20and=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is useful to control I²S bus 2 pins if we would like to connect an audio codec. Reported-by: mouse Reported-by: Pierre-Louis Bossart Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-merrifield.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 2c213714df30..e4ff8da1b894 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -340,6 +340,7 @@ static const struct pinctrl_pin_desc mrfld_pins[] = { }; static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 }; +static const unsigned int mrfld_i2s2_pins[] = { 75, 76, 77, 78 }; static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 }; static const unsigned int mrfld_uart0_pins[] = { 115, 116, 117, 118 }; static const unsigned int mrfld_uart1_pins[] = { 119, 120, 121, 122 }; @@ -351,6 +352,7 @@ static const unsigned int mrfld_pwm3_pins[] = { 133 }; static const struct intel_pingroup mrfld_groups[] = { PIN_GROUP("sdio_grp", mrfld_sdio_pins, 1), + PIN_GROUP("i2s2_grp", mrfld_i2s2_pins, 1), PIN_GROUP("spi5_grp", mrfld_spi5_pins, 1), PIN_GROUP("uart0_grp", mrfld_uart0_pins, 1), PIN_GROUP("uart1_grp", mrfld_uart1_pins, 1), @@ -362,6 +364,7 @@ static const struct intel_pingroup mrfld_groups[] = { }; static const char * const mrfld_sdio_groups[] = { "sdio_grp" }; +static const char * const mrfld_i2s2_groups[] = { "i2s2_grp" }; static const char * const mrfld_spi5_groups[] = { "spi5_grp" }; static const char * const mrfld_uart0_groups[] = { "uart0_grp" }; static const char * const mrfld_uart1_groups[] = { "uart1_grp" }; @@ -373,6 +376,7 @@ static const char * const mrfld_pwm3_groups[] = { "pwm3_grp" }; static const struct intel_function mrfld_functions[] = { FUNCTION("sdio", mrfld_sdio_groups), + FUNCTION("i2s2", mrfld_i2s2_groups), FUNCTION("spi5", mrfld_spi5_groups), FUNCTION("uart0", mrfld_uart0_groups), FUNCTION("uart1", mrfld_uart1_groups), From 653d96455e1e30811f4b9ec44d3b9df9bd7a55a3 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 25 Jun 2020 16:20:53 +0300 Subject: [PATCH 086/242] pinctrl: tigerlake: Add support for Tiger Lake-H Intel Tiger Lake-H has different pin layout than the -LP variant so add support for this to the existing Tiger Lake driver. Signed-off-by: Mika Westerberg Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-tigerlake.c | 358 ++++++++++++++++++++++ 1 file changed, 358 insertions(+) diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c index bcfd7548e282..8c162dd5f5a1 100644 --- a/drivers/pinctrl/intel/pinctrl-tigerlake.c +++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c @@ -380,8 +380,366 @@ static const struct intel_pinctrl_soc_data tgllp_soc_data = { .ncommunities = ARRAY_SIZE(tgllp_communities), }; +/* Tiger Lake-H */ +static const struct pinctrl_pin_desc tglh_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "SPI0_IO_2"), + PINCTRL_PIN(1, "SPI0_IO_3"), + PINCTRL_PIN(2, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(3, "SPI0_MISO_IO_1"), + PINCTRL_PIN(4, "SPI0_TPM_CSB"), + PINCTRL_PIN(5, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(6, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(7, "SPI0_CLK"), + PINCTRL_PIN(8, "ESPI_IO_0"), + PINCTRL_PIN(9, "ESPI_IO_1"), + PINCTRL_PIN(10, "ESPI_IO_2"), + PINCTRL_PIN(11, "ESPI_IO_3"), + PINCTRL_PIN(12, "ESPI_CS0B"), + PINCTRL_PIN(13, "ESPI_CLK"), + PINCTRL_PIN(14, "ESPI_RESETB"), + PINCTRL_PIN(15, "ESPI_CS1B"), + PINCTRL_PIN(16, "ESPI_CS2B"), + PINCTRL_PIN(17, "ESPI_CS3B"), + PINCTRL_PIN(18, "ESPI_ALERT0B"), + PINCTRL_PIN(19, "ESPI_ALERT1B"), + PINCTRL_PIN(20, "ESPI_ALERT2B"), + PINCTRL_PIN(21, "ESPI_ALERT3B"), + PINCTRL_PIN(22, "GPPC_A_14"), + PINCTRL_PIN(23, "SPI0_CLK_LOOPBK"), + PINCTRL_PIN(24, "ESPI_CLK_LOOPBK"), + /* GPP_R */ + PINCTRL_PIN(25, "HDA_BCLK"), + PINCTRL_PIN(26, "HDA_SYNC"), + PINCTRL_PIN(27, "HDA_SDO"), + PINCTRL_PIN(28, "HDA_SDI_0"), + PINCTRL_PIN(29, "HDA_RSTB"), + PINCTRL_PIN(30, "HDA_SDI_1"), + PINCTRL_PIN(31, "GPP_R_6"), + PINCTRL_PIN(32, "GPP_R_7"), + PINCTRL_PIN(33, "GPP_R_8"), + PINCTRL_PIN(34, "PCIE_LNK_DOWN"), + PINCTRL_PIN(35, "ISH_UART0_RTSB"), + PINCTRL_PIN(36, "SX_EXIT_HOLDOFFB"), + PINCTRL_PIN(37, "CLKOUT_48"), + PINCTRL_PIN(38, "ISH_GP_7"), + PINCTRL_PIN(39, "ISH_GP_0"), + PINCTRL_PIN(40, "ISH_GP_1"), + PINCTRL_PIN(41, "ISH_GP_2"), + PINCTRL_PIN(42, "ISH_GP_3"), + PINCTRL_PIN(43, "ISH_GP_4"), + PINCTRL_PIN(44, "ISH_GP_5"), + /* GPP_B */ + PINCTRL_PIN(45, "GSPI0_CS1B"), + PINCTRL_PIN(46, "GSPI1_CS1B"), + PINCTRL_PIN(47, "VRALERTB"), + PINCTRL_PIN(48, "CPU_GP_2"), + PINCTRL_PIN(49, "CPU_GP_3"), + PINCTRL_PIN(50, "SRCCLKREQB_0"), + PINCTRL_PIN(51, "SRCCLKREQB_1"), + PINCTRL_PIN(52, "SRCCLKREQB_2"), + PINCTRL_PIN(53, "SRCCLKREQB_3"), + PINCTRL_PIN(54, "SRCCLKREQB_4"), + PINCTRL_PIN(55, "SRCCLKREQB_5"), + PINCTRL_PIN(56, "I2S_MCLK"), + PINCTRL_PIN(57, "SLP_S0B"), + PINCTRL_PIN(58, "PLTRSTB"), + PINCTRL_PIN(59, "SPKR"), + PINCTRL_PIN(60, "GSPI0_CS0B"), + PINCTRL_PIN(61, "GSPI0_CLK"), + PINCTRL_PIN(62, "GSPI0_MISO"), + PINCTRL_PIN(63, "GSPI0_MOSI"), + PINCTRL_PIN(64, "GSPI1_CS0B"), + PINCTRL_PIN(65, "GSPI1_CLK"), + PINCTRL_PIN(66, "GSPI1_MISO"), + PINCTRL_PIN(67, "GSPI1_MOSI"), + PINCTRL_PIN(68, "SML1ALERTB"), + PINCTRL_PIN(69, "GSPI0_CLK_LOOPBK"), + PINCTRL_PIN(70, "GSPI1_CLK_LOOPBK"), + /* vGPIO_0 */ + PINCTRL_PIN(71, "ESPI_USB_OCB_0"), + PINCTRL_PIN(72, "ESPI_USB_OCB_1"), + PINCTRL_PIN(73, "ESPI_USB_OCB_2"), + PINCTRL_PIN(74, "ESPI_USB_OCB_3"), + PINCTRL_PIN(75, "USB_CPU_OCB_0"), + PINCTRL_PIN(76, "USB_CPU_OCB_1"), + PINCTRL_PIN(77, "USB_CPU_OCB_2"), + PINCTRL_PIN(78, "USB_CPU_OCB_3"), + /* GPP_D */ + PINCTRL_PIN(79, "SPI1_CSB"), + PINCTRL_PIN(80, "SPI1_CLK"), + PINCTRL_PIN(81, "SPI1_MISO_IO_1"), + PINCTRL_PIN(82, "SPI1_MOSI_IO_0"), + PINCTRL_PIN(83, "SML1CLK"), + PINCTRL_PIN(84, "I2S2_SFRM"), + PINCTRL_PIN(85, "I2S2_TXD"), + PINCTRL_PIN(86, "I2S2_RXD"), + PINCTRL_PIN(87, "I2S2_SCLK"), + PINCTRL_PIN(88, "SML0CLK"), + PINCTRL_PIN(89, "SML0DATA"), + PINCTRL_PIN(90, "GPP_D_11"), + PINCTRL_PIN(91, "ISH_UART0_CTSB"), + PINCTRL_PIN(92, "SPI1_IO_2"), + PINCTRL_PIN(93, "SPI1_IO_3"), + PINCTRL_PIN(94, "SML1DATA"), + PINCTRL_PIN(95, "GSPI3_CS0B"), + PINCTRL_PIN(96, "GSPI3_CLK"), + PINCTRL_PIN(97, "GSPI3_MISO"), + PINCTRL_PIN(98, "GSPI3_MOSI"), + PINCTRL_PIN(99, "UART3_RXD"), + PINCTRL_PIN(100, "UART3_TXD"), + PINCTRL_PIN(101, "UART3_RTSB"), + PINCTRL_PIN(102, "UART3_CTSB"), + PINCTRL_PIN(103, "SPI1_CLK_LOOPBK"), + PINCTRL_PIN(104, "GSPI3_CLK_LOOPBK"), + /* GPP_C */ + PINCTRL_PIN(105, "SMBCLK"), + PINCTRL_PIN(106, "SMBDATA"), + PINCTRL_PIN(107, "SMBALERTB"), + PINCTRL_PIN(108, "ISH_UART0_RXD"), + PINCTRL_PIN(109, "ISH_UART0_TXD"), + PINCTRL_PIN(110, "SML0ALERTB"), + PINCTRL_PIN(111, "ISH_I2C2_SDA"), + PINCTRL_PIN(112, "ISH_I2C2_SCL"), + PINCTRL_PIN(113, "UART0_RXD"), + PINCTRL_PIN(114, "UART0_TXD"), + PINCTRL_PIN(115, "UART0_RTSB"), + PINCTRL_PIN(116, "UART0_CTSB"), + PINCTRL_PIN(117, "UART1_RXD"), + PINCTRL_PIN(118, "UART1_TXD"), + PINCTRL_PIN(119, "UART1_RTSB"), + PINCTRL_PIN(120, "UART1_CTSB"), + PINCTRL_PIN(121, "I2C0_SDA"), + PINCTRL_PIN(122, "I2C0_SCL"), + PINCTRL_PIN(123, "I2C1_SDA"), + PINCTRL_PIN(124, "I2C1_SCL"), + PINCTRL_PIN(125, "UART2_RXD"), + PINCTRL_PIN(126, "UART2_TXD"), + PINCTRL_PIN(127, "UART2_RTSB"), + PINCTRL_PIN(128, "UART2_CTSB"), + /* GPP_S */ + PINCTRL_PIN(129, "SNDW1_CLK"), + PINCTRL_PIN(130, "SNDW1_DATA"), + PINCTRL_PIN(131, "SNDW2_CLK"), + PINCTRL_PIN(132, "SNDW2_DATA"), + PINCTRL_PIN(133, "SNDW3_CLK"), + PINCTRL_PIN(134, "SNDW3_DATA"), + PINCTRL_PIN(135, "SNDW4_CLK"), + PINCTRL_PIN(136, "SNDW4_DATA"), + /* GPP_G */ + PINCTRL_PIN(137, "DDPA_CTRLCLK"), + PINCTRL_PIN(138, "DDPA_CTRLDATA"), + PINCTRL_PIN(139, "DNX_FORCE_RELOAD"), + PINCTRL_PIN(140, "GMII_MDC_0"), + PINCTRL_PIN(141, "GMII_MDIO_0"), + PINCTRL_PIN(142, "SLP_DRAMB"), + PINCTRL_PIN(143, "GPPC_G_6"), + PINCTRL_PIN(144, "GPPC_G_7"), + PINCTRL_PIN(145, "ISH_SPI_CSB"), + PINCTRL_PIN(146, "ISH_SPI_CLK"), + PINCTRL_PIN(147, "ISH_SPI_MISO"), + PINCTRL_PIN(148, "ISH_SPI_MOSI"), + PINCTRL_PIN(149, "DDP1_CTRLCLK"), + PINCTRL_PIN(150, "DDP1_CTRLDATA"), + PINCTRL_PIN(151, "DDP2_CTRLCLK"), + PINCTRL_PIN(152, "DDP2_CTRLDATA"), + PINCTRL_PIN(153, "GSPI2_CLK_LOOPBK"), + /* vGPIO */ + PINCTRL_PIN(154, "CNV_BTEN"), + PINCTRL_PIN(155, "CNV_BT_HOST_WAKEB"), + PINCTRL_PIN(156, "CNV_BT_IF_SELECT"), + PINCTRL_PIN(157, "vCNV_BT_UART_TXD"), + PINCTRL_PIN(158, "vCNV_BT_UART_RXD"), + PINCTRL_PIN(159, "vCNV_BT_UART_CTS_B"), + PINCTRL_PIN(160, "vCNV_BT_UART_RTS_B"), + PINCTRL_PIN(161, "vCNV_MFUART1_TXD"), + PINCTRL_PIN(162, "vCNV_MFUART1_RXD"), + PINCTRL_PIN(163, "vCNV_MFUART1_CTS_B"), + PINCTRL_PIN(164, "vCNV_MFUART1_RTS_B"), + PINCTRL_PIN(165, "vUART0_TXD"), + PINCTRL_PIN(166, "vUART0_RXD"), + PINCTRL_PIN(167, "vUART0_CTS_B"), + PINCTRL_PIN(168, "vUART0_RTS_B"), + PINCTRL_PIN(169, "vISH_UART0_TXD"), + PINCTRL_PIN(170, "vISH_UART0_RXD"), + PINCTRL_PIN(171, "vISH_UART0_CTS_B"), + PINCTRL_PIN(172, "vISH_UART0_RTS_B"), + PINCTRL_PIN(173, "vCNV_BT_I2S_BCLK"), + PINCTRL_PIN(174, "vCNV_BT_I2S_WS_SYNC"), + PINCTRL_PIN(175, "vCNV_BT_I2S_SDO"), + PINCTRL_PIN(176, "vCNV_BT_I2S_SDI"), + PINCTRL_PIN(177, "vI2S2_SCLK"), + PINCTRL_PIN(178, "vI2S2_SFRM"), + PINCTRL_PIN(179, "vI2S2_TXD"), + PINCTRL_PIN(180, "vI2S2_RXD"), + /* GPP_E */ + PINCTRL_PIN(181, "SATAXPCIE_0"), + PINCTRL_PIN(182, "SATAXPCIE_1"), + PINCTRL_PIN(183, "SATAXPCIE_2"), + PINCTRL_PIN(184, "CPU_GP_0"), + PINCTRL_PIN(185, "SATA_DEVSLP_0"), + PINCTRL_PIN(186, "SATA_DEVSLP_1"), + PINCTRL_PIN(187, "SATA_DEVSLP_2"), + PINCTRL_PIN(188, "CPU_GP_1"), + PINCTRL_PIN(189, "SATA_LEDB"), + PINCTRL_PIN(190, "USB2_OCB_0"), + PINCTRL_PIN(191, "USB2_OCB_1"), + PINCTRL_PIN(192, "USB2_OCB_2"), + PINCTRL_PIN(193, "USB2_OCB_3"), + /* GPP_F */ + PINCTRL_PIN(194, "SATAXPCIE_3"), + PINCTRL_PIN(195, "SATAXPCIE_4"), + PINCTRL_PIN(196, "SATAXPCIE_5"), + PINCTRL_PIN(197, "SATAXPCIE_6"), + PINCTRL_PIN(198, "SATAXPCIE_7"), + PINCTRL_PIN(199, "SATA_DEVSLP_3"), + PINCTRL_PIN(200, "SATA_DEVSLP_4"), + PINCTRL_PIN(201, "SATA_DEVSLP_5"), + PINCTRL_PIN(202, "SATA_DEVSLP_6"), + PINCTRL_PIN(203, "SATA_DEVSLP_7"), + PINCTRL_PIN(204, "SATA_SCLOCK"), + PINCTRL_PIN(205, "SATA_SLOAD"), + PINCTRL_PIN(206, "SATA_SDATAOUT1"), + PINCTRL_PIN(207, "SATA_SDATAOUT0"), + PINCTRL_PIN(208, "PS_ONB"), + PINCTRL_PIN(209, "M2_SKT2_CFG_0"), + PINCTRL_PIN(210, "M2_SKT2_CFG_1"), + PINCTRL_PIN(211, "M2_SKT2_CFG_2"), + PINCTRL_PIN(212, "M2_SKT2_CFG_3"), + PINCTRL_PIN(213, "L_VDDEN"), + PINCTRL_PIN(214, "L_BKLTEN"), + PINCTRL_PIN(215, "L_BKLTCTL"), + PINCTRL_PIN(216, "VNN_CTRL"), + PINCTRL_PIN(217, "GPP_F_23"), + /* GPP_H */ + PINCTRL_PIN(218, "SRCCLKREQB_6"), + PINCTRL_PIN(219, "SRCCLKREQB_7"), + PINCTRL_PIN(220, "SRCCLKREQB_8"), + PINCTRL_PIN(221, "SRCCLKREQB_9"), + PINCTRL_PIN(222, "SRCCLKREQB_10"), + PINCTRL_PIN(223, "SRCCLKREQB_11"), + PINCTRL_PIN(224, "SRCCLKREQB_12"), + PINCTRL_PIN(225, "SRCCLKREQB_13"), + PINCTRL_PIN(226, "SRCCLKREQB_14"), + PINCTRL_PIN(227, "SRCCLKREQB_15"), + PINCTRL_PIN(228, "SML2CLK"), + PINCTRL_PIN(229, "SML2DATA"), + PINCTRL_PIN(230, "SML2ALERTB"), + PINCTRL_PIN(231, "SML3CLK"), + PINCTRL_PIN(232, "SML3DATA"), + PINCTRL_PIN(233, "SML3ALERTB"), + PINCTRL_PIN(234, "SML4CLK"), + PINCTRL_PIN(235, "SML4DATA"), + PINCTRL_PIN(236, "SML4ALERTB"), + PINCTRL_PIN(237, "ISH_I2C0_SDA"), + PINCTRL_PIN(238, "ISH_I2C0_SCL"), + PINCTRL_PIN(239, "ISH_I2C1_SDA"), + PINCTRL_PIN(240, "ISH_I2C1_SCL"), + PINCTRL_PIN(241, "TIME_SYNC_0"), + /* GPP_J */ + PINCTRL_PIN(242, "CNV_PA_BLANKING"), + PINCTRL_PIN(243, "CPU_C10_GATEB"), + PINCTRL_PIN(244, "CNV_BRI_DT"), + PINCTRL_PIN(245, "CNV_BRI_RSP"), + PINCTRL_PIN(246, "CNV_RGI_DT"), + PINCTRL_PIN(247, "CNV_RGI_RSP"), + PINCTRL_PIN(248, "CNV_MFUART2_RXD"), + PINCTRL_PIN(249, "CNV_MFUART2_TXD"), + PINCTRL_PIN(250, "GPP_J_8"), + PINCTRL_PIN(251, "GPP_J_9"), + /* GPP_K */ + PINCTRL_PIN(252, "GSXDOUT"), + PINCTRL_PIN(253, "GSXSLOAD"), + PINCTRL_PIN(254, "GSXDIN"), + PINCTRL_PIN(255, "GSXSRESETB"), + PINCTRL_PIN(256, "GSXCLK"), + PINCTRL_PIN(257, "ADR_COMPLETE"), + PINCTRL_PIN(258, "DDSP_HPD_A"), + PINCTRL_PIN(259, "DDSP_HPD_B"), + PINCTRL_PIN(260, "CORE_VID_0"), + PINCTRL_PIN(261, "CORE_VID_1"), + PINCTRL_PIN(262, "DDSP_HPD_C"), + PINCTRL_PIN(263, "GPP_K_11"), + PINCTRL_PIN(264, "SYS_PWROK"), + PINCTRL_PIN(265, "SYS_RESETB"), + PINCTRL_PIN(266, "MLK_RSTB"), + /* GPP_I */ + PINCTRL_PIN(267, "PMCALERTB"), + PINCTRL_PIN(268, "DDSP_HPD_1"), + PINCTRL_PIN(269, "DDSP_HPD_2"), + PINCTRL_PIN(270, "DDSP_HPD_3"), + PINCTRL_PIN(271, "DDSP_HPD_4"), + PINCTRL_PIN(272, "DDPB_CTRLCLK"), + PINCTRL_PIN(273, "DDPB_CTRLDATA"), + PINCTRL_PIN(274, "DDPC_CTRLCLK"), + PINCTRL_PIN(275, "DDPC_CTRLDATA"), + PINCTRL_PIN(276, "FUSA_DIAGTEST_EN"), + PINCTRL_PIN(277, "FUSA_DIAGTEST_MODE"), + PINCTRL_PIN(278, "USB2_OCB_4"), + PINCTRL_PIN(279, "USB2_OCB_5"), + PINCTRL_PIN(280, "USB2_OCB_6"), + PINCTRL_PIN(281, "USB2_OCB_7"), + /* JTAG */ + PINCTRL_PIN(282, "JTAG_TDO"), + PINCTRL_PIN(283, "JTAGX"), + PINCTRL_PIN(284, "PRDYB"), + PINCTRL_PIN(285, "PREQB"), + PINCTRL_PIN(286, "JTAG_TDI"), + PINCTRL_PIN(287, "JTAG_TMS"), + PINCTRL_PIN(288, "JTAG_TCK"), + PINCTRL_PIN(289, "DBG_PMODE"), + PINCTRL_PIN(290, "CPU_TRSTB"), +}; + +static const struct intel_padgroup tglh_community0_gpps[] = { + TGL_GPP(0, 0, 24, 0), /* GPP_A */ + TGL_GPP(1, 25, 44, 128), /* GPP_R */ + TGL_GPP(2, 45, 70, 32), /* GPP_B */ + TGL_GPP(3, 71, 78, INTEL_GPIO_BASE_NOMAP), /* vGPIO_0 */ +}; + +static const struct intel_padgroup tglh_community1_gpps[] = { + TGL_GPP(0, 79, 104, 96), /* GPP_D */ + TGL_GPP(1, 105, 128, 64), /* GPP_C */ + TGL_GPP(2, 129, 136, 160), /* GPP_S */ + TGL_GPP(3, 137, 153, 192), /* GPP_G */ + TGL_GPP(4, 154, 180, 224), /* vGPIO */ +}; + +static const struct intel_padgroup tglh_community3_gpps[] = { + TGL_GPP(0, 181, 193, 256), /* GPP_E */ + TGL_GPP(1, 194, 217, 288), /* GPP_F */ +}; + +static const struct intel_padgroup tglh_community4_gpps[] = { + TGL_GPP(0, 218, 241, 320), /* GPP_H */ + TGL_GPP(1, 242, 251, 384), /* GPP_J */ + TGL_GPP(2, 252, 266, 352), /* GPP_K */ +}; + +static const struct intel_padgroup tglh_community5_gpps[] = { + TGL_GPP(0, 267, 281, 416), /* GPP_I */ + TGL_GPP(1, 282, 290, INTEL_GPIO_BASE_NOMAP), /* JTAG */ +}; + +static const struct intel_community tglh_communities[] = { + TGL_COMMUNITY(0, 0, 78, tglh_community0_gpps), + TGL_COMMUNITY(1, 79, 180, tglh_community1_gpps), + TGL_COMMUNITY(2, 181, 217, tglh_community3_gpps), + TGL_COMMUNITY(3, 218, 266, tglh_community4_gpps), + TGL_COMMUNITY(4, 267, 290, tglh_community5_gpps), +}; + +static const struct intel_pinctrl_soc_data tglh_soc_data = { + .pins = tglh_pins, + .npins = ARRAY_SIZE(tglh_pins), + .communities = tglh_communities, + .ncommunities = ARRAY_SIZE(tglh_communities), +}; + static const struct acpi_device_id tgl_pinctrl_acpi_match[] = { { "INT34C5", (kernel_ulong_t)&tgllp_soc_data }, + { "INT34C6", (kernel_ulong_t)&tglh_soc_data }, { } }; MODULE_DEVICE_TABLE(acpi, tgl_pinctrl_acpi_match); From 482dcb2a04fdf6d4306e40f2b0537a313a466558 Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Thu, 2 Jul 2020 14:05:50 +0000 Subject: [PATCH 087/242] mtd: spi-nor: macronix: Add support for MX25R1635F The MX25R1635F is the smaller sibling of the MX25R3235F that is already supported. It's only half the size (16Mb). It was tested on the Kontron Electronics i.MX8MM SoM (N8010) using raw read and write from and to the mtd device and the 'flash_erase' command. Signed-off-by: Frieder Schrempf [tudor.ambarus@microchip.com: update subject] Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200702140523.6811-1-frieder.schrempf@kontron.de --- drivers/mtd/spi-nor/macronix.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index 96735d83c77c..0ae0815a3633 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -52,6 +52,9 @@ static const struct flash_info macronix_parts[] = { { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, + { "mx25r1635f", INFO(0xc22815, 0, 64 * 1024, 32, + SECT_4K | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ) }, { "mx25r3235f", INFO(0xc22816, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, From 0ee2872f105b997ba5f09f7fdae542e4cbc1d676 Mon Sep 17 00:00:00 2001 From: Sven Van Asbroeck Date: Mon, 29 Jun 2020 15:53:06 -0400 Subject: [PATCH 088/242] mtd: spi-nor: winbond: Add support for w25q64jvm This chip is (nearly) identical to the Winbond w25q64 which is already supported by Linux. Compared to the w25q64, the 'jvm' has a different JEDEC ID. Signed-off-by: Sven Van Asbroeck [tudor.ambarus@microchip.com: Order entry alphabetically, update subject, update Sven's email address] Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200629195306.1030-1-TheSven73@gmail.com --- drivers/mtd/spi-nor/winbond.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 5062af10f138..a5eb1d56cb88 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -68,6 +68,7 @@ static const struct flash_info winbond_parts[] = { { "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, + { "w25q64jvm", INFO(0xef7017, 0, 64 * 1024, 128, SECT_4K) }, { "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, From b4554dee38b0cf4f15199afc8ad5004dfe133959 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:23:56 +0800 Subject: [PATCH 089/242] pinctrl: imx: Support i.MX8 SoCs pinctrl driver built as module Export necessary APIs to support i.MX8 SoCs pinctrl driver to be built as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-2-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index cb7e0f08d2cf..f18f0d7d5ae1 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -878,6 +878,7 @@ int imx_pinctrl_probe(struct platform_device *pdev, return pinctrl_enable(ipctl->pctl); } +EXPORT_SYMBOL_GPL(imx_pinctrl_probe); static int __maybe_unused imx_pinctrl_suspend(struct device *dev) { @@ -897,3 +898,4 @@ const struct dev_pm_ops imx_pinctrl_pm_ops = { SET_LATE_SYSTEM_SLEEP_PM_OPS(imx_pinctrl_suspend, imx_pinctrl_resume) }; +EXPORT_SYMBOL_GPL(imx_pinctrl_pm_ops); From 0adbfcee61a7c953919baa10e4ab2e66acea407f Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:23:57 +0800 Subject: [PATCH 090/242] pinctrl: imx: scu: Support i.MX8 SCU SoCs pinctrl driver built as module Export necessary APIs to support i.MX8 SCU SoCs pinctrl driver to be built as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-3-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-scu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/freescale/pinctrl-scu.c b/drivers/pinctrl/freescale/pinctrl-scu.c index 23cf04bdfc55..9df45d3e3226 100644 --- a/drivers/pinctrl/freescale/pinctrl-scu.c +++ b/drivers/pinctrl/freescale/pinctrl-scu.c @@ -41,6 +41,7 @@ int imx_pinctrl_sc_ipc_init(struct platform_device *pdev) { return imx_scu_get_handle(&pinctrl_ipc_handle); } +EXPORT_SYMBOL_GPL(imx_pinctrl_sc_ipc_init); int imx_pinconf_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id, unsigned long *config) @@ -66,6 +67,7 @@ int imx_pinconf_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id, return 0; } +EXPORT_SYMBOL_GPL(imx_pinconf_get_scu); int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id, unsigned long *configs, unsigned num_configs) @@ -101,6 +103,7 @@ int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id, return ret; } +EXPORT_SYMBOL_GPL(imx_pinconf_set_scu); void imx_pinctrl_parse_pin_scu(struct imx_pinctrl *ipctl, unsigned int *pin_id, struct imx_pin *pin, @@ -119,3 +122,4 @@ void imx_pinctrl_parse_pin_scu(struct imx_pinctrl *ipctl, dev_dbg(ipctl->dev, "%s: 0x%x 0x%08lx", info->pins[pin->pin].name, pin_scu->mux_mode, pin_scu->config); } +EXPORT_SYMBOL_GPL(imx_pinctrl_parse_pin_scu); From a302b0e1001a889e5dd64b09ca76892f01b9610e Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:23:58 +0800 Subject: [PATCH 091/242] pinctrl: imx8mm: Support building as module Change configuration to "tristate", add module device table, author, description and license to support building i.MX8MM pinctrl driver as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-4-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 2 +- drivers/pinctrl/freescale/pinctrl-imx8mm.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index 4ca44dd69e53..3681c4dbb1f6 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -124,7 +124,7 @@ config PINCTRL_IMX7ULP Say Y here to enable the imx7ulp pinctrl driver config PINCTRL_IMX8MM - bool "IMX8MM pinctrl driver" + tristate "IMX8MM pinctrl driver" depends on ARCH_MXC select PINCTRL_IMX help diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mm.c b/drivers/pinctrl/freescale/pinctrl-imx8mm.c index 6d1038af59f4..31c5d8861406 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mm.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mm.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -326,6 +327,7 @@ static const struct of_device_id imx8mm_pinctrl_of_match[] = { { .compatible = "fsl,imx8mm-iomuxc", .data = &imx8mm_pinctrl_info, }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8mm_pinctrl_of_match); static int imx8mm_pinctrl_probe(struct platform_device *pdev) { @@ -346,3 +348,7 @@ static int __init imx8mm_pinctrl_init(void) return platform_driver_register(&imx8mm_pinctrl_driver); } arch_initcall(imx8mm_pinctrl_init); + +MODULE_AUTHOR("Bai Ping "); +MODULE_DESCRIPTION("NXP i.MX8MM pinctrl driver"); +MODULE_LICENSE("GPL v2"); From 4bb63d2166cd2899f138f49c9bc83f25aa571f5b Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:23:59 +0800 Subject: [PATCH 092/242] pinctrl: imx8mn: Support building as module Change configuration to "tristate", add module device table, author, description and license to support building i.MX8MN pinctrl driver as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-5-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 2 +- drivers/pinctrl/freescale/pinctrl-imx8mn.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index 3681c4dbb1f6..b90971945e3a 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -131,7 +131,7 @@ config PINCTRL_IMX8MM Say Y here to enable the imx8mm pinctrl driver config PINCTRL_IMX8MN - bool "IMX8MN pinctrl driver" + tristate "IMX8MN pinctrl driver" depends on ARCH_MXC select PINCTRL_IMX help diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mn.c b/drivers/pinctrl/freescale/pinctrl-imx8mn.c index 100ed8c1039a..14c9deb51fec 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mn.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mn.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -326,6 +327,7 @@ static const struct of_device_id imx8mn_pinctrl_of_match[] = { { .compatible = "fsl,imx8mn-iomuxc", .data = &imx8mn_pinctrl_info, }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8mn_pinctrl_of_match); static int imx8mn_pinctrl_probe(struct platform_device *pdev) { @@ -346,3 +348,7 @@ static int __init imx8mn_pinctrl_init(void) return platform_driver_register(&imx8mn_pinctrl_driver); } arch_initcall(imx8mn_pinctrl_init); + +MODULE_AUTHOR("Anson Huang "); +MODULE_DESCRIPTION("NXP i.MX8MN pinctrl driver"); +MODULE_LICENSE("GPL v2"); From e38b6bb211733f08523c1571820a86884635239a Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:24:00 +0800 Subject: [PATCH 093/242] pinctrl: imx8mq: Support building as module Change configuration to "tristate", add module device table, author, description and license to support building i.MX8MQ pinctrl driver as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-6-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 2 +- drivers/pinctrl/freescale/pinctrl-imx8mq.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index b90971945e3a..df77e752003d 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -145,7 +145,7 @@ config PINCTRL_IMX8MP Say Y here to enable the imx8mp pinctrl driver config PINCTRL_IMX8MQ - bool "IMX8MQ pinctrl driver" + tristate "IMX8MQ pinctrl driver" depends on ARCH_MXC select PINCTRL_IMX help diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mq.c b/drivers/pinctrl/freescale/pinctrl-imx8mq.c index 50aa1c00c4b2..ae3ea5b5c204 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mq.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mq.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -329,6 +330,7 @@ static const struct of_device_id imx8mq_pinctrl_of_match[] = { { .compatible = "fsl,imx8mq-iomuxc", .data = &imx8mq_pinctrl_info, }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8mq_pinctrl_of_match); static int imx8mq_pinctrl_probe(struct platform_device *pdev) { @@ -350,3 +352,7 @@ static int __init imx8mq_pinctrl_init(void) return platform_driver_register(&imx8mq_pinctrl_driver); } arch_initcall(imx8mq_pinctrl_init); + +MODULE_AUTHOR("Lucas Stach "); +MODULE_DESCRIPTION("NXP i.MX8MQ pinctrl driver"); +MODULE_LICENSE("GPL v2"); From d73080c3938fe7ba8c33e02615ea5e57ba183bcd Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:24:01 +0800 Subject: [PATCH 094/242] pinctrl: imx8mp: Support building as module Change configuration to "tristate", add module device table, author, description and license to support building i.MX8MP pinctrl driver as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-7-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 2 +- drivers/pinctrl/freescale/pinctrl-imx8mp.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index df77e752003d..2bf90b356112 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -138,7 +138,7 @@ config PINCTRL_IMX8MN Say Y here to enable the imx8mn pinctrl driver config PINCTRL_IMX8MP - bool "IMX8MP pinctrl driver" + tristate "IMX8MP pinctrl driver" depends on ARCH_MXC select PINCTRL_IMX help diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mp.c b/drivers/pinctrl/freescale/pinctrl-imx8mp.c index e3f644c2ec13..bf4bbb5e2446 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mp.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -324,6 +325,7 @@ static const struct of_device_id imx8mp_pinctrl_of_match[] = { { .compatible = "fsl,imx8mp-iomuxc", .data = &imx8mp_pinctrl_info, }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8mp_pinctrl_of_match); static int imx8mp_pinctrl_probe(struct platform_device *pdev) { @@ -343,3 +345,7 @@ static int __init imx8mp_pinctrl_init(void) return platform_driver_register(&imx8mp_pinctrl_driver); } arch_initcall(imx8mp_pinctrl_init); + +MODULE_AUTHOR("Anson Huang "); +MODULE_DESCRIPTION("NXP i.MX8MP pinctrl driver"); +MODULE_LICENSE("GPL v2"); From 3aace899ecd4f584fd93ec5a32625ff33d4cbeca Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:24:02 +0800 Subject: [PATCH 095/242] pinctrl: imx8qxp: Support building as module Change configuration to "tristate", add module device table, author, description and license to support building i.MX8QXP pinctrl driver as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-8-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 2 +- drivers/pinctrl/freescale/pinctrl-imx8qxp.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index 2bf90b356112..0a728bb009a1 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -159,7 +159,7 @@ config PINCTRL_IMX8QM Say Y here to enable the imx8qm pinctrl driver config PINCTRL_IMX8QXP - bool "IMX8QXP pinctrl driver" + tristate "IMX8QXP pinctrl driver" depends on IMX_SCU && ARCH_MXC && ARM64 select PINCTRL_IMX_SCU help diff --git a/drivers/pinctrl/freescale/pinctrl-imx8qxp.c b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c index 1131dc3c084e..81ebd4c952ec 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8qxp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c @@ -204,6 +204,7 @@ static const struct of_device_id imx8qxp_pinctrl_of_match[] = { { .compatible = "fsl,imx8qxp-iomuxc", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8qxp_pinctrl_of_match); static int imx8qxp_pinctrl_probe(struct platform_device *pdev) { @@ -230,3 +231,7 @@ static int __init imx8qxp_pinctrl_init(void) return platform_driver_register(&imx8qxp_pinctrl_driver); } arch_initcall(imx8qxp_pinctrl_init); + +MODULE_AUTHOR("Aisheng Dong "); +MODULE_DESCRIPTION("NXP i.MX8QXP pinctrl driver"); +MODULE_LICENSE("GPL v2"); From 36d640fa90a58b9e95f709b8eb75778a422ad418 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:24:03 +0800 Subject: [PATCH 096/242] pinctrl: imx8qm: Support building as module Change configuration to "tristate", add module device table, author, description and license to support building i.MX8QM pinctrl driver as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-9-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 2 +- drivers/pinctrl/freescale/pinctrl-imx8qm.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index 0a728bb009a1..d9fb5f29b7af 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -152,7 +152,7 @@ config PINCTRL_IMX8MQ Say Y here to enable the imx8mq pinctrl driver config PINCTRL_IMX8QM - bool "IMX8QM pinctrl driver" + tristate "IMX8QM pinctrl driver" depends on IMX_SCU && ARCH_MXC && ARM64 select PINCTRL_IMX_SCU help diff --git a/drivers/pinctrl/freescale/pinctrl-imx8qm.c b/drivers/pinctrl/freescale/pinctrl-imx8qm.c index 0b6029b29731..095acf494641 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8qm.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8qm.c @@ -298,6 +298,7 @@ static const struct of_device_id imx8qm_pinctrl_of_match[] = { { .compatible = "fsl,imx8qm-iomuxc", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8qm_pinctrl_of_match); static int imx8qm_pinctrl_probe(struct platform_device *pdev) { @@ -324,3 +325,7 @@ static int __init imx8qm_pinctrl_init(void) return platform_driver_register(&imx8qm_pinctrl_driver); } arch_initcall(imx8qm_pinctrl_init); + +MODULE_AUTHOR("Aisheng Dong "); +MODULE_DESCRIPTION("NXP i.MX8QM pinctrl driver"); +MODULE_LICENSE("GPL v2"); From 614038d628c02ad6f2439bdf9baa6acceb8ec772 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jun 2020 14:24:04 +0800 Subject: [PATCH 097/242] pinctrl: imx8dxl: Support building as module Change configuration to "tristate", add module device table, author, description and license to support building i.MX8DXL pinctrl driver as module. Signed-off-by: Anson Huang Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/1592979844-18833-10-git-send-email-Anson.Huang@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 2 +- drivers/pinctrl/freescale/pinctrl-imx8dxl.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index d9fb5f29b7af..08fcf5c79296 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -166,7 +166,7 @@ config PINCTRL_IMX8QXP Say Y here to enable the imx8qxp pinctrl driver config PINCTRL_IMX8DXL - bool "IMX8DXL pinctrl driver" + tristate "IMX8DXL pinctrl driver" depends on IMX_SCU && ARCH_MXC && ARM64 select PINCTRL_IMX_SCU help diff --git a/drivers/pinctrl/freescale/pinctrl-imx8dxl.c b/drivers/pinctrl/freescale/pinctrl-imx8dxl.c index 7f32e57b7f6a..12b97daa0407 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8dxl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8dxl.c @@ -165,6 +165,7 @@ static const struct of_device_id imx8dxl_pinctrl_of_match[] = { { .compatible = "fsl,imx8dxl-iomuxc", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, imx8dxl_pinctrl_of_match); static int imx8dxl_pinctrl_probe(struct platform_device *pdev) { @@ -191,3 +192,7 @@ static int __init imx8dxl_pinctrl_init(void) return platform_driver_register(&imx8dxl_pinctrl_driver); } arch_initcall(imx8dxl_pinctrl_init); + +MODULE_AUTHOR("Anson Huang "); +MODULE_DESCRIPTION("NXP i.MX8DXL pinctrl driver"); +MODULE_LICENSE("GPL v2"); From 0c33f125732d0d33392ba6774d85469d565d3496 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Mon, 22 Jun 2020 17:45:12 +0200 Subject: [PATCH 098/242] kbuild: run the checker after the compiler Since the pre-git time the checker is run first, before the compiler. But if the source file contains some syntax error, the warnings from the compiler are more useful than those from sparse (and other checker most probably too). So move the 'check' command to run after the compiler. Signed-off-by: Luc Van Oostenryck Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 2e8810b7e5ed..7ba6a752d5bd 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -252,9 +252,9 @@ cmd_gen_ksymdeps = \ endif define rule_cc_o_c - $(call cmd,checksrc) $(call cmd_and_fixdep,cc_o_c) $(call cmd,gen_ksymdeps) + $(call cmd,checksrc) $(call cmd,checkdoc) $(call cmd,objtool) $(call cmd,modversions_c) @@ -277,8 +277,8 @@ endif # Built-in and composite module parts $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE - $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) + $(call cmd,force_checksrc) cmd_mod = { \ echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \ From dd7699e37f289fa433f42c6bcc108468c8b198c0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 23 Jun 2020 17:05:49 +0900 Subject: [PATCH 099/242] Revert "kbuild: Create directory for target DTB" This reverts commit 77479b38e2f58890eb221a0418357502a5b41cd6. Since commit 8a78756eb545 ("kbuild: create object directories simpler and faster"), all directories for 'targets' are created. 'mkdir -p $(dir ${dtc-tmp})' is no longer needed. Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 916b2f7f7098..8fa9aa2c9fca 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -303,8 +303,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb FORCE $(call if_changed,dt_S_dtb) quiet_cmd_dtc = DTC $@ -cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ - $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ +cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ $(DTC) -O $(patsubst .%,%,$(suffix $@)) -o $@ -b 0 \ $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ From 893ab00439a45513cae55781fc8e3b7108ee1cda Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 27 Jun 2020 03:59:12 +0900 Subject: [PATCH 100/242] kbuild: remove cc-option test of -fno-stack-protector Some Makefiles already pass -fno-stack-protector unconditionally. For example, arch/arm64/kernel/vdso/Makefile, arch/x86/xen/Makefile. No problem report so far about hard-coding this option. So, we can assume all supported compilers know -fno-stack-protector. GCC 4.8 and Clang support this option (https://godbolt.org/z/_HDGzN) Get rid of cc-option from -fno-stack-protector. Remove CONFIG_CC_HAS_STACKPROTECTOR_NONE, which is always 'y'. Note: arch/mips/vdso/Makefile adds -fno-stack-protector twice, first unconditionally, and second conditionally. I removed the second one. Signed-off-by: Masahiro Yamada Reviewed-by: Kees Cook Acked-by: Ard Biesheuvel Reviewed-by: Nick Desaulniers --- Documentation/kbuild/kconfig-language.rst | 4 ++-- Makefile | 2 +- arch/Kconfig | 3 --- arch/arm/boot/compressed/Makefile | 3 +-- arch/mips/vdso/Makefile | 3 +-- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/platforms/powermac/Makefile | 2 +- arch/sparc/vdso/Makefile | 4 ++-- arch/um/Makefile | 3 +-- arch/x86/Makefile | 2 +- arch/x86/boot/compressed/Makefile | 2 +- arch/x86/entry/vdso/Makefile | 4 ++-- arch/x86/kernel/cpu/Makefile | 3 +-- arch/x86/lib/Makefile | 2 +- arch/x86/mm/Makefile | 7 +++---- arch/x86/power/Makefile | 3 +-- arch/x86/purgatory/Makefile | 2 +- arch/x86/um/vdso/Makefile | 2 +- arch/x86/xen/Makefile | 5 ++--- drivers/firmware/efi/libstub/Makefile | 2 +- drivers/xen/Makefile | 3 +-- lib/Makefile | 4 ++-- mm/kasan/Makefile | 2 +- 23 files changed, 29 insertions(+), 40 deletions(-) diff --git a/Documentation/kbuild/kconfig-language.rst b/Documentation/kbuild/kconfig-language.rst index a1601ec3317b..2538e7cb08e6 100644 --- a/Documentation/kbuild/kconfig-language.rst +++ b/Documentation/kbuild/kconfig-language.rst @@ -540,8 +540,8 @@ followed by a test macro:: If you need to expose a compiler capability to makefiles and/or C source files, `CC_HAS_` is the recommended prefix for the config option:: - config CC_HAS_STACKPROTECTOR_NONE - def_bool $(cc-option,-fno-stack-protector) + config CC_HAS_ASM_GOTO + def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC)) Build as module only ~~~~~~~~~~~~~~~~~~~~ diff --git a/Makefile b/Makefile index fe0164a654c7..ea283c9bbaa8 100644 --- a/Makefile +++ b/Makefile @@ -762,7 +762,7 @@ ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += -Wframe-larger-than=$(CONFIG_FRAME_WARN) endif -stackp-flags-$(CONFIG_CC_HAS_STACKPROTECTOR_NONE) := -fno-stack-protector +stackp-flags-y := -fno-stack-protector stackp-flags-$(CONFIG_STACKPROTECTOR) := -fstack-protector stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-strong diff --git a/arch/Kconfig b/arch/Kconfig index 8cc35dc556c7..1ea61290900a 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -478,9 +478,6 @@ config HAVE_STACKPROTECTOR An arch should select this symbol if: - it has implemented a stack canary (e.g. __stack_chk_guard) -config CC_HAS_STACKPROTECTOR_NONE - def_bool $(cc-option,-fno-stack-protector) - config STACKPROTECTOR bool "Stack Protector buffer overflow detection" depends on HAVE_STACKPROTECTOR diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 00602a6fba04..cb7a56c6723c 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -84,9 +84,8 @@ endif # -fstack-protector-strong triggers protection checks in this code, # but it is being used too early to link to meaningful stack_chk logic. -nossp-flags-$(CONFIG_CC_HAS_STACKPROTECTOR_NONE) := -fno-stack-protector $(foreach o, $(libfdt_objs) atags_to_fdt.o, \ - $(eval CFLAGS_$(o) := -I $(srctree)/scripts/dtc/libfdt $(nossp-flags-y))) + $(eval CFLAGS_$(o) := -I $(srctree)/scripts/dtc/libfdt -fno-stack-protector)) # These were previously generated C files. When you are building the kernel # with O=, make sure to remove the stale files in the output tree. Otherwise, diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index 2e64c7600eea..57fe83235281 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -35,8 +35,7 @@ cflags-vdso := $(ccflags-vdso) \ -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ -mrelax-pic-calls $(call cc-option, -mexplicit-relocs) \ -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ - $(call cc-option, -fno-asynchronous-unwind-tables) \ - $(call cc-option, -fno-stack-protector) + $(call cc-option, -fno-asynchronous-unwind-tables) aflags-vdso := $(ccflags-vdso) \ -D__ASSEMBLY__ -Wa,-gdwarf-2 diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 244542ae2a91..3a83f2b876a5 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -16,7 +16,7 @@ CFLAGS_prom_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) -CFLAGS_prom_init.o += $(call cc-option, -fno-stack-protector) +CFLAGS_prom_init.o += -fno-stack-protector CFLAGS_prom_init.o += -DDISABLE_BRANCH_PROFILING CFLAGS_prom_init.o += -ffreestanding diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index f4247ade71ca..cf85f0662d0d 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS_bootx_init.o += -fPIC -CFLAGS_bootx_init.o += $(call cc-option, -fno-stack-protector) +CFLAGS_bootx_init.o += -fno-stack-protector KASAN_SANITIZE_bootx_init.o := n diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile index 708cb6304c2d..f44355e46f31 100644 --- a/arch/sparc/vdso/Makefile +++ b/arch/sparc/vdso/Makefile @@ -54,7 +54,7 @@ $(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(obj)/vdso2c FORCE # optimize sibling calls. # CFL := $(PROFILING) -mcmodel=medlow -fPIC -O2 -fasynchronous-unwind-tables -m64 \ - $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \ + $(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \ -fno-omit-frame-pointer -foptimize-sibling-calls \ -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO @@ -93,7 +93,7 @@ KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(SPARC_REG_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 += -m32 -msoft-float -fpic -KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) +KBUILD_CFLAGS_32 += -fno-stack-protector KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) KBUILD_CFLAGS_32 += -fno-omit-frame-pointer KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING diff --git a/arch/um/Makefile b/arch/um/Makefile index 3f27aa3ec0a6..1cea46ff9bb7 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -121,8 +121,7 @@ LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib $(call cc-option, -no-pie) CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ - $(call cc-option, -fno-stack-protector,) \ - $(call cc-option, -fno-stack-protector-all,) + -fno-stack-protector $(call cc-option, -fno-stack-protector-all) # Options used by linker script export LDS_START := $(START) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 00e378de8bc0..89c3cdfba753 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -37,7 +37,7 @@ REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -DDISABLE_BRANCH_PROFILING \ -mno-mmx -mno-sse REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding) -REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector) +REALMODE_CFLAGS += -fno-stack-protector REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4)) export REALMODE_CFLAGS diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 7619742f91c9..c88a31569a5e 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -36,7 +36,7 @@ cflags-$(CONFIG_X86_64) := -mcmodel=small KBUILD_CFLAGS += $(cflags-y) KBUILD_CFLAGS += -mno-mmx -mno-sse KBUILD_CFLAGS += $(call cc-option,-ffreestanding) -KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) +KBUILD_CFLAGS += -fno-stack-protector KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS += $(call cc-disable-warning, gnu) KBUILD_CFLAGS += -Wno-pointer-sign diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index 04e65f0698f6..215376d975a2 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -82,7 +82,7 @@ $(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso%.so $(obj)/vdso2c FORCE # optimize sibling calls. # CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ - $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \ + $(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \ -fno-omit-frame-pointer -foptimize-sibling-calls \ -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO @@ -151,7 +151,7 @@ KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 := $(filter-out $(RETPOLINE_CFLAGS),$(KBUILD_CFLAGS_32)) KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic -KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector) +KBUILD_CFLAGS_32 += -fno-stack-protector KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls) KBUILD_CFLAGS_32 += -fno-omit-frame-pointer KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index dba6a83bc349..93792b457b81 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -17,8 +17,7 @@ KCOV_INSTRUMENT_perf_event.o := n KCSAN_SANITIZE_common.o := n # Make sure load_percpu_segment has no stackprotector -nostackp := $(call cc-option, -fno-stack-protector) -CFLAGS_common.o := $(nostackp) +CFLAGS_common.o := -fno-stack-protector obj-y := cacheinfo.o scattered.o topology.o obj-y += common.o diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 6110bce7237b..d46fff11f06f 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -24,7 +24,7 @@ ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_cmdline.o = -pg endif -CFLAGS_cmdline.o := $(call cc-option, -fno-stack-protector) +CFLAGS_cmdline.o := -fno-stack-protector endif inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index f7fd0e868c9c..5864219221ca 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -22,10 +22,9 @@ obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o mmap.o \ obj-y += pat/ # Make sure __phys_addr has no stackprotector -nostackp := $(call cc-option, -fno-stack-protector) -CFLAGS_physaddr.o := $(nostackp) -CFLAGS_setup_nx.o := $(nostackp) -CFLAGS_mem_encrypt_identity.o := $(nostackp) +CFLAGS_physaddr.o := -fno-stack-protector +CFLAGS_setup_nx.o := -fno-stack-protector +CFLAGS_mem_encrypt_identity.o := -fno-stack-protector CFLAGS_fault.o := -I $(srctree)/$(src)/../include/asm/trace diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile index 37923d715741..6907b523e856 100644 --- a/arch/x86/power/Makefile +++ b/arch/x86/power/Makefile @@ -3,8 +3,7 @@ OBJECT_FILES_NON_STANDARD_hibernate_asm_$(BITS).o := y # __restore_processor_state() restores %gs after S3 resume and so should not # itself be stack-protected -nostackp := $(call cc-option, -fno-stack-protector) -CFLAGS_cpu.o := $(nostackp) +CFLAGS_cpu.o := -fno-stack-protector obj-$(CONFIG_PM_SLEEP) += cpu.o obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o hibernate.o diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile index 088bd764e0b7..183ac60e5990 100644 --- a/arch/x86/purgatory/Makefile +++ b/arch/x86/purgatory/Makefile @@ -34,7 +34,7 @@ KCOV_INSTRUMENT := n PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING -PURGATORY_CFLAGS += $(call cc-option,-fno-stack-protector) +PURGATORY_CFLAGS += -fno-stack-protector # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That # in turn leaves some undefined symbols like __fentry__ in purgatory and not diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile index 0caddd6acb22..5943387e3f35 100644 --- a/arch/x86/um/vdso/Makefile +++ b/arch/x86/um/vdso/Makefile @@ -42,7 +42,7 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE # optimize sibling calls. # CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ - $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \ + $(filter -g%,$(KBUILD_CFLAGS)) -fno-stack-protector \ -fno-omit-frame-pointer -foptimize-sibling-calls $(vobjs): KBUILD_CFLAGS += $(CFL) diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 084de77a109e..5f1db522d06b 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile @@ -9,9 +9,8 @@ CFLAGS_REMOVE_irq.o = -pg endif # Make sure early boot has no stackprotector -nostackp := $(call cc-option, -fno-stack-protector) -CFLAGS_enlighten_pv.o := $(nostackp) -CFLAGS_mmu_pv.o := $(nostackp) +CFLAGS_enlighten_pv.o := -fno-stack-protector +CFLAGS_mmu_pv.o := -fno-stack-protector obj-y += enlighten.o obj-y += mmu.o diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 4cce372edaf4..12c4436e77fb 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -30,7 +30,7 @@ KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ -include $(srctree)/drivers/firmware/efi/libstub/hidden.h \ -D__NO_FORTIFY \ $(call cc-option,-ffreestanding) \ - $(call cc-option,-fno-stack-protector) \ + -fno-stack-protector \ $(call cc-option,-fno-addrsig) \ -D__DISABLE_EXPORTS diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 0d322f3d90cd..c25c9a699b48 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -5,8 +5,7 @@ obj-y += mem-reservation.o obj-y += events/ obj-y += xenbus/ -nostackp := $(call cc-option, -fno-stack-protector) -CFLAGS_features.o := $(nostackp) +CFLAGS_features.o := -fno-stack-protector dom0-$(CONFIG_ARM64) += arm-device.o dom0-$(CONFIG_PCI) += pci.o diff --git a/lib/Makefile b/lib/Makefile index b1c42c10073b..0cda70649f1c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -22,7 +22,7 @@ KCOV_INSTRUMENT_fault-inject.o := n ifdef CONFIG_AMD_MEM_ENCRYPT KASAN_SANITIZE_string.o := n -CFLAGS_string.o := $(call cc-option, -fno-stack-protector) +CFLAGS_string.o := -fno-stack-protector endif # Used by KCSAN while enabled, avoid recursion. @@ -300,7 +300,7 @@ endif UBSAN_SANITIZE_ubsan.o := n KASAN_SANITIZE_ubsan.o := n KCSAN_SANITIZE_ubsan.o := n -CFLAGS_ubsan.o := $(call cc-option, -fno-stack-protector) $(DISABLE_STACKLEAK_PLUGIN) +CFLAGS_ubsan.o := -fno-stack-protector $(DISABLE_STACKLEAK_PLUGIN) obj-$(CONFIG_SBITMAP) += sbitmap.o diff --git a/mm/kasan/Makefile b/mm/kasan/Makefile index d532c2587731..370d970e5ab5 100644 --- a/mm/kasan/Makefile +++ b/mm/kasan/Makefile @@ -16,7 +16,7 @@ CFLAGS_REMOVE_tags_report.o = $(CC_FLAGS_FTRACE) # Function splitter causes unnecessary splits in __asan_load1/__asan_store1 # see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63533 CC_FLAGS_KASAN_RUNTIME := $(call cc-option, -fno-conserve-stack) -CC_FLAGS_KASAN_RUNTIME += $(call cc-option, -fno-stack-protector) +CC_FLAGS_KASAN_RUNTIME += -fno-stack-protector # Disable branch tracing to avoid recursion. CC_FLAGS_KASAN_RUNTIME += -DDISABLE_BRANCH_PROFILING From 685969e0bd732ff92e6626acc0c05f7204aa7ea6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 27 Jun 2020 03:59:13 +0900 Subject: [PATCH 101/242] kbuild: remove cc-option test of -ffreestanding Some Makefiles already pass -ffreestanding unconditionally. For example, arch/arm64/lib/Makefile, arch/x86/purgatory/Makefile. No problem report so far about hard-coding this option. So, we can assume all supported compilers know -ffreestanding. I confirmed GCC 4.8 and Clang manuals document this option. Get rid of cc-option from -ffreestanding. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Kees Cook Acked-by: Ard Biesheuvel --- arch/s390/Makefile | 2 +- arch/x86/Makefile | 2 +- arch/x86/boot/compressed/Makefile | 2 +- drivers/firmware/efi/libstub/Makefile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 8dfa2cf1f05c..ba94b03c8b2f 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -27,7 +27,7 @@ KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables -KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-option,-ffreestanding) +KBUILD_CFLAGS_DECOMPRESSOR += -ffreestanding KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 89c3cdfba753..edc68538a04e 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -36,7 +36,7 @@ REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -DDISABLE_BRANCH_PROFILING \ -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ -mno-mmx -mno-sse -REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding) +REALMODE_CFLAGS += -ffreestanding REALMODE_CFLAGS += -fno-stack-protector REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4)) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index c88a31569a5e..b7beabecef8a 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -35,7 +35,7 @@ cflags-$(CONFIG_X86_32) := -march=i386 cflags-$(CONFIG_X86_64) := -mcmodel=small KBUILD_CFLAGS += $(cflags-y) KBUILD_CFLAGS += -mno-mmx -mno-sse -KBUILD_CFLAGS += $(call cc-option,-ffreestanding) +KBUILD_CFLAGS += -ffreestanding KBUILD_CFLAGS += -fno-stack-protector KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS += $(call cc-disable-warning, gnu) diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 12c4436e77fb..2a156f7fec3b 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -29,7 +29,7 @@ cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ -include $(srctree)/drivers/firmware/efi/libstub/hidden.h \ -D__NO_FORTIFY \ - $(call cc-option,-ffreestanding) \ + -ffreestanding \ -fno-stack-protector \ $(call cc-option,-fno-addrsig) \ -D__DISABLE_EXPORTS From 55a87cd858578a4c3f0ab6e24696df1954e86f2c Mon Sep 17 00:00:00 2001 From: Domenico Andreoli Date: Sat, 27 Jun 2020 14:25:05 +0200 Subject: [PATCH 102/242] kbuild: buildtar: add dtbs support Make 'make tar-pkg' install dtbs. Signed-off-by: Domenico Andreoli Signed-off-by: Masahiro Yamada --- scripts/package/buildtar | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scripts/package/buildtar b/scripts/package/buildtar index fb1578e72ab9..936198a90477 100755 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -53,6 +53,18 @@ rm -rf -- "${tmpdir}" mkdir -p -- "${tmpdir}/boot" dirs=boot + +# +# Try to install dtbs +# +if grep -q '^CONFIG_OF_EARLY_FLATTREE=y' include/config/auto.conf; then + # Only some architectures with OF support have this target + if [ -d "${srctree}/arch/${SRCARCH}/boot/dts" ]; then + $MAKE ARCH="${ARCH}" -f ${srctree}/Makefile INSTALL_DTBS_PATH="${tmpdir}/boot/dtbs/${KERNELRELEASE}" dtbs_install + fi +fi + + # # Try to install modules # From a133954188887a830b5ce438a287a5e4e234b1be Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Wed, 1 Jul 2020 03:33:19 +0200 Subject: [PATCH 103/242] pinctrl: single: parse #pinctrl-cells = 2 If "pinctrl-single,pins" has 3 arguments (offset, conf, mux), then pcs_parse_one_pinctrl_entry() does an OR operation on conf and mux to get the value to store in the register. Signed-off-by: Drew Fustini Acked-by: Tony Lindgren Acked-by: Haojian Zhuang Link: https://lore.kernel.org/r/20200701013320.130441-2-drew@beagleboard.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index a9d511982780..17b32cafe5f0 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1017,10 +1017,17 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, break; } - /* Index plus one value cell */ offset = pinctrl_spec.args[0]; vals[found].reg = pcs->base + offset; - vals[found].val = pinctrl_spec.args[1]; + + switch (pinctrl_spec.args_count) { + case 2: + vals[found].val = pinctrl_spec.args[1]; + break; + case 3: + vals[found].val = (pinctrl_spec.args[1] | pinctrl_spec.args[2]); + break; + } dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x\n", pinctrl_spec.np, offset, pinctrl_spec.args[1]); From 27c90e5e48d008bfda1cf6108eb699697317c67b Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Wed, 1 Jul 2020 03:33:20 +0200 Subject: [PATCH 104/242] ARM: dts: am33xx-l4: change #pinctrl-cells from 1 to 2 Increase #pinctrl-cells to 2 so that mux and conf be kept separate. This requires the AM33XX_PADCONF macro in omap.h to also be modified to keep pin conf and pin mux values separate. Signed-off-by: Drew Fustini Acked-by: Tony Lindgren Acked-by: Haojian Zhuang Link: https://lore.kernel.org/r/20200701013320.130441-3-drew@beagleboard.org Signed-off-by: Linus Walleij --- arch/arm/boot/dts/am33xx-l4.dtsi | 2 +- include/dt-bindings/pinctrl/omap.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi index 7ff11d6bf0f2..dafd6e8b42a1 100644 --- a/arch/arm/boot/dts/am33xx-l4.dtsi +++ b/arch/arm/boot/dts/am33xx-l4.dtsi @@ -278,7 +278,7 @@ am33xx_pinmux: pinmux@800 { compatible = "pinctrl-single"; reg = <0x800 0x238>; - #pinctrl-cells = <1>; + #pinctrl-cells = <2>; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0x7f>; }; diff --git a/include/dt-bindings/pinctrl/omap.h b/include/dt-bindings/pinctrl/omap.h index 625718042413..2d2a8c737822 100644 --- a/include/dt-bindings/pinctrl/omap.h +++ b/include/dt-bindings/pinctrl/omap.h @@ -65,7 +65,7 @@ #define DM814X_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x0800) (val) #define DM816X_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x0800) (val) #define AM33XX_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x0800) (val) -#define AM33XX_PADCONF(pa, dir, mux) OMAP_IOPAD_OFFSET((pa), 0x0800) ((dir) | (mux)) +#define AM33XX_PADCONF(pa, conf, mux) OMAP_IOPAD_OFFSET((pa), 0x0800) (conf) (mux) /* * Macros to allow using the offset from the padconf physical address From bc6d201591344aa21d616179ee9ad406a7336267 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Wed, 17 Jun 2020 20:05:43 +0200 Subject: [PATCH 105/242] pinctrl: single: fix function name in documentation Use the correct the function name in the documentation for "pcs_parse_one_pinctrl_entry()". "smux_parse_one_pinctrl_entry()" appears to be an artifact from the development of a prior patch series ("simple pinmux driver") which transformed into pinctrl-single. Fixes: 8b8b091bf07f ("pinctrl: Add one-register-per-pin type device tree based pinctrl driver") Signed-off-by: Drew Fustini Link: https://lore.kernel.org/r/20200617180543.GA4186054@x1 Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 17b32cafe5f0..e6d1cf25782c 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -958,7 +958,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, } /** - * smux_parse_one_pinctrl_entry() - parses a device tree mux entry + * pcs_parse_one_pinctrl_entry() - parses a device tree mux entry * @pctldev: pin controller device * @pcs: pinctrl driver instance * @np: device node of the mux entry From f088ab6d4f4ce49d422c220074b7e605f54e2299 Mon Sep 17 00:00:00 2001 From: Hyeonki Hong Date: Thu, 18 Jun 2020 11:59:22 +0900 Subject: [PATCH 106/242] pinctrl: meson: fix drive strength register and bit calculation If a GPIO bank has greater than 16 pins, PAD_DS_REG is split into two or more registers. However, when register and bit were calculated, the first register defined in the bank was used, and the bit was calculated based on the first pin. This causes problems in setting the driving strength. The following method was used to solve this problem: A bit is calculated first using predefined strides. Then, If the bit is 32 or more, the register is changed by the quotient of the bit divided by 32. And the bit is set to the remainder. Signed-off-by: Hyeonki Hong Link: https://lore.kernel.org/r/20200618025916.GA19368@home-desktop Signed-off-by: Linus Walleij --- drivers/pinctrl/meson/pinctrl-meson.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 079f8ee8d353..20683cd072bb 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -56,6 +56,10 @@ #include "../pinctrl-utils.h" #include "pinctrl-meson.h" +static const unsigned int meson_bit_strides[] = { + 1, 1, 1, 1, 1, 2, 1 +}; + /** * meson_get_bank() - find the bank containing a given pin * @@ -96,8 +100,9 @@ static void meson_calc_reg_and_bit(struct meson_bank *bank, unsigned int pin, { struct meson_reg_desc *desc = &bank->regs[reg_type]; - *reg = desc->reg * 4; - *bit = desc->bit + pin - bank->first; + *bit = (desc->bit + pin - bank->first) * meson_bit_strides[reg_type]; + *reg = (desc->reg + (*bit / 32)) * 4; + *bit &= 0x1f; } static int meson_get_groups_count(struct pinctrl_dev *pcdev) @@ -314,7 +319,6 @@ static int meson_pinconf_set_drive_strength(struct meson_pinctrl *pc, return ret; meson_calc_reg_and_bit(bank, pin, REG_DS, ®, &bit); - bit = bit << 1; if (drive_strength_ua <= 500) { ds_val = MESON_PINCONF_DRV_500UA; @@ -441,7 +445,6 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc, return ret; meson_calc_reg_and_bit(bank, pin, REG_DS, ®, &bit); - bit = bit << 1; ret = regmap_read(pc->reg_ds, reg, &val); if (ret) From f8a7476077eaac1ba9dc18f70c99d2311edd59ee Mon Sep 17 00:00:00 2001 From: Lars Povlsen Date: Mon, 15 Jun 2020 15:32:37 +0200 Subject: [PATCH 107/242] pinctrl: ocelot: Add Sparx5 SoC support This add support for Sparx5 pinctrl, using the ocelot drives as basis. It adds pinconfig support as well, as supported by the platform. Signed-off-by: Lars Povlsen Reviewed-by: Alexandre Belloni Link: https://lore.kernel.org/r/20200615133242.24911-6-lars.povlsen@microchip.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ocelot.c | 430 ++++++++++++++++++++++++++++++- 1 file changed, 429 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c index 95c225bc7572..425a3d764f00 100644 --- a/drivers/pinctrl/pinctrl-ocelot.c +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -25,6 +25,23 @@ #include "pinconf.h" #include "pinmux.h" +#define ocelot_clrsetbits(addr, clear, set) \ + writel((readl(addr) & ~(clear)) | (set), (addr)) + +/* PINCONFIG bits (sparx5 only) */ +enum { + PINCONF_BIAS, + PINCONF_SCHMITT, + PINCONF_DRIVE_STRENGTH, +}; + +#define BIAS_PD_BIT BIT(4) +#define BIAS_PU_BIT BIT(3) +#define BIAS_BITS (BIAS_PD_BIT|BIAS_PU_BIT) +#define SCHMITT_BIT BIT(2) +#define DRIVE_BITS GENMASK(1, 0) + +/* GPIO standard registers */ #define OCELOT_GPIO_OUT_SET 0x0 #define OCELOT_GPIO_OUT_CLR 0x4 #define OCELOT_GPIO_OUT 0x8 @@ -42,12 +59,17 @@ enum { FUNC_NONE, FUNC_GPIO, + FUNC_IRQ0, FUNC_IRQ0_IN, FUNC_IRQ0_OUT, + FUNC_IRQ1, FUNC_IRQ1_IN, FUNC_IRQ1_OUT, + FUNC_EXT_IRQ, FUNC_MIIM, + FUNC_PHY_LED, FUNC_PCI_WAKE, + FUNC_MD, FUNC_PTP0, FUNC_PTP1, FUNC_PTP2, @@ -59,24 +81,36 @@ enum { FUNC_SG1, FUNC_SG2, FUNC_SI, + FUNC_SI2, FUNC_TACHO, FUNC_TWI, FUNC_TWI2, + FUNC_TWI3, FUNC_TWI_SCL_M, FUNC_UART, FUNC_UART2, + FUNC_UART3, + FUNC_PLL_STAT, + FUNC_EMMC, + FUNC_REF_CLK, + FUNC_RCVRD_CLK, FUNC_MAX }; static const char *const ocelot_function_names[] = { [FUNC_NONE] = "none", [FUNC_GPIO] = "gpio", + [FUNC_IRQ0] = "irq0", [FUNC_IRQ0_IN] = "irq0_in", [FUNC_IRQ0_OUT] = "irq0_out", + [FUNC_IRQ1] = "irq1", [FUNC_IRQ1_IN] = "irq1_in", [FUNC_IRQ1_OUT] = "irq1_out", + [FUNC_EXT_IRQ] = "ext_irq", [FUNC_MIIM] = "miim", + [FUNC_PHY_LED] = "phy_led", [FUNC_PCI_WAKE] = "pci_wake", + [FUNC_MD] = "md", [FUNC_PTP0] = "ptp0", [FUNC_PTP1] = "ptp1", [FUNC_PTP2] = "ptp2", @@ -88,12 +122,19 @@ static const char *const ocelot_function_names[] = { [FUNC_SG1] = "sg1", [FUNC_SG2] = "sg2", [FUNC_SI] = "si", + [FUNC_SI2] = "si2", [FUNC_TACHO] = "tacho", [FUNC_TWI] = "twi", [FUNC_TWI2] = "twi2", + [FUNC_TWI3] = "twi3", [FUNC_TWI_SCL_M] = "twi_scl_m", [FUNC_UART] = "uart", [FUNC_UART2] = "uart2", + [FUNC_UART3] = "uart3", + [FUNC_PLL_STAT] = "pll_stat", + [FUNC_EMMC] = "emmc", + [FUNC_REF_CLK] = "ref_clk", + [FUNC_RCVRD_CLK] = "rcvrd_clk", }; struct ocelot_pmx_func { @@ -111,6 +152,7 @@ struct ocelot_pinctrl { struct pinctrl_dev *pctl; struct gpio_chip gpio_chip; struct regmap *map; + void __iomem *pincfg; struct pinctrl_desc *desc; struct ocelot_pmx_func func[FUNC_MAX]; u8 stride; @@ -324,6 +366,152 @@ static const struct pinctrl_pin_desc jaguar2_pins[] = { JAGUAR2_PIN(63), }; +#define SPARX5_P(p, f0, f1, f2) \ +static struct ocelot_pin_caps sparx5_pin_##p = { \ + .pin = p, \ + .functions = { \ + FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2 \ + }, \ +} + +SPARX5_P(0, SG0, PLL_STAT, NONE); +SPARX5_P(1, SG0, NONE, NONE); +SPARX5_P(2, SG0, NONE, NONE); +SPARX5_P(3, SG0, NONE, NONE); +SPARX5_P(4, SG1, NONE, NONE); +SPARX5_P(5, SG1, NONE, NONE); +SPARX5_P(6, IRQ0_IN, IRQ0_OUT, SFP); +SPARX5_P(7, IRQ1_IN, IRQ1_OUT, SFP); +SPARX5_P(8, PTP0, NONE, SFP); +SPARX5_P(9, PTP1, SFP, TWI_SCL_M); +SPARX5_P(10, UART, NONE, NONE); +SPARX5_P(11, UART, NONE, NONE); +SPARX5_P(12, SG1, NONE, NONE); +SPARX5_P(13, SG1, NONE, NONE); +SPARX5_P(14, TWI, TWI_SCL_M, NONE); +SPARX5_P(15, TWI, NONE, NONE); +SPARX5_P(16, SI, TWI_SCL_M, SFP); +SPARX5_P(17, SI, TWI_SCL_M, SFP); +SPARX5_P(18, SI, TWI_SCL_M, SFP); +SPARX5_P(19, PCI_WAKE, TWI_SCL_M, SFP); +SPARX5_P(20, IRQ0_OUT, TWI_SCL_M, SFP); +SPARX5_P(21, IRQ1_OUT, TACHO, SFP); +SPARX5_P(22, TACHO, IRQ0_OUT, TWI_SCL_M); +SPARX5_P(23, PWM, UART3, TWI_SCL_M); +SPARX5_P(24, PTP2, UART3, TWI_SCL_M); +SPARX5_P(25, PTP3, SI, TWI_SCL_M); +SPARX5_P(26, UART2, SI, TWI_SCL_M); +SPARX5_P(27, UART2, SI, TWI_SCL_M); +SPARX5_P(28, TWI2, SI, SFP); +SPARX5_P(29, TWI2, SI, SFP); +SPARX5_P(30, SG2, SI, PWM); +SPARX5_P(31, SG2, SI, TWI_SCL_M); +SPARX5_P(32, SG2, SI, TWI_SCL_M); +SPARX5_P(33, SG2, SI, SFP); +SPARX5_P(34, NONE, TWI_SCL_M, EMMC); +SPARX5_P(35, SFP, TWI_SCL_M, EMMC); +SPARX5_P(36, SFP, TWI_SCL_M, EMMC); +SPARX5_P(37, SFP, NONE, EMMC); +SPARX5_P(38, NONE, TWI_SCL_M, EMMC); +SPARX5_P(39, SI2, TWI_SCL_M, EMMC); +SPARX5_P(40, SI2, TWI_SCL_M, EMMC); +SPARX5_P(41, SI2, TWI_SCL_M, EMMC); +SPARX5_P(42, SI2, TWI_SCL_M, EMMC); +SPARX5_P(43, SI2, TWI_SCL_M, EMMC); +SPARX5_P(44, SI, SFP, EMMC); +SPARX5_P(45, SI, SFP, EMMC); +SPARX5_P(46, NONE, SFP, EMMC); +SPARX5_P(47, NONE, SFP, EMMC); +SPARX5_P(48, TWI3, SI, SFP); +SPARX5_P(49, TWI3, NONE, SFP); +SPARX5_P(50, SFP, NONE, TWI_SCL_M); +SPARX5_P(51, SFP, SI, TWI_SCL_M); +SPARX5_P(52, SFP, MIIM, TWI_SCL_M); +SPARX5_P(53, SFP, MIIM, TWI_SCL_M); +SPARX5_P(54, SFP, PTP2, TWI_SCL_M); +SPARX5_P(55, SFP, PTP3, PCI_WAKE); +SPARX5_P(56, MIIM, SFP, TWI_SCL_M); +SPARX5_P(57, MIIM, SFP, TWI_SCL_M); +SPARX5_P(58, MIIM, SFP, TWI_SCL_M); +SPARX5_P(59, MIIM, SFP, NONE); +SPARX5_P(60, RECO_CLK, NONE, NONE); +SPARX5_P(61, RECO_CLK, NONE, NONE); +SPARX5_P(62, RECO_CLK, PLL_STAT, NONE); +SPARX5_P(63, RECO_CLK, NONE, NONE); + +#define SPARX5_PIN(n) { \ + .number = n, \ + .name = "GPIO_"#n, \ + .drv_data = &sparx5_pin_##n \ +} + +static const struct pinctrl_pin_desc sparx5_pins[] = { + SPARX5_PIN(0), + SPARX5_PIN(1), + SPARX5_PIN(2), + SPARX5_PIN(3), + SPARX5_PIN(4), + SPARX5_PIN(5), + SPARX5_PIN(6), + SPARX5_PIN(7), + SPARX5_PIN(8), + SPARX5_PIN(9), + SPARX5_PIN(10), + SPARX5_PIN(11), + SPARX5_PIN(12), + SPARX5_PIN(13), + SPARX5_PIN(14), + SPARX5_PIN(15), + SPARX5_PIN(16), + SPARX5_PIN(17), + SPARX5_PIN(18), + SPARX5_PIN(19), + SPARX5_PIN(20), + SPARX5_PIN(21), + SPARX5_PIN(22), + SPARX5_PIN(23), + SPARX5_PIN(24), + SPARX5_PIN(25), + SPARX5_PIN(26), + SPARX5_PIN(27), + SPARX5_PIN(28), + SPARX5_PIN(29), + SPARX5_PIN(30), + SPARX5_PIN(31), + SPARX5_PIN(32), + SPARX5_PIN(33), + SPARX5_PIN(34), + SPARX5_PIN(35), + SPARX5_PIN(36), + SPARX5_PIN(37), + SPARX5_PIN(38), + SPARX5_PIN(39), + SPARX5_PIN(40), + SPARX5_PIN(41), + SPARX5_PIN(42), + SPARX5_PIN(43), + SPARX5_PIN(44), + SPARX5_PIN(45), + SPARX5_PIN(46), + SPARX5_PIN(47), + SPARX5_PIN(48), + SPARX5_PIN(49), + SPARX5_PIN(50), + SPARX5_PIN(51), + SPARX5_PIN(52), + SPARX5_PIN(53), + SPARX5_PIN(54), + SPARX5_PIN(55), + SPARX5_PIN(56), + SPARX5_PIN(57), + SPARX5_PIN(58), + SPARX5_PIN(59), + SPARX5_PIN(60), + SPARX5_PIN(61), + SPARX5_PIN(62), + SPARX5_PIN(63), +}; + static int ocelot_get_functions_count(struct pinctrl_dev *pctldev) { return ARRAY_SIZE(ocelot_function_names); @@ -382,6 +570,7 @@ static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, * ALT[1] * This is racy because both registers can't be updated at the same time * but it doesn't matter much for now. + * Note: ALT0/ALT1 are organized specially for 64 gpio targets */ regmap_update_bits(info->map, REG_ALT(0, info, pin->pin), BIT(p), f << p); @@ -458,6 +647,219 @@ static int ocelot_pctl_get_group_pins(struct pinctrl_dev *pctldev, return 0; } +static int ocelot_hw_get_value(struct ocelot_pinctrl *info, + unsigned int pin, + unsigned int reg, + int *val) +{ + int ret = -EOPNOTSUPP; + + if (info->pincfg) { + u32 regcfg = readl(info->pincfg + (pin * sizeof(u32))); + + ret = 0; + switch (reg) { + case PINCONF_BIAS: + *val = regcfg & BIAS_BITS; + break; + + case PINCONF_SCHMITT: + *val = regcfg & SCHMITT_BIT; + break; + + case PINCONF_DRIVE_STRENGTH: + *val = regcfg & DRIVE_BITS; + break; + + default: + ret = -EOPNOTSUPP; + break; + } + } + return ret; +} + +static int ocelot_hw_set_value(struct ocelot_pinctrl *info, + unsigned int pin, + unsigned int reg, + int val) +{ + int ret = -EOPNOTSUPP; + + if (info->pincfg) { + void __iomem *regaddr = info->pincfg + (pin * sizeof(u32)); + + ret = 0; + switch (reg) { + case PINCONF_BIAS: + ocelot_clrsetbits(regaddr, BIAS_BITS, val); + break; + + case PINCONF_SCHMITT: + ocelot_clrsetbits(regaddr, SCHMITT_BIT, val); + break; + + case PINCONF_DRIVE_STRENGTH: + if (val <= 3) + ocelot_clrsetbits(regaddr, DRIVE_BITS, val); + else + ret = -EINVAL; + break; + + default: + ret = -EOPNOTSUPP; + break; + } + } + return ret; +} + +static int ocelot_pinconf_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + u32 param = pinconf_to_config_param(*config); + int val, err; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + err = ocelot_hw_get_value(info, pin, PINCONF_BIAS, &val); + if (err) + return err; + if (param == PIN_CONFIG_BIAS_DISABLE) + val = (val == 0 ? true : false); + else if (param == PIN_CONFIG_BIAS_PULL_DOWN) + val = (val & BIAS_PD_BIT ? true : false); + else /* PIN_CONFIG_BIAS_PULL_UP */ + val = (val & BIAS_PU_BIT ? true : false); + break; + + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + err = ocelot_hw_get_value(info, pin, PINCONF_SCHMITT, &val); + if (err) + return err; + + val = (val & SCHMITT_BIT ? true : false); + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + err = ocelot_hw_get_value(info, pin, PINCONF_DRIVE_STRENGTH, + &val); + if (err) + return err; + break; + + case PIN_CONFIG_OUTPUT: + err = regmap_read(info->map, REG(OCELOT_GPIO_OUT, info, pin), + &val); + if (err) + return err; + val = !!(val & BIT(pin % 32)); + break; + + case PIN_CONFIG_INPUT_ENABLE: + case PIN_CONFIG_OUTPUT_ENABLE: + err = regmap_read(info->map, REG(OCELOT_GPIO_OE, info, pin), + &val); + if (err) + return err; + val = val & BIT(pin % 32); + if (param == PIN_CONFIG_OUTPUT_ENABLE) + val = !!val; + else + val = !val; + break; + + default: + return -EOPNOTSUPP; + } + + *config = pinconf_to_config_packed(param, val); + + return 0; +} + +static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + u32 param, arg, p; + int cfg, err = 0; + + for (cfg = 0; cfg < num_configs; cfg++) { + param = pinconf_to_config_param(configs[cfg]); + arg = pinconf_to_config_argument(configs[cfg]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 : + (param == PIN_CONFIG_BIAS_PULL_UP) ? BIAS_PU_BIT : + BIAS_PD_BIT; + + err = ocelot_hw_set_value(info, pin, PINCONF_BIAS, arg); + if (err) + goto err; + + break; + + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + arg = arg ? SCHMITT_BIT : 0; + err = ocelot_hw_set_value(info, pin, PINCONF_SCHMITT, + arg); + if (err) + goto err; + + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + err = ocelot_hw_set_value(info, pin, + PINCONF_DRIVE_STRENGTH, + arg); + if (err) + goto err; + + break; + + case PIN_CONFIG_OUTPUT_ENABLE: + case PIN_CONFIG_INPUT_ENABLE: + case PIN_CONFIG_OUTPUT: + p = pin % 32; + if (arg) + regmap_write(info->map, + REG(OCELOT_GPIO_OUT_SET, info, + pin), + BIT(p)); + else + regmap_write(info->map, + REG(OCELOT_GPIO_OUT_CLR, info, + pin), + BIT(p)); + regmap_update_bits(info->map, + REG(OCELOT_GPIO_OE, info, pin), + BIT(p), + param == PIN_CONFIG_INPUT_ENABLE ? + 0 : BIT(p)); + break; + + default: + err = -EOPNOTSUPP; + } + } +err: + return err; +} + +static const struct pinconf_ops ocelot_confops = { + .is_generic = true, + .pin_config_get = ocelot_pinconf_get, + .pin_config_set = ocelot_pinconf_set, + .pin_config_config_dbg_show = pinconf_generic_dump_config, +}; + static const struct pinctrl_ops ocelot_pctl_ops = { .get_groups_count = ocelot_pctl_get_groups_count, .get_group_name = ocelot_pctl_get_group_name, @@ -484,6 +886,16 @@ static struct pinctrl_desc jaguar2_desc = { .owner = THIS_MODULE, }; +static struct pinctrl_desc sparx5_desc = { + .name = "sparx5-pinctrl", + .pins = sparx5_pins, + .npins = ARRAY_SIZE(sparx5_pins), + .pctlops = &ocelot_pctl_ops, + .pmxops = &ocelot_pmx_ops, + .confops = &ocelot_confops, + .owner = THIS_MODULE, +}; + static int ocelot_create_group_func_map(struct device *dev, struct ocelot_pinctrl *info) { @@ -511,7 +923,8 @@ static int ocelot_create_group_func_map(struct device *dev, } for (i = 0; i < npins; i++) - info->func[f].groups[i] = info->desc->pins[pins[i]].name; + info->func[f].groups[i] = + info->desc->pins[pins[i]].name; } kfree(pins); @@ -744,6 +1157,7 @@ static int ocelot_gpiochip_register(struct platform_device *pdev, static const struct of_device_id ocelot_pinctrl_of_match[] = { { .compatible = "mscc,ocelot-pinctrl", .data = &ocelot_desc }, { .compatible = "mscc,jaguar2-pinctrl", .data = &jaguar2_desc }, + { .compatible = "microchip,sparx5-pinctrl", .data = &sparx5_desc }, {}, }; @@ -752,6 +1166,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct ocelot_pinctrl *info; void __iomem *base; + struct resource *res; int ret; struct regmap_config regmap_config = { .reg_bits = 32, @@ -773,6 +1188,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) } info->stride = 1 + (info->desc->npins - 1) / 32; + regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4; info->map = devm_regmap_init_mmio(dev, base, ®map_config); @@ -783,6 +1199,16 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) dev_set_drvdata(dev, info->map); info->dev = dev; + /* Pinconf registers */ + if (info->desc->confops) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + dev_dbg(dev, "Failed to ioremap config registers (no extended pinconf)\n"); + else + info->pincfg = base; + } + ret = ocelot_pinctrl_register(pdev, info); if (ret) return ret; @@ -791,6 +1217,8 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) if (ret) return ret; + dev_info(dev, "driver registered\n"); + return 0; } From 17cc38e7846b462e03b718d1ca231da96809407d Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 22 Jun 2020 21:25:51 +0200 Subject: [PATCH 108/242] pinctrl: qcom: spmi-gpio: Add pm660(l) compatibility Add support for pm660(l) SPMI GPIOs. The PMICs feature 13 and 12 GPIOs respectively, though with a lot of holes inbetween. Signed-off-by: Konrad Dybcio Acked-by: Bjorn Andersson Link: https://lore.kernel.org/r/20200622192558.152828-2-konradybcio@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index fe0be8a6ebb7..95ca66e24e7c 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1118,6 +1118,10 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pma8084-gpio", .data = (void *) 22 }, /* pms405 has 12 GPIOs with holes on 1, 9, and 10 */ { .compatible = "qcom,pms405-gpio", .data = (void *) 12 }, + /* pm660 has 13 GPIOs with holes on 1, 5, 6, 7, 8 and 10 */ + { .compatible = "qcom,pm660-gpio", .data = (void *) 13 }, + /* pm660l has 12 GPIOs with holes on 1, 2, 10, 11 and 12 */ + { .compatible = "qcom,pm660l-gpio", .data = (void *) 12 }, /* pm8150 has 10 GPIOs with holes on 2, 5, 7 and 8 */ { .compatible = "qcom,pm8150-gpio", .data = (void *) 10 }, /* pm8150b has 12 GPIOs with holes on 3, r and 7 */ From 7203d3684eafd711bfa1ebda7d36b89f4ac20c4c Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 22 Jun 2020 21:25:52 +0200 Subject: [PATCH 109/242] Documentation: Document pm660(l) SPMI GPIOs compatible Signed-off-by: Konrad Dybcio Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20200622192558.152828-3-konradybcio@gmail.com Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt index 7be5de8d253f..c3d1914381ae 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -23,6 +23,8 @@ PMIC's from Qualcomm. "qcom,pmi8994-gpio" "qcom,pmi8998-gpio" "qcom,pms405-gpio" + "qcom,pm660-gpio" + "qcom,pm660l-gpio" "qcom,pm8150-gpio" "qcom,pm8150b-gpio" "qcom,pm6150-gpio" From b77eab32c4492178adfb7ea81569c311120f5682 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 22 Jun 2020 13:37:40 +0200 Subject: [PATCH 110/242] dt-bindings: pinctrl: Convert ingenic,pinctrl.txt to YAML Convert the ingenic,pinctrl.txt doc file to ingenic,pinctrl.yaml. In the process, some compatible strings now require a fallback, as the corresponding SoCs are pin-compatible with their fallback variant. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20200622113740.46450-1-paul@crapouillou.net Signed-off-by: Linus Walleij --- .../bindings/pinctrl/ingenic,pinctrl.txt | 81 ----------- .../bindings/pinctrl/ingenic,pinctrl.yaml | 136 ++++++++++++++++++ 2 files changed, 136 insertions(+), 81 deletions(-) delete mode 100644 Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt create mode 100644 Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt deleted file mode 100644 index d9b2100c98e8..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.txt +++ /dev/null @@ -1,81 +0,0 @@ -Ingenic XBurst pin controller - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -For the XBurst SoCs, pin control is tightly bound with GPIO ports. All pins may -be used as GPIOs, multiplexed device functions are configured within the -GPIO port configuration registers and it is typical to refer to pins using the -naming scheme "PxN" where x is a character identifying the GPIO port with -which the pin is associated and N is an integer from 0 to 31 identifying the -pin within that GPIO port. For example PA0 is the first pin in GPIO port A, and -PB31 is the last pin in GPIO port B. The jz4740, the x1000 and the x1830 -contains 4 GPIO ports, PA to PD, for a total of 128 pins. The jz4760, the -jz4770 and the jz4780 contains 6 GPIO ports, PA to PF, for a total of 192 pins. - - -Required properties: --------------------- - - - compatible: One of: - - "ingenic,jz4740-pinctrl" - - "ingenic,jz4725b-pinctrl" - - "ingenic,jz4760-pinctrl" - - "ingenic,jz4760b-pinctrl" - - "ingenic,jz4770-pinctrl" - - "ingenic,jz4780-pinctrl" - - "ingenic,x1000-pinctrl" - - "ingenic,x1000e-pinctrl" - - "ingenic,x1500-pinctrl" - - "ingenic,x1830-pinctrl" - - reg: Address range of the pinctrl registers. - - -Required properties for sub-nodes (GPIO chips): ------------------------------------------------ - - - compatible: Must contain one of: - - "ingenic,jz4740-gpio" - - "ingenic,jz4760-gpio" - - "ingenic,jz4770-gpio" - - "ingenic,jz4780-gpio" - - "ingenic,x1000-gpio" - - "ingenic,x1830-gpio" - - reg: The GPIO bank number. - - interrupt-controller: Marks the device node as an interrupt controller. - - interrupts: Interrupt specifier for the controllers interrupt. - - #interrupt-cells: Should be 2. Refer to - ../interrupt-controller/interrupts.txt for more details. - - gpio-controller: Marks the device node as a GPIO controller. - - #gpio-cells: Should be 2. The first cell is the GPIO number and the second - cell specifies GPIO flags, as defined in . Only the - GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags are supported. - - gpio-ranges: Range of pins managed by the GPIO controller. Refer to - ../gpio/gpio.txt for more details. - - -Example: --------- - -pinctrl: pin-controller@10010000 { - compatible = "ingenic,jz4740-pinctrl"; - reg = <0x10010000 0x400>; - #address-cells = <1>; - #size-cells = <0>; - - gpa: gpio@0 { - compatible = "ingenic,jz4740-gpio"; - reg = <0>; - - gpio-controller; - gpio-ranges = <&pinctrl 0 0 32>; - #gpio-cells = <2>; - - interrupt-controller; - #interrupt-cells = <2>; - - interrupt-parent = <&intc>; - interrupts = <28>; - }; -}; diff --git a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml new file mode 100644 index 000000000000..5be2b1e95b36 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml @@ -0,0 +1,136 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/ingenic,pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ingenic SoCs pin controller devicetree bindings + +description: > + Please refer to pinctrl-bindings.txt in this directory for details of the + common pinctrl bindings used by client devices, including the meaning of the + phrase "pin configuration node". + + For the Ingenic SoCs, pin control is tightly bound with GPIO ports. All pins + may be used as GPIOs, multiplexed device functions are configured within the + GPIO port configuration registers and it is typical to refer to pins using the + naming scheme "PxN" where x is a character identifying the GPIO port with + which the pin is associated and N is an integer from 0 to 31 identifying the + pin within that GPIO port. For example PA0 is the first pin in GPIO port A, + and PB31 is the last pin in GPIO port B. The JZ4740, the X1000 and the X1830 + contains 4 GPIO ports, PA to PD, for a total of 128 pins. The JZ4760, the + JZ4770 and the JZ4780 contains 6 GPIO ports, PA to PF, for a total of 192 + pins. + +maintainers: + - Paul Cercueil + +properties: + nodename: + pattern: "^pinctrl@[0-9a-f]+$" + + compatible: + oneOf: + - enum: + - ingenic,jz4740-pinctrl + - ingenic,jz4725b-pinctrl + - ingenic,jz4760-pinctrl + - ingenic,jz4770-pinctrl + - ingenic,jz4780-pinctrl + - ingenic,x1000-pinctrl + - ingenic,x1500-pinctrl + - ingenic,x1830-pinctrl + - items: + - const: ingenic,jz4760b-pinctrl + - const: ingenic,jz4760-pinctrl + - items: + - const: ingenic,x1000e-pinctrl + - const: ingenic,x1000-pinctrl + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^gpio@[0-9]$": + type: object + properties: + compatible: + enum: + - ingenic,jz4740-gpio + - ingenic,jz4725b-gpio + - ingenic,jz4760-gpio + - ingenic,jz4770-gpio + - ingenic,jz4780-gpio + - ingenic,x1000-gpio + - ingenic,x1500-gpio + - ingenic,x1830-gpio + + reg: + items: + - description: The GPIO bank number + + gpio-controller: true + + "#gpio-cells": + const: 2 + + gpio-ranges: + maxItems: 1 + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + description: + Refer to ../interrupt-controller/interrupts.txt for more details. + + interrupts: + maxItems: 1 + + required: + - compatible + - reg + - gpio-controller + - "#gpio-cells" + - interrupts + - interrupt-controller + - "#interrupt-cells" + + additionalProperties: false + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +examples: + - | + pin-controller@10010000 { + compatible = "ingenic,jz4770-pinctrl"; + reg = <0x10010000 0x600>; + + #address-cells = <1>; + #size-cells = <0>; + + gpio@0 { + compatible = "ingenic,jz4770-gpio"; + reg = <0>; + + gpio-controller; + gpio-ranges = <&pinctrl 0 0 32>; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + + interrupt-parent = <&intc>; + interrupts = <17>; + }; + }; From 1c95348ba327fe8621d3680890c2341523d3524a Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 22 Jun 2020 23:45:47 +0200 Subject: [PATCH 111/242] pinctrl: ingenic: Enhance support for IRQ_TYPE_EDGE_BOTH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ingenic SoCs don't natively support registering an interrupt for both rising and falling edges. This has to be emulated in software. Until now, this was emulated by switching back and forth between IRQ_TYPE_EDGE_RISING and IRQ_TYPE_EDGE_FALLING according to the level of the GPIO. While this worked most of the time, when used with GPIOs that need debouncing, some events would be lost. For instance, between the time a falling-edge interrupt happens and the interrupt handler configures the hardware for rising-edge, the level of the pin may have already risen, and the rising-edge event is lost. To address that issue, instead of switching back and forth between IRQ_TYPE_EDGE_RISING and IRQ_TYPE_EDGE_FALLING, we now switch back and forth between IRQ_TYPE_LEVEL_LOW and IRQ_TYPE_LEVEL_HIGH. Since we always switch in the interrupt handler, they actually permit to detect level changes. In the example above, if the pin level rises before switching the IRQ type from IRQ_TYPE_LEVEL_LOW to IRQ_TYPE_LEVEL_HIGH, a new interrupt will raise as soon as the handler exits, and the rising-edge event will be properly detected. Fixes: e72394e2ea19 ("pinctrl: ingenic: Merge GPIO functionality") Reported-by: João Henrique Signed-off-by: Paul Cercueil Tested-by: João Henrique Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200622214548.265417-1-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index fc0d10411aa9..241e563d5814 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -1813,9 +1813,9 @@ static void ingenic_gpio_irq_ack(struct irq_data *irqd) */ high = ingenic_gpio_get_value(jzgc, irq); if (high) - irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING); + irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_LOW); else - irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING); + irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_HIGH); } if (jzgc->jzpc->info->version >= ID_JZ4760) @@ -1851,7 +1851,7 @@ static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type) */ bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq); - type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING; + type = high ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH; } irq_set_type(jzgc, irqd->hwirq, type); From 84e7a946da71f678affacea301f6d5cb4d9784e8 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 22 Jun 2020 23:45:48 +0200 Subject: [PATCH 112/242] pinctrl: ingenic: Properly detect GPIO direction when configured for IRQ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PAT1 register contains information about the IRQ type (edge/level) for input GPIOs with IRQ enabled, and the direction for non-IRQ GPIOs. So it makes sense to read it only if the GPIO has no interrupt configured, otherwise input GPIOs configured for level IRQs are misdetected as output GPIOs. Fixes: ebd6651418b6 ("pinctrl: ingenic: Implement .get_direction for GPIO chips") Reported-by: João Henrique Signed-off-by: Paul Cercueil Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200622214548.265417-2-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 241e563d5814..a8d1b53ec4c1 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -1958,7 +1958,8 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) unsigned int pin = gc->base + offset; if (jzpc->info->version >= ID_JZ4760) { - if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1)) + if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_INT) || + ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1)) return GPIO_LINE_DIRECTION_IN; return GPIO_LINE_DIRECTION_OUT; } From 5f4962dd55d86d6a3ba5ddbfaf2d793e3b676a20 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Fri, 26 Jun 2020 14:10:26 -0700 Subject: [PATCH 113/242] pinctrl: amd: Honor IRQ trigger type requested by the caller This change drops the override in `amd_gpio_irq_set_type()` that ignores the IRQ trigger type settings from the caller. The device driver (caller) is in a better position to identify the right trigger type for the device based on the usage as well as the information exposed by the BIOS. There are instances where the device driver might want to configure the trigger type differently in different modes. An example of this is gpio-keys driver which configures IRQ type as trigger on both edges (to identify assert and deassert events) when in S0 and reconfigures the trigger type using the information provided by the BIOS when going into suspend to ensure that the wake happens on the required edge. This override in `amd_gpio_irq_set_type()` prevents the caller from being able to reconfigure trigger type once it is set either based on ACPI information or the type used by the first caller for IRQ on a given GPIO line. Without this change, pen-insert gpio key (used by garaged stylus on a Chromebook) works fine in S0 (i.e. insert and eject events are correctly identified), however, BIOS configuration for wake on only pen eject i.e. only-rising edge or only-falling edge is not honored. With this change, it was verified that pen-insert gpio key behavior is correct in both S0 and for wakeup from S3. Signed-off-by: Furquan Shaikh Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20200626211026.513520-1-furquan@google.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-amd.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 1fe62a35bb12..c34e6a950b3f 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -417,22 +417,13 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type) { int ret = 0; u32 pin_reg, pin_reg_irq_en, mask; - unsigned long flags, irq_flags; + unsigned long flags; struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct amd_gpio *gpio_dev = gpiochip_get_data(gc); raw_spin_lock_irqsave(&gpio_dev->lock, flags); pin_reg = readl(gpio_dev->base + (d->hwirq)*4); - /* Ignore the settings coming from the client and - * read the values from the ACPI tables - * while setting the trigger type - */ - - irq_flags = irq_get_trigger_type(d->irq); - if (irq_flags != IRQ_TYPE_NONE) - type = irq_flags; - switch (type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_RISING: pin_reg &= ~BIT(LEVEL_TRIG_OFF); From d2e639d6ad60fc164b75462bcdf8a43331116fd8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 24 Jun 2020 16:26:40 +0300 Subject: [PATCH 114/242] mtd: rawnand: ingenic: cleanup ARRAY_SIZE() vs sizeof() use The ARRAY_SIZE() is the number of elements but we want to use sizeof() here for the number of bytes. Fortunately, they are the same thing because it's an array of u8 so this has no effect on runtime. Signed-off-by: Dan Carpenter Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200624132640.GC9972@mwanda --- drivers/mtd/nand/raw/ingenic/jz4740_ecc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/ingenic/jz4740_ecc.c b/drivers/mtd/nand/raw/ingenic/jz4740_ecc.c index 13fea645c7f0..54e377754a6c 100644 --- a/drivers/mtd/nand/raw/ingenic/jz4740_ecc.c +++ b/drivers/mtd/nand/raw/ingenic/jz4740_ecc.c @@ -90,8 +90,8 @@ static int jz4740_ecc_calculate(struct ingenic_ecc *ecc, * If the written data is completely 0xff, we also want to write 0xff as * ECC, otherwise we will get in trouble when doing subpage writes. */ - if (memcmp(ecc_code, empty_block_ecc, ARRAY_SIZE(empty_block_ecc)) == 0) - memset(ecc_code, 0xff, ARRAY_SIZE(empty_block_ecc)); + if (memcmp(ecc_code, empty_block_ecc, sizeof(empty_block_ecc)) == 0) + memset(ecc_code, 0xff, sizeof(empty_block_ecc)); return 0; } From 5eeb7fe919ff4f683d96cf8c74a9de7e54722040 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Fri, 12 Jun 2020 17:22:37 +0200 Subject: [PATCH 115/242] mtd: rawnand: stm32_fmc2: do not display errors if the driver is deferred A MDMA issue has been solved on Kernel 5.7. The effect of this fix is that the MDMA driver is now deferred and the FMC2 NFC driver is also deferred. All is working fine but there is a FMC2 log in the console: stm32_fmc2_nfc 58002000.nand-controller: failed to request tx DMA channel: -517 This patch removes the display of this log in the console in case of this error is -EPROBE_DEFER. Signed-off-by: Christophe Kerello Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/1591975362-22009-2-git-send-email-christophe.kerello@st.com --- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index 65c9d17b25a3..e7b706b8ec4e 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -1570,7 +1570,7 @@ static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc) nfc->dma_tx_ch = dma_request_chan(nfc->dev, "tx"); if (IS_ERR(nfc->dma_tx_ch)) { ret = PTR_ERR(nfc->dma_tx_ch); - if (ret != -ENODEV) + if (ret != -ENODEV && ret != -EPROBE_DEFER) dev_err(nfc->dev, "failed to request tx DMA channel: %d\n", ret); nfc->dma_tx_ch = NULL; @@ -1580,7 +1580,7 @@ static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc) nfc->dma_rx_ch = dma_request_chan(nfc->dev, "rx"); if (IS_ERR(nfc->dma_rx_ch)) { ret = PTR_ERR(nfc->dma_rx_ch); - if (ret != -ENODEV) + if (ret != -ENODEV && ret != -EPROBE_DEFER) dev_err(nfc->dev, "failed to request rx DMA channel: %d\n", ret); nfc->dma_rx_ch = NULL; @@ -1590,7 +1590,7 @@ static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc) nfc->dma_ecc_ch = dma_request_chan(nfc->dev, "ecc"); if (IS_ERR(nfc->dma_ecc_ch)) { ret = PTR_ERR(nfc->dma_ecc_ch); - if (ret != -ENODEV) + if (ret != -ENODEV && ret != -EPROBE_DEFER) dev_err(nfc->dev, "failed to request ecc DMA channel: %d\n", ret); nfc->dma_ecc_ch = NULL; From bce49d1e3cfe48eb7a33a39da2530156c27fa3b2 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Fri, 12 Jun 2020 17:22:38 +0200 Subject: [PATCH 116/242] dt-bindings: mtd: update STM32 FMC2 NAND controller documentation These bindings can be used on SOCs where the FMC2 NAND controller is in standalone. In case that the FMC2 embeds 2 controllers (an external bus controller and a raw NAND controller), the register base address, the clock and the reset will be defined in the parent node. Signed-off-by: Christophe Kerello Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/1591975362-22009-3-git-send-email-christophe.kerello@st.com --- .../bindings/mtd/st,stm32-fmc2-nand.yaml | 83 +++++++++++++------ 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml index b059267f6d20..6ae7de15d172 100644 --- a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml +++ b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml @@ -9,32 +9,19 @@ title: STMicroelectronics Flexible Memory Controller 2 (FMC2) Bindings maintainers: - Christophe Kerello -allOf: - - $ref: "nand-controller.yaml#" - properties: compatible: - const: st,stm32mp15-fmc2 + enum: + - st,stm32mp15-fmc2 + - st,stm32mp1-fmc2-nfc reg: - items: - - description: Registers - - description: Chip select 0 data - - description: Chip select 0 command - - description: Chip select 0 address space - - description: Chip select 1 data - - description: Chip select 1 command - - description: Chip select 1 address space + minItems: 6 + maxItems: 7 interrupts: maxItems: 1 - clocks: - maxItems: 1 - - resets: - maxItems: 1 - dmas: items: - description: tx DMA channel @@ -57,11 +44,55 @@ patternProperties: nand-ecc-strength: enum: [1, 4 ,8 ] +allOf: + - $ref: "nand-controller.yaml#" + + - if: + properties: + compatible: + contains: + const: st,stm32mp15-fmc2 + then: + properties: + reg: + items: + - description: Registers + - description: Chip select 0 data + - description: Chip select 0 command + - description: Chip select 0 address space + - description: Chip select 1 data + - description: Chip select 1 command + - description: Chip select 1 address space + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + required: + - clocks + + - if: + properties: + compatible: + contains: + const: st,stm32mp1-fmc2-nfc + then: + properties: + reg: + items: + - description: Chip select 0 data + - description: Chip select 0 command + - description: Chip select 0 address space + - description: Chip select 1 data + - description: Chip select 1 command + - description: Chip select 1 address space + required: - compatible - reg - interrupts - - clocks examples: - | @@ -77,13 +108,13 @@ examples: <0x81000000 0x1000>, <0x89010000 0x1000>, <0x89020000 0x1000>; - interrupts = ; - dmas = <&mdma1 20 0x10 0x12000a02 0x0 0x0>, - <&mdma1 20 0x10 0x12000a08 0x0 0x0>, - <&mdma1 21 0x10 0x12000a0a 0x0 0x0>; - dma-names = "tx", "rx", "ecc"; - clocks = <&rcc FMC_K>; - resets = <&rcc FMC_R>; + interrupts = ; + dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>, + <&mdma1 20 0x2 0x12000a08 0x0 0x0>, + <&mdma1 21 0x2 0x12000a0a 0x0 0x0>; + dma-names = "tx", "rx", "ecc"; + clocks = <&rcc FMC_K>; + resets = <&rcc FMC_R>; #address-cells = <1>; #size-cells = <0>; From 1ab2f86f996fae09e2e216511584143c82efd030 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Fri, 12 Jun 2020 17:22:39 +0200 Subject: [PATCH 117/242] dt-bindings: memory-controller: add STM32 FMC2 EBI controller documentation This patch adds the documentation of the device tree bindings for the STM32 FMC2 EBI controller. Signed-off-by: Christophe Kerello Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/1591975362-22009-4-git-send-email-christophe.kerello@st.com --- .../memory-controllers/st,stm32-fmc2-ebi.yaml | 252 ++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml diff --git a/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml new file mode 100644 index 000000000000..70eaf739036b --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml @@ -0,0 +1,252 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/memory-controllers/st,stm32-fmc2-ebi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: STMicroelectronics Flexible Memory Controller 2 (FMC2) Bindings + +description: | + The FMC2 functional block makes the interface with: synchronous and + asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped + peripherals) and NAND flash memories. + Its main purposes are: + - to translate AXI transactions into the appropriate external device + protocol + - to meet the access time requirements of the external devices + All external devices share the addresses, data and control signals with the + controller. Each external device is accessed by means of a unique Chip + Select. The FMC2 performs only one access at a time to an external device. + +maintainers: + - Christophe Kerello + +properties: + compatible: + const: st,stm32mp1-fmc2-ebi + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + "#address-cells": + const: 2 + + "#size-cells": + const: 1 + + ranges: + description: | + Reflects the memory layout with four integer values per bank. Format: + 0
+ +patternProperties: + "^.*@[0-4],[a-f0-9]+$": + type: object + + properties: + reg: + description: Bank number, base address and size of the device. + + st,fmc2-ebi-cs-transaction-type: + description: | + Select one of the transactions type supported + 0: Asynchronous mode 1 SRAM/FRAM. + 1: Asynchronous mode 1 PSRAM. + 2: Asynchronous mode A SRAM/FRAM. + 3: Asynchronous mode A PSRAM. + 4: Asynchronous mode 2 NOR. + 5: Asynchronous mode B NOR. + 6: Asynchronous mode C NOR. + 7: Asynchronous mode D NOR. + 8: Synchronous read synchronous write PSRAM. + 9: Synchronous read asynchronous write PSRAM. + 10: Synchronous read synchronous write NOR. + 11: Synchronous read asynchronous write NOR. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 11 + + st,fmc2-ebi-cs-cclk-enable: + description: Continuous clock enable (first bank must be configured + in synchronous mode). The FMC_CLK is generated continuously + during asynchronous and synchronous access. By default, the + FMC_CLK is only generated during synchronous access. + $ref: /schemas/types.yaml#/definitions/flag + + st,fmc2-ebi-cs-mux-enable: + description: Address/Data multiplexed on databus (valid only with + NOR and PSRAM transactions type). By default, Address/Data + are not multiplexed. + $ref: /schemas/types.yaml#/definitions/flag + + st,fmc2-ebi-cs-buswidth: + description: Data bus width + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 8, 16 ] + default: 16 + + st,fmc2-ebi-cs-waitpol-high: + description: Wait signal polarity (NWAIT signal active high). + By default, NWAIT is active low. + $ref: /schemas/types.yaml#/definitions/flag + + st,fmc2-ebi-cs-waitcfg-enable: + description: The NWAIT signal indicates wheither the data from the + device are valid or if a wait state must be inserted when accessing + the device in synchronous mode. By default, the NWAIT signal is + active one data cycle before wait state. + $ref: /schemas/types.yaml#/definitions/flag + + st,fmc2-ebi-cs-wait-enable: + description: The NWAIT signal is enabled (its level is taken into + account after the programmed latency period to insert wait states + if asserted). By default, the NWAIT signal is disabled. + $ref: /schemas/types.yaml#/definitions/flag + + st,fmc2-ebi-cs-asyncwait-enable: + description: The NWAIT signal is taken into account during asynchronous + transactions. By default, the NWAIT signal is not taken into account + during asynchronous transactions. + $ref: /schemas/types.yaml#/definitions/flag + + st,fmc2-ebi-cs-cpsize: + description: CRAM page size. The controller splits the burst access + when the memory page is reached. By default, no burst split when + crossing page boundary. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 128, 256, 512, 1024 ] + default: 0 + + st,fmc2-ebi-cs-byte-lane-setup-ns: + description: This property configures the byte lane setup timing + defined in nanoseconds from NBLx low to Chip Select NEx low. + + st,fmc2-ebi-cs-address-setup-ns: + description: This property defines the duration of the address setup + phase in nanoseconds used for asynchronous read/write transactions. + + st,fmc2-ebi-cs-address-hold-ns: + description: This property defines the duration of the address hold + phase in nanoseconds used for asynchronous multiplexed read/write + transactions. + + st,fmc2-ebi-cs-data-setup-ns: + description: This property defines the duration of the data setup phase + in nanoseconds used for asynchronous read/write transactions. + + st,fmc2-ebi-cs-bus-turnaround-ns: + description: This property defines the delay in nanoseconds between the + end of current read/write transaction and the next transaction. + + st,fmc2-ebi-cs-data-hold-ns: + description: This property defines the duration of the data hold phase + in nanoseconds used for asynchronous read/write transactions. + + st,fmc2-ebi-cs-clk-period-ns: + description: This property defines the FMC_CLK output signal period in + nanoseconds. + + st,fmc2-ebi-cs-data-latency-ns: + description: This property defines the data latency before reading or + writing the first data in nanoseconds. + + st,fmc2_ebi-cs-write-address-setup-ns: + description: This property defines the duration of the address setup + phase in nanoseconds used for asynchronous write transactions. + + st,fmc2-ebi-cs-write-address-hold-ns: + description: This property defines the duration of the address hold + phase in nanoseconds used for asynchronous multiplexed write + transactions. + + st,fmc2-ebi-cs-write-data-setup-ns: + description: This property defines the duration of the data setup + phase in nanoseconds used for asynchronous write transactions. + + st,fmc2-ebi-cs-write-bus-turnaround-ns: + description: This property defines the delay between the end of current + write transaction and the next transaction in nanoseconds. + + st,fmc2-ebi-cs-write-data-hold-ns: + description: This property defines the duration of the data hold phase + in nanoseconds used for asynchronous write transactions. + + st,fmc2-ebi-cs-max-low-pulse-ns: + description: This property defines the maximum chip select low pulse + duration in nanoseconds for synchronous transactions. When this timing + reaches 0, the controller splits the current access, toggles NE to + allow device refresh and restarts a new access. + + required: + - reg + +required: + - "#address-cells" + - "#size-cells" + - compatible + - reg + - clocks + - ranges + +examples: + - | + #include + #include + #include + memory-controller@58002000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "st,stm32mp1-fmc2-ebi"; + reg = <0x58002000 0x1000>; + clocks = <&rcc FMC_K>; + resets = <&rcc FMC_R>; + + ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */ + <1 0 0x64000000 0x04000000>, /* EBI CS 2 */ + <2 0 0x68000000 0x04000000>, /* EBI CS 3 */ + <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */ + <4 0 0x80000000 0x10000000>; /* NAND */ + + psram@0,0 { + compatible = "mtd-ram"; + reg = <0 0x00000000 0x100000>; + bank-width = <2>; + + st,fmc2-ebi-cs-transaction-type = <1>; + st,fmc2-ebi-cs-address-setup-ns = <60>; + st,fmc2-ebi-cs-data-setup-ns = <30>; + st,fmc2-ebi-cs-bus-turnaround-ns = <5>; + }; + + nand-controller@4,0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32mp1-fmc2-nfc"; + reg = <4 0x00000000 0x1000>, + <4 0x08010000 0x1000>, + <4 0x08020000 0x1000>, + <4 0x01000000 0x1000>, + <4 0x09010000 0x1000>, + <4 0x09020000 0x1000>; + interrupts = ; + dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>, + <&mdma1 20 0x2 0x12000a08 0x0 0x0>, + <&mdma1 21 0x2 0x12000a0a 0x0 0x0>; + dma-names = "tx", "rx", "ecc"; + + nand@0 { + reg = <0>; + nand-on-flash-bbt; + #address-cells = <1>; + #size-cells = <1>; + }; + }; + }; + +... From 66b8173a197fb754a54798820f1e46f3d9df7819 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Fri, 12 Jun 2020 17:22:40 +0200 Subject: [PATCH 118/242] memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver The driver adds the support for the STMicroelectronics FMC2 EBI controller found on STM32MP SOCs. Signed-off-by: Christophe Kerello Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/1591975362-22009-5-git-send-email-christophe.kerello@st.com --- drivers/memory/Kconfig | 10 + drivers/memory/Makefile | 1 + drivers/memory/stm32-fmc2-ebi.c | 1206 +++++++++++++++++++++++++++++++ 3 files changed, 1217 insertions(+) create mode 100644 drivers/memory/stm32-fmc2-ebi.c diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 04368ee2a809..be69c07b8941 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -174,6 +174,16 @@ config PL353_SMC This driver is for the ARM PL351/PL353 Static Memory Controller(SMC) module. +config STM32_FMC2_EBI + tristate "Support for FMC2 External Bus Interface on STM32MP SoCs" + depends on MACH_STM32MP157 || COMPILE_TEST + select MFD_SYSCON + help + Select this option to enable the STM32 FMC2 External Bus Interface + controller. This driver configures the transactions with external + devices (like SRAM, ethernet adapters, FPGAs, LCD displays, ...) on + SOCs containing the FMC2 External Bus Interface. + source "drivers/memory/samsung/Kconfig" source "drivers/memory/tegra/Kconfig" diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index 6d7e3e64ba62..d3d8d6ced342 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o obj-$(CONFIG_MTK_SMI) += mtk-smi.o obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o obj-$(CONFIG_PL353_SMC) += pl353-smc.o +obj-$(CONFIG_STM32_FMC2_EBI) += stm32-fmc2-ebi.o obj-$(CONFIG_SAMSUNG_MC) += samsung/ obj-$(CONFIG_TEGRA_MC) += tegra/ diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c new file mode 100644 index 000000000000..4d5758c419c5 --- /dev/null +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -0,0 +1,1206 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) STMicroelectronics 2020 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* FMC2 Controller Registers */ +#define FMC2_BCR1 0x0 +#define FMC2_BTR1 0x4 +#define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1) +#define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1) +#define FMC2_PCSCNTR 0x20 +#define FMC2_BWTR1 0x104 +#define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1) + +/* Register: FMC2_BCR1 */ +#define FMC2_BCR1_CCLKEN BIT(20) +#define FMC2_BCR1_FMC2EN BIT(31) + +/* Register: FMC2_BCRx */ +#define FMC2_BCR_MBKEN BIT(0) +#define FMC2_BCR_MUXEN BIT(1) +#define FMC2_BCR_MTYP GENMASK(3, 2) +#define FMC2_BCR_MWID GENMASK(5, 4) +#define FMC2_BCR_FACCEN BIT(6) +#define FMC2_BCR_BURSTEN BIT(8) +#define FMC2_BCR_WAITPOL BIT(9) +#define FMC2_BCR_WAITCFG BIT(11) +#define FMC2_BCR_WREN BIT(12) +#define FMC2_BCR_WAITEN BIT(13) +#define FMC2_BCR_EXTMOD BIT(14) +#define FMC2_BCR_ASYNCWAIT BIT(15) +#define FMC2_BCR_CPSIZE GENMASK(18, 16) +#define FMC2_BCR_CBURSTRW BIT(19) +#define FMC2_BCR_NBLSET GENMASK(23, 22) + +/* Register: FMC2_BTRx/FMC2_BWTRx */ +#define FMC2_BXTR_ADDSET GENMASK(3, 0) +#define FMC2_BXTR_ADDHLD GENMASK(7, 4) +#define FMC2_BXTR_DATAST GENMASK(15, 8) +#define FMC2_BXTR_BUSTURN GENMASK(19, 16) +#define FMC2_BTR_CLKDIV GENMASK(23, 20) +#define FMC2_BTR_DATLAT GENMASK(27, 24) +#define FMC2_BXTR_ACCMOD GENMASK(29, 28) +#define FMC2_BXTR_DATAHLD GENMASK(31, 30) + +/* Register: FMC2_PCSCNTR */ +#define FMC2_PCSCNTR_CSCOUNT GENMASK(15, 0) +#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16) + +#define FMC2_MAX_EBI_CE 4 +#define FMC2_MAX_BANKS 5 + +#define FMC2_BCR_CPSIZE_0 0x0 +#define FMC2_BCR_CPSIZE_128 0x1 +#define FMC2_BCR_CPSIZE_256 0x2 +#define FMC2_BCR_CPSIZE_512 0x3 +#define FMC2_BCR_CPSIZE_1024 0x4 + +#define FMC2_BCR_MWID_8 0x0 +#define FMC2_BCR_MWID_16 0x1 + +#define FMC2_BCR_MTYP_SRAM 0x0 +#define FMC2_BCR_MTYP_PSRAM 0x1 +#define FMC2_BCR_MTYP_NOR 0x2 + +#define FMC2_BXTR_EXTMOD_A 0x0 +#define FMC2_BXTR_EXTMOD_B 0x1 +#define FMC2_BXTR_EXTMOD_C 0x2 +#define FMC2_BXTR_EXTMOD_D 0x3 + +#define FMC2_BCR_NBLSET_MAX 0x3 +#define FMC2_BXTR_ADDSET_MAX 0xf +#define FMC2_BXTR_ADDHLD_MAX 0xf +#define FMC2_BXTR_DATAST_MAX 0xff +#define FMC2_BXTR_BUSTURN_MAX 0xf +#define FMC2_BXTR_DATAHLD_MAX 0x3 +#define FMC2_BTR_CLKDIV_MAX 0xf +#define FMC2_BTR_DATLAT_MAX 0xf +#define FMC2_PCSCNTR_CSCOUNT_MAX 0xff + +enum stm32_fmc2_ebi_bank { + FMC2_EBI1 = 0, + FMC2_EBI2, + FMC2_EBI3, + FMC2_EBI4, + FMC2_NAND +}; + +enum stm32_fmc2_ebi_register_type { + FMC2_REG_BCR = 1, + FMC2_REG_BTR, + FMC2_REG_BWTR, + FMC2_REG_PCSCNTR +}; + +enum stm32_fmc2_ebi_transaction_type { + FMC2_ASYNC_MODE_1_SRAM = 0, + FMC2_ASYNC_MODE_1_PSRAM, + FMC2_ASYNC_MODE_A_SRAM, + FMC2_ASYNC_MODE_A_PSRAM, + FMC2_ASYNC_MODE_2_NOR, + FMC2_ASYNC_MODE_B_NOR, + FMC2_ASYNC_MODE_C_NOR, + FMC2_ASYNC_MODE_D_NOR, + FMC2_SYNC_READ_SYNC_WRITE_PSRAM, + FMC2_SYNC_READ_ASYNC_WRITE_PSRAM, + FMC2_SYNC_READ_SYNC_WRITE_NOR, + FMC2_SYNC_READ_ASYNC_WRITE_NOR +}; + +enum stm32_fmc2_ebi_buswidth { + FMC2_BUSWIDTH_8 = 8, + FMC2_BUSWIDTH_16 = 16 +}; + +enum stm32_fmc2_ebi_cpsize { + FMC2_CPSIZE_0 = 0, + FMC2_CPSIZE_128 = 128, + FMC2_CPSIZE_256 = 256, + FMC2_CPSIZE_512 = 512, + FMC2_CPSIZE_1024 = 1024 +}; + +struct stm32_fmc2_ebi { + struct device *dev; + struct clk *clk; + struct regmap *regmap; + u8 bank_assigned; + + u32 bcr[FMC2_MAX_EBI_CE]; + u32 btr[FMC2_MAX_EBI_CE]; + u32 bwtr[FMC2_MAX_EBI_CE]; + u32 pcscntr; +}; + +/* + * struct stm32_fmc2_prop - STM32 FMC2 EBI property + * @name: the device tree binding name of the property + * @bprop: indicate that it is a boolean property + * @mprop: indicate that it is a mandatory property + * @reg_type: the register that have to be modified + * @reg_mask: the bit that have to be modified in the selected register + * in case of it is a boolean property + * @reset_val: the default value that have to be set in case the property + * has not been defined in the device tree + * @check: this callback ckecks that the property is compliant with the + * transaction type selected + * @calculate: this callback is called to calculate for exemple a timing + * set in nanoseconds in the device tree in clock cycles or in + * clock period + * @set: this callback applies the values in the registers + */ +struct stm32_fmc2_prop { + const char *name; + bool bprop; + bool mprop; + int reg_type; + u32 reg_mask; + u32 reset_val; + int (*check)(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, int cs); + u32 (*calculate)(struct stm32_fmc2_ebi *ebi, int cs, u32 setup); + int (*set)(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup); +}; + +static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr; + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + + if (bcr & FMC2_BCR_MTYP) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + + if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr; + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + + if (bcr & FMC2_BCR_BURSTEN) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr; + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + + if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + + if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr, bxtr, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (prop->reg_type == FMC2_REG_BWTR) + regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); + else + regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); + + if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) && + ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr, bcr1; + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (cs) + regmap_read(ebi->regmap, FMC2_BCR1, &bcr1); + else + bcr1 = bcr; + + if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN))) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_cclk(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + if (cs) + return -EINVAL; + + return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs); +} + +static u32 stm32_fmc2_ebi_ns_to_clock_cycles(struct stm32_fmc2_ebi *ebi, + int cs, u32 setup) +{ + unsigned long hclk = clk_get_rate(ebi->clk); + unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000); + + return DIV_ROUND_UP(setup * 1000, hclkp); +} + +static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi, + int cs, u32 setup) +{ + u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup); + u32 bcr, btr, clk_period; + + regmap_read(ebi->regmap, FMC2_BCR1, &bcr); + if (bcr & FMC2_BCR1_CCLKEN || !cs) + regmap_read(ebi->regmap, FMC2_BTR1, &btr); + else + regmap_read(ebi->regmap, FMC2_BTR(cs), &btr); + + clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1; + + return DIV_ROUND_UP(nb_clk_cycles, clk_period); +} + +static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg) +{ + switch (reg_type) { + case FMC2_REG_BCR: + *reg = FMC2_BCR(cs); + break; + case FMC2_REG_BTR: + *reg = FMC2_BTR(cs); + break; + case FMC2_REG_BWTR: + *reg = FMC2_BWTR(cs); + break; + case FMC2_REG_PCSCNTR: + *reg = FMC2_PCSCNTR; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int stm32_fmc2_ebi_set_bit_field(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + regmap_update_bits(ebi->regmap, reg, prop->reg_mask, + setup ? prop->reg_mask : 0); + + return 0; +} + +static int stm32_fmc2_ebi_set_trans_type(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 bcr_mask, bcr = FMC2_BCR_WREN; + u32 btr_mask, btr = 0; + u32 bwtr_mask, bwtr = 0; + + bwtr_mask = FMC2_BXTR_ACCMOD; + btr_mask = FMC2_BXTR_ACCMOD; + bcr_mask = FMC2_BCR_MUXEN | FMC2_BCR_MTYP | FMC2_BCR_FACCEN | + FMC2_BCR_WREN | FMC2_BCR_WAITEN | FMC2_BCR_BURSTEN | + FMC2_BCR_EXTMOD | FMC2_BCR_CBURSTRW; + + switch (setup) { + case FMC2_ASYNC_MODE_1_SRAM: + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM); + /* + * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + break; + case FMC2_ASYNC_MODE_1_PSRAM: + /* + * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + break; + case FMC2_ASYNC_MODE_A_SRAM: + /* + * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM); + bcr |= FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A); + break; + case FMC2_ASYNC_MODE_A_PSRAM: + /* + * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + bcr |= FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A); + break; + case FMC2_ASYNC_MODE_2_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN; + break; + case FMC2_ASYNC_MODE_B_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 1 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B); + break; + case FMC2_ASYNC_MODE_C_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 2 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C); + break; + case FMC2_ASYNC_MODE_D_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 3 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + break; + case FMC2_SYNC_READ_SYNC_WRITE_PSRAM: + /* + * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + bcr |= FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW; + break; + case FMC2_SYNC_READ_ASYNC_WRITE_PSRAM: + /* + * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + bcr |= FMC2_BCR_BURSTEN; + break; + case FMC2_SYNC_READ_SYNC_WRITE_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW; + break; + case FMC2_SYNC_READ_ASYNC_WRITE_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN; + break; + default: + /* Type of transaction not supported */ + return -EINVAL; + } + + if (bcr & FMC2_BCR_EXTMOD) + regmap_update_bits(ebi->regmap, FMC2_BWTR(cs), + bwtr_mask, bwtr); + regmap_update_bits(ebi->regmap, FMC2_BTR(cs), btr_mask, btr); + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), bcr_mask, bcr); + + return 0; +} + +static int stm32_fmc2_ebi_set_buswidth(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + switch (setup) { + case FMC2_BUSWIDTH_8: + val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_8); + break; + case FMC2_BUSWIDTH_16: + val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_16); + break; + default: + /* Buswidth not supported */ + return -EINVAL; + } + + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MWID, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_cpsize(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + switch (setup) { + case FMC2_CPSIZE_0: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_0); + break; + case FMC2_CPSIZE_128: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_128); + break; + case FMC2_CPSIZE_256: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_256); + break; + case FMC2_CPSIZE_512: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_512); + break; + case FMC2_CPSIZE_1024: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_1024); + break; + default: + /* Cpsize not supported */ + return -EINVAL; + } + + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_CPSIZE, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_bl_setup(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + val = min_t(u32, setup, FMC2_BCR_NBLSET_MAX); + val = FIELD_PREP(FMC2_BCR_NBLSET, val); + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_NBLSET, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 bcr, bxtr, reg; + u32 val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (prop->reg_type == FMC2_REG_BWTR) + regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); + else + regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); + + if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN) + val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX); + else + val = min_t(u32, setup, FMC2_BXTR_ADDSET_MAX); + val = FIELD_PREP(FMC2_BXTR_ADDSET, val); + regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_ADDSET, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_address_hold(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + val = clamp_val(setup, 1, FMC2_BXTR_ADDHLD_MAX); + val = FIELD_PREP(FMC2_BXTR_ADDHLD, val); + regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_ADDHLD, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_data_setup(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + val = clamp_val(setup, 1, FMC2_BXTR_DATAST_MAX); + val = FIELD_PREP(FMC2_BXTR_DATAST, val); + regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_DATAST, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_bus_turnaround(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + val = setup ? min_t(u32, setup - 1, FMC2_BXTR_BUSTURN_MAX) : 0; + val = FIELD_PREP(FMC2_BXTR_BUSTURN, val); + regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_BUSTURN, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_data_hold(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + if (prop->reg_type == FMC2_REG_BWTR) + val = setup ? min_t(u32, setup - 1, FMC2_BXTR_DATAHLD_MAX) : 0; + else + val = min_t(u32, setup, FMC2_BXTR_DATAHLD_MAX); + val = FIELD_PREP(FMC2_BXTR_DATAHLD, val); + regmap_update_bits(ebi->regmap, reg, FMC2_BXTR_DATAHLD, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_clk_period(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1; + val = FIELD_PREP(FMC2_BTR_CLKDIV, val); + regmap_update_bits(ebi->regmap, FMC2_BTR(cs), FMC2_BTR_CLKDIV, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + val = setup > 1 ? min_t(u32, setup - 2, FMC2_BTR_DATLAT_MAX) : 0; + val = FIELD_PREP(FMC2_BTR_DATLAT, val); + regmap_update_bits(ebi->regmap, FMC2_BTR(cs), FMC2_BTR_DATLAT, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 old_val, new_val, pcscntr; + + if (setup < 1) + return 0; + + regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr); + + /* Enable counter for the bank */ + regmap_update_bits(ebi->regmap, FMC2_PCSCNTR, + FMC2_PCSCNTR_CNTBEN(cs), + FMC2_PCSCNTR_CNTBEN(cs)); + + new_val = min_t(u32, setup - 1, FMC2_PCSCNTR_CSCOUNT_MAX); + old_val = FIELD_GET(FMC2_PCSCNTR_CSCOUNT, pcscntr); + if (old_val && new_val > old_val) + /* Keep current counter value */ + return 0; + + new_val = FIELD_PREP(FMC2_PCSCNTR_CSCOUNT, new_val); + regmap_update_bits(ebi->regmap, FMC2_PCSCNTR, + FMC2_PCSCNTR_CSCOUNT, new_val); + + return 0; +} + +static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = { + /* st,fmc2-ebi-cs-trans-type must be the first property */ + { + .name = "st,fmc2-ebi-cs-transaction-type", + .mprop = true, + .set = stm32_fmc2_ebi_set_trans_type, + }, + { + .name = "st,fmc2-ebi-cs-cclk-enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR1_CCLKEN, + .check = stm32_fmc2_ebi_check_cclk, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2-ebi-cs-mux-enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_MUXEN, + .check = stm32_fmc2_ebi_check_mux, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2-ebi-cs-buswidth", + .reset_val = FMC2_BUSWIDTH_16, + .set = stm32_fmc2_ebi_set_buswidth, + }, + { + .name = "st,fmc2-ebi-cs-waitpol-high", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_WAITPOL, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2-ebi-cs-waitcfg-enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_WAITCFG, + .check = stm32_fmc2_ebi_check_waitcfg, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2-ebi-cs-wait-enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_WAITEN, + .check = stm32_fmc2_ebi_check_sync_trans, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2-ebi-cs-asyncwait-enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_ASYNCWAIT, + .check = stm32_fmc2_ebi_check_async_trans, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2-ebi-cs-cpsize", + .check = stm32_fmc2_ebi_check_cpsize, + .set = stm32_fmc2_ebi_set_cpsize, + }, + { + .name = "st,fmc2-ebi-cs-byte-lane-setup-ns", + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_bl_setup, + }, + { + .name = "st,fmc2-ebi-cs-address-setup-ns", + .reg_type = FMC2_REG_BTR, + .reset_val = FMC2_BXTR_ADDSET_MAX, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_address_setup, + }, + { + .name = "st,fmc2-ebi-cs-address-hold-ns", + .reg_type = FMC2_REG_BTR, + .reset_val = FMC2_BXTR_ADDHLD_MAX, + .check = stm32_fmc2_ebi_check_address_hold, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_address_hold, + }, + { + .name = "st,fmc2-ebi-cs-data-setup-ns", + .reg_type = FMC2_REG_BTR, + .reset_val = FMC2_BXTR_DATAST_MAX, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_data_setup, + }, + { + .name = "st,fmc2-ebi-cs-bus-turnaround-ns", + .reg_type = FMC2_REG_BTR, + .reset_val = FMC2_BXTR_BUSTURN_MAX + 1, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_bus_turnaround, + }, + { + .name = "st,fmc2-ebi-cs-data-hold-ns", + .reg_type = FMC2_REG_BTR, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_data_hold, + }, + { + .name = "st,fmc2-ebi-cs-clk-period-ns", + .reset_val = FMC2_BTR_CLKDIV_MAX + 1, + .check = stm32_fmc2_ebi_check_clk_period, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_clk_period, + }, + { + .name = "st,fmc2-ebi-cs-data-latency-ns", + .check = stm32_fmc2_ebi_check_sync_trans, + .calculate = stm32_fmc2_ebi_ns_to_clk_period, + .set = stm32_fmc2_ebi_set_data_latency, + }, + { + .name = "st,fmc2-ebi-cs-write-address-setup-ns", + .reg_type = FMC2_REG_BWTR, + .reset_val = FMC2_BXTR_ADDSET_MAX, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_address_setup, + }, + { + .name = "st,fmc2-ebi-cs-write-address-hold-ns", + .reg_type = FMC2_REG_BWTR, + .reset_val = FMC2_BXTR_ADDHLD_MAX, + .check = stm32_fmc2_ebi_check_address_hold, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_address_hold, + }, + { + .name = "st,fmc2-ebi-cs-write-data-setup-ns", + .reg_type = FMC2_REG_BWTR, + .reset_val = FMC2_BXTR_DATAST_MAX, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_data_setup, + }, + { + .name = "st,fmc2-ebi-cs-write-bus-turnaround-ns", + .reg_type = FMC2_REG_BWTR, + .reset_val = FMC2_BXTR_BUSTURN_MAX + 1, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_bus_turnaround, + }, + { + .name = "st,fmc2-ebi-cs-write-data-hold-ns", + .reg_type = FMC2_REG_BWTR, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_data_hold, + }, + { + .name = "st,fmc2-ebi-cs-max-low-pulse-ns", + .calculate = stm32_fmc2_ebi_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_max_low_pulse, + }, +}; + +static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi, + struct device_node *dev_node, + const struct stm32_fmc2_prop *prop, + int cs) +{ + struct device *dev = ebi->dev; + u32 setup = 0; + + if (!prop->set) { + dev_err(dev, "property %s is not well defined\n", prop->name); + return -EINVAL; + } + + if (prop->check && prop->check(ebi, prop, cs)) + /* Skeep this property */ + return 0; + + if (prop->bprop) { + bool bprop; + + bprop = of_property_read_bool(dev_node, prop->name); + if (prop->mprop && !bprop) { + dev_err(dev, "mandatory property %s not defined in the device tree\n", + prop->name); + return -EINVAL; + } + + if (bprop) + setup = 1; + } else { + u32 val; + int ret; + + ret = of_property_read_u32(dev_node, prop->name, &val); + if (prop->mprop && ret) { + dev_err(dev, "mandatory property %s not defined in the device tree\n", + prop->name); + return ret; + } + + if (ret) + setup = prop->reset_val; + else if (prop->calculate) + setup = prop->calculate(ebi, cs, val); + else + setup = val; + } + + return prop->set(ebi, prop, cs, setup); +} + +static void stm32_fmc2_ebi_enable_bank(struct stm32_fmc2_ebi *ebi, int cs) +{ + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), + FMC2_BCR_MBKEN, FMC2_BCR_MBKEN); +} + +static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs) +{ + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MBKEN, 0); +} + +static void stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi) +{ + unsigned int cs; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); + regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]); + regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); + } + + regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr); +} + +static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi) +{ + unsigned int cs; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + regmap_write(ebi->regmap, FMC2_BCR(cs), ebi->bcr[cs]); + regmap_write(ebi->regmap, FMC2_BTR(cs), ebi->btr[cs]); + regmap_write(ebi->regmap, FMC2_BWTR(cs), ebi->bwtr[cs]); + } + + regmap_write(ebi->regmap, FMC2_PCSCNTR, ebi->pcscntr); +} + +static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2_ebi *ebi) +{ + unsigned int cs; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + if (!(ebi->bank_assigned & BIT(cs))) + continue; + + stm32_fmc2_ebi_disable_bank(ebi, cs); + } +} + +/* NWAIT signal can not be connected to EBI controller and NAND controller */ +static bool stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi) +{ + unsigned int cs; + u32 bcr; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + if (!(ebi->bank_assigned & BIT(cs))) + continue; + + regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) && + ebi->bank_assigned & BIT(FMC2_NAND)) + return true; + } + + return false; +} + +static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi) +{ + regmap_update_bits(ebi->regmap, FMC2_BCR1, + FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN); +} + +static void stm32_fmc2_ebi_disable(struct stm32_fmc2_ebi *ebi) +{ + regmap_update_bits(ebi->regmap, FMC2_BCR1, FMC2_BCR1_FMC2EN, 0); +} + +static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi, + struct device_node *dev_node, + u32 cs) +{ + unsigned int i; + int ret; + + stm32_fmc2_ebi_disable_bank(ebi, cs); + + for (i = 0; i < ARRAY_SIZE(stm32_fmc2_child_props); i++) { + const struct stm32_fmc2_prop *p = &stm32_fmc2_child_props[i]; + + ret = stm32_fmc2_ebi_parse_prop(ebi, dev_node, p, cs); + if (ret) { + dev_err(ebi->dev, "property %s could not be set: %d\n", + p->name, ret); + return ret; + } + } + + stm32_fmc2_ebi_enable_bank(ebi, cs); + + return 0; +} + +static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi) +{ + struct device *dev = ebi->dev; + struct device_node *child; + bool child_found = false; + u32 bank; + int ret; + + for_each_available_child_of_node(dev->of_node, child) { + ret = of_property_read_u32(child, "reg", &bank); + if (ret) { + dev_err(dev, "could not retrieve reg property: %d\n", + ret); + return ret; + } + + if (bank >= FMC2_MAX_BANKS) { + dev_err(dev, "invalid reg value: %d\n", bank); + return -EINVAL; + } + + if (ebi->bank_assigned & BIT(bank)) { + dev_err(dev, "bank already assigned: %d\n", bank); + return -EINVAL; + } + + if (bank < FMC2_MAX_EBI_CE) { + ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank); + if (ret) { + dev_err(dev, "setup chip select %d failed: %d\n", + bank, ret); + return ret; + } + } + + ebi->bank_assigned |= BIT(bank); + child_found = true; + } + + if (!child_found) { + dev_warn(dev, "no subnodes found, disable the driver.\n"); + return -ENODEV; + } + + if (stm32_fmc2_ebi_nwait_used_by_ctrls(ebi)) { + dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n"); + return -EINVAL; + } + + stm32_fmc2_ebi_enable(ebi); + + return of_platform_populate(dev->of_node, NULL, NULL, dev); +} + +static int stm32_fmc2_ebi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct stm32_fmc2_ebi *ebi; + struct reset_control *rstc; + int ret; + + ebi = devm_kzalloc(&pdev->dev, sizeof(*ebi), GFP_KERNEL); + if (!ebi) + return -ENOMEM; + + ebi->dev = dev; + + ebi->regmap = device_node_to_regmap(dev->of_node); + if (IS_ERR(ebi->regmap)) + return PTR_ERR(ebi->regmap); + + ebi->clk = devm_clk_get(dev, NULL); + if (IS_ERR(ebi->clk)) + return PTR_ERR(ebi->clk); + + rstc = devm_reset_control_get(dev, NULL); + if (PTR_ERR(rstc) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + ret = clk_prepare_enable(ebi->clk); + if (ret) + return ret; + + if (!IS_ERR(rstc)) { + reset_control_assert(rstc); + reset_control_deassert(rstc); + } + + ret = stm32_fmc2_ebi_parse_dt(ebi); + if (ret) + goto err_release; + + stm32_fmc2_ebi_save_setup(ebi); + platform_set_drvdata(pdev, ebi); + + return 0; + +err_release: + stm32_fmc2_ebi_disable_banks(ebi); + stm32_fmc2_ebi_disable(ebi); + clk_disable_unprepare(ebi->clk); + + return ret; +} + +static int stm32_fmc2_ebi_remove(struct platform_device *pdev) +{ + struct stm32_fmc2_ebi *ebi = platform_get_drvdata(pdev); + + of_platform_depopulate(&pdev->dev); + stm32_fmc2_ebi_disable_banks(ebi); + stm32_fmc2_ebi_disable(ebi); + clk_disable_unprepare(ebi->clk); + + return 0; +} + +static int __maybe_unused stm32_fmc2_ebi_suspend(struct device *dev) +{ + struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev); + + stm32_fmc2_ebi_disable(ebi); + clk_disable_unprepare(ebi->clk); + pinctrl_pm_select_sleep_state(dev); + + return 0; +} + +static int __maybe_unused stm32_fmc2_ebi_resume(struct device *dev) +{ + struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev); + int ret; + + pinctrl_pm_select_default_state(dev); + + ret = clk_prepare_enable(ebi->clk); + if (ret) + return ret; + + stm32_fmc2_ebi_set_setup(ebi); + stm32_fmc2_ebi_enable(ebi); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(stm32_fmc2_ebi_pm_ops, stm32_fmc2_ebi_suspend, + stm32_fmc2_ebi_resume); + +static const struct of_device_id stm32_fmc2_ebi_match[] = { + {.compatible = "st,stm32mp1-fmc2-ebi"}, + {} +}; +MODULE_DEVICE_TABLE(of, stm32_fmc2_ebi_match); + +static struct platform_driver stm32_fmc2_ebi_driver = { + .probe = stm32_fmc2_ebi_probe, + .remove = stm32_fmc2_ebi_remove, + .driver = { + .name = "stm32_fmc2_ebi", + .of_match_table = stm32_fmc2_ebi_match, + .pm = &stm32_fmc2_ebi_pm_ops, + }, +}; +module_platform_driver(stm32_fmc2_ebi_driver); + +MODULE_ALIAS("platform:stm32_fmc2_ebi"); +MODULE_AUTHOR("Christophe Kerello "); +MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 ebi driver"); +MODULE_LICENSE("GPL v2"); From 51c88a8d3b02cfd4d9209c282b815336c5952619 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Fri, 12 Jun 2020 17:22:41 +0200 Subject: [PATCH 119/242] mtd: rawnand: stm32_fmc2: use regmap APIs This patch uses regmap APIs to access all FMC2 registers. Signed-off-by: Christophe Kerello Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/1591975362-22009-6-git-send-email-christophe.kerello@st.com --- drivers/mtd/nand/raw/Kconfig | 2 + drivers/mtd/nand/raw/stm32_fmc2_nand.c | 270 ++++++++++++------------- 2 files changed, 128 insertions(+), 144 deletions(-) diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 113f61052269..0a03ebf08cd6 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -415,6 +415,8 @@ config MTD_NAND_TEGRA config MTD_NAND_STM32_FMC2 tristate "Support for NAND controller on STM32MP SoCs" depends on MACH_STM32MP157 || COMPILE_TEST + select REGMAP + select REGMAP_MMIO help Enables support for NAND Flash chips on SoCs containing the FMC2 NAND controller. This controller is found on STM32MP SoCs. diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index e7b706b8ec4e..6aa36950810c 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -15,6 +15,7 @@ #include #include #include +#include #include /* Bad block marker length */ @@ -203,6 +204,16 @@ #define FMC2_BCHDSR4_EBP7 GENMASK(12, 0) #define FMC2_BCHDSR4_EBP8 GENMASK(28, 16) +/* Regmap registers configuration */ +#define FMC2_MAX_REGISTER 0x3fc + +static const struct regmap_config stm32_fmc2_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = sizeof(u32), + .max_register = FMC2_MAX_REGISTER, +}; + enum stm32_fmc2_ecc { FMC2_ECC_HAM = 1, FMC2_ECC_BCH4 = 4, @@ -242,7 +253,7 @@ struct stm32_fmc2_nfc { struct nand_controller base; struct stm32_fmc2_nand nand; struct device *dev; - void __iomem *io_base; + struct regmap *regmap; void __iomem *data_base[FMC2_MAX_CE]; void __iomem *cmd_base[FMC2_MAX_CE]; void __iomem *addr_base[FMC2_MAX_CE]; @@ -277,40 +288,37 @@ static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip) struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); struct stm32_fmc2_timings *timings = &nand->timings; - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); u32 pmem, patt; /* Set tclr/tar timings */ - pcr &= ~FMC2_PCR_TCLR; - pcr |= FIELD_PREP(FMC2_PCR_TCLR, timings->tclr); - pcr &= ~FMC2_PCR_TAR; - pcr |= FIELD_PREP(FMC2_PCR_TAR, timings->tar); + regmap_update_bits(nfc->regmap, FMC2_PCR, + FMC2_PCR_TCLR | FMC2_PCR_TAR, + FIELD_PREP(FMC2_PCR_TCLR, timings->tclr) | + FIELD_PREP(FMC2_PCR_TAR, timings->tar)); /* Set tset/twait/thold/thiz timings in common bank */ pmem = FIELD_PREP(FMC2_PMEM_MEMSET, timings->tset_mem); pmem |= FIELD_PREP(FMC2_PMEM_MEMWAIT, timings->twait); pmem |= FIELD_PREP(FMC2_PMEM_MEMHOLD, timings->thold_mem); pmem |= FIELD_PREP(FMC2_PMEM_MEMHIZ, timings->thiz); + regmap_write(nfc->regmap, FMC2_PMEM, pmem); /* Set tset/twait/thold/thiz timings in attribut bank */ patt = FIELD_PREP(FMC2_PATT_ATTSET, timings->tset_att); patt |= FIELD_PREP(FMC2_PATT_ATTWAIT, timings->twait); patt |= FIELD_PREP(FMC2_PATT_ATTHOLD, timings->thold_att); patt |= FIELD_PREP(FMC2_PATT_ATTHIZ, timings->thiz); - - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); - writel_relaxed(pmem, nfc->io_base + FMC2_PMEM); - writel_relaxed(patt, nfc->io_base + FMC2_PATT); + regmap_write(nfc->regmap, FMC2_PATT, patt); } static void stm32_fmc2_nfc_setup(struct nand_chip *chip) { struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); + u32 pcr = 0, pcr_mask; /* Configure ECC algorithm (default configuration is Hamming) */ - pcr &= ~FMC2_PCR_ECCALG; - pcr &= ~FMC2_PCR_BCHECC; + pcr_mask = FMC2_PCR_ECCALG; + pcr_mask |= FMC2_PCR_BCHECC; if (chip->ecc.strength == FMC2_ECC_BCH8) { pcr |= FMC2_PCR_ECCALG; pcr |= FMC2_PCR_BCHECC; @@ -319,15 +327,15 @@ static void stm32_fmc2_nfc_setup(struct nand_chip *chip) } /* Set buswidth */ - pcr &= ~FMC2_PCR_PWID; + pcr_mask |= FMC2_PCR_PWID; if (chip->options & NAND_BUSWIDTH_16) pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16); /* Set ECC sector size */ - pcr &= ~FMC2_PCR_ECCSS; + pcr_mask |= FMC2_PCR_ECCSS; pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_512); - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + regmap_update_bits(nfc->regmap, FMC2_PCR, pcr_mask, pcr); } static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr) @@ -393,81 +401,63 @@ static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr) static void stm32_fmc2_nfc_set_buswidth_16(struct stm32_fmc2_nfc *nfc, bool set) { - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); + u32 pcr; - pcr &= ~FMC2_PCR_PWID; - if (set) - pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16); - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + pcr = set ? FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16) : + FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_8); + + regmap_update_bits(nfc->regmap, FMC2_PCR, FMC2_PCR_PWID, pcr); } static void stm32_fmc2_nfc_set_ecc(struct stm32_fmc2_nfc *nfc, bool enable) { - u32 pcr = readl(nfc->io_base + FMC2_PCR); - - pcr &= ~FMC2_PCR_ECCEN; - if (enable) - pcr |= FMC2_PCR_ECCEN; - writel(pcr, nfc->io_base + FMC2_PCR); + regmap_update_bits(nfc->regmap, FMC2_PCR, FMC2_PCR_ECCEN, + enable ? FMC2_PCR_ECCEN : 0); } -static inline void stm32_fmc2_nfc_enable_seq_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_enable_seq_irq(struct stm32_fmc2_nfc *nfc) { - u32 csqier = readl_relaxed(nfc->io_base + FMC2_CSQIER); - - csqier |= FMC2_CSQIER_TCIE; - nfc->irq_state = FMC2_IRQ_SEQ; - writel_relaxed(csqier, nfc->io_base + FMC2_CSQIER); + regmap_update_bits(nfc->regmap, FMC2_CSQIER, + FMC2_CSQIER_TCIE, FMC2_CSQIER_TCIE); } -static inline void stm32_fmc2_nfc_disable_seq_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_disable_seq_irq(struct stm32_fmc2_nfc *nfc) { - u32 csqier = readl_relaxed(nfc->io_base + FMC2_CSQIER); - - csqier &= ~FMC2_CSQIER_TCIE; - - writel_relaxed(csqier, nfc->io_base + FMC2_CSQIER); + regmap_update_bits(nfc->regmap, FMC2_CSQIER, FMC2_CSQIER_TCIE, 0); nfc->irq_state = FMC2_IRQ_UNKNOWN; } -static inline void stm32_fmc2_nfc_clear_seq_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_clear_seq_irq(struct stm32_fmc2_nfc *nfc) { - writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, nfc->io_base + FMC2_CSQICR); + regmap_write(nfc->regmap, FMC2_CSQICR, FMC2_CSQICR_CLEAR_IRQ); } -static inline void stm32_fmc2_nfc_enable_bch_irq(struct stm32_fmc2_nfc *nfc, - int mode) +static void stm32_fmc2_nfc_enable_bch_irq(struct stm32_fmc2_nfc *nfc, int mode) { - u32 bchier = readl_relaxed(nfc->io_base + FMC2_BCHIER); - - if (mode == NAND_ECC_WRITE) - bchier |= FMC2_BCHIER_EPBRIE; - else - bchier |= FMC2_BCHIER_DERIE; - nfc->irq_state = FMC2_IRQ_BCH; - writel_relaxed(bchier, nfc->io_base + FMC2_BCHIER); + if (mode == NAND_ECC_WRITE) + regmap_update_bits(nfc->regmap, FMC2_BCHIER, + FMC2_BCHIER_EPBRIE, FMC2_BCHIER_EPBRIE); + else + regmap_update_bits(nfc->regmap, FMC2_BCHIER, + FMC2_BCHIER_DERIE, FMC2_BCHIER_DERIE); } -static inline void stm32_fmc2_nfc_disable_bch_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_disable_bch_irq(struct stm32_fmc2_nfc *nfc) { - u32 bchier = readl_relaxed(nfc->io_base + FMC2_BCHIER); - - bchier &= ~FMC2_BCHIER_DERIE; - bchier &= ~FMC2_BCHIER_EPBRIE; - - writel_relaxed(bchier, nfc->io_base + FMC2_BCHIER); + regmap_update_bits(nfc->regmap, FMC2_BCHIER, + FMC2_BCHIER_DERIE | FMC2_BCHIER_EPBRIE, 0); nfc->irq_state = FMC2_IRQ_UNKNOWN; } -static inline void stm32_fmc2_nfc_clear_bch_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_clear_bch_irq(struct stm32_fmc2_nfc *nfc) { - writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, nfc->io_base + FMC2_BCHICR); + regmap_write(nfc->regmap, FMC2_BCHICR, FMC2_BCHICR_CLEAR_IRQ); } /* @@ -481,13 +471,8 @@ static void stm32_fmc2_nfc_hwctl(struct nand_chip *chip, int mode) stm32_fmc2_nfc_set_ecc(nfc, false); if (chip->ecc.strength != FMC2_ECC_HAM) { - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); - - if (mode == NAND_ECC_WRITE) - pcr |= FMC2_PCR_WEN; - else - pcr &= ~FMC2_PCR_WEN; - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + regmap_update_bits(nfc->regmap, FMC2_PCR, FMC2_PCR_WEN, + mode == NAND_ECC_WRITE ? FMC2_PCR_WEN : 0); reinit_completion(&nfc->complete); stm32_fmc2_nfc_clear_bch_irq(nfc); @@ -502,7 +487,7 @@ static void stm32_fmc2_nfc_hwctl(struct nand_chip *chip, int mode) * ECC is 3 bytes for 512 bytes of data (supports error correction up to * max of 1-bit) */ -static inline void stm32_fmc2_nfc_ham_set_ecc(const u32 ecc_sta, u8 *ecc) +static void stm32_fmc2_nfc_ham_set_ecc(const u32 ecc_sta, u8 *ecc) { ecc[0] = ecc_sta; ecc[1] = ecc_sta >> 8; @@ -516,15 +501,15 @@ static int stm32_fmc2_nfc_ham_calculate(struct nand_chip *chip, const u8 *data, u32 sr, heccr; int ret; - ret = readl_relaxed_poll_timeout(nfc->io_base + FMC2_SR, - sr, sr & FMC2_SR_NWRF, 1, - 1000 * FMC2_TIMEOUT_MS); + ret = regmap_read_poll_timeout(nfc->regmap, FMC2_SR, sr, + sr & FMC2_SR_NWRF, 1, + 1000 * FMC2_TIMEOUT_MS); if (ret) { dev_err(nfc->dev, "ham timeout\n"); return ret; } - heccr = readl_relaxed(nfc->io_base + FMC2_HECCR); + regmap_read(nfc->regmap, FMC2_HECCR, &heccr); stm32_fmc2_nfc_ham_set_ecc(heccr, ecc); stm32_fmc2_nfc_set_ecc(nfc, false); @@ -603,13 +588,13 @@ static int stm32_fmc2_nfc_bch_calculate(struct nand_chip *chip, const u8 *data, } /* Read parity bits */ - bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR1); + regmap_read(nfc->regmap, FMC2_BCHPBR1, &bchpbr); ecc[0] = bchpbr; ecc[1] = bchpbr >> 8; ecc[2] = bchpbr >> 16; ecc[3] = bchpbr >> 24; - bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR2); + regmap_read(nfc->regmap, FMC2_BCHPBR2, &bchpbr); ecc[4] = bchpbr; ecc[5] = bchpbr >> 8; ecc[6] = bchpbr >> 16; @@ -617,13 +602,13 @@ static int stm32_fmc2_nfc_bch_calculate(struct nand_chip *chip, const u8 *data, if (chip->ecc.strength == FMC2_ECC_BCH8) { ecc[7] = bchpbr >> 24; - bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR3); + regmap_read(nfc->regmap, FMC2_BCHPBR3, &bchpbr); ecc[8] = bchpbr; ecc[9] = bchpbr >> 8; ecc[10] = bchpbr >> 16; ecc[11] = bchpbr >> 24; - bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR4); + regmap_read(nfc->regmap, FMC2_BCHPBR4, &bchpbr); ecc[12] = bchpbr; } @@ -685,11 +670,7 @@ static int stm32_fmc2_nfc_bch_correct(struct nand_chip *chip, u8 *dat, return -ETIMEDOUT; } - ecc_sta[0] = readl_relaxed(nfc->io_base + FMC2_BCHDSR0); - ecc_sta[1] = readl_relaxed(nfc->io_base + FMC2_BCHDSR1); - ecc_sta[2] = readl_relaxed(nfc->io_base + FMC2_BCHDSR2); - ecc_sta[3] = readl_relaxed(nfc->io_base + FMC2_BCHDSR3); - ecc_sta[4] = readl_relaxed(nfc->io_base + FMC2_BCHDSR4); + regmap_bulk_read(nfc->regmap, FMC2_BCHDSR0, ecc_sta, 5); stm32_fmc2_nfc_set_ecc(nfc, false); @@ -764,30 +745,29 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, { struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct mtd_info *mtd = nand_to_mtd(chip); - u32 csqcfgr1, csqcfgr2, csqcfgr3; - u32 csqar1, csqar2; u32 ecc_offset = mtd->writesize + FMC2_BBM_LEN; - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); + /* + * cfg[0] => csqcfgr1, cfg[1] => csqcfgr2, cfg[2] => csqcfgr3 + * cfg[3] => csqar1, cfg[4] => csqar2 + */ + u32 cfg[5]; - if (write_data) - pcr |= FMC2_PCR_WEN; - else - pcr &= ~FMC2_PCR_WEN; - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + regmap_update_bits(nfc->regmap, FMC2_PCR, FMC2_PCR_WEN, + write_data ? FMC2_PCR_WEN : 0); /* * - Set Program Page/Page Read command * - Enable DMA request data * - Set timings */ - csqcfgr1 = FMC2_CSQCFGR1_DMADEN | FMC2_CSQCFGR1_CMD1T; + cfg[0] = FMC2_CSQCFGR1_DMADEN | FMC2_CSQCFGR1_CMD1T; if (write_data) - csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_SEQIN); + cfg[0] |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_SEQIN); else - csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_READ0) | - FMC2_CSQCFGR1_CMD2EN | - FIELD_PREP(FMC2_CSQCFGR1_CMD2, NAND_CMD_READSTART) | - FMC2_CSQCFGR1_CMD2T; + cfg[0] |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_READ0) | + FMC2_CSQCFGR1_CMD2EN | + FIELD_PREP(FMC2_CSQCFGR1_CMD2, NAND_CMD_READSTART) | + FMC2_CSQCFGR1_CMD2T; /* * - Set Random Data Input/Random Data Read command @@ -796,30 +776,29 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * - Set timings */ if (write_data) - csqcfgr2 = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDIN); + cfg[1] = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDIN); else - csqcfgr2 = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDOUT) | - FMC2_CSQCFGR2_RCMD2EN | - FIELD_PREP(FMC2_CSQCFGR2_RCMD2, - NAND_CMD_RNDOUTSTART) | - FMC2_CSQCFGR2_RCMD1T | - FMC2_CSQCFGR2_RCMD2T; + cfg[1] = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDOUT) | + FMC2_CSQCFGR2_RCMD2EN | + FIELD_PREP(FMC2_CSQCFGR2_RCMD2, NAND_CMD_RNDOUTSTART) | + FMC2_CSQCFGR2_RCMD1T | + FMC2_CSQCFGR2_RCMD2T; if (!raw) { - csqcfgr2 |= write_data ? 0 : FMC2_CSQCFGR2_DMASEN; - csqcfgr2 |= FMC2_CSQCFGR2_SQSDTEN; + cfg[1] |= write_data ? 0 : FMC2_CSQCFGR2_DMASEN; + cfg[1] |= FMC2_CSQCFGR2_SQSDTEN; } /* * - Set the number of sectors to be written * - Set timings */ - csqcfgr3 = FIELD_PREP(FMC2_CSQCFGR3_SNBR, chip->ecc.steps - 1); + cfg[2] = FIELD_PREP(FMC2_CSQCFGR3_SNBR, chip->ecc.steps - 1); if (write_data) { - csqcfgr3 |= FMC2_CSQCFGR3_RAC2T; + cfg[2] |= FMC2_CSQCFGR3_RAC2T; if (chip->options & NAND_ROW_ADDR_3) - csqcfgr3 |= FMC2_CSQCFGR3_AC5T; + cfg[2] |= FMC2_CSQCFGR3_AC5T; else - csqcfgr3 |= FMC2_CSQCFGR3_AC4T; + cfg[2] |= FMC2_CSQCFGR3_AC4T; } /* @@ -827,8 +806,8 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * Byte 1 and byte 2 => column, we start at 0x0 * Byte 3 and byte 4 => page */ - csqar1 = FIELD_PREP(FMC2_CSQCAR1_ADDC3, page); - csqar1 |= FIELD_PREP(FMC2_CSQCAR1_ADDC4, page >> 8); + cfg[3] = FIELD_PREP(FMC2_CSQCAR1_ADDC3, page); + cfg[3] |= FIELD_PREP(FMC2_CSQCAR1_ADDC4, page >> 8); /* * - Set chip enable number @@ -836,23 +815,19 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * - Calculate the number of address cycles to be issued * - Set byte 5 of address cycle if needed */ - csqar2 = FIELD_PREP(FMC2_CSQCAR2_NANDCEN, nfc->cs_sel); + cfg[4] = FIELD_PREP(FMC2_CSQCAR2_NANDCEN, nfc->cs_sel); if (chip->options & NAND_BUSWIDTH_16) - csqar2 |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset >> 1); + cfg[4] |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset >> 1); else - csqar2 |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset); + cfg[4] |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset); if (chip->options & NAND_ROW_ADDR_3) { - csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 5); - csqar2 |= FIELD_PREP(FMC2_CSQCAR2_ADDC5, page >> 16); + cfg[0] |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 5); + cfg[4] |= FIELD_PREP(FMC2_CSQCAR2_ADDC5, page >> 16); } else { - csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 4); + cfg[0] |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 4); } - writel_relaxed(csqcfgr1, nfc->io_base + FMC2_CSQCFGR1); - writel_relaxed(csqcfgr2, nfc->io_base + FMC2_CSQCFGR2); - writel_relaxed(csqcfgr3, nfc->io_base + FMC2_CSQCFGR3); - writel_relaxed(csqar1, nfc->io_base + FMC2_CSQAR1); - writel_relaxed(csqar2, nfc->io_base + FMC2_CSQAR2); + regmap_bulk_write(nfc->regmap, FMC2_CSQCFGR1, cfg, 5); } static void stm32_fmc2_nfc_dma_callback(void *arg) @@ -870,7 +845,6 @@ static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf, struct dma_chan *dma_ch = nfc->dma_rx_ch; enum dma_data_direction dma_data_dir = DMA_FROM_DEVICE; enum dma_transfer_direction dma_transfer_dir = DMA_DEV_TO_MEM; - u32 csqcr = readl_relaxed(nfc->io_base + FMC2_CSQCR); int eccsteps = chip->ecc.steps; int eccsize = chip->ecc.size; unsigned long timeout = msecs_to_jiffies(FMC2_TIMEOUT_MS); @@ -948,8 +922,8 @@ static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf, stm32_fmc2_nfc_enable_seq_irq(nfc); /* Start the transfer */ - csqcr |= FMC2_CSQCR_CSQSTART; - writel_relaxed(csqcr, nfc->io_base + FMC2_CSQCR); + regmap_update_bits(nfc->regmap, FMC2_CSQCR, + FMC2_CSQCR_CSQSTART, FMC2_CSQCR_CSQSTART); /* Wait end of sequencer transfer */ if (!wait_for_completion_timeout(&nfc->complete, timeout)) { @@ -1042,11 +1016,13 @@ static int stm32_fmc2_nfc_seq_write_page_raw(struct nand_chip *chip, } /* Get a status indicating which sectors have errors */ -static inline u16 stm32_fmc2_nfc_get_mapping_status(struct stm32_fmc2_nfc *nfc) +static u16 stm32_fmc2_nfc_get_mapping_status(struct stm32_fmc2_nfc *nfc) { - u32 csqemsr = readl_relaxed(nfc->io_base + FMC2_CSQEMSR); + u32 csqemsr; - return csqemsr & FMC2_CSQEMSR_SEM; + regmap_read(nfc->regmap, FMC2_CSQEMSR, &csqemsr); + + return FIELD_GET(FMC2_CSQEMSR_SEM, csqemsr); } static int stm32_fmc2_nfc_seq_correct(struct nand_chip *chip, u8 *dat, @@ -1302,9 +1278,9 @@ static int stm32_fmc2_nfc_waitrdy(struct nand_chip *chip, u32 isr, sr; /* Check if there is no pending requests to the NAND flash */ - if (readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_SR, sr, - sr & FMC2_SR_NWRF, 1, - 1000 * FMC2_TIMEOUT_MS)) + if (regmap_read_poll_timeout(nfc->regmap, FMC2_SR, sr, + sr & FMC2_SR_NWRF, 1, + 1000 * FMC2_TIMEOUT_MS)) dev_warn(nfc->dev, "Waitrdy timeout\n"); /* Wait tWB before R/B# signal is low */ @@ -1312,12 +1288,12 @@ static int stm32_fmc2_nfc_waitrdy(struct nand_chip *chip, ndelay(PSEC_TO_NSEC(timings->tWB_max)); /* R/B# signal is low, clear high level flag */ - writel_relaxed(FMC2_ICR_CIHLF, nfc->io_base + FMC2_ICR); + regmap_write(nfc->regmap, FMC2_ICR, FMC2_ICR_CIHLF); /* Wait R/B# signal is high */ - return readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_ISR, - isr, isr & FMC2_ISR_IHLF, - 5, 1000 * timeout_ms); + return regmap_read_poll_timeout(nfc->regmap, FMC2_ISR, isr, + isr & FMC2_ISR_IHLF, 5, + 1000 * FMC2_TIMEOUT_MS); } static int stm32_fmc2_nfc_exec_op(struct nand_chip *chip, @@ -1375,8 +1351,9 @@ static int stm32_fmc2_nfc_exec_op(struct nand_chip *chip, static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc) { - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); - u32 bcr1 = readl_relaxed(nfc->io_base + FMC2_BCR1); + u32 pcr; + + regmap_read(nfc->regmap, FMC2_PCR, &pcr); /* Set CS used to undefined */ nfc->cs_sel = -1; @@ -1407,12 +1384,12 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc) pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT); /* Enable FMC2 controller */ - bcr1 |= FMC2_BCR1_FMC2EN; + regmap_update_bits(nfc->regmap, FMC2_BCR1, + FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN); - writel_relaxed(bcr1, nfc->io_base + FMC2_BCR1); - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); - writel_relaxed(FMC2_PMEM_DEFAULT, nfc->io_base + FMC2_PMEM); - writel_relaxed(FMC2_PATT_DEFAULT, nfc->io_base + FMC2_PATT); + regmap_write(nfc->regmap, FMC2_PCR, pcr); + regmap_write(nfc->regmap, FMC2_PMEM, FMC2_PMEM_DEFAULT); + regmap_write(nfc->regmap, FMC2_PATT, FMC2_PATT_DEFAULT); } static void stm32_fmc2_nfc_calc_timings(struct nand_chip *chip, @@ -1847,6 +1824,7 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) struct resource *res; struct mtd_info *mtd; struct nand_chip *chip; + void __iomem *mmio; int chip_cs, mem_region, ret, irq; nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); @@ -1862,9 +1840,13 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - nfc->io_base = devm_ioremap_resource(dev, res); - if (IS_ERR(nfc->io_base)) - return PTR_ERR(nfc->io_base); + mmio = devm_ioremap_resource(dev, res); + if (IS_ERR(mmio)) + return PTR_ERR(mmio); + + nfc->regmap = devm_regmap_init_mmio(dev, mmio, &stm32_fmc2_regmap_cfg); + if (IS_ERR(nfc->regmap)) + return PTR_ERR(nfc->regmap); nfc->io_phys_addr = res->start; From fbd9b5437b668900f6d8c8e29c8aabf4955189ff Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Fri, 12 Jun 2020 17:22:42 +0200 Subject: [PATCH 120/242] mtd: rawnand: stm32_fmc2: get resources from parent node FMC2 EBI support has been added. Common resources (registers base address and clock) can now be shared between the 2 drivers using "st,stm32mp1-fmc2-nfc" compatible string. It means that the common resources should now be found in the parent device when EBI node is available. Signed-off-by: Christophe Kerello Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/1591975362-22009-7-git-send-email-christophe.kerello@st.com --- drivers/mtd/nand/raw/Kconfig | 3 +- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 71 ++++++++++++++++++-------- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 0a03ebf08cd6..8dd0d7c8dfcf 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -415,8 +415,7 @@ config MTD_NAND_TEGRA config MTD_NAND_STM32_FMC2 tristate "Support for NAND controller on STM32MP SoCs" depends on MACH_STM32MP157 || COMPILE_TEST - select REGMAP - select REGMAP_MMIO + select MFD_SYSCON help Enables support for NAND Flash chips on SoCs containing the FMC2 NAND controller. This controller is found on STM32MP SoCs. diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index 6aa36950810c..396b3257f707 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -204,16 +206,6 @@ #define FMC2_BCHDSR4_EBP7 GENMASK(12, 0) #define FMC2_BCHDSR4_EBP8 GENMASK(28, 16) -/* Regmap registers configuration */ -#define FMC2_MAX_REGISTER 0x3fc - -static const struct regmap_config stm32_fmc2_regmap_cfg = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = sizeof(u32), - .max_register = FMC2_MAX_REGISTER, -}; - enum stm32_fmc2_ecc { FMC2_ECC_HAM = 1, FMC2_ECC_BCH4 = 4, @@ -253,6 +245,7 @@ struct stm32_fmc2_nfc { struct nand_controller base; struct stm32_fmc2_nand nand; struct device *dev; + struct device *cdev; struct regmap *regmap; void __iomem *data_base[FMC2_MAX_CE]; void __iomem *cmd_base[FMC2_MAX_CE]; @@ -1384,8 +1377,9 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc) pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT); /* Enable FMC2 controller */ - regmap_update_bits(nfc->regmap, FMC2_BCR1, - FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN); + if (nfc->dev == nfc->cdev) + regmap_update_bits(nfc->regmap, FMC2_BCR1, + FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN); regmap_write(nfc->regmap, FMC2_PCR, pcr); regmap_write(nfc->regmap, FMC2_PMEM, FMC2_PMEM_DEFAULT); @@ -1815,6 +1809,33 @@ static int stm32_fmc2_nfc_parse_dt(struct stm32_fmc2_nfc *nfc) return ret; } +static int stm32_fmc2_nfc_set_cdev(struct stm32_fmc2_nfc *nfc) +{ + struct device *dev = nfc->dev; + bool ebi_found = false; + + if (dev->parent && of_device_is_compatible(dev->parent->of_node, + "st,stm32mp1-fmc2-ebi")) + ebi_found = true; + + if (of_device_is_compatible(dev->of_node, "st,stm32mp1-fmc2-nfc")) { + if (ebi_found) { + nfc->cdev = dev->parent; + + return 0; + } + + return -EINVAL; + } + + if (ebi_found) + return -EINVAL; + + nfc->cdev = dev; + + return 0; +} + static int stm32_fmc2_nfc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1824,8 +1845,9 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) struct resource *res; struct mtd_info *mtd; struct nand_chip *chip; - void __iomem *mmio; + struct resource cres; int chip_cs, mem_region, ret, irq; + int start_region = 0; nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); if (!nfc) @@ -1835,22 +1857,28 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) nand_controller_init(&nfc->base); nfc->base.ops = &stm32_fmc2_nfc_controller_ops; + ret = stm32_fmc2_nfc_set_cdev(nfc); + if (ret) + return ret; + ret = stm32_fmc2_nfc_parse_dt(nfc); if (ret) return ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mmio = devm_ioremap_resource(dev, res); - if (IS_ERR(mmio)) - return PTR_ERR(mmio); + ret = of_address_to_resource(nfc->cdev->of_node, 0, &cres); + if (ret) + return ret; - nfc->regmap = devm_regmap_init_mmio(dev, mmio, &stm32_fmc2_regmap_cfg); + nfc->io_phys_addr = cres.start; + + nfc->regmap = device_node_to_regmap(nfc->cdev->of_node); if (IS_ERR(nfc->regmap)) return PTR_ERR(nfc->regmap); - nfc->io_phys_addr = res->start; + if (nfc->dev == nfc->cdev) + start_region = 1; - for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE; + for (chip_cs = 0, mem_region = start_region; chip_cs < FMC2_MAX_CE; chip_cs++, mem_region += 3) { if (!(nfc->cs_assigned & BIT(chip_cs))) continue; @@ -1888,7 +1916,7 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) init_completion(&nfc->complete); - nfc->clk = devm_clk_get(dev, NULL); + nfc->clk = devm_clk_get(nfc->cdev, NULL); if (IS_ERR(nfc->clk)) return PTR_ERR(nfc->clk); @@ -2029,6 +2057,7 @@ static SIMPLE_DEV_PM_OPS(stm32_fmc2_nfc_pm_ops, stm32_fmc2_nfc_suspend, static const struct of_device_id stm32_fmc2_nfc_match[] = { {.compatible = "st,stm32mp15-fmc2"}, + {.compatible = "st,stm32mp1-fmc2-nfc"}, {} }; MODULE_DEVICE_TABLE(of, stm32_fmc2_nfc_match); From da151e3458c825fa9d57c2db6e37748166e4d129 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 3 Jun 2020 15:49:22 +0200 Subject: [PATCH 121/242] dt-bindings: mtd: fsl-upm-nand: Deprecate chip-delay and fsl, upm-wait-flags Those properties are no longer parsed by the driver which is being passed those information by the core now. Let's deprecate them. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200603134922.1352340-11-boris.brezillon@collabora.com --- Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt b/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt index fce4894f5a98..25f07c1f9e44 100644 --- a/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt +++ b/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt @@ -7,14 +7,16 @@ Required properties: - fsl,upm-cmd-offset : UPM pattern offset for the command latch. Optional properties: -- fsl,upm-wait-flags : add chip-dependent short delays after running the - UPM pattern (0x1), after writing a data byte (0x2) or after - writing out a buffer (0x4). - fsl,upm-addr-line-cs-offsets : address offsets for multi-chip support. The corresponding address lines are used to select the chip. - gpios : may specify optional GPIOs connected to the Ready-Not-Busy pins (R/B#). For multi-chip devices, "n" GPIO definitions are required according to the number of chips. + +Deprecated properties: +- fsl,upm-wait-flags : add chip-dependent short delays after running the + UPM pattern (0x1), after writing a data byte (0x2) or after + writing out a buffer (0x4). - chip-delay : chip dependent delay for transferring data from array to read registers (tR). Required if property "gpios" is not used (R/B# pins not connected). @@ -52,8 +54,6 @@ upm@3,0 { fsl,upm-cmd-offset = <0x08>; /* Multi-chip NAND device */ fsl,upm-addr-line-cs-offsets = <0x0 0x200>; - fsl,upm-wait-flags = <0x5>; - chip-delay = <25>; // in micro-seconds nand@0 { #address-cells = <1>; From 94c70241efbb1e7e008d433d3b020808f1984330 Mon Sep 17 00:00:00 2001 From: Mark Tomlinson Date: Fri, 3 Jul 2020 13:18:30 +1200 Subject: [PATCH 122/242] pinctrl: nsp: Set irq handler based on trig type Rather than always using handle_simple_irq() as the gpio_irq_chip handler, set a more appropriate handler based on the IRQ trigger type requested. This is important for level triggered interrupts which need to be masked during handling. Also, fix the interrupt acknowledge so that it clears only one interrupt instead of all interrupts which are currently active. Finally there is no need to clear the interrupt during the interrupt handler, since the edge-triggered handler will do that for us. Signed-off-by: Mark Tomlinson Reviewed-by: Ray Jui Link: https://lore.kernel.org/r/20200703011830.15655-1-mark.tomlinson@alliedtelesis.co.nz Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-nsp-gpio.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c index bed0124388c0..a00a42a61a90 100644 --- a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c @@ -154,15 +154,9 @@ static irqreturn_t nsp_gpio_irq_handler(int irq, void *data) level &= readl(chip->base + NSP_GPIO_INT_MASK); int_bits = level | event; - for_each_set_bit(bit, &int_bits, gc->ngpio) { - /* - * Clear the interrupt before invoking the - * handler, so we do not leave any window - */ - writel(BIT(bit), chip->base + NSP_GPIO_EVENT); + for_each_set_bit(bit, &int_bits, gc->ngpio) generic_handle_irq( irq_linear_revmap(gc->irq.domain, bit)); - } } return int_bits ? IRQ_HANDLED : IRQ_NONE; @@ -178,7 +172,7 @@ static void nsp_gpio_irq_ack(struct irq_data *d) trigger_type = irq_get_trigger_type(d->irq); if (trigger_type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) - nsp_set_bit(chip, REG, NSP_GPIO_EVENT, gpio, val); + writel(val, chip->base + NSP_GPIO_EVENT); } /* @@ -262,6 +256,12 @@ static int nsp_gpio_irq_set_type(struct irq_data *d, unsigned int type) nsp_set_bit(chip, REG, NSP_GPIO_EVENT_INT_POLARITY, gpio, falling); nsp_set_bit(chip, REG, NSP_GPIO_INT_POLARITY, gpio, level_low); + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(d, handle_edge_irq); + else + irq_set_handler_locked(d, handle_level_irq); + raw_spin_unlock_irqrestore(&chip->lock, flags); dev_dbg(chip->dev, "gpio:%u level_low:%s falling:%s\n", gpio, @@ -691,7 +691,7 @@ static int nsp_gpio_probe(struct platform_device *pdev) girq->num_parents = 0; girq->parents = NULL; girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_simple_irq; + girq->handler = handle_bad_irq; } ret = devm_gpiochip_add_data(dev, gc, chip); From 89b060a01b533a02fdb0dbb6810b5ca64cb33e5e Mon Sep 17 00:00:00 2001 From: Kathiravan T Date: Tue, 7 Jul 2020 13:09:48 +0530 Subject: [PATCH 123/242] pinctrl: qcom: ipq8074: route gpio interrupts to APPS set target proc as APPS to route the gpio interrupts to APPS Co-developed-by: Rajkumar Ayyasamy Signed-off-by: Rajkumar Ayyasamy Signed-off-by: Kathiravan T Acked-by: Bjorn Andersson Link: https://lore.kernel.org/r/1594107588-17055-1-git-send-email-kathirav@codeaurora.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-ipq8074.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/qcom/pinctrl-ipq8074.c b/drivers/pinctrl/qcom/pinctrl-ipq8074.c index 0edd41cdc64f..aec68b1c9f53 100644 --- a/drivers/pinctrl/qcom/pinctrl-ipq8074.c +++ b/drivers/pinctrl/qcom/pinctrl-ipq8074.c @@ -50,6 +50,7 @@ .intr_enable_bit = 0, \ .intr_status_bit = 0, \ .intr_target_bit = 5, \ + .intr_target_kpss_val = 3, \ .intr_raw_status_bit = 4, \ .intr_polarity_bit = 1, \ .intr_detection_bit = 2, \ From 5cec8bc3707be699e2ace103bb4daecfdd0d3386 Mon Sep 17 00:00:00 2001 From: Pratyush Yadav Date: Wed, 24 Jun 2020 00:00:24 +0530 Subject: [PATCH 124/242] mtd: spi-nor: sfdp: do not make invalid quad enable fatal The Micron MT35XU512ABA flash does not support the quad enable bit. But instead of programming the Quad Enable Require field to 000b ("Device does not have a QE bit"), it is programmed to 111b ("Reserved"). While this is technically incorrect, it is not reason enough to abort BFPT parsing. Instead, continue BFPT parsing and let flashes set it in their fixup hooks. Signed-off-by: Pratyush Yadav Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200623183030.26591-12-p.yadav@ti.com --- drivers/mtd/spi-nor/sfdp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index 55c0c508464b..e2a43d39eb5f 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -598,7 +598,8 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, break; default: - return -EINVAL; + dev_dbg(nor->dev, "BFPT QER reserved value used\n"); + break; } /* Stop here if not JESD216 rev C or later. */ From 8c8f97573eb3843ddd2d8cb95c80ce0243b17d7e Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Fri, 26 Jun 2020 14:16:50 +0900 Subject: [PATCH 125/242] mtd: spi-nor: spansion: Remove s70fl01gs from flash_info The s70fl01gs is a dual die stack of two s25fl512s die with dedicated chip select pins to each. Tested with the device and confirmed that is working as two s25fl512s devices. The current device ID in the flash_info table matches with s70fs01gs which does not work with current MTD (s70fs01gs does not support RDSR(05h) which is critical for erase/write). Signed-off-by: Takahiro Kuwano Signed-off-by: Tudor Ambarus Link: https://lore.kernel.org/r/20200626051650.495-1-Takahiro.Kuwano@cypress.com --- drivers/mtd/spi-nor/spansion.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index e550cd5c9d3a..953df1c488ec 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -64,7 +64,6 @@ static const struct flash_info spansion_parts[] = { { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) .fixups = &s25fs_s_fixups, }, - { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, From be192209d5a33c912caa4a05d6f92b89328d8db8 Mon Sep 17 00:00:00 2001 From: Yicong Yang Date: Mon, 6 Jul 2020 17:22:35 +0800 Subject: [PATCH 126/242] mtd: spi-nor: Add capability to disable flash quad mode Previous we didn't provide a way to disable the flash's quad mode. Which means we cannot do some cleanup works when to remove or poweroff the flash, like what set 4-byte address mode does in spi_nor_restore(). Add the capability to disable the flash quad mode, by introducing an enable flag in the flash parameters quad_enable() hooks and related functions. Signed-off-by: Yicong Yang Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/1594027356-19088-2-git-send-email-yangyicong@hisilicon.com --- drivers/mtd/spi-nor/core.c | 55 +++++++++++++++++++++++++------------- drivers/mtd/spi-nor/core.h | 10 +++---- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 0369d98b2d12..ab8f55438e21 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1907,15 +1907,16 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) } /** - * spi_nor_sr1_bit6_quad_enable() - Set the Quad Enable BIT(6) in the Status - * Register 1. + * spi_nor_sr1_bit6_quad_enable() - Set/Unset the Quad Enable BIT(6) in the + * Status Register 1. * @nor: pointer to a 'struct spi_nor' + * @enable: true to enable Quad mode, false to disable Quad mode. * * Bit 6 of the Status Register 1 is the QE bit for Macronix like QSPI memories. * * Return: 0 on success, -errno otherwise. */ -int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor) +int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor, bool enable) { int ret; @@ -1923,45 +1924,56 @@ int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor) if (ret) return ret; - if (nor->bouncebuf[0] & SR1_QUAD_EN_BIT6) + if ((enable && (nor->bouncebuf[0] & SR1_QUAD_EN_BIT6)) || + (!enable && !(nor->bouncebuf[0] & SR1_QUAD_EN_BIT6))) return 0; - nor->bouncebuf[0] |= SR1_QUAD_EN_BIT6; + if (enable) + nor->bouncebuf[0] |= SR1_QUAD_EN_BIT6; + else + nor->bouncebuf[0] &= ~SR1_QUAD_EN_BIT6; return spi_nor_write_sr1_and_check(nor, nor->bouncebuf[0]); } /** - * spi_nor_sr2_bit1_quad_enable() - set the Quad Enable BIT(1) in the Status - * Register 2. + * spi_nor_sr2_bit1_quad_enable() - set/unset the Quad Enable BIT(1) in the + * Status Register 2. * @nor: pointer to a 'struct spi_nor'. + * @enable: true to enable Quad mode, false to disable Quad mode. * * Bit 1 of the Status Register 2 is the QE bit for Spansion like QSPI memories. * * Return: 0 on success, -errno otherwise. */ -int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor) +int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor, bool enable) { int ret; if (nor->flags & SNOR_F_NO_READ_CR) - return spi_nor_write_16bit_cr_and_check(nor, SR2_QUAD_EN_BIT1); + return spi_nor_write_16bit_cr_and_check(nor, + enable ? SR2_QUAD_EN_BIT1 : 0); ret = spi_nor_read_cr(nor, nor->bouncebuf); if (ret) return ret; - if (nor->bouncebuf[0] & SR2_QUAD_EN_BIT1) + if ((enable && (nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)) || + (!enable && !(nor->bouncebuf[0] & SR2_QUAD_EN_BIT1))) return 0; - nor->bouncebuf[0] |= SR2_QUAD_EN_BIT1; + if (enable) + nor->bouncebuf[0] |= SR2_QUAD_EN_BIT1; + else + nor->bouncebuf[0] &= ~SR2_QUAD_EN_BIT1; return spi_nor_write_16bit_cr_and_check(nor, nor->bouncebuf[0]); } /** - * spi_nor_sr2_bit7_quad_enable() - set QE bit in Status Register 2. + * spi_nor_sr2_bit7_quad_enable() - set/unset QE bit in Status Register 2. * @nor: pointer to a 'struct spi_nor' + * @enable: true to enable Quad mode, false to disable Quad mode. * * Set the Quad Enable (QE) bit in the Status Register 2. * @@ -1971,7 +1983,7 @@ int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor) * * Return: 0 on success, -errno otherwise. */ -int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor) +int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor, bool enable) { u8 *sr2 = nor->bouncebuf; int ret; @@ -1981,11 +1993,15 @@ int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor) ret = spi_nor_read_sr2(nor, sr2); if (ret) return ret; - if (*sr2 & SR2_QUAD_EN_BIT7) + if ((enable && (*sr2 & SR2_QUAD_EN_BIT7)) || + (!enable && !(*sr2 & SR2_QUAD_EN_BIT7))) return 0; /* Update the Quad Enable bit. */ - *sr2 |= SR2_QUAD_EN_BIT7; + if (enable) + *sr2 |= SR2_QUAD_EN_BIT7; + else + *sr2 &= ~SR2_QUAD_EN_BIT7; ret = spi_nor_write_sr2(nor, sr2); if (ret) @@ -2898,12 +2914,13 @@ static int spi_nor_init_params(struct spi_nor *nor) } /** - * spi_nor_quad_enable() - enable Quad I/O if needed. + * spi_nor_quad_enable() - enable/disable Quad I/O if needed. * @nor: pointer to a 'struct spi_nor' + * @enable: true to enable Quad mode. false to disable Quad mode. * * Return: 0 on success, -errno otherwise. */ -static int spi_nor_quad_enable(struct spi_nor *nor) +static int spi_nor_quad_enable(struct spi_nor *nor, bool enable) { if (!nor->params->quad_enable) return 0; @@ -2912,7 +2929,7 @@ static int spi_nor_quad_enable(struct spi_nor *nor) spi_nor_get_protocol_width(nor->write_proto) == 4)) return 0; - return nor->params->quad_enable(nor); + return nor->params->quad_enable(nor, enable); } /** @@ -2936,7 +2953,7 @@ static int spi_nor_init(struct spi_nor *nor) { int err; - err = spi_nor_quad_enable(nor); + err = spi_nor_quad_enable(nor, true); if (err) { dev_dbg(nor->dev, "quad mode not supported\n"); return err; diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 6f2f6b27173f..95aa32f3ceb1 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -198,7 +198,7 @@ struct spi_nor_locking_ops { * higher index in the array, the higher priority. * @erase_map: the erase map parsed from the SFDP Sector Map Parameter * Table. - * @quad_enable: enables SPI NOR quad mode. + * @quad_enable: enables/disables SPI NOR Quad mode. * @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode. * @convert_addr: converts an absolute address into something the flash * will understand. Particularly useful when pagesize is @@ -219,7 +219,7 @@ struct spi_nor_flash_parameter { struct spi_nor_erase_map erase_map; - int (*quad_enable)(struct spi_nor *nor); + int (*quad_enable)(struct spi_nor *nor, bool enable); int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable); u32 (*convert_addr)(struct spi_nor *nor, u32 addr); int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps); @@ -406,9 +406,9 @@ int spi_nor_write_ear(struct spi_nor *nor, u8 ear); int spi_nor_wait_till_ready(struct spi_nor *nor); int spi_nor_lock_and_prep(struct spi_nor *nor); void spi_nor_unlock_and_unprep(struct spi_nor *nor); -int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor); -int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor); -int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor); +int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor, bool enable); +int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor, bool enable); +int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor, bool enable); int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr); ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, From cc59e6bb6cd69d3347c06ccce088c5c6052e041e Mon Sep 17 00:00:00 2001 From: Yicong Yang Date: Mon, 6 Jul 2020 17:22:36 +0800 Subject: [PATCH 127/242] mtd: spi-nor: Disable the flash quad mode in spi_nor_restore() If the flash's quad mode is enabled, it'll remain in the quad mode when it's removed. If we drive the flash next time in Standard/Dual SPI mode, the QE bit is not cleared and the function of flash's WP# and RESET#/HOLD# have been switched to IO2 and IO3 and are not restored. Disable the Quad mode in spi_nor_restore(), then the flash's QE bit will be cleared when removed. This will make sure the flash always enter the Standard/Dual SPI mode when loaded. Signed-off-by: Yicong Yang Signed-off-by: Tudor Ambarus Reviewed-by: Pratyush Yadav Link: https://lore.kernel.org/r/1594027356-19088-3-git-send-email-yangyicong@hisilicon.com --- drivers/mtd/spi-nor/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index ab8f55438e21..65eff4ce6ab1 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -3000,6 +3000,8 @@ void spi_nor_restore(struct spi_nor *nor) if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES) && nor->flags & SNOR_F_BROKEN_RESET) nor->params->set_4byte_addr_mode(nor, false); + + spi_nor_quad_enable(nor, false); } EXPORT_SYMBOL_GPL(spi_nor_restore); From c1326210477ecc06c53221f0005c64419aba30d6 Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:20 +0000 Subject: [PATCH 128/242] nfs,nfsd: NFSv4.2 extended attribute protocol definitions Add definitions for the new operations, errors and flags as defined in RFC 8276 (File System Extended Attributes in NFSv4). Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- include/linux/nfs4.h | 20 ++++++++++++++++++++ include/uapi/linux/nfs4.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 4dba3c948932..e6ca9d1d2e76 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -150,6 +150,12 @@ enum nfs_opnum4 { OP_WRITE_SAME = 70, OP_CLONE = 71, + /* xattr support (RFC8726) */ + OP_GETXATTR = 72, + OP_SETXATTR = 73, + OP_LISTXATTRS = 74, + OP_REMOVEXATTR = 75, + OP_ILLEGAL = 10044, }; @@ -280,6 +286,10 @@ enum nfsstat4 { NFS4ERR_WRONG_LFS = 10092, NFS4ERR_BADLABEL = 10093, NFS4ERR_OFFLOAD_NO_REQS = 10094, + + /* xattr (RFC8276) */ + NFS4ERR_NOXATTR = 10095, + NFS4ERR_XATTR2BIG = 10096, }; static inline bool seqid_mutating_err(u32 err) @@ -452,6 +462,7 @@ enum change_attr_type4 { #define FATTR4_WORD2_CHANGE_ATTR_TYPE (1UL << 15) #define FATTR4_WORD2_SECURITY_LABEL (1UL << 16) #define FATTR4_WORD2_MODE_UMASK (1UL << 17) +#define FATTR4_WORD2_XATTR_SUPPORT (1UL << 18) /* MDS threshold bitmap bits */ #define THRESHOLD_RD (1UL << 0) @@ -700,4 +711,13 @@ struct nl4_server { struct nfs42_netaddr nl4_addr; /* NL4_NETADDR */ } u; }; + +/* + * Options for setxattr. These match the flags for setxattr(2). + */ +enum nfs4_setxattr_options { + SETXATTR4_EITHER = 0, + SETXATTR4_CREATE = 1, + SETXATTR4_REPLACE = 2, +}; #endif diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 8572930cf5b0..bf197e99b98f 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -33,6 +33,9 @@ #define NFS4_ACCESS_EXTEND 0x0008 #define NFS4_ACCESS_DELETE 0x0010 #define NFS4_ACCESS_EXECUTE 0x0020 +#define NFS4_ACCESS_XAREAD 0x0040 +#define NFS4_ACCESS_XAWRITE 0x0080 +#define NFS4_ACCESS_XALIST 0x0100 #define NFS4_FH_PERSISTENT 0x0000 #define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001 From 08b5d5014a27e717826999ad20e394a8811aae92 Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:18 +0000 Subject: [PATCH 129/242] xattr: break delegations in {set,remove}xattr set/removexattr on an exported filesystem should break NFS delegations. This is true in general, but also for the upcoming support for RFC 8726 (NFSv4 extended attribute support). Make sure that they do. Additionally, they need to grow a _locked variant, since callers might call this with i_rwsem held (like the NFS server code). Cc: stable@vger.kernel.org # v4.9+ Cc: linux-fsdevel@vger.kernel.org Cc: Al Viro Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- fs/xattr.c | 84 +++++++++++++++++++++++++++++++++++++++---- include/linux/xattr.h | 2 ++ 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/fs/xattr.c b/fs/xattr.c index 91608d9bfc6a..95f38f57347f 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -204,10 +204,22 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, return error; } - +/** + * __vfs_setxattr_locked: set an extended attribute while holding the inode + * lock + * + * @dentry - object to perform setxattr on + * @name - xattr name to set + * @value - value to set @name to + * @size - size of @value + * @flags - flags to pass into filesystem operations + * @delegated_inode - on return, will contain an inode pointer that + * a delegation was broken on, NULL if none. + */ int -vfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags) +__vfs_setxattr_locked(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, + struct inode **delegated_inode) { struct inode *inode = dentry->d_inode; int error; @@ -216,15 +228,40 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value, if (error) return error; - inode_lock(inode); error = security_inode_setxattr(dentry, name, value, size, flags); if (error) goto out; + error = try_break_deleg(inode, delegated_inode); + if (error) + goto out; + error = __vfs_setxattr_noperm(dentry, name, value, size, flags); out: + return error; +} +EXPORT_SYMBOL_GPL(__vfs_setxattr_locked); + +int +vfs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t size, int flags) +{ + struct inode *inode = dentry->d_inode; + struct inode *delegated_inode = NULL; + int error; + +retry_deleg: + inode_lock(inode); + error = __vfs_setxattr_locked(dentry, name, value, size, flags, + &delegated_inode); inode_unlock(inode); + + if (delegated_inode) { + error = break_deleg_wait(&delegated_inode); + if (!error) + goto retry_deleg; + } return error; } EXPORT_SYMBOL_GPL(vfs_setxattr); @@ -378,8 +415,18 @@ __vfs_removexattr(struct dentry *dentry, const char *name) } EXPORT_SYMBOL(__vfs_removexattr); +/** + * __vfs_removexattr_locked: set an extended attribute while holding the inode + * lock + * + * @dentry - object to perform setxattr on + * @name - name of xattr to remove + * @delegated_inode - on return, will contain an inode pointer that + * a delegation was broken on, NULL if none. + */ int -vfs_removexattr(struct dentry *dentry, const char *name) +__vfs_removexattr_locked(struct dentry *dentry, const char *name, + struct inode **delegated_inode) { struct inode *inode = dentry->d_inode; int error; @@ -388,11 +435,14 @@ vfs_removexattr(struct dentry *dentry, const char *name) if (error) return error; - inode_lock(inode); error = security_inode_removexattr(dentry, name); if (error) goto out; + error = try_break_deleg(inode, delegated_inode); + if (error) + goto out; + error = __vfs_removexattr(dentry, name); if (!error) { @@ -401,12 +451,32 @@ vfs_removexattr(struct dentry *dentry, const char *name) } out: + return error; +} +EXPORT_SYMBOL_GPL(__vfs_removexattr_locked); + +int +vfs_removexattr(struct dentry *dentry, const char *name) +{ + struct inode *inode = dentry->d_inode; + struct inode *delegated_inode = NULL; + int error; + +retry_deleg: + inode_lock(inode); + error = __vfs_removexattr_locked(dentry, name, &delegated_inode); inode_unlock(inode); + + if (delegated_inode) { + error = break_deleg_wait(&delegated_inode); + if (!error) + goto retry_deleg; + } + return error; } EXPORT_SYMBOL_GPL(vfs_removexattr); - /* * Extended attribute SET operations */ diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 47eaa34f8761..a2f3cd02653c 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -51,8 +51,10 @@ ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); int __vfs_setxattr(struct dentry *, struct inode *, const char *, const void *, size_t, int); int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int); +int __vfs_setxattr_locked(struct dentry *, const char *, const void *, size_t, int, struct inode **); int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); int __vfs_removexattr(struct dentry *, const char *); +int __vfs_removexattr_locked(struct dentry *, const char *, struct inode **); int vfs_removexattr(struct dentry *, const char *); ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); From cab8d289c5ad541a5351a651d95c4086b7f84d7c Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:19 +0000 Subject: [PATCH 130/242] xattr: add a function to check if a namespace is supported Add a function that checks is an extended attribute namespace is supported for an inode, meaning that a handler must be present for either the whole namespace, or at least one synthetic xattr in the namespace. To be used by the nfs server code when being queried for extended attributes support. Cc: linux-fsdevel@vger.kernel.org Cc: Al Viro Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- fs/xattr.c | 27 +++++++++++++++++++++++++++ include/linux/xattr.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/fs/xattr.c b/fs/xattr.c index 95f38f57347f..386b45676d7e 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -134,6 +134,33 @@ xattr_permission(struct inode *inode, const char *name, int mask) return inode_permission(inode, mask); } +/* + * Look for any handler that deals with the specified namespace. + */ +int +xattr_supported_namespace(struct inode *inode, const char *prefix) +{ + const struct xattr_handler **handlers = inode->i_sb->s_xattr; + const struct xattr_handler *handler; + size_t preflen; + + if (!(inode->i_opflags & IOP_XATTR)) { + if (unlikely(is_bad_inode(inode))) + return -EIO; + return -EOPNOTSUPP; + } + + preflen = strlen(prefix); + + for_each_xattr_handler(handlers, handler) { + if (!strncmp(xattr_prefix(handler), prefix, preflen)) + return 0; + } + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL(xattr_supported_namespace); + int __vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) diff --git a/include/linux/xattr.h b/include/linux/xattr.h index a2f3cd02653c..fac75810d9d3 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -61,6 +61,8 @@ ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_siz ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, size_t size, gfp_t flags); +int xattr_supported_namespace(struct inode *inode, const char *prefix); + static inline const char *xattr_prefix(const struct xattr_handler *handler) { return handler->prefix ?: handler->name; From 874c7b8ea545c7ebc50990843a234eafbc5c0c7f Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:21 +0000 Subject: [PATCH 131/242] nfsd: split off the write decode code into a separate function nfs4_decode_write has code to parse incoming XDR write data in to a kvec head, and a list of pages. Put this code in to a separate function, so that it can be used later by the xattr code, for setxattr. No functional change. Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 72 +++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 996ac01ee977..48806b493eba 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -257,6 +257,44 @@ svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len) return p; } +static __be32 +svcxdr_construct_vector(struct nfsd4_compoundargs *argp, struct kvec *head, + struct page ***pagelist, u32 buflen) +{ + int avail; + int len; + int pages; + + /* Sorry .. no magic macros for this.. * + * READ_BUF(write->wr_buflen); + * SAVEMEM(write->wr_buf, write->wr_buflen); + */ + avail = (char *)argp->end - (char *)argp->p; + if (avail + argp->pagelen < buflen) { + dprintk("NFSD: xdr error (%s:%d)\n", + __FILE__, __LINE__); + return nfserr_bad_xdr; + } + head->iov_base = argp->p; + head->iov_len = avail; + *pagelist = argp->pagelist; + + len = XDR_QUADLEN(buflen) << 2; + if (len >= avail) { + len -= avail; + + pages = len >> PAGE_SHIFT; + argp->pagelist += pages; + argp->pagelen -= pages * PAGE_SIZE; + len -= pages * PAGE_SIZE; + + next_decode_page(argp); + } + argp->p += XDR_QUADLEN(len); + + return 0; +} + /** * savemem - duplicate a chunk of memory for later processing * @argp: NFSv4 compound argument structure to be freed with @@ -1265,8 +1303,6 @@ nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify static __be32 nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) { - int avail; - int len; DECODE_HEAD; status = nfsd4_decode_stateid(argp, &write->wr_stateid); @@ -1279,34 +1315,10 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write) goto xdr_error; write->wr_buflen = be32_to_cpup(p++); - /* Sorry .. no magic macros for this.. * - * READ_BUF(write->wr_buflen); - * SAVEMEM(write->wr_buf, write->wr_buflen); - */ - avail = (char*)argp->end - (char*)argp->p; - if (avail + argp->pagelen < write->wr_buflen) { - dprintk("NFSD: xdr error (%s:%d)\n", - __FILE__, __LINE__); - goto xdr_error; - } - write->wr_head.iov_base = p; - write->wr_head.iov_len = avail; - write->wr_pagelist = argp->pagelist; - - len = XDR_QUADLEN(write->wr_buflen) << 2; - if (len >= avail) { - int pages; - - len -= avail; - - pages = len >> PAGE_SHIFT; - argp->pagelist += pages; - argp->pagelen -= pages * PAGE_SIZE; - len -= pages * PAGE_SIZE; - - next_decode_page(argp); - } - argp->p += XDR_QUADLEN(len); + status = svcxdr_construct_vector(argp, &write->wr_head, + &write->wr_pagelist, write->wr_buflen); + if (status) + return status; DECODE_TAIL; } From 4dd05fceb7eeceac4daeceec0d6a2e6a2528a3e4 Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:22 +0000 Subject: [PATCH 132/242] nfsd: add defines for NFSv4.2 extended attribute support Add defines for server-side extended attribute support. Most have already been added as part of client support, but these are the network order error codes for the noxattr and xattr2big errors, and the addition of the xattr support to the supported file attributes (if configured). Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- fs/nfsd/nfsd.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 57c832d1b30f..cb742e17e04a 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -286,6 +286,8 @@ void nfsd_lockd_shutdown(void); #define nfserr_wrong_lfs cpu_to_be32(NFS4ERR_WRONG_LFS) #define nfserr_badlabel cpu_to_be32(NFS4ERR_BADLABEL) #define nfserr_file_open cpu_to_be32(NFS4ERR_FILE_OPEN) +#define nfserr_xattr2big cpu_to_be32(NFS4ERR_XATTR2BIG) +#define nfserr_noxattr cpu_to_be32(NFS4ERR_NOXATTR) /* error codes for internal use */ /* if a request fails due to kmalloc failure, it gets dropped. @@ -387,7 +389,8 @@ void nfsd_lockd_shutdown(void); (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \ FATTR4_WORD2_CHANGE_ATTR_TYPE | \ FATTR4_WORD2_MODE_UMASK | \ - NFSD4_2_SECURITY_ATTRS) + NFSD4_2_SECURITY_ATTRS | \ + FATTR4_WORD2_XATTR_SUPPORT) extern const u32 nfsd_suppattrs[3][3]; From 32119446bb65da559eb6f05236086fe449d2a024 Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:23 +0000 Subject: [PATCH 133/242] nfsd: define xattr functions to call into their vfs counterparts This adds the filehandle based functions for the xattr operations that call in to the vfs layer to do the actual work. Signed-off-by: Frank van der Linden [ cel: address checkpatch.pl complaint ] Signed-off-by: Chuck Lever --- fs/nfsd/vfs.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/vfs.h | 10 +++ 2 files changed, 237 insertions(+) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index d22a056da477..6d2955253f73 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -2065,6 +2065,233 @@ static int exp_rdonly(struct svc_rqst *rqstp, struct svc_export *exp) return nfsexp_flags(rqstp, exp) & NFSEXP_READONLY; } +#ifdef CONFIG_NFSD_V4 +/* + * Helper function to translate error numbers. In the case of xattr operations, + * some error codes need to be translated outside of the standard translations. + * + * ENODATA needs to be translated to nfserr_noxattr. + * E2BIG to nfserr_xattr2big. + * + * Additionally, vfs_listxattr can return -ERANGE. This means that the + * file has too many extended attributes to retrieve inside an + * XATTR_LIST_MAX sized buffer. This is a bug in the xattr implementation: + * filesystems will allow the adding of extended attributes until they hit + * their own internal limit. This limit may be larger than XATTR_LIST_MAX. + * So, at that point, the attributes are present and valid, but can't + * be retrieved using listxattr, since the upper level xattr code enforces + * the XATTR_LIST_MAX limit. + * + * This bug means that we need to deal with listxattr returning -ERANGE. The + * best mapping is to return TOOSMALL. + */ +static __be32 +nfsd_xattr_errno(int err) +{ + switch (err) { + case -ENODATA: + return nfserr_noxattr; + case -E2BIG: + return nfserr_xattr2big; + case -ERANGE: + return nfserr_toosmall; + } + return nfserrno(err); +} + +/* + * Retrieve the specified user extended attribute. To avoid always + * having to allocate the maximum size (since we are not getting + * a maximum size from the RPC), do a probe + alloc. Hold a reader + * lock on i_rwsem to prevent the extended attribute from changing + * size while we're doing this. + */ +__be32 +nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, + void **bufp, int *lenp) +{ + ssize_t len; + __be32 err; + char *buf; + struct inode *inode; + struct dentry *dentry; + + err = fh_verify(rqstp, fhp, 0, NFSD_MAY_READ); + if (err) + return err; + + err = nfs_ok; + dentry = fhp->fh_dentry; + inode = d_inode(dentry); + + inode_lock_shared(inode); + + len = vfs_getxattr(dentry, name, NULL, 0); + + /* + * Zero-length attribute, just return. + */ + if (len == 0) { + *bufp = NULL; + *lenp = 0; + goto out; + } + + if (len < 0) { + err = nfsd_xattr_errno(len); + goto out; + } + + if (len > *lenp) { + err = nfserr_toosmall; + goto out; + } + + buf = kvmalloc(len, GFP_KERNEL | GFP_NOFS); + if (buf == NULL) { + err = nfserr_jukebox; + goto out; + } + + len = vfs_getxattr(dentry, name, buf, len); + if (len <= 0) { + kvfree(buf); + buf = NULL; + err = nfsd_xattr_errno(len); + } + + *lenp = len; + *bufp = buf; + +out: + inode_unlock_shared(inode); + + return err; +} + +/* + * Retrieve the xattr names. Since we can't know how many are + * user extended attributes, we must get all attributes here, + * and have the XDR encode filter out the "user." ones. + * + * While this could always just allocate an XATTR_LIST_MAX + * buffer, that's a waste, so do a probe + allocate. To + * avoid any changes between the probe and allocate, wrap + * this in inode_lock. + */ +__be32 +nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char **bufp, + int *lenp) +{ + ssize_t len; + __be32 err; + char *buf; + struct inode *inode; + struct dentry *dentry; + + err = fh_verify(rqstp, fhp, 0, NFSD_MAY_READ); + if (err) + return err; + + dentry = fhp->fh_dentry; + inode = d_inode(dentry); + *lenp = 0; + + inode_lock_shared(inode); + + len = vfs_listxattr(dentry, NULL, 0); + if (len <= 0) { + err = nfsd_xattr_errno(len); + goto out; + } + + if (len > XATTR_LIST_MAX) { + err = nfserr_xattr2big; + goto out; + } + + /* + * We're holding i_rwsem - use GFP_NOFS. + */ + buf = kvmalloc(len, GFP_KERNEL | GFP_NOFS); + if (buf == NULL) { + err = nfserr_jukebox; + goto out; + } + + len = vfs_listxattr(dentry, buf, len); + if (len <= 0) { + kvfree(buf); + err = nfsd_xattr_errno(len); + goto out; + } + + *lenp = len; + *bufp = buf; + + err = nfs_ok; +out: + inode_unlock_shared(inode); + + return err; +} + +/* + * Removexattr and setxattr need to call fh_lock to both lock the inode + * and set the change attribute. Since the top-level vfs_removexattr + * and vfs_setxattr calls already do their own inode_lock calls, call + * the _locked variant. Pass in a NULL pointer for delegated_inode, + * and let the client deal with NFS4ERR_DELAY (same as with e.g. + * setattr and remove). + */ +__be32 +nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name) +{ + int err, ret; + + err = fh_verify(rqstp, fhp, 0, NFSD_MAY_WRITE); + if (err) + return err; + + ret = fh_want_write(fhp); + if (ret) + return nfserrno(ret); + + fh_lock(fhp); + + ret = __vfs_removexattr_locked(fhp->fh_dentry, name, NULL); + + fh_unlock(fhp); + fh_drop_write(fhp); + + return nfsd_xattr_errno(ret); +} + +__be32 +nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, char *name, + void *buf, u32 len, u32 flags) +{ + int err, ret; + + err = fh_verify(rqstp, fhp, 0, NFSD_MAY_WRITE); + if (err) + return err; + + ret = fh_want_write(fhp); + if (ret) + return nfserrno(ret); + fh_lock(fhp); + + ret = __vfs_setxattr_locked(fhp->fh_dentry, name, buf, len, flags, + NULL); + + fh_unlock(fhp); + fh_drop_write(fhp); + + return nfsd_xattr_errno(ret); +} +#endif + /* * Check for a user's access permissions to this inode. */ diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 3eb660ad80d1..a2442ebe5acf 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -76,6 +76,16 @@ __be32 do_nfsd_create(struct svc_rqst *, struct svc_fh *, __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, loff_t, unsigned long, __be32 *verf); #endif /* CONFIG_NFSD_V3 */ +#ifdef CONFIG_NFSD_V4 +__be32 nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, + char *name, void **bufp, int *lenp); +__be32 nfsd_listxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, + char **bufp, int *lenp); +__be32 nfsd_removexattr(struct svc_rqst *rqstp, struct svc_fh *fhp, + char *name); +__be32 nfsd_setxattr(struct svc_rqst *rqstp, struct svc_fh *fhp, + char *name, void *buf, u32 len, u32 flags); +#endif int nfsd_open_break_lease(struct inode *, int); __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t, int, struct file **); From c11d7fd1b3178cc651d532bab54adca7f26ae0d0 Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:24 +0000 Subject: [PATCH 134/242] nfsd: take xattr bits into account for permission checks Since the NFSv4.2 extended attributes extension defines 3 new access bits for xattr operations, take them in to account when validating what the client is asking for, and when checking permissions. Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- fs/nfsd/nfs4proc.c | 8 +++++++- fs/nfsd/vfs.c | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a09c35f0f6f0..841aad772798 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -566,8 +566,14 @@ nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { struct nfsd4_access *access = &u->access; + u32 access_full; - if (access->ac_req_access & ~NFS3_ACCESS_FULL) + access_full = NFS3_ACCESS_FULL; + if (cstate->minorversion >= 2) + access_full |= NFS4_ACCESS_XALIST | NFS4_ACCESS_XAREAD | + NFS4_ACCESS_XAWRITE; + + if (access->ac_req_access & ~access_full) return nfserr_inval; access->ac_resp_access = access->ac_req_access; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 6d2955253f73..7d2933b85b65 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -612,6 +612,12 @@ static struct accessmap nfs3_regaccess[] = { { NFS3_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_TRUNC }, { NFS3_ACCESS_EXTEND, NFSD_MAY_WRITE }, +#ifdef CONFIG_NFSD_V4 + { NFS4_ACCESS_XAREAD, NFSD_MAY_READ }, + { NFS4_ACCESS_XAWRITE, NFSD_MAY_WRITE }, + { NFS4_ACCESS_XALIST, NFSD_MAY_READ }, +#endif + { 0, 0 } }; @@ -622,6 +628,12 @@ static struct accessmap nfs3_diraccess[] = { { NFS3_ACCESS_EXTEND, NFSD_MAY_EXEC|NFSD_MAY_WRITE }, { NFS3_ACCESS_DELETE, NFSD_MAY_REMOVE }, +#ifdef CONFIG_NFSD_V4 + { NFS4_ACCESS_XAREAD, NFSD_MAY_READ }, + { NFS4_ACCESS_XAWRITE, NFSD_MAY_WRITE }, + { NFS4_ACCESS_XALIST, NFSD_MAY_READ }, +#endif + { 0, 0 } }; From 6178713bd46b06a1115f5bc6a3ff38e95b6da9ca Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:25 +0000 Subject: [PATCH 135/242] nfsd: add structure definitions for xattr requests / responses Add the structures used in extended attribute request / response handling. Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- fs/nfsd/xdr4.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index db63d39b1507..66499fb6b567 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -224,6 +224,32 @@ struct nfsd4_putfh { bool no_verify; /* represents foreigh fh */ }; +struct nfsd4_getxattr { + char *getxa_name; /* request */ + u32 getxa_len; /* request */ + void *getxa_buf; +}; + +struct nfsd4_setxattr { + u32 setxa_flags; /* request */ + char *setxa_name; /* request */ + char *setxa_buf; /* request */ + u32 setxa_len; /* request */ + struct nfsd4_change_info setxa_cinfo; /* response */ +}; + +struct nfsd4_removexattr { + char *rmxa_name; /* request */ + struct nfsd4_change_info rmxa_cinfo; /* response */ +}; + +struct nfsd4_listxattrs { + u64 lsxa_cookie; /* request */ + u32 lsxa_maxcount; /* request */ + char *lsxa_buf; /* unfiltered buffer (reply) */ + u32 lsxa_len; /* unfiltered len (reply) */ +}; + struct nfsd4_open { u32 op_claim_type; /* request */ struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */ @@ -649,6 +675,11 @@ struct nfsd4_op { struct nfsd4_offload_status offload_status; struct nfsd4_copy_notify copy_notify; struct nfsd4_seek seek; + + struct nfsd4_getxattr getxattr; + struct nfsd4_setxattr setxattr; + struct nfsd4_listxattrs listxattrs; + struct nfsd4_removexattr removexattr; } u; struct nfs4_replay * replay; }; From 23e50fe3a5e6045a573c69d4b0e3d78aa6183323 Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:26 +0000 Subject: [PATCH 136/242] nfsd: implement the xattr functions and en/decode logic Implement the main entry points for the *XATTR operations. Add functions to calculate the reply size for the user extended attribute operations, and implement the XDR encode / decode logic for these operations. Add the user extended attributes operations to nfsd4_ops. Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- fs/nfsd/nfs4proc.c | 120 ++++++++++++ fs/nfsd/nfs4xdr.c | 450 +++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs4.h | 2 +- 3 files changed, 571 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 841aad772798..a527da3d8052 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2097,6 +2097,68 @@ out: } #endif /* CONFIG_NFSD_PNFS */ +static __be32 +nfsd4_getxattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) +{ + struct nfsd4_getxattr *getxattr = &u->getxattr; + + return nfsd_getxattr(rqstp, &cstate->current_fh, + getxattr->getxa_name, &getxattr->getxa_buf, + &getxattr->getxa_len); +} + +static __be32 +nfsd4_setxattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) +{ + struct nfsd4_setxattr *setxattr = &u->setxattr; + __be32 ret; + + if (opens_in_grace(SVC_NET(rqstp))) + return nfserr_grace; + + ret = nfsd_setxattr(rqstp, &cstate->current_fh, setxattr->setxa_name, + setxattr->setxa_buf, setxattr->setxa_len, + setxattr->setxa_flags); + + if (!ret) + set_change_info(&setxattr->setxa_cinfo, &cstate->current_fh); + + return ret; +} + +static __be32 +nfsd4_listxattrs(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) +{ + /* + * Get the entire list, then copy out only the user attributes + * in the encode function. + */ + return nfsd_listxattr(rqstp, &cstate->current_fh, + &u->listxattrs.lsxa_buf, &u->listxattrs.lsxa_len); +} + +static __be32 +nfsd4_removexattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) +{ + struct nfsd4_removexattr *removexattr = &u->removexattr; + __be32 ret; + + if (opens_in_grace(SVC_NET(rqstp))) + return nfserr_grace; + + ret = nfsd_removexattr(rqstp, &cstate->current_fh, + removexattr->rmxa_name); + + if (!ret) + set_change_info(&removexattr->rmxa_cinfo, &cstate->current_fh); + + return ret; +} + /* * NULL call. */ @@ -2706,6 +2768,42 @@ static inline u32 nfsd4_seek_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) return (op_encode_hdr_size + 3) * sizeof(__be32); } +static inline u32 nfsd4_getxattr_rsize(struct svc_rqst *rqstp, + struct nfsd4_op *op) +{ + u32 maxcount, rlen; + + maxcount = svc_max_payload(rqstp); + rlen = min_t(u32, XATTR_SIZE_MAX, maxcount); + + return (op_encode_hdr_size + 1 + XDR_QUADLEN(rlen)) * sizeof(__be32); +} + +static inline u32 nfsd4_setxattr_rsize(struct svc_rqst *rqstp, + struct nfsd4_op *op) +{ + return (op_encode_hdr_size + op_encode_change_info_maxsz) + * sizeof(__be32); +} +static inline u32 nfsd4_listxattrs_rsize(struct svc_rqst *rqstp, + struct nfsd4_op *op) +{ + u32 maxcount, rlen; + + maxcount = svc_max_payload(rqstp); + rlen = min(op->u.listxattrs.lsxa_maxcount, maxcount); + + return (op_encode_hdr_size + 4 + XDR_QUADLEN(rlen)) * sizeof(__be32); +} + +static inline u32 nfsd4_removexattr_rsize(struct svc_rqst *rqstp, + struct nfsd4_op *op) +{ + return (op_encode_hdr_size + op_encode_change_info_maxsz) + * sizeof(__be32); +} + + static const struct nfsd4_operation nfsd4_ops[] = { [OP_ACCESS] = { .op_func = nfsd4_access, @@ -3087,6 +3185,28 @@ static const struct nfsd4_operation nfsd4_ops[] = { .op_name = "OP_COPY_NOTIFY", .op_rsize_bop = nfsd4_copy_notify_rsize, }, + [OP_GETXATTR] = { + .op_func = nfsd4_getxattr, + .op_name = "OP_GETXATTR", + .op_rsize_bop = nfsd4_getxattr_rsize, + }, + [OP_SETXATTR] = { + .op_func = nfsd4_setxattr, + .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, + .op_name = "OP_SETXATTR", + .op_rsize_bop = nfsd4_setxattr_rsize, + }, + [OP_LISTXATTRS] = { + .op_func = nfsd4_listxattrs, + .op_name = "OP_LISTXATTRS", + .op_rsize_bop = nfsd4_listxattrs_rsize, + }, + [OP_REMOVEXATTR] = { + .op_func = nfsd4_removexattr, + .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, + .op_name = "OP_REMOVEXATTR", + .op_rsize_bop = nfsd4_removexattr_rsize, + }, }; /** diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 48806b493eba..8bacc0ceae19 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include "idmap.h" #include "acl.h" @@ -1877,6 +1879,208 @@ nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) DECODE_TAIL; } +/* + * XDR data that is more than PAGE_SIZE in size is normally part of a + * read or write. However, the size of extended attributes is limited + * by the maximum request size, and then further limited by the underlying + * filesystem limits. This can exceed PAGE_SIZE (currently, XATTR_SIZE_MAX + * is 64k). Since there is no kvec- or page-based interface to xattrs, + * and we're not dealing with contiguous pages, we need to do some copying. + */ + +/* + * Decode data into buffer. Uses head and pages constructed by + * svcxdr_construct_vector. + */ +static __be32 +nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct kvec *head, + struct page **pages, char **bufp, u32 buflen) +{ + char *tmp, *dp; + u32 len; + + if (buflen <= head->iov_len) { + /* + * We're in luck, the head has enough space. Just return + * the head, no need for copying. + */ + *bufp = head->iov_base; + return 0; + } + + tmp = svcxdr_tmpalloc(argp, buflen); + if (tmp == NULL) + return nfserr_jukebox; + + dp = tmp; + memcpy(dp, head->iov_base, head->iov_len); + buflen -= head->iov_len; + dp += head->iov_len; + + while (buflen > 0) { + len = min_t(u32, buflen, PAGE_SIZE); + memcpy(dp, page_address(*pages), len); + + buflen -= len; + dp += len; + pages++; + } + + *bufp = tmp; + return 0; +} + +/* + * Get a user extended attribute name from the XDR buffer. + * It will not have the "user." prefix, so prepend it. + * Lastly, check for nul characters in the name. + */ +static __be32 +nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep) +{ + DECODE_HEAD; + char *name, *sp, *dp; + u32 namelen, cnt; + + READ_BUF(4); + namelen = be32_to_cpup(p++); + + if (namelen > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) + return nfserr_nametoolong; + + if (namelen == 0) + goto xdr_error; + + READ_BUF(namelen); + + name = svcxdr_tmpalloc(argp, namelen + XATTR_USER_PREFIX_LEN + 1); + if (!name) + return nfserr_jukebox; + + memcpy(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); + + /* + * Copy the extended attribute name over while checking for 0 + * characters. + */ + sp = (char *)p; + dp = name + XATTR_USER_PREFIX_LEN; + cnt = namelen; + + while (cnt-- > 0) { + if (*sp == '\0') + goto xdr_error; + *dp++ = *sp++; + } + *dp = '\0'; + + *namep = name; + + DECODE_TAIL; +} + +/* + * A GETXATTR op request comes without a length specifier. We just set the + * maximum length for the reply based on XATTR_SIZE_MAX and the maximum + * channel reply size. nfsd_getxattr will probe the length of the xattr, + * check it against getxa_len, and allocate + return the value. + */ +static __be32 +nfsd4_decode_getxattr(struct nfsd4_compoundargs *argp, + struct nfsd4_getxattr *getxattr) +{ + __be32 status; + u32 maxcount; + + status = nfsd4_decode_xattr_name(argp, &getxattr->getxa_name); + if (status) + return status; + + maxcount = svc_max_payload(argp->rqstp); + maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount); + + getxattr->getxa_len = maxcount; + + return status; +} + +static __be32 +nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp, + struct nfsd4_setxattr *setxattr) +{ + DECODE_HEAD; + u32 flags, maxcount, size; + struct kvec head; + struct page **pagelist; + + READ_BUF(4); + flags = be32_to_cpup(p++); + + if (flags > SETXATTR4_REPLACE) + return nfserr_inval; + setxattr->setxa_flags = flags; + + status = nfsd4_decode_xattr_name(argp, &setxattr->setxa_name); + if (status) + return status; + + maxcount = svc_max_payload(argp->rqstp); + maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount); + + READ_BUF(4); + size = be32_to_cpup(p++); + if (size > maxcount) + return nfserr_xattr2big; + + setxattr->setxa_len = size; + if (size > 0) { + status = svcxdr_construct_vector(argp, &head, &pagelist, size); + if (status) + return status; + + status = nfsd4_vbuf_from_vector(argp, &head, pagelist, + &setxattr->setxa_buf, size); + } + + DECODE_TAIL; +} + +static __be32 +nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp, + struct nfsd4_listxattrs *listxattrs) +{ + DECODE_HEAD; + u32 maxcount; + + READ_BUF(12); + p = xdr_decode_hyper(p, &listxattrs->lsxa_cookie); + + /* + * If the cookie is too large to have even one user.x attribute + * plus trailing '\0' left in a maximum size buffer, it's invalid. + */ + if (listxattrs->lsxa_cookie >= + (XATTR_LIST_MAX / (XATTR_USER_PREFIX_LEN + 2))) + return nfserr_badcookie; + + maxcount = be32_to_cpup(p++); + if (maxcount < 8) + /* Always need at least 2 words (length and one character) */ + return nfserr_inval; + + maxcount = min(maxcount, svc_max_payload(argp->rqstp)); + listxattrs->lsxa_maxcount = maxcount; + + DECODE_TAIL; +} + +static __be32 +nfsd4_decode_removexattr(struct nfsd4_compoundargs *argp, + struct nfsd4_removexattr *removexattr) +{ + return nfsd4_decode_xattr_name(argp, &removexattr->rmxa_name); +} + static __be32 nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) { @@ -1973,6 +2177,11 @@ static const nfsd4_dec nfsd4_dec_ops[] = { [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek, [OP_WRITE_SAME] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_CLONE] = (nfsd4_dec)nfsd4_decode_clone, + /* RFC 8276 extended atributes operations */ + [OP_GETXATTR] = (nfsd4_dec)nfsd4_decode_getxattr, + [OP_SETXATTR] = (nfsd4_dec)nfsd4_decode_setxattr, + [OP_LISTXATTRS] = (nfsd4_dec)nfsd4_decode_listxattrs, + [OP_REMOVEXATTR] = (nfsd4_dec)nfsd4_decode_removexattr, }; static inline bool @@ -4458,6 +4667,241 @@ nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p) return nfserr; } +/* + * Encode kmalloc-ed buffer in to XDR stream. + */ +static int +nfsd4_vbuf_to_stream(struct xdr_stream *xdr, char *buf, u32 buflen) +{ + u32 cplen; + __be32 *p; + + cplen = min_t(unsigned long, buflen, + ((void *)xdr->end - (void *)xdr->p)); + p = xdr_reserve_space(xdr, cplen); + if (!p) + return nfserr_resource; + + memcpy(p, buf, cplen); + buf += cplen; + buflen -= cplen; + + while (buflen) { + cplen = min_t(u32, buflen, PAGE_SIZE); + p = xdr_reserve_space(xdr, cplen); + if (!p) + return nfserr_resource; + + memcpy(p, buf, cplen); + + if (cplen < PAGE_SIZE) { + /* + * We're done, with a length that wasn't page + * aligned, so possibly not word aligned. Pad + * any trailing bytes with 0. + */ + xdr_encode_opaque_fixed(p, NULL, cplen); + break; + } + + buflen -= PAGE_SIZE; + buf += PAGE_SIZE; + } + + return 0; +} + +static __be32 +nfsd4_encode_getxattr(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_getxattr *getxattr) +{ + struct xdr_stream *xdr = &resp->xdr; + __be32 *p, err; + + p = xdr_reserve_space(xdr, 4); + if (!p) + return nfserr_resource; + + *p = cpu_to_be32(getxattr->getxa_len); + + if (getxattr->getxa_len == 0) + return 0; + + err = nfsd4_vbuf_to_stream(xdr, getxattr->getxa_buf, + getxattr->getxa_len); + + kvfree(getxattr->getxa_buf); + + return err; +} + +static __be32 +nfsd4_encode_setxattr(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_setxattr *setxattr) +{ + struct xdr_stream *xdr = &resp->xdr; + __be32 *p; + + p = xdr_reserve_space(xdr, 20); + if (!p) + return nfserr_resource; + + encode_cinfo(p, &setxattr->setxa_cinfo); + + return 0; +} + +/* + * See if there are cookie values that can be rejected outright. + */ +static __be32 +nfsd4_listxattr_validate_cookie(struct nfsd4_listxattrs *listxattrs, + u32 *offsetp) +{ + u64 cookie = listxattrs->lsxa_cookie; + + /* + * If the cookie is larger than the maximum number we can fit + * in either the buffer we just got back from vfs_listxattr, or, + * XDR-encoded, in the return buffer, it's invalid. + */ + if (cookie > (listxattrs->lsxa_len) / (XATTR_USER_PREFIX_LEN + 2)) + return nfserr_badcookie; + + if (cookie > (listxattrs->lsxa_maxcount / + (XDR_QUADLEN(XATTR_USER_PREFIX_LEN + 2) + 4))) + return nfserr_badcookie; + + *offsetp = (u32)cookie; + return 0; +} + +static __be32 +nfsd4_encode_listxattrs(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_listxattrs *listxattrs) +{ + struct xdr_stream *xdr = &resp->xdr; + u32 cookie_offset, count_offset, eof; + u32 left, xdrleft, slen, count; + u32 xdrlen, offset; + u64 cookie; + char *sp; + __be32 status; + __be32 *p; + u32 nuser; + + eof = 1; + + status = nfsd4_listxattr_validate_cookie(listxattrs, &offset); + if (status) + goto out; + + /* + * Reserve space for the cookie and the name array count. Record + * the offsets to save them later. + */ + cookie_offset = xdr->buf->len; + count_offset = cookie_offset + 8; + p = xdr_reserve_space(xdr, 12); + if (!p) { + status = nfserr_resource; + goto out; + } + + count = 0; + left = listxattrs->lsxa_len; + sp = listxattrs->lsxa_buf; + nuser = 0; + + xdrleft = listxattrs->lsxa_maxcount; + + while (left > 0 && xdrleft > 0) { + slen = strlen(sp); + + /* + * Check if this a user. attribute, skip it if not. + */ + if (strncmp(sp, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) + goto contloop; + + slen -= XATTR_USER_PREFIX_LEN; + xdrlen = 4 + ((slen + 3) & ~3); + if (xdrlen > xdrleft) { + if (count == 0) { + /* + * Can't even fit the first attribute name. + */ + status = nfserr_toosmall; + goto out; + } + eof = 0; + goto wreof; + } + + left -= XATTR_USER_PREFIX_LEN; + sp += XATTR_USER_PREFIX_LEN; + if (nuser++ < offset) + goto contloop; + + + p = xdr_reserve_space(xdr, xdrlen); + if (!p) { + status = nfserr_resource; + goto out; + } + + p = xdr_encode_opaque(p, sp, slen); + + xdrleft -= xdrlen; + count++; +contloop: + sp += slen + 1; + left -= slen + 1; + } + + /* + * If there were user attributes to copy, but we didn't copy + * any, the offset was too large (e.g. the cookie was invalid). + */ + if (nuser > 0 && count == 0) { + status = nfserr_badcookie; + goto out; + } + +wreof: + p = xdr_reserve_space(xdr, 4); + if (!p) { + status = nfserr_resource; + goto out; + } + *p = cpu_to_be32(eof); + + cookie = offset + count; + + write_bytes_to_xdr_buf(xdr->buf, cookie_offset, &cookie, 8); + count = htonl(count); + write_bytes_to_xdr_buf(xdr->buf, count_offset, &count, 4); +out: + if (listxattrs->lsxa_len) + kvfree(listxattrs->lsxa_buf); + return status; +} + +static __be32 +nfsd4_encode_removexattr(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_removexattr *removexattr) +{ + struct xdr_stream *xdr = &resp->xdr; + __be32 *p; + + p = xdr_reserve_space(xdr, 20); + if (!p) + return nfserr_resource; + + p = encode_cinfo(p, &removexattr->rmxa_cinfo); + return 0; +} + typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *); /* @@ -4547,6 +4991,12 @@ static const nfsd4_enc nfsd4_enc_ops[] = { [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek, [OP_WRITE_SAME] = (nfsd4_enc)nfsd4_encode_noop, [OP_CLONE] = (nfsd4_enc)nfsd4_encode_noop, + + /* RFC 8276 extended atributes operations */ + [OP_GETXATTR] = (nfsd4_enc)nfsd4_encode_getxattr, + [OP_SETXATTR] = (nfsd4_enc)nfsd4_encode_setxattr, + [OP_LISTXATTRS] = (nfsd4_enc)nfsd4_encode_listxattrs, + [OP_REMOVEXATTR] = (nfsd4_enc)nfsd4_encode_removexattr, }; /* diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index e6ca9d1d2e76..33ebe476428e 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -165,7 +165,7 @@ Needs to be updated if more operations are defined in future.*/ #define FIRST_NFS4_OP OP_ACCESS #define LAST_NFS40_OP OP_RELEASE_LOCKOWNER #define LAST_NFS41_OP OP_RECLAIM_COMPLETE -#define LAST_NFS42_OP OP_CLONE +#define LAST_NFS42_OP OP_REMOVEXATTR #define LAST_NFS4_OP LAST_NFS42_OP enum nfsstat4 { From 0e885e846d96df0c8a4a829b1ad355a82ccda656 Mon Sep 17 00:00:00 2001 From: Frank van der Linden Date: Tue, 23 Jun 2020 22:39:27 +0000 Subject: [PATCH 137/242] nfsd: add fattr support for user extended attributes Check if user extended attributes are supported for an inode, and return the answer when being queried for file attributes. An exported filesystem can now signal its RFC8276 user extended attributes capability. Signed-off-by: Frank van der Linden Signed-off-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8bacc0ceae19..259d5ad0e3f4 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3213,6 +3213,15 @@ out_acl: } #endif + if (bmval2 & FATTR4_WORD2_XATTR_SUPPORT) { + p = xdr_reserve_space(xdr, 4); + if (!p) + goto out_resource; + err = xattr_supported_namespace(d_inode(dentry), + XATTR_USER_PREFIX); + *p++ = cpu_to_be32(err == 0); + } + attrlen = htonl(xdr->buf->len - attrlen_offset - 4); write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4); status = nfs_ok; From 10b9d99a3dbbf5e9af838d1887a1047875dcafd9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 18 Apr 2020 18:30:42 -0400 Subject: [PATCH 138/242] SUNRPC: Augment server-side rpcgss tracepoints Add similar tracepoints to those that were recently added on the client side to track failures in the integ and priv unwrap paths. And, let's collect the seqno-specific tracepoints together with a common naming convention. Regarding the gss_check_seq_num() changes: everywhere else treats the GSS sequence number as an unsigned 32-bit integer. As far back as 2.6.12, I couldn't find a compelling reason to do things differently here. As a defensive change it's better to eliminate needless implicit sign conversions. Signed-off-by: Chuck Lever --- include/trace/events/rpcgss.h | 168 +++++++++++++++++++++++++----- net/sunrpc/auth_gss/svcauth_gss.c | 117 ++++++++++++++------- net/sunrpc/auth_gss/trace.c | 3 + 3 files changed, 224 insertions(+), 64 deletions(-) diff --git a/include/trace/events/rpcgss.h b/include/trace/events/rpcgss.h index b9b51a4b1db1..ffdbe6f85da8 100644 --- a/include/trace/events/rpcgss.h +++ b/include/trace/events/rpcgss.h @@ -170,55 +170,144 @@ DECLARE_EVENT_CLASS(rpcgss_ctx_class, DEFINE_CTX_EVENT(init); DEFINE_CTX_EVENT(destroy); +DECLARE_EVENT_CLASS(rpcgss_svc_gssapi_class, + TP_PROTO( + const struct svc_rqst *rqstp, + u32 maj_stat + ), + + TP_ARGS(rqstp, maj_stat), + + TP_STRUCT__entry( + __field(u32, xid) + __field(u32, maj_stat) + __string(addr, rqstp->rq_xprt->xpt_remotebuf) + ), + + TP_fast_assign( + __entry->xid = __be32_to_cpu(rqstp->rq_xid); + __entry->maj_stat = maj_stat; + __assign_str(addr, rqstp->rq_xprt->xpt_remotebuf); + ), + + TP_printk("addr=%s xid=0x%08x maj_stat=%s", + __get_str(addr), __entry->xid, + __entry->maj_stat == 0 ? + "GSS_S_COMPLETE" : show_gss_status(__entry->maj_stat)) +); + +#define DEFINE_SVC_GSSAPI_EVENT(name) \ + DEFINE_EVENT(rpcgss_svc_gssapi_class, rpcgss_svc_##name, \ + TP_PROTO( \ + const struct svc_rqst *rqstp, \ + u32 maj_stat \ + ), \ + TP_ARGS(rqstp, maj_stat)) + +DEFINE_SVC_GSSAPI_EVENT(unwrap); +DEFINE_SVC_GSSAPI_EVENT(mic); + +TRACE_EVENT(rpcgss_svc_unwrap_failed, + TP_PROTO( + const struct svc_rqst *rqstp + ), + + TP_ARGS(rqstp), + + TP_STRUCT__entry( + __field(u32, xid) + __string(addr, rqstp->rq_xprt->xpt_remotebuf) + ), + + TP_fast_assign( + __entry->xid = be32_to_cpu(rqstp->rq_xid); + __assign_str(addr, rqstp->rq_xprt->xpt_remotebuf); + ), + + TP_printk("addr=%s xid=0x%08x", __get_str(addr), __entry->xid) +); + +TRACE_EVENT(rpcgss_svc_seqno_bad, + TP_PROTO( + const struct svc_rqst *rqstp, + u32 expected, + u32 received + ), + + TP_ARGS(rqstp, expected, received), + + TP_STRUCT__entry( + __field(u32, expected) + __field(u32, received) + __field(u32, xid) + __string(addr, rqstp->rq_xprt->xpt_remotebuf) + ), + + TP_fast_assign( + __entry->expected = expected; + __entry->received = received; + __entry->xid = __be32_to_cpu(rqstp->rq_xid); + __assign_str(addr, rqstp->rq_xprt->xpt_remotebuf); + ), + + TP_printk("addr=%s xid=0x%08x expected seqno %u, received seqno %u", + __get_str(addr), __entry->xid, + __entry->expected, __entry->received) +); + TRACE_EVENT(rpcgss_svc_accept_upcall, TP_PROTO( - __be32 xid, + const struct svc_rqst *rqstp, u32 major_status, u32 minor_status ), - TP_ARGS(xid, major_status, minor_status), + TP_ARGS(rqstp, major_status, minor_status), TP_STRUCT__entry( - __field(u32, xid) __field(u32, minor_status) __field(unsigned long, major_status) + __field(u32, xid) + __string(addr, rqstp->rq_xprt->xpt_remotebuf) ), TP_fast_assign( - __entry->xid = be32_to_cpu(xid); __entry->minor_status = minor_status; __entry->major_status = major_status; + __entry->xid = be32_to_cpu(rqstp->rq_xid); + __assign_str(addr, rqstp->rq_xprt->xpt_remotebuf); ), - TP_printk("xid=0x%08x major_status=%s (0x%08lx) minor_status=%u", - __entry->xid, __entry->major_status == 0 ? "GSS_S_COMPLETE" : - show_gss_status(__entry->major_status), + TP_printk("addr=%s xid=0x%08x major_status=%s (0x%08lx) minor_status=%u", + __get_str(addr), __entry->xid, + (__entry->major_status == 0) ? "GSS_S_COMPLETE" : + show_gss_status(__entry->major_status), __entry->major_status, __entry->minor_status ) ); -TRACE_EVENT(rpcgss_svc_accept, +TRACE_EVENT(rpcgss_svc_authenticate, TP_PROTO( - __be32 xid, - size_t len + const struct svc_rqst *rqstp, + const struct rpc_gss_wire_cred *gc ), - TP_ARGS(xid, len), + TP_ARGS(rqstp, gc), TP_STRUCT__entry( + __field(u32, seqno) __field(u32, xid) - __field(size_t, len) + __string(addr, rqstp->rq_xprt->xpt_remotebuf) ), TP_fast_assign( - __entry->xid = be32_to_cpu(xid); - __entry->len = len; + __entry->xid = be32_to_cpu(rqstp->rq_xid); + __entry->seqno = gc->gc_seq; + __assign_str(addr, rqstp->rq_xprt->xpt_remotebuf); ), - TP_printk("xid=0x%08x len=%zu", - __entry->xid, __entry->len - ) + TP_printk("addr=%s xid=0x%08x seqno=%u", __get_str(addr), + __entry->xid, __entry->seqno) ); @@ -371,11 +460,11 @@ TRACE_EVENT(rpcgss_update_slack, DECLARE_EVENT_CLASS(rpcgss_svc_seqno_class, TP_PROTO( - __be32 xid, + const struct svc_rqst *rqstp, u32 seqno ), - TP_ARGS(xid, seqno), + TP_ARGS(rqstp, seqno), TP_STRUCT__entry( __field(u32, xid) @@ -383,25 +472,52 @@ DECLARE_EVENT_CLASS(rpcgss_svc_seqno_class, ), TP_fast_assign( - __entry->xid = be32_to_cpu(xid); + __entry->xid = be32_to_cpu(rqstp->rq_xid); __entry->seqno = seqno; ), - TP_printk("xid=0x%08x seqno=%u, request discarded", + TP_printk("xid=0x%08x seqno=%u", __entry->xid, __entry->seqno) ); #define DEFINE_SVC_SEQNO_EVENT(name) \ - DEFINE_EVENT(rpcgss_svc_seqno_class, rpcgss_svc_##name, \ + DEFINE_EVENT(rpcgss_svc_seqno_class, rpcgss_svc_seqno_##name, \ TP_PROTO( \ - __be32 xid, \ + const struct svc_rqst *rqstp, \ u32 seqno \ ), \ - TP_ARGS(xid, seqno)) + TP_ARGS(rqstp, seqno)) -DEFINE_SVC_SEQNO_EVENT(large_seqno); -DEFINE_SVC_SEQNO_EVENT(old_seqno); +DEFINE_SVC_SEQNO_EVENT(large); +DEFINE_SVC_SEQNO_EVENT(seen); +TRACE_EVENT(rpcgss_svc_seqno_low, + TP_PROTO( + const struct svc_rqst *rqstp, + u32 seqno, + u32 min, + u32 max + ), + + TP_ARGS(rqstp, seqno, min, max), + + TP_STRUCT__entry( + __field(u32, xid) + __field(u32, seqno) + __field(u32, min) + __field(u32, max) + ), + + TP_fast_assign( + __entry->xid = be32_to_cpu(rqstp->rq_xid); + __entry->seqno = seqno; + __entry->min = min; + __entry->max = max; + ), + + TP_printk("xid=0x%08x seqno=%u window=[%u..%u]", + __entry->xid, __entry->seqno, __entry->min, __entry->max) +); /** ** gssd upcall related trace events diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 46027d0c903f..7d83f54aaaa6 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -332,7 +332,7 @@ static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct r struct gss_svc_seq_data { /* highest seq number seen so far: */ - int sd_max; + u32 sd_max; /* for i such that sd_max-GSS_SEQ_WIN < i <= sd_max, the i-th bit of * sd_win is nonzero iff sequence number i has been seen already: */ unsigned long sd_win[GSS_SEQ_WIN/BITS_PER_LONG]; @@ -613,16 +613,29 @@ gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle) return found; } -/* Implements sequence number algorithm as specified in RFC 2203. */ -static int -gss_check_seq_num(struct rsc *rsci, int seq_num) +/** + * gss_check_seq_num - GSS sequence number window check + * @rqstp: RPC Call to use when reporting errors + * @rsci: cached GSS context state (updated on return) + * @seq_num: sequence number to check + * + * Implements sequence number algorithm as specified in + * RFC 2203, Section 5.3.3.1. "Context Management". + * + * Return values: + * %true: @rqstp's GSS sequence number is inside the window + * %false: @rqstp's GSS sequence number is outside the window + */ +static bool gss_check_seq_num(const struct svc_rqst *rqstp, struct rsc *rsci, + u32 seq_num) { struct gss_svc_seq_data *sd = &rsci->seqdata; + bool result = false; spin_lock(&sd->sd_lock); if (seq_num > sd->sd_max) { if (seq_num >= sd->sd_max + GSS_SEQ_WIN) { - memset(sd->sd_win,0,sizeof(sd->sd_win)); + memset(sd->sd_win, 0, sizeof(sd->sd_win)); sd->sd_max = seq_num; } else while (sd->sd_max < seq_num) { sd->sd_max++; @@ -631,17 +644,25 @@ gss_check_seq_num(struct rsc *rsci, int seq_num) __set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win); goto ok; } else if (seq_num <= sd->sd_max - GSS_SEQ_WIN) { - goto drop; + goto toolow; } - /* sd_max - GSS_SEQ_WIN < seq_num <= sd_max */ if (__test_and_set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win)) - goto drop; + goto alreadyseen; + ok: + result = true; +out: spin_unlock(&sd->sd_lock); - return 1; -drop: - spin_unlock(&sd->sd_lock); - return 0; + return result; + +toolow: + trace_rpcgss_svc_seqno_low(rqstp, seq_num, + sd->sd_max - GSS_SEQ_WIN, + sd->sd_max); + goto out; +alreadyseen: + trace_rpcgss_svc_seqno_seen(rqstp, seq_num); + goto out; } static inline u32 round_up_to_quad(u32 i) @@ -721,14 +742,12 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci, } if (gc->gc_seq > MAXSEQ) { - trace_rpcgss_svc_large_seqno(rqstp->rq_xid, gc->gc_seq); + trace_rpcgss_svc_seqno_large(rqstp, gc->gc_seq); *authp = rpcsec_gsserr_ctxproblem; return SVC_DENIED; } - if (!gss_check_seq_num(rsci, gc->gc_seq)) { - trace_rpcgss_svc_old_seqno(rqstp->rq_xid, gc->gc_seq); + if (!gss_check_seq_num(rqstp, rsci, gc->gc_seq)) return SVC_DROP; - } return SVC_OK; } @@ -866,11 +885,13 @@ read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj) static int unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx) { + u32 integ_len, rseqno, maj_stat; int stat = -EINVAL; - u32 integ_len, maj_stat; struct xdr_netobj mic; struct xdr_buf integ_buf; + mic.data = NULL; + /* NFS READ normally uses splice to send data in-place. However * the data in cache can change after the reply's MIC is computed * but before the RPC reply is sent. To prevent the client from @@ -885,34 +906,44 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g integ_len = svc_getnl(&buf->head[0]); if (integ_len & 3) - return stat; + goto unwrap_failed; if (integ_len > buf->len) - return stat; - if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len)) { - WARN_ON_ONCE(1); - return stat; - } + goto unwrap_failed; + if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len)) + goto unwrap_failed; + /* copy out mic... */ if (read_u32_from_xdr_buf(buf, integ_len, &mic.len)) - return stat; + goto unwrap_failed; if (mic.len > RPC_MAX_AUTH_SIZE) - return stat; + goto unwrap_failed; mic.data = kmalloc(mic.len, GFP_KERNEL); if (!mic.data) - return stat; + goto unwrap_failed; if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len)) - goto out; + goto unwrap_failed; maj_stat = gss_verify_mic(ctx, &integ_buf, &mic); if (maj_stat != GSS_S_COMPLETE) - goto out; - if (svc_getnl(&buf->head[0]) != seq) - goto out; + goto bad_mic; + rseqno = svc_getnl(&buf->head[0]); + if (rseqno != seq) + goto bad_seqno; /* trim off the mic and padding at the end before returning */ xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4); stat = 0; out: kfree(mic.data); return stat; + +unwrap_failed: + trace_rpcgss_svc_unwrap_failed(rqstp); + goto out; +bad_seqno: + trace_rpcgss_svc_seqno_bad(rqstp, seq, rseqno); + goto out; +bad_mic: + trace_rpcgss_svc_mic(rqstp, maj_stat); + goto out; } static inline int @@ -937,6 +968,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs { u32 priv_len, maj_stat; int pad, remaining_len, offset; + u32 rseqno; clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); @@ -951,7 +983,7 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs * not yet read from the head, so these two values are different: */ remaining_len = total_buf_len(buf); if (priv_len > remaining_len) - return -EINVAL; + goto unwrap_failed; pad = remaining_len - priv_len; buf->len -= pad; fix_priv_head(buf, pad); @@ -972,11 +1004,22 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs fix_priv_head(buf, pad); } if (maj_stat != GSS_S_COMPLETE) - return -EINVAL; + goto bad_unwrap; out_seq: - if (svc_getnl(&buf->head[0]) != seq) - return -EINVAL; + rseqno = svc_getnl(&buf->head[0]); + if (rseqno != seq) + goto bad_seqno; return 0; + +unwrap_failed: + trace_rpcgss_svc_unwrap_failed(rqstp); + return -EINVAL; +bad_seqno: + trace_rpcgss_svc_seqno_bad(rqstp, seq, rseqno); + return -EINVAL; +bad_unwrap: + trace_rpcgss_svc_unwrap(rqstp, maj_stat); + return -EINVAL; } struct gss_svc_data { @@ -1314,8 +1357,7 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp, if (status) goto out; - trace_rpcgss_svc_accept_upcall(rqstp->rq_xid, ud.major_status, - ud.minor_status); + trace_rpcgss_svc_accept_upcall(rqstp, ud.major_status, ud.minor_status); switch (ud.major_status) { case GSS_S_CONTINUE_NEEDED: @@ -1490,8 +1532,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) int ret; struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id); - trace_rpcgss_svc_accept(rqstp->rq_xid, argv->iov_len); - *authp = rpc_autherr_badcred; if (!svcdata) svcdata = kmalloc(sizeof(*svcdata), GFP_KERNEL); @@ -1608,6 +1648,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) GSS_C_QOP_DEFAULT, gc->gc_svc); ret = SVC_OK; + trace_rpcgss_svc_authenticate(rqstp, gc); goto out; } garbage_args: diff --git a/net/sunrpc/auth_gss/trace.c b/net/sunrpc/auth_gss/trace.c index 49fa583d7f91..d26036a57443 100644 --- a/net/sunrpc/auth_gss/trace.c +++ b/net/sunrpc/auth_gss/trace.c @@ -5,6 +5,9 @@ #include #include +#include +#include +#include #include #include From e814eecbe3bbeaa8b004d25a4b8974d232b765a9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 11 Jun 2020 12:44:56 -0400 Subject: [PATCH 139/242] svcrdma: Fix page leak in svc_rdma_recv_read_chunk() Commit 07d0ff3b0cd2 ("svcrdma: Clean up Read chunk path") moved the page saver logic so that it gets executed event when an error occurs. In that case, the I/O is never posted, and those pages are then leaked. Errors in this path, however, are quite rare. Fixes: 07d0ff3b0cd2 ("svcrdma: Clean up Read chunk path") Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_rw.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index 5eb35309ecef..83806fa94def 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -684,7 +684,6 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, struct svc_rdma_read_info *info, __be32 *p) { - unsigned int i; int ret; ret = -EINVAL; @@ -707,12 +706,6 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, info->ri_chunklen += rs_length; } - /* Pages under I/O have been copied to head->rc_pages. - * Prevent their premature release by svc_xprt_release() . - */ - for (i = 0; i < info->ri_readctxt->rc_page_count; i++) - rqstp->rq_pages[i] = NULL; - return ret; } @@ -807,6 +800,26 @@ out: return ret; } +/* Pages under I/O have been copied to head->rc_pages. Ensure they + * are not released by svc_xprt_release() until the I/O is complete. + * + * This has to be done after all Read WRs are constructed to properly + * handle a page that is part of I/O on behalf of two different RDMA + * segments. + * + * Do this only if I/O has been posted. Otherwise, we do indeed want + * svc_xprt_release() to clean things up properly. + */ +static void svc_rdma_save_io_pages(struct svc_rqst *rqstp, + const unsigned int start, + const unsigned int num_pages) +{ + unsigned int i; + + for (i = start; i < num_pages + start; i++) + rqstp->rq_pages[i] = NULL; +} + /** * svc_rdma_recv_read_chunk - Pull a Read chunk from the client * @rdma: controlling RDMA transport @@ -860,6 +873,7 @@ int svc_rdma_recv_read_chunk(struct svcxprt_rdma *rdma, struct svc_rqst *rqstp, ret = svc_rdma_post_chunk_ctxt(&info->ri_cc); if (ret < 0) goto out_err; + svc_rdma_save_io_pages(rqstp, 0, head->rc_page_count); return 0; out_err: From 6e9fab7073e5b6bdba4d5891cd486ffdd7de373f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Mar 2020 11:15:55 -0400 Subject: [PATCH 140/242] svcrdma: Remove save_io_pages() call from send_error_msg() Commit 4757d90b15d8 ("svcrdma: Report Write/Reply chunk overruns") made an effort to preserve I/O pages until RDMA Write completion. In a subsequent patch, I intend to de-duplicate the two functions that send ERR_CHUNK responses. Pull the save_io_pages() call out of svc_rdma_send_error_msg() to make it more like svc_rdma_send_error(). Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 38e7c3c8c4a9..2f88d01e8d27 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -806,8 +806,7 @@ static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, /* Given the client-provided Write and Reply chunks, the server was not * able to form a complete reply. Return an RDMA_ERROR message so the - * client can retire this RPC transaction. As above, the Send completion - * routine releases payload pages that were part of a previous RDMA Write. + * client can retire this RPC transaction. * * Remote Invalidation is skipped for simplicity. */ @@ -834,8 +833,6 @@ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, *p = err_chunk; trace_svcrdma_err_chunk(*rdma_argp); - svc_rdma_save_io_pages(rqstp, ctxt); - ctxt->sc_send_wr.num_sge = 1; ctxt->sc_send_wr.opcode = IB_WR_SEND; ctxt->sc_sges[0].length = ctxt->sc_hdrbuf.len; @@ -930,6 +927,10 @@ int svc_rdma_sendto(struct svc_rqst *rqstp) if (ret != -E2BIG && ret != -EINVAL) goto err1; + /* Send completion releases payload pages that were part + * of previously posted RDMA Writes. + */ + svc_rdma_save_io_pages(rqstp, sctxt); ret = svc_rdma_send_error_msg(rdma, sctxt, rqstp); if (ret < 0) goto err1; From d1f6e2369c63f2cbc7a7441d3ee9b0eabfa9a327 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Mar 2020 11:31:37 -0400 Subject: [PATCH 141/242] svcrdma: Add @rctxt parameter to svc_rdma_send_error() functions Another step towards making svc_rdma_send_error_msg() and svc_rdma_send_error() similar enough to eliminate one of them. Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 9 +++++---- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 23 +++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index e426fedb9524..60d855116ae7 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -715,10 +715,11 @@ static void rdma_read_complete(struct svc_rqst *rqstp, } static void svc_rdma_send_error(struct svcxprt_rdma *xprt, - __be32 *rdma_argp, int status) + struct svc_rdma_recv_ctxt *rctxt, + int status) { + __be32 *p, *rdma_argp = rctxt->rc_recv_buf; struct svc_rdma_send_ctxt *ctxt; - __be32 *p; int ret; ctxt = svc_rdma_send_ctxt_get(xprt); @@ -900,13 +901,13 @@ out_readchunk: return 0; out_err: - svc_rdma_send_error(rdma_xprt, p, ret); + svc_rdma_send_error(rdma_xprt, ctxt, ret); svc_rdma_recv_ctxt_put(rdma_xprt, ctxt); return 0; out_postfail: if (ret == -EINVAL) - svc_rdma_send_error(rdma_xprt, p, ret); + svc_rdma_send_error(rdma_xprt, ctxt, ret); svc_rdma_recv_ctxt_put(rdma_xprt, ctxt); return ret; diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 2f88d01e8d27..47ada61411c3 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -811,18 +811,17 @@ static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, * Remote Invalidation is skipped for simplicity. */ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, - struct svc_rdma_send_ctxt *ctxt, - struct svc_rqst *rqstp) + struct svc_rdma_send_ctxt *sctxt, + struct svc_rdma_recv_ctxt *rctxt) { - struct svc_rdma_recv_ctxt *rctxt = rqstp->rq_xprt_ctxt; __be32 *rdma_argp = rctxt->rc_recv_buf; __be32 *p; - rpcrdma_set_xdrlen(&ctxt->sc_hdrbuf, 0); - xdr_init_encode(&ctxt->sc_stream, &ctxt->sc_hdrbuf, ctxt->sc_xprt_buf, - NULL); + rpcrdma_set_xdrlen(&sctxt->sc_hdrbuf, 0); + xdr_init_encode(&sctxt->sc_stream, &sctxt->sc_hdrbuf, + sctxt->sc_xprt_buf, NULL); - p = xdr_reserve_space(&ctxt->sc_stream, RPCRDMA_HDRLEN_ERR); + p = xdr_reserve_space(&sctxt->sc_stream, RPCRDMA_HDRLEN_ERR); if (!p) return -ENOMSG; @@ -833,10 +832,10 @@ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, *p = err_chunk; trace_svcrdma_err_chunk(*rdma_argp); - ctxt->sc_send_wr.num_sge = 1; - ctxt->sc_send_wr.opcode = IB_WR_SEND; - ctxt->sc_sges[0].length = ctxt->sc_hdrbuf.len; - return svc_rdma_send(rdma, &ctxt->sc_send_wr); + sctxt->sc_send_wr.num_sge = 1; + sctxt->sc_send_wr.opcode = IB_WR_SEND; + sctxt->sc_sges[0].length = sctxt->sc_hdrbuf.len; + return svc_rdma_send(rdma, &sctxt->sc_send_wr); } /** @@ -931,7 +930,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp) * of previously posted RDMA Writes. */ svc_rdma_save_io_pages(rqstp, sctxt); - ret = svc_rdma_send_error_msg(rdma, sctxt, rqstp); + ret = svc_rdma_send_error_msg(rdma, sctxt, rctxt); if (ret < 0) goto err1; return 0; From 4f200bd8affbccc3152d497b4ce5cfaca5a7c53f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Mar 2020 11:57:51 -0400 Subject: [PATCH 142/242] svcrdma: Add a @status parameter to svc_rdma_send_error_msg() The common "send RDMA_ERR" function should be in svc_rdma_sendto.c, since that is where the other Send-related functions are located. So from here, I will beef up svc_rdma_send_error_msg() and deprecate svc_rdma_send_error(). A generic svc_rdma_send_error_msg() will need to handle both ERR_CHUNK and ERR_VERS. Copy that logic from svc_rdma_send_error() to svc_rdma_send_error_msg(). Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 32 ++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 47ada61411c3..73fe7a213169 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -812,7 +812,8 @@ static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, */ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, struct svc_rdma_send_ctxt *sctxt, - struct svc_rdma_recv_ctxt *rctxt) + struct svc_rdma_recv_ctxt *rctxt, + int status) { __be32 *rdma_argp = rctxt->rc_recv_buf; __be32 *p; @@ -821,16 +822,35 @@ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, xdr_init_encode(&sctxt->sc_stream, &sctxt->sc_hdrbuf, sctxt->sc_xprt_buf, NULL); - p = xdr_reserve_space(&sctxt->sc_stream, RPCRDMA_HDRLEN_ERR); + p = xdr_reserve_space(&sctxt->sc_stream, + rpcrdma_fixed_maxsz * sizeof(*p)); if (!p) return -ENOMSG; *p++ = *rdma_argp; *p++ = *(rdma_argp + 1); *p++ = rdma->sc_fc_credits; - *p++ = rdma_error; - *p = err_chunk; - trace_svcrdma_err_chunk(*rdma_argp); + *p = rdma_error; + + switch (status) { + case -EPROTONOSUPPORT: + p = xdr_reserve_space(&sctxt->sc_stream, 3 * sizeof(*p)); + if (!p) + return -ENOMSG; + + *p++ = err_vers; + *p++ = rpcrdma_version; + *p = rpcrdma_version; + trace_svcrdma_err_vers(*rdma_argp); + break; + default: + p = xdr_reserve_space(&sctxt->sc_stream, sizeof(*p)); + if (!p) + return -ENOMSG; + + *p = err_chunk; + trace_svcrdma_err_chunk(*rdma_argp); + } sctxt->sc_send_wr.num_sge = 1; sctxt->sc_send_wr.opcode = IB_WR_SEND; @@ -930,7 +950,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp) * of previously posted RDMA Writes. */ svc_rdma_save_io_pages(rqstp, sctxt); - ret = svc_rdma_send_error_msg(rdma, sctxt, rctxt); + ret = svc_rdma_send_error_msg(rdma, sctxt, rctxt, ret); if (ret < 0) goto err1; return 0; From 605c61bee5b13bc9d597192779865a1a707166ed Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Mar 2020 14:38:07 -0400 Subject: [PATCH 143/242] svcrdma: Eliminate return value for svc_rdma_send_error_msg() Like svc_rdma_send_error(), have svc_rdma_send_error_msg() handle any error conditions internally, rather than duplicating that recovery logic at every call site. Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 73fe7a213169..fb548b548c4b 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -810,10 +810,10 @@ static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, * * Remote Invalidation is skipped for simplicity. */ -static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, - struct svc_rdma_send_ctxt *sctxt, - struct svc_rdma_recv_ctxt *rctxt, - int status) +static void svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, + struct svc_rdma_send_ctxt *sctxt, + struct svc_rdma_recv_ctxt *rctxt, + int status) { __be32 *rdma_argp = rctxt->rc_recv_buf; __be32 *p; @@ -825,7 +825,7 @@ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, p = xdr_reserve_space(&sctxt->sc_stream, rpcrdma_fixed_maxsz * sizeof(*p)); if (!p) - return -ENOMSG; + goto put_ctxt; *p++ = *rdma_argp; *p++ = *(rdma_argp + 1); @@ -836,7 +836,7 @@ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, case -EPROTONOSUPPORT: p = xdr_reserve_space(&sctxt->sc_stream, 3 * sizeof(*p)); if (!p) - return -ENOMSG; + goto put_ctxt; *p++ = err_vers; *p++ = rpcrdma_version; @@ -846,7 +846,7 @@ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, default: p = xdr_reserve_space(&sctxt->sc_stream, sizeof(*p)); if (!p) - return -ENOMSG; + goto put_ctxt; *p = err_chunk; trace_svcrdma_err_chunk(*rdma_argp); @@ -855,7 +855,12 @@ static int svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, sctxt->sc_send_wr.num_sge = 1; sctxt->sc_send_wr.opcode = IB_WR_SEND; sctxt->sc_sges[0].length = sctxt->sc_hdrbuf.len; - return svc_rdma_send(rdma, &sctxt->sc_send_wr); + if (svc_rdma_send(rdma, &sctxt->sc_send_wr)) + goto put_ctxt; + return; + +put_ctxt: + svc_rdma_send_ctxt_put(rdma, sctxt); } /** @@ -950,9 +955,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp) * of previously posted RDMA Writes. */ svc_rdma_save_io_pages(rqstp, sctxt); - ret = svc_rdma_send_error_msg(rdma, sctxt, rctxt, ret); - if (ret < 0) - goto err1; + svc_rdma_send_error_msg(rdma, sctxt, rctxt, ret); return 0; err1: From c65b326b1eb983bca35ed43d0e453d1b15705f10 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 25 Mar 2020 14:41:46 -0400 Subject: [PATCH 144/242] svcrdma: Make svc_rdma_send_error_msg() a global function Prepare for svc_rdma_send_error_msg() to be invoked from another source file. Signed-off-by: Chuck Lever --- include/linux/sunrpc/svc_rdma.h | 4 ++++ net/sunrpc/xprtrdma/svc_rdma_sendto.c | 26 ++++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 7ed82625dc0b..1579f7a14ab4 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -195,6 +195,10 @@ extern int svc_rdma_map_reply_msg(struct svcxprt_rdma *rdma, struct svc_rdma_send_ctxt *sctxt, const struct svc_rdma_recv_ctxt *rctxt, struct xdr_buf *xdr); +extern void svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, + struct svc_rdma_send_ctxt *sctxt, + struct svc_rdma_recv_ctxt *rctxt, + int status); extern int svc_rdma_sendto(struct svc_rqst *); extern int svc_rdma_read_payload(struct svc_rqst *rqstp, unsigned int offset, unsigned int length); diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index fb548b548c4b..57041298fe4f 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -804,16 +804,25 @@ static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, return svc_rdma_send(rdma, &sctxt->sc_send_wr); } -/* Given the client-provided Write and Reply chunks, the server was not - * able to form a complete reply. Return an RDMA_ERROR message so the - * client can retire this RPC transaction. +/** + * svc_rdma_send_error_msg - Send an RPC/RDMA v1 error response + * @rdma: controlling transport context + * @sctxt: Send context for the response + * @rctxt: Receive context for incoming bad message + * @status: negative errno indicating error that occurred * - * Remote Invalidation is skipped for simplicity. + * Given the client-provided Read, Write, and Reply chunks, the + * server was not able to parse the Call or form a complete Reply. + * Return an RDMA_ERROR message so the client can retire the RPC + * transaction. + * + * The caller does not have to release @sctxt. It is released by + * Send completion, or by this function on error. */ -static void svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, - struct svc_rdma_send_ctxt *sctxt, - struct svc_rdma_recv_ctxt *rctxt, - int status) +void svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, + struct svc_rdma_send_ctxt *sctxt, + struct svc_rdma_recv_ctxt *rctxt, + int status) { __be32 *rdma_argp = rctxt->rc_recv_buf; __be32 *p; @@ -852,6 +861,7 @@ static void svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, trace_svcrdma_err_chunk(*rdma_argp); } + /* Remote Invalidation is skipped for simplicity. */ sctxt->sc_send_wr.num_sge = 1; sctxt->sc_send_wr.opcode = IB_WR_SEND; sctxt->sc_sges[0].length = sctxt->sc_hdrbuf.len; From ba6cc97738a15751350d3f85a6b856e4d6d4c202 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 24 Mar 2020 17:57:18 -0400 Subject: [PATCH 145/242] svcrdma: Consolidate send_error helper functions Final refactor: Replace internals of svc_rdma_send_error() with a simple call to svc_rdma_send_error_msg(). Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 52 +++---------------------- 1 file changed, 5 insertions(+), 47 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 60d855116ae7..c072ce61b393 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -714,58 +714,16 @@ static void rdma_read_complete(struct svc_rqst *rqstp, rqstp->rq_arg.buflen = head->rc_arg.buflen; } -static void svc_rdma_send_error(struct svcxprt_rdma *xprt, +static void svc_rdma_send_error(struct svcxprt_rdma *rdma, struct svc_rdma_recv_ctxt *rctxt, int status) { - __be32 *p, *rdma_argp = rctxt->rc_recv_buf; - struct svc_rdma_send_ctxt *ctxt; - int ret; + struct svc_rdma_send_ctxt *sctxt; - ctxt = svc_rdma_send_ctxt_get(xprt); - if (!ctxt) + sctxt = svc_rdma_send_ctxt_get(rdma); + if (!sctxt) return; - - p = xdr_reserve_space(&ctxt->sc_stream, - rpcrdma_fixed_maxsz * sizeof(*p)); - if (!p) - goto put_ctxt; - - *p++ = *rdma_argp; - *p++ = *(rdma_argp + 1); - *p++ = xprt->sc_fc_credits; - *p = rdma_error; - - switch (status) { - case -EPROTONOSUPPORT: - p = xdr_reserve_space(&ctxt->sc_stream, 3 * sizeof(*p)); - if (!p) - goto put_ctxt; - - *p++ = err_vers; - *p++ = rpcrdma_version; - *p = rpcrdma_version; - trace_svcrdma_err_vers(*rdma_argp); - break; - default: - p = xdr_reserve_space(&ctxt->sc_stream, sizeof(*p)); - if (!p) - goto put_ctxt; - - *p = err_chunk; - trace_svcrdma_err_chunk(*rdma_argp); - } - - ctxt->sc_send_wr.num_sge = 1; - ctxt->sc_send_wr.opcode = IB_WR_SEND; - ctxt->sc_sges[0].length = ctxt->sc_hdrbuf.len; - ret = svc_rdma_send(xprt, &ctxt->sc_send_wr); - if (ret) - goto put_ctxt; - return; - -put_ctxt: - svc_rdma_send_ctxt_put(xprt, ctxt); + svc_rdma_send_error_msg(rdma, sctxt, rctxt, status); } /* By convention, backchannel calls arrive via rdma_msg type From 3f8f25c696f9c4e352a4d705ba767af676421564 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 30 Apr 2020 14:17:40 -0400 Subject: [PATCH 146/242] svcrdma: Clean up trace_svcrdma_send_failed() tracepoint - Use the _err naming convention instead - Remove display of kernel memory address of the controlling xprt Signed-off-by: Chuck Lever --- include/trace/events/rpcrdma.h | 7 ++----- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index 0f05a6e2b9cb..0eff80dee066 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -1716,7 +1716,7 @@ TRACE_EVENT(svcrdma_send_pullup, TP_printk("len=%u", __entry->len) ); -TRACE_EVENT(svcrdma_send_failed, +TRACE_EVENT(svcrdma_send_err, TP_PROTO( const struct svc_rqst *rqst, int status @@ -1727,19 +1727,16 @@ TRACE_EVENT(svcrdma_send_failed, TP_STRUCT__entry( __field(int, status) __field(u32, xid) - __field(const void *, xprt) __string(addr, rqst->rq_xprt->xpt_remotebuf) ), TP_fast_assign( __entry->status = status; __entry->xid = __be32_to_cpu(rqst->rq_xid); - __entry->xprt = rqst->rq_xprt; __assign_str(addr, rqst->rq_xprt->xpt_remotebuf); ), - TP_printk("xprt=%p addr=%s xid=0x%08x status=%d", - __entry->xprt, __get_str(addr), + TP_printk("addr=%s xid=0x%08x status=%d", __get_str(addr), __entry->xid, __entry->status ) ); diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 57041298fe4f..f985f548346a 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -971,7 +971,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp) err1: svc_rdma_send_ctxt_put(rdma, sctxt); err0: - trace_svcrdma_send_failed(rqstp, ret); + trace_svcrdma_send_err(rqstp, ret); set_bit(XPT_CLOSE, &xprt->xpt_flags); return -ENOTCONN; } From 0b8dc1b69995cbd81c2c9a2f1730c46cce085f62 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 18 May 2020 11:34:47 -0400 Subject: [PATCH 147/242] svcrdma: Remove declarations for functions long removed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pavane pour une infante défunte. Signed-off-by: Chuck Lever --- include/linux/sunrpc/svc_rdma.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 1579f7a14ab4..d28ca1b6f2eb 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -204,10 +204,6 @@ extern int svc_rdma_read_payload(struct svc_rqst *rqstp, unsigned int offset, unsigned int length); /* svc_rdma_transport.c */ -extern int svc_rdma_create_listen(struct svc_serv *, int, struct sockaddr *); -extern void svc_sq_reap(struct svcxprt_rdma *); -extern void svc_rq_reap(struct svcxprt_rdma *); - extern struct svc_xprt_class svc_rdma_class; #ifdef CONFIG_SUNRPC_BACKCHANNEL extern struct svc_xprt_class svc_rdma_bc_class; From 07e9a6325a35fb9655f7b52e2b9dc632da6eef51 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sat, 28 Mar 2020 13:43:22 -0400 Subject: [PATCH 148/242] SUNRPC: Add helpers for decoding list discriminators symbolically Use these helpers in a few spots to demonstrate their use. The remaining open-coded discriminator checks in rpcrdma will be addressed in subsequent patches. Signed-off-by: Chuck Lever --- include/linux/sunrpc/xdr.h | 26 +++++++++++++++++++++++++ net/sunrpc/xprtrdma/rpc_rdma.c | 12 ++++++------ net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 17 ++++++++-------- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 22c207b2425f..5a6a81b7cd9f 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -474,6 +474,32 @@ xdr_stream_encode_uint32_array(struct xdr_stream *xdr, return ret; } +/** + * xdr_item_is_absent - symbolically handle XDR discriminators + * @p: pointer to undecoded discriminator + * + * Return values: + * %true if the following XDR item is absent + * %false if the following XDR item is present + */ +static inline bool xdr_item_is_absent(const __be32 *p) +{ + return *p == xdr_zero; +} + +/** + * xdr_item_is_present - symbolically handle XDR discriminators + * @p: pointer to undecoded discriminator + * + * Return values: + * %true if the following XDR item is present + * %false if the following XDR item is absent + */ +static inline bool xdr_item_is_present(const __be32 *p) +{ + return *p != xdr_zero; +} + /** * xdr_stream_decode_u32 - Decode a 32-bit integer * @xdr: pointer to xdr_stream diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 935bbef2f7be..feecd1f55f18 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -1133,11 +1133,11 @@ rpcrdma_is_bcall(struct rpcrdma_xprt *r_xprt, struct rpcrdma_rep *rep) p = xdr_inline_decode(xdr, 0); /* Chunk lists */ - if (*p++ != xdr_zero) + if (xdr_item_is_present(p++)) return false; - if (*p++ != xdr_zero) + if (xdr_item_is_present(p++)) return false; - if (*p++ != xdr_zero) + if (xdr_item_is_present(p++)) return false; /* RPC header */ @@ -1215,7 +1215,7 @@ static int decode_read_list(struct xdr_stream *xdr) p = xdr_inline_decode(xdr, sizeof(*p)); if (unlikely(!p)) return -EIO; - if (unlikely(*p != xdr_zero)) + if (unlikely(xdr_item_is_present(p))) return -EIO; return 0; } @@ -1234,7 +1234,7 @@ static int decode_write_list(struct xdr_stream *xdr, u32 *length) p = xdr_inline_decode(xdr, sizeof(*p)); if (unlikely(!p)) return -EIO; - if (*p == xdr_zero) + if (xdr_item_is_absent(p)) break; if (!first) return -EIO; @@ -1256,7 +1256,7 @@ static int decode_reply_chunk(struct xdr_stream *xdr, u32 *length) return -EIO; *length = 0; - if (*p != xdr_zero) + if (xdr_item_is_present(p)) if (decode_write_chunk(xdr, length)) return -EIO; return 0; diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index c072ce61b393..5e78067889f3 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -419,7 +419,7 @@ static bool xdr_check_read_list(struct svc_rdma_recv_ctxt *rctxt) len = 0; first = true; - while (*p != xdr_zero) { + while (xdr_item_is_present(p)) { p = xdr_inline_decode(&rctxt->rc_stream, rpcrdma_readseg_maxsz * sizeof(*p)); if (!p) @@ -500,7 +500,7 @@ static bool xdr_check_write_list(struct svc_rdma_recv_ctxt *rctxt) if (!p) return false; rctxt->rc_write_list = p; - while (*p != xdr_zero) { + while (xdr_item_is_present(p)) { if (!xdr_check_write_chunk(rctxt, MAX_BYTES_WRITE_CHUNK)) return false; ++chcount; @@ -532,12 +532,11 @@ static bool xdr_check_reply_chunk(struct svc_rdma_recv_ctxt *rctxt) p = xdr_inline_decode(&rctxt->rc_stream, sizeof(*p)); if (!p) return false; - rctxt->rc_reply_chunk = p; - if (*p != xdr_zero) { + rctxt->rc_reply_chunk = NULL; + if (xdr_item_is_present(p)) { if (!xdr_check_write_chunk(rctxt, MAX_BYTES_SPECIAL_CHUNK)) return false; - } else { - rctxt->rc_reply_chunk = NULL; + rctxt->rc_reply_chunk = p; } return true; } @@ -568,7 +567,7 @@ static void svc_rdma_get_inv_rkey(struct svcxprt_rdma *rdma, p += rpcrdma_fixed_maxsz; /* Read list */ - while (*p++ != xdr_zero) { + while (xdr_item_is_present(p++)) { p++; /* position */ if (inv_rkey == xdr_zero) inv_rkey = *p; @@ -578,7 +577,7 @@ static void svc_rdma_get_inv_rkey(struct svcxprt_rdma *rdma, } /* Write list */ - while (*p++ != xdr_zero) { + while (xdr_item_is_present(p++)) { segcount = be32_to_cpup(p++); for (i = 0; i < segcount; i++) { if (inv_rkey == xdr_zero) @@ -590,7 +589,7 @@ static void svc_rdma_get_inv_rkey(struct svcxprt_rdma *rdma, } /* Reply chunk */ - if (*p++ != xdr_zero) { + if (xdr_item_is_present(p++)) { segcount = be32_to_cpup(p++); for (i = 0; i < segcount; i++) { if (inv_rkey == xdr_zero) From f60a08697d28b138c73b14c3204947bc8e637197 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Sun, 29 Mar 2020 16:44:13 -0400 Subject: [PATCH 149/242] svcrdma: Add common XDR decoders for RDMA and Read segments Clean up: De-duplicate some code. Signed-off-by: Chuck Lever --- include/linux/sunrpc/rpc_rdma.h | 37 ++++++++++++++++++++++++ net/sunrpc/xprtrdma/frwr_ops.c | 1 - net/sunrpc/xprtrdma/rpc_rdma.c | 5 +--- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 4 +-- net/sunrpc/xprtrdma/svc_rdma_rw.c | 37 ++++++++++-------------- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 5 +--- net/sunrpc/xprtrdma/svc_rdma_transport.c | 1 - 7 files changed, 56 insertions(+), 34 deletions(-) diff --git a/include/linux/sunrpc/rpc_rdma.h b/include/linux/sunrpc/rpc_rdma.h index 320c672d84de..db50380f64f4 100644 --- a/include/linux/sunrpc/rpc_rdma.h +++ b/include/linux/sunrpc/rpc_rdma.h @@ -124,4 +124,41 @@ rpcrdma_decode_buffer_size(u8 val) return ((unsigned int)val + 1) << 10; } +/** + * xdr_decode_rdma_segment - Decode contents of an RDMA segment + * @p: Pointer to the undecoded RDMA segment + * @handle: Upon return, the RDMA handle + * @length: Upon return, the RDMA length + * @offset: Upon return, the RDMA offset + * + * Return value: + * Pointer to the XDR item that follows the RDMA segment + */ +static inline __be32 *xdr_decode_rdma_segment(__be32 *p, u32 *handle, + u32 *length, u64 *offset) +{ + *handle = be32_to_cpup(p++); + *length = be32_to_cpup(p++); + return xdr_decode_hyper(p, offset); +} + +/** + * xdr_decode_read_segment - Decode contents of a Read segment + * @p: Pointer to the undecoded Read segment + * @position: Upon return, the segment's position + * @handle: Upon return, the RDMA handle + * @length: Upon return, the RDMA length + * @offset: Upon return, the RDMA offset + * + * Return value: + * Pointer to the XDR item that follows the Read segment + */ +static inline __be32 *xdr_decode_read_segment(__be32 *p, u32 *position, + u32 *handle, u32 *length, + u64 *offset) +{ + *position = be32_to_cpup(p++); + return xdr_decode_rdma_segment(p, handle, length, offset); +} + #endif /* _LINUX_SUNRPC_RPC_RDMA_H */ diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index b647562a26dd..7f94c9a19fd3 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -40,7 +40,6 @@ * New MRs are created on demand. */ -#include #include #include "xprt_rdma.h" diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index feecd1f55f18..5461f01eeca6 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -1176,10 +1176,7 @@ static int decode_rdma_segment(struct xdr_stream *xdr, u32 *length) if (unlikely(!p)) return -EIO; - handle = be32_to_cpup(p++); - *length = be32_to_cpup(p++); - xdr_decode_hyper(p, &offset); - + xdr_decode_rdma_segment(p, &handle, length, &offset); trace_xprtrdma_decode_seg(handle, *length, offset); return 0; } diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 5e78067889f3..c0587d3cd389 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -466,9 +466,7 @@ static bool xdr_check_write_chunk(struct svc_rdma_recv_ctxt *rctxt, u32 maxlen) if (!p) return false; - handle = be32_to_cpup(p++); - length = be32_to_cpup(p++); - xdr_decode_hyper(p, &offset); + xdr_decode_rdma_segment(p, &handle, &length, &offset); trace_svcrdma_decode_wseg(handle, length, offset); total += length; diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index 83806fa94def..2038b1b286dd 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -7,6 +7,7 @@ #include +#include #include #include @@ -441,34 +442,32 @@ svc_rdma_build_writes(struct svc_rdma_write_info *info, seg = info->wi_segs + info->wi_seg_no * rpcrdma_segment_maxsz; do { unsigned int write_len; - u32 seg_length, seg_handle; - u64 seg_offset; + u32 handle, length; + u64 offset; if (info->wi_seg_no >= info->wi_nsegs) goto out_overflow; - seg_handle = be32_to_cpup(seg); - seg_length = be32_to_cpup(seg + 1); - xdr_decode_hyper(seg + 2, &seg_offset); - seg_offset += info->wi_seg_off; + xdr_decode_rdma_segment(seg, &handle, &length, &offset); + offset += info->wi_seg_off; - write_len = min(remaining, seg_length - info->wi_seg_off); + write_len = min(remaining, length - info->wi_seg_off); ctxt = svc_rdma_get_rw_ctxt(rdma, (write_len >> PAGE_SHIFT) + 2); if (!ctxt) return -ENOMEM; constructor(info, write_len, ctxt); - ret = svc_rdma_rw_ctx_init(rdma, ctxt, seg_offset, seg_handle, + ret = svc_rdma_rw_ctx_init(rdma, ctxt, offset, handle, DMA_TO_DEVICE); if (ret < 0) return -EIO; - trace_svcrdma_send_wseg(seg_handle, write_len, seg_offset); + trace_svcrdma_send_wseg(handle, write_len, offset); list_add(&ctxt->rw_list, &cc->cc_rwctxts); cc->cc_sqecount += ret; - if (write_len == seg_length - info->wi_seg_off) { + if (write_len == length - info->wi_seg_off) { seg += 4; info->wi_seg_no++; info->wi_seg_off = 0; @@ -689,21 +688,17 @@ static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, ret = -EINVAL; info->ri_chunklen = 0; while (*p++ != xdr_zero && be32_to_cpup(p++) == info->ri_position) { - u32 rs_handle, rs_length; - u64 rs_offset; + u32 handle, length; + u64 offset; - rs_handle = be32_to_cpup(p++); - rs_length = be32_to_cpup(p++); - p = xdr_decode_hyper(p, &rs_offset); - - ret = svc_rdma_build_read_segment(info, rqstp, - rs_handle, rs_length, - rs_offset); + p = xdr_decode_rdma_segment(p, &handle, &length, &offset); + ret = svc_rdma_build_read_segment(info, rqstp, handle, length, + offset); if (ret < 0) break; - trace_svcrdma_send_rseg(rs_handle, rs_length, rs_offset); - info->ri_chunklen += rs_length; + trace_svcrdma_send_rseg(handle, length, offset); + info->ri_chunklen += length; } return ret; diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index f985f548346a..a78f1d22e9bb 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -106,7 +106,6 @@ #include #include -#include #include #include "xprt_rdma.h" @@ -375,9 +374,7 @@ static ssize_t svc_rdma_encode_write_segment(__be32 *src, if (!p) return -EMSGSIZE; - handle = be32_to_cpup(src++); - length = be32_to_cpup(src++); - xdr_decode_hyper(src, &offset); + xdr_decode_rdma_segment(src, &handle, &length, &offset); *p++ = cpu_to_be32(handle); if (*remaining < length) { diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index d38be57b00ed..3da7901a49e6 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -55,7 +55,6 @@ #include #include -#include #include #include From 379c3bc6b4eb989ee37c4ce8ab403719e06fe35f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 7 Apr 2020 15:32:14 -0400 Subject: [PATCH 150/242] svcrdma: Add common XDR encoders for RDMA and Read segments Clean up: De-duplicate some code. Signed-off-by: Chuck Lever --- include/linux/sunrpc/rpc_rdma.h | 37 +++++++++++++++++++++++++++ net/sunrpc/xprtrdma/rpc_rdma.c | 14 +++------- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 4 +-- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/include/linux/sunrpc/rpc_rdma.h b/include/linux/sunrpc/rpc_rdma.h index db50380f64f4..4af31bbc8802 100644 --- a/include/linux/sunrpc/rpc_rdma.h +++ b/include/linux/sunrpc/rpc_rdma.h @@ -124,6 +124,43 @@ rpcrdma_decode_buffer_size(u8 val) return ((unsigned int)val + 1) << 10; } +/** + * xdr_encode_rdma_segment - Encode contents of an RDMA segment + * @p: Pointer into a send buffer + * @handle: The RDMA handle to encode + * @length: The RDMA length to encode + * @offset: The RDMA offset to encode + * + * Return value: + * Pointer to the XDR position that follows the encoded RDMA segment + */ +static inline __be32 *xdr_encode_rdma_segment(__be32 *p, u32 handle, + u32 length, u64 offset) +{ + *p++ = cpu_to_be32(handle); + *p++ = cpu_to_be32(length); + return xdr_encode_hyper(p, offset); +} + +/** + * xdr_encode_read_segment - Encode contents of a Read segment + * @p: Pointer into a send buffer + * @position: The position to encode + * @handle: The RDMA handle to encode + * @length: The RDMA length to encode + * @offset: The RDMA offset to encode + * + * Return value: + * Pointer to the XDR position that follows the encoded Read segment + */ +static inline __be32 *xdr_encode_read_segment(__be32 *p, u32 position, + u32 handle, u32 length, + u64 offset) +{ + *p++ = cpu_to_be32(position); + return xdr_encode_rdma_segment(p, handle, length, offset); +} + /** * xdr_decode_rdma_segment - Decode contents of an RDMA segment * @p: Pointer to the undecoded RDMA segment diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 5461f01eeca6..73ed51893175 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c @@ -275,14 +275,6 @@ out: return n; } -static void -xdr_encode_rdma_segment(__be32 *iptr, struct rpcrdma_mr *mr) -{ - *iptr++ = cpu_to_be32(mr->mr_handle); - *iptr++ = cpu_to_be32(mr->mr_length); - xdr_encode_hyper(iptr, mr->mr_offset); -} - static int encode_rdma_segment(struct xdr_stream *xdr, struct rpcrdma_mr *mr) { @@ -292,7 +284,7 @@ encode_rdma_segment(struct xdr_stream *xdr, struct rpcrdma_mr *mr) if (unlikely(!p)) return -EMSGSIZE; - xdr_encode_rdma_segment(p, mr); + xdr_encode_rdma_segment(p, mr->mr_handle, mr->mr_length, mr->mr_offset); return 0; } @@ -307,8 +299,8 @@ encode_read_segment(struct xdr_stream *xdr, struct rpcrdma_mr *mr, return -EMSGSIZE; *p++ = xdr_one; /* Item present */ - *p++ = cpu_to_be32(position); - xdr_encode_rdma_segment(p, mr); + xdr_encode_read_segment(p, position, mr->mr_handle, mr->mr_length, + mr->mr_offset); return 0; } diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index a78f1d22e9bb..38d8f0ee35ec 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -376,7 +376,6 @@ static ssize_t svc_rdma_encode_write_segment(__be32 *src, xdr_decode_rdma_segment(src, &handle, &length, &offset); - *p++ = cpu_to_be32(handle); if (*remaining < length) { /* segment only partly filled */ length = *remaining; @@ -385,8 +384,7 @@ static ssize_t svc_rdma_encode_write_segment(__be32 *src, /* entire segment was consumed */ *remaining -= length; } - *p++ = cpu_to_be32(length); - xdr_encode_hyper(p, offset); + xdr_encode_rdma_segment(p, handle, length, offset); trace_svcrdma_encode_wseg(handle, length, offset); return len; From f7bd657b55e3484cadc37a6439de23d2fd703bd6 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 19 May 2020 09:30:32 -0400 Subject: [PATCH 151/242] svcrdma: Introduce infrastructure to support completion IDs The goal is to replace CQE kernel memory addresses in completion- related tracepoints. Each completion ID matches an incoming Send or Receive completion to a Completion Queue and to a previous ib_post_*(). The ID can then be displayed in an error message or recorded in a trace record. Signed-off-by: Chuck Lever --- include/linux/sunrpc/rpc_rdma_cid.h | 24 ++++++++++++++++ include/trace/events/rpcrdma.h | 43 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 include/linux/sunrpc/rpc_rdma_cid.h diff --git a/include/linux/sunrpc/rpc_rdma_cid.h b/include/linux/sunrpc/rpc_rdma_cid.h new file mode 100644 index 000000000000..be24ab2baa6a --- /dev/null +++ b/include/linux/sunrpc/rpc_rdma_cid.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * * Copyright (c) 2020, Oracle and/or its affiliates. + */ + +#ifndef RPC_RDMA_CID_H +#define RPC_RDMA_CID_H + +/* + * The rpc_rdma_cid struct records completion ID information. A + * completion ID matches an incoming Send or Receive completion + * to a Completion Queue and to a previous ib_post_*(). The ID + * can then be displayed in an error message or recorded in a + * trace record. + * + * This struct is shared between the server and client RPC/RDMA + * transport implementations. + */ +struct rpc_rdma_cid { + u32 ci_queue_id; + int ci_completion_id; +}; + +#endif /* RPC_RDMA_CID_H */ diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index 0eff80dee066..70ab989aa3b7 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -11,6 +11,7 @@ #define _TRACE_RPCRDMA_H #include +#include #include #include @@ -18,6 +19,48 @@ ** Event classes **/ +DECLARE_EVENT_CLASS(rpcrdma_completion_class, + TP_PROTO( + const struct ib_wc *wc, + const struct rpc_rdma_cid *cid + ), + + TP_ARGS(wc, cid), + + TP_STRUCT__entry( + __field(u32, cq_id) + __field(int, completion_id) + __field(unsigned long, status) + __field(unsigned int, vendor_err) + ), + + TP_fast_assign( + __entry->cq_id = cid->ci_queue_id; + __entry->completion_id = cid->ci_completion_id; + __entry->status = wc->status; + if (wc->status) + __entry->vendor_err = wc->vendor_err; + else + __entry->vendor_err = 0; + ), + + TP_printk("cq.id=%u cid=%d status=%s (%lu/0x%x)", + __entry->cq_id, __entry->completion_id, + rdma_show_wc_status(__entry->status), + __entry->status, __entry->vendor_err + ) +); + +#define DEFINE_COMPLETION_EVENT(name) \ + DEFINE_EVENT(rpcrdma_completion_class, name, \ + TP_PROTO( \ + const struct ib_wc *wc, \ + const struct rpc_rdma_cid *cid \ + ), \ + TP_ARGS(wc, cid)) + +DEFINE_COMPLETION_EVENT(dummy); + DECLARE_EVENT_CLASS(xprtrdma_reply_event, TP_PROTO( const struct rpcrdma_rep *rep From 9b3bcf8c5c134038e30624db5b57992ae50b80a9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 29 Apr 2020 16:22:26 -0400 Subject: [PATCH 152/242] svcrdma: Introduce Receive completion IDs Set up a completion ID in each svc_rdma_recv_ctxt. The ID is used to match an incoming Receive completion to a transport and to a previous ib_post_recv(). Signed-off-by: Chuck Lever --- include/linux/sunrpc/svc_rdma.h | 4 ++ include/trace/events/rpcrdma.h | 51 ++++++++++--------------- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 15 ++++++-- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index d28ca1b6f2eb..c3c1e46f510f 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -109,6 +110,8 @@ struct svcxprt_rdma { struct work_struct sc_work; struct llist_head sc_recv_ctxts; + + atomic_t sc_completion_ids; }; /* sc_flags */ #define RDMAXPRT_CONN_PENDING 3 @@ -129,6 +132,7 @@ struct svc_rdma_recv_ctxt { struct list_head rc_list; struct ib_recv_wr rc_recv_wr; struct ib_cqe rc_cqe; + struct rpc_rdma_cid rc_cid; struct ib_sge rc_recv_sge; void *rc_recv_buf; struct xdr_buf rc_arg; diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index 70ab989aa3b7..a0330a557e34 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -59,8 +59,6 @@ DECLARE_EVENT_CLASS(rpcrdma_completion_class, ), \ TP_ARGS(wc, cid)) -DEFINE_COMPLETION_EVENT(dummy); - DECLARE_EVENT_CLASS(xprtrdma_reply_event, TP_PROTO( const struct rpcrdma_rep *rep @@ -1849,57 +1847,48 @@ DEFINE_SENDCOMP_EVENT(send); TRACE_EVENT(svcrdma_post_recv, TP_PROTO( - const struct ib_recv_wr *wr, - int status + const struct svc_rdma_recv_ctxt *ctxt ), - TP_ARGS(wr, status), + TP_ARGS(ctxt), TP_STRUCT__entry( - __field(const void *, cqe) - __field(int, status) + __field(u32, cq_id) + __field(int, completion_id) ), TP_fast_assign( - __entry->cqe = wr->wr_cqe; - __entry->status = status; + __entry->cq_id = ctxt->rc_cid.ci_queue_id; + __entry->completion_id = ctxt->rc_cid.ci_completion_id; ), - TP_printk("cqe=%p status=%d", - __entry->cqe, __entry->status + TP_printk("cq.id=%d cid=%d", + __entry->cq_id, __entry->completion_id ) ); -TRACE_EVENT(svcrdma_wc_receive, +DEFINE_COMPLETION_EVENT(svcrdma_wc_receive); + +TRACE_EVENT(svcrdma_rq_post_err, TP_PROTO( - const struct ib_wc *wc + const struct svcxprt_rdma *rdma, + int status ), - TP_ARGS(wc), + TP_ARGS(rdma, status), TP_STRUCT__entry( - __field(const void *, cqe) - __field(u32, byte_len) - __field(unsigned int, status) - __field(u32, vendor_err) + __field(int, status) + __string(addr, rdma->sc_xprt.xpt_remotebuf) ), TP_fast_assign( - __entry->cqe = wc->wr_cqe; - __entry->status = wc->status; - if (wc->status) { - __entry->byte_len = 0; - __entry->vendor_err = wc->vendor_err; - } else { - __entry->byte_len = wc->byte_len; - __entry->vendor_err = 0; - } + __entry->status = status; + __assign_str(addr, rdma->sc_xprt.xpt_remotebuf); ), - TP_printk("cqe=%p byte_len=%u status=%s (%u/0x%x)", - __entry->cqe, __entry->byte_len, - rdma_show_wc_status(__entry->status), - __entry->status, __entry->vendor_err + TP_printk("addr=%s status=%d", + __get_str(addr), __entry->status ) ); diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index c0587d3cd389..e6d7401232d2 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -117,6 +117,13 @@ svc_rdma_next_recv_ctxt(struct list_head *list) rc_list); } +static void svc_rdma_recv_cid_init(struct svcxprt_rdma *rdma, + struct rpc_rdma_cid *cid) +{ + cid->ci_queue_id = rdma->sc_rq_cq->res.id; + cid->ci_completion_id = atomic_inc_return(&rdma->sc_completion_ids); +} + static struct svc_rdma_recv_ctxt * svc_rdma_recv_ctxt_alloc(struct svcxprt_rdma *rdma) { @@ -135,6 +142,8 @@ svc_rdma_recv_ctxt_alloc(struct svcxprt_rdma *rdma) if (ib_dma_mapping_error(rdma->sc_pd->device, addr)) goto fail2; + svc_rdma_recv_cid_init(rdma, &ctxt->rc_cid); + ctxt->rc_recv_wr.next = NULL; ctxt->rc_recv_wr.wr_cqe = &ctxt->rc_cqe; ctxt->rc_recv_wr.sg_list = &ctxt->rc_recv_sge; @@ -249,13 +258,14 @@ static int __svc_rdma_post_recv(struct svcxprt_rdma *rdma, int ret; svc_xprt_get(&rdma->sc_xprt); + trace_svcrdma_post_recv(ctxt); ret = ib_post_recv(rdma->sc_qp, &ctxt->rc_recv_wr, NULL); - trace_svcrdma_post_recv(&ctxt->rc_recv_wr, ret); if (ret) goto err_post; return 0; err_post: + trace_svcrdma_rq_post_err(rdma, ret); svc_rdma_recv_ctxt_put(rdma, ctxt); svc_xprt_put(&rdma->sc_xprt); return ret; @@ -309,11 +319,10 @@ static void svc_rdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc) struct ib_cqe *cqe = wc->wr_cqe; struct svc_rdma_recv_ctxt *ctxt; - trace_svcrdma_wc_receive(wc); - /* WARNING: Only wc->wr_cqe and wc->status are reliable */ ctxt = container_of(cqe, struct svc_rdma_recv_ctxt, rc_cqe); + trace_svcrdma_wc_receive(wc, &ctxt->rc_cid); if (wc->status != IB_WC_SUCCESS) goto flushed; From 007140ee9b4fc4e59538677799c916890a2f13e2 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 29 Apr 2020 17:16:31 -0400 Subject: [PATCH 153/242] svcrdma: Record Receive completion ID in svc_rdma_decode_rqst When recording a trace event in the Receive path, tie decoding results and errors to an incoming Receive completion. Signed-off-by: Chuck Lever --- include/trace/events/rpcrdma.h | 34 ++++++++++++++++++++----- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 12 ++++----- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index a0330a557e34..df49ae5d447b 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -1369,13 +1369,16 @@ TRACE_DEFINE_ENUM(RDMA_ERROR); TRACE_EVENT(svcrdma_decode_rqst, TP_PROTO( + const struct svc_rdma_recv_ctxt *ctxt, __be32 *p, unsigned int hdrlen ), - TP_ARGS(p, hdrlen), + TP_ARGS(ctxt, p, hdrlen), TP_STRUCT__entry( + __field(u32, cq_id) + __field(int, completion_id) __field(u32, xid) __field(u32, vers) __field(u32, proc) @@ -1384,6 +1387,8 @@ TRACE_EVENT(svcrdma_decode_rqst, ), TP_fast_assign( + __entry->cq_id = ctxt->rc_cid.ci_queue_id; + __entry->completion_id = ctxt->rc_cid.ci_completion_id; __entry->xid = be32_to_cpup(p++); __entry->vers = be32_to_cpup(p++); __entry->credits = be32_to_cpup(p++); @@ -1391,37 +1396,48 @@ TRACE_EVENT(svcrdma_decode_rqst, __entry->hdrlen = hdrlen; ), - TP_printk("xid=0x%08x vers=%u credits=%u proc=%s hdrlen=%u", + TP_printk("cq.id=%u cid=%d xid=0x%08x vers=%u credits=%u proc=%s hdrlen=%u", + __entry->cq_id, __entry->completion_id, __entry->xid, __entry->vers, __entry->credits, show_rpcrdma_proc(__entry->proc), __entry->hdrlen) ); TRACE_EVENT(svcrdma_decode_short_err, TP_PROTO( + const struct svc_rdma_recv_ctxt *ctxt, unsigned int hdrlen ), - TP_ARGS(hdrlen), + TP_ARGS(ctxt, hdrlen), TP_STRUCT__entry( + __field(u32, cq_id) + __field(int, completion_id) __field(unsigned int, hdrlen) ), TP_fast_assign( + __entry->cq_id = ctxt->rc_cid.ci_queue_id; + __entry->completion_id = ctxt->rc_cid.ci_completion_id; __entry->hdrlen = hdrlen; ), - TP_printk("hdrlen=%u", __entry->hdrlen) + TP_printk("cq.id=%u cid=%d hdrlen=%u", + __entry->cq_id, __entry->completion_id, + __entry->hdrlen) ); DECLARE_EVENT_CLASS(svcrdma_badreq_event, TP_PROTO( + const struct svc_rdma_recv_ctxt *ctxt, __be32 *p ), - TP_ARGS(p), + TP_ARGS(ctxt, p), TP_STRUCT__entry( + __field(u32, cq_id) + __field(int, completion_id) __field(u32, xid) __field(u32, vers) __field(u32, proc) @@ -1429,13 +1445,16 @@ DECLARE_EVENT_CLASS(svcrdma_badreq_event, ), TP_fast_assign( + __entry->cq_id = ctxt->rc_cid.ci_queue_id; + __entry->completion_id = ctxt->rc_cid.ci_completion_id; __entry->xid = be32_to_cpup(p++); __entry->vers = be32_to_cpup(p++); __entry->credits = be32_to_cpup(p++); __entry->proc = be32_to_cpup(p); ), - TP_printk("xid=0x%08x vers=%u credits=%u proc=%u", + TP_printk("cq.id=%u cid=%d xid=0x%08x vers=%u credits=%u proc=%u", + __entry->cq_id, __entry->completion_id, __entry->xid, __entry->vers, __entry->credits, __entry->proc) ); @@ -1443,9 +1462,10 @@ DECLARE_EVENT_CLASS(svcrdma_badreq_event, DEFINE_EVENT(svcrdma_badreq_event, \ svcrdma_decode_##name##_err, \ TP_PROTO( \ + const struct svc_rdma_recv_ctxt *ctxt, \ __be32 *p \ ), \ - TP_ARGS(p)) + TP_ARGS(ctxt, p)) DEFINE_BADREQ_EVENT(badvers); DEFINE_BADREQ_EVENT(drop); diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index e6d7401232d2..d5ec85cb652c 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -667,27 +667,27 @@ static int svc_rdma_xdr_decode_req(struct xdr_buf *rq_arg, hdr_len = xdr_stream_pos(&rctxt->rc_stream); rq_arg->head[0].iov_len -= hdr_len; rq_arg->len -= hdr_len; - trace_svcrdma_decode_rqst(rdma_argp, hdr_len); + trace_svcrdma_decode_rqst(rctxt, rdma_argp, hdr_len); return hdr_len; out_short: - trace_svcrdma_decode_short_err(rq_arg->len); + trace_svcrdma_decode_short_err(rctxt, rq_arg->len); return -EINVAL; out_version: - trace_svcrdma_decode_badvers_err(rdma_argp); + trace_svcrdma_decode_badvers_err(rctxt, rdma_argp); return -EPROTONOSUPPORT; out_drop: - trace_svcrdma_decode_drop_err(rdma_argp); + trace_svcrdma_decode_drop_err(rctxt, rdma_argp); return 0; out_proc: - trace_svcrdma_decode_badproc_err(rdma_argp); + trace_svcrdma_decode_badproc_err(rctxt, rdma_argp); return -EINVAL; out_inval: - trace_svcrdma_decode_parse_err(rdma_argp); + trace_svcrdma_decode_parse_err(rctxt, rdma_argp); return -EINVAL; } From 3ac56c2fb166fea25974d8c48bb4a72ee298361b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 30 Apr 2020 13:47:07 -0400 Subject: [PATCH 154/242] svcrdma: Introduce Send completion IDs Set up a completion ID in each svc_rdma_send_ctxt. The ID is used to match an incoming Send completion to a transport and to a previous ib_post_send(). Signed-off-by: Chuck Lever --- include/linux/sunrpc/svc_rdma.h | 2 ++ include/trace/events/rpcrdma.h | 2 +- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 15 ++++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index c3c1e46f510f..c91e00bc937e 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -151,6 +151,8 @@ struct svc_rdma_recv_ctxt { struct svc_rdma_send_ctxt { struct list_head sc_list; + struct rpc_rdma_cid sc_cid; + struct ib_send_wr sc_send_wr; struct ib_cqe sc_cqe; struct xdr_buf sc_hdrbuf; diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index df49ae5d447b..782a4d826a4b 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -1863,7 +1863,7 @@ TRACE_EVENT(svcrdma_post_send, ) ); -DEFINE_SENDCOMP_EVENT(send); +DEFINE_COMPLETION_EVENT(svcrdma_wc_send); TRACE_EVENT(svcrdma_post_recv, TP_PROTO( diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 38d8f0ee35ec..c720dcf56231 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -122,6 +122,13 @@ svc_rdma_next_send_ctxt(struct list_head *list) sc_list); } +static void svc_rdma_send_cid_init(struct svcxprt_rdma *rdma, + struct rpc_rdma_cid *cid) +{ + cid->ci_queue_id = rdma->sc_sq_cq->res.id; + cid->ci_completion_id = atomic_inc_return(&rdma->sc_completion_ids); +} + static struct svc_rdma_send_ctxt * svc_rdma_send_ctxt_alloc(struct svcxprt_rdma *rdma) { @@ -144,6 +151,8 @@ svc_rdma_send_ctxt_alloc(struct svcxprt_rdma *rdma) if (ib_dma_mapping_error(rdma->sc_pd->device, addr)) goto fail2; + svc_rdma_send_cid_init(rdma, &ctxt->sc_cid); + ctxt->sc_send_wr.next = NULL; ctxt->sc_send_wr.wr_cqe = &ctxt->sc_cqe; ctxt->sc_send_wr.sg_list = ctxt->sc_sges; @@ -268,14 +277,14 @@ static void svc_rdma_wc_send(struct ib_cq *cq, struct ib_wc *wc) { struct svcxprt_rdma *rdma = cq->cq_context; struct ib_cqe *cqe = wc->wr_cqe; - struct svc_rdma_send_ctxt *ctxt; + struct svc_rdma_send_ctxt *ctxt = + container_of(cqe, struct svc_rdma_send_ctxt, sc_cqe); - trace_svcrdma_wc_send(wc); + trace_svcrdma_wc_send(wc, &ctxt->sc_cid); atomic_inc(&rdma->sc_sq_avail); wake_up(&rdma->sc_send_wait); - ctxt = container_of(cqe, struct svc_rdma_send_ctxt, sc_cqe); svc_rdma_send_ctxt_put(rdma, ctxt); if (unlikely(wc->status != IB_WC_SUCCESS)) { From 17f70f8dd52be3723250d21093403bb3a9f2162f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 29 Apr 2020 11:05:33 -0400 Subject: [PATCH 155/242] svcrdma: Record send_ctxt completion ID in trace_svcrdma_post_send() First, refactor: Dereference the svc_rdma_send_ctxt inside svc_rdma_send() instead of at every call site. Then, it can be passed into trace_svcrdma_post_send() to get the proper completion ID. Signed-off-by: Chuck Lever --- include/linux/sunrpc/svc_rdma.h | 3 ++- include/trace/events/rpcrdma.h | 18 +++++++++++------- net/sunrpc/xprtrdma/svc_rdma_backchannel.c | 2 +- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 11 ++++++----- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index c91e00bc937e..9dc3a3b88391 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -196,7 +196,8 @@ extern struct svc_rdma_send_ctxt * svc_rdma_send_ctxt_get(struct svcxprt_rdma *rdma); extern void svc_rdma_send_ctxt_put(struct svcxprt_rdma *rdma, struct svc_rdma_send_ctxt *ctxt); -extern int svc_rdma_send(struct svcxprt_rdma *rdma, struct ib_send_wr *wr); +extern int svc_rdma_send(struct svcxprt_rdma *rdma, + struct svc_rdma_send_ctxt *ctxt); extern int svc_rdma_map_reply_msg(struct svcxprt_rdma *rdma, struct svc_rdma_send_ctxt *sctxt, const struct svc_rdma_recv_ctxt *rctxt, diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index 782a4d826a4b..aeeba9188ed5 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -1839,27 +1839,31 @@ DECLARE_EVENT_CLASS(svcrdma_sendcomp_event, TRACE_EVENT(svcrdma_post_send, TP_PROTO( - const struct ib_send_wr *wr + const struct svc_rdma_send_ctxt *ctxt ), - TP_ARGS(wr), + TP_ARGS(ctxt), TP_STRUCT__entry( - __field(const void *, cqe) + __field(u32, cq_id) + __field(int, completion_id) __field(unsigned int, num_sge) __field(u32, inv_rkey) ), TP_fast_assign( - __entry->cqe = wr->wr_cqe; + const struct ib_send_wr *wr = &ctxt->sc_send_wr; + + __entry->cq_id = ctxt->sc_cid.ci_queue_id; + __entry->completion_id = ctxt->sc_cid.ci_completion_id; __entry->num_sge = wr->num_sge; __entry->inv_rkey = (wr->opcode == IB_WR_SEND_WITH_INV) ? wr->ex.invalidate_rkey : 0; ), - TP_printk("cqe=%p num_sge=%u inv_rkey=0x%08x", - __entry->cqe, __entry->num_sge, - __entry->inv_rkey + TP_printk("cq_id=%u cid=%d num_sge=%u inv_rkey=0x%08x", + __entry->cq_id, __entry->completion_id, + __entry->num_sge, __entry->inv_rkey ) ); diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c index 1ee73f7cf931..5e7c4ba9e147 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c +++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c @@ -87,7 +87,7 @@ static int svc_rdma_bc_sendto(struct svcxprt_rdma *rdma, */ get_page(virt_to_page(rqst->rq_buffer)); ctxt->sc_send_wr.opcode = IB_WR_SEND; - return svc_rdma_send(rdma, &ctxt->sc_send_wr); + return svc_rdma_send(rdma, ctxt); } /* Server-side transport endpoint wants a whole page for its send diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index c720dcf56231..73d46e8cdc16 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -298,13 +298,14 @@ static void svc_rdma_wc_send(struct ib_cq *cq, struct ib_wc *wc) /** * svc_rdma_send - Post a single Send WR * @rdma: transport on which to post the WR - * @wr: prepared Send WR to post + * @ctxt: send ctxt with a Send WR ready to post * * Returns zero the Send WR was posted successfully. Otherwise, a * negative errno is returned. */ -int svc_rdma_send(struct svcxprt_rdma *rdma, struct ib_send_wr *wr) +int svc_rdma_send(struct svcxprt_rdma *rdma, struct svc_rdma_send_ctxt *ctxt) { + struct ib_send_wr *wr = &ctxt->sc_send_wr; int ret; might_sleep(); @@ -330,7 +331,7 @@ int svc_rdma_send(struct svcxprt_rdma *rdma, struct ib_send_wr *wr) } svc_xprt_get(&rdma->sc_xprt); - trace_svcrdma_post_send(wr); + trace_svcrdma_post_send(ctxt); ret = ib_post_send(rdma->sc_qp, wr, NULL); if (ret) break; @@ -805,7 +806,7 @@ static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, } else { sctxt->sc_send_wr.opcode = IB_WR_SEND; } - return svc_rdma_send(rdma, &sctxt->sc_send_wr); + return svc_rdma_send(rdma, sctxt); } /** @@ -869,7 +870,7 @@ void svc_rdma_send_error_msg(struct svcxprt_rdma *rdma, sctxt->sc_send_wr.num_sge = 1; sctxt->sc_send_wr.opcode = IB_WR_SEND; sctxt->sc_sges[0].length = sctxt->sc_hdrbuf.len; - if (svc_rdma_send(rdma, &sctxt->sc_send_wr)) + if (svc_rdma_send(rdma, sctxt)) goto put_ctxt; return; From 6787f0bea27a24e4c306616565b02234ee558cfb Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 29 Apr 2020 17:25:36 -0400 Subject: [PATCH 156/242] svcrdma: Display chunk completion ID when posting a rw_ctxt Re-use the post_rw tracepoint (safely) to trace cc_info lifetime events, including completion IDs. Signed-off-by: Chuck Lever --- include/trace/events/rpcrdma.h | 56 +++++++------------------------ net/sunrpc/xprtrdma/svc_rdma_rw.c | 14 ++++++-- 2 files changed, 24 insertions(+), 46 deletions(-) diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index aeeba9188ed5..abe942225637 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -1802,41 +1802,6 @@ TRACE_EVENT(svcrdma_send_err, ) ); -DECLARE_EVENT_CLASS(svcrdma_sendcomp_event, - TP_PROTO( - const struct ib_wc *wc - ), - - TP_ARGS(wc), - - TP_STRUCT__entry( - __field(const void *, cqe) - __field(unsigned int, status) - __field(unsigned int, vendor_err) - ), - - TP_fast_assign( - __entry->cqe = wc->wr_cqe; - __entry->status = wc->status; - if (wc->status) - __entry->vendor_err = wc->vendor_err; - else - __entry->vendor_err = 0; - ), - - TP_printk("cqe=%p status=%s (%u/0x%x)", - __entry->cqe, rdma_show_wc_status(__entry->status), - __entry->status, __entry->vendor_err - ) -); - -#define DEFINE_SENDCOMP_EVENT(name) \ - DEFINE_EVENT(svcrdma_sendcomp_event, svcrdma_wc_##name, \ - TP_PROTO( \ - const struct ib_wc *wc \ - ), \ - TP_ARGS(wc)) - TRACE_EVENT(svcrdma_post_send, TP_PROTO( const struct svc_rdma_send_ctxt *ctxt @@ -1916,31 +1881,34 @@ TRACE_EVENT(svcrdma_rq_post_err, ) ); -TRACE_EVENT(svcrdma_post_rw, +TRACE_EVENT(svcrdma_post_chunk, TP_PROTO( - const void *cqe, + const struct rpc_rdma_cid *cid, int sqecount ), - TP_ARGS(cqe, sqecount), + TP_ARGS(cid, sqecount), TP_STRUCT__entry( - __field(const void *, cqe) + __field(u32, cq_id) + __field(int, completion_id) __field(int, sqecount) ), TP_fast_assign( - __entry->cqe = cqe; + __entry->cq_id = cid->ci_queue_id; + __entry->completion_id = cid->ci_completion_id; __entry->sqecount = sqecount; ), - TP_printk("cqe=%p sqecount=%d", - __entry->cqe, __entry->sqecount + TP_printk("cq.id=%u cid=%d sqecount=%d", + __entry->cq_id, __entry->completion_id, + __entry->sqecount ) ); -DEFINE_SENDCOMP_EVENT(read); -DEFINE_SENDCOMP_EVENT(write); +DEFINE_COMPLETION_EVENT(svcrdma_wc_read); +DEFINE_COMPLETION_EVENT(svcrdma_wc_write); TRACE_EVENT(svcrdma_qp_error, TP_PROTO( diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index 2038b1b286dd..c16d10601d65 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -145,15 +145,24 @@ static int svc_rdma_rw_ctx_init(struct svcxprt_rdma *rdma, * demand, and not cached. */ struct svc_rdma_chunk_ctxt { + struct rpc_rdma_cid cc_cid; struct ib_cqe cc_cqe; struct svcxprt_rdma *cc_rdma; struct list_head cc_rwctxts; int cc_sqecount; }; +static void svc_rdma_cc_cid_init(struct svcxprt_rdma *rdma, + struct rpc_rdma_cid *cid) +{ + cid->ci_queue_id = rdma->sc_sq_cq->res.id; + cid->ci_completion_id = atomic_inc_return(&rdma->sc_completion_ids); +} + static void svc_rdma_cc_init(struct svcxprt_rdma *rdma, struct svc_rdma_chunk_ctxt *cc) { + svc_rdma_cc_cid_init(rdma, &cc->cc_cid); cc->cc_rdma = rdma; svc_xprt_get(&rdma->sc_xprt); @@ -237,7 +246,7 @@ static void svc_rdma_write_done(struct ib_cq *cq, struct ib_wc *wc) struct svc_rdma_write_info *info = container_of(cc, struct svc_rdma_write_info, wi_cc); - trace_svcrdma_wc_write(wc); + trace_svcrdma_wc_write(wc, &cc->cc_cid); atomic_add(cc->cc_sqecount, &rdma->sc_sq_avail); wake_up(&rdma->sc_send_wait); @@ -295,7 +304,7 @@ static void svc_rdma_wc_read_done(struct ib_cq *cq, struct ib_wc *wc) struct svc_rdma_read_info *info = container_of(cc, struct svc_rdma_read_info, ri_cc); - trace_svcrdma_wc_read(wc); + trace_svcrdma_wc_read(wc, &cc->cc_cid); atomic_add(cc->cc_sqecount, &rdma->sc_sq_avail); wake_up(&rdma->sc_send_wait); @@ -351,6 +360,7 @@ static int svc_rdma_post_chunk_ctxt(struct svc_rdma_chunk_ctxt *cc) do { if (atomic_sub_return(cc->cc_sqecount, &rdma->sc_sq_avail) > 0) { + trace_svcrdma_post_chunk(&cc->cc_cid, cc->cc_sqecount); ret = ib_post_send(rdma->sc_qp, first_wr, &bad_wr); if (ret) break; From 0b7cd9d9ca66e5181f3a120cb5b44433efd0ad55 Mon Sep 17 00:00:00 2001 From: Xu Wang Date: Thu, 18 Jun 2020 01:56:13 +0000 Subject: [PATCH 157/242] nfsd: Use seq_putc() in two functions A single character (line break) should be put into a sequence. Thus use the corresponding function "seq_putc()". Signed-off-by: Xu Wang Signed-off-by: Chuck Lever --- fs/nfsd/nfs4idmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index 9460be8a8321..f92161ce1f97 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -168,7 +168,7 @@ idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) ent->id); if (test_bit(CACHE_VALID, &h->flags)) seq_printf(m, " %s", ent->name); - seq_printf(m, "\n"); + seq_putc(m, '\n'); return 0; } @@ -346,7 +346,7 @@ nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) ent->name); if (test_bit(CACHE_VALID, &h->flags)) seq_printf(m, " %u", ent->id); - seq_printf(m, "\n"); + seq_putc(m, '\n'); return 0; } From 94415b06eb8aed13481646026dc995f04a3a534a Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 7 Jul 2020 09:28:05 -0400 Subject: [PATCH 158/242] nfsd4: a client's own opens needn't prevent delegations We recently fixed lease breaking so that a client's actions won't break its own delegations. But we still have an unnecessary self-conflict when granting delegations: a client's own write opens will prevent us from handing out a read delegation even when no other client has the file open for write. Fix that by turning off the checks for conflicting opens under vfs_setlease, and instead performing those checks in the nfsd code. We don't depend much on locks here: instead we acquire the delegation, then check for conflicts, and drop the delegation again if we find any. The check beforehand is an optimization of sorts, just to avoid acquiring the delegation unnecessarily. There's a race where the first check could cause us to deny the delegation when we could have granted it. But, that's OK, delegation grants are optional (and probably not even a good idea in that case). Signed-off-by: J. Bruce Fields Signed-off-by: Chuck Lever --- fs/locks.c | 3 +++ fs/nfsd/nfs4state.c | 54 +++++++++++++++++++++++++++++++++------------ 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 7df0f9fa66f4..d5de9039dbd7 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1807,6 +1807,9 @@ check_conflicting_open(struct file *filp, const long arg, int flags) if (flags & FL_LAYOUT) return 0; + if (flags & FL_DELEG) + /* We leave these checks to the caller. */ + return 0; if (arg == F_RDLCK) return inode_is_open_for_write(inode) ? -EAGAIN : 0; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index cce2510b2cca..fdba971d06c3 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4922,6 +4922,32 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, return fl; } +static int nfsd4_check_conflicting_opens(struct nfs4_client *clp, + struct nfs4_file *fp) +{ + struct nfs4_clnt_odstate *co; + struct file *f = fp->fi_deleg_file->nf_file; + struct inode *ino = locks_inode(f); + int writes = atomic_read(&ino->i_writecount); + + if (fp->fi_fds[O_WRONLY]) + writes--; + if (fp->fi_fds[O_RDWR]) + writes--; + WARN_ON_ONCE(writes < 0); + if (writes > 0) + return -EAGAIN; + spin_lock(&fp->fi_lock); + list_for_each_entry(co, &fp->fi_clnt_odstate, co_perfile) { + if (co->co_client != clp) { + spin_unlock(&fp->fi_lock); + return -EAGAIN; + } + } + spin_unlock(&fp->fi_lock); + return 0; +} + static struct nfs4_delegation * nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, struct nfs4_file *fp, struct nfs4_clnt_odstate *odstate) @@ -4941,9 +4967,12 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, nf = find_readable_file(fp); if (!nf) { - /* We should always have a readable file here */ - WARN_ON_ONCE(1); - return ERR_PTR(-EBADF); + /* + * We probably could attempt another open and get a read + * delegation, but for now, don't bother until the + * client actually sends us one. + */ + return ERR_PTR(-EAGAIN); } spin_lock(&state_lock); spin_lock(&fp->fi_lock); @@ -4973,11 +5002,19 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, if (!fl) goto out_clnt_odstate; + status = nfsd4_check_conflicting_opens(clp, fp); + if (status) { + locks_free_lock(fl); + goto out_clnt_odstate; + } status = vfs_setlease(fp->fi_deleg_file->nf_file, fl->fl_type, &fl, NULL); if (fl) locks_free_lock(fl); if (status) goto out_clnt_odstate; + status = nfsd4_check_conflicting_opens(clp, fp); + if (status) + goto out_clnt_odstate; spin_lock(&state_lock); spin_lock(&fp->fi_lock); @@ -5059,17 +5096,6 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, goto out_no_deleg; if (!cb_up || !(oo->oo_flags & NFS4_OO_CONFIRMED)) goto out_no_deleg; - /* - * Also, if the file was opened for write or - * create, there's a good chance the client's - * about to write to it, resulting in an - * immediate recall (since we don't support - * write delegations): - */ - if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) - goto out_no_deleg; - if (open->op_create == NFS4_OPEN_CREATE) - goto out_no_deleg; break; default: goto out_no_deleg; From df60446cd1fb487becd1f36f4c0da9e0e523c0cf Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Fri, 10 Jul 2020 16:33:07 -0400 Subject: [PATCH 159/242] nfsd: avoid a NULL dereference in __cld_pipe_upcall() If the rpc_pipefs is unmounted, then the rpc_pipe->dentry becomes NULL and dereferencing the dentry->d_sb will trigger an oops. The only reason we're doing that is to determine the nfsd_net, which could instead be passed in by the caller. So do that instead. Fixes: 11a60d159259 ("nfsd: add a "GetVersion" upcall for nfsdcld") Signed-off-by: Scott Mayhew Signed-off-by: Chuck Lever --- fs/nfsd/nfs4recover.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 9e40dfecf1b1..186fa2c2c6ba 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -747,13 +747,11 @@ struct cld_upcall { }; static int -__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg) +__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn) { int ret; struct rpc_pipe_msg msg; struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u); - struct nfsd_net *nn = net_generic(pipe->dentry->d_sb->s_fs_info, - nfsd_net_id); memset(&msg, 0, sizeof(msg)); msg.data = cmsg; @@ -773,7 +771,7 @@ out: } static int -cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg) +cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn) { int ret; @@ -782,7 +780,7 @@ cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg) * upcalls queued. */ do { - ret = __cld_pipe_upcall(pipe, cmsg); + ret = __cld_pipe_upcall(pipe, cmsg, nn); } while (ret == -EAGAIN); return ret; @@ -1115,7 +1113,7 @@ nfsd4_cld_create(struct nfs4_client *clp) memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, clp->cl_name.len); - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); if (!ret) { ret = cup->cu_u.cu_msg.cm_status; set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); @@ -1180,7 +1178,7 @@ nfsd4_cld_create_v2(struct nfs4_client *clp) } else cmsg->cm_u.cm_clntinfo.cc_princhash.cp_len = 0; - ret = cld_pipe_upcall(cn->cn_pipe, cmsg); + ret = cld_pipe_upcall(cn->cn_pipe, cmsg, nn); if (!ret) { ret = cmsg->cm_status; set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); @@ -1218,7 +1216,7 @@ nfsd4_cld_remove(struct nfs4_client *clp) memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, clp->cl_name.len); - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); if (!ret) { ret = cup->cu_u.cu_msg.cm_status; clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); @@ -1261,7 +1259,7 @@ nfsd4_cld_check_v0(struct nfs4_client *clp) memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, clp->cl_name.len); - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); if (!ret) { ret = cup->cu_u.cu_msg.cm_status; set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); @@ -1404,7 +1402,7 @@ nfsd4_cld_grace_start(struct nfsd_net *nn) } cup->cu_u.cu_msg.cm_cmd = Cld_GraceStart; - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); if (!ret) ret = cup->cu_u.cu_msg.cm_status; @@ -1432,7 +1430,7 @@ nfsd4_cld_grace_done_v0(struct nfsd_net *nn) cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone; cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time; - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); if (!ret) ret = cup->cu_u.cu_msg.cm_status; @@ -1460,7 +1458,7 @@ nfsd4_cld_grace_done(struct nfsd_net *nn) } cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone; - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); if (!ret) ret = cup->cu_u.cu_msg.cm_status; @@ -1524,7 +1522,7 @@ nfsd4_cld_get_version(struct nfsd_net *nn) goto out_err; } cup->cu_u.cu_msg.cm_cmd = Cld_GetVersion; - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); if (!ret) { ret = cup->cu_u.cu_msg.cm_status; if (ret) From d33cfc2e591a90f540cd696240ff953b8aaba17d Mon Sep 17 00:00:00 2001 From: Marian-Cristian Rotariu Date: Tue, 7 Jul 2020 17:18:11 +0100 Subject: [PATCH 160/242] dt-bindings: pinctrl: sh-pfc: Document r8a774e1 PFC support Document PFC support for the RZ/G2H (R8A774E1) SoC. Signed-off-by: Marian-Cristian Rotariu Signed-off-by: Lad Prabhakar Link: https://lore.kernel.org/r/1594138692-16816-12-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt index b68613188c19..6a494c65291c 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -21,6 +21,7 @@ Required Properties: - "renesas,pfc-r8a774a1": for R8A774A1 (RZ/G2M) compatible pin-controller. - "renesas,pfc-r8a774b1": for R8A774B1 (RZ/G2N) compatible pin-controller. - "renesas,pfc-r8a774c0": for R8A774C0 (RZ/G2E) compatible pin-controller. + - "renesas,pfc-r8a774e1": for R8A774E1 (RZ/G2H) compatible pin-controller. - "renesas,pfc-r8a7778": for R8A7778 (R-Car M1) compatible pin-controller. - "renesas,pfc-r8a7779": for R8A7779 (R-Car H1) compatible pin-controller. - "renesas,pfc-r8a7790": for R8A7790 (R-Car H2) compatible pin-controller. From a5e8b53adeb4b458971dfd6232b71299010e981a Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 7 Jul 2020 17:18:12 +0100 Subject: [PATCH 161/242] pinctrl: sh-pfc: pfc-r8a77951: Add R8A774E1 PFC support Renesas RZ/G2H (r8a774e1) is pin compatible with R-Car H3 (R8A77951), however it doesn't have several automotive specific peripherals. Add automotive-specific pin groups/functions along with common pin groups/functions for supporting both r8a77951 and r8a774e1 SoC. Signed-off-by: Lad Prabhakar Link: https://lore.kernel.org/r/1594138692-16816-13-git-send-email-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/sh-pfc/Kconfig | 4 + drivers/pinctrl/sh-pfc/Makefile | 1 + drivers/pinctrl/sh-pfc/core.c | 6 + drivers/pinctrl/sh-pfc/pfc-r8a77951.c | 881 ++++++++++++++------------ drivers/pinctrl/sh-pfc/sh_pfc.h | 1 + 5 files changed, 476 insertions(+), 417 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig index c461a2f1927a..7fdc7ed8bd2e 100644 --- a/drivers/pinctrl/sh-pfc/Kconfig +++ b/drivers/pinctrl/sh-pfc/Kconfig @@ -20,6 +20,7 @@ config PINCTRL_SH_PFC select PINCTRL_PFC_R8A774A1 if ARCH_R8A774A1 select PINCTRL_PFC_R8A774B1 if ARCH_R8A774B1 select PINCTRL_PFC_R8A774C0 if ARCH_R8A774C0 + select PINCTRL_PFC_R8A774E1 if ARCH_R8A774E1 select PINCTRL_PFC_R8A7778 if ARCH_R8A7778 select PINCTRL_PFC_R8A7779 if ARCH_R8A7779 select PINCTRL_PFC_R8A7790 if ARCH_R8A7790 @@ -99,6 +100,9 @@ config PINCTRL_PFC_R8A774B1 config PINCTRL_PFC_R8A774C0 bool "RZ/G2E pin control support" if COMPILE_TEST +config PINCTRL_PFC_R8A774E1 + bool "RZ/G2H pin control support" if COMPILE_TEST + config PINCTRL_PFC_R8A7778 bool "R-Car M1A pin control support" if COMPILE_TEST diff --git a/drivers/pinctrl/sh-pfc/Makefile b/drivers/pinctrl/sh-pfc/Makefile index 3855d82069c9..7bb99187cd8e 100644 --- a/drivers/pinctrl/sh-pfc/Makefile +++ b/drivers/pinctrl/sh-pfc/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A77470) += pfc-r8a77470.o obj-$(CONFIG_PINCTRL_PFC_R8A774A1) += pfc-r8a7796.o obj-$(CONFIG_PINCTRL_PFC_R8A774B1) += pfc-r8a77965.o obj-$(CONFIG_PINCTRL_PFC_R8A774C0) += pfc-r8a77990.o +obj-$(CONFIG_PINCTRL_PFC_R8A774E1) += pfc-r8a77951.o obj-$(CONFIG_PINCTRL_PFC_R8A7778) += pfc-r8a7778.o obj-$(CONFIG_PINCTRL_PFC_R8A7779) += pfc-r8a7779.o obj-$(CONFIG_PINCTRL_PFC_R8A7790) += pfc-r8a7790.o diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index f368383cba61..c528c124fb0e 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -533,6 +533,12 @@ static const struct of_device_id sh_pfc_of_table[] = { .data = &r8a774c0_pinmux_info, }, #endif +#ifdef CONFIG_PINCTRL_PFC_R8A774E1 + { + .compatible = "renesas,pfc-r8a774e1", + .data = &r8a774e1_pinmux_info, + }, +#endif #ifdef CONFIG_PINCTRL_PFC_R8A7778 { .compatible = "renesas,pfc-r8a7778", diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77951.c b/drivers/pinctrl/sh-pfc/pfc-r8a77951.c index 256fab4b03d3..a94ebe0bf5d0 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a77951.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a77951.c @@ -4157,357 +4157,365 @@ static const unsigned int vin5_clk_mux[] = { VI5_CLK_MARK, }; -static const struct sh_pfc_pin_group pinmux_groups[] = { - SH_PFC_PIN_GROUP(audio_clk_a_a), - SH_PFC_PIN_GROUP(audio_clk_a_b), - SH_PFC_PIN_GROUP(audio_clk_a_c), - SH_PFC_PIN_GROUP(audio_clk_b_a), - SH_PFC_PIN_GROUP(audio_clk_b_b), - SH_PFC_PIN_GROUP(audio_clk_c_a), - SH_PFC_PIN_GROUP(audio_clk_c_b), - SH_PFC_PIN_GROUP(audio_clkout_a), - SH_PFC_PIN_GROUP(audio_clkout_b), - SH_PFC_PIN_GROUP(audio_clkout_c), - SH_PFC_PIN_GROUP(audio_clkout_d), - SH_PFC_PIN_GROUP(audio_clkout1_a), - SH_PFC_PIN_GROUP(audio_clkout1_b), - SH_PFC_PIN_GROUP(audio_clkout2_a), - SH_PFC_PIN_GROUP(audio_clkout2_b), - SH_PFC_PIN_GROUP(audio_clkout3_a), - SH_PFC_PIN_GROUP(audio_clkout3_b), - SH_PFC_PIN_GROUP(avb_link), - SH_PFC_PIN_GROUP(avb_magic), - SH_PFC_PIN_GROUP(avb_phy_int), - SH_PFC_PIN_GROUP_ALIAS(avb_mdc, avb_mdio), /* Deprecated */ - SH_PFC_PIN_GROUP(avb_mdio), - SH_PFC_PIN_GROUP(avb_mii), - SH_PFC_PIN_GROUP(avb_avtp_pps), - SH_PFC_PIN_GROUP(avb_avtp_match_a), - SH_PFC_PIN_GROUP(avb_avtp_capture_a), - SH_PFC_PIN_GROUP(avb_avtp_match_b), - SH_PFC_PIN_GROUP(avb_avtp_capture_b), - SH_PFC_PIN_GROUP(can0_data_a), - SH_PFC_PIN_GROUP(can0_data_b), - SH_PFC_PIN_GROUP(can1_data), - SH_PFC_PIN_GROUP(can_clk), - SH_PFC_PIN_GROUP(canfd0_data_a), - SH_PFC_PIN_GROUP(canfd0_data_b), - SH_PFC_PIN_GROUP(canfd1_data), - SH_PFC_PIN_GROUP(drif0_ctrl_a), - SH_PFC_PIN_GROUP(drif0_data0_a), - SH_PFC_PIN_GROUP(drif0_data1_a), - SH_PFC_PIN_GROUP(drif0_ctrl_b), - SH_PFC_PIN_GROUP(drif0_data0_b), - SH_PFC_PIN_GROUP(drif0_data1_b), - SH_PFC_PIN_GROUP(drif0_ctrl_c), - SH_PFC_PIN_GROUP(drif0_data0_c), - SH_PFC_PIN_GROUP(drif0_data1_c), - SH_PFC_PIN_GROUP(drif1_ctrl_a), - SH_PFC_PIN_GROUP(drif1_data0_a), - SH_PFC_PIN_GROUP(drif1_data1_a), - SH_PFC_PIN_GROUP(drif1_ctrl_b), - SH_PFC_PIN_GROUP(drif1_data0_b), - SH_PFC_PIN_GROUP(drif1_data1_b), - SH_PFC_PIN_GROUP(drif1_ctrl_c), - SH_PFC_PIN_GROUP(drif1_data0_c), - SH_PFC_PIN_GROUP(drif1_data1_c), - SH_PFC_PIN_GROUP(drif2_ctrl_a), - SH_PFC_PIN_GROUP(drif2_data0_a), - SH_PFC_PIN_GROUP(drif2_data1_a), - SH_PFC_PIN_GROUP(drif2_ctrl_b), - SH_PFC_PIN_GROUP(drif2_data0_b), - SH_PFC_PIN_GROUP(drif2_data1_b), - SH_PFC_PIN_GROUP(drif3_ctrl_a), - SH_PFC_PIN_GROUP(drif3_data0_a), - SH_PFC_PIN_GROUP(drif3_data1_a), - SH_PFC_PIN_GROUP(drif3_ctrl_b), - SH_PFC_PIN_GROUP(drif3_data0_b), - SH_PFC_PIN_GROUP(drif3_data1_b), - SH_PFC_PIN_GROUP(du_rgb666), - SH_PFC_PIN_GROUP(du_rgb888), - SH_PFC_PIN_GROUP(du_clk_out_0), - SH_PFC_PIN_GROUP(du_clk_out_1), - SH_PFC_PIN_GROUP(du_sync), - SH_PFC_PIN_GROUP(du_oddf), - SH_PFC_PIN_GROUP(du_cde), - SH_PFC_PIN_GROUP(du_disp), - SH_PFC_PIN_GROUP(hscif0_data), - SH_PFC_PIN_GROUP(hscif0_clk), - SH_PFC_PIN_GROUP(hscif0_ctrl), - SH_PFC_PIN_GROUP(hscif1_data_a), - SH_PFC_PIN_GROUP(hscif1_clk_a), - SH_PFC_PIN_GROUP(hscif1_ctrl_a), - SH_PFC_PIN_GROUP(hscif1_data_b), - SH_PFC_PIN_GROUP(hscif1_clk_b), - SH_PFC_PIN_GROUP(hscif1_ctrl_b), - SH_PFC_PIN_GROUP(hscif2_data_a), - SH_PFC_PIN_GROUP(hscif2_clk_a), - SH_PFC_PIN_GROUP(hscif2_ctrl_a), - SH_PFC_PIN_GROUP(hscif2_data_b), - SH_PFC_PIN_GROUP(hscif2_clk_b), - SH_PFC_PIN_GROUP(hscif2_ctrl_b), - SH_PFC_PIN_GROUP(hscif2_data_c), - SH_PFC_PIN_GROUP(hscif2_clk_c), - SH_PFC_PIN_GROUP(hscif2_ctrl_c), - SH_PFC_PIN_GROUP(hscif3_data_a), - SH_PFC_PIN_GROUP(hscif3_clk), - SH_PFC_PIN_GROUP(hscif3_ctrl), - SH_PFC_PIN_GROUP(hscif3_data_b), - SH_PFC_PIN_GROUP(hscif3_data_c), - SH_PFC_PIN_GROUP(hscif3_data_d), - SH_PFC_PIN_GROUP(hscif4_data_a), - SH_PFC_PIN_GROUP(hscif4_clk), - SH_PFC_PIN_GROUP(hscif4_ctrl), - SH_PFC_PIN_GROUP(hscif4_data_b), - SH_PFC_PIN_GROUP(i2c0), - SH_PFC_PIN_GROUP(i2c1_a), - SH_PFC_PIN_GROUP(i2c1_b), - SH_PFC_PIN_GROUP(i2c2_a), - SH_PFC_PIN_GROUP(i2c2_b), - SH_PFC_PIN_GROUP(i2c3), - SH_PFC_PIN_GROUP(i2c5), - SH_PFC_PIN_GROUP(i2c6_a), - SH_PFC_PIN_GROUP(i2c6_b), - SH_PFC_PIN_GROUP(i2c6_c), - SH_PFC_PIN_GROUP(intc_ex_irq0), - SH_PFC_PIN_GROUP(intc_ex_irq1), - SH_PFC_PIN_GROUP(intc_ex_irq2), - SH_PFC_PIN_GROUP(intc_ex_irq3), - SH_PFC_PIN_GROUP(intc_ex_irq4), - SH_PFC_PIN_GROUP(intc_ex_irq5), - SH_PFC_PIN_GROUP(msiof0_clk), - SH_PFC_PIN_GROUP(msiof0_sync), - SH_PFC_PIN_GROUP(msiof0_ss1), - SH_PFC_PIN_GROUP(msiof0_ss2), - SH_PFC_PIN_GROUP(msiof0_txd), - SH_PFC_PIN_GROUP(msiof0_rxd), - SH_PFC_PIN_GROUP(msiof1_clk_a), - SH_PFC_PIN_GROUP(msiof1_sync_a), - SH_PFC_PIN_GROUP(msiof1_ss1_a), - SH_PFC_PIN_GROUP(msiof1_ss2_a), - SH_PFC_PIN_GROUP(msiof1_txd_a), - SH_PFC_PIN_GROUP(msiof1_rxd_a), - SH_PFC_PIN_GROUP(msiof1_clk_b), - SH_PFC_PIN_GROUP(msiof1_sync_b), - SH_PFC_PIN_GROUP(msiof1_ss1_b), - SH_PFC_PIN_GROUP(msiof1_ss2_b), - SH_PFC_PIN_GROUP(msiof1_txd_b), - SH_PFC_PIN_GROUP(msiof1_rxd_b), - SH_PFC_PIN_GROUP(msiof1_clk_c), - SH_PFC_PIN_GROUP(msiof1_sync_c), - SH_PFC_PIN_GROUP(msiof1_ss1_c), - SH_PFC_PIN_GROUP(msiof1_ss2_c), - SH_PFC_PIN_GROUP(msiof1_txd_c), - SH_PFC_PIN_GROUP(msiof1_rxd_c), - SH_PFC_PIN_GROUP(msiof1_clk_d), - SH_PFC_PIN_GROUP(msiof1_sync_d), - SH_PFC_PIN_GROUP(msiof1_ss1_d), - SH_PFC_PIN_GROUP(msiof1_ss2_d), - SH_PFC_PIN_GROUP(msiof1_txd_d), - SH_PFC_PIN_GROUP(msiof1_rxd_d), - SH_PFC_PIN_GROUP(msiof1_clk_e), - SH_PFC_PIN_GROUP(msiof1_sync_e), - SH_PFC_PIN_GROUP(msiof1_ss1_e), - SH_PFC_PIN_GROUP(msiof1_ss2_e), - SH_PFC_PIN_GROUP(msiof1_txd_e), - SH_PFC_PIN_GROUP(msiof1_rxd_e), - SH_PFC_PIN_GROUP(msiof1_clk_f), - SH_PFC_PIN_GROUP(msiof1_sync_f), - SH_PFC_PIN_GROUP(msiof1_ss1_f), - SH_PFC_PIN_GROUP(msiof1_ss2_f), - SH_PFC_PIN_GROUP(msiof1_txd_f), - SH_PFC_PIN_GROUP(msiof1_rxd_f), - SH_PFC_PIN_GROUP(msiof1_clk_g), - SH_PFC_PIN_GROUP(msiof1_sync_g), - SH_PFC_PIN_GROUP(msiof1_ss1_g), - SH_PFC_PIN_GROUP(msiof1_ss2_g), - SH_PFC_PIN_GROUP(msiof1_txd_g), - SH_PFC_PIN_GROUP(msiof1_rxd_g), - SH_PFC_PIN_GROUP(msiof2_clk_a), - SH_PFC_PIN_GROUP(msiof2_sync_a), - SH_PFC_PIN_GROUP(msiof2_ss1_a), - SH_PFC_PIN_GROUP(msiof2_ss2_a), - SH_PFC_PIN_GROUP(msiof2_txd_a), - SH_PFC_PIN_GROUP(msiof2_rxd_a), - SH_PFC_PIN_GROUP(msiof2_clk_b), - SH_PFC_PIN_GROUP(msiof2_sync_b), - SH_PFC_PIN_GROUP(msiof2_ss1_b), - SH_PFC_PIN_GROUP(msiof2_ss2_b), - SH_PFC_PIN_GROUP(msiof2_txd_b), - SH_PFC_PIN_GROUP(msiof2_rxd_b), - SH_PFC_PIN_GROUP(msiof2_clk_c), - SH_PFC_PIN_GROUP(msiof2_sync_c), - SH_PFC_PIN_GROUP(msiof2_ss1_c), - SH_PFC_PIN_GROUP(msiof2_ss2_c), - SH_PFC_PIN_GROUP(msiof2_txd_c), - SH_PFC_PIN_GROUP(msiof2_rxd_c), - SH_PFC_PIN_GROUP(msiof2_clk_d), - SH_PFC_PIN_GROUP(msiof2_sync_d), - SH_PFC_PIN_GROUP(msiof2_ss1_d), - SH_PFC_PIN_GROUP(msiof2_ss2_d), - SH_PFC_PIN_GROUP(msiof2_txd_d), - SH_PFC_PIN_GROUP(msiof2_rxd_d), - SH_PFC_PIN_GROUP(msiof3_clk_a), - SH_PFC_PIN_GROUP(msiof3_sync_a), - SH_PFC_PIN_GROUP(msiof3_ss1_a), - SH_PFC_PIN_GROUP(msiof3_ss2_a), - SH_PFC_PIN_GROUP(msiof3_txd_a), - SH_PFC_PIN_GROUP(msiof3_rxd_a), - SH_PFC_PIN_GROUP(msiof3_clk_b), - SH_PFC_PIN_GROUP(msiof3_sync_b), - SH_PFC_PIN_GROUP(msiof3_ss1_b), - SH_PFC_PIN_GROUP(msiof3_ss2_b), - SH_PFC_PIN_GROUP(msiof3_txd_b), - SH_PFC_PIN_GROUP(msiof3_rxd_b), - SH_PFC_PIN_GROUP(msiof3_clk_c), - SH_PFC_PIN_GROUP(msiof3_sync_c), - SH_PFC_PIN_GROUP(msiof3_txd_c), - SH_PFC_PIN_GROUP(msiof3_rxd_c), - SH_PFC_PIN_GROUP(msiof3_clk_d), - SH_PFC_PIN_GROUP(msiof3_sync_d), - SH_PFC_PIN_GROUP(msiof3_ss1_d), - SH_PFC_PIN_GROUP(msiof3_txd_d), - SH_PFC_PIN_GROUP(msiof3_rxd_d), - SH_PFC_PIN_GROUP(msiof3_clk_e), - SH_PFC_PIN_GROUP(msiof3_sync_e), - SH_PFC_PIN_GROUP(msiof3_ss1_e), - SH_PFC_PIN_GROUP(msiof3_ss2_e), - SH_PFC_PIN_GROUP(msiof3_txd_e), - SH_PFC_PIN_GROUP(msiof3_rxd_e), - SH_PFC_PIN_GROUP(pwm0), - SH_PFC_PIN_GROUP(pwm1_a), - SH_PFC_PIN_GROUP(pwm1_b), - SH_PFC_PIN_GROUP(pwm2_a), - SH_PFC_PIN_GROUP(pwm2_b), - SH_PFC_PIN_GROUP(pwm3_a), - SH_PFC_PIN_GROUP(pwm3_b), - SH_PFC_PIN_GROUP(pwm4_a), - SH_PFC_PIN_GROUP(pwm4_b), - SH_PFC_PIN_GROUP(pwm5_a), - SH_PFC_PIN_GROUP(pwm5_b), - SH_PFC_PIN_GROUP(pwm6_a), - SH_PFC_PIN_GROUP(pwm6_b), - SH_PFC_PIN_GROUP(sata0_devslp_a), - SH_PFC_PIN_GROUP(sata0_devslp_b), - SH_PFC_PIN_GROUP(scif0_data), - SH_PFC_PIN_GROUP(scif0_clk), - SH_PFC_PIN_GROUP(scif0_ctrl), - SH_PFC_PIN_GROUP(scif1_data_a), - SH_PFC_PIN_GROUP(scif1_clk), - SH_PFC_PIN_GROUP(scif1_ctrl), - SH_PFC_PIN_GROUP(scif1_data_b), - SH_PFC_PIN_GROUP(scif2_data_a), - SH_PFC_PIN_GROUP(scif2_clk), - SH_PFC_PIN_GROUP(scif2_data_b), - SH_PFC_PIN_GROUP(scif3_data_a), - SH_PFC_PIN_GROUP(scif3_clk), - SH_PFC_PIN_GROUP(scif3_ctrl), - SH_PFC_PIN_GROUP(scif3_data_b), - SH_PFC_PIN_GROUP(scif4_data_a), - SH_PFC_PIN_GROUP(scif4_clk_a), - SH_PFC_PIN_GROUP(scif4_ctrl_a), - SH_PFC_PIN_GROUP(scif4_data_b), - SH_PFC_PIN_GROUP(scif4_clk_b), - SH_PFC_PIN_GROUP(scif4_ctrl_b), - SH_PFC_PIN_GROUP(scif4_data_c), - SH_PFC_PIN_GROUP(scif4_clk_c), - SH_PFC_PIN_GROUP(scif4_ctrl_c), - SH_PFC_PIN_GROUP(scif5_data_a), - SH_PFC_PIN_GROUP(scif5_clk_a), - SH_PFC_PIN_GROUP(scif5_data_b), - SH_PFC_PIN_GROUP(scif5_clk_b), - SH_PFC_PIN_GROUP(scif_clk_a), - SH_PFC_PIN_GROUP(scif_clk_b), - SH_PFC_PIN_GROUP(sdhi0_data1), - SH_PFC_PIN_GROUP(sdhi0_data4), - SH_PFC_PIN_GROUP(sdhi0_ctrl), - SH_PFC_PIN_GROUP(sdhi0_cd), - SH_PFC_PIN_GROUP(sdhi0_wp), - SH_PFC_PIN_GROUP(sdhi1_data1), - SH_PFC_PIN_GROUP(sdhi1_data4), - SH_PFC_PIN_GROUP(sdhi1_ctrl), - SH_PFC_PIN_GROUP(sdhi1_cd), - SH_PFC_PIN_GROUP(sdhi1_wp), - SH_PFC_PIN_GROUP(sdhi2_data1), - SH_PFC_PIN_GROUP(sdhi2_data4), - SH_PFC_PIN_GROUP(sdhi2_data8), - SH_PFC_PIN_GROUP(sdhi2_ctrl), - SH_PFC_PIN_GROUP(sdhi2_cd_a), - SH_PFC_PIN_GROUP(sdhi2_wp_a), - SH_PFC_PIN_GROUP(sdhi2_cd_b), - SH_PFC_PIN_GROUP(sdhi2_wp_b), - SH_PFC_PIN_GROUP(sdhi2_ds), - SH_PFC_PIN_GROUP(sdhi3_data1), - SH_PFC_PIN_GROUP(sdhi3_data4), - SH_PFC_PIN_GROUP(sdhi3_data8), - SH_PFC_PIN_GROUP(sdhi3_ctrl), - SH_PFC_PIN_GROUP(sdhi3_cd), - SH_PFC_PIN_GROUP(sdhi3_wp), - SH_PFC_PIN_GROUP(sdhi3_ds), - SH_PFC_PIN_GROUP(ssi0_data), - SH_PFC_PIN_GROUP(ssi01239_ctrl), - SH_PFC_PIN_GROUP(ssi1_data_a), - SH_PFC_PIN_GROUP(ssi1_data_b), - SH_PFC_PIN_GROUP(ssi1_ctrl_a), - SH_PFC_PIN_GROUP(ssi1_ctrl_b), - SH_PFC_PIN_GROUP(ssi2_data_a), - SH_PFC_PIN_GROUP(ssi2_data_b), - SH_PFC_PIN_GROUP(ssi2_ctrl_a), - SH_PFC_PIN_GROUP(ssi2_ctrl_b), - SH_PFC_PIN_GROUP(ssi3_data), - SH_PFC_PIN_GROUP(ssi349_ctrl), - SH_PFC_PIN_GROUP(ssi4_data), - SH_PFC_PIN_GROUP(ssi4_ctrl), - SH_PFC_PIN_GROUP(ssi5_data), - SH_PFC_PIN_GROUP(ssi5_ctrl), - SH_PFC_PIN_GROUP(ssi6_data), - SH_PFC_PIN_GROUP(ssi6_ctrl), - SH_PFC_PIN_GROUP(ssi7_data), - SH_PFC_PIN_GROUP(ssi78_ctrl), - SH_PFC_PIN_GROUP(ssi8_data), - SH_PFC_PIN_GROUP(ssi9_data_a), - SH_PFC_PIN_GROUP(ssi9_data_b), - SH_PFC_PIN_GROUP(ssi9_ctrl_a), - SH_PFC_PIN_GROUP(ssi9_ctrl_b), - SH_PFC_PIN_GROUP(tmu_tclk1_a), - SH_PFC_PIN_GROUP(tmu_tclk1_b), - SH_PFC_PIN_GROUP(tmu_tclk2_a), - SH_PFC_PIN_GROUP(tmu_tclk2_b), - SH_PFC_PIN_GROUP(tpu_to0), - SH_PFC_PIN_GROUP(tpu_to1), - SH_PFC_PIN_GROUP(tpu_to2), - SH_PFC_PIN_GROUP(tpu_to3), - SH_PFC_PIN_GROUP(usb0), - SH_PFC_PIN_GROUP(usb1), - SH_PFC_PIN_GROUP(usb2), - SH_PFC_PIN_GROUP(usb2_ch3), - SH_PFC_PIN_GROUP(usb30), - VIN_DATA_PIN_GROUP(vin4_data, 8, _a), - VIN_DATA_PIN_GROUP(vin4_data, 10, _a), - VIN_DATA_PIN_GROUP(vin4_data, 12, _a), - VIN_DATA_PIN_GROUP(vin4_data, 16, _a), - SH_PFC_PIN_GROUP(vin4_data18_a), - VIN_DATA_PIN_GROUP(vin4_data, 20, _a), - VIN_DATA_PIN_GROUP(vin4_data, 24, _a), - VIN_DATA_PIN_GROUP(vin4_data, 8, _b), - VIN_DATA_PIN_GROUP(vin4_data, 10, _b), - VIN_DATA_PIN_GROUP(vin4_data, 12, _b), - VIN_DATA_PIN_GROUP(vin4_data, 16, _b), - SH_PFC_PIN_GROUP(vin4_data18_b), - VIN_DATA_PIN_GROUP(vin4_data, 20, _b), - VIN_DATA_PIN_GROUP(vin4_data, 24, _b), - SH_PFC_PIN_GROUP(vin4_sync), - SH_PFC_PIN_GROUP(vin4_field), - SH_PFC_PIN_GROUP(vin4_clkenb), - SH_PFC_PIN_GROUP(vin4_clk), - VIN_DATA_PIN_GROUP(vin5_data, 8), - VIN_DATA_PIN_GROUP(vin5_data, 10), - VIN_DATA_PIN_GROUP(vin5_data, 12), - VIN_DATA_PIN_GROUP(vin5_data, 16), - SH_PFC_PIN_GROUP(vin5_sync), - SH_PFC_PIN_GROUP(vin5_field), - SH_PFC_PIN_GROUP(vin5_clkenb), - SH_PFC_PIN_GROUP(vin5_clk), +static const struct { + struct sh_pfc_pin_group common[320]; + struct sh_pfc_pin_group automotive[30]; +} pinmux_groups = { + .common = { + SH_PFC_PIN_GROUP(audio_clk_a_a), + SH_PFC_PIN_GROUP(audio_clk_a_b), + SH_PFC_PIN_GROUP(audio_clk_a_c), + SH_PFC_PIN_GROUP(audio_clk_b_a), + SH_PFC_PIN_GROUP(audio_clk_b_b), + SH_PFC_PIN_GROUP(audio_clk_c_a), + SH_PFC_PIN_GROUP(audio_clk_c_b), + SH_PFC_PIN_GROUP(audio_clkout_a), + SH_PFC_PIN_GROUP(audio_clkout_b), + SH_PFC_PIN_GROUP(audio_clkout_c), + SH_PFC_PIN_GROUP(audio_clkout_d), + SH_PFC_PIN_GROUP(audio_clkout1_a), + SH_PFC_PIN_GROUP(audio_clkout1_b), + SH_PFC_PIN_GROUP(audio_clkout2_a), + SH_PFC_PIN_GROUP(audio_clkout2_b), + SH_PFC_PIN_GROUP(audio_clkout3_a), + SH_PFC_PIN_GROUP(audio_clkout3_b), + SH_PFC_PIN_GROUP(avb_link), + SH_PFC_PIN_GROUP(avb_magic), + SH_PFC_PIN_GROUP(avb_phy_int), + SH_PFC_PIN_GROUP_ALIAS(avb_mdc, avb_mdio), /* Deprecated */ + SH_PFC_PIN_GROUP(avb_mdio), + SH_PFC_PIN_GROUP(avb_mii), + SH_PFC_PIN_GROUP(avb_avtp_pps), + SH_PFC_PIN_GROUP(avb_avtp_match_a), + SH_PFC_PIN_GROUP(avb_avtp_capture_a), + SH_PFC_PIN_GROUP(avb_avtp_match_b), + SH_PFC_PIN_GROUP(avb_avtp_capture_b), + SH_PFC_PIN_GROUP(can0_data_a), + SH_PFC_PIN_GROUP(can0_data_b), + SH_PFC_PIN_GROUP(can1_data), + SH_PFC_PIN_GROUP(can_clk), + SH_PFC_PIN_GROUP(canfd0_data_a), + SH_PFC_PIN_GROUP(canfd0_data_b), + SH_PFC_PIN_GROUP(canfd1_data), + SH_PFC_PIN_GROUP(du_rgb666), + SH_PFC_PIN_GROUP(du_rgb888), + SH_PFC_PIN_GROUP(du_clk_out_0), + SH_PFC_PIN_GROUP(du_clk_out_1), + SH_PFC_PIN_GROUP(du_sync), + SH_PFC_PIN_GROUP(du_oddf), + SH_PFC_PIN_GROUP(du_cde), + SH_PFC_PIN_GROUP(du_disp), + SH_PFC_PIN_GROUP(hscif0_data), + SH_PFC_PIN_GROUP(hscif0_clk), + SH_PFC_PIN_GROUP(hscif0_ctrl), + SH_PFC_PIN_GROUP(hscif1_data_a), + SH_PFC_PIN_GROUP(hscif1_clk_a), + SH_PFC_PIN_GROUP(hscif1_ctrl_a), + SH_PFC_PIN_GROUP(hscif1_data_b), + SH_PFC_PIN_GROUP(hscif1_clk_b), + SH_PFC_PIN_GROUP(hscif1_ctrl_b), + SH_PFC_PIN_GROUP(hscif2_data_a), + SH_PFC_PIN_GROUP(hscif2_clk_a), + SH_PFC_PIN_GROUP(hscif2_ctrl_a), + SH_PFC_PIN_GROUP(hscif2_data_b), + SH_PFC_PIN_GROUP(hscif2_clk_b), + SH_PFC_PIN_GROUP(hscif2_ctrl_b), + SH_PFC_PIN_GROUP(hscif2_data_c), + SH_PFC_PIN_GROUP(hscif2_clk_c), + SH_PFC_PIN_GROUP(hscif2_ctrl_c), + SH_PFC_PIN_GROUP(hscif3_data_a), + SH_PFC_PIN_GROUP(hscif3_clk), + SH_PFC_PIN_GROUP(hscif3_ctrl), + SH_PFC_PIN_GROUP(hscif3_data_b), + SH_PFC_PIN_GROUP(hscif3_data_c), + SH_PFC_PIN_GROUP(hscif3_data_d), + SH_PFC_PIN_GROUP(hscif4_data_a), + SH_PFC_PIN_GROUP(hscif4_clk), + SH_PFC_PIN_GROUP(hscif4_ctrl), + SH_PFC_PIN_GROUP(hscif4_data_b), + SH_PFC_PIN_GROUP(i2c0), + SH_PFC_PIN_GROUP(i2c1_a), + SH_PFC_PIN_GROUP(i2c1_b), + SH_PFC_PIN_GROUP(i2c2_a), + SH_PFC_PIN_GROUP(i2c2_b), + SH_PFC_PIN_GROUP(i2c3), + SH_PFC_PIN_GROUP(i2c5), + SH_PFC_PIN_GROUP(i2c6_a), + SH_PFC_PIN_GROUP(i2c6_b), + SH_PFC_PIN_GROUP(i2c6_c), + SH_PFC_PIN_GROUP(intc_ex_irq0), + SH_PFC_PIN_GROUP(intc_ex_irq1), + SH_PFC_PIN_GROUP(intc_ex_irq2), + SH_PFC_PIN_GROUP(intc_ex_irq3), + SH_PFC_PIN_GROUP(intc_ex_irq4), + SH_PFC_PIN_GROUP(intc_ex_irq5), + SH_PFC_PIN_GROUP(msiof0_clk), + SH_PFC_PIN_GROUP(msiof0_sync), + SH_PFC_PIN_GROUP(msiof0_ss1), + SH_PFC_PIN_GROUP(msiof0_ss2), + SH_PFC_PIN_GROUP(msiof0_txd), + SH_PFC_PIN_GROUP(msiof0_rxd), + SH_PFC_PIN_GROUP(msiof1_clk_a), + SH_PFC_PIN_GROUP(msiof1_sync_a), + SH_PFC_PIN_GROUP(msiof1_ss1_a), + SH_PFC_PIN_GROUP(msiof1_ss2_a), + SH_PFC_PIN_GROUP(msiof1_txd_a), + SH_PFC_PIN_GROUP(msiof1_rxd_a), + SH_PFC_PIN_GROUP(msiof1_clk_b), + SH_PFC_PIN_GROUP(msiof1_sync_b), + SH_PFC_PIN_GROUP(msiof1_ss1_b), + SH_PFC_PIN_GROUP(msiof1_ss2_b), + SH_PFC_PIN_GROUP(msiof1_txd_b), + SH_PFC_PIN_GROUP(msiof1_rxd_b), + SH_PFC_PIN_GROUP(msiof1_clk_c), + SH_PFC_PIN_GROUP(msiof1_sync_c), + SH_PFC_PIN_GROUP(msiof1_ss1_c), + SH_PFC_PIN_GROUP(msiof1_ss2_c), + SH_PFC_PIN_GROUP(msiof1_txd_c), + SH_PFC_PIN_GROUP(msiof1_rxd_c), + SH_PFC_PIN_GROUP(msiof1_clk_d), + SH_PFC_PIN_GROUP(msiof1_sync_d), + SH_PFC_PIN_GROUP(msiof1_ss1_d), + SH_PFC_PIN_GROUP(msiof1_ss2_d), + SH_PFC_PIN_GROUP(msiof1_txd_d), + SH_PFC_PIN_GROUP(msiof1_rxd_d), + SH_PFC_PIN_GROUP(msiof1_clk_e), + SH_PFC_PIN_GROUP(msiof1_sync_e), + SH_PFC_PIN_GROUP(msiof1_ss1_e), + SH_PFC_PIN_GROUP(msiof1_ss2_e), + SH_PFC_PIN_GROUP(msiof1_txd_e), + SH_PFC_PIN_GROUP(msiof1_rxd_e), + SH_PFC_PIN_GROUP(msiof1_clk_f), + SH_PFC_PIN_GROUP(msiof1_sync_f), + SH_PFC_PIN_GROUP(msiof1_ss1_f), + SH_PFC_PIN_GROUP(msiof1_ss2_f), + SH_PFC_PIN_GROUP(msiof1_txd_f), + SH_PFC_PIN_GROUP(msiof1_rxd_f), + SH_PFC_PIN_GROUP(msiof1_clk_g), + SH_PFC_PIN_GROUP(msiof1_sync_g), + SH_PFC_PIN_GROUP(msiof1_ss1_g), + SH_PFC_PIN_GROUP(msiof1_ss2_g), + SH_PFC_PIN_GROUP(msiof1_txd_g), + SH_PFC_PIN_GROUP(msiof1_rxd_g), + SH_PFC_PIN_GROUP(msiof2_clk_a), + SH_PFC_PIN_GROUP(msiof2_sync_a), + SH_PFC_PIN_GROUP(msiof2_ss1_a), + SH_PFC_PIN_GROUP(msiof2_ss2_a), + SH_PFC_PIN_GROUP(msiof2_txd_a), + SH_PFC_PIN_GROUP(msiof2_rxd_a), + SH_PFC_PIN_GROUP(msiof2_clk_b), + SH_PFC_PIN_GROUP(msiof2_sync_b), + SH_PFC_PIN_GROUP(msiof2_ss1_b), + SH_PFC_PIN_GROUP(msiof2_ss2_b), + SH_PFC_PIN_GROUP(msiof2_txd_b), + SH_PFC_PIN_GROUP(msiof2_rxd_b), + SH_PFC_PIN_GROUP(msiof2_clk_c), + SH_PFC_PIN_GROUP(msiof2_sync_c), + SH_PFC_PIN_GROUP(msiof2_ss1_c), + SH_PFC_PIN_GROUP(msiof2_ss2_c), + SH_PFC_PIN_GROUP(msiof2_txd_c), + SH_PFC_PIN_GROUP(msiof2_rxd_c), + SH_PFC_PIN_GROUP(msiof2_clk_d), + SH_PFC_PIN_GROUP(msiof2_sync_d), + SH_PFC_PIN_GROUP(msiof2_ss1_d), + SH_PFC_PIN_GROUP(msiof2_ss2_d), + SH_PFC_PIN_GROUP(msiof2_txd_d), + SH_PFC_PIN_GROUP(msiof2_rxd_d), + SH_PFC_PIN_GROUP(msiof3_clk_a), + SH_PFC_PIN_GROUP(msiof3_sync_a), + SH_PFC_PIN_GROUP(msiof3_ss1_a), + SH_PFC_PIN_GROUP(msiof3_ss2_a), + SH_PFC_PIN_GROUP(msiof3_txd_a), + SH_PFC_PIN_GROUP(msiof3_rxd_a), + SH_PFC_PIN_GROUP(msiof3_clk_b), + SH_PFC_PIN_GROUP(msiof3_sync_b), + SH_PFC_PIN_GROUP(msiof3_ss1_b), + SH_PFC_PIN_GROUP(msiof3_ss2_b), + SH_PFC_PIN_GROUP(msiof3_txd_b), + SH_PFC_PIN_GROUP(msiof3_rxd_b), + SH_PFC_PIN_GROUP(msiof3_clk_c), + SH_PFC_PIN_GROUP(msiof3_sync_c), + SH_PFC_PIN_GROUP(msiof3_txd_c), + SH_PFC_PIN_GROUP(msiof3_rxd_c), + SH_PFC_PIN_GROUP(msiof3_clk_d), + SH_PFC_PIN_GROUP(msiof3_sync_d), + SH_PFC_PIN_GROUP(msiof3_ss1_d), + SH_PFC_PIN_GROUP(msiof3_txd_d), + SH_PFC_PIN_GROUP(msiof3_rxd_d), + SH_PFC_PIN_GROUP(msiof3_clk_e), + SH_PFC_PIN_GROUP(msiof3_sync_e), + SH_PFC_PIN_GROUP(msiof3_ss1_e), + SH_PFC_PIN_GROUP(msiof3_ss2_e), + SH_PFC_PIN_GROUP(msiof3_txd_e), + SH_PFC_PIN_GROUP(msiof3_rxd_e), + SH_PFC_PIN_GROUP(pwm0), + SH_PFC_PIN_GROUP(pwm1_a), + SH_PFC_PIN_GROUP(pwm1_b), + SH_PFC_PIN_GROUP(pwm2_a), + SH_PFC_PIN_GROUP(pwm2_b), + SH_PFC_PIN_GROUP(pwm3_a), + SH_PFC_PIN_GROUP(pwm3_b), + SH_PFC_PIN_GROUP(pwm4_a), + SH_PFC_PIN_GROUP(pwm4_b), + SH_PFC_PIN_GROUP(pwm5_a), + SH_PFC_PIN_GROUP(pwm5_b), + SH_PFC_PIN_GROUP(pwm6_a), + SH_PFC_PIN_GROUP(pwm6_b), + SH_PFC_PIN_GROUP(sata0_devslp_a), + SH_PFC_PIN_GROUP(sata0_devslp_b), + SH_PFC_PIN_GROUP(scif0_data), + SH_PFC_PIN_GROUP(scif0_clk), + SH_PFC_PIN_GROUP(scif0_ctrl), + SH_PFC_PIN_GROUP(scif1_data_a), + SH_PFC_PIN_GROUP(scif1_clk), + SH_PFC_PIN_GROUP(scif1_ctrl), + SH_PFC_PIN_GROUP(scif1_data_b), + SH_PFC_PIN_GROUP(scif2_data_a), + SH_PFC_PIN_GROUP(scif2_clk), + SH_PFC_PIN_GROUP(scif2_data_b), + SH_PFC_PIN_GROUP(scif3_data_a), + SH_PFC_PIN_GROUP(scif3_clk), + SH_PFC_PIN_GROUP(scif3_ctrl), + SH_PFC_PIN_GROUP(scif3_data_b), + SH_PFC_PIN_GROUP(scif4_data_a), + SH_PFC_PIN_GROUP(scif4_clk_a), + SH_PFC_PIN_GROUP(scif4_ctrl_a), + SH_PFC_PIN_GROUP(scif4_data_b), + SH_PFC_PIN_GROUP(scif4_clk_b), + SH_PFC_PIN_GROUP(scif4_ctrl_b), + SH_PFC_PIN_GROUP(scif4_data_c), + SH_PFC_PIN_GROUP(scif4_clk_c), + SH_PFC_PIN_GROUP(scif4_ctrl_c), + SH_PFC_PIN_GROUP(scif5_data_a), + SH_PFC_PIN_GROUP(scif5_clk_a), + SH_PFC_PIN_GROUP(scif5_data_b), + SH_PFC_PIN_GROUP(scif5_clk_b), + SH_PFC_PIN_GROUP(scif_clk_a), + SH_PFC_PIN_GROUP(scif_clk_b), + SH_PFC_PIN_GROUP(sdhi0_data1), + SH_PFC_PIN_GROUP(sdhi0_data4), + SH_PFC_PIN_GROUP(sdhi0_ctrl), + SH_PFC_PIN_GROUP(sdhi0_cd), + SH_PFC_PIN_GROUP(sdhi0_wp), + SH_PFC_PIN_GROUP(sdhi1_data1), + SH_PFC_PIN_GROUP(sdhi1_data4), + SH_PFC_PIN_GROUP(sdhi1_ctrl), + SH_PFC_PIN_GROUP(sdhi1_cd), + SH_PFC_PIN_GROUP(sdhi1_wp), + SH_PFC_PIN_GROUP(sdhi2_data1), + SH_PFC_PIN_GROUP(sdhi2_data4), + SH_PFC_PIN_GROUP(sdhi2_data8), + SH_PFC_PIN_GROUP(sdhi2_ctrl), + SH_PFC_PIN_GROUP(sdhi2_cd_a), + SH_PFC_PIN_GROUP(sdhi2_wp_a), + SH_PFC_PIN_GROUP(sdhi2_cd_b), + SH_PFC_PIN_GROUP(sdhi2_wp_b), + SH_PFC_PIN_GROUP(sdhi2_ds), + SH_PFC_PIN_GROUP(sdhi3_data1), + SH_PFC_PIN_GROUP(sdhi3_data4), + SH_PFC_PIN_GROUP(sdhi3_data8), + SH_PFC_PIN_GROUP(sdhi3_ctrl), + SH_PFC_PIN_GROUP(sdhi3_cd), + SH_PFC_PIN_GROUP(sdhi3_wp), + SH_PFC_PIN_GROUP(sdhi3_ds), + SH_PFC_PIN_GROUP(ssi0_data), + SH_PFC_PIN_GROUP(ssi01239_ctrl), + SH_PFC_PIN_GROUP(ssi1_data_a), + SH_PFC_PIN_GROUP(ssi1_data_b), + SH_PFC_PIN_GROUP(ssi1_ctrl_a), + SH_PFC_PIN_GROUP(ssi1_ctrl_b), + SH_PFC_PIN_GROUP(ssi2_data_a), + SH_PFC_PIN_GROUP(ssi2_data_b), + SH_PFC_PIN_GROUP(ssi2_ctrl_a), + SH_PFC_PIN_GROUP(ssi2_ctrl_b), + SH_PFC_PIN_GROUP(ssi3_data), + SH_PFC_PIN_GROUP(ssi349_ctrl), + SH_PFC_PIN_GROUP(ssi4_data), + SH_PFC_PIN_GROUP(ssi4_ctrl), + SH_PFC_PIN_GROUP(ssi5_data), + SH_PFC_PIN_GROUP(ssi5_ctrl), + SH_PFC_PIN_GROUP(ssi6_data), + SH_PFC_PIN_GROUP(ssi6_ctrl), + SH_PFC_PIN_GROUP(ssi7_data), + SH_PFC_PIN_GROUP(ssi78_ctrl), + SH_PFC_PIN_GROUP(ssi8_data), + SH_PFC_PIN_GROUP(ssi9_data_a), + SH_PFC_PIN_GROUP(ssi9_data_b), + SH_PFC_PIN_GROUP(ssi9_ctrl_a), + SH_PFC_PIN_GROUP(ssi9_ctrl_b), + SH_PFC_PIN_GROUP(tmu_tclk1_a), + SH_PFC_PIN_GROUP(tmu_tclk1_b), + SH_PFC_PIN_GROUP(tmu_tclk2_a), + SH_PFC_PIN_GROUP(tmu_tclk2_b), + SH_PFC_PIN_GROUP(tpu_to0), + SH_PFC_PIN_GROUP(tpu_to1), + SH_PFC_PIN_GROUP(tpu_to2), + SH_PFC_PIN_GROUP(tpu_to3), + SH_PFC_PIN_GROUP(usb0), + SH_PFC_PIN_GROUP(usb1), + SH_PFC_PIN_GROUP(usb2), + SH_PFC_PIN_GROUP(usb2_ch3), + SH_PFC_PIN_GROUP(usb30), + VIN_DATA_PIN_GROUP(vin4_data, 8, _a), + VIN_DATA_PIN_GROUP(vin4_data, 10, _a), + VIN_DATA_PIN_GROUP(vin4_data, 12, _a), + VIN_DATA_PIN_GROUP(vin4_data, 16, _a), + SH_PFC_PIN_GROUP(vin4_data18_a), + VIN_DATA_PIN_GROUP(vin4_data, 20, _a), + VIN_DATA_PIN_GROUP(vin4_data, 24, _a), + VIN_DATA_PIN_GROUP(vin4_data, 8, _b), + VIN_DATA_PIN_GROUP(vin4_data, 10, _b), + VIN_DATA_PIN_GROUP(vin4_data, 12, _b), + VIN_DATA_PIN_GROUP(vin4_data, 16, _b), + SH_PFC_PIN_GROUP(vin4_data18_b), + VIN_DATA_PIN_GROUP(vin4_data, 20, _b), + VIN_DATA_PIN_GROUP(vin4_data, 24, _b), + SH_PFC_PIN_GROUP(vin4_sync), + SH_PFC_PIN_GROUP(vin4_field), + SH_PFC_PIN_GROUP(vin4_clkenb), + SH_PFC_PIN_GROUP(vin4_clk), + VIN_DATA_PIN_GROUP(vin5_data, 8), + VIN_DATA_PIN_GROUP(vin5_data, 10), + VIN_DATA_PIN_GROUP(vin5_data, 12), + VIN_DATA_PIN_GROUP(vin5_data, 16), + SH_PFC_PIN_GROUP(vin5_sync), + SH_PFC_PIN_GROUP(vin5_field), + SH_PFC_PIN_GROUP(vin5_clkenb), + SH_PFC_PIN_GROUP(vin5_clk), + }, + .automotive = { + SH_PFC_PIN_GROUP(drif0_ctrl_a), + SH_PFC_PIN_GROUP(drif0_data0_a), + SH_PFC_PIN_GROUP(drif0_data1_a), + SH_PFC_PIN_GROUP(drif0_ctrl_b), + SH_PFC_PIN_GROUP(drif0_data0_b), + SH_PFC_PIN_GROUP(drif0_data1_b), + SH_PFC_PIN_GROUP(drif0_ctrl_c), + SH_PFC_PIN_GROUP(drif0_data0_c), + SH_PFC_PIN_GROUP(drif0_data1_c), + SH_PFC_PIN_GROUP(drif1_ctrl_a), + SH_PFC_PIN_GROUP(drif1_data0_a), + SH_PFC_PIN_GROUP(drif1_data1_a), + SH_PFC_PIN_GROUP(drif1_ctrl_b), + SH_PFC_PIN_GROUP(drif1_data0_b), + SH_PFC_PIN_GROUP(drif1_data1_b), + SH_PFC_PIN_GROUP(drif1_ctrl_c), + SH_PFC_PIN_GROUP(drif1_data0_c), + SH_PFC_PIN_GROUP(drif1_data1_c), + SH_PFC_PIN_GROUP(drif2_ctrl_a), + SH_PFC_PIN_GROUP(drif2_data0_a), + SH_PFC_PIN_GROUP(drif2_data1_a), + SH_PFC_PIN_GROUP(drif2_ctrl_b), + SH_PFC_PIN_GROUP(drif2_data0_b), + SH_PFC_PIN_GROUP(drif2_data1_b), + SH_PFC_PIN_GROUP(drif3_ctrl_a), + SH_PFC_PIN_GROUP(drif3_data0_a), + SH_PFC_PIN_GROUP(drif3_data1_a), + SH_PFC_PIN_GROUP(drif3_ctrl_b), + SH_PFC_PIN_GROUP(drif3_data0_b), + SH_PFC_PIN_GROUP(drif3_data1_b), + } + }; static const char * const audio_clk_groups[] = { @@ -5031,64 +5039,72 @@ static const char * const vin5_groups[] = { "vin5_clk", }; -static const struct sh_pfc_function pinmux_functions[] = { - SH_PFC_FUNCTION(audio_clk), - SH_PFC_FUNCTION(avb), - SH_PFC_FUNCTION(can0), - SH_PFC_FUNCTION(can1), - SH_PFC_FUNCTION(can_clk), - SH_PFC_FUNCTION(canfd0), - SH_PFC_FUNCTION(canfd1), - SH_PFC_FUNCTION(drif0), - SH_PFC_FUNCTION(drif1), - SH_PFC_FUNCTION(drif2), - SH_PFC_FUNCTION(drif3), - SH_PFC_FUNCTION(du), - SH_PFC_FUNCTION(hscif0), - SH_PFC_FUNCTION(hscif1), - SH_PFC_FUNCTION(hscif2), - SH_PFC_FUNCTION(hscif3), - SH_PFC_FUNCTION(hscif4), - SH_PFC_FUNCTION(i2c0), - SH_PFC_FUNCTION(i2c1), - SH_PFC_FUNCTION(i2c2), - SH_PFC_FUNCTION(i2c3), - SH_PFC_FUNCTION(i2c5), - SH_PFC_FUNCTION(i2c6), - SH_PFC_FUNCTION(intc_ex), - SH_PFC_FUNCTION(msiof0), - SH_PFC_FUNCTION(msiof1), - SH_PFC_FUNCTION(msiof2), - SH_PFC_FUNCTION(msiof3), - SH_PFC_FUNCTION(pwm0), - SH_PFC_FUNCTION(pwm1), - SH_PFC_FUNCTION(pwm2), - SH_PFC_FUNCTION(pwm3), - SH_PFC_FUNCTION(pwm4), - SH_PFC_FUNCTION(pwm5), - SH_PFC_FUNCTION(pwm6), - SH_PFC_FUNCTION(sata0), - SH_PFC_FUNCTION(scif0), - SH_PFC_FUNCTION(scif1), - SH_PFC_FUNCTION(scif2), - SH_PFC_FUNCTION(scif3), - SH_PFC_FUNCTION(scif4), - SH_PFC_FUNCTION(scif5), - SH_PFC_FUNCTION(scif_clk), - SH_PFC_FUNCTION(sdhi0), - SH_PFC_FUNCTION(sdhi1), - SH_PFC_FUNCTION(sdhi2), - SH_PFC_FUNCTION(sdhi3), - SH_PFC_FUNCTION(ssi), - SH_PFC_FUNCTION(tmu), - SH_PFC_FUNCTION(tpu), - SH_PFC_FUNCTION(usb0), - SH_PFC_FUNCTION(usb1), - SH_PFC_FUNCTION(usb2), - SH_PFC_FUNCTION(usb2_ch3), - SH_PFC_FUNCTION(usb30), - SH_PFC_FUNCTION(vin4), - SH_PFC_FUNCTION(vin5), +static const struct { + struct sh_pfc_function common[53]; + struct sh_pfc_function automotive[4]; +} pinmux_functions = { + .common = { + SH_PFC_FUNCTION(audio_clk), + SH_PFC_FUNCTION(avb), + SH_PFC_FUNCTION(can0), + SH_PFC_FUNCTION(can1), + SH_PFC_FUNCTION(can_clk), + SH_PFC_FUNCTION(canfd0), + SH_PFC_FUNCTION(canfd1), + SH_PFC_FUNCTION(du), + SH_PFC_FUNCTION(hscif0), + SH_PFC_FUNCTION(hscif1), + SH_PFC_FUNCTION(hscif2), + SH_PFC_FUNCTION(hscif3), + SH_PFC_FUNCTION(hscif4), + SH_PFC_FUNCTION(i2c0), + SH_PFC_FUNCTION(i2c1), + SH_PFC_FUNCTION(i2c2), + SH_PFC_FUNCTION(i2c3), + SH_PFC_FUNCTION(i2c5), + SH_PFC_FUNCTION(i2c6), + SH_PFC_FUNCTION(intc_ex), + SH_PFC_FUNCTION(msiof0), + SH_PFC_FUNCTION(msiof1), + SH_PFC_FUNCTION(msiof2), + SH_PFC_FUNCTION(msiof3), + SH_PFC_FUNCTION(pwm0), + SH_PFC_FUNCTION(pwm1), + SH_PFC_FUNCTION(pwm2), + SH_PFC_FUNCTION(pwm3), + SH_PFC_FUNCTION(pwm4), + SH_PFC_FUNCTION(pwm5), + SH_PFC_FUNCTION(pwm6), + SH_PFC_FUNCTION(sata0), + SH_PFC_FUNCTION(scif0), + SH_PFC_FUNCTION(scif1), + SH_PFC_FUNCTION(scif2), + SH_PFC_FUNCTION(scif3), + SH_PFC_FUNCTION(scif4), + SH_PFC_FUNCTION(scif5), + SH_PFC_FUNCTION(scif_clk), + SH_PFC_FUNCTION(sdhi0), + SH_PFC_FUNCTION(sdhi1), + SH_PFC_FUNCTION(sdhi2), + SH_PFC_FUNCTION(sdhi3), + SH_PFC_FUNCTION(ssi), + SH_PFC_FUNCTION(tmu), + SH_PFC_FUNCTION(tpu), + SH_PFC_FUNCTION(usb0), + SH_PFC_FUNCTION(usb1), + SH_PFC_FUNCTION(usb2), + SH_PFC_FUNCTION(usb2_ch3), + SH_PFC_FUNCTION(usb30), + SH_PFC_FUNCTION(vin4), + SH_PFC_FUNCTION(vin5), + }, + .automotive = { + SH_PFC_FUNCTION(drif0), + SH_PFC_FUNCTION(drif1), + SH_PFC_FUNCTION(drif2), + SH_PFC_FUNCTION(drif3), + } + }; static const struct pinmux_cfg_reg pinmux_config_regs[] = { @@ -5777,7 +5793,9 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = { { PIN_DU_DOTCLKIN1, 0, 2 }, /* DU_DOTCLKIN1 */ } }, { PINMUX_DRIVE_REG("DRVCTRL12", 0xe6060330) { +#ifdef CONFIG_PINCTRL_PFC_R8A77951 { PIN_DU_DOTCLKIN2, 28, 2 }, /* DU_DOTCLKIN2 */ +#endif { PIN_DU_DOTCLKIN3, 24, 2 }, /* DU_DOTCLKIN3 */ { PIN_FSCLKST_N, 20, 2 }, /* FSCLKST# */ { PIN_TMS, 4, 2 }, /* TMS */ @@ -5898,8 +5916,8 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = { { RCAR_GP_PIN(6, 27), 20, 3 }, /* USB1_OVC */ { RCAR_GP_PIN(6, 28), 16, 3 }, /* USB30_PWEN */ { RCAR_GP_PIN(6, 29), 12, 3 }, /* USB30_OVC */ - { RCAR_GP_PIN(6, 30), 8, 3 }, /* USB2_CH3_PWEN */ - { RCAR_GP_PIN(6, 31), 4, 3 }, /* USB2_CH3_OVC */ + { RCAR_GP_PIN(6, 30), 8, 3 }, /* GP6_30/USB2_CH3_PWEN */ + { RCAR_GP_PIN(6, 31), 4, 3 }, /* GP6_31/USB2_CH3_OVC */ } }, { }, }; @@ -6220,8 +6238,9 @@ static const struct sh_pfc_soc_operations r8a77951_pinmux_ops = { .set_bias = r8a77951_pinmux_set_bias, }; -const struct sh_pfc_soc_info r8a77951_pinmux_info = { - .name = "r8a77951_pfc", +#ifdef CONFIG_PINCTRL_PFC_R8A774E1 +const struct sh_pfc_soc_info r8a774e1_pinmux_info = { + .name = "r8a774e1_pfc", .ops = &r8a77951_pinmux_ops, .unlock_reg = 0xe6060000, /* PMMR */ @@ -6229,10 +6248,10 @@ const struct sh_pfc_soc_info r8a77951_pinmux_info = { .pins = pinmux_pins, .nr_pins = ARRAY_SIZE(pinmux_pins), - .groups = pinmux_groups, - .nr_groups = ARRAY_SIZE(pinmux_groups), - .functions = pinmux_functions, - .nr_functions = ARRAY_SIZE(pinmux_functions), + .groups = pinmux_groups.common, + .nr_groups = ARRAY_SIZE(pinmux_groups.common), + .functions = pinmux_functions.common, + .nr_functions = ARRAY_SIZE(pinmux_functions.common), .cfg_regs = pinmux_config_regs, .drive_regs = pinmux_drive_regs, @@ -6242,3 +6261,31 @@ const struct sh_pfc_soc_info r8a77951_pinmux_info = { .pinmux_data = pinmux_data, .pinmux_data_size = ARRAY_SIZE(pinmux_data), }; +#endif + +#ifdef CONFIG_PINCTRL_PFC_R8A77951 +const struct sh_pfc_soc_info r8a77951_pinmux_info = { + .name = "r8a77951_pfc", + .ops = &r8a77951_pinmux_ops, + .unlock_reg = 0xe6060000, /* PMMR */ + + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .pins = pinmux_pins, + .nr_pins = ARRAY_SIZE(pinmux_pins), + .groups = pinmux_groups.common, + .nr_groups = ARRAY_SIZE(pinmux_groups.common) + + ARRAY_SIZE(pinmux_groups.automotive), + .functions = pinmux_functions.common, + .nr_functions = ARRAY_SIZE(pinmux_functions.common) + + ARRAY_SIZE(pinmux_functions.automotive), + + .cfg_regs = pinmux_config_regs, + .drive_regs = pinmux_drive_regs, + .bias_regs = pinmux_bias_regs, + .ioctrl_regs = pinmux_ioctrl_regs, + + .pinmux_data = pinmux_data, + .pinmux_data_size = ARRAY_SIZE(pinmux_data), +}; +#endif diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 0f013827baf9..eff1bb872325 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -312,6 +312,7 @@ extern const struct sh_pfc_soc_info r8a77470_pinmux_info; extern const struct sh_pfc_soc_info r8a774a1_pinmux_info; extern const struct sh_pfc_soc_info r8a774b1_pinmux_info; extern const struct sh_pfc_soc_info r8a774c0_pinmux_info; +extern const struct sh_pfc_soc_info r8a774e1_pinmux_info; extern const struct sh_pfc_soc_info r8a7778_pinmux_info; extern const struct sh_pfc_soc_info r8a7779_pinmux_info; extern const struct sh_pfc_soc_info r8a7790_pinmux_info; From 6d31fa6aea09b3714c7a0a27d8cad3639c5f54ff Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:25 +0100 Subject: [PATCH 162/242] pinctrl: rza1: Demote some kerneldoc headers and fix others Some description blocks are void of any description/documentation, others are missing 'struct' identifiers, there are also a couple of misspellings of function parameter names. Fix all of them. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinctrl-rza1.c:81: warning: cannot understand function prototype: 'struct rza1_bidir_pin ' drivers/pinctrl/pinctrl-rza1.c:90: warning: cannot understand function prototype: 'struct rza1_bidir_entry ' drivers/pinctrl/pinctrl-rza1.c:98: warning: cannot understand function prototype: 'struct rza1_swio_pin ' drivers/pinctrl/pinctrl-rza1.c:108: warning: cannot understand function prototype: 'struct rza1_swio_entry ' drivers/pinctrl/pinctrl-rza1.c:116: warning: cannot understand function prototype: 'struct rza1_pinmux_conf ' drivers/pinctrl/pinctrl-rza1.c:443: warning: cannot understand function prototype: 'struct rza1_mux_conf ' drivers/pinctrl/pinctrl-rza1.c:462: warning: cannot understand function prototype: 'struct rza1_port ' drivers/pinctrl/pinctrl-rza1.c:482: warning: cannot understand function prototype: 'struct rza1_pinctrl ' drivers/pinctrl/pinctrl-rza1.c:546: warning: Function parameter or member 'port' not described in 'rza1_pinmux_get_flags' drivers/pinctrl/pinctrl-rza1.c:546: warning: Function parameter or member 'pin' not described in 'rza1_pinmux_get_flags' drivers/pinctrl/pinctrl-rza1.c:546: warning: Function parameter or member 'func' not described in 'rza1_pinmux_get_flags' drivers/pinctrl/pinctrl-rza1.c:546: warning: Function parameter or member 'rza1_pctl' not described in 'rza1_pinmux_get_flags' drivers/pinctrl/pinctrl-rza1.c:575: warning: Function parameter or member 'port' not described in 'rza1_set_bit' drivers/pinctrl/pinctrl-rza1.c:575: warning: Function parameter or member 'reg' not described in 'rza1_set_bit' drivers/pinctrl/pinctrl-rza1.c:575: warning: Function parameter or member 'bit' not described in 'rza1_set_bit' drivers/pinctrl/pinctrl-rza1.c:575: warning: Function parameter or member 'set' not described in 'rza1_set_bit' drivers/pinctrl/pinctrl-rza1.c:672: warning: Function parameter or member 'rza1_pctl' not described in 'rza1_pin_mux_single' drivers/pinctrl/pinctrl-rza1.c:672: warning: Excess function parameter 'pinctrl' description in 'rza1_pin_mux_single' Signed-off-by: Lee Jones Acked-by: Jacopo Mondi Link: https://lore.kernel.org/r/20200713144930.1034632-21-lee.jones@linaro.org Signed-off-by: Geert Uytterhoeven --- drivers/pinctrl/pinctrl-rza1.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rza1.c b/drivers/pinctrl/pinctrl-rza1.c index 38a14bbced5f..511f232ab7bc 100644 --- a/drivers/pinctrl/pinctrl-rza1.c +++ b/drivers/pinctrl/pinctrl-rza1.c @@ -75,7 +75,7 @@ * RZ/A1 pinmux flags */ -/** +/* * rza1_bidir_pin - describe a single pin that needs bidir flag applied. */ struct rza1_bidir_pin { @@ -83,7 +83,7 @@ struct rza1_bidir_pin { u8 func: 4; }; -/** +/* * rza1_bidir_entry - describe a list of pins that needs bidir flag applied. * Each struct rza1_bidir_entry describes a port. */ @@ -92,7 +92,7 @@ struct rza1_bidir_entry { const struct rza1_bidir_pin *pins; }; -/** +/* * rza1_swio_pin - describe a single pin that needs swio flag applied. */ struct rza1_swio_pin { @@ -102,7 +102,7 @@ struct rza1_swio_pin { u16 input: 1; }; -/** +/* * rza1_swio_entry - describe a list of pins that needs swio flag applied */ struct rza1_swio_entry { @@ -110,7 +110,7 @@ struct rza1_swio_entry { const struct rza1_swio_pin *pins; }; -/** +/* * rza1_pinmux_conf - group together bidir and swio pinmux flag tables */ struct rza1_pinmux_conf { @@ -431,7 +431,7 @@ static const struct rza1_pinmux_conf rza1l_pmx_conf = { * RZ/A1 types */ /** - * rza1_mux_conf - describes a pin multiplexing operation + * struct rza1_mux_conf - describes a pin multiplexing operation * * @id: the pin identifier from 0 to RZA1_NPINS * @port: the port where pin sits on @@ -450,7 +450,7 @@ struct rza1_mux_conf { }; /** - * rza1_port - describes a pin port + * struct rza1_port - describes a pin port * * This is mostly useful to lock register writes per-bank and not globally. * @@ -467,12 +467,12 @@ struct rza1_port { }; /** - * rza1_pinctrl - RZ pincontroller device + * struct rza1_pinctrl - RZ pincontroller device * * @dev: parent device structure * @mutex: protect [pinctrl|pinmux]_generic functions * @base: logical address base - * @nports: number of pin controller ports + * @nport: number of pin controller ports * @ports: pin controller banks * @pins: pin array for pinctrl core * @desc: pincontroller desc for pinctrl core @@ -536,7 +536,7 @@ static inline int rza1_pinmux_get_swio(unsigned int port, return -ENOENT; } -/** +/* * rza1_pinmux_get_flags() - return pinmux flags associated to a pin */ static unsigned int rza1_pinmux_get_flags(unsigned int port, unsigned int pin, @@ -566,7 +566,7 @@ static unsigned int rza1_pinmux_get_flags(unsigned int port, unsigned int pin, * RZ/A1 SoC operations */ -/** +/* * rza1_set_bit() - un-locked set/clear a single bit in pin configuration * registers */ @@ -664,7 +664,7 @@ static inline int rza1_pin_get(struct rza1_port *port, unsigned int pin) /** * rza1_pin_mux_single() - configure pin multiplexing on a single pin * - * @pinctrl: RZ/A1 pin controller device + * @rza1_pctl: RZ/A1 pin controller device * @mux_conf: pin multiplexing descriptor */ static int rza1_pin_mux_single(struct rza1_pinctrl *rza1_pctl, From 4d0e62679f17b8bde01aa9995233b5b9ca05ab7f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 26 Jun 2020 16:36:38 +0200 Subject: [PATCH 163/242] dt-bindings: pinctrl: renesas,rza2-pinctrl: Convert to json-schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the Renesas RZ/A2 combined Pin and GPIO controller Device Tree binding documentation to json-schema. Signed-off-by: Geert Uytterhoeven Reviewed-by: Rob Herring Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/20200626143638.16512-1-geert+renesas@glider.be --- .../bindings/pinctrl/renesas,rza2-pinctrl.txt | 87 --------------- .../pinctrl/renesas,rza2-pinctrl.yaml | 100 ++++++++++++++++++ 2 files changed, 100 insertions(+), 87 deletions(-) delete mode 100644 Documentation/devicetree/bindings/pinctrl/renesas,rza2-pinctrl.txt create mode 100644 Documentation/devicetree/bindings/pinctrl/renesas,rza2-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rza2-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,rza2-pinctrl.txt deleted file mode 100644 index a63ccd476cda..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/renesas,rza2-pinctrl.txt +++ /dev/null @@ -1,87 +0,0 @@ -Renesas RZ/A2 combined Pin and GPIO controller - -The Renesas SoCs of the RZ/A2 series feature a combined Pin and GPIO controller. -Pin multiplexing and GPIO configuration is performed on a per-pin basis. -Each port features up to 8 pins, each of them configurable for GPIO -function (port mode) or in alternate function mode. -Up to 8 different alternate function modes exist for each single pin. - -Pin controller node -------------------- - -Required properties: - - compatible: shall be: - - "renesas,r7s9210-pinctrl": for RZ/A2M - - reg - Address base and length of the memory area where the pin controller - hardware is mapped to. - - gpio-controller - This pin controller also controls pins as GPIO - - #gpio-cells - Must be 2 - - gpio-ranges - Expresses the total number of GPIO ports/pins in this SoC - -Example: Pin controller node for RZ/A2M SoC (r7s9210) - - pinctrl: pin-controller@fcffe000 { - compatible = "renesas,r7s9210-pinctrl"; - reg = <0xfcffe000 0x1000>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl 0 0 176>; - }; - -Sub-nodes ---------- - -The child nodes of the pin controller designate pins to be used for -specific peripheral functions or as GPIO. - -- Pin multiplexing sub-nodes: - A pin multiplexing sub-node describes how to configure a set of - (or a single) pin in some desired alternate function mode. - The values for the pinmux properties are a combination of port name, pin - number and the desired function index. Use the RZA2_PINMUX macro located - in include/dt-bindings/pinctrl/r7s9210-pinctrl.h to easily define these. - For assigning GPIO pins, use the macro RZA2_PIN also in r7s9210-pinctrl.h - to express the desired port pin. - - Required properties: - - pinmux: - integer array representing pin number and pin multiplexing configuration. - When a pin has to be configured in alternate function mode, use this - property to identify the pin by its global index, and provide its - alternate function configuration number along with it. - When multiple pins are required to be configured as part of the same - alternate function they shall be specified as members of the same - argument list of a single "pinmux" property. - Helper macros to ease assembling the pin index from its position - (port where it sits on and pin number) and alternate function identifier - are provided by the pin controller header file at: - - Integers values in "pinmux" argument list are assembled as: - ((PORT * 8 + PIN) | MUX_FUNC << 16) - - Example: Board specific pins configuration - - &pinctrl { - /* Serial Console */ - scif4_pins: serial4 { - pinmux = , /* TxD4 */ - ; /* RxD4 */ - }; - }; - - Example: Assigning a GPIO: - - leds { - status = "okay"; - compatible = "gpio-leds"; - - led0 { - /* P6_0 */ - gpios = <&pinctrl RZA2_PIN(PORT6, 0) GPIO_ACTIVE_HIGH>; - }; - }; diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rza2-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rza2-pinctrl.yaml new file mode 100644 index 000000000000..b7911a994f3a --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rza2-pinctrl.yaml @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/renesas,rza2-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/A2 combined Pin and GPIO controller + +maintainers: + - Chris Brandt + - Geert Uytterhoeven + +description: + The Renesas SoCs of the RZ/A2 series feature a combined Pin and GPIO + controller. + Pin multiplexing and GPIO configuration is performed on a per-pin basis. + Each port features up to 8 pins, each of them configurable for GPIO function + (port mode) or in alternate function mode. + Up to 8 different alternate function modes exist for each single pin. + +properties: + compatible: + const: "renesas,r7s9210-pinctrl" # RZ/A2M + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + description: + The first cell contains the global GPIO port index, constructed using the + RZA2_PIN() helper macro in r7s9210-pinctrl.h. + E.g. "RZA2_PIN(PORT6, 0)" for P6_0. + + gpio-ranges: + maxItems: 1 + +patternProperties: + "^.*$": + if: + type: object + then: + allOf: + - $ref: pincfg-node.yaml# + - $ref: pinmux-node.yaml# + description: + The child nodes of the pin controller designate pins to be used for + specific peripheral functions or as GPIO. + + A pin multiplexing sub-node describes how to configure a set of + (or a single) pin in some desired alternate function mode. + The values for the pinmux properties are a combination of port name, + pin number and the desired function index. Use the RZA2_PINMUX macro + located in include/dt-bindings/pinctrl/r7s9210-pinctrl.h to easily + define these. + For assigning GPIO pins, use the macro RZA2_PIN also in + to express the desired port pin. + + properties: + phandle: true + + pinmux: + description: + Values are constructed from GPIO port number, pin number, and + alternate function configuration number using the RZA2_PINMUX() + helper macro in r7s9210-pinctrl.h. + + required: + - pinmux + + additionalProperties: false + +required: + - compatible + - reg + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + - | + #include + pinctrl: pin-controller@fcffe000 { + compatible = "renesas,r7s9210-pinctrl"; + reg = <0xfcffe000 0x1000>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 0 176>; + + /* Serial Console */ + scif4_pins: serial4 { + pinmux = , /* TxD4 */ + ; /* RxD4 */ + }; + }; From 40e30d26d909af89de2dcd0b4abdd27c47ac2235 Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Wed, 15 Jul 2020 23:37:38 +0200 Subject: [PATCH 164/242] gpio: omap: handle pin config bias flags Modify omap_gpio_set_config() to handle pin config bias flags by calling gpiochip_generic_config(). The pin group for the gpio line must have the corresponding pinconf properties: PIN_CONFIG_BIAS_PULL_UP requires "pinctrl-single,bias-pullup" PIN_CONFIG_BIAS_PULL_DOWN requires "pinctrl-single,bias-pulldown" This is necessary for pcs_pinconf_set() to find the requested bias parameter in the PIN_MAP_TYPE_CONFIGS_GROUP pinctrl map. Signed-off-by: Drew Fustini Acked-by: Grygorii Strashko Acked-by: Tony Lindgren Link: https://lore.kernel.org/r/20200715213738.1640030-1-drew@beagleboard.org Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index b8e2ecc3eade..eba303cff7cb 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -896,12 +896,21 @@ static int omap_gpio_set_config(struct gpio_chip *chip, unsigned offset, unsigned long config) { u32 debounce; + int ret = -ENOTSUPP; - if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) - return -ENOTSUPP; + if ((pinconf_to_config_param(config) == PIN_CONFIG_BIAS_DISABLE) || + (pinconf_to_config_param(config) == PIN_CONFIG_BIAS_PULL_UP) || + (pinconf_to_config_param(config) == PIN_CONFIG_BIAS_PULL_DOWN)) + { + ret = gpiochip_generic_config(chip, offset, config); + } + else if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) + { + debounce = pinconf_to_config_argument(config); + ret = omap_gpio_debounce(chip, offset, debounce); + } - debounce = pinconf_to_config_argument(config); - return omap_gpio_debounce(chip, offset, debounce); + return ret; } static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value) From aa639e4437046a2519779932d8aa8842b517e20f Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Wed, 1 Jul 2020 12:30:39 +0930 Subject: [PATCH 165/242] pinctrl: aspeed: Improve debug output We need to iterate over each pin in a group for a function and disable higher priority mux configurations on the pin before finally muxing the relevant function's signal. With the current debug output it is hard to track what register output is relevant to which operation, so break up the actions in the debug output by providing some more context. Before: [ 5.446656] aspeed-g6-pinctrl 1e6e2000.syscon:pinctrl: request pin 37 (B26) for 1e780000.gpio:341 [ 5.447377] Want SCU414[0x00000020]=0x1, got 0x0 from 0x00000000 [ 5.447854] Want SCU4B4[0x00000020]=0x1, got 0x0 from 0x00000000 [ 5.448340] Want SCU4B4[0x00000020]=0x1, got 0x0 from 0x00000000 After: [ 5.298053] Muxing pin 37 for GPIO [ 5.298294] Disabling signal NRI4 for NRI4 [ 5.298593] Want SCU414[0x00000020]=0x1, got 0x0 from 0x00000000 [ 5.298983] Disabling signal RGMII4RXD1 for RGMII4 [ 5.299309] Want SCU4B4[0x00000020]=0x1, got 0x0 from 0x00000000 [ 5.299694] Disabling signal RMII4RXD1 for RMII4 [ 5.300014] Want SCU4B4[0x00000020]=0x1, got 0x0 from 0x00000000 [ 5.300396] Enabling signal GPIOE5 for GPIOE5 [ 5.300687] Muxed pin 37 as GPIOE5 Signed-off-by: Andrew Jeffery Signed-off-by: Joel Stanley Link: https://lore.kernel.org/r/20200701030039.2834418-1-joel@jms.id.au Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c index b625a657171e..53f3f8aec695 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c @@ -76,6 +76,9 @@ static int aspeed_sig_expr_enable(struct aspeed_pinmux_data *ctx, { int ret; + pr_debug("Enabling signal %s for %s\n", expr->signal, + expr->function); + ret = aspeed_sig_expr_eval(ctx, expr, true); if (ret < 0) return ret; @@ -91,6 +94,9 @@ static int aspeed_sig_expr_disable(struct aspeed_pinmux_data *ctx, { int ret; + pr_debug("Disabling signal %s for %s\n", expr->signal, + expr->function); + ret = aspeed_sig_expr_eval(ctx, expr, true); if (ret < 0) return ret; @@ -229,7 +235,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, const struct aspeed_sig_expr **funcs; const struct aspeed_sig_expr ***prios; - pr_debug("Muxing pin %d for %s\n", pin, pfunc->name); + pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name); if (!pdesc) return -EINVAL; @@ -269,6 +275,9 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, ret = aspeed_sig_expr_enable(&pdata->pinmux, expr); if (ret) return ret; + + pr_debug("Muxed pin %s as %s for %s\n", pdesc->name, expr->signal, + expr->function); } return 0; @@ -317,6 +326,8 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, if (!prios) return -ENXIO; + pr_debug("Muxing pin %s for GPIO\n", pdesc->name); + /* Disable any functions of higher priority than GPIO */ while ((funcs = *prios)) { if (aspeed_gpio_in_exprs(funcs)) @@ -346,14 +357,22 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, * lowest-priority signal type. As such it has no associated * expression. */ - if (!expr) + if (!expr) { + pr_debug("Muxed pin %s as GPIO\n", pdesc->name); return 0; + } /* * If GPIO is not the lowest priority signal type, assume there is only * one expression defined to enable the GPIO function */ - return aspeed_sig_expr_enable(&pdata->pinmux, expr); + ret = aspeed_sig_expr_enable(&pdata->pinmux, expr); + if (ret) + return ret; + + pr_debug("Muxed pin %s as %s\n", pdesc->name, expr->signal); + + return 0; } int aspeed_pinctrl_probe(struct platform_device *pdev, From 13c502c863df0ee50b50bcadb59895984248dc8b Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Wed, 1 Jul 2020 12:37:56 +0930 Subject: [PATCH 166/242] pinctrl: aspeed: Describe the heartbeat function on ball Y23 The default pinmux configuration for Y23 is to route a heartbeat to drive a LED. Previous revisions of the AST2600 datasheet did not include a description of this function. Fixes: 2eda1cdec49f ("pinctrl: aspeed: Add AST2600 pinmux support") Signed-off-by: Andrew Jeffery Signed-off-by: Joel Stanley Link: https://lore.kernel.org/r/20200701030756.2834657-1-joel@jms.id.au Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c index fa32c3e9c9d1..7efe6dbe4398 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -46,6 +46,7 @@ #define SCU634 0x634 /* Disable GPIO Internal Pull-Down #5 */ #define SCU638 0x638 /* Disable GPIO Internal Pull-Down #6 */ #define SCU694 0x694 /* Multi-function Pin Control #25 */ +#define SCU69C 0x69C /* Multi-function Pin Control #27 */ #define SCUC20 0xC20 /* PCIE configuration Setting Control */ #define ASPEED_G6_NR_PINS 256 @@ -819,11 +820,13 @@ FUNC_DECL_2(PWM14, PWM14G0, PWM14G1); #define Y23 127 SIG_EXPR_LIST_DECL_SEMG(Y23, PWM15, PWM15G1, PWM15, SIG_DESC_SET(SCU41C, 31)); SIG_EXPR_LIST_DECL_SESG(Y23, THRUOUT3, THRU3, SIG_DESC_SET(SCU4BC, 31)); -PIN_DECL_2(Y23, GPIOP7, PWM15, THRUOUT3); +SIG_EXPR_LIST_DECL_SESG(Y23, HEARTBEAT, HEARTBEAT, SIG_DESC_SET(SCU69C, 31)); +PIN_DECL_3(Y23, GPIOP7, PWM15, THRUOUT3, HEARTBEAT); GROUP_DECL(PWM15G1, Y23); FUNC_DECL_2(PWM15, PWM15G0, PWM15G1); FUNC_GROUP_DECL(THRU3, AB24, Y23); +FUNC_GROUP_DECL(HEARTBEAT, Y23); #define AA25 128 SSSF_PIN_DECL(AA25, GPIOQ0, TACH0, SIG_DESC_SET(SCU430, 0)); @@ -1920,6 +1923,7 @@ static const struct aspeed_pin_group aspeed_g6_groups[] = { ASPEED_PINCTRL_GROUP(GPIU5), ASPEED_PINCTRL_GROUP(GPIU6), ASPEED_PINCTRL_GROUP(GPIU7), + ASPEED_PINCTRL_GROUP(HEARTBEAT), ASPEED_PINCTRL_GROUP(HVI3C3), ASPEED_PINCTRL_GROUP(HVI3C4), ASPEED_PINCTRL_GROUP(I2C1), @@ -2158,6 +2162,7 @@ static const struct aspeed_pin_function aspeed_g6_functions[] = { ASPEED_PINCTRL_FUNC(GPIU5), ASPEED_PINCTRL_FUNC(GPIU6), ASPEED_PINCTRL_FUNC(GPIU7), + ASPEED_PINCTRL_FUNC(HEARTBEAT), ASPEED_PINCTRL_FUNC(I2C1), ASPEED_PINCTRL_FUNC(I2C10), ASPEED_PINCTRL_FUNC(I2C11), From 13355ca35cd16f5024655ac06e228b3c199e52a9 Mon Sep 17 00:00:00 2001 From: Jaiganesh Narayanan Date: Fri, 3 Jul 2020 01:06:45 -0700 Subject: [PATCH 167/242] pinctrl: qcom: ipq4019: add open drain support [ Brian: adapted from from the Chromium OS kernel used on IPQ4019-based WiFi APs. ] Signed-off-by: Jaiganesh Narayanan Signed-off-by: Brian Norris Link: https://lore.kernel.org/r/20200703080646.23233-1-computersforpeace@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-ipq4019.c | 1 + drivers/pinctrl/qcom/pinctrl-msm.c | 13 +++++++++++++ drivers/pinctrl/qcom/pinctrl-msm.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-ipq4019.c b/drivers/pinctrl/qcom/pinctrl-ipq4019.c index 8bdb5bd393d2..63915cb210ff 100644 --- a/drivers/pinctrl/qcom/pinctrl-ipq4019.c +++ b/drivers/pinctrl/qcom/pinctrl-ipq4019.c @@ -254,6 +254,7 @@ DECLARE_QCA_GPIO_PINS(99); .mux_bit = 2, \ .pull_bit = 0, \ .drv_bit = 6, \ + .od_bit = 12, \ .oe_bit = 9, \ .in_bit = 0, \ .out_bit = 1, \ diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 83b7d64bc4c1..dac0404dadf4 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -233,6 +233,10 @@ static int msm_config_reg(struct msm_pinctrl *pctrl, *bit = g->pull_bit; *mask = 3; break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + *bit = g->od_bit; + *mask = 1; + break; case PIN_CONFIG_DRIVE_STRENGTH: *bit = g->drv_bit; *mask = 7; @@ -310,6 +314,12 @@ static int msm_config_group_get(struct pinctrl_dev *pctldev, if (!arg) return -EINVAL; break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + /* Pin is not open-drain */ + if (!arg) + return -EINVAL; + arg = 1; + break; case PIN_CONFIG_DRIVE_STRENGTH: arg = msm_regval_to_drive(arg); break; @@ -382,6 +392,9 @@ static int msm_config_group_set(struct pinctrl_dev *pctldev, else arg = MSM_PULL_UP; break; + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + arg = 1; + break; case PIN_CONFIG_DRIVE_STRENGTH: /* Check for invalid values */ if (arg > 16 || arg < 2 || (arg % 2) != 0) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h index 9452da18a78b..dc7f8c84744b 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.h +++ b/drivers/pinctrl/qcom/pinctrl-msm.h @@ -38,6 +38,7 @@ struct msm_function { * @mux_bit: Offset in @ctl_reg for the pinmux function selection. * @pull_bit: Offset in @ctl_reg for the bias configuration. * @drv_bit: Offset in @ctl_reg for the drive strength configuration. + * @od_bit: Offset in @ctl_reg for controlling open drain. * @oe_bit: Offset in @ctl_reg for controlling output enable. * @in_bit: Offset in @io_reg for the input bit value. * @out_bit: Offset in @io_reg for the output bit value. @@ -75,6 +76,7 @@ struct msm_pingroup { unsigned pull_bit:5; unsigned drv_bit:5; + unsigned od_bit:5; unsigned oe_bit:5; unsigned in_bit:5; unsigned out_bit:5; From 99d19f5a48ee6fbc647935de458505e9308078e3 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 3 Jul 2020 01:06:46 -0700 Subject: [PATCH 168/242] dt-bindings: pinctrl: qcom: add drive-open-drain to ipq4019 We've added drive-open-drain support, so note it in the DT binding. Signed-off-by: Brian Norris Acked-by: Rob Herring Link: https://lore.kernel.org/r/20200703080646.23233-2-computersforpeace@gmail.com Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt index 84be0f2c6f3b..0861afeccfc9 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt @@ -44,7 +44,8 @@ information about e.g. the mux function. The following generic properties as defined in pinctrl-bindings.txt are valid to specify in a pin configuration subnode: - pins, function, bias-disable, bias-pull-down, bias-pull-up, drive-strength. + pins, function, bias-disable, bias-pull-down, bias-pull-up, drive-open-drain, + drive-strength. Non-empty subnodes must specify the 'pins' property. Note that not all properties are valid for all pins. From 80fa3300b7e5d738365698052d999ea71bb24723 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:06 +0100 Subject: [PATCH 169/242] pinctrl: actions: pinctrl-owl: Supply missing 'struct owl_pinctrl' attribute descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/pinctrl/actions/pinctrl-owl.c:52: warning: Function parameter or member 'clk' not described in 'owl_pinctrl' drivers/pinctrl/actions/pinctrl-owl.c:52: warning: Function parameter or member 'irq_chip' not described in 'owl_pinctrl' drivers/pinctrl/actions/pinctrl-owl.c:52: warning: Function parameter or member 'num_irq' not described in 'owl_pinctrl' drivers/pinctrl/actions/pinctrl-owl.c:52: warning: Function parameter or member 'irq' not described in 'owl_pinctrl' Signed-off-by: Lee Jones Reviewed-by: Manivannan Sadhasivam Cc: "Andreas Färber" Cc: Manivannan Sadhasivam Cc: David Liu Link: https://lore.kernel.org/r/20200713144930.1034632-2-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/actions/pinctrl-owl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c index 5a0c8e87aa7c..7efdfb4f3e9b 100644 --- a/drivers/pinctrl/actions/pinctrl-owl.c +++ b/drivers/pinctrl/actions/pinctrl-owl.c @@ -35,8 +35,12 @@ * @pctrldev: pinctrl handle * @chip: gpio chip * @lock: spinlock to protect registers + * @clk: clock control * @soc: reference to soc_data * @base: pinctrl register base address + * @irq_chip: IRQ chip information + * @num_irq: number of possible interrupts + * @irq: interrupt numbers */ struct owl_pinctrl { struct device *dev; From bef63e6615e3411a830e34b993c15721ab0a3550 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:07 +0100 Subject: [PATCH 170/242] pinctrl: sirf: pinctrl-atlas7: Fix a bunch of documentation misdemeanours >From ill formatted kerneldoc, to incomplete *and* incorrect struct headers, through to formatting issues and missing attribute descriptions. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/sirf/pinctrl-atlas7.c:197: warning: Function parameter or member 'id' not described in 'atlas7_pad_config' drivers/pinctrl/sirf/pinctrl-atlas7.c:221: warning: Function parameter or member 'func' not described in 'atlas7_pad_status' drivers/pinctrl/sirf/pinctrl-atlas7.c:221: warning: Function parameter or member 'pull' not described in 'atlas7_pad_status' drivers/pinctrl/sirf/pinctrl-atlas7.c:221: warning: Function parameter or member 'dstr' not described in 'atlas7_pad_status' drivers/pinctrl/sirf/pinctrl-atlas7.c:221: warning: Function parameter or member 'reserved' not described in 'atlas7_pad_status' drivers/pinctrl/sirf/pinctrl-atlas7.c:359: warning: Cannot understand * @dev: a pointer back to containing device on line 359 - I thought it was a doc line drivers/pinctrl/sirf/pinctrl-atlas7.c:4794: warning: Function parameter or member 'pad_type' not described in 'atlas7_pull_info' drivers/pinctrl/sirf/pinctrl-atlas7.c:4917: warning: Function parameter or member 'reserved' not described in 'atlas7_ds_info' drivers/pinctrl/sirf/pinctrl-atlas7.c:5617: warning: Function parameter or member 'a7gc' not described in 'atlas7_gpio_to_bank' drivers/pinctrl/sirf/pinctrl-atlas7.c:5617: warning: Function parameter or member 'gpio' not described in 'atlas7_gpio_to_bank' Signed-off-by: Lee Jones Cc: Barry Song Link: https://lore.kernel.org/r/20200713144930.1034632-3-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/sirf/pinctrl-atlas7.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c index 50df9e084414..e54a6e3cafd2 100644 --- a/drivers/pinctrl/sirf/pinctrl-atlas7.c +++ b/drivers/pinctrl/sirf/pinctrl-atlas7.c @@ -169,7 +169,7 @@ struct dt_params { /** * struct atlas7_pad_conf - Atlas7 Pad Configuration - * @id The ID of this Pad. + * @id: The ID of this Pad. * @type: The type of this Pad. * @mux_reg: The mux register offset. * This register contains the mux. @@ -210,7 +210,7 @@ struct atlas7_pad_config { .ad_ctrl_bit = adb, \ } -/** +/* * struct atlas7_pad_status - Atlas7 Pad status */ struct atlas7_pad_status { @@ -355,10 +355,6 @@ struct atlas7_gpio_chip { struct atlas7_gpio_bank banks[]; }; -/** - * @dev: a pointer back to containing device - * @virtbase: the offset to the controller in virtual memory - */ struct atlas7_pmx { struct device *dev; struct pinctrl_dev *pctl; @@ -376,7 +372,7 @@ struct atlas7_pmx { * refer to A7DA IO Summary - CS-314158-DD-4E.xls */ -/*Pads in IOC RTC & TOP */ +/* Pads in IOC RTC & TOP */ static const struct pinctrl_pin_desc atlas7_ioc_pads[] = { /* RTC PADs */ PINCTRL_PIN(0, "rtc_gpio_0"), @@ -4781,10 +4777,10 @@ struct map_data { /** * struct atlas7_pull_info - Atlas7 Pad pull info - * @type:The type of this Pad. - * @mask:The mas value of this pin's pull bits. - * @v2s: The map of pull register value to pull status. - * @s2v: The map of pull status to pull register value. + * @pad_type: The type of this Pad. + * @mask: The mas value of this pin's pull bits. + * @v2s: The map of pull register value to pull status. + * @s2v: The map of pull status to pull register value. */ struct atlas7_pull_info { u8 pad_type; @@ -4908,6 +4904,7 @@ static const struct atlas7_ds_ma_info atlas7_ma2ds_map[] = { * @type: The type of this Pad. * @mask: The mask value of this pin's pull bits. * @imval: The immediate value of drives trength register. + * @reserved: Reserved space */ struct atlas7_ds_info { u8 type; @@ -5609,7 +5606,7 @@ static int __init atlas7_pinmux_init(void) arch_initcall(atlas7_pinmux_init); -/** +/* * The Following is GPIO Code */ static inline struct From 1294754e1c1f72809e1bf9a6ecd209f472c5adb7 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:08 +0100 Subject: [PATCH 171/242] pinctrl: bcm: pinctrl-bcm281xx: Demote obvious misuse of kerneldoc to standard comment blocks There has been little to no attempt to document any of the demoted structures here. These are obviously not kerneldoc headers. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/bcm/pinctrl-bcm281xx.c:65: warning: cannot understand function prototype: 'enum bcm281xx_pin_type ' drivers/pinctrl/bcm/pinctrl-bcm281xx.c:79: warning: cannot understand function prototype: 'struct bcm281xx_pin_function ' drivers/pinctrl/bcm/pinctrl-bcm281xx.c:89: warning: cannot understand function prototype: 'struct bcm281xx_pinctrl_data ' Signed-off-by: Lee Jones Acked-by: Scott Branden Cc: Florian Fainelli Cc: Ray Jui Cc: Scott Branden Cc: bcm-kernel-feedback-list@broadcom.com Cc: YueHaibing Link: https://lore.kernel.org/r/20200713144930.1034632-4-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm281xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c index 71e666178300..9ab1f427286a 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm281xx.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm281xx.c @@ -59,7 +59,7 @@ #define BCM281XX_HDMI_PIN_REG_MODE_MASK 0x0010 #define BCM281XX_HDMI_PIN_REG_MODE_SHIFT 4 -/** +/* * bcm281xx_pin_type - types of pin register */ enum bcm281xx_pin_type { @@ -73,7 +73,7 @@ static enum bcm281xx_pin_type std_pin = BCM281XX_PIN_TYPE_STD; static enum bcm281xx_pin_type i2c_pin = BCM281XX_PIN_TYPE_I2C; static enum bcm281xx_pin_type hdmi_pin = BCM281XX_PIN_TYPE_HDMI; -/** +/* * bcm281xx_pin_function- define pin function */ struct bcm281xx_pin_function { @@ -82,7 +82,7 @@ struct bcm281xx_pin_function { const unsigned ngroups; }; -/** +/* * bcm281xx_pinctrl_data - Broadcom-specific pinctrl data * @reg_base - base of pinctrl registers */ From 2dd2dbc527ff9a505a020a154d309a691668abc5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:09 +0100 Subject: [PATCH 172/242] pinctrl: bcm: pinctrl-iproc-gpio: Rename incorrectly documented function param Fixes the following W=1 kernel build warning(s): drivers/pinctrl/bcm/pinctrl-iproc-gpio.c:141: warning: Function parameter or member 'chip' not described in 'iproc_set_bit' drivers/pinctrl/bcm/pinctrl-iproc-gpio.c:141: warning: Excess function parameter 'iproc_gpio' description in 'iproc_set_bit' Signed-off-by: Lee Jones Acked-by: Scott Branden Cc: Ray Jui Cc: Scott Branden Cc: bcm-kernel-feedback-list@broadcom.com Link: https://lore.kernel.org/r/20200713144930.1034632-5-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c index a38f0d5f47ce..e2bd2dce6bb4 100644 --- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c @@ -131,7 +131,7 @@ static inline unsigned iproc_pin_to_gpio(unsigned pin) * iproc_set_bit - set or clear one bit (corresponding to the GPIO pin) in a * Iproc GPIO register * - * @iproc_gpio: Iproc GPIO device + * @chip: Iproc GPIO device * @reg: register offset * @gpio: GPIO pin * @set: set or clear From 0b33c72a19bdaf5a6a2ea78556d6be47bce2bc95 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:10 +0100 Subject: [PATCH 173/242] pinctrl: qcom: pinctrl-msm: Complete 'struct msm_pinctrl' documentation Add missing descriptions for attributes and fix 1 formatting issue. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/qcom/pinctrl-msm.c:75: warning: Function parameter or member 'desc' not described in 'msm_pinctrl' drivers/pinctrl/qcom/pinctrl-msm.c:75: warning: Function parameter or member 'irq_chip' not described in 'msm_pinctrl' drivers/pinctrl/qcom/pinctrl-msm.c:75: warning: Function parameter or member 'intr_target_use_scm' not described in 'msm_pinctrl' drivers/pinctrl/qcom/pinctrl-msm.c:75: warning: Function parameter or member 'soc' not described in 'msm_pinctrl' drivers/pinctrl/qcom/pinctrl-msm.c:75: warning: Function parameter or member 'phys_base' not described in 'msm_pinctrl' Signed-off-by: Lee Jones Cc: Bjorn Andersson Cc: Andy Gross Cc: linux-arm-msm@vger.kernel.org Link: https://lore.kernel.org/r/20200713144930.1034632-6-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index dac0404dadf4..0269a5b1fa10 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -40,16 +40,20 @@ * @dev: device handle. * @pctrl: pinctrl handle. * @chip: gpiochip handle. + * @desc: pin controller descriptor * @restart_nb: restart notifier block. + * @irq_chip: irq chip information * @irq: parent irq for the TLMM irq_chip. + * @intr_target_use_scm: route irq to application cpu using scm calls * @lock: Spinlock to protect register resources as well * as msm_pinctrl data structures. * @enabled_irqs: Bitmap of currently enabled irqs. * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge * detection. * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller - * @soc; Reference to soc_data of platform specific data. + * @soc: Reference to soc_data of platform specific data. * @regs: Base addresses for the TLMM tiles. + * @phys_base: Physical base address */ struct msm_pinctrl { struct device *dev; From 84a3fce5e914742e7f243bffdbbc90055c737ef7 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:11 +0100 Subject: [PATCH 174/242] pinctrl: samsung: pinctrl-samsung: Demote obvious misuse of kerneldoc to standard comment blocks No attempt has been made to document either of the demoted functions here. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/samsung/pinctrl-samsung.c:1149: warning: Function parameter or member 'dev' not described in 'samsung_pinctrl_suspend' drivers/pinctrl/samsung/pinctrl-samsung.c:1199: warning: Function parameter or member 'dev' not described in 'samsung_pinctrl_resume' Signed-off-by: Lee Jones Cc: Tomasz Figa Cc: Krzysztof Kozlowski Cc: Sylwester Nawrocki Cc: Thomas Abraham Cc: linux-samsung-soc@vger.kernel.org Link: https://lore.kernel.org/r/20200713144930.1034632-7-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/samsung/pinctrl-samsung.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index f26574ef234a..608eb5a07248 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1140,7 +1140,7 @@ static int samsung_pinctrl_probe(struct platform_device *pdev) return 0; } -/** +/* * samsung_pinctrl_suspend - save pinctrl state for suspend * * Save data for all banks handled by this device. @@ -1187,7 +1187,7 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev) return 0; } -/** +/* * samsung_pinctrl_resume - restore pinctrl state from suspend * * Restore one of the banks that was saved during suspend. From 26b72162e10b51e2b2be04ea7ea58f91a782dfc5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:12 +0100 Subject: [PATCH 175/242] pinctrl: samsung: pinctrl-s3c24xx: Fix formatting issues Kerneldoc struct titles must be followed by whitespace. Also attributes need to be in the format '@.*: ' else the checker gets confused. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/samsung/pinctrl-s3c24xx.c:100: warning: cannot understand function prototype: 'struct s3c24xx_eint_domain_data ' Signed-off-by: Lee Jones Reviewed-by: Heiko Stuebner Cc: Kukjin Kim Cc: Krzysztof Kozlowski Cc: Tomasz Figa Cc: Sylwester Nawrocki Cc: Heiko Stuebner Cc: linux-samsung-soc@vger.kernel.org Link: https://lore.kernel.org/r/20200713144930.1034632-8-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c index 9bd0a3de101d..5e24838a582f 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -80,7 +80,7 @@ static const struct samsung_pin_bank_type bank_type_2bit = { } /** - * struct s3c24xx_eint_data: EINT common data + * struct s3c24xx_eint_data - EINT common data * @drvdata: pin controller driver data * @domains: IRQ domains of particular EINT interrupts * @parents: mapped parent irqs in the main interrupt controller @@ -92,10 +92,10 @@ struct s3c24xx_eint_data { }; /** - * struct s3c24xx_eint_domain_data: per irq-domain data + * struct s3c24xx_eint_domain_data - per irq-domain data * @bank: pin bank related to the domain * @eint_data: common data - * eint0_3_parent_only: live eints 0-3 only in the main intc + * @eint0_3_parent_only: live eints 0-3 only in the main intc */ struct s3c24xx_eint_domain_data { struct samsung_pin_bank *bank; From 0dc0bdf069784704c6bc798d9f7ed1bafe221c7a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:13 +0100 Subject: [PATCH 176/242] pinctrl: samsung: pinctrl-s3c64xx: Fix formatting issues Kerneldoc struct titles must be followed by whitespace else the checker gets confused. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/samsung/pinctrl-s3c64xx.c:212: warning: cannot understand function prototype: 'struct s3c64xx_eint0_domain_data ' Signed-off-by: Lee Jones Cc: Tomasz Figa Cc: Krzysztof Kozlowski Cc: Sylwester Nawrocki Cc: linux-samsung-soc@vger.kernel.org Link: https://lore.kernel.org/r/20200713144930.1034632-9-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c index f97f8179f2b1..b8166e3fe4ce 100644 --- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -193,7 +193,7 @@ static const struct samsung_pin_bank_type bank_type_2bit_alive = { } /** - * struct s3c64xx_eint0_data: EINT0 common data + * struct s3c64xx_eint0_data - EINT0 common data * @drvdata: pin controller driver data * @domains: IRQ domains of particular EINT0 interrupts * @pins: pin offsets inside of banks of particular EINT0 interrupts @@ -205,7 +205,7 @@ struct s3c64xx_eint0_data { }; /** - * struct s3c64xx_eint0_domain_data: EINT0 per-domain data + * struct s3c64xx_eint0_domain_data - EINT0 per-domain data * @bank: pin bank related to the domain * @eints: EINT0 interrupts related to the domain */ @@ -215,7 +215,7 @@ struct s3c64xx_eint0_domain_data { }; /** - * struct s3c64xx_eint_gpio_data: GPIO EINT data + * struct s3c64xx_eint_gpio_data - GPIO EINT data * @drvdata: pin controller driver data * @domains: array of domains related to EINT interrupt groups */ From cba053ff5e81a1dd04a7013bb95fe2e4c28e4f74 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:14 +0100 Subject: [PATCH 177/242] pinctrl: qcom: pinctrl-msm8976: Remove unused variable 'nav_tsync_groups' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/pinctrl/qcom/pinctrl-msm8976.c:802:27: warning: ‘nav_tsync_groups’ defined but not used [-Wunused-const-variable=] 802 | static const char const nav_tsync_groups[] = { | ^~~~~~~~~~~~~~~~ Signed-off-by: Lee Jones Cc: Andy Gross Cc: Bjorn Andersson Cc: Del Regno Cc: linux-arm-msm@vger.kernel.org Link: https://lore.kernel.org/r/20200713144930.1034632-10-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-msm8976.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-msm8976.c b/drivers/pinctrl/qcom/pinctrl-msm8976.c index 183f0b2d9f8e..ec43edf9b660 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8976.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8976.c @@ -799,9 +799,6 @@ static const char * const pa_indicator_groups[] = { static const char * const modem_tsync_groups[] = { "gpio93", }; -static const char * const nav_tsync_groups[] = { - "gpio93", -}; static const char * const ssbi_wtr1_groups[] = { "gpio79", "gpio94", }; From ea0b879b5d6e9af2e7b60ff62fc5c985d43fc920 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:15 +0100 Subject: [PATCH 178/242] pinctrl: mediatek: pinctrl-mtk-common-v2: Mark 'mtk_default_register_base_names' as __maybe_unused MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not all sourcefiles which end up including pinctrl-mtk-common-v2.h make use of 'mtk_default_register_base_names' and there is nowhere we can place the definition to void the need for __maybe_unused except its own headerfile, which seems like overkill. So instead we tell the compiler that it's okay for it to be unused by some of the consumers. Fixes the following W=1 kernel build warning(s): In file included from drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c:19: drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h:83:27: warning: ‘mtk_default_register_base_names’ defined but not used [-Wunused-const-variable=] 83 | static const char const mtk_default_register_base_names[] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/pinctrl/mediatek/pinctrl-moore.h:25, from drivers/pinctrl/mediatek/pinctrl-moore.c:12: drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h:83:27: warning: ‘mtk_default_register_base_names’ defined but not used [-Wunused-const-variable=] 83 | static const char const mtk_default_register_base_names[] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/pinctrl/mediatek/pinctrl-paris.h:27, from drivers/pinctrl/mediatek/pinctrl-paris.c:15: drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h:83:27: warning: ‘mtk_default_register_base_names’ defined but not used [-Wunused-const-variable=] 83 | static const char const mtk_default_register_base_names[] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/pinctrl/mediatek/pinctrl-paris.h:27, from drivers/pinctrl/mediatek/pinctrl-mtk-mt6797.h:15, from drivers/pinctrl/mediatek/pinctrl-mt6797.c:13: drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h:83:27: warning: ‘mtk_default_register_base_names’ defined but not used [-Wunused-const-variable=] 83 | static const char const mtk_default_register_base_names[] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/pinctrl/mediatek/pinctrl-paris.h:27, from drivers/pinctrl/mediatek/pinctrl-mtk-mt8183.h:12, from drivers/pinctrl/mediatek/pinctrl-mt8183.c:9: drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h:83:27: warning: ‘mtk_default_register_base_names’ defined but not used [-Wunused-const-variable=] 83 | static const char const mtk_default_register_base_names[] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/pinctrl/mediatek/pinctrl-paris.h:27, from drivers/pinctrl/mediatek/pinctrl-mtk-mt6765.h:12, from drivers/pinctrl/mediatek/pinctrl-mt6765.c:10: drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h:83:27: warning: ‘mtk_default_register_base_names’ defined but not used [-Wunused-const-variable=] 83 | static const char const mtk_default_register_base_names[] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Lee Jones Acked-by: Sean Wang Cc: Sean Wang Cc: Matthias Brugger Cc: linux-mediatek@lists.infradead.org Link: https://lore.kernel.org/r/20200713144930.1034632-11-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 27df08736396..45aa0fdbe330 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -80,7 +80,7 @@ enum { DRV_GRP_MAX, }; -static const char * const mtk_default_register_base_names[] = { +static const char * const mtk_default_register_base_names[] __maybe_unused = { "base", }; From 9c340bbbf7203ebaa7286eb2cd3b21b5e142ed3b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:16 +0100 Subject: [PATCH 179/242] pinctrl: core: Fix a bunch of kerneldoc issues Most are likely due to bitrot/API slip. Some are formatting issues. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/core.c:167: warning: Function parameter or member 'pin' not described in 'pin_get_name' drivers/pinctrl/core.c:167: warning: Excess function parameter 'name' description in 'pin_get_name' drivers/pinctrl/core.c:584: warning: Function parameter or member 'selector' not described in 'pinctrl_generic_get_group' drivers/pinctrl/core.c:584: warning: Excess function parameter 'gselector' description in 'pinctrl_generic_get_group' drivers/pinctrl/core.c:1356: error: Cannot parse struct or union! drivers/pinctrl/core.c:1458: warning: Function parameter or member 'map' not described in 'pinctrl_unregister_mappings' drivers/pinctrl/core.c:1458: warning: Excess function parameter 'maps' description in 'pinctrl_unregister_mappings' drivers/pinctrl/core.c:2239: warning: Function parameter or member 'pctldev' not described in 'devm_pinctrl_register_and_init' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200713144930.1034632-12-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 821242bb4b16..3e8d1630d29e 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -161,7 +161,7 @@ int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) /** * pin_get_name_from_id() - look up a pin name from a pin id * @pctldev: the pin control device to lookup the pin on - * @name: the name of the pin to look up + * @pin: pin number/id to look up */ const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin) { @@ -577,7 +577,7 @@ EXPORT_SYMBOL_GPL(pinctrl_generic_get_group_pins); /** * pinctrl_generic_get_group() - returns a pin group based on the number * @pctldev: pin controller device - * @gselector: group number + * @selector: group number */ struct group_desc *pinctrl_generic_get_group(struct pinctrl_dev *pctldev, unsigned int selector) @@ -1329,7 +1329,7 @@ static void devm_pinctrl_release(struct device *dev, void *res) } /** - * struct devm_pinctrl_get() - Resource managed pinctrl_get() + * devm_pinctrl_get() - Resource managed pinctrl_get() * @dev: the device to obtain the handle for * * If there is a need to explicitly destroy the returned struct pinctrl, @@ -1451,7 +1451,7 @@ EXPORT_SYMBOL_GPL(pinctrl_register_mappings); /** * pinctrl_unregister_mappings() - unregister a set of pin controller mappings - * @maps: the pincontrol mappings table passed to pinctrl_register_mappings() + * @map: the pincontrol mappings table passed to pinctrl_register_mappings() * when registering the mappings. */ void pinctrl_unregister_mappings(const struct pinctrl_map *map) @@ -2226,9 +2226,9 @@ EXPORT_SYMBOL_GPL(devm_pinctrl_register); * @dev: parent device for this pin controller * @pctldesc: descriptor for this pin controller * @driver_data: private pin controller data for this pin controller + * @pctldev: pin controller device * - * Returns an error pointer if pincontrol register failed. Otherwise - * it returns valid pinctrl handle. + * Returns zero on success or an error number on failure. * * The pinctrl device will be automatically released when the device is unbound. */ From d340351f8168d29e80f0b61aebb06618db8d2031 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:17 +0100 Subject: [PATCH 180/242] pinctrl: pinmux: Add some missing parameter descriptions And rename another which has probably bitrotted. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinmux.c:83: warning: Function parameter or member 'pctldev' not described in 'pinmux_can_be_used_for_gpio' drivers/pinctrl/pinmux.c:108: warning: Function parameter or member 'pctldev' not described in 'pin_request' drivers/pinctrl/pinmux.c:261: warning: Function parameter or member 'gpio' not described in 'pinmux_request_gpio' drivers/pinctrl/pinmux.c:751: warning: Function parameter or member 'selector' not described in 'pinmux_generic_get_function' drivers/pinctrl/pinmux.c:751: warning: Excess function parameter 'group_selector' description in 'pinmux_generic_get_function' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200713144930.1034632-13-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 9503ddf2edc7..bab888fe3f8e 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -74,6 +74,7 @@ int pinmux_validate_map(const struct pinctrl_map *map, int i) * pinmux_can_be_used_for_gpio() - check if a specific pin * is either muxed to a different function or used as gpio. * + * @pctldev: the associated pin controller device * @pin: the pin number in the global pin space * * Controllers not defined as strict will always return true, @@ -96,6 +97,7 @@ bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned pin) /** * pin_request() - request a single pin to be muxed in, typically for GPIO + * @pctldev: the associated pin controller device * @pin: the pin number in the global pin space * @owner: a representation of the owner of this pin; typically the device * name that controls its mux function, or the requested GPIO name @@ -254,6 +256,7 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, * @pctldev: pin controller device affected * @pin: the pin to mux in for GPIO * @range: the applicable GPIO range + * @gpio: number of requested GPIO */ int pinmux_request_gpio(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, @@ -744,7 +747,7 @@ EXPORT_SYMBOL_GPL(pinmux_generic_get_function_groups); /** * pinmux_generic_get_function() - returns a function based on the number * @pctldev: pin controller device - * @group_selector: function number + * @selector: function number */ struct function_desc *pinmux_generic_get_function(struct pinctrl_dev *pctldev, unsigned int selector) From 0b93a57a6a144d2152dbb1042143c1b9833eed9c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:18 +0100 Subject: [PATCH 181/242] pinctrl: devicetree: Add one new attribute description and rename another two Fixes the following W=1 kernel build warning(s): drivers/pinctrl/devicetree.c:27: warning: Function parameter or member 'map' not described in 'pinctrl_dt_map' drivers/pinctrl/devicetree.c:27: warning: Function parameter or member 'num_maps' not described in 'pinctrl_dt_map' drivers/pinctrl/devicetree.c:409: warning: Function parameter or member 'out_args' not described in 'pinctrl_parse_index_with_args' drivers/pinctrl/devicetree.c:409: warning: Excess function parameter 'out_arts' description in 'pinctrl_parse_index_with_args' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200713144930.1034632-14-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/devicetree.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index c6fe7d64c913..5eff8c296552 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -17,7 +17,8 @@ * struct pinctrl_dt_map - mapping table chunk parsed from device tree * @node: list node for struct pinctrl's @dt_maps field * @pctldev: the pin controller that allocated this struct, and will free it - * @maps: the mapping table entries + * @map: the mapping table entries + * @num_maps: number of mapping table entries */ struct pinctrl_dt_map { struct list_head node; @@ -397,7 +398,7 @@ static int pinctrl_copy_args(const struct device_node *np, * @np: pointer to device node with the property * @list_name: property that contains the list * @index: index within the list - * @out_arts: entries in the list pointed by index + * @out_args: entries in the list pointed by index * * Finds the selected element in a pinctrl array consisting of an index * within the controller and a number of u32 entries specified for each From b4dab7743e65e96faf878c46858c19b8b77d5d50 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:19 +0100 Subject: [PATCH 182/242] pinctrl: pinconf-generic: Add function parameter description 'pctldev' Fix a spelling/typo while we're here. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinconf-generic.c:242: warning: Function parameter or member 'pctldev' not described in 'pinconf_generic_parse_dt_config' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200713144930.1034632-15-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf-generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index dfef471201f6..1e225d513988 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -231,9 +231,10 @@ static void parse_dt_cfg(struct device_node *np, * pinconf_generic_parse_dt_config() * parse the config properties into generic pinconfig values. * @np: node containing the pinconfig properties + * @pctldev: pincontrol device * @configs: array with nconfigs entries containing the generic pinconf values * must be freed when no longer necessary. - * @nconfigs: umber of configurations + * @nconfigs: number of configurations */ int pinconf_generic_parse_dt_config(struct device_node *np, struct pinctrl_dev *pctldev, From 898503ee0b9b27c214ad0e584a1fcfec24e71ef0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:20 +0100 Subject: [PATCH 183/242] pinctrl: pinctrl-at91-pio4: PM related attribute descriptions Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinctrl-at91-pio4.c:132: warning: Function parameter or member 'pm_wakeup_sources' not described in 'atmel_pioctrl' drivers/pinctrl/pinctrl-at91-pio4.c:132: warning: Function parameter or member 'pm_suspend_backup' not described in 'atmel_pioctrl' Signed-off-by: Lee Jones Cc: Ludovic Desroches Cc: Nicolas Ferre Cc: Alexandre Belloni Link: https://lore.kernel.org/r/20200713144930.1034632-16-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91-pio4.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index 54222ccddfb1..8e5a5053a47e 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -106,6 +106,8 @@ struct atmel_pin { * @irq_domain: irq domain for the gpio controller. * @irqs: table containing the hw irq number of the bank. The index of the * table is the bank id. + * @pm_wakeup_sources: bitmap of wakeup sources (lines) + * @pm_suspend_backup: backup/restore register values on suspend/resume * @dev: device entry for the Atmel PIO controller. * @node: node of the Atmel PIO controller. */ From aa78655d49b1b686ebe733d55294b287f582e315 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:22 +0100 Subject: [PATCH 184/242] pinctrl: pinctrl-at91: Demote non-kerneldoc header and complete another The documentation header for 'struct at91_pinctrl_mux_ops' was missing entries for {g,s}et_drivestrength and {g,s}et_slewrate. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinctrl-at91.c:77: warning: cannot understand function prototype: 'enum drive_strength_bit ' drivers/pinctrl/pinctrl-at91.c:187: warning: Function parameter or member 'get_drivestrength' not described in 'at91_pinctrl_mux_ops' drivers/pinctrl/pinctrl-at91.c:187: warning: Function parameter or member 'set_drivestrength' not described in 'at91_pinctrl_mux_ops' drivers/pinctrl/pinctrl-at91.c:187: warning: Function parameter or member 'get_slewrate' not described in 'at91_pinctrl_mux_ops' drivers/pinctrl/pinctrl-at91.c:187: warning: Function parameter or member 'set_slewrate' not described in 'at91_pinctrl_mux_ops' Signed-off-by: Lee Jones Cc: Ludovic Desroches Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Jean-Christophe PLAGNIOL-VILLARD Link: https://lore.kernel.org/r/20200713144930.1034632-18-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 9c5213087659..72edc675431c 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -65,7 +65,7 @@ static int gpio_banks; #define DEBOUNCE_VAL_SHIFT 17 #define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) -/** +/* * These defines will translated the dt binding settings to our internal * settings. They are not necessarily the same value as the register setting. * The actual drive strength current of low, medium and high must be looked up @@ -161,6 +161,10 @@ struct at91_pin_group { * @set_pulldown: enable/disable pulldown * @get_schmitt_trig: get schmitt trigger status * @disable_schmitt_trig: disable schmitt trigger + * @get_drivestrength: get driver strength + * @set_drivestrength: set driver strength + * @get_slewrate: get slew rate + * @set_slewrate: set slew rate * @irq_type: return irq type */ struct at91_pinctrl_mux_ops { From 21f97985003c5053f15ee27e1a3f91dc744acf30 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:23 +0100 Subject: [PATCH 185/242] pinctrl: pinctrl-bm1880: Rename ill documented struct attribute entries Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinctrl-bm1880.c:40: warning: Function parameter or member 'pctrldev' not described in 'bm1880_pinctrl' drivers/pinctrl/pinctrl-bm1880.c:40: warning: Function parameter or member 'pinconf' not described in 'bm1880_pinctrl' Signed-off-by: Lee Jones Reviewed-by: Manivannan Sadhasivam Cc: Manivannan Sadhasivam Link: https://lore.kernel.org/r/20200713144930.1034632-19-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-bm1880.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-bm1880.c b/drivers/pinctrl/pinctrl-bm1880.c index d1a7d9836787..a8e267237435 100644 --- a/drivers/pinctrl/pinctrl-bm1880.c +++ b/drivers/pinctrl/pinctrl-bm1880.c @@ -22,12 +22,12 @@ /** * struct bm1880_pinctrl - driver data * @base: Pinctrl base address - * @pctrl: Pinctrl device + * @pctrldev: Pinctrl device * @groups: Pingroups * @ngroups: Number of @groups * @funcs: Pinmux functions * @nfuncs: Number of @funcs - * @pconf: Pinconf data + * @pinconf: Pinconf data */ struct bm1880_pinctrl { void __iomem *base; From e1524ea84af7172acc20827f8dca3fc8f72b8f37 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:24 +0100 Subject: [PATCH 186/242] pinctrl: pinctrl-rockchip: Fix a bunch of kerneldoc misdemeanours Demote headers which are clearly not kerneldoc, provide titles for struct definition blocks, fix API slip (bitrot) misspellings and provide some missing entries. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinctrl-rockchip.c:82: warning: cannot understand function prototype: 'struct rockchip_iomux ' drivers/pinctrl/pinctrl-rockchip.c:97: warning: Enum value 'DRV_TYPE_IO_DEFAULT' not described in enum 'rockchip_pin_drv_type' drivers/pinctrl/pinctrl-rockchip.c:97: warning: Enum value 'DRV_TYPE_IO_1V8_OR_3V0' not described in enum 'rockchip_pin_drv_type' drivers/pinctrl/pinctrl-rockchip.c:97: warning: Enum value 'DRV_TYPE_IO_1V8_ONLY' not described in enum 'rockchip_pin_drv_type' drivers/pinctrl/pinctrl-rockchip.c:97: warning: Enum value 'DRV_TYPE_IO_1V8_3V0_AUTO' not described in enum 'rockchip_pin_drv_type' drivers/pinctrl/pinctrl-rockchip.c:97: warning: Enum value 'DRV_TYPE_IO_3V3_ONLY' not described in enum 'rockchip_pin_drv_type' drivers/pinctrl/pinctrl-rockchip.c:97: warning: Enum value 'DRV_TYPE_MAX' not described in enum 'rockchip_pin_drv_type' drivers/pinctrl/pinctrl-rockchip.c:106: warning: Enum value 'PULL_TYPE_IO_DEFAULT' not described in enum 'rockchip_pin_pull_type' drivers/pinctrl/pinctrl-rockchip.c:106: warning: Enum value 'PULL_TYPE_IO_1V8_ONLY' not described in enum 'rockchip_pin_pull_type' drivers/pinctrl/pinctrl-rockchip.c:106: warning: Enum value 'PULL_TYPE_MAX' not described in enum 'rockchip_pin_pull_type' drivers/pinctrl/pinctrl-rockchip.c:109: warning: Cannot understand * @drv_type: drive strength variant using rockchip_perpin_drv_type on line 109 - I thought it was a doc line drivers/pinctrl/pinctrl-rockchip.c:122: warning: Cannot understand * @reg_base: register base of the gpio bank on line 109 - I thought it was a doc line drivers/pinctrl/pinctrl-rockchip.c:325: warning: Function parameter or member 'route_location' not described in 'rockchip_mux_route_data' drivers/pinctrl/pinctrl-rockchip.c:328: warning: Cannot understand */ on line 109 - I thought it was a doc line drivers/pinctrl/pinctrl-rockchip.c:375: warning: Function parameter or member 'data' not described in 'rockchip_pin_group' drivers/pinctrl/pinctrl-rockchip.c:387: warning: Function parameter or member 'ngroups' not described in 'rockchip_pmx_func' Signed-off-by: Lee Jones Reviewed-by: Heiko Stuebner Cc: Heiko Stuebner Cc: Jean-Christophe PLAGNIOL-VILLARD Cc: linux-rockchip@lists.infradead.org Link: https://lore.kernel.org/r/20200713144930.1034632-20-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index c07324d1f265..c96d810635ad 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -63,7 +63,7 @@ enum rockchip_pinctrl_type { RK3399, }; -/** +/* * Encode variants of iomux registers into a type variable */ #define IOMUX_GPIO_ONLY BIT(0) @@ -74,6 +74,7 @@ enum rockchip_pinctrl_type { #define IOMUX_WIDTH_2BIT BIT(5) /** + * struct rockchip_iomux * @type: iomux variant using IOMUX_* constants * @offset: if initialized to -1 it will be autocalculated, by specifying * an initial offset value the relevant source offset can be reset @@ -84,7 +85,7 @@ struct rockchip_iomux { int offset; }; -/** +/* * enum type index corresponding to rockchip_perpin_drv_list arrays index. */ enum rockchip_pin_drv_type { @@ -96,7 +97,7 @@ enum rockchip_pin_drv_type { DRV_TYPE_MAX }; -/** +/* * enum type index corresponding to rockchip_pull_list arrays index. */ enum rockchip_pin_pull_type { @@ -106,6 +107,7 @@ enum rockchip_pin_pull_type { }; /** + * struct rockchip_drv * @drv_type: drive strength variant using rockchip_perpin_drv_type * @offset: if initialized to -1 it will be autocalculated, by specifying * an initial offset value the relevant source offset can be reset @@ -119,8 +121,9 @@ struct rockchip_drv { }; /** + * struct rockchip_pin_bank * @reg_base: register base of the gpio bank - * @reg_pull: optional separate register for additional pull settings + * @regmap_pull: optional separate register for additional pull settings * @clk: clock of the gpio bank * @irq: interrupt of the gpio bank * @saved_masks: Saved content of GPIO_INTEN at suspend time. @@ -138,6 +141,8 @@ struct rockchip_drv { * @gpio_chip: gpiolib chip * @grange: gpio range * @slock: spinlock for the gpio bank + * @toggle_edge_mode: bit mask to toggle (falling/rising) edge mode + * @recalced_mask: bit mask to indicate a need to recalulate the mask * @route_mask: bits describing the routing pins of per bank */ struct rockchip_pin_bank { @@ -312,6 +317,7 @@ enum rockchip_mux_route_location { * @bank_num: bank number. * @pin: index at register or used to calc index. * @func: the min pin. + * @route_location: the mux route location (same, pmu, grf). * @route_offset: the max pin. * @route_val: the register offset. */ @@ -324,8 +330,6 @@ struct rockchip_mux_route_data { u32 route_val; }; -/** - */ struct rockchip_pin_ctrl { struct rockchip_pin_bank *pin_banks; u32 nr_banks; @@ -363,9 +367,7 @@ struct rockchip_pin_config { * @name: name of the pin group, used to lookup the group. * @pins: the pins included in this group. * @npins: number of pins included in this group. - * @func: the mux function number to be programmed when selected. - * @configs: the config values to be set for each pin - * @nconfigs: number of configs for each pin + * @data: local pin configuration */ struct rockchip_pin_group { const char *name; @@ -378,7 +380,7 @@ struct rockchip_pin_group { * struct rockchip_pmx_func: represent a pin function. * @name: name of the pin function, used to lookup the function. * @groups: one or more names of pin groups that provide this function. - * @num_groups: number of groups included in @groups. + * @ngroups: number of groups included in @groups. */ struct rockchip_pmx_func { const char *name; From 0ba5ab002b9eb0de507ef9e38be304b77576860b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:26 +0100 Subject: [PATCH 187/242] pinctrl: pinctrl-single: Fix struct/function documentation blocks Add some missing attributes/parameter descriptions, remove other superfluous ones, add struct header titles and fix misspellings. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinctrl-single.c:50: warning: Function parameter or member 'mask' not described in 'pcs_func_vals' drivers/pinctrl/pinctrl-single.c:97: warning: Function parameter or member 'conf' not described in 'pcs_function' drivers/pinctrl/pinctrl-single.c:97: warning: Function parameter or member 'nconfs' not described in 'pcs_function' drivers/pinctrl/pinctrl-single.c:659: warning: Function parameter or member 'pin_pos' not described in 'pcs_add_pin' drivers/pinctrl/pinctrl-single.c:985: warning: Excess function parameter 'pctldev' description in 'pcs_parse_one_pinctrl_entry' drivers/pinctrl/pinctrl-single.c:1357: warning: Cannot understand * @reg: virtual address of interrupt register drivers/pinctrl/pinctrl-single.c:1377: warning: Function parameter or member 'pcs_soc' not described in 'pcs_irq_set' drivers/pinctrl/pinctrl-single.c:1377: warning: Function parameter or member 'irq' not described in 'pcs_irq_set' drivers/pinctrl/pinctrl-single.c:1377: warning: Function parameter or member 'enable' not described in 'pcs_irq_set' drivers/pinctrl/pinctrl-single.c:1458: warning: Function parameter or member 'pcs_soc' not described in 'pcs_irq_handle' drivers/pinctrl/pinctrl-single.c:1458: warning: Excess function parameter 'pcs_irq' description in 'pcs_irq_handle' drivers/pinctrl/pinctrl-single.c:1506: warning: Excess function parameter 'irq' description in 'pcs_irq_chain_handler' Signed-off-by: Lee Jones Acked-by: Tony Lindgren Cc: Tony Lindgren Cc: Haojian Zhuang Cc: linux-omap@vger.kernel.org Link: https://lore.kernel.org/r/20200713144930.1034632-22-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index e6d1cf25782c..542578d0bda2 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -42,6 +42,7 @@ * struct pcs_func_vals - mux function register offset and value pair * @reg: register virtual address * @val: register value + * @mask: mask */ struct pcs_func_vals { void __iomem *reg; @@ -83,6 +84,8 @@ struct pcs_conf_type { * @nvals: number of entries in vals array * @pgnames: array of pingroup names the function uses * @npgnames: number of pingroup names the function uses + * @conf: array of pin configurations + * @nconfs: number of pin configurations available * @node: list node */ struct pcs_function { @@ -653,6 +656,7 @@ static const struct pinconf_ops pcs_pinconf_ops = { * pcs_add_pin() - add a pin to the static per controller pin array * @pcs: pcs driver instance * @offset: register offset from base + * @pin_pos: unused */ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, unsigned pin_pos) @@ -959,7 +963,6 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, /** * pcs_parse_one_pinctrl_entry() - parses a device tree mux entry - * @pctldev: pin controller device * @pcs: pinctrl driver instance * @np: device node of the mux entry * @map: map entry @@ -1353,7 +1356,9 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) } return ret; } + /** + * struct pcs_interrupt * @reg: virtual address of interrupt register * @hwirq: hardware irq number * @irq: virtual irq number @@ -1368,6 +1373,9 @@ struct pcs_interrupt { /** * pcs_irq_set() - enables or disables an interrupt + * @pcs_soc: SoC specific settings + * @irq: interrupt + * @enable: enable or disable the interrupt * * Note that this currently assumes one interrupt per pinctrl * register that is typically used for wake-up events. @@ -1448,7 +1456,7 @@ static int pcs_irq_set_wake(struct irq_data *d, unsigned int state) /** * pcs_irq_handle() - common interrupt handler - * @pcs_irq: interrupt data + * @pcs_soc: SoC specific settings * * Note that this currently assumes we have one interrupt bit per * mux register. This interrupt is typically used for wake-up events. @@ -1496,7 +1504,6 @@ static irqreturn_t pcs_irq_handler(int irq, void *d) /** * pcs_irq_handle() - handler for the dedicated chained interrupt case - * @irq: interrupt * @desc: interrupt descriptor * * Use this if you have a separate interrupt for each From 92cadf68e50a5641356fe9dcbc486ae23168b568 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:27 +0100 Subject: [PATCH 188/242] pinctrl: tegra: pinctrl-tegra194: Do not initialise field twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both PIN_PINGROUP_ENTRY_Y() and DRV_PINGROUP_ENTRY_Y() macros are called for each of the 2 pin groups defined here, and both of them initialise 'drv_reg', causing the compiler to complain. Only initialise 'drv_reg' once. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/tegra/pinctrl-tegra194.c:71:14: warning: initialized field overwritten [-Woverride-init] 71 | .drv_reg = ((r)), | ^ drivers/pinctrl/tegra/pinctrl-tegra194.c:105:2: note: in expansion of macro ‘DRV_PINGROUP_ENTRY_Y’ 105 | DRV_PINGROUP_ENTRY_Y(0x14004, 12, 5, 20, 5, -1, -1, -1, -1, 0) | ^~~~~~~~~~~~~~~~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:124:3: note: in expansion of macro ‘drive_pex_l5_clkreq_n_pgg0’ 124 | drive_##pg_name, | ^~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:128:2: note: in expansion of macro ‘PINGROUP’ 128 | PINGROUP(pex_l5_clkreq_n_pgg0, PE5, RSVD1, RSVD2, RSVD3, 0x14000, 0, | ^~~~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:71:14: note: (near initialization for ‘tegra194_groups[0].drv_reg’) 71 | .drv_reg = ((r)), | ^ drivers/pinctrl/tegra/pinctrl-tegra194.c:105:2: note: in expansion of macro ‘DRV_PINGROUP_ENTRY_Y’ 105 | DRV_PINGROUP_ENTRY_Y(0x14004, 12, 5, 20, 5, -1, -1, -1, -1, 0) | ^~~~~~~~~~~~~~~~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:124:3: note: in expansion of macro ‘drive_pex_l5_clkreq_n_pgg0’ 124 | drive_##pg_name, | ^~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:128:2: note: in expansion of macro ‘PINGROUP’ 128 | PINGROUP(pex_l5_clkreq_n_pgg0, PE5, RSVD1, RSVD2, RSVD3, 0x14000, 0, | ^~~~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:71:14: warning: initialized field overwritten [-Woverride-init] 71 | .drv_reg = ((r)), | ^ drivers/pinctrl/tegra/pinctrl-tegra194.c:107:2: note: in expansion of macro ‘DRV_PINGROUP_ENTRY_Y’ 107 | DRV_PINGROUP_ENTRY_Y(0x1400c, 12, 5, 20, 5, -1, -1, -1, -1, 0) | ^~~~~~~~~~~~~~~~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:124:3: note: in expansion of macro ‘drive_pex_l5_rst_n_pgg1’ 124 | drive_##pg_name, | ^~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:130:2: note: in expansion of macro ‘PINGROUP’ 130 | PINGROUP(pex_l5_rst_n_pgg1, PE5, RSVD1, RSVD2, RSVD3, 0x14008, 0, | ^~~~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:71:14: note: (near initialization for ‘tegra194_groups[1].drv_reg’) 71 | .drv_reg = ((r)), | ^ drivers/pinctrl/tegra/pinctrl-tegra194.c:107:2: note: in expansion of macro ‘DRV_PINGROUP_ENTRY_Y’ 107 | DRV_PINGROUP_ENTRY_Y(0x1400c, 12, 5, 20, 5, -1, -1, -1, -1, 0) | ^~~~~~~~~~~~~~~~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:124:3: note: in expansion of macro ‘drive_pex_l5_rst_n_pgg1’ 124 | drive_##pg_name, | ^~~~~~ drivers/pinctrl/tegra/pinctrl-tegra194.c:130:2: note: in expansion of macro ‘PINGROUP’ 130 | PINGROUP(pex_l5_rst_n_pgg1, PE5, RSVD1, RSVD2, RSVD3, 0x14008, 0, | ^~~~~~~~ Signed-off-by: Lee Jones Acked-by: Thierry Reding Cc: Thierry Reding Cc: Jonathan Hunter Cc: linux-tegra@vger.kernel.org Link: https://lore.kernel.org/r/20200713144930.1034632-23-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/tegra/pinctrl-tegra194.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/tegra/pinctrl-tegra194.c b/drivers/pinctrl/tegra/pinctrl-tegra194.c index 2e0b5f7bb095..c94ba17243c8 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra194.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra194.c @@ -98,7 +98,6 @@ static struct tegra_function tegra194_functions[] = { .sfsel_bit = 10, \ .schmitt_bit = schmitt_b, \ .drvtype_bit = 13, \ - .drv_reg = -1, \ .parked_bitmask = 0 #define drive_pex_l5_clkreq_n_pgg0 \ From fb5dd4297d0c7b2d09701defb02795ab3f0a57bf Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:28 +0100 Subject: [PATCH 189/242] pinctrl: meson: pinctrl-meson-a1: Remove unused const variable 'i2c_slave_groups' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It has never been used. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/meson/pinctrl-meson-a1.c:749:27: warning: ‘i2c_slave_groups’ defined but not used [-Wunused-const-variable=] 749 | static const char const i2c_slave_groups[] = { | ^~~~~~~~~~~~~~~~ Signed-off-by: Lee Jones Cc: Kevin Hilman Cc: Qianggui Song Cc: linux-amlogic@lists.infradead.org Link: https://lore.kernel.org/r/20200713144930.1034632-24-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/meson/pinctrl-meson-a1.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/pinctrl/meson/pinctrl-meson-a1.c b/drivers/pinctrl/meson/pinctrl-meson-a1.c index 0bcec03f344a..8abf750eac7e 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-a1.c +++ b/drivers/pinctrl/meson/pinctrl-meson-a1.c @@ -746,11 +746,6 @@ static const char * const i2c3_groups[] = { "i2c3_sck_x", "i2c3_sda_x", "i2c3_sck_f", "i2c3_sda_f", }; -static const char * const i2c_slave_groups[] = { - "i2c_slave_sda_a", "i2c_slave_sck_a", - "i2c_slave_sda_f", "i2c_slave_sck_f", -}; - static const char * const spi_a_groups[] = { "spi_a_mosi_x2", "spi_a_ss0_x3", "spi_a_sclk_x4", "spi_a_miso_x5", "spi_a_mosi_x7", "spi_a_miso_x8", "spi_a_ss0_x9", "spi_a_sclk_x10", From 192b752e0e4653b0c136d3ed5e588e16021778aa Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:29 +0100 Subject: [PATCH 190/242] pinctrl: mvebu: pinctrl-armada-37xx: Update documentation block for 'struct armada_37xx_pin_group' Correct misspellings and provide missing entries. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/mvebu/pinctrl-armada-37xx.c:68: warning: Function parameter or member 'start_pin' not described in 'armada_37xx_pin_group' drivers/pinctrl/mvebu/pinctrl-armada-37xx.c:68: warning: Function parameter or member 'val' not described in 'armada_37xx_pin_group' drivers/pinctrl/mvebu/pinctrl-armada-37xx.c:68: warning: Function parameter or member 'extra_pin' not described in 'armada_37xx_pin_group' drivers/pinctrl/mvebu/pinctrl-armada-37xx.c:68: warning: Function parameter or member 'extra_npins' not described in 'armada_37xx_pin_group' Signed-off-by: Lee Jones Cc: Jason Cooper Cc: Andrew Lunn Cc: Gregory Clement Cc: Sebastian Hesselbarth Link: https://lore.kernel.org/r/20200713144930.1034632-25-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 5f125bd6279d..953126bf6657 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -45,13 +45,14 @@ * The pins of a pinmux groups are composed of one or two groups of contiguous * pins. * @name: Name of the pin group, used to lookup the group. - * @start_pins: Index of the first pin of the main range of pins belonging to + * @start_pin: Index of the first pin of the main range of pins belonging to * the group * @npins: Number of pins included in the first range * @reg_mask: Bit mask matching the group in the selection register - * @extra_pins: Index of the first pin of the optional second range of pins + * @val: Value to write to the registers for a given function + * @extra_pin: Index of the first pin of the optional second range of pins * belonging to the group - * @npins: Number of pins included in the second optional range + * @extra_npins:Number of pins included in the second optional range * @funcs: A list of pinmux functions that can be selected for this group. * @pins: List of the pins included in the group */ From de4334f7da83a169b984d617af0d7eb383aef5a5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 13 Jul 2020 15:49:30 +0100 Subject: [PATCH 191/242] pinctrl: pinctrl-amd: Do not define 'struct acpi_device_id' when !CONFIG_ACPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since ACPI_PTR() is used to NULLify the value when !CONFIG_ACPI, 'struct amd_gpio_acpi_match' becomes defined but unused. Fixes the following W=1 kernel build warning(s): drivers/pinctrl/pinctrl-amd.c:959:36: warning: ‘amd_gpio_acpi_match’ defined but not used [-Wunused-const-variable=] 959 | static const struct acpi_device_id amd_gpio_acpi_match[] = { Signed-off-by: Lee Jones Cc: Ken Xue Cc: "Wu, Jeff" Cc: Nehal Shah Cc: Sundar S K Link: https://lore.kernel.org/r/20200713144930.1034632-26-lee.jones@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-amd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index c34e6a950b3f..ccf612031119 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -956,12 +956,14 @@ static int amd_gpio_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_ACPI static const struct acpi_device_id amd_gpio_acpi_match[] = { { "AMD0030", 0 }, { "AMDI0030", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match); +#endif static struct platform_driver amd_gpio_driver = { .driver = { From 3e3f742b23ac975c49572c34f333e6b5b43c35e8 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 13 Jul 2020 20:35:41 +0200 Subject: [PATCH 192/242] pinctrl: rockchip: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Acked-by: Heiko Stuebner Link: https://lore.kernel.org/r/20200713183541.36963-1-grandmaster@al2klimov.de Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index c96d810635ad..0401c1da79dd 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -9,7 +9,7 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd. * http://www.samsung.com * Copyright (c) 2012 Linaro Ltd - * http://www.linaro.org + * https://www.linaro.org * * and pinctrl-at91: * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD From bf3d3999084aac96d60597b2745d81081642a2f7 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 16 Jul 2020 16:21:09 -0500 Subject: [PATCH 193/242] pinctrl: lpc18xx: Use fallthrough pseudo-keyword Replace the existing /* fall through */ comments and its variants with the new pseudo-keyword macro fallthrough[1]. [1] https://www.kernel.org/doc/html/latest/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through Signed-off-by: Gustavo A. R. Silva Link: https://lore.kernel.org/r/20200716212109.GA17525@embeddedor Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-lpc18xx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-lpc18xx.c b/drivers/pinctrl/pinctrl-lpc18xx.c index e4677546aec4..7b2f885e68bd 100644 --- a/drivers/pinctrl/pinctrl-lpc18xx.c +++ b/drivers/pinctrl/pinctrl-lpc18xx.c @@ -838,11 +838,11 @@ static int lpc18xx_pconf_get_pin(struct pinctrl_dev *pctldev, unsigned param, *arg = (reg & LPC18XX_SCU_PIN_EHD_MASK) >> LPC18XX_SCU_PIN_EHD_POS; switch (*arg) { case 3: *arg += 5; - /* fall through */ + fallthrough; case 2: *arg += 5; - /* fall through */ + fallthrough; case 1: *arg += 3; - /* fall through */ + fallthrough; case 0: *arg += 4; } break; @@ -1057,11 +1057,11 @@ static int lpc18xx_pconf_set_pin(struct pinctrl_dev *pctldev, unsigned param, switch (param_val) { case 20: param_val -= 5; - /* fall through */ + fallthrough; case 14: param_val -= 5; - /* fall through */ + fallthrough; case 8: param_val -= 3; - /* fall through */ + fallthrough; case 4: param_val -= 4; break; default: From 0a0930206762b34c74bf14242765dc52d56f2792 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 16 Jul 2020 16:19:19 -0500 Subject: [PATCH 194/242] pinctrl: baytrail: Use fallthrough pseudo-keyword Replace the existing /* fall through */ comments and its variants with the new pseudo-keyword macro fallthrough[1]. [1] https://www.kernel.org/doc/html/latest/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through Signed-off-by: Gustavo A. R. Silva Signed-off-by: Andy Shevchenko --- drivers/pinctrl/intel/pinctrl-baytrail.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index a917a2df520e..d6e35cba3065 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1372,13 +1372,13 @@ static void byt_irq_unmask(struct irq_data *d) switch (irqd_get_trigger_type(d)) { case IRQ_TYPE_LEVEL_HIGH: value |= BYT_TRIG_LVL; - /* fall through */ + fallthrough; case IRQ_TYPE_EDGE_RISING: value |= BYT_TRIG_POS; break; case IRQ_TYPE_LEVEL_LOW: value |= BYT_TRIG_LVL; - /* fall through */ + fallthrough; case IRQ_TYPE_EDGE_FALLING: value |= BYT_TRIG_NEG; break; From 1586f556ca90668f096284bc12cd3e311f5a04dc Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 16 Jul 2020 16:22:13 -0500 Subject: [PATCH 195/242] pinctrl: qcom: spmi-gpio: Use fallthrough pseudo-keyword Replace the existing /* fall through */ comments and its variants with the new pseudo-keyword macro fallthrough[1]. [1] https://www.kernel.org/doc/html/latest/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through Signed-off-by: Gustavo A. R. Silva Link: https://lore.kernel.org/r/20200716212213.GA17623@embeddedor Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 4 ++-- drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 95ca66e24e7c..a86dbd42d09f 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -793,13 +793,13 @@ static int pmic_gpio_populate(struct pmic_gpio_state *state, switch (subtype) { case PMIC_GPIO_SUBTYPE_GPIO_4CH: pad->have_buffer = true; - /* Fall through */ + fallthrough; case PMIC_GPIO_SUBTYPE_GPIOC_4CH: pad->num_sources = 4; break; case PMIC_GPIO_SUBTYPE_GPIO_8CH: pad->have_buffer = true; - /* Fall through */ + fallthrough; case PMIC_GPIO_SUBTYPE_GPIOC_8CH: pad->num_sources = 8; break; diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c index 338a15d08629..b5949f766a7a 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c @@ -346,7 +346,7 @@ static int pm8xxx_pin_config_set(struct pinctrl_dev *pctldev, return -EINVAL; } pin->pull_up_strength = arg; - /* FALLTHROUGH */ + fallthrough; case PIN_CONFIG_BIAS_PULL_UP: pin->bias = pin->pull_up_strength; banks |= BIT(2); From c4429556646edd7f557e1b6451e0b14b832634d3 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 16 Jul 2020 16:23:17 -0500 Subject: [PATCH 196/242] pinctrl: single: Use fallthrough pseudo-keyword Replace the existing /* fall through */ comments and its variants with the new pseudo-keyword macro fallthrough[1]. [1] https://www.kernel.org/doc/html/latest/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through Signed-off-by: Gustavo A. R. Silva Link: https://lore.kernel.org/r/20200716212317.GA17754@embeddedor Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 542578d0bda2..efe41abc5d47 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -563,7 +563,7 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, case PIN_CONFIG_BIAS_PULL_UP: if (arg) pcs_pinconf_clear_bias(pctldev, pin); - /* fall through */ + fallthrough; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: data &= ~func->conf[i].mask; if (arg) From 3762442af6ad914b537f444f3d4672af7685ab2e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 20 Jul 2020 16:00:43 +0200 Subject: [PATCH 197/242] Revert "gpio: omap: handle pin config bias flags" This reverts commit 40e30d26d909af89de2dcd0b4abdd27c47ac2235. I applied the patch to the wrong tree, oooups. Also there is a new version of it. Revert it out of pinctrl and apply to the gpio tree. Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index eba303cff7cb..b8e2ecc3eade 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -896,21 +896,12 @@ static int omap_gpio_set_config(struct gpio_chip *chip, unsigned offset, unsigned long config) { u32 debounce; - int ret = -ENOTSUPP; - if ((pinconf_to_config_param(config) == PIN_CONFIG_BIAS_DISABLE) || - (pinconf_to_config_param(config) == PIN_CONFIG_BIAS_PULL_UP) || - (pinconf_to_config_param(config) == PIN_CONFIG_BIAS_PULL_DOWN)) - { - ret = gpiochip_generic_config(chip, offset, config); - } - else if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) - { - debounce = pinconf_to_config_argument(config); - ret = omap_gpio_debounce(chip, offset, debounce); - } + if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) + return -ENOTSUPP; - return ret; + debounce = pinconf_to_config_argument(config); + return omap_gpio_debounce(chip, offset, debounce); } static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value) From 42348547cef0ecf3a79db255f10066ec8593be76 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Sat, 18 Jul 2020 14:08:07 +0200 Subject: [PATCH 198/242] pinctl: ti: iodelay: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Link: https://lore.kernel.org/r/20200718120807.19714-1-grandmaster@al2klimov.de Signed-off-by: Linus Walleij --- drivers/pinctrl/ti/pinctrl-ti-iodelay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c index b522ca010332..cfb924228d87 100644 --- a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c +++ b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c @@ -2,7 +2,7 @@ * Support for configuration of IO Delay module found on Texas Instruments SoCs * such as DRA7 * - * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/ * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any From b4f2fcb534875e2e57c96a0358267f2109d68004 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 16 Jul 2020 15:42:44 +0300 Subject: [PATCH 199/242] pinctrl: intel: Add Intel Emmitsburg pin controller support This driver adds pinctrl/GPIO support for Intel Emmitsburg PCH. The GPIO controller is based on the next generation GPIO hardware but still compatible with the one supported by the Intel core pinctrl/GPIO driver. Signed-off-by: Andy Shevchenko Reviewed-by: Linus Walleij Acked-by: Mika Westerberg --- drivers/pinctrl/intel/Kconfig | 8 + drivers/pinctrl/intel/Makefile | 1 + drivers/pinctrl/intel/pinctrl-emmitsburg.c | 387 +++++++++++++++++++++ 3 files changed, 396 insertions(+) create mode 100644 drivers/pinctrl/intel/pinctrl-emmitsburg.c diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 787833e343a4..b3e6060db52d 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -95,6 +95,14 @@ config PINCTRL_DENVERTON This pinctrl driver provides an interface that allows configuring of Intel Denverton SoC pins and using them as GPIOs. +config PINCTRL_EMMITSBURG + tristate "Intel Emmitsburg pinctrl and GPIO driver" + depends on ACPI + select PINCTRL_INTEL + help + This pinctrl driver provides an interface that allows configuring + of Intel Emmitsburg pins and using them as GPIOs. + config PINCTRL_GEMINILAKE tristate "Intel Gemini Lake SoC pinctrl and GPIO driver" depends on ACPI diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile index f6f63eb8100f..1c1c316f98b9 100644 --- a/drivers/pinctrl/intel/Makefile +++ b/drivers/pinctrl/intel/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o obj-$(CONFIG_PINCTRL_CANNONLAKE) += pinctrl-cannonlake.o obj-$(CONFIG_PINCTRL_CEDARFORK) += pinctrl-cedarfork.o obj-$(CONFIG_PINCTRL_DENVERTON) += pinctrl-denverton.o +obj-$(CONFIG_PINCTRL_EMMITSBURG) += pinctrl-emmitsburg.o obj-$(CONFIG_PINCTRL_GEMINILAKE) += pinctrl-geminilake.o obj-$(CONFIG_PINCTRL_ICELAKE) += pinctrl-icelake.o obj-$(CONFIG_PINCTRL_JASPERLAKE) += pinctrl-jasperlake.o diff --git a/drivers/pinctrl/intel/pinctrl-emmitsburg.c b/drivers/pinctrl/intel/pinctrl-emmitsburg.c new file mode 100644 index 000000000000..f6114dbf7520 --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-emmitsburg.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Emmitsburg PCH pinctrl/GPIO driver + * + * Copyright (C) 2020, Intel Corporation + * Author: Andy Shevchenko + */ + +#include +#include +#include + +#include + +#include "pinctrl-intel.h" + +#define EBG_PAD_OWN 0x0a0 +#define EBG_PADCFGLOCK 0x100 +#define EBG_HOSTSW_OWN 0x130 +#define EBG_GPI_IS 0x200 +#define EBG_GPI_IE 0x210 + +#define EBG_GPP(r, s, e) \ + { \ + .reg_num = (r), \ + .base = (s), \ + .size = ((e) - (s) + 1), \ + } + +#define EBG_COMMUNITY(b, s, e, g) \ + { \ + .barno = (b), \ + .padown_offset = EBG_PAD_OWN, \ + .padcfglock_offset = EBG_PADCFGLOCK, \ + .hostown_offset = EBG_HOSTSW_OWN, \ + .is_offset = EBG_GPI_IS, \ + .ie_offset = EBG_GPI_IE, \ + .pin_base = (s), \ + .npins = ((e) - (s) + 1), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ + } + +/* Emmitsburg */ +static const struct pinctrl_pin_desc ebg_pins[] = { + /* GPP_A */ + PINCTRL_PIN(0, "ESPI_ALERT0B"), + PINCTRL_PIN(1, "ESPI_ALERT1B"), + PINCTRL_PIN(2, "ESPI_IO_0"), + PINCTRL_PIN(3, "ESPI_IO_1"), + PINCTRL_PIN(4, "ESPI_IO_2"), + PINCTRL_PIN(5, "ESPI_IO_3"), + PINCTRL_PIN(6, "ESPI_CS0B"), + PINCTRL_PIN(7, "ESPI_CS1B"), + PINCTRL_PIN(8, "ESPI_RESETB"), + PINCTRL_PIN(9, "ESPI_CLK"), + PINCTRL_PIN(10, "SRCCLKREQB_0"), + PINCTRL_PIN(11, "SRCCLKREQB_1"), + PINCTRL_PIN(12, "SRCCLKREQB_2"), + PINCTRL_PIN(13, "SRCCLKREQB_3"), + PINCTRL_PIN(14, "SRCCLKREQB_4"), + PINCTRL_PIN(15, "SRCCLKREQB_5"), + PINCTRL_PIN(16, "SRCCLKREQB_6"), + PINCTRL_PIN(17, "SRCCLKREQB_7"), + PINCTRL_PIN(18, "SRCCLKREQB_8"), + PINCTRL_PIN(19, "SRCCLKREQB_9"), + PINCTRL_PIN(20, "ESPI_CLK_LOOPBK"), + /* GPP_B */ + PINCTRL_PIN(21, "GSXDOUT"), + PINCTRL_PIN(22, "GSXSLOAD"), + PINCTRL_PIN(23, "GSXDIN"), + PINCTRL_PIN(24, "GSXSRESETB"), + PINCTRL_PIN(25, "GSXCLK"), + PINCTRL_PIN(26, "USB2_OCB_0"), + PINCTRL_PIN(27, "USB2_OCB_1"), + PINCTRL_PIN(28, "USB2_OCB_2"), + PINCTRL_PIN(29, "USB2_OCB_3"), + PINCTRL_PIN(30, "USB2_OCB_4"), + PINCTRL_PIN(31, "USB2_OCB_5"), + PINCTRL_PIN(32, "USB2_OCB_6"), + PINCTRL_PIN(33, "HS_UART0_RXD"), + PINCTRL_PIN(34, "HS_UART0_TXD"), + PINCTRL_PIN(35, "HS_UART0_RTSB"), + PINCTRL_PIN(36, "HS_UART0_CTSB"), + PINCTRL_PIN(37, "HS_UART1_RXD"), + PINCTRL_PIN(38, "HS_UART1_TXD"), + PINCTRL_PIN(39, "HS_UART1_RTSB"), + PINCTRL_PIN(40, "HS_UART1_CTSB"), + PINCTRL_PIN(41, "GPPC_B_20"), + PINCTRL_PIN(42, "GPPC_B_21"), + PINCTRL_PIN(43, "GPPC_B_22"), + PINCTRL_PIN(44, "PS_ONB"), + /* SPI */ + PINCTRL_PIN(45, "SPI0_IO_2"), + PINCTRL_PIN(46, "SPI0_IO_3"), + PINCTRL_PIN(47, "SPI0_MOSI_IO_0"), + PINCTRL_PIN(48, "SPI0_MISO_IO_1"), + PINCTRL_PIN(49, "SPI0_TPM_CSB"), + PINCTRL_PIN(50, "SPI0_FLASH_0_CSB"), + PINCTRL_PIN(51, "SPI0_FLASH_1_CSB"), + PINCTRL_PIN(52, "SPI0_CLK"), + PINCTRL_PIN(53, "TIME_SYNC_0"), + PINCTRL_PIN(54, "SPKR"), + PINCTRL_PIN(55, "CPU_GP_0"), + PINCTRL_PIN(56, "CPU_GP_1"), + PINCTRL_PIN(57, "CPU_GP_2"), + PINCTRL_PIN(58, "CPU_GP_3"), + PINCTRL_PIN(59, "SUSWARNB_SUSPWRDNACK"), + PINCTRL_PIN(60, "SUSACKB"), + PINCTRL_PIN(61, "NMIB"), + PINCTRL_PIN(62, "SMIB"), + PINCTRL_PIN(63, "GPPC_S_10"), + PINCTRL_PIN(64, "GPPC_S_11"), + PINCTRL_PIN(65, "SPI_CLK_LOOPBK"), + /* GPP_C */ + PINCTRL_PIN(66, "ME_SML0CLK"), + PINCTRL_PIN(67, "ME_SML0DATA"), + PINCTRL_PIN(68, "ME_SML0ALERTB"), + PINCTRL_PIN(69, "ME_SML0BDATA"), + PINCTRL_PIN(70, "ME_SML0BCLK"), + PINCTRL_PIN(71, "ME_SML0BALERTB"), + PINCTRL_PIN(72, "ME_SML1CLK"), + PINCTRL_PIN(73, "ME_SML1DATA"), + PINCTRL_PIN(74, "ME_SML1ALERTB"), + PINCTRL_PIN(75, "ME_SML2CLK"), + PINCTRL_PIN(76, "ME_SML2DATA"), + PINCTRL_PIN(77, "ME_SML2ALERTB"), + PINCTRL_PIN(78, "ME_SML3CLK"), + PINCTRL_PIN(79, "ME_SML3DATA"), + PINCTRL_PIN(80, "ME_SML3ALERTB"), + PINCTRL_PIN(81, "ME_SML4CLK"), + PINCTRL_PIN(82, "ME_SML4DATA"), + PINCTRL_PIN(83, "ME_SML4ALERTB"), + PINCTRL_PIN(84, "GPPC_C_18"), + PINCTRL_PIN(85, "MC_SMBCLK"), + PINCTRL_PIN(86, "MC_SMBDATA"), + PINCTRL_PIN(87, "MC_SMBALERTB"), + /* GPP_D */ + PINCTRL_PIN(88, "HS_SMBCLK"), + PINCTRL_PIN(89, "HS_SMBDATA"), + PINCTRL_PIN(90, "HS_SMBALERTB"), + PINCTRL_PIN(91, "GBE_SMB_ALRT_N"), + PINCTRL_PIN(92, "GBE_SMB_CLK"), + PINCTRL_PIN(93, "GBE_SMB_DATA"), + PINCTRL_PIN(94, "GBE_GPIO10"), + PINCTRL_PIN(95, "GBE_GPIO11"), + PINCTRL_PIN(96, "CRASHLOG_TRIG_N"), + PINCTRL_PIN(97, "PMEB"), + PINCTRL_PIN(98, "BM_BUSYB"), + PINCTRL_PIN(99, "PLTRSTB"), + PINCTRL_PIN(100, "PCHHOTB"), + PINCTRL_PIN(101, "ADR_COMPLETE"), + PINCTRL_PIN(102, "ADR_TRIGGER_N"), + PINCTRL_PIN(103, "VRALERTB"), + PINCTRL_PIN(104, "ADR_ACK"), + PINCTRL_PIN(105, "THERMTRIP_N"), + PINCTRL_PIN(106, "MEMTRIP_N"), + PINCTRL_PIN(107, "MSMI_N"), + PINCTRL_PIN(108, "CATERR_N"), + PINCTRL_PIN(109, "GLB_RST_WARN_B"), + PINCTRL_PIN(110, "USB2_OCB_7"), + PINCTRL_PIN(111, "GPP_D_23"), + /* GPP_E */ + PINCTRL_PIN(112, "SATA1_XPCIE_0"), + PINCTRL_PIN(113, "SATA1_XPCIE_1"), + PINCTRL_PIN(114, "SATA1_XPCIE_2"), + PINCTRL_PIN(115, "SATA1_XPCIE_3"), + PINCTRL_PIN(116, "SATA0_XPCIE_2"), + PINCTRL_PIN(117, "SATA0_XPCIE_3"), + PINCTRL_PIN(118, "SATA0_USB3_XPCIE_0"), + PINCTRL_PIN(119, "SATA0_USB3_XPCIE_1"), + PINCTRL_PIN(120, "SATA0_SCLOCK"), + PINCTRL_PIN(121, "SATA0_SLOAD"), + PINCTRL_PIN(122, "SATA0_SDATAOUT"), + PINCTRL_PIN(123, "SATA1_SCLOCK"), + PINCTRL_PIN(124, "SATA1_SLOAD"), + PINCTRL_PIN(125, "SATA1_SDATAOUT"), + PINCTRL_PIN(126, "SATA2_SCLOCK"), + PINCTRL_PIN(127, "SATA2_SLOAD"), + PINCTRL_PIN(128, "SATA2_SDATAOUT"), + PINCTRL_PIN(129, "ERR0_N"), + PINCTRL_PIN(130, "ERR1_N"), + PINCTRL_PIN(131, "ERR2_N"), + PINCTRL_PIN(132, "GBE_UART_RXD"), + PINCTRL_PIN(133, "GBE_UART_TXD"), + PINCTRL_PIN(134, "GBE_UART_RTSB"), + PINCTRL_PIN(135, "GBE_UART_CTSB"), + /* JTAG */ + PINCTRL_PIN(136, "JTAG_TDO"), + PINCTRL_PIN(137, "JTAG_TDI"), + PINCTRL_PIN(138, "JTAG_TCK"), + PINCTRL_PIN(139, "JTAG_TMS"), + PINCTRL_PIN(140, "JTAGX"), + PINCTRL_PIN(141, "PRDYB"), + PINCTRL_PIN(142, "PREQB"), + PINCTRL_PIN(143, "GLB_PC_DISABLE"), + PINCTRL_PIN(144, "DBG_PMODE"), + PINCTRL_PIN(145, "GLB_EXT_ACC_DISABLE"), + /* GPP_H */ + PINCTRL_PIN(146, "GBE_GPIO12"), + PINCTRL_PIN(147, "GBE_GPIO13"), + PINCTRL_PIN(148, "GBE_SDP_TIMESYNC0_S2N"), + PINCTRL_PIN(149, "GBE_SDP_TIMESYNC1_S2N"), + PINCTRL_PIN(150, "GBE_SDP_TIMESYNC2_S2N"), + PINCTRL_PIN(151, "GBE_SDP_TIMESYNC3_S2N"), + PINCTRL_PIN(152, "GPPC_H_6"), + PINCTRL_PIN(153, "GPPC_H_7"), + PINCTRL_PIN(154, "NCSI_CLK_IN"), + PINCTRL_PIN(155, "NCSI_CRS_DV"), + PINCTRL_PIN(156, "NCSI_RXD0"), + PINCTRL_PIN(157, "NCSI_RXD1"), + PINCTRL_PIN(158, "NCSI_TX_EN"), + PINCTRL_PIN(159, "NCSI_TXD0"), + PINCTRL_PIN(160, "NCSI_TXD1"), + PINCTRL_PIN(161, "NAC_NCSI_CLK_OUT_0"), + PINCTRL_PIN(162, "NAC_NCSI_CLK_OUT_1"), + PINCTRL_PIN(163, "NAC_NCSI_CLK_OUT_2"), + PINCTRL_PIN(164, "PMCALERTB"), + PINCTRL_PIN(165, "GPPC_H_19"), + /* GPP_J */ + PINCTRL_PIN(166, "CPUPWRGD"), + PINCTRL_PIN(167, "CPU_THRMTRIP_N"), + PINCTRL_PIN(168, "PLTRST_CPUB"), + PINCTRL_PIN(169, "TRIGGER0_N"), + PINCTRL_PIN(170, "TRIGGER1_N"), + PINCTRL_PIN(171, "CPU_PWR_DEBUG_N"), + PINCTRL_PIN(172, "CPU_MEMTRIP_N"), + PINCTRL_PIN(173, "CPU_MSMI_N"), + PINCTRL_PIN(174, "ME_PECI"), + PINCTRL_PIN(175, "NAC_SPARE0"), + PINCTRL_PIN(176, "NAC_SPARE1"), + PINCTRL_PIN(177, "NAC_SPARE2"), + PINCTRL_PIN(178, "CPU_ERR0_N"), + PINCTRL_PIN(179, "CPU_CATERR_N"), + PINCTRL_PIN(180, "CPU_ERR1_N"), + PINCTRL_PIN(181, "CPU_ERR2_N"), + PINCTRL_PIN(182, "GPP_J_16"), + PINCTRL_PIN(183, "GPP_J_17"), + /* GPP_I */ + PINCTRL_PIN(184, "GBE_GPIO4"), + PINCTRL_PIN(185, "GBE_GPIO5"), + PINCTRL_PIN(186, "GBE_GPIO6"), + PINCTRL_PIN(187, "GBE_GPIO7"), + PINCTRL_PIN(188, "GBE1_LED1"), + PINCTRL_PIN(189, "GBE1_LED2"), + PINCTRL_PIN(190, "GBE2_LED0"), + PINCTRL_PIN(191, "GBE2_LED1"), + PINCTRL_PIN(192, "GBE2_LED2"), + PINCTRL_PIN(193, "GBE3_LED0"), + PINCTRL_PIN(194, "GBE3_LED1"), + PINCTRL_PIN(195, "GBE3_LED2"), + PINCTRL_PIN(196, "GBE0_I2C_CLK"), + PINCTRL_PIN(197, "GBE0_I2C_DATA"), + PINCTRL_PIN(198, "GBE1_I2C_CLK"), + PINCTRL_PIN(199, "GBE1_I2C_DATA"), + PINCTRL_PIN(200, "GBE2_I2C_CLK"), + PINCTRL_PIN(201, "GBE2_I2C_DATA"), + PINCTRL_PIN(202, "GBE3_I2C_CLK"), + PINCTRL_PIN(203, "GBE3_I2C_DATA"), + PINCTRL_PIN(204, "GBE4_I2C_CLK"), + PINCTRL_PIN(205, "GBE4_I2C_DATA"), + PINCTRL_PIN(206, "GBE_GPIO8"), + PINCTRL_PIN(207, "GBE_GPIO9"), + /* GPP_L */ + PINCTRL_PIN(208, "PM_SYNC_0"), + PINCTRL_PIN(209, "PM_DOWN_0"), + PINCTRL_PIN(210, "PM_SYNC_CLK_0"), + PINCTRL_PIN(211, "GPP_L_3"), + PINCTRL_PIN(212, "GPP_L_4"), + PINCTRL_PIN(213, "GPP_L_5"), + PINCTRL_PIN(214, "GPP_L_6"), + PINCTRL_PIN(215, "GPP_L_7"), + PINCTRL_PIN(216, "GPP_L_8"), + PINCTRL_PIN(217, "NAC_GBE_GPIO0_S2N"), + PINCTRL_PIN(218, "NAC_GBE_GPIO1_S2N"), + PINCTRL_PIN(219, "NAC_GBE_GPIO2_S2N"), + PINCTRL_PIN(220, "NAC_GBE_GPIO3_S2N"), + PINCTRL_PIN(221, "NAC_GBE_SMB_DATA_IN"), + PINCTRL_PIN(222, "NAC_GBE_SMB_DATA_OUT"), + PINCTRL_PIN(223, "NAC_GBE_SMB_ALRT_N"), + PINCTRL_PIN(224, "NAC_GBE_SMB_CLK_IN"), + PINCTRL_PIN(225, "NAC_GBE_SMB_CLK_OUT"), + /* GPP_M */ + PINCTRL_PIN(226, "GPP_M_0"), + PINCTRL_PIN(227, "GPP_M_1"), + PINCTRL_PIN(228, "GPP_M_2"), + PINCTRL_PIN(229, "GPP_M_3"), + PINCTRL_PIN(230, "NAC_WAKE_N"), + PINCTRL_PIN(231, "GPP_M_5"), + PINCTRL_PIN(232, "GPP_M_6"), + PINCTRL_PIN(233, "GPP_M_7"), + PINCTRL_PIN(234, "GPP_M_8"), + PINCTRL_PIN(235, "NAC_SBLINK_S2N"), + PINCTRL_PIN(236, "NAC_SBLINK_N2S"), + PINCTRL_PIN(237, "NAC_SBLINK_CLK_N2S"), + PINCTRL_PIN(238, "NAC_SBLINK_CLK_S2N"), + PINCTRL_PIN(239, "NAC_XTAL_VALID"), + PINCTRL_PIN(240, "NAC_RESET_NAC_N"), + PINCTRL_PIN(241, "GPP_M_15"), + PINCTRL_PIN(242, "GPP_M_16"), + PINCTRL_PIN(243, "GPP_M_17"), + /* GPP_N */ + PINCTRL_PIN(244, "GPP_N_0"), + PINCTRL_PIN(245, "NAC_NCSI_TXD0"), + PINCTRL_PIN(246, "GPP_N_2"), + PINCTRL_PIN(247, "GPP_N_3"), + PINCTRL_PIN(248, "NAC_NCSI_REFCLK_IN"), + PINCTRL_PIN(249, "GPP_N_5"), + PINCTRL_PIN(250, "GPP_N_6"), + PINCTRL_PIN(251, "GPP_N_7"), + PINCTRL_PIN(252, "NAC_NCSI_RXD0"), + PINCTRL_PIN(253, "NAC_NCSI_RXD1"), + PINCTRL_PIN(254, "NAC_NCSI_CRS_DV"), + PINCTRL_PIN(255, "NAC_NCSI_CLK_IN"), + PINCTRL_PIN(256, "NAC_NCSI_REFCLK_OUT"), + PINCTRL_PIN(257, "NAC_NCSI_TX_EN"), + PINCTRL_PIN(258, "NAC_NCSI_TXD1"), + PINCTRL_PIN(259, "NAC_NCSI_OE_N"), + PINCTRL_PIN(260, "NAC_GR_N"), + PINCTRL_PIN(261, "NAC_INIT_SX_WAKE_N"), +}; + +static const struct intel_padgroup ebg_community0_gpps[] = { + EBG_GPP(0, 0, 20), /* GPP_A */ + EBG_GPP(1, 21, 44), /* GPP_B */ + EBG_GPP(2, 45, 65), /* SPI */ +}; + +static const struct intel_padgroup ebg_community1_gpps[] = { + EBG_GPP(0, 66, 87), /* GPP_C */ + EBG_GPP(1, 88, 111), /* GPP_D */ +}; + +static const struct intel_padgroup ebg_community3_gpps[] = { + EBG_GPP(0, 112, 135), /* GPP_E */ + EBG_GPP(1, 136, 145), /* JTAG */ +}; + +static const struct intel_padgroup ebg_community4_gpps[] = { + EBG_GPP(0, 146, 165), /* GPP_H */ + EBG_GPP(1, 166, 183), /* GPP_J */ +}; + +static const struct intel_padgroup ebg_community5_gpps[] = { + EBG_GPP(0, 184, 207), /* GPP_I */ + EBG_GPP(1, 208, 225), /* GPP_L */ + EBG_GPP(2, 226, 243), /* GPP_M */ + EBG_GPP(3, 244, 261), /* GPP_N */ +}; + +static const struct intel_community ebg_communities[] = { + EBG_COMMUNITY(0, 0, 65, ebg_community0_gpps), + EBG_COMMUNITY(1, 66, 111, ebg_community1_gpps), + EBG_COMMUNITY(2, 112, 145, ebg_community3_gpps), + EBG_COMMUNITY(3, 146, 183, ebg_community4_gpps), + EBG_COMMUNITY(4, 184, 261, ebg_community5_gpps), +}; + +static const struct intel_pinctrl_soc_data ebg_soc_data = { + .pins = ebg_pins, + .npins = ARRAY_SIZE(ebg_pins), + .communities = ebg_communities, + .ncommunities = ARRAY_SIZE(ebg_communities), +}; + +static const struct acpi_device_id ebg_pinctrl_acpi_match[] = { + { "INTC1071", (kernel_ulong_t)&ebg_soc_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, ebg_pinctrl_acpi_match); + +static INTEL_PINCTRL_PM_OPS(ebg_pinctrl_pm_ops); + +static struct platform_driver ebg_pinctrl_driver = { + .probe = intel_pinctrl_probe_by_hid, + .driver = { + .name = "emmitsburg-pinctrl", + .acpi_match_table = ebg_pinctrl_acpi_match, + .pm = &ebg_pinctrl_pm_ops, + }, +}; + +module_platform_driver(ebg_pinctrl_driver); + +MODULE_AUTHOR("Andy Shevchenko "); +MODULE_DESCRIPTION("Intel Emmitsburg PCH pinctrl/GPIO driver"); +MODULE_LICENSE("GPL v2"); From 66c00f561d94f8b5eae8c0e1aa8e4cfad9cf64f9 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 20 Jul 2020 17:45:48 +0200 Subject: [PATCH 200/242] dt-bindings: ingenic,pinctrl: Support pinmux/pinconf nodes Add YAML to describe the pinmux/pinconf sub-nodes of the pinctrl IP on Ingenic SoCs. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20200720154548.12453-1-paul@crapouillou.net Signed-off-by: Linus Walleij --- .../bindings/pinctrl/ingenic,pinctrl.yaml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml index 5be2b1e95b36..18163fb69ce7 100644 --- a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml @@ -110,6 +110,46 @@ required: - "#address-cells" - "#size-cells" +additionalProperties: + anyOf: + - type: object + allOf: + - $ref: pincfg-node.yaml# + - $ref: pinmux-node.yaml# + + properties: + phandle: true + function: true + groups: true + pins: true + bias-disable: true + bias-pull-up: true + bias-pull-down: true + output-low: true + output-high: true + additionalProperties: false + + - type: object + properties: + phandle: true + additionalProperties: + type: object + allOf: + - $ref: pincfg-node.yaml# + - $ref: pinmux-node.yaml# + + properties: + phandle: true + function: true + groups: true + pins: true + bias-disable: true + bias-pull-up: true + bias-pull-down: true + output-low: true + output-high: true + additionalProperties: false + examples: - | pin-controller@10010000 { From 1bca544050e596f04e4fd3e23b87cde85282a931 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 13 Jul 2020 16:56:28 +0900 Subject: [PATCH 201/242] powerpc/boot: add DTB to 'targets' PowerPC always re-builds DTB even if nothing has been changed. As for other architectures, arch/*/boot/dts/Makefile builds DTB by using the dtb-y syntax. In contrast, arch/powerpc/boot/dts/(fsl/)Makefile does nothing unless CONFIG_OF_ALL_DTBS is defined. Instead, arch/powerpc/boot/Makefile builds DTB on demand. You need to add DTB to 'targets' explicitly so .*.cmd files are included. Signed-off-by: Masahiro Yamada Acked-by: Michael Ellerman --- arch/powerpc/boot/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 63d7456b9518..8792323707fd 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -366,6 +366,8 @@ initrd-y := $(patsubst zImage%, zImage.initrd%, \ $(patsubst treeImage%, treeImage.initrd%, $(image-y))))) initrd-y := $(filter-out $(image-y), $(initrd-y)) targets += $(image-y) $(initrd-y) +targets += $(foreach x, dtbImage uImage cuImage simpleImage treeImage, \ + $(patsubst $(x).%, dts/%.dtb, $(filter $(x).%, $(image-y)))) $(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz From 0a04d767af8cf1498a73b8f20dc727e2eb74ff28 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 21 Jul 2020 15:25:37 +0200 Subject: [PATCH 202/242] pinctrl: sx150x: Use irqchip template This makes the driver use the irqchip template to assign properties to the gpio_irq_chip instead of using the explicit calls to gpiochip_irqchip_add_nested() and gpiochip_set_nested_irqchip(). The irqchip is instead added while adding the gpiochip. Signed-off-by: Linus Walleij Acked-by: Neil Armstrong Cc: Peter Rosin Cc: Andrey Smirnov Cc: Neil Armstrong Link: https://lore.kernel.org/r/20200721132537.362160-1-linus.walleij@linaro.org --- drivers/pinctrl/pinctrl-sx150x.c | 44 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/pinctrl/pinctrl-sx150x.c b/drivers/pinctrl/pinctrl-sx150x.c index 708bc91862fe..b325a136ac48 100644 --- a/drivers/pinctrl/pinctrl-sx150x.c +++ b/drivers/pinctrl/pinctrl-sx150x.c @@ -1187,17 +1187,10 @@ static int sx150x_probe(struct i2c_client *client, if (pctl->data->model != SX150X_789) pctl->gpio.set_multiple = sx150x_gpio_set_multiple; - ret = devm_gpiochip_add_data(dev, &pctl->gpio, pctl); - if (ret) - return ret; - - ret = gpiochip_add_pin_range(&pctl->gpio, dev_name(dev), - 0, 0, pctl->data->npins); - if (ret) - return ret; - /* Add Interrupt support if an irq is specified */ if (client->irq > 0) { + struct gpio_irq_chip *girq; + pctl->irq_chip.irq_mask = sx150x_irq_mask; pctl->irq_chip.irq_unmask = sx150x_irq_unmask; pctl->irq_chip.irq_set_type = sx150x_irq_set_type; @@ -1213,8 +1206,8 @@ static int sx150x_probe(struct i2c_client *client, /* * Because sx150x_irq_threaded_fn invokes all of the - * nested interrrupt handlers via handle_nested_irq, - * any "handler" passed to gpiochip_irqchip_add() + * nested interrupt handlers via handle_nested_irq, + * any "handler" assigned to struct gpio_irq_chip * below is going to be ignored, so the choice of the * function does not matter that much. * @@ -1222,13 +1215,15 @@ static int sx150x_probe(struct i2c_client *client, * plus it will be instantly noticeable if it is ever * called (should not happen) */ - ret = gpiochip_irqchip_add_nested(&pctl->gpio, - &pctl->irq_chip, 0, - handle_bad_irq, IRQ_TYPE_NONE); - if (ret) { - dev_err(dev, "could not connect irqchip to gpiochip\n"); - return ret; - } + girq = &pctl->gpio.irq; + girq->chip = &pctl->irq_chip; + /* This will let us handle the parent IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_bad_irq; + girq->threaded = true; ret = devm_request_threaded_irq(dev, client->irq, NULL, sx150x_irq_thread_fn, @@ -1237,12 +1232,17 @@ static int sx150x_probe(struct i2c_client *client, pctl->irq_chip.name, pctl); if (ret < 0) return ret; - - gpiochip_set_nested_irqchip(&pctl->gpio, - &pctl->irq_chip, - client->irq); } + ret = devm_gpiochip_add_data(dev, &pctl->gpio, pctl); + if (ret) + return ret; + + ret = gpiochip_add_pin_range(&pctl->gpio, dev_name(dev), + 0, 0, pctl->data->npins); + if (ret) + return ret; + return 0; } From 57597e150f1b589046bf0da865eeee2b58792079 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 21 Jul 2020 14:52:23 +0200 Subject: [PATCH 203/242] pinctrl: mcp23s08: Use irqchip template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the driver use the irqchip template to assign properties to the gpio_irq_chip instead of using the explicit calls to gpiochip_irqchip_add_nested() and gpiochip_set_nested_irqchip(). The irqchip is instead added while adding the gpiochip. Signed-off-by: Linus Walleij Reviewed-by: Andy Shevchenko Cc: Andy Shevchenko Cc: Jan Kundrát Cc: Phil Reid Cc: Lars Poeschel Cc: Jason Kridner Link: https://lore.kernel.org/r/20200721125223.344411-1-linus.walleij@linaro.org --- drivers/pinctrl/pinctrl-mcp23s08.c | 44 ++++++++++-------------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index 151931b593f6..42b12ea14d6b 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -522,29 +522,6 @@ static int mcp23s08_irq_setup(struct mcp23s08 *mcp) return 0; } -static int mcp23s08_irqchip_setup(struct mcp23s08 *mcp) -{ - struct gpio_chip *chip = &mcp->chip; - int err; - - err = gpiochip_irqchip_add_nested(chip, - &mcp->irq_chip, - 0, - handle_simple_irq, - IRQ_TYPE_NONE); - if (err) { - dev_err(chip->parent, - "could not connect irqchip to gpiochip: %d\n", err); - return err; - } - - gpiochip_set_nested_irqchip(chip, - &mcp->irq_chip, - mcp->irq); - - return 0; -} - /*----------------------------------------------------------------------*/ int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, @@ -589,10 +566,6 @@ int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, if (ret < 0) goto fail; - ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp); - if (ret < 0) - goto fail; - mcp->irq_controller = device_property_read_bool(dev, "interrupt-controller"); if (mcp->irq && mcp->irq_controller) { @@ -629,11 +602,22 @@ int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, } if (mcp->irq && mcp->irq_controller) { - ret = mcp23s08_irqchip_setup(mcp); - if (ret) - goto fail; + struct gpio_irq_chip *girq = &mcp->chip.irq; + + girq->chip = &mcp->irq_chip; + /* This will let us handle the parent IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_simple_irq; + girq->threaded = true; } + ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp); + if (ret < 0) + goto fail; + mcp->pinctrl_desc.pctlops = &mcp_pinctrl_ops; mcp->pinctrl_desc.confops = &mcp_pinconf_ops; mcp->pinctrl_desc.npins = mcp->chip.ngpio; From 290a9f937e5a8b4eb41f7e48237816dc6ba0c783 Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Mon, 15 Jun 2020 14:44:56 +0200 Subject: [PATCH 204/242] pinctrl: stm32: use the hwspin_lock_timeout_in_atomic() API Use the hwspin_lock_timeout_in_atomic() API which is the most appropriated here. Indeed: - hwspin_lock_() is called after spin_lock_irqsave() - the hwspin_lock_timeout() API relies on jiffies count which won't work if IRQs are disabled which is the case here. Signed-off-by: Fabien Dessenne Signed-off-by: Alexandre Torgue Link: https://lore.kernel.org/r/20200615124456.27328-1-alexandre.torgue@st.com Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 78 ++++++++++++++------------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index faf2660298f5..7d9bdedcd71b 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -64,7 +64,7 @@ #define gpio_range_to_bank(chip) \ container_of(chip, struct stm32_gpio_bank, range) -#define HWSPINLOCK_TIMEOUT 5 /* msec */ +#define HWSPNLCK_TIMEOUT 1000 /* usec */ static const char * const stm32_gpio_functions[] = { "gpio", "af0", "af1", @@ -422,12 +422,14 @@ static int stm32_gpio_domain_activate(struct irq_domain *d, * to avoid overriding. */ spin_lock_irqsave(&pctl->irqmux_lock, flags); - if (pctl->hwlock) - ret = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - if (ret) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + ret = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (ret) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } if (pctl->irqmux_map & BIT(irq_data->hwirq)) { @@ -435,7 +437,7 @@ static int stm32_gpio_domain_activate(struct irq_domain *d, irq_data->hwirq); ret = -EBUSY; if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); goto unlock; } else { pctl->irqmux_map |= BIT(irq_data->hwirq); @@ -444,7 +446,7 @@ static int stm32_gpio_domain_activate(struct irq_domain *d, regmap_field_write(pctl->irqmux[irq_data->hwirq], bank->bank_ioport_nr); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); unlock: spin_unlock_irqrestore(&pctl->irqmux_lock, flags); @@ -752,12 +754,13 @@ static int stm32_pmx_set_mode(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - if (pctl->hwlock) - err = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - - if (err) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + err = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (err) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } val = readl_relaxed(bank->base + alt_offset); @@ -771,7 +774,7 @@ static int stm32_pmx_set_mode(struct stm32_gpio_bank *bank, writel_relaxed(val, bank->base + STM32_GPIO_MODER); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); stm32_gpio_backup_mode(bank, pin, mode, alt); @@ -871,12 +874,13 @@ static int stm32_pconf_set_driving(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - if (pctl->hwlock) - err = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - - if (err) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + err = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (err) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } val = readl_relaxed(bank->base + STM32_GPIO_TYPER); @@ -885,7 +889,7 @@ static int stm32_pconf_set_driving(struct stm32_gpio_bank *bank, writel_relaxed(val, bank->base + STM32_GPIO_TYPER); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); stm32_gpio_backup_driving(bank, offset, drive); @@ -925,12 +929,13 @@ static int stm32_pconf_set_speed(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - if (pctl->hwlock) - err = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - - if (err) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + err = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (err) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } val = readl_relaxed(bank->base + STM32_GPIO_SPEEDR); @@ -939,7 +944,7 @@ static int stm32_pconf_set_speed(struct stm32_gpio_bank *bank, writel_relaxed(val, bank->base + STM32_GPIO_SPEEDR); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); stm32_gpio_backup_speed(bank, offset, speed); @@ -979,12 +984,13 @@ static int stm32_pconf_set_bias(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - if (pctl->hwlock) - err = hwspin_lock_timeout(pctl->hwlock, HWSPINLOCK_TIMEOUT); - - if (err) { - dev_err(pctl->dev, "Can't get hwspinlock\n"); - goto unlock; + if (pctl->hwlock) { + err = hwspin_lock_timeout_in_atomic(pctl->hwlock, + HWSPNLCK_TIMEOUT); + if (err) { + dev_err(pctl->dev, "Can't get hwspinlock\n"); + goto unlock; + } } val = readl_relaxed(bank->base + STM32_GPIO_PUPDR); @@ -993,7 +999,7 @@ static int stm32_pconf_set_bias(struct stm32_gpio_bank *bank, writel_relaxed(val, bank->base + STM32_GPIO_PUPDR); if (pctl->hwlock) - hwspin_unlock(pctl->hwlock); + hwspin_unlock_in_atomic(pctl->hwlock); stm32_gpio_backup_bias(bank, offset, bias); From b07b616214857c9db01e2807cde2f6bba8019fc3 Mon Sep 17 00:00:00 2001 From: Hanks Chen Date: Thu, 23 Jul 2020 19:19:51 +0800 Subject: [PATCH 205/242] pinctrl: mediatek: update pinmux definitions for mt6779 Add devicetree bindings for Mediatek mt6779 SoC Pin Controller. Signed-off-by: Mars Cheng Signed-off-by: Andy Teng Signed-off-by: Hanks Chen Acked-by: Sean Wang Link: https://lore.kernel.org/r/1595503197-15246-2-git-send-email-hanks.chen@mediatek.com Signed-off-by: Linus Walleij --- include/dt-bindings/pinctrl/mt6779-pinfunc.h | 1242 ++++++++++++++++++ 1 file changed, 1242 insertions(+) create mode 100644 include/dt-bindings/pinctrl/mt6779-pinfunc.h diff --git a/include/dt-bindings/pinctrl/mt6779-pinfunc.h b/include/dt-bindings/pinctrl/mt6779-pinfunc.h new file mode 100644 index 000000000000..87fdc4310936 --- /dev/null +++ b/include/dt-bindings/pinctrl/mt6779-pinfunc.h @@ -0,0 +1,1242 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + * Author: Andy Teng + * + */ + +#ifndef __MT6779_PINFUNC_H +#define __MT6779_PINFUNC_H + +#include + +#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define PINMUX_GPIO0__FUNC_SPI6_MI (MTK_PIN_NO(0) | 1) +#define PINMUX_GPIO0__FUNC_I2S5_LRCK (MTK_PIN_NO(0) | 2) +#define PINMUX_GPIO0__FUNC_TDM_LRCK_2ND (MTK_PIN_NO(0) | 3) +#define PINMUX_GPIO0__FUNC_PCM1_SYNC (MTK_PIN_NO(0) | 4) +#define PINMUX_GPIO0__FUNC_SCL_6306 (MTK_PIN_NO(0) | 5) +#define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 6) +#define PINMUX_GPIO0__FUNC_PTA_RXD (MTK_PIN_NO(0) | 7) + +#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define PINMUX_GPIO1__FUNC_SPI6_CSB (MTK_PIN_NO(1) | 1) +#define PINMUX_GPIO1__FUNC_I2S5_DO (MTK_PIN_NO(1) | 2) +#define PINMUX_GPIO1__FUNC_TDM_DATA0_2ND (MTK_PIN_NO(1) | 3) +#define PINMUX_GPIO1__FUNC_PCM1_DO0 (MTK_PIN_NO(1) | 4) +#define PINMUX_GPIO1__FUNC_SDA_6306 (MTK_PIN_NO(1) | 5) +#define PINMUX_GPIO1__FUNC_TP_GPIO1_AO (MTK_PIN_NO(1) | 6) +#define PINMUX_GPIO1__FUNC_PTA_TXD (MTK_PIN_NO(1) | 7) + +#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define PINMUX_GPIO2__FUNC_SPI6_MO (MTK_PIN_NO(2) | 1) +#define PINMUX_GPIO2__FUNC_I2S5_BCK (MTK_PIN_NO(2) | 2) +#define PINMUX_GPIO2__FUNC_TDM_BCK_2ND (MTK_PIN_NO(2) | 3) +#define PINMUX_GPIO2__FUNC_PCM1_CLK (MTK_PIN_NO(2) | 4) +#define PINMUX_GPIO2__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(2) | 5) +#define PINMUX_GPIO2__FUNC_TP_GPIO2_AO (MTK_PIN_NO(2) | 6) + +#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define PINMUX_GPIO3__FUNC_SPI6_CLK (MTK_PIN_NO(3) | 1) +#define PINMUX_GPIO3__FUNC_I2S5_MCK (MTK_PIN_NO(3) | 2) +#define PINMUX_GPIO3__FUNC_TDM_MCK_2ND (MTK_PIN_NO(3) | 3) +#define PINMUX_GPIO3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(3) | 4) +#define PINMUX_GPIO3__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(3) | 5) +#define PINMUX_GPIO3__FUNC_TP_GPIO3_AO (MTK_PIN_NO(3) | 6) + +#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define PINMUX_GPIO4__FUNC_SPI7_MI (MTK_PIN_NO(4) | 1) +#define PINMUX_GPIO4__FUNC_I2S0_MCK (MTK_PIN_NO(4) | 2) +#define PINMUX_GPIO4__FUNC_TDM_DATA1_2ND (MTK_PIN_NO(4) | 3) +#define PINMUX_GPIO4__FUNC_PCM1_DO1 (MTK_PIN_NO(4) | 4) +#define PINMUX_GPIO4__FUNC_DMIC1_CLK (MTK_PIN_NO(4) | 5) +#define PINMUX_GPIO4__FUNC_TP_GPIO4_AO (MTK_PIN_NO(4) | 6) +#define PINMUX_GPIO4__FUNC_SCL8 (MTK_PIN_NO(4) | 7) + +#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define PINMUX_GPIO5__FUNC_SPI7_CSB (MTK_PIN_NO(5) | 1) +#define PINMUX_GPIO5__FUNC_I2S0_BCK (MTK_PIN_NO(5) | 2) +#define PINMUX_GPIO5__FUNC_TDM_DATA2_2ND (MTK_PIN_NO(5) | 3) +#define PINMUX_GPIO5__FUNC_PCM1_DO2 (MTK_PIN_NO(5) | 4) +#define PINMUX_GPIO5__FUNC_DMIC1_DAT (MTK_PIN_NO(5) | 5) +#define PINMUX_GPIO5__FUNC_TP_GPIO5_AO (MTK_PIN_NO(5) | 6) +#define PINMUX_GPIO5__FUNC_SDA8 (MTK_PIN_NO(5) | 7) + +#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define PINMUX_GPIO6__FUNC_SPI7_MO (MTK_PIN_NO(6) | 1) +#define PINMUX_GPIO6__FUNC_I2S0_LRCK (MTK_PIN_NO(6) | 2) +#define PINMUX_GPIO6__FUNC_TDM_DATA3_2ND (MTK_PIN_NO(6) | 3) +#define PINMUX_GPIO6__FUNC_PCM1_DI (MTK_PIN_NO(6) | 4) +#define PINMUX_GPIO6__FUNC_DMIC_CLK (MTK_PIN_NO(6) | 5) +#define PINMUX_GPIO6__FUNC_TP_GPIO6_AO (MTK_PIN_NO(6) | 6) +#define PINMUX_GPIO6__FUNC_SCL9 (MTK_PIN_NO(6) | 7) + +#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define PINMUX_GPIO7__FUNC_SPI7_CLK (MTK_PIN_NO(7) | 1) +#define PINMUX_GPIO7__FUNC_I2S0_DI (MTK_PIN_NO(7) | 2) +#define PINMUX_GPIO7__FUNC_SRCLKENAI1 (MTK_PIN_NO(7) | 3) +#define PINMUX_GPIO7__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(7) | 4) +#define PINMUX_GPIO7__FUNC_DMIC_DAT (MTK_PIN_NO(7) | 5) +#define PINMUX_GPIO7__FUNC_TP_GPIO7_AO (MTK_PIN_NO(7) | 6) +#define PINMUX_GPIO7__FUNC_SDA9 (MTK_PIN_NO(7) | 7) + +#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define PINMUX_GPIO8__FUNC_PWM_0 (MTK_PIN_NO(8) | 1) +#define PINMUX_GPIO8__FUNC_I2S2_DI2 (MTK_PIN_NO(8) | 2) +#define PINMUX_GPIO8__FUNC_SRCLKENAI0 (MTK_PIN_NO(8) | 3) +#define PINMUX_GPIO8__FUNC_URXD1 (MTK_PIN_NO(8) | 4) +#define PINMUX_GPIO8__FUNC_I2S0_MCK (MTK_PIN_NO(8) | 5) +#define PINMUX_GPIO8__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(8) | 6) +#define PINMUX_GPIO8__FUNC_IDDIG (MTK_PIN_NO(8) | 7) + +#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define PINMUX_GPIO9__FUNC_PWM_3 (MTK_PIN_NO(9) | 1) +#define PINMUX_GPIO9__FUNC_MD_INT0 (MTK_PIN_NO(9) | 2) +#define PINMUX_GPIO9__FUNC_SRCLKENAI1 (MTK_PIN_NO(9) | 3) +#define PINMUX_GPIO9__FUNC_UTXD1 (MTK_PIN_NO(9) | 4) +#define PINMUX_GPIO9__FUNC_I2S0_BCK (MTK_PIN_NO(9) | 5) +#define PINMUX_GPIO9__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(9) | 6) +#define PINMUX_GPIO9__FUNC_USB_DRVVBUS (MTK_PIN_NO(9) | 7) + +#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define PINMUX_GPIO10__FUNC_MSDC1_CLK_A (MTK_PIN_NO(10) | 1) +#define PINMUX_GPIO10__FUNC_TP_URXD1_AO (MTK_PIN_NO(10) | 2) +#define PINMUX_GPIO10__FUNC_I2S1_LRCK (MTK_PIN_NO(10) | 3) +#define PINMUX_GPIO10__FUNC_UCTS0 (MTK_PIN_NO(10) | 4) +#define PINMUX_GPIO10__FUNC_DMIC1_CLK (MTK_PIN_NO(10) | 5) +#define PINMUX_GPIO10__FUNC_KPCOL2 (MTK_PIN_NO(10) | 6) +#define PINMUX_GPIO10__FUNC_SCL8 (MTK_PIN_NO(10) | 7) + +#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define PINMUX_GPIO11__FUNC_MSDC1_CMD_A (MTK_PIN_NO(11) | 1) +#define PINMUX_GPIO11__FUNC_TP_UTXD1_AO (MTK_PIN_NO(11) | 2) +#define PINMUX_GPIO11__FUNC_I2S1_DO (MTK_PIN_NO(11) | 3) +#define PINMUX_GPIO11__FUNC_URTS0 (MTK_PIN_NO(11) | 4) +#define PINMUX_GPIO11__FUNC_DMIC1_DAT (MTK_PIN_NO(11) | 5) +#define PINMUX_GPIO11__FUNC_KPROW2 (MTK_PIN_NO(11) | 6) +#define PINMUX_GPIO11__FUNC_SDA8 (MTK_PIN_NO(11) | 7) + +#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define PINMUX_GPIO12__FUNC_MSDC1_DAT3_A (MTK_PIN_NO(12) | 1) +#define PINMUX_GPIO12__FUNC_TP_URXD2_AO (MTK_PIN_NO(12) | 2) +#define PINMUX_GPIO12__FUNC_I2S1_MCK (MTK_PIN_NO(12) | 3) +#define PINMUX_GPIO12__FUNC_UCTS1 (MTK_PIN_NO(12) | 4) +#define PINMUX_GPIO12__FUNC_DMIC_CLK (MTK_PIN_NO(12) | 5) +#define PINMUX_GPIO12__FUNC_ANT_SEL9 (MTK_PIN_NO(12) | 6) +#define PINMUX_GPIO12__FUNC_SCL9 (MTK_PIN_NO(12) | 7) + +#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define PINMUX_GPIO13__FUNC_MSDC1_DAT0_A (MTK_PIN_NO(13) | 1) +#define PINMUX_GPIO13__FUNC_TP_UTXD2_AO (MTK_PIN_NO(13) | 2) +#define PINMUX_GPIO13__FUNC_I2S1_BCK (MTK_PIN_NO(13) | 3) +#define PINMUX_GPIO13__FUNC_URTS1 (MTK_PIN_NO(13) | 4) +#define PINMUX_GPIO13__FUNC_DMIC_DAT (MTK_PIN_NO(13) | 5) +#define PINMUX_GPIO13__FUNC_ANT_SEL10 (MTK_PIN_NO(13) | 6) +#define PINMUX_GPIO13__FUNC_SDA9 (MTK_PIN_NO(13) | 7) + +#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define PINMUX_GPIO14__FUNC_MSDC1_DAT2_A (MTK_PIN_NO(14) | 1) +#define PINMUX_GPIO14__FUNC_PWM_3 (MTK_PIN_NO(14) | 2) +#define PINMUX_GPIO14__FUNC_IDDIG (MTK_PIN_NO(14) | 3) +#define PINMUX_GPIO14__FUNC_MD_INT0 (MTK_PIN_NO(14) | 4) +#define PINMUX_GPIO14__FUNC_PTA_RXD (MTK_PIN_NO(14) | 5) +#define PINMUX_GPIO14__FUNC_ANT_SEL11 (MTK_PIN_NO(14) | 6) + +#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define PINMUX_GPIO15__FUNC_MSDC1_DAT1_A (MTK_PIN_NO(15) | 1) +#define PINMUX_GPIO15__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(15) | 2) +#define PINMUX_GPIO15__FUNC_USB_DRVVBUS (MTK_PIN_NO(15) | 3) +#define PINMUX_GPIO15__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(15) | 4) +#define PINMUX_GPIO15__FUNC_PTA_TXD (MTK_PIN_NO(15) | 5) +#define PINMUX_GPIO15__FUNC_ANT_SEL12 (MTK_PIN_NO(15) | 6) + +#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define PINMUX_GPIO16__FUNC_SRCLKENAI0 (MTK_PIN_NO(16) | 1) +#define PINMUX_GPIO16__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(16) | 2) +#define PINMUX_GPIO16__FUNC_MFG_EJTAG_TRSTN (MTK_PIN_NO(16) | 3) +#define PINMUX_GPIO16__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(16) | 4) +#define PINMUX_GPIO16__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(16) | 5) +#define PINMUX_GPIO16__FUNC_PWM_2 (MTK_PIN_NO(16) | 6) +#define PINMUX_GPIO16__FUNC_JTRSTN_SEL1 (MTK_PIN_NO(16) | 7) + +#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define PINMUX_GPIO17__FUNC_SPI0_A_MI (MTK_PIN_NO(17) | 1) +#define PINMUX_GPIO17__FUNC_SCP_SPI0_MI (MTK_PIN_NO(17) | 2) +#define PINMUX_GPIO17__FUNC_MFG_EJTAG_TDO (MTK_PIN_NO(17) | 3) +#define PINMUX_GPIO17__FUNC_DPI_HSYNC (MTK_PIN_NO(17) | 4) +#define PINMUX_GPIO17__FUNC_MFG_DFD_JTAG_TDO (MTK_PIN_NO(17) | 5) +#define PINMUX_GPIO17__FUNC_DFD_TDO (MTK_PIN_NO(17) | 6) +#define PINMUX_GPIO17__FUNC_JTDO_SEL1 (MTK_PIN_NO(17) | 7) + +#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define PINMUX_GPIO18__FUNC_SPI0_A_MO (MTK_PIN_NO(18) | 1) +#define PINMUX_GPIO18__FUNC_SCP_SPI0_MO (MTK_PIN_NO(18) | 2) +#define PINMUX_GPIO18__FUNC_MFG_EJTAG_TDI (MTK_PIN_NO(18) | 3) +#define PINMUX_GPIO18__FUNC_DPI_VSYNC (MTK_PIN_NO(18) | 4) +#define PINMUX_GPIO18__FUNC_MFG_DFD_JTAG_TDI (MTK_PIN_NO(18) | 5) +#define PINMUX_GPIO18__FUNC_DFD_TDI (MTK_PIN_NO(18) | 6) +#define PINMUX_GPIO18__FUNC_JTDI_SEL1 (MTK_PIN_NO(18) | 7) + +#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define PINMUX_GPIO19__FUNC_SPI0_A_CSB (MTK_PIN_NO(19) | 1) +#define PINMUX_GPIO19__FUNC_SCP_SPI0_CS (MTK_PIN_NO(19) | 2) +#define PINMUX_GPIO19__FUNC_MFG_EJTAG_TMS (MTK_PIN_NO(19) | 3) +#define PINMUX_GPIO19__FUNC_DPI_DE (MTK_PIN_NO(19) | 4) +#define PINMUX_GPIO19__FUNC_MFG_DFD_JTAG_TMS (MTK_PIN_NO(19) | 5) +#define PINMUX_GPIO19__FUNC_DFD_TMS (MTK_PIN_NO(19) | 6) +#define PINMUX_GPIO19__FUNC_JTMS_SEL1 (MTK_PIN_NO(19) | 7) + +#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define PINMUX_GPIO20__FUNC_SPI0_A_CLK (MTK_PIN_NO(20) | 1) +#define PINMUX_GPIO20__FUNC_SCP_SPI0_CK (MTK_PIN_NO(20) | 2) +#define PINMUX_GPIO20__FUNC_MFG_EJTAG_TCK (MTK_PIN_NO(20) | 3) +#define PINMUX_GPIO20__FUNC_DPI_CK (MTK_PIN_NO(20) | 4) +#define PINMUX_GPIO20__FUNC_MFG_DFD_JTAG_TCK (MTK_PIN_NO(20) | 5) +#define PINMUX_GPIO20__FUNC_DFD_TCK_XI (MTK_PIN_NO(20) | 6) +#define PINMUX_GPIO20__FUNC_JTCK_SEL1 (MTK_PIN_NO(20) | 7) + +#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define PINMUX_GPIO21__FUNC_PWM_0 (MTK_PIN_NO(21) | 1) +#define PINMUX_GPIO21__FUNC_CMFLASH0 (MTK_PIN_NO(21) | 2) +#define PINMUX_GPIO21__FUNC_CMVREF2 (MTK_PIN_NO(21) | 3) +#define PINMUX_GPIO21__FUNC_CLKM0 (MTK_PIN_NO(21) | 4) +#define PINMUX_GPIO21__FUNC_ANT_SEL9 (MTK_PIN_NO(21) | 5) +#define PINMUX_GPIO21__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(21) | 6) +#define PINMUX_GPIO21__FUNC_DBG_MON_A27 (MTK_PIN_NO(21) | 7) + +#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define PINMUX_GPIO22__FUNC_PWM_1 (MTK_PIN_NO(22) | 1) +#define PINMUX_GPIO22__FUNC_CMFLASH1 (MTK_PIN_NO(22) | 2) +#define PINMUX_GPIO22__FUNC_CMVREF3 (MTK_PIN_NO(22) | 3) +#define PINMUX_GPIO22__FUNC_CLKM1 (MTK_PIN_NO(22) | 4) +#define PINMUX_GPIO22__FUNC_ANT_SEL10 (MTK_PIN_NO(22) | 5) +#define PINMUX_GPIO22__FUNC_DBG_MON_A28 (MTK_PIN_NO(22) | 7) + +#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define PINMUX_GPIO23__FUNC_PWM_2 (MTK_PIN_NO(23) | 1) +#define PINMUX_GPIO23__FUNC_CMFLASH2 (MTK_PIN_NO(23) | 2) +#define PINMUX_GPIO23__FUNC_CMVREF0 (MTK_PIN_NO(23) | 3) +#define PINMUX_GPIO23__FUNC_CLKM2 (MTK_PIN_NO(23) | 4) +#define PINMUX_GPIO23__FUNC_ANT_SEL11 (MTK_PIN_NO(23) | 5) +#define PINMUX_GPIO23__FUNC_DBG_MON_A29 (MTK_PIN_NO(23) | 7) + +#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define PINMUX_GPIO24__FUNC_PWM_0 (MTK_PIN_NO(24) | 1) +#define PINMUX_GPIO24__FUNC_CMFLASH3 (MTK_PIN_NO(24) | 2) +#define PINMUX_GPIO24__FUNC_CMVREF1 (MTK_PIN_NO(24) | 3) +#define PINMUX_GPIO24__FUNC_CLKM3 (MTK_PIN_NO(24) | 4) +#define PINMUX_GPIO24__FUNC_ANT_SEL12 (MTK_PIN_NO(24) | 5) +#define PINMUX_GPIO24__FUNC_DBG_MON_A30 (MTK_PIN_NO(24) | 7) + +#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define PINMUX_GPIO25__FUNC_SRCLKENAI0 (MTK_PIN_NO(25) | 1) +#define PINMUX_GPIO25__FUNC_UCTS0 (MTK_PIN_NO(25) | 2) +#define PINMUX_GPIO25__FUNC_SCL8 (MTK_PIN_NO(25) | 3) +#define PINMUX_GPIO25__FUNC_CMVREF4 (MTK_PIN_NO(25) | 4) +#define PINMUX_GPIO25__FUNC_I2S0_LRCK (MTK_PIN_NO(25) | 5) +#define PINMUX_GPIO25__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(25) | 6) +#define PINMUX_GPIO25__FUNC_DBG_MON_A31 (MTK_PIN_NO(25) | 7) + +#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define PINMUX_GPIO26__FUNC_PWM_0 (MTK_PIN_NO(26) | 1) +#define PINMUX_GPIO26__FUNC_URTS0 (MTK_PIN_NO(26) | 2) +#define PINMUX_GPIO26__FUNC_SDA8 (MTK_PIN_NO(26) | 3) +#define PINMUX_GPIO26__FUNC_CLKM0 (MTK_PIN_NO(26) | 4) +#define PINMUX_GPIO26__FUNC_I2S0_DI (MTK_PIN_NO(26) | 5) +#define PINMUX_GPIO26__FUNC_AGPS_SYNC (MTK_PIN_NO(26) | 6) +#define PINMUX_GPIO26__FUNC_DBG_MON_A32 (MTK_PIN_NO(26) | 7) + +#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define PINMUX_GPIO27__FUNC_AP_GOOD (MTK_PIN_NO(27) | 1) + +#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define PINMUX_GPIO28__FUNC_SCL5 (MTK_PIN_NO(28) | 1) + +#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define PINMUX_GPIO29__FUNC_SDA5 (MTK_PIN_NO(29) | 1) + +#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define PINMUX_GPIO30__FUNC_I2S1_MCK (MTK_PIN_NO(30) | 1) +#define PINMUX_GPIO30__FUNC_I2S3_MCK (MTK_PIN_NO(30) | 2) +#define PINMUX_GPIO30__FUNC_I2S2_MCK (MTK_PIN_NO(30) | 3) +#define PINMUX_GPIO30__FUNC_DPI_D0 (MTK_PIN_NO(30) | 4) +#define PINMUX_GPIO30__FUNC_SPI4_MI (MTK_PIN_NO(30) | 5) +#define PINMUX_GPIO30__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(30) | 6) + +#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define PINMUX_GPIO31__FUNC_I2S1_BCK (MTK_PIN_NO(31) | 1) +#define PINMUX_GPIO31__FUNC_I2S3_BCK (MTK_PIN_NO(31) | 2) +#define PINMUX_GPIO31__FUNC_I2S2_BCK (MTK_PIN_NO(31) | 3) +#define PINMUX_GPIO31__FUNC_DPI_D1 (MTK_PIN_NO(31) | 4) +#define PINMUX_GPIO31__FUNC_SPI4_CSB (MTK_PIN_NO(31) | 5) +#define PINMUX_GPIO31__FUNC_CONN_MCU_TDO (MTK_PIN_NO(31) | 6) + +#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define PINMUX_GPIO32__FUNC_I2S1_LRCK (MTK_PIN_NO(32) | 1) +#define PINMUX_GPIO32__FUNC_I2S3_LRCK (MTK_PIN_NO(32) | 2) +#define PINMUX_GPIO32__FUNC_I2S2_LRCK (MTK_PIN_NO(32) | 3) +#define PINMUX_GPIO32__FUNC_DPI_D2 (MTK_PIN_NO(32) | 4) +#define PINMUX_GPIO32__FUNC_SPI4_MO (MTK_PIN_NO(32) | 5) +#define PINMUX_GPIO32__FUNC_CONN_MCU_TDI (MTK_PIN_NO(32) | 6) + +#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define PINMUX_GPIO33__FUNC_I2S2_DI (MTK_PIN_NO(33) | 1) +#define PINMUX_GPIO33__FUNC_I2S0_DI (MTK_PIN_NO(33) | 2) +#define PINMUX_GPIO33__FUNC_I2S5_DO (MTK_PIN_NO(33) | 3) +#define PINMUX_GPIO33__FUNC_DPI_D3 (MTK_PIN_NO(33) | 4) +#define PINMUX_GPIO33__FUNC_SPI4_CLK (MTK_PIN_NO(33) | 5) +#define PINMUX_GPIO33__FUNC_CONN_MCU_TMS (MTK_PIN_NO(33) | 6) + +#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define PINMUX_GPIO34__FUNC_I2S1_DO (MTK_PIN_NO(34) | 1) +#define PINMUX_GPIO34__FUNC_I2S3_DO (MTK_PIN_NO(34) | 2) +#define PINMUX_GPIO34__FUNC_I2S2_DI2 (MTK_PIN_NO(34) | 3) +#define PINMUX_GPIO34__FUNC_DPI_D4 (MTK_PIN_NO(34) | 4) +#define PINMUX_GPIO34__FUNC_AGPS_SYNC (MTK_PIN_NO(34) | 5) +#define PINMUX_GPIO34__FUNC_CONN_MCU_TCK (MTK_PIN_NO(34) | 6) + +#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define PINMUX_GPIO35__FUNC_TDM_LRCK (MTK_PIN_NO(35) | 1) +#define PINMUX_GPIO35__FUNC_I2S1_LRCK (MTK_PIN_NO(35) | 2) +#define PINMUX_GPIO35__FUNC_I2S5_LRCK (MTK_PIN_NO(35) | 3) +#define PINMUX_GPIO35__FUNC_DPI_D5 (MTK_PIN_NO(35) | 4) +#define PINMUX_GPIO35__FUNC_SPI5_A_MO (MTK_PIN_NO(35) | 5) +#define PINMUX_GPIO35__FUNC_IO_JTAG_TDI (MTK_PIN_NO(35) | 6) +#define PINMUX_GPIO35__FUNC_PWM_2 (MTK_PIN_NO(35) | 7) + +#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define PINMUX_GPIO36__FUNC_TDM_BCK (MTK_PIN_NO(36) | 1) +#define PINMUX_GPIO36__FUNC_I2S1_BCK (MTK_PIN_NO(36) | 2) +#define PINMUX_GPIO36__FUNC_I2S5_BCK (MTK_PIN_NO(36) | 3) +#define PINMUX_GPIO36__FUNC_DPI_D6 (MTK_PIN_NO(36) | 4) +#define PINMUX_GPIO36__FUNC_SPI5_A_CSB (MTK_PIN_NO(36) | 5) +#define PINMUX_GPIO36__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(36) | 6) +#define PINMUX_GPIO36__FUNC_SRCLKENAI1 (MTK_PIN_NO(36) | 7) + +#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define PINMUX_GPIO37__FUNC_TDM_MCK (MTK_PIN_NO(37) | 1) +#define PINMUX_GPIO37__FUNC_I2S1_MCK (MTK_PIN_NO(37) | 2) +#define PINMUX_GPIO37__FUNC_I2S5_MCK (MTK_PIN_NO(37) | 3) +#define PINMUX_GPIO37__FUNC_DPI_D7 (MTK_PIN_NO(37) | 4) +#define PINMUX_GPIO37__FUNC_SPI5_A_MI (MTK_PIN_NO(37) | 5) +#define PINMUX_GPIO37__FUNC_IO_JTAG_TCK (MTK_PIN_NO(37) | 6) +#define PINMUX_GPIO37__FUNC_SRCLKENAI0 (MTK_PIN_NO(37) | 7) + +#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define PINMUX_GPIO38__FUNC_TDM_DATA0 (MTK_PIN_NO(38) | 1) +#define PINMUX_GPIO38__FUNC_I2S2_DI (MTK_PIN_NO(38) | 2) +#define PINMUX_GPIO38__FUNC_I2S5_DO (MTK_PIN_NO(38) | 3) +#define PINMUX_GPIO38__FUNC_DPI_D8 (MTK_PIN_NO(38) | 4) +#define PINMUX_GPIO38__FUNC_SPI5_A_CLK (MTK_PIN_NO(38) | 5) +#define PINMUX_GPIO38__FUNC_IO_JTAG_TDO (MTK_PIN_NO(38) | 6) +#define PINMUX_GPIO38__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(38) | 7) + +#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define PINMUX_GPIO39__FUNC_TDM_DATA1 (MTK_PIN_NO(39) | 1) +#define PINMUX_GPIO39__FUNC_I2S1_DO (MTK_PIN_NO(39) | 2) +#define PINMUX_GPIO39__FUNC_I2S2_DI2 (MTK_PIN_NO(39) | 3) +#define PINMUX_GPIO39__FUNC_DPI_D9 (MTK_PIN_NO(39) | 4) +#define PINMUX_GPIO39__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(39) | 5) +#define PINMUX_GPIO39__FUNC_IO_JTAG_TMS (MTK_PIN_NO(39) | 6) +#define PINMUX_GPIO39__FUNC_IDDIG (MTK_PIN_NO(39) | 7) + +#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define PINMUX_GPIO40__FUNC_TDM_DATA2 (MTK_PIN_NO(40) | 1) +#define PINMUX_GPIO40__FUNC_SCL9 (MTK_PIN_NO(40) | 2) +#define PINMUX_GPIO40__FUNC_PWM_3 (MTK_PIN_NO(40) | 3) +#define PINMUX_GPIO40__FUNC_DPI_D10 (MTK_PIN_NO(40) | 4) +#define PINMUX_GPIO40__FUNC_SRCLKENAI0 (MTK_PIN_NO(40) | 5) +#define PINMUX_GPIO40__FUNC_DAP_MD32_SWD (MTK_PIN_NO(40) | 6) +#define PINMUX_GPIO40__FUNC_USB_DRVVBUS (MTK_PIN_NO(40) | 7) + +#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define PINMUX_GPIO41__FUNC_TDM_DATA3 (MTK_PIN_NO(41) | 1) +#define PINMUX_GPIO41__FUNC_SDA9 (MTK_PIN_NO(41) | 2) +#define PINMUX_GPIO41__FUNC_PWM_1 (MTK_PIN_NO(41) | 3) +#define PINMUX_GPIO41__FUNC_DPI_D11 (MTK_PIN_NO(41) | 4) +#define PINMUX_GPIO41__FUNC_CLKM1 (MTK_PIN_NO(41) | 5) +#define PINMUX_GPIO41__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(41) | 6) + +#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define PINMUX_GPIO42__FUNC_DISP_PWM (MTK_PIN_NO(42) | 1) + +#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define PINMUX_GPIO43__FUNC_DSI_TE (MTK_PIN_NO(43) | 1) + +#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define PINMUX_GPIO44__FUNC_LCM_RST (MTK_PIN_NO(44) | 1) + +#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define PINMUX_GPIO45__FUNC_SCL6 (MTK_PIN_NO(45) | 1) +#define PINMUX_GPIO45__FUNC_SCP_SCL0 (MTK_PIN_NO(45) | 2) +#define PINMUX_GPIO45__FUNC_SCP_SCL1 (MTK_PIN_NO(45) | 3) +#define PINMUX_GPIO45__FUNC_SCL_6306 (MTK_PIN_NO(45) | 4) + +#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define PINMUX_GPIO46__FUNC_SDA6 (MTK_PIN_NO(46) | 1) +#define PINMUX_GPIO46__FUNC_SCP_SDA0 (MTK_PIN_NO(46) | 2) +#define PINMUX_GPIO46__FUNC_SCP_SDA1 (MTK_PIN_NO(46) | 3) +#define PINMUX_GPIO46__FUNC_SDA_6306 (MTK_PIN_NO(46) | 4) + +#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define PINMUX_GPIO47__FUNC_SPI1_A_MI (MTK_PIN_NO(47) | 1) +#define PINMUX_GPIO47__FUNC_SCP_SPI1_A_MI (MTK_PIN_NO(47) | 2) +#define PINMUX_GPIO47__FUNC_KPCOL2 (MTK_PIN_NO(47) | 3) +#define PINMUX_GPIO47__FUNC_MD_URXD0 (MTK_PIN_NO(47) | 4) +#define PINMUX_GPIO47__FUNC_CONN_UART0_RXD (MTK_PIN_NO(47) | 5) +#define PINMUX_GPIO47__FUNC_SSPM_URXD_AO (MTK_PIN_NO(47) | 6) +#define PINMUX_GPIO47__FUNC_DBG_MON_B32 (MTK_PIN_NO(47) | 7) + +#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define PINMUX_GPIO48__FUNC_SPI1_A_CSB (MTK_PIN_NO(48) | 1) +#define PINMUX_GPIO48__FUNC_SCP_SPI1_A_CS (MTK_PIN_NO(48) | 2) +#define PINMUX_GPIO48__FUNC_KPROW2 (MTK_PIN_NO(48) | 3) +#define PINMUX_GPIO48__FUNC_MD_UTXD0 (MTK_PIN_NO(48) | 4) +#define PINMUX_GPIO48__FUNC_CONN_UART0_TXD (MTK_PIN_NO(48) | 5) +#define PINMUX_GPIO48__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(48) | 6) +#define PINMUX_GPIO48__FUNC_DBG_MON_B31 (MTK_PIN_NO(48) | 7) + +#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define PINMUX_GPIO49__FUNC_SPI1_A_MO (MTK_PIN_NO(49) | 1) +#define PINMUX_GPIO49__FUNC_SCP_SPI1_A_MO (MTK_PIN_NO(49) | 2) +#define PINMUX_GPIO49__FUNC_UCTS0 (MTK_PIN_NO(49) | 3) +#define PINMUX_GPIO49__FUNC_MD_URXD1 (MTK_PIN_NO(49) | 4) +#define PINMUX_GPIO49__FUNC_PWM_1 (MTK_PIN_NO(49) | 5) +#define PINMUX_GPIO49__FUNC_TP_URXD2_AO (MTK_PIN_NO(49) | 6) +#define PINMUX_GPIO49__FUNC_DBG_MON_B30 (MTK_PIN_NO(49) | 7) + +#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define PINMUX_GPIO50__FUNC_SPI1_A_CLK (MTK_PIN_NO(50) | 1) +#define PINMUX_GPIO50__FUNC_SCP_SPI1_A_CK (MTK_PIN_NO(50) | 2) +#define PINMUX_GPIO50__FUNC_URTS0 (MTK_PIN_NO(50) | 3) +#define PINMUX_GPIO50__FUNC_MD_UTXD1 (MTK_PIN_NO(50) | 4) +#define PINMUX_GPIO50__FUNC_WIFI_TXD (MTK_PIN_NO(50) | 5) +#define PINMUX_GPIO50__FUNC_TP_UTXD2_AO (MTK_PIN_NO(50) | 6) +#define PINMUX_GPIO50__FUNC_DBG_MON_B29 (MTK_PIN_NO(50) | 7) + +#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define PINMUX_GPIO51__FUNC_SCL0 (MTK_PIN_NO(51) | 1) + +#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define PINMUX_GPIO52__FUNC_SDA0 (MTK_PIN_NO(52) | 1) + +#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define PINMUX_GPIO53__FUNC_URXD0 (MTK_PIN_NO(53) | 1) +#define PINMUX_GPIO53__FUNC_UTXD0 (MTK_PIN_NO(53) | 2) +#define PINMUX_GPIO53__FUNC_MD_URXD0 (MTK_PIN_NO(53) | 3) +#define PINMUX_GPIO53__FUNC_MD_URXD1 (MTK_PIN_NO(53) | 4) +#define PINMUX_GPIO53__FUNC_SSPM_URXD_AO (MTK_PIN_NO(53) | 5) +#define PINMUX_GPIO53__FUNC_CONN_UART0_RXD (MTK_PIN_NO(53) | 7) + +#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define PINMUX_GPIO54__FUNC_UTXD0 (MTK_PIN_NO(54) | 1) +#define PINMUX_GPIO54__FUNC_URXD0 (MTK_PIN_NO(54) | 2) +#define PINMUX_GPIO54__FUNC_MD_UTXD0 (MTK_PIN_NO(54) | 3) +#define PINMUX_GPIO54__FUNC_MD_UTXD1 (MTK_PIN_NO(54) | 4) +#define PINMUX_GPIO54__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(54) | 5) +#define PINMUX_GPIO54__FUNC_WIFI_TXD (MTK_PIN_NO(54) | 6) +#define PINMUX_GPIO54__FUNC_CONN_UART0_TXD (MTK_PIN_NO(54) | 7) + +#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define PINMUX_GPIO55__FUNC_SCL3 (MTK_PIN_NO(55) | 1) +#define PINMUX_GPIO55__FUNC_SCP_SCL0 (MTK_PIN_NO(55) | 2) +#define PINMUX_GPIO55__FUNC_SCP_SCL1 (MTK_PIN_NO(55) | 3) +#define PINMUX_GPIO55__FUNC_SCL_6306 (MTK_PIN_NO(55) | 4) + +#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define PINMUX_GPIO56__FUNC_SDA3 (MTK_PIN_NO(56) | 1) +#define PINMUX_GPIO56__FUNC_SCP_SDA0 (MTK_PIN_NO(56) | 2) +#define PINMUX_GPIO56__FUNC_SCP_SDA1 (MTK_PIN_NO(56) | 3) +#define PINMUX_GPIO56__FUNC_SDA_6306 (MTK_PIN_NO(56) | 4) + +#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define PINMUX_GPIO57__FUNC_KPROW1 (MTK_PIN_NO(57) | 1) +#define PINMUX_GPIO57__FUNC_PWM_1 (MTK_PIN_NO(57) | 2) +#define PINMUX_GPIO57__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(57) | 3) +#define PINMUX_GPIO57__FUNC_CLKM1 (MTK_PIN_NO(57) | 4) +#define PINMUX_GPIO57__FUNC_IDDIG (MTK_PIN_NO(57) | 5) +#define PINMUX_GPIO57__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(57) | 6) +#define PINMUX_GPIO57__FUNC_MBISTREADEN_TRIGGER (MTK_PIN_NO(57) | 7) + +#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define PINMUX_GPIO58__FUNC_KPROW0 (MTK_PIN_NO(58) | 1) +#define PINMUX_GPIO58__FUNC_DBG_MON_B28 (MTK_PIN_NO(58) | 7) + +#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define PINMUX_GPIO59__FUNC_KPCOL0 (MTK_PIN_NO(59) | 1) +#define PINMUX_GPIO59__FUNC_DBG_MON_B27 (MTK_PIN_NO(59) | 7) + +#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define PINMUX_GPIO60__FUNC_KPCOL1 (MTK_PIN_NO(60) | 1) +#define PINMUX_GPIO60__FUNC_PWM_2 (MTK_PIN_NO(60) | 2) +#define PINMUX_GPIO60__FUNC_UCTS1 (MTK_PIN_NO(60) | 3) +#define PINMUX_GPIO60__FUNC_CLKM2 (MTK_PIN_NO(60) | 4) +#define PINMUX_GPIO60__FUNC_USB_DRVVBUS (MTK_PIN_NO(60) | 5) +#define PINMUX_GPIO60__FUNC_MBISTWRITEEN_TRIGGER (MTK_PIN_NO(60) | 7) + +#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define PINMUX_GPIO61__FUNC_SCL1 (MTK_PIN_NO(61) | 1) +#define PINMUX_GPIO61__FUNC_SCP_SCL0 (MTK_PIN_NO(61) | 2) +#define PINMUX_GPIO61__FUNC_SCP_SCL1 (MTK_PIN_NO(61) | 3) + +#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define PINMUX_GPIO62__FUNC_SDA1 (MTK_PIN_NO(62) | 1) +#define PINMUX_GPIO62__FUNC_SCP_SDA0 (MTK_PIN_NO(62) | 2) +#define PINMUX_GPIO62__FUNC_SCP_SDA1 (MTK_PIN_NO(62) | 3) + +#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define PINMUX_GPIO63__FUNC_SPI2_MI (MTK_PIN_NO(63) | 1) +#define PINMUX_GPIO63__FUNC_SCP_SPI2_MI (MTK_PIN_NO(63) | 2) +#define PINMUX_GPIO63__FUNC_KPCOL2 (MTK_PIN_NO(63) | 3) +#define PINMUX_GPIO63__FUNC_MRG_DI (MTK_PIN_NO(63) | 4) +#define PINMUX_GPIO63__FUNC_MD_URXD0 (MTK_PIN_NO(63) | 5) +#define PINMUX_GPIO63__FUNC_CONN_UART0_RXD (MTK_PIN_NO(63) | 6) +#define PINMUX_GPIO63__FUNC_DBG_MON_B26 (MTK_PIN_NO(63) | 7) + +#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define PINMUX_GPIO64__FUNC_SPI2_CSB (MTK_PIN_NO(64) | 1) +#define PINMUX_GPIO64__FUNC_SCP_SPI2_CS (MTK_PIN_NO(64) | 2) +#define PINMUX_GPIO64__FUNC_KPROW2 (MTK_PIN_NO(64) | 3) +#define PINMUX_GPIO64__FUNC_MRG_SYNC (MTK_PIN_NO(64) | 4) +#define PINMUX_GPIO64__FUNC_MD_UTXD0 (MTK_PIN_NO(64) | 5) +#define PINMUX_GPIO64__FUNC_CONN_UART0_TXD (MTK_PIN_NO(64) | 6) +#define PINMUX_GPIO64__FUNC_DBG_MON_B25 (MTK_PIN_NO(64) | 7) + +#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define PINMUX_GPIO65__FUNC_SPI2_MO (MTK_PIN_NO(65) | 1) +#define PINMUX_GPIO65__FUNC_SCP_SPI2_MO (MTK_PIN_NO(65) | 2) +#define PINMUX_GPIO65__FUNC_SCP_SDA1 (MTK_PIN_NO(65) | 3) +#define PINMUX_GPIO65__FUNC_MRG_DO (MTK_PIN_NO(65) | 4) +#define PINMUX_GPIO65__FUNC_MD_URXD1 (MTK_PIN_NO(65) | 5) +#define PINMUX_GPIO65__FUNC_PWM_3 (MTK_PIN_NO(65) | 6) + +#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define PINMUX_GPIO66__FUNC_SPI2_CLK (MTK_PIN_NO(66) | 1) +#define PINMUX_GPIO66__FUNC_SCP_SPI2_CK (MTK_PIN_NO(66) | 2) +#define PINMUX_GPIO66__FUNC_SCP_SCL1 (MTK_PIN_NO(66) | 3) +#define PINMUX_GPIO66__FUNC_MRG_CLK (MTK_PIN_NO(66) | 4) +#define PINMUX_GPIO66__FUNC_MD_UTXD1 (MTK_PIN_NO(66) | 5) +#define PINMUX_GPIO66__FUNC_WIFI_TXD (MTK_PIN_NO(66) | 6) + +#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define PINMUX_GPIO67__FUNC_I2S3_LRCK (MTK_PIN_NO(67) | 1) +#define PINMUX_GPIO67__FUNC_I2S1_LRCK (MTK_PIN_NO(67) | 2) +#define PINMUX_GPIO67__FUNC_URXD1 (MTK_PIN_NO(67) | 3) +#define PINMUX_GPIO67__FUNC_PCM0_SYNC (MTK_PIN_NO(67) | 4) +#define PINMUX_GPIO67__FUNC_I2S5_LRCK (MTK_PIN_NO(67) | 5) +#define PINMUX_GPIO67__FUNC_ANT_SEL9 (MTK_PIN_NO(67) | 6) +#define PINMUX_GPIO67__FUNC_DBG_MON_B10 (MTK_PIN_NO(67) | 7) + +#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define PINMUX_GPIO68__FUNC_I2S3_DO (MTK_PIN_NO(68) | 1) +#define PINMUX_GPIO68__FUNC_I2S1_DO (MTK_PIN_NO(68) | 2) +#define PINMUX_GPIO68__FUNC_UTXD1 (MTK_PIN_NO(68) | 3) +#define PINMUX_GPIO68__FUNC_PCM0_DO (MTK_PIN_NO(68) | 4) +#define PINMUX_GPIO68__FUNC_I2S5_DO (MTK_PIN_NO(68) | 5) +#define PINMUX_GPIO68__FUNC_ANT_SEL10 (MTK_PIN_NO(68) | 6) +#define PINMUX_GPIO68__FUNC_DBG_MON_B9 (MTK_PIN_NO(68) | 7) + +#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define PINMUX_GPIO69__FUNC_I2S3_MCK (MTK_PIN_NO(69) | 1) +#define PINMUX_GPIO69__FUNC_I2S1_MCK (MTK_PIN_NO(69) | 2) +#define PINMUX_GPIO69__FUNC_URTS1 (MTK_PIN_NO(69) | 3) +#define PINMUX_GPIO69__FUNC_AGPS_SYNC (MTK_PIN_NO(69) | 4) +#define PINMUX_GPIO69__FUNC_I2S5_MCK (MTK_PIN_NO(69) | 5) +#define PINMUX_GPIO69__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(69) | 6) +#define PINMUX_GPIO69__FUNC_DBG_MON_B8 (MTK_PIN_NO(69) | 7) + +#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define PINMUX_GPIO70__FUNC_I2S0_DI (MTK_PIN_NO(70) | 1) +#define PINMUX_GPIO70__FUNC_I2S2_DI (MTK_PIN_NO(70) | 2) +#define PINMUX_GPIO70__FUNC_KPCOL2 (MTK_PIN_NO(70) | 3) +#define PINMUX_GPIO70__FUNC_PCM0_DI (MTK_PIN_NO(70) | 4) +#define PINMUX_GPIO70__FUNC_I2S2_DI2 (MTK_PIN_NO(70) | 5) +#define PINMUX_GPIO70__FUNC_ANT_SEL11 (MTK_PIN_NO(70) | 6) +#define PINMUX_GPIO70__FUNC_DBG_MON_B7 (MTK_PIN_NO(70) | 7) + +#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define PINMUX_GPIO71__FUNC_I2S3_BCK (MTK_PIN_NO(71) | 1) +#define PINMUX_GPIO71__FUNC_I2S1_BCK (MTK_PIN_NO(71) | 2) +#define PINMUX_GPIO71__FUNC_KPROW2 (MTK_PIN_NO(71) | 3) +#define PINMUX_GPIO71__FUNC_PCM0_CLK (MTK_PIN_NO(71) | 4) +#define PINMUX_GPIO71__FUNC_I2S5_BCK (MTK_PIN_NO(71) | 5) +#define PINMUX_GPIO71__FUNC_ANT_SEL12 (MTK_PIN_NO(71) | 6) +#define PINMUX_GPIO71__FUNC_DBG_MON_B6 (MTK_PIN_NO(71) | 7) + +#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define PINMUX_GPIO72__FUNC_BPI_BUS19_OLAT0 (MTK_PIN_NO(72) | 1) +#define PINMUX_GPIO72__FUNC_CONN_BPI_BUS19_OLAT0 (MTK_PIN_NO(72) | 2) + +#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define PINMUX_GPIO73__FUNC_BPI_BUS18_PA_VM1 (MTK_PIN_NO(73) | 1) +#define PINMUX_GPIO73__FUNC_CONN_MIPI5_SCLK (MTK_PIN_NO(73) | 2) +#define PINMUX_GPIO73__FUNC_MIPI5_SCLK (MTK_PIN_NO(73) | 3) + +#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) +#define PINMUX_GPIO74__FUNC_BPI_BUS17_PA_VM0 (MTK_PIN_NO(74) | 1) +#define PINMUX_GPIO74__FUNC_CONN_MIPI5_SDATA (MTK_PIN_NO(74) | 2) +#define PINMUX_GPIO74__FUNC_MIPI5_SDATA (MTK_PIN_NO(74) | 3) + +#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) +#define PINMUX_GPIO75__FUNC_BPI_BUS20_OLAT1 (MTK_PIN_NO(75) | 1) +#define PINMUX_GPIO75__FUNC_CONN_BPI_BUS20_OLAT1 (MTK_PIN_NO(75) | 2) +#define PINMUX_GPIO75__FUNC_RFIC0_BSI_D2 (MTK_PIN_NO(75) | 3) + +#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) +#define PINMUX_GPIO76__FUNC_RFIC0_BSI_D1 (MTK_PIN_NO(76) | 1) + +#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) +#define PINMUX_GPIO77__FUNC_RFIC0_BSI_D0 (MTK_PIN_NO(77) | 1) + +#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) +#define PINMUX_GPIO78__FUNC_BPI_BUS7 (MTK_PIN_NO(78) | 1) +#define PINMUX_GPIO78__FUNC_DBG_MON_B24 (MTK_PIN_NO(78) | 7) + +#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define PINMUX_GPIO79__FUNC_BPI_BUS6 (MTK_PIN_NO(79) | 1) +#define PINMUX_GPIO79__FUNC_DBG_MON_B23 (MTK_PIN_NO(79) | 7) + +#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define PINMUX_GPIO80__FUNC_BPI_BUS8 (MTK_PIN_NO(80) | 1) +#define PINMUX_GPIO80__FUNC_DBG_MON_B22 (MTK_PIN_NO(80) | 7) + +#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define PINMUX_GPIO81__FUNC_BPI_BUS9 (MTK_PIN_NO(81) | 1) +#define PINMUX_GPIO81__FUNC_DBG_MON_B21 (MTK_PIN_NO(81) | 7) + +#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define PINMUX_GPIO82__FUNC_BPI_BUS10 (MTK_PIN_NO(82) | 1) +#define PINMUX_GPIO82__FUNC_DBG_MON_B20 (MTK_PIN_NO(82) | 7) + +#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) +#define PINMUX_GPIO83__FUNC_BPI_BUS11 (MTK_PIN_NO(83) | 1) +#define PINMUX_GPIO83__FUNC_DBG_MON_B19 (MTK_PIN_NO(83) | 7) + +#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) +#define PINMUX_GPIO84__FUNC_BPI_BUS12 (MTK_PIN_NO(84) | 1) +#define PINMUX_GPIO84__FUNC_CONN_BPI_BUS12 (MTK_PIN_NO(84) | 2) + +#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) +#define PINMUX_GPIO85__FUNC_BPI_BUS13 (MTK_PIN_NO(85) | 1) +#define PINMUX_GPIO85__FUNC_CONN_BPI_BUS13 (MTK_PIN_NO(85) | 2) + +#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) +#define PINMUX_GPIO86__FUNC_BPI_BUS14 (MTK_PIN_NO(86) | 1) +#define PINMUX_GPIO86__FUNC_CONN_BPI_BUS14 (MTK_PIN_NO(86) | 2) + +#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) +#define PINMUX_GPIO87__FUNC_BPI_BUS15 (MTK_PIN_NO(87) | 1) +#define PINMUX_GPIO87__FUNC_CONN_BPI_BUS15 (MTK_PIN_NO(87) | 2) + +#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) +#define PINMUX_GPIO88__FUNC_BPI_BUS16 (MTK_PIN_NO(88) | 1) +#define PINMUX_GPIO88__FUNC_CONN_BPI_BUS16 (MTK_PIN_NO(88) | 2) + +#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) +#define PINMUX_GPIO89__FUNC_BPI_BUS5 (MTK_PIN_NO(89) | 1) +#define PINMUX_GPIO89__FUNC_DBG_MON_B18 (MTK_PIN_NO(89) | 7) + +#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) +#define PINMUX_GPIO90__FUNC_BPI_BUS4 (MTK_PIN_NO(90) | 1) +#define PINMUX_GPIO90__FUNC_DBG_MON_B17 (MTK_PIN_NO(90) | 7) + +#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) +#define PINMUX_GPIO91__FUNC_BPI_BUS3 (MTK_PIN_NO(91) | 1) + +#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) +#define PINMUX_GPIO92__FUNC_BPI_BUS2 (MTK_PIN_NO(92) | 1) +#define PINMUX_GPIO92__FUNC_DBG_MON_B16 (MTK_PIN_NO(92) | 7) + +#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) +#define PINMUX_GPIO93__FUNC_BPI_BUS1 (MTK_PIN_NO(93) | 1) + +#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) +#define PINMUX_GPIO94__FUNC_BPI_BUS0 (MTK_PIN_NO(94) | 1) +#define PINMUX_GPIO94__FUNC_DBG_MON_B15 (MTK_PIN_NO(94) | 7) + +#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) +#define PINMUX_GPIO95__FUNC_MIPI0_SDATA (MTK_PIN_NO(95) | 1) + +#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) +#define PINMUX_GPIO96__FUNC_MIPI0_SCLK (MTK_PIN_NO(96) | 1) + +#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) +#define PINMUX_GPIO97__FUNC_MIPI1_SDATA (MTK_PIN_NO(97) | 1) + +#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) +#define PINMUX_GPIO98__FUNC_MIPI1_SCLK (MTK_PIN_NO(98) | 1) + +#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) +#define PINMUX_GPIO99__FUNC_MIPI2_SCLK (MTK_PIN_NO(99) | 1) +#define PINMUX_GPIO99__FUNC_DBG_MON_B14 (MTK_PIN_NO(99) | 7) + +#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define PINMUX_GPIO100__FUNC_MIPI2_SDATA (MTK_PIN_NO(100) | 1) +#define PINMUX_GPIO100__FUNC_DBG_MON_B13 (MTK_PIN_NO(100) | 7) + +#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define PINMUX_GPIO101__FUNC_MIPI3_SCLK (MTK_PIN_NO(101) | 1) +#define PINMUX_GPIO101__FUNC_DBG_MON_B12 (MTK_PIN_NO(101) | 7) + +#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define PINMUX_GPIO102__FUNC_MIPI3_SDATA (MTK_PIN_NO(102) | 1) +#define PINMUX_GPIO102__FUNC_DBG_MON_B11 (MTK_PIN_NO(102) | 7) + +#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define PINMUX_GPIO103__FUNC_MIPI4_SCLK (MTK_PIN_NO(103) | 1) +#define PINMUX_GPIO103__FUNC_CONN_MIPI4_SCLK (MTK_PIN_NO(103) | 2) + +#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define PINMUX_GPIO104__FUNC_MIPI4_SDATA (MTK_PIN_NO(104) | 1) +#define PINMUX_GPIO104__FUNC_CONN_MIPI4_SDATA (MTK_PIN_NO(104) | 2) + +#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define PINMUX_GPIO105__FUNC_BPI_BUS22_OLAT3 (MTK_PIN_NO(105) | 1) +#define PINMUX_GPIO105__FUNC_CONN_BPI_BUS22_OLAT3 (MTK_PIN_NO(105) | 2) + +#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define PINMUX_GPIO106__FUNC_BPI_BUS21_OLAT2 (MTK_PIN_NO(106) | 1) +#define PINMUX_GPIO106__FUNC_CONN_BPI_BUS21_OLAT2 (MTK_PIN_NO(106) | 2) + +#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define PINMUX_GPIO107__FUNC_BPI_BUS24_ANT1 (MTK_PIN_NO(107) | 1) +#define PINMUX_GPIO107__FUNC_CONN_BPI_BUS24_ANT1 (MTK_PIN_NO(107) | 2) + +#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define PINMUX_GPIO108__FUNC_BPI_BUS25_ANT2 (MTK_PIN_NO(108) | 1) +#define PINMUX_GPIO108__FUNC_CONN_BPI_BUS25_ANT2 (MTK_PIN_NO(108) | 2) + +#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define PINMUX_GPIO109__FUNC_BPI_BUS23_ANT0 (MTK_PIN_NO(109) | 1) +#define PINMUX_GPIO109__FUNC_CONN_BPI_BUS23_ANT0 (MTK_PIN_NO(109) | 2) + +#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define PINMUX_GPIO110__FUNC_SCL4 (MTK_PIN_NO(110) | 1) + +#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define PINMUX_GPIO111__FUNC_SDA4 (MTK_PIN_NO(111) | 1) + +#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define PINMUX_GPIO112__FUNC_SCL2 (MTK_PIN_NO(112) | 1) + +#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define PINMUX_GPIO113__FUNC_SDA2 (MTK_PIN_NO(113) | 1) + +#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define PINMUX_GPIO114__FUNC_CLKM0 (MTK_PIN_NO(114) | 1) +#define PINMUX_GPIO114__FUNC_SPI3_MI (MTK_PIN_NO(114) | 2) +#define PINMUX_GPIO114__FUNC_DBG_MON_B5 (MTK_PIN_NO(114) | 7) + +#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define PINMUX_GPIO115__FUNC_CLKM1 (MTK_PIN_NO(115) | 1) +#define PINMUX_GPIO115__FUNC_SPI3_CSB (MTK_PIN_NO(115) | 2) +#define PINMUX_GPIO115__FUNC_DBG_MON_B4 (MTK_PIN_NO(115) | 7) + +#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define PINMUX_GPIO116__FUNC_CMMCLK0 (MTK_PIN_NO(116) | 1) +#define PINMUX_GPIO116__FUNC_DBG_MON_B3 (MTK_PIN_NO(116) | 7) + +#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define PINMUX_GPIO117__FUNC_CMMCLK1 (MTK_PIN_NO(117) | 1) +#define PINMUX_GPIO117__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(117) | 2) +#define PINMUX_GPIO117__FUNC_DBG_MON_B2 (MTK_PIN_NO(117) | 7) + +#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define PINMUX_GPIO118__FUNC_CLKM2 (MTK_PIN_NO(118) | 1) +#define PINMUX_GPIO118__FUNC_SPI3_MO (MTK_PIN_NO(118) | 2) +#define PINMUX_GPIO118__FUNC_DBG_MON_B1 (MTK_PIN_NO(118) | 7) + +#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define PINMUX_GPIO119__FUNC_CLKM3 (MTK_PIN_NO(119) | 1) +#define PINMUX_GPIO119__FUNC_SPI3_CLK (MTK_PIN_NO(119) | 2) +#define PINMUX_GPIO119__FUNC_DBG_MON_B0 (MTK_PIN_NO(119) | 7) + +#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define PINMUX_GPIO120__FUNC_CMMCLK2 (MTK_PIN_NO(120) | 1) +#define PINMUX_GPIO120__FUNC_CLKM2 (MTK_PIN_NO(120) | 2) +#define PINMUX_GPIO120__FUNC_ANT_SEL12 (MTK_PIN_NO(120) | 6) +#define PINMUX_GPIO120__FUNC_TP_UCTS2_AO (MTK_PIN_NO(120) | 7) + +#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define PINMUX_GPIO121__FUNC_CMMCLK3 (MTK_PIN_NO(121) | 1) +#define PINMUX_GPIO121__FUNC_CLKM3 (MTK_PIN_NO(121) | 2) +#define PINMUX_GPIO121__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(121) | 3) +#define PINMUX_GPIO121__FUNC_ANT_SEL11 (MTK_PIN_NO(121) | 6) +#define PINMUX_GPIO121__FUNC_TP_URTS2_AO (MTK_PIN_NO(121) | 7) + +#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define PINMUX_GPIO122__FUNC_CMVREF1 (MTK_PIN_NO(122) | 1) +#define PINMUX_GPIO122__FUNC_PCM0_SYNC (MTK_PIN_NO(122) | 2) +#define PINMUX_GPIO122__FUNC_SRCLKENAI1 (MTK_PIN_NO(122) | 3) +#define PINMUX_GPIO122__FUNC_AGPS_SYNC (MTK_PIN_NO(122) | 4) +#define PINMUX_GPIO122__FUNC_PWM_1 (MTK_PIN_NO(122) | 5) +#define PINMUX_GPIO122__FUNC_ANT_SEL9 (MTK_PIN_NO(122) | 6) +#define PINMUX_GPIO122__FUNC_TP_UCTS1_AO (MTK_PIN_NO(122) | 7) + +#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define PINMUX_GPIO123__FUNC_PCM0_DI (MTK_PIN_NO(123) | 2) +#define PINMUX_GPIO123__FUNC_ADSP_JTAG_TRSTN (MTK_PIN_NO(123) | 3) +#define PINMUX_GPIO123__FUNC_VPU_UDI_NTRST (MTK_PIN_NO(123) | 4) +#define PINMUX_GPIO123__FUNC_SPM_JTAG_TRSTN (MTK_PIN_NO(123) | 5) +#define PINMUX_GPIO123__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(123) | 6) + +#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define PINMUX_GPIO124__FUNC_CMVREF2 (MTK_PIN_NO(124) | 1) +#define PINMUX_GPIO124__FUNC_PCM0_CLK (MTK_PIN_NO(124) | 2) +#define PINMUX_GPIO124__FUNC_MD_INT0 (MTK_PIN_NO(124) | 3) +#define PINMUX_GPIO124__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(124) | 4) +#define PINMUX_GPIO124__FUNC_PWM_2 (MTK_PIN_NO(124) | 5) +#define PINMUX_GPIO124__FUNC_ANT_SEL10 (MTK_PIN_NO(124) | 6) +#define PINMUX_GPIO124__FUNC_TP_URTS1_AO (MTK_PIN_NO(124) | 7) + +#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) +#define PINMUX_GPIO125__FUNC_CMVREF3 (MTK_PIN_NO(125) | 1) +#define PINMUX_GPIO125__FUNC_PCM0_DO (MTK_PIN_NO(125) | 2) +#define PINMUX_GPIO125__FUNC_ADSP_JTAG_TMS (MTK_PIN_NO(125) | 3) +#define PINMUX_GPIO125__FUNC_VPU_UDI_TMS (MTK_PIN_NO(125) | 4) +#define PINMUX_GPIO125__FUNC_SPM_JTAG_TMS (MTK_PIN_NO(125) | 5) +#define PINMUX_GPIO125__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(125) | 6) + +#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) +#define PINMUX_GPIO126__FUNC_CMVREF4 (MTK_PIN_NO(126) | 1) +#define PINMUX_GPIO126__FUNC_CMFLASH0 (MTK_PIN_NO(126) | 2) +#define PINMUX_GPIO126__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(126) | 6) + +#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) +#define PINMUX_GPIO127__FUNC_CMVREF0 (MTK_PIN_NO(127) | 1) +#define PINMUX_GPIO127__FUNC_CMFLASH1 (MTK_PIN_NO(127) | 2) +#define PINMUX_GPIO127__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(127) | 6) + +#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) +#define PINMUX_GPIO128__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(128) | 1) +#define PINMUX_GPIO128__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(128) | 2) +#define PINMUX_GPIO128__FUNC_CCU_JTAG_TRST (MTK_PIN_NO(128) | 3) +#define PINMUX_GPIO128__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(128) | 4) +#define PINMUX_GPIO128__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(128) | 5) +#define PINMUX_GPIO128__FUNC_LVTS_FOUT (MTK_PIN_NO(128) | 6) +#define PINMUX_GPIO128__FUNC_DBG_MON_A3 (MTK_PIN_NO(128) | 7) + +#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) +#define PINMUX_GPIO129__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(129) | 1) +#define PINMUX_GPIO129__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(129) | 2) +#define PINMUX_GPIO129__FUNC_CCU_JTAG_TCK (MTK_PIN_NO(129) | 3) +#define PINMUX_GPIO129__FUNC_CONN_DSP_JCK (MTK_PIN_NO(129) | 4) +#define PINMUX_GPIO129__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(129) | 5) +#define PINMUX_GPIO129__FUNC_LVTS_SDO (MTK_PIN_NO(129) | 6) +#define PINMUX_GPIO129__FUNC_DBG_MON_A4 (MTK_PIN_NO(129) | 7) + +#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) +#define PINMUX_GPIO130__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(130) | 1) +#define PINMUX_GPIO130__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(130) | 2) +#define PINMUX_GPIO130__FUNC_LVTS_26M (MTK_PIN_NO(130) | 6) +#define PINMUX_GPIO130__FUNC_DBG_MON_A5 (MTK_PIN_NO(130) | 7) + +#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) +#define PINMUX_GPIO131__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(131) | 1) +#define PINMUX_GPIO131__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(131) | 2) +#define PINMUX_GPIO131__FUNC_CCU_JTAG_TDI (MTK_PIN_NO(131) | 3) +#define PINMUX_GPIO131__FUNC_CONN_DSP_JDI (MTK_PIN_NO(131) | 4) +#define PINMUX_GPIO131__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(131) | 5) +#define PINMUX_GPIO131__FUNC_LVTS_SCK (MTK_PIN_NO(131) | 6) +#define PINMUX_GPIO131__FUNC_DBG_MON_A0 (MTK_PIN_NO(131) | 7) + +#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) +#define PINMUX_GPIO132__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(132) | 1) +#define PINMUX_GPIO132__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(132) | 2) +#define PINMUX_GPIO132__FUNC_CCU_JTAG_TMS (MTK_PIN_NO(132) | 3) +#define PINMUX_GPIO132__FUNC_CONN_DSP_JMS (MTK_PIN_NO(132) | 4) +#define PINMUX_GPIO132__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(132) | 5) +#define PINMUX_GPIO132__FUNC_LVTS_SDI (MTK_PIN_NO(132) | 6) +#define PINMUX_GPIO132__FUNC_DBG_MON_A1 (MTK_PIN_NO(132) | 7) + +#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) +#define PINMUX_GPIO133__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(133) | 1) +#define PINMUX_GPIO133__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(133) | 2) +#define PINMUX_GPIO133__FUNC_CCU_JTAG_TDO (MTK_PIN_NO(133) | 3) +#define PINMUX_GPIO133__FUNC_CONN_DSP_JDO (MTK_PIN_NO(133) | 4) +#define PINMUX_GPIO133__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(133) | 5) +#define PINMUX_GPIO133__FUNC_LVTS_SCF (MTK_PIN_NO(133) | 6) +#define PINMUX_GPIO133__FUNC_DBG_MON_A2 (MTK_PIN_NO(133) | 7) + +#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) +#define PINMUX_GPIO134__FUNC_MSDC1_CLK (MTK_PIN_NO(134) | 1) +#define PINMUX_GPIO134__FUNC_PCM1_CLK (MTK_PIN_NO(134) | 2) +#define PINMUX_GPIO134__FUNC_SPI5_B_MI (MTK_PIN_NO(134) | 3) +#define PINMUX_GPIO134__FUNC_UDI_TCK (MTK_PIN_NO(134) | 4) +#define PINMUX_GPIO134__FUNC_CONN_DSP_JCK (MTK_PIN_NO(134) | 5) +#define PINMUX_GPIO134__FUNC_IPU_JTAG_TCK (MTK_PIN_NO(134) | 6) +#define PINMUX_GPIO134__FUNC_JTCK_SEL3 (MTK_PIN_NO(134) | 7) + +#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) +#define PINMUX_GPIO135__FUNC_MSDC1_CMD (MTK_PIN_NO(135) | 1) +#define PINMUX_GPIO135__FUNC_PCM1_SYNC (MTK_PIN_NO(135) | 2) +#define PINMUX_GPIO135__FUNC_SPI5_B_CSB (MTK_PIN_NO(135) | 3) +#define PINMUX_GPIO135__FUNC_UDI_TMS (MTK_PIN_NO(135) | 4) +#define PINMUX_GPIO135__FUNC_CONN_DSP_JMS (MTK_PIN_NO(135) | 5) +#define PINMUX_GPIO135__FUNC_IPU_JTAG_TMS (MTK_PIN_NO(135) | 6) +#define PINMUX_GPIO135__FUNC_JTMS_SEL3 (MTK_PIN_NO(135) | 7) + +#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) +#define PINMUX_GPIO136__FUNC_MSDC1_DAT3 (MTK_PIN_NO(136) | 1) +#define PINMUX_GPIO136__FUNC_PCM1_DI (MTK_PIN_NO(136) | 2) +#define PINMUX_GPIO136__FUNC_SPI5_B_MO (MTK_PIN_NO(136) | 3) +#define PINMUX_GPIO136__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(136) | 4) +#define PINMUX_GPIO136__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(136) | 5) +#define PINMUX_GPIO136__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(136) | 6) + +#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) +#define PINMUX_GPIO137__FUNC_MSDC1_DAT0 (MTK_PIN_NO(137) | 1) +#define PINMUX_GPIO137__FUNC_PCM1_DO0 (MTK_PIN_NO(137) | 2) +#define PINMUX_GPIO137__FUNC_SPI5_B_CLK (MTK_PIN_NO(137) | 3) +#define PINMUX_GPIO137__FUNC_UDI_TDI (MTK_PIN_NO(137) | 4) +#define PINMUX_GPIO137__FUNC_CONN_DSP_JDI (MTK_PIN_NO(137) | 5) +#define PINMUX_GPIO137__FUNC_IPU_JTAG_TDI (MTK_PIN_NO(137) | 6) +#define PINMUX_GPIO137__FUNC_JTDI_SEL3 (MTK_PIN_NO(137) | 7) + +#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) +#define PINMUX_GPIO138__FUNC_MSDC1_DAT2 (MTK_PIN_NO(138) | 1) +#define PINMUX_GPIO138__FUNC_PCM1_DO2 (MTK_PIN_NO(138) | 2) +#define PINMUX_GPIO138__FUNC_ANT_SEL11 (MTK_PIN_NO(138) | 3) +#define PINMUX_GPIO138__FUNC_UDI_NTRST (MTK_PIN_NO(138) | 4) +#define PINMUX_GPIO138__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(138) | 5) +#define PINMUX_GPIO138__FUNC_IPU_JTAG_TRST (MTK_PIN_NO(138) | 6) +#define PINMUX_GPIO138__FUNC_JTRSTN_SEL3 (MTK_PIN_NO(138) | 7) + +#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) +#define PINMUX_GPIO139__FUNC_MSDC1_DAT1 (MTK_PIN_NO(139) | 1) +#define PINMUX_GPIO139__FUNC_PCM1_DO1 (MTK_PIN_NO(139) | 2) +#define PINMUX_GPIO139__FUNC_ANT_SEL12 (MTK_PIN_NO(139) | 3) +#define PINMUX_GPIO139__FUNC_UDI_TDO (MTK_PIN_NO(139) | 4) +#define PINMUX_GPIO139__FUNC_CONN_DSP_JDO (MTK_PIN_NO(139) | 5) +#define PINMUX_GPIO139__FUNC_IPU_JTAG_TDO (MTK_PIN_NO(139) | 6) +#define PINMUX_GPIO139__FUNC_JTDO_SEL3 (MTK_PIN_NO(139) | 7) + +#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) +#define PINMUX_GPIO140__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(140) | 1) +#define PINMUX_GPIO140__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(140) | 2) +#define PINMUX_GPIO140__FUNC_ADSP_URXD0 (MTK_PIN_NO(140) | 3) +#define PINMUX_GPIO140__FUNC_SCL_6306 (MTK_PIN_NO(140) | 4) +#define PINMUX_GPIO140__FUNC_PTA_RXD (MTK_PIN_NO(140) | 5) +#define PINMUX_GPIO140__FUNC_SSPM_URXD_AO (MTK_PIN_NO(140) | 6) + +#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) +#define PINMUX_GPIO141__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(141) | 1) +#define PINMUX_GPIO141__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(141) | 2) +#define PINMUX_GPIO141__FUNC_ADSP_UTXD0 (MTK_PIN_NO(141) | 3) +#define PINMUX_GPIO141__FUNC_SDA_6306 (MTK_PIN_NO(141) | 4) +#define PINMUX_GPIO141__FUNC_PTA_TXD (MTK_PIN_NO(141) | 5) +#define PINMUX_GPIO141__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(141) | 6) + +#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) +#define PINMUX_GPIO142__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(142) | 1) +#define PINMUX_GPIO142__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(142) | 2) + +#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) +#define PINMUX_GPIO143__FUNC_AUD_DAT_MOSI2 (MTK_PIN_NO(143) | 1) +#define PINMUX_GPIO143__FUNC_DBG_MON_A9 (MTK_PIN_NO(143) | 7) + +#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0) +#define PINMUX_GPIO144__FUNC_AUD_NLE_MOSI1 (MTK_PIN_NO(144) | 1) +#define PINMUX_GPIO144__FUNC_AUD_CLK_MISO (MTK_PIN_NO(144) | 2) +#define PINMUX_GPIO144__FUNC_I2S2_MCK (MTK_PIN_NO(144) | 3) +#define PINMUX_GPIO144__FUNC_UDI_TCK (MTK_PIN_NO(144) | 5) +#define PINMUX_GPIO144__FUNC_UFS_UNIPRO_SDA (MTK_PIN_NO(144) | 6) +#define PINMUX_GPIO144__FUNC_DBG_MON_A10 (MTK_PIN_NO(144) | 7) + +#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0) +#define PINMUX_GPIO145__FUNC_AUD_NLE_MOSI0 (MTK_PIN_NO(145) | 1) +#define PINMUX_GPIO145__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(145) | 2) +#define PINMUX_GPIO145__FUNC_I2S2_BCK (MTK_PIN_NO(145) | 3) +#define PINMUX_GPIO145__FUNC_UDI_TMS (MTK_PIN_NO(145) | 5) +#define PINMUX_GPIO145__FUNC_DBG_MON_A11 (MTK_PIN_NO(145) | 7) + +#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0) +#define PINMUX_GPIO146__FUNC_AUD_DAT_MISO2 (MTK_PIN_NO(146) | 1) +#define PINMUX_GPIO146__FUNC_I2S2_DI2 (MTK_PIN_NO(146) | 3) +#define PINMUX_GPIO146__FUNC_UDI_TDO (MTK_PIN_NO(146) | 5) +#define PINMUX_GPIO146__FUNC_DBG_MON_A14 (MTK_PIN_NO(146) | 7) + +#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0) +#define PINMUX_GPIO147__FUNC_ANT_SEL0 (MTK_PIN_NO(147) | 1) +#define PINMUX_GPIO147__FUNC_PWM_3 (MTK_PIN_NO(147) | 2) + +#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0) +#define PINMUX_GPIO148__FUNC_ANT_SEL1 (MTK_PIN_NO(148) | 1) +#define PINMUX_GPIO148__FUNC_SPI0_B_MI (MTK_PIN_NO(148) | 2) +#define PINMUX_GPIO148__FUNC_SSPM_URXD_AO (MTK_PIN_NO(148) | 3) +#define PINMUX_GPIO148__FUNC_TP_UCTS2_AO (MTK_PIN_NO(148) | 5) +#define PINMUX_GPIO148__FUNC_CLKM0 (MTK_PIN_NO(148) | 6) + +#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0) +#define PINMUX_GPIO149__FUNC_ANT_SEL2 (MTK_PIN_NO(149) | 1) +#define PINMUX_GPIO149__FUNC_SPI0_B_CSB (MTK_PIN_NO(149) | 2) +#define PINMUX_GPIO149__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(149) | 3) +#define PINMUX_GPIO149__FUNC_TP_URTS2_AO (MTK_PIN_NO(149) | 5) +#define PINMUX_GPIO149__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(149) | 6) + +#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0) +#define PINMUX_GPIO150__FUNC_ANT_SEL3 (MTK_PIN_NO(150) | 1) +#define PINMUX_GPIO150__FUNC_SPI0_B_MO (MTK_PIN_NO(150) | 2) +#define PINMUX_GPIO150__FUNC_UCTS1 (MTK_PIN_NO(150) | 3) +#define PINMUX_GPIO150__FUNC_TP_UCTS1_AO (MTK_PIN_NO(150) | 5) +#define PINMUX_GPIO150__FUNC_IDDIG (MTK_PIN_NO(150) | 6) +#define PINMUX_GPIO150__FUNC_SCL9 (MTK_PIN_NO(150) | 7) + +#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0) +#define PINMUX_GPIO151__FUNC_ANT_SEL4 (MTK_PIN_NO(151) | 1) +#define PINMUX_GPIO151__FUNC_SPI0_B_CLK (MTK_PIN_NO(151) | 2) +#define PINMUX_GPIO151__FUNC_URTS1 (MTK_PIN_NO(151) | 3) +#define PINMUX_GPIO151__FUNC_TP_URTS1_AO (MTK_PIN_NO(151) | 5) +#define PINMUX_GPIO151__FUNC_USB_DRVVBUS (MTK_PIN_NO(151) | 6) +#define PINMUX_GPIO151__FUNC_SDA9 (MTK_PIN_NO(151) | 7) + +#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0) +#define PINMUX_GPIO152__FUNC_ANT_SEL5 (MTK_PIN_NO(152) | 1) +#define PINMUX_GPIO152__FUNC_SPI1_B_MI (MTK_PIN_NO(152) | 2) +#define PINMUX_GPIO152__FUNC_CLKM3 (MTK_PIN_NO(152) | 3) +#define PINMUX_GPIO152__FUNC_TP_URXD1_AO (MTK_PIN_NO(152) | 5) +#define PINMUX_GPIO152__FUNC_SCP_SPI1_B_MI (MTK_PIN_NO(152) | 6) +#define PINMUX_GPIO152__FUNC_SCL8 (MTK_PIN_NO(152) | 7) + +#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0) +#define PINMUX_GPIO153__FUNC_ANT_SEL6 (MTK_PIN_NO(153) | 1) +#define PINMUX_GPIO153__FUNC_SPI1_B_CSB (MTK_PIN_NO(153) | 2) +#define PINMUX_GPIO153__FUNC_SRCLKENAI0 (MTK_PIN_NO(153) | 3) +#define PINMUX_GPIO153__FUNC_PWM_0 (MTK_PIN_NO(153) | 4) +#define PINMUX_GPIO153__FUNC_TP_UTXD1_AO (MTK_PIN_NO(153) | 5) +#define PINMUX_GPIO153__FUNC_SCP_SPI1_B_CS (MTK_PIN_NO(153) | 6) +#define PINMUX_GPIO153__FUNC_SDA8 (MTK_PIN_NO(153) | 7) + +#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0) +#define PINMUX_GPIO154__FUNC_ANT_SEL7 (MTK_PIN_NO(154) | 1) +#define PINMUX_GPIO154__FUNC_SPI1_B_MO (MTK_PIN_NO(154) | 2) +#define PINMUX_GPIO154__FUNC_SRCLKENAI1 (MTK_PIN_NO(154) | 3) +#define PINMUX_GPIO154__FUNC_TP_URXD2_AO (MTK_PIN_NO(154) | 5) +#define PINMUX_GPIO154__FUNC_SCP_SPI1_B_MO (MTK_PIN_NO(154) | 6) + +#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0) +#define PINMUX_GPIO155__FUNC_ANT_SEL8 (MTK_PIN_NO(155) | 1) +#define PINMUX_GPIO155__FUNC_SPI1_B_CLK (MTK_PIN_NO(155) | 2) +#define PINMUX_GPIO155__FUNC_MD_INT0 (MTK_PIN_NO(155) | 3) +#define PINMUX_GPIO155__FUNC_TP_UTXD2_AO (MTK_PIN_NO(155) | 5) +#define PINMUX_GPIO155__FUNC_SCP_SPI1_B_CK (MTK_PIN_NO(155) | 6) +#define PINMUX_GPIO155__FUNC_DBG_MON_A15 (MTK_PIN_NO(155) | 7) + +#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0) +#define PINMUX_GPIO156__FUNC_CONN_TOP_CLK (MTK_PIN_NO(156) | 1) +#define PINMUX_GPIO156__FUNC_AUXIF_CLK0 (MTK_PIN_NO(156) | 2) +#define PINMUX_GPIO156__FUNC_DBG_MON_A16 (MTK_PIN_NO(156) | 7) + +#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0) +#define PINMUX_GPIO157__FUNC_CONN_TOP_DATA (MTK_PIN_NO(157) | 1) +#define PINMUX_GPIO157__FUNC_AUXIF_ST0 (MTK_PIN_NO(157) | 2) +#define PINMUX_GPIO157__FUNC_DBG_MON_A17 (MTK_PIN_NO(157) | 7) + +#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0) +#define PINMUX_GPIO158__FUNC_CONN_HRST_B (MTK_PIN_NO(158) | 1) +#define PINMUX_GPIO158__FUNC_DBG_MON_A18 (MTK_PIN_NO(158) | 7) + +#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0) +#define PINMUX_GPIO159__FUNC_CONN_WB_PTA (MTK_PIN_NO(159) | 1) +#define PINMUX_GPIO159__FUNC_DBG_MON_A19 (MTK_PIN_NO(159) | 7) + +#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0) +#define PINMUX_GPIO160__FUNC_CONN_BT_CLK (MTK_PIN_NO(160) | 1) +#define PINMUX_GPIO160__FUNC_AUXIF_CLK1 (MTK_PIN_NO(160) | 2) +#define PINMUX_GPIO160__FUNC_DBG_MON_A20 (MTK_PIN_NO(160) | 7) + +#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0) +#define PINMUX_GPIO161__FUNC_CONN_BT_DATA (MTK_PIN_NO(161) | 1) +#define PINMUX_GPIO161__FUNC_AUXIF_ST1 (MTK_PIN_NO(161) | 2) +#define PINMUX_GPIO161__FUNC_DBG_MON_A21 (MTK_PIN_NO(161) | 7) + +#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0) +#define PINMUX_GPIO162__FUNC_CONN_WF_CTRL0 (MTK_PIN_NO(162) | 1) +#define PINMUX_GPIO162__FUNC_DBG_MON_A22 (MTK_PIN_NO(162) | 7) + +#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0) +#define PINMUX_GPIO163__FUNC_CONN_WF_CTRL1 (MTK_PIN_NO(163) | 1) +#define PINMUX_GPIO163__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(163) | 2) +#define PINMUX_GPIO163__FUNC_DBG_MON_A23 (MTK_PIN_NO(163) | 7) + +#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0) +#define PINMUX_GPIO164__FUNC_CONN_WF_CTRL2 (MTK_PIN_NO(164) | 1) +#define PINMUX_GPIO164__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(164) | 2) +#define PINMUX_GPIO164__FUNC_DBG_MON_A24 (MTK_PIN_NO(164) | 7) + +#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0) +#define PINMUX_GPIO165__FUNC_CONN_WF_CTRL3 (MTK_PIN_NO(165) | 1) +#define PINMUX_GPIO165__FUNC_UFS_UNIPRO_SDA (MTK_PIN_NO(165) | 2) +#define PINMUX_GPIO165__FUNC_DBG_MON_A25 (MTK_PIN_NO(165) | 7) + +#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0) +#define PINMUX_GPIO166__FUNC_CONN_WF_CTRL4 (MTK_PIN_NO(166) | 1) +#define PINMUX_GPIO166__FUNC_UFS_UNIPRO_SCL (MTK_PIN_NO(166) | 2) +#define PINMUX_GPIO166__FUNC_DBG_MON_A26 (MTK_PIN_NO(166) | 7) + +#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0) +#define PINMUX_GPIO167__FUNC_MSDC0_CMD (MTK_PIN_NO(167) | 1) + +#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0) +#define PINMUX_GPIO168__FUNC_MSDC0_DAT0 (MTK_PIN_NO(168) | 1) + +#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0) +#define PINMUX_GPIO169__FUNC_MSDC0_DAT2 (MTK_PIN_NO(169) | 1) + +#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0) +#define PINMUX_GPIO170__FUNC_MSDC0_DAT4 (MTK_PIN_NO(170) | 1) + +#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0) +#define PINMUX_GPIO171__FUNC_MSDC0_DAT6 (MTK_PIN_NO(171) | 1) + +#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0) +#define PINMUX_GPIO172__FUNC_MSDC0_DAT1 (MTK_PIN_NO(172) | 1) + +#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0) +#define PINMUX_GPIO173__FUNC_MSDC0_DAT5 (MTK_PIN_NO(173) | 1) + +#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0) +#define PINMUX_GPIO174__FUNC_MSDC0_DAT7 (MTK_PIN_NO(174) | 1) + +#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0) +#define PINMUX_GPIO175__FUNC_MSDC0_DSL (MTK_PIN_NO(175) | 1) +#define PINMUX_GPIO175__FUNC_ANT_SEL9 (MTK_PIN_NO(175) | 2) + +#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0) +#define PINMUX_GPIO176__FUNC_MSDC0_CLK (MTK_PIN_NO(176) | 1) +#define PINMUX_GPIO176__FUNC_ANT_SEL10 (MTK_PIN_NO(176) | 2) + +#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0) +#define PINMUX_GPIO177__FUNC_MSDC0_DAT3 (MTK_PIN_NO(177) | 1) + +#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0) +#define PINMUX_GPIO178__FUNC_MSDC0_RSTB (MTK_PIN_NO(178) | 1) + +#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0) +#define PINMUX_GPIO179__FUNC_RFIC0_BSI_EN (MTK_PIN_NO(179) | 1) + +#define PINMUX_GPIO180__FUNC_GPIO180 (MTK_PIN_NO(180) | 0) +#define PINMUX_GPIO180__FUNC_RFIC0_BSI_CK (MTK_PIN_NO(180) | 1) + +#define PINMUX_GPIO181__FUNC_GPIO181 (MTK_PIN_NO(181) | 0) +#define PINMUX_GPIO181__FUNC_SRCLKENA0 (MTK_PIN_NO(181) | 1) + +#define PINMUX_GPIO182__FUNC_GPIO182 (MTK_PIN_NO(182) | 0) +#define PINMUX_GPIO182__FUNC_SRCLKENA1 (MTK_PIN_NO(182) | 1) + +#define PINMUX_GPIO183__FUNC_GPIO183 (MTK_PIN_NO(183) | 0) +#define PINMUX_GPIO183__FUNC_WATCHDOG (MTK_PIN_NO(183) | 1) + +#define PINMUX_GPIO184__FUNC_GPIO184 (MTK_PIN_NO(184) | 0) +#define PINMUX_GPIO184__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(184) | 1) +#define PINMUX_GPIO184__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(184) | 2) + +#define PINMUX_GPIO185__FUNC_GPIO185 (MTK_PIN_NO(185) | 0) +#define PINMUX_GPIO185__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(185) | 1) + +#define PINMUX_GPIO186__FUNC_GPIO186 (MTK_PIN_NO(186) | 0) +#define PINMUX_GPIO186__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(186) | 1) +#define PINMUX_GPIO186__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(186) | 2) + +#define PINMUX_GPIO187__FUNC_GPIO187 (MTK_PIN_NO(187) | 0) +#define PINMUX_GPIO187__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(187) | 1) + +#define PINMUX_GPIO188__FUNC_GPIO188 (MTK_PIN_NO(188) | 0) +#define PINMUX_GPIO188__FUNC_RTC32K_CK (MTK_PIN_NO(188) | 1) + +#define PINMUX_GPIO189__FUNC_GPIO189 (MTK_PIN_NO(189) | 0) +#define PINMUX_GPIO189__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(189) | 1) +#define PINMUX_GPIO189__FUNC_I2S1_MCK (MTK_PIN_NO(189) | 3) +#define PINMUX_GPIO189__FUNC_UFS_UNIPRO_SCL (MTK_PIN_NO(189) | 6) + +#define PINMUX_GPIO190__FUNC_GPIO190 (MTK_PIN_NO(190) | 0) +#define PINMUX_GPIO190__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(190) | 1) +#define PINMUX_GPIO190__FUNC_I2S1_BCK (MTK_PIN_NO(190) | 3) +#define PINMUX_GPIO190__FUNC_DBG_MON_A6 (MTK_PIN_NO(190) | 7) + +#define PINMUX_GPIO191__FUNC_GPIO191 (MTK_PIN_NO(191) | 0) +#define PINMUX_GPIO191__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(191) | 1) +#define PINMUX_GPIO191__FUNC_I2S1_LRCK (MTK_PIN_NO(191) | 3) +#define PINMUX_GPIO191__FUNC_DBG_MON_A7 (MTK_PIN_NO(191) | 7) + +#define PINMUX_GPIO192__FUNC_GPIO192 (MTK_PIN_NO(192) | 0) +#define PINMUX_GPIO192__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(192) | 1) +#define PINMUX_GPIO192__FUNC_I2S1_DO (MTK_PIN_NO(192) | 3) +#define PINMUX_GPIO192__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(192) | 6) +#define PINMUX_GPIO192__FUNC_DBG_MON_A8 (MTK_PIN_NO(192) | 7) + +#define PINMUX_GPIO193__FUNC_GPIO193 (MTK_PIN_NO(193) | 0) +#define PINMUX_GPIO193__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(193) | 1) +#define PINMUX_GPIO193__FUNC_VOW_DAT_MISO (MTK_PIN_NO(193) | 2) +#define PINMUX_GPIO193__FUNC_I2S2_LRCK (MTK_PIN_NO(193) | 3) +#define PINMUX_GPIO193__FUNC_UDI_TDI (MTK_PIN_NO(193) | 5) +#define PINMUX_GPIO193__FUNC_DBG_MON_A12 (MTK_PIN_NO(193) | 7) + +#define PINMUX_GPIO194__FUNC_GPIO194 (MTK_PIN_NO(194) | 0) +#define PINMUX_GPIO194__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(194) | 1) +#define PINMUX_GPIO194__FUNC_VOW_CLK_MISO (MTK_PIN_NO(194) | 2) +#define PINMUX_GPIO194__FUNC_I2S2_DI (MTK_PIN_NO(194) | 3) +#define PINMUX_GPIO194__FUNC_UDI_NTRST (MTK_PIN_NO(194) | 5) +#define PINMUX_GPIO194__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(194) | 6) +#define PINMUX_GPIO194__FUNC_DBG_MON_A13 (MTK_PIN_NO(194) | 7) + +#define PINMUX_GPIO195__FUNC_GPIO195 (MTK_PIN_NO(195) | 0) +#define PINMUX_GPIO195__FUNC_ADSP_JTAG_TCK (MTK_PIN_NO(195) | 3) +#define PINMUX_GPIO195__FUNC_VPU_UDI_TCK (MTK_PIN_NO(195) | 4) +#define PINMUX_GPIO195__FUNC_SPM_JTAG_TCK (MTK_PIN_NO(195) | 5) +#define PINMUX_GPIO195__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(195) | 6) + +#define PINMUX_GPIO196__FUNC_GPIO196 (MTK_PIN_NO(196) | 0) +#define PINMUX_GPIO196__FUNC_CMMCLK4 (MTK_PIN_NO(196) | 1) +#define PINMUX_GPIO196__FUNC_ADSP_JTAG_TDI (MTK_PIN_NO(196) | 3) +#define PINMUX_GPIO196__FUNC_VPU_UDI_TDI (MTK_PIN_NO(196) | 4) +#define PINMUX_GPIO196__FUNC_SPM_JTAG_TDI (MTK_PIN_NO(196) | 5) +#define PINMUX_GPIO196__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(196) | 6) + +#define PINMUX_GPIO197__FUNC_GPIO197 (MTK_PIN_NO(197) | 0) +#define PINMUX_GPIO197__FUNC_ADSP_JTAG_TDO (MTK_PIN_NO(197) | 3) +#define PINMUX_GPIO197__FUNC_VPU_UDI_TDO (MTK_PIN_NO(197) | 4) +#define PINMUX_GPIO197__FUNC_SPM_JTAG_TDO (MTK_PIN_NO(197) | 5) +#define PINMUX_GPIO197__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(197) | 6) + +#define PINMUX_GPIO198__FUNC_GPIO198 (MTK_PIN_NO(198) | 0) +#define PINMUX_GPIO198__FUNC_SCL7 (MTK_PIN_NO(198) | 1) + +#define PINMUX_GPIO199__FUNC_GPIO199 (MTK_PIN_NO(199) | 0) +#define PINMUX_GPIO199__FUNC_SDA7 (MTK_PIN_NO(199) | 1) + +#define PINMUX_GPIO200__FUNC_GPIO200 (MTK_PIN_NO(200) | 0) +#define PINMUX_GPIO200__FUNC_URXD1 (MTK_PIN_NO(200) | 1) +#define PINMUX_GPIO200__FUNC_ADSP_URXD0 (MTK_PIN_NO(200) | 2) +#define PINMUX_GPIO200__FUNC_TP_URXD1_AO (MTK_PIN_NO(200) | 3) +#define PINMUX_GPIO200__FUNC_SSPM_URXD_AO (MTK_PIN_NO(200) | 4) +#define PINMUX_GPIO200__FUNC_TP_URXD2_AO (MTK_PIN_NO(200) | 5) +#define PINMUX_GPIO200__FUNC_MBISTREADEN_TRIGGER (MTK_PIN_NO(200) | 6) + +#define PINMUX_GPIO201__FUNC_GPIO201 (MTK_PIN_NO(201) | 0) +#define PINMUX_GPIO201__FUNC_UTXD1 (MTK_PIN_NO(201) | 1) +#define PINMUX_GPIO201__FUNC_ADSP_UTXD0 (MTK_PIN_NO(201) | 2) +#define PINMUX_GPIO201__FUNC_TP_UTXD1_AO (MTK_PIN_NO(201) | 3) +#define PINMUX_GPIO201__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(201) | 4) +#define PINMUX_GPIO201__FUNC_TP_UTXD2_AO (MTK_PIN_NO(201) | 5) +#define PINMUX_GPIO201__FUNC_MBISTWRITEEN_TRIGGER (MTK_PIN_NO(201) | 6) + +#define PINMUX_GPIO202__FUNC_GPIO202 (MTK_PIN_NO(202) | 0) +#define PINMUX_GPIO202__FUNC_PWM_3 (MTK_PIN_NO(202) | 1) +#define PINMUX_GPIO202__FUNC_CLKM3 (MTK_PIN_NO(202) | 2) + +#define PINMUX_GPIO203__FUNC_GPIO203 (MTK_PIN_NO(203) | 0) + +#define PINMUX_GPIO204__FUNC_GPIO204 (MTK_PIN_NO(204) | 0) + +#define PINMUX_GPIO205__FUNC_GPIO205 (MTK_PIN_NO(205) | 0) + +#define PINMUX_GPIO206__FUNC_GPIO206 (MTK_PIN_NO(206) | 0) + +#define PINMUX_GPIO207__FUNC_GPIO207 (MTK_PIN_NO(207) | 0) + +#define PINMUX_GPIO208__FUNC_GPIO208 (MTK_PIN_NO(208) | 0) + +#define PINMUX_GPIO209__FUNC_GPIO209 (MTK_PIN_NO(209) | 0) + +#endif /* __MT6779-PINFUNC_H */ From 986a4b63d3bc5f2c0eb4083b05aff2bf883b7b2f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 24 Jul 2020 17:08:57 -0400 Subject: [PATCH 206/242] SUNRPC: Fix ("SUNRPC: Add "@len" parameter to gss_unwrap()") Braino when converting "buf->len -=" to "buf->len = len -". The result is under-estimation of the ralign and rslack values. On krb5p mounts, this has caused READDIR to fail with EIO, and KASAN splats when decoding READLINK replies. As a result of fixing this oversight, the gss_unwrap method now returns a buf->len that can be shorter than priv_len for small RPC messages. The additional adjustment done in unwrap_priv_data() can underflow buf->len. This causes the nfsd_request_too_large check to fail during some NFSv3 operations. Reported-by: Marian Rainer-Harbach Reported-by: Pierre Sauter BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1886277 Fixes: 31c9590ae468 ("SUNRPC: Add "@len" parameter to gss_unwrap()") Reviewed-by: J. Bruce Fields Signed-off-by: Chuck Lever --- net/sunrpc/auth_gss/gss_krb5_wrap.c | 2 +- net/sunrpc/auth_gss/svcauth_gss.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index cf0fd170ac18..90b8329fef82 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -584,7 +584,7 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, int len, buf->head[0].iov_len); memmove(ptr, ptr + GSS_KRB5_TOK_HDR_LEN + headskip, movelen); buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip; - buf->len = len - GSS_KRB5_TOK_HDR_LEN + headskip; + buf->len = len - (GSS_KRB5_TOK_HDR_LEN + headskip); /* Trim off the trailing "extra count" and checksum blob */ xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip); diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 7d83f54aaaa6..258b04372f85 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -990,7 +990,6 @@ unwrap_priv_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gs maj_stat = gss_unwrap(ctx, 0, priv_len, buf); pad = priv_len - buf->len; - buf->len -= pad; /* The upper layers assume the buffer is aligned on 4-byte boundaries. * In the krb5p case, at least, the data ends up offset, so we need to * move it around. */ From 94a4beaa6b3756dbb661bc9a748574b9bc0cb4ae Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 19 Jul 2020 17:14:03 -0700 Subject: [PATCH 207/242] nfsd: netns.h: delete a duplicated word Drop the repeated word "the" in a comment. Signed-off-by: Randy Dunlap Cc: "J. Bruce Fields" Cc: Chuck Lever Cc: linux-nfs@vger.kernel.org Signed-off-by: Chuck Lever --- fs/nfsd/netns.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 9217cb64bf0e..7346acda9d76 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -171,7 +171,7 @@ struct nfsd_net { unsigned int longest_chain_cachesize; struct shrinker nfsd_reply_cache_shrinker; - /* utsname taken from the the process that starts the server */ + /* utsname taken from the process that starts the server */ char nfsd_name[UNX_MAXNODENAME+1]; }; From a68d5a502bbacfbd31f98371f777d574b3a91baf Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 24 Jul 2020 15:26:47 -0400 Subject: [PATCH 208/242] SUNRPC: Refresh the show_rqstp_flags() macro Ensure that show_rqstp_flags() can recognize and display the RQ_AUTHERR flag, added in commit 83dd59a0b9af ("SUNRPC/nfs: Fix return value for nfs4_callback_compound()") and the RQ_DATA flag, added in commit ff3ac5c3dc23 ("SUNRPC: Add a server side per-connection limit"). Signed-off-by: Chuck Lever --- include/trace/events/sunrpc.h | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 6a12935b8b14..65d7dfbbc9cd 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -1250,15 +1250,34 @@ DECLARE_EVENT_CLASS(svc_xdr_buf_class, DEFINE_SVCXDRBUF_EVENT(recvfrom); DEFINE_SVCXDRBUF_EVENT(sendto); +/* + * from include/linux/sunrpc/svc.h + */ +#define SVC_RQST_FLAG_LIST \ + svc_rqst_flag(SECURE) \ + svc_rqst_flag(LOCAL) \ + svc_rqst_flag(USEDEFERRAL) \ + svc_rqst_flag(DROPME) \ + svc_rqst_flag(SPLICE_OK) \ + svc_rqst_flag(VICTIM) \ + svc_rqst_flag(BUSY) \ + svc_rqst_flag(DATA) \ + svc_rqst_flag_end(AUTHERR) + +#undef svc_rqst_flag +#undef svc_rqst_flag_end +#define svc_rqst_flag(x) TRACE_DEFINE_ENUM(RQ_##x); +#define svc_rqst_flag_end(x) TRACE_DEFINE_ENUM(RQ_##x); + +SVC_RQST_FLAG_LIST + +#undef svc_rqst_flag +#undef svc_rqst_flag_end +#define svc_rqst_flag(x) { BIT(RQ_##x), #x }, +#define svc_rqst_flag_end(x) { BIT(RQ_##x), #x } + #define show_rqstp_flags(flags) \ - __print_flags(flags, "|", \ - { (1UL << RQ_SECURE), "RQ_SECURE"}, \ - { (1UL << RQ_LOCAL), "RQ_LOCAL"}, \ - { (1UL << RQ_USEDEFERRAL), "RQ_USEDEFERRAL"}, \ - { (1UL << RQ_DROPME), "RQ_DROPME"}, \ - { (1UL << RQ_SPLICE_OK), "RQ_SPLICE_OK"}, \ - { (1UL << RQ_VICTIM), "RQ_VICTIM"}, \ - { (1UL << RQ_BUSY), "RQ_BUSY"}) + __print_flags(flags, "|", SVC_RQST_FLAG_LIST) TRACE_EVENT(svc_recv, TP_PROTO(struct svc_rqst *rqst, int len), From 44a80df4bfce02f5d51fe5040bdbdf10d0d78f4e Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Wed, 22 Jul 2020 16:01:36 +0200 Subject: [PATCH 209/242] mtd: spi-nor: intel-spi: Simulate WRDI command After spi_nor_write_disable() return code checks were introduced in the spi-nor front end intel-spi backend stopped to work because WRDI was never supported and always failed. Just pretend it was sucessful and ignore the command itself. HW sequencer shall do the right thing automatically, while with SW sequencer we cannot do it anyway, because the only tool we had was preopcode and it makes no sense for WRDI. Fixes: bce679e5ae3a ("mtd: spi-nor: Check for errors after each Register Operation") Signed-off-by: Alexander Sverdlin Reviewed-by: Mika Westerberg Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/282e1305-fd08-e446-1a22-eb4dff78cfb4@nokia.com Signed-off-by: Tudor Ambarus --- drivers/mtd/spi-nor/controllers/intel-spi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi.c index 61d2a0ad2131..3259c9fc981f 100644 --- a/drivers/mtd/spi-nor/controllers/intel-spi.c +++ b/drivers/mtd/spi-nor/controllers/intel-spi.c @@ -612,6 +612,15 @@ static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, return 0; } + /* + * We hope that HW sequencer will do the right thing automatically and + * with the SW sequencer we cannot use preopcode anyway, so just ignore + * the Write Disable operation and pretend it was completed + * successfully. + */ + if (opcode == SPINOR_OP_WRDI) + return 0; + writel(0, ispi->base + FADDR); /* Write the value beforehand */ From 48029e620decc185c88041e12156e4f5d871b28a Mon Sep 17 00:00:00 2001 From: David Clear Date: Mon, 20 Jul 2020 09:36:55 -0700 Subject: [PATCH 210/242] mtd: spi-nor: macronix: Add support for mx66u2g45g The Macronix mx66u2g45g is a 1.8V, 2Gbit (256MB) device that supports x1, x2, or x4 operation. Tested on Pensando SoC hardware with a cadence quadspi controller via drivers/spi/spi-cadence-quadspi.c, in x2 mode at 50MHz. - random data write, erase, read - verified erase operations - random data write, read/compare - verified write/read operations Signed-off-by: David Clear Acked-by: Shannon Nelson Link: https://lore.kernel.org/r/20200720163656.38006-2-dac2@pensando.io Signed-off-by: Tudor Ambarus --- drivers/mtd/spi-nor/macronix.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index 0ae0815a3633..f97f3d127575 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -87,6 +87,9 @@ static const struct flash_info macronix_parts[] = { SPI_NOR_QUAD_READ) }, { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, + { "mx66u2g45g", INFO(0xc2253c, 0, 64 * 1024, 4096, + SECT_4K | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, }; static void macronix_default_init(struct spi_nor *nor) From 1371a80cac33d5b0df4c33f918b9dd810cf4edab Mon Sep 17 00:00:00 2001 From: David Clear Date: Mon, 20 Jul 2020 09:36:56 -0700 Subject: [PATCH 211/242] mtd: spi-nor: micron: Add SPI_NOR_DUAL_READ flag on mt25qu02g The Micron mt25qu02g supports both x2 and x4 transactions. Add the SPI_NOR_DUAL_READ flag to its spi_nor_ids[] table entry. Tested on Pensando SoC hardware with a cadence quadspi controller via drivers/spi/spi-cadence-quadspi.c, in x2 mode at 50MHz. - random data write, erase, read - verified erase operations - random data write, read/compare - verified write/read operations Signed-off-by: David Clear Acked-by: Shannon Nelson Link: https://lore.kernel.org/r/20200720163656.38006-3-dac2@pensando.io Signed-off-by: Tudor Ambarus --- drivers/mtd/spi-nor/micron-st.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index 3dca5b9af3b6..ef3695080710 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -71,8 +71,8 @@ static const struct flash_info st_parts[] = { SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, { "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096, - SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | - NO_CHIP_ERASE) }, + SECT_4K | USE_FSR | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, From 99eae48fd4c5c59a76de17bc036a2dbd7f698bfd Mon Sep 17 00:00:00 2001 From: Rayagonda Kokatanur Date: Fri, 29 May 2020 12:46:55 +0530 Subject: [PATCH 212/242] mtd: spi-nor: update read capabilities for w25q64 and s25fl064k Both w25q64 and s25fl064k nor flash support QUAD and DUAL read command, hence update the same in flash_info table. This is tested on Broadcom Stingray SoC (bcm958742t). s25fl064k and w25q64 share the same JEDEC ID. The search alg will return the first hit, so s25fl064k even for the winbond parts. We should differentiate between these flashes, but it's not in the scope of this patch. Related discussion at: Link: https://lore.kernel.org/patchwork/patch/628090/ Signed-off-by: Rayagonda Kokatanur Link: https://lore.kernel.org/r/20200529071655.739-1-rayagonda.kokatanur@broadcom.com [tudor.ambarus@microchip.com: Update commit message and indicate that s25fl064k and w25q64 share the same JEDEC ID] Signed-off-by: Tudor Ambarus --- drivers/mtd/spi-nor/spansion.c | 3 ++- drivers/mtd/spi-nor/winbond.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 953df1c488ec..8429b4af999a 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -83,7 +83,8 @@ static const struct flash_info spansion_parts[] = { SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index a5eb1d56cb88..6dcde15fb1aa 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -64,7 +64,8 @@ static const struct flash_info winbond_parts[] = { SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, - { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, From bb1a773d5b6bf018bf84fdb3fbba01d3ef54e2c9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 22 May 2020 20:02:02 -0400 Subject: [PATCH 213/242] kill unused dump_fpu() instances dump_fpu() is used only on the architectures that support elf and have neither CORE_DUMP_USE_REGSET nor ELF_CORE_COPY_FPREGS defined. Currently that's csky, m68k, microblaze, nds32 and unicore32. The rest of the instances are dead code. NB: THIS MUST GO AFTER ELF_FDPIC CONVERSION Signed-off-by: Al Viro --- arch/arc/kernel/process.c | 5 --- arch/arm/kernel/process.c | 15 -------- arch/hexagon/kernel/process.c | 9 ----- arch/ia64/kernel/process.c | 34 ------------------ arch/nios2/kernel/process.c | 8 ----- arch/openrisc/kernel/process.c | 7 ---- arch/parisc/include/asm/elf.h | 3 -- arch/parisc/kernel/process.c | 19 ---------- arch/s390/kernel/process.c | 18 ---------- arch/sh/include/asm/fpu.h | 5 --- arch/sh/kernel/process_32.c | 18 ---------- arch/sh/kernel/ptrace_32.c | 2 +- arch/sparc/kernel/process_32.c | 49 ------------------------- arch/sparc/kernel/process_64.c | 66 ---------------------------------- 14 files changed, 1 insertion(+), 257 deletions(-) diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index 8c8e5172fecd..4bfe721513ab 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -295,11 +295,6 @@ void flush_thread(void) { } -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) -{ - return 0; -} - int elf_check_arch(const struct elf32_hdr *x) { unsigned int eflags; diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 58eaa1f60e16..844099e934bd 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -282,21 +282,6 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) return 1; } -/* - * fill in the fpe structure for a core dump... - */ -int dump_fpu (struct pt_regs *regs, struct user_fp *fp) -{ - struct thread_info *thread = current_thread_info(); - int used_math = thread->used_cp[1] | thread->used_cp[2]; - - if (used_math) - memcpy(fp, &thread->fpstate.soft, sizeof (*fp)); - - return used_math != 0; -} -EXPORT_SYMBOL(dump_fpu); - unsigned long get_wchan(struct task_struct *p) { struct stackframe frame; diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index ac07f5f4b76b..05a8fe59d528 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -153,15 +153,6 @@ unsigned long get_wchan(struct task_struct *p) return 0; } -/* - * Required placeholder. - */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) -{ - return 0; -} - - /* * Called on the exit path of event entry; see vm_entry.S * diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 96dfb9e4b16f..e681a6d82260 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -514,52 +514,18 @@ do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void * unw_get_ar(info, UNW_AR_SSD, &dst[56]); } -void -do_dump_task_fpu (struct task_struct *task, struct unw_frame_info *info, void *arg) -{ - elf_fpreg_t *dst = arg; - int i; - - memset(dst, 0, sizeof(elf_fpregset_t)); /* don't leak any "random" bits */ - - if (unw_unwind_to_user(info) < 0) - return; - - /* f0 is 0.0, f1 is 1.0 */ - - for (i = 2; i < 32; ++i) - unw_get_fr(info, i, dst + i); - - ia64_flush_fph(task); - if ((task->thread.flags & IA64_THREAD_FPH_VALID) != 0) - memcpy(dst + 32, task->thread.fph, 96*16); -} - void do_copy_regs (struct unw_frame_info *info, void *arg) { do_copy_task_regs(current, info, arg); } -void -do_dump_fpu (struct unw_frame_info *info, void *arg) -{ - do_dump_task_fpu(current, info, arg); -} - void ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst) { unw_init_running(do_copy_regs, dst); } -int -dump_fpu (struct pt_regs *pt, elf_fpregset_t dst) -{ - unw_init_running(do_dump_fpu, dst); - return 1; /* f0-f31 are always valid so we always return 1 */ -} - /* * Flush thread state. This is called when a thread does an execve(). */ diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c index 509e7855e8dc..9392d55c7471 100644 --- a/arch/nios2/kernel/process.c +++ b/arch/nios2/kernel/process.c @@ -251,11 +251,3 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) regs->ea = pc; regs->sp = sp; } - -#include - -/* Fill in the FPU structure for a core dump. */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) -{ - return 0; /* Nios2 has no FPU and thus no FPU registers */ -} diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c index d7010e72450c..3895d06a06af 100644 --- a/arch/openrisc/kernel/process.c +++ b/arch/openrisc/kernel/process.c @@ -214,13 +214,6 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) regs->sp = sp; } -/* Fill in the fpu structure for a core dump. */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu) -{ - /* TODO */ - return 0; -} - extern struct thread_info *_switch(struct thread_info *old_ti, struct thread_info *new_ti); extern int lwa_flag; diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h index d00973aab7f1..651eacdb549b 100644 --- a/arch/parisc/include/asm/elf.h +++ b/arch/parisc/include/asm/elf.h @@ -305,9 +305,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; struct task_struct; -extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); -#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) - struct pt_regs; /* forward declaration... */ diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 230a6422b99f..680147969d4f 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -152,25 +152,6 @@ void release_thread(struct task_struct *dead_task) { } -/* - * Fill in the FPU structure for a core dump. - */ - -int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r) -{ - if (regs == NULL) - return 0; - - memcpy(r, regs->fr, sizeof *r); - return 1; -} - -int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) -{ - memcpy(r, tsk->thread.regs.fr, sizeof(*r)); - return 1; -} - /* * Idle thread support * diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index eb6e23ad15a2..21b573cfe8d9 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -160,24 +160,6 @@ asmlinkage void execve_tail(void) asm volatile("sfpc %0" : : "d" (0)); } -/* - * fill in the FPU structure for a core dump. - */ -int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) -{ - save_fpu_regs(); - fpregs->fpc = current->thread.fpu.fpc; - fpregs->pad = 0; - if (MACHINE_HAS_VX) - convert_vx_to_fp((freg_t *)&fpregs->fprs, - current->thread.fpu.vxrs); - else - memcpy(&fpregs->fprs, current->thread.fpu.fprs, - sizeof(fpregs->fprs)); - return 1; -} -EXPORT_SYMBOL(dump_fpu); - unsigned long get_wchan(struct task_struct *p) { struct unwind_state state; diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h index 43cfaf929aa7..04584be8986c 100644 --- a/arch/sh/include/asm/fpu.h +++ b/arch/sh/include/asm/fpu.h @@ -37,11 +37,6 @@ struct user_regset; extern int do_fpu_inst(unsigned short, struct pt_regs *); extern int init_fpu(struct task_struct *); -extern int fpregs_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf); - static inline void __unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs) { if (task_thread_info(tsk)->status & TS_USEDFPU) { diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 6ab397bc47ed..7a59a63560c5 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -93,24 +93,6 @@ void release_thread(struct task_struct *dead_task) /* do nothing */ } -/* Fill in the fpu structure for a core dump.. */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) -{ - int fpvalid = 0; - -#if defined(CONFIG_SH_FPU) - struct task_struct *tsk = current; - - fpvalid = !!tsk_used_math(tsk); - if (fpvalid) - fpvalid = !fpregs_get(tsk, NULL, - (struct membuf){fpu, sizeof(*fpu)}); -#endif - - return fpvalid; -} -EXPORT_SYMBOL(dump_fpu); - asmlinkage void ret_from_fork(void); asmlinkage void ret_from_kernel_thread(void); diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 5c93bdb6c41a..609b7c917e6e 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -165,7 +165,7 @@ static int genregs_set(struct task_struct *target, } #ifdef CONFIG_SH_FPU -int fpregs_get(struct task_struct *target, +static int fpregs_get(struct task_struct *target, const struct user_regset *regset, struct membuf to) { diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 13cb5638fab8..32b41693e648 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -408,55 +408,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, return 0; } -/* - * fill in the fpu structure for a core dump. - */ -int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) -{ - if (used_math()) { - memset(fpregs, 0, sizeof(*fpregs)); - fpregs->pr_q_entrysize = 8; - return 1; - } -#ifdef CONFIG_SMP - if (test_thread_flag(TIF_USEDFPU)) { - put_psr(get_psr() | PSR_EF); - fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, - ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); - if (regs != NULL) { - regs->psr &= ~(PSR_EF); - clear_thread_flag(TIF_USEDFPU); - } - } -#else - if (current == last_task_used_math) { - put_psr(get_psr() | PSR_EF); - fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, - ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); - if (regs != NULL) { - regs->psr &= ~(PSR_EF); - last_task_used_math = NULL; - } - } -#endif - memcpy(&fpregs->pr_fr.pr_regs[0], - ¤t->thread.float_regs[0], - (sizeof(unsigned long) * 32)); - fpregs->pr_fsr = current->thread.fsr; - fpregs->pr_qcnt = current->thread.fpqdepth; - fpregs->pr_q_entrysize = 8; - fpregs->pr_en = 1; - if(fpregs->pr_qcnt != 0) { - memcpy(&fpregs->pr_q[0], - ¤t->thread.fpqueue[0], - sizeof(struct fpq) * fpregs->pr_qcnt); - } - /* Zero out the rest. */ - memset(&fpregs->pr_q[fpregs->pr_qcnt], 0, - sizeof(struct fpq) * (32 - fpregs->pr_qcnt)); - return 1; -} - unsigned long get_wchan(struct task_struct *task) { unsigned long pc, fp, bias = 0; diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 54945eacd3b5..c31b2ac70e3c 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -700,72 +700,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) return 0; } -typedef struct { - union { - unsigned int pr_regs[32]; - unsigned long pr_dregs[16]; - } pr_fr; - unsigned int __unused; - unsigned int pr_fsr; - unsigned char pr_qcnt; - unsigned char pr_q_entrysize; - unsigned char pr_en; - unsigned int pr_q[64]; -} elf_fpregset_t32; - -/* - * fill in the fpu structure for a core dump. - */ -int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) -{ - unsigned long *kfpregs = current_thread_info()->fpregs; - unsigned long fprs = current_thread_info()->fpsaved[0]; - - if (test_thread_flag(TIF_32BIT)) { - elf_fpregset_t32 *fpregs32 = (elf_fpregset_t32 *)fpregs; - - if (fprs & FPRS_DL) - memcpy(&fpregs32->pr_fr.pr_regs[0], kfpregs, - sizeof(unsigned int) * 32); - else - memset(&fpregs32->pr_fr.pr_regs[0], 0, - sizeof(unsigned int) * 32); - fpregs32->pr_qcnt = 0; - fpregs32->pr_q_entrysize = 8; - memset(&fpregs32->pr_q[0], 0, - (sizeof(unsigned int) * 64)); - if (fprs & FPRS_FEF) { - fpregs32->pr_fsr = (unsigned int) current_thread_info()->xfsr[0]; - fpregs32->pr_en = 1; - } else { - fpregs32->pr_fsr = 0; - fpregs32->pr_en = 0; - } - } else { - if(fprs & FPRS_DL) - memcpy(&fpregs->pr_regs[0], kfpregs, - sizeof(unsigned int) * 32); - else - memset(&fpregs->pr_regs[0], 0, - sizeof(unsigned int) * 32); - if(fprs & FPRS_DU) - memcpy(&fpregs->pr_regs[16], kfpregs+16, - sizeof(unsigned int) * 32); - else - memset(&fpregs->pr_regs[16], 0, - sizeof(unsigned int) * 32); - if(fprs & FPRS_FEF) { - fpregs->pr_fsr = current_thread_info()->xfsr[0]; - fpregs->pr_gsr = current_thread_info()->gsr[0]; - } else { - fpregs->pr_fsr = fpregs->pr_gsr = 0; - } - fpregs->pr_fprs = fprs; - } - return 1; -} -EXPORT_SYMBOL(dump_fpu); - unsigned long get_wchan(struct task_struct *task) { unsigned long pc, fp, bias = 0; From e93a977367b2aefff3c1fb426bbdfc6e2980815f Mon Sep 17 00:00:00 2001 From: Luis Alberto Herrera Date: Wed, 10 Jun 2020 22:46:49 +0000 Subject: [PATCH 214/242] mtd: revert "spi-nor: intel: provide a range for poll_timout" This change reverts aba3a882a178: "mtd: spi-nor: intel: provide a range for poll_timout". That change introduces a performance regression when reading sequentially from flash. Logging calls to intel_spi_read without this change we get: Start MTD read [ 20.045527] intel_spi_read(from=1800000, len=400000) [ 20.045527] intel_spi_read(from=1800000, len=400000) [ 282.199274] intel_spi_read(from=1c00000, len=400000) [ 282.199274] intel_spi_read(from=1c00000, len=400000) [ 544.351528] intel_spi_read(from=2000000, len=400000) [ 544.351528] intel_spi_read(from=2000000, len=400000) End MTD read With this change: Start MTD read [ 21.942922] intel_spi_read(from=1c00000, len=400000) [ 21.942922] intel_spi_read(from=1c00000, len=400000) [ 23.784058] intel_spi_read(from=2000000, len=400000) [ 23.784058] intel_spi_read(from=2000000, len=400000) [ 25.625006] intel_spi_read(from=2400000, len=400000) [ 25.625006] intel_spi_read(from=2400000, len=400000) End MTD read Signed-off-by: Luis Alberto Herrera Tested-by: Alexander Sverdlin Acked-by: Mika Westerberg Link: https://lore.kernel.org/r/20200610224652.64336-1-luisalberto@google.com Signed-off-by: Tudor Ambarus --- drivers/mtd/spi-nor/controllers/intel-spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi.c index 3259c9fc981f..b54a56a68100 100644 --- a/drivers/mtd/spi-nor/controllers/intel-spi.c +++ b/drivers/mtd/spi-nor/controllers/intel-spi.c @@ -292,7 +292,7 @@ static int intel_spi_wait_hw_busy(struct intel_spi *ispi) u32 val; return readl_poll_timeout(ispi->base + HSFSTS_CTL, val, - !(val & HSFSTS_CTL_SCIP), 40, + !(val & HSFSTS_CTL_SCIP), 0, INTEL_SPI_TIMEOUT * 1000); } @@ -301,7 +301,7 @@ static int intel_spi_wait_sw_busy(struct intel_spi *ispi) u32 val; return readl_poll_timeout(ispi->sregs + SSFSTS_CTL, val, - !(val & SSFSTS_CTL_SCIP), 40, + !(val & SSFSTS_CTL_SCIP), 0, INTEL_SPI_TIMEOUT * 1000); } From 64d26422516b2e347b32e6d9b1d40b3c19a62aae Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 30 Jun 2020 15:55:45 -0400 Subject: [PATCH 215/242] svcrdma: Fix another Receive buffer leak During a connection tear down, the Receive queue is flushed before the device resources are freed. Typically, all the Receives flush with IB_WR_FLUSH_ERR. However, any pending successful Receives flush with IB_WR_SUCCESS, and the server automatically posts a fresh Receive to replace the completing one. This happens even after the connection has closed and the RQ is drained. Receives that are posted after the RQ is drained appear never to complete, causing a Receive resource leak. The leaked Receive buffer is left DMA-mapped. To prevent these late-posted recv_ctxt's from leaking, block new Receive posting after XPT_CLOSE is set. Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index d5ec85cb652c..5bb97b5f4606 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -275,6 +275,8 @@ static int svc_rdma_post_recv(struct svcxprt_rdma *rdma) { struct svc_rdma_recv_ctxt *ctxt; + if (test_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags)) + return 0; ctxt = svc_rdma_recv_ctxt_get(rdma); if (!ctxt) return -ENOMEM; From 365e9992b90fbbfda89f72866783fd52bbd58e64 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 30 Jun 2020 13:25:41 -0400 Subject: [PATCH 216/242] svcrdma: Remove transport reference counting Jason tells me that a ULP cannot rely on getting an ESTABLISHED and DISCONNECTED event pair for each connection, so transport reference counting in the CM event handler will never be reliable. Now that we have ib_drain_qp(), svcrdma should no longer need to hold transport references while Sends and Receives are posted. So remove the get/put call sites in the CM event handlers. This eliminates a significant source of locked memory bus traffic. Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 6 +----- net/sunrpc/xprtrdma/svc_rdma_rw.c | 2 -- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 4 ---- net/sunrpc/xprtrdma/svc_rdma_transport.c | 17 +---------------- 4 files changed, 2 insertions(+), 27 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 5bb97b5f4606..c6ea2903c21a 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -257,7 +257,6 @@ static int __svc_rdma_post_recv(struct svcxprt_rdma *rdma, { int ret; - svc_xprt_get(&rdma->sc_xprt); trace_svcrdma_post_recv(ctxt); ret = ib_post_recv(rdma->sc_qp, &ctxt->rc_recv_wr, NULL); if (ret) @@ -267,7 +266,6 @@ static int __svc_rdma_post_recv(struct svcxprt_rdma *rdma, err_post: trace_svcrdma_rq_post_err(rdma, ret); svc_rdma_recv_ctxt_put(rdma, ctxt); - svc_xprt_put(&rdma->sc_xprt); return ret; } @@ -344,15 +342,13 @@ static void svc_rdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc) spin_unlock(&rdma->sc_rq_dto_lock); if (!test_bit(RDMAXPRT_CONN_PENDING, &rdma->sc_flags)) svc_xprt_enqueue(&rdma->sc_xprt); - goto out; + return; flushed: post_err: svc_rdma_recv_ctxt_put(rdma, ctxt); set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags); svc_xprt_enqueue(&rdma->sc_xprt); -out: - svc_xprt_put(&rdma->sc_xprt); } /** diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index c16d10601d65..fe54cbe97a46 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -164,7 +164,6 @@ static void svc_rdma_cc_init(struct svcxprt_rdma *rdma, { svc_rdma_cc_cid_init(rdma, &cc->cc_cid); cc->cc_rdma = rdma; - svc_xprt_get(&rdma->sc_xprt); INIT_LIST_HEAD(&cc->cc_rwctxts); cc->cc_sqecount = 0; @@ -184,7 +183,6 @@ static void svc_rdma_cc_release(struct svc_rdma_chunk_ctxt *cc, ctxt->rw_nents, dir); svc_rdma_put_rw_ctxt(rdma, ctxt); } - svc_xprt_put(&rdma->sc_xprt); } /* State for sending a Write or Reply chunk. diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 73d46e8cdc16..7b94d971feb3 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -291,8 +291,6 @@ static void svc_rdma_wc_send(struct ib_cq *cq, struct ib_wc *wc) set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags); svc_xprt_enqueue(&rdma->sc_xprt); } - - svc_xprt_put(&rdma->sc_xprt); } /** @@ -330,7 +328,6 @@ int svc_rdma_send(struct svcxprt_rdma *rdma, struct svc_rdma_send_ctxt *ctxt) continue; } - svc_xprt_get(&rdma->sc_xprt); trace_svcrdma_post_send(ctxt); ret = ib_post_send(rdma->sc_qp, wr, NULL); if (ret) @@ -340,7 +337,6 @@ int svc_rdma_send(struct svcxprt_rdma *rdma, struct svc_rdma_send_ctxt *ctxt) trace_svcrdma_sq_post_err(rdma, ret); set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags); - svc_xprt_put(&rdma->sc_xprt); wake_up(&rdma->sc_send_wait); return ret; } diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 3da7901a49e6..aa60f75c8c1d 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -271,7 +271,6 @@ static int rdma_cma_handler(struct rdma_cm_id *cma_id, switch (event->event) { case RDMA_CM_EVENT_ESTABLISHED: /* Accept complete */ - svc_xprt_get(xprt); dprintk("svcrdma: Connection completed on DTO xprt=%p, " "cm_id=%p\n", xprt, cma_id); clear_bit(RDMAXPRT_CONN_PENDING, &rdma->sc_flags); @@ -282,7 +281,6 @@ static int rdma_cma_handler(struct rdma_cm_id *cma_id, xprt, cma_id); set_bit(XPT_CLOSE, &xprt->xpt_flags); svc_xprt_enqueue(xprt); - svc_xprt_put(xprt); break; case RDMA_CM_EVENT_DEVICE_REMOVAL: dprintk("svcrdma: Device removal cma_id=%p, xprt = %p, " @@ -290,7 +288,6 @@ static int rdma_cma_handler(struct rdma_cm_id *cma_id, rdma_event_msg(event->event), event->event); set_bit(XPT_CLOSE, &xprt->xpt_flags); svc_xprt_enqueue(xprt); - svc_xprt_put(xprt); break; default: dprintk("svcrdma: Unexpected event on DTO endpoint %p, " @@ -539,24 +536,11 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) return NULL; } -/* - * When connected, an svc_xprt has at least two references: - * - * - A reference held by the cm_id between the ESTABLISHED and - * DISCONNECTED events. If the remote peer disconnected first, this - * reference could be gone. - * - * - A reference held by the svc_recv code that called this function - * as part of close processing. - * - * At a minimum one references should still be held. - */ static void svc_rdma_detach(struct svc_xprt *xprt) { struct svcxprt_rdma *rdma = container_of(xprt, struct svcxprt_rdma, sc_xprt); - /* Disconnect and flush posted WQE */ rdma_disconnect(rdma->sc_cm_id); } @@ -566,6 +550,7 @@ static void __svc_rdma_free(struct work_struct *work) container_of(work, struct svcxprt_rdma, sc_work); struct svc_xprt *xprt = &rdma->sc_xprt; + /* This blocks until the Completion Queues are empty */ if (rdma->sc_qp && !IS_ERR(rdma->sc_qp)) ib_drain_qp(rdma->sc_qp); From b297fed699ad9e50315b27e78de42ac631c9990d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 30 Jun 2020 17:16:35 -0400 Subject: [PATCH 217/242] svcrdma: CM event handler clean up Now that there's a core tracepoint that reports these events, there's no need to maintain dprintk() call sites in each arm of the switch statements. We also refresh the documenting comments. Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_transport.c | 56 +++++++++++------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index aa60f75c8c1d..fb044792b571 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -237,62 +237,56 @@ static void handle_connect_req(struct rdma_cm_id *new_cma_id, svc_xprt_enqueue(&listen_xprt->sc_xprt); } -/* - * Handles events generated on the listening endpoint. These events will be - * either be incoming connect requests or adapter removal events. +/** + * svc_rdma_listen_handler - Handle CM events generated on a listening endpoint + * @cma_id: the server's listener rdma_cm_id + * @event: details of the event + * + * Return values: + * %0: Do not destroy @cma_id + * %1: Destroy @cma_id (never returned here) + * + * NB: There is never a DEVICE_REMOVAL event for INADDR_ANY listeners. */ -static int rdma_listen_handler(struct rdma_cm_id *cma_id, - struct rdma_cm_event *event) +static int svc_rdma_listen_handler(struct rdma_cm_id *cma_id, + struct rdma_cm_event *event) { switch (event->event) { case RDMA_CM_EVENT_CONNECT_REQUEST: - dprintk("svcrdma: Connect request on cma_id=%p, xprt = %p, " - "event = %s (%d)\n", cma_id, cma_id->context, - rdma_event_msg(event->event), event->event); handle_connect_req(cma_id, &event->param.conn); break; default: - /* NB: No device removal upcall for INADDR_ANY listeners */ - dprintk("svcrdma: Unexpected event on listening endpoint %p, " - "event = %s (%d)\n", cma_id, - rdma_event_msg(event->event), event->event); break; } - return 0; } -static int rdma_cma_handler(struct rdma_cm_id *cma_id, - struct rdma_cm_event *event) +/** + * svc_rdma_cma_handler - Handle CM events on client connections + * @cma_id: the server's listener rdma_cm_id + * @event: details of the event + * + * Return values: + * %0: Do not destroy @cma_id + * %1: Destroy @cma_id (never returned here) + */ +static int svc_rdma_cma_handler(struct rdma_cm_id *cma_id, + struct rdma_cm_event *event) { struct svcxprt_rdma *rdma = cma_id->context; struct svc_xprt *xprt = &rdma->sc_xprt; switch (event->event) { case RDMA_CM_EVENT_ESTABLISHED: - /* Accept complete */ - dprintk("svcrdma: Connection completed on DTO xprt=%p, " - "cm_id=%p\n", xprt, cma_id); clear_bit(RDMAXPRT_CONN_PENDING, &rdma->sc_flags); svc_xprt_enqueue(xprt); break; case RDMA_CM_EVENT_DISCONNECTED: - dprintk("svcrdma: Disconnect on DTO xprt=%p, cm_id=%p\n", - xprt, cma_id); - set_bit(XPT_CLOSE, &xprt->xpt_flags); - svc_xprt_enqueue(xprt); - break; case RDMA_CM_EVENT_DEVICE_REMOVAL: - dprintk("svcrdma: Device removal cma_id=%p, xprt = %p, " - "event = %s (%d)\n", cma_id, xprt, - rdma_event_msg(event->event), event->event); set_bit(XPT_CLOSE, &xprt->xpt_flags); svc_xprt_enqueue(xprt); break; default: - dprintk("svcrdma: Unexpected event on DTO endpoint %p, " - "event = %s (%d)\n", cma_id, - rdma_event_msg(event->event), event->event); break; } return 0; @@ -318,7 +312,7 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags); strcpy(cma_xprt->sc_xprt.xpt_remotebuf, "listener"); - listen_id = rdma_create_id(net, rdma_listen_handler, cma_xprt, + listen_id = rdma_create_id(net, svc_rdma_listen_handler, cma_xprt, RDMA_PS_TCP, IB_QPT_RC); if (IS_ERR(listen_id)) { ret = PTR_ERR(listen_id); @@ -482,7 +476,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) goto errout; /* Swap out the handler */ - newxprt->sc_cm_id->event_handler = rdma_cma_handler; + newxprt->sc_cm_id->event_handler = svc_rdma_cma_handler; /* Construct RDMA-CM private message */ pmsg.cp_magic = rpcrdma_cmp_magic; From 614a895fc69497d99cc02c076fa712c75194eab3 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 9 Jul 2020 20:07:33 +0200 Subject: [PATCH 218/242] mtd: hyperbus: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Signed-off-by: Richard Weinberger --- drivers/mtd/hyperbus/hbmc-am654.c | 2 +- drivers/mtd/hyperbus/hyperbus-core.c | 2 +- include/linux/mtd/hyperbus.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/hyperbus/hbmc-am654.c b/drivers/mtd/hyperbus/hbmc-am654.c index f350a0809f88..e0e33f6bf513 100644 --- a/drivers/mtd/hyperbus/hbmc-am654.c +++ b/drivers/mtd/hyperbus/hbmc-am654.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // -// Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ +// Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/ // Author: Vignesh Raghavendra #include diff --git a/drivers/mtd/hyperbus/hyperbus-core.c b/drivers/mtd/hyperbus/hyperbus-core.c index 32685e8dd278..2f9fc4e17d53 100644 --- a/drivers/mtd/hyperbus/hyperbus-core.c +++ b/drivers/mtd/hyperbus/hyperbus-core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // -// Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ +// Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/ // Author: Vignesh Raghavendra #include diff --git a/include/linux/mtd/hyperbus.h b/include/linux/mtd/hyperbus.h index 2dfe65964f6e..2129f7d3b6eb 100644 --- a/include/linux/mtd/hyperbus.h +++ b/include/linux/mtd/hyperbus.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 * - * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/ */ #ifndef __LINUX_MTD_HYPERBUS_H__ From c13ac5552546c8971c0a4a3e947e25b0f8786aa9 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 13 Jul 2020 18:54:08 +0200 Subject: [PATCH 219/242] mtd: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Acked-by: Rob Herring Signed-off-by: Richard Weinberger --- Documentation/devicetree/bindings/mtd/davinci-nand.txt | 4 ++-- drivers/mtd/chips/Kconfig | 2 +- drivers/mtd/maps/Kconfig | 2 +- drivers/mtd/maps/sc520cdp.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/davinci-nand.txt b/Documentation/devicetree/bindings/mtd/davinci-nand.txt index cfb18abe6001..edebeae1f5b3 100644 --- a/Documentation/devicetree/bindings/mtd/davinci-nand.txt +++ b/Documentation/devicetree/bindings/mtd/davinci-nand.txt @@ -4,8 +4,8 @@ This file provides information, what the device node for the davinci/keystone NAND interface contains. Documentation: -Davinci DM646x - http://www.ti.com/lit/ug/sprueq7c/sprueq7c.pdf -Kestone - http://www.ti.com/lit/ug/sprugz3a/sprugz3a.pdf +Davinci DM646x - https://www.ti.com/lit/ug/sprueq7c/sprueq7c.pdf +Kestone - https://www.ti.com/lit/ug/sprugz3a/sprugz3a.pdf Required properties: diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index a7e47e068ad9..aef14990e5f7 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig @@ -11,7 +11,7 @@ config MTD_CFI AMD and other flash manufactures that provides a universal method for probing the capabilities of flash devices. If you wish to support any device that is CFI-compliant, you need to enable this - option. Visit + option. Visit for more information on CFI. config MTD_JEDECPROBE diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index b28225a7c4f3..fd37553f1b07 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -310,7 +310,7 @@ config MTD_DC21285 help This provides a driver for the flash accessed using Intel's 21285 bridge used with Intel's StrongARM processors. More info at - . + . config MTD_IXP4XX tristate "CFI Flash device mapped on Intel IXP4xx based systems" diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c index 9902b37e18b4..8ef7aec634c7 100644 --- a/drivers/mtd/maps/sc520cdp.c +++ b/drivers/mtd/maps/sc520cdp.c @@ -6,7 +6,7 @@ * The SC520CDP is an evaluation board for the Elan SC520 processor available * from AMD. It has two banks of 32-bit Flash ROM, each 8 Megabytes in size, * and up to 512 KiB of 8-bit DIL Flash ROM. - * For details see http://www.amd.com/products/epd/desiging/evalboards/18.elansc520/520_cdp_brief/index.html + * For details see https://www.amd.com/products/epd/desiging/evalboards/18.elansc520/520_cdp_brief/index.html */ #include From 3d19792a7d7279b1aece733c2605a3671c6459c9 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 13 Jul 2020 19:04:20 +0200 Subject: [PATCH 220/242] mtd: rawnand: omap_elm: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Signed-off-by: Richard Weinberger --- drivers/mtd/nand/raw/omap_elm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c index 078b1022ac2a..4b799521a427 100644 --- a/drivers/mtd/nand/raw/omap_elm.c +++ b/drivers/mtd/nand/raw/omap_elm.c @@ -2,7 +2,7 @@ /* * Error Location Module * - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ */ #define DRIVER_NAME "omap-elm" From f8951902b9daa65ba240ce8a054c727748df2147 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 18 Jul 2020 17:32:08 -0700 Subject: [PATCH 221/242] MTD: mtd-abi.h: drop a duplicated word Drop the repeated word "mode" in a comment. Signed-off-by: Randy Dunlap Cc: Miquel Raynal Cc: Richard Weinberger Cc: Vignesh Raghavendra Cc: linux-mtd@lists.infradead.org Signed-off-by: Richard Weinberger --- include/uapi/mtd/mtd-abi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h index 4b48fbf7d343..65b9db936557 100644 --- a/include/uapi/mtd/mtd-abi.h +++ b/include/uapi/mtd/mtd-abi.h @@ -262,7 +262,7 @@ struct mtd_ecc_stats { * @MTD_FILE_MODE_OTP_USER: OTP enabled in user mode * @MTD_FILE_MODE_RAW: OTP disabled, ECC disabled * - * These modes can be set via ioctl(MTDFILEMODE). The mode mode will be retained + * These modes can be set via ioctl(MTDFILEMODE). The mode will be retained * separately for each open file descriptor. * * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW - From 0c84b7fc973f9220ef8732c430ccc7c92d083184 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 18 Jul 2020 17:29:54 -0700 Subject: [PATCH 222/242] MTD: pfow.h: drop a duplicated word Drop the repeated word "can" in a comment. Signed-off-by: Randy Dunlap Cc: Miquel Raynal Cc: Richard Weinberger Cc: Vignesh Raghavendra Cc: linux-mtd@lists.infradead.org Signed-off-by: Richard Weinberger --- include/linux/mtd/pfow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mtd/pfow.h b/include/linux/mtd/pfow.h index 122f3439e1af..6166e7c60869 100644 --- a/include/linux/mtd/pfow.h +++ b/include/linux/mtd/pfow.h @@ -19,7 +19,7 @@ /* Identification info for LPDDR chip */ #define PFOW_MANUFACTURER_ID 0x0020 #define PFOW_DEVICE_ID 0x0022 -/* Address in PFOW where prog buffer can can be found */ +/* Address in PFOW where prog buffer can be found */ #define PFOW_PROGRAM_BUFFER_OFFSET 0x0040 /* Size of program buffer in words */ #define PFOW_PROGRAM_BUFFER_SIZE 0x0042 From edd546465002621665a3a275abe908a30efdce5b Mon Sep 17 00:00:00 2001 From: Hanks Chen Date: Thu, 23 Jul 2020 19:19:53 +0800 Subject: [PATCH 223/242] pinctrl: mediatek: avoid virtual gpio trying to set reg for virtual gpios, they should not do reg setting and should behave as expected for eint function. Signed-off-by: Mars Cheng Signed-off-by: Hanks Chen Acked-by: Sean Wang Link: https://lore.kernel.org/r/1595503197-15246-4-git-send-email-hanks.chen@mediatek.com Signed-off-by: Linus Walleij --- .../pinctrl/mediatek/pinctrl-mtk-common-v2.c | 25 +++++++++++++++++++ .../pinctrl/mediatek/pinctrl-mtk-common-v2.h | 1 + drivers/pinctrl/mediatek/pinctrl-paris.c | 7 ++++++ 3 files changed, 33 insertions(+) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index b77b18fe5adc..c53e2c391e32 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -243,6 +243,28 @@ static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n) return EINT_NA; } +/* + * Virtual GPIO only used inside SOC and not being exported to outside SOC. + * Some modules use virtual GPIO as eint (e.g. pmif or usb). + * In MTK platform, external interrupt (EINT) and GPIO is 1-1 mapping + * and we can set GPIO as eint. + * But some modules use specific eint which doesn't have real GPIO pin. + * So we use virtual GPIO to map it. + */ + +bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n) +{ + const struct mtk_pin_desc *desc; + bool virt_gpio = false; + + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n]; + + if (desc->funcs && !desc->funcs[desc->eint.eint_m].name) + virt_gpio = true; + + return virt_gpio; +} + static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n, unsigned int *gpio_n, struct gpio_chip **gpio_chip) @@ -295,6 +317,9 @@ static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n) if (err) return err; + if (mtk_is_virt_gpio(hw, gpio_n)) + return 0; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio_n]; err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE, diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h index 45aa0fdbe330..e2aae285b5fc 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -315,4 +315,5 @@ int mtk_pinconf_adv_drive_set(struct mtk_pinctrl *hw, int mtk_pinconf_adv_drive_get(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 *val); +bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n); #endif /* __PINCTRL_MTK_COMMON_V2_H */ diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c index 90a432bf9fed..a23c18251965 100644 --- a/drivers/pinctrl/mediatek/pinctrl-paris.c +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -769,6 +769,13 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio) if (gpio >= hw->soc->npins) return -EINVAL; + /* + * "Virtual" GPIOs are always and only used for interrupts + * Since they are only used for interrupts, they are always inputs + */ + if (mtk_is_virt_gpio(hw, gpio)) + return 1; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value); From 920e469e15c820a432c8dc21f7c5221f9dfdf716 Mon Sep 17 00:00:00 2001 From: Hanks Chen Date: Thu, 23 Jul 2020 19:19:54 +0800 Subject: [PATCH 224/242] pinctrl: mediatek: add pinctrl support for MT6779 SoC This adds MT6779 pinctrl driver based on MediaTek pinctrl-paris core. Signed-off-by: Mars Cheng Signed-off-by: Andy Teng Signed-off-by: Hanks Chen Acked-by: Sean Wang Link: https://lore.kernel.org/r/1595503197-15246-5-git-send-email-hanks.chen@mediatek.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/Kconfig | 12 + drivers/pinctrl/mediatek/Makefile | 1 + drivers/pinctrl/mediatek/pinctrl-mt6779.c | 777 ++++++ drivers/pinctrl/mediatek/pinctrl-mtk-mt6779.h | 2085 +++++++++++++++++ 4 files changed, 2875 insertions(+) create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt6779.c create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt6779.h diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig index f32d3644c509..1cedc5f2aadb 100644 --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -93,6 +93,18 @@ config PINCTRL_MT6765 default ARM64 && ARCH_MEDIATEK select PINCTRL_MTK_PARIS +config PINCTRL_MT6779 + tristate "Mediatek MT6779 pin control" + depends on OF + depends on ARM64 || COMPILE_TEST + default ARM64 && ARCH_MEDIATEK + select PINCTRL_MTK_PARIS + help + Say yes here to support pin controller and gpio driver + on Mediatek MT6779 SoC. + In MTK platform, we support virtual gpio and use it to + map specific eint which doesn't have real gpio pin. + config PINCTRL_MT6797 bool "Mediatek MT6797 pin control" depends on OF diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile index 4b7132876e71..b0b07c541d11 100644 --- a/drivers/pinctrl/mediatek/Makefile +++ b/drivers/pinctrl/mediatek/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_PINCTRL_MT2712) += pinctrl-mt2712.o obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o obj-$(CONFIG_PINCTRL_MT6765) += pinctrl-mt6765.o +obj-$(CONFIG_PINCTRL_MT6779) += pinctrl-mt6779.o obj-$(CONFIG_PINCTRL_MT6797) += pinctrl-mt6797.o obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6779.c b/drivers/pinctrl/mediatek/pinctrl-mt6779.c new file mode 100644 index 000000000000..ede185b58d41 --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mt6779.c @@ -0,0 +1,777 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * Author: Andy Teng + * + */ + +#include +#include "pinctrl-mtk-mt6779.h" +#include "pinctrl-paris.h" + +/* MT6779 have multiple bases to program pin configuration listed as the below: + * gpio:0x10005000, iocfg_rm:0x11C20000, iocfg_br:0x11D10000, + * iocfg_lm:0x11E20000, iocfg_lb:0x11E70000, iocfg_rt:0x11EA0000, + * iocfg_lt:0x11F20000, iocfg_tl:0x11F30000 + * _i_based could be used to indicate what base the pin should be mapped into. + */ + +#define PIN_FIELD_BASE(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits) \ + PIN_FIELD_CALC(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits, \ + 32, 0) + +#define PINS_FIELD_BASE(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits) \ + PIN_FIELD_CALC(s_pin, e_pin, i_base, s_addr, x_addrs, s_bit, x_bits, \ + 32, 1) + +static const struct mtk_pin_field_calc mt6779_pin_mode_range[] = { + PIN_FIELD_BASE(0, 7, 0, 0x0300, 0x10, 0, 4), + PIN_FIELD_BASE(8, 15, 0, 0x0310, 0x10, 0, 4), + PIN_FIELD_BASE(16, 23, 0, 0x0320, 0x10, 0, 4), + PIN_FIELD_BASE(24, 31, 0, 0x0330, 0x10, 0, 4), + PIN_FIELD_BASE(32, 39, 0, 0x0340, 0x10, 0, 4), + PIN_FIELD_BASE(40, 47, 0, 0x0350, 0x10, 0, 4), + PIN_FIELD_BASE(48, 55, 0, 0x0360, 0x10, 0, 4), + PIN_FIELD_BASE(56, 63, 0, 0x0370, 0x10, 0, 4), + PIN_FIELD_BASE(64, 71, 0, 0x0380, 0x10, 0, 4), + PIN_FIELD_BASE(72, 79, 0, 0x0390, 0x10, 0, 4), + PIN_FIELD_BASE(80, 87, 0, 0x03A0, 0x10, 0, 4), + PIN_FIELD_BASE(88, 95, 0, 0x03B0, 0x10, 0, 4), + PIN_FIELD_BASE(96, 103, 0, 0x03C0, 0x10, 0, 4), + PIN_FIELD_BASE(104, 111, 0, 0x03D0, 0x10, 0, 4), + PIN_FIELD_BASE(112, 119, 0, 0x03E0, 0x10, 0, 4), + PIN_FIELD_BASE(120, 127, 0, 0x03F0, 0x10, 0, 4), + PIN_FIELD_BASE(128, 135, 0, 0x0400, 0x10, 0, 4), + PIN_FIELD_BASE(136, 143, 0, 0x0410, 0x10, 0, 4), + PIN_FIELD_BASE(144, 151, 0, 0x0420, 0x10, 0, 4), + PIN_FIELD_BASE(152, 159, 0, 0x0430, 0x10, 0, 4), + PIN_FIELD_BASE(160, 167, 0, 0x0440, 0x10, 0, 4), + PIN_FIELD_BASE(168, 175, 0, 0x0450, 0x10, 0, 4), + PIN_FIELD_BASE(176, 183, 0, 0x0460, 0x10, 0, 4), + PIN_FIELD_BASE(184, 191, 0, 0x0470, 0x10, 0, 4), + PIN_FIELD_BASE(192, 199, 0, 0x0480, 0x10, 0, 4), + PIN_FIELD_BASE(200, 202, 0, 0x0490, 0x10, 0, 4), +}; + +static const struct mtk_pin_field_calc mt6779_pin_dir_range[] = { + PIN_FIELD_BASE(0, 31, 0, 0x0000, 0x10, 0, 1), + PIN_FIELD_BASE(32, 63, 0, 0x0010, 0x10, 0, 1), + PIN_FIELD_BASE(64, 95, 0, 0x0020, 0x10, 0, 1), + PIN_FIELD_BASE(96, 127, 0, 0x0030, 0x10, 0, 1), + PIN_FIELD_BASE(128, 159, 0, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(160, 191, 0, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(192, 202, 0, 0x0060, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_di_range[] = { + PIN_FIELD_BASE(0, 31, 0, 0x0200, 0x10, 0, 1), + PIN_FIELD_BASE(32, 63, 0, 0x0210, 0x10, 0, 1), + PIN_FIELD_BASE(64, 95, 0, 0x0220, 0x10, 0, 1), + PIN_FIELD_BASE(96, 127, 0, 0x0230, 0x10, 0, 1), + PIN_FIELD_BASE(128, 159, 0, 0x0240, 0x10, 0, 1), + PIN_FIELD_BASE(160, 191, 0, 0x0250, 0x10, 0, 1), + PIN_FIELD_BASE(192, 202, 0, 0x0260, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_do_range[] = { + PIN_FIELD_BASE(0, 31, 0, 0x0100, 0x10, 0, 1), + PIN_FIELD_BASE(32, 63, 0, 0x0110, 0x10, 0, 1), + PIN_FIELD_BASE(64, 95, 0, 0x0120, 0x10, 0, 1), + PIN_FIELD_BASE(96, 127, 0, 0x0130, 0x10, 0, 1), + PIN_FIELD_BASE(128, 159, 0, 0x0140, 0x10, 0, 1), + PIN_FIELD_BASE(160, 191, 0, 0x0150, 0x10, 0, 1), + PIN_FIELD_BASE(192, 202, 0, 0x0160, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_ies_range[] = { + PIN_FIELD_BASE(0, 9, 6, 0x0030, 0x10, 3, 1), + PIN_FIELD_BASE(10, 16, 3, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(17, 18, 6, 0x0030, 0x10, 28, 1), + PIN_FIELD_BASE(19, 19, 6, 0x0030, 0x10, 27, 1), + PIN_FIELD_BASE(20, 20, 6, 0x0030, 0x10, 26, 1), + PIN_FIELD_BASE(21, 24, 6, 0x0030, 0x10, 19, 1), + PIN_FIELD_BASE(25, 25, 6, 0x0030, 0x10, 30, 1), + PIN_FIELD_BASE(26, 26, 6, 0x0030, 0x10, 23, 1), + PIN_FIELD_BASE(27, 27, 6, 0x0030, 0x10, 0, 1), + PIN_FIELD_BASE(28, 29, 6, 0x0030, 0x10, 24, 1), + PIN_FIELD_BASE(30, 30, 6, 0x0030, 0x10, 16, 1), + PIN_FIELD_BASE(31, 31, 6, 0x0030, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 6, 0x0030, 0x10, 15, 1), + PIN_FIELD_BASE(33, 33, 6, 0x0030, 0x10, 17, 1), + PIN_FIELD_BASE(34, 34, 6, 0x0030, 0x10, 14, 1), + PIN_FIELD_BASE(35, 35, 6, 0x0040, 0x10, 4, 1), + PIN_FIELD_BASE(36, 36, 6, 0x0030, 0x10, 31, 1), + PIN_FIELD_BASE(37, 37, 6, 0x0040, 0x10, 5, 1), + PIN_FIELD_BASE(38, 41, 6, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(42, 43, 6, 0x0030, 0x10, 1, 1), + PIN_FIELD_BASE(44, 44, 6, 0x0030, 0x10, 18, 1), + PIN_FIELD_BASE(45, 45, 3, 0x0050, 0x10, 14, 1), + PIN_FIELD_BASE(46, 46, 3, 0x0050, 0x10, 22, 1), + PIN_FIELD_BASE(47, 47, 3, 0x0050, 0x10, 25, 1), + PIN_FIELD_BASE(48, 48, 3, 0x0050, 0x10, 24, 1), + PIN_FIELD_BASE(49, 49, 3, 0x0050, 0x10, 26, 1), + PIN_FIELD_BASE(50, 50, 3, 0x0050, 0x10, 23, 1), + PIN_FIELD_BASE(51, 51, 3, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(52, 52, 3, 0x0050, 0x10, 19, 1), + PIN_FIELD_BASE(53, 54, 3, 0x0050, 0x10, 27, 1), + PIN_FIELD_BASE(55, 55, 3, 0x0050, 0x10, 13, 1), + PIN_FIELD_BASE(56, 56, 3, 0x0050, 0x10, 21, 1), + PIN_FIELD_BASE(57, 57, 3, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(58, 58, 3, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(59, 60, 3, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(61, 61, 3, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(62, 62, 3, 0x0050, 0x10, 20, 1), + PIN_FIELD_BASE(63, 63, 3, 0x0050, 0x10, 17, 1), + PIN_FIELD_BASE(64, 64, 3, 0x0050, 0x10, 16, 1), + PIN_FIELD_BASE(65, 65, 3, 0x0050, 0x10, 18, 1), + PIN_FIELD_BASE(66, 66, 3, 0x0050, 0x10, 15, 1), + PIN_FIELD_BASE(67, 67, 2, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(68, 68, 2, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(69, 69, 2, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(70, 71, 2, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(72, 72, 4, 0x0020, 0x10, 3, 1), + PIN_FIELD_BASE(73, 73, 4, 0x0020, 0x10, 2, 1), + PIN_FIELD_BASE(74, 74, 4, 0x0020, 0x10, 1, 1), + PIN_FIELD_BASE(75, 75, 4, 0x0020, 0x10, 4, 1), + PIN_FIELD_BASE(76, 76, 4, 0x0020, 0x10, 12, 1), + PIN_FIELD_BASE(77, 77, 4, 0x0020, 0x10, 11, 1), + PIN_FIELD_BASE(78, 78, 2, 0x0050, 0x10, 18, 1), + PIN_FIELD_BASE(79, 79, 2, 0x0050, 0x10, 17, 1), + PIN_FIELD_BASE(80, 81, 2, 0x0050, 0x10, 19, 1), + PIN_FIELD_BASE(82, 88, 2, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(89, 89, 2, 0x0050, 0x10, 16, 1), + PIN_FIELD_BASE(90, 90, 2, 0x0050, 0x10, 15, 1), + PIN_FIELD_BASE(91, 91, 2, 0x0050, 0x10, 14, 1), + PIN_FIELD_BASE(92, 92, 2, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(93, 93, 4, 0x0020, 0x10, 0, 1), + PIN_FIELD_BASE(94, 94, 2, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(95, 95, 4, 0x0020, 0x10, 7, 1), + PIN_FIELD_BASE(96, 96, 4, 0x0020, 0x10, 5, 1), + PIN_FIELD_BASE(97, 97, 4, 0x0020, 0x10, 8, 1), + PIN_FIELD_BASE(98, 98, 4, 0x0020, 0x10, 6, 1), + PIN_FIELD_BASE(99, 99, 2, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(100, 100, 2, 0x0060, 0x10, 12, 1), + PIN_FIELD_BASE(101, 101, 2, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(102, 102, 2, 0x0060, 0x10, 13, 1), + PIN_FIELD_BASE(103, 103, 2, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(104, 104, 2, 0x0060, 0x10, 14, 1), + PIN_FIELD_BASE(105, 105, 2, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(106, 106, 2, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(107, 108, 2, 0x0050, 0x10, 12, 1), + PIN_FIELD_BASE(109, 109, 2, 0x0050, 0x10, 11, 1), + PIN_FIELD_BASE(110, 110, 2, 0x0060, 0x10, 16, 1), + PIN_FIELD_BASE(111, 111, 2, 0x0060, 0x10, 18, 1), + PIN_FIELD_BASE(112, 112, 2, 0x0060, 0x10, 15, 1), + PIN_FIELD_BASE(113, 113, 2, 0x0060, 0x10, 17, 1), + PIN_FIELD_BASE(114, 115, 2, 0x0050, 0x10, 26, 1), + PIN_FIELD_BASE(116, 117, 2, 0x0050, 0x10, 21, 1), + PIN_FIELD_BASE(118, 118, 2, 0x0050, 0x10, 31, 1), + PIN_FIELD_BASE(119, 119, 2, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(120, 121, 2, 0x0050, 0x10, 23, 1), + PIN_FIELD_BASE(122, 123, 2, 0x0050, 0x10, 28, 1), + PIN_FIELD_BASE(124, 125, 2, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(126, 127, 1, 0x0030, 0x10, 8, 1), + PIN_FIELD_BASE(128, 129, 1, 0x0030, 0x10, 17, 1), + PIN_FIELD_BASE(130, 130, 1, 0x0030, 0x10, 16, 1), + PIN_FIELD_BASE(131, 131, 1, 0x0030, 0x10, 19, 1), + PIN_FIELD_BASE(132, 132, 1, 0x0030, 0x10, 21, 1), + PIN_FIELD_BASE(133, 133, 1, 0x0030, 0x10, 20, 1), + PIN_FIELD_BASE(134, 135, 1, 0x0030, 0x10, 2, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0030, 0x10, 7, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0030, 0x10, 4, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0030, 0x10, 6, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0030, 0x10, 5, 1), + PIN_FIELD_BASE(140, 141, 1, 0x0030, 0x10, 0, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0030, 0x10, 15, 1), + PIN_FIELD_BASE(143, 143, 5, 0x0020, 0x10, 15, 1), + PIN_FIELD_BASE(144, 144, 5, 0x0020, 0x10, 17, 1), + PIN_FIELD_BASE(145, 145, 5, 0x0020, 0x10, 16, 1), + PIN_FIELD_BASE(146, 146, 5, 0x0020, 0x10, 12, 1), + PIN_FIELD_BASE(147, 155, 5, 0x0020, 0x10, 0, 1), + PIN_FIELD_BASE(156, 157, 5, 0x0020, 0x10, 22, 1), + PIN_FIELD_BASE(158, 158, 5, 0x0020, 0x10, 21, 1), + PIN_FIELD_BASE(159, 159, 5, 0x0020, 0x10, 24, 1), + PIN_FIELD_BASE(160, 161, 5, 0x0020, 0x10, 19, 1), + PIN_FIELD_BASE(162, 166, 5, 0x0020, 0x10, 25, 1), + PIN_FIELD_BASE(167, 168, 7, 0x0010, 0x10, 1, 1), + PIN_FIELD_BASE(169, 169, 7, 0x0010, 0x10, 4, 1), + PIN_FIELD_BASE(170, 170, 7, 0x0010, 0x10, 6, 1), + PIN_FIELD_BASE(171, 171, 7, 0x0010, 0x10, 8, 1), + PIN_FIELD_BASE(172, 172, 7, 0x0010, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 7, 0x0010, 0x10, 7, 1), + PIN_FIELD_BASE(174, 175, 7, 0x0010, 0x10, 9, 1), + PIN_FIELD_BASE(176, 176, 7, 0x0010, 0x10, 0, 1), + PIN_FIELD_BASE(177, 177, 7, 0x0010, 0x10, 5, 1), + PIN_FIELD_BASE(178, 178, 7, 0x0010, 0x10, 11, 1), + PIN_FIELD_BASE(179, 179, 4, 0x0020, 0x10, 13, 1), + PIN_FIELD_BASE(180, 180, 4, 0x0020, 0x10, 10, 1), + PIN_FIELD_BASE(181, 183, 1, 0x0030, 0x10, 22, 1), + PIN_FIELD_BASE(184, 184, 1, 0x0030, 0x10, 12, 1), + PIN_FIELD_BASE(185, 185, 1, 0x0030, 0x10, 11, 1), + PIN_FIELD_BASE(186, 186, 1, 0x0030, 0x10, 13, 1), + PIN_FIELD_BASE(187, 187, 1, 0x0030, 0x10, 10, 1), + PIN_FIELD_BASE(188, 188, 1, 0x0030, 0x10, 14, 1), + PIN_FIELD_BASE(189, 189, 5, 0x0020, 0x10, 9, 1), + PIN_FIELD_BASE(190, 190, 5, 0x0020, 0x10, 18, 1), + PIN_FIELD_BASE(191, 192, 5, 0x0020, 0x10, 13, 1), + PIN_FIELD_BASE(193, 194, 5, 0x0020, 0x10, 10, 1), + PIN_FIELD_BASE(195, 195, 2, 0x0050, 0x10, 30, 1), + PIN_FIELD_BASE(196, 196, 2, 0x0050, 0x10, 25, 1), + PIN_FIELD_BASE(197, 197, 2, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(198, 199, 4, 0x0020, 0x10, 14, 1), + PIN_FIELD_BASE(200, 201, 6, 0x0040, 0x10, 6, 1), + PIN_FIELD_BASE(202, 202, 4, 0x0020, 0x10, 9, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_smt_range[] = { + PINS_FIELD_BASE(0, 9, 6, 0x00c0, 0x10, 3, 1), + PIN_FIELD_BASE(10, 11, 3, 0x00e0, 0x10, 0, 1), + PINS_FIELD_BASE(12, 15, 3, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(16, 16, 3, 0x00e0, 0x10, 3, 1), + PINS_FIELD_BASE(17, 20, 6, 0x00c0, 0x10, 11, 1), + PINS_FIELD_BASE(21, 24, 6, 0x00c0, 0x10, 7, 1), + PIN_FIELD_BASE(25, 25, 6, 0x00c0, 0x10, 12, 1), + PIN_FIELD_BASE(26, 26, 6, 0x00c0, 0x10, 8, 1), + PIN_FIELD_BASE(27, 27, 6, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(28, 29, 6, 0x00c0, 0x10, 9, 1), + PINS_FIELD_BASE(30, 32, 6, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(33, 33, 6, 0x00c0, 0x10, 5, 1), + PIN_FIELD_BASE(34, 34, 6, 0x00c0, 0x10, 4, 1), + PINS_FIELD_BASE(35, 41, 6, 0x00c0, 0x10, 13, 1), + PIN_FIELD_BASE(42, 43, 6, 0x00c0, 0x10, 1, 1), + PIN_FIELD_BASE(44, 44, 6, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(45, 45, 3, 0x00e0, 0x10, 8, 1), + PIN_FIELD_BASE(46, 46, 3, 0x00e0, 0x10, 13, 1), + PINS_FIELD_BASE(47, 50, 3, 0x00e0, 0x10, 14, 1), + PIN_FIELD_BASE(51, 51, 3, 0x00e0, 0x10, 5, 1), + PIN_FIELD_BASE(52, 52, 3, 0x00e0, 0x10, 10, 1), + PIN_FIELD_BASE(53, 54, 3, 0x00e0, 0x10, 15, 1), + PIN_FIELD_BASE(55, 55, 3, 0x00e0, 0x10, 7, 1), + PIN_FIELD_BASE(56, 56, 3, 0x00e0, 0x10, 12, 1), + PINS_FIELD_BASE(57, 60, 3, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(61, 61, 3, 0x00e0, 0x10, 6, 1), + PIN_FIELD_BASE(62, 62, 3, 0x00e0, 0x10, 11, 1), + PINS_FIELD_BASE(63, 66, 3, 0x00e0, 0x10, 9, 1), + PINS_FIELD_BASE(67, 69, 2, 0x00e0, 0x10, 11, 1), + PIN_FIELD_BASE(70, 71, 2, 0x00e0, 0x10, 10, 1), + PINS_FIELD_BASE(72, 75, 4, 0x0070, 0x10, 1, 1), + PINS_FIELD_BASE(76, 77, 4, 0x0070, 0x10, 4, 1), + PINS_FIELD_BASE(78, 86, 2, 0x00e0, 0x10, 1, 1), + PINS_FIELD_BASE(87, 92, 2, 0x00e0, 0x10, 2, 1), + PIN_FIELD_BASE(93, 93, 4, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(94, 94, 2, 0x00e0, 0x10, 2, 1), + PINS_FIELD_BASE(95, 98, 4, 0x0070, 0x10, 2, 1), + PINS_FIELD_BASE(99, 104, 2, 0x00e0, 0x10, 12, 1), + PINS_FIELD_BASE(105, 109, 2, 0x00e0, 0x10, 0, 1), + PIN_FIELD_BASE(110, 110, 2, 0x00e0, 0x10, 14, 1), + PIN_FIELD_BASE(111, 111, 2, 0x00e0, 0x10, 16, 1), + PIN_FIELD_BASE(112, 112, 2, 0x00e0, 0x10, 13, 1), + PIN_FIELD_BASE(113, 113, 2, 0x00e0, 0x10, 15, 1), + PINS_FIELD_BASE(114, 115, 2, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(116, 117, 2, 0x00e0, 0x10, 5, 1), + PINS_FIELD_BASE(118, 119, 2, 0x00e0, 0x10, 4, 1), + PIN_FIELD_BASE(120, 121, 2, 0x00e0, 0x10, 7, 1), + PINS_FIELD_BASE(122, 125, 2, 0x00e0, 0x10, 3, 1), + PINS_FIELD_BASE(126, 127, 1, 0x00c0, 0x10, 5, 1), + PINS_FIELD_BASE(128, 130, 1, 0x00c0, 0x10, 9, 1), + PINS_FIELD_BASE(131, 133, 1, 0x00c0, 0x10, 10, 1), + PIN_FIELD_BASE(134, 135, 1, 0x00c0, 0x10, 2, 1), + PINS_FIELD_BASE(136, 139, 1, 0x00c0, 0x10, 4, 1), + PIN_FIELD_BASE(140, 141, 1, 0x00c0, 0x10, 0, 1), + PIN_FIELD_BASE(142, 142, 1, 0x00c0, 0x10, 8, 1), + PINS_FIELD_BASE(143, 146, 5, 0x0060, 0x10, 1, 1), + PINS_FIELD_BASE(147, 155, 5, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(156, 157, 5, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(158, 158, 5, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(159, 159, 5, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(160, 161, 5, 0x0060, 0x10, 3, 1), + PINS_FIELD_BASE(162, 166, 5, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(167, 167, 7, 0x0060, 0x10, 1, 1), + PINS_FIELD_BASE(168, 174, 7, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(175, 175, 7, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(176, 176, 7, 0x0060, 0x10, 0, 1), + PINS_FIELD_BASE(177, 178, 7, 0x0060, 0x10, 2, 1), + PINS_FIELD_BASE(179, 180, 4, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(181, 183, 1, 0x00c0, 0x10, 11, 1), + PINS_FIELD_BASE(184, 187, 1, 0x00c0, 0x10, 6, 1), + PIN_FIELD_BASE(188, 188, 1, 0x00c0, 0x10, 7, 1), + PINS_FIELD_BASE(189, 194, 5, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(195, 195, 2, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(196, 196, 2, 0x00e0, 0x10, 9, 1), + PIN_FIELD_BASE(197, 197, 2, 0x00e0, 0x10, 3, 1), + PIN_FIELD_BASE(198, 199, 4, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(200, 201, 6, 0x00c0, 0x10, 14, 1), + PIN_FIELD_BASE(202, 202, 4, 0x0070, 0x10, 3, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_pu_range[] = { + PIN_FIELD_BASE(0, 9, 6, 0x0070, 0x10, 3, 1), + PIN_FIELD_BASE(16, 16, 3, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(17, 18, 6, 0x0070, 0x10, 28, 1), + PIN_FIELD_BASE(19, 19, 6, 0x0070, 0x10, 27, 1), + PIN_FIELD_BASE(20, 20, 6, 0x0070, 0x10, 26, 1), + PIN_FIELD_BASE(21, 24, 6, 0x0070, 0x10, 19, 1), + PIN_FIELD_BASE(25, 25, 6, 0x0070, 0x10, 30, 1), + PIN_FIELD_BASE(26, 26, 6, 0x0070, 0x10, 23, 1), + PIN_FIELD_BASE(27, 27, 6, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(28, 29, 6, 0x0070, 0x10, 24, 1), + PIN_FIELD_BASE(30, 30, 6, 0x0070, 0x10, 16, 1), + PIN_FIELD_BASE(31, 31, 6, 0x0070, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 6, 0x0070, 0x10, 15, 1), + PIN_FIELD_BASE(33, 33, 6, 0x0070, 0x10, 17, 1), + PIN_FIELD_BASE(34, 34, 6, 0x0070, 0x10, 14, 1), + PIN_FIELD_BASE(35, 35, 6, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(36, 36, 6, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(37, 37, 6, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(38, 41, 6, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(42, 43, 6, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(44, 44, 6, 0x0070, 0x10, 18, 1), + PIN_FIELD_BASE(45, 45, 3, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(46, 46, 3, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(47, 47, 3, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(48, 48, 3, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(49, 49, 3, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(50, 50, 3, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(51, 51, 3, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(52, 52, 3, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(53, 54, 3, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(55, 55, 3, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(56, 56, 3, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(61, 61, 3, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(62, 62, 3, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(63, 63, 3, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(64, 64, 3, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(65, 65, 3, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(66, 66, 3, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(67, 67, 2, 0x00a0, 0x10, 7, 1), + PIN_FIELD_BASE(68, 68, 2, 0x00a0, 0x10, 6, 1), + PIN_FIELD_BASE(69, 69, 2, 0x00a0, 0x10, 8, 1), + PIN_FIELD_BASE(70, 71, 2, 0x00a0, 0x10, 4, 1), + PIN_FIELD_BASE(72, 72, 4, 0x0040, 0x10, 3, 1), + PIN_FIELD_BASE(73, 73, 4, 0x0040, 0x10, 2, 1), + PIN_FIELD_BASE(74, 74, 4, 0x0040, 0x10, 1, 1), + PIN_FIELD_BASE(75, 75, 4, 0x0040, 0x10, 4, 1), + PIN_FIELD_BASE(76, 76, 4, 0x0040, 0x10, 12, 1), + PIN_FIELD_BASE(77, 77, 4, 0x0040, 0x10, 11, 1), + PIN_FIELD_BASE(78, 78, 2, 0x0090, 0x10, 18, 1), + PIN_FIELD_BASE(79, 79, 2, 0x0090, 0x10, 17, 1), + PIN_FIELD_BASE(80, 81, 2, 0x0090, 0x10, 19, 1), + PIN_FIELD_BASE(82, 88, 2, 0x0090, 0x10, 1, 1), + PIN_FIELD_BASE(89, 89, 2, 0x0090, 0x10, 16, 1), + PIN_FIELD_BASE(90, 90, 2, 0x0090, 0x10, 15, 1), + PIN_FIELD_BASE(91, 91, 2, 0x0090, 0x10, 14, 1), + PIN_FIELD_BASE(92, 92, 2, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(93, 93, 4, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(94, 94, 2, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(95, 95, 4, 0x0040, 0x10, 7, 1), + PIN_FIELD_BASE(96, 96, 4, 0x0040, 0x10, 5, 1), + PIN_FIELD_BASE(97, 97, 4, 0x0040, 0x10, 8, 1), + PIN_FIELD_BASE(98, 98, 4, 0x0040, 0x10, 6, 1), + PIN_FIELD_BASE(99, 99, 2, 0x00a0, 0x10, 9, 1), + PIN_FIELD_BASE(100, 100, 2, 0x00a0, 0x10, 12, 1), + PIN_FIELD_BASE(101, 101, 2, 0x00a0, 0x10, 10, 1), + PIN_FIELD_BASE(102, 102, 2, 0x00a0, 0x10, 13, 1), + PIN_FIELD_BASE(103, 103, 2, 0x00a0, 0x10, 11, 1), + PIN_FIELD_BASE(104, 104, 2, 0x00a0, 0x10, 14, 1), + PIN_FIELD_BASE(105, 105, 2, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(106, 106, 2, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(107, 108, 2, 0x0090, 0x10, 12, 1), + PIN_FIELD_BASE(109, 109, 2, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(110, 110, 2, 0x00a0, 0x10, 16, 1), + PIN_FIELD_BASE(111, 111, 2, 0x00a0, 0x10, 18, 1), + PIN_FIELD_BASE(112, 112, 2, 0x00a0, 0x10, 15, 1), + PIN_FIELD_BASE(113, 113, 2, 0x00a0, 0x10, 17, 1), + PIN_FIELD_BASE(114, 115, 2, 0x0090, 0x10, 26, 1), + PIN_FIELD_BASE(116, 117, 2, 0x0090, 0x10, 21, 1), + PIN_FIELD_BASE(118, 118, 2, 0x0090, 0x10, 31, 1), + PIN_FIELD_BASE(119, 119, 2, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(120, 121, 2, 0x0090, 0x10, 23, 1), + PIN_FIELD_BASE(122, 123, 2, 0x0090, 0x10, 28, 1), + PIN_FIELD_BASE(124, 125, 2, 0x00a0, 0x10, 1, 1), + PIN_FIELD_BASE(126, 127, 1, 0x0070, 0x10, 2, 1), + PIN_FIELD_BASE(140, 141, 1, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(143, 143, 5, 0x0040, 0x10, 15, 1), + PIN_FIELD_BASE(144, 144, 5, 0x0040, 0x10, 17, 1), + PIN_FIELD_BASE(145, 145, 5, 0x0040, 0x10, 16, 1), + PIN_FIELD_BASE(146, 146, 5, 0x0040, 0x10, 12, 1), + PIN_FIELD_BASE(147, 155, 5, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(156, 157, 5, 0x0040, 0x10, 22, 1), + PIN_FIELD_BASE(158, 158, 5, 0x0040, 0x10, 21, 1), + PIN_FIELD_BASE(159, 159, 5, 0x0040, 0x10, 24, 1), + PIN_FIELD_BASE(160, 161, 5, 0x0040, 0x10, 19, 1), + PIN_FIELD_BASE(162, 166, 5, 0x0040, 0x10, 25, 1), + PIN_FIELD_BASE(179, 179, 4, 0x0040, 0x10, 13, 1), + PIN_FIELD_BASE(180, 180, 4, 0x0040, 0x10, 10, 1), + PIN_FIELD_BASE(181, 183, 1, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(184, 184, 1, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(185, 185, 1, 0x0070, 0x10, 5, 1), + PIN_FIELD_BASE(186, 186, 1, 0x0070, 0x10, 7, 1), + PIN_FIELD_BASE(187, 187, 1, 0x0070, 0x10, 4, 1), + PIN_FIELD_BASE(188, 188, 1, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(189, 189, 5, 0x0040, 0x10, 9, 1), + PIN_FIELD_BASE(190, 190, 5, 0x0040, 0x10, 18, 1), + PIN_FIELD_BASE(191, 192, 5, 0x0040, 0x10, 13, 1), + PIN_FIELD_BASE(193, 194, 5, 0x0040, 0x10, 10, 1), + PIN_FIELD_BASE(195, 195, 2, 0x0090, 0x10, 30, 1), + PIN_FIELD_BASE(196, 196, 2, 0x0090, 0x10, 25, 1), + PIN_FIELD_BASE(197, 197, 2, 0x00a0, 0x10, 3, 1), + PIN_FIELD_BASE(198, 199, 4, 0x0040, 0x10, 14, 1), + PIN_FIELD_BASE(200, 201, 6, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(202, 202, 4, 0x0040, 0x10, 9, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_pd_range[] = { + PIN_FIELD_BASE(0, 9, 6, 0x0050, 0x10, 3, 1), + PIN_FIELD_BASE(16, 16, 3, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(17, 18, 6, 0x0050, 0x10, 28, 1), + PIN_FIELD_BASE(19, 19, 6, 0x0050, 0x10, 27, 1), + PIN_FIELD_BASE(20, 20, 6, 0x0050, 0x10, 26, 1), + PIN_FIELD_BASE(21, 24, 6, 0x0050, 0x10, 19, 1), + PIN_FIELD_BASE(25, 25, 6, 0x0050, 0x10, 30, 1), + PIN_FIELD_BASE(26, 26, 6, 0x0050, 0x10, 23, 1), + PIN_FIELD_BASE(27, 27, 6, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(28, 29, 6, 0x0050, 0x10, 24, 1), + PIN_FIELD_BASE(30, 30, 6, 0x0050, 0x10, 16, 1), + PIN_FIELD_BASE(31, 31, 6, 0x0050, 0x10, 13, 1), + PIN_FIELD_BASE(32, 32, 6, 0x0050, 0x10, 15, 1), + PIN_FIELD_BASE(33, 33, 6, 0x0050, 0x10, 17, 1), + PIN_FIELD_BASE(34, 34, 6, 0x0050, 0x10, 14, 1), + PIN_FIELD_BASE(35, 35, 6, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(36, 36, 6, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(37, 37, 6, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(38, 41, 6, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(42, 43, 6, 0x0050, 0x10, 1, 1), + PIN_FIELD_BASE(44, 44, 6, 0x0050, 0x10, 18, 1), + PIN_FIELD_BASE(45, 45, 3, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(46, 46, 3, 0x0060, 0x10, 12, 1), + PIN_FIELD_BASE(47, 47, 3, 0x0060, 0x10, 15, 1), + PIN_FIELD_BASE(48, 48, 3, 0x0060, 0x10, 14, 1), + PIN_FIELD_BASE(49, 49, 3, 0x0060, 0x10, 16, 1), + PIN_FIELD_BASE(50, 50, 3, 0x0060, 0x10, 13, 1), + PIN_FIELD_BASE(51, 51, 3, 0x0060, 0x10, 1, 1), + PIN_FIELD_BASE(52, 52, 3, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(53, 54, 3, 0x0060, 0x10, 18, 1), + PIN_FIELD_BASE(55, 55, 3, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(56, 56, 3, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(61, 61, 3, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(62, 62, 3, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(63, 63, 3, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(64, 64, 3, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(65, 65, 3, 0x0060, 0x10, 8, 1), + PIN_FIELD_BASE(66, 66, 3, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(67, 67, 2, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(68, 68, 2, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(69, 69, 2, 0x0080, 0x10, 8, 1), + PIN_FIELD_BASE(70, 71, 2, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(72, 72, 4, 0x0030, 0x10, 3, 1), + PIN_FIELD_BASE(73, 73, 4, 0x0030, 0x10, 2, 1), + PIN_FIELD_BASE(74, 74, 4, 0x0030, 0x10, 1, 1), + PIN_FIELD_BASE(75, 75, 4, 0x0030, 0x10, 4, 1), + PIN_FIELD_BASE(76, 76, 4, 0x0030, 0x10, 12, 1), + PIN_FIELD_BASE(77, 77, 4, 0x0030, 0x10, 11, 1), + PIN_FIELD_BASE(78, 78, 2, 0x0070, 0x10, 18, 1), + PIN_FIELD_BASE(79, 79, 2, 0x0070, 0x10, 17, 1), + PIN_FIELD_BASE(80, 81, 2, 0x0070, 0x10, 19, 1), + PIN_FIELD_BASE(82, 88, 2, 0x0070, 0x10, 1, 1), + PIN_FIELD_BASE(89, 89, 2, 0x0070, 0x10, 16, 1), + PIN_FIELD_BASE(90, 90, 2, 0x0070, 0x10, 15, 1), + PIN_FIELD_BASE(91, 91, 2, 0x0070, 0x10, 14, 1), + PIN_FIELD_BASE(92, 92, 2, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(93, 93, 4, 0x0030, 0x10, 0, 1), + PIN_FIELD_BASE(94, 94, 2, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(95, 95, 4, 0x0030, 0x10, 7, 1), + PIN_FIELD_BASE(96, 96, 4, 0x0030, 0x10, 5, 1), + PIN_FIELD_BASE(97, 97, 4, 0x0030, 0x10, 8, 1), + PIN_FIELD_BASE(98, 98, 4, 0x0030, 0x10, 6, 1), + PIN_FIELD_BASE(99, 99, 2, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(100, 100, 2, 0x0080, 0x10, 12, 1), + PIN_FIELD_BASE(101, 101, 2, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(102, 102, 2, 0x0080, 0x10, 13, 1), + PIN_FIELD_BASE(103, 103, 2, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(104, 104, 2, 0x0080, 0x10, 14, 1), + PIN_FIELD_BASE(105, 105, 2, 0x0070, 0x10, 10, 1), + PIN_FIELD_BASE(106, 106, 2, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(107, 108, 2, 0x0070, 0x10, 12, 1), + PIN_FIELD_BASE(109, 109, 2, 0x0070, 0x10, 11, 1), + PIN_FIELD_BASE(110, 110, 2, 0x0080, 0x10, 16, 1), + PIN_FIELD_BASE(111, 111, 2, 0x0080, 0x10, 18, 1), + PIN_FIELD_BASE(112, 112, 2, 0x0080, 0x10, 15, 1), + PIN_FIELD_BASE(113, 113, 2, 0x0080, 0x10, 17, 1), + PIN_FIELD_BASE(114, 115, 2, 0x0070, 0x10, 26, 1), + PIN_FIELD_BASE(116, 117, 2, 0x0070, 0x10, 21, 1), + PIN_FIELD_BASE(118, 118, 2, 0x0070, 0x10, 31, 1), + PIN_FIELD_BASE(119, 119, 2, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(120, 121, 2, 0x0070, 0x10, 23, 1), + PIN_FIELD_BASE(122, 123, 2, 0x0070, 0x10, 28, 1), + PIN_FIELD_BASE(124, 125, 2, 0x0080, 0x10, 1, 1), + PIN_FIELD_BASE(126, 127, 1, 0x0050, 0x10, 2, 1), + PIN_FIELD_BASE(140, 141, 1, 0x0050, 0x10, 0, 1), + PIN_FIELD_BASE(142, 142, 1, 0x0050, 0x10, 9, 1), + PIN_FIELD_BASE(143, 143, 5, 0x0030, 0x10, 15, 1), + PIN_FIELD_BASE(144, 144, 5, 0x0030, 0x10, 17, 1), + PIN_FIELD_BASE(145, 145, 5, 0x0030, 0x10, 16, 1), + PIN_FIELD_BASE(146, 146, 5, 0x0030, 0x10, 12, 1), + PIN_FIELD_BASE(147, 155, 5, 0x0030, 0x10, 0, 1), + PIN_FIELD_BASE(156, 157, 5, 0x0030, 0x10, 22, 1), + PIN_FIELD_BASE(158, 158, 5, 0x0030, 0x10, 21, 1), + PIN_FIELD_BASE(159, 159, 5, 0x0030, 0x10, 24, 1), + PIN_FIELD_BASE(160, 161, 5, 0x0030, 0x10, 19, 1), + PIN_FIELD_BASE(162, 166, 5, 0x0030, 0x10, 25, 1), + PIN_FIELD_BASE(179, 179, 4, 0x0030, 0x10, 13, 1), + PIN_FIELD_BASE(180, 180, 4, 0x0030, 0x10, 10, 1), + PIN_FIELD_BASE(181, 183, 1, 0x0050, 0x10, 10, 1), + PIN_FIELD_BASE(184, 184, 1, 0x0050, 0x10, 6, 1), + PIN_FIELD_BASE(185, 185, 1, 0x0050, 0x10, 5, 1), + PIN_FIELD_BASE(186, 186, 1, 0x0050, 0x10, 7, 1), + PIN_FIELD_BASE(187, 187, 1, 0x0050, 0x10, 4, 1), + PIN_FIELD_BASE(188, 188, 1, 0x0050, 0x10, 8, 1), + PIN_FIELD_BASE(189, 189, 5, 0x0030, 0x10, 9, 1), + PIN_FIELD_BASE(190, 190, 5, 0x0030, 0x10, 18, 1), + PIN_FIELD_BASE(191, 192, 5, 0x0030, 0x10, 13, 1), + PIN_FIELD_BASE(193, 194, 5, 0x0030, 0x10, 10, 1), + PIN_FIELD_BASE(195, 195, 2, 0x0070, 0x10, 30, 1), + PIN_FIELD_BASE(196, 196, 2, 0x0070, 0x10, 25, 1), + PIN_FIELD_BASE(197, 197, 2, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(198, 199, 4, 0x0030, 0x10, 14, 1), + PIN_FIELD_BASE(200, 201, 6, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(202, 202, 4, 0x0030, 0x10, 9, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_drv_range[] = { + PINS_FIELD_BASE(0, 9, 6, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(10, 16, 3, 0x0000, 0x10, 0, 3), + PINS_FIELD_BASE(17, 19, 6, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(20, 20, 6, 0x0010, 0x10, 6, 3), + PINS_FIELD_BASE(21, 24, 6, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(25, 25, 6, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(26, 26, 6, 0x0000, 0x10, 24, 3), + PIN_FIELD_BASE(27, 27, 6, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(28, 28, 6, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(29, 29, 6, 0x0010, 0x10, 0, 3), + PINS_FIELD_BASE(30, 32, 6, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(33, 33, 6, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(34, 34, 6, 0x0000, 0x10, 12, 3), + PINS_FIELD_BASE(35, 41, 6, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(42, 43, 6, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(44, 44, 6, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(45, 45, 3, 0x0010, 0x10, 12, 3), + PIN_FIELD_BASE(46, 46, 3, 0x0020, 0x10, 0, 3), + PINS_FIELD_BASE(47, 49, 3, 0x0020, 0x10, 3, 3), + PIN_FIELD_BASE(50, 50, 3, 0x0020, 0x10, 6, 3), + PIN_FIELD_BASE(51, 51, 3, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(52, 52, 3, 0x0010, 0x10, 21, 3), + PINS_FIELD_BASE(53, 54, 3, 0x0020, 0x10, 9, 3), + PIN_FIELD_BASE(55, 55, 3, 0x0010, 0x10, 9, 3), + PIN_FIELD_BASE(56, 56, 3, 0x0010, 0x10, 27, 3), + PIN_FIELD_BASE(57, 57, 3, 0x0010, 0x10, 0, 3), + PIN_FIELD_BASE(58, 58, 3, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(59, 60, 3, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(61, 61, 3, 0x0010, 0x10, 6, 3), + PIN_FIELD_BASE(62, 62, 3, 0x0010, 0x10, 24, 3), + PINS_FIELD_BASE(63, 65, 3, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(66, 66, 3, 0x0010, 0x10, 18, 3), + PINS_FIELD_BASE(67, 69, 2, 0x0010, 0x10, 3, 3), + PIN_FIELD_BASE(70, 71, 2, 0x0010, 0x10, 0, 3), + PINS_FIELD_BASE(72, 75, 4, 0x0000, 0x10, 0, 3), + PINS_FIELD_BASE(76, 77, 4, 0x0000, 0x10, 15, 3), + PINS_FIELD_BASE(78, 86, 2, 0x0000, 0x10, 3, 3), + PINS_FIELD_BASE(87, 92, 2, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(93, 93, 4, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(94, 94, 2, 0x0000, 0x10, 6, 3), + PINS_FIELD_BASE(95, 96, 4, 0x0000, 0x10, 6, 3), + PINS_FIELD_BASE(97, 98, 4, 0x0000, 0x10, 9, 3), + PINS_FIELD_BASE(99, 100, 2, 0x0010, 0x10, 6, 3), + PINS_FIELD_BASE(101, 102, 2, 0x0010, 0x10, 9, 3), + PINS_FIELD_BASE(103, 104, 2, 0x0010, 0x10, 12, 3), + PINS_FIELD_BASE(105, 109, 2, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(110, 110, 2, 0x0010, 0x10, 18, 3), + PIN_FIELD_BASE(111, 111, 2, 0x0010, 0x10, 24, 3), + PIN_FIELD_BASE(112, 112, 2, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(113, 113, 2, 0x0010, 0x10, 21, 3), + PINS_FIELD_BASE(114, 115, 2, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(116, 117, 2, 0x0000, 0x10, 15, 3), + PINS_FIELD_BASE(118, 119, 2, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(120, 121, 2, 0x0000, 0x10, 21, 3), + PINS_FIELD_BASE(122, 125, 2, 0x0000, 0x10, 9, 3), + PINS_FIELD_BASE(126, 127, 1, 0x0000, 0x10, 12, 3), + PIN_FIELD_BASE(128, 128, 1, 0x0000, 0x10, 29, 2), + PIN_FIELD_BASE(129, 129, 1, 0x0010, 0x10, 0, 2), + PIN_FIELD_BASE(130, 130, 1, 0x0000, 0x10, 27, 2), + PIN_FIELD_BASE(131, 131, 1, 0x0010, 0x10, 2, 2), + PIN_FIELD_BASE(132, 132, 1, 0x0010, 0x10, 6, 2), + PIN_FIELD_BASE(133, 133, 1, 0x0010, 0x10, 4, 2), + PIN_FIELD_BASE(134, 135, 1, 0x0000, 0x10, 3, 3), + PINS_FIELD_BASE(136, 139, 1, 0x0000, 0x10, 9, 3), + PINS_FIELD_BASE(140, 141, 1, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(142, 142, 1, 0x0000, 0x10, 24, 3), + PINS_FIELD_BASE(143, 146, 5, 0x0000, 0x10, 3, 3), + PINS_FIELD_BASE(147, 155, 5, 0x0000, 0x10, 0, 3), + PIN_FIELD_BASE(156, 157, 5, 0x0000, 0x10, 21, 3), + PIN_FIELD_BASE(158, 158, 5, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(159, 159, 5, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(160, 161, 5, 0x0000, 0x10, 9, 3), + PINS_FIELD_BASE(162, 166, 5, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(167, 167, 7, 0x0000, 0x10, 3, 3), + PINS_FIELD_BASE(168, 174, 7, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(175, 175, 7, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(176, 176, 7, 0x0000, 0x10, 0, 3), + PINS_FIELD_BASE(177, 178, 7, 0x0000, 0x10, 6, 3), + PIN_FIELD_BASE(179, 180, 4, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(181, 183, 1, 0x0010, 0x10, 8, 3), + PINS_FIELD_BASE(184, 186, 1, 0x0000, 0x10, 15, 3), + PIN_FIELD_BASE(187, 188, 1, 0x0000, 0x10, 18, 3), + PIN_FIELD_BASE(189, 189, 5, 0x0000, 0x10, 6, 3), + PINS_FIELD_BASE(190, 194, 5, 0x0000, 0x10, 3, 3), + PIN_FIELD_BASE(195, 195, 2, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(196, 196, 2, 0x0000, 0x10, 27, 3), + PIN_FIELD_BASE(197, 197, 2, 0x0000, 0x10, 9, 3), + PIN_FIELD_BASE(198, 199, 4, 0x0000, 0x10, 21, 3), + PINS_FIELD_BASE(200, 201, 6, 0x0010, 0x10, 15, 3), + PIN_FIELD_BASE(202, 202, 4, 0x0000, 0x10, 12, 3), +}; + +static const struct mtk_pin_field_calc mt6779_pin_pupd_range[] = { + PIN_FIELD_BASE(10, 15, 3, 0x0070, 0x10, 0, 1), + PIN_FIELD_BASE(57, 57, 3, 0x0070, 0x10, 9, 1), + PIN_FIELD_BASE(58, 58, 3, 0x0070, 0x10, 8, 1), + PIN_FIELD_BASE(59, 60, 3, 0x0070, 0x10, 6, 1), + PIN_FIELD_BASE(128, 129, 1, 0x0060, 0x10, 7, 1), + PIN_FIELD_BASE(130, 130, 1, 0x0060, 0x10, 6, 1), + PIN_FIELD_BASE(131, 131, 1, 0x0060, 0x10, 9, 1), + PIN_FIELD_BASE(132, 132, 1, 0x0060, 0x10, 11, 1), + PIN_FIELD_BASE(133, 133, 1, 0x0060, 0x10, 10, 1), + PIN_FIELD_BASE(134, 135, 1, 0x0060, 0x10, 0, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0060, 0x10, 5, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0060, 0x10, 2, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0060, 0x10, 4, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0060, 0x10, 3, 1), + PIN_FIELD_BASE(167, 168, 7, 0x0020, 0x10, 1, 1), + PIN_FIELD_BASE(169, 169, 7, 0x0020, 0x10, 4, 1), + PIN_FIELD_BASE(170, 170, 7, 0x0020, 0x10, 6, 1), + PIN_FIELD_BASE(171, 171, 7, 0x0020, 0x10, 8, 1), + PIN_FIELD_BASE(172, 172, 7, 0x0020, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 7, 0x0020, 0x10, 7, 1), + PIN_FIELD_BASE(174, 175, 7, 0x0020, 0x10, 9, 1), + PIN_FIELD_BASE(176, 176, 7, 0x0020, 0x10, 0, 1), + PIN_FIELD_BASE(177, 177, 7, 0x0020, 0x10, 5, 1), + PIN_FIELD_BASE(178, 178, 7, 0x0020, 0x10, 11, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_r0_range[] = { + PIN_FIELD_BASE(10, 15, 3, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(57, 57, 3, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(58, 58, 3, 0x0090, 0x10, 8, 1), + PIN_FIELD_BASE(59, 60, 3, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(128, 129, 1, 0x0080, 0x10, 7, 1), + PIN_FIELD_BASE(130, 130, 1, 0x0080, 0x10, 6, 1), + PIN_FIELD_BASE(131, 131, 1, 0x0080, 0x10, 9, 1), + PIN_FIELD_BASE(132, 132, 1, 0x0080, 0x10, 11, 1), + PIN_FIELD_BASE(133, 133, 1, 0x0080, 0x10, 10, 1), + PIN_FIELD_BASE(134, 135, 1, 0x0080, 0x10, 0, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0080, 0x10, 5, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0080, 0x10, 2, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0080, 0x10, 4, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0080, 0x10, 3, 1), + PIN_FIELD_BASE(167, 168, 7, 0x0030, 0x10, 1, 1), + PIN_FIELD_BASE(169, 169, 7, 0x0030, 0x10, 4, 1), + PIN_FIELD_BASE(170, 170, 7, 0x0030, 0x10, 6, 1), + PIN_FIELD_BASE(171, 171, 7, 0x0030, 0x10, 8, 1), + PIN_FIELD_BASE(172, 172, 7, 0x0030, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 7, 0x0030, 0x10, 7, 1), + PIN_FIELD_BASE(174, 175, 7, 0x0030, 0x10, 9, 1), + PIN_FIELD_BASE(176, 176, 7, 0x0030, 0x10, 0, 1), + PIN_FIELD_BASE(177, 177, 7, 0x0030, 0x10, 5, 1), + PIN_FIELD_BASE(178, 178, 7, 0x0030, 0x10, 11, 1), +}; + +static const struct mtk_pin_field_calc mt6779_pin_r1_range[] = { + PIN_FIELD_BASE(10, 15, 3, 0x00a0, 0x10, 0, 1), + PIN_FIELD_BASE(57, 57, 3, 0x00a0, 0x10, 9, 1), + PIN_FIELD_BASE(58, 58, 3, 0x00a0, 0x10, 8, 1), + PIN_FIELD_BASE(59, 60, 3, 0x00a0, 0x10, 6, 1), + PIN_FIELD_BASE(128, 129, 1, 0x0090, 0x10, 7, 1), + PIN_FIELD_BASE(130, 130, 1, 0x0090, 0x10, 6, 1), + PIN_FIELD_BASE(131, 131, 1, 0x0090, 0x10, 9, 1), + PIN_FIELD_BASE(132, 132, 1, 0x0090, 0x10, 11, 1), + PIN_FIELD_BASE(133, 133, 1, 0x0090, 0x10, 10, 1), + PIN_FIELD_BASE(134, 135, 1, 0x0090, 0x10, 0, 1), + PIN_FIELD_BASE(136, 136, 1, 0x0090, 0x10, 5, 1), + PIN_FIELD_BASE(137, 137, 1, 0x0090, 0x10, 2, 1), + PIN_FIELD_BASE(138, 138, 1, 0x0090, 0x10, 4, 1), + PIN_FIELD_BASE(139, 139, 1, 0x0090, 0x10, 3, 1), + PIN_FIELD_BASE(167, 168, 7, 0x0040, 0x10, 1, 1), + PIN_FIELD_BASE(169, 169, 7, 0x0040, 0x10, 4, 1), + PIN_FIELD_BASE(170, 170, 7, 0x0040, 0x10, 6, 1), + PIN_FIELD_BASE(171, 171, 7, 0x0040, 0x10, 8, 1), + PIN_FIELD_BASE(172, 172, 7, 0x0040, 0x10, 3, 1), + PIN_FIELD_BASE(173, 173, 7, 0x0040, 0x10, 7, 1), + PIN_FIELD_BASE(174, 175, 7, 0x0040, 0x10, 9, 1), + PIN_FIELD_BASE(176, 176, 7, 0x0040, 0x10, 0, 1), + PIN_FIELD_BASE(177, 177, 7, 0x0040, 0x10, 5, 1), + PIN_FIELD_BASE(178, 178, 7, 0x0040, 0x10, 11, 1), +}; + +static const struct mtk_pin_reg_calc mt6779_reg_cals[PINCTRL_PIN_REG_MAX] = { + [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt6779_pin_mode_range), + [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt6779_pin_dir_range), + [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt6779_pin_di_range), + [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt6779_pin_do_range), + [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt6779_pin_smt_range), + [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt6779_pin_ies_range), + [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt6779_pin_pu_range), + [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt6779_pin_pd_range), + [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt6779_pin_drv_range), + [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt6779_pin_pupd_range), + [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt6779_pin_r0_range), + [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt6779_pin_r1_range), +}; + +static const char * const mt6779_pinctrl_register_base_names[] = { + "gpio", "iocfg_rm", "iocfg_br", "iocfg_lm", "iocfg_lb", + "iocfg_rt", "iocfg_lt", "iocfg_tl", +}; + +static const struct mtk_pin_soc mt6779_data = { + .reg_cal = mt6779_reg_cals, + .pins = mtk_pins_mt6779, + .npins = ARRAY_SIZE(mtk_pins_mt6779), + .ngrps = ARRAY_SIZE(mtk_pins_mt6779), + .gpio_m = 0, + .ies_present = true, + .base_names = mt6779_pinctrl_register_base_names, + .nbase_names = ARRAY_SIZE(mt6779_pinctrl_register_base_names), + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, + .drive_set = mtk_pinconf_drive_set_raw, + .drive_get = mtk_pinconf_drive_get_raw, + .adv_pull_get = mtk_pinconf_adv_pull_get, + .adv_pull_set = mtk_pinconf_adv_pull_set, +}; + +static const struct of_device_id mt6779_pinctrl_of_match[] = { + { .compatible = "mediatek,mt6779-pinctrl", }, + { } +}; + +static int mt6779_pinctrl_probe(struct platform_device *pdev) +{ + return mtk_paris_pinctrl_probe(pdev, &mt6779_data); +} + +static struct platform_driver mt6779_pinctrl_driver = { + .driver = { + .name = "mt6779-pinctrl", + .of_match_table = mt6779_pinctrl_of_match, + }, + .probe = mt6779_pinctrl_probe, +}; + +static int __init mt6779_pinctrl_init(void) +{ + return platform_driver_register(&mt6779_pinctrl_driver); +} +arch_initcall(mt6779_pinctrl_init); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MediaTek MT6779 Pinctrl Driver"); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt6779.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6779.h new file mode 100644 index 000000000000..0a48d6686ebb --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6779.h @@ -0,0 +1,2085 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 MediaTek Inc. + * Author: Andy Teng + * + */ + +#ifndef __PINCTRL_MTK_MT6779_H +#define __PINCTRL_MTK_MT6779_H + +#include "pinctrl-paris.h" + +static const struct mtk_pin_desc mtk_pins_mt6779[] = { + MTK_PIN( + 0, "GPIO0", + MTK_EINT_FUNCTION(0, 0), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO0"), + MTK_FUNCTION(1, "SPI6_MI"), + MTK_FUNCTION(2, "I2S5_LRCK"), + MTK_FUNCTION(3, "TDM_LRCK_2ND"), + MTK_FUNCTION(4, "PCM1_SYNC"), + MTK_FUNCTION(5, "SCL_6306"), + MTK_FUNCTION(6, "TP_GPIO0_AO"), + MTK_FUNCTION(7, "PTA_RXD") + ), + MTK_PIN( + 1, "GPIO1", + MTK_EINT_FUNCTION(0, 1), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO1"), + MTK_FUNCTION(1, "SPI6_CSB"), + MTK_FUNCTION(2, "I2S5_DO"), + MTK_FUNCTION(3, "TDM_DATA0_2ND"), + MTK_FUNCTION(4, "PCM1_DO0"), + MTK_FUNCTION(5, "SDA_6306"), + MTK_FUNCTION(6, "TP_GPIO1_AO"), + MTK_FUNCTION(7, "PTA_TXD") + ), + MTK_PIN( + 2, "GPIO2", + MTK_EINT_FUNCTION(0, 2), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO2"), + MTK_FUNCTION(1, "SPI6_MO"), + MTK_FUNCTION(2, "I2S5_BCK"), + MTK_FUNCTION(3, "TDM_BCK_2ND"), + MTK_FUNCTION(4, "PCM1_CLK"), + MTK_FUNCTION(5, "MD_INT1_C2K_UIM0_HOT_PLUG"), + MTK_FUNCTION(6, "TP_GPIO2_AO") + ), + MTK_PIN( + 3, "GPIO3", + MTK_EINT_FUNCTION(0, 3), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO3"), + MTK_FUNCTION(1, "SPI6_CLK"), + MTK_FUNCTION(2, "I2S5_MCK"), + MTK_FUNCTION(3, "TDM_MCK_2ND"), + MTK_FUNCTION(4, "EXT_FRAME_SYNC"), + MTK_FUNCTION(5, "MD_INT2_C2K_UIM1_HOT_PLUG"), + MTK_FUNCTION(6, "TP_GPIO3_AO") + ), + MTK_PIN( + 4, "GPIO4", + MTK_EINT_FUNCTION(0, 4), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO4"), + MTK_FUNCTION(1, "SPI7_MI"), + MTK_FUNCTION(2, "I2S0_MCK"), + MTK_FUNCTION(3, "TDM_DATA1_2ND"), + MTK_FUNCTION(4, "PCM1_DO1"), + MTK_FUNCTION(5, "DMIC1_CLK"), + MTK_FUNCTION(6, "TP_GPIO4_AO"), + MTK_FUNCTION(7, "SCL8") + ), + MTK_PIN( + 5, "GPIO5", + MTK_EINT_FUNCTION(0, 5), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO5"), + MTK_FUNCTION(1, "SPI7_CSB"), + MTK_FUNCTION(2, "I2S0_BCK"), + MTK_FUNCTION(3, "TDM_DATA2_2ND"), + MTK_FUNCTION(4, "PCM1_DO2"), + MTK_FUNCTION(5, "DMIC1_DAT"), + MTK_FUNCTION(6, "TP_GPIO5_AO"), + MTK_FUNCTION(7, "SDA8") + ), + MTK_PIN( + 6, "GPIO6", + MTK_EINT_FUNCTION(0, 6), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO6"), + MTK_FUNCTION(1, "SPI7_MO"), + MTK_FUNCTION(2, "I2S0_LRCK"), + MTK_FUNCTION(3, "TDM_DATA3_2ND"), + MTK_FUNCTION(4, "PCM1_DI"), + MTK_FUNCTION(5, "DMIC_CLK"), + MTK_FUNCTION(6, "TP_GPIO6_AO"), + MTK_FUNCTION(7, "SCL9") + ), + MTK_PIN( + 7, "GPIO7", + MTK_EINT_FUNCTION(0, 7), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO7"), + MTK_FUNCTION(1, "SPI7_CLK"), + MTK_FUNCTION(2, "I2S0_DI"), + MTK_FUNCTION(3, "SRCLKENAI1"), + MTK_FUNCTION(4, "DVFSRC_EXT_REQ"), + MTK_FUNCTION(5, "DMIC_DAT"), + MTK_FUNCTION(6, "TP_GPIO7_AO"), + MTK_FUNCTION(7, "SDA9") + ), + MTK_PIN( + 8, "GPIO8", + MTK_EINT_FUNCTION(0, 8), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO8"), + MTK_FUNCTION(1, "PWM_0"), + MTK_FUNCTION(2, "I2S2_DI2"), + MTK_FUNCTION(3, "SRCLKENAI0"), + MTK_FUNCTION(4, "URXD1"), + MTK_FUNCTION(5, "I2S0_MCK"), + MTK_FUNCTION(6, "CONN_MCU_DBGACK_N"), + MTK_FUNCTION(7, "IDDIG") + ), + MTK_PIN( + 9, "GPIO9", + MTK_EINT_FUNCTION(0, 9), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO9"), + MTK_FUNCTION(1, "PWM_3"), + MTK_FUNCTION(2, "MD_INT0"), + MTK_FUNCTION(3, "SRCLKENAI1"), + MTK_FUNCTION(4, "UTXD1"), + MTK_FUNCTION(5, "I2S0_BCK"), + MTK_FUNCTION(6, "CONN_MCU_TRST_B"), + MTK_FUNCTION(7, "USB_DRVVBUS") + ), + MTK_PIN( + 10, "GPIO10", + MTK_EINT_FUNCTION(0, 10), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO10"), + MTK_FUNCTION(1, "MSDC1_CLK_A"), + MTK_FUNCTION(2, "TP_URXD1_AO"), + MTK_FUNCTION(3, "I2S1_LRCK"), + MTK_FUNCTION(4, "UCTS0"), + MTK_FUNCTION(5, "DMIC1_CLK"), + MTK_FUNCTION(6, "KPCOL2"), + MTK_FUNCTION(7, "SCL8") + ), + MTK_PIN( + 11, "GPIO11", + MTK_EINT_FUNCTION(0, 11), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO11"), + MTK_FUNCTION(1, "MSDC1_CMD_A"), + MTK_FUNCTION(2, "TP_UTXD1_AO"), + MTK_FUNCTION(3, "I2S1_DO"), + MTK_FUNCTION(4, "URTS0"), + MTK_FUNCTION(5, "DMIC1_DAT"), + MTK_FUNCTION(6, "KPROW2"), + MTK_FUNCTION(7, "SDA8") + ), + MTK_PIN( + 12, "GPIO12", + MTK_EINT_FUNCTION(0, 12), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO12"), + MTK_FUNCTION(1, "MSDC1_DAT3_A"), + MTK_FUNCTION(2, "TP_URXD2_AO"), + MTK_FUNCTION(3, "I2S1_MCK"), + MTK_FUNCTION(4, "UCTS1"), + MTK_FUNCTION(5, "DMIC_CLK"), + MTK_FUNCTION(6, "ANT_SEL9"), + MTK_FUNCTION(7, "SCL9") + ), + MTK_PIN( + 13, "GPIO13", + MTK_EINT_FUNCTION(0, 13), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO13"), + MTK_FUNCTION(1, "MSDC1_DAT0_A"), + MTK_FUNCTION(2, "TP_UTXD2_AO"), + MTK_FUNCTION(3, "I2S1_BCK"), + MTK_FUNCTION(4, "URTS1"), + MTK_FUNCTION(5, "DMIC_DAT"), + MTK_FUNCTION(6, "ANT_SEL10"), + MTK_FUNCTION(7, "SDA9") + ), + MTK_PIN( + 14, "GPIO14", + MTK_EINT_FUNCTION(0, 14), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO14"), + MTK_FUNCTION(1, "MSDC1_DAT2_A"), + MTK_FUNCTION(2, "PWM_3"), + MTK_FUNCTION(3, "IDDIG"), + MTK_FUNCTION(4, "MD_INT0"), + MTK_FUNCTION(5, "PTA_RXD"), + MTK_FUNCTION(6, "ANT_SEL11") + ), + MTK_PIN( + 15, "GPIO15", + MTK_EINT_FUNCTION(0, 15), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO15"), + MTK_FUNCTION(1, "MSDC1_DAT1_A"), + MTK_FUNCTION(2, "DVFSRC_EXT_REQ"), + MTK_FUNCTION(3, "USB_DRVVBUS"), + MTK_FUNCTION(4, "MD_INT1_C2K_UIM0_HOT_PLUG"), + MTK_FUNCTION(5, "PTA_TXD"), + MTK_FUNCTION(6, "ANT_SEL12") + ), + MTK_PIN( + 16, "GPIO16", + MTK_EINT_FUNCTION(0, 16), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO16"), + MTK_FUNCTION(1, "SRCLKENAI0"), + MTK_FUNCTION(2, "EXT_FRAME_SYNC"), + MTK_FUNCTION(3, "MFG_EJTAG_TRSTN"), + MTK_FUNCTION(4, "MD_INT2_C2K_UIM1_HOT_PLUG"), + MTK_FUNCTION(5, "CONN_TCXOENA_REQ"), + MTK_FUNCTION(6, "PWM_2"), + MTK_FUNCTION(7, "JTRSTN_SEL1") + ), + MTK_PIN( + 17, "GPIO17", + MTK_EINT_FUNCTION(0, 17), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO17"), + MTK_FUNCTION(1, "SPI0_A_MI"), + MTK_FUNCTION(2, "SCP_SPI0_MI"), + MTK_FUNCTION(3, "MFG_EJTAG_TDO"), + MTK_FUNCTION(4, "DPI_HSYNC"), + MTK_FUNCTION(5, "MFG_DFD_JTAG_TDO"), + MTK_FUNCTION(6, "DFD_TDO"), + MTK_FUNCTION(7, "JTDO_SEL1") + ), + MTK_PIN( + 18, "GPIO18", + MTK_EINT_FUNCTION(0, 18), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO18"), + MTK_FUNCTION(1, "SPI0_A_MO"), + MTK_FUNCTION(2, "SCP_SPI0_MO"), + MTK_FUNCTION(3, "MFG_EJTAG_TDI"), + MTK_FUNCTION(4, "DPI_VSYNC"), + MTK_FUNCTION(5, "MFG_DFD_JTAG_TDI"), + MTK_FUNCTION(6, "DFD_TDI"), + MTK_FUNCTION(7, "JTDI_SEL1") + ), + MTK_PIN( + 19, "GPIO19", + MTK_EINT_FUNCTION(0, 19), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO19"), + MTK_FUNCTION(1, "SPI0_A_CSB"), + MTK_FUNCTION(2, "SCP_SPI0_CS"), + MTK_FUNCTION(3, "MFG_EJTAG_TMS"), + MTK_FUNCTION(4, "DPI_DE"), + MTK_FUNCTION(5, "MFG_DFD_JTAG_TMS"), + MTK_FUNCTION(6, "DFD_TMS"), + MTK_FUNCTION(7, "JTMS_SEL1") + ), + MTK_PIN( + 20, "GPIO20", + MTK_EINT_FUNCTION(0, 20), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO20"), + MTK_FUNCTION(1, "SPI0_A_CLK"), + MTK_FUNCTION(2, "SCP_SPI0_CK"), + MTK_FUNCTION(3, "MFG_EJTAG_TCK"), + MTK_FUNCTION(4, "DPI_CK"), + MTK_FUNCTION(5, "MFG_DFD_JTAG_TCK"), + MTK_FUNCTION(6, "DFD_TCK_XI"), + MTK_FUNCTION(7, "JTCK_SEL1") + ), + MTK_PIN( + 21, "GPIO21", + MTK_EINT_FUNCTION(0, 21), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO21"), + MTK_FUNCTION(1, "PWM_0"), + MTK_FUNCTION(2, "CMFLASH0"), + MTK_FUNCTION(3, "CMVREF2"), + MTK_FUNCTION(4, "CLKM0"), + MTK_FUNCTION(5, "ANT_SEL9"), + MTK_FUNCTION(6, "CONN_TCXOENA_REQ"), + MTK_FUNCTION(7, "DBG_MON_A27") + ), + MTK_PIN( + 22, "GPIO22", + MTK_EINT_FUNCTION(0, 22), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO22"), + MTK_FUNCTION(1, "PWM_1"), + MTK_FUNCTION(2, "CMFLASH1"), + MTK_FUNCTION(3, "CMVREF3"), + MTK_FUNCTION(4, "CLKM1"), + MTK_FUNCTION(5, "ANT_SEL10"), + MTK_FUNCTION(7, "DBG_MON_A28") + ), + MTK_PIN( + 23, "GPIO23", + MTK_EINT_FUNCTION(0, 23), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO23"), + MTK_FUNCTION(1, "PWM_2"), + MTK_FUNCTION(2, "CMFLASH2"), + MTK_FUNCTION(3, "CMVREF0"), + MTK_FUNCTION(4, "CLKM2"), + MTK_FUNCTION(5, "ANT_SEL11"), + MTK_FUNCTION(7, "DBG_MON_A29") + ), + MTK_PIN( + 24, "GPIO24", + MTK_EINT_FUNCTION(0, 24), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO24"), + MTK_FUNCTION(1, "PWM_0"), + MTK_FUNCTION(2, "CMFLASH3"), + MTK_FUNCTION(3, "CMVREF1"), + MTK_FUNCTION(4, "CLKM3"), + MTK_FUNCTION(5, "ANT_SEL12"), + MTK_FUNCTION(7, "DBG_MON_A30") + ), + MTK_PIN( + 25, "GPIO25", + MTK_EINT_FUNCTION(0, 25), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO25"), + MTK_FUNCTION(1, "SRCLKENAI0"), + MTK_FUNCTION(2, "UCTS0"), + MTK_FUNCTION(3, "SCL8"), + MTK_FUNCTION(4, "CMVREF4"), + MTK_FUNCTION(5, "I2S0_LRCK"), + MTK_FUNCTION(6, "CONN_TCXOENA_REQ"), + MTK_FUNCTION(7, "DBG_MON_A31") + ), + MTK_PIN( + 26, "GPIO26", + MTK_EINT_FUNCTION(0, 26), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO26"), + MTK_FUNCTION(1, "PWM_0"), + MTK_FUNCTION(2, "URTS0"), + MTK_FUNCTION(3, "SDA8"), + MTK_FUNCTION(4, "CLKM0"), + MTK_FUNCTION(5, "I2S0_DI"), + MTK_FUNCTION(6, "AGPS_SYNC"), + MTK_FUNCTION(7, "DBG_MON_A32") + ), + MTK_PIN( + 27, "GPIO27", + MTK_EINT_FUNCTION(0, 27), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO27"), + MTK_FUNCTION(1, "AP_GOOD") + ), + MTK_PIN( + 28, "GPIO28", + MTK_EINT_FUNCTION(0, 28), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO28"), + MTK_FUNCTION(1, "SCL5") + ), + MTK_PIN( + 29, "GPIO29", + MTK_EINT_FUNCTION(0, 29), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO29"), + MTK_FUNCTION(1, "SDA5") + ), + MTK_PIN( + 30, "GPIO30", + MTK_EINT_FUNCTION(0, 30), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO30"), + MTK_FUNCTION(1, "I2S1_MCK"), + MTK_FUNCTION(2, "I2S3_MCK"), + MTK_FUNCTION(3, "I2S2_MCK"), + MTK_FUNCTION(4, "DPI_D0"), + MTK_FUNCTION(5, "SPI4_MI"), + MTK_FUNCTION(6, "CONN_MCU_DBGI_N") + ), + MTK_PIN( + 31, "GPIO31", + MTK_EINT_FUNCTION(0, 31), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO31"), + MTK_FUNCTION(1, "I2S1_BCK"), + MTK_FUNCTION(2, "I2S3_BCK"), + MTK_FUNCTION(3, "I2S2_BCK"), + MTK_FUNCTION(4, "DPI_D1"), + MTK_FUNCTION(5, "SPI4_CSB"), + MTK_FUNCTION(6, "CONN_MCU_TDO") + ), + MTK_PIN( + 32, "GPIO32", + MTK_EINT_FUNCTION(0, 32), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO32"), + MTK_FUNCTION(1, "I2S1_LRCK"), + MTK_FUNCTION(2, "I2S3_LRCK"), + MTK_FUNCTION(3, "I2S2_LRCK"), + MTK_FUNCTION(4, "DPI_D2"), + MTK_FUNCTION(5, "SPI4_MO"), + MTK_FUNCTION(6, "CONN_MCU_TDI") + ), + MTK_PIN( + 33, "GPIO33", + MTK_EINT_FUNCTION(0, 33), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO33"), + MTK_FUNCTION(1, "I2S2_DI"), + MTK_FUNCTION(2, "I2S0_DI"), + MTK_FUNCTION(3, "I2S5_DO"), + MTK_FUNCTION(4, "DPI_D3"), + MTK_FUNCTION(5, "SPI4_CLK"), + MTK_FUNCTION(6, "CONN_MCU_TMS") + ), + MTK_PIN( + 34, "GPIO34", + MTK_EINT_FUNCTION(0, 34), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO34"), + MTK_FUNCTION(1, "I2S1_DO"), + MTK_FUNCTION(2, "I2S3_DO"), + MTK_FUNCTION(3, "I2S2_DI2"), + MTK_FUNCTION(4, "DPI_D4"), + MTK_FUNCTION(5, "AGPS_SYNC"), + MTK_FUNCTION(6, "CONN_MCU_TCK") + ), + MTK_PIN( + 35, "GPIO35", + MTK_EINT_FUNCTION(0, 35), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO35"), + MTK_FUNCTION(1, "TDM_LRCK"), + MTK_FUNCTION(2, "I2S1_LRCK"), + MTK_FUNCTION(3, "I2S5_LRCK"), + MTK_FUNCTION(4, "DPI_D5"), + MTK_FUNCTION(5, "SPI5_A_MO"), + MTK_FUNCTION(6, "IO_JTAG_TDI"), + MTK_FUNCTION(7, "PWM_2") + ), + MTK_PIN( + 36, "GPIO36", + MTK_EINT_FUNCTION(0, 36), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO36"), + MTK_FUNCTION(1, "TDM_BCK"), + MTK_FUNCTION(2, "I2S1_BCK"), + MTK_FUNCTION(3, "I2S5_BCK"), + MTK_FUNCTION(4, "DPI_D6"), + MTK_FUNCTION(5, "SPI5_A_CSB"), + MTK_FUNCTION(6, "IO_JTAG_TRSTN"), + MTK_FUNCTION(7, "SRCLKENAI1") + ), + MTK_PIN( + 37, "GPIO37", + MTK_EINT_FUNCTION(0, 37), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO37"), + MTK_FUNCTION(1, "TDM_MCK"), + MTK_FUNCTION(2, "I2S1_MCK"), + MTK_FUNCTION(3, "I2S5_MCK"), + MTK_FUNCTION(4, "DPI_D7"), + MTK_FUNCTION(5, "SPI5_A_MI"), + MTK_FUNCTION(6, "IO_JTAG_TCK"), + MTK_FUNCTION(7, "SRCLKENAI0") + ), + MTK_PIN( + 38, "GPIO38", + MTK_EINT_FUNCTION(0, 38), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO38"), + MTK_FUNCTION(1, "TDM_DATA0"), + MTK_FUNCTION(2, "I2S2_DI"), + MTK_FUNCTION(3, "I2S5_DO"), + MTK_FUNCTION(4, "DPI_D8"), + MTK_FUNCTION(5, "SPI5_A_CLK"), + MTK_FUNCTION(6, "IO_JTAG_TDO"), + MTK_FUNCTION(7, "CONN_TCXOENA_REQ") + ), + MTK_PIN( + 39, "GPIO39", + MTK_EINT_FUNCTION(0, 39), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO39"), + MTK_FUNCTION(1, "TDM_DATA1"), + MTK_FUNCTION(2, "I2S1_DO"), + MTK_FUNCTION(3, "I2S2_DI2"), + MTK_FUNCTION(4, "DPI_D9"), + MTK_FUNCTION(5, "DVFSRC_EXT_REQ"), + MTK_FUNCTION(6, "IO_JTAG_TMS"), + MTK_FUNCTION(7, "IDDIG") + ), + MTK_PIN( + 40, "GPIO40", + MTK_EINT_FUNCTION(0, 40), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO40"), + MTK_FUNCTION(1, "TDM_DATA2"), + MTK_FUNCTION(2, "SCL9"), + MTK_FUNCTION(3, "PWM_3"), + MTK_FUNCTION(4, "DPI_D10"), + MTK_FUNCTION(5, "SRCLKENAI0"), + MTK_FUNCTION(6, "DAP_MD32_SWD"), + MTK_FUNCTION(7, "USB_DRVVBUS") + ), + MTK_PIN( + 41, "GPIO41", + MTK_EINT_FUNCTION(0, 41), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO41"), + MTK_FUNCTION(1, "TDM_DATA3"), + MTK_FUNCTION(2, "SDA9"), + MTK_FUNCTION(3, "PWM_1"), + MTK_FUNCTION(4, "DPI_D11"), + MTK_FUNCTION(5, "CLKM1"), + MTK_FUNCTION(6, "DAP_MD32_SWCK") + ), + MTK_PIN( + 42, "GPIO42", + MTK_EINT_FUNCTION(0, 42), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO42"), + MTK_FUNCTION(1, "DISP_PWM") + ), + MTK_PIN( + 43, "GPIO43", + MTK_EINT_FUNCTION(0, 43), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO43"), + MTK_FUNCTION(1, "DSI_TE") + ), + MTK_PIN( + 44, "GPIO44", + MTK_EINT_FUNCTION(0, 44), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO44"), + MTK_FUNCTION(1, "LCM_RST") + ), + MTK_PIN( + 45, "GPIO45", + MTK_EINT_FUNCTION(0, 45), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO45"), + MTK_FUNCTION(1, "SCL6"), + MTK_FUNCTION(2, "SCP_SCL0"), + MTK_FUNCTION(3, "SCP_SCL1"), + MTK_FUNCTION(4, "SCL_6306") + ), + MTK_PIN( + 46, "GPIO46", + MTK_EINT_FUNCTION(0, 46), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO46"), + MTK_FUNCTION(1, "SDA6"), + MTK_FUNCTION(2, "SCP_SDA0"), + MTK_FUNCTION(3, "SCP_SDA1"), + MTK_FUNCTION(4, "SDA_6306") + ), + MTK_PIN( + 47, "GPIO47", + MTK_EINT_FUNCTION(0, 47), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO47"), + MTK_FUNCTION(1, "SPI1_A_MI"), + MTK_FUNCTION(2, "SCP_SPI1_A_MI"), + MTK_FUNCTION(3, "KPCOL2"), + MTK_FUNCTION(4, "MD_URXD0"), + MTK_FUNCTION(5, "CONN_UART0_RXD"), + MTK_FUNCTION(6, "SSPM_URXD_AO"), + MTK_FUNCTION(7, "DBG_MON_B32") + ), + MTK_PIN( + 48, "GPIO48", + MTK_EINT_FUNCTION(0, 48), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO48"), + MTK_FUNCTION(1, "SPI1_A_CSB"), + MTK_FUNCTION(2, "SCP_SPI1_A_CS"), + MTK_FUNCTION(3, "KPROW2"), + MTK_FUNCTION(4, "MD_UTXD0"), + MTK_FUNCTION(5, "CONN_UART0_TXD"), + MTK_FUNCTION(6, "SSPM_UTXD_AO"), + MTK_FUNCTION(7, "DBG_MON_B31") + ), + MTK_PIN( + 49, "GPIO49", + MTK_EINT_FUNCTION(0, 49), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO49"), + MTK_FUNCTION(1, "SPI1_A_MO"), + MTK_FUNCTION(2, "SCP_SPI1_A_MO"), + MTK_FUNCTION(3, "UCTS0"), + MTK_FUNCTION(4, "MD_URXD1"), + MTK_FUNCTION(5, "PWM_1"), + MTK_FUNCTION(6, "TP_URXD2_AO"), + MTK_FUNCTION(7, "DBG_MON_B30") + ), + MTK_PIN( + 50, "GPIO50", + MTK_EINT_FUNCTION(0, 50), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO50"), + MTK_FUNCTION(1, "SPI1_A_CLK"), + MTK_FUNCTION(2, "SCP_SPI1_A_CK"), + MTK_FUNCTION(3, "URTS0"), + MTK_FUNCTION(4, "MD_UTXD1"), + MTK_FUNCTION(5, "WIFI_TXD"), + MTK_FUNCTION(6, "TP_UTXD2_AO"), + MTK_FUNCTION(7, "DBG_MON_B29") + ), + MTK_PIN( + 51, "GPIO51", + MTK_EINT_FUNCTION(0, 51), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO51"), + MTK_FUNCTION(1, "SCL0") + ), + MTK_PIN( + 52, "GPIO52", + MTK_EINT_FUNCTION(0, 52), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO52"), + MTK_FUNCTION(1, "SDA0") + ), + MTK_PIN( + 53, "GPIO53", + MTK_EINT_FUNCTION(0, 53), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO53"), + MTK_FUNCTION(1, "URXD0"), + MTK_FUNCTION(2, "UTXD0"), + MTK_FUNCTION(3, "MD_URXD0"), + MTK_FUNCTION(4, "MD_URXD1"), + MTK_FUNCTION(5, "SSPM_URXD_AO"), + MTK_FUNCTION(7, "CONN_UART0_RXD") + ), + MTK_PIN( + 54, "GPIO54", + MTK_EINT_FUNCTION(0, 54), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO54"), + MTK_FUNCTION(1, "UTXD0"), + MTK_FUNCTION(2, "URXD0"), + MTK_FUNCTION(3, "MD_UTXD0"), + MTK_FUNCTION(4, "MD_UTXD1"), + MTK_FUNCTION(5, "SSPM_UTXD_AO"), + MTK_FUNCTION(6, "WIFI_TXD"), + MTK_FUNCTION(7, "CONN_UART0_TXD") + ), + MTK_PIN( + 55, "GPIO55", + MTK_EINT_FUNCTION(0, 55), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO55"), + MTK_FUNCTION(1, "SCL3"), + MTK_FUNCTION(2, "SCP_SCL0"), + MTK_FUNCTION(3, "SCP_SCL1"), + MTK_FUNCTION(4, "SCL_6306") + ), + MTK_PIN( + 56, "GPIO56", + MTK_EINT_FUNCTION(0, 56), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO56"), + MTK_FUNCTION(1, "SDA3"), + MTK_FUNCTION(2, "SCP_SDA0"), + MTK_FUNCTION(3, "SCP_SDA1"), + MTK_FUNCTION(4, "SDA_6306") + ), + MTK_PIN( + 57, "GPIO57", + MTK_EINT_FUNCTION(0, 57), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO57"), + MTK_FUNCTION(1, "KPROW1"), + MTK_FUNCTION(2, "PWM_1"), + MTK_FUNCTION(3, "DVFSRC_EXT_REQ"), + MTK_FUNCTION(4, "CLKM1"), + MTK_FUNCTION(5, "IDDIG"), + MTK_FUNCTION(6, "CONN_TCXOENA_REQ"), + MTK_FUNCTION(7, "MBISTREADEN_TRIGGER") + ), + MTK_PIN( + 58, "GPIO58", + MTK_EINT_FUNCTION(0, 58), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO58"), + MTK_FUNCTION(1, "KPROW0"), + MTK_FUNCTION(7, "DBG_MON_B28") + ), + MTK_PIN( + 59, "GPIO59", + MTK_EINT_FUNCTION(0, 59), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO59"), + MTK_FUNCTION(1, "KPCOL0"), + MTK_FUNCTION(7, "DBG_MON_B27") + ), + MTK_PIN( + 60, "GPIO60", + MTK_EINT_FUNCTION(0, 60), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO60"), + MTK_FUNCTION(1, "KPCOL1"), + MTK_FUNCTION(2, "PWM_2"), + MTK_FUNCTION(3, "UCTS1"), + MTK_FUNCTION(4, "CLKM2"), + MTK_FUNCTION(5, "USB_DRVVBUS"), + MTK_FUNCTION(7, "MBISTWRITEEN_TRIGGER") + ), + MTK_PIN( + 61, "GPIO61", + MTK_EINT_FUNCTION(0, 61), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO61"), + MTK_FUNCTION(1, "SCL1"), + MTK_FUNCTION(2, "SCP_SCL0"), + MTK_FUNCTION(3, "SCP_SCL1") + ), + MTK_PIN( + 62, "GPIO62", + MTK_EINT_FUNCTION(0, 62), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO62"), + MTK_FUNCTION(1, "SDA1"), + MTK_FUNCTION(2, "SCP_SDA0"), + MTK_FUNCTION(3, "SCP_SDA1") + ), + MTK_PIN( + 63, "GPIO63", + MTK_EINT_FUNCTION(0, 63), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO63"), + MTK_FUNCTION(1, "SPI2_MI"), + MTK_FUNCTION(2, "SCP_SPI2_MI"), + MTK_FUNCTION(3, "KPCOL2"), + MTK_FUNCTION(4, "MRG_DI"), + MTK_FUNCTION(5, "MD_URXD0"), + MTK_FUNCTION(6, "CONN_UART0_RXD"), + MTK_FUNCTION(7, "DBG_MON_B26") + ), + MTK_PIN( + 64, "GPIO64", + MTK_EINT_FUNCTION(0, 64), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO64"), + MTK_FUNCTION(1, "SPI2_CSB"), + MTK_FUNCTION(2, "SCP_SPI2_CS"), + MTK_FUNCTION(3, "KPROW2"), + MTK_FUNCTION(4, "MRG_SYNC"), + MTK_FUNCTION(5, "MD_UTXD0"), + MTK_FUNCTION(6, "CONN_UART0_TXD"), + MTK_FUNCTION(7, "DBG_MON_B25") + ), + MTK_PIN( + 65, "GPIO65", + MTK_EINT_FUNCTION(0, 65), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO65"), + MTK_FUNCTION(1, "SPI2_MO"), + MTK_FUNCTION(2, "SCP_SPI2_MO"), + MTK_FUNCTION(3, "SCP_SDA1"), + MTK_FUNCTION(4, "MRG_DO"), + MTK_FUNCTION(5, "MD_URXD1"), + MTK_FUNCTION(6, "PWM_3") + ), + MTK_PIN( + 66, "GPIO66", + MTK_EINT_FUNCTION(0, 66), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO66"), + MTK_FUNCTION(1, "SPI2_CLK"), + MTK_FUNCTION(2, "SCP_SPI2_CK"), + MTK_FUNCTION(3, "SCP_SCL1"), + MTK_FUNCTION(4, "MRG_CLK"), + MTK_FUNCTION(5, "MD_UTXD1"), + MTK_FUNCTION(6, "WIFI_TXD") + ), + MTK_PIN( + 67, "GPIO67", + MTK_EINT_FUNCTION(0, 67), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO67"), + MTK_FUNCTION(1, "I2S3_LRCK"), + MTK_FUNCTION(2, "I2S1_LRCK"), + MTK_FUNCTION(3, "URXD1"), + MTK_FUNCTION(4, "PCM0_SYNC"), + MTK_FUNCTION(5, "I2S5_LRCK"), + MTK_FUNCTION(6, "ANT_SEL9"), + MTK_FUNCTION(7, "DBG_MON_B10") + ), + MTK_PIN( + 68, "GPIO68", + MTK_EINT_FUNCTION(0, 68), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO68"), + MTK_FUNCTION(1, "I2S3_DO"), + MTK_FUNCTION(2, "I2S1_DO"), + MTK_FUNCTION(3, "UTXD1"), + MTK_FUNCTION(4, "PCM0_DO"), + MTK_FUNCTION(5, "I2S5_DO"), + MTK_FUNCTION(6, "ANT_SEL10"), + MTK_FUNCTION(7, "DBG_MON_B9") + ), + MTK_PIN( + 69, "GPIO69", + MTK_EINT_FUNCTION(0, 69), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO69"), + MTK_FUNCTION(1, "I2S3_MCK"), + MTK_FUNCTION(2, "I2S1_MCK"), + MTK_FUNCTION(3, "URTS1"), + MTK_FUNCTION(4, "AGPS_SYNC"), + MTK_FUNCTION(5, "I2S5_MCK"), + MTK_FUNCTION(6, "DVFSRC_EXT_REQ"), + MTK_FUNCTION(7, "DBG_MON_B8") + ), + MTK_PIN( + 70, "GPIO70", + MTK_EINT_FUNCTION(0, 70), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO70"), + MTK_FUNCTION(1, "I2S0_DI"), + MTK_FUNCTION(2, "I2S2_DI"), + MTK_FUNCTION(3, "KPCOL2"), + MTK_FUNCTION(4, "PCM0_DI"), + MTK_FUNCTION(5, "I2S2_DI2"), + MTK_FUNCTION(6, "ANT_SEL11"), + MTK_FUNCTION(7, "DBG_MON_B7") + ), + MTK_PIN( + 71, "GPIO71", + MTK_EINT_FUNCTION(0, 71), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO71"), + MTK_FUNCTION(1, "I2S3_BCK"), + MTK_FUNCTION(2, "I2S1_BCK"), + MTK_FUNCTION(3, "KPROW2"), + MTK_FUNCTION(4, "PCM0_CLK"), + MTK_FUNCTION(5, "I2S5_BCK"), + MTK_FUNCTION(6, "ANT_SEL12"), + MTK_FUNCTION(7, "DBG_MON_B6") + ), + MTK_PIN( + 72, "GPIO72", + MTK_EINT_FUNCTION(0, 72), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO72"), + MTK_FUNCTION(1, "BPI_BUS19_OLAT0"), + MTK_FUNCTION(2, "CONN_BPI_BUS19_OLAT0") + ), + MTK_PIN( + 73, "GPIO73", + MTK_EINT_FUNCTION(0, 73), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO73"), + MTK_FUNCTION(1, "BPI_BUS18_PA_VM1"), + MTK_FUNCTION(2, "CONN_MIPI5_SCLK"), + MTK_FUNCTION(3, "MIPI5_SCLK") + ), + MTK_PIN( + 74, "GPIO74", + MTK_EINT_FUNCTION(0, 74), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO74"), + MTK_FUNCTION(1, "BPI_BUS17_PA_VM0"), + MTK_FUNCTION(2, "CONN_MIPI5_SDATA"), + MTK_FUNCTION(3, "MIPI5_SDATA") + ), + MTK_PIN( + 75, "GPIO75", + MTK_EINT_FUNCTION(0, 75), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO75"), + MTK_FUNCTION(1, "BPI_BUS20_OLAT1"), + MTK_FUNCTION(2, "CONN_BPI_BUS20_OLAT1"), + MTK_FUNCTION(3, "RFIC0_BSI_D2") + ), + MTK_PIN( + 76, "GPIO76", + MTK_EINT_FUNCTION(0, 76), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO76"), + MTK_FUNCTION(1, "RFIC0_BSI_D1") + ), + MTK_PIN( + 77, "GPIO77", + MTK_EINT_FUNCTION(0, 77), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO77"), + MTK_FUNCTION(1, "RFIC0_BSI_D0") + ), + MTK_PIN( + 78, "GPIO78", + MTK_EINT_FUNCTION(0, 78), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO78"), + MTK_FUNCTION(1, "BPI_BUS7"), + MTK_FUNCTION(7, "DBG_MON_B24") + ), + MTK_PIN( + 79, "GPIO79", + MTK_EINT_FUNCTION(0, 79), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO79"), + MTK_FUNCTION(1, "BPI_BUS6"), + MTK_FUNCTION(7, "DBG_MON_B23") + ), + MTK_PIN( + 80, "GPIO80", + MTK_EINT_FUNCTION(0, 80), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO80"), + MTK_FUNCTION(1, "BPI_BUS8"), + MTK_FUNCTION(7, "DBG_MON_B22") + ), + MTK_PIN( + 81, "GPIO81", + MTK_EINT_FUNCTION(0, 81), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO81"), + MTK_FUNCTION(1, "BPI_BUS9"), + MTK_FUNCTION(7, "DBG_MON_B21") + ), + MTK_PIN( + 82, "GPIO82", + MTK_EINT_FUNCTION(0, 82), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO82"), + MTK_FUNCTION(1, "BPI_BUS10"), + MTK_FUNCTION(7, "DBG_MON_B20") + ), + MTK_PIN( + 83, "GPIO83", + MTK_EINT_FUNCTION(0, 83), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO83"), + MTK_FUNCTION(1, "BPI_BUS11"), + MTK_FUNCTION(7, "DBG_MON_B19") + ), + MTK_PIN( + 84, "GPIO84", + MTK_EINT_FUNCTION(0, 84), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO84"), + MTK_FUNCTION(1, "BPI_BUS12"), + MTK_FUNCTION(2, "CONN_BPI_BUS12") + ), + MTK_PIN( + 85, "GPIO85", + MTK_EINT_FUNCTION(0, 85), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO85"), + MTK_FUNCTION(1, "BPI_BUS13"), + MTK_FUNCTION(2, "CONN_BPI_BUS13") + ), + MTK_PIN( + 86, "GPIO86", + MTK_EINT_FUNCTION(0, 86), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO86"), + MTK_FUNCTION(1, "BPI_BUS14"), + MTK_FUNCTION(2, "CONN_BPI_BUS14") + ), + MTK_PIN( + 87, "GPIO87", + MTK_EINT_FUNCTION(0, 87), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO87"), + MTK_FUNCTION(1, "BPI_BUS15"), + MTK_FUNCTION(2, "CONN_BPI_BUS15") + ), + MTK_PIN( + 88, "GPIO88", + MTK_EINT_FUNCTION(0, 88), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO88"), + MTK_FUNCTION(1, "BPI_BUS16"), + MTK_FUNCTION(2, "CONN_BPI_BUS16") + ), + MTK_PIN( + 89, "GPIO89", + MTK_EINT_FUNCTION(0, 89), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO89"), + MTK_FUNCTION(1, "BPI_BUS5"), + MTK_FUNCTION(7, "DBG_MON_B18") + ), + MTK_PIN( + 90, "GPIO90", + MTK_EINT_FUNCTION(0, 90), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO90"), + MTK_FUNCTION(1, "BPI_BUS4"), + MTK_FUNCTION(7, "DBG_MON_B17") + ), + MTK_PIN( + 91, "GPIO91", + MTK_EINT_FUNCTION(0, 91), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO91"), + MTK_FUNCTION(1, "BPI_BUS3") + ), + MTK_PIN( + 92, "GPIO92", + MTK_EINT_FUNCTION(0, 92), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO92"), + MTK_FUNCTION(1, "BPI_BUS2"), + MTK_FUNCTION(7, "DBG_MON_B16") + ), + MTK_PIN( + 93, "GPIO93", + MTK_EINT_FUNCTION(0, 93), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO93"), + MTK_FUNCTION(1, "BPI_BUS1") + ), + MTK_PIN( + 94, "GPIO94", + MTK_EINT_FUNCTION(0, 94), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO94"), + MTK_FUNCTION(1, "BPI_BUS0"), + MTK_FUNCTION(7, "DBG_MON_B15") + ), + MTK_PIN( + 95, "GPIO95", + MTK_EINT_FUNCTION(0, 95), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO95"), + MTK_FUNCTION(1, "MIPI0_SDATA") + ), + MTK_PIN( + 96, "GPIO96", + MTK_EINT_FUNCTION(0, 96), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO96"), + MTK_FUNCTION(1, "MIPI0_SCLK") + ), + MTK_PIN( + 97, "GPIO97", + MTK_EINT_FUNCTION(0, 97), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO97"), + MTK_FUNCTION(1, "MIPI1_SDATA") + ), + MTK_PIN( + 98, "GPIO98", + MTK_EINT_FUNCTION(0, 98), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO98"), + MTK_FUNCTION(1, "MIPI1_SCLK") + ), + MTK_PIN( + 99, "GPIO99", + MTK_EINT_FUNCTION(0, 99), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO99"), + MTK_FUNCTION(1, "MIPI2_SCLK"), + MTK_FUNCTION(7, "DBG_MON_B14") + ), + MTK_PIN( + 100, "GPIO100", + MTK_EINT_FUNCTION(0, 100), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO100"), + MTK_FUNCTION(1, "MIPI2_SDATA"), + MTK_FUNCTION(7, "DBG_MON_B13") + ), + MTK_PIN( + 101, "GPIO101", + MTK_EINT_FUNCTION(0, 101), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO101"), + MTK_FUNCTION(1, "MIPI3_SCLK"), + MTK_FUNCTION(7, "DBG_MON_B12") + ), + MTK_PIN( + 102, "GPIO102", + MTK_EINT_FUNCTION(0, 102), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO102"), + MTK_FUNCTION(1, "MIPI3_SDATA"), + MTK_FUNCTION(7, "DBG_MON_B11") + ), + MTK_PIN( + 103, "GPIO103", + MTK_EINT_FUNCTION(0, 103), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO103"), + MTK_FUNCTION(1, "MIPI4_SCLK"), + MTK_FUNCTION(2, "CONN_MIPI4_SCLK") + ), + MTK_PIN( + 104, "GPIO104", + MTK_EINT_FUNCTION(0, 104), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO104"), + MTK_FUNCTION(1, "MIPI4_SDATA"), + MTK_FUNCTION(2, "CONN_MIPI4_SDATA") + ), + MTK_PIN( + 105, "GPIO105", + MTK_EINT_FUNCTION(0, 105), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO105"), + MTK_FUNCTION(1, "BPI_BUS22_OLAT3"), + MTK_FUNCTION(2, "CONN_BPI_BUS22_OLAT3") + ), + MTK_PIN( + 106, "GPIO106", + MTK_EINT_FUNCTION(0, 106), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO106"), + MTK_FUNCTION(1, "BPI_BUS21_OLAT2"), + MTK_FUNCTION(2, "CONN_BPI_BUS21_OLAT2") + ), + MTK_PIN( + 107, "GPIO107", + MTK_EINT_FUNCTION(0, 107), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO107"), + MTK_FUNCTION(1, "BPI_BUS24_ANT1"), + MTK_FUNCTION(2, "CONN_BPI_BUS24_ANT1") + ), + MTK_PIN( + 108, "GPIO108", + MTK_EINT_FUNCTION(0, 108), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO108"), + MTK_FUNCTION(1, "BPI_BUS25_ANT2"), + MTK_FUNCTION(2, "CONN_BPI_BUS25_ANT2") + ), + MTK_PIN( + 109, "GPIO109", + MTK_EINT_FUNCTION(0, 109), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO109"), + MTK_FUNCTION(1, "BPI_BUS23_ANT0"), + MTK_FUNCTION(2, "CONN_BPI_BUS23_ANT0") + ), + MTK_PIN( + 110, "GPIO110", + MTK_EINT_FUNCTION(0, 110), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO110"), + MTK_FUNCTION(1, "SCL4") + ), + MTK_PIN( + 111, "GPIO111", + MTK_EINT_FUNCTION(0, 111), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO111"), + MTK_FUNCTION(1, "SDA4") + ), + MTK_PIN( + 112, "GPIO112", + MTK_EINT_FUNCTION(0, 112), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO112"), + MTK_FUNCTION(1, "SCL2") + ), + MTK_PIN( + 113, "GPIO113", + MTK_EINT_FUNCTION(0, 113), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO113"), + MTK_FUNCTION(1, "SDA2") + ), + MTK_PIN( + 114, "GPIO114", + MTK_EINT_FUNCTION(0, 114), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO114"), + MTK_FUNCTION(1, "CLKM0"), + MTK_FUNCTION(2, "SPI3_MI"), + MTK_FUNCTION(7, "DBG_MON_B5") + ), + MTK_PIN( + 115, "GPIO115", + MTK_EINT_FUNCTION(0, 115), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO115"), + MTK_FUNCTION(1, "CLKM1"), + MTK_FUNCTION(2, "SPI3_CSB"), + MTK_FUNCTION(7, "DBG_MON_B4") + ), + MTK_PIN( + 116, "GPIO116", + MTK_EINT_FUNCTION(0, 116), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO116"), + MTK_FUNCTION(1, "CMMCLK0"), + MTK_FUNCTION(7, "DBG_MON_B3") + ), + MTK_PIN( + 117, "GPIO117", + MTK_EINT_FUNCTION(0, 117), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO117"), + MTK_FUNCTION(1, "CMMCLK1"), + MTK_FUNCTION(2, "DVFSRC_EXT_REQ"), + MTK_FUNCTION(7, "DBG_MON_B2") + ), + MTK_PIN( + 118, "GPIO118", + MTK_EINT_FUNCTION(0, 118), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO118"), + MTK_FUNCTION(1, "CLKM2"), + MTK_FUNCTION(2, "SPI3_MO"), + MTK_FUNCTION(7, "DBG_MON_B1") + ), + MTK_PIN( + 119, "GPIO119", + MTK_EINT_FUNCTION(0, 119), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO119"), + MTK_FUNCTION(1, "CLKM3"), + MTK_FUNCTION(2, "SPI3_CLK"), + MTK_FUNCTION(7, "DBG_MON_B0") + ), + MTK_PIN( + 120, "GPIO120", + MTK_EINT_FUNCTION(0, 120), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO120"), + MTK_FUNCTION(1, "CMMCLK2"), + MTK_FUNCTION(2, "CLKM2"), + MTK_FUNCTION(6, "ANT_SEL12"), + MTK_FUNCTION(7, "TP_UCTS2_AO") + ), + MTK_PIN( + 121, "GPIO121", + MTK_EINT_FUNCTION(0, 121), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO121"), + MTK_FUNCTION(1, "CMMCLK3"), + MTK_FUNCTION(2, "CLKM3"), + MTK_FUNCTION(3, "DVFSRC_EXT_REQ"), + MTK_FUNCTION(6, "ANT_SEL11"), + MTK_FUNCTION(7, "TP_URTS2_AO") + ), + MTK_PIN( + 122, "GPIO122", + MTK_EINT_FUNCTION(0, 122), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO122"), + MTK_FUNCTION(1, "CMVREF1"), + MTK_FUNCTION(2, "PCM0_SYNC"), + MTK_FUNCTION(3, "SRCLKENAI1"), + MTK_FUNCTION(4, "AGPS_SYNC"), + MTK_FUNCTION(5, "PWM_1"), + MTK_FUNCTION(6, "ANT_SEL9"), + MTK_FUNCTION(7, "TP_UCTS1_AO") + ), + MTK_PIN( + 123, "GPIO123", + MTK_EINT_FUNCTION(0, 123), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO123"), + MTK_FUNCTION(2, "PCM0_DI"), + MTK_FUNCTION(3, "ADSP_JTAG_TRSTN"), + MTK_FUNCTION(4, "VPU_UDI_NTRST"), + MTK_FUNCTION(5, "SPM_JTAG_TRSTN"), + MTK_FUNCTION(6, "SSPM_JTAG_TRSTN") + ), + MTK_PIN( + 124, "GPIO124", + MTK_EINT_FUNCTION(0, 124), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO124"), + MTK_FUNCTION(1, "CMVREF2"), + MTK_FUNCTION(2, "PCM0_CLK"), + MTK_FUNCTION(3, "MD_INT0"), + MTK_FUNCTION(4, "EXT_FRAME_SYNC"), + MTK_FUNCTION(5, "PWM_2"), + MTK_FUNCTION(6, "ANT_SEL10"), + MTK_FUNCTION(7, "TP_URTS1_AO") + ), + MTK_PIN( + 125, "GPIO125", + MTK_EINT_FUNCTION(0, 125), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO125"), + MTK_FUNCTION(1, "CMVREF3"), + MTK_FUNCTION(2, "PCM0_DO"), + MTK_FUNCTION(3, "ADSP_JTAG_TMS"), + MTK_FUNCTION(4, "VPU_UDI_TMS"), + MTK_FUNCTION(5, "SPM_JTAG_TMS"), + MTK_FUNCTION(6, "SSPM_JTAG_TMS") + ), + MTK_PIN( + 126, "GPIO126", + MTK_EINT_FUNCTION(0, 126), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO126"), + MTK_FUNCTION(1, "CMVREF4"), + MTK_FUNCTION(2, "CMFLASH0"), + MTK_FUNCTION(6, "CONN_MCU_AICE_TMSC") + ), + MTK_PIN( + 127, "GPIO127", + MTK_EINT_FUNCTION(0, 127), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO127"), + MTK_FUNCTION(1, "CMVREF0"), + MTK_FUNCTION(2, "CMFLASH1"), + MTK_FUNCTION(6, "CONN_MCU_AICE_TCKC") + ), + MTK_PIN( + 128, "GPIO128", + MTK_EINT_FUNCTION(0, 128), + DRV_GRP0, + MTK_FUNCTION(0, "GPIO128"), + MTK_FUNCTION(1, "MD1_SIM1_SIO"), + MTK_FUNCTION(2, "MD1_SIM2_SIO"), + MTK_FUNCTION(3, "CCU_JTAG_TRST"), + MTK_FUNCTION(4, "CONN_DSP_JINTP"), + MTK_FUNCTION(5, "SCP_JTAG_TRSTN"), + MTK_FUNCTION(6, "LVTS_FOUT"), + MTK_FUNCTION(7, "DBG_MON_A3") + ), + MTK_PIN( + 129, "GPIO129", + MTK_EINT_FUNCTION(0, 129), + DRV_GRP0, + MTK_FUNCTION(0, "GPIO129"), + MTK_FUNCTION(1, "MD1_SIM1_SRST"), + MTK_FUNCTION(2, "MD1_SIM2_SRST"), + MTK_FUNCTION(3, "CCU_JTAG_TCK"), + MTK_FUNCTION(4, "CONN_DSP_JCK"), + MTK_FUNCTION(5, "SCP_JTAG_TCK"), + MTK_FUNCTION(6, "LVTS_SDO"), + MTK_FUNCTION(7, "DBG_MON_A4") + ), + MTK_PIN( + 130, "GPIO130", + MTK_EINT_FUNCTION(0, 130), + DRV_GRP0, + MTK_FUNCTION(0, "GPIO130"), + MTK_FUNCTION(1, "MD1_SIM1_SCLK"), + MTK_FUNCTION(2, "MD1_SIM2_SCLK"), + MTK_FUNCTION(6, "LVTS_26M"), + MTK_FUNCTION(7, "DBG_MON_A5") + ), + MTK_PIN( + 131, "GPIO131", + MTK_EINT_FUNCTION(0, 131), + DRV_GRP0, + MTK_FUNCTION(0, "GPIO131"), + MTK_FUNCTION(1, "MD1_SIM2_SCLK"), + MTK_FUNCTION(2, "MD1_SIM1_SCLK"), + MTK_FUNCTION(3, "CCU_JTAG_TDI"), + MTK_FUNCTION(4, "CONN_DSP_JDI"), + MTK_FUNCTION(5, "SCP_JTAG_TDI"), + MTK_FUNCTION(6, "LVTS_SCK"), + MTK_FUNCTION(7, "DBG_MON_A0") + ), + MTK_PIN( + 132, "GPIO132", + MTK_EINT_FUNCTION(0, 132), + DRV_GRP0, + MTK_FUNCTION(0, "GPIO132"), + MTK_FUNCTION(1, "MD1_SIM2_SRST"), + MTK_FUNCTION(2, "MD1_SIM1_SRST"), + MTK_FUNCTION(3, "CCU_JTAG_TMS"), + MTK_FUNCTION(4, "CONN_DSP_JMS"), + MTK_FUNCTION(5, "SCP_JTAG_TMS"), + MTK_FUNCTION(6, "LVTS_SDI"), + MTK_FUNCTION(7, "DBG_MON_A1") + ), + MTK_PIN( + 133, "GPIO133", + MTK_EINT_FUNCTION(0, 133), + DRV_GRP0, + MTK_FUNCTION(0, "GPIO133"), + MTK_FUNCTION(1, "MD1_SIM2_SIO"), + MTK_FUNCTION(2, "MD1_SIM1_SIO"), + MTK_FUNCTION(3, "CCU_JTAG_TDO"), + MTK_FUNCTION(4, "CONN_DSP_JDO"), + MTK_FUNCTION(5, "SCP_JTAG_TDO"), + MTK_FUNCTION(6, "LVTS_SCF"), + MTK_FUNCTION(7, "DBG_MON_A2") + ), + MTK_PIN( + 134, "GPIO134", + MTK_EINT_FUNCTION(0, 134), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO134"), + MTK_FUNCTION(1, "MSDC1_CLK"), + MTK_FUNCTION(2, "PCM1_CLK"), + MTK_FUNCTION(3, "SPI5_B_MI"), + MTK_FUNCTION(4, "UDI_TCK"), + MTK_FUNCTION(5, "CONN_DSP_JCK"), + MTK_FUNCTION(6, "IPU_JTAG_TCK"), + MTK_FUNCTION(7, "JTCK_SEL3") + ), + MTK_PIN( + 135, "GPIO135", + MTK_EINT_FUNCTION(0, 135), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO135"), + MTK_FUNCTION(1, "MSDC1_CMD"), + MTK_FUNCTION(2, "PCM1_SYNC"), + MTK_FUNCTION(3, "SPI5_B_CSB"), + MTK_FUNCTION(4, "UDI_TMS"), + MTK_FUNCTION(5, "CONN_DSP_JMS"), + MTK_FUNCTION(6, "IPU_JTAG_TMS"), + MTK_FUNCTION(7, "JTMS_SEL3") + ), + MTK_PIN( + 136, "GPIO136", + MTK_EINT_FUNCTION(0, 136), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO136"), + MTK_FUNCTION(1, "MSDC1_DAT3"), + MTK_FUNCTION(2, "PCM1_DI"), + MTK_FUNCTION(3, "SPI5_B_MO"), + MTK_FUNCTION(4, "CONN_TCXOENA_REQ"), + MTK_FUNCTION(5, "CONN_DSP_JINTP"), + MTK_FUNCTION(6, "CONN_MCU_AICE_TMSC") + ), + MTK_PIN( + 137, "GPIO137", + MTK_EINT_FUNCTION(0, 137), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO137"), + MTK_FUNCTION(1, "MSDC1_DAT0"), + MTK_FUNCTION(2, "PCM1_DO0"), + MTK_FUNCTION(3, "SPI5_B_CLK"), + MTK_FUNCTION(4, "UDI_TDI"), + MTK_FUNCTION(5, "CONN_DSP_JDI"), + MTK_FUNCTION(6, "IPU_JTAG_TDI"), + MTK_FUNCTION(7, "JTDI_SEL3") + ), + MTK_PIN( + 138, "GPIO138", + MTK_EINT_FUNCTION(0, 138), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO138"), + MTK_FUNCTION(1, "MSDC1_DAT2"), + MTK_FUNCTION(2, "PCM1_DO2"), + MTK_FUNCTION(3, "ANT_SEL11"), + MTK_FUNCTION(4, "UDI_NTRST"), + MTK_FUNCTION(5, "CONN_MCU_AICE_TCKC"), + MTK_FUNCTION(6, "IPU_JTAG_TRST"), + MTK_FUNCTION(7, "JTRSTN_SEL3") + ), + MTK_PIN( + 139, "GPIO139", + MTK_EINT_FUNCTION(0, 139), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO139"), + MTK_FUNCTION(1, "MSDC1_DAT1"), + MTK_FUNCTION(2, "PCM1_DO1"), + MTK_FUNCTION(3, "ANT_SEL12"), + MTK_FUNCTION(4, "UDI_TDO"), + MTK_FUNCTION(5, "CONN_DSP_JDO"), + MTK_FUNCTION(6, "IPU_JTAG_TDO"), + MTK_FUNCTION(7, "JTDO_SEL3") + ), + MTK_PIN( + 140, "GPIO140", + MTK_EINT_FUNCTION(0, 140), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO140"), + MTK_FUNCTION(1, "MD_INT1_C2K_UIM0_HOT_PLUG"), + MTK_FUNCTION(2, "MD_INT2_C2K_UIM1_HOT_PLUG"), + MTK_FUNCTION(3, "ADSP_URXD0"), + MTK_FUNCTION(4, "SCL_6306"), + MTK_FUNCTION(5, "PTA_RXD"), + MTK_FUNCTION(6, "SSPM_URXD_AO") + ), + MTK_PIN( + 141, "GPIO141", + MTK_EINT_FUNCTION(0, 141), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO141"), + MTK_FUNCTION(1, "MD_INT2_C2K_UIM1_HOT_PLUG"), + MTK_FUNCTION(2, "MD_INT1_C2K_UIM0_HOT_PLUG"), + MTK_FUNCTION(3, "ADSP_UTXD0"), + MTK_FUNCTION(4, "SDA_6306"), + MTK_FUNCTION(5, "PTA_TXD"), + MTK_FUNCTION(6, "SSPM_UTXD_AO") + ), + MTK_PIN( + 142, "GPIO142", + MTK_EINT_FUNCTION(0, 142), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO142"), + MTK_FUNCTION(1, "SCP_VREQ_VAO"), + MTK_FUNCTION(2, "DVFSRC_EXT_REQ") + ), + MTK_PIN( + 143, "GPIO143", + MTK_EINT_FUNCTION(0, 143), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO143"), + MTK_FUNCTION(1, "AUD_DAT_MOSI2"), + MTK_FUNCTION(7, "DBG_MON_A9") + ), + MTK_PIN( + 144, "GPIO144", + MTK_EINT_FUNCTION(0, 144), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO144"), + MTK_FUNCTION(1, "AUD_NLE_MOSI1"), + MTK_FUNCTION(2, "AUD_CLK_MISO"), + MTK_FUNCTION(3, "I2S2_MCK"), + MTK_FUNCTION(5, "UDI_TCK"), + MTK_FUNCTION(6, "UFS_UNIPRO_SDA"), + MTK_FUNCTION(7, "DBG_MON_A10") + ), + MTK_PIN( + 145, "GPIO145", + MTK_EINT_FUNCTION(0, 145), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO145"), + MTK_FUNCTION(1, "AUD_NLE_MOSI0"), + MTK_FUNCTION(2, "AUD_SYNC_MISO"), + MTK_FUNCTION(3, "I2S2_BCK"), + MTK_FUNCTION(5, "UDI_TMS"), + MTK_FUNCTION(7, "DBG_MON_A11") + ), + MTK_PIN( + 146, "GPIO146", + MTK_EINT_FUNCTION(0, 146), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO146"), + MTK_FUNCTION(1, "AUD_DAT_MISO2"), + MTK_FUNCTION(3, "I2S2_DI2"), + MTK_FUNCTION(5, "UDI_TDO"), + MTK_FUNCTION(7, "DBG_MON_A14") + ), + MTK_PIN( + 147, "GPIO147", + MTK_EINT_FUNCTION(0, 147), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO147"), + MTK_FUNCTION(1, "ANT_SEL0"), + MTK_FUNCTION(2, "PWM_3") + ), + MTK_PIN( + 148, "GPIO148", + MTK_EINT_FUNCTION(0, 148), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO148"), + MTK_FUNCTION(1, "ANT_SEL1"), + MTK_FUNCTION(2, "SPI0_B_MI"), + MTK_FUNCTION(3, "SSPM_URXD_AO"), + MTK_FUNCTION(5, "TP_UCTS2_AO"), + MTK_FUNCTION(6, "CLKM0") + ), + MTK_PIN( + 149, "GPIO149", + MTK_EINT_FUNCTION(0, 149), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO149"), + MTK_FUNCTION(1, "ANT_SEL2"), + MTK_FUNCTION(2, "SPI0_B_CSB"), + MTK_FUNCTION(3, "SSPM_UTXD_AO"), + MTK_FUNCTION(5, "TP_URTS2_AO"), + MTK_FUNCTION(6, "CONN_TCXOENA_REQ") + ), + MTK_PIN( + 150, "GPIO150", + MTK_EINT_FUNCTION(0, 150), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO150"), + MTK_FUNCTION(1, "ANT_SEL3"), + MTK_FUNCTION(2, "SPI0_B_MO"), + MTK_FUNCTION(3, "UCTS1"), + MTK_FUNCTION(5, "TP_UCTS1_AO"), + MTK_FUNCTION(6, "IDDIG"), + MTK_FUNCTION(7, "SCL9") + ), + MTK_PIN( + 151, "GPIO151", + MTK_EINT_FUNCTION(0, 151), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO151"), + MTK_FUNCTION(1, "ANT_SEL4"), + MTK_FUNCTION(2, "SPI0_B_CLK"), + MTK_FUNCTION(3, "URTS1"), + MTK_FUNCTION(5, "TP_URTS1_AO"), + MTK_FUNCTION(6, "USB_DRVVBUS"), + MTK_FUNCTION(7, "SDA9") + ), + MTK_PIN( + 152, "GPIO152", + MTK_EINT_FUNCTION(0, 152), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO152"), + MTK_FUNCTION(1, "ANT_SEL5"), + MTK_FUNCTION(2, "SPI1_B_MI"), + MTK_FUNCTION(3, "CLKM3"), + MTK_FUNCTION(5, "TP_URXD1_AO"), + MTK_FUNCTION(6, "SCP_SPI1_B_MI"), + MTK_FUNCTION(7, "SCL8") + ), + MTK_PIN( + 153, "GPIO153", + MTK_EINT_FUNCTION(0, 153), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO153"), + MTK_FUNCTION(1, "ANT_SEL6"), + MTK_FUNCTION(2, "SPI1_B_CSB"), + MTK_FUNCTION(3, "SRCLKENAI0"), + MTK_FUNCTION(4, "PWM_0"), + MTK_FUNCTION(5, "TP_UTXD1_AO"), + MTK_FUNCTION(6, "SCP_SPI1_B_CS"), + MTK_FUNCTION(7, "SDA8") + ), + MTK_PIN( + 154, "GPIO154", + MTK_EINT_FUNCTION(0, 154), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO154"), + MTK_FUNCTION(1, "ANT_SEL7"), + MTK_FUNCTION(2, "SPI1_B_MO"), + MTK_FUNCTION(3, "SRCLKENAI1"), + MTK_FUNCTION(5, "TP_URXD2_AO"), + MTK_FUNCTION(6, "SCP_SPI1_B_MO") + ), + MTK_PIN( + 155, "GPIO155", + MTK_EINT_FUNCTION(0, 155), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO155"), + MTK_FUNCTION(1, "ANT_SEL8"), + MTK_FUNCTION(2, "SPI1_B_CLK"), + MTK_FUNCTION(3, "MD_INT0"), + MTK_FUNCTION(5, "TP_UTXD2_AO"), + MTK_FUNCTION(6, "SCP_SPI1_B_CK"), + MTK_FUNCTION(7, "DBG_MON_A15") + ), + MTK_PIN( + 156, "GPIO156", + MTK_EINT_FUNCTION(0, 156), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO156"), + MTK_FUNCTION(1, "CONN_TOP_CLK"), + MTK_FUNCTION(2, "AUXIF_CLK0"), + MTK_FUNCTION(7, "DBG_MON_A16") + ), + MTK_PIN( + 157, "GPIO157", + MTK_EINT_FUNCTION(0, 157), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO157"), + MTK_FUNCTION(1, "CONN_TOP_DATA"), + MTK_FUNCTION(2, "AUXIF_ST0"), + MTK_FUNCTION(7, "DBG_MON_A17") + ), + MTK_PIN( + 158, "GPIO158", + MTK_EINT_FUNCTION(0, 158), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO158"), + MTK_FUNCTION(1, "CONN_HRST_B"), + MTK_FUNCTION(7, "DBG_MON_A18") + ), + MTK_PIN( + 159, "GPIO159", + MTK_EINT_FUNCTION(0, 159), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO159"), + MTK_FUNCTION(1, "CONN_WB_PTA"), + MTK_FUNCTION(7, "DBG_MON_A19") + ), + MTK_PIN( + 160, "GPIO160", + MTK_EINT_FUNCTION(0, 160), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO160"), + MTK_FUNCTION(1, "CONN_BT_CLK"), + MTK_FUNCTION(2, "AUXIF_CLK1"), + MTK_FUNCTION(7, "DBG_MON_A20") + ), + MTK_PIN( + 161, "GPIO161", + MTK_EINT_FUNCTION(0, 161), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO161"), + MTK_FUNCTION(1, "CONN_BT_DATA"), + MTK_FUNCTION(2, "AUXIF_ST1"), + MTK_FUNCTION(7, "DBG_MON_A21") + ), + MTK_PIN( + 162, "GPIO162", + MTK_EINT_FUNCTION(0, 162), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO162"), + MTK_FUNCTION(1, "CONN_WF_CTRL0"), + MTK_FUNCTION(7, "DBG_MON_A22") + ), + MTK_PIN( + 163, "GPIO163", + MTK_EINT_FUNCTION(0, 163), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO163"), + MTK_FUNCTION(1, "CONN_WF_CTRL1"), + MTK_FUNCTION(2, "UFS_MPHY_SCL"), + MTK_FUNCTION(7, "DBG_MON_A23") + ), + MTK_PIN( + 164, "GPIO164", + MTK_EINT_FUNCTION(0, 164), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO164"), + MTK_FUNCTION(1, "CONN_WF_CTRL2"), + MTK_FUNCTION(2, "UFS_MPHY_SDA"), + MTK_FUNCTION(7, "DBG_MON_A24") + ), + MTK_PIN( + 165, "GPIO165", + MTK_EINT_FUNCTION(0, 165), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO165"), + MTK_FUNCTION(1, "CONN_WF_CTRL3"), + MTK_FUNCTION(2, "UFS_UNIPRO_SDA"), + MTK_FUNCTION(7, "DBG_MON_A25") + ), + MTK_PIN( + 166, "GPIO166", + MTK_EINT_FUNCTION(0, 166), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO166"), + MTK_FUNCTION(1, "CONN_WF_CTRL4"), + MTK_FUNCTION(2, "UFS_UNIPRO_SCL"), + MTK_FUNCTION(7, "DBG_MON_A26") + ), + MTK_PIN( + 167, "GPIO167", + MTK_EINT_FUNCTION(0, 167), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO167"), + MTK_FUNCTION(1, "MSDC0_CMD") + ), + MTK_PIN( + 168, "GPIO168", + MTK_EINT_FUNCTION(0, 168), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO168"), + MTK_FUNCTION(1, "MSDC0_DAT0") + ), + MTK_PIN( + 169, "GPIO169", + MTK_EINT_FUNCTION(0, 169), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO169"), + MTK_FUNCTION(1, "MSDC0_DAT2") + ), + MTK_PIN( + 170, "GPIO170", + MTK_EINT_FUNCTION(0, 170), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO170"), + MTK_FUNCTION(1, "MSDC0_DAT4") + ), + MTK_PIN( + 171, "GPIO171", + MTK_EINT_FUNCTION(0, 171), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO171"), + MTK_FUNCTION(1, "MSDC0_DAT6") + ), + MTK_PIN( + 172, "GPIO172", + MTK_EINT_FUNCTION(0, 172), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO172"), + MTK_FUNCTION(1, "MSDC0_DAT1") + ), + MTK_PIN( + 173, "GPIO173", + MTK_EINT_FUNCTION(0, 173), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO173"), + MTK_FUNCTION(1, "MSDC0_DAT5") + ), + MTK_PIN( + 174, "GPIO174", + MTK_EINT_FUNCTION(0, 174), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO174"), + MTK_FUNCTION(1, "MSDC0_DAT7") + ), + MTK_PIN( + 175, "GPIO175", + MTK_EINT_FUNCTION(0, 175), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO175"), + MTK_FUNCTION(1, "MSDC0_DSL"), + MTK_FUNCTION(2, "ANT_SEL9") + ), + MTK_PIN( + 176, "GPIO176", + MTK_EINT_FUNCTION(0, 176), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO176"), + MTK_FUNCTION(1, "MSDC0_CLK"), + MTK_FUNCTION(2, "ANT_SEL10") + ), + MTK_PIN( + 177, "GPIO177", + MTK_EINT_FUNCTION(0, 177), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO177"), + MTK_FUNCTION(1, "MSDC0_DAT3") + ), + MTK_PIN( + 178, "GPIO178", + MTK_EINT_FUNCTION(0, 178), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO178"), + MTK_FUNCTION(1, "MSDC0_RSTB") + ), + MTK_PIN( + 179, "GPIO179", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO179"), + MTK_FUNCTION(1, "RFIC0_BSI_EN") + ), + MTK_PIN( + 180, "GPIO180", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO180"), + MTK_FUNCTION(1, "RFIC0_BSI_CK") + ), + MTK_PIN( + 181, "GPIO181", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO181"), + MTK_FUNCTION(1, "SRCLKENA0") + ), + MTK_PIN( + 182, "GPIO182", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO182"), + MTK_FUNCTION(1, "SRCLKENA1") + ), + MTK_PIN( + 183, "GPIO183", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO183"), + MTK_FUNCTION(1, "WATCHDOG") + ), + MTK_PIN( + 184, "GPIO184", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO184"), + MTK_FUNCTION(1, "PWRAP_SPI0_MI"), + MTK_FUNCTION(2, "PWRAP_SPI0_MO") + ), + MTK_PIN( + 185, "GPIO185", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO185"), + MTK_FUNCTION(1, "PWRAP_SPI0_CSN") + ), + MTK_PIN( + 186, "GPIO186", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO186"), + MTK_FUNCTION(1, "PWRAP_SPI0_MO"), + MTK_FUNCTION(2, "PWRAP_SPI0_MI") + ), + MTK_PIN( + 187, "GPIO187", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO187"), + MTK_FUNCTION(1, "PWRAP_SPI0_CK") + ), + MTK_PIN( + 188, "GPIO188", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO188"), + MTK_FUNCTION(1, "RTC32K_CK") + ), + MTK_PIN( + 189, "GPIO189", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO189"), + MTK_FUNCTION(1, "AUD_CLK_MOSI"), + MTK_FUNCTION(3, "I2S1_MCK"), + MTK_FUNCTION(6, "UFS_UNIPRO_SCL") + ), + MTK_PIN( + 190, "GPIO190", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO190"), + MTK_FUNCTION(1, "AUD_SYNC_MOSI"), + MTK_FUNCTION(3, "I2S1_BCK"), + MTK_FUNCTION(7, "DBG_MON_A6") + ), + MTK_PIN( + 191, "GPIO191", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO191"), + MTK_FUNCTION(1, "AUD_DAT_MOSI0"), + MTK_FUNCTION(3, "I2S1_LRCK"), + MTK_FUNCTION(7, "DBG_MON_A7") + ), + MTK_PIN( + 192, "GPIO192", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO192"), + MTK_FUNCTION(1, "AUD_DAT_MOSI1"), + MTK_FUNCTION(3, "I2S1_DO"), + MTK_FUNCTION(6, "UFS_MPHY_SDA"), + MTK_FUNCTION(7, "DBG_MON_A8") + ), + MTK_PIN( + 193, "GPIO193", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO193"), + MTK_FUNCTION(1, "AUD_DAT_MISO0"), + MTK_FUNCTION(2, "VOW_DAT_MISO"), + MTK_FUNCTION(3, "I2S2_LRCK"), + MTK_FUNCTION(5, "UDI_TDI"), + MTK_FUNCTION(7, "DBG_MON_A12") + ), + MTK_PIN( + 194, "GPIO194", + MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO194"), + MTK_FUNCTION(1, "AUD_DAT_MISO1"), + MTK_FUNCTION(2, "VOW_CLK_MISO"), + MTK_FUNCTION(3, "I2S2_DI"), + MTK_FUNCTION(5, "UDI_NTRST"), + MTK_FUNCTION(6, "UFS_MPHY_SCL"), + MTK_FUNCTION(7, "DBG_MON_A13") + ), + MTK_PIN( + 195, "GPIO195", + MTK_EINT_FUNCTION(0, 179), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO195"), + MTK_FUNCTION(3, "ADSP_JTAG_TCK"), + MTK_FUNCTION(4, "VPU_UDI_TCK"), + MTK_FUNCTION(5, "SPM_JTAG_TCK"), + MTK_FUNCTION(6, "SSPM_JTAG_TCK") + ), + MTK_PIN( + 196, "GPIO196", + MTK_EINT_FUNCTION(0, 180), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO196"), + MTK_FUNCTION(1, "CMMCLK4"), + MTK_FUNCTION(3, "ADSP_JTAG_TDI"), + MTK_FUNCTION(4, "VPU_UDI_TDI"), + MTK_FUNCTION(5, "SPM_JTAG_TDI"), + MTK_FUNCTION(6, "SSPM_JTAG_TDI") + ), + MTK_PIN( + 197, "GPIO197", + MTK_EINT_FUNCTION(0, 181), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO197"), + MTK_FUNCTION(3, "ADSP_JTAG_TDO"), + MTK_FUNCTION(4, "VPU_UDI_TDO"), + MTK_FUNCTION(5, "SPM_JTAG_TDO"), + MTK_FUNCTION(6, "SSPM_JTAG_TDO") + ), + MTK_PIN( + 198, "GPIO198", + MTK_EINT_FUNCTION(0, 182), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO198"), + MTK_FUNCTION(1, "SCL7") + ), + MTK_PIN( + 199, "GPIO199", + MTK_EINT_FUNCTION(0, 183), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO199"), + MTK_FUNCTION(1, "SDA7") + ), + MTK_PIN( + 200, "GPIO200", + MTK_EINT_FUNCTION(0, 184), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO200"), + MTK_FUNCTION(1, "URXD1"), + MTK_FUNCTION(2, "ADSP_URXD0"), + MTK_FUNCTION(3, "TP_URXD1_AO"), + MTK_FUNCTION(4, "SSPM_URXD_AO"), + MTK_FUNCTION(5, "TP_URXD2_AO"), + MTK_FUNCTION(6, "MBISTREADEN_TRIGGER") + ), + MTK_PIN( + 201, "GPIO201", + MTK_EINT_FUNCTION(0, 185), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO201"), + MTK_FUNCTION(1, "UTXD1"), + MTK_FUNCTION(2, "ADSP_UTXD0"), + MTK_FUNCTION(3, "TP_UTXD1_AO"), + MTK_FUNCTION(4, "SSPM_UTXD_AO"), + MTK_FUNCTION(5, "TP_UTXD2_AO"), + MTK_FUNCTION(6, "MBISTWRITEEN_TRIGGER") + ), + MTK_PIN( + 202, "GPIO202", + MTK_EINT_FUNCTION(0, 186), + DRV_GRP4, + MTK_FUNCTION(0, "GPIO202"), + MTK_FUNCTION(1, "PWM_3"), + MTK_FUNCTION(2, "CLKM3") + ), + MTK_PIN( + 203, "GPIO203", + MTK_EINT_FUNCTION(0, 187), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 204, "GPIO204", + MTK_EINT_FUNCTION(0, 188), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 205, "GPIO205", + MTK_EINT_FUNCTION(0, 189), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 206, "GPIO206", + MTK_EINT_FUNCTION(0, 190), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 207, "GPIO207", + MTK_EINT_FUNCTION(0, 191), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 208, "GPIO208", + MTK_EINT_FUNCTION(0, 193), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), + MTK_PIN( + 209, "GPIO209", + MTK_EINT_FUNCTION(0, 194), + DRV_GRP4, + MTK_FUNCTION(0, NULL) + ), +}; + +#endif /* __PINCTRL-MTK-MT6779_H */ From c1282ae87882aff2a1adbc8d168c8fb3391d288a Mon Sep 17 00:00:00 2001 From: Hanks Chen Date: Thu, 23 Jul 2020 19:19:55 +0800 Subject: [PATCH 225/242] pinctrl: mediatek: add mt6779 eint support add driver setting to support mt6779 eint Signed-off-by: Mars Cheng Signed-off-by: Hanks Chen Acked-by: Sean Wang Link: https://lore.kernel.org/r/1595503197-15246-6-git-send-email-hanks.chen@mediatek.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mt6779.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6779.c b/drivers/pinctrl/mediatek/pinctrl-mt6779.c index ede185b58d41..bb0851c73304 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt6779.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt6779.c @@ -732,11 +732,19 @@ static const char * const mt6779_pinctrl_register_base_names[] = { "iocfg_rt", "iocfg_lt", "iocfg_tl", }; +static const struct mtk_eint_hw mt6779_eint_hw = { + .port_mask = 7, + .ports = 6, + .ap_num = 195, + .db_cnt = 13, +}; + static const struct mtk_pin_soc mt6779_data = { .reg_cal = mt6779_reg_cals, .pins = mtk_pins_mt6779, .npins = ARRAY_SIZE(mtk_pins_mt6779), .ngrps = ARRAY_SIZE(mtk_pins_mt6779), + .eint_hw = &mt6779_eint_hw, .gpio_m = 0, .ies_present = true, .base_names = mt6779_pinctrl_register_base_names, From f1b206cf7c57561ea156798f323b0541a783bd2f Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Wed, 22 Jul 2020 14:27:52 +0200 Subject: [PATCH 226/242] pinctrl: core: print gpio in pins debugfs file If there is a gpio range mapping for the pin, then print out the gpio chip and line index for the pin in the debugfs 'pins' file with the format: "[line-index]:[gpio-label]" Here is example output on the BeagleBoard.org PocketBeagle (AM3358): /sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pins pin 25 (PIN25) 25:gpio-32-63 44e10864 00000037 pinctrl-single pin 26 (PIN26) 26:gpio-32-63 44e10868 00000037 pinctrl-single pin 27 (PIN27) 27:gpio-32-63 44e1086c 00000037 pinctrl-single pin 28 (PIN28) 0:? 44e10870 00000036 pinctrl-single pin 29 (PIN29) 0:? 44e10874 00000006 pinctrl-single pin 30 (PIN30) 28:gpio-32-63 44e10878 00000027 pinctrl-single pin 31 (PIN31) 29:gpio-32-63 44e1087c 00000037 pinctrl-single pin 32 (PIN32) 30:gpio-32-63 44e10880 00000037 pinctrl-single pin 33 (PIN33) 31:gpio-32-63 44e10884 00000037 pinctrl-single pin 34 (PIN34) 0:gpio-64-95 44e10888 00000037 pinctrl-single pin 35 (PIN35) 1:gpio-64-95 44e1088c 00000037 pinctrl-single Suggested-by: Andy Shevchenko Suggested-by: Tony Lindgren Signed-off-by: Drew Fustini Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20200722122751.266440-1-drew@beagleboard.org Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 3e8d1630d29e..3663d87f51a0 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -27,6 +27,7 @@ #include #ifdef CONFIG_GPIOLIB +#include "../gpio/gpiolib.h" #include #endif @@ -1601,6 +1602,9 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) struct pinctrl_dev *pctldev = s->private; const struct pinctrl_ops *ops = pctldev->desc->pctlops; unsigned i, pin; + struct pinctrl_gpio_range *range; + unsigned int gpio_num; + struct gpio_chip *chip; seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); @@ -1618,6 +1622,23 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) seq_printf(s, "pin %d (%s) ", pin, desc->name); +#ifdef CONFIG_GPIOLIB + gpio_num = 0; + list_for_each_entry(range, &pctldev->gpio_ranges, node) { + if ((pin >= range->pin_base) && + (pin < (range->pin_base + range->npins))) { + gpio_num = range->base + (pin - range->pin_base); + break; + } + } + chip = gpio_to_chip(gpio_num); + if (chip && chip->gpiodev && chip->gpiodev->base) + seq_printf(s, "%u:%s ", gpio_num - + chip->gpiodev->base, chip->label); + else + seq_puts(s, "0:? "); +#endif + /* Driver-specific info per pin */ if (ops->pin_dbg_show) ops->pin_dbg_show(pctldev, s, pin); From 85745c870a757c21f880b7e73d2b6fd1e5113a03 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 20 Jul 2020 16:54:12 +0200 Subject: [PATCH 227/242] pinctrl: samsung: Use bank name as irqchip name Use the bank name as the irqchip name. This name is later visible in /proc/interrupts, what makes it possible to easily identify each GPIO interrupt. /proc/interrupts before this patch: 143: 0 exynos4210_wkup_irq_chip 7 Edge hdmi 144: 0 exynos4210_wkup_irq_chip 6 Level wm8994 145: 1 exynos4210_wkup_irq_chip 7 Edge max77686-pmic, max77686-rtc 146: 1 exynos_gpio_irq_chip 3 Edge 3-0048 /proc/interrupts after this patch: 143: 0 gpx3 7 Edge hdmi 144: 0 gpx3 6 Level wm8994 145: 1 gpx0 7 Edge max77686-pmic, max77686-rtc 146: 1 gpm2 3 Edge 3-0048 Handling of the eint_wake_mask_value has been reworked, because each bank has now its own exynos_irq_chip structure allocated. Signed-off-by: Marek Szyprowski Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20200720145412.24221-1-krzk@kernel.org Signed-off-by: Linus Walleij --- drivers/pinctrl/samsung/pinctrl-exynos.c | 58 +++++++++++++----------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 84501c785473..b9ea09fabf84 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -38,7 +38,7 @@ struct exynos_irq_chip { u32 eint_con; u32 eint_mask; u32 eint_pend; - u32 eint_wake_mask_value; + u32 *eint_wake_mask_value; u32 eint_wake_mask_reg; void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata, struct exynos_irq_chip *irq_chip); @@ -207,7 +207,7 @@ static void exynos_irq_release_resources(struct irq_data *irqd) /* * irq_chip for gpio interrupts. */ -static struct exynos_irq_chip exynos_gpio_irq_chip = { +static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst = { .chip = { .name = "exynos_gpio_irq_chip", .irq_unmask = exynos_irq_unmask, @@ -274,7 +274,7 @@ struct exynos_eint_gpio_save { * exynos_eint_gpio_init() - setup handling of external gpio interrupts. * @d: driver data of samsung pinctrl driver. */ -int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) +__init int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) { struct samsung_pin_bank *bank; struct device *dev = d->dev; @@ -297,6 +297,15 @@ int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) for (i = 0; i < d->nr_banks; ++i, ++bank) { if (bank->eint_type != EINT_TYPE_GPIO) continue; + + bank->irq_chip = devm_kmemdup(dev, &exynos_gpio_irq_chip, + sizeof(*bank->irq_chip), GFP_KERNEL); + if (!bank->irq_chip) { + ret = -ENOMEM; + goto err_domains; + } + bank->irq_chip->chip.name = bank->name; + bank->irq_domain = irq_domain_add_linear(bank->of_node, bank->nr_pins, &exynos_eint_irqd_ops, bank); if (!bank->irq_domain) { @@ -313,7 +322,6 @@ int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) goto err_domains; } - bank->irq_chip = &exynos_gpio_irq_chip; } return 0; @@ -338,9 +346,9 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on) pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq); if (!on) - our_chip->eint_wake_mask_value |= bit; + *our_chip->eint_wake_mask_value |= bit; else - our_chip->eint_wake_mask_value &= ~bit; + *our_chip->eint_wake_mask_value &= ~bit; return 0; } @@ -360,10 +368,10 @@ exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata, pmu_regs = drvdata->retention_ctrl->priv; dev_info(drvdata->dev, "Setting external wakeup interrupt mask: 0x%x\n", - irq_chip->eint_wake_mask_value); + *irq_chip->eint_wake_mask_value); regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg, - irq_chip->eint_wake_mask_value); + *irq_chip->eint_wake_mask_value); } static void @@ -382,10 +390,11 @@ s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata, clk_base = (void __iomem *) drvdata->retention_ctrl->priv; - __raw_writel(irq_chip->eint_wake_mask_value, + __raw_writel(*irq_chip->eint_wake_mask_value, clk_base + irq_chip->eint_wake_mask_reg); } +static u32 eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED; /* * irq_chip for wakeup interrupts */ @@ -403,7 +412,7 @@ static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = { .eint_con = EXYNOS_WKUP_ECON_OFFSET, .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, + .eint_wake_mask_value = &eint_wake_mask_value, /* Only differences with exynos4210_wkup_irq_chip: */ .eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK, .set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask, @@ -423,7 +432,7 @@ static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = { .eint_con = EXYNOS_WKUP_ECON_OFFSET, .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, - .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, + .eint_wake_mask_value = &eint_wake_mask_value, .eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK, .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, }; @@ -442,7 +451,7 @@ static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = { .eint_con = EXYNOS7_WKUP_ECON_OFFSET, .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET, .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET, - .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, + .eint_wake_mask_value = &eint_wake_mask_value, .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK, .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, }; @@ -513,7 +522,7 @@ static void exynos_irq_demux_eint16_31(struct irq_desc *desc) * exynos_eint_wkup_init() - setup handling of external wakeup interrupts. * @d: driver data of samsung pinctrl driver. */ -int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) +__init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) { struct device *dev = d->dev; struct device_node *wkup_np = NULL; @@ -521,7 +530,7 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) struct samsung_pin_bank *bank; struct exynos_weint_data *weint_data; struct exynos_muxed_weint_data *muxed_data; - struct exynos_irq_chip *irq_chip; + const struct exynos_irq_chip *irq_chip; unsigned int muxed_banks = 0; unsigned int i; int idx, irq; @@ -531,12 +540,7 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) match = of_match_node(exynos_wkup_irq_ids, np); if (match) { - irq_chip = kmemdup(match->data, - sizeof(*irq_chip), GFP_KERNEL); - if (!irq_chip) { - of_node_put(np); - return -ENOMEM; - } + irq_chip = match->data; wkup_np = np; break; } @@ -549,6 +553,14 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) if (bank->eint_type != EINT_TYPE_WKUP) continue; + bank->irq_chip = devm_kmemdup(dev, irq_chip, sizeof(*irq_chip), + GFP_KERNEL); + if (!bank->irq_chip) { + of_node_put(wkup_np); + return -ENOMEM; + } + bank->irq_chip->chip.name = bank->name; + bank->irq_domain = irq_domain_add_linear(bank->of_node, bank->nr_pins, &exynos_eint_irqd_ops, bank); if (!bank->irq_domain) { @@ -557,8 +569,6 @@ int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) return -ENXIO; } - bank->irq_chip = irq_chip; - if (!of_find_property(bank->of_node, "interrupts", NULL)) { bank->eint_type = EINT_TYPE_WKUP_MUX; ++muxed_banks; @@ -657,10 +667,6 @@ void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) irq_chip = bank->irq_chip; irq_chip->set_eint_wakeup_mask(drvdata, irq_chip); - } else if (bank->irq_chip != irq_chip) { - dev_warn(drvdata->dev, - "More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n", - bank->name); } } } From 047cd9a6bd8a2a73e8d92eb97a1b50c7bcd59279 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 27 Jul 2020 22:55:45 -0700 Subject: [PATCH 228/242] pinctrl: mediatek: fix build for tristate changes Export mtk_is_virt_gpio() for the case when CONFIG_PINCTRL_MTK=y CONFIG_PINCTRL_MTK_V2=y CONFIG_PINCTRL_MTK_MOORE=y CONFIG_PINCTRL_MTK_PARIS=m to fix this build error: ERROR: modpost: "mtk_is_virt_gpio" [drivers/pinctrl/mediatek/pinctrl-paris.ko] undefined! Signed-off-by: Randy Dunlap Cc: Sean Wang Cc: linux-mediatek@lists.infradead.org Link: https://lore.kernel.org/r/d15827a3-d0c8-e231-9f61-8507b3d7be3a@infradead.org Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index c53e2c391e32..2f3dfb56c3fa 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -264,6 +264,7 @@ bool mtk_is_virt_gpio(struct mtk_pinctrl *hw, unsigned int gpio_n) return virt_gpio; } +EXPORT_SYMBOL_GPL(mtk_is_virt_gpio); static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n, unsigned int *gpio_n, From e81376ebbafc679a5cea65f25f5ab242172f52df Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 22 Jul 2020 12:15:45 +0200 Subject: [PATCH 229/242] pinctrl: amd: Use irqchip template This makes the driver use the irqchip template to assign properties to the gpio_irq_chip instead of using the explicit call to gpiochip_irqchip_add(). The irqchip is instead added while adding the gpiochip. Signed-off-by: Linus Walleij Cc: Shyam Sundar S K Cc: Sandeep Singh Link: https://lore.kernel.org/r/20200722101545.144373-1-linus.walleij@linaro.org --- drivers/pinctrl/pinctrl-amd.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index ccf612031119..9a760f5cd7ed 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -846,6 +846,7 @@ static int amd_gpio_probe(struct platform_device *pdev) int irq_base; struct resource *res; struct amd_gpio *gpio_dev; + struct gpio_irq_chip *girq; gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct amd_gpio), GFP_KERNEL); @@ -907,6 +908,15 @@ static int amd_gpio_probe(struct platform_device *pdev) return PTR_ERR(gpio_dev->pctrl); } + girq = &gpio_dev->gc.irq; + girq->chip = &amd_gpio_irqchip; + /* This will let us handle the parent IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_simple_irq; + ret = gpiochip_add_data(&gpio_dev->gc, gpio_dev); if (ret) return ret; @@ -918,17 +928,6 @@ static int amd_gpio_probe(struct platform_device *pdev) goto out2; } - ret = gpiochip_irqchip_add(&gpio_dev->gc, - &amd_gpio_irqchip, - 0, - handle_simple_irq, - IRQ_TYPE_NONE); - if (ret) { - dev_err(&pdev->dev, "could not add irqchip\n"); - ret = -ENODEV; - goto out2; - } - ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, IRQF_SHARED, KBUILD_MODNAME, gpio_dev); if (ret) From 1de39b64bfd9a674f9c5ee21abe8b8ae33fa5a07 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 21 Jul 2020 15:18:14 +0200 Subject: [PATCH 230/242] pinctrl: stmfx: Use irqchip template This makes the driver use the irqchip template to assign properties to the gpio_irq_chip instead of using the explicit calls to gpiochip_irqchip_add_nested() and gpiochip_set_nested_irqchip(). The irqchip is instead added while adding the gpiochip. Signed-off-by: Linus Walleij Cc: Amelie Delaunay Cc: Benjamin Gaignard Link: https://lore.kernel.org/r/20200721131814.357182-1-linus.walleij@linaro.org --- drivers/pinctrl/pinctrl-stmfx.c | 38 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 1aae803c12cd..008c83107a3c 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -616,6 +616,7 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev) struct stmfx *stmfx = dev_get_drvdata(pdev->dev.parent); struct device_node *np = pdev->dev.of_node; struct stmfx_pinctrl *pctl; + struct gpio_irq_chip *girq; int irq, ret; pctl = devm_kzalloc(stmfx->dev, sizeof(*pctl), GFP_KERNEL); @@ -674,6 +675,25 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev) pctl->gpio_chip.can_sleep = true; pctl->gpio_chip.of_node = np; + pctl->irq_chip.name = dev_name(pctl->dev); + pctl->irq_chip.irq_mask = stmfx_pinctrl_irq_mask; + pctl->irq_chip.irq_unmask = stmfx_pinctrl_irq_unmask; + pctl->irq_chip.irq_set_type = stmfx_pinctrl_irq_set_type; + pctl->irq_chip.irq_bus_lock = stmfx_pinctrl_irq_bus_lock; + pctl->irq_chip.irq_bus_sync_unlock = stmfx_pinctrl_irq_bus_sync_unlock; + pctl->irq_chip.irq_request_resources = stmfx_gpio_irq_request_resources; + pctl->irq_chip.irq_release_resources = stmfx_gpio_irq_release_resources; + + girq = &pctl->gpio_chip.irq; + girq->chip = &pctl->irq_chip; + /* This will let us handle the parent IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_bad_irq; + girq->threaded = true; + ret = devm_gpiochip_add_data(pctl->dev, &pctl->gpio_chip, pctl); if (ret) { dev_err(pctl->dev, "gpio_chip registration failed\n"); @@ -684,22 +704,6 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev) if (ret) return ret; - pctl->irq_chip.name = dev_name(pctl->dev); - pctl->irq_chip.irq_mask = stmfx_pinctrl_irq_mask; - pctl->irq_chip.irq_unmask = stmfx_pinctrl_irq_unmask; - pctl->irq_chip.irq_set_type = stmfx_pinctrl_irq_set_type; - pctl->irq_chip.irq_bus_lock = stmfx_pinctrl_irq_bus_lock; - pctl->irq_chip.irq_bus_sync_unlock = stmfx_pinctrl_irq_bus_sync_unlock; - pctl->irq_chip.irq_request_resources = stmfx_gpio_irq_request_resources; - pctl->irq_chip.irq_release_resources = stmfx_gpio_irq_release_resources; - - ret = gpiochip_irqchip_add_nested(&pctl->gpio_chip, &pctl->irq_chip, - 0, handle_bad_irq, IRQ_TYPE_NONE); - if (ret) { - dev_err(pctl->dev, "cannot add irqchip to gpiochip\n"); - return ret; - } - ret = devm_request_threaded_irq(pctl->dev, irq, NULL, stmfx_pinctrl_irq_thread_fn, IRQF_ONESHOT, @@ -709,8 +713,6 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev) return ret; } - gpiochip_set_nested_irqchip(&pctl->gpio_chip, &pctl->irq_chip, irq); - dev_info(pctl->dev, "%ld GPIOs available\n", hweight_long(pctl->gpio_valid_mask)); From 7ee193e2dda3f48b692fad46ab9df90e99e7b811 Mon Sep 17 00:00:00 2001 From: Andy Teng Date: Thu, 30 Jul 2020 21:30:14 +0800 Subject: [PATCH 231/242] dt-bindings: pinctrl: add bindings for MediaTek MT6779 SoC Add devicetree bindings for MediaTek MT6779 pinctrl driver. Signed-off-by: Andy Teng Signed-off-by: Hanks Chen Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1596115816-11758-2-git-send-email-hanks.chen@mediatek.com Signed-off-by: Linus Walleij --- .../pinctrl/mediatek,mt6779-pinctrl.yaml | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml new file mode 100644 index 000000000000..152c151c27ad --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6779-pinctrl.yaml @@ -0,0 +1,202 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt6779-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT6779 Pin Controller Device Tree Bindings + +maintainers: + - Andy Teng + +description: |+ + The pin controller node should be the child of a syscon node with the + required property: + - compatible: "syscon" + +properties: + compatible: + const: mediatek,mt6779-pinctrl + + reg: + minItems: 9 + maxItems: 9 + + reg-names: + items: + - const: "gpio" + - const: "iocfg_rm" + - const: "iocfg_br" + - const: "iocfg_lm" + - const: "iocfg_lb" + - const: "iocfg_rt" + - const: "iocfg_lt" + - const: "iocfg_tl" + - const: "eint" + + gpio-controller: true + + "#gpio-cells": + const: 2 + description: | + Number of cells in GPIO specifier. Since the generic GPIO + binding is used, the amount of cells must be specified as 2. See the below + mentioned gpio binding representation for description of particular cells. + + gpio-ranges: + minItems: 1 + maxItems: 5 + description: | + GPIO valid number range. + + interrupt-controller: true + + interrupts: + maxItems: 1 + description: | + Specifies the summary IRQ. + + "#interrupt-cells": + const: 2 + +required: + - compatible + - reg + - reg-names + - gpio-controller + - "#gpio-cells" + - gpio-ranges + - interrupt-controller + - interrupts + - "#interrupt-cells" + +patternProperties: + '-[0-9]*$': + type: object + patternProperties: + '-pins*$': + type: object + description: | + A pinctrl node should contain at least one subnodes representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to muxer + configuration, pullups, drive strength, input enable/disable and input schmitt. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pinmux: + description: + integer array, represents gpio pin number and mux setting. + Supported pin number and mux varies for different SoCs, and are defined + as macros in boot/dts/-pinfunc.h directly. + + bias-disable: true + + bias-pull-up: true + + bias-pull-down: true + + input-enable: true + + input-disable: true + + output-low: true + + output-high: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + mediatek,pull-up-adv: + description: | + Pull up setings for 2 pull resistors, R0 and R1. User can + configure those special pins. Valid arguments are described as below: + 0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled. + 1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled. + 2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled. + 3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + mediatek,pull-down-adv: + description: | + Pull down settings for 2 pull resistors, R0 and R1. User can + configure those special pins. Valid arguments are described as below: + 0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled. + 1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled. + 2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled. + 3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + required: + - pinmux + + additionalProperties: false + +additionalProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + pio: pinctrl@10005000 { + compatible = "mediatek,mt6779-pinctrl"; + reg = <0 0x10005000 0 0x1000>, + <0 0x11c20000 0 0x1000>, + <0 0x11d10000 0 0x1000>, + <0 0x11e20000 0 0x1000>, + <0 0x11e70000 0 0x1000>, + <0 0x11ea0000 0 0x1000>, + <0 0x11f20000 0 0x1000>, + <0 0x11f30000 0 0x1000>, + <0 0x1000b000 0 0x1000>; + reg-names = "gpio", "iocfg_rm", + "iocfg_br", "iocfg_lm", + "iocfg_lb", "iocfg_rt", + "iocfg_lt", "iocfg_tl", + "eint"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 210>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = ; + + mmc0_pins_default: mmc0-0 { + cmd-dat-pins { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + mediatek,pull-up-adv = <1>; + }; + clk-pins { + pinmux = ; + mediatek,pull-down-adv = <2>; + }; + rst-pins { + pinmux = ; + mediatek,pull-up-adv = <0>; + }; + }; + }; + + mmc0 { + pinctrl-0 = <&mmc0_pins_default>; + pinctrl-names = "default"; + }; + }; From cc8a51ca6f05ade72f7dd2624bc5f9b948e216fc Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 1 Jul 2020 12:29:51 +0900 Subject: [PATCH 232/242] kbuild: always create directories of targets Currently, the directories of objects are automatically created only for O= builds. It should not hurt to cater to this for in-tree builds too. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 7ba6a752d5bd..246426fa1282 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -515,15 +515,13 @@ existing-targets := $(wildcard $(sort $(targets))) -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) -ifdef building_out_of_srctree # Create directories for object files if they do not exist -obj-dirs := $(sort $(obj) $(patsubst %/,%, $(dir $(targets)))) +obj-dirs := $(sort $(patsubst %/,%, $(dir $(targets)))) # If targets exist, their directories apparently exist. Skip mkdir. existing-dirs := $(sort $(patsubst %/,%, $(dir $(existing-targets)))) obj-dirs := $(strip $(filter-out $(existing-dirs), $(obj-dirs))) ifneq ($(obj-dirs),) $(shell mkdir -p $(obj-dirs)) endif -endif .PHONY: $(PHONY) From 3ec8a5b33deacdeca4bef24fb15498a975e875ba Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 2 Jul 2020 04:29:36 +0900 Subject: [PATCH 233/242] kbuild: do not export LDFLAGS_vmlinux When you clean the build tree for ARCH=arm, you may see the following error message from 'nm' command: $ make -j24 ARCH=arm clean CLEAN arch/arm/crypto CLEAN arch/arm/kernel CLEAN arch/arm/mach-at91 CLEAN arch/arm/mach-omap2 CLEAN arch/arm/vdso CLEAN certs CLEAN lib CLEAN usr CLEAN net/wireless CLEAN drivers/firmware/efi/libstub nm: 'arch/arm/boot/compressed/../../../../vmlinux': No such file /bin/sh: 1: arithmetic expression: expecting primary: " " CLEAN arch/arm/boot/compressed CLEAN drivers/scsi CLEAN drivers/tty/vt CLEAN arch/arm/boot CLEAN vmlinux.symvers modules.builtin modules.builtin.modinfo Even if you rerun the same command, the error message will not be shown despite vmlinux is already gone. To reproduce it, the parallel option -j is needed. Single thread cleaning always executes 'archclean', 'vmlinuxclean' in this order, so vmlinux still exists when arch/arm/boot/compressed/ is cleaned. Looking at arch/arm/boot/compressed/Makefile does not help understand the reason of the error message. Both KBSS_SZ and LDFLAGS_vmlinux are assigned with '=' operator, hence, they are not expanded unless used. Obviously, 'make clean' does not use them. In fact, the root cause exists in the top Makefile: export LDFLAGS_vmlinux Since LDFLAGS_vmlinux is an exported variable, LDFLAGS_vmlinux in arch/arm/boot/compressed/Makefile is expanded when scripts/Makefile.clean has a command to execute. This is why the error message shows up only when there exist build artifacts in arch/arm/boot/compressed/. Adding 'unexport LDFLAGS_vmlinux' to arch/arm/boot/compressed/Makefile will fix it as far as ARCH=arm is concerned, but I think the proper fix is to get rid of 'export LDFLAGS_vmlinux' from the top Makefile. LDFLAGS_vmlinux in the top Makefile contains linker flags for the top vmlinux. LDFLAGS_vmlinux in arch/arm/boot/compressed/Makefile is for arch/arm/boot/compressed/vmlinux. They just happen to have the same variable name, but are used for different purposes. Stop shadowing LDFLAGS_vmlinux. This commit passes LDFLAGS_vmlinux to scripts/link-vmlinux.sh via a command line parameter instead of via an environment variable. LD and KBUILD_LDFLAGS are exported, but I did the same for consistency. Anyway, they must be included in cmd_link-vmlinux to allow if_changed to detect the changes in LD or KBUILD_LDFLAGS. The following Makefiles are not affected: arch/arm/boot/compressed/Makefile arch/h8300/boot/compressed/Makefile arch/nios2/boot/compressed/Makefile arch/parisc/boot/compressed/Makefile arch/s390/boot/compressed/Makefile arch/sh/boot/compressed/Makefile arch/sh/boot/romimage/Makefile arch/x86/boot/compressed/Makefile They use ':=' or '=' to clear the LDFLAGS_vmlinux inherited from the top Makefile. We need to take a closer look at the impact to unicore32 and xtensa. arch/unicore32/boot/compressed/Makefile only uses '+=' operator for LDFLAGS_vmlinux. So, the decompressor previously inherited the linker flags from the top Makefile. However, commit 70fac51feaf2 ("unicore32 additional architecture files: boot process") was merged before commit 1f2bfbd00e46 ("kbuild: link of vmlinux moved to a script"). So, I rather consider this is a bug fix of 1f2bfbd00e46. arch/xtensa/boot/boot-elf/Makefile is also affected, but this is also considered a fix for the same reason. It did not inherit LDFLAGS_vmlinux when commit 4bedea945451 ("[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 2") was merged. I deleted $(LDFLAGS_vmlinux), which is now empty. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Tested-by: Nick Desaulniers --- Makefile | 3 +-- arch/xtensa/boot/boot-elf/Makefile | 2 +- scripts/link-vmlinux.sh | 4 ++++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index ea283c9bbaa8..ebf4d3ce492c 100644 --- a/Makefile +++ b/Makefile @@ -1100,7 +1100,6 @@ KBUILD_VMLINUX_OBJS += $(patsubst %/,%/built-in.a, $(drivers-y)) export KBUILD_VMLINUX_OBJS KBUILD_VMLINUX_LIBS export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds -export LDFLAGS_vmlinux # used by scripts/Makefile.package export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) LICENSES arch include scripts tools) @@ -1132,7 +1131,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) # Final link of vmlinux with optional arch pass after final link cmd_link-vmlinux = \ - $(CONFIG_SHELL) $< $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_vmlinux) ; \ + $(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index 12ae1e91cb75..a62a25506536 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile @@ -25,7 +25,7 @@ $(obj)/Image.o: vmlinux.bin $(OBJS) $(OBJS) $@ $(obj)/../Image.elf: $(obj)/Image.o $(obj)/boot.lds - $(Q)$(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_vmlinux) \ + $(Q)$(LD) $(KBUILD_LDFLAGS) \ -T $(obj)/boot.lds \ --build-id=none \ -o $@ $(obj)/Image.o diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 92dd745906f4..68e7de2dbe90 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -30,6 +30,10 @@ # Error out on error set -e +LD="$1" +KBUILD_LDFLAGS="$2" +LDFLAGS_vmlinux="$3" + # Nice output in kbuild format # Will be supressed by "make -s" info() From 15d5761ad31dfb194ebe76554e6af0437eb20424 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 7 Jul 2020 18:21:16 +0900 Subject: [PATCH 234/242] kbuild: introduce ccflags-remove-y and asflags-remove-y CFLAGS_REMOVE_.o filters out flags when compiling a particular object, but there is no convenient way to do that for every object in a directory. Add ccflags-remove-y and asflags-remove-y to make it easily. Use ccflags-remove-y to clean up some Makefiles. The add/remove order works as follows: [1] KBUILD_CFLAGS specifies compiler flags used globally [2] ccflags-y adds compiler flags for all objects in the current Makefile [3] ccflags-remove-y removes compiler flags for all objects in the current Makefile (New feature) [4] CFLAGS_ adds compiler flags per file. [5] CFLAGS_REMOVE_ removes compiler flags per file. Having [3] before [4] allows us to remove flags from most (but not all) objects in the current Makefile. For example, kernel/trace/Makefile removes $(CC_FLAGS_FTRACE) from all objects in the directory, then adds it back to trace_selftest_dynamic.o and CFLAGS_trace_kprobe_selftest.o The same applies to lib/livepatch/Makefile. Please note ccflags-remove-y has no effect to the sub-directories. In contrast, the previous notation got rid of compiler flags also from all the sub-directories. The following are not affected because they have no sub-directories: arch/arm/boot/compressed/ arch/powerpc/xmon/ arch/sh/ kernel/trace/ However, lib/ has several sub-directories. To keep the behavior, I added ccflags-remove-y to all Makefiles in subdirectories of lib/, except the following: lib/vdso/Makefile - Kbuild does not descend into this Makefile lib/raid/test/Makefile - This is not used for the kernel build I think commit 2464a609ded0 ("ftrace: do not trace library functions") excluded too much. In the next commit, I will remove ccflags-remove-y from the sub-directories of lib/. Suggested-by: Sami Tolvanen Signed-off-by: Masahiro Yamada Acked-by: Steven Rostedt (VMware) Acked-by: Michael Ellerman (powerpc) Acked-by: Brendan Higgins (KUnit) Tested-by: Anders Roxell --- Documentation/kbuild/makefiles.rst | 14 ++++++++++++++ arch/arm/boot/compressed/Makefile | 6 +----- arch/powerpc/xmon/Makefile | 3 +-- arch/sh/boot/compressed/Makefile | 5 +---- kernel/trace/Makefile | 4 ++-- lib/842/Makefile | 3 +++ lib/Makefile | 5 +---- lib/crypto/Makefile | 2 ++ lib/dim/Makefile | 2 ++ lib/fonts/Makefile | 2 ++ lib/kunit/Makefile | 3 +++ lib/livepatch/Makefile | 2 ++ lib/lz4/Makefile | 1 + lib/lzo/Makefile | 2 ++ lib/math/Makefile | 2 ++ lib/mpi/Makefile | 2 ++ lib/raid6/Makefile | 3 +++ lib/reed_solomon/Makefile | 2 ++ lib/xz/Makefile | 3 +++ lib/zlib_deflate/Makefile | 2 ++ lib/zlib_dfltcc/Makefile | 2 ++ lib/zlib_inflate/Makefile | 2 ++ lib/zstd/Makefile | 1 + scripts/Makefile.lib | 14 ++++++++------ 24 files changed, 64 insertions(+), 23 deletions(-) diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 6515ebc12b6f..14d8e7d23c04 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -368,6 +368,14 @@ more details, with real examples. subdir-ccflags-y := -Werror + ccflags-remove-y, asflags-remove-y + These flags are used to remove particular flags for the compiler, + assembler invocations. + + Example:: + + ccflags-remove-$(CONFIG_MCOUNT) += -pg + CFLAGS_$@, AFLAGS_$@ CFLAGS_$@ and AFLAGS_$@ only apply to commands in current kbuild makefile. @@ -375,6 +383,9 @@ more details, with real examples. $(CFLAGS_$@) specifies per-file options for $(CC). The $@ part has a literal value which specifies the file that it is for. + CFLAGS_$@ has the higher priority than ccflags-remove-y; CFLAGS_$@ + can re-add compiler flags that were removed by ccflags-remove-y. + Example:: # drivers/scsi/Makefile @@ -387,6 +398,9 @@ more details, with real examples. $(AFLAGS_$@) is a similar feature for source files in assembly languages. + AFLAGS_$@ has the higher priority than asflags-remove-y; AFLAGS_$@ + can re-add assembler flags that were removed by asflags-remove-y. + Example:: # arch/arm/kernel/Makefile diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index cb7a56c6723c..b1147b7f2c8d 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -102,13 +102,9 @@ clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S hyp-stub.S KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING -ifeq ($(CONFIG_FUNCTION_TRACER),y) -ORIG_CFLAGS := $(KBUILD_CFLAGS) -KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) -endif - ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \ -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += -pg asflags-y := -DZIMAGE # Supply kernel BSS size to the decompressor via a linker symbol. diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 89c76ca35640..eb25d7554ffd 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -7,8 +7,7 @@ UBSAN_SANITIZE := n KASAN_SANITIZE := n # Disable ftrace for the entire directory -ORIG_CFLAGS := $(KBUILD_CFLAGS) -KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS)) +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) ifdef CONFIG_CC_IS_CLANG # clang stores addresses on the stack causing the frame size to blow diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index ad0e2403e56f..589d2d8a573d 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -28,10 +28,7 @@ IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \ $(CONFIG_BOOT_LINK_OFFSET)]') endif -ifeq ($(CONFIG_MCOUNT),y) -ORIG_CFLAGS := $(KBUILD_CFLAGS) -KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) -endif +ccflags-remove-$(CONFIG_MCOUNT) += -pg LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(IMAGE_OFFSET) -e startup \ -T $(obj)/../../kernel/vmlinux.lds diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 6575bb0a0434..7492844a8b1b 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -2,9 +2,9 @@ # Do not instrument the tracer itself: +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + ifdef CONFIG_FUNCTION_TRACER -ORIG_CFLAGS := $(KBUILD_CFLAGS) -KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS)) # Avoid recursion due to instrumentation. KCSAN_SANITIZE := n diff --git a/lib/842/Makefile b/lib/842/Makefile index 6f7aad269288..b815e824ae37 100644 --- a/lib/842/Makefile +++ b/lib/842/Makefile @@ -1,3 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only + +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_842_COMPRESS) += 842_compress.o obj-$(CONFIG_842_DECOMPRESS) += 842_decompress.o diff --git a/lib/Makefile b/lib/Makefile index 0cda70649f1c..233f6e644eeb 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -3,10 +3,7 @@ # Makefile for some libs needed in the kernel. # -ifdef CONFIG_FUNCTION_TRACER -ORIG_CFLAGS := $(KBUILD_CFLAGS) -KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS)) -endif +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) # These files are disabled because they produce lots of non-interesting and/or # flaky coverage that is not a function of syscall inputs. For example, diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index 3a435629d9ce..b557ef0b07c2 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + # chacha is used by the /dev/random driver which is always builtin obj-y += chacha.o obj-$(CONFIG_CRYPTO_LIB_CHACHA_GENERIC) += libchacha.o diff --git a/lib/dim/Makefile b/lib/dim/Makefile index 1d6858a108cb..97fc3e89d34e 100644 --- a/lib/dim/Makefile +++ b/lib/dim/Makefile @@ -2,6 +2,8 @@ # DIM Dynamic Interrupt Moderation library # +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_DIMLIB) += dim.o dim-y := dim.o net_dim.o rdma_dim.o diff --git a/lib/fonts/Makefile b/lib/fonts/Makefile index ed95070860de..f951750c179e 100644 --- a/lib/fonts/Makefile +++ b/lib/fonts/Makefile @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # Font handling +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + font-objs := fonts.o font-objs-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile index 724b94311ca3..8c847557ab24 100644 --- a/lib/kunit/Makefile +++ b/lib/kunit/Makefile @@ -1,3 +1,6 @@ + +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_KUNIT) += kunit.o kunit-objs += test.o \ diff --git a/lib/livepatch/Makefile b/lib/livepatch/Makefile index 295b94bff370..9abdf615b088 100644 --- a/lib/livepatch/Makefile +++ b/lib/livepatch/Makefile @@ -2,6 +2,8 @@ # # Makefile for livepatch test code. +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_TEST_LIVEPATCH) += test_klp_atomic_replace.o \ test_klp_callbacks_demo.o \ test_klp_callbacks_demo2.o \ diff --git a/lib/lz4/Makefile b/lib/lz4/Makefile index 5b42242afaa2..53da4cab7015 100644 --- a/lib/lz4/Makefile +++ b/lib/lz4/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only ccflags-y += -O3 +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) obj-$(CONFIG_LZ4_COMPRESS) += lz4_compress.o obj-$(CONFIG_LZ4HC_COMPRESS) += lz4hc_compress.o diff --git a/lib/lzo/Makefile b/lib/lzo/Makefile index 2f58fafbbddd..9565a555275b 100644 --- a/lib/lzo/Makefile +++ b/lib/lzo/Makefile @@ -1,4 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + lzo_compress-objs := lzo1x_compress.o lzo_decompress-objs := lzo1x_decompress_safe.o diff --git a/lib/math/Makefile b/lib/math/Makefile index be6909e943bd..49aa50e28185 100644 --- a/lib/math/Makefile +++ b/lib/math/Makefile @@ -1,4 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-y += div64.o gcd.o lcm.o int_pow.o int_sqrt.o reciprocal_div.o obj-$(CONFIG_CORDIC) += cordic.o diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile index d5874a7f5ff9..df7883521619 100644 --- a/lib/mpi/Makefile +++ b/lib/mpi/Makefile @@ -3,6 +3,8 @@ # MPI multiprecision maths library (from gpg) # +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_MPILIB) = mpi.o mpi-y = \ diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile index b4c0df6d706d..3482d6ae3f3b 100644 --- a/lib/raid6/Makefile +++ b/lib/raid6/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_RAID6_PQ) += raid6_pq.o raid6_pq-y += algos.o recov.o tables.o int1.o int2.o int4.o \ diff --git a/lib/reed_solomon/Makefile b/lib/reed_solomon/Makefile index 5d4fa68f26cb..a5c9defdac7f 100644 --- a/lib/reed_solomon/Makefile +++ b/lib/reed_solomon/Makefile @@ -3,5 +3,7 @@ # This is a modified version of reed solomon lib, # +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_REED_SOLOMON) += reed_solomon.o obj-$(CONFIG_REED_SOLOMON_TEST) += test_rslib.o diff --git a/lib/xz/Makefile b/lib/xz/Makefile index fa6af814a8d1..fae9b6c7c389 100644 --- a/lib/xz/Makefile +++ b/lib/xz/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_XZ_DEC) += xz_dec.o xz_dec-y := xz_dec_syms.o xz_dec_stream.o xz_dec_lzma2.o xz_dec-$(CONFIG_XZ_DEC_BCJ) += xz_dec_bcj.o diff --git a/lib/zlib_deflate/Makefile b/lib/zlib_deflate/Makefile index 2622e03c0b94..1fcefe73536f 100644 --- a/lib/zlib_deflate/Makefile +++ b/lib/zlib_deflate/Makefile @@ -7,6 +7,8 @@ # decompression code. # +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate.o zlib_deflate-objs := deflate.o deftree.o deflate_syms.o diff --git a/lib/zlib_dfltcc/Makefile b/lib/zlib_dfltcc/Makefile index 8e4d5afbbb10..7a8067f6e772 100644 --- a/lib/zlib_dfltcc/Makefile +++ b/lib/zlib_dfltcc/Makefile @@ -6,6 +6,8 @@ # This is the code for s390 zlib hardware support. # +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc.o zlib_dfltcc-objs := dfltcc.o dfltcc_deflate.o dfltcc_inflate.o dfltcc_syms.o diff --git a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile index 27327d3e9f54..a451e96f9845 100644 --- a/lib/zlib_inflate/Makefile +++ b/lib/zlib_inflate/Makefile @@ -14,6 +14,8 @@ # uncompression can be done without blocking on allocation). # +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) + obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o zlib_inflate-objs := inffast.o inflate.o infutil.o \ diff --git a/lib/zstd/Makefile b/lib/zstd/Makefile index f5d778e7e5c7..01be908a2d94 100644 --- a/lib/zstd/Makefile +++ b/lib/zstd/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o ccflags-y += -O3 +ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) zstd_compress-y := fse_compress.o huf_compress.o compress.o \ entropy_common.o fse_decompress.o zstd_common.o diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 8fa9aa2c9fca..5cfd377778b4 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -111,12 +111,14 @@ basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile)) -orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ - $(ccflags-y) $(CFLAGS_$(target-stem).o) -_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), $(orig_c_flags)) -orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \ - $(asflags-y) $(AFLAGS_$(target-stem).o) -_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), $(orig_a_flags)) +_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(ccflags-remove-y), \ + $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \ + $(CFLAGS_$(target-stem).o)) +_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(asflags-remove-y), \ + $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \ + $(AFLAGS_$(target-stem).o)) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds) # From b16838c608ef97c29896518117c30a2aa3931fac Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 7 Jul 2020 18:21:17 +0900 Subject: [PATCH 235/242] kbuild: trace functions in subdirectories of lib/ ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) exists here in sub-directories of lib/ to keep the behavior of commit 2464a609ded0 ("ftrace: do not trace library functions"). Since that commit, not only the objects in lib/ but also the ones in the sub-directories are excluded from ftrace (although the commit description did not explicitly mention this). However, most of library functions in sub-directories are not so hot. Re-add them to ftrace. Going forward, only the objects right under lib/ will be excluded. Cc: Ingo Molnar Signed-off-by: Masahiro Yamada Acked-by: Steven Rostedt (VMware) --- lib/842/Makefile | 3 --- lib/crypto/Makefile | 2 -- lib/dim/Makefile | 2 -- lib/fonts/Makefile | 2 -- lib/kunit/Makefile | 3 --- lib/livepatch/Makefile | 6 ------ lib/lz4/Makefile | 1 - lib/lzo/Makefile | 2 -- lib/math/Makefile | 2 -- lib/mpi/Makefile | 2 -- lib/raid6/Makefile | 3 --- lib/reed_solomon/Makefile | 2 -- lib/xz/Makefile | 3 --- lib/zlib_deflate/Makefile | 2 -- lib/zlib_dfltcc/Makefile | 2 -- lib/zlib_inflate/Makefile | 2 -- lib/zstd/Makefile | 1 - 17 files changed, 40 deletions(-) diff --git a/lib/842/Makefile b/lib/842/Makefile index b815e824ae37..6f7aad269288 100644 --- a/lib/842/Makefile +++ b/lib/842/Makefile @@ -1,6 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only - -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_842_COMPRESS) += 842_compress.o obj-$(CONFIG_842_DECOMPRESS) += 842_decompress.o diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index b557ef0b07c2..3a435629d9ce 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - # chacha is used by the /dev/random driver which is always builtin obj-y += chacha.o obj-$(CONFIG_CRYPTO_LIB_CHACHA_GENERIC) += libchacha.o diff --git a/lib/dim/Makefile b/lib/dim/Makefile index 97fc3e89d34e..1d6858a108cb 100644 --- a/lib/dim/Makefile +++ b/lib/dim/Makefile @@ -2,8 +2,6 @@ # DIM Dynamic Interrupt Moderation library # -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_DIMLIB) += dim.o dim-y := dim.o net_dim.o rdma_dim.o diff --git a/lib/fonts/Makefile b/lib/fonts/Makefile index f951750c179e..ed95070860de 100644 --- a/lib/fonts/Makefile +++ b/lib/fonts/Makefile @@ -1,8 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 # Font handling -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - font-objs := fonts.o font-objs-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile index 8c847557ab24..724b94311ca3 100644 --- a/lib/kunit/Makefile +++ b/lib/kunit/Makefile @@ -1,6 +1,3 @@ - -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_KUNIT) += kunit.o kunit-objs += test.o \ diff --git a/lib/livepatch/Makefile b/lib/livepatch/Makefile index 9abdf615b088..dcc912b3478f 100644 --- a/lib/livepatch/Makefile +++ b/lib/livepatch/Makefile @@ -2,8 +2,6 @@ # # Makefile for livepatch test code. -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_TEST_LIVEPATCH) += test_klp_atomic_replace.o \ test_klp_callbacks_demo.o \ test_klp_callbacks_demo2.o \ @@ -14,7 +12,3 @@ obj-$(CONFIG_TEST_LIVEPATCH) += test_klp_atomic_replace.o \ test_klp_state.o \ test_klp_state2.o \ test_klp_state3.o - -# Target modules to be livepatched require CC_FLAGS_FTRACE -CFLAGS_test_klp_callbacks_busy.o += $(CC_FLAGS_FTRACE) -CFLAGS_test_klp_callbacks_mod.o += $(CC_FLAGS_FTRACE) diff --git a/lib/lz4/Makefile b/lib/lz4/Makefile index 53da4cab7015..5b42242afaa2 100644 --- a/lib/lz4/Makefile +++ b/lib/lz4/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only ccflags-y += -O3 -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) obj-$(CONFIG_LZ4_COMPRESS) += lz4_compress.o obj-$(CONFIG_LZ4HC_COMPRESS) += lz4hc_compress.o diff --git a/lib/lzo/Makefile b/lib/lzo/Makefile index 9565a555275b..2f58fafbbddd 100644 --- a/lib/lzo/Makefile +++ b/lib/lzo/Makefile @@ -1,6 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - lzo_compress-objs := lzo1x_compress.o lzo_decompress-objs := lzo1x_decompress_safe.o diff --git a/lib/math/Makefile b/lib/math/Makefile index 49aa50e28185..be6909e943bd 100644 --- a/lib/math/Makefile +++ b/lib/math/Makefile @@ -1,6 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-y += div64.o gcd.o lcm.o int_pow.o int_sqrt.o reciprocal_div.o obj-$(CONFIG_CORDIC) += cordic.o diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile index df7883521619..d5874a7f5ff9 100644 --- a/lib/mpi/Makefile +++ b/lib/mpi/Makefile @@ -3,8 +3,6 @@ # MPI multiprecision maths library (from gpg) # -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_MPILIB) = mpi.o mpi-y = \ diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile index 3482d6ae3f3b..b4c0df6d706d 100644 --- a/lib/raid6/Makefile +++ b/lib/raid6/Makefile @@ -1,7 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 - -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_RAID6_PQ) += raid6_pq.o raid6_pq-y += algos.o recov.o tables.o int1.o int2.o int4.o \ diff --git a/lib/reed_solomon/Makefile b/lib/reed_solomon/Makefile index a5c9defdac7f..5d4fa68f26cb 100644 --- a/lib/reed_solomon/Makefile +++ b/lib/reed_solomon/Makefile @@ -3,7 +3,5 @@ # This is a modified version of reed solomon lib, # -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_REED_SOLOMON) += reed_solomon.o obj-$(CONFIG_REED_SOLOMON_TEST) += test_rslib.o diff --git a/lib/xz/Makefile b/lib/xz/Makefile index fae9b6c7c389..fa6af814a8d1 100644 --- a/lib/xz/Makefile +++ b/lib/xz/Makefile @@ -1,7 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only - -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_XZ_DEC) += xz_dec.o xz_dec-y := xz_dec_syms.o xz_dec_stream.o xz_dec_lzma2.o xz_dec-$(CONFIG_XZ_DEC_BCJ) += xz_dec_bcj.o diff --git a/lib/zlib_deflate/Makefile b/lib/zlib_deflate/Makefile index 1fcefe73536f..2622e03c0b94 100644 --- a/lib/zlib_deflate/Makefile +++ b/lib/zlib_deflate/Makefile @@ -7,8 +7,6 @@ # decompression code. # -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate.o zlib_deflate-objs := deflate.o deftree.o deflate_syms.o diff --git a/lib/zlib_dfltcc/Makefile b/lib/zlib_dfltcc/Makefile index 7a8067f6e772..8e4d5afbbb10 100644 --- a/lib/zlib_dfltcc/Makefile +++ b/lib/zlib_dfltcc/Makefile @@ -6,8 +6,6 @@ # This is the code for s390 zlib hardware support. # -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc.o zlib_dfltcc-objs := dfltcc.o dfltcc_deflate.o dfltcc_inflate.o dfltcc_syms.o diff --git a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile index a451e96f9845..27327d3e9f54 100644 --- a/lib/zlib_inflate/Makefile +++ b/lib/zlib_inflate/Makefile @@ -14,8 +14,6 @@ # uncompression can be done without blocking on allocation). # -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) - obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o zlib_inflate-objs := inffast.o inflate.o infutil.o \ diff --git a/lib/zstd/Makefile b/lib/zstd/Makefile index 01be908a2d94..f5d778e7e5c7 100644 --- a/lib/zstd/Makefile +++ b/lib/zstd/Makefile @@ -3,7 +3,6 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o ccflags-y += -O3 -ccflags-remove-$(CONFIG_FUNCTION_TRACER) += $(CC_FLAGS_FTRACE) zstd_compress-y := fse_compress.o huf_compress.o compress.o \ entropy_common.o fse_decompress.o zstd_common.o From 16a122c743b327f714606eff2cd8ff31c206bafc Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Sun, 19 Jul 2020 21:46:02 +0200 Subject: [PATCH 236/242] kbuild: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Signed-off-by: Masahiro Yamada --- Documentation/kbuild/Kconfig.recursion-issue-02 | 2 +- Documentation/kbuild/kconfig-language.rst | 14 +++++++------- Documentation/kbuild/llvm.rst | 2 +- scripts/package/mkdebian | 2 +- scripts/package/mkspec | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Documentation/kbuild/Kconfig.recursion-issue-02 b/Documentation/kbuild/Kconfig.recursion-issue-02 index b9fd56c4b57e..df245fd7670d 100644 --- a/Documentation/kbuild/Kconfig.recursion-issue-02 +++ b/Documentation/kbuild/Kconfig.recursion-issue-02 @@ -42,7 +42,7 @@ # "select FW_LOADER" [0], in the end the simple alternative solution to this # problem consisted on matching semantics with newly introduced features. # -# [0] http://lkml.kernel.org/r/1432241149-8762-1-git-send-email-mcgrof@do-not-panic.com +# [0] https://lkml.kernel.org/r/1432241149-8762-1-git-send-email-mcgrof@do-not-panic.com mainmenu "Simple example to demo cumulative kconfig recursive dependency implication" diff --git a/Documentation/kbuild/kconfig-language.rst b/Documentation/kbuild/kconfig-language.rst index 2538e7cb08e6..d918c7ed7336 100644 --- a/Documentation/kbuild/kconfig-language.rst +++ b/Documentation/kbuild/kconfig-language.rst @@ -688,10 +688,10 @@ and real world requirements were not well understood. As it stands though only reverse engineering techniques have been used to deduce semantics from variability modeling languages such as Kconfig [3]_. -.. [0] http://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf -.. [1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf -.. [2] http://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf -.. [3] http://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf +.. [0] https://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf +.. [1] https://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf +.. [2] https://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf +.. [3] https://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf Full SAT solver for Kconfig ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -710,10 +710,10 @@ such efforts somehow on Kconfig. There is enough interest from mentors of existing projects to not only help advise how to integrate this work upstream but also help maintain it long term. Interested developers should visit: -http://kernelnewbies.org/KernelProjects/kconfig-sat +https://kernelnewbies.org/KernelProjects/kconfig-sat -.. [4] http://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf -.. [5] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf +.. [4] https://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf +.. [5] https://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf .. [6] https://cados.cs.fau.de .. [7] https://vamos.cs.fau.de .. [8] https://undertaker.cs.fau.de diff --git a/Documentation/kbuild/llvm.rst b/Documentation/kbuild/llvm.rst index c776b6eee969..2aac50b97921 100644 --- a/Documentation/kbuild/llvm.rst +++ b/Documentation/kbuild/llvm.rst @@ -76,7 +76,7 @@ Getting Help Getting LLVM ------------- -- http://releases.llvm.org/download.html +- https://releases.llvm.org/download.html - https://github.com/llvm/llvm-project - https://llvm.org/docs/GettingStarted.html - https://llvm.org/docs/CMake.html diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index df1adbfb8ead..48fbd3d0284a 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -175,7 +175,7 @@ Section: kernel Priority: optional Maintainer: $maintainer Build-Depends: bc, rsync, kmod, cpio, bison, flex | flex:native $extra_build_depends -Homepage: http://www.kernel.org/ +Homepage: https://www.kernel.org/ Package: $packagename Architecture: $debarch diff --git a/scripts/package/mkspec b/scripts/package/mkspec index 8640c278f1aa..7c477ca7dc98 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -46,7 +46,7 @@ sed -e '/^DEL/d' -e 's/^\t*//' < Date: Wed, 29 Jul 2020 12:15:36 +0900 Subject: [PATCH 237/242] kbuild: move host .so build rules to scripts/gcc-plugins/Makefile The host shared library rules are currently implemented in scripts/Makefile.host, but actually GCC-plugin is the only user of them. (The VDSO .so files are built for the target by different build rules) Hence, they do not need to be treewide available. Move all the relevant build rules to scripts/gcc-plugins/Makefile. I also optimized the build steps so *.so is directly built from .c because every upstream plugin is compiled from a single source file. I am still keeping the multi-file plugin support, which Kees Cook mentioned might be needed by out-of-tree plugins. (https://lkml.org/lkml/2019/1/11/1107) If the plugin, foo.so, is compiled from two files foo.c and foo2.c, then you can do like follows: foo-objs := foo.o foo2.o Single-file plugins do not need the *-objs notation. Signed-off-by: Masahiro Yamada Acked-by: Kees Cook --- scripts/Makefile.build | 4 +-- scripts/Makefile.clean | 3 +- scripts/Makefile.host | 30 ++---------------- scripts/gcc-plugins/Makefile | 61 +++++++++++++++++++++++++++++------- 4 files changed, 55 insertions(+), 43 deletions(-) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 246426fa1282..d54adf0dcf39 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -45,8 +45,8 @@ include $(kbuild-file) include scripts/Makefile.lib -# Do not include host rules unless needed -ifneq ($(hostprogs)$(hostcxxlibs-y)$(hostcxxlibs-m),) +# Do not include hostprogs rules unless needed +ifneq ($(hostprogs),) include scripts/Makefile.host endif diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index e2c76122319d..3cdf31218198 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -29,8 +29,7 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn)) __clean-files := $(extra-y) $(extra-m) $(extra-) \ $(always) $(always-y) $(always-m) $(always-) $(targets) $(clean-files) \ - $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) $(userprogs) \ - $(hostcxxlibs-y) $(hostcxxlibs-m) + $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) $(userprogs) __clean-files := $(filter-out $(no-clean-files), $(__clean-files)) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index c8a4a033dc3e..687ca3f309e9 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -39,7 +39,6 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE # They are linked as C++ code to the executable qconf __hostprogs := $(sort $(hostprogs)) -host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m)) # C code # Executables compiled from a single .c file @@ -61,16 +60,11 @@ host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m))) # C++ Object (.o) files compiled from .cc files host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) -# Object (.o) files used by the shared libaries -host-cxxshobjs := $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs)))) - host-csingle := $(addprefix $(obj)/,$(host-csingle)) host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) -host-cxxshlib := $(addprefix $(obj)/,$(host-cxxshlib)) -host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs)) ##### # Handle options to gcc. Support building with separate output directory @@ -136,25 +130,5 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@ $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE $(call if_changed_dep,host-cxxobjs) -# Compile .c file, create position independent .o file -# Note that plugin capable gcc versions can be either C or C++ based -# therefore plugin source files have to be compilable in both C and C++ mode. -# This is why a C++ compiler is invoked on a .c file. -# host-cxxshobjs -> .o -quiet_cmd_host-cxxshobjs = HOSTCXX -fPIC $@ - cmd_host-cxxshobjs = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $< -$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE - $(call if_changed_dep,host-cxxshobjs) - -# Link a shared library, based on position independent .o files -# *.o -> .so shared library (host-cxxshlib) -quiet_cmd_host-cxxshlib = HOSTLLD -shared $@ - cmd_host-cxxshlib = $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -shared -o $@ \ - $(addprefix $(obj)/, $($(target-stem)-objs)) \ - $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem).so) -$(host-cxxshlib): FORCE - $(call if_changed,host-cxxshlib) -$(call multi_depend, $(host-cxxshlib), .so, -objs) - -targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\ - $(host-cxxmulti) $(host-cxxobjs) $(host-cxxshlib) $(host-cxxshobjs) +targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \ + $(host-cxxmulti) $(host-cxxobjs) diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile index 4014ba7e2fbd..d66949bfeba4 100644 --- a/scripts/gcc-plugins/Makefile +++ b/scripts/gcc-plugins/Makefile @@ -1,22 +1,61 @@ # SPDX-License-Identifier: GPL-2.0 -GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin) -HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) -std=gnu++98 -fno-rtti -HOST_EXTRACXXFLAGS += -fno-exceptions -fasynchronous-unwind-tables -ggdb -HOST_EXTRACXXFLAGS += -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat -HOST_EXTRACXXFLAGS += -Wno-format-diag - -$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h +$(obj)/randomize_layout_plugin.so: $(objtree)/$(obj)/randomize_layout_seed.h quiet_cmd_create_randomize_layout_seed = GENSEED $@ cmd_create_randomize_layout_seed = \ $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h $(objtree)/$(obj)/randomize_layout_seed.h: FORCE $(call if_changed,create_randomize_layout_seed) -targets = randomize_layout_seed.h randomize_layout_hash.h +targets += randomize_layout_seed.h randomize_layout_hash.h -hostcxxlibs-y := $(GCC_PLUGIN) -always-y := $(hostcxxlibs-y) +# Build rules for plugins +# +# No extra code is needed for single-file plugins. +# For multi-file plugins, use *-objs syntax to list the objects. +# +# If the plugin foo.so is compiled from foo.c and foo2.c, you can do: +# +# foo-objs := foo.o foo2.o -$(foreach p,$(hostcxxlibs-y:%.so=%),$(eval $(p)-objs := $(p).o)) +always-y += $(GCC_PLUGIN) +GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin) + +plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \ + -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++98 \ + -fno-rtti -fno-exceptions -fasynchronous-unwind-tables \ + -ggdb -Wno-narrowing -Wno-unused-variable -Wno-c++11-compat \ + -Wno-format-diag + +plugin_ldflags = -shared + +plugin-single := $(foreach m, $(GCC_PLUGIN), $(if $($(m:%.so=%-objs)),,$(m))) +plugin-multi := $(filter-out $(plugin-single), $(GCC_PLUGIN)) +plugin-objs := $(sort $(foreach m, $(plugin-multi), $($(m:%.so=%-objs)))) + +targets += $(plugin-single) $(plugin-multi) $(plugin-objs) clean-files += *.so + +plugin-single := $(addprefix $(obj)/, $(plugin-single)) +plugin-multi := $(addprefix $(obj)/, $(plugin-multi)) +plugin-objs := $(addprefix $(obj)/, $(plugin-objs)) + +quiet_cmd_plugin_cxx_so_c = HOSTCXX $@ + cmd_plugin_cxx_so_c = $(HOSTCXX) $(plugin_cxxflags) $(plugin_ldflags) -o $@ $< + +$(plugin-single): $(obj)/%.so: $(src)/%.c FORCE + $(call if_changed_dep,plugin_cxx_so_c) + +quiet_cmd_plugin_ld_so_o = HOSTLD $@ + cmd_plugin_ld_so_o = $(HOSTCXX) $(plugin_ldflags) -o $@ \ + $(addprefix $(obj)/, $($(target-stem)-objs)) + +$(plugin-multi): FORCE + $(call if_changed,plugin_ld_so_o) +$(foreach m, $(notdir $(plugin-multi)), $(eval $(obj)/$m: $(addprefix $(obj)/, $($(m:%.so=%-objs))))) + +quiet_cmd_plugin_cxx_o_c = HOSTCXX $@ + cmd_plugin_cxx_o_c = $(HOSTCXX) $(plugin_cxxflags) -c -o $@ $< + +$(plugin-objs): $(obj)/%.o: $(src)/%.c FORCE + $(call if_changed_dep,plugin_cxx_o_c) From 85569d19d0f57df5e6cbb918dbddd4f82c0117b5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 29 Jul 2020 12:15:37 +0900 Subject: [PATCH 238/242] kbuild: sort hostprogs before passing it to ifneq The conditional: ifneq ($(hostprogs),) ... is evaluated to true if $(hostprogs) does not contain any word but whitespace characters. ifneq ($(strip $(hostprogs)),) ... is a safe way to avoid interpreting whitespace as a non-empty value, but I'd rather want to use the side-effect of $(sort ...) to do the equivalent. $(sort ...) is used in scripts/Makefile.host in order to drop duplication in $(hostprogs). It is also useful to strip excessive spaces. Move $(sort ...) before evaluating the ifneq. Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 5 ++++- scripts/Makefile.host | 10 ++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index d54adf0dcf39..a467b9323442 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -45,12 +45,15 @@ include $(kbuild-file) include scripts/Makefile.lib -# Do not include hostprogs rules unless needed +# Do not include hostprogs rules unless needed. +# $(sort ...) is used here to remove duplicated words and excessive spaces. +hostprogs := $(sort $(hostprogs)) ifneq ($(hostprogs),) include scripts/Makefile.host endif # Do not include userprogs rules unless needed. +# $(sort ...) is used here to remove duplicated words and excessive spaces. userprogs := $(sort $(userprogs)) ifneq ($(userprogs),) include scripts/Makefile.userprogs diff --git a/scripts/Makefile.host b/scripts/Makefile.host index 687ca3f309e9..278b4d6ac945 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -38,24 +38,22 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE # Will compile qconf as a C++ program, and menu as a C program. # They are linked as C++ code to the executable qconf -__hostprogs := $(sort $(hostprogs)) - # C code # Executables compiled from a single .c file -host-csingle := $(foreach m,$(__hostprogs), \ +host-csingle := $(foreach m,$(hostprogs), \ $(if $($(m)-objs)$($(m)-cxxobjs),,$(m))) # C executables linked based on several .o files -host-cmulti := $(foreach m,$(__hostprogs),\ +host-cmulti := $(foreach m,$(hostprogs),\ $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) # Object (.o) files compiled from .c files -host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs))) +host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs))) # C++ code # C++ executables compiled from at least one .cc file # and zero or more .c files -host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m))) +host-cxxmulti := $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m))) # C++ Object (.o) files compiled from .cc files host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) From faabed295cccc2aba2b67f2e7b309f2892d55004 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 1 Aug 2020 21:27:18 +0900 Subject: [PATCH 239/242] kbuild: introduce hostprogs-always-y and userprogs-always-y To build host programs, you need to add the program names to 'hostprogs' to use the necessary build rule, but it is not enough to build them because there is no dependency. There are two types of host programs: built as the prerequisite of another (e.g. gen_crc32table in lib/Makefile), or always built when Kbuild visits the Makefile (e.g. genksyms in scripts/genksyms/Makefile). The latter is typical in Makefiles under scripts/, which contains host programs globally used during the kernel build. To build them, you need to add them to both 'hostprogs' and 'always-y'. This commit adds hostprogs-always-y as a shorthand. The same applies to user programs. net/bpfilter/Makefile builds bpfilter_umh on demand, hence always-y is unneeded. In contrast, programs under samples/ are added to both 'userprogs' and 'always-y' so they are always built when Kbuild visits the Makefiles. userprogs-always-y works as a shorthand. Signed-off-by: Masahiro Yamada Acked-by: Miguel Ojeda --- Documentation/kbuild/makefiles.rst | 31 ++++++++++++++++++++++++++++- samples/auxdisplay/Makefile | 3 +-- samples/binderfs/Makefile | 3 +-- samples/connector/Makefile | 3 +-- samples/hidraw/Makefile | 3 +-- samples/mei/Makefile | 4 +--- samples/pidfd/Makefile | 4 +--- samples/seccomp/Makefile | 4 +--- samples/timers/Makefile | 3 +-- samples/uhid/Makefile | 3 +-- samples/vfs/Makefile | 3 +-- samples/watch_queue/Makefile | 3 +-- samples/watchdog/Makefile | 3 +-- scripts/Makefile | 18 ++++++++--------- scripts/Makefile.clean | 12 ++++++++--- scripts/Makefile.lib | 11 ++++++++++ scripts/basic/Makefile | 3 +-- scripts/dtc/Makefile | 5 ++--- scripts/genksyms/Makefile | 3 +-- scripts/mod/Makefile | 4 ++-- scripts/selinux/genheaders/Makefile | 4 +--- scripts/selinux/mdp/Makefile | 3 +-- 22 files changed, 78 insertions(+), 55 deletions(-) diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 14d8e7d23c04..b81b8913a5a3 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -749,6 +749,10 @@ Both possibilities are described in the following. hostprogs := lxdialog always-y := $(hostprogs) + Kbuild provides the following shorthand for this: + + hostprogs-always-y := lxdialog + This will tell kbuild to build lxdialog even if not referenced in any rule. @@ -831,7 +835,32 @@ The syntax is quite similar. The difference is to use "userprogs" instead of 5.4 When userspace programs are actually built ---------------------------------------------- - Same as "When host programs are actually built". + Kbuild builds userspace programs only when told to do so. + There are two ways to do this. + + (1) Add it as the prerequisite of another file + + Example:: + + #net/bpfilter/Makefile + userprogs := bpfilter_umh + $(obj)/bpfilter_umh_blob.o: $(obj)/bpfilter_umh + + $(obj)/bpfilter_umh is built before $(obj)/bpfilter_umh_blob.o + + (2) Use always-y + + Example:: + + userprogs := binderfs_example + always-y := $(userprogs) + + Kbuild provides the following shorthand for this: + + userprogs-always-y := binderfs_example + + This will tell Kbuild to build binderfs_example when it visits this + Makefile. 6 Kbuild clean infrastructure ============================= diff --git a/samples/auxdisplay/Makefile b/samples/auxdisplay/Makefile index dbdf939af94a..19d5568938c3 100644 --- a/samples/auxdisplay/Makefile +++ b/samples/auxdisplay/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 -userprogs := cfag12864b-example -always-y := $(userprogs) +userprogs-always-y += cfag12864b-example diff --git a/samples/binderfs/Makefile b/samples/binderfs/Makefile index 989e4badaee2..629e43b9b129 100644 --- a/samples/binderfs/Makefile +++ b/samples/binderfs/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -userprogs := binderfs_example -always-y := $(userprogs) +userprogs-always-y += binderfs_example userccflags += -I usr/include diff --git a/samples/connector/Makefile b/samples/connector/Makefile index 50cb40e09a7b..d98a9e047c11 100644 --- a/samples/connector/Makefile +++ b/samples/connector/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_SAMPLE_CONNECTOR) += cn_test.o -userprogs := ucon -always-$(CONFIG_CC_CAN_LINK) := $(userprogs) +userprogs-always-$(CONFIG_CC_CAN_LINK) += ucon userccflags += -I usr/include diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile index d2c77ed60b39..594d989e5486 100644 --- a/samples/hidraw/Makefile +++ b/samples/hidraw/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -userprogs := hid-example -always-y := $(userprogs) +userprogs-always-y += hid-example userccflags += -I usr/include diff --git a/samples/mei/Makefile b/samples/mei/Makefile index 329411f82369..c54b8a0ab04e 100644 --- a/samples/mei/Makefile +++ b/samples/mei/Makefile @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2012-2019, Intel Corporation. All rights reserved. - -userprogs := mei-amt-version -always-y := $(userprogs) +userprogs-always-y += mei-amt-version userccflags += -I usr/include diff --git a/samples/pidfd/Makefile b/samples/pidfd/Makefile index 6e5b67e648c2..9754e2d81f70 100644 --- a/samples/pidfd/Makefile +++ b/samples/pidfd/Makefile @@ -1,6 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 - -usertprogs := pidfd-metadata -always-y := $(userprogs) +usertprogs-always-y += pidfd-metadata userccflags += -I usr/include diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile index 75916c23e416..c85ae0ed8342 100644 --- a/samples/seccomp/Makefile +++ b/samples/seccomp/Makefile @@ -1,8 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -userprogs := bpf-fancy dropper bpf-direct user-trap +userprogs-always-y += bpf-fancy dropper bpf-direct user-trap bpf-fancy-objs := bpf-fancy.o bpf-helper.o userccflags += -I usr/include - -always-y := $(userprogs) diff --git a/samples/timers/Makefile b/samples/timers/Makefile index 15c7ddbc8c51..e6836cdea4e2 100644 --- a/samples/timers/Makefile +++ b/samples/timers/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -userprogs := hpet_example -always-y := $(userprogs) +userprogs-always-y += hpet_example userccflags += -I usr/include diff --git a/samples/uhid/Makefile b/samples/uhid/Makefile index 9e652fc34103..0aa424ec4899 100644 --- a/samples/uhid/Makefile +++ b/samples/uhid/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -userprogs := uhid-example -always-y := $(userprogs) +userprogs-always-y += uhid-example userccflags += -I usr/include diff --git a/samples/vfs/Makefile b/samples/vfs/Makefile index 00b6824f9237..6377a678134a 100644 --- a/samples/vfs/Makefile +++ b/samples/vfs/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -userprogs := test-fsmount test-statx -always-y := $(userprogs) +userprogs-always-y += test-fsmount test-statx userccflags += -I usr/include diff --git a/samples/watch_queue/Makefile b/samples/watch_queue/Makefile index 792b22f593cf..c0db3a6bc524 100644 --- a/samples/watch_queue/Makefile +++ b/samples/watch_queue/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -userprogs := watch_test -always-y := $(userprogs) +userprogs-always-y += watch_test userccflags += -I usr/include diff --git a/samples/watchdog/Makefile b/samples/watchdog/Makefile index 17384cfb387e..ab39d23dc96b 100644 --- a/samples/watchdog/Makefile +++ b/samples/watchdog/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 -userprogs := watchdog-simple -always-y := $(userprogs) +userprogs-always-y += watchdog-simple diff --git a/scripts/Makefile b/scripts/Makefile index 95ecf970c74c..bc018e4b733e 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -3,14 +3,14 @@ # scripts contains sources for various helper programs used throughout # the kernel for the build process. -always-$(CONFIG_BUILD_BIN2C) += bin2c -always-$(CONFIG_KALLSYMS) += kallsyms -always-$(BUILD_C_RECORDMCOUNT) += recordmcount -always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable -always-$(CONFIG_ASN1) += asn1_compiler -always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file -always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert -always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert +hostprogs-always-$(CONFIG_BUILD_BIN2C) += bin2c +hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms +hostprogs-always-$(BUILD_C_RECORDMCOUNT) += recordmcount +hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable +hostprogs-always-$(CONFIG_ASN1) += asn1_compiler +hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file +hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert +hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include @@ -26,8 +26,6 @@ HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED HOSTLDLIBS_sorttable = -lpthread endif -hostprogs := $(always-y) $(always-m) - # The following programs are only built on demand hostprogs += unifdef diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean index 3cdf31218198..d9e0ceace6a6 100644 --- a/scripts/Makefile.clean +++ b/scripts/Makefile.clean @@ -27,9 +27,15 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn)) # build a list of files to remove, usually relative to the current # directory -__clean-files := $(extra-y) $(extra-m) $(extra-) \ - $(always) $(always-y) $(always-m) $(always-) $(targets) $(clean-files) \ - $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) $(userprogs) +__clean-files := \ + $(clean-files) $(targets) $(hostprogs) $(userprogs) \ + $(extra-y) $(extra-m) $(extra-) \ + $(always-y) $(always-m) $(always-) \ + $(hostprogs-always-y) $(hostprogs-always-m) $(hostprogs-always-) \ + $(userprogs-always-y) $(userprogs-always-m) $(userprogs-always-) + +# deprecated +__clean-files += $(always) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) __clean-files := $(filter-out $(no-clean-files), $(__clean-files)) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 5cfd377778b4..841ac038132b 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -68,6 +68,17 @@ real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) always-y += $(always-m) +# hostprogs-always-y += foo +# ... is a shorthand for +# hostprogs += foo +# always-y += foo +hostprogs += $(hostprogs-always-y) $(hostprogs-always-m) +always-y += $(hostprogs-always-y) $(hostprogs-always-m) + +# userprogs-always-y is likewise. +userprogs += $(userprogs-always-y) $(userprogs-always-m) +always-y += $(userprogs-always-y) $(userprogs-always-m) + # DTB # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built extra-y += $(dtb-y) diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile index 290dd27d2809..eeb6a38c5551 100644 --- a/scripts/basic/Makefile +++ b/scripts/basic/Makefile @@ -2,5 +2,4 @@ # # fixdep: used to generate dependency information during build process -hostprogs := fixdep -always-y := $(hostprogs) +hostprogs-always-y += fixdep diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 0b44917f981c..a698ece43fff 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -1,9 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # scripts/dtc makefile -hostprogs := dtc -always-$(CONFIG_DTC) += $(hostprogs) -always-$(CHECK_DT_BINDING) += $(hostprogs) +hostprogs-always-$(CONFIG_DTC) += dtc +hostprogs-always-$(CHECK_DT_BINDING) += dtc dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ srcpos.o checks.o util.o diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index d328de1e10ee..ce4f99935de5 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -hostprogs := genksyms -always-y := $(hostprogs) +hostprogs-always-y += genksyms genksyms-objs := genksyms.o parse.tab.o lex.lex.o diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index 296b6a3878b2..78071681d924 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 OBJECT_FILES_NON_STANDARD := y -hostprogs := modpost mk_elfconfig -always-y := $(hostprogs) empty.o +hostprogs-always-y += modpost mk_elfconfig +always-y += empty.o modpost-objs := modpost.o file2alias.o sumversion.o diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile index 70cf8d95d07c..1faf7f07e8db 100644 --- a/scripts/selinux/genheaders/Makefile +++ b/scripts/selinux/genheaders/Makefile @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -hostprogs := genheaders +hostprogs-always-y += genheaders HOST_EXTRACFLAGS += \ -I$(srctree)/include/uapi -I$(srctree)/include \ -I$(srctree)/security/selinux/include - -always-y := $(hostprogs) diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile index 3026f3c2aa2b..d61058ddd15c 100644 --- a/scripts/selinux/mdp/Makefile +++ b/scripts/selinux/mdp/Makefile @@ -1,8 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 -hostprogs := mdp +hostprogs-always-y += mdp HOST_EXTRACFLAGS += \ -I$(srctree)/include/uapi -I$(srctree)/include \ -I$(srctree)/security/selinux/include -I$(objtree)/include -always-y := $(hostprogs) clean-files := policy.* file_contexts From e0fe0bbe57b8d708a18756be5bc289bdaf78d2a8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 2 Aug 2020 00:00:49 +0900 Subject: [PATCH 240/242] kbuild: include scripts/Makefile.* only when relevant CONFIG is enabled Currently, the top Makefile includes all of scripts/Makefile. even if the associated CONFIG option is disabled. Do not include unneeded Makefiles in order to slightly optimize the parse stage. Include $(include-y), and ignore $(include-). Signed-off-by: Masahiro Yamada --- Makefile | 16 +++++++++------- scripts/Makefile.kcov | 4 ---- scripts/Makefile.kcsan | 4 ---- scripts/Makefile.ubsan | 3 --- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index ebf4d3ce492c..483456d5dd3e 100644 --- a/Makefile +++ b/Makefile @@ -745,9 +745,6 @@ endif KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) KBUILD_CFLAGS += $(call cc-option,-fno-allow-store-data-races) -include scripts/Makefile.kcov -include scripts/Makefile.gcc-plugins - ifdef CONFIG_READABLE_ASM # Disable optimizations that make assembler listings hard to read. # reorder blocks reorders the control in the function @@ -948,10 +945,15 @@ ifdef CONFIG_RETPOLINE KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) endif -include scripts/Makefile.kasan -include scripts/Makefile.extrawarn -include scripts/Makefile.ubsan -include scripts/Makefile.kcsan +# include additional Makefiles when needed +include-y := scripts/Makefile.extrawarn +include-$(CONFIG_KASAN) += scripts/Makefile.kasan +include-$(CONFIG_KCSAN) += scripts/Makefile.kcsan +include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan +include-$(CONFIG_KCOV) += scripts/Makefile.kcov +include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins + +include $(addprefix $(srctree)/, $(include-y)) # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments KBUILD_CPPFLAGS += $(KCPPFLAGS) diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov index 52b113302443..67e8cfe3474b 100644 --- a/scripts/Makefile.kcov +++ b/scripts/Makefile.kcov @@ -1,10 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -ifdef CONFIG_KCOV - kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS) += -fsanitize-coverage=trace-cmp kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV) += -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so export CFLAGS_KCOV := $(kcov-flags-y) - -endif diff --git a/scripts/Makefile.kcsan b/scripts/Makefile.kcsan index bd4da1af5953..2b0743e6566e 100644 --- a/scripts/Makefile.kcsan +++ b/scripts/Makefile.kcsan @@ -1,6 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -ifdef CONFIG_KCSAN - # GCC and Clang accept backend options differently. Do not wrap in cc-option, # because Clang accepts "--param" even if it is unused. ifdef CONFIG_CC_IS_CLANG @@ -15,5 +13,3 @@ CFLAGS_KCSAN := -fsanitize=thread \ $(call cc-option,$(call cc-param,tsan-instrument-func-entry-exit=0) -fno-optimize-sibling-calls) \ $(call cc-option,$(call cc-param,tsan-instrument-read-before-write=1)) \ $(call cc-param,tsan-distinguish-volatile=1) - -endif # CONFIG_KCSAN diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan index 5b15bc425ec9..27348029b2b8 100644 --- a/scripts/Makefile.ubsan +++ b/scripts/Makefile.ubsan @@ -1,6 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -ifdef CONFIG_UBSAN - ifdef CONFIG_UBSAN_ALIGNMENT CFLAGS_UBSAN += $(call cc-option, -fsanitize=alignment) endif @@ -26,4 +24,3 @@ endif # -fsanitize=* options makes GCC less smart than usual and # increase number of 'maybe-uninitialized false-positives CFLAGS_UBSAN += $(call cc-option, -Wno-maybe-uninitialized) -endif From 132305b3b474a85152302ceda4551384cce3904e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 2 Aug 2020 00:00:50 +0900 Subject: [PATCH 241/242] kbuild: stop filtering out $(GCC_PLUGINS_CFLAGS) from cc-option base Commit d26e94149276 ("kbuild: no gcc-plugins during cc-option tests") was neeeded because scripts/Makefile.gcc-plugins was too early. This is unneeded by including scripts/Makefile.gcc-plugins last, and being careful to not add cc-option tests after it. Signed-off-by: Masahiro Yamada --- Makefile | 5 ++++- scripts/Kbuild.include | 10 +++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 483456d5dd3e..712206381a27 100644 --- a/Makefile +++ b/Makefile @@ -506,7 +506,6 @@ KBUILD_CFLAGS_MODULE := -DMODULE KBUILD_LDFLAGS_MODULE := export KBUILD_LDS_MODULE := $(srctree)/scripts/module-common.lds KBUILD_LDFLAGS := -GCC_PLUGINS_CFLAGS := CLANG_FLAGS := export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC @@ -955,6 +954,10 @@ include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins include $(addprefix $(srctree)/, $(include-y)) +# scripts/Makefile.gcc-plugins is intentionally included last. +# Do not add $(call cc-option,...) below this line. When you build the kernel +# from the clean source tree, the GCC plugins do not exist at this point. + # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments KBUILD_CPPFLAGS += $(KCPPFLAGS) KBUILD_AFLAGS += $(KAFLAGS) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 9a15fbf66aa1..83a1637417e5 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -119,25 +119,21 @@ as-instr = $(call try-run,\ __cc-option = $(call try-run,\ $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4)) -# Do not attempt to build with gcc plugins during cc-option tests. -# (And this uses delayed resolution so the flags will be up to date.) -CC_OPTION_CFLAGS = $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) - # cc-option # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) cc-option = $(call __cc-option, $(CC),\ - $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2)) + $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS),$(1),$(2)) # cc-option-yn # Usage: flag := $(call cc-option-yn,-march=winchip-c6) cc-option-yn = $(call try-run,\ - $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) # cc-disable-warning # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) cc-disable-warning = $(call try-run,\ - $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) # cc-ifversion # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) From 71fa1a4489ff93ac4acd7e6c5b00098ba53a4485 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 30 Jun 2020 15:51:50 +1000 Subject: [PATCH 242/242] thunderbolt: merge fix for kunix_resource changes Signed-off-by: Stephen Rothwell Signed-off-by: Linus Torvalds --- drivers/thunderbolt/test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c index acb8b6256847..a4d78811f7e2 100644 --- a/drivers/thunderbolt/test.c +++ b/drivers/thunderbolt/test.c @@ -17,13 +17,13 @@ static int __ida_init(struct kunit_resource *res, void *context) struct ida *ida = context; ida_init(ida); - res->allocation = ida; + res->data = ida; return 0; } static void __ida_destroy(struct kunit_resource *res) { - struct ida *ida = res->allocation; + struct ida *ida = res->data; ida_destroy(ida); }