* [PATCH v2 1/2] tegra20: add pinctrl driver @ 2013-05-10 18:28 Lucas Stach 2013-05-10 18:28 ` [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux Lucas Stach ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: Lucas Stach @ 2013-05-10 18:28 UTC (permalink / raw) To: barebox This adds a pinctrl driver for the Tegra 20 line of SoCs. It only supports the three basic pinconfiguration settings function mux, tristate control and pullup/down control. The driver understands the same devicetree bindings as the Linux one, unimplemented pinconfiguration options will be ignored. Signed-off-by: Lucas Stach <dev@lynxeye.de> --- v2: - use named regs - check for return value of request_mem_region --- arch/arm/dts/tegra20.dtsi | 8 + arch/arm/mach-tegra/Kconfig | 1 + drivers/pinctrl/Kconfig | 6 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-tegra20.c | 346 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 362 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-tegra20.c diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi index b7d1e27..f63ead8 100644 --- a/arch/arm/dts/tegra20.dtsi +++ b/arch/arm/dts/tegra20.dtsi @@ -34,6 +34,14 @@ interrupt-controller; }; + pinmux: pinmux { + compatible = "nvidia,tegra20-pinmux"; + reg = <0x70000014 0x10 /* Tri-state registers */ + 0x70000080 0x20 /* Mux registers */ + 0x700000a0 0x14 /* Pull-up/down registers */ + 0x70000868 0xa8>; /* Pad control registers */ + }; + pmc { compatible = "nvidia,tegra20-pmc"; reg = <0x7000e400 0x400>; diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 965e7ab..53ae070 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -5,6 +5,7 @@ choice config ARCH_TEGRA_2x_SOC bool "Tegra 20" + select PINCTRL_TEGRA20 endchoice diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e6aee50..0b859b8 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3 help This iomux controller is found on i.MX25,35,51,53,6. +config PINCTRL_TEGRA20 + select PINCTRL + bool "Tegra 20 pinmux" + help + The pinmux controller found on the Tegra 20 line of SoCs. + endmenu diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index e9272d0..169ed18 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o +obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c new file mode 100644 index 0000000..053981f --- /dev/null +++ b/drivers/pinctrl/pinctrl-tegra20.c @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de> + * + * Partly based on code + * Copyright (C) 2011-2012 NVIDIA Corporation <www.nvidia.com> + * Copyright (C) 2010 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * @file + * @brief Device driver for the Tegra 20 pincontrol hardware module. + */ + +#include <common.h> +#include <init.h> +#include <io.h> +#include <malloc.h> +#include <pinctrl.h> + +struct pinctrl_tegra20 { + struct { + u32 __iomem *tri; + u32 __iomem *mux; + u32 __iomem *pull; + } regs; + struct pinctrl_device pinctrl; +}; + +struct tegra20_pingroup { + const char *name; + const char *funcs[4]; + s16 trictrl_id; + s16 muxctrl_id; + s16 pullctrl_id; +}; + +#define PG(pg_name, f0, f1, f2, f3, tri, mux, pull) \ + { \ + .name = #pg_name, \ + .funcs = { #f0, #f1, #f2, #f3, }, \ + .trictrl_id = tri, \ + .muxctrl_id = mux, \ + .pullctrl_id = pull \ + } + +static const struct tegra20_pingroup tegra20_groups[] = { + /* name, f0, f1, f2, f3, tri, mux, pull */ + PG(ata, ide, nand, gmi, rsvd4, 0, 12, 0 ), + PG(atb, ide, nand, gmi, sdio4, 1, 8, 1 ), + PG(atc, ide, nand, gmi, sdio4, 2, 11, 2 ), + PG(atd, ide, nand, gmi, sdio4, 3, 10, 3 ), + PG(ate, ide, nand, gmi, rsvd4, 57, 6, 4 ), + PG(cdev1, osc, plla_out, pllm_out1, audio_sync, 4, 33, 32 ), + PG(cdev2, osc, ahb_clk, apb_clk, pllp_out4, 5, 34, 33 ), + PG(crtp, crt, rsvd2, rsvd3, rsvd4, 110, 105, 28 ), + PG(csus, pllc_out1, pllp_out2, pllp_out3, vi_sensor_clk, 6, 35, 60 ), + PG(dap1, dap1, rsvd2, gmi, sdio2, 7, 42, 5 ), + PG(dap2, dap2, twc, rsvd3, gmi, 8, 43, 6 ), + PG(dap3, dap3, rsvd2, rsvd3, rsvd4, 9, 44, 7 ), + PG(dap4, dap4, rsvd2, gmi, rsvd4, 10, 45, 8 ), + PG(ddc, i2c2, rsvd2, rsvd3, rsvd4, 63, 32, 78 ), + PG(dta, rsvd1, sdio2, vi, rsvd4, 11, 26, 9 ), + PG(dtb, rsvd1, rsvd2, vi, spi1, 12, 27, 10 ), + PG(dtc, rsvd1, rsvd2, vi, rsvd4, 13, 29, 11 ), + PG(dtd, rsvd1, sdio2, vi, rsvd4, 14, 30, 12 ), + PG(dte, rsvd1, rsvd2, vi, spi1, 15, 31, 13 ), + PG(dtf, i2c3, rsvd2, vi, rsvd4, 108, 110, 14 ), + PG(gma, uarte, spi3, gmi, sdio4, 28, 16, 74 ), + PG(gmb, ide, nand, gmi, gmi_int, 61, 46, 75 ), + PG(gmc, uartd, spi4, gmi, sflash, 29, 17, 76 ), + PG(gmd, rsvd1, nand, gmi, sflash, 62, 47, 77 ), + PG(gme, rsvd1, dap5, gmi, sdio4, 32, 48, 44 ), + PG(gpu, pwm, uarta, gmi, rsvd4, 16, 50, 26 ), + PG(gpu7, rtck, rsvd2, rsvd3, rsvd4, 107, 109, 19 ), + PG(gpv, pcie, rsvd2, rsvd3, rsvd4, 17, 49, 15 ), + PG(hdint, hdmi, rsvd2, rsvd3, rsvd4, 87, 18, -1 ), + PG(i2cp, i2cp, rsvd2, rsvd3, rsvd4, 18, 36, 17 ), + PG(irrx, uarta, uartb, gmi, spi4, 20, 41, 43 ), + PG(irtx, uarta, uartb, gmi, spi4, 19, 40, 42 ), + PG(kbca, kbc, nand, sdio2, emc_test0_dll, 22, 37, 20 ), + PG(kbcb, kbc, nand, sdio2, mio, 21, 38, 21 ), + PG(kbcc, kbc, nand, trace, emc_test1_dll, 58, 39, 22 ), + PG(kbcd, kbc, nand, sdio2, mio, 106, 108, 23 ), + PG(kbce, kbc, nand, owr, rsvd4, 26, 14, 65 ), + PG(kbcf, kbc, nand, trace, mio, 27, 13, 64 ), + PG(lcsn, displaya, displayb, spi3, rsvd4, 95, 70, -1 ), + PG(ld0, displaya, displayb, xio, rsvd4, 64, 80, -1 ), + PG(ld1, displaya, displayb, xio, rsvd4, 65, 81, -1 ), + PG(ld2, displaya, displayb, xio, rsvd4, 66, 82, -1 ), + PG(ld3, displaya, displayb, xio, rsvd4, 67, 83, -1 ), + PG(ld4, displaya, displayb, xio, rsvd4, 68, 84, -1 ), + PG(ld5, displaya, displayb, xio, rsvd4, 69, 85, -1 ), + PG(ld6, displaya, displayb, xio, rsvd4, 70, 86, -1 ), + PG(ld7, displaya, displayb, xio, rsvd4, 71, 87, -1 ), + PG(ld8, displaya, displayb, xio, rsvd4, 72, 88, -1 ), + PG(ld9, displaya, displayb, xio, rsvd4, 73, 89, -1 ), + PG(ld10, displaya, displayb, xio, rsvd4, 74, 90, -1 ), + PG(ld11, displaya, displayb, xio, rsvd4, 75, 91, -1 ), + PG(ld12, displaya, displayb, xio, rsvd4, 76, 92, -1 ), + PG(ld13, displaya, displayb, xio, rsvd4, 77, 93, -1 ), + PG(ld14, displaya, displayb, xio, rsvd4, 78, 94, -1 ), + PG(ld15, displaya, displayb, xio, rsvd4, 79, 95, -1 ), + PG(ld16, displaya, displayb, xio, rsvd4, 80, 96, -1 ), + PG(ld17, displaya, displayb, rsvd3, rsvd4, 81, 97, -1 ), + PG(ldc, displaya, displayb, rsvd3, rsvd4, 94, 71, -1 ), + PG(ldi, displaya, displayb, rsvd3, rsvd4, 102, 104, -1 ), + PG(lhp0, displaya, displayb, rsvd3, rsvd4, 82, 101, -1 ), + PG(lhp1, displaya, displayb, rsvd3, rsvd4, 83, 98, -1 ), + PG(lhp2, displaya, displayb, rsvd3, rsvd4, 84, 99, -1 ), + PG(lhs, displaya, displayb, xio, rsvd4, 103, 75, -1 ), + PG(lm0, displaya, displayb, spi3, rsvd4, 88, 77, -1 ), + PG(lm1, displaya, displayb, rsvd3, CRT, 89, 78, -1 ), + PG(lpp, displaya, displayb, rsvd3, rsvd4, 104, 103, -1 ), + PG(lpw0, displaya, displayb, spi3, hdmi, 99, 64, -1 ), + PG(lpw1, displaya, displayb, rsvd3, rsvd4, 100, 65, -1 ), + PG(lpw2, displaya, displayb, spi3, hdmi, 101, 66, -1 ), + PG(lsc0, displaya, displayb, xio, rsvd4, 91, 73, -1 ), + PG(lsc1, displaya, displayb, spi3, hdmi, 92, 74, -1 ), + PG(lsck, displaya, displayb, spi3, hdmi, 93, 72, -1 ), + PG(lsda, displaya, displayb, spi3, hdmi, 97, 68, -1 ), + PG(lsdi, displaya, displayb, spi3, rsvd4, 98, 67, -1 ), + PG(lspi, displaya, displayb, xio, hdmi, 96, 69, -1 ), + PG(lvp0, displaya, displayb, rsvd3, rsvd4, 85, 79, -1 ), + PG(lvp1, displaya, displayb, rsvd3, rsvd4, 86, 100, -1 ), + PG(lvs, displaya, displayb, xio, rsvd4, 90, 76, -1 ), + PG(owc, owr, rsvd2, rsvd3, rsvd4, 31, 20, 79 ), + PG(pmc, pwr_on, pwr_intr, rsvd3, rsvd4, 23, 105, -1 ), + PG(pta, i2c2, hdmi, gmi, rsvd4, 24, 107, 18 ), + PG(rm, i2c1, rsvd2, rsvd3, rsvd4, 25, 7, 16 ), + PG(sdb, uarta, pwm, sdio3, spi2, 111, 53, -1 ), + PG(sdc, pwm, twc, sdio3, spi3, 33, 54, 62 ), + PG(sdd, uarta, pwm, sdio3, spi3, 34, 55, 63 ), + PG(sdio1, sdio1, rsvd2, uarte, uarta, 30, 15, 73 ), + PG(slxa, pcie, spi4, sdio3, spi2, 36, 19, 27 ), + PG(slxc, spdif, spi4, sdio3, spi2, 37, 21, 29 ), + PG(slxd, spdif, spi4, sdio3, spi2, 38, 22, 30 ), + PG(slxk, pcie, spi4, sdio3, spi2, 39, 23, 31 ), + PG(spdi, spdif, rsvd2, i2c1, sdio2, 40, 52, 24 ), + PG(spdo, spdif, rsvd2, i2c1, sdio2, 41, 51, 25 ), + PG(spia, spi1, spi2, spi3, gmi, 42, 63, 34 ), + PG(spib, spi1, spi2, spi3, gmi, 43, 62, 35 ), + PG(spic, spi1, spi2, spi3, gmi, 44, 61, 36 ), + PG(spid, spi2, spi1, spi2_alt, gmi, 45, 60, 37 ), + PG(spie, spi2, spi1, spi2_alt, gmi, 46, 59, 38 ), + PG(spif, spi3, spi1, spi2, rsvd4, 47, 58, 39 ), + PG(spig, spi3, spi2, spi2_alt, i2c1, 48, 57, 40 ), + PG(spih, spi3, spi2, spi2_alt, i2c1, 49, 56, 41 ), + PG(uaa, spi3, mipi_hs, uarta, ulpi, 50, 0, 48 ), + PG(uab, spi2, mipi_hs, uarta, ulpi, 51, 1, 49 ), + PG(uac, owr, rsvd2, rsvd3, rsvd4, 52, 2, 50 ), + PG(uad, irda, spdif, uarta, spi4, 53, 3, 51 ), + PG(uca, uartc, rsvd2, gmi, rsvd4, 54, 24, 52 ), + PG(ucb, uartc, pwm, gmi, rsvd4, 55, 25, 53 ), + PG(uda, spi1, rsvd2, uartd, ulpi, 109, 4, 72 ), +}; + +static void pinctrl_tegra20_set_func(struct pinctrl_tegra20 *ctrl, + int muxctrl_id, int func) +{ + u32 __iomem *regaddr = ctrl->regs.mux; + u32 reg; + int maskbit; + + regaddr += muxctrl_id >> 4; + maskbit = (muxctrl_id << 1) & 0x1f; + + reg = readl(regaddr); + reg &= ~(0x3 << maskbit); + reg |= func << maskbit; + writel(reg, regaddr); +} + +static void pinctrl_tegra20_set_pull(struct pinctrl_tegra20 *ctrl, + int pullctrl_id, int pull) +{ + u32 __iomem *regaddr = ctrl->regs.pull; + u32 reg; + int maskbit; + + regaddr += pullctrl_id >> 4; + maskbit = (pullctrl_id << 1) & 0x1f; + + reg = readl(regaddr); + reg &= ~(0x3 << maskbit); + reg |= pull << maskbit; + writel(reg, regaddr); +} + +static void pinctrl_tegra20_set_tristate(struct pinctrl_tegra20 *ctrl, + int trictrl_id, int tristate) +{ + u32 __iomem *regaddr = ctrl->regs.tri; + u32 reg; + int maskbit; + + regaddr += trictrl_id >> 5; + maskbit = trictrl_id & 0x1f; + + reg = readl(regaddr); + reg &= ~(1 << maskbit); + reg |= tristate << maskbit; + writel(reg, regaddr); +} + +static int pinctrl_tegra20_set_state(struct pinctrl_device *pdev, + struct device_node *np) +{ + struct pinctrl_tegra20 *ctrl = + container_of(pdev, struct pinctrl_tegra20, pinctrl); + struct device_node *childnode; + int pull = -1, tri = -1, i, j, k; + const char *pins, *func = NULL; + const struct tegra20_pingroup *group; + + /* + * At first look if the node we are pointed at has children, + * which we may want to visit. + */ + list_for_each_entry(childnode, &np->children, parent_list) + pinctrl_tegra20_set_state(pdev, childnode); + + /* read relevant state from devicetree */ + of_property_read_string(np, "nvidia,function", &func); + of_property_read_u32_array(np, "nvidia,pull", &pull, 1); + of_property_read_u32_array(np, "nvidia,tristate", &tri, 1); + + /* iterate over all pingroups referenced in the dt node */ + for (i = 0; ; i++) { + if (of_property_read_string_index(np, "nvidia,pins", i, &pins)) + break; + + for (j = 0; j < ARRAY_SIZE(tegra20_groups); j++) { + if (!strcmp(pins, tegra20_groups[j].name)) { + group = &tegra20_groups[j]; + break; + } + } + /* if no matching pingroup is found bail out */ + if (j == ARRAY_SIZE(tegra20_groups)) { + dev_warn(ctrl->pinctrl.dev, + "invalid pingroup %s referenced in node %s\n", + pins, np->name); + continue; + } + + if (func) { + for (k = 0; k < 4; k++) { + if (!strcmp(func, group->funcs[k])) + break; + } + if (k < 4) + pinctrl_tegra20_set_func(ctrl, + group->muxctrl_id, k); + else + dev_warn(ctrl->pinctrl.dev, + "invalid function %s for pingroup %s in node %s\n", + func, group->name, np->name); + } + + if (pull >= 0) { + if (group->pullctrl_id >= 0) + pinctrl_tegra20_set_pull(ctrl, + group->pullctrl_id, + pull); + else + dev_warn(ctrl->pinctrl.dev, + "pingroup %s in node %s doesn't support pull configuration\n", + group->name, np->name); + } + + if (tri >= 0) + pinctrl_tegra20_set_tristate(ctrl, + group->trictrl_id, tri); + } + + return 0; +} + +static struct pinctrl_ops pinctrl_tegra20_ops = { + .set_state = pinctrl_tegra20_set_state, +}; + +static int pinctrl_tegra20_probe(struct device_d *dev) +{ + struct pinctrl_tegra20 *ctrl; + int i, ret; + u32 **regs; + + ctrl = xzalloc(sizeof(*ctrl)); + + /* + * Tegra pincontrol is split out into four independent memory ranges: + * tristate control, function mux, pullup/down control, pad control + * (from lowest to highest hardware address). + * We are only interested in the first three for now. + */ + regs = (u32 **)&ctrl->regs; + for (i = 0; i <= 2; i++) { + regs[i] = dev_request_mem_region(dev, i); + if (!regs[i]) { + dev_err(dev, "Could not get iomem region %d\n", i); + return -ENODEV; + } + } + + ctrl->pinctrl.dev = dev; + ctrl->pinctrl.ops = &pinctrl_tegra20_ops; + + ret = pinctrl_register(&ctrl->pinctrl); + if (ret) + free(ctrl); + + return ret; +} + +static __maybe_unused struct of_device_id pinctrl_tegra20_dt_ids[] = { + { + .compatible = "nvidia,tegra20-pinmux", + }, { + /* sentinel */ + } +}; + +static struct driver_d pinctrl_tegra20_driver = { + .name = "pinctrl-tegra20", + .probe = pinctrl_tegra20_probe, + .of_compatible = DRV_OF_COMPAT(pinctrl_tegra20_dt_ids), +}; + +static int pinctrl_tegra20_init(void) +{ + return platform_driver_register(&pinctrl_tegra20_driver); +} +postcore_initcall(pinctrl_tegra20_init); -- 1.8.1.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux 2013-05-10 18:28 [PATCH v2 1/2] tegra20: add pinctrl driver Lucas Stach @ 2013-05-10 18:28 ` Lucas Stach 2013-05-10 19:03 ` [PATCH v2 1/2] tegra20: add pinctrl driver Alexander Aring 2013-10-22 15:07 ` Uwe Kleine-König 2 siblings, 0 replies; 6+ messages in thread From: Lucas Stach @ 2013-05-10 18:28 UTC (permalink / raw) To: barebox Signed-off-by: Lucas Stach <dev@lynxeye.de> --- arch/arm/dts/tegra20-paz00.dts | 216 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) diff --git a/arch/arm/dts/tegra20-paz00.dts b/arch/arm/dts/tegra20-paz00.dts index 09ccb8b..e8486aa 100644 --- a/arch/arm/dts/tegra20-paz00.dts +++ b/arch/arm/dts/tegra20-paz00.dts @@ -9,4 +9,220 @@ memory { reg = <0x00000000 0x20000000>; }; + + pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + ata { + nvidia,pins = "ata", "atc", "atd", "ate", + "dap2", "gmb", "gmc", "gmd", "spia", + "spib", "spic", "spid", "spie"; + nvidia,function = "gmi"; + }; + atb { + nvidia,pins = "atb", "gma", "gme"; + nvidia,function = "sdio4"; + }; + cdev1 { + nvidia,pins = "cdev1"; + nvidia,function = "plla_out"; + }; + cdev2 { + nvidia,pins = "cdev2"; + nvidia,function = "pllp_out4"; + }; + crtp { + nvidia,pins = "crtp"; + nvidia,function = "crt"; + }; + csus { + nvidia,pins = "csus"; + nvidia,function = "pllc_out1"; + }; + dap1 { + nvidia,pins = "dap1"; + nvidia,function = "dap1"; + }; + dap3 { + nvidia,pins = "dap3"; + nvidia,function = "dap3"; + }; + dap4 { + nvidia,pins = "dap4"; + nvidia,function = "dap4"; + }; + ddc { + nvidia,pins = "ddc"; + nvidia,function = "i2c2"; + }; + dta { + nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte"; + nvidia,function = "rsvd1"; + }; + dtf { + nvidia,pins = "dtf"; + nvidia,function = "i2c3"; + }; + gpu { + nvidia,pins = "gpu", "sdb", "sdd"; + nvidia,function = "pwm"; + }; + gpu7 { + nvidia,pins = "gpu7"; + nvidia,function = "rtck"; + }; + gpv { + nvidia,pins = "gpv", "slxa", "slxk"; + nvidia,function = "pcie"; + }; + hdint { + nvidia,pins = "hdint", "pta"; + nvidia,function = "hdmi"; + }; + i2cp { + nvidia,pins = "i2cp"; + nvidia,function = "i2cp"; + }; + irrx { + nvidia,pins = "irrx", "irtx"; + nvidia,function = "uarta"; + }; + kbca { + nvidia,pins = "kbca", "kbcc", "kbce", "kbcf"; + nvidia,function = "kbc"; + }; + kbcb { + nvidia,pins = "kbcb", "kbcd"; + nvidia,function = "sdio2"; + }; + lcsn { + nvidia,pins = "lcsn", "ld0", "ld1", "ld2", + "ld3", "ld4", "ld5", "ld6", "ld7", + "ld8", "ld9", "ld10", "ld11", "ld12", + "ld13", "ld14", "ld15", "ld16", "ld17", + "ldc", "ldi", "lhp0", "lhp1", "lhp2", + "lhs", "lm0", "lm1", "lpp", "lpw0", + "lpw1", "lpw2", "lsc0", "lsc1", "lsck", + "lsda", "lsdi", "lspi", "lvp0", "lvp1", + "lvs"; + nvidia,function = "displaya"; + }; + owc { + nvidia,pins = "owc"; + nvidia,function = "owr"; + }; + pmc { + nvidia,pins = "pmc"; + nvidia,function = "pwr_on"; + }; + rm { + nvidia,pins = "rm"; + nvidia,function = "i2c1"; + }; + sdc { + nvidia,pins = "sdc"; + nvidia,function = "twc"; + }; + sdio1 { + nvidia,pins = "sdio1"; + nvidia,function = "sdio1"; + }; + slxc { + nvidia,pins = "slxc", "slxd"; + nvidia,function = "spi4"; + }; + spdi { + nvidia,pins = "spdi", "spdo"; + nvidia,function = "rsvd2"; + }; + spif { + nvidia,pins = "spif", "uac"; + nvidia,function = "rsvd4"; + }; + spig { + nvidia,pins = "spig", "spih"; + nvidia,function = "spi2_alt"; + }; + uaa { + nvidia,pins = "uaa", "uab", "uda"; + nvidia,function = "ulpi"; + }; + uad { + nvidia,pins = "uad"; + nvidia,function = "spdif"; + }; + uca { + nvidia,pins = "uca", "ucb"; + nvidia,function = "uartc"; + }; + conf_ata { + nvidia,pins = "ata", "atb", "atc", "atd", "ate", + "cdev1", "cdev2", "dap1", "dap2", "dtf", + "gma", "gmb", "gmc", "gmd", "gme", + "gpu", "gpu7", "gpv", "i2cp", "pta", + "rm", "sdio1", "slxk", "spdo", "uac", + "uda"; + nvidia,pull = <0>; + nvidia,tristate = <0>; + }; + conf_ck32 { + nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", + "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; + nvidia,pull = <0>; + }; + conf_crtp { + nvidia,pins = "crtp", "dap3", "dap4", "dtb", + "dtc", "dte", "slxa", "slxc", "slxd", + "spdi"; + nvidia,pull = <0>; + nvidia,tristate = <1>; + }; + conf_csus { + nvidia,pins = "csus", "spia", "spib", "spid", + "spif"; + nvidia,pull = <1>; + nvidia,tristate = <1>; + }; + conf_ddc { + nvidia,pins = "ddc", "irrx", "irtx", "kbca", + "kbcb", "kbcc", "kbcd", "kbce", "kbcf", + "spic", "spig", "uaa", "uab"; + nvidia,pull = <2>; + nvidia,tristate = <0>; + }; + conf_dta { + nvidia,pins = "dta", "dtd", "owc", "sdc", "sdd", + "spie", "spih", "uad", "uca", "ucb"; + nvidia,pull = <2>; + nvidia,tristate = <1>; + }; + conf_hdint { + nvidia,pins = "hdint", "ld0", "ld1", "ld2", + "ld3", "ld4", "ld5", "ld6", "ld7", + "ld8", "ld9", "ld10", "ld11", "ld12", + "ld13", "ld14", "ld15", "ld16", "ld17", + "ldc", "ldi", "lhs", "lsc0", "lspi", + "lvs", "pmc"; + nvidia,tristate = <0>; + }; + conf_lc { + nvidia,pins = "lc", "ls"; + nvidia,pull = <2>; + }; + conf_lcsn { + nvidia,pins = "lcsn", "lhp0", "lhp1", "lhp2", + "lm0", "lm1", "lpp", "lpw0", "lpw1", + "lpw2", "lsc1", "lsck", "lsda", "lsdi", + "lvp0", "lvp1", "sdb"; + nvidia,tristate = <1>; + }; + conf_ld17_0 { + nvidia,pins = "ld17_0", "ld19_18", "ld21_20", + "ld23_22"; + nvidia,pull = <1>; + }; + }; + }; }; -- 1.8.1.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] tegra20: add pinctrl driver 2013-05-10 18:28 [PATCH v2 1/2] tegra20: add pinctrl driver Lucas Stach 2013-05-10 18:28 ` [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux Lucas Stach @ 2013-05-10 19:03 ` Alexander Aring 2013-05-11 15:17 ` Sascha Hauer 2013-10-22 15:07 ` Uwe Kleine-König 2 siblings, 1 reply; 6+ messages in thread From: Alexander Aring @ 2013-05-10 19:03 UTC (permalink / raw) To: Lucas Stach; +Cc: barebox Hi Lucas, On Fri, May 10, 2013 at 08:28:57PM +0200, Lucas Stach wrote: > This adds a pinctrl driver for the Tegra 20 line of SoCs. It only > supports the three basic pinconfiguration settings function mux, > tristate control and pullup/down control. > > The driver understands the same devicetree bindings as the Linux one, > unimplemented pinconfiguration options will be ignored. > > Signed-off-by: Lucas Stach <dev@lynxeye.de> > --- > v2: > - use named regs > - check for return value of request_mem_region > --- > arch/arm/dts/tegra20.dtsi | 8 + > arch/arm/mach-tegra/Kconfig | 1 + > drivers/pinctrl/Kconfig | 6 + > drivers/pinctrl/Makefile | 1 + > drivers/pinctrl/pinctrl-tegra20.c | 346 ++++++++++++++++++++++++++++++++++++++ > 5 files changed, 362 insertions(+) > create mode 100644 drivers/pinctrl/pinctrl-tegra20.c > > diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi > index b7d1e27..f63ead8 100644 > --- a/arch/arm/dts/tegra20.dtsi > +++ b/arch/arm/dts/tegra20.dtsi > @@ -34,6 +34,14 @@ > interrupt-controller; > }; > > + pinmux: pinmux { > + compatible = "nvidia,tegra20-pinmux"; > + reg = <0x70000014 0x10 /* Tri-state registers */ > + 0x70000080 0x20 /* Mux registers */ > + 0x700000a0 0x14 /* Pull-up/down registers */ > + 0x70000868 0xa8>; /* Pad control registers */ > + }; > + > pmc { > compatible = "nvidia,tegra20-pmc"; > reg = <0x7000e400 0x400>; > diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig > index 965e7ab..53ae070 100644 > --- a/arch/arm/mach-tegra/Kconfig > +++ b/arch/arm/mach-tegra/Kconfig > @@ -5,6 +5,7 @@ choice > > config ARCH_TEGRA_2x_SOC > bool "Tegra 20" > + select PINCTRL_TEGRA20 > > endchoice > > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig > index e6aee50..0b859b8 100644 > --- a/drivers/pinctrl/Kconfig > +++ b/drivers/pinctrl/Kconfig > @@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3 > help > This iomux controller is found on i.MX25,35,51,53,6. > > +config PINCTRL_TEGRA20 > + select PINCTRL > + bool "Tegra 20 pinmux" > + help > + The pinmux controller found on the Tegra 20 line of SoCs. > + > endmenu > diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile > index e9272d0..169ed18 100644 > --- a/drivers/pinctrl/Makefile > +++ b/drivers/pinctrl/Makefile > @@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o > obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o > obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o > obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o > +obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o > diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c > new file mode 100644 > index 0000000..053981f > --- /dev/null > +++ b/drivers/pinctrl/pinctrl-tegra20.c > @@ -0,0 +1,346 @@ > +/* > + * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de> > + * > + * Partly based on code > + * Copyright (C) 2011-2012 NVIDIA Corporation <www.nvidia.com> > + * Copyright (C) 2010 Google, Inc. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +/** > + * @file > + * @brief Device driver for the Tegra 20 pincontrol hardware module. > + */ > + > +#include <common.h> > +#include <init.h> > +#include <io.h> > +#include <malloc.h> > +#include <pinctrl.h> > + > +struct pinctrl_tegra20 { > + struct { > + u32 __iomem *tri; > + u32 __iomem *mux; > + u32 __iomem *pull; > + } regs; > + struct pinctrl_device pinctrl; > +}; > + > +struct tegra20_pingroup { > + const char *name; > + const char *funcs[4]; > + s16 trictrl_id; > + s16 muxctrl_id; > + s16 pullctrl_id; > +}; > + > +#define PG(pg_name, f0, f1, f2, f3, tri, mux, pull) \ > + { \ > + .name = #pg_name, \ > + .funcs = { #f0, #f1, #f2, #f3, }, \ > + .trictrl_id = tri, \ > + .muxctrl_id = mux, \ > + .pullctrl_id = pull \ > + } > + > +static const struct tegra20_pingroup tegra20_groups[] = { > + /* name, f0, f1, f2, f3, tri, mux, pull */ > + PG(ata, ide, nand, gmi, rsvd4, 0, 12, 0 ), > + PG(atb, ide, nand, gmi, sdio4, 1, 8, 1 ), > + PG(atc, ide, nand, gmi, sdio4, 2, 11, 2 ), > + PG(atd, ide, nand, gmi, sdio4, 3, 10, 3 ), > + PG(ate, ide, nand, gmi, rsvd4, 57, 6, 4 ), > + PG(cdev1, osc, plla_out, pllm_out1, audio_sync, 4, 33, 32 ), > + PG(cdev2, osc, ahb_clk, apb_clk, pllp_out4, 5, 34, 33 ), > + PG(crtp, crt, rsvd2, rsvd3, rsvd4, 110, 105, 28 ), > + PG(csus, pllc_out1, pllp_out2, pllp_out3, vi_sensor_clk, 6, 35, 60 ), > + PG(dap1, dap1, rsvd2, gmi, sdio2, 7, 42, 5 ), > + PG(dap2, dap2, twc, rsvd3, gmi, 8, 43, 6 ), > + PG(dap3, dap3, rsvd2, rsvd3, rsvd4, 9, 44, 7 ), > + PG(dap4, dap4, rsvd2, gmi, rsvd4, 10, 45, 8 ), > + PG(ddc, i2c2, rsvd2, rsvd3, rsvd4, 63, 32, 78 ), > + PG(dta, rsvd1, sdio2, vi, rsvd4, 11, 26, 9 ), > + PG(dtb, rsvd1, rsvd2, vi, spi1, 12, 27, 10 ), > + PG(dtc, rsvd1, rsvd2, vi, rsvd4, 13, 29, 11 ), > + PG(dtd, rsvd1, sdio2, vi, rsvd4, 14, 30, 12 ), > + PG(dte, rsvd1, rsvd2, vi, spi1, 15, 31, 13 ), > + PG(dtf, i2c3, rsvd2, vi, rsvd4, 108, 110, 14 ), > + PG(gma, uarte, spi3, gmi, sdio4, 28, 16, 74 ), > + PG(gmb, ide, nand, gmi, gmi_int, 61, 46, 75 ), > + PG(gmc, uartd, spi4, gmi, sflash, 29, 17, 76 ), > + PG(gmd, rsvd1, nand, gmi, sflash, 62, 47, 77 ), > + PG(gme, rsvd1, dap5, gmi, sdio4, 32, 48, 44 ), > + PG(gpu, pwm, uarta, gmi, rsvd4, 16, 50, 26 ), > + PG(gpu7, rtck, rsvd2, rsvd3, rsvd4, 107, 109, 19 ), > + PG(gpv, pcie, rsvd2, rsvd3, rsvd4, 17, 49, 15 ), > + PG(hdint, hdmi, rsvd2, rsvd3, rsvd4, 87, 18, -1 ), > + PG(i2cp, i2cp, rsvd2, rsvd3, rsvd4, 18, 36, 17 ), > + PG(irrx, uarta, uartb, gmi, spi4, 20, 41, 43 ), > + PG(irtx, uarta, uartb, gmi, spi4, 19, 40, 42 ), > + PG(kbca, kbc, nand, sdio2, emc_test0_dll, 22, 37, 20 ), > + PG(kbcb, kbc, nand, sdio2, mio, 21, 38, 21 ), > + PG(kbcc, kbc, nand, trace, emc_test1_dll, 58, 39, 22 ), > + PG(kbcd, kbc, nand, sdio2, mio, 106, 108, 23 ), > + PG(kbce, kbc, nand, owr, rsvd4, 26, 14, 65 ), > + PG(kbcf, kbc, nand, trace, mio, 27, 13, 64 ), > + PG(lcsn, displaya, displayb, spi3, rsvd4, 95, 70, -1 ), > + PG(ld0, displaya, displayb, xio, rsvd4, 64, 80, -1 ), > + PG(ld1, displaya, displayb, xio, rsvd4, 65, 81, -1 ), > + PG(ld2, displaya, displayb, xio, rsvd4, 66, 82, -1 ), > + PG(ld3, displaya, displayb, xio, rsvd4, 67, 83, -1 ), > + PG(ld4, displaya, displayb, xio, rsvd4, 68, 84, -1 ), > + PG(ld5, displaya, displayb, xio, rsvd4, 69, 85, -1 ), > + PG(ld6, displaya, displayb, xio, rsvd4, 70, 86, -1 ), > + PG(ld7, displaya, displayb, xio, rsvd4, 71, 87, -1 ), > + PG(ld8, displaya, displayb, xio, rsvd4, 72, 88, -1 ), > + PG(ld9, displaya, displayb, xio, rsvd4, 73, 89, -1 ), > + PG(ld10, displaya, displayb, xio, rsvd4, 74, 90, -1 ), > + PG(ld11, displaya, displayb, xio, rsvd4, 75, 91, -1 ), > + PG(ld12, displaya, displayb, xio, rsvd4, 76, 92, -1 ), > + PG(ld13, displaya, displayb, xio, rsvd4, 77, 93, -1 ), > + PG(ld14, displaya, displayb, xio, rsvd4, 78, 94, -1 ), > + PG(ld15, displaya, displayb, xio, rsvd4, 79, 95, -1 ), > + PG(ld16, displaya, displayb, xio, rsvd4, 80, 96, -1 ), > + PG(ld17, displaya, displayb, rsvd3, rsvd4, 81, 97, -1 ), > + PG(ldc, displaya, displayb, rsvd3, rsvd4, 94, 71, -1 ), > + PG(ldi, displaya, displayb, rsvd3, rsvd4, 102, 104, -1 ), > + PG(lhp0, displaya, displayb, rsvd3, rsvd4, 82, 101, -1 ), > + PG(lhp1, displaya, displayb, rsvd3, rsvd4, 83, 98, -1 ), > + PG(lhp2, displaya, displayb, rsvd3, rsvd4, 84, 99, -1 ), > + PG(lhs, displaya, displayb, xio, rsvd4, 103, 75, -1 ), > + PG(lm0, displaya, displayb, spi3, rsvd4, 88, 77, -1 ), > + PG(lm1, displaya, displayb, rsvd3, CRT, 89, 78, -1 ), > + PG(lpp, displaya, displayb, rsvd3, rsvd4, 104, 103, -1 ), > + PG(lpw0, displaya, displayb, spi3, hdmi, 99, 64, -1 ), > + PG(lpw1, displaya, displayb, rsvd3, rsvd4, 100, 65, -1 ), > + PG(lpw2, displaya, displayb, spi3, hdmi, 101, 66, -1 ), > + PG(lsc0, displaya, displayb, xio, rsvd4, 91, 73, -1 ), > + PG(lsc1, displaya, displayb, spi3, hdmi, 92, 74, -1 ), > + PG(lsck, displaya, displayb, spi3, hdmi, 93, 72, -1 ), > + PG(lsda, displaya, displayb, spi3, hdmi, 97, 68, -1 ), > + PG(lsdi, displaya, displayb, spi3, rsvd4, 98, 67, -1 ), > + PG(lspi, displaya, displayb, xio, hdmi, 96, 69, -1 ), > + PG(lvp0, displaya, displayb, rsvd3, rsvd4, 85, 79, -1 ), > + PG(lvp1, displaya, displayb, rsvd3, rsvd4, 86, 100, -1 ), > + PG(lvs, displaya, displayb, xio, rsvd4, 90, 76, -1 ), > + PG(owc, owr, rsvd2, rsvd3, rsvd4, 31, 20, 79 ), > + PG(pmc, pwr_on, pwr_intr, rsvd3, rsvd4, 23, 105, -1 ), > + PG(pta, i2c2, hdmi, gmi, rsvd4, 24, 107, 18 ), > + PG(rm, i2c1, rsvd2, rsvd3, rsvd4, 25, 7, 16 ), > + PG(sdb, uarta, pwm, sdio3, spi2, 111, 53, -1 ), > + PG(sdc, pwm, twc, sdio3, spi3, 33, 54, 62 ), > + PG(sdd, uarta, pwm, sdio3, spi3, 34, 55, 63 ), > + PG(sdio1, sdio1, rsvd2, uarte, uarta, 30, 15, 73 ), > + PG(slxa, pcie, spi4, sdio3, spi2, 36, 19, 27 ), > + PG(slxc, spdif, spi4, sdio3, spi2, 37, 21, 29 ), > + PG(slxd, spdif, spi4, sdio3, spi2, 38, 22, 30 ), > + PG(slxk, pcie, spi4, sdio3, spi2, 39, 23, 31 ), > + PG(spdi, spdif, rsvd2, i2c1, sdio2, 40, 52, 24 ), > + PG(spdo, spdif, rsvd2, i2c1, sdio2, 41, 51, 25 ), > + PG(spia, spi1, spi2, spi3, gmi, 42, 63, 34 ), > + PG(spib, spi1, spi2, spi3, gmi, 43, 62, 35 ), > + PG(spic, spi1, spi2, spi3, gmi, 44, 61, 36 ), > + PG(spid, spi2, spi1, spi2_alt, gmi, 45, 60, 37 ), > + PG(spie, spi2, spi1, spi2_alt, gmi, 46, 59, 38 ), > + PG(spif, spi3, spi1, spi2, rsvd4, 47, 58, 39 ), > + PG(spig, spi3, spi2, spi2_alt, i2c1, 48, 57, 40 ), > + PG(spih, spi3, spi2, spi2_alt, i2c1, 49, 56, 41 ), > + PG(uaa, spi3, mipi_hs, uarta, ulpi, 50, 0, 48 ), > + PG(uab, spi2, mipi_hs, uarta, ulpi, 51, 1, 49 ), > + PG(uac, owr, rsvd2, rsvd3, rsvd4, 52, 2, 50 ), > + PG(uad, irda, spdif, uarta, spi4, 53, 3, 51 ), > + PG(uca, uartc, rsvd2, gmi, rsvd4, 54, 24, 52 ), > + PG(ucb, uartc, pwm, gmi, rsvd4, 55, 25, 53 ), > + PG(uda, spi1, rsvd2, uartd, ulpi, 109, 4, 72 ), > +}; > + > +static void pinctrl_tegra20_set_func(struct pinctrl_tegra20 *ctrl, > + int muxctrl_id, int func) > +{ > + u32 __iomem *regaddr = ctrl->regs.mux; > + u32 reg; > + int maskbit; > + > + regaddr += muxctrl_id >> 4; > + maskbit = (muxctrl_id << 1) & 0x1f; > + > + reg = readl(regaddr); > + reg &= ~(0x3 << maskbit); > + reg |= func << maskbit; > + writel(reg, regaddr); > +} > + > +static void pinctrl_tegra20_set_pull(struct pinctrl_tegra20 *ctrl, > + int pullctrl_id, int pull) > +{ > + u32 __iomem *regaddr = ctrl->regs.pull; > + u32 reg; > + int maskbit; > + > + regaddr += pullctrl_id >> 4; > + maskbit = (pullctrl_id << 1) & 0x1f; > + > + reg = readl(regaddr); > + reg &= ~(0x3 << maskbit); > + reg |= pull << maskbit; > + writel(reg, regaddr); > +} > + > +static void pinctrl_tegra20_set_tristate(struct pinctrl_tegra20 *ctrl, > + int trictrl_id, int tristate) > +{ > + u32 __iomem *regaddr = ctrl->regs.tri; > + u32 reg; > + int maskbit; > + > + regaddr += trictrl_id >> 5; > + maskbit = trictrl_id & 0x1f; > + > + reg = readl(regaddr); > + reg &= ~(1 << maskbit); > + reg |= tristate << maskbit; > + writel(reg, regaddr); > +} > + > +static int pinctrl_tegra20_set_state(struct pinctrl_device *pdev, > + struct device_node *np) > +{ > + struct pinctrl_tegra20 *ctrl = > + container_of(pdev, struct pinctrl_tegra20, pinctrl); > + struct device_node *childnode; > + int pull = -1, tri = -1, i, j, k; > + const char *pins, *func = NULL; > + const struct tegra20_pingroup *group; > + > + /* > + * At first look if the node we are pointed at has children, > + * which we may want to visit. > + */ > + list_for_each_entry(childnode, &np->children, parent_list) > + pinctrl_tegra20_set_state(pdev, childnode); > + > + /* read relevant state from devicetree */ > + of_property_read_string(np, "nvidia,function", &func); > + of_property_read_u32_array(np, "nvidia,pull", &pull, 1); > + of_property_read_u32_array(np, "nvidia,tristate", &tri, 1); > + > + /* iterate over all pingroups referenced in the dt node */ > + for (i = 0; ; i++) { > + if (of_property_read_string_index(np, "nvidia,pins", i, &pins)) > + break; > + > + for (j = 0; j < ARRAY_SIZE(tegra20_groups); j++) { > + if (!strcmp(pins, tegra20_groups[j].name)) { > + group = &tegra20_groups[j]; > + break; > + } > + } > + /* if no matching pingroup is found bail out */ > + if (j == ARRAY_SIZE(tegra20_groups)) { > + dev_warn(ctrl->pinctrl.dev, > + "invalid pingroup %s referenced in node %s\n", > + pins, np->name); > + continue; > + } > + > + if (func) { > + for (k = 0; k < 4; k++) { > + if (!strcmp(func, group->funcs[k])) > + break; > + } > + if (k < 4) > + pinctrl_tegra20_set_func(ctrl, > + group->muxctrl_id, k); > + else > + dev_warn(ctrl->pinctrl.dev, > + "invalid function %s for pingroup %s in node %s\n", > + func, group->name, np->name); > + } > + > + if (pull >= 0) { > + if (group->pullctrl_id >= 0) > + pinctrl_tegra20_set_pull(ctrl, > + group->pullctrl_id, > + pull); > + else > + dev_warn(ctrl->pinctrl.dev, > + "pingroup %s in node %s doesn't support pull configuration\n", > + group->name, np->name); > + } > + > + if (tri >= 0) > + pinctrl_tegra20_set_tristate(ctrl, > + group->trictrl_id, tri); > + } > + > + return 0; > +} > + > +static struct pinctrl_ops pinctrl_tegra20_ops = { > + .set_state = pinctrl_tegra20_set_state, > +}; > + > +static int pinctrl_tegra20_probe(struct device_d *dev) > +{ > + struct pinctrl_tegra20 *ctrl; > + int i, ret; > + u32 **regs; > + > + ctrl = xzalloc(sizeof(*ctrl)); > + > + /* > + * Tegra pincontrol is split out into four independent memory ranges: > + * tristate control, function mux, pullup/down control, pad control > + * (from lowest to highest hardware address). > + * We are only interested in the first three for now. > + */ > + regs = (u32 **)&ctrl->regs; > + for (i = 0; i <= 2; i++) { > + regs[i] = dev_request_mem_region(dev, i); > + if (!regs[i]) { > + dev_err(dev, "Could not get iomem region %d\n", i); Do we need a free(ctrl); here? Regards Alex _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] tegra20: add pinctrl driver 2013-05-10 19:03 ` [PATCH v2 1/2] tegra20: add pinctrl driver Alexander Aring @ 2013-05-11 15:17 ` Sascha Hauer 2013-05-12 13:48 ` Jean-Christophe PLAGNIOL-VILLARD 0 siblings, 1 reply; 6+ messages in thread From: Sascha Hauer @ 2013-05-11 15:17 UTC (permalink / raw) To: Alexander Aring; +Cc: barebox On Fri, May 10, 2013 at 09:03:10PM +0200, Alexander Aring wrote: > Hi Lucas, > > On Fri, May 10, 2013 at 08:28:57PM +0200, Lucas Stach wrote: > > This adds a pinctrl driver for the Tegra 20 line of SoCs. It only > > supports the three basic pinconfiguration settings function mux, > > tristate control and pullup/down control. > > > > The driver understands the same devicetree bindings as the Linux one, > > unimplemented pinconfiguration options will be ignored. > > > > Signed-off-by: Lucas Stach <dev@lynxeye.de> [...] > > + > > +static int pinctrl_tegra20_probe(struct device_d *dev) > > +{ > > + struct pinctrl_tegra20 *ctrl; > > + int i, ret; > > + u32 **regs; > > + > > + ctrl = xzalloc(sizeof(*ctrl)); > > + > > + /* > > + * Tegra pincontrol is split out into four independent memory ranges: > > + * tristate control, function mux, pullup/down control, pad control > > + * (from lowest to highest hardware address). > > + * We are only interested in the first three for now. > > + */ > > + regs = (u32 **)&ctrl->regs; > > + for (i = 0; i <= 2; i++) { > > + regs[i] = dev_request_mem_region(dev, i); > > + if (!regs[i]) { > > + dev_err(dev, "Could not get iomem region %d\n", i); > Do we need a free(ctrl); here? To be correct, yes, we would need a free() here. I've never been very thoroughly with releasing the resources in the error pathes in the drivers in barebox though and I never felt bad about it. The probe calls are called only once for each device and whether or not we have a few bytes of malloc space more doesn't really matter. Also you may have noticed that there even is no dev_release_mem_region in barebox which makes nearly all error pathes wrong in barebox anyway. And no, I don't want to have -EPROBE_DEFER in barebox. So I don't really know what to do with the error pathes in driver probe functions. I don't really care about them, but I also don't feel like removing the freeing of resources either to reduce the binary size. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] tegra20: add pinctrl driver 2013-05-11 15:17 ` Sascha Hauer @ 2013-05-12 13:48 ` Jean-Christophe PLAGNIOL-VILLARD 0 siblings, 0 replies; 6+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-12 13:48 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox On 17:17 Sat 11 May , Sascha Hauer wrote: > On Fri, May 10, 2013 at 09:03:10PM +0200, Alexander Aring wrote: > > Hi Lucas, > > > > On Fri, May 10, 2013 at 08:28:57PM +0200, Lucas Stach wrote: > > > This adds a pinctrl driver for the Tegra 20 line of SoCs. It only > > > supports the three basic pinconfiguration settings function mux, > > > tristate control and pullup/down control. > > > > > > The driver understands the same devicetree bindings as the Linux one, > > > unimplemented pinconfiguration options will be ignored. > > > > > > Signed-off-by: Lucas Stach <dev@lynxeye.de> > > [...] > > > > + > > > +static int pinctrl_tegra20_probe(struct device_d *dev) > > > +{ > > > + struct pinctrl_tegra20 *ctrl; > > > + int i, ret; > > > + u32 **regs; > > > + > > > + ctrl = xzalloc(sizeof(*ctrl)); > > > + > > > + /* > > > + * Tegra pincontrol is split out into four independent memory ranges: > > > + * tristate control, function mux, pullup/down control, pad control > > > + * (from lowest to highest hardware address). > > > + * We are only interested in the first three for now. > > > + */ > > > + regs = (u32 **)&ctrl->regs; > > > + for (i = 0; i <= 2; i++) { > > > + regs[i] = dev_request_mem_region(dev, i); > > > + if (!regs[i]) { > > > + dev_err(dev, "Could not get iomem region %d\n", i); > > Do we need a free(ctrl); here? > > To be correct, yes, we would need a free() here. > > I've never been very thoroughly with releasing the resources in the > error pathes in the drivers in barebox though and I never felt bad about > it. > > The probe calls are called only once for each device and whether or not > we have a few bytes of malloc space more doesn't really matter. Also you > may have noticed that there even is no dev_release_mem_region in barebox > which makes nearly all error pathes wrong in barebox anyway. > > And no, I don't want to have -EPROBE_DEFER in barebox. this can be problematic for some pinctrl as they will present late that's why we introduce it in the kernel > > So I don't really know what to do with the error pathes in driver probe > functions. I don't really care about them, but I also don't feel like > removing the freeing of resources either to reduce the binary size. > > Sascha > > > -- > Pengutronix e.K. | | > Industrial Linux Solutions | http://www.pengutronix.de/ | > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] tegra20: add pinctrl driver 2013-05-10 18:28 [PATCH v2 1/2] tegra20: add pinctrl driver Lucas Stach 2013-05-10 18:28 ` [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux Lucas Stach 2013-05-10 19:03 ` [PATCH v2 1/2] tegra20: add pinctrl driver Alexander Aring @ 2013-10-22 15:07 ` Uwe Kleine-König 2 siblings, 0 replies; 6+ messages in thread From: Uwe Kleine-König @ 2013-10-22 15:07 UTC (permalink / raw) To: Lucas Stach; +Cc: barebox Hello Lucas, On Fri, May 10, 2013 at 08:28:57PM +0200, Lucas Stach wrote: > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig > index e6aee50..0b859b8 100644 > --- a/drivers/pinctrl/Kconfig > +++ b/drivers/pinctrl/Kconfig > @@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3 > help > This iomux controller is found on i.MX25,35,51,53,6. > > +config PINCTRL_TEGRA20 > + select PINCTRL > + bool "Tegra 20 pinmux" Now that I tried barebox' master on an i.MX28 I was presented with the question to enable PINCTRL_TEGRA20 or not during oldconfig. Maybe don't make this user-selectable? (The other pinctrl driver are affected by the same "issue".) > + help > + The pinmux controller found on the Tegra 20 line of SoCs. > + > endmenu -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | http://www.pengutronix.de/ | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-10-22 15:07 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-05-10 18:28 [PATCH v2 1/2] tegra20: add pinctrl driver Lucas Stach 2013-05-10 18:28 ` [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux Lucas Stach 2013-05-10 19:03 ` [PATCH v2 1/2] tegra20: add pinctrl driver Alexander Aring 2013-05-11 15:17 ` Sascha Hauer 2013-05-12 13:48 ` Jean-Christophe PLAGNIOL-VILLARD 2013-10-22 15:07 ` Uwe Kleine-König
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox