* [PATCH v8 08/12] pinctrl: generic: dump pin configuration
From: Haojian Zhuang @ 2013-02-02 17:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359825953-15663-1-git-send-email-haojian.zhuang@linaro.org>
Add the support of dumping pin configuration.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/pinctrl/pinconf-generic.c | 12 ++++++++++++
drivers/pinctrl/pinconf.h | 8 ++++++++
2 files changed, 20 insertions(+)
diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index e5948f8..66e4ae5 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -120,4 +120,16 @@ void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
}
}
+void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned long config)
+{
+ int i;
+
+ for(i = 0; i < ARRAY_SIZE(conf_items); i++) {
+ if (pinconf_to_config_param(config) != conf_items[i].param)
+ continue;
+ seq_printf(s, "%s: 0x%x", conf_items[i].display,
+ pinconf_to_config_argument(config));
+ }
+}
#endif
diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h
index e3ed8cb..8023421 100644
--- a/drivers/pinctrl/pinconf.h
+++ b/drivers/pinctrl/pinconf.h
@@ -98,6 +98,8 @@ void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
struct seq_file *s, const char *gname);
+void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned long config);
#else
static inline void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
@@ -114,4 +116,10 @@ static inline void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
return;
}
+static void pinconf_generic_dump_config(struct pinctrl_dev *pctldev,
+ struct seq_file *s,
+ unsigned long config)
+{
+ return;
+}
#endif
--
1.7.10.4
^ permalink raw reply related
* [PATCH v8 09/12] pinctrl: single: set function mask as optional
From: Haojian Zhuang @ 2013-02-02 17:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359825953-15663-1-git-send-email-haojian.zhuang@linaro.org>
Since Hisilicon's pin controller is divided into two parts. One is the
function mux, and the other is pin configuration. These two parts are
in the different memory regions. So make pinctrl-single,function-mask
as optional property. Then we can define pingroups without valid
function mux that is only used for pin configuration.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/pinctrl/pinctrl-single.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 8b9dd95..fe8f321 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -350,6 +350,9 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
int i;
pcs = pinctrl_dev_get_drvdata(pctldev);
+ /* If function mask is null, needn't enable it. */
+ if (!pcs->fmask)
+ return 0;
func = radix_tree_lookup(&pcs->ftree, fselector);
if (!func)
return -EINVAL;
@@ -384,6 +387,10 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
int i;
pcs = pinctrl_dev_get_drvdata(pctldev);
+ /* If function mask is null, needn't disable it. */
+ if (!pcs->fmask)
+ return;
+
func = radix_tree_lookup(&pcs->ftree, fselector);
if (!func) {
dev_err(pcs->dev, "%s could not find function%i\n",
@@ -427,6 +434,10 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,
int mux_bytes = 0;
unsigned data;
+ /* If function mask is null, return directly. */
+ if (!pcs->fmask)
+ return -ENOTSUPP;
+
list_for_each_safe(pos, tmp, &pcs->gpiofuncs) {
frange = list_entry(pos, struct pcs_gpiofunc_range, node);
if (pin >= frange->offset + frange->npins
@@ -969,10 +980,17 @@ static int pcs_probe(struct platform_device *pdev)
PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width,
"register width not specified\n");
- PCS_GET_PROP_U32("pinctrl-single,function-mask", &pcs->fmask,
- "function register mask not specified\n");
- pcs->fshift = ffs(pcs->fmask) - 1;
- pcs->fmax = pcs->fmask >> pcs->fshift;
+ ret = of_property_read_u32(np, "pinctrl-single,function-mask",
+ &pcs->fmask);
+ if (!ret) {
+ pcs->fshift = ffs(pcs->fmask) - 1;
+ pcs->fmax = pcs->fmask >> pcs->fshift;
+ } else {
+ /* If mask property doesn't exist, function mux is invalid. */
+ pcs->fmask = 0;
+ pcs->fshift = 0;
+ pcs->fmax = 0;
+ }
ret = of_property_read_u32(np, "pinctrl-single,function-off",
&pcs->foff);
--
1.7.10.4
^ permalink raw reply related
* [PATCH v8 10/12] pinctrl: single: support generic pinconf
From: Haojian Zhuang @ 2013-02-02 17:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359825953-15663-1-git-send-email-haojian.zhuang@linaro.org>
Support the operation of generic pinconf. The supported config arguments
are INPUT_SCHMITT, INPUT_SCHMITT_DISABLE, POWER_SOURCE, BIAS_DISABLE,
BIAS_PULLUP, BIAS_PULLDOWN, SLEW_RATE.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
drivers/pinctrl/Kconfig | 1 +
drivers/pinctrl/pinctrl-single.c | 339 +++++++++++++++++++++++++++++++++++++-
2 files changed, 333 insertions(+), 7 deletions(-)
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 9db3497..066581c 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -154,6 +154,7 @@ config PINCTRL_SINGLE
depends on OF
select PINMUX
select PINCONF
+ select GENERIC_PINCONF
help
This selects the device tree based generic pinctrl driver.
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index fe8f321..1d9f3cc 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -22,8 +22,10 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf-generic.h>
#include "core.h"
+#include "pinconf.h"
#define DRIVER_NAME "pinctrl-single"
#define PCS_MUX_PINS_NAME "pinctrl-single,pins"
@@ -59,6 +61,31 @@ struct pcs_func_vals {
};
/**
+ * struct pcs_conf_vals - pinconf parameter, pinconf register offset
+ * and value, match, mask
+ * @param: config parameter
+ * @val: register value
+ * @match: register match value
+ * @mask: mask of register value
+ */
+struct pcs_conf_vals {
+ enum pin_config_param param;
+ unsigned val;
+ unsigned match;
+ unsigned mask;
+};
+
+/**
+ * struct pcs_conf_type - pinconf property name, pinconf param pair
+ * @name: property name in DTS file
+ * @param: config parameter
+ */
+struct pcs_conf_type {
+ const char *name;
+ enum pin_config_param param;
+};
+
+/**
* struct pcs_function - pinctrl function
* @name: pinctrl function name
* @vals: register and vals array
@@ -73,6 +100,8 @@ struct pcs_function {
unsigned nvals;
const char **pgnames;
int npgnames;
+ struct pcs_conf_vals *conf;
+ int nconfs;
struct list_head node;
};
@@ -131,6 +160,7 @@ struct pcs_name {
* @fshift: function register shift
* @foff: value to turn mux off
* @fmax: max number of functions in fmask
+ * @is_pinconf: whether supports pinconf
* @names: array of register names for pins
* @pins: physical pins on the SoC
* @pgtree: pingroup index radix tree
@@ -157,6 +187,7 @@ struct pcs_device {
unsigned foff;
unsigned fmax;
bool bits_per_mux;
+ bool is_pinconf;
struct pcs_name *names;
struct pcs_data pins;
struct radix_tree_root pgtree;
@@ -342,6 +373,28 @@ static int pcs_get_function_groups(struct pinctrl_dev *pctldev,
return 0;
}
+static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned pin,
+ struct pcs_function **func)
+{
+ struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+ struct pin_desc *pdesc = pin_desc_get(pctldev, pin);
+ const struct pinctrl_setting_mux *setting;
+ unsigned fselector;
+
+ /* If pin is not described in DTS & enabled, mux_setting is NULL. */
+ setting = pdesc->mux_setting;
+ if (!setting)
+ return -ENOTSUPP;
+ fselector = setting->func;
+ *func = radix_tree_lookup(&pcs->ftree, fselector);
+ if (!(*func)) {
+ dev_err(pcs->dev, "%s could not find function%i\n",
+ __func__, fselector);
+ return -ENOTSUPP;
+ }
+ return 0;
+}
+
static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
unsigned group)
{
@@ -464,29 +517,137 @@ static struct pinmux_ops pcs_pinmux_ops = {
static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long *config)
{
+ struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+ struct pcs_function *func;
+ unsigned offset = 0, data = 0, i, j, ret;
+
+ ret = pcs_get_function(pctldev, pin, &func);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < func->nconfs; i++) {
+ if (pinconf_to_config_param(*config) != func->conf[i].param)
+ continue;
+ offset = pin * (pcs->width / BITS_PER_BYTE);
+ data = pcs->read(pcs->base + offset) & func->conf[i].mask;
+ switch (func->conf[i].param) {
+ /* 3 parameters */
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_INPUT_SCHMITT_DISABLE:
+ if (data != func->conf[i].match)
+ return -ENOTSUPP;
+ *config = data;
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT:
+ /* either INPUT_SCHMITT or DISABLE */
+ for (j = 0; j < func->nconfs; j++) {
+ switch (func->conf[j].param) {
+ case PIN_CONFIG_INPUT_SCHMITT_DISABLE:
+ if (data == func->conf[j].match)
+ return -ENOTSUPP;
+ break;
+ default:
+ break;
+ }
+ }
+ *config = data;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ case PIN_CONFIG_SLEW_RATE:
+ default:
+ *config = data;
+ break;
+ }
+ return 0;
+ }
return -ENOTSUPP;
}
static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long config)
{
+ struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+ struct pcs_function *func;
+ unsigned offset = 0, shift = 0, arg = 0, i, data, ret;
+
+ ret = pcs_get_function(pctldev, pin, &func);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < func->nconfs; i++) {
+ if (pinconf_to_config_param(config) == func->conf[i].param) {
+ offset = pin * (pcs->width / BITS_PER_BYTE);
+ data = pcs->read(pcs->base + offset);
+ switch (func->conf[i].param) {
+ /* 2 parameters */
+ case PIN_CONFIG_INPUT_SCHMITT:
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ case PIN_CONFIG_SLEW_RATE:
+ shift = ffs(func->conf[i].mask) - 1;
+ arg = pinconf_to_config_argument(config);
+ data &= ~func->conf[i].mask;
+ data |= (arg << shift) & func->conf[i].mask;
+ break;
+ /* 3 parameters */
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_INPUT_SCHMITT_DISABLE:
+ data &= ~func->conf[i].mask;
+ data |= func->conf[i].val;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ pcs->write(data, pcs->base + offset);
+ return 0;
+ }
+ }
return -ENOTSUPP;
}
static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
unsigned group, unsigned long *config)
{
- return -ENOTSUPP;
+ const unsigned *pins;
+ unsigned npins, old = 0;
+ int i, ret;
+
+ ret = pcs_get_group_pins(pctldev, group, &pins, &npins);
+ if (ret)
+ return ret;
+ for (i = 0; i < npins; i++) {
+ if (pcs_pinconf_get(pctldev, pins[i], config))
+ return -ENOTSUPP;
+ /* configs do not match between two pins */
+ if (i && (old != *config))
+ return -ENOTSUPP;
+ old = *config;
+ }
+ return 0;
}
static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned group, unsigned long config)
{
- return -ENOTSUPP;
+ const unsigned *pins;
+ unsigned npins;
+ int i, ret;
+
+ ret = pcs_get_group_pins(pctldev, group, &pins, &npins);
+ if (ret)
+ return ret;
+ for (i = 0; i < npins; i++) {
+ if (pcs_pinconf_set(pctldev, pins[i], config))
+ return -ENOTSUPP;
+ }
+ return 0;
}
static void pcs_pinconf_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s, unsigned offset)
+ struct seq_file *s, unsigned pin)
{
}
@@ -495,6 +656,13 @@ static void pcs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
{
}
+static void pcs_pinconf_config_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s,
+ unsigned long config)
+{
+ pinconf_generic_dump_config(pctldev, s, config);
+}
+
static struct pinconf_ops pcs_pinconf_ops = {
.pin_config_get = pcs_pinconf_get,
.pin_config_set = pcs_pinconf_set,
@@ -502,6 +670,7 @@ static struct pinconf_ops pcs_pinconf_ops = {
.pin_config_group_set = pcs_pinconf_group_set,
.pin_config_dbg_show = pcs_pinconf_dbg_show,
.pin_config_group_dbg_show = pcs_pinconf_group_dbg_show,
+ .pin_config_config_dbg_show = pcs_pinconf_config_dbg_show,
};
/**
@@ -692,11 +861,151 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset)
return index;
}
+static int pcs_config_match(unsigned data, unsigned match)
+{
+ int ret = 0;
+
+ if (!match) {
+ if (!data)
+ ret = 1;
+ } else {
+ if ((data & match) == match)
+ ret = 1;
+ }
+ return ret;
+}
+
+static void add_config(struct pcs_conf_vals **conf, enum pin_config_param param,
+ unsigned value, unsigned match, unsigned mask)
+{
+ (*conf)->param = param;
+ (*conf)->val = value;
+ (*conf)->match = match;
+ (*conf)->mask = mask;
+ (*conf)++;
+}
+
+static void add_setting(unsigned long **setting, enum pin_config_param param,
+ unsigned arg)
+{
+ **setting = pinconf_to_config_packed(param, arg);
+ (*setting)++;
+}
+
+/* add pinconf setting with 2 parameters */
+static void pcs_add_conf2(struct device_node *np, const char *name,
+ enum pin_config_param param,
+ struct pcs_conf_vals **conf,
+ unsigned long **settings)
+{
+ unsigned value[2];
+ int ret;
+
+ ret = of_property_read_u32_array(np, name, value, 2);
+ if (ret)
+ return;
+ /* value to set, mask */
+ value[0] &= value[1];
+ add_config(conf, param, value[0], 0, value[1]);
+ add_setting(settings, param, value[0]);
+}
+
+/* add pinconf setting with 3 parameters */
+static void pcs_add_conf3(struct device_node *np, const char *name,
+ enum pin_config_param param,
+ struct pcs_conf_vals **conf,
+ unsigned long **settings)
+{
+ unsigned value[3];
+ int ret;
+
+ ret = of_property_read_u32_array(np, name, value, 3);
+ if (ret)
+ return;
+ /* value to set, match, mask */
+ value[0] &= value[2];
+ value[1] &= value[2];
+ add_config(conf, param, value[0], value[1], value[2]);
+ if (pcs_config_match(value[0], value[1]))
+ ret = 1;
+ else
+ ret = 0;
+ add_setting(settings, param, ret);
+}
+
+static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np,
+ struct pcs_function *func,
+ struct pinctrl_map **map)
+
+{
+ struct pinctrl_map *m = *map;
+ int i = 0, nconfs = 0;
+ unsigned long *settings = NULL, *s = NULL;
+ struct pcs_conf_vals *conf = NULL;
+ struct pcs_conf_type prop2[] = {
+ { "pinctrl-single,drive-strength", PIN_CONFIG_DRIVE_STRENGTH, },
+ { "pinctrl-single,slew-rate", PIN_CONFIG_SLEW_RATE, },
+ { "pinctrl-single,input-schmitt", PIN_CONFIG_INPUT_SCHMITT, },
+ };
+ struct pcs_conf_type prop3[] = {
+ { "pinctrl-single,bias-disable", PIN_CONFIG_BIAS_DISABLE, },
+ { "pinctrl-single,bias-pullup", PIN_CONFIG_BIAS_PULL_UP, },
+ { "pinctrl-single,bias-pulldown", PIN_CONFIG_BIAS_PULL_DOWN, },
+ { "pinctrl-single,input-schmitt-disable",
+ PIN_CONFIG_INPUT_SCHMITT_DISABLE, },
+ };
+
+ /* If pinconf isn't supported, don't parse properties in below. */
+ if (!pcs->is_pinconf)
+ return 0;
+
+ /* cacluate how much properties are supported in current node */
+ for (i = 0; i < ARRAY_SIZE(prop2); i++) {
+ if (of_find_property(np, prop2[i].name, NULL))
+ nconfs++;
+ }
+ for (i = 0; i < ARRAY_SIZE(prop3); i++) {
+ if (of_find_property(np, prop3[i].name, NULL))
+ nconfs++;
+ }
+ if (!nconfs)
+ return 0;
+
+ func->conf = devm_kzalloc(pcs->dev,
+ sizeof(struct pcs_conf_vals) * nconfs,
+ GFP_KERNEL);
+ if (!func->conf)
+ return -ENOMEM;
+ func->nconfs = nconfs;
+ conf = &(func->conf[0]);
+ m++;
+ settings = devm_kzalloc(pcs->dev, sizeof(unsigned long) * nconfs,
+ GFP_KERNEL);
+ if (!settings)
+ return -ENOMEM;
+ s = &settings[0];
+
+ for (i = 0; i < ARRAY_SIZE(prop2); i++) {
+ pcs_add_conf2(np, prop2[i].name, prop2[i].param, &conf, &s);
+ }
+ for (i = 0; i < ARRAY_SIZE(prop3); i++) {
+ pcs_add_conf3(np, prop3[i].name, prop3[i].param, &conf, &s);
+ }
+ m->type = PIN_MAP_TYPE_CONFIGS_GROUP;
+ m->data.configs.group_or_pin = np->name;
+ m->data.configs.configs = settings;
+ m->data.configs.num_configs = nconfs;
+ return 0;
+}
+
+static void pcs_free_pingroups(struct pcs_device *pcs);
+
/**
* smux_parse_one_pinctrl_entry() - parses a device tree mux entry
* @pcs: pinctrl driver instance
* @np: device node of the mux entry
* @map: map entry
+ * @num_maps: number of map
* @pgnames: pingroup names
*
* Note that this binding currently supports only sets of one register + value.
@@ -713,6 +1022,7 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset)
static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
struct device_node *np,
struct pinctrl_map **map,
+ unsigned *num_maps,
const char **pgnames)
{
struct pcs_func_vals *vals;
@@ -785,8 +1095,18 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
(*map)->data.mux.group = np->name;
(*map)->data.mux.function = np->name;
+ if (pcs->is_pinconf) {
+ if (pcs_parse_pinconf(pcs, np, function, map))
+ goto free_pingroups;
+ *num_maps = 2;
+ } else {
+ *num_maps = 1;
+ }
return 0;
+free_pingroups:
+ pcs_free_pingroups(pcs);
+ *num_maps = 1;
free_function:
pcs_remove_function(pcs, function);
@@ -815,7 +1135,8 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
pcs = pinctrl_dev_get_drvdata(pctldev);
- *map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL);
+ /* create 2 maps. One is for pinmux, and the other is for pinconf. */
+ *map = devm_kzalloc(pcs->dev, sizeof(**map) * 2, GFP_KERNEL);
if (!*map)
return -ENOMEM;
@@ -827,13 +1148,13 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
goto free_map;
}
- ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, pgnames);
+ ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, num_maps,
+ pgnames);
if (ret < 0) {
dev_err(pcs->dev, "no pins entries for %s\n",
np_config->name);
goto free_pgnames;
}
- *num_maps = 1;
return 0;
@@ -976,6 +1297,7 @@ static int pcs_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&pcs->pingroups);
INIT_LIST_HEAD(&pcs->functions);
INIT_LIST_HEAD(&pcs->gpiofuncs);
+ pcs->is_pinconf = match->data;
PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width,
"register width not specified\n");
@@ -1046,6 +1368,8 @@ static int pcs_probe(struct platform_device *pdev)
pcs->desc.pmxops = &pcs_pinmux_ops;
pcs->desc.confops = &pcs_pinconf_ops;
pcs->desc.owner = THIS_MODULE;
+ if (match->data)
+ pcs_pinconf_ops.is_generic = true;
ret = pcs_allocate_pin_table(pcs);
if (ret < 0)
@@ -1086,7 +1410,8 @@ static int pcs_remove(struct platform_device *pdev)
}
static struct of_device_id pcs_of_match[] = {
- { .compatible = DRIVER_NAME, },
+ { .compatible = "pinctrl-single", .data = (void *)false },
+ { .compatible = "pinconf-single", .data = (void *)true },
{ },
};
MODULE_DEVICE_TABLE(of, pcs_of_match);
--
1.7.10.4
^ permalink raw reply related
* [PATCH v8 11/12] ARM: hs: enable hi4511 with device tree
From: Haojian Zhuang @ 2013-02-02 17:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359825953-15663-1-git-send-email-haojian.zhuang@linaro.org>
Enable Hisilicon Hi4511 development platform with device tree support.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/hi3620.dtsi | 556 +++++++++++++++++++++++++++++
arch/arm/boot/dts/hi4511.dts | 772 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 1329 insertions(+)
create mode 100644 arch/arm/boot/dts/hi3620.dtsi
create mode 100644 arch/arm/boot/dts/hi4511.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index ea2c272..2a22336 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -50,6 +50,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
exynos5440-ssdk5440.dtb
dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
ecx-2000.dtb
+dtb-$(CONFIG_ARCH_HS) += hi4511.dtb
dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
integratorcp.dtb
dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi
new file mode 100644
index 0000000..547a93b
--- /dev/null
+++ b/arch/arm/boot/dts/hi3620.dtsi
@@ -0,0 +1,556 @@
+/*
+ * Hisilicon Ltd. Hi3620 SoC
+ *
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ };
+
+ amba {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "arm,amba-bus";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ osc32k: osc at 0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "osc32khz";
+ };
+
+ osc26m: osc at 1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "osc26mhz";
+ };
+
+ pclk: clk at 0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "apb_pclk";
+ };
+
+ timclk0: clk at 1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <60000000>;
+ clock-output-names = "timer0";
+ };
+
+ timclk1: clk at 2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <60000000>;
+ clock-output-names = "timer1";
+ };
+
+ l2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0xfc10000 0x100000>;
+ interrupts = <0 15 4>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ intc: interrupt-controller at fc001000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ /* gic dist base, gic cpu base */
+ reg = <0xfc001000 0x1000>, <0xfc000100 0x100>;
+ };
+
+ timer0: timer at fc800000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xfc800000 0x1000>;
+ /* timer00 & timer01 */
+ interrupts = <0 0 4>, <0 1 4>;
+ clocks = <&timclk0 &timclk1 &pclk>;
+ clock-names = "timer0", "timer1", "apb_pclk";
+ status = "disabled";
+ };
+
+ timer1: timer at fc801000 {
+ /*
+ * Only used in NORMAL state, not available ins
+ * SLOW or DOZE state.
+ * The rate is fixed in 24MHz.
+ */
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xfc801000 0x1000>;
+ /* timer10 & timer11 */
+ interrupts = <0 2 4>, <0 3 4>;
+ clocks = <&timclk0 &timclk1 &pclk>;
+ clock-names = "timer0", "timer1", "apb_pclk";
+ status = "disabled";
+ };
+
+ timer2: timer at fca01000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xfca01000 0x1000>;
+ /* timer20 & timer21 */
+ interrupts = <0 4 4>, <0 5 4>;
+ clocks = <&timclk0 &timclk1 &pclk>;
+ clock-names = "timer0", "timer1", "apb_pclk";
+ status = "disabled";
+ };
+
+ timer3: timer at fca02000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xfca02000 0x1000>;
+ /* timer30 & timer31 */
+ interrupts = <0 6 4>, <0 7 4>;
+ clocks = <&timclk0 &timclk1 &pclk>;
+ clock-names = "timer0", "timer1", "apb_pclk";
+ status = "disabled";
+ };
+
+ timer4: timer at fca03000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0xfca03000 0x1000>;
+ /* timer40 & timer41 */
+ interrupts = <0 96 4>, <0 97 4>;
+ clocks = <&timclk0 &timclk1 &pclk>;
+ clock-names = "timer0", "timer1", "apb_pclk";
+ status = "disabled";
+ };
+
+ uart0: uart at fcb00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xfcb00000 0x1000>;
+ interrupts = <0 20 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart1: uart at fcb01000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xfcb01000 0x1000>;
+ interrupts = <0 21 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart2: uart at fcb02000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xfcb02000 0x1000>;
+ interrupts = <0 22 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart3: uart at fcb03000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xfcb03000 0x1000>;
+ interrupts = <0 23 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ uart4: uart at fcb04000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xfcb04000 0x1000>;
+ interrupts = <0 24 4>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disabled";
+ };
+
+ gpio0: gpio at fc806000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc806000 0x1000>;
+ interrupts = <0 64 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 2 0 1 &pmx0 3 0 1 &pmx0 4 0 1
+ &pmx0 5 0 1 &pmx0 6 1 1 &pmx0 7 2 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio1: gpio at fc807000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc807000 0x1000>;
+ interrupts = <0 65 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1
+ &pmx0 3 3 1 &pmx0 4 3 1 &pmx0 5 4 1
+ &pmx0 6 5 1 &pmx0 7 6 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio2: gpio at fc808000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc808000 0x1000>;
+ interrupts = <0 66 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 7 1 &pmx0 1 8 1 &pmx0 2 9 1
+ &pmx0 3 10 1 &pmx0 4 3 1 &pmx0 5 3 1
+ &pmx0 6 3 1 &pmx0 7 3 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio3: gpio at fc809000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc809000 0x1000>;
+ interrupts = <0 67 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1
+ &pmx0 3 3 1 &pmx0 4 11 1 &pmx0 5 11 1
+ &pmx0 6 11 1 &pmx0 7 11 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio4: gpio at fc80a000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc80a000 0x1000>;
+ interrupts = <0 68 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 11 1 &pmx0 1 11 1 &pmx0 2 11 1
+ &pmx0 3 11 1 &pmx0 4 12 1 &pmx0 5 12 1
+ &pmx0 6 13 1 &pmx0 7 13 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio5: gpio at fc80b000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc80b000 0x1000>;
+ interrupts = <0 69 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 14 1 &pmx0 1 15 1 &pmx0 2 16 1
+ &pmx0 3 16 1 &pmx0 4 16 1 &pmx0 5 16 1
+ &pmx0 6 16 1 &pmx0 7 16 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio6: gpio at fc80c000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc80c000 0x1000>;
+ interrupts = <0 70 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 16 1 &pmx0 1 16 1 &pmx0 2 17 1
+ &pmx0 3 17 1 &pmx0 4 18 1 &pmx0 5 18 1
+ &pmx0 6 18 1 &pmx0 7 19 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio7: gpio at fc80d000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc80d000 0x1000>;
+ interrupts = <0 71 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 19 1 &pmx0 1 20 1 &pmx0 2 21 1
+ &pmx0 3 22 1 &pmx0 4 23 1 &pmx0 5 24 1
+ &pmx0 6 25 1 &pmx0 7 26 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio8: gpio at fc80e000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc80e000 0x1000>;
+ interrupts = <0 72 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 27 1 &pmx0 1 28 1 &pmx0 2 29 1
+ &pmx0 3 30 1 &pmx0 4 31 1 &pmx0 5 32 1
+ &pmx0 6 33 1 &pmx0 7 34 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio9: gpio at fc80f000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc80f000 0x1000>;
+ interrupts = <0 73 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 35 1 &pmx0 1 36 1 &pmx0 2 37 1
+ &pmx0 3 38 1 &pmx0 4 39 1 &pmx0 5 40 1
+ &pmx0 6 41 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio10: gpio at fc810000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc810000 0x1000>;
+ interrupts = <0 74 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 2 43 1 &pmx0 3 44 1 &pmx0 4 45 1
+ &pmx0 5 45 1 &pmx0 6 46 1 &pmx0 7 46 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio11: gpio at fc811000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc811000 0x1000>;
+ interrupts = <0 75 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 47 1 &pmx0 1 47 1 &pmx0 2 47 1
+ &pmx0 3 47 1 &pmx0 4 47 1 &pmx0 5 48 1
+ &pmx0 6 49 1 &pmx0 7 49 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio12: gpio at fc812000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc812000 0x1000>;
+ interrupts = <0 76 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 49 1 &pmx0 1 50 1 &pmx0 2 49 1
+ &pmx0 3 49 1 &pmx0 4 51 1 &pmx0 5 51 1
+ &pmx0 6 51 1 &pmx0 7 52 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio13: gpio at fc813000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc813000 0x1000>;
+ interrupts = <0 77 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 51 1 &pmx0 1 51 1 &pmx0 2 53 1
+ &pmx0 3 53 1 &pmx0 4 53 1 &pmx0 5 54 1
+ &pmx0 6 55 1 &pmx0 7 56 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio14: gpio at fc814000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc814000 0x1000>;
+ interrupts = <0 78 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 57 1 &pmx0 1 97 1 &pmx0 2 97 1
+ &pmx0 3 58 1 &pmx0 4 59 1 &pmx0 5 60 1
+ &pmx0 6 60 1 &pmx0 7 61 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio15: gpio at fc815000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc815000 0x1000>;
+ interrupts = <0 79 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 61 1 &pmx0 1 62 1 &pmx0 2 62 1
+ &pmx0 3 63 1 &pmx0 4 63 1 &pmx0 5 64 1
+ &pmx0 6 64 1 &pmx0 7 65 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio16: gpio at fc816000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc816000 0x1000>;
+ interrupts = <0 80 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 66 1 &pmx0 1 67 1 &pmx0 2 68 1
+ &pmx0 3 69 1 &pmx0 4 70 1 &pmx0 5 71 1
+ &pmx0 6 72 1 &pmx0 7 73 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio17: gpio at fc817000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc817000 0x1000>;
+ interrupts = <0 81 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 74 1 &pmx0 1 75 1 &pmx0 2 76 1
+ &pmx0 3 77 1 &pmx0 4 78 1 &pmx0 5 79 1
+ &pmx0 6 80 1 &pmx0 7 81 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio18: gpio at fc818000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc818000 0x1000>;
+ interrupts = <0 82 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 82 1 &pmx0 1 83 1 &pmx0 2 83 1
+ &pmx0 3 84 1 &pmx0 4 84 1 &pmx0 5 85 1
+ &pmx0 6 86 1 &pmx0 7 87 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio19: gpio at fc819000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc819000 0x1000>;
+ interrupts = <0 83 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 87 1 &pmx0 1 87 1 &pmx0 2 88 1
+ &pmx0 3 88 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio20: gpio at fc81a000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc81a000 0x1000>;
+ interrupts = <0 84 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 0 89 1 &pmx0 1 89 1 &pmx0 2 90 1
+ &pmx0 3 90 1 &pmx0 4 91 1 &pmx0 5 92 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ gpio21: gpio at fc81b000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xfc81b000 0x1000>;
+ interrupts = <0 85 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = < &pmx0 3 94 1 &pmx0 7 96 1>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ clocks = <&pclk>;
+ clock-names = "apb_pclk";
+ status = "disable";
+ };
+
+ pmx0: pinmux at fc803000 {
+ compatible = "pinctrl-single";
+ reg = <0xfc803000 0x188>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #gpio-range-cells = <3>;
+ ranges;
+
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <7>;
+ /* pin base, nr pins & gpio function */
+ pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1
+ &range 12 1 0 &range 13 29 1
+ &range 43 1 0 &range 44 49 1
+ &range 94 1 1 &range 96 2 1>;
+
+ range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
+ };
+ };
+
+ pmx1: pinmux at fc803800 {
+ compatible = "pinconf-single";
+ reg = <0xfc803800 0x2dc>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pinctrl-single,register-width = <32>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/hi4511.dts b/arch/arm/boot/dts/hi4511.dts
new file mode 100644
index 0000000..f10b28f
--- /dev/null
+++ b/arch/arm/boot/dts/hi4511.dts
@@ -0,0 +1,772 @@
+/*
+ * Copyright (C) 2012-2013 Linaro Ltd.
+ * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ */
+
+/dts-v1/;
+/include/ "hi3620.dtsi"
+
+/ {
+ model = "Hisilicon Hi4511 Development Board";
+ compatible = "hisilicon,hi3620-hi4511";
+
+ chosen {
+ bootargs = "console=ttyAMA0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on mem=512m earlyprintk";
+ };
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ amba {
+ timer0: timer at fc800000 {
+ status = "ok";
+ };
+
+ uart0: uart at fcb00000 { /* console */
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart0_pmx_func &uart0_cfg_func>;
+ pinctrl-1 = <&uart0_pmx_idle &uart0_cfg_idle>;
+ status = "ok";
+ };
+
+ uart1: uart at fcb01000 { /* modem */
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart1_pmx_func &uart1_cfg_func>;
+ pinctrl-1 = <&uart1_pmx_idle &uart1_cfg_idle>;
+ status = "ok";
+ };
+
+ uart2: uart at fcb02000 { /* audience */
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart2_pmx_func &uart2_cfg_func>;
+ pinctrl-1 = <&uart2_pmx_idle &uart2_cfg_idle>;
+ status = "ok";
+ };
+
+ uart3: uart at fcb03000 {
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>;
+ pinctrl-1 = <&uart3_pmx_idle &uart3_cfg_idle>;
+ status = "ok";
+ };
+
+ uart4: uart at fcb04000 {
+ pinctrl-names = "default", "idle";
+ pinctrl-0 = <&uart4_pmx_func &uart4_cfg_func>;
+ pinctrl-1 = <&uart4_pmx_idle &uart4_cfg_func>;
+ status = "ok";
+ };
+
+ gpio0: gpio at fc806000 {
+ status = "ok";
+ };
+
+ gpio1: gpio at fc807000 {
+ status = "ok";
+ };
+
+ gpio2: gpio at fc808000 {
+ status = "ok";
+ };
+
+ gpio3: gpio at fc809000 {
+ status = "ok";
+ };
+
+ gpio4: gpio at fc80a000 {
+ status = "ok";
+ };
+
+ gpio5: gpio at fc80b000 {
+ status = "ok";
+ };
+
+ gpio6: gpio at fc80c000 {
+ status = "ok";
+ };
+
+ gpio7: gpio at fc80d000 {
+ status = "ok";
+ };
+
+ gpio8: gpio at fc80e000 {
+ status = "ok";
+ };
+
+ gpio9: gpio at fc80f000 {
+ status = "ok";
+ };
+
+ gpio10: gpio at fc810000 {
+ status = "ok";
+ };
+
+ gpio11: gpio at fc811000 {
+ status = "ok";
+ };
+
+ gpio12: gpio at fc812000 {
+ status = "ok";
+ };
+
+ gpio13: gpio at fc813000 {
+ status = "ok";
+ };
+
+ gpio14: gpio at fc814000 {
+ status = "ok";
+ };
+
+ gpio15: gpio at fc815000 {
+ status = "ok";
+ };
+
+ gpio16: gpio at fc816000 {
+ status = "ok";
+ };
+
+ gpio17: gpio at fc817000 {
+ status = "ok";
+ };
+
+ gpio18: gpio at fc818000 {
+ status = "ok";
+ };
+
+ gpio19: gpio at fc819000 {
+ status = "ok";
+ };
+
+ gpio20: gpio at fc81a000 {
+ status = "ok";
+ };
+
+ gpio21: gpio at fc81b000 {
+ status = "ok";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ call {
+ label = "call";
+ gpios = <&gpio17 2 0>;
+ linux,code = <169>; /* KEY_PHONE */
+ };
+ };
+
+ pmx0: pinmux at fc803000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pmx_func>;
+
+ board_pmx_pins: pinmux_board_pmx_pins {
+ pinctrl-single,pins = <
+ 0x008 0x0 /* GPIO -- eFUSE_DOUT */
+ 0x100 0x0 /* USIM_CLK & USIM_DATA (IOMG63) */
+ 0x104 0x0 /* USIM_RST (IOMG96) */
+ >;
+ };
+ sd_pmx_pins: pinmux_sd_pins {
+ pinctrl-single,pins = <
+ 0x0bc 0x0 /* SD_CLK, SD_CMD, SD_DATA[0:2] */
+ >;
+ };
+ uart0_pmx_func: pinmux_uart0_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0f0 0x0
+ 0x0f4 0x0 /* UART0_RX & UART0_TX */
+ >;
+ };
+ uart0_pmx_idle: pinmux_uart0_pins at 1 {
+ pinctrl-single,pins = <
+ /*0x0f0 0x1*/ /* UART0_CTS & UART0_RTS */
+ 0x0f4 0x1 /* UART0_RX & UART0_TX */
+ >;
+ };
+ uart1_pmx_func: pinmux_uart1_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0f8 0x0 /* UART1_CTS & UART1_RTS (IOMG61) */
+ 0x0fc 0x0 /* UART1_RX & UART1_TX (IOMG62) */
+ >;
+ };
+ uart1_pmx_idle: pinmux_uart1_pins at 1 {
+ pinctrl-single,pins = <
+ 0x0f8 0x1 /* GPIO (IOMG61) */
+ 0x0fc 0x1 /* GPIO (IOMG62) */
+ >;
+ };
+ uart2_pmx_func: pinmux_uart2_pins at 0 {
+ pinctrl-single,pins = <
+ 0x104 0x2 /* UART2_RXD (IOMG96) */
+ 0x108 0x2 /* UART2_TXD (IOMG64) */
+ >;
+ };
+ uart2_pmx_idle: pinmux_uart2_pins at 1 {
+ pinctrl-single,pins = <
+ 0x104 0x1 /* GPIO (IOMG96) */
+ 0x108 0x1 /* GPIO (IOMG64) */
+ >;
+ };
+ uart3_pmx_func: pinmux_uart3_pins at 0 {
+ pinctrl-single,pins = <
+ 0x160 0x2 /* UART3_CTS & UART3_RTS (IOMG85) */
+ 0x164 0x2 /* UART3_RXD & UART3_TXD (IOMG86) */
+ >;
+ };
+ uart3_pmx_idle: pinmux_uart3_pins at 1 {
+ pinctrl-single,pins = <
+ 0x160 0x1 /* GPIO (IOMG85) */
+ 0x164 0x1 /* GPIO (IOMG86) */
+ >;
+ };
+ uart4_pmx_func: pinmux_uart4_pins at 0 {
+ pinctrl-single,pins = <
+ 0x168 0x0 /* UART4_CTS & UART4_RTS (IOMG87) */
+ 0x16c 0x0 /* UART4_RXD (IOMG88) */
+ 0x170 0x0 /* UART4_TXD (IOMG93) */
+ >;
+ };
+ uart4_pmx_idle: pinmux_uart4_pins at 1 {
+ pinctrl-single,pins = <
+ 0x168 0x1 /* GPIO (IOMG87) */
+ 0x16c 0x1 /* GPIO (IOMG88) */
+ 0x170 0x1 /* GPIO (IOMG93) */
+ >;
+ };
+ i2c0_pmx_func: pinmux_i2c0_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0b4 0x0 /* I2C0_SCL & I2C0_SDA (IOMG45) */
+ >;
+ };
+ i2c0_pmx_idle: pinmux_i2c0_pins at 1 {
+ pinctrl-single,pins = <
+ 0x0b4 0x1 /* GPIO (IOMG45) */
+ >;
+ };
+ i2c1_pmx_func: pinmux_i2c1_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0b8 0x0 /* I2C1_SCL & I2C1_SDA (IOMG46) */
+ >;
+ };
+ i2c1_pmx_idle: pinmux_i2c1_pins at 1 {
+ pinctrl-single,pins = <
+ 0x0b8 0x1 /* GPIO (IOMG46) */
+ >;
+ };
+ i2c2_pmx_func: pinmux_i2c2_pins at 0 {
+ pinctrl-single,pins = <
+ 0x068 0x0 /* I2C2_SCL (IOMG26) */
+ 0x06c 0x0 /* I2C2_SDA (IOMG27) */
+ >;
+ };
+ i2c2_pmx_idle: pinmux_i2c2_pins at 0 {
+ pinctrl-single,pins = <
+ 0x068 0x1 /* GPIO (IOMG26) */
+ 0x06c 0x1 /* GPIO (IOMG27) */
+ >;
+ };
+ i2c3_pmx_func: pinmux_i2c3_pins at 0 {
+ pinctrl-single,pins = <
+ 0x050 0x2 /* I2C3_SCL (IOMG20) */
+ 0x054 0x2 /* I2C3_SDA (IOMG21) */
+ >;
+ };
+ i2c3_pmx_idle: pinmux_i2c3_pins at 0 {
+ pinctrl-single,pins = <
+ 0x050 0x1 /* GPIO (IOMG20) */
+ 0x054 0x1 /* GPIO (IOMG21) */
+ >;
+ };
+ spi0_pmx_func: pinmux_spi0_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0d4 0x0 /* SPI0_CLK/SPI0_DI/SPI0_DO (IOMG53) */
+ 0x0d8 0x0 /* SPI0_CS0 (IOMG54) */
+ 0x0dc 0x0 /* SPI0_CS1 (IOMG55) */
+ 0x0e0 0x0 /* SPI0_CS2 (IOMG56) */
+ 0x0e4 0x0 /* SPI0_CS3 (IOMG57) */
+ >;
+ };
+ spi0_pmx_idle: pinmux_spi0_pins at 1 {
+ pinctrl-single,pins = <
+ 0x0d4 0x1 /* GPIO (IOMG53) */
+ 0x0d8 0x1 /* GPIO (IOMG54) */
+ 0x0dc 0x1 /* GPIO (IOMG55) */
+ 0x0e0 0x1 /* GPIO (IOMG56) */
+ 0x0e4 0x1 /* GPIO (IOMG57) */
+ >;
+ };
+ spi1_pmx_func: pinmux_spi1_pins at 0 {
+ pinctrl-single,pins = <
+ 0x184 0x0 /* SPI1_CLK/SPI1_DI (IOMG98) */
+ 0x0e8 0x0 /* SPI1_DO (IOMG58) */
+ 0x0ec 0x0 /* SPI1_CS (IOMG95) */
+ >;
+ };
+ spi1_pmx_idle: pinmux_spi1_pins at 1 {
+ pinctrl-single,pins = <
+ 0x184 0x1 /* GPIO (IOMG98) */
+ 0x0e8 0x1 /* GPIO (IOMG58) */
+ 0x0ec 0x1 /* GPIO (IOMG95) */
+ >;
+ };
+ kpc_pmx_func: pinmux_kpc_pins at 0 {
+ pinctrl-single,pins = <
+ 0x12c 0x0 /* KEY_IN0 (IOMG73) */
+ 0x130 0x0 /* KEY_IN1 (IOMG74) */
+ 0x134 0x0 /* KEY_IN2 (IOMG75) */
+ 0x10c 0x0 /* KEY_OUT0 (IOMG65) */
+ 0x110 0x0 /* KEY_OUT1 (IOMG66) */
+ 0x114 0x0 /* KEY_OUT2 (IOMG67) */
+ >;
+ };
+ kpc_pmx_idle: pinmux_kpc_pins at 1 {
+ pinctrl-single,pins = <
+ 0x12c 0x1 /* GPIO (IOMG73) */
+ 0x130 0x1 /* GPIO (IOMG74) */
+ 0x134 0x1 /* GPIO (IOMG75) */
+ 0x10c 0x1 /* GPIO (IOMG65) */
+ 0x110 0x1 /* GPIO (IOMG66) */
+ 0x114 0x1 /* GPIO (IOMG67) */
+ >;
+ };
+ gpio_key_func: pinmux_gpiokey_pins {
+ pinctrl-single,pins = <
+ 0x10c 0x1 /* KEY_OUT0/GPIO (IOMG65) */
+ 0x130 0x1 /* KEY_IN1/GPIO (IOMG74) */
+ >;
+ };
+ emmc_pmx_func: pinmux_emmc_pins at 0 {
+ pinctrl-single,pins = <
+ 0x030 0x2 /* eMMC_CMD/eMMC_CLK (IOMG12) */
+ 0x018 0x0 /* NAND_CS3_N (IOMG6) */
+ 0x024 0x0 /* NAND_BUSY2_N (IOMG8) */
+ 0x028 0x0 /* NAND_BUSY3_N (IOMG9) */
+ 0x02c 0x2 /* eMMC_DATA[0:7] (IOMG10) */
+ >;
+ };
+ emmc_pmx_idle: pinmux_emmc_pins at 1 {
+ pinctrl-single,pins = <
+ 0x030 0x0 /* GPIO (IOMG12) */
+ 0x018 0x1 /* GPIO (IOMG6) */
+ 0x024 0x1 /* GPIO (IOMG8) */
+ 0x028 0x1 /* GPIO (IOMG9) */
+ 0x02c 0x1 /* GPIO (IOMG10) */
+ >;
+ };
+ sd_pmx_func: pinmux_sd_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0bc 0x0 /* SD_CLK/SD_CMD/SD_DATA0/SD_DATA1/SD_DATA2 (IOMG47) */
+ 0x0c0 0x0 /* SD_DATA3 (IOMG48) */
+ >;
+ };
+ sd_pmx_idle: pinmux_sd_pins at 1 {
+ pinctrl-single,pins = <
+ 0x0bc 0x1 /* GPIO (IOMG47) */
+ 0x0c0 0x1 /* GPIO (IOMG48) */
+ >;
+ };
+ nand_pmx_func: pinmux_nand_pins at 0 {
+ pinctrl-single,pins = <
+ 0x00c 0x0 /* NAND_ALE/NAND_CLE/.../NAND_DATA[0:7] (IOMG3) */
+ 0x010 0x0 /* NAND_CS1_N (IOMG4) */
+ 0x014 0x0 /* NAND_CS2_N (IOMG5) */
+ 0x018 0x0 /* NAND_CS3_N (IOMG6) */
+ 0x01c 0x0 /* NAND_BUSY0_N (IOMG94) */
+ 0x020 0x0 /* NAND_BUSY1_N (IOMG7) */
+ 0x024 0x0 /* NAND_BUSY2_N (IOMG8) */
+ 0x028 0x0 /* NAND_BUSY3_N (IOMG9) */
+ 0x02c 0x0 /* NAND_DATA[8:15] (IOMG10) */
+ >;
+ };
+ nand_pmx_idle: pinmux_nand_pins at 1 {
+ pinctrl-single,pins = <
+ 0x00c 0x1 /* GPIO (IOMG3) */
+ 0x010 0x1 /* GPIO (IOMG4) */
+ 0x014 0x1 /* GPIO (IOMG5) */
+ 0x018 0x1 /* GPIO (IOMG6) */
+ 0x01c 0x1 /* GPIO (IOMG94) */
+ 0x020 0x1 /* GPIO (IOMG7) */
+ 0x024 0x1 /* GPIO (IOMG8) */
+ 0x028 0x1 /* GPIO (IOMG9) */
+ 0x02c 0x1 /* GPIO (IOMG10) */
+ >;
+ };
+ sdio_pmx_func: pinmux_sdio_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0c4 0x0 /* SDIO_CLK/SDIO_CMD/SDIO_DATA[0:3] (IOMG49) */
+ >;
+ };
+ sdio_pmx_idle: pinmux_sdio_pins at 1 {
+ pinctrl-single,pins = <
+ 0x0c4 0x1 /* GPIO (IOMG49) */
+ >;
+ };
+ audio_out_pmx_func: pinmux_audio_pins at 0 {
+ pinctrl-single,pins = <
+ 0x0f0 0x1 /* GPIO (IOMG59), audio spk & earphone */
+ >;
+ };
+ };
+
+ pmx1: pinmux at fc803800 {
+ pinctrl-names = "default";
+ pinctrl-0 = < &board_pu_pins &board_pd_pins &board_pd_ps_pins
+ &board_np_pins &board_ps_pins &kpc_cfg_func
+ &audio_out_cfg_func>;
+ board_pu_pins: pinmux_board_pu_pins {
+ pinctrl-single,pins = <
+ 0x014 0 /* GPIO_158 (IOCFG2) */
+ 0x018 0 /* GPIO_159 (IOCFG3) */
+ 0x01c 0 /* BOOT_MODE0 (IOCFG4) */
+ 0x020 0 /* BOOT_MODE1 (IOCFG5) */
+ >;
+ pinctrl-single,bias-pullup = <1 1 1>;
+ pinctrl-single,bias-disable = <1 0 1>;
+ };
+ board_pd_pins: pinmux_board_pd_pins {
+ pinctrl-single,pins = <
+ 0x038 0 /* eFUSE_DOUT (IOCFG11) */
+ 0x150 0 /* ISP_GPIO8 (IOCFG93) */
+ 0x154 0 /* ISP_GPIO9 (IOCFG94) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ };
+ board_pd_ps_pins: pinmux_board_pd_ps_pins {
+ pinctrl-single,pins = <
+ 0x220 0 /* USIM_CLK (IOCFG144) */
+ 0x224 0 /* USIM_DATA (IOCFG145) */
+ 0x228 0 /* USIM_RST (IOCFG146) */
+ 0x2d8 0 /* CLK_OUT0 (IOCFG190) */
+ 0x004 0 /* PMU_SPI_DATA (IOCFG192) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ board_np_pins: pinmux_board_np_pins {
+ pinctrl-single,pins = <
+ 0x24c 0 /* KEYPAD_OUT7 (IOCFG155) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ };
+ board_ps_pins: pinmux_board_ps_pins {
+ pinctrl-single,pins = <
+ 0x000 0 /* PMU_SPI_CLK (IOCFG191) */
+ 0x008 0 /* PMU_SPI_CS_N (IOCFG193) */
+ >;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ uart0_cfg_func: pinmux_uart0_pins at 2 {
+ pinctrl-single,pins = <
+ 0x208 0 /* UART0_RXD (IOCFG138) */
+ 0x20c 0 /* UART0_TXD (IOCFG139) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ };
+ uart0_cfg_idle: pinmux_uart0_pins at 3 {
+ pinctrl-single,pins = <
+ 0x208 0 /* UART0_RXD (IOCFG138) */
+ 0x20c 0 /* UART0_TXD (IOCFG139) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ };
+ uart1_cfg_func: pinmux_uart1_pins at 2 {
+ pinctrl-single,pins = <
+ 0x210 0 /* UART1_CTS (IOCFG140) */
+ 0x214 0 /* UART1_RTS (IOCFG141) */
+ 0x218 0 /* UART1_RXD (IOCFG142) */
+ 0x21c 0 /* UART1_TXD (IOCFG143) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ };
+ uart1_cfg_idle: pinmux_uart1_pins at 3 {
+ pinctrl-single,pins = <
+ 0x210 0 /* UART1_CTS (IOCFG140) */
+ 0x214 0 /* UART1_RTS (IOCFG141) */
+ 0x218 0 /* UART1_RXD (IOCFG142) */
+ 0x21c 0 /* UART1_TXD (IOCFG143) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ };
+ uart2_cfg_func: pinmux_uart2_pins at 2 {
+ pinctrl-single,pins = <
+ 0x210 0 /* UART1_CTS (IOCFG140) */
+ 0x214 0 /* UART1_RTS (IOCFG141) */
+ 0x218 0 /* UART1_RXD (IOCFG142) */
+ 0x21c 0 /* UART1_TXD (IOCFG143) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ };
+ uart2_cfg_idle: pinmux_uart2_pins at 3 {
+ pinctrl-single,pins = <
+ 0x210 0 /* GPIO (IOCFG140) */
+ 0x214 0 /* GPIO (IOCFG141) */
+ 0x218 0 /* GPIO (IOCFG142) */
+ 0x21c 0 /* GPIO (IOCFG143) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ };
+ uart3_cfg_func: pinmux_uart3_pins at 2 {
+ pinctrl-single,pins = <
+ 0x294 0 /* UART3_CTS (IOCFG173) */
+ 0x298 0 /* UART3_RTS (IOCFG174) */
+ 0x29c 0 /* UART3_RXD (IOCFG175) */
+ 0x2a0 0 /* UART3_TXD (IOCFG176) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ };
+ uart3_cfg_idle: pinmux_uart3_pins at 3 {
+ pinctrl-single,pins = <
+ 0x294 0 /* UART3_CTS (IOCFG173) */
+ 0x298 0 /* UART3_RTS (IOCFG174) */
+ 0x29c 0 /* UART3_RXD (IOCFG175) */
+ 0x2a0 0 /* UART3_TXD (IOCFG176) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ };
+ uart4_cfg_func: pinmux_uart4_pins at 2 {
+ pinctrl-single,pins = <
+ 0x2a4 0 /* UART4_CTS (IOCFG177) */
+ 0x2a8 0 /* UART4_RTS (IOCFG178) */
+ 0x2ac 0 /* UART4_RXD (IOCFG179) */
+ 0x2b0 0 /* UART4_TXD (IOCFG180) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ };
+ i2c0_cfg_func: pinmux_i2c0_pins at 2 {
+ pinctrl-single,pins = <
+ 0x17c 0 /* I2C0_SCL (IOCFG103) */
+ 0x180 0 /* I2C0_SDA (IOCFG104) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ i2c1_cfg_func: pinmux_i2c1_pins at 2 {
+ pinctrl-single,pins = <
+ 0x184 0 /* I2C1_SCL (IOCFG105) */
+ 0x188 0 /* I2C1_SDA (IOCFG106) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ i2c2_cfg_func: pinmux_i2c2_pins at 2 {
+ pinctrl-single,pins = <
+ 0x118 0 /* I2C2_SCL (IOCFG79) */
+ 0x11c 0 /* I2C2_SDA (IOCFG80) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ i2c3_cfg_func: pinmux_i2c3_pins at 2 {
+ pinctrl-single,pins = <
+ 0x100 0 /* I2C3_SCL (IOCFG73) */
+ 0x104 0 /* I2C3_SDA (IOCFG74) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ spi0_cfg_func1: pinmux_spi0_pins at 2 {
+ pinctrl-single,pins = <
+ 0x1d4 0 /* SPI0_CLK (IOCFG125) */
+ 0x1d8 0 /* SPI0_DI (IOCFG126) */
+ 0x1dc 0 /* SPI0_DO (IOCFG127) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ spi0_cfg_func2: pinmux_spi0_pins at 3 {
+ pinctrl-single,pins = <
+ 0x1e0 0 /* SPI0_CS0 (IOCFG128) */
+ 0x1e4 0 /* SPI0_CS1 (IOCFG129) */
+ 0x1e8 0 /* SPI0_CS2 (IOCFG130 */
+ 0x1ec 0 /* SPI0_CS3 (IOCFG131) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <1 1 1>;
+ pinctrl-single,bias-disable = <1 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ spi1_cfg_func1: pinmux_spi1_pins at 2 {
+ pinctrl-single,pins = <
+ 0x1f0 0 /* SPI1_CLK (IOCFG132) */
+ 0x1f4 0 /* SPI1_DI (IOCFG133) */
+ 0x1f8 0 /* SPI1_DO (IOCFG134) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ spi1_cfg_func2: pinmux_spi1_pins at 3 {
+ pinctrl-single,pins = <
+ 0x1fc 0 /* SPI1_CS (IOCFG135) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <1 1 1>;
+ pinctrl-single,bias-disable = <1 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ kpc_cfg_func: pinmux_kpc_pins at 2 {
+ pinctrl-single,pins = <
+ 0x250 0 /* KEY_IN0 (IOCFG156) */
+ 0x254 0 /* KEY_IN1 (IOCFG157) */
+ 0x258 0 /* KEY_IN2 (IOCFG158) */
+ 0x230 0 /* KEY_OUT0 (IOCFG148) */
+ 0x234 0 /* KEY_OUT1 (IOCFG149) */
+ 0x238 0 /* KEY_OUT2 (IOCFG150) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ };
+ emmc_cfg_func: pinmux_emmc_pins at 2 {
+ pinctrl-single,pins = <
+ 0x0ac 0 /* eMMC_CMD (IOCFG40) */
+ 0x0b0 0 /* eMMC_CLK (IOCFG41) */
+ 0x058 0 /* NAND_CS3_N (IOCFG19) */
+ 0x064 0 /* NAND_BUSY2_N (IOCFG22) */
+ 0x068 0 /* NAND_BUSY3_N (IOCFG23) */
+ 0x08c 0 /* NAND_DATA8 (IOCFG32) */
+ 0x090 0 /* NAND_DATA9 (IOCFG33) */
+ 0x094 0 /* NAND_DATA10 (IOCFG34) */
+ 0x098 0 /* NAND_DATA11 (IOCFG35) */
+ 0x09c 0 /* NAND_DATA12 (IOCFG36) */
+ 0x0a0 0 /* NAND_DATA13 (IOCFG37) */
+ 0x0a4 0 /* NAND_DATA14 (IOCFG38) */
+ 0x0a8 0 /* NAND_DATA15 (IOCFG39) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <1 1 1>;
+ pinctrl-single,bias-disable = <1 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ sd_cfg_func1: pinmux_sd_pins at 2 {
+ pinctrl-single,pins = <
+ 0x18c 0 /* SD_CLK (IOCFG107) */
+ 0x190 0 /* SD_CMD (IOCFG108) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ sd_cfg_func2: pinmux_sd_pins at 3 {
+ pinctrl-single,pins = <
+ 0x194 0 /* SD_DATA0 (IOCFG109) */
+ 0x198 0 /* SD_DATA1 (IOCFG110) */
+ 0x19c 0 /* SD_DATA2 (IOCFG111) */
+ 0x1a0 0 /* SD_DATA3 (IOCFG112) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ pinctrl-single,drive-strength = <0x70 0xf0>;
+ };
+ nand_cfg_func1: pinmux_nand_pins at 2 {
+ pinctrl-single,pins = <
+ 0x03c 0 /* NAND_ALE (IOCFG12) */
+ 0x040 0 /* NAND_CLE (IOCFG13) */
+ 0x06c 0 /* NAND_DATA0 (IOCFG24) */
+ 0x070 0 /* NAND_DATA1 (IOCFG25) */
+ 0x074 0 /* NAND_DATA2 (IOCFG26) */
+ 0x078 0 /* NAND_DATA3 (IOCFG27) */
+ 0x07c 0 /* NAND_DATA4 (IOCFG28) */
+ 0x080 0 /* NAND_DATA5 (IOCFG29) */
+ 0x084 0 /* NAND_DATA6 (IOCFG30) */
+ 0x088 0 /* NAND_DATA7 (IOCFG31) */
+ 0x08c 0 /* NAND_DATA8 (IOCFG32) */
+ 0x090 0 /* NAND_DATA9 (IOCFG33) */
+ 0x094 0 /* NAND_DATA10 (IOCFG34) */
+ 0x098 0 /* NAND_DATA11 (IOCFG35) */
+ 0x09c 0 /* NAND_DATA12 (IOCFG36) */
+ 0x0a0 0 /* NAND_DATA13 (IOCFG37) */
+ 0x0a4 0 /* NAND_DATA14 (IOCFG38) */
+ 0x0a8 0 /* NAND_DATA15 (IOCFG39) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ nand_cfg_func2: pinmux_nand_pins at 3 {
+ pinctrl-single,pins = <
+ 0x044 0 /* NAND_RE_N (IOCFG14) */
+ 0x048 0 /* NAND_WE_N (IOCFG15) */
+ 0x04c 0 /* NAND_CS0_N (IOCFG16) */
+ 0x050 0 /* NAND_CS1_N (IOCFG17) */
+ 0x054 0 /* NAND_CS2_N (IOCFG18) */
+ 0x058 0 /* NAND_CS3_N (IOCFG19) */
+ 0x05c 0 /* NAND_BUSY0_N (IOCFG20) */
+ 0x060 0 /* NAND_BUSY1_N (IOCFG21) */
+ 0x064 0 /* NAND_BUSY2_N (IOCFG22) */
+ 0x068 0 /* NAND_BUSY3_N (IOCFG23) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <1 1 1>;
+ pinctrl-single,bias-disable = <1 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ sdio_cfg_func: pinmux_sdio_pins at 2 {
+ pinctrl-single,pins = <
+ 0x1a4 0 /* SDIO0_CLK (IOCG113) */
+ 0x1a8 0 /* SDIO0_CMD (IOCG114) */
+ 0x1ac 0 /* SDIO0_DATA0 (IOCG115) */
+ 0x1b0 0 /* SDIO0_DATA1 (IOCG116) */
+ 0x1b4 0 /* SDIO0_DATA2 (IOCG117) */
+ 0x1b8 0 /* SDIO0_DATA3 (IOCG118) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ pinctrl-single,drive-strength = <0x30 0xf0>;
+ };
+ audio_out_cfg_func: pinmux_audio_pins at 1 {
+ pinctrl-single,pins = <
+ 0x200 0 /* GPIO (IOCFG136) */
+ 0x204 0 /* GPIO (IOCFG137) */
+ >;
+ pinctrl-single,bias-pulldown = <2 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <2 0 3>;
+ };
+ };
+ };
+};
--
1.7.10.4
^ permalink raw reply related
* [PATCH v8 12/12] document: devicetree: bind pinconf with pin single
From: Haojian Zhuang @ 2013-02-02 17:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359825953-15663-1-git-send-email-haojian.zhuang@linaro.org>
From: Haojian Zhuang <haojian.zhuang@gmail.com>
Add comments with pinconf & gpio range in the document of
pinctrl-single.
Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
.../devicetree/bindings/pinctrl/pinctrl-single.txt | 108 +++++++++++++++++++-
1 file changed, 107 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
index 2c81e45..eeb2e93 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
@@ -1,7 +1,9 @@
One-register-per-pin type device tree based pinctrl driver
Required properties:
-- compatible : "pinctrl-single"
+- compatible : "pinctrl-single" or "pinconf-single".
+ "pinctrl-single" means that pinconf isn't supported.
+ "pinconf-single" means that generic pinconf is supported.
- reg : offset and length of the register set for the mux registers
@@ -14,9 +16,61 @@ Optional properties:
- pinctrl-single,function-off : function off mode for disabled state if
available and same for all registers; if not specified, disabling of
pin functions is ignored
+
- pinctrl-single,bit-per-mux : boolean to indicate that one register controls
more than one pin
+- pinctrl-single,drive-strength : array of value that are used to configure
+ drive strength in the pinmux register. They're value of drive strength
+ current and drive strength mask.
+
+ /* drive strength current, mask */
+ pinctrl-single,power-source = <0x30 0xf0>;
+
+- pinctrl-single,bias-disable : array of value that are used to configure the
+ input bias disabled in the pinmux register. They're value of bias value,
+ match bias disabled value and bias disabled mask.
+
+ /* bias value, match bias disabled value, mask */
+ pinctrl-single,bias-disable = <2 0 3>;
+
+- pinctrl-single,bias-pullup : array of value that are used to configure the
+ input bias pullup in the pinmux register. They're value of bias value,
+ match bias pullup value and bias pullup mask.
+
+ /* bias value, match bias pullup value, mask */
+ pinctrl-single,bias-pullup = <0 1 1>;
+
+- pinctrl-single,bias-pulldown : array of value that are used to configure the
+ input bias pulldown in the pinmux register. They're value of bias value,
+ match bias pulldown value and bias pulldown mask.
+
+ /* bias value, match bias pulldown value, mask */
+ pinctrl-single,bias-pulldown = <2 2 2>;
+
+- pinctrl-single,input-schmitt : array of value that are used to configure
+ input schmitt in the pinmux register. In some silicons, there're two input
+ schmitt value (rising-edge & falling-edge) in the pinmux register.
+
+ /* input schmitt value, mask */
+ pinctrl-single,input-schmitt = <0x30 0x70>;
+
+- pinctrl-single,input-schmitt-disable : array of value that are used to
+ configure input schmitt disabled in the pinmux register. They're value of
+ input schmitt field, match disable value & mask.
+
+ /* input schmitt value, match disable value, mask */
+ pinctrl-single,input-schmitt-disable = <0x30 0x40 0x70>;
+
+- pinctrl-single,gpio-range : list of value that are used to configure a GPIO
+ range. They're value of subnode phandle, pin base in pinctrl device, pin
+ number in this range, GPIO function value of this GPIO range.
+ The number of parameters is depend on #pinctrl-single,gpio-range-cells
+ property.
+
+ /* pin base, nr pins & gpio function */
+ pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1>;
+
This driver assumes that there is only one register for each pin (unless the
pinctrl-single,bit-per-mux is set), and uses the common pinctrl bindings as
specified in the pinctrl-bindings.txt document in this directory.
@@ -42,6 +96,20 @@ Where 0xdc is the offset from the pinctrl register base address for the
device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
be used when applying this change to the register.
+
+Optional sub-node: In case some pins could be configured as GPIO in the pinmux
+register, those pins could be defined as a GPIO range. This sub-node is required
+by pinctrl-single,gpio-range property.
+
+Required properties in sub-node:
+- #pinctrl-single,gpio-range-cells : the number of parameters after phandle in
+ pinctrl-single,gpio-range property.
+
+ range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
+ };
+
+
Example:
/* SoC common file */
@@ -76,6 +144,29 @@ control_devconf0: pinmux at 48002274 {
pinctrl-single,function-mask = <0x5F>;
};
+/* third controller instance for pins in gpio domain */
+pmx_gpio: pinmux at d401e000 {
+ compatible = "pinconf-single";
+ reg = <0xd401e000 0x0330>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <7>;
+
+ /* sparse GPIO range could be supported */
+ pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1
+ &range 12 1 0 &range 13 29 1
+ &range 43 1 0 &range 44 49 1
+ &range 94 1 1 &range 96 2 1>;
+
+ range: gpio-range {
+ #pinctrl-single,gpio-range-cells = <3>;
+ };
+};
+
+
/* board specific .dts file */
&pmx_core {
@@ -96,6 +187,16 @@ control_devconf0: pinmux at 48002274 {
>;
};
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ 0x208 0 /* UART0_RXD (IOCFG138) */
+ 0x20c 0 /* UART0_TXD (IOCFG139) */
+ >;
+ pinctrl-single,bias-pulldown = <0 2 2>;
+ pinctrl-single,bias-pullup = <0 1 1>;
+ pinctrl-single,bias-disable = <0 0 3>;
+ };
+
/* map uart2 pins */
uart2_pins: pinmux_uart2_pins {
pinctrl-single,pins = <
@@ -122,6 +223,11 @@ control_devconf0: pinmux@48002274 {
};
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+};
+
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>;
--
1.7.10.4
^ permalink raw reply related
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Sergei Shtylyov @ 2013-02-02 17:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130202124533.GA2637@n2100.arm.linux.org.uk>
Hello.
On 02-02-2013 16:45, Russell King - ARM Linux wrote:
> Now, CPPI is brand new code to arch/arm - always has been. It post-dates
> the DMA engine API. And it's been said many times about moving it to
> drivers/dma. The problem is Sergei doesn't want to do it - he's anti the
I *can't* do it, and I have denied all further responibility for it.
> DMA engine API for whatever reasons he can dream up. He professes no
I'm not dreaming anything up. Please understand that CPPI 4.1 is not just
a normal DMA controller -- it's a complex of several devices with DMA
controller being only one of them, and one that can't work autonomously but
only thru the proxy of the queue manager. That queue manager stuff I found
hard to fit into drivers/dma/ infrastructure. Myabe it was a honest mistake,
of course.
> knowledge of my dislike for having it in arch/arm, yet there's emails
> from years back showing that he knew about it. TI knows about it; Ajay
> about it. Yet... well... history speaks volumes about this.
Some details have slipped rom my memory after that many years. Im sorry
for that.
> Now, there may be a new problem with CPPI. That being we're now requiring
> DT support. _Had_ this been done prior to the push for DT, then it would
> not have been a concern, because then the problem becomes one for DT.
> But now that OMAP is being converted to DT, and DT is The Way To Go now,
> that's an additional problem that needs to be grappled with - or it may
> make things easier.
DaVinci is also being converted to device tree. However, that support
remains optional for now. Not sure it will make things easier, as we still
have two distinct devices to declare in the device tree: DMA controller and
queue manager, and we'll have to describe the interconnect between them too
(as a props of DMA controller I guess)...
WBR, Sergei
^ permalink raw reply
* [PATCH] ARM:omap2: using strlcpy instead of strncpy
From: Tony Lindgren @ 2013-02-02 18:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510C7925.9040006@asianux.com>
* Chen Gang <gang.chen@asianux.com> [130201 18:29]:
> ? 2013?02?02? 06:45, Tony Lindgren ??:
> > Added Peter to cc on this one too, it's best that he queues
> > all the twl changes.
>
> is it suitable to sync the MAINTAINER file for it ?
> if suitable, can you help to change it ?
Yes I suggest we add Peter as the maintainer for all twl
related things.
Regards,
Tony
^ permalink raw reply
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Matt Porter @ 2013-02-02 18:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e9be6668da8b4372a04687847daa1d8c@DFLE72.ent.ti.com>
On Sat, Feb 02, 2013 at 12:01:37AM +0000, Sergei Shtylyov wrote:
> Hello.
>
> On 01-02-2013 22:59, Matt Porter wrote:
>
> >>>>> Move mach-davinci/dma.c to common/edma.c so it can be used
> >>>>> by OMAP (specifically AM33xx) as well.
>
> >>>> I think this should rather go to drivers/dma/?
>
> >>> No, this is the private EDMA API. It's the analogous thing to
> >>> the private OMAP dma API that is in plat-omap/dma.c. The actual
> >>> dmaengine driver is in drivers/dma/edma.c as a wrapper around
> >>> this...same way OMAP DMA engine conversion is being done.
>
> >> Keeps me wondering why we couldn't have the same with CPPI 4.1 when I proposed
> >> that, instead of waiting indefinitely for TI to convert it to drivers/dma/
> >> directly. We could have working MUSB DMA on OMAP-L1x/Sitara all this time... Sigh.
>
> > That is a shame. Yeah, I've pointed out that I was doing this exactly
> > the same way as was acceptable for the OMAP DMA conversion since it was
> > in RFC. The reasons are sound since in both cases, we have many drivers
> > to convert that need to continue using the private DMA APIs.
>
> In case of CPPI 4.1, we'd only have to convert MUSB DMA driver. Other
> in-tree CPPI 4.1 having SoCs don't use it for anything but MUSB -- it even is
> sub-block of their MUSB device, AFAIK (I maybe wrong about Sitaras -- I don't
> know them well).
Well, it's pretty clear to me now that there's good reason for it not
landing in arch/arm/ so the obvious path is to do the dmaengine
conversion and put it in drivers/dma/ if it's really a generic dma engine.
I'm not sure why you express concern over the dma engine api not fitting
with CPPI 4.1? If it doesn't work, work with Vinod to fix the api. It's
expected, I'm working on dmaengine API changes right now to deal with a
limitation of EDMA that needs to be abstracted.
As pointed out, edma.c is already here in arch/arm/, so moving it doesn't
add something new. It does let us regression test all platforms that use it
(both Davinci and AM33xx) as I go through the conversion process.
-Matt
^ permalink raw reply
* [PATCH 2/2] ARM: OMAP2: Fix GPMC memory initialisation
From: Tony Lindgren @ 2013-02-02 18:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510C6A3D.70401@ti.com>
* Jon Hunter <jon-hunter@ti.com> [130201 17:25]:
>
> On 02/01/2013 03:51 PM, Tony Lindgren wrote:
> >
> > How about let's fix this properly to start with so we don't add
> > more blockers moving this code to drivers/bus?
> >
> > Looks like gpmc_mem_init() gets called from gpmc_probe() so
> > we can pass that information in pdev.
>
> I wondered if you would suggest that ;-)
:)
> I definitely can and it is probably best. Things like this become
> painful when we move to device-tree. We really need a generic way for
> passing stuff like this to drivers for omap. Our options are auxdata or
> bus notifiers. I am wondering whether we can plug pdata in the
> omap_device bus notifier for device-tree. Let me know if you have any
> thoughts.
Hmm but in this case can't you just do it based on the compatible
flag? For legacy systems we also need to pass it in pdata.
Regarding omap_device, we should find a way to keep the dependencies
between drivers and the bus code down to minimum. So ideally things
like this would be only done using just the compatible flag. But the
pdata we cannot remove quite yet.
Regards,
Tony
^ permalink raw reply
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Tony Lindgren @ 2013-02-02 18:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130202180747.GS2244@beef>
* Matt Porter <mporter@ti.com> [130202 10:10]:
> If it doesn't work, work with Vinod to fix the api. It's expected,
> I'm working on dmaengine API changes right now to deal with a
> limitation of EDMA that needs to be abstracted.
Regarding the DMA API limitations, I'm only aware of lack of capability
to configure autoincrement at the device end. And that keeps us from
converting all GPMC related devices using omap SDMA to use the DMA API.
Are there other limitations currently known with the DMA API?
Regards,
Tony
^ permalink raw reply
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Sergei Shtylyov @ 2013-02-02 19:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130202180747.GS2244@beef>
Hello.
On 02-02-2013 22:07, Matt Porter wrote:
>>>>>>> Move mach-davinci/dma.c to common/edma.c so it can be used
>>>>>>> by OMAP (specifically AM33xx) as well.
>>>>>> I think this should rather go to drivers/dma/?
>>>>> No, this is the private EDMA API. It's the analogous thing to
>>>>> the private OMAP dma API that is in plat-omap/dma.c. The actual
>>>>> dmaengine driver is in drivers/dma/edma.c as a wrapper around
>>>>> this...same way OMAP DMA engine conversion is being done.
>>>> Keeps me wondering why we couldn't have the same with CPPI 4.1 when I proposed
>>>> that, instead of waiting indefinitely for TI to convert it to drivers/dma/
>>>> directly. We could have working MUSB DMA on OMAP-L1x/Sitara all this time... Sigh.
>>> That is a shame. Yeah, I've pointed out that I was doing this exactly
>>> the same way as was acceptable for the OMAP DMA conversion since it was
>>> in RFC. The reasons are sound since in both cases, we have many drivers
>>> to convert that need to continue using the private DMA APIs.
>> In case of CPPI 4.1, we'd only have to convert MUSB DMA driver. Other
>> in-tree CPPI 4.1 having SoCs don't use it for anything but MUSB -- it even is
>> sub-block of their MUSB device, AFAIK (I maybe wrong about Sitaras -- I don't
>> know them well).
> Well, it's pretty clear to me now that there's good reason for it not
> landing in arch/arm/ so the obvious path is to do the dmaengine
> conversion and put it in drivers/dma/ if it's really a generic dma engine.
> I'm not sure why you express concern over the dma engine api not fitting
> with CPPI 4.1?
It's not a DMA controller only, it's 3 distinct devices, with the DMA
controller being one among them and using another one, the queue manager, as
some sort of proxy. The third device doesn't exist on OMAP-L1x SoCs -- it's
the buffer manager.
> If it doesn't work, work with Vinod to fix the api. It's
> expected, I'm working on dmaengine API changes right now to deal with a
> limitation of EDMA that needs to be abstracted.
Sorry, now it's TI's task. I no longer have time to work on this (my
internal project to push OMAP-L1x support upstream has expired at Sep 2010)
and my future in MV is very uncertain at this moment. Most probably I'll leave
it (or be forced to leave).
> As pointed out, edma.c is already here in arch/arm/, so moving it doesn't
> add something new. It does let us regression test all platforms that use it
> (both Davinci and AM33xx) as I go through the conversion process.
Could have been the same with CPPI 4.1 in theory if it was added to
mach-davinci/ back in 2009... we'd then only have to move it. EDMA code is
much older of course, so it's probably more justified.
> -Matt
WBR, Sergei
^ permalink raw reply
* [PATCHv2 for soc 4/4] arm: socfpga: Add SMP support for actual socfpga harware
From: Pavel Machek @ 2013-02-02 19:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359736762.2932.1.camel@linux-builds1>
Hi!
> > > > I actually thought about that... but could not think of non-ugly way
> > > > of doing that. I hope dts will normally be "right" for any production
> > > > system...
> > >
> > > I think a panic is better just for the reason that if someone is
> > > expecting SMP, but missed the warning message, and later finds out that
> > > the secondary core never came up, it would save some debugging time.
> > >
> > > Since I have to send out a v3 from the 1st patch anyways, let me verify
> > > that I can get the early warning.
> >
> > The choice is between a panic() at a point where the only way to find
> > out is to throw in printascii() or a working printk, and ending up with
> > an unbootable kernel, vs continuing the boot and having an almost
> > working system which can be logged into and the messages viewed.
> >
> > If you have an application which relies on the second CPU coming up,
> > why not have it verify that the second CPU came up (it's quite easy
> > to do - there's POSIX standard libc calls to get the number of online
> > CPUs).
>
> Point taken...thanks Russell.
Well, I don't think we normally check dtbs for validity with
user-helpful error messages, but it is relatively easy in this case.
---cut here---
Continue booting with second core disabled if cpu1-start-addr is not
present in .dtb.
Signed-off-by: Pavel Machek <pavel@denx.de>
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
index 81e0da0..90facdd 100644
--- a/arch/arm/mach-socfpga/platsmp.c
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -82,6 +82,9 @@ static void __init socfpga_smp_init_cpus(void)
ncores = 1;
}
#endif
+ if (!cpu1start_addr)
+ ncores = 1;
+
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index 334c330..c3cd88b 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -74,10 +74,9 @@ static void __init socfpga_sysmgr_init(void)
np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
- if (of_property_read_u32(np, "cpu1-start-addr", (u32 *) &cpu1start_addr)) {
- early_printk("Need cpu1-start-addr in device tree.\n");
- panic("Need cpu1-start-addr in device tree.\n");
- }
+ if (of_property_read_u32(np, "cpu1-start-addr", (u32 *) &cpu1start_addr))
+ printk(KERN_ALERT "Need cpu1-start-addr in device tree for SMP operation.\n");
+
sys_manager_base_addr = of_iomap(np, 0);
np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply related
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Matt Porter @ 2013-02-02 19:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130202181643.GD577@atomide.com>
On Sat, Feb 02, 2013 at 10:16:43AM -0800, Tony Lindgren wrote:
> * Matt Porter <mporter@ti.com> [130202 10:10]:
> > If it doesn't work, work with Vinod to fix the api. It's expected,
> > I'm working on dmaengine API changes right now to deal with a
> > limitation of EDMA that needs to be abstracted.
>
> Regarding the DMA API limitations, I'm only aware of lack of capability
> to configure autoincrement at the device end. And that keeps us from
> converting all GPMC related devices using omap SDMA to use the DMA API.
>
> Are there other limitations currently known with the DMA API?
Yes, I called one out when this was first posted as an RFC and was
working it in parallel with this support. This one blocks AM33XX support
in mmc and is the reason I split all of the mmc support out of the base
edma dmaengine for am33xx series. Independent of the blockage, whatever
we finally settle on to address this API need will also cleanup the use
of magic values in the davinci mmc driver (that's part of the second
thread below).
RFC posting:
https://patchwork.kernel.org/patch/1583531/
Posting with initial attempt at a caps api:
http://www.spinics.net/lists/linux-mmc/msg18351.html
Also, I haven't fully vetted the situation with cyclic transfers and
EDMA, however, I'm pretty sure that we'll need some API changes there.
The reason is that some Davinci platforms have no FIFO on their McASP
implementation (that was a new feature added on DA8xx and also AM33xx).
As such they have audio support implemented using ping-pong buffering
via an SRAM buffer. There's been a number of patches ahead of all this
that myself and others have worked upstream to get the SRAM stuff to be
Davinci-independent (genalloc). But, at the end of all of this, there's
no notion in a cyclic transfer of doing synchronized ping-pong buffering
using two chain channels. This is how it is implemented (and documented
in EDMA docs going back to the DSPs this IP first showed up on) using
the private API. I'll be looking at this soon, but, I'm more interested
in 1) getting the base support in 2) then the mmc stuff blocking DT
populated platforms using omap_hsmmc (split out and posted) 3) v3 of the
caps api w/ vinod's concerns address (working it not)
Normally, I'm not going to bring up the cyclic transfer issue until I
have some code to show or reference for discussion...but it's worth
being aware. But, in any case, I'm confident that will gate having the
mcasp driver that am33xx also uses converted to dmaengine. Except for
the gpmc limitation you menationed, that's the last in kernel user of
the privat edma api needed to be converted such that we can kill off
arch/arm/common/edma.c once it's taken in.
-Matt
^ permalink raw reply
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Matt Porter @ 2013-02-02 19:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3245316d7aa94b2e823f98b69497547d@DLEE74.ent.ti.com>
On Sat, Feb 02, 2013 at 07:06:06PM +0000, Sergei Shtylyov wrote:
> Hello.
>
> On 02-02-2013 22:07, Matt Porter wrote:
>
> >>>>>>> Move mach-davinci/dma.c to common/edma.c so it can be used
> >>>>>>> by OMAP (specifically AM33xx) as well.
>
> >>>>>> I think this should rather go to drivers/dma/?
>
> >>>>> No, this is the private EDMA API. It's the analogous thing to
> >>>>> the private OMAP dma API that is in plat-omap/dma.c. The actual
> >>>>> dmaengine driver is in drivers/dma/edma.c as a wrapper around
> >>>>> this...same way OMAP DMA engine conversion is being done.
>
> >>>> Keeps me wondering why we couldn't have the same with CPPI 4.1 when I proposed
> >>>> that, instead of waiting indefinitely for TI to convert it to drivers/dma/
> >>>> directly. We could have working MUSB DMA on OMAP-L1x/Sitara all this time... Sigh.
>
> >>> That is a shame. Yeah, I've pointed out that I was doing this exactly
> >>> the same way as was acceptable for the OMAP DMA conversion since it was
> >>> in RFC. The reasons are sound since in both cases, we have many drivers
> >>> to convert that need to continue using the private DMA APIs.
>
> >> In case of CPPI 4.1, we'd only have to convert MUSB DMA driver. Other
> >> in-tree CPPI 4.1 having SoCs don't use it for anything but MUSB -- it even is
> >> sub-block of their MUSB device, AFAIK (I maybe wrong about Sitaras -- I don't
> >> know them well).
>
> > Well, it's pretty clear to me now that there's good reason for it not
> > landing in arch/arm/ so the obvious path is to do the dmaengine
> > conversion and put it in drivers/dma/ if it's really a generic dma engine.
> > I'm not sure why you express concern over the dma engine api not fitting
> > with CPPI 4.1?
>
> It's not a DMA controller only, it's 3 distinct devices, with the DMA
> controller being one among them and using another one, the queue manager, as
> some sort of proxy. The third device doesn't exist on OMAP-L1x SoCs -- it's
> the buffer manager.
Interesting, and you don't see a way to have this split between
dmaengine and the musb driver? This all assumes there's even a match as
RMK did raise concerns elsewhere in this thread.
> > If it doesn't work, work with Vinod to fix the api. It's
> > expected, I'm working on dmaengine API changes right now to deal with a
> > limitation of EDMA that needs to be abstracted.
>
> Sorry, now it's TI's task. I no longer have time to work on this (my
> internal project to push OMAP-L1x support upstream has expired at Sep 2010)
> and my future in MV is very uncertain at this moment. Most probably I'll leave
> it (or be forced to leave).
Too bad, it's certainly "somebody's task". The people employed by TI
have names too. ;) I suspect it falls to Felipe or Kishon these days,
but I try to avoid USB as it's generally a source of pain.
> > As pointed out, edma.c is already here in arch/arm/, so moving it doesn't
> > add something new. It does let us regression test all platforms that use it
> > (both Davinci and AM33xx) as I go through the conversion process.
>
> Could have been the same with CPPI 4.1 in theory if it was added to
> mach-davinci/ back in 2009... we'd then only have to move it. EDMA code is
> much older of course, so it's probably more justified.
Absolutely, timing is everything. I can assure you I've flamed enough
people "internally" about leaving this EDMA dmaengine conversion for so
long. As you might have guessed, AM33xx is a bit of a driver for it, but
all of this would have been quite a bit simpler had somebody taken a
little effort and moved edma to dmaengine years ago when slave dma
support was added to dmaengine. ;)
-Matt
^ permalink raw reply
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Sergei Shtylyov @ 2013-02-02 20:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130202195548.GU2244@beef>
Hello.
On 02-02-2013 23:55, Matt Porter wrote:
>>>>>>>>> Move mach-davinci/dma.c to common/edma.c so it can be used
>>>>>>>>> by OMAP (specifically AM33xx) as well.
>>>>>>>> I think this should rather go to drivers/dma/?
>>>>>>> No, this is the private EDMA API. It's the analogous thing to
>>>>>>> the private OMAP dma API that is in plat-omap/dma.c. The actual
>>>>>>> dmaengine driver is in drivers/dma/edma.c as a wrapper around
>>>>>>> this...same way OMAP DMA engine conversion is being done.
>>>>>> Keeps me wondering why we couldn't have the same with CPPI 4.1 when I proposed
>>>>>> that, instead of waiting indefinitely for TI to convert it to drivers/dma/
>>>>>> directly. We could have working MUSB DMA on OMAP-L1x/Sitara all this time... Sigh.
>>>>> That is a shame. Yeah, I've pointed out that I was doing this exactly
>>>>> the same way as was acceptable for the OMAP DMA conversion since it was
>>>>> in RFC. The reasons are sound since in both cases, we have many drivers
>>>>> to convert that need to continue using the private DMA APIs.
>>>> In case of CPPI 4.1, we'd only have to convert MUSB DMA driver. Other
>>>> in-tree CPPI 4.1 having SoCs don't use it for anything but MUSB -- it even is
>>>> sub-block of their MUSB device, AFAIK (I maybe wrong about Sitaras -- I don't
>>>> know them well).
>>> Well, it's pretty clear to me now that there's good reason for it not
>>> landing in arch/arm/ so the obvious path is to do the dmaengine
>>> conversion and put it in drivers/dma/ if it's really a generic dma engine.
>>> I'm not sure why you express concern over the dma engine api not fitting
>>> with CPPI 4.1?
>> It's not a DMA controller only, it's 3 distinct devices, with the DMA
>> controller being one among them and using another one, the queue manager, as
>> some sort of proxy. The third device doesn't exist on OMAP-L1x SoCs -- it's
>> the buffer manager.
> Interesting, and you don't see a way to have this split between
> dmaengine and the musb driver?
This can't be split into the MUSB DMA driver, as the neither of CPPI 4.1
devices are really MUSB specific. The support should be generic.
> This all assumes there's even a match as
> RMK did raise concerns elsewhere in this thread.
Didn't quite get this sentence.
>>> If it doesn't work, work with Vinod to fix the api. It's
>>> expected, I'm working on dmaengine API changes right now to deal with a
>>> limitation of EDMA that needs to be abstracted.
>> Sorry, now it's TI's task. I no longer have time to work on this (my
>> internal project to push OMAP-L1x support upstream has expired at Sep 2010)
If not somewhat earlier... anyway, I wasn't able to spent much time on
this project in 2010.
>> and my future in MV is very uncertain at this moment. Most probably I'll leave
>> it (or be forced to leave).
> Too bad, it's certainly "somebody's task". The people employed by TI
> have names too. ;) I suspect it falls to Felipe or Kishon these days,
> but I try to avoid USB as it's generally a source of pain.
I'm probably masochistic then since I'm still sending MUSB patches, eben
though I wasn't working on it at MV until I switched to Kontron boards 2 weeks
ago. Now my task is fixing USB bugs on real Sitara with dual MUSB. :-)
>>> As pointed out, edma.c is already here in arch/arm/, so moving it doesn't
>>> add something new. It does let us regression test all platforms that use it
>>> (both Davinci and AM33xx) as I go through the conversion process.
>> Could have been the same with CPPI 4.1 in theory if it was added to
>> mach-davinci/ back in 2009... we'd then only have to move it. EDMA code is
I don't know why Kevin didn't merge it then. I remembere he didn't like
that it was not a proper platform driver and was tied with the platform code
thru some variables, and I refused to change that...
>> much older of course, so it's probably more justified.
> Absolutely, timing is everything. I can assure you I've flamed enough
> people "internally" about leaving this EDMA dmaengine conversion for so
> long. As you might have guessed, AM33xx is a bit of a driver for it, but
> all of this would have been quite a bit simpler had somebody taken a
> little effort and moved edma to dmaengine years ago when slave dma
> support was added to dmaengine. ;)
Hm, it seems to have happened back in 2008 when I was working on CPPI 4.1
code. Too bad I only knew that drivers/dma/ are for accelerating RAIDs back
then (if actually noot later than that).
TI seems to put more efforts into its Arago project than in supoporting
the cutting edge (or not) CPUs in mainline -- at lest things seem go there
first. Many Arago patches never reached mainline (not that they can be applied
without cleanup though).
> -Matt
WBR, Sergei
^ permalink raw reply
* [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
From: Tony Lindgren @ 2013-02-02 21:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130202194853.GT2244@beef>
* Matt Porter <mporter@ti.com> [130202 11:51]:
> On Sat, Feb 02, 2013 at 10:16:43AM -0800, Tony Lindgren wrote:
> > * Matt Porter <mporter@ti.com> [130202 10:10]:
> > > If it doesn't work, work with Vinod to fix the api. It's expected,
> > > I'm working on dmaengine API changes right now to deal with a
> > > limitation of EDMA that needs to be abstracted.
> >
> > Regarding the DMA API limitations, I'm only aware of lack of capability
> > to configure autoincrement at the device end. And that keeps us from
> > converting all GPMC related devices using omap SDMA to use the DMA API.
> >
> > Are there other limitations currently known with the DMA API?
>
> Yes, I called one out when this was first posted as an RFC and was
> working it in parallel with this support. This one blocks AM33XX support
> in mmc and is the reason I split all of the mmc support out of the base
> edma dmaengine for am33xx series. Independent of the blockage, whatever
> we finally settle on to address this API need will also cleanup the use
> of magic values in the davinci mmc driver (that's part of the second
> thread below).
>
> RFC posting:
> https://patchwork.kernel.org/patch/1583531/
> Posting with initial attempt at a caps api:
> http://www.spinics.net/lists/linux-mmc/msg18351.html
OK thanks for the links, good to hear at least some work is happening
on it.
> Also, I haven't fully vetted the situation with cyclic transfers and
> EDMA, however, I'm pretty sure that we'll need some API changes there.
> The reason is that some Davinci platforms have no FIFO on their McASP
> implementation (that was a new feature added on DA8xx and also AM33xx).
> As such they have audio support implemented using ping-pong buffering
> via an SRAM buffer. There's been a number of patches ahead of all this
> that myself and others have worked upstream to get the SRAM stuff to be
> Davinci-independent (genalloc). But, at the end of all of this, there's
> no notion in a cyclic transfer of doing synchronized ping-pong buffering
> using two chain channels. This is how it is implemented (and documented
> in EDMA docs going back to the DSPs this IP first showed up on) using
> the private API. I'll be looking at this soon, but, I'm more interested
> in 1) getting the base support in 2) then the mmc stuff blocking DT
> populated platforms using omap_hsmmc (split out and posted) 3) v3 of the
> caps api w/ vinod's concerns address (working it not)
>
> Normally, I'm not going to bring up the cyclic transfer issue until I
> have some code to show or reference for discussion...but it's worth
> being aware. But, in any case, I'm confident that will gate having the
> mcasp driver that am33xx also uses converted to dmaengine. Except for
> the gpmc limitation you menationed, that's the last in kernel user of
> the privat edma api needed to be converted such that we can kill off
> arch/arm/common/edma.c once it's taken in.
And then there's the case of device-to-device DMA that we're not
currently doing luckily. And I don't think I've even seen that being
used so we probably don't need to worry about that one right now.
Regards,
Tony
^ permalink raw reply
* [PATCHv2 for soc 4/4] arm: socfpga: Add SMP support for actual socfpga harware
From: Dinh Nguyen @ 2013-02-02 21:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130202192409.GA17736@amd.pavel.ucw.cz>
Hi Pavel,
> -----Original Message-----
> From: ZY - pavel
> Sent: Saturday, February 02, 2013 1:24 PM
> To: Dinh Nguyen
> Cc: Russell King - ARM Linux; olof at lixom.net; linux-arm-
> kernel at lists.infradead.org; arnd at arndb.de
> Subject: Re: [PATCHv2 for soc 4/4] arm: socfpga: Add SMP support for
> actual socfpga harware
>
> Hi!
>
> > > > > I actually thought about that... but could not think of non-
> ugly way
> > > > > of doing that. I hope dts will normally be "right" for any
> production
> > > > > system...
> > > >
> > > > I think a panic is better just for the reason that if someone is
> > > > expecting SMP, but missed the warning message, and later finds
> out that
> > > > the secondary core never came up, it would save some debugging
> time.
> > > >
> > > > Since I have to send out a v3 from the 1st patch anyways, let me
> verify
> > > > that I can get the early warning.
> > >
> > > The choice is between a panic() at a point where the only way to
> find
> > > out is to throw in printascii() or a working printk, and ending up
> with
> > > an unbootable kernel, vs continuing the boot and having an almost
> > > working system which can be logged into and the messages viewed.
> > >
> > > If you have an application which relies on the second CPU coming
> up,
> > > why not have it verify that the second CPU came up (it's quite easy
> > > to do - there's POSIX standard libc calls to get the number of
> online
> > > CPUs).
> >
> > Point taken...thanks Russell.
>
> Well, I don't think we normally check dtbs for validity with
> user-helpful error messages, but it is relatively easy in this case.
>
> ---cut here---
>
> Continue booting with second core disabled if cpu1-start-addr is not
> present in .dtb.
>
> Signed-off-by: Pavel Machek <pavel@denx.de>
>
> diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-
> socfpga/platsmp.c
> index 81e0da0..90facdd 100644
> --- a/arch/arm/mach-socfpga/platsmp.c
> +++ b/arch/arm/mach-socfpga/platsmp.c
> @@ -82,6 +82,9 @@ static void __init socfpga_smp_init_cpus(void)
> ncores = 1;
> }
> #endif
> + if (!cpu1start_addr)
> + ncores = 1;
> +
This will not work because of commit 5587164eea4aad88fcb79d9b21dc8f14fea598cd
I sent out a V3 series of this patch, CPU1 will simply fail to come online if
cpu1-start-addr is not defined.
Dinh
> for (i = 0; i < ncores; i++)
> set_cpu_possible(i, true);
>
> diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-
> socfpga/socfpga.c
> index 334c330..c3cd88b 100644
> --- a/arch/arm/mach-socfpga/socfpga.c
> +++ b/arch/arm/mach-socfpga/socfpga.c
> @@ -74,10 +74,9 @@ static void __init socfpga_sysmgr_init(void)
>
> np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
>
> - if (of_property_read_u32(np, "cpu1-start-addr", (u32 *)
> &cpu1start_addr)) {
> - early_printk("Need cpu1-start-addr in device tree.\n");
> - panic("Need cpu1-start-addr in device tree.\n");
> - }
> + if (of_property_read_u32(np, "cpu1-start-addr", (u32 *)
> &cpu1start_addr))
> + printk(KERN_ALERT "Need cpu1-start-addr in device tree for
> SMP operation.\n");
> +
> sys_manager_base_addr = of_iomap(np, 0);
>
> np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
>
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures)
> http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Confidentiality Notice.
This message may contain information that is confidential or otherwise protected from disclosure. If you are not the intended recipient, you are hereby notified that any use, disclosure, dissemination, distribution, or copying of this message, or any attachments, is strictly prohibited. If you have received this message in error, please advise the sender by reply e-mail, and delete the message and any attachments. Thank you.
^ permalink raw reply
* [PATCH v3 00/22] PCI: Iterate pci host bridge instead of pci root bus
From: Bjorn Helgaas @ 2013-02-02 21:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359314629-18651-1-git-send-email-yinghai@kernel.org>
On Sun, Jan 27, 2013 at 12:23 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> Now we have pci_root_buses list, and there is lots of iteration with
> list_of_each of it, that is not safe after we add pci root bus hotplug
> support after booting stage.
>
> Add pci_get_next_host_bridge and use bus_find_device in driver core to
> iterate host bridge and the same time get root bus.
>
> We replace searching root bus with searching host_bridge,
> as host_bridge->bus is the root bus.
> After those replacing, we even could kill pci_root_buses list.
These are the problems I think you're fixing:
1) pci_find_next_bus() is not safe because even though it holds
pci_bus_sem while walking the pci_root_buses list, it doesn't hold a
reference on the bus it returns. The bus could be removed while the
caller is using it.
2) "list_for_each_entry(bus, &pci_root_buses, node)" is not safe
because hotplug might modify the pci_root_buses list. Replacing that
with for_each_pci_host_bridge() solves that problem by using
bus_find_device(), which is built on klists, which are designed for
that problem.
3) pci_find_next_bus() claims to iterate through all known PCI buses,
but in fact only iterates through root buses.
So far, so good. Those are problems we need to fix.
Your solution is to introduce for_each_pci_host_bridge() as an
iterator through the known host bridges. There are two scenarios
where we use something like this:
1) We want to perform an operation on every known host bridge.
2) We want to initialize something for every host bridge.
In my opinion, the only instance of scenario 1) is bus_rescan_store(),
where we want to rescan all PCI host bridges.
In every other case, we're doing some kind of initialization of all
the host bridges. For these cases, for_each_pci_host_bridge() is the
wrong solution because it doesn't work for hot-added bridges. I think
these cases should be changed to use pcibios_root_bridge_prepare() or
something something else called in the host bridge add path.
Bjorn
^ permalink raw reply
* [PATCH v3 13/15] ARM: CCI: ensure powerdown-time data is flushed from cache
From: Nicolas Pitre @ 2013-02-02 22:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <510B5CF7.5080902@ti.com>
On Fri, 1 Feb 2013, Santosh Shilimkar wrote:
> On Tuesday 29 January 2013 01:21 PM, Nicolas Pitre wrote:
> > From: Dave Martin <dave.martin@linaro.org>
> >
> > Non-local variables used by the CCI management function called after
> > disabling the cache must be flushed out to main memory in advance,
> > otherwise incoherency of those values may occur if they are sitting
> > in the cache of some other CPU when cci_disable() executes.
> >
> Any CPU calling cci_disable() would have already cleaned its local
> cache and the snoop unit should take care of syncing the shared data
> before hand from other CPU local caches for shared accesses.
> May be I am unable to visualize the issue here or missing some key
> point.
Let's suppose CPU0 initializes the CCI. Without this patch, the CCI
base address might be sitting in CPU0's cache.
The last CPU in a cluster to shut itself down is responsible for calling
cci_disable(). And being the last, it is also responsible for flushing
out its L1 and L2 caches before doing that. If CPU0 went down before
that, it did flush its L1 already. So the base address will be flushed
to RAM in that case.
But if it is a CPU in _another_ cluster which is shutting down and
becoming the last man _there_. It will flush its L1 and L2 cache
before calling cci_disable(). And
because the cache is disabled at that point, that CPU won't
send any snoop request across to the other cluster where CPU0 holds the
base address in its L1 or even L2 cache.
This is why we must push out that value out to RAM before cci_disable()
is used.
> > This patch adds the appropriate flushing to the CCI driver to ensure
> > that the relevant data is available in RAM ahead of time.
> >
> > Because this creates a dependency on arch-specific cacheflushing
> > functions, this patch also makes ARM_CCI depend on ARM.
> >
> You should do that otherwise to avoid other arch building this
> driver for random builds and breaking their builds.
Before this patch the driver was buildable on any architecture. That's
why this dependency is added only in this patch.
> > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > ---
> Patch is fine apart from the question.
>
> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>
Nicvolas
^ permalink raw reply
* [PATCH v2 1/2] ARM: kirkwood: Ensure that kirkwood_ge0[01]_init() finds its clock
From: Simon Baatz @ 2013-02-02 23:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130201001932.GA13044@obsidianresearch.com>
Hi Jason,
On Thu, Jan 31, 2013 at 05:19:32PM -0700, Jason Gunthorpe wrote:
> On Thu, Jan 31, 2013 at 07:01:09PM -0500, Jason Cooper wrote:
>
> > If you're interested, I still have a few ideas. One was to wire two USB
> > serial adapters end to end to create a different console
> > (console=/dev/ttyUSB0,115200, getty, etc). Since they would be going
> > over usb, that's a different clock, so it should work and provide us
> > with a safety net.
>
> I can't recall, can you still use JTAG once the CPU has hung on a mbus
> access?
>
> If so memory dumping the console ring, or cpu registers would get the
> answer pretty directly..
>
> My guesses would be the RTC and/or GPIO blocks (the GPIO blinker needs
> a clock), based on table 94.
These guesses seem to be dead on:
Moved the RTC module and GPIO modules (keys, leds) out of the way, to
see whether they cause the boot with disabled runit to lock up.
System boots now and SSH login is possible!
# mount -t debugfs debugfs /sys/kernel/debug
# cat /sys/kernel/debug/clk/tclk/runit/clk_enable_count
0
# insmod ./gpio_keys.ko
System locks up.
and, after a reboot:
# insmod ./rtc-mv.ko
System locks up.
Bingo!
- Simon
^ permalink raw reply
* [PATCH v2 2/2] ARM: kirkwood: fix to retain gbe MAC addresses for DT kernels
From: Simon Baatz @ 2013-02-02 23:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359577799-23351-1-git-send-email-sebastian.hesselbarth@gmail.com>
Hi Sebastian, Jason,
On Wed, Jan 30, 2013 at 09:29:58PM +0100, Sebastian Hesselbarth wrote:
> The ethernet controller used on kirkwood looses its MAC address
> register contents when the corresponding clock is gated. As soon as
> mv643xx_eth is built as module, the clock gets gated and when loading
> the module, the MAC address is gone.
>
> Proper DT support for the mv643xx_eth driver is expected soon, so we add
> a workaround to always enable ge0/ge1 clocks on kirkwood. This workaround
> is also already used on non-DT kirkwood kernels.
>
> Reported-by: Simon Baatz <gmbnomis@gmail.com>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Tested this on IB-NAS6210 (kirkwood, single GBE interface). Using
mv643xx_eth as a module works again now and yields
# cat /sys/kernel/debug/clk/tclk/ge[01]/clk_enable_count
2
1
as expected.
- Simon
^ permalink raw reply
* [PATCH] ARM: OMAP2+: mux: correct wrong error messages
From: Ruslan Bilovol @ 2013-02-03 0:15 UTC (permalink / raw)
To: linux-arm-kernel
This is needed because the omap_mux_get_by_name()
function calls the _omap_mux_get_by_name subfunction
for each mux partition until needed mux is not found.
As a result, we get messages like
"Could not find signal XXX" for each partition
where this mux name does not exist.
This patch fixes wrong error message in
the _omap_mux_get_by_name() function moving it
to the omap_mux_get_by_name() one and as result
reduces noise in the kernel log.
My kernel log without this patch:
[...]
[ 0.221801] omap_mux_init: Add partition: #2: wkup, flags: 3
[ 0.222045] _omap_mux_get_by_name: Could not find signal fref_clk0_out.sys_drm_msecure
[ 0.222137] _omap_mux_get_by_name: Could not find signal sys_nirq
[ 0.222167] _omap_mux_get_by_name: Could not find signal sys_nirq
[ 0.225006] _omap_mux_get_by_name: Could not find signal uart1_rx.uart1_rx
[ 0.225006] _omap_mux_get_by_name: Could not find signal uart1_rx.uart1_rx
[ 0.270111] _omap_mux_get_by_name: Could not find signal fref_clk4_out.fref_clk4_out
[ 0.273406] twl: not initialized
[...]
My kernel log with this patch:
[...]
[ 0.221771] omap_mux_init: Add partition: #2: wkup, flags: 3
[ 0.222106] omap_mux_get_by_name: Could not find signal sys_nirq
[ 0.224945] omap_mux_get_by_name: Could not find signal uart1_rx.uart1_rx
[ 0.274536] twl: not initialized
[...]
Signed-off-by: Ruslan Bilovol <ruslan.bilovol@ti.com>
---
arch/arm/mach-omap2/mux.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 6a217c9..9578ec0 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -211,8 +211,6 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
return -EINVAL;
}
- pr_err("%s: Could not find signal %s\n", __func__, muxname);
-
return -ENODEV;
}
@@ -234,6 +232,8 @@ int __init omap_mux_get_by_name(const char *muxname,
return mux_mode;
}
+ pr_err("%s: Could not find signal %s\n", __func__, muxname);
+
return -ENODEV;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/2] arm: pxa: tosa: do not use gpiochip_reserve()
From: Haojian Zhuang @ 2013-02-03 0:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1359816246-3979-2-git-send-email-acourbot@nvidia.com>
On Sat, Feb 2, 2013 at 10:44 PM, Alexandre Courbot <acourbot@nvidia.com> wrote:
> GPIO address space reservation during early platform initialization is
> not needed anymore for Tosa. Remove the calls to gpiochip_reserve()
> which is due to be removed.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> arch/arm/mach-pxa/tosa.c | 6 ------
> 1 file changed, 6 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
> index 9e7998d..3d91d2e 100644
> --- a/arch/arm/mach-pxa/tosa.c
> +++ b/arch/arm/mach-pxa/tosa.c
> @@ -927,8 +927,6 @@ static void tosa_restart(char mode, const char *cmd)
>
> static void __init tosa_init(void)
> {
> - int dummy;
> -
> pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config));
>
> pxa_set_ffuart_info(NULL);
> @@ -947,10 +945,6 @@ static void __init tosa_init(void)
> /* enable batt_fault */
> PMCR = 0x01;
>
> - dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12);
> - dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12);
> - dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
> -
> pxa_set_mci_info(&tosa_mci_platform_data);
> pxa_set_ficp_info(&tosa_ficp_platform_data);
> pxa_set_i2c_info(NULL);
> --
> 1.8.1.1
>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Linus,
Could you help to merge this patch into your gpio git tree? I think
that both of them should go through one git tree.
Regards
Haojian
^ permalink raw reply
* [PATCH] ab8500: btemp: demote initcall sequence
From: Anton Vorontsov @ 2013-02-03 3:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1358915205-7786-1-git-send-email-rajanikanth.hv@stericsson.com>
On Wed, Jan 23, 2013 at 09:56:45AM +0530, Rajanikanth H.V wrote:
> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
>
> Power supply subsystem creates thermal zone device for
> the property 'POWER_SUPPLY_PROP_TEMP' which requires
> thermal subsystem to be ready before 'ab8500 battery temperature monitor'
> driver is initialized.
> ab8500 btemp driver is initialized with subsys_initcall whereas thermal
> subsystem is initialized with fs_initcall which causes
> thermal_zone_device_register(...) to crash since the required structure
> 'thermal_class' is not initialized yet.
>
> crash log:
[...]
> Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
> ---
Applied and added Cc: stable.
Thanks!
^ permalink raw reply
* [GIT PULL] power: ab8500-bm: Latest Mainline<->STE delta reduction patch-set
From: Anton Vorontsov @ 2013-02-03 3:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130131120833.GH5301@gmail.com>
On Thu, Jan 31, 2013 at 12:08:33PM +0000, Lee Jones wrote:
> > Okay, after Linus Walleij's diligent observaions, I have removed all
> > new functionallity related to Deep Debug and will continue to
> > investigate what I need to do in that regard.
> >
> > In the mean-time, here's the fresh deep-debug:less pull-request:
> >
> > ----------------------------------------------------------------
> >
> > The following changes since commit 8fd526fd18233887ba652079a369f4eee0de9d9d:
> >
> > qnap-poweroff: Fix license string (2013-01-19 18:04:04 -0800)
> >
> > are available in the git repository at:
> >
> > git://git.linaro.org/people/ljones/linux-3.0-ux500.git tb-power-2
> >
> > for you to fetch changes up to 34c11a709e928090cf34ecd706f7d3170f4e5026:
> >
> > u8500-charger: Delay for USB enumeration (2013-01-23 14:39:22 +0000)
>
> Did you pull this in the end?
I was buried under my homework, sorry. :-) The changes look good, thanks a
lot! Pulled now.
Anton
^ 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