Message ID | c0ecf4f4-94f1-2efd-b05b-fc117c62e516@digi.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/6] pinctrl: ls1012a: Add pinctrl driver support | expand |
On Tue, Aug 27, 2024 at 12:12:24PM +1000, David Leonard wrote: > > Add QorIQ LS1046A pinctrl driver allowing i2c-core to exert > GPIO control over the third and fourth I2C buses. > > Signed-off-by: David Leonard <David.Leonard@digi.com> > --- Why not use pinctrl-single, please ref fsl,lx2160x.dtsi for GPIO/i2c recover. Frank > drivers/pinctrl/freescale/Kconfig | 8 + > drivers/pinctrl/freescale/Makefile | 1 + > drivers/pinctrl/freescale/pinctrl-ls1046a.c | 224 ++++++++++++++++++++ > 3 files changed, 233 insertions(+) > create mode 100644 drivers/pinctrl/freescale/pinctrl-ls1046a.c > > diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig > index a2038042eeae..2641db6c64c7 100644 > --- a/drivers/pinctrl/freescale/Kconfig > +++ b/drivers/pinctrl/freescale/Kconfig > @@ -217,6 +217,14 @@ config PINCTRL_LS1012A > help > Say Y here to enable the ls1012a pinctrl driver > > +config PINCTRL_LS1046A > + tristate "LS1046A pinctrl driver" > + depends on ARCH_LAYERSCAPE && OF || COMPILE_TEST > + select PINMUX > + select GENERIC_PINCONF > + help > + Say Y here to enable the ls1046a pinctrl driver > + > config PINCTRL_VF610 > bool "Freescale Vybrid VF610 pinctrl driver" > depends on SOC_VF610 > diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile > index 6926529d8635..66fec747af73 100644 > --- a/drivers/pinctrl/freescale/Makefile > +++ b/drivers/pinctrl/freescale/Makefile > @@ -36,3 +36,4 @@ obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o > obj-$(CONFIG_PINCTRL_IMXRT1050) += pinctrl-imxrt1050.o > obj-$(CONFIG_PINCTRL_IMXRT1170) += pinctrl-imxrt1170.o > obj-$(CONFIG_PINCTRL_LS1012A) += pinctrl-ls1012a.o > +obj-$(CONFIG_PINCTRL_LS1046A) += pinctrl-ls1046a.o > diff --git a/drivers/pinctrl/freescale/pinctrl-ls1046a.c b/drivers/pinctrl/freescale/pinctrl-ls1046a.c > new file mode 100644 > index 000000000000..9f5ec31f1e05 > --- /dev/null > +++ b/drivers/pinctrl/freescale/pinctrl-ls1046a.c > @@ -0,0 +1,224 @@ > +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) > +/* > + * Pin controller for NXP QorIQ LS1046A. > + * > + * Copyright (c) 2024 Digi International, Inc. > + * Author: David Leonard <David.Leonard@digi.com> > + */ > +#include <linux/module.h> > +#include <linux/mfd/syscon.h> > +#include <linux/pinctrl/pinctrl.h> > +#include <linux/pinctrl/pinmux.h> > +#include <linux/pinctrl/pinconf-generic.h> > +#include <linux/of.h> > +#include <linux/io.h> > +#include <linux/platform_device.h> > +#include <linux/sys_soc.h> > + > +struct ls1046a_pinctrl_pdata { > + struct pinctrl_dev *pctl_dev; > + void __iomem *cr0mem; > + bool big_endian; > + u32 ssc; > +}; > + > +/* > + * L4 M4 M3 N3 > + * i2c IIC3_SCL IIC3_SDA IIC4_SCL IIC4_SDA > + * gpio GPIO_4[10] GPIO_4[11] GPIO_4[12] GPIO_4[13] > + * evt EVT_B[5] EVT_B[6] EVT_B[7] EVT_B[8] > + * usb USB2_DRVVBUS USB2_PWRFAULT USB3_DRVVBUS USB3_PWRFAULT > + * ftm FTM8_CH0 FTM8_CH1 FTM3_FAULT FTM_EXT3CLK > + */ > + > +/* SCFG_RCWPMUXCR0 pinmux control register */ > +#define SCFG_RCWPMUXCR0 0x0157040c > +#define RCWPMUXCR0_FIELD(shift, func) ((u32)(func) << (29 - (shift))) > +#define RCWPMUXCR0_MASK(shift) RCWPMUXCR0_FIELD(shift, RCWPMUXCR0_FUNC_MASK) > +#define RCWPMUXCR0_IIC3_SCL_SHIFT 17 > +#define RCWPMUXCR0_IIC3_SDA_SHIFT 21 > +#define RCWPMUXCR0_IIC4_SCL_SHIFT 25 > +#define RCWPMUXCR0_IIC4_SDA_SHIFT 29 > +#define RCWPMUXCR0_FUNC_I2C 0 > +#define RCWPMUXCR0_FUNC_GPIO 1 > +#define RCWPMUXCR0_FUNC_EVT 2 > +#define RCWPMUXCR0_FUNC_USB 3 > +#define RCWPMUXCR0_FUNC_FTM 5 > +#define RCWPMUXCR0_FUNC_CLK 6 > +#define RCWPMUXCR0_FUNC_MASK 7 > + > +#define PIN_L4 0 /* IIC3_SCL/GPIO_4[10]/EVT_B[5]/USB2_DRVVBUS/FTM8_CH0 */ > +#define PIN_M4 1 /* IIC3_SDA/GPIO_4[11]/EVT_B[6]/USB2_PWRFAULT/FTM8_CH1 */ > +#define PIN_M3 2 /* IIC4_SCL/GPIO_4[12]/EVT_B[7]/USB3_DRVVBUS/FTM3_FAULT */ > +#define PIN_N3 3 /* IIC4_SDA/GPIO_4[13]/EVT_B[8]/USB3_PWRFAULT/FTM_EXT3CLK */ > + > +const struct pinctrl_pin_desc ls1046a_pins[] = { > + PINCTRL_PIN(PIN_L4, "L4"), > + PINCTRL_PIN(PIN_M4, "M4"), > + PINCTRL_PIN(PIN_M3, "M3"), > + PINCTRL_PIN(PIN_N3, "N3"), > +}; > + > +/* Each pin is its own group */ > +static const char * const ls1046a_groups[] = { "L4", "M4", "M3", "N3" }; > + > +static int ls1046a_get_groups_count(struct pinctrl_dev *pcdev) > +{ > + return ARRAY_SIZE(ls1046a_pins); > +} > + > +static const char *ls1046a_get_group_name(struct pinctrl_dev *pcdev, > + unsigned int selector) > +{ > + return ls1046a_pins[selector].name; > +} > + > +static int ls1046a_get_group_pins(struct pinctrl_dev *pcdev, > + unsigned int selector, const unsigned int **pins, unsigned int *npins) > +{ > + *pins = &ls1046a_pins[selector].number; > + *npins = 1; > + return 0; > +} > + > +static const struct pinctrl_ops ls1046a_pinctrl_ops = { > + .get_groups_count = ls1046a_get_groups_count, > + .get_group_name = ls1046a_get_group_name, > + .get_group_pins = ls1046a_get_group_pins, > + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, > + .dt_free_map = pinconf_generic_dt_free_map, > +}; > + > +/* Every pin has the same set of functions */ > +#define FUNC_i2c 0 > +#define FUNC_gpio 1 > +#define FUNC_evt 2 > +#define FUNC_usb 3 > +#define FUNC_ftm 4 > + > +#define _PINFUNC(name) \ > + [FUNC_##name] = PINCTRL_PINFUNCTION(#name, ls1046a_groups, ARRAY_SIZE(ls1046a_groups)) > +static const struct pinfunction ls1046a_functions[] = { > + _PINFUNC(i2c), > + _PINFUNC(gpio), > + _PINFUNC(evt), > + _PINFUNC(usb), > + _PINFUNC(ftm), > +}; > + > +static int ls1046a_get_functions_count(struct pinctrl_dev *pctldev) > +{ > + return ARRAY_SIZE(ls1046a_functions); > +} > + > +static const char *ls1046a_get_function_name(struct pinctrl_dev *pctldev, unsigned int func) > +{ > + return ls1046a_functions[func].name; > +} > + > +static int ls1046a_get_function_groups(struct pinctrl_dev *pctldev, unsigned int func, > + const char * const **groups, > + unsigned int * const ngroups) > +{ > + *groups = ls1046a_functions[func].groups; > + *ngroups = ls1046a_functions[func].ngroups; > + return 0; > +} > + > +static int ls1046a_set_mux(struct pinctrl_dev *pcdev, > + unsigned int func, unsigned int pin) > +{ > + struct ls1046a_pinctrl_pdata *pd = pinctrl_dev_get_drvdata(pcdev); > + static const u32 cr0_reg_func[] = { > + [FUNC_i2c] = RCWPMUXCR0_FUNC_I2C, > + [FUNC_gpio] = RCWPMUXCR0_FUNC_GPIO, > + [FUNC_evt] = RCWPMUXCR0_FUNC_EVT, > + [FUNC_usb] = RCWPMUXCR0_FUNC_USB, > + [FUNC_ftm] = RCWPMUXCR0_FUNC_FTM, > + }; > + static const unsigned int cr0_pin_shift[] = { > + [PIN_L4] = RCWPMUXCR0_IIC3_SCL_SHIFT, > + [PIN_M4] = RCWPMUXCR0_IIC3_SDA_SHIFT, > + [PIN_M3] = RCWPMUXCR0_IIC4_SCL_SHIFT, > + [PIN_N3] = RCWPMUXCR0_IIC4_SDA_SHIFT, > + }; > + u32 cr0; > + > + if (pd->big_endian) > + cr0 = ioread32be(pd->cr0mem); > + else > + cr0 = ioread32(pd->cr0mem); > + > + unsigned int pin_shift = cr0_pin_shift[pin]; > + u32 reg_func = cr0_reg_func[func]; > + u32 newcr0 = (cr0 & ~RCWPMUXCR0_MASK(pin_shift)) | > + RCWPMUXCR0_FIELD(pin_shift, reg_func); > + > + if (pd->big_endian) > + iowrite32be(newcr0, pd->cr0mem); > + else > + iowrite32(newcr0, pd->cr0mem); > + return 0; > +} > + > +static const struct pinmux_ops ls1046a_pinmux_ops = { > + .get_functions_count = ls1046a_get_functions_count, > + .get_function_name = ls1046a_get_function_name, > + .get_function_groups = ls1046a_get_function_groups, > + .set_mux = ls1046a_set_mux, > +}; > + > +static const struct pinctrl_desc ls1046a_pinctrl_desc = { > + .name = "ls1046a", > + .pins = ls1046a_pins, > + .npins = ARRAY_SIZE(ls1046a_pins), > + .pctlops = &ls1046a_pinctrl_ops, > + .pmxops = &ls1046a_pinmux_ops, > + .owner = THIS_MODULE, > +}; > + > +static int ls1046a_pinctrl_probe(struct platform_device *pdev) > +{ > + struct ls1046a_pinctrl_pdata *pd; > + int ret; > + > + pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); > + if (!pd) > + return -ENOMEM; > + platform_set_drvdata(pdev, pd); > + > + pd->big_endian = device_is_big_endian(&pdev->dev); > + > + /* SCFG PMUX0 */ > + pd->cr0mem = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(pd->cr0mem)) > + return PTR_ERR(pd->cr0mem); > + dev_dbg(&pdev->dev, "scfg pmuxcr0 at %px %s", pd->cr0mem, > + pd->big_endian ? "be" : "le"); > + > + ret = devm_pinctrl_register_and_init(&pdev->dev, &ls1046a_pinctrl_desc, > + pd, &pd->pctl_dev); > + if (ret) > + return dev_err_probe(&pdev->dev, ret, "Failed pinctrl init\n"); > + > + pinctrl_enable(pd->pctl_dev); > + return ret; > +} > + > +static const struct of_device_id ls1046a_pinctrl_match_table[] = { > + { .compatible = "fsl,ls1046a-pinctrl" }, > + { /* sentinel */ } > +}; > + > +static struct platform_driver ls1046a_pinctrl_driver = { > + .driver = { > + .name = "ls1046a_pinctrl", > + .of_match_table = ls1046a_pinctrl_match_table, > + }, > + .probe = ls1046a_pinctrl_probe, > +}; > + > +builtin_platform_driver(ls1046a_pinctrl_driver) > + > +MODULE_DESCRIPTION("LS1046A pinctrl driver"); > +MODULE_LICENSE("GPL"); > -- > 2.43.0 >
Hi David, kernel test robot noticed the following build errors: [auto build test ERROR on linusw-pinctrl/devel] [also build test ERROR on linusw-pinctrl/for-next shawnguo/for-next arm64/for-next/core kvmarm/next rockchip/for-next soc/for-next linus/master v6.11-rc5 next-20240827] [cannot apply to arm/for-next arm/fixes] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/David-Leonard/arm64-dts-ls1012a-add-pinctrl-node/20240827-104431 base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel patch link: https://lore.kernel.org/r/c0ecf4f4-94f1-2efd-b05b-fc117c62e516%40digi.com patch subject: [PATCH 4/6] pinctrl: ls1046a: Add pinctrl driver support config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20240828/202408280509.Jr3oFGGy-lkp@intel.com/config) compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 08e5a1de8227512d4774a534b91cb2353cef6284) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240828/202408280509.Jr3oFGGy-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202408280509.Jr3oFGGy-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from drivers/pinctrl/freescale/pinctrl-ls1046a.c:8: In file included from include/linux/module.h:19: In file included from include/linux/elf.h:6: In file included from arch/s390/include/asm/elf.h:181: In file included from arch/s390/include/asm/mmu_context.h:11: In file included from arch/s390/include/asm/pgalloc.h:18: In file included from include/linux/mm.h:2228: include/linux/vmstat.h:500:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion] 500 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~ ^ 501 | item]; | ~~~~ include/linux/vmstat.h:507:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion] 507 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~ ^ 508 | NR_VM_NUMA_EVENT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~~ include/linux/vmstat.h:514:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 514 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ include/linux/vmstat.h:519:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion] 519 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~ ^ 520 | NR_VM_NUMA_EVENT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~~ include/linux/vmstat.h:528:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion] 528 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~ ^ 529 | NR_VM_NUMA_EVENT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/pinctrl/freescale/pinctrl-ls1046a.c:14: In file included from include/linux/io.h:14: In file included from arch/s390/include/asm/io.h:93: include/asm-generic/io.h:548:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 548 | val = __raw_readb(PCI_IOBASE + addr); | ~~~~~~~~~~ ^ include/asm-generic/io.h:561:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 561 | val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); | ~~~~~~~~~~ ^ include/uapi/linux/byteorder/big_endian.h:37:59: note: expanded from macro '__le16_to_cpu' 37 | #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x)) | ^ include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16' 102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x)) | ^ In file included from drivers/pinctrl/freescale/pinctrl-ls1046a.c:14: In file included from include/linux/io.h:14: In file included from arch/s390/include/asm/io.h:93: include/asm-generic/io.h:574:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 574 | val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); | ~~~~~~~~~~ ^ include/uapi/linux/byteorder/big_endian.h:35:59: note: expanded from macro '__le32_to_cpu' 35 | #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x)) | ^ include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32' 115 | #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x)) | ^ In file included from drivers/pinctrl/freescale/pinctrl-ls1046a.c:14: In file included from include/linux/io.h:14: In file included from arch/s390/include/asm/io.h:93: include/asm-generic/io.h:585:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 585 | __raw_writeb(value, PCI_IOBASE + addr); | ~~~~~~~~~~ ^ include/asm-generic/io.h:595:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 595 | __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); | ~~~~~~~~~~ ^ include/asm-generic/io.h:605:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 605 | __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); | ~~~~~~~~~~ ^ include/asm-generic/io.h:693:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 693 | readsb(PCI_IOBASE + addr, buffer, count); | ~~~~~~~~~~ ^ include/asm-generic/io.h:701:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 701 | readsw(PCI_IOBASE + addr, buffer, count); | ~~~~~~~~~~ ^ include/asm-generic/io.h:709:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 709 | readsl(PCI_IOBASE + addr, buffer, count); | ~~~~~~~~~~ ^ include/asm-generic/io.h:718:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 718 | writesb(PCI_IOBASE + addr, buffer, count); | ~~~~~~~~~~ ^ include/asm-generic/io.h:727:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 727 | writesw(PCI_IOBASE + addr, buffer, count); | ~~~~~~~~~~ ^ include/asm-generic/io.h:736:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] 736 | writesl(PCI_IOBASE + addr, buffer, count); | ~~~~~~~~~~ ^ >> drivers/pinctrl/freescale/pinctrl-ls1046a.c:199:51: error: passing 'const struct pinctrl_desc *' to parameter of type 'struct pinctrl_desc *' discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers] 199 | ret = devm_pinctrl_register_and_init(&pdev->dev, &ls1046a_pinctrl_desc, | ^~~~~~~~~~~~~~~~~~~~~ include/linux/pinctrl/pinctrl.h:180:26: note: passing argument to parameter 'pctldesc' here 180 | struct pinctrl_desc *pctldesc, | ^ 17 warnings and 1 error generated. vim +199 drivers/pinctrl/freescale/pinctrl-ls1046a.c 179 180 static int ls1046a_pinctrl_probe(struct platform_device *pdev) 181 { 182 struct ls1046a_pinctrl_pdata *pd; 183 int ret; 184 185 pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); 186 if (!pd) 187 return -ENOMEM; 188 platform_set_drvdata(pdev, pd); 189 190 pd->big_endian = device_is_big_endian(&pdev->dev); 191 192 /* SCFG PMUX0 */ 193 pd->cr0mem = devm_platform_ioremap_resource(pdev, 0); 194 if (IS_ERR(pd->cr0mem)) 195 return PTR_ERR(pd->cr0mem); 196 dev_dbg(&pdev->dev, "scfg pmuxcr0 at %px %s", pd->cr0mem, 197 pd->big_endian ? "be" : "le"); 198 > 199 ret = devm_pinctrl_register_and_init(&pdev->dev, &ls1046a_pinctrl_desc, 200 pd, &pd->pctl_dev); 201 if (ret) 202 return dev_err_probe(&pdev->dev, ret, "Failed pinctrl init\n"); 203 204 pinctrl_enable(pd->pctl_dev); 205 return ret; 206 } 207
Hi David, kernel test robot noticed the following build warnings: [auto build test WARNING on linusw-pinctrl/devel] [also build test WARNING on linusw-pinctrl/for-next shawnguo/for-next arm64/for-next/core kvmarm/next rockchip/for-next soc/for-next linus/master v6.11-rc5 next-20240827] [cannot apply to arm/for-next arm/fixes] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/David-Leonard/arm64-dts-ls1012a-add-pinctrl-node/20240827-104431 base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel patch link: https://lore.kernel.org/r/c0ecf4f4-94f1-2efd-b05b-fc117c62e516%40digi.com patch subject: [PATCH 4/6] pinctrl: ls1046a: Add pinctrl driver support config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20240828/202408280532.YGyLCCNL-lkp@intel.com/config) compiler: s390-linux-gcc (GCC) 14.1.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240828/202408280532.YGyLCCNL-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202408280532.YGyLCCNL-lkp@intel.com/ All warnings (new ones prefixed by >>): drivers/pinctrl/freescale/pinctrl-ls1046a.c: In function 'ls1046a_pinctrl_probe': >> drivers/pinctrl/freescale/pinctrl-ls1046a.c:199:58: warning: passing argument 2 of 'devm_pinctrl_register_and_init' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] 199 | ret = devm_pinctrl_register_and_init(&pdev->dev, &ls1046a_pinctrl_desc, | ^~~~~~~~~~~~~~~~~~~~~ In file included from drivers/pinctrl/freescale/pinctrl-ls1046a.c:10: include/linux/pinctrl/pinctrl.h:180:54: note: expected 'struct pinctrl_desc *' but argument is of type 'const struct pinctrl_desc *' 180 | struct pinctrl_desc *pctldesc, | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~ vim +199 drivers/pinctrl/freescale/pinctrl-ls1046a.c 179 180 static int ls1046a_pinctrl_probe(struct platform_device *pdev) 181 { 182 struct ls1046a_pinctrl_pdata *pd; 183 int ret; 184 185 pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); 186 if (!pd) 187 return -ENOMEM; 188 platform_set_drvdata(pdev, pd); 189 190 pd->big_endian = device_is_big_endian(&pdev->dev); 191 192 /* SCFG PMUX0 */ 193 pd->cr0mem = devm_platform_ioremap_resource(pdev, 0); 194 if (IS_ERR(pd->cr0mem)) 195 return PTR_ERR(pd->cr0mem); 196 dev_dbg(&pdev->dev, "scfg pmuxcr0 at %px %s", pd->cr0mem, 197 pd->big_endian ? "be" : "le"); 198 > 199 ret = devm_pinctrl_register_and_init(&pdev->dev, &ls1046a_pinctrl_desc, 200 pd, &pd->pctl_dev); 201 if (ret) 202 return dev_err_probe(&pdev->dev, ret, "Failed pinctrl init\n"); 203 204 pinctrl_enable(pd->pctl_dev); 205 return ret; 206 } 207
Hi David, kernel test robot noticed the following build warnings: [auto build test WARNING on linusw-pinctrl/devel] [also build test WARNING on linusw-pinctrl/for-next shawnguo/for-next arm64/for-next/core kvmarm/next rockchip/for-next soc/for-next linus/master v6.11-rc5 next-20240827] [cannot apply to arm/for-next arm/fixes] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/David-Leonard/arm64-dts-ls1012a-add-pinctrl-node/20240827-104431 base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel patch link: https://lore.kernel.org/r/c0ecf4f4-94f1-2efd-b05b-fc117c62e516%40digi.com patch subject: [PATCH 4/6] pinctrl: ls1046a: Add pinctrl driver support config: sh-randconfig-r113-20240828 (https://download.01.org/0day-ci/archive/20240828/202408281442.Xos98wkO-lkp@intel.com/config) compiler: sh4-linux-gcc (GCC) 14.1.0 reproduce: (https://download.01.org/0day-ci/archive/20240828/202408281442.Xos98wkO-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202408281442.Xos98wkO-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) >> drivers/pinctrl/freescale/pinctrl-ls1046a.c:55:31: sparse: sparse: symbol 'ls1046a_pins' was not declared. Should it be static? >> drivers/pinctrl/freescale/pinctrl-ls1046a.c:199:59: sparse: sparse: incorrect type in argument 2 (different modifiers) @@ expected struct pinctrl_desc *pctldesc @@ got struct pinctrl_desc const * @@ drivers/pinctrl/freescale/pinctrl-ls1046a.c:199:59: sparse: expected struct pinctrl_desc *pctldesc drivers/pinctrl/freescale/pinctrl-ls1046a.c:199:59: sparse: got struct pinctrl_desc const * vim +/ls1046a_pins +55 drivers/pinctrl/freescale/pinctrl-ls1046a.c 54 > 55 const struct pinctrl_pin_desc ls1046a_pins[] = { 56 PINCTRL_PIN(PIN_L4, "L4"), 57 PINCTRL_PIN(PIN_M4, "M4"), 58 PINCTRL_PIN(PIN_M3, "M3"), 59 PINCTRL_PIN(PIN_N3, "N3"), 60 }; 61 62 /* Each pin is its own group */ 63 static const char * const ls1046a_groups[] = { "L4", "M4", "M3", "N3" }; 64 65 static int ls1046a_get_groups_count(struct pinctrl_dev *pcdev) 66 { 67 return ARRAY_SIZE(ls1046a_pins); 68 } 69 70 static const char *ls1046a_get_group_name(struct pinctrl_dev *pcdev, 71 unsigned int selector) 72 { 73 return ls1046a_pins[selector].name; 74 } 75 76 static int ls1046a_get_group_pins(struct pinctrl_dev *pcdev, 77 unsigned int selector, const unsigned int **pins, unsigned int *npins) 78 { 79 *pins = &ls1046a_pins[selector].number; 80 *npins = 1; 81 return 0; 82 } 83 84 static const struct pinctrl_ops ls1046a_pinctrl_ops = { 85 .get_groups_count = ls1046a_get_groups_count, 86 .get_group_name = ls1046a_get_group_name, 87 .get_group_pins = ls1046a_get_group_pins, 88 .dt_node_to_map = pinconf_generic_dt_node_to_map_group, 89 .dt_free_map = pinconf_generic_dt_free_map, 90 }; 91 92 /* Every pin has the same set of functions */ 93 #define FUNC_i2c 0 94 #define FUNC_gpio 1 95 #define FUNC_evt 2 96 #define FUNC_usb 3 97 #define FUNC_ftm 4 98 99 #define _PINFUNC(name) \ 100 [FUNC_##name] = PINCTRL_PINFUNCTION(#name, ls1046a_groups, ARRAY_SIZE(ls1046a_groups)) 101 static const struct pinfunction ls1046a_functions[] = { 102 _PINFUNC(i2c), 103 _PINFUNC(gpio), 104 _PINFUNC(evt), 105 _PINFUNC(usb), 106 _PINFUNC(ftm), 107 }; 108 109 static int ls1046a_get_functions_count(struct pinctrl_dev *pctldev) 110 { 111 return ARRAY_SIZE(ls1046a_functions); 112 } 113 114 static const char *ls1046a_get_function_name(struct pinctrl_dev *pctldev, unsigned int func) 115 { 116 return ls1046a_functions[func].name; 117 } 118 119 static int ls1046a_get_function_groups(struct pinctrl_dev *pctldev, unsigned int func, 120 const char * const **groups, 121 unsigned int * const ngroups) 122 { 123 *groups = ls1046a_functions[func].groups; 124 *ngroups = ls1046a_functions[func].ngroups; 125 return 0; 126 } 127 128 static int ls1046a_set_mux(struct pinctrl_dev *pcdev, 129 unsigned int func, unsigned int pin) 130 { 131 struct ls1046a_pinctrl_pdata *pd = pinctrl_dev_get_drvdata(pcdev); 132 static const u32 cr0_reg_func[] = { 133 [FUNC_i2c] = RCWPMUXCR0_FUNC_I2C, 134 [FUNC_gpio] = RCWPMUXCR0_FUNC_GPIO, 135 [FUNC_evt] = RCWPMUXCR0_FUNC_EVT, 136 [FUNC_usb] = RCWPMUXCR0_FUNC_USB, 137 [FUNC_ftm] = RCWPMUXCR0_FUNC_FTM, 138 }; 139 static const unsigned int cr0_pin_shift[] = { 140 [PIN_L4] = RCWPMUXCR0_IIC3_SCL_SHIFT, 141 [PIN_M4] = RCWPMUXCR0_IIC3_SDA_SHIFT, 142 [PIN_M3] = RCWPMUXCR0_IIC4_SCL_SHIFT, 143 [PIN_N3] = RCWPMUXCR0_IIC4_SDA_SHIFT, 144 }; 145 u32 cr0; 146 147 if (pd->big_endian) 148 cr0 = ioread32be(pd->cr0mem); 149 else 150 cr0 = ioread32(pd->cr0mem); 151 152 unsigned int pin_shift = cr0_pin_shift[pin]; 153 u32 reg_func = cr0_reg_func[func]; 154 u32 newcr0 = (cr0 & ~RCWPMUXCR0_MASK(pin_shift)) | 155 RCWPMUXCR0_FIELD(pin_shift, reg_func); 156 157 if (pd->big_endian) 158 iowrite32be(newcr0, pd->cr0mem); 159 else 160 iowrite32(newcr0, pd->cr0mem); 161 return 0; 162 } 163 164 static const struct pinmux_ops ls1046a_pinmux_ops = { 165 .get_functions_count = ls1046a_get_functions_count, 166 .get_function_name = ls1046a_get_function_name, 167 .get_function_groups = ls1046a_get_function_groups, 168 .set_mux = ls1046a_set_mux, 169 }; 170 171 static const struct pinctrl_desc ls1046a_pinctrl_desc = { 172 .name = "ls1046a", 173 .pins = ls1046a_pins, 174 .npins = ARRAY_SIZE(ls1046a_pins), 175 .pctlops = &ls1046a_pinctrl_ops, 176 .pmxops = &ls1046a_pinmux_ops, 177 .owner = THIS_MODULE, 178 }; 179 180 static int ls1046a_pinctrl_probe(struct platform_device *pdev) 181 { 182 struct ls1046a_pinctrl_pdata *pd; 183 int ret; 184 185 pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); 186 if (!pd) 187 return -ENOMEM; 188 platform_set_drvdata(pdev, pd); 189 190 pd->big_endian = device_is_big_endian(&pdev->dev); 191 192 /* SCFG PMUX0 */ 193 pd->cr0mem = devm_platform_ioremap_resource(pdev, 0); 194 if (IS_ERR(pd->cr0mem)) 195 return PTR_ERR(pd->cr0mem); 196 dev_dbg(&pdev->dev, "scfg pmuxcr0 at %px %s", pd->cr0mem, 197 pd->big_endian ? "be" : "le"); 198 > 199 ret = devm_pinctrl_register_and_init(&pdev->dev, &ls1046a_pinctrl_desc, 200 pd, &pd->pctl_dev); 201 if (ret) 202 return dev_err_probe(&pdev->dev, ret, "Failed pinctrl init\n"); 203 204 pinctrl_enable(pd->pctl_dev); 205 return ret; 206 } 207
On Tue, Aug 27, 2024 at 9:20 PM Frank Li <Frank.li@nxp.com> wrote: > On Tue, Aug 27, 2024 at 12:12:24PM +1000, David Leonard wrote: > > > > Add QorIQ LS1046A pinctrl driver allowing i2c-core to exert > > GPIO control over the third and fourth I2C buses. > > > > Signed-off-by: David Leonard <David.Leonard@digi.com> > > --- > > Why not use pinctrl-single, please ref fsl,lx2160x.dtsi for GPIO/i2c > recover. I'm not so sure about that. Since the 1012 need to use a unique driver this will be confusing across the family: one chip has registers and values defined in the device tree, another has them in the driver, if possible I would advice to keep this consistent across sibling SoCs. I can't stop anyone from using pinctrl-single but it's a bit seductive in it's simplicity, while not always so user-friendly with all the magic that ends up in the device trees. Yours, Linus Walleij
On Sat, Aug 31, 2024 at 12:26:47AM +0200, Linus Walleij wrote: > On Tue, Aug 27, 2024 at 9:20 PM Frank Li <Frank.li@nxp.com> wrote: > > On Tue, Aug 27, 2024 at 12:12:24PM +1000, David Leonard wrote: > > > > > > Add QorIQ LS1046A pinctrl driver allowing i2c-core to exert > > > GPIO control over the third and fourth I2C buses. > > > > > > Signed-off-by: David Leonard <David.Leonard@digi.com> > > > --- > > > > Why not use pinctrl-single, please ref fsl,lx2160x.dtsi for GPIO/i2c > > recover. > > I'm not so sure about that. Since the 1012 need to use a unique > driver this will be confusing across the family: one chip has > registers and values defined in the device tree, another has > them in the driver, if possible I would advice to keep this > consistent across sibling SoCs. There are not new productions of Layerscape. IMX will take over these. There are only few I2C pins need mux to gpio. It is not wonth to add new driver for it if pinctrl-single can work. And 1012 pinctrl driver was not shared with 1046. Frank > > I can't stop anyone from using pinctrl-single but it's a bit > seductive in it's simplicity, while not always so user-friendly > with all the magic that ends up in the device trees. > > Yours, > Linus Walleij
diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index a2038042eeae..2641db6c64c7 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -217,6 +217,14 @@ config PINCTRL_LS1012A help Say Y here to enable the ls1012a pinctrl driver +config PINCTRL_LS1046A + tristate "LS1046A pinctrl driver" + depends on ARCH_LAYERSCAPE && OF || COMPILE_TEST + select PINMUX + select GENERIC_PINCONF + help + Say Y here to enable the ls1046a pinctrl driver + config PINCTRL_VF610 bool "Freescale Vybrid VF610 pinctrl driver" depends on SOC_VF610 diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile index 6926529d8635..66fec747af73 100644 --- a/drivers/pinctrl/freescale/Makefile +++ b/drivers/pinctrl/freescale/Makefile @@ -36,3 +36,4 @@ obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o obj-$(CONFIG_PINCTRL_IMXRT1050) += pinctrl-imxrt1050.o obj-$(CONFIG_PINCTRL_IMXRT1170) += pinctrl-imxrt1170.o obj-$(CONFIG_PINCTRL_LS1012A) += pinctrl-ls1012a.o +obj-$(CONFIG_PINCTRL_LS1046A) += pinctrl-ls1046a.o diff --git a/drivers/pinctrl/freescale/pinctrl-ls1046a.c b/drivers/pinctrl/freescale/pinctrl-ls1046a.c new file mode 100644 index 000000000000..9f5ec31f1e05 --- /dev/null +++ b/drivers/pinctrl/freescale/pinctrl-ls1046a.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Pin controller for NXP QorIQ LS1046A. + * + * Copyright (c) 2024 Digi International, Inc. + * Author: David Leonard <David.Leonard@digi.com> + */ +#include <linux/module.h> +#include <linux/mfd/syscon.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/of.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/sys_soc.h> + +struct ls1046a_pinctrl_pdata { + struct pinctrl_dev *pctl_dev; + void __iomem *cr0mem; + bool big_endian; + u32 ssc; +}; + +/* + * L4 M4 M3 N3 + * i2c IIC3_SCL IIC3_SDA IIC4_SCL IIC4_SDA + * gpio GPIO_4[10] GPIO_4[11] GPIO_4[12] GPIO_4[13] + * evt EVT_B[5] EVT_B[6] EVT_B[7] EVT_B[8] + * usb USB2_DRVVBUS USB2_PWRFAULT USB3_DRVVBUS USB3_PWRFAULT + * ftm FTM8_CH0 FTM8_CH1 FTM3_FAULT FTM_EXT3CLK + */ + +/* SCFG_RCWPMUXCR0 pinmux control register */ +#define SCFG_RCWPMUXCR0 0x0157040c +#define RCWPMUXCR0_FIELD(shift, func) ((u32)(func) << (29 - (shift))) +#define RCWPMUXCR0_MASK(shift) RCWPMUXCR0_FIELD(shift, RCWPMUXCR0_FUNC_MASK) +#define RCWPMUXCR0_IIC3_SCL_SHIFT 17 +#define RCWPMUXCR0_IIC3_SDA_SHIFT 21 +#define RCWPMUXCR0_IIC4_SCL_SHIFT 25 +#define RCWPMUXCR0_IIC4_SDA_SHIFT 29 +#define RCWPMUXCR0_FUNC_I2C 0 +#define RCWPMUXCR0_FUNC_GPIO 1 +#define RCWPMUXCR0_FUNC_EVT 2 +#define RCWPMUXCR0_FUNC_USB 3 +#define RCWPMUXCR0_FUNC_FTM 5 +#define RCWPMUXCR0_FUNC_CLK 6 +#define RCWPMUXCR0_FUNC_MASK 7 + +#define PIN_L4 0 /* IIC3_SCL/GPIO_4[10]/EVT_B[5]/USB2_DRVVBUS/FTM8_CH0 */ +#define PIN_M4 1 /* IIC3_SDA/GPIO_4[11]/EVT_B[6]/USB2_PWRFAULT/FTM8_CH1 */ +#define PIN_M3 2 /* IIC4_SCL/GPIO_4[12]/EVT_B[7]/USB3_DRVVBUS/FTM3_FAULT */ +#define PIN_N3 3 /* IIC4_SDA/GPIO_4[13]/EVT_B[8]/USB3_PWRFAULT/FTM_EXT3CLK */ + +const struct pinctrl_pin_desc ls1046a_pins[] = { + PINCTRL_PIN(PIN_L4, "L4"), + PINCTRL_PIN(PIN_M4, "M4"), + PINCTRL_PIN(PIN_M3, "M3"), + PINCTRL_PIN(PIN_N3, "N3"), +}; + +/* Each pin is its own group */ +static const char * const ls1046a_groups[] = { "L4", "M4", "M3", "N3" }; + +static int ls1046a_get_groups_count(struct pinctrl_dev *pcdev) +{ + return ARRAY_SIZE(ls1046a_pins); +} + +static const char *ls1046a_get_group_name(struct pinctrl_dev *pcdev, + unsigned int selector) +{ + return ls1046a_pins[selector].name; +} + +static int ls1046a_get_group_pins(struct pinctrl_dev *pcdev, + unsigned int selector, const unsigned int **pins, unsigned int *npins) +{ + *pins = &ls1046a_pins[selector].number; + *npins = 1; + return 0; +} + +static const struct pinctrl_ops ls1046a_pinctrl_ops = { + .get_groups_count = ls1046a_get_groups_count, + .get_group_name = ls1046a_get_group_name, + .get_group_pins = ls1046a_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_free_map = pinconf_generic_dt_free_map, +}; + +/* Every pin has the same set of functions */ +#define FUNC_i2c 0 +#define FUNC_gpio 1 +#define FUNC_evt 2 +#define FUNC_usb 3 +#define FUNC_ftm 4 + +#define _PINFUNC(name) \ + [FUNC_##name] = PINCTRL_PINFUNCTION(#name, ls1046a_groups, ARRAY_SIZE(ls1046a_groups)) +static const struct pinfunction ls1046a_functions[] = { + _PINFUNC(i2c), + _PINFUNC(gpio), + _PINFUNC(evt), + _PINFUNC(usb), + _PINFUNC(ftm), +}; + +static int ls1046a_get_functions_count(struct pinctrl_dev *pctldev) +{ + return ARRAY_SIZE(ls1046a_functions); +} + +static const char *ls1046a_get_function_name(struct pinctrl_dev *pctldev, unsigned int func) +{ + return ls1046a_functions[func].name; +} + +static int ls1046a_get_function_groups(struct pinctrl_dev *pctldev, unsigned int func, + const char * const **groups, + unsigned int * const ngroups) +{ + *groups = ls1046a_functions[func].groups; + *ngroups = ls1046a_functions[func].ngroups; + return 0; +} + +static int ls1046a_set_mux(struct pinctrl_dev *pcdev, + unsigned int func, unsigned int pin) +{ + struct ls1046a_pinctrl_pdata *pd = pinctrl_dev_get_drvdata(pcdev); + static const u32 cr0_reg_func[] = { + [FUNC_i2c] = RCWPMUXCR0_FUNC_I2C, + [FUNC_gpio] = RCWPMUXCR0_FUNC_GPIO, + [FUNC_evt] = RCWPMUXCR0_FUNC_EVT, + [FUNC_usb] = RCWPMUXCR0_FUNC_USB, + [FUNC_ftm] = RCWPMUXCR0_FUNC_FTM, + }; + static const unsigned int cr0_pin_shift[] = { + [PIN_L4] = RCWPMUXCR0_IIC3_SCL_SHIFT, + [PIN_M4] = RCWPMUXCR0_IIC3_SDA_SHIFT, + [PIN_M3] = RCWPMUXCR0_IIC4_SCL_SHIFT, + [PIN_N3] = RCWPMUXCR0_IIC4_SDA_SHIFT, + }; + u32 cr0; + + if (pd->big_endian) + cr0 = ioread32be(pd->cr0mem); + else + cr0 = ioread32(pd->cr0mem); + + unsigned int pin_shift = cr0_pin_shift[pin]; + u32 reg_func = cr0_reg_func[func]; + u32 newcr0 = (cr0 & ~RCWPMUXCR0_MASK(pin_shift)) | + RCWPMUXCR0_FIELD(pin_shift, reg_func); + + if (pd->big_endian) + iowrite32be(newcr0, pd->cr0mem); + else + iowrite32(newcr0, pd->cr0mem); + return 0; +} + +static const struct pinmux_ops ls1046a_pinmux_ops = { + .get_functions_count = ls1046a_get_functions_count, + .get_function_name = ls1046a_get_function_name, + .get_function_groups = ls1046a_get_function_groups, + .set_mux = ls1046a_set_mux, +}; + +static const struct pinctrl_desc ls1046a_pinctrl_desc = { + .name = "ls1046a", + .pins = ls1046a_pins, + .npins = ARRAY_SIZE(ls1046a_pins), + .pctlops = &ls1046a_pinctrl_ops, + .pmxops = &ls1046a_pinmux_ops, + .owner = THIS_MODULE, +}; + +static int ls1046a_pinctrl_probe(struct platform_device *pdev) +{ + struct ls1046a_pinctrl_pdata *pd; + int ret; + + pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + platform_set_drvdata(pdev, pd); + + pd->big_endian = device_is_big_endian(&pdev->dev); + + /* SCFG PMUX0 */ + pd->cr0mem = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(pd->cr0mem)) + return PTR_ERR(pd->cr0mem); + dev_dbg(&pdev->dev, "scfg pmuxcr0 at %px %s", pd->cr0mem, + pd->big_endian ? "be" : "le"); + + ret = devm_pinctrl_register_and_init(&pdev->dev, &ls1046a_pinctrl_desc, + pd, &pd->pctl_dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Failed pinctrl init\n"); + + pinctrl_enable(pd->pctl_dev); + return ret; +} + +static const struct of_device_id ls1046a_pinctrl_match_table[] = { + { .compatible = "fsl,ls1046a-pinctrl" }, + { /* sentinel */ } +}; + +static struct platform_driver ls1046a_pinctrl_driver = { + .driver = { + .name = "ls1046a_pinctrl", + .of_match_table = ls1046a_pinctrl_match_table, + }, + .probe = ls1046a_pinctrl_probe, +}; + +builtin_platform_driver(ls1046a_pinctrl_driver) + +MODULE_DESCRIPTION("LS1046A pinctrl driver"); +MODULE_LICENSE("GPL");
Add QorIQ LS1046A pinctrl driver allowing i2c-core to exert GPIO control over the third and fourth I2C buses. Signed-off-by: David Leonard <David.Leonard@digi.com> --- drivers/pinctrl/freescale/Kconfig | 8 + drivers/pinctrl/freescale/Makefile | 1 + drivers/pinctrl/freescale/pinctrl-ls1046a.c | 224 ++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 drivers/pinctrl/freescale/pinctrl-ls1046a.c