Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND 2/2] gpio: axp209: add pinctrl support
From: Quentin Schulz @ 2016-11-23 14:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161123141151.25315-1-quentin.schulz@free-electrons.com>

The GPIOs present in the AXP209 PMIC have multiple functions. They
typically allow a pin to be used as GPIO input or output and can also be
used as ADC or regulator for example.[1]

This adds the possibility to use all functions of the GPIOs present in
the AXP209 PMIC thanks to pinctrl subsystem.

[1] see registers 90H, 92H and 93H at
    http://dl.linux-sunxi.org/AXP/AXP209_Datasheet_v1.0en.pdf

Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
---
 .../devicetree/bindings/gpio/gpio-axp209.txt       |  28 +-
 drivers/gpio/gpio-axp209.c                         | 551 ++++++++++++++++++---
 2 files changed, 503 insertions(+), 76 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
index a661130..a5bfe87 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-axp209.txt
@@ -1,4 +1,4 @@
-AXP209 GPIO controller
+AXP209 GPIO & pinctrl controller
 
 This driver follows the usual GPIO bindings found in
 Documentation/devicetree/bindings/gpio/gpio.txt
@@ -28,3 +28,29 @@ axp209: pmic at 34 {
 		#gpio-cells = <2>;
 	};
 };
+
+The GPIOs can be muxed to other functions and therefore, must be a subnode of
+axp_gpio.
+
+Example:
+
+&axp_gpio {
+	gpio0_adc: gpio0_adc {
+		pin = "GPIO0";
+		function = "adc";
+	};
+};
+
+&example_node {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gpio0_adc>;
+};
+
+GPIOs and their functions
+-------------------------
+
+GPIO	|	Functions
+------------------------
+GPIO0	|	gpio_in, gpio_out, ldo, adc
+GPIO1	|	gpio_in, gpio_out, ldo, adc
+GPIO2	|	gpio_in, gpio_out
diff --git a/drivers/gpio/gpio-axp209.c b/drivers/gpio/gpio-axp209.c
index 4a346b7..0a64cfc 100644
--- a/drivers/gpio/gpio-axp209.c
+++ b/drivers/gpio/gpio-axp209.c
@@ -1,7 +1,8 @@
 /*
- * AXP20x GPIO driver
+ * AXP20x Pin control driver
  *
  * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
+ * Copyright (C) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under  the terms of the GNU General  Public License as published by the
@@ -21,52 +22,103 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf-generic.h>
 
 #define AXP20X_GPIO_FUNCTIONS		0x7
 #define AXP20X_GPIO_FUNCTION_OUT_LOW	0
 #define AXP20X_GPIO_FUNCTION_OUT_HIGH	1
 #define AXP20X_GPIO_FUNCTION_INPUT	2
 
-struct axp20x_gpio {
-	struct gpio_chip	chip;
-	struct regmap		*regmap;
-};
+#define AXP20X_PINCTRL_PIN(_pin_num, _pin, _regs)		\
+	{							\
+		.number = _pin_num,				\
+		.name = _pin,					\
+		.drv_data = _regs,				\
+	}
 
-static int axp20x_gpio_get_reg(unsigned offset)
-{
-	switch (offset) {
-	case 0:
-		return AXP20X_GPIO0_CTRL;
-	case 1:
-		return AXP20X_GPIO1_CTRL;
-	case 2:
-		return AXP20X_GPIO2_CTRL;
+#define AXP20X_PIN(_pin, ...)					\
+	{							\
+		.pin = _pin,					\
+		.functions = (struct axp20x_desc_function[]) {	\
+			      __VA_ARGS__, { } },		\
 	}
 
-	return -EINVAL;
-}
+#define AXP20X_FUNCTION(_val, _name)				\
+	{							\
+		.name = _name,					\
+		.muxval = _val,					\
+	}
 
-static int axp20x_gpio_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct axp20x_gpio *gpio = gpiochip_get_data(chip);
-	int reg;
+struct axp20x_desc_function {
+	const char	*name;
+	u8		muxval;
+};
 
-	reg = axp20x_gpio_get_reg(offset);
-	if (reg < 0)
-		return reg;
+struct axp20x_desc_pin {
+	struct pinctrl_pin_desc		pin;
+	struct axp20x_desc_function	*functions;
+};
 
-	return regmap_update_bits(gpio->regmap, reg,
-				  AXP20X_GPIO_FUNCTIONS,
-				  AXP20X_GPIO_FUNCTION_INPUT);
-}
+struct axp20x_pinctrl_desc {
+	const struct axp20x_desc_pin	*pins;
+	int				npins;
+	unsigned int			pin_base;
+};
+
+struct axp20x_pinctrl_function {
+	const char	*name;
+	const char	**groups;
+	unsigned int	ngroups;
+};
+
+struct axp20x_pinctrl_group {
+	const char	*name;
+	unsigned long	config;
+	unsigned int	pin;
+};
+
+struct axp20x_pctl {
+	struct pinctrl_dev			*pctl_dev;
+	struct device				*dev;
+	struct gpio_chip			chip;
+	struct regmap				*regmap;
+	const struct axp20x_pinctrl_desc	*desc;
+	struct axp20x_pinctrl_group		*groups;
+	unsigned int				ngroups;
+	struct axp20x_pinctrl_function		*functions;
+	unsigned int				nfunctions;
+};
+
+static const struct axp20x_desc_pin axp209_pins[] = {
+	AXP20X_PIN(AXP20X_PINCTRL_PIN(0, "GPIO0", (void *)AXP20X_GPIO0_CTRL),
+		   AXP20X_FUNCTION(0x0, "gpio_out"),
+		   AXP20X_FUNCTION(0x2, "gpio_in"),
+		   AXP20X_FUNCTION(0x3, "ldo"),
+		   AXP20X_FUNCTION(0x4, "adc")),
+	AXP20X_PIN(AXP20X_PINCTRL_PIN(1, "GPIO1", (void *)AXP20X_GPIO1_CTRL),
+		   AXP20X_FUNCTION(0x0, "gpio_out"),
+		   AXP20X_FUNCTION(0x2, "gpio_in"),
+		   AXP20X_FUNCTION(0x3, "ldo"),
+		   AXP20X_FUNCTION(0x4, "adc")),
+	AXP20X_PIN(AXP20X_PINCTRL_PIN(2, "GPIO2", (void *)AXP20X_GPIO2_CTRL),
+		   AXP20X_FUNCTION(0x0, "gpio_out"),
+		   AXP20X_FUNCTION(0x2, "gpio_in")),
+};
+
+static const struct axp20x_pinctrl_desc axp20x_pinctrl_data = {
+	.pins	= axp209_pins,
+	.npins	= ARRAY_SIZE(axp209_pins),
+};
 
 static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	struct axp20x_gpio *gpio = gpiochip_get_data(chip);
+	struct axp20x_pctl *pctl = gpiochip_get_data(chip);
 	unsigned int val;
 	int ret;
 
-	ret = regmap_read(gpio->regmap, AXP20X_GPIO20_SS, &val);
+	ret = regmap_read(pctl->regmap, AXP20X_GPIO20_SS, &val);
 	if (ret)
 		return ret;
 
@@ -75,15 +127,12 @@ static int axp20x_gpio_get(struct gpio_chip *chip, unsigned offset)
 
 static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
 {
-	struct axp20x_gpio *gpio = gpiochip_get_data(chip);
+	struct axp20x_pctl *pctl = gpiochip_get_data(chip);
+	int pin_reg = (int)pctl->desc->pins[offset].pin.drv_data;
 	unsigned int val;
-	int reg, ret;
-
-	reg = axp20x_gpio_get_reg(offset);
-	if (reg < 0)
-		return reg;
+	int ret;
 
-	ret = regmap_read(gpio->regmap, reg, &val);
+	ret = regmap_read(pctl->regmap, pin_reg, &val);
 	if (ret)
 		return ret;
 
@@ -102,33 +151,335 @@ static int axp20x_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
 	return val & 2;
 }
 
-static int axp20x_gpio_output(struct gpio_chip *chip, unsigned offset,
+static void axp20x_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			    int value)
+{
+	struct axp20x_pctl *pctl = gpiochip_get_data(chip);
+	int pin_reg = (int)pctl->desc->pins[offset].pin.drv_data;
+
+	regmap_update_bits(pctl->regmap, pin_reg,
+			   AXP20X_GPIO_FUNCTIONS,
+			   value ? AXP20X_GPIO_FUNCTION_OUT_HIGH
+				 : AXP20X_GPIO_FUNCTION_OUT_LOW);
+}
+
+static int axp20x_gpio_input(struct gpio_chip *chip, unsigned int offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int axp20x_gpio_output(struct gpio_chip *chip, unsigned int offset,
 			      int value)
 {
-	struct axp20x_gpio *gpio = gpiochip_get_data(chip);
-	int reg;
+	chip->set(chip, offset, value);
 
-	reg = axp20x_gpio_get_reg(offset);
-	if (reg < 0)
-		return reg;
+	return 0;
+}
 
-	return regmap_update_bits(gpio->regmap, reg,
-				  AXP20X_GPIO_FUNCTIONS,
-				  value ? AXP20X_GPIO_FUNCTION_OUT_HIGH
-				  : AXP20X_GPIO_FUNCTION_OUT_LOW);
+static int axp20x_pmx_set(struct pinctrl_dev *pctldev, unsigned int offset,
+			  u8 config)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	int pin_reg = (int)pctl->desc->pins[offset].pin.drv_data;
+
+	return regmap_update_bits(pctl->regmap, pin_reg, AXP20X_GPIO_FUNCTIONS,
+				  config);
 }
 
-static void axp20x_gpio_set(struct gpio_chip *chip, unsigned offset,
-			    int value)
+static int axp20x_pmx_func_cnt(struct pinctrl_dev *pctldev)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->nfunctions;
+}
+
+static const char *axp20x_pmx_func_name(struct pinctrl_dev *pctldev,
+					unsigned int selector)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->functions[selector].name;
+}
+
+static int axp20x_pmx_func_groups(struct pinctrl_dev *pctldev,
+				  unsigned int selector,
+				  const char * const **groups,
+				  unsigned int *num_groups)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = pctl->functions[selector].groups;
+	*num_groups = pctl->functions[selector].ngroups;
+
+	return 0;
+}
+
+static struct axp20x_desc_function *
+axp20x_pinctrl_desc_find_func_by_name(struct axp20x_pctl *pctl,
+				      const char *group, const char *func)
+{
+	const struct axp20x_desc_pin *pin;
+	struct axp20x_desc_function *desc_func;
+	int i;
+
+	for (i = 0; i < pctl->desc->npins; i++) {
+		pin = &pctl->desc->pins[i];
+
+		if (!strcmp(pin->pin.name, group)) {
+			desc_func = pin->functions;
+
+			while (desc_func->name) {
+				if (!strcmp(desc_func->name, func))
+					return desc_func;
+				desc_func++;
+			}
+
+			/*
+			 * Pins are uniquely named. Groups are named after one
+			 * pin name. If one pin matches group name but its
+			 * function cannot be found, no other pin will match
+			 * group name.
+			 */
+			return NULL;
+		}
+	}
+
+	return NULL;
+}
+
+static int axp20x_pmx_set_mux(struct pinctrl_dev *pctldev,
+			      unsigned int function, unsigned int group)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct axp20x_pinctrl_group *g = pctl->groups + group;
+	struct axp20x_pinctrl_function *func = pctl->functions + function;
+	struct axp20x_desc_function *desc_func =
+		axp20x_pinctrl_desc_find_func_by_name(pctl, g->name,
+						      func->name);
+	if (!desc_func)
+		return -EINVAL;
+
+	return axp20x_pmx_set(pctldev, g->pin, desc_func->muxval);
+}
+
+static struct axp20x_desc_function *
+axp20x_pctl_desc_find_func_by_pin(struct axp20x_pctl *pctl, unsigned int offset,
+				  const char *func)
+{
+	const struct axp20x_desc_pin *pin;
+	struct axp20x_desc_function *desc_func;
+	int i;
+
+	for (i = 0; i < pctl->desc->npins; i++) {
+		pin = &pctl->desc->pins[i];
+
+		if (pin->pin.number == offset) {
+			desc_func = pin->functions;
+
+			while (desc_func->name) {
+				if (!strcmp(desc_func->name, func))
+					return desc_func;
+
+				desc_func++;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static int axp20x_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+					 struct pinctrl_gpio_range *range,
+					 unsigned int offset, bool input)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct axp20x_desc_function *desc_func;
+	const char *func;
+
+	if (input)
+		func = "gpio_in";
+	else
+		func = "gpio_out";
+
+	desc_func = axp20x_pctl_desc_find_func_by_pin(pctl, offset, func);
+	if (!desc_func)
+		return -EINVAL;
+
+	return axp20x_pmx_set(pctldev, offset, desc_func->muxval);
+}
+
+static const struct pinmux_ops axp20x_pmx_ops = {
+	.get_functions_count	= axp20x_pmx_func_cnt,
+	.get_function_name	= axp20x_pmx_func_name,
+	.get_function_groups	= axp20x_pmx_func_groups,
+	.set_mux		= axp20x_pmx_set_mux,
+	.gpio_set_direction	= axp20x_pmx_gpio_set_direction,
+	.strict			= true,
+};
+
+static int axp20x_groups_cnt(struct pinctrl_dev *pctldev)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->ngroups;
+}
+
+static int axp20x_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
+			     const unsigned int **pins, unsigned int *num_pins)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct axp20x_pinctrl_group *g = pctl->groups + selector;
+
+	*pins = (unsigned int *)&g->pin;
+	*num_pins = 1;
+
+	return 0;
+}
+
+static const char *axp20x_group_name(struct pinctrl_dev *pctldev,
+				     unsigned int selector)
+{
+	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->groups[selector].name;
+}
+
+static const struct pinctrl_ops axp20x_pctrl_ops = {
+	.dt_node_to_map		= pinconf_generic_dt_node_to_map_group,
+	.dt_free_map		= pinconf_generic_dt_free_map,
+	.get_groups_count	= axp20x_groups_cnt,
+	.get_group_name		= axp20x_group_name,
+	.get_group_pins		= axp20x_group_pins,
+};
+
+static struct axp20x_pinctrl_function *
+axp20x_pinctrl_function_by_name(struct axp20x_pctl *pctl, const char *name)
+{
+	struct axp20x_pinctrl_function *func = pctl->functions;
+
+	while (func->name) {
+		if (!strcmp(func->name, name))
+			return func;
+		func++;
+	}
+
+	return NULL;
+}
+
+static int axp20x_pinctrl_add_function(struct axp20x_pctl *pctl,
+				       const char *name)
 {
-	axp20x_gpio_output(chip, offset, value);
+	struct axp20x_pinctrl_function *func = pctl->functions;
+
+	while (func->name) {
+		if (!strcmp(func->name, name)) {
+			func->ngroups++;
+			return -EEXIST;
+		}
+
+		func++;
+	}
+
+	func->name = name;
+	func->ngroups = 1;
+
+	pctl->nfunctions++;
+
+	return 0;
 }
 
-static int axp20x_gpio_probe(struct platform_device *pdev)
+static int axp20x_attach_group_function(struct platform_device *pdev,
+					const struct axp20x_desc_pin *pin)
+{
+	struct axp20x_pctl *pctl = platform_get_drvdata(pdev);
+	struct axp20x_desc_function *desc_func = pin->functions;
+	struct axp20x_pinctrl_function *func;
+	const char **func_grp;
+
+	while (desc_func->name) {
+		func = axp20x_pinctrl_function_by_name(pctl, desc_func->name);
+		if (!func)
+			return -EINVAL;
+
+		if (!func->groups) {
+			func->groups = devm_kzalloc(&pdev->dev,
+						    func->ngroups * sizeof(const char *),
+						    GFP_KERNEL);
+			if (!func->groups)
+				return -ENOMEM;
+		}
+
+		func_grp = func->groups;
+		while (*func_grp)
+			func_grp++;
+
+		*func_grp = pin->pin.name;
+		desc_func++;
+	}
+
+	return 0;
+}
+
+static int axp20x_build_state(struct platform_device *pdev)
+{
+	struct axp20x_pctl *pctl = platform_get_drvdata(pdev);
+	unsigned int npins = pctl->desc->npins;
+	const struct axp20x_desc_pin *pin;
+	struct axp20x_desc_function *func;
+	int i, ret;
+
+	pctl->ngroups = npins;
+	pctl->groups = devm_kzalloc(&pdev->dev,
+				    pctl->ngroups * sizeof(*pctl->groups),
+				    GFP_KERNEL);
+	if (!pctl->groups)
+		return -ENOMEM;
+
+	for (i = 0; i < npins; i++) {
+		pctl->groups[i].name = pctl->desc->pins[i].pin.name;
+		pctl->groups[i].pin = pctl->desc->pins[i].pin.number;
+	}
+
+	/* We assume 4 functions per pin should be enough as a default max */
+	pctl->functions = devm_kzalloc(&pdev->dev,
+				       npins * 4 * sizeof(*pctl->functions),
+				       GFP_KERNEL);
+	if (!pctl->functions)
+		return -ENOMEM;
+
+	/* Create a list of uniquely named functions */
+	for (i = 0; i < npins; i++) {
+		pin = &pctl->desc->pins[i];
+		func = pin->functions;
+
+		while (func->name) {
+			axp20x_pinctrl_add_function(pctl, func->name);
+			func++;
+		}
+	}
+
+	pctl->functions = krealloc(pctl->functions,
+				   pctl->nfunctions * sizeof(*pctl->functions),
+				   GFP_KERNEL);
+
+	for (i = 0; i < npins; i++) {
+		pin = &pctl->desc->pins[i];
+		ret = axp20x_attach_group_function(pdev, pin);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int axp20x_pctl_probe(struct platform_device *pdev)
 {
 	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
-	struct axp20x_gpio *gpio;
-	int ret;
+	const struct axp20x_desc_pin *pin;
+	struct axp20x_pctl *pctl;
+	struct pinctrl_desc *pctrl_desc;
+	struct pinctrl_pin_desc *pins;
+	int ret, i;
 
 	if (!of_device_is_available(pdev->dev.of_node))
 		return -ENODEV;
@@ -138,51 +489,101 @@ static int axp20x_gpio_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
-	if (!gpio)
+	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
+	if (!pctl)
+		return -ENOMEM;
+
+	pctl->chip.base			= -1;
+	pctl->chip.can_sleep		= true;
+	pctl->chip.request		= gpiochip_generic_request;
+	pctl->chip.free			= gpiochip_generic_free;
+	pctl->chip.parent		= &pdev->dev;
+	pctl->chip.label		= dev_name(&pdev->dev);
+	pctl->chip.owner		= THIS_MODULE;
+	pctl->chip.get			= axp20x_gpio_get;
+	pctl->chip.get_direction	= axp20x_gpio_get_direction;
+	pctl->chip.set			= axp20x_gpio_set;
+	pctl->chip.direction_input	= axp20x_gpio_input;
+	pctl->chip.direction_output	= axp20x_gpio_output;
+	pctl->chip.ngpio		= 3;
+	pctl->chip.can_sleep		= true;
+
+	pctl->regmap = axp20x->regmap;
+
+	pctl->desc = &axp20x_pinctrl_data;
+	pctl->dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, pctl);
+
+	ret = axp20x_build_state(pdev);
+	if (ret)
+		return ret;
+
+	pins = devm_kzalloc(&pdev->dev, pctl->desc->npins * sizeof(*pins),
+			    GFP_KERNEL);
+	if (!pins)
 		return -ENOMEM;
 
-	gpio->chip.base			= -1;
-	gpio->chip.can_sleep		= true;
-	gpio->chip.parent		= &pdev->dev;
-	gpio->chip.label		= dev_name(&pdev->dev);
-	gpio->chip.owner		= THIS_MODULE;
-	gpio->chip.get			= axp20x_gpio_get;
-	gpio->chip.get_direction	= axp20x_gpio_get_direction;
-	gpio->chip.set			= axp20x_gpio_set;
-	gpio->chip.direction_input	= axp20x_gpio_input;
-	gpio->chip.direction_output	= axp20x_gpio_output;
-	gpio->chip.ngpio		= 3;
-
-	gpio->regmap = axp20x->regmap;
-
-	ret = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
+	for (i = 0; i < pctl->desc->npins; i++)
+		pins[i] = pctl->desc->pins[i].pin;
+
+	pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctrl_desc), GFP_KERNEL);
+	if (!pctrl_desc)
+		return -ENOMEM;
+
+	pctrl_desc->name = dev_name(&pdev->dev);
+	pctrl_desc->owner = THIS_MODULE;
+	pctrl_desc->pins = pins;
+	pctrl_desc->npins = pctl->desc->npins;
+	pctrl_desc->pctlops = &axp20x_pctrl_ops;
+	pctrl_desc->pmxops = &axp20x_pmx_ops;
+
+	pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl);
+	if (IS_ERR(pctl->pctl_dev)) {
+		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
+		return PTR_ERR(pctl->pctl_dev);
+	}
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &pctl->chip, pctl);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register GPIO chip\n");
 		return ret;
 	}
 
+	for (i = 0; i < pctl->desc->npins; i++) {
+		pin = pctl->desc->pins + i;
+
+		ret = gpiochip_add_pin_range(&pctl->chip, dev_name(&pdev->dev),
+					     pin->pin.number, pin->pin.number,
+					     1);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to add pin range\n");
+			return ret;
+		}
+	}
+
 	dev_info(&pdev->dev, "AXP209 GPIO driver loaded\n");
 
 	return 0;
 }
 
-static const struct of_device_id axp20x_gpio_match[] = {
+static const struct of_device_id axp20x_pctl_match[] = {
 	{ .compatible = "x-powers,axp209-gpio" },
 	{ }
 };
-MODULE_DEVICE_TABLE(of, axp20x_gpio_match);
+MODULE_DEVICE_TABLE(of, axp20x_pctl_match);
 
-static struct platform_driver axp20x_gpio_driver = {
-	.probe		= axp20x_gpio_probe,
+static struct platform_driver axp20x_pctl_driver = {
+	.probe		= axp20x_pctl_probe,
 	.driver = {
 		.name		= "axp20x-gpio",
-		.of_match_table	= axp20x_gpio_match,
+		.of_match_table	= axp20x_pctl_match,
 	},
 };
 
-module_platform_driver(axp20x_gpio_driver);
+module_platform_driver(axp20x_pctl_driver);
 
 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
 MODULE_DESCRIPTION("AXP20x PMIC GPIO driver");
 MODULE_LICENSE("GPL");
-- 
2.9.3

^ permalink raw reply related

* [PATCH 1/2] i2c: designware: report short transfers
From: Jarkko Nikula @ 2016-11-23 14:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161121103200.GG1446@lahna.fi.intel.com>

On 21.11.2016 12:32, Mika Westerberg wrote:
> On Fri, Nov 18, 2016 at 07:40:04PM +0000, Russell King wrote:
>> Rather than reporting success for a short transfer due to interrupt
>> latency, report an error both to the caller, as well as to the kernel
>> log.
>>
>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>

^ permalink raw reply

* [PATCH 2/2] i2c: designware: fix rx fifo depth tracking
From: Jarkko Nikula @ 2016-11-23 14:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161121104032.GH1446@lahna.fi.intel.com>

On 21.11.2016 12:40, Mika Westerberg wrote:
> On Fri, Nov 18, 2016 at 07:40:10PM +0000, Russell King wrote:
>> When loading the TX fifo to receive bytes on the I2C bus, we incorrectly
>> count the number of bytes:
>>
>> 	rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR);
>>
>> 	while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) {
>> 		if (rx_limit - dev->rx_outstanding <= 0)
>> 			break;
>> 		rx_limit--;
>> 		dev->rx_outstanding++;
>> 	}
>>
>> DW_IC_RXFLR indicates how many bytes are available to be read in the
>> FIFO, dev->rx_fifo_depth is the FIFO size, and dev->rx_outstanding is
>> the number of bytes that we've requested to be read so far, but which
>> have not been read.
>>
>> Firstly, increasing dev->rx_outstanding and decreasing rx_limit and then
>> comparing them results in each byte consuming "two" bytes in this
>> tracking, so this is obviously wrong.
>>
>> Secondly, the number of bytes that _could_ be received into the FIFO at
>> any time is the number of bytes we have so far requested but not yet
>> read from the FIFO - in other words dev->rx_outstanding.
>>
>> So, in order to request enough bytes to fill the RX FIFO, we need to
>> request dev->rx_fifo_depth - dev->rx_outstanding bytes.
>>
>> Modifying the code thusly results in us reaching the maximum number of
>> bytes outstanding each time we queue more "receive" operations, provided
>> the transfer allows that to happen.
>>
>> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
>
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>

^ permalink raw reply

* [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06
From: Arnd Bergmann @ 2016-11-23 14:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E1F921A0F@lhreml507-mbx>

On Friday, November 18, 2016 5:03:11 PM CET Gabriele Paoloni wrote:
> > On Friday, November 18, 2016 4:18:07 PM CET Gabriele Paoloni wrote:
> > > From: Arnd Bergmann [mailto:arnd at arndb.de]
> > > > On Friday, November 18, 2016 12:53:08 PM CET Gabriele Paoloni
> > wrote:
> > > > For the ISA/LPC spaces there are only 4k of addresses, they
> > > > the bus addresses always overlap, but we can trivially
> > > > figure out the bus address from Linux I/O port number
> > > > by subtracting the start of the range.
> > >
> > > Are you saying that our LPC controller should specify a
> > > range property to map bus addresses into a cpu address range?
> > 
> > No. There is not CPU address associated with it, because it's
> > not memory mapped.
> > 
> > Instead, we need to associate a bus address with a logical
> > Linux port number, both in of_address_to_resource and
> > in inb()/outb().
> 
> I think this is effectively what we are doing so far with patch 2/3.
> The problem with this patch is that we are carving out a "forbidden"
> IO tokens range that goes from 0 to PCIBIOS_MIN_IO.
> 
> I think that the proper solution would be to have the LPC driver to
> set the carveout threshold used in pci_register_io_range(), 
> pci_pio_to_address(), pci_address_to_pio(), but this would impose
> a probe dependency on the LPC itself that should be probed before
> the PCI controller (or before any other devices calling these
> functions...)

Why do you think the order matters? My point was that we should
be able to register any region of logical port numbers for any
bus here.


> > > > > To be honest with you I would keep things simple for this
> > > > > LPC and introduce more complex reworks later if more devices
> > > > > need to be introduced.
> > > > >
> > > > > What if we stick on a single domain now where we introduce a
> > > > > reserved threshold for the IO space (say INDIRECT_MAX_IO).
> > > >
> > > > I said having a single domain is fine, but I still don't
> > > > like the idea of reserving low port numbers for this hack,
> > > > it would mean that the numbers change for everyone else.
> > >
> > > I don't get this much...I/O tokens that are passed to the I/O
> > > accessors are not fixed anyway and they vary depending on the order
> > > of adding ranges to io_range_list...so I don't see a big issue
> > > with this...
> > 
> > On machines with a legacy devices behind the PCI bridge,
> > there may still be a reason to have the low I/O port range
> > reserved for the primary bus, e.g. to get a VGA text console
> > to work.
> > 
> > On powerpc, this is called the "primary" PCI host, i.e. the
> > only one that is allowed to have an ISA bridge.
> 
> Yes but
> 1) isn't the PCI controller range property that defines how IO bus address
>    map into physical CPU addresses?

Correct, but the DT knows nothing about logical port numbers in Linux.

> 2) How can you guarantee that the cpu range associated with this
>    IO bus range is the first to be registered in pci_register_io_range()?
>    ( i.e. are you saying that they are just relying on the fact that it is the
>      only IO range in the system and by chance the IO tokens and corresponding
>      bus addresses are the same? )

To clarify: the special properties of having the first 0x1000 logical
port numbers go to a particular physical bus are very obscure. I think
it's more important to not change the behavior for existing systems
that might rely on it than for new systems that have no such legacy.

The ipmi and uart drivers in particular will get the port numbers filled
in their platform device from the DT bus scanning, so they don't care
at all about having the same numeric value for port numbers on the bus
and logical numbers, but other drivers might rely on particular ports
to be mapped on a specific PCI host, especially when those drivers
are  used only on systems that don't have more than one PCI domain.

	Arnd

^ permalink raw reply

* [GIT PULL] Second Round of Renesas ARM Based SoC DT Updates for v4.10
From: Simon Horman @ 2016-11-23 14:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161123095717.GA16339@verge.net.au>

On Wed, Nov 23, 2016 at 10:57:18AM +0100, Simon Horman wrote:
> On Mon, Nov 21, 2016 at 11:53:18AM +0100, Simon Horman wrote:
> > On Fri, Nov 18, 2016 at 05:49:29PM -0800, Olof Johansson wrote:
> > > On Thu, Nov 17, 2016 at 03:11:45PM +0100, Simon Horman wrote:
> > > > Hi Olof, Hi Kevin, Hi Arnd,
> > > > 
> > > > Please consider these second round of Renesas ARM based SoC DT updates for v4.10.
> > > > 
> > > > This pull request is based on a merge of:
> > > > 
> > > > * The previous round of such requests, tagged as renesas-dt-for-v4.10,
> > > >   which I have already sent a pull-request for.
> > > > * The rzg-clock-defs tag of Geert Uytterhoeven's renesas-driver's tree.
> > > >   This is to provide dependencies for adding the r8a7743 and r8a7745 SoCs.
> > > > * The "Second Round of Renesas ARM Based SoC Drivers Updates for v4.10",
> > > >   tagged as renesas-drivers2-for-v4.10, which I have also sent a pull
> > > >   request for. This is included to provide dependencies for adding device
> > > >   nodes for PRR, and adding the r8a7743 and r8a7745 SoCs.
> > > 
> > > Again, nack. And again, I don't understand why you create dependencies that
> > > aren't needed. Please fix.
> > 
> > Hi Olof,
> > 
> > I agree that calling out PRR above was incorrect. Please disregard that.
> > 
> > However, there are dependencies for adding r8a7743 and r8a7745 SoCs
> > in the form of header files:
> > 
> > * The rzg-clock-defs tag provides dt-bindings/clock/r8a774[35]-cpg-mssr.h
> > * The renesas-drivers2-for-v4.10 tag provides
> >   dt-bindings/power/r8a774[35]-sysc.h
> > 
> > The drivers branches are usually pretty light-weight. But this time it is a
> > bit heavy and you rightly raised some questions about it. After some
> > discussion with Geert we'd like to suggest that for future releases
> > we provide a "driver-defs" branch which both driver code and DT can
> > depend on. Thus avoiding pulling (non essential) driver changes into the DT
> > branch.
> > 
> > Unfortunately its a bit late to do that for v4.10 as the r8a7743 sysc
> > driver and its defines were already accepted accepted together
> > (renesas-drivers-for-v4.10 tag). So for this release we would be grateful
> > if you could re-consider the renesas-drivers2-for-v4.10 tag given the
> > feedback which Geert has provided. And in turn re-consider this pull
> > request.
> 
> Hi again,
> 
> while the above remains my preferred option I would like to put another one
> on the table in case it would help in any way for v4.10.
> 
> I could split this pull-request up as follows:
> 1. The patches that add the r8a774[35] SoCs:
>    - r8a7743 depends on renesas-drivers-for-v4.10 and rzg-clock-defs
>    - r8a7745 depends on renesas-drivers2-for-v4.10 and rzg-clock-defs
> 2. The patches rest of the patches
>    - I believe these have no special dependencies

After some discussion on IRC with Arnd I think it makes sense to simplify
the dependencies pulled in to this pull request to the extent of
only pulling in patches which provide headers for macros used in DT.

I am working on making this so.

^ permalink raw reply

* [PATCH 0/2] ARM: dts: r8a7743/r8a7745: Move RST nodes before SYSC nodes
From: Simon Horman @ 2016-11-23 14:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479464663-19054-1-git-send-email-geert+renesas@glider.be>

On Fri, Nov 18, 2016 at 11:24:21AM +0100, Geert Uytterhoeven wrote:
> 	Hi Simon, Magnus,
> 
> This patch series moves the RST nodes in the recently added RZ/G DTS
> files before the SYSC nodes, to preserve both alphabetical (label) and
> numerical ordering (unit address).
> 
> Thanks for applying!

Thanks, I have queued these up for v4.11.

^ permalink raw reply

* [PATCH] drm/sun4i: Only count TCON endpoints as valid outputs
From: Chen-Yu Tsai @ 2016-11-23 14:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161122153730.nj5fl34oleu2uylz@lukather>

On Tue, Nov 22, 2016 at 11:37 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Fri, Nov 18, 2016 at 10:22:40AM +0800, Chen-Yu Tsai wrote:
>> On Fri, Nov 18, 2016 at 3:02 AM, Maxime Ripard
>> <maxime.ripard@free-electrons.com> wrote:
>> > On Wed, Nov 16, 2016 at 05:37:31PM +0800, Chen-Yu Tsai wrote:
>> >> The sun4i DRM driver counts the number of endpoints it found and
>> >> registers the whole DRM pipeline if any endpoints are found.
>> >>
>> >> However, if the TCON and its child endpoints (LCD panels, TV encoder,
>> >> HDMI encoder, MIPI DSI encoder, etc.) aren't found, that means we
>> >> don't have any usable CRTCs, and the display pipeline is incomplete
>> >> and useless.
>> >
>> > If some node set as available is not probed, then yes, it does, but
>> > I'm not really sure how it's a problem. Quite the opposite actually.
>>
>> Actually the problem occurs when the TCON is _not_ available, but
>> the other endpoints preceding it are.
>
> By preceding, you mean the display engine or the HDMI or TV encoders?

The display engine.

>> >> The debug message "Queued %d outputs on pipeline %d\n" is also telling.
>> >>
>> >> This patch makes the driver only count enabled TCON endpoints. If
>> >> none are found, the DRM pipeline is not used. This avoids screwing
>> >> up the simple framebuffer provided by the bootloader in cases where
>> >> we aren't able to support the display with the DRM subsystem, due
>> >> to lack of panel or bridge drivers, or just lack of progress.
>> >
>> > The framebuffer is removed only at bind time, which means that all the
>> > drivers have probed already. Lack of progress isn't an issue here,
>> > since the node simply won't be there, and we wouldn't have it in the
>> > component lists. And lack of drivers shouldn't be an issue either,
>> > since in order for bind to be called, all the drivers would have
>> > gone through their probe.
>> >
>> > So I'm not really sure what it fixes.
>>
>> To recap, on sun6i I had enabled the display engine node by default
>> in the dtsi, along with the backend and drc. The tcon is disabled
>> by default, so it doesn't get added to the list of components.
>> The available components get probed, binded, and simplefb gets
>> pushed out.
>>
>> I suppose disabling the display engine by default would be better?
>> At least simplefb still works.
>
> Yep, that works for me.

OK. I'll send out a patch.

ChenYu

^ permalink raw reply

* [PATCH 0/2] ARM: dts: r8a7743/r8a7745: Add device nodes for PRR
From: Simon Horman @ 2016-11-23 14:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479465463-19572-1-git-send-email-geert+renesas@glider.be>

On Fri, Nov 18, 2016 at 11:37:41AM +0100, Geert Uytterhoeven wrote:
> 	Hi Simon, Magnus,
> 
> This patch series adds the device nodes for the Product Register to the
> recently added RZ/G DTS files, which allow to provide SoC product
> and revision information.
> 
> This depends on "[PATCH 0/2] ARM: dts: r8a7743/r8a7745: Move RST nodes
> before SYSC nodes".

Thanks, I have queued these up for v4.11.

^ permalink raw reply

* [PATCH] arm64: dts: r8a7796: Add all MSIOF nodes
From: Simon Horman @ 2016-11-23 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479749213-13744-1-git-send-email-geert+renesas@glider.be>

On Mon, Nov 21, 2016 at 06:26:53PM +0100, Geert Uytterhoeven wrote:
> Add the device nodes for all MSIOF SPI controllers.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> Tested with MSIOF2(B) on EXIO connector D of r8a7796/salvator-x, using
> spidev, gpio-74x164, and a logic analyzer.

Thanks, I have queued this up for v4.11.

^ permalink raw reply

* [PATCH 2/4] ARM: dts: exynos: specify snps, dwmac in compatible string for gmac
From: Niklas Cassel @ 2016-11-23 14:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Niklas Cassel <niklas.cassel@axis.com>

devicetree binding for stmmac states:
- compatible: Should be "snps,dwmac-<ip_version>", "snps,dwmac"
	For backwards compatibility: "st,spear600-gmac" is also supported.

No functional change intended.

Signed-off-by: Niklas Cassel <niklas.cassel@axis.com>
---
 arch/arm/boot/dts/exynos5440.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi
index 97c9f0e38526..2a2e570bbee6 100644
--- a/arch/arm/boot/dts/exynos5440.dtsi
+++ b/arch/arm/boot/dts/exynos5440.dtsi
@@ -197,7 +197,7 @@
 	};
 
 	gmac: ethernet at 00230000 {
-		compatible = "snps,dwmac-3.70a";
+		compatible = "snps,dwmac-3.70a", "snps,dwmac";
 		reg = <0x00230000 0x8000>;
 		interrupt-parent = <&gic>;
 		interrupts = <GIC_SPI 31 4>;
-- 
2.1.4

^ permalink raw reply related

* [PATCH 3/3] ARM: dts: sunxi: enable SDIO Wi-Fi on Orange Pi Zero
From: Chen-Yu Tsai @ 2016-11-23 14:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161123075950.fjtplylunwale6j4@lukather>

On Wed, Nov 23, 2016 at 3:59 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Tue, Nov 22, 2016 at 12:24:21AM +0800, Icenowy Zheng wrote:
>> There's a Allwinner's XR819 SDIO Wi-Fi module soldered on the board of
>> Orange Pi Zero, which used a dedicated regulator to power.
>>
>> Add the device tree node of the regulator, the enable gpio (with
>> mmc-pwrseq) and the sdio controller.
>>
>> There's a out-of-tree driver tested to work with this device tree.
>>
>> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
>> ---
>> New patch in the patchset, since a out-of-tree working xradio driver is done.
>>
>> If there is any problem in this patch, it can be omitted.
>
> No particular problem with this one, however it can and should be
> merged with the previous one.
>
> Minor comments below though.
>
>>
>>  arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts | 42 ++++++++++++++++++++++++
>>  1 file changed, 42 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>> index b428e47..39cac26 100644
>> --- a/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>> +++ b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>> @@ -79,6 +79,24 @@
>>                       gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>;
>>               };
>>       };
>> +
>> +     reg_vcc_wifi: reg_vcc_wifi {
>> +             compatible = "regulator-fixed";
>> +             pinctrl-names = "default";
>> +             pinctrl-0 = <&vcc_wifi_pin_opi0>;
>> +             regulator-min-microvolt = <3300000>;
>> +             regulator-max-microvolt = <3300000>;
>> +             regulator-name = "vcc-wifi";
>> +             enable-active-high;
>> +             gpio = <&pio 0 20 GPIO_ACTIVE_HIGH>;
>> +     };
>> +
>> +     wifi_pwrseq: wifi_pwrseq {
>> +             compatible = "mmc-pwrseq-simple";
>> +             pinctrl-names = "default";
>> +             pinctrl-0 = <&wifi_pwrseq_pin_opi0>;
>> +             reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>;
>> +     };
>>  };
>>
>>  &ehci1 {
>> @@ -95,6 +113,20 @@
>>       status = "okay";
>>  };
>>
>> +&mmc1 {
>> +     pinctrl-names = "default";
>> +     pinctrl-0 = <&mmc1_pins_a>;
>> +     vmmc-supply = <&reg_vcc_wifi>;
>> +     mmc-pwrseq = <&wifi_pwrseq>;
>> +     bus-width = <4>;
>> +     non-removable;
>> +     status = "okay";
>> +};
>> +
>> +&mmc1_pins_a {
>> +     allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
>
> This should be bias-pull-up.

IIRC I already added this for _all_ existing mmc pinmux settings?

>
>> +};
>> +
>>  &ohci1 {
>>       status = "okay";
>>  };
>> @@ -104,6 +136,11 @@
>>               pins = "PA17";
>>               function = "gpio_out";
>>       };
>> +
>> +     vcc_wifi_pin_opi0: vcc_wifi_pin at 0 {
>> +             allwinner,pins = "PA20";
>
> This should be pins
>
>> +             allwinner,function = "gpio_out";
>
> This should be function
>
>> +     };
>>  };
>>
>>  &r_pio {
>> @@ -111,6 +148,11 @@
>>               pins = "PL10";
>>               function = "gpio_out";
>>       };
>> +
>> +     wifi_pwrseq_pin_opi0: wifi_pwrseq_pin at 0 {
>> +             allwinner,pins = "PL7";
>> +             allwinner,function = "gpio_out";
>
> And same thing here.

Might we do away with the pinmux for gpio pins tradition?
Recent patches I've sent all omit them.

ChenYu

^ permalink raw reply

* [PATCH 3/3] ARM: dts: sunxi: enable SDIO Wi-Fi on Orange Pi Zero
From: Hans de Goede @ 2016-11-23 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGb2v64taF9x9MDYW+KUEEUUoSx0bF68QNc7uZXQoNrsozMGtg@mail.gmail.com>

Hi,

On 23-11-16 15:25, Chen-Yu Tsai wrote:
> On Wed, Nov 23, 2016 at 3:59 PM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
>> Hi,
>>
>> On Tue, Nov 22, 2016 at 12:24:21AM +0800, Icenowy Zheng wrote:
>>> There's a Allwinner's XR819 SDIO Wi-Fi module soldered on the board of
>>> Orange Pi Zero, which used a dedicated regulator to power.
>>>
>>> Add the device tree node of the regulator, the enable gpio (with
>>> mmc-pwrseq) and the sdio controller.
>>>
>>> There's a out-of-tree driver tested to work with this device tree.
>>>
>>> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
>>> ---
>>> New patch in the patchset, since a out-of-tree working xradio driver is done.
>>>
>>> If there is any problem in this patch, it can be omitted.
>>
>> No particular problem with this one, however it can and should be
>> merged with the previous one.
>>
>> Minor comments below though.
>>
>>>
>>>  arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts | 42 ++++++++++++++++++++++++
>>>  1 file changed, 42 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>>> index b428e47..39cac26 100644
>>> --- a/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>>> +++ b/arch/arm/boot/dts/sun8i-h2plus-orangepi-zero.dts
>>> @@ -79,6 +79,24 @@
>>>                       gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>;
>>>               };
>>>       };
>>> +
>>> +     reg_vcc_wifi: reg_vcc_wifi {
>>> +             compatible = "regulator-fixed";
>>> +             pinctrl-names = "default";
>>> +             pinctrl-0 = <&vcc_wifi_pin_opi0>;
>>> +             regulator-min-microvolt = <3300000>;
>>> +             regulator-max-microvolt = <3300000>;
>>> +             regulator-name = "vcc-wifi";
>>> +             enable-active-high;
>>> +             gpio = <&pio 0 20 GPIO_ACTIVE_HIGH>;
>>> +     };
>>> +
>>> +     wifi_pwrseq: wifi_pwrseq {
>>> +             compatible = "mmc-pwrseq-simple";
>>> +             pinctrl-names = "default";
>>> +             pinctrl-0 = <&wifi_pwrseq_pin_opi0>;
>>> +             reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>;
>>> +     };
>>>  };
>>>
>>>  &ehci1 {
>>> @@ -95,6 +113,20 @@
>>>       status = "okay";
>>>  };
>>>
>>> +&mmc1 {
>>> +     pinctrl-names = "default";
>>> +     pinctrl-0 = <&mmc1_pins_a>;
>>> +     vmmc-supply = <&reg_vcc_wifi>;
>>> +     mmc-pwrseq = <&wifi_pwrseq>;
>>> +     bus-width = <4>;
>>> +     non-removable;
>>> +     status = "okay";
>>> +};
>>> +
>>> +&mmc1_pins_a {
>>> +     allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
>>
>> This should be bias-pull-up.
>
> IIRC I already added this for _all_ existing mmc pinmux settings?
>
>>
>>> +};
>>> +
>>>  &ohci1 {
>>>       status = "okay";
>>>  };
>>> @@ -104,6 +136,11 @@
>>>               pins = "PA17";
>>>               function = "gpio_out";
>>>       };
>>> +
>>> +     vcc_wifi_pin_opi0: vcc_wifi_pin at 0 {
>>> +             allwinner,pins = "PA20";
>>
>> This should be pins
>>
>>> +             allwinner,function = "gpio_out";
>>
>> This should be function
>>
>>> +     };
>>>  };
>>>
>>>  &r_pio {
>>> @@ -111,6 +148,11 @@
>>>               pins = "PL10";
>>>               function = "gpio_out";
>>>       };
>>> +
>>> +     wifi_pwrseq_pin_opi0: wifi_pwrseq_pin at 0 {
>>> +             allwinner,pins = "PL7";
>>> +             allwinner,function = "gpio_out";
>>
>> And same thing here.
>
> Might we do away with the pinmux for gpio pins tradition?
> Recent patches I've sent all omit them.

I'm in favor of doing away with them, except there were
we need to configure bias / strength.

Regards,

Hans

^ permalink raw reply

* [PATCH 0/3] arm64: dts: r8a7796: Add CAN/CAN FD support
From: Simon Horman @ 2016-11-23 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f358442c-8373-328c-1270-709498c133f5@pengutronix.de>

On Wed, Nov 23, 2016 at 02:18:13PM +0100, Marc Kleine-Budde wrote:
> On 11/23/2016 01:14 PM, Chris Paterson wrote:
> > This patch series adds CAN and CAN FD support to the r8a7796.
> > 
> > Based on renesas-devel-20161122-v4.9-rc6.
> > 
> > Chris Paterson (3):
> >   arm64: dts: r8a7796: Add CAN external clock support
> >   arm64: dts: r8a7796: Add CAN support
> >   arm64: dts: r8a7796: Add CAN FD support
> > 
> >  .../devicetree/bindings/net/can/rcar_can.txt       | 12 +++--
> >  .../devicetree/bindings/net/can/rcar_canfd.txt     | 12 +++--
> >  arch/arm64/boot/dts/renesas/r8a7796.dtsi           | 61 ++++++++++++++++++++++
> >  3 files changed, 75 insertions(+), 10 deletions(-)
> 
> For all three:
> 
> Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
> 
> Who takes this series?

I would like to see these patches split up so that the
.../devicetree/bindings/ portions can go through you whole
the arch/arm64/boot/dts/renesas/ portions go thorugh my renesas tree.

Regarding the arch/arm64/boot/dts/renesas/ portion, I would like
some consideration given to what effect enabling memory above 4Gb
(64bit addressing) would have.

^ permalink raw reply

* [PATCH 0/3] arm64: dts: r8a7796: Add CAN/CAN FD support
From: Marc Kleine-Budde @ 2016-11-23 14:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161123142938.GF9057@verge.net.au>

On 11/23/2016 03:29 PM, Simon Horman wrote:
> On Wed, Nov 23, 2016 at 02:18:13PM +0100, Marc Kleine-Budde wrote:
>> On 11/23/2016 01:14 PM, Chris Paterson wrote:
>>> This patch series adds CAN and CAN FD support to the r8a7796.
>>>
>>> Based on renesas-devel-20161122-v4.9-rc6.
>>>
>>> Chris Paterson (3):
>>>   arm64: dts: r8a7796: Add CAN external clock support
>>>   arm64: dts: r8a7796: Add CAN support
>>>   arm64: dts: r8a7796: Add CAN FD support
>>>
>>>  .../devicetree/bindings/net/can/rcar_can.txt       | 12 +++--
>>>  .../devicetree/bindings/net/can/rcar_canfd.txt     | 12 +++--
>>>  arch/arm64/boot/dts/renesas/r8a7796.dtsi           | 61 ++++++++++++++++++++++
>>>  3 files changed, 75 insertions(+), 10 deletions(-)
>>
>> For all three:
>>
>> Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
>>
>> Who takes this series?
> 
> I would like to see these patches split up so that the
> .../devicetree/bindings/ portions can go through you whole
> the arch/arm64/boot/dts/renesas/ portions go thorugh my renesas tree.

Ok

> Regarding the arch/arm64/boot/dts/renesas/ portion, I would like
> some consideration given to what effect enabling memory above 4Gb
> (64bit addressing) would have.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161123/803507ec/attachment.sig>

^ permalink raw reply

* [PATCH] arm: perf: use builtin_platform_driver
From: Geliang Tang @ 2016-11-23 14:39 UTC (permalink / raw)
  To: linux-arm-kernel

Use builtin_platform_driver() helper to simplify the code.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 arch/arm/kernel/perf_event_v6.c     | 6 +-----
 arch/arm/kernel/perf_event_v7.c     | 6 +-----
 arch/arm/kernel/perf_event_xscale.c | 6 +-----
 3 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index 09413e7..96b7a47 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -581,9 +581,5 @@ static struct platform_driver armv6_pmu_driver = {
 	.probe		= armv6_pmu_device_probe,
 };
 
-static int __init register_armv6_pmu_driver(void)
-{
-	return platform_driver_register(&armv6_pmu_driver);
-}
-device_initcall(register_armv6_pmu_driver);
+builtin_platform_driver(armv6_pmu_driver);
 #endif	/* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index b942349..ab6522b 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -2034,9 +2034,5 @@ static struct platform_driver armv7_pmu_driver = {
 	.probe		= armv7_pmu_device_probe,
 };
 
-static int __init register_armv7_pmu_driver(void)
-{
-	return platform_driver_register(&armv7_pmu_driver);
-}
-device_initcall(register_armv7_pmu_driver);
+builtin_platform_driver(armv7_pmu_driver);
 #endif	/* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index aa0499e..0e51f5e 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -767,9 +767,5 @@ static struct platform_driver xscale_pmu_driver = {
 	.probe		= xscale_pmu_device_probe,
 };
 
-static int __init register_xscale_pmu_driver(void)
-{
-	return platform_driver_register(&xscale_pmu_driver);
-}
-device_initcall(register_xscale_pmu_driver);
+builtin_platform_driver(xscale_pmu_driver);
 #endif	/* CONFIG_CPU_XSCALE */
-- 
2.9.3

^ permalink raw reply related

* [PATCH] arm64: defconfig: Do not lower CONFIG_LOG_BUF_SHIFT
From: Catalin Marinas @ 2016-11-23 14:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479908176-13625-1-git-send-email-geert+renesas@glider.be>

On Wed, Nov 23, 2016 at 02:36:16PM +0100, Geert Uytterhoeven wrote:
> The default value of 17 for CONFIG_LOG_BUF_SHIFT is much more suitable
> than 14. The latter easily leads to lost kernel messages on systems with
> only one CPU core.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
>  arch/arm64/configs/defconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 0e41290f6cbb4101..f284568373adf917 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -11,7 +11,6 @@ CONFIG_TASK_XACCT=y
>  CONFIG_TASK_IO_ACCOUNTING=y
>  CONFIG_IKCONFIG=y
>  CONFIG_IKCONFIG_PROC=y
> -CONFIG_LOG_BUF_SHIFT=14
>  CONFIG_MEMCG=y
>  CONFIG_MEMCG_SWAP=y
>  CONFIG_BLK_CGROUP=y

The defconfig updates usually go via arm-soc. The patch looks fine to
me:

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply

* [PATCH RFC] ARM: dts: add support for Turris Omnia
From: Andrew Lunn @ 2016-11-23 14:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479851991.26813.2@smtp.gmail.com>

> >CZ11NIC12 is indicated on my board.
> 
> :-( Well, this board version has wrongly matched length of some
> differential pairs, IRQ from 88E1514 is connected differently, there
> are slight differences in power supplies and (if I am not mistaken)
> something changed in RTC support circuitry. It looks like a huge
> mistake on our side.

Hi Tomas

Would these problems also explain why the Ethernet links to the switch
don't work? Maybe the differential pairs?

> It seems that libphy is probed before pca9538 and we end up with:
> [    4.217550] libphy: orion_mdio_bus: probed
> [    4.221777] irq: no irq domain found for
> /soc/internal-regs/i2c at 11000/i2cmux at 70/i2c at 7/gpio at 71 !
> 
> Any clue where to look in order to defer probing libphy or at least
> orion_mdio_bus?

I think there is a known phylib problem here. Somewhere in the call
chain there is a void function, so the EPROBE_DEFFER gets
discarded. But i could be remembering this wrongly.

      Andrew

^ permalink raw reply

* [PATCH] soc/fsl/qe: use builtin_platform_driver
From: Geliang Tang @ 2016-11-23 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

Use builtin_platform_driver() helper to simplify the code.

Signed-off-by: Geliang Tang <geliangtang@gmail.com>
---
 drivers/soc/fsl/qe/qe.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 2707a82..ade168f 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -717,9 +717,5 @@ static struct platform_driver qe_driver = {
 	.resume = qe_resume,
 };
 
-static int __init qe_drv_init(void)
-{
-	return platform_driver_register(&qe_driver);
-}
-device_initcall(qe_drv_init);
+builtin_platform_driver(qe_driver);
 #endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */
-- 
2.9.3

^ permalink raw reply related

* [PATCH] PCI: Add information about describing PCI in ACPI
From: Bjorn Helgaas @ 2016-11-23 15:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu-TW__+eZFS2p=1ZLN7fBs7pqQ+SitbEX46Z4JiS64egA@mail.gmail.com>

On Wed, Nov 23, 2016 at 07:28:12AM +0000, Ard Biesheuvel wrote:
> On 23 November 2016 at 01:06, Bjorn Helgaas <helgaas@kernel.org> wrote:
> > On Tue, Nov 22, 2016 at 10:09:50AM +0000, Ard Biesheuvel wrote:
> >> On 17 November 2016 at 17:59, Bjorn Helgaas <bhelgaas@google.com> wrote:
> >
> >> > +PCI host bridges are PNP0A03 or PNP0A08 devices.  Their _CRS should
> >> > +describe all the address space they consume.  In principle, this would
> >> > +be all the windows they forward down to the PCI bus, as well as the
> >> > +bridge registers themselves.  The bridge registers include things like
> >> > +secondary/subordinate bus registers that determine the bus range below
> >> > +the bridge, window registers that describe the apertures, etc.  These
> >> > +are all device-specific, non-architected things, so the only way a
> >> > +PNP0A03/PNP0A08 driver can manage them is via _PRS/_CRS/_SRS, which
> >> > +contain the device-specific details.  These bridge registers also
> >> > +include ECAM space, since it is consumed by the bridge.
> >> > +
> >> > +ACPI defined a Producer/Consumer bit that was intended to distinguish
> >> > +the bridge apertures from the bridge registers [4, 5].  However,
> >> > +BIOSes didn't use that bit correctly, and the result is that OSes have
> >> > +to assume that everything in a PCI host bridge _CRS is a window.  That
> >> > +leaves no way to describe the bridge registers in the PNP0A03/PNP0A08
> >> > +device itself.
> >>
> >> Is that universally true? Or is it still possible to do the right
> >> thing here on new ACPI architectures such as arm64?
> >
> > That's a very good question.  I had thought that the ACPI spec had
> > given up on Consumer/Producer completely, but I was wrong.  In the 6.0
> > spec, the Consumer/Producer bit is still documented in the Extended
> > Address Space Descriptor (sec 6.4.3.5.4).  It is documented as
> > "ignored" in the QWord, DWord, and Word descriptors (sec 6.4.3.5.1,2,3).
> >
> > Linux looks at the producer_consumer bit in acpi_decode_space(), which
> > I think is used for all these descriptors (QWord, DWord, Word, and
> > Extended).  This doesn't quite follow the spec -- we probably should
> > ignore it except for Extended.  In any event, acpi_decode_space() sets
> > IORESOURCE_WINDOW for Producer descriptors, but we don't test
> > IORESOURCE_WINDOW in the PCI host bridge code.
> >
> > x86 and ia64 supply their own pci_acpi_root_prepare_resources()
> > functions that call acpi_pci_probe_root_resources(), which parses _CRS
> > and looks at producer_consumer.  Then they do a little arch-specific
> > stuff on the result.
> >
> > On arm64 we use acpi_pci_probe_root_resources() directly, with no
> > arch-specific stuff.
> >
> > On all three arches, we ignore the Consumer/Producer bit, so all the
> > resources are treated as Producers, e.g., as bridge windows.
> >
> > I think we *could* implement an arm64 version of
> > pci_acpi_root_prepare_resources() that would pay attention to the
> > Consumer/Producer bit by checking IORESOURCE_WINDOW.  To be spec
> > compliant, we would have to use Extended descriptors for all bridge
> > windows, even if they would fit in a DWord or QWord.
> >
> > Should we do that?  I dunno.  I'd like to hear your opinion(s).
> >
> 
> Yes, I think we should. If the spec allows for a way for a PNP0A03
> device to describe all of its resources unambiguously, we should not
> be relying on workarounds that were designed for another architecture
> in another decade (for, presumably, another OS)
> 
> Just for my understanding, we will need to use extended descriptors
> for all consumed *and* produced regions, even though dword/qword are
> implicitly produced-only, due to the fact that the bit is ignored?

>From an ACPI spec point of view, I would say QWord/DWord/Word
descriptors are implicitly *consumer*-only because ResourceConsumer
is the default and they don't have a bit to indicate otherwise.

The current code assumes all PNP0A03 resources are producers.  If we
implement an arm64 pci_acpi_root_prepare_resources() that pays
attention to the Consumer/Producer bit, we would have to:

  - Reserve all producer regions in the iomem/ioport trees.  This is
    already done via pci_acpi_root_add_resources(), but we might need
    a new check to handle consumers differently.

  - Reserve all consumer regions.  This corresponds to what
    pnp/system.c does for PNP0C02 devices.  This is similar to the
    producer regions, but I think the consumer ones should be marked
    IORESOURCE_BUSY.

  - Use every producer (IORESOURCE_WINDOW) as a host bridge window.

I think it's a bug that acpi_decode_space() looks at producer_consumer
for QWord/DWord/Word descriptors, but I think QWord/DWord/Word
descriptors for consumed regions should be safe, as long as they don't
set the Consumer/Producer bit.

^ permalink raw reply

* [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06
From: Gabriele Paoloni @ 2016-11-23 15:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2359248.XjnRfPbj1B@wuerfel>

Hi Arnd

> -----Original Message-----
> From: Arnd Bergmann [mailto:arnd at arndb.de]
> Sent: 23 November 2016 14:16
> To: Gabriele Paoloni
> Cc: linux-arm-kernel at lists.infradead.org; mark.rutland at arm.com;
> benh at kernel.crashing.org; catalin.marinas at arm.com; liviu.dudau at arm.com;
> Linuxarm; lorenzo.pieralisi at arm.com; xuwei (O); Jason Gunthorpe; linux-
> serial at vger.kernel.org; linux-pci at vger.kernel.org;
> devicetree at vger.kernel.org; minyard at acm.org; will.deacon at arm.com; John
> Garry; zourongrong at gmail.com; robh+dt at kernel.org; bhelgaas at go og
> le.com; kantyzc at 163.com; zhichang.yuan02 at gmail.com; T homas Petazzoni;
> linux-kernel at vger.kernel.org; Yuanzhichang; olof at lixom.net
> Subject: Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on
> Hip06
> 
> On Friday, November 18, 2016 5:03:11 PM CET Gabriele Paoloni wrote:
> > > On Friday, November 18, 2016 4:18:07 PM CET Gabriele Paoloni wrote:
> > > > From: Arnd Bergmann [mailto:arnd at arndb.de]
> > > > > On Friday, November 18, 2016 12:53:08 PM CET Gabriele Paoloni
> > > wrote:
> > > > > For the ISA/LPC spaces there are only 4k of addresses, they
> > > > > the bus addresses always overlap, but we can trivially
> > > > > figure out the bus address from Linux I/O port number
> > > > > by subtracting the start of the range.
> > > >
> > > > Are you saying that our LPC controller should specify a
> > > > range property to map bus addresses into a cpu address range?
> > >
> > > No. There is not CPU address associated with it, because it's
> > > not memory mapped.
> > >
> > > Instead, we need to associate a bus address with a logical
> > > Linux port number, both in of_address_to_resource and
> > > in inb()/outb().
> >
> > I think this is effectively what we are doing so far with patch 2/3.
> > The problem with this patch is that we are carving out a "forbidden"
> > IO tokens range that goes from 0 to PCIBIOS_MIN_IO.
> >
> > I think that the proper solution would be to have the LPC driver to
> > set the carveout threshold used in pci_register_io_range(),
> > pci_pio_to_address(), pci_address_to_pio(), but this would impose
> > a probe dependency on the LPC itself that should be probed before
> > the PCI controller (or before any other devices calling these
> > functions...)
> 
> Why do you think the order matters? My point was that we should
> be able to register any region of logical port numbers for any
> bus here.

Maybe I have not followed well so let's roll back to your previous
comment...

"we need to associate a bus address with a logical Linux port number,
both in of_address_to_resource and in inb()/outb()"

Actually of_address_to_resource() returns the port number to used
in inb/outb(); inb() and outb() add the port number to PCI_IOBASE
to rd/wr to the right virtual address.

Our LPC cannot operate on the virtual address and it operates on
a bus address range that for LPC is also equal to the cpu address
range and goes from 0 to 0x1000.

Now as I understand it is risky and not appropriate to reserve
the logical port numbers from 0 to 0x1000 or to whatever other
upper bound because existing systems may rely on these port numbers
retrieved by __of_address_to_resource().

In this scenario I think the best thing to do would be
in the probe function of the LPC driver:
1) call pci_register_io_range() passing [0, 0x1000] (that is the
   range for LPC)
2) retrieve the logical port numbers associated to the LPC range
   by calling pci_address_to_pio() for 0 and 0x1000 and assign
   them to extio_ops_node->start and extio_ops_node->end
3) implement the LPC accessors to operate on the logical ports
   associated to the LPC range (in practice in the accessors
   implementation we will call pci_pio_to_address to retrieve
   the cpu address to operate on)

What do you think?

Thanks

Gab


> 
>
> > > > > > To be honest with you I would keep things simple for this
> > > > > > LPC and introduce more complex reworks later if more devices
> > > > > > need to be introduced.
> > > > > >
> > > > > > What if we stick on a single domain now where we introduce a
> > > > > > reserved threshold for the IO space (say INDIRECT_MAX_IO).
> > > > >
> > > > > I said having a single domain is fine, but I still don't
> > > > > like the idea of reserving low port numbers for this hack,
> > > > > it would mean that the numbers change for everyone else.
> > > >
> > > > I don't get this much...I/O tokens that are passed to the I/O
> > > > accessors are not fixed anyway and they vary depending on the
> order
> > > > of adding ranges to io_range_list...so I don't see a big issue
> > > > with this...
> > >
> > > On machines with a legacy devices behind the PCI bridge,
> > > there may still be a reason to have the low I/O port range
> > > reserved for the primary bus, e.g. to get a VGA text console
> > > to work.
> > >
> > > On powerpc, this is called the "primary" PCI host, i.e. the
> > > only one that is allowed to have an ISA bridge.
> >
> > Yes but
> > 1) isn't the PCI controller range property that defines how IO bus
> address
> >    map into physical CPU addresses?
> 
> Correct, but the DT knows nothing about logical port numbers in Linux.
> 
> > 2) How can you guarantee that the cpu range associated with this
> >    IO bus range is the first to be registered in
> pci_register_io_range()?
> >    ( i.e. are you saying that they are just relying on the fact that
> it is the
> >      only IO range in the system and by chance the IO tokens and
> corresponding
> >      bus addresses are the same? )
> 
> To clarify: the special properties of having the first 0x1000 logical
> port numbers go to a particular physical bus are very obscure. I think
> it's more important to not change the behavior for existing systems
> that might rely on it than for new systems that have no such legacy.
> 
> The ipmi and uart drivers in particular will get the port numbers
> filled
> in their platform device from the DT bus scanning, so they don't care
> at all about having the same numeric value for port numbers on the bus
> and logical numbers, but other drivers might rely on particular ports
> to be mapped on a specific PCI host, especially when those drivers
> are  used only on systems that don't have more than one PCI domain.
> 
> 	Arnd

^ permalink raw reply

* [PATCH 2/4] ARM: dts: davinci: da850: add VPIF
From: Kevin Hilman @ 2016-11-23 15:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <d4e696d1-f9b2-665c-c44f-c661856c5098@ti.com>

Sekhar Nori <nsekhar@ti.com> writes:

> On Wednesday 23 November 2016 11:13 AM, Kevin Hilman wrote:
>> David Lechner <david@lechnology.com> writes:
>> 
>>> On 11/22/2016 01:45 PM, Kevin Hilman wrote:
>>>> Add VPIF and VPIF capture nodes to da850.  VPIF capture has two input
>>>> channels describe using the standard DT ports and enpoints.
>>>>
>>>> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
>>>> ---
>>>>  arch/arm/boot/dts/da850.dtsi | 28 ++++++++++++++++++++++++++++
>>>>  1 file changed, 28 insertions(+)
>>>>
>>>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>>>> index 6205917b4f59..e05e2bb834e8 100644
>>>> --- a/arch/arm/boot/dts/da850.dtsi
>>>> +++ b/arch/arm/boot/dts/da850.dtsi
>>>> @@ -453,7 +453,35 @@
>>>>  			interrupts = <52>;
>>>>  			status = "disabled";
>>>>  		};
>>>> +
>>>> +		vpif: video at 0x00217000 {
>>>
>>> Should be @217000
>>>
>>>> +			compatible = "ti,da850-vpif";
>>>> +			reg = <0x00217000 0x1000>;
>>>
>>> Could omit leading 0's to be consistent with existing entries.
>>>
>>> 	reg = <0x217000 0x1000>;
>> 
>> Ugh, yeah. I hate that convention, but better to be consistent, I guess.
>> 
>>>> +			status = "disabled";
>>>> +		};
>>>> +
>>>> +		vpif_capture: video-capture at 0x00217000 {
>>>
>>> Again, @217000. But it seems odd to have two device nodes with the
>>> same address. Is enabling these mutually exclusive?
>> 
>> They're not mutually exclusive because the vpif is the one that actually
>> maps the register range (since it's shared between vpif_display and
>> vpif_capture) so I guess I should just drop the reg property from the
>> vpif_capture node.
>
> Reading the documentation, VPIF is presented as a single device, with
> two channels dedicated to display and two for capture. Most of the
> channel registers are independent, but there are are some like interrupt
> enable which are common for all channels. So I believe we cannot use
> simple-mfd. But I believe VPIF display and capture should be subdevices
> of a single VPIF device.

OK, I can give it a try that way.

> It should look something like this, I think:
>
> 		vpif: video at 217000 {
> 			compatible = "ti,da850-vpif";
> 			reg = <0x217000 0x1000>;
> 			interrupts = <92>;
> 			status = "disabled";
>
> 			vpif_capture: video-capture {
> 				compatible = "ti,da850-vpif-capture"
> 				port {
> 					vpif_ch0: endpoint at 0 {
> 						  reg = <0>;
> 						  bus-width = <8>;
> 					};
> 	
> 					vpif_ch1: endpoint at 1 {
> 						  reg = <1>;
> 						  bus-width = <8>;
> 						  data-shift = <8>;
> 					};
> 				};
> 			};
>
> 			vpif_display: video-display {
> 				compatible = "ti,da850-vpif-display"
> 				port {
> 					vpif_ch2: endpoint at 2 {
> 						  reg = <2>;
> 						  bus-width = <8>;
> 						  data-shift = <16>;
> 					};
>
> 					vpif_ch3: endpoint at 3 {
> 						  reg = <3>;
> 						  bus-width = <8>;
> 						  data-shift = <24>;
> 					};
> 				};
> 			};
> 		};

> The interrupt too, seems to be common interrupt for both display and
> capture. So, it should not be under the capture node.

Possibly.  That will require reworking of the way the driver works
today, since the vpif driver doesn't request interrupts, but the capture
and display drivers both register interrupts, one per channel.  I'll
have a closer look.

> BTW, I am sure
> what exactly data-shift is used for. It does not seem to be used in the
> driver patches too. I just extrapolated the values based on the pattern
> I saw.

For video out, the way I read the spec, and based on the schematics,
there appears to be a separate 16-bit parallel bus, so the data-shift on
the video-display endpoints should probably be zero and 16 like for
catpure.  Anyways, I'll get to that when I get to the display part.

Kevin

^ permalink raw reply

* [PATCH] ARM: dts: am335x-baltos: use phy-phandle declarations
From: Tony Lindgren @ 2016-11-23 15:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1479894757-32736-1-git-send-email-yegorslists@googlemail.com>

* yegorslists at googlemail.com <yegorslists@googlemail.com> [161123 01:53]:
> From: Yegor Yefremov <yegorslists@googlemail.com>

Description missing? Something like "do so and so because of" :)

Regards

Tony

^ permalink raw reply

* [RFC PATCH 11/11] ARM: Allow ARCH_MULTIPLATFORM to be selected for NOMMU
From: Afzal Mohammed @ 2016-11-23 15:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <583478FB.4020008@arm.com>

Hi,

On Tue, Nov 22, 2016 at 04:57:31PM +0000, Vladimir Murzin wrote:

> I used defconfigs

Which defconfig was used ?

multi_v7_defconfig, MMU & SMP disabled - thus spake the compiler,

kernel/built-in.o: In function `kimage_free_entry':
memremap.c:(.text+0x4dafc): undefined reference to
`arch_phys_to_idmap_offset'
memremap.c:(.text+0x4db04): undefined reference to
`arch_phys_to_idmap_offset'
kernel/built-in.o: In function `kimage_alloc_page':
memremap.c:(.text+0x4dbc0): undefined reference to
`arch_phys_to_idmap_offset'
memremap.c:(.text+0x4dbc8): undefined reference to
`arch_phys_to_idmap_offset'
memremap.c:(.text+0x4dc1c): undefined reference to
`arch_phys_to_idmap_offset'
kernel/built-in.o:memremap.c:(.text+0x4dc30): more undefined
references to `arch_phys_to_idmap_offset' follow

multi_v7_defconfig & MMU disabled, stderr was more verbose and was
unhappy with Kconfig dependencies,

warning: (SOC_IMX31 && SOC_IMX35 && SOC_VF610 && REALVIEW_DT) selects
SMP_ON_UP which has unmet direct dependencies (SMP && !XIP_KERNEL &&
MMU)
warning: (SOC_IMX31 && SOC_IMX35 && SOC_VF610 && REALVIEW_DT) selects
SMP_ON_UP which has unmet direct dependencies (SMP && !XIP_KERNEL &&
MMU)

Ulterior motive here is to try !MMU on Cortex A

Regards
afzal

^ permalink raw reply

* [PATCH v2] ARM: dts: am335x-baltos: use phy-phandle declarations
From: yegorslists at googlemail.com @ 2016-11-23 15:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Yegor Yefremov <yegorslists@googlemail.com>

phy-phandle is now a preferred method to reference a PHY device.
Especially in regards to cpsw it enables PHY specific settings like
max-speed etc. being specified in DTS.

Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
---
Changes:
	v2: add patch description (Tony Lindgren)

 arch/arm/boot/dts/am335x-baltos-ir2110.dts | 10 ++++++++--
 arch/arm/boot/dts/am335x-baltos-ir3220.dts |  2 +-
 arch/arm/boot/dts/am335x-baltos-ir5221.dts |  2 +-
 arch/arm/boot/dts/am335x-baltos.dtsi       |  5 ++++-
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-baltos-ir2110.dts b/arch/arm/boot/dts/am335x-baltos-ir2110.dts
index a9a9730..501c752 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir2110.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir2110.dts
@@ -54,16 +54,22 @@
 	dr_mode = "host";
 };
 
+&davinci_mdio {
+	phy0: ethernet-phy at 0 {
+		reg = <1>;
+	};
+};
+
 &cpsw_emac0 {
-	phy_id = <&davinci_mdio>, <1>;
 	phy-mode = "rmii";
 	dual_emac_res_vlan = <1>;
+	phy-handle = <&phy0>;
 };
 
 &cpsw_emac1 {
-	phy_id = <&davinci_mdio>, <7>;
 	phy-mode = "rgmii-txid";
 	dual_emac_res_vlan = <2>;
+	phy-handle = <&phy1>;
 };
 
 &phy_sel {
diff --git a/arch/arm/boot/dts/am335x-baltos-ir3220.dts b/arch/arm/boot/dts/am335x-baltos-ir3220.dts
index fe002a1..19f53b8 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir3220.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir3220.dts
@@ -109,9 +109,9 @@
 };
 
 &cpsw_emac1 {
-	phy_id = <&davinci_mdio>, <7>;
 	phy-mode = "rgmii-txid";
 	dual_emac_res_vlan = <2>;
+	phy-handle = <&phy1>;
 };
 
 &phy_sel {
diff --git a/arch/arm/boot/dts/am335x-baltos-ir5221.dts b/arch/arm/boot/dts/am335x-baltos-ir5221.dts
index f599350..2b9d7f4 100644
--- a/arch/arm/boot/dts/am335x-baltos-ir5221.dts
+++ b/arch/arm/boot/dts/am335x-baltos-ir5221.dts
@@ -127,9 +127,9 @@
 };
 
 &cpsw_emac1 {
-	phy_id = <&davinci_mdio>, <7>;
 	phy-mode = "rgmii-txid";
 	dual_emac_res_vlan = <2>;
+	phy-handle = <&phy1>;
 };
 
 &phy_sel {
diff --git a/arch/arm/boot/dts/am335x-baltos.dtsi b/arch/arm/boot/dts/am335x-baltos.dtsi
index 09b9541..efb5eae 100644
--- a/arch/arm/boot/dts/am335x-baltos.dtsi
+++ b/arch/arm/boot/dts/am335x-baltos.dtsi
@@ -364,11 +364,14 @@
 };
 
 &davinci_mdio {
+	status = "okay";
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&davinci_mdio_default>;
 	pinctrl-1 = <&davinci_mdio_sleep>;
 
-	status = "okay";
+	phy1: ethernet-phy at 1 {
+		reg = <7>;
+	};
 };
 
 &mmc1 {
-- 
2.1.4

^ permalink raw reply related

* [RFC PATCH 03/11] ARM: omap: do not select HIGHMEM explicitly
From: Tony Lindgren @ 2016-11-23 15:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161122095136.GU1041@n2100.armlinux.org.uk>

* Russell King - ARM Linux <linux@armlinux.org.uk> [161122 01:51]:
> On Tue, Nov 22, 2016 at 09:26:00AM +0000, Vladimir Murzin wrote:
> > Explicit selection of HIGHMEM breaks NOMMU builds. It seems that
> > HIGHMEM is user selectable option, so probably it would be better to
> > let user to make a decision on this options or, at least, move it to
> > defconfig.
> 
> That's kind of the point of ARCH_OMAP2PLUS_TYPICAL - it's a user
> option to let the user select a range of options for typical OMAP2+
> configurations, so that the user doesn't have to dig around looking
> for multiple options, some of which are hard requirements for OMAP
> to be functional.  OMAP is a particularly difficult case because the
> hardware tends to be very complex.
> 
> However, HIGHMEM should never be a requirement to boot, so this looks
> sane.

Yeah we can add that to the defconfig:

Acked-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox