* [PATCH 2/2] pinctrl: add ZTE ZX pinctrl driver support
From: Shawn Guo @ 2017-04-24 13:01 UTC (permalink / raw)
To: Linus Walleij
Cc: Rob Herring, linux-gpio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Baoyou Xie,
Xin Zhou, Jun Nie, Shawn Guo
In-Reply-To: <1493038873-18354-1-git-send-email-shawnguo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
From: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
The pin controller on ZTE ZX platforms is kinda of hybrid. It consists
of a main controller and an auxiliary one. For example, on ZX296718 SoC,
the main controller is TOP_PMM and the auxiliary one is AON_IOCFG. Both
controllers work together to control pin multiplexing and configuration.
For most of pins, the pinmux function is controlled by main controller
only, and this type of pins are meant by term 'TOP pins'. For other
pins, the pinmux is controlled by both main and auxiliary controllers,
as the available multiplexing functions for the pin spread in both
controllers. This type of pins are called 'AON pins'. Though pinmux
implementation is quite different, pinconf is same for both types of
pins. Both are controlled by auxiliary controller, i.e. AON_IOCFG on
ZX296718.
The patch adds the ZTE ZX core pinctrl driver to support this hybrid
pin controller as well as ZX296718 SoC specific pin data.
Signed-off-by: Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
drivers/pinctrl/Kconfig | 1 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/zte/Kconfig | 13 +
drivers/pinctrl/zte/Makefile | 2 +
drivers/pinctrl/zte/pinctrl-zx.c | 445 ++++++++++++++
drivers/pinctrl/zte/pinctrl-zx.h | 105 ++++
drivers/pinctrl/zte/pinctrl-zx296718.c | 1027 ++++++++++++++++++++++++++++++++
7 files changed, 1594 insertions(+)
create mode 100644 drivers/pinctrl/zte/Kconfig
create mode 100644 drivers/pinctrl/zte/Makefile
create mode 100644 drivers/pinctrl/zte/pinctrl-zx.c
create mode 100644 drivers/pinctrl/zte/pinctrl-zx.h
create mode 100644 drivers/pinctrl/zte/pinctrl-zx296718.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 8f8c2af45781..97c202ba9a7a 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -304,6 +304,7 @@ source "drivers/pinctrl/ti/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
source "drivers/pinctrl/vt8500/Kconfig"
source "drivers/pinctrl/mediatek/Kconfig"
+source "drivers/pinctrl/zte/Kconfig"
config PINCTRL_XWAY
bool
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a251f439626f..dce8ff892b23 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -57,3 +57,4 @@ obj-y += ti/
obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_ARCH_VT8500) += vt8500/
obj-$(CONFIG_PINCTRL_MTK) += mediatek/
+obj-$(CONFIG_PINCTRL_ZX) += zte/
diff --git a/drivers/pinctrl/zte/Kconfig b/drivers/pinctrl/zte/Kconfig
new file mode 100644
index 000000000000..0d97352a24ec
--- /dev/null
+++ b/drivers/pinctrl/zte/Kconfig
@@ -0,0 +1,13 @@
+config PINCTRL_ZX
+ bool
+ select PINMUX
+ select GENERIC_PINCONF
+ select GENERIC_PINCTRL_GROUPS
+ select GENERIC_PINMUX_FUNCTIONS
+
+config PINCTRL_ZX296718
+ bool "ZTE ZX296718 pinctrl driver"
+ depends on OF && ARCH_ZX
+ select PINCTRL_ZX
+ help
+ Say Y here to enable the ZX296718 pinctrl driver
diff --git a/drivers/pinctrl/zte/Makefile b/drivers/pinctrl/zte/Makefile
new file mode 100644
index 000000000000..c42e651d7a73
--- /dev/null
+++ b/drivers/pinctrl/zte/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_PINCTRL_ZX) += pinctrl-zx.o
+obj-$(CONFIG_PINCTRL_ZX296718) += pinctrl-zx296718.o
diff --git a/drivers/pinctrl/zte/pinctrl-zx.c b/drivers/pinctrl/zte/pinctrl-zx.c
new file mode 100644
index 000000000000..2aca4e4b3f1c
--- /dev/null
+++ b/drivers/pinctrl/zte/pinctrl-zx.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2017 Sanechips Technology Co., Ltd.
+ * Copyright 2017 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+#include "../pinmux.h"
+#include "pinctrl-zx.h"
+
+#define ZX_PULL_DOWN BIT(0)
+#define ZX_PULL_UP BIT(1)
+#define ZX_INPUT_ENABLE BIT(3)
+#define ZX_DS_SHIFT 4
+#define ZX_DS_MASK (0x7 << ZX_DS_SHIFT)
+#define ZX_DS_VALUE(x) (((x) << ZX_DS_SHIFT) & ZX_DS_MASK)
+#define ZX_SLEW BIT(8)
+
+struct zx_pinctrl {
+ struct pinctrl_dev *pctldev;
+ struct device *dev;
+ void __iomem *base;
+ void __iomem *aux_base;
+ spinlock_t lock;
+ struct zx_pinctrl_soc_info *info;
+};
+
+static int zx_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map, u32 *num_maps)
+{
+ return pinconf_generic_dt_node_to_map(pctldev, np_config, map,
+ num_maps, PIN_MAP_TYPE_INVALID);
+}
+
+static const struct pinctrl_ops zx_pinctrl_ops = {
+ .dt_node_to_map = zx_dt_node_to_map,
+ .dt_free_map = pinctrl_utils_free_map,
+ .get_groups_count = pinctrl_generic_get_group_count,
+ .get_group_name = pinctrl_generic_get_group_name,
+ .get_group_pins = pinctrl_generic_get_group_pins,
+};
+
+#define NONAON_MVAL 2
+
+static int zx_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
+ unsigned int group_selector)
+{
+ struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev);
+ struct zx_pinctrl_soc_info *info = zpctl->info;
+ const struct pinctrl_pin_desc *pindesc = info->pins + group_selector;
+ struct zx_pin_data *data = pindesc->drv_data;
+ struct zx_mux_desc *mux = data->muxes;
+ u32 mask = (1 << data->width) - 1;
+ u32 offset = data->offset;
+ u32 bitpos = data->bitpos;
+ struct function_desc *func;
+ unsigned long flags;
+ u32 val, mval;
+
+ /* Skip reserved pin */
+ if (!data)
+ return -EINVAL;
+
+ func = pinmux_generic_get_function(pctldev, func_selector);
+ if (!func)
+ return -EINVAL;
+
+ while (mux->name) {
+ if (strcmp(mux->name, func->name) == 0)
+ break;
+ mux++;
+ }
+
+ /* Found mux value to be written */
+ mval = mux->muxval;
+
+ spin_lock_irqsave(&zpctl->lock, flags);
+
+ if (data->aon_pin) {
+ /*
+ * It's an AON pin, whose mux register offset and bit position
+ * can be caluculated from pin number. Each register covers 16
+ * pins, and each pin occupies 2 bits.
+ */
+ u16 aoffset = pindesc->number / 16 * 4;
+ u16 abitpos = (pindesc->number % 16) * 2;
+
+ if (mval & AON_MUX_FLAG) {
+ /*
+ * This is a mux value that needs to be written into
+ * AON pinmux register. Write it and then we're done.
+ */
+ val = readl(zpctl->aux_base + aoffset);
+ val &= ~(0x3 << abitpos);
+ val |= (mval & 0x3) << abitpos;
+ writel(val, zpctl->aux_base + aoffset);
+ } else {
+ /*
+ * It's a mux value that needs to be written into TOP
+ * pinmux register.
+ */
+ val = readl(zpctl->base + offset);
+ val &= ~(mask << bitpos);
+ val |= (mval & mask) << bitpos;
+ writel(val, zpctl->base + offset);
+
+ /*
+ * In this case, the AON pinmux register needs to be
+ * set up to select non-AON function.
+ */
+ val = readl(zpctl->aux_base + aoffset);
+ val &= ~(0x3 << abitpos);
+ val |= NONAON_MVAL << abitpos;
+ writel(val, zpctl->aux_base + aoffset);
+ }
+
+ } else {
+ /*
+ * This is a TOP pin, and we only need to set up TOP pinmux
+ * register and then we're done with it.
+ */
+ val = readl(zpctl->base + offset);
+ val &= ~(mask << bitpos);
+ val |= (mval & mask) << bitpos;
+ writel(val, zpctl->base + offset);
+ }
+
+ spin_unlock_irqrestore(&zpctl->lock, flags);
+
+ return 0;
+}
+
+static const struct pinmux_ops zx_pinmux_ops = {
+ .get_functions_count = pinmux_generic_get_function_count,
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,
+ .set_mux = zx_set_mux,
+};
+
+static int zx_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *config)
+{
+ struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev);
+ struct zx_pinctrl_soc_info *info = zpctl->info;
+ const struct pinctrl_pin_desc *pindesc = info->pins + pin;
+ struct zx_pin_data *data = pindesc->drv_data;
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 val;
+
+ /* Skip reserved pin */
+ if (!data)
+ return -EINVAL;
+
+ val = readl(zpctl->aux_base + data->coffset);
+ val = val >> data->cbitpos;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ val &= ZX_PULL_DOWN;
+ val = !!val;
+ if (val == 0)
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ val &= ZX_PULL_UP;
+ val = !!val;
+ if (val == 0)
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ val &= ZX_INPUT_ENABLE;
+ val = !!val;
+ if (val == 0)
+ return -EINVAL;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ val &= ZX_DS_MASK;
+ val = val >> ZX_DS_SHIFT;
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ val &= ZX_SLEW;
+ val = !!val;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, val);
+
+ return 0;
+}
+
+static int zx_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ unsigned long *configs, unsigned int num_configs)
+{
+ struct zx_pinctrl *zpctl = pinctrl_dev_get_drvdata(pctldev);
+ struct zx_pinctrl_soc_info *info = zpctl->info;
+ const struct pinctrl_pin_desc *pindesc = info->pins + pin;
+ struct zx_pin_data *data = pindesc->drv_data;
+ enum pin_config_param param;
+ u32 val, arg;
+ int i;
+
+ /* Skip reserved pin */
+ if (!data)
+ return -EINVAL;
+
+ val = readl(zpctl->aux_base + data->coffset);
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ val |= ZX_PULL_DOWN << data->cbitpos;
+ break;
+ case PIN_CONFIG_BIAS_PULL_UP:
+ val |= ZX_PULL_UP << data->cbitpos;
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ val |= ZX_INPUT_ENABLE << data->cbitpos;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ val &= ~(ZX_DS_MASK << data->cbitpos);
+ val |= ZX_DS_VALUE(arg) << data->cbitpos;
+ break;
+ case PIN_CONFIG_SLEW_RATE:
+ if (arg)
+ val |= ZX_SLEW << data->cbitpos;
+ else
+ val &= ~ZX_SLEW << data->cbitpos;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ }
+
+ writel(val, zpctl->aux_base + data->coffset);
+ return 0;
+}
+
+static const struct pinconf_ops zx_pinconf_ops = {
+ .pin_config_set = zx_pin_config_set,
+ .pin_config_get = zx_pin_config_get,
+ .is_generic = true,
+};
+
+static int zx_pinctrl_build_state(struct platform_device *pdev)
+{
+ struct zx_pinctrl *zpctl = platform_get_drvdata(pdev);
+ struct zx_pinctrl_soc_info *info = zpctl->info;
+ struct pinctrl_dev *pctldev = zpctl->pctldev;
+ struct function_desc *functions;
+ int nfunctions;
+ struct group_desc *groups;
+ int ngroups;
+ int i;
+
+ /* Every single pin composes a group */
+ ngroups = info->npins;
+ groups = devm_kzalloc(&pdev->dev, ngroups * sizeof(*groups),
+ GFP_KERNEL);
+ if (!groups)
+ return -ENOMEM;
+
+ for (i = 0; i < ngroups; i++) {
+ const struct pinctrl_pin_desc *pindesc = info->pins + i;
+ struct group_desc *group = groups + i;
+ int id = pindesc->number;
+
+ group->name = pindesc->name;
+ group->pins = &id;
+ radix_tree_insert(&pctldev->pin_group_tree, i, group);
+ }
+
+ pctldev->num_groups = ngroups;
+
+ /* Build function list from pin mux functions */
+ functions = devm_kzalloc(&pdev->dev, info->npins * sizeof(*functions),
+ GFP_KERNEL);
+ if (!functions)
+ return -ENOMEM;
+
+ nfunctions = 0;
+ for (i = 0; i < info->npins; i++) {
+ const struct pinctrl_pin_desc *pindesc = info->pins + i;
+ struct zx_pin_data *data = pindesc->drv_data;
+ struct zx_mux_desc *mux;
+
+ /* Reserved pins do not have a drv_data at all */
+ if (!data)
+ continue;
+
+ /* Loop over all muxes for the pin */
+ mux = data->muxes;
+ while (mux->name) {
+ struct function_desc *func = functions;
+
+ /* Search function list for given mux */
+ while (func->name) {
+ if (strcmp(mux->name, func->name) == 0) {
+ /* Function exists */
+ func->num_group_names++;
+ break;
+ }
+ func++;
+ }
+
+ if (!func->name) {
+ /* New function */
+ func->name = mux->name;
+ func->num_group_names = 1;
+ radix_tree_insert(&pctldev->pin_function_tree,
+ nfunctions++, func);
+ }
+
+ mux++;
+ }
+ }
+
+ pctldev->num_functions = nfunctions;
+ functions = krealloc(functions, nfunctions * sizeof(*functions),
+ GFP_KERNEL);
+
+ /* Find pin groups for every single function */
+ for (i = 0; i < info->npins; i++) {
+ const struct pinctrl_pin_desc *pindesc = info->pins + i;
+ struct zx_pin_data *data = pindesc->drv_data;
+ struct zx_mux_desc *mux;
+
+ if (!data)
+ continue;
+
+ mux = data->muxes;
+ while (mux->name) {
+ struct function_desc *func;
+ const char **group;
+ int j;
+
+ /* Find function for given mux */
+ for (j = 0; j < nfunctions; j++)
+ if (strcmp(functions[j].name, mux->name) == 0)
+ break;
+
+ func = functions + j;
+ if (!func->group_names) {
+ func->group_names = devm_kzalloc(&pdev->dev,
+ func->num_group_names *
+ sizeof(*func->group_names),
+ GFP_KERNEL);
+ if (!func->group_names)
+ return -ENOMEM;
+ }
+
+ group = func->group_names;
+ while (*group)
+ group++;
+ *group = pindesc->name;
+
+ mux++;
+ }
+ }
+
+ return 0;
+}
+
+int zx_pinctrl_init(struct platform_device *pdev,
+ struct zx_pinctrl_soc_info *info)
+{
+ struct pinctrl_desc *pctldesc;
+ struct zx_pinctrl *zpctl;
+ struct device_node *np;
+ struct resource *res;
+ int ret;
+
+ zpctl = devm_kzalloc(&pdev->dev, sizeof(*zpctl), GFP_KERNEL);
+ if (!zpctl)
+ return -ENOMEM;
+
+ spin_lock_init(&zpctl->lock);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ zpctl->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(zpctl->base))
+ return PTR_ERR(zpctl->base);
+
+ np = of_parse_phandle(pdev->dev.of_node, "zte,auxiliary-controller", 0);
+ if (!np) {
+ dev_err(&pdev->dev, "failed to find auxiliary controller\n");
+ return -ENODEV;
+ }
+
+ zpctl->aux_base = of_iomap(np, 0);
+ if (!zpctl->aux_base)
+ return -ENOMEM;
+
+ zpctl->dev = &pdev->dev;
+ zpctl->info = info;
+
+ pctldesc = devm_kzalloc(&pdev->dev, sizeof(*pctldesc), GFP_KERNEL);
+ if (!pctldesc)
+ return -ENOMEM;
+
+ pctldesc->name = dev_name(&pdev->dev);
+ pctldesc->owner = THIS_MODULE;
+ pctldesc->pins = info->pins;
+ pctldesc->npins = info->npins;
+ pctldesc->pctlops = &zx_pinctrl_ops;
+ pctldesc->pmxops = &zx_pinmux_ops;
+ pctldesc->confops = &zx_pinconf_ops;
+
+ zpctl->pctldev = devm_pinctrl_register(&pdev->dev, pctldesc, zpctl);
+ if (IS_ERR(zpctl->pctldev)) {
+ ret = PTR_ERR(zpctl->pctldev);
+ dev_err(&pdev->dev, "failed to register pinctrl: %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, zpctl);
+
+ ret = zx_pinctrl_build_state(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to build state: %d\n", ret);
+ return ret;
+ }
+
+ dev_info(&pdev->dev, "initialized pinctrl driver\n");
+ return 0;
+}
diff --git a/drivers/pinctrl/zte/pinctrl-zx.h b/drivers/pinctrl/zte/pinctrl-zx.h
new file mode 100644
index 000000000000..bc67e2be0503
--- /dev/null
+++ b/drivers/pinctrl/zte/pinctrl-zx.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 Sanechips Technology Co., Ltd.
+ * Copyright 2017 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PINCTRL_ZX_H
+#define __PINCTRL_ZX_H
+
+/**
+ * struct zx_mux_desc - hardware mux descriptor
+ * @name: mux function name
+ * @muxval: mux register bit value
+ */
+struct zx_mux_desc {
+ const char *name;
+ u8 muxval;
+};
+
+/**
+ * struct zx_pin_data - hardware per-pin data
+ * @aon_pin: whether it's an AON pin
+ * @offset: register offset within TOP pinmux controller
+ * @bitpos: bit position within TOP pinmux register
+ * @width: bit width within TOP pinmux register
+ * @coffset: pinconf register offset within AON controller
+ * @cbitpos: pinconf bit position within AON register
+ * @muxes: available mux function names and corresponding register values
+ *
+ * Unlike TOP pinmux and AON pinconf registers which are arranged pretty
+ * arbitrarily, AON pinmux register bits are well organized per pin id, and
+ * each pin occupies two bits, so that we can calculate the AON register offset
+ * and bit position from pin id. Thus, we only need to define TOP pinmux and
+ * AON pinconf register data for the pin.
+ */
+struct zx_pin_data {
+ bool aon_pin;
+ u16 offset;
+ u16 bitpos;
+ u16 width;
+ u16 coffset;
+ u16 cbitpos;
+ struct zx_mux_desc *muxes;
+};
+
+struct zx_pinctrl_soc_info {
+ const struct pinctrl_pin_desc *pins;
+ unsigned int npins;
+};
+
+#define TOP_PIN(pin, off, bp, wd, coff, cbp, ...) { \
+ .number = pin, \
+ .name = #pin, \
+ .drv_data = &(struct zx_pin_data) { \
+ .aon_pin = false, \
+ .offset = off, \
+ .bitpos = bp, \
+ .width = wd, \
+ .coffset = coff, \
+ .cbitpos = cbp, \
+ .muxes = (struct zx_mux_desc[]) { \
+ __VA_ARGS__, { } }, \
+ }, \
+}
+
+#define AON_PIN(pin, off, bp, wd, coff, cbp, ...) { \
+ .number = pin, \
+ .name = #pin, \
+ .drv_data = &(struct zx_pin_data) { \
+ .aon_pin = true, \
+ .offset = off, \
+ .bitpos = bp, \
+ .width = wd, \
+ .coffset = coff, \
+ .cbitpos = cbp, \
+ .muxes = (struct zx_mux_desc[]) { \
+ __VA_ARGS__, { } }, \
+ }, \
+}
+
+#define ZX_RESERVED(pin) PINCTRL_PIN(pin, #pin)
+
+#define TOP_MUX(_val, _name) { \
+ .name = _name, \
+ .muxval = _val, \
+}
+
+/*
+ * When the flag is set, it's a mux configuration for an AON pin that sits in
+ * AON register. Otherwise, it's one for AON pin but sitting in TOP register.
+ */
+#define AON_MUX_FLAG BIT(7)
+
+#define AON_MUX(_val, _name) { \
+ .name = _name, \
+ .muxval = _val | AON_MUX_FLAG, \
+}
+
+int zx_pinctrl_init(struct platform_device *pdev,
+ struct zx_pinctrl_soc_info *info);
+
+#endif /* __PINCTRL_ZX_H */
diff --git a/drivers/pinctrl/zte/pinctrl-zx296718.c b/drivers/pinctrl/zte/pinctrl-zx296718.c
new file mode 100644
index 000000000000..71efec17ee7e
--- /dev/null
+++ b/drivers/pinctrl/zte/pinctrl-zx296718.c
@@ -0,0 +1,1027 @@
+/*
+ * Copyright (C) 2017 Sanechips Technology Co., Ltd.
+ * Copyright 2017 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-zx.h"
+
+#define TOP_REG0 0x00
+#define TOP_REG1 0x04
+#define TOP_REG2 0x08
+#define TOP_REG3 0x0c
+#define TOP_REG4 0x10
+#define TOP_REG5 0x14
+#define TOP_REG6 0x18
+#define TOP_REG7 0x1c
+#define TOP_REG8 0x20
+
+/*
+ * The pin numbering starts from AON pins with reserved ones included,
+ * so that register data like offset and bit position for AON pins can
+ * be calculated from pin number.
+ */
+enum zx296718_pin {
+ /* aon_pmm_reg_0 */
+ I2C3_SCL = 0,
+ I2C3_SDA = 1,
+ AON_RESERVED0 = 2,
+ AON_RESERVED1 = 3,
+ SEC_EN = 4,
+ UART0_RXD = 5,
+ UART0_TXD = 6,
+ IR_IN = 7,
+ SPI0_CLK = 8,
+ SPI0_CS = 9,
+ SPI0_TXD = 10,
+ SPI0_RXD = 11,
+ KEY_COL0 = 12,
+ KEY_COL1 = 13,
+ KEY_COL2 = 14,
+ KEY_ROW0 = 15,
+
+ /* aon_pmm_reg_1 */
+ KEY_ROW1 = 16,
+ KEY_ROW2 = 17,
+ HDMI_SCL = 18,
+ HDMI_SDA = 19,
+ JTAG_TCK = 20,
+ JTAG_TRSTN = 21,
+ JTAG_TMS = 22,
+ JTAG_TDI = 23,
+ JTAG_TDO = 24,
+ I2C0_SCL = 25,
+ I2C0_SDA = 26,
+ I2C1_SCL = 27,
+ I2C1_SDA = 28,
+ AON_RESERVED2 = 29,
+ AON_RESERVED3 = 30,
+ AON_RESERVED4 = 31,
+
+ /* aon_pmm_reg_2 */
+ SPI1_CLK = 32,
+ SPI1_CS = 33,
+ SPI1_TXD = 34,
+ SPI1_RXD = 35,
+ AON_RESERVED5 = 36,
+ AON_RESERVED6 = 37,
+ AUDIO_DET = 38,
+ SPDIF_OUT = 39,
+ HDMI_CEC = 40,
+ HDMI_HPD = 41,
+ GMAC_25M_OUT = 42,
+ BOOT_SEL0 = 43,
+ BOOT_SEL1 = 44,
+ BOOT_SEL2 = 45,
+ DEEP_SLEEP_OUT_N = 46,
+ AON_RESERVED7 = 47,
+
+ /* top_pmm_reg_0 */
+ GMII_GTX_CLK = 48,
+ GMII_TX_CLK = 49,
+ GMII_TXD0 = 50,
+ GMII_TXD1 = 51,
+ GMII_TXD2 = 52,
+ GMII_TXD3 = 53,
+ GMII_TXD4 = 54,
+ GMII_TXD5 = 55,
+ GMII_TXD6 = 56,
+ GMII_TXD7 = 57,
+ GMII_TX_ER = 58,
+ GMII_TX_EN = 59,
+ GMII_RX_CLK = 60,
+ GMII_RXD0 = 61,
+ GMII_RXD1 = 62,
+ GMII_RXD2 = 63,
+
+ /* top_pmm_reg_1 */
+ GMII_RXD3 = 64,
+ GMII_RXD4 = 65,
+ GMII_RXD5 = 66,
+ GMII_RXD6 = 67,
+ GMII_RXD7 = 68,
+ GMII_RX_ER = 69,
+ GMII_RX_DV = 70,
+ GMII_COL = 71,
+ GMII_CRS = 72,
+ GMII_MDC = 73,
+ GMII_MDIO = 74,
+ SDIO1_CLK = 75,
+ SDIO1_CMD = 76,
+ SDIO1_DATA0 = 77,
+ SDIO1_DATA1 = 78,
+ SDIO1_DATA2 = 79,
+
+ /* top_pmm_reg_2 */
+ SDIO1_DATA3 = 80,
+ SDIO1_CD = 81,
+ SDIO1_WP = 82,
+ USIM1_CD = 83,
+ USIM1_CLK = 84,
+ USIM1_RST = 85,
+
+ /* top_pmm_reg_3 */
+ USIM1_DATA = 86,
+ SDIO0_CLK = 87,
+ SDIO0_CMD = 88,
+ SDIO0_DATA0 = 89,
+ SDIO0_DATA1 = 90,
+ SDIO0_DATA2 = 91,
+ SDIO0_DATA3 = 92,
+ SDIO0_CD = 93,
+ SDIO0_WP = 94,
+
+ /* top_pmm_reg_4 */
+ TSI0_DATA0 = 95,
+ SPINOR_CLK = 96,
+ TSI2_DATA = 97,
+ TSI2_CLK = 98,
+ TSI2_SYNC = 99,
+ TSI2_VALID = 100,
+ SPINOR_CS = 101,
+ SPINOR_DQ0 = 102,
+ SPINOR_DQ1 = 103,
+ SPINOR_DQ2 = 104,
+ SPINOR_DQ3 = 105,
+ VGA_HS = 106,
+ VGA_VS = 107,
+ TSI3_DATA = 108,
+
+ /* top_pmm_reg_5 */
+ TSI3_CLK = 109,
+ TSI3_SYNC = 110,
+ TSI3_VALID = 111,
+ I2S1_WS = 112,
+ I2S1_BCLK = 113,
+ I2S1_MCLK = 114,
+ I2S1_DIN0 = 115,
+ I2S1_DOUT0 = 116,
+ SPI3_CLK = 117,
+ SPI3_CS = 118,
+ SPI3_TXD = 119,
+ NAND_LDO_MS18_SEL = 120,
+
+ /* top_pmm_reg_6 */
+ SPI3_RXD = 121,
+ I2S0_MCLK = 122,
+ I2S0_BCLK = 123,
+ I2S0_WS = 124,
+ I2S0_DIN0 = 125,
+ I2S0_DOUT0 = 126,
+ I2C5_SCL = 127,
+ I2C5_SDA = 128,
+ SPI2_CLK = 129,
+ SPI2_CS = 130,
+ SPI2_TXD = 131,
+
+ /* top_pmm_reg_7 */
+ SPI2_RXD = 132,
+ NAND_WP_N = 133,
+ NAND_PAGE_SIZE0 = 134,
+ NAND_PAGE_SIZE1 = 135,
+ NAND_ADDR_CYCLE = 136,
+ NAND_RB0 = 137,
+ NAND_RB1 = 138,
+ NAND_RB2 = 139,
+ NAND_RB3 = 140,
+
+ /* top_pmm_reg_8 */
+ GMAC_125M_IN = 141,
+ GMAC_50M_OUT = 142,
+ SPINOR_SSCLK_LOOPBACK = 143,
+ SPINOR_SDIO1CLK_LOOPBACK = 144,
+};
+
+static const struct pinctrl_pin_desc zx296718_pins[] = {
+ /* aon_pmm_reg_0 */
+ AON_PIN(I2C3_SCL, TOP_REG2, 18, 2, 0x48, 0,
+ AON_MUX(0x0, "ANMI"), /* anmi */
+ AON_MUX(0x1, "AGPIO"), /* agpio29 */
+ AON_MUX(0x2, "nonAON"), /* pin0 */
+ AON_MUX(0x3, "EXT_INT"), /* int4 */
+ TOP_MUX(0x0, "I2C3"), /* scl */
+ TOP_MUX(0x1, "SPI2"), /* txd */
+ TOP_MUX(0x2, "I2S1")), /* din0 */
+ AON_PIN(I2C3_SDA, TOP_REG2, 20, 2, 0x48, 9,
+ AON_MUX(0x0, "WD"), /* rst_b */
+ AON_MUX(0x1, "AGPIO"), /* agpio30 */
+ AON_MUX(0x2, "nonAON"), /* pin1 */
+ AON_MUX(0x3, "EXT_INT"), /* int5 */
+ TOP_MUX(0x0, "I2C3"), /* sda */
+ TOP_MUX(0x1, "SPI2"), /* rxd */
+ TOP_MUX(0x2, "I2S0")), /* mclk */
+ ZX_RESERVED(AON_RESERVED0),
+ ZX_RESERVED(AON_RESERVED1),
+ AON_PIN(SEC_EN, TOP_REG3, 5, 1, 0x50, 0,
+ AON_MUX(0x0, "SEC"), /* en */
+ AON_MUX(0x1, "AGPIO"), /* agpio28 */
+ AON_MUX(0x2, "nonAON"), /* pin3 */
+ AON_MUX(0x3, "EXT_INT"), /* int7 */
+ TOP_MUX(0x0, "I2C2"), /* sda */
+ TOP_MUX(0x1, "SPI2")), /* cs */
+ AON_PIN(UART0_RXD, 0, 0, 0, 0x50, 9,
+ AON_MUX(0x0, "UART0"), /* rxd */
+ AON_MUX(0x1, "AGPIO"), /* agpio20 */
+ AON_MUX(0x2, "nonAON")), /* pin34 */
+ AON_PIN(UART0_TXD, 0, 0, 0, 0x50, 18,
+ AON_MUX(0x0, "UART0"), /* txd */
+ AON_MUX(0x1, "AGPIO"), /* agpio21 */
+ AON_MUX(0x2, "nonAON")), /* pin32 */
+ AON_PIN(IR_IN, 0, 0, 0, 0x64, 0,
+ AON_MUX(0x0, "IR"), /* in */
+ AON_MUX(0x1, "AGPIO"), /* agpio0 */
+ AON_MUX(0x2, "nonAON")), /* pin27 */
+ AON_PIN(SPI0_CLK, TOP_REG3, 16, 1, 0x64, 9,
+ AON_MUX(0x0, "EXT_INT"), /* int0 */
+ AON_MUX(0x1, "AGPIO"), /* agpio23 */
+ AON_MUX(0x2, "nonAON"), /* pin5 */
+ AON_MUX(0x3, "PCU"), /* test6 */
+ TOP_MUX(0x0, "SPI0"), /* clk */
+ TOP_MUX(0x1, "ISP")), /* flash_trig */
+ AON_PIN(SPI0_CS, TOP_REG3, 17, 1, 0x64, 18,
+ AON_MUX(0x0, "EXT_INT"), /* int1 */
+ AON_MUX(0x1, "AGPIO"), /* agpio24 */
+ AON_MUX(0x2, "nonAON"), /* pin6 */
+ AON_MUX(0x3, "PCU"), /* test0 */
+ TOP_MUX(0x0, "SPI0"), /* cs */
+ TOP_MUX(0x1, "ISP")), /* prelight_trig */
+ AON_PIN(SPI0_TXD, TOP_REG3, 18, 1, 0x68, 0,
+ AON_MUX(0x0, "EXT_INT"), /* int2 */
+ AON_MUX(0x1, "AGPIO"), /* agpio25 */
+ AON_MUX(0x2, "nonAON"), /* pin7 */
+ AON_MUX(0x3, "PCU"), /* test1 */
+ TOP_MUX(0x0, "SPI0"), /* txd */
+ TOP_MUX(0x1, "ISP")), /* shutter_trig */
+ AON_PIN(SPI0_RXD, TOP_REG3, 19, 1, 0x68, 9,
+ AON_MUX(0x0, "EXT_INT"), /* int3 */
+ AON_MUX(0x1, "AGPIO"), /* agpio26 */
+ AON_MUX(0x2, "nonAON"), /* pin8 */
+ AON_MUX(0x3, "PCU"), /* test2 */
+ TOP_MUX(0x0, "SPI0"), /* rxd */
+ TOP_MUX(0x1, "ISP")), /* shutter_open */
+ AON_PIN(KEY_COL0, TOP_REG3, 20, 1, 0x68, 18,
+ AON_MUX(0x0, "KEY"), /* col0 */
+ AON_MUX(0x1, "AGPIO"), /* agpio5 */
+ AON_MUX(0x2, "nonAON"), /* pin9 */
+ AON_MUX(0x3, "PCU"), /* test3 */
+ TOP_MUX(0x0, "UART3"), /* rxd */
+ TOP_MUX(0x1, "I2S0")), /* din1 */
+ AON_PIN(KEY_COL1, TOP_REG3, 21, 2, 0x6c, 0,
+ AON_MUX(0x0, "KEY"), /* col1 */
+ AON_MUX(0x1, "AGPIO"), /* agpio6 */
+ AON_MUX(0x2, "nonAON"), /* pin10 */
+ TOP_MUX(0x0, "UART3"), /* txd */
+ TOP_MUX(0x1, "I2S0"), /* din2 */
+ TOP_MUX(0x2, "VGA")), /* scl */
+ AON_PIN(KEY_COL2, TOP_REG3, 23, 2, 0x6c, 9,
+ AON_MUX(0x0, "KEY"), /* col2 */
+ AON_MUX(0x1, "AGPIO"), /* agpio7 */
+ AON_MUX(0x2, "nonAON"), /* pin11 */
+ TOP_MUX(0x0, "PWM"), /* out1 */
+ TOP_MUX(0x1, "I2S0"), /* din3 */
+ TOP_MUX(0x2, "VGA")), /* sda */
+ AON_PIN(KEY_ROW0, 0, 0, 0, 0x6c, 18,
+ AON_MUX(0x0, "KEY"), /* row0 */
+ AON_MUX(0x1, "AGPIO"), /* agpio8 */
+ AON_MUX(0x2, "nonAON"), /* pin33 */
+ AON_MUX(0x3, "WD")), /* rst_b */
+
+ /* aon_pmm_reg_1 */
+ AON_PIN(KEY_ROW1, TOP_REG3, 25, 2, 0x70, 0,
+ AON_MUX(0x0, "KEY"), /* row1 */
+ AON_MUX(0x1, "AGPIO"), /* agpio9 */
+ AON_MUX(0x2, "nonAON"), /* pin12 */
+ TOP_MUX(0x0, "LCD"), /* port0 lcd_te */
+ TOP_MUX(0x1, "I2S0"), /* dout2 */
+ TOP_MUX(0x2, "PWM"), /* out2 */
+ TOP_MUX(0x3, "VGA")), /* hs1 */
+ AON_PIN(KEY_ROW2, TOP_REG3, 27, 2, 0x70, 9,
+ AON_MUX(0x0, "KEY"), /* row2 */
+ AON_MUX(0x1, "AGPIO"), /* agpio10 */
+ AON_MUX(0x2, "nonAON"), /* pin13 */
+ TOP_MUX(0x0, "LCD"), /* port1 lcd_te */
+ TOP_MUX(0x1, "I2S0"), /* dout3 */
+ TOP_MUX(0x2, "PWM"), /* out3 */
+ TOP_MUX(0x3, "VGA")), /* vs1 */
+ AON_PIN(HDMI_SCL, TOP_REG3, 29, 1, 0x70, 18,
+ AON_MUX(0x0, "PCU"), /* test7 */
+ AON_MUX(0x1, "AGPIO"), /* agpio3 */
+ AON_MUX(0x2, "nonAON"), /* pin14 */
+ TOP_MUX(0x0, "HDMI"), /* scl */
+ TOP_MUX(0x1, "UART3")), /* rxd */
+ AON_PIN(HDMI_SDA, TOP_REG3, 30, 1, 0x74, 0,
+ AON_MUX(0x0, "PCU"), /* test8 */
+ AON_MUX(0x1, "AGPIO"), /* agpio4 */
+ AON_MUX(0x2, "nonAON"), /* pin15 */
+ TOP_MUX(0x0, "HDMI"), /* sda */
+ TOP_MUX(0x1, "UART3")), /* txd */
+ AON_PIN(JTAG_TCK, TOP_REG7, 3, 1, 0x78, 18,
+ AON_MUX(0x0, "JTAG"), /* tck */
+ AON_MUX(0x1, "AGPIO"), /* agpio11 */
+ AON_MUX(0x2, "nonAON"), /* pin22 */
+ AON_MUX(0x3, "EXT_INT"), /* int4 */
+ TOP_MUX(0x0, "SPI4"), /* clk */
+ TOP_MUX(0x1, "UART1")), /* rxd */
+ AON_PIN(JTAG_TRSTN, TOP_REG7, 4, 1, 0xac, 0,
+ AON_MUX(0x0, "JTAG"), /* trstn */
+ AON_MUX(0x1, "AGPIO"), /* agpio12 */
+ AON_MUX(0x2, "nonAON"), /* pin23 */
+ AON_MUX(0x3, "EXT_INT"), /* int5 */
+ TOP_MUX(0x0, "SPI4"), /* cs */
+ TOP_MUX(0x1, "UART1")), /* txd */
+ AON_PIN(JTAG_TMS, TOP_REG7, 5, 1, 0xac, 9,
+ AON_MUX(0x0, "JTAG"), /* tms */
+ AON_MUX(0x1, "AGPIO"), /* agpio13 */
+ AON_MUX(0x2, "nonAON"), /* pin24 */
+ AON_MUX(0x3, "EXT_INT"), /* int6 */
+ TOP_MUX(0x0, "SPI4"), /* txd */
+ TOP_MUX(0x1, "UART2")), /* rxd */
+ AON_PIN(JTAG_TDI, TOP_REG7, 6, 1, 0xac, 18,
+ AON_MUX(0x0, "JTAG"), /* tdi */
+ AON_MUX(0x1, "AGPIO"), /* agpio14 */
+ AON_MUX(0x2, "nonAON"), /* pin25 */
+ AON_MUX(0x3, "EXT_INT"), /* int7 */
+ TOP_MUX(0x0, "SPI4"), /* rxd */
+ TOP_MUX(0x1, "UART2")), /* txd */
+ AON_PIN(JTAG_TDO, 0, 0, 0, 0xb0, 0,
+ AON_MUX(0x0, "JTAG"), /* tdo */
+ AON_MUX(0x1, "AGPIO"), /* agpio15 */
+ AON_MUX(0x2, "nonAON")), /* pin26 */
+ AON_PIN(I2C0_SCL, 0, 0, 0, 0xb0, 9,
+ AON_MUX(0x0, "I2C0"), /* scl */
+ AON_MUX(0x1, "AGPIO"), /* agpio16 */
+ AON_MUX(0x2, "nonAON")), /* pin28 */
+ AON_PIN(I2C0_SDA, 0, 0, 0, 0xb0, 18,
+ AON_MUX(0x0, "I2C0"), /* sda */
+ AON_MUX(0x1, "AGPIO"), /* agpio17 */
+ AON_MUX(0x2, "nonAON")), /* pin29 */
+ AON_PIN(I2C1_SCL, TOP_REG8, 4, 1, 0xb4, 0,
+ AON_MUX(0x0, "I2C1"), /* scl */
+ AON_MUX(0x1, "AGPIO"), /* agpio18 */
+ AON_MUX(0x2, "nonAON"), /* pin30 */
+ TOP_MUX(0x0, "LCD")), /* port0 lcd_te */
+ AON_PIN(I2C1_SDA, TOP_REG8, 5, 1, 0xb4, 9,
+ AON_MUX(0x0, "I2C1"), /* sda */
+ AON_MUX(0x1, "AGPIO"), /* agpio19 */
+ AON_MUX(0x2, "nonAON"), /* pin31 */
+ TOP_MUX(0x0, "LCD")), /* port1 lcd_te */
+ ZX_RESERVED(AON_RESERVED2),
+ ZX_RESERVED(AON_RESERVED3),
+ ZX_RESERVED(AON_RESERVED4),
+
+ /* aon_pmm_reg_2 */
+ AON_PIN(SPI1_CLK, TOP_REG2, 6, 3, 0x40, 9,
+ AON_MUX(0x0, "EXT_INT"), /* int0 */
+ AON_MUX(0x1, "PCU"), /* test12 */
+ AON_MUX(0x2, "nonAON"), /* pin39 */
+ TOP_MUX(0x0, "SPI1"), /* clk */
+ TOP_MUX(0x1, "PCM"), /* clk */
+ TOP_MUX(0x2, "BGPIO"), /* gpio35 */
+ TOP_MUX(0x3, "I2C4"), /* scl */
+ TOP_MUX(0x4, "I2S1"), /* mclk */
+ TOP_MUX(0x5, "ISP")), /* flash_trig */
+ AON_PIN(SPI1_CS, TOP_REG2, 9, 3, 0x40, 18,
+ AON_MUX(0x0, "EXT_INT"), /* int1 */
+ AON_MUX(0x1, "PCU"), /* test13 */
+ AON_MUX(0x2, "nonAON"), /* pin40 */
+ TOP_MUX(0x0, "SPI1"), /* cs */
+ TOP_MUX(0x1, "PCM"), /* fs */
+ TOP_MUX(0x2, "BGPIO"), /* gpio36 */
+ TOP_MUX(0x3, "I2C4"), /* sda */
+ TOP_MUX(0x4, "I2S1"), /* bclk */
+ TOP_MUX(0x5, "ISP")), /* prelight_trig */
+ AON_PIN(SPI1_TXD, TOP_REG2, 12, 3, 0x44, 0,
+ AON_MUX(0x0, "EXT_INT"), /* int2 */
+ AON_MUX(0x1, "PCU"), /* test14 */
+ AON_MUX(0x2, "nonAON"), /* pin41 */
+ TOP_MUX(0x0, "SPI1"), /* txd */
+ TOP_MUX(0x1, "PCM"), /* txd */
+ TOP_MUX(0x2, "BGPIO"), /* gpio37 */
+ TOP_MUX(0x3, "UART5"), /* rxd */
+ TOP_MUX(0x4, "I2S1"), /* ws */
+ TOP_MUX(0x5, "ISP")), /* shutter_trig */
+ AON_PIN(SPI1_RXD, TOP_REG2, 15, 3, 0x44, 9,
+ AON_MUX(0x0, "EXT_INT"), /* int3 */
+ AON_MUX(0x1, "PCU"), /* test15 */
+ AON_MUX(0x2, "nonAON"), /* pin42 */
+ TOP_MUX(0x0, "SPI1"), /* rxd */
+ TOP_MUX(0x1, "PCM"), /* rxd */
+ TOP_MUX(0x2, "BGPIO"), /* gpio38 */
+ TOP_MUX(0x3, "UART5"), /* txd */
+ TOP_MUX(0x4, "I2S1"), /* dout0 */
+ TOP_MUX(0x5, "ISP")), /* shutter_open */
+ ZX_RESERVED(AON_RESERVED5),
+ ZX_RESERVED(AON_RESERVED6),
+ AON_PIN(AUDIO_DET, TOP_REG3, 3, 2, 0x48, 18,
+ AON_MUX(0x0, "PCU"), /* test4 */
+ AON_MUX(0x1, "AGPIO"), /* agpio27 */
+ AON_MUX(0x2, "nonAON"), /* pin2 */
+ AON_MUX(0x3, "EXT_INT"), /* int16 */
+ TOP_MUX(0x0, "AUDIO"), /* detect */
+ TOP_MUX(0x1, "I2C2"), /* scl */
+ TOP_MUX(0x2, "SPI2")), /* clk */
+ AON_PIN(SPDIF_OUT, TOP_REG3, 14, 2, 0x78, 9,
+ AON_MUX(0x0, "PCU"), /* test5 */
+ AON_MUX(0x1, "AGPIO"), /* agpio22 */
+ AON_MUX(0x2, "nonAON"), /* pin4 */
+ TOP_MUX(0x0, "SPDIF"), /* out */
+ TOP_MUX(0x1, "PWM"), /* out0 */
+ TOP_MUX(0x2, "ISP")), /* fl_trig */
+ AON_PIN(HDMI_CEC, 0, 0, 0, 0x74, 9,
+ AON_MUX(0x0, "PCU"), /* test9 */
+ AON_MUX(0x1, "AGPIO"), /* agpio1 */
+ AON_MUX(0x2, "nonAON")), /* pin16 */
+ AON_PIN(HDMI_HPD, 0, 0, 0, 0x74, 18,
+ AON_MUX(0x0, "PCU"), /* test10 */
+ AON_MUX(0x1, "AGPIO"), /* agpio2 */
+ AON_MUX(0x2, "nonAON")), /* pin17 */
+ AON_PIN(GMAC_25M_OUT, 0, 0, 0, 0x78, 0,
+ AON_MUX(0x0, "PCU"), /* test11 */
+ AON_MUX(0x1, "AGPIO"), /* agpio31 */
+ AON_MUX(0x2, "nonAON")), /* pin43 */
+ AON_PIN(BOOT_SEL0, 0, 0, 0, 0xc0, 9,
+ AON_MUX(0x0, "BOOT"), /* sel0 */
+ AON_MUX(0x1, "AGPIO"), /* agpio18 */
+ AON_MUX(0x2, "nonAON")), /* pin18 */
+ AON_PIN(BOOT_SEL1, 0, 0, 0, 0xc0, 18,
+ AON_MUX(0x0, "BOOT"), /* sel1 */
+ AON_MUX(0x1, "AGPIO"), /* agpio19 */
+ AON_MUX(0x2, "nonAON")), /* pin19 */
+ AON_PIN(BOOT_SEL2, 0, 0, 0, 0xc4, 0,
+ AON_MUX(0x0, "BOOT"), /* sel2 */
+ AON_MUX(0x1, "AGPIO"), /* agpio20 */
+ AON_MUX(0x2, "nonAON")), /* pin20 */
+ AON_PIN(DEEP_SLEEP_OUT_N, 0, 0, 0, 0xc4, 9,
+ AON_MUX(0x0, "DEEPSLP"), /* deep sleep out_n */
+ AON_MUX(0x1, "AGPIO"), /* agpio21 */
+ AON_MUX(0x2, "nonAON")), /* pin21 */
+ ZX_RESERVED(AON_RESERVED7),
+
+ /* top_pmm_reg_0 */
+ TOP_PIN(GMII_GTX_CLK, TOP_REG0, 0, 2, 0x10, 0,
+ TOP_MUX(0x0, "GMII"), /* gtx_clk */
+ TOP_MUX(0x1, "DVI0"), /* clk */
+ TOP_MUX(0x2, "BGPIO")), /* gpio0 */
+ TOP_PIN(GMII_TX_CLK, TOP_REG0, 2, 2, 0x10, 9,
+ TOP_MUX(0x0, "GMII"), /* tx_clk */
+ TOP_MUX(0x1, "DVI0"), /* vs */
+ TOP_MUX(0x2, "BGPIO")), /* gpio1 */
+ TOP_PIN(GMII_TXD0, TOP_REG0, 4, 2, 0x10, 18,
+ TOP_MUX(0x0, "GMII"), /* txd0 */
+ TOP_MUX(0x1, "DVI0"), /* hs */
+ TOP_MUX(0x2, "BGPIO")), /* gpio2 */
+ TOP_PIN(GMII_TXD1, TOP_REG0, 6, 2, 0x14, 0,
+ TOP_MUX(0x0, "GMII"), /* txd1 */
+ TOP_MUX(0x1, "DVI0"), /* d0 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio3 */
+ TOP_PIN(GMII_TXD2, TOP_REG0, 8, 2, 0x14, 9,
+ TOP_MUX(0x0, "GMII"), /* txd2 */
+ TOP_MUX(0x1, "DVI0"), /* d1 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio4 */
+ TOP_PIN(GMII_TXD3, TOP_REG0, 10, 2, 0x14, 18,
+ TOP_MUX(0x0, "GMII"), /* txd3 */
+ TOP_MUX(0x1, "DVI0"), /* d2 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio5 */
+ TOP_PIN(GMII_TXD4, TOP_REG0, 12, 2, 0x18, 0,
+ TOP_MUX(0x0, "GMII"), /* txd4 */
+ TOP_MUX(0x1, "DVI0"), /* d3 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio6 */
+ TOP_PIN(GMII_TXD5, TOP_REG0, 14, 2, 0x18, 9,
+ TOP_MUX(0x0, "GMII"), /* txd5 */
+ TOP_MUX(0x1, "DVI0"), /* d4 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio7 */
+ TOP_PIN(GMII_TXD6, TOP_REG0, 16, 2, 0x18, 18,
+ TOP_MUX(0x0, "GMII"), /* txd6 */
+ TOP_MUX(0x1, "DVI0"), /* d5 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio8 */
+ TOP_PIN(GMII_TXD7, TOP_REG0, 18, 2, 0x1c, 0,
+ TOP_MUX(0x0, "GMII"), /* txd7 */
+ TOP_MUX(0x1, "DVI0"), /* d6 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio9 */
+ TOP_PIN(GMII_TX_ER, TOP_REG0, 20, 2, 0x1c, 9,
+ TOP_MUX(0x0, "GMII"), /* tx_er */
+ TOP_MUX(0x1, "DVI0"), /* d7 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio10 */
+ TOP_PIN(GMII_TX_EN, TOP_REG0, 22, 2, 0x1c, 18,
+ TOP_MUX(0x0, "GMII"), /* tx_en */
+ TOP_MUX(0x1, "DVI0"), /* d8 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio11 */
+ TOP_PIN(GMII_RX_CLK, TOP_REG0, 24, 2, 0x20, 0,
+ TOP_MUX(0x0, "GMII"), /* rx_clk */
+ TOP_MUX(0x1, "DVI0"), /* d9 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio12 */
+ TOP_PIN(GMII_RXD0, TOP_REG0, 26, 2, 0x20, 9,
+ TOP_MUX(0x0, "GMII"), /* rxd0 */
+ TOP_MUX(0x1, "DVI0"), /* d10 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio13 */
+ TOP_PIN(GMII_RXD1, TOP_REG0, 28, 2, 0x20, 18,
+ TOP_MUX(0x0, "GMII"), /* rxd1 */
+ TOP_MUX(0x1, "DVI0"), /* d11 */
+ TOP_MUX(0x2, "BGPIO")), /* gpio14 */
+ TOP_PIN(GMII_RXD2, TOP_REG0, 30, 2, 0x24, 0,
+ TOP_MUX(0x0, "GMII"), /* rxd2 */
+ TOP_MUX(0x1, "DVI1"), /* clk */
+ TOP_MUX(0x2, "BGPIO")), /* gpio15 */
+
+ /* top_pmm_reg_1 */
+ TOP_PIN(GMII_RXD3, TOP_REG1, 0, 2, 0x24, 9,
+ TOP_MUX(0x0, "GMII"), /* rxd3 */
+ TOP_MUX(0x1, "DVI1"), /* hs */
+ TOP_MUX(0x2, "BGPIO")), /* gpio16 */
+ TOP_PIN(GMII_RXD4, TOP_REG1, 2, 2, 0x24, 18,
+ TOP_MUX(0x0, "GMII"), /* rxd4 */
+ TOP_MUX(0x1, "DVI1"), /* vs */
+ TOP_MUX(0x2, "BGPIO")), /* gpio17 */
+ TOP_PIN(GMII_RXD5, TOP_REG1, 4, 2, 0x28, 0,
+ TOP_MUX(0x0, "GMII"), /* rxd5 */
+ TOP_MUX(0x1, "DVI1"), /* d0 */
+ TOP_MUX(0x2, "BGPIO"), /* gpio18 */
+ TOP_MUX(0x3, "TSI0")), /* dat0 */
+ TOP_PIN(GMII_RXD6, TOP_REG1, 6, 2, 0x28, 9,
+ TOP_MUX(0x0, "GMII"), /* rxd6 */
+ TOP_MUX(0x1, "DVI1"), /* d1 */
+ TOP_MUX(0x2, "BGPIO"), /* gpio19 */
+ TOP_MUX(0x3, "TSI0")), /* clk */
+ TOP_PIN(GMII_RXD7, TOP_REG1, 8, 2, 0x28, 18,
+ TOP_MUX(0x0, "GMII"), /* rxd7 */
+ TOP_MUX(0x1, "DVI1"), /* d2 */
+ TOP_MUX(0x2, "BGPIO"), /* gpio20 */
+ TOP_MUX(0x3, "TSI0")), /* sync */
+ TOP_PIN(GMII_RX_ER, TOP_REG1, 10, 2, 0x2c, 0,
+ TOP_MUX(0x0, "GMII"), /* rx_er */
+ TOP_MUX(0x1, "DVI1"), /* d3 */
+ TOP_MUX(0x2, "BGPIO"), /* gpio21 */
+ TOP_MUX(0x3, "TSI0")), /* valid */
+ TOP_PIN(GMII_RX_DV, TOP_REG1, 12, 2, 0x2c, 9,
+ TOP_MUX(0x0, "GMII"), /* rx_dv */
+ TOP_MUX(0x1, "DVI1"), /* d4 */
+ TOP_MUX(0x2, "BGPIO"), /* gpio22 */
+ TOP_MUX(0x3, "TSI1")), /* dat0 */
+ TOP_PIN(GMII_COL, TOP_REG1, 14, 2, 0x2c, 18,
+ TOP_MUX(0x0, "GMII"), /* col */
+ TOP_MUX(0x1, "DVI1"), /* d5 */
+ TOP_MUX(0x2, "BGPIO"), /* gpio23 */
+ TOP_MUX(0x3, "TSI1")), /* clk */
+ TOP_PIN(GMII_CRS, TOP_REG1, 16, 2, 0x30, 0,
+ TOP_MUX(0x0, "GMII"), /* crs */
+ TOP_MUX(0x1, "DVI1"), /* d6 */
+ TOP_MUX(0x2, "BGPIO"), /* gpio24 */
+ TOP_MUX(0x3, "TSI1")), /* sync */
+ TOP_PIN(GMII_MDC, TOP_REG1, 18, 2, 0x30, 9,
+ TOP_MUX(0x0, "GMII"), /* mdc */
+ TOP_MUX(0x1, "DVI1"), /* d7 */
+ TOP_MUX(0x2, "BGPIO"), /* gpio25 */
+ TOP_MUX(0x3, "TSI1")), /* valid */
+ TOP_PIN(GMII_MDIO, TOP_REG1, 20, 1, 0x30, 18,
+ TOP_MUX(0x0, "GMII"), /* mdio */
+ TOP_MUX(0x2, "BGPIO")), /* gpio26 */
+ TOP_PIN(SDIO1_CLK, TOP_REG1, 21, 2, 0x34, 18,
+ TOP_MUX(0x0, "SDIO1"), /* clk */
+ TOP_MUX(0x1, "USIM0"), /* clk */
+ TOP_MUX(0x2, "BGPIO"), /* gpio27 */
+ TOP_MUX(0x3, "SPINOR")), /* clk */
+ TOP_PIN(SDIO1_CMD, TOP_REG1, 23, 2, 0x38, 0,
+ TOP_MUX(0x0, "SDIO1"), /* cmd */
+ TOP_MUX(0x1, "USIM0"), /* cd */
+ TOP_MUX(0x2, "BGPIO"), /* gpio28 */
+ TOP_MUX(0x3, "SPINOR")), /* cs */
+ TOP_PIN(SDIO1_DATA0, TOP_REG1, 25, 2, 0x38, 9,
+ TOP_MUX(0x0, "SDIO1"), /* dat0 */
+ TOP_MUX(0x1, "USIM0"), /* rst */
+ TOP_MUX(0x2, "BGPIO"), /* gpio29 */
+ TOP_MUX(0x3, "SPINOR")), /* dq0 */
+ TOP_PIN(SDIO1_DATA1, TOP_REG1, 27, 2, 0x38, 18,
+ TOP_MUX(0x0, "SDIO1"), /* dat1 */
+ TOP_MUX(0x1, "USIM0"), /* data */
+ TOP_MUX(0x2, "BGPIO"), /* gpio30 */
+ TOP_MUX(0x3, "SPINOR")), /* dq1 */
+ TOP_PIN(SDIO1_DATA2, TOP_REG1, 29, 2, 0x3c, 0,
+ TOP_MUX(0x0, "SDIO1"), /* dat2 */
+ TOP_MUX(0x1, "BGPIO"), /* gpio31 */
+ TOP_MUX(0x2, "SPINOR")), /* dq2 */
+
+ /* top_pmm_reg_2 */
+ TOP_PIN(SDIO1_DATA3, TOP_REG2, 0, 2, 0x3c, 9,
+ TOP_MUX(0x0, "SDIO1"), /* dat3 */
+ TOP_MUX(0x1, "BGPIO"), /* gpio32 */
+ TOP_MUX(0x2, "SPINOR")), /* dq3 */
+ TOP_PIN(SDIO1_CD, TOP_REG2, 2, 2, 0x3c, 18,
+ TOP_MUX(0x0, "SDIO1"), /* cd */
+ TOP_MUX(0x1, "BGPIO"), /* gpio33 */
+ TOP_MUX(0x2, "ISP")), /* fl_trig */
+ TOP_PIN(SDIO1_WP, TOP_REG2, 4, 2, 0x40, 0,
+ TOP_MUX(0x0, "SDIO1"), /* wp */
+ TOP_MUX(0x1, "BGPIO"), /* gpio34 */
+ TOP_MUX(0x2, "ISP")), /* ref_clk */
+ TOP_PIN(USIM1_CD, TOP_REG2, 22, 3, 0x44, 18,
+ TOP_MUX(0x0, "USIM1"), /* cd */
+ TOP_MUX(0x1, "UART4"), /* rxd */
+ TOP_MUX(0x2, "BGPIO"), /* gpio39 */
+ TOP_MUX(0x3, "SPI3"), /* clk */
+ TOP_MUX(0x4, "I2S0"), /* bclk */
+ TOP_MUX(0x5, "B_DVI0")), /* d8 */
+ TOP_PIN(USIM1_CLK, TOP_REG2, 25, 3, 0x4c, 18,
+ TOP_MUX(0x0, "USIM1"), /* clk */
+ TOP_MUX(0x1, "UART4"), /* txd */
+ TOP_MUX(0x2, "BGPIO"), /* gpio40 */
+ TOP_MUX(0x3, "SPI3"), /* cs */
+ TOP_MUX(0x4, "I2S0"), /* ws */
+ TOP_MUX(0x5, "B_DVI0")), /* d9 */
+ TOP_PIN(USIM1_RST, TOP_REG2, 28, 3, 0x4c, 0,
+ TOP_MUX(0x0, "USIM1"), /* rst */
+ TOP_MUX(0x1, "UART4"), /* cts */
+ TOP_MUX(0x2, "BGPIO"), /* gpio41 */
+ TOP_MUX(0x3, "SPI3"), /* txd */
+ TOP_MUX(0x4, "I2S0"), /* dout0 */
+ TOP_MUX(0x5, "B_DVI0")), /* d10 */
+
+ /* top_pmm_reg_3 */
+ TOP_PIN(USIM1_DATA, TOP_REG3, 0, 3, 0x4c, 9,
+ TOP_MUX(0x0, "USIM1"), /* dat */
+ TOP_MUX(0x1, "UART4"), /* rst */
+ TOP_MUX(0x2, "BGPIO"), /* gpio42 */
+ TOP_MUX(0x3, "SPI3"), /* rxd */
+ TOP_MUX(0x4, "I2S0"), /* din0 */
+ TOP_MUX(0x5, "B_DVI0")), /* d11 */
+ TOP_PIN(SDIO0_CLK, TOP_REG3, 6, 1, 0x58, 0,
+ TOP_MUX(0x0, "SDIO0"), /* clk */
+ TOP_MUX(0x1, "GPIO")), /* gpio43 */
+ TOP_PIN(SDIO0_CMD, TOP_REG3, 7, 1, 0x58, 9,
+ TOP_MUX(0x0, "SDIO0"), /* cmd */
+ TOP_MUX(0x1, "GPIO")), /* gpio44 */
+ TOP_PIN(SDIO0_DATA0, TOP_REG3, 8, 1, 0x58, 18,
+ TOP_MUX(0x0, "SDIO0"), /* dat0 */
+ TOP_MUX(0x1, "GPIO")), /* gpio45 */
+ TOP_PIN(SDIO0_DATA1, TOP_REG3, 9, 1, 0x5c, 0,
+ TOP_MUX(0x0, "SDIO0"), /* dat1 */
+ TOP_MUX(0x1, "GPIO")), /* gpio46 */
+ TOP_PIN(SDIO0_DATA2, TOP_REG3, 10, 1, 0x5c, 9,
+ TOP_MUX(0x0, "SDIO0"), /* dat2 */
+ TOP_MUX(0x1, "GPIO")), /* gpio47 */
+ TOP_PIN(SDIO0_DATA3, TOP_REG3, 11, 1, 0x5c, 18,
+ TOP_MUX(0x0, "SDIO0"), /* dat3 */
+ TOP_MUX(0x1, "GPIO")), /* gpio48 */
+ TOP_PIN(SDIO0_CD, TOP_REG3, 12, 1, 0x60, 0,
+ TOP_MUX(0x0, "SDIO0"), /* cd */
+ TOP_MUX(0x1, "GPIO")), /* gpio49 */
+ TOP_PIN(SDIO0_WP, TOP_REG3, 13, 1, 0x60, 9,
+ TOP_MUX(0x0, "SDIO0"), /* wp */
+ TOP_MUX(0x1, "GPIO")), /* gpio50 */
+
+ /* top_pmm_reg_4 */
+ TOP_PIN(TSI0_DATA0, TOP_REG4, 0, 2, 0x60, 18,
+ TOP_MUX(0x0, "TSI0"), /* dat0 */
+ TOP_MUX(0x1, "LCD"), /* clk */
+ TOP_MUX(0x2, "BGPIO")), /* gpio51 */
+ TOP_PIN(SPINOR_CLK, TOP_REG4, 2, 2, 0xa8, 18,
+ TOP_MUX(0x0, "SPINOR"), /* clk */
+ TOP_MUX(0x1, "TSI0"), /* dat1 */
+ TOP_MUX(0x2, "LCD"), /* dat0 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio52 */
+ TOP_PIN(TSI2_DATA, TOP_REG4, 4, 2, 0x7c, 0,
+ TOP_MUX(0x0, "TSI2"), /* dat */
+ TOP_MUX(0x1, "TSI0"), /* dat2 */
+ TOP_MUX(0x2, "LCD"), /* dat1 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio53 */
+ TOP_PIN(TSI2_CLK, TOP_REG4, 6, 2, 0x7c, 9,
+ TOP_MUX(0x0, "TSI2"), /* clk */
+ TOP_MUX(0x1, "TSI0"), /* dat3 */
+ TOP_MUX(0x2, "LCD"), /* dat2 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio54 */
+ TOP_PIN(TSI2_SYNC, TOP_REG4, 8, 2, 0x7c, 18,
+ TOP_MUX(0x0, "TSI2"), /* sync */
+ TOP_MUX(0x1, "TSI0"), /* dat4 */
+ TOP_MUX(0x2, "LCD"), /* dat3 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio55 */
+ TOP_PIN(TSI2_VALID, TOP_REG4, 10, 2, 0x80, 0,
+ TOP_MUX(0x0, "TSI2"), /* valid */
+ TOP_MUX(0x1, "TSI0"), /* dat5 */
+ TOP_MUX(0x2, "LCD"), /* dat4 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio56 */
+ TOP_PIN(SPINOR_CS, TOP_REG4, 12, 2, 0x80, 9,
+ TOP_MUX(0x0, "SPINOR"), /* cs */
+ TOP_MUX(0x1, "TSI0"), /* dat6 */
+ TOP_MUX(0x2, "LCD"), /* dat5 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio57 */
+ TOP_PIN(SPINOR_DQ0, TOP_REG4, 14, 2, 0x80, 18,
+ TOP_MUX(0x0, "SPINOR"), /* dq0 */
+ TOP_MUX(0x1, "TSI0"), /* dat7 */
+ TOP_MUX(0x2, "LCD"), /* dat6 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio58 */
+ TOP_PIN(SPINOR_DQ1, TOP_REG4, 16, 2, 0x84, 0,
+ TOP_MUX(0x0, "SPINOR"), /* dq1 */
+ TOP_MUX(0x1, "TSI0"), /* clk */
+ TOP_MUX(0x2, "LCD"), /* dat7 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio59 */
+ TOP_PIN(SPINOR_DQ2, TOP_REG4, 18, 2, 0x84, 9,
+ TOP_MUX(0x0, "SPINOR"), /* dq2 */
+ TOP_MUX(0x1, "TSI0"), /* sync */
+ TOP_MUX(0x2, "LCD"), /* dat8 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio60 */
+ TOP_PIN(SPINOR_DQ3, TOP_REG4, 20, 2, 0x84, 18,
+ TOP_MUX(0x0, "SPINOR"), /* dq3 */
+ TOP_MUX(0x1, "TSI0"), /* valid */
+ TOP_MUX(0x2, "LCD"), /* dat9 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio61 */
+ TOP_PIN(VGA_HS, TOP_REG4, 22, 3, 0x88, 0,
+ TOP_MUX(0x0, "VGA"), /* hs */
+ TOP_MUX(0x1, "TSI1"), /* dat0 */
+ TOP_MUX(0x2, "LCD"), /* dat10 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio62 */
+ TOP_MUX(0x4, "I2S1"), /* din1 */
+ TOP_MUX(0x5, "B_DVI0")), /* clk */
+ TOP_PIN(VGA_VS, TOP_REG4, 25, 3, 0x88, 9,
+ TOP_MUX(0x0, "VGA"), /* vs0 */
+ TOP_MUX(0x1, "TSI1"), /* dat1 */
+ TOP_MUX(0x2, "LCD"), /* dat11 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio63 */
+ TOP_MUX(0x4, "I2S1"), /* din2 */
+ TOP_MUX(0x5, "B_DVI0")), /* vs */
+ TOP_PIN(TSI3_DATA, TOP_REG4, 28, 3, 0x88, 18,
+ TOP_MUX(0x0, "TSI3"), /* dat */
+ TOP_MUX(0x1, "TSI1"), /* dat2 */
+ TOP_MUX(0x2, "LCD"), /* dat12 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio64 */
+ TOP_MUX(0x4, "I2S1"), /* din3 */
+ TOP_MUX(0x5, "B_DVI0")), /* hs */
+
+ /* top_pmm_reg_5 */
+ TOP_PIN(TSI3_CLK, TOP_REG5, 0, 3, 0x8c, 0,
+ TOP_MUX(0x0, "TSI3"), /* clk */
+ TOP_MUX(0x1, "TSI1"), /* dat3 */
+ TOP_MUX(0x2, "LCD"), /* dat13 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio65 */
+ TOP_MUX(0x4, "I2S1"), /* dout1 */
+ TOP_MUX(0x5, "B_DVI0")), /* d0 */
+ TOP_PIN(TSI3_SYNC, TOP_REG5, 3, 3, 0x8c, 9,
+ TOP_MUX(0x0, "TSI3"), /* sync */
+ TOP_MUX(0x1, "TSI1"), /* dat4 */
+ TOP_MUX(0x2, "LCD"), /* dat14 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio66 */
+ TOP_MUX(0x4, "I2S1"), /* dout2 */
+ TOP_MUX(0x5, "B_DVI0")), /* d1 */
+ TOP_PIN(TSI3_VALID, TOP_REG5, 6, 3, 0x8c, 18,
+ TOP_MUX(0x0, "TSI3"), /* valid */
+ TOP_MUX(0x1, "TSI1"), /* dat5 */
+ TOP_MUX(0x2, "LCD"), /* dat15 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio67 */
+ TOP_MUX(0x4, "I2S1"), /* dout3 */
+ TOP_MUX(0x5, "B_DVI0")), /* d2 */
+ TOP_PIN(I2S1_WS, TOP_REG5, 9, 3, 0x90, 0,
+ TOP_MUX(0x0, "I2S1"), /* ws */
+ TOP_MUX(0x1, "TSI1"), /* dat6 */
+ TOP_MUX(0x2, "LCD"), /* dat16 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio68 */
+ TOP_MUX(0x4, "VGA"), /* scl */
+ TOP_MUX(0x5, "B_DVI0")), /* d3 */
+ TOP_PIN(I2S1_BCLK, TOP_REG5, 12, 3, 0x90, 9,
+ TOP_MUX(0x0, "I2S1"), /* bclk */
+ TOP_MUX(0x1, "TSI1"), /* dat7 */
+ TOP_MUX(0x2, "LCD"), /* dat17 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio69 */
+ TOP_MUX(0x4, "VGA"), /* sda */
+ TOP_MUX(0x5, "B_DVI0")), /* d4 */
+ TOP_PIN(I2S1_MCLK, TOP_REG5, 15, 2, 0x90, 18,
+ TOP_MUX(0x0, "I2S1"), /* mclk */
+ TOP_MUX(0x1, "TSI1"), /* clk */
+ TOP_MUX(0x2, "LCD"), /* dat18 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio70 */
+ TOP_PIN(I2S1_DIN0, TOP_REG5, 17, 2, 0x94, 0,
+ TOP_MUX(0x0, "I2S1"), /* din0 */
+ TOP_MUX(0x1, "TSI1"), /* sync */
+ TOP_MUX(0x2, "LCD"), /* dat19 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio71 */
+ TOP_PIN(I2S1_DOUT0, TOP_REG5, 19, 2, 0x94, 9,
+ TOP_MUX(0x0, "I2S1"), /* dout0 */
+ TOP_MUX(0x1, "TSI1"), /* valid */
+ TOP_MUX(0x2, "LCD"), /* dat20 */
+ TOP_MUX(0x3, "BGPIO")), /* gpio72 */
+ TOP_PIN(SPI3_CLK, TOP_REG5, 21, 3, 0x94, 18,
+ TOP_MUX(0x0, "SPI3"), /* clk */
+ TOP_MUX(0x1, "TSO1"), /* clk */
+ TOP_MUX(0x2, "LCD"), /* dat21 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio73 */
+ TOP_MUX(0x4, "UART5"), /* rxd */
+ TOP_MUX(0x5, "PCM"), /* fs */
+ TOP_MUX(0x6, "I2S0"), /* din1 */
+ TOP_MUX(0x7, "B_DVI0")), /* d5 */
+ TOP_PIN(SPI3_CS, TOP_REG5, 24, 3, 0x98, 0,
+ TOP_MUX(0x0, "SPI3"), /* cs */
+ TOP_MUX(0x1, "TSO1"), /* dat0 */
+ TOP_MUX(0x2, "LCD"), /* dat22 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio74 */
+ TOP_MUX(0x4, "UART5"), /* txd */
+ TOP_MUX(0x5, "PCM"), /* clk */
+ TOP_MUX(0x6, "I2S0"), /* din2 */
+ TOP_MUX(0x7, "B_DVI0")), /* d6 */
+ TOP_PIN(SPI3_TXD, TOP_REG5, 27, 3, 0x98, 9,
+ TOP_MUX(0x0, "SPI3"), /* txd */
+ TOP_MUX(0x1, "TSO1"), /* dat1 */
+ TOP_MUX(0x2, "LCD"), /* dat23 */
+ TOP_MUX(0x3, "BGPIO"), /* gpio75 */
+ TOP_MUX(0x4, "UART5"), /* cts */
+ TOP_MUX(0x5, "PCM"), /* txd */
+ TOP_MUX(0x6, "I2S0"), /* din3 */
+ TOP_MUX(0x7, "B_DVI0")), /* d7 */
+ TOP_PIN(NAND_LDO_MS18_SEL, TOP_REG5, 30, 1, 0xe4, 0,
+ TOP_MUX(0x0, "NAND"), /* ldo_ms18_sel */
+ TOP_MUX(0x1, "BGPIO")), /* gpio99 */
+
+ /* top_pmm_reg_6 */
+ TOP_PIN(SPI3_RXD, TOP_REG6, 0, 3, 0x98, 18,
+ TOP_MUX(0x0, "SPI3"), /* rxd */
+ TOP_MUX(0x1, "TSO1"), /* dat2 */
+ TOP_MUX(0x2, "LCD"), /* stvu_vsync */
+ TOP_MUX(0x3, "BGPIO"), /* gpio76 */
+ TOP_MUX(0x4, "UART5"), /* rts */
+ TOP_MUX(0x5, "PCM"), /* rxd */
+ TOP_MUX(0x6, "I2S0"), /* dout1 */
+ TOP_MUX(0x7, "B_DVI1")), /* clk */
+ TOP_PIN(I2S0_MCLK, TOP_REG6, 3, 3, 0x9c, 0,
+ TOP_MUX(0x0, "I2S0"), /* mclk */
+ TOP_MUX(0x1, "TSO1"), /* dat3 */
+ TOP_MUX(0x2, "LCD"), /* stvd */
+ TOP_MUX(0x3, "BGPIO"), /* gpio77 */
+ TOP_MUX(0x4, "USIM0"), /* cd */
+ TOP_MUX(0x5, "B_DVI1")), /* vs */
+ TOP_PIN(I2S0_BCLK, TOP_REG6, 6, 3, 0x9c, 9,
+ TOP_MUX(0x0, "I2S0"), /* bclk */
+ TOP_MUX(0x1, "TSO1"), /* dat4 */
+ TOP_MUX(0x2, "LCD"), /* sthl_hsync */
+ TOP_MUX(0x3, "BGPIO"), /* gpio78 */
+ TOP_MUX(0x4, "USIM0"), /* clk */
+ TOP_MUX(0x5, "B_DVI1")), /* hs */
+ TOP_PIN(I2S0_WS, TOP_REG6, 9, 3, 0x9c, 18,
+ TOP_MUX(0x0, "I2S0"), /* ws */
+ TOP_MUX(0x1, "TSO1"), /* dat5 */
+ TOP_MUX(0x2, "LCD"), /* sthr */
+ TOP_MUX(0x3, "BGPIO"), /* gpio79 */
+ TOP_MUX(0x4, "USIM0"), /* rst */
+ TOP_MUX(0x5, "B_DVI1")), /* d0 */
+ TOP_PIN(I2S0_DIN0, TOP_REG6, 12, 3, 0xa0, 0,
+ TOP_MUX(0x0, "I2S0"), /* din0 */
+ TOP_MUX(0x1, "TSO1"), /* dat6 */
+ TOP_MUX(0x2, "LCD"), /* oev_dataen */
+ TOP_MUX(0x3, "BGPIO"), /* gpio80 */
+ TOP_MUX(0x4, "USIM0"), /* dat */
+ TOP_MUX(0x5, "B_DVI1")), /* d1 */
+ TOP_PIN(I2S0_DOUT0, TOP_REG6, 15, 2, 0xa0, 9,
+ TOP_MUX(0x0, "I2S0"), /* dout0 */
+ TOP_MUX(0x1, "TSO1"), /* dat7 */
+ TOP_MUX(0x2, "LCD"), /* ckv */
+ TOP_MUX(0x3, "BGPIO")), /* gpio81 */
+ TOP_PIN(I2C5_SCL, TOP_REG6, 17, 3, 0xa0, 18,
+ TOP_MUX(0x0, "I2C5"), /* scl */
+ TOP_MUX(0x1, "TSO1"), /* sync */
+ TOP_MUX(0x2, "LCD"), /* ld */
+ TOP_MUX(0x3, "BGPIO"), /* gpio82 */
+ TOP_MUX(0x4, "PWM"), /* out2 */
+ TOP_MUX(0x5, "I2S0"), /* dout2 */
+ TOP_MUX(0x6, "B_DVI1")), /* d2 */
+ TOP_PIN(I2C5_SDA, TOP_REG6, 20, 3, 0xa4, 0,
+ TOP_MUX(0x0, "I2C5"), /* sda */
+ TOP_MUX(0x1, "TSO1"), /* vld */
+ TOP_MUX(0x2, "LCD"), /* pol */
+ TOP_MUX(0x3, "BGPIO"), /* gpio83 */
+ TOP_MUX(0x4, "PWM"), /* out3 */
+ TOP_MUX(0x5, "I2S0"), /* dout3 */
+ TOP_MUX(0x6, "B_DVI1")), /* d3 */
+ TOP_PIN(SPI2_CLK, TOP_REG6, 23, 3, 0xa4, 9,
+ TOP_MUX(0x0, "SPI2"), /* clk */
+ TOP_MUX(0x1, "TSO0"), /* clk */
+ TOP_MUX(0x2, "LCD"), /* degsl */
+ TOP_MUX(0x3, "BGPIO"), /* gpio84 */
+ TOP_MUX(0x4, "I2C4"), /* scl */
+ TOP_MUX(0x5, "B_DVI1")), /* d4 */
+ TOP_PIN(SPI2_CS, TOP_REG6, 26, 3, 0xa4, 18,
+ TOP_MUX(0x0, "SPI2"), /* cs */
+ TOP_MUX(0x1, "TSO0"), /* data */
+ TOP_MUX(0x2, "LCD"), /* rev */
+ TOP_MUX(0x3, "BGPIO"), /* gpio85 */
+ TOP_MUX(0x4, "I2C4"), /* sda */
+ TOP_MUX(0x5, "B_DVI1")), /* d5 */
+ TOP_PIN(SPI2_TXD, TOP_REG6, 29, 3, 0xa8, 0,
+ TOP_MUX(0x0, "SPI2"), /* txd */
+ TOP_MUX(0x1, "TSO0"), /* sync */
+ TOP_MUX(0x2, "LCD"), /* u_d */
+ TOP_MUX(0x3, "BGPIO"), /* gpio86 */
+ TOP_MUX(0x4, "I2C4"), /* scl */
+ TOP_MUX(0x5, "B_DVI1")), /* d6 */
+
+ /* top_pmm_reg_7 */
+ TOP_PIN(SPI2_RXD, TOP_REG7, 0, 3, 0xa8, 9,
+ TOP_MUX(0x0, "SPI2"), /* rxd */
+ TOP_MUX(0x1, "TSO0"), /* vld */
+ TOP_MUX(0x2, "LCD"), /* r_l */
+ TOP_MUX(0x3, "BGPIO"), /* gpio87 */
+ TOP_MUX(0x4, "I2C3"), /* sda */
+ TOP_MUX(0x5, "B_DVI1")), /* d7 */
+ TOP_PIN(NAND_WP_N, TOP_REG7, 7, 3, 0x54, 9,
+ TOP_MUX(0x0, "NAND"), /* wp */
+ TOP_MUX(0x1, "PWM"), /* out2 */
+ TOP_MUX(0x2, "SPI2"), /* clk */
+ TOP_MUX(0x3, "BGPIO"), /* gpio88 */
+ TOP_MUX(0x4, "TSI0"), /* dat0 */
+ TOP_MUX(0x5, "I2S1")), /* din1 */
+ TOP_PIN(NAND_PAGE_SIZE0, TOP_REG7, 10, 3, 0xb8, 0,
+ TOP_MUX(0x0, "NAND"), /* boot_pagesize0 */
+ TOP_MUX(0x1, "PWM"), /* out3 */
+ TOP_MUX(0x2, "SPI2"), /* cs */
+ TOP_MUX(0x3, "BGPIO"), /* gpio89 */
+ TOP_MUX(0x4, "TSI0"), /* clk */
+ TOP_MUX(0x5, "I2S1")), /* din2 */
+ TOP_PIN(NAND_PAGE_SIZE1, TOP_REG7, 13, 3, 0xb8, 9,
+ TOP_MUX(0x0, "NAND"), /* boot_pagesize1 */
+ TOP_MUX(0x1, "I2C4"), /* scl */
+ TOP_MUX(0x2, "SPI2"), /* txd */
+ TOP_MUX(0x3, "BGPIO"), /* gpio90 */
+ TOP_MUX(0x4, "TSI0"), /* sync */
+ TOP_MUX(0x5, "I2S1")), /* din3 */
+ TOP_PIN(NAND_ADDR_CYCLE, TOP_REG7, 16, 3, 0xb8, 18,
+ TOP_MUX(0x0, "NAND"), /* boot_addr_cycles */
+ TOP_MUX(0x1, "I2C4"), /* sda */
+ TOP_MUX(0x2, "SPI2"), /* rxd */
+ TOP_MUX(0x3, "BGPIO"), /* gpio91 */
+ TOP_MUX(0x4, "TSI0"), /* valid */
+ TOP_MUX(0x5, "I2S1")), /* dout1 */
+ TOP_PIN(NAND_RB0, TOP_REG7, 19, 3, 0xbc, 0,
+ TOP_MUX(0x0, "NAND"), /* rdy_busy0 */
+ TOP_MUX(0x1, "I2C2"), /* scl */
+ TOP_MUX(0x2, "USIM0"), /* cd */
+ TOP_MUX(0x3, "BGPIO"), /* gpio92 */
+ TOP_MUX(0x4, "TSI1")), /* data0 */
+ TOP_PIN(NAND_RB1, TOP_REG7, 22, 3, 0xbc, 9,
+ TOP_MUX(0x0, "NAND"), /* rdy_busy1 */
+ TOP_MUX(0x1, "I2C2"), /* sda */
+ TOP_MUX(0x2, "USIM0"), /* clk */
+ TOP_MUX(0x3, "BGPIO"), /* gpio93 */
+ TOP_MUX(0x4, "TSI1")), /* clk */
+ TOP_PIN(NAND_RB2, TOP_REG7, 25, 3, 0xbc, 18,
+ TOP_MUX(0x0, "NAND"), /* rdy_busy2 */
+ TOP_MUX(0x1, "UART5"), /* rxd */
+ TOP_MUX(0x2, "USIM0"), /* rst */
+ TOP_MUX(0x3, "BGPIO"), /* gpio94 */
+ TOP_MUX(0x4, "TSI1"), /* sync */
+ TOP_MUX(0x4, "I2S1")), /* dout2 */
+ TOP_PIN(NAND_RB3, TOP_REG7, 28, 3, 0x54, 18,
+ TOP_MUX(0x0, "NAND"), /* rdy_busy3 */
+ TOP_MUX(0x1, "UART5"), /* txd */
+ TOP_MUX(0x2, "USIM0"), /* dat */
+ TOP_MUX(0x3, "BGPIO"), /* gpio95 */
+ TOP_MUX(0x4, "TSI1"), /* valid */
+ TOP_MUX(0x4, "I2S1")), /* dout3 */
+
+ /* top_pmm_reg_8 */
+ TOP_PIN(GMAC_125M_IN, TOP_REG8, 0, 2, 0x34, 0,
+ TOP_MUX(0x0, "GMII"), /* 125m_in */
+ TOP_MUX(0x1, "USB2"), /* 0_drvvbus */
+ TOP_MUX(0x2, "ISP"), /* ref_clk */
+ TOP_MUX(0x3, "BGPIO")), /* gpio96 */
+ TOP_PIN(GMAC_50M_OUT, TOP_REG8, 2, 2, 0x34, 9,
+ TOP_MUX(0x0, "GMII"), /* 50m_out */
+ TOP_MUX(0x1, "USB2"), /* 1_drvvbus */
+ TOP_MUX(0x2, "BGPIO"), /* gpio97 */
+ TOP_MUX(0x3, "USB2")), /* 0_drvvbus */
+ TOP_PIN(SPINOR_SSCLK_LOOPBACK, TOP_REG8, 6, 1, 0xc8, 9,
+ TOP_MUX(0x0, "SPINOR")), /* sdio1_clk_i */
+ TOP_PIN(SPINOR_SDIO1CLK_LOOPBACK, TOP_REG8, 7, 1, 0xc8, 18,
+ TOP_MUX(0x0, "SPINOR")), /* ssclk_i */
+};
+
+static struct zx_pinctrl_soc_info zx296718_pinctrl_info = {
+ .pins = zx296718_pins,
+ .npins = ARRAY_SIZE(zx296718_pins),
+};
+
+static int zx296718_pinctrl_probe(struct platform_device *pdev)
+{
+ return zx_pinctrl_init(pdev, &zx296718_pinctrl_info);
+}
+
+static const struct of_device_id zx296718_pinctrl_match[] = {
+ { .compatible = "zte,zx296718-pmm", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, zx296718_pinctrl_match);
+
+static struct platform_driver zx296718_pinctrl_driver = {
+ .probe = zx296718_pinctrl_probe,
+ .driver = {
+ .name = "zx296718-pinctrl",
+ .of_match_table = zx296718_pinctrl_match,
+ },
+};
+builtin_platform_driver(zx296718_pinctrl_driver);
+
+MODULE_DESCRIPTION("ZTE ZX296718 pinctrl driver");
+MODULE_LICENSE("GPL");
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: add bindings doc for ZTE pinctrl
From: Shawn Guo @ 2017-04-24 13:01 UTC (permalink / raw)
To: Linus Walleij
Cc: Rob Herring, linux-gpio, devicetree, linux-arm-kernel, Baoyou Xie,
Xin Zhou, Jun Nie, Shawn Guo
In-Reply-To: <1493038873-18354-1-git-send-email-shawnguo@kernel.org>
From: Shawn Guo <shawn.guo@linaro.org>
It adds device tree bindings for ZTE pin controller found on ZX2967xx
family SoCs.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
.../devicetree/bindings/pinctrl/pinctrl-zx.txt | 85 ++++++++++++++++++++++
1 file changed, 85 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt
new file mode 100644
index 000000000000..e219849b21ca
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt
@@ -0,0 +1,85 @@
+* ZTE ZX Pin Controller
+
+The pin controller on ZTE ZX platforms is kinda of hybrid. It consists of
+a main controller and an auxiliary one. For example, on ZX296718 SoC, the
+main controller is TOP_PMM and the auxiliary one is AON_IOCFG. Both
+controllers work together to control pin multiplexing and configuration in
+the way illustrated as below.
+
+
+ GMII_RXD3 ---+
+ |
+ DVI1_HS ---+----------------------------- GMII_RXD3 (TOP pin)
+ |
+ BGPIO16 ---+ ^
+ | pinconf
+ ^ |
+ | pinmux |
+ | |
+
+ TOP_PMM (main) AON_IOCFG (aux)
+
+ | | |
+ | pinmux | |
+ | pinmux v |
+ v | pinconf
+ KEY_ROW2 ---+ v
+ PORT1_LCD_TE ---+ |
+ | AGPIO10 ---+------ KEY_ROW2 (AON pin)
+ I2S0_DOUT3 ---+ |
+ |-----------------------+
+ PWM_OUT3 ---+
+ |
+ VGA_VS1 ---+
+
+
+For most of pins like GMII_RXD3 in the figure, the pinmux function is
+controlled by TOP_PMM block only, and this type of pins are meant by term
+'TOP pins'. For pins like KEY_ROW2, the pinmux is controlled by both
+TOP_PMM and AON_IOCFG blocks, as the available multiplexing functions for
+the pin spread in both controllers. This type of pins are called 'AON pins'.
+Though pinmux implementation is quite different, pinconf is same for both
+types of pins. Both are controlled by auxiliary controller, i.e. AON_IOCFG
+on ZX296718.
+
+Required properties:
+- compatible: should be "zte,zx296718-pmm".
+- reg: the register physical address and length.
+- zte,auxiliary-controller: phandle to the auxiliary pin controller which
+ implements pinmux for AON pins and pinconf for all pins.
+
+The following pin configuration are supported. Please refer to
+pinctrl-bindings.txt in this directory for more details of the common
+pinctrl bindings used by client devices.
+
+- bias-pull-up
+- bias-pull-down
+- drive-strength
+- input-enable
+- slew-rate
+
+Examples:
+
+iocfg: pin-controller@119000 {
+ compatible = "zte,zx296718-iocfg";
+ reg = <0x119000 0x1000>;
+};
+
+pmm: pin-controller@1462000 {
+ compatible = "zte,zx296718-pmm";
+ reg = <0x1462000 0x1000>;
+ zte,auxiliary-controller = <&iocfg>;
+};
+
+&pmm {
+ vga_pins: vga {
+ pins = "KEY_COL1", "KEY_COL2", "KEY_ROW1", "KEY_ROW2";
+ function = "VGA";
+ };
+};
+
+&vga {
+ pinctrl-names = "default";
+ pinctrl-0 = <&vga_pins>;
+ status = "okay";
+};
--
1.9.1
^ permalink raw reply related
* [PATCH 0/2] Add ZTE ZX pinctrl driver support
From: Shawn Guo @ 2017-04-24 13:01 UTC (permalink / raw)
To: Linus Walleij
Cc: Rob Herring, linux-gpio, devicetree, linux-arm-kernel, Baoyou Xie,
Xin Zhou, Jun Nie, Shawn Guo
From: Shawn Guo <shawn.guo@linaro.org>
This is basically a rewrite of Jun's ZTE ZX pinctrl driver. It
has quite a few significant changes from Jun's version.
- It handles the relation between main and auxiliary controllers
internally, and then we do not need to export core function
pin_request().
- Update bindings document with a ASCII figure to illustrate how this
'hybrid' pin controller hardware works.
- Rather than making up pin name with the fake port name and pin
number, name the pins in the exactly same way how hardware manual
name them.
- Instead of encoding AON register data, calculate the offset and bit
position from pin id.
- Utilize the generic groups and functions support from core to save
quite some code in our driver.
- Simplify the data structures and add documents for important ones.
- Clean up some unnecessary function calls.
Shawn
[1] https://www.spinics.net/lists/linux-gpio/msg16147.html
Shawn Guo (2):
dt-bindings: add bindings doc for ZTE pinctrl
pinctrl: add ZTE ZX pinctrl driver support
.../devicetree/bindings/pinctrl/pinctrl-zx.txt | 85 ++
drivers/pinctrl/Kconfig | 1 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/zte/Kconfig | 13 +
drivers/pinctrl/zte/Makefile | 2 +
drivers/pinctrl/zte/pinctrl-zx.c | 445 +++++++++
drivers/pinctrl/zte/pinctrl-zx.h | 105 ++
drivers/pinctrl/zte/pinctrl-zx296718.c | 1027 ++++++++++++++++++++
8 files changed, 1679 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt
create mode 100644 drivers/pinctrl/zte/Kconfig
create mode 100644 drivers/pinctrl/zte/Makefile
create mode 100644 drivers/pinctrl/zte/pinctrl-zx.c
create mode 100644 drivers/pinctrl/zte/pinctrl-zx.h
create mode 100644 drivers/pinctrl/zte/pinctrl-zx296718.c
--
1.9.1
^ permalink raw reply
* Re: [PATCH v4 13/18] arm64: allwinner: sun50i-a64: add dwmac-sun8i Ethernet driver
From: Chen-Yu Tsai @ 2017-04-24 12:58 UTC (permalink / raw)
To: Corentin Labbe
Cc: Maxime Ripard, Rob Herring, Mark Rutland, Chen-Yu Tsai,
Russell King, Catalin Marinas, Will Deacon, Giuseppe Cavallaro,
alexandre.torgue-qxv4g6HH51o, linux-sunxi, devicetree,
linux-kernel, netdev, linux-arm-kernel
In-Reply-To: <20170424122411.GA9349@Red>
On Mon, Apr 24, 2017 at 8:24 PM, Corentin Labbe
<clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Wed, Apr 12, 2017 at 02:41:53PM +0200, Maxime Ripard wrote:
>> On Wed, Apr 12, 2017 at 01:13:55PM +0200, Corentin Labbe wrote:
>> > The dwmac-sun8i is an Ethernet MAC that supports 10/100/1000 Mbit
>> > connections. It is very similar to the device found in the Allwinner
>> > H3, but lacks the internal 100 Mbit PHY and its associated control
>> > bits.
>> > This adds the necessary bits to the Allwinner A64 SoC .dtsi, but keeps
>> > it disabled at this level.
>> >
>> > Signed-off-by: Corentin Labbe <clabbe.montjoie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> > ---
>> > arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 37 +++++++++++++++++++++++++++
>> > 1 file changed, 37 insertions(+)
>> >
>> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>> > index 0b0f4ab..2569827 100644
>> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
>> > @@ -287,6 +287,23 @@
>> > bias-pull-up;
>> > };
>> >
>> > + rmii_pins: rmii_pins {
>> > + pins = "PD10", "PD11", "PD13", "PD14",
>> > + "PD17", "PD18", "PD19", "PD20",
>> > + "PD22", "PD23";
>>
>> Please align the wrapped lines on the first pin.
>>
>
> OK
>
>> > + function = "emac";
>> > + drive-strength = <40>;
>>
>> Do you actually need that for all the boards, or only a few of them?
>
> I have tried to use lower value without success on some boards. (opipc/pine64 in my memory)
FYI we need them for all the boards that use RGMII.
The signals at gigabit speed run at 125 MHz DDR.
For RMII we probably don't need it. Even at 100 Mbps,
it's only 50 MHz SDR. drive-strength = <30> should be
enough.
ChenYu
^ permalink raw reply
* Re: [PATCH v4 06/14] MIPS: jz4740: DTS: Add nodes for ingenic pinctrl and gpio drivers
From: Linus Walleij @ 2017-04-24 12:58 UTC (permalink / raw)
To: Paul Cercueil
Cc: Alexandre Courbot, Rob Herring, Mark Rutland, Ralf Baechle,
Boris Brezillon, Thierry Reding, Bartlomiej Zolnierkiewicz,
Maarten ter Huurne, Lars-Peter Clausen, Paul Burton, James Hogan,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Linux MIPS,
linux-mmc@vger.kernel.org
In-Reply-To: <e4aaf8c3e8a54df2c5878f8e873e290f@crapouillou.net>
On Fri, Apr 7, 2017 at 3:57 PM, Paul Cercueil <paul@crapouillou.net> wrote:
> I think the 'reg' property makes more sense, yes. I'll fix this in the v5,
> this
> week-end. Do you think it can go in 4.12?
Surely, Torvalds just cut an -rc8 giving me more time to queue more
material, and I really like this series.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v2 4/4] pinctrl: aspeed: g5: Add pinconf support
From: Linus Walleij @ 2017-04-24 12:56 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Joel Stanley, Benjamin Herrenschmidt,
linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
OpenBMC Maillist
In-Reply-To: <20170407125713.15678-5-andrew-zrmu5oMJ5Fs@public.gmane.org>
On Fri, Apr 7, 2017 at 2:57 PM, Andrew Jeffery <andrew-zrmu5oMJ5Fs@public.gmane.org> wrote:
> Testing for pinctrl-aspeed-g5 was performed on an AST2500EVB system,
> using the strategy outlined in the commit message for the change to the
> Aspeed pinctrl core.
>
> Signed-off-by: Andrew Jeffery <andrew-zrmu5oMJ5Fs@public.gmane.org>
Patch applied.
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 3/4] pinctrl: aspeed: g4: Add pinconf support
From: Linus Walleij @ 2017-04-24 12:55 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Joel Stanley, Benjamin Herrenschmidt,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, OpenBMC Maillist
In-Reply-To: <20170407125713.15678-4-andrew@aj.id.au>
On Fri, Apr 7, 2017 at 2:57 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> Testing for pinctrl-aspeed-g4 was performed on an OpenPOWER Palmetto
> system, using the strategy outlined in the commit message for the
> change to the Aspeed pinctrl core.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v2 2/4] pinctrl: aspeed: Add core pinconf support
From: Linus Walleij @ 2017-04-24 12:54 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Joel Stanley, Benjamin Herrenschmidt,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, OpenBMC Maillist
In-Reply-To: <20170407125713.15678-3-andrew@aj.id.au>
On Fri, Apr 7, 2017 at 2:57 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> Several pinconf parameters have a fairly straight-forward mapping onto
> the Aspeed pin controller. These include management of pull-down bias,
> drive-strength, and some debounce configuration.
>
> Pin biasing largely is managed on a per-GPIO-bank basis, aside from the
> ADC and RMII/RGMII pins. As the bias configuration for each pin in a
> bank maps onto a single per-bank bit, configuration tables will be
> introduced to describe the ranges of pins and the supported pinconf
> parameter. The use of tables also helps with the sparse support of
> pinconf properties, and the fact that not all GPIO banks support
> biasing or drive-strength configuration.
>
> Further, as the pin controller uses a consistent approach for bias and
> drive strength configuration at the register level, a second table is
> defined for looking up the the bit-state required to enable or query the
> provided configuration.
>
> Testing for pinctrl-aspeed-g4 was performed on an OpenPOWER Palmetto
> system, and pinctrl-aspeed-g5 on an AST2500EVB as well as under QEMU.
> The test method was to set the appropriate bits via devmem and verify
> the result through the controller's pinconf-pins debugfs file. This
> simultaneously validates the get() path and half of the set() path. The
> remainder of the set() path was validated by configuring a handful of
> pins via the devicetree with the supported pinconf properties and
> verifying the appropriate registers were touched.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Patch applied.
Yours,
Linus Waleij
^ permalink raw reply
* Re: [PATCH v2 4/4] gpio: aspeed: Add open-source and open-drain support
From: Linus Walleij @ 2017-04-24 12:52 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Joel Stanley, Benjamin Herrenschmidt,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, OpenBMC Maillist
In-Reply-To: <20170407125902.15960-5-andrew@aj.id.au>
On Fri, Apr 7, 2017 at 2:59 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> As per the datasheet, manage the IO and value states to implement
> open-source/open-drain, but do this by falling back to gpiolib's
> emulation.
>
> This commit simply makes the behaviour explicit for clarity, rather than
> relying on the implicit return of -ENOTSUPP to trigger the emulation.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v2 3/4] gpio: aspeed: Add debounce support
From: Linus Walleij @ 2017-04-24 12:50 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Joel Stanley, Benjamin Herrenschmidt,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, OpenBMC Maillist
In-Reply-To: <20170407125902.15960-4-andrew@aj.id.au>
On Fri, Apr 7, 2017 at 2:59 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> Each GPIO in the Aspeed GPIO controller can choose one of four input
> debounce states: to disable debouncing for an input, or select from one
> of three programmable debounce timer values. Each GPIO in a
> four-bank-set is assigned one bit in each of two debounce configuration
> registers dedicated to the set, and selects a debounce state by
> configuring the two bits to select one of the four options.
>
> The limitation on debounce timer values is managed by mapping offsets
> onto a configured timer value and keeping count of the number of users
> a timer has. Timer values are configured on a first-come-first-served
> basis.
>
> A small twist in the hardware design is that the debounce configuration
> register numbering is reversed with respect to the binary representation
> of the debounce timer of interest (i.e. debounce register 1 represents
> bit 1, and debounce register 2 represents bit 0 of the timer numbering).
>
> Tested on an AST2500EVB with additional inspection under QEMU's
> romulus-bmc machine.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Patch applied.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH RFC 0/5] *** SPI Slave mode support ***
From: Jiada Wang @ 2017-04-24 12:48 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Mark Brown, Rob Herring, Mark Rutland, Shawn Guo, Sascha Hauer,
Fabio Estevam, linux-spi,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <CAMuHMdXa_O6RsqUciiNWQ0Zp6dniS47AUmPN9UWAWitP0csx=Q@mail.gmail.com>
Hello Geert
On 04/24/2017 03:55 AM, Geert Uytterhoeven wrote:
> Hi Jiada,
>
> On Fri, Apr 14, 2017 at 7:39 AM, Jiada Wang<jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org> wrote:
>> On 04/13/2017 12:47 PM, Geert Uytterhoeven wrote:
>>> On Thu, Apr 13, 2017 at 2:59 PM, Mark Brown<broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>>>> On Thu, Apr 13, 2017 at 05:13:59AM -0700, jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org wrote:
>>>>> From: Jiada Wang<jiada_wang-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>
>>>>>
>>>>> v1:
>>>>> add Slave mode support in SPI core
>>>>> spidev create slave device when SPI controller work in slave mode
>>>>> spi-imx support to work in slave mode
>>>> Adding Geert who also had a series doing this in progress that was
>>>> getting very near to being merged.
>>> Thank you!
>>>
>>> Actually my plan is to fix the last remaining issues and resubmit for
>>> v4.13.
>> I noticed your patch set for SPI slave support,
>> (I am sure you can find out some of the change
>> in this patch set is based on your work).
>> we have similar requirement to add slave mode support to ecspi IP on imx6
>> Soc.
>>
>> Our use case is to use spidev as an interface to communicate with external
>> SPI master devices.
>> meanwhile the SPI bus controller can also act as master device to send data
>> to other
>> SPI slave devices on the board.
> That sounds a bit hackish to me. SPI was never meant to be a multi-master bus.
> While it can be done, you will need external synchronization (signals) to
> avoid conflicts between the SPI masters.
It doesn't need to be a multi-master bus,
for example A is master device for slave device B.
while B has its own slave device C
for each SPI connection A <=> B, and B <=> C, there is only one master
device.
and I think from use case point of view, it's very normal,
one CPU upon receives command from external SPI master device,
it writes data to its own slave device (EEPROM) connected to it.
Thanks,
Jiada
>> I found in your implementation, SPI bus controller is limited to either work
>> in master mode or
>> slave mode, is there any reasoning to not configure SPI mode based on SPI
>> devices use case?
> If you really need both master and slave support, you can use 2 subnodes
> in DT, the first representing the master, the second the slave.
>
> Mark, what's your opinion about this?
>
> Thanks!
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert-Td1EMuHUCqxL1ZNQvxDV9g@public.gmane.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 2/4] gpio: aspeed: dt: Add optional clocks property
From: Linus Walleij @ 2017-04-24 12:47 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Joel Stanley, Benjamin Herrenschmidt,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, OpenBMC Maillist
In-Reply-To: <20170407125902.15960-3-andrew@aj.id.au>
On Fri, Apr 7, 2017 at 2:59 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> We need a reference to the HPLL to calculate debounce cycles. If the
> clocks property is not supplied in the GPIO node then the consumer
> should deny any debounce requests.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Patch applied with Rob's ACK.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v2 1/4] gpio: aspeed: dt: Fix description alignment in bindings document
From: Linus Walleij @ 2017-04-24 12:46 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Joel Stanley, Benjamin Herrenschmidt,
linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
OpenBMC Maillist
In-Reply-To: <20170407125902.15960-2-andrew-zrmu5oMJ5Fs@public.gmane.org>
On Fri, Apr 7, 2017 at 2:58 PM, Andrew Jeffery <andrew-zrmu5oMJ5Fs@public.gmane.org> wrote:
> Signed-off-by: Andrew Jeffery <andrew-zrmu5oMJ5Fs@public.gmane.org>
Patch applied with Rob's ACK.
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 1/4] pinctrl: aspeed: Document pinconf in devicetree bindings
From: Linus Walleij @ 2017-04-24 12:42 UTC (permalink / raw)
To: Andrew Jeffery
Cc: Rob Herring, Joel Stanley, Benjamin Herrenschmidt,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, OpenBMC Maillist
In-Reply-To: <20170407125713.15678-2-andrew@aj.id.au>
On Fri, Apr 7, 2017 at 2:57 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Patch applied with the ACKs.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH V2 4/4] mtd: ofpart: add of_match_table with "fixed-partitions"
From: Rafał Miłecki @ 2017-04-24 12:41 UTC (permalink / raw)
To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen
Cc: Rob Herring, Mark Rutland, Frank Rowand, Linus Walleij,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
Jonas Gorski, Rafał Miłecki
In-Reply-To: <20170424124120.31613-1-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
This allows using this parser with any flash driver that takes care of
setting of_node (using mtd_set_of_node helper) correctly. Up to now
support for "fixed-partitions" DT compatibility string was working only
with flash drivers that were specifying "ofpart" (manually or by letting
mtd use the default set of parsers).
This matches existing bindings documentation.
Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Reviewed-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Tested-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/mtd/ofpart.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 2861c7079d7b..fb6f3df40e94 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -140,9 +140,16 @@ static int parse_ofpart_partitions(struct mtd_info *master,
return ret;
}
+static const struct of_device_id parse_ofpart_match_table[] = {
+ { .compatible = "fixed-partitions" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+
static struct mtd_part_parser ofpart_parser = {
.parse_fn = parse_ofpart_partitions,
.name = "ofpart",
+ .of_match_table = parse_ofpart_match_table,
};
static int parse_ofoldpart_partitions(struct mtd_info *master,
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V2 3/4] mtd: partitions: add of_match_table parser matching
From: Rafał Miłecki @ 2017-04-24 12:41 UTC (permalink / raw)
To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen
Cc: Rob Herring, Mark Rutland, Frank Rowand, Linus Walleij,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
Jonas Gorski, Rafał Miłecki
In-Reply-To: <20170424124120.31613-1-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree.
This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.
Signed-off-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Acked-by: Brian Norris <computersforpeac-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
This is based on Brian's patches:
[RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
[RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching
V1: Put helpers in mtdpart.c instead of drivers/of/of_mtd.c
Merge helpers into a single of_mtd_match_mtd_parser
---
drivers/mtd/mtdpart.c | 47 ++++++++++++++++++++++++++++++++++++++++++
include/linux/mtd/partitions.h | 1 +
2 files changed, 48 insertions(+)
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 73c52f1a2e4c..d0cb1a892ed2 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -861,6 +861,41 @@ static int mtd_part_do_parse(struct mtd_part_parser *parser,
return ret;
}
+static bool of_mtd_match_mtd_parser(struct mtd_info *mtd,
+ struct mtd_part_parser *parser)
+{
+ struct device_node *np;
+ bool ret;
+
+ np = mtd_get_of_node(mtd);
+ np = of_get_child_by_name(np, "partitions");
+
+ ret = !!of_match_node(parser->of_match_table, np);
+
+ of_node_put(np);
+
+ return ret;
+}
+
+static struct mtd_part_parser *mtd_part_get_parser_by_of(struct mtd_info *mtd)
+{
+ struct mtd_part_parser *p, *ret = NULL;
+
+ spin_lock(&part_parser_lock);
+
+ list_for_each_entry(p, &part_parsers, list) {
+ if (of_mtd_match_mtd_parser(mtd, p) &&
+ try_module_get(p->owner)) {
+ ret = p;
+ break;
+ }
+ }
+
+ spin_unlock(&part_parser_lock);
+
+ return ret;
+}
+
/**
* parse_mtd_partitions - parse MTD partitions
* @master: the master partition (describes whole MTD device)
@@ -913,6 +948,18 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
if (ret < 0 && !err)
err = ret;
}
+
+ parser = mtd_part_get_parser_by_of(master);
+ if (!parser)
+ return err;
+
+ ret = mtd_part_do_parse(parser, master, pparts, data);
+ if (ret > 0)
+ return 0;
+ mtd_part_parser_put(parser);
+ if (ret < 0 && !err)
+ err = ret;
+
return err;
}
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 2787e76c030f..073e1d8d5d17 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
struct list_head list;
struct module *owner;
const char *name;
+ const struct of_device_id *of_match_table;
int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
struct mtd_part_parser_data *);
void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V2 2/4] mtd: partitions: factor out code calling parser
From: Rafał Miłecki @ 2017-04-24 12:41 UTC (permalink / raw)
To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen
Cc: Rob Herring, Mark Rutland, Frank Rowand, Linus Walleij,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
Jonas Gorski, Rafał Miłecki
In-Reply-To: <20170424124120.31613-1-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
This code is going to be reused for parsers matched using OF so let's
factor it out to make this easier.
Signed-off-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
Acked-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
This is based on Brian's patch:
[RFC PATCH 5/7] mtd: partitions: factor out "match by name" handling
V1: Do not factor out mtd_part_parser_get_by_name as it's not required by this
patchset.
---
drivers/mtd/mtdpart.c | 33 ++++++++++++++++++++++++---------
1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 81e0b80237df..73c52f1a2e4c 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -840,6 +840,27 @@ static const char * const default_mtd_part_types[] = {
NULL
};
+static int mtd_part_do_parse(struct mtd_part_parser *parser,
+ struct mtd_info *master,
+ struct mtd_partitions *pparts,
+ struct mtd_part_parser_data *data)
+{
+ int ret;
+
+ ret = (*parser->parse_fn)(master, &pparts->parts, data);
+ pr_debug("%s: parser %s: %i\n", master->name, parser->name, ret);
+ if (ret <= 0)
+ return ret;
+
+ pr_notice("%d %s partitions found on MTD device %s\n", ret,
+ parser->name, master->name);
+
+ pparts->nr_parts = ret;
+ pparts->parser = parser;
+
+ return ret;
+}
+
/**
* parse_mtd_partitions - parse MTD partitions
* @master: the master partition (describes whole MTD device)
@@ -880,16 +901,10 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
parser ? parser->name : NULL);
if (!parser)
continue;
- ret = (*parser->parse_fn)(master, &pparts->parts, data);
- pr_debug("%s: parser %s: %i\n",
- master->name, parser->name, ret);
- if (ret > 0) {
- printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
- ret, parser->name, master->name);
- pparts->nr_parts = ret;
- pparts->parser = parser;
+ ret = mtd_part_do_parse(parser, master, pparts, data);
+ /* Found partitions! */
+ if (ret > 0)
return 0;
- }
mtd_part_parser_put(parser);
/*
* Stash the first error we see; only report it if no parser
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V2 1/4] dt-bindings: mtd: make partitions doc a bit more generic
From: Rafał Miłecki @ 2017-04-24 12:41 UTC (permalink / raw)
To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen
Cc: Rob Herring, Mark Rutland, Frank Rowand, Linus Walleij,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
Jonas Gorski, Rafał Miłecki
In-Reply-To: <20170424124120.31613-1-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Currently the only documented partitioning is "fixed-partitions" but
there are more methods in use that we may want to support in the future.
Mention them and make it clear Fixed Partitions are just a single case.
Signed-off-by: Brian Norris <computersforpeace-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
---
This is based on Brian's patch:
[RFC PATCH 3/7] doc: dt: mtd: partition: add on-flash format binding
V1: Dropped "Section B: On-Flash Partition Tables" with Google's FMAP as this
patchset doesn't add that new parser.
V2: Add "We currently only document a binding for fixed layouts." part
---
.../devicetree/bindings/mtd/partition.txt | 30 +++++++++++++++++-----
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt
index 81a224da63be..b5de311b967a 100644
--- a/Documentation/devicetree/bindings/mtd/partition.txt
+++ b/Documentation/devicetree/bindings/mtd/partition.txt
@@ -1,29 +1,47 @@
-Representing flash partitions in devicetree
+Flash partitions in device tree
+===============================
-Partitions can be represented by sub-nodes of an mtd device. This can be used
+Flash devices can be partitioned into one or more functional ranges (e.g. "boot
+code", "nvram", "kernel").
+
+Different devices may be partitioned in a different ways. Some may use a fixed
+flash layout set at production time. Some may use on-flash table that describes
+the geometry and naming/purpose of each functional region. It is also possible
+to see these methods mixed.
+
+To assist system software in locating partitions, we provide a binding to
+describe which method is used for a given flash.
+
+We currently only document a binding for fixed layouts.
+
+
+Fixed Partitions
+================
+
+Partitions can be represented by sub-nodes of a flash device. This can be used
on platforms which have strong conventions about which portions of a flash are
used for what purposes, but which don't use an on-flash partition table such
as RedBoot.
-The partition table should be a subnode of the mtd node and should be named
+The partition table should be a subnode of the flash node and should be named
'partitions'. This node should have the following property:
- compatible : (required) must be "fixed-partitions"
Partitions are then defined in subnodes of the partitions node.
-For backwards compatibility partitions as direct subnodes of the mtd device are
+For backwards compatibility partitions as direct subnodes of the flash device are
supported. This use is discouraged.
NOTE: also for backwards compatibility, direct subnodes that have a compatible
string are not considered partitions, as they may be used for other bindings.
#address-cells & #size-cells must both be present in the partitions subnode of the
-mtd device. There are two valid values for both:
+flash device. There are two valid values for both:
<1>: for partitions that require a single 32-bit cell to represent their
size/address (aka the value is below 4 GiB)
<2>: for partitions that require two 32-bit cells to represent their
size/address (aka the value is 4 GiB or greater).
Required properties:
-- reg : The partition's offset and size within the mtd bank.
+- reg : The partition's offset and size within the flash
Optional properties:
- label : The label / name for this partition. If omitted, the label is taken
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V2 0/4] mtd: extend support for "fixed-partitions"
From: Rafał Miłecki @ 2017-04-24 12:41 UTC (permalink / raw)
To: David Woodhouse, Brian Norris, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen
Cc: Rob Herring, Mark Rutland, Frank Rowand, Linus Walleij,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, Geert Uytterhoeven,
Jonas Gorski, Rafał Miłecki
In-Reply-To: <20170420135731.13272-2-zajec5-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Rafał Miłecki <rafal-g1n6cQUeyibVItvQsEIGlw@public.gmane.org>
My recent work on adding wide support for linux,part-probe was reviewed and
kind of Nack-ed, but fortunately I was pointed to the old (!) patchset from
Brian doing similar thing in a cleaner way.
This patchset picks the important changes from Brian, cleans them and rebases.
Original patches:
(not picked) [RFC PATCH 1/7] mtd: move partition parsers to drivers/mtd/partitions/
(not picked) [RFC PATCH 2/7] mtd: move partition parsers' Kconfig under a sub-menu
(partially) [RFC PATCH 3/7] doc: dt: mtd: partition: add on-flash format binding
(picked) [RFC PATCH 4/7] mtd: add of_match_mtd_parser() and of_mtd_match_mtd_parser() helpers
(partially) [RFC PATCH 5/7] mtd: partitions: factor out "match by name" handling
(picked) [RFC PATCH 6/7] RFC: mtd: partitions: enable of_match_table matching
(not picked) [RFC PATCH 7/7] mtd: partitions: add Google's FMAP partition parser
At this point this simply adds a full support for "fixed-partitions" binding.
It should also make adding new bindings (like Google's FMAP) easier in the
future.
I've successfully tested this with bcm47xxsflash driver on Tenda AC9 device. I
used following DT node to get "ofpart" driver parse & register my partitions.
&bcma-sflash {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "cfe";
reg = <0x0000000 0x40000>;
read-only;
};
firmware@40000 {
label = "firmware";
reg = <0x40000 0x7f0000>;
};
};
};
V2: Modify patch 1/4
Include list of original patches in 0/4
Include changelog in every patch
Add Brian's tags (Acked/Reviewed/Tested)
Brian Norris (3):
dt-bindings: mtd: make partitions doc a bit more generic
mtd: partitions: factor out code calling parser
mtd: partitions: add of_match_table parser matching
Rafał Miłecki (1):
mtd: ofpart: add of_match_table with "fixed-partitions"
.../devicetree/bindings/mtd/partition.txt | 30 ++++++--
drivers/mtd/mtdpart.c | 80 +++++++++++++++++++---
drivers/mtd/ofpart.c | 7 ++
include/linux/mtd/partitions.h | 1 +
4 files changed, 103 insertions(+), 15 deletions(-)
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 4/4] ARM: dts: stm32: Set gpio controller also as interrupt controller
From: Linus Walleij @ 2017-04-24 12:38 UTC (permalink / raw)
To: Alexandre TORGUE
Cc: Maxime Coquelin, Patrice Chotard, Paul Gortmaker, Rob Herring,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1491577811-26989-5-git-send-email-alexandre.torgue-qxv4g6HH51o@public.gmane.org>
On Fri, Apr 7, 2017 at 5:10 PM, Alexandre TORGUE
<alexandre.torgue-qxv4g6HH51o@public.gmane.org> wrote:
> This patch set each gpio controller as a interrupt controller. User who
> wants to use gpio as interrupt will have choice to use either "gpiolib"
> interface or "common" interrupt interface.
>
> Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V7 4/7] mfd: da9061: MFD core support
From: Lee Jones @ 2017-04-24 12:38 UTC (permalink / raw)
To: Steve Twiss
Cc: LINUX-KERNEL, DEVICETREE, Dmitry Torokhov, Eduardo Valentin,
Guenter Roeck, LINUX-INPUT, LINUX-PM, LINUX-WATCHDOG,
Liam Girdwood, Mark Brown, Mark Rutland, Rob Herring,
Support Opensource, Wim Van Sebroeck, Zhang Rui
In-Reply-To: <6ED8E3B22081A4459DAC7699F3695FB7018CD71434@SW-EX-MBX02.diasemi.com>
On Mon, 24 Apr 2017, Steve Twiss wrote:
> On 04 April 2017 09:39, Lee Jones wrote:
> > Subject: Re: [PATCH V7 4/7] mfd: da9061: MFD core support
> >
> > On Mon, 03 Apr 2017, Steve Twiss wrote:
> > > From: Steve Twiss <stwiss.opensource@diasemi.com>
> > > MFD support for DA9061 is provided as part of the DA9062 device driver.
> > >
> > > The registers header file adds two new chip variant IDs defined in DA9061
> > > and DA9062 hardware. The core header file adds new software enumerations
> > > for listing the valid DA9061 IRQs and a da9062_compatible_types enumeration
> > > for distinguishing between DA9061/62 devices in software.
> > >
> > > The core source code adds a new .compatible of_device_id entry. This is
> > > extended from DA9062 to support both "dlg,da9061" and "dlg,da9062". The
> > > .data entry now holds a reference to the enumerated device type.
> > >
> > > A new regmap_irq_chip model is added for DA9061 and this supports the new
> > > list of regmap_irq entries. A new mfd_cell da9061_devs[] array lists the
> > > new sub system components for DA9061. Support is added for a new DA9061
> > > regmap_config which lists the correct readable, writable and volatile
> > > ranges for this chip.
> > >
> > > The probe function uses the device tree compatible string to switch on the
> > > da9062_compatible_types and configure the correct mfd cells, irq chip and
> > > regmap config.
> > >
> > > Kconfig is updated to reflect support for DA9061 and DA9062 PMICs.
> > >
> > > Signed-off-by: Steve Twiss <stwiss.opensource@diasemi.com>
> >
> > Ah, here it is.
> >
> > Applied, thanks.
>
> Hi Lee,
>
> I noticed the DA9061 core support has been added into linux-next, however
> the commit message was changed from the original title:
>
> "mfd: da9061: MFD core support"
>
> to add the mistake:
>
> "mfd: Add suppfor for DA9061"
>
> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=d3fe0806025cacdab1462d5704e1c98ab9db4564
>
> Can this be fixed please?
> This patch has not been upstreamed into linux-mainline and is still in linux-next.
You're right, thanks for pointing that out.
Now fixed.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCH v14 00/11] mux controller abstraction and iio/i2c muxes
From: Philipp Zabel @ 2017-04-24 12:38 UTC (permalink / raw)
To: Peter Rosin
Cc: Jonathan Cameron, linux-kernel, Greg Kroah-Hartman, Wolfram Sang,
Rob Herring, Mark Rutland, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler, Jonathan Corbet, linux-i2c, devicetree,
linux-iio, linux-doc, Andrew Morton, Colin Ian King,
Paul Gortmaker, kernel
In-Reply-To: <2d978956-d247-917d-4150-a6723917a733@axentia.se>
On Mon, 2017-04-24 at 13:37 +0200, Peter Rosin wrote:
[...]
> Ok, so the difference is probably that the rwsem locking primitive
> don't have any lockdep checking hooked up. Because the rwsem was
> definitely held in the same way in v13 as the mutex is now held in
> v14, so there's no fundamental difference.
>
> So, yes, we can use some kind of refcount scheme to not hold an actual
> mutex for the duration of the mux select/deselect, but that doesn't
> really change anything. Userspace is still locking something, and that
> seems dangerous. How do you make sure that mux_control_deselect is
> called as it should?
My current video_mux link setup implementation looks like this (it is
called from userspace via the MEDIA_IOC_SETUP_LINK ioctl):
----------8<----------
static int video_mux_link_setup(struct media_entity *entity,
const struct media_pad *local,
const struct media_pad *remote, u32 flags)
{
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
struct video_mux *video_mux = v4l2_subdev_to_video_mux(sd);
int ret;
/*
* The mux state is determined by the enabled sink pad link.
* Enabling or disabling the source pad link has no effect.
*/
if (!is_sink_pad(video_mux, local->index))
return 0;
dev_dbg(sd->dev, "link setup '%s':%d->'%s':%d[%d]", remote->entity->name,
remote->index, local->entity->name, local->index,
flags & MEDIA_LNK_FL_ENABLED);
if (flags & MEDIA_LNK_FL_ENABLED) {
if (video_mux->active == local->index)
return 0;
if (video_mux->active >= 0)
return -EBUSY;
dev_dbg(sd->dev, "setting %d active\n", local->index);
ret = mux_control_try_select(video_mux->mux, local->index);
if (ret < 0)
return ret;
video_mux->active = local->index;
} else {
if (video_mux->active != local->index)
return 0;
dev_dbg(sd->dev, "going inactive\n");
mux_control_deselect(video_mux->mux);
video_mux->active = -1;
}
return 0;
}
---------->8----------
If a mux state was already selected, this should return -EBUSY, until a
call to disable the active link deselects the mux.
> What I don't like about abandoning the lock is that there is still a
> need to support the multi-consumer case and then you need some way
> of keeping track of waiters. A lock does this, and any attempt to open
> code that will get messy.
>
> What might be better is to support some kind of exclusive mux, i.e. a
> mux that only allows one consumer per mux controller. Then the mux core
> could trust that exclusive consumer to not fuck things up for itself and
> thus have no lock at all for select/deselect for the exclusive case. Or
> perhaps keep a refcount (as you suggested) for the exclusive case so
> that mux_control_try_select still makes sense, because you still want
> that, right?
In the case of an exclusive mux without lock, I don't see any need for a
try_select call.
> The question then becomes how to best tell the mux core that you want
> an exclusive mux. I see two options. Either you declare a mux controller
> as exclusive up front somehow (in the device tree presumably), or you
> add a mux_control_get_exclusive call that makes further calls to
> mux_control_get{,_exclusive} fail with -EBUSY. I think I like the
> latter better, if that can be made to work...
There is a precedent for the latter in the reset controller framework
(reset_control_get_shared and reset_control_get_exclusive variants).
Since this distinction is a matter of usage, and not a hardware property
of the mux/reset controller itself, I'd also prefer that.
regards
Philipp
^ permalink raw reply
* Re: [PATCH 3/4] pinctrl: stm32: Implement .get_direction gpio_chip callback
From: Linus Walleij @ 2017-04-24 12:37 UTC (permalink / raw)
To: Alexandre TORGUE
Cc: Maxime Coquelin, Patrice Chotard, Paul Gortmaker, Rob Herring,
linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
In-Reply-To: <1491577811-26989-4-git-send-email-alexandre.torgue@st.com>
On Fri, Apr 7, 2017 at 5:10 PM, Alexandre TORGUE
<alexandre.torgue@st.com> wrote:
> Add .get_direction() gpiochip callback in STM32 pinctrl driver.
>
> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
(...)
> +#include <linux/gpio.h>
No this is wrong, drivers should never include this file.
It is a deprecated consumer header.
> + if ((alt == 0) && (mode == 0))
> + ret = GPIOF_DIR_IN;
> + else if ((alt == 0) && (mode == 1))
> + ret = GPIOF_DIR_OUT;
Just return 0 or 1, that is the driver-internal API.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 1/4] pinctrl: stm32: set pin to gpio input when used as interrupt
From: Linus Walleij @ 2017-04-24 12:36 UTC (permalink / raw)
To: Alexandre TORGUE
Cc: Maxime Coquelin, Patrice Chotard, Paul Gortmaker, Rob Herring,
linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
In-Reply-To: <1491577811-26989-2-git-send-email-alexandre.torgue@st.com>
On Fri, Apr 7, 2017 at 5:10 PM, Alexandre TORGUE
<alexandre.torgue@st.com> wrote:
> This patch ensures that pin is correctly set as gpio input when it is used
> as an interrupt.
>
> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
(...)
> +static int stm32_gpio_irq_request_resources(struct irq_data *irq_data)
> +{
> + struct stm32_gpio_bank *bank = irq_data->domain->host_data;
> + u32 ret;
> +
> + if (!gpiochip_is_requested(&bank->gpio_chip, irq_data->hwirq)) {
> + ret = stm32_gpio_request(&bank->gpio_chip, irq_data->hwirq);
> + if (ret)
> + return ret;
> + }
This is wrong. You should only use gpiochip_lock_as_irq(), because of the
following in Documentation/gpio/driver.txt:
---------------
It is legal for any IRQ consumer to request an IRQ from any irqchip no matter
if that is a combined GPIO+IRQ driver. The basic premise is that gpio_chip and
irq_chip are orthogonal, and offering their services independent of each
other.
(...)
So always prepare the hardware and make it ready for action in respective
callbacks from the GPIO and irqchip APIs. Do not rely on gpiod_to_irq() having
been called first.
This orthogonality leads to ambiguities that we need to solve: if there is
competition inside the subsystem which side is using the resource (a certain
GPIO line and register for example) it needs to deny certain operations and
keep track of usage inside of the gpiolib subsystem. This is why the API
below exists.
Locking IRQ usage
-----------------
Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
to mark the GPIO as being used as an IRQ:
int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
is released:
void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
When implementing an irqchip inside a GPIO driver, these two functions should
typically be called in the .startup() and .shutdown() callbacks from the
irqchip.
When using the gpiolib irqchip helpers, these callback are automatically
assigned.
--------------
It is because of easy to make errors like this that I prefer that people try
to use GPIOLIB_IRQCHIP helpers insteaf of rolling their own irqchip code.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v2 6/7] ARM: Kconfig: Introduce MACH_STM32F469 flag
From: Linus Walleij @ 2017-04-24 12:30 UTC (permalink / raw)
To: Alexandre TORGUE
Cc: Maxime Coquelin, Rob Herring, Mark Rutland, Arnd Bergmann,
Russell King, Olof Johansson, Lee Jones, Jonathan Corbet,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1491568984-20169-7-git-send-email-alexandre.torgue@st.com>
On Fri, Apr 7, 2017 at 2:43 PM, Alexandre TORGUE
<alexandre.torgue@st.com> wrote:
> This patch introduces the MACH_STM32F469 to make possible to only select
> STM32F469 pinctrl driver
>
> By default, all the MACH_STM32Fxxx flags will be set with STM32 defconfig.
>
> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Please funnel this through the ARM SoC tree.
Yours,
Linus Walleij
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox