* [PATCH 02/12] power/reset: vexpress: Use udelay instead of timers
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
At this stage of system shutdown procedure the jiffies may
not be updated anymore, so just use udelay instead.
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
drivers/power/reset/vexpress-poweroff.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c
index 37e7799..195235c 100644
--- a/drivers/power/reset/vexpress-poweroff.c
+++ b/drivers/power/reset/vexpress-poweroff.c
@@ -11,7 +11,7 @@
* Copyright (C) 2012 ARM Limited
*/
-#include <linux/jiffies.h>
+#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -26,13 +26,9 @@ static void vexpress_reset_do(struct device *dev, const char *what)
struct regmap *reg = dev_get_drvdata(dev);
if (reg) {
- unsigned long timeout;
-
err = regmap_write(reg, 0, 0);
-
- timeout = jiffies + HZ;
- while (time_before(jiffies, timeout))
- cpu_relax();
+ if (!err)
+ mdelay(1000);
}
dev_emerg(dev, "Unable to %s (%d)\n", what, err);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 03/12] clk: versatile: Split config options for sp810 and vexpress_osc
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
Move the Kconfig entry for Versatile (& Express) clock drivers
into a separate file and add individual options for sp810
and vexpress_osc drivers, as they are optional in some
configurations and may have separate dependencies.
Cc: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
drivers/clk/Kconfig | 9 +--------
drivers/clk/versatile/Kconfig | 26 ++++++++++++++++++++++++++
drivers/clk/versatile/Makefile | 5 +++--
3 files changed, 30 insertions(+), 10 deletions(-)
create mode 100644 drivers/clk/versatile/Kconfig
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 7641965..11e7058 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -30,14 +30,7 @@ config COMMON_CLK_WM831X
Supports the clocking subsystem of the WM831x/2x series of
PMICs from Wolfson Microlectronics.
-config COMMON_CLK_VERSATILE
- bool "Clock driver for ARM Reference designs"
- depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64
- ---help---
- Supports clocking on ARM Reference designs:
- - Integrator/AP and Integrator/CP
- - RealView PB1176, EB, PB11MP and PBX
- - Versatile Express
+source "drivers/clk/versatile/Kconfig"
config COMMON_CLK_MAX77686
tristate "Clock driver for Maxim 77686 MFD"
diff --git a/drivers/clk/versatile/Kconfig b/drivers/clk/versatile/Kconfig
new file mode 100644
index 0000000..1530c93
--- /dev/null
+++ b/drivers/clk/versatile/Kconfig
@@ -0,0 +1,26 @@
+config COMMON_CLK_VERSATILE
+ bool "Clock driver for ARM Reference designs"
+ depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64
+ ---help---
+ Supports clocking on ARM Reference designs:
+ - Integrator/AP and Integrator/CP
+ - RealView PB1176, EB, PB11MP and PBX
+ - Versatile Express
+
+config CLK_SP810
+ bool "Clock driver for ARM SP810 System Controller"
+ depends on COMMON_CLK_VERSATILE
+ default y if ARCH_VEXPRESS
+ ---help---
+ Supports clock muxing (REFCLK/TIMCLK to TIMERCLKEN0-3) capabilities
+ of the ARM SP810 System Controller cell.
+
+config CLK_VEXPRESS_OSC
+ bool "Clock driver for Versatile Express OSC clock generators"
+ depends on COMMON_CLK_VERSATILE
+ depends on VEXPRESS_CONFIG
+ default y if ARCH_VEXPRESS
+ ---help---
+ Simple regmap-based driver driving clock generators on Versatile
+ Express platforms hidden behind its configuration infrastructure,
+ commonly known as OSCs.
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile
index c16ca78..fd449f9 100644
--- a/drivers/clk/versatile/Makefile
+++ b/drivers/clk/versatile/Makefile
@@ -3,5 +3,6 @@ obj-$(CONFIG_ICST) += clk-icst.o
obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o
obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o
obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o
-obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o clk-sp810.o
-obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o
+obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o
+obj-$(CONFIG_CLK_SP810) += clk-sp810.o
+obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk-vexpress-osc.o
--
1.8.3.2
^ permalink raw reply related
* [PATCH 04/12] clocksource: Sched clock source for Versatile Express
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
This patch adds a trival sched clock source using free
running, 24MHz clocked counter present in the ARM Ltd.
Versatile Express platform's System Registers block.
This code replaces the call in the VE machine code.
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
arch/arm/mach-vexpress/v2m.c | 2 --
drivers/clocksource/Kconfig | 9 +++++++++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/vexpress.c | 40 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 50 insertions(+), 2 deletions(-)
create mode 100644 drivers/clocksource/vexpress.c
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 90f04c9..d8a9fd7 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -418,8 +418,6 @@ void __init v2m_dt_init_early(void)
pr_warning("vexpress: DT HBI (%x) is not matching "
"hardware (%x)!\n", dt_hbi, hbi);
}
-
- versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
}
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cd6950f..9799744 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -140,3 +140,12 @@ config VF_PIT_TIMER
bool
help
Support for Period Interrupt Timer on Freescale Vybrid Family SoCs.
+
+config CLKSRC_VEXPRESS
+ bool
+ depends on MFD_VEXPRESS_SYSREG
+ depends on GENERIC_SCHED_CLOCK
+ select CLKSRC_OF
+ default y
+ help
+ Simple provider of sched clock on ARM Versatile Express platform.
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index c7ca50a..1051a23 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -37,3 +37,4 @@ obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o
+obj-$(CONFIG_CLKSRC_VEXPRESS) += vexpress.o
diff --git a/drivers/clocksource/vexpress.c b/drivers/clocksource/vexpress.c
new file mode 100644
index 0000000..55b8ab4
--- /dev/null
+++ b/drivers/clocksource/vexpress.c
@@ -0,0 +1,40 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2013 ARM Limited
+ */
+
+#include <linux/clocksource.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/sched_clock.h>
+
+#define SYS_24MHZ 0x05c
+
+static void __iomem *vexpress_sys_24mhz;
+
+static u32 notrace vexpress_sys_24mhz_read(void)
+{
+ return readl(vexpress_sys_24mhz);
+}
+
+static void __init vexpress_sched_clock_init(struct device_node *node)
+{
+ void __iomem *base = of_iomap(node, 0);
+
+ if (!base)
+ return;
+
+ vexpress_sys_24mhz = base + SYS_24MHZ;
+
+ setup_sched_clock(vexpress_sys_24mhz_read, 32, 24000000);
+}
+CLOCKSOURCE_OF_DECLARE(vexpress, "arm,vexpress-sysreg",
+ vexpress_sched_clock_init);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 05/12] GPIO: gpio-generic: Add label to platform data
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
When registering more than one platform device, it is
useful to set the gpio chip label in the platform data.
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
This patch has been already merged by Linux; it has been included
for completeness only.
drivers/gpio/gpio-generic.c | 2 ++
include/linux/basic_mmio_gpio.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c
index d2196bf..8c778af 100644
--- a/drivers/gpio/gpio-generic.c
+++ b/drivers/gpio/gpio-generic.c
@@ -531,6 +531,8 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
return err;
if (pdata) {
+ if (pdata->label)
+ bgc->gc.label = pdata->label;
bgc->gc.base = pdata->base;
if (pdata->ngpio > 0)
bgc->gc.ngpio = pdata->ngpio;
diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h
index d8a97ec..0e97856 100644
--- a/include/linux/basic_mmio_gpio.h
+++ b/include/linux/basic_mmio_gpio.h
@@ -19,6 +19,7 @@
#include <linux/spinlock_types.h>
struct bgpio_pdata {
+ const char *label;
int base;
int ngpio;
};
--
1.8.3.2
^ permalink raw reply related
* [PATCH 06/12] mfd: vexpress-sysreg: Add labels to gpio banks
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
... so debugfs interfaces are easier to use.
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
drivers/mfd/vexpress-sysreg.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index f639dff..ece5ac8 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -133,16 +133,19 @@ void __init vexpress_sysreg_early_init(void __iomem *base)
/* The sysreg block is just a random collection of various functions... */
static struct bgpio_pdata vexpress_sysreg_sys_led_pdata = {
+ .label = "sys_led",
.base = -1,
.ngpio = 8,
};
static struct bgpio_pdata vexpress_sysreg_sys_mci_pdata = {
+ .label = "sys_mci",
.base = -1,
.ngpio = 2,
};
static struct bgpio_pdata vexpress_sysreg_sys_flash_pdata = {
+ .label = "sys_flash",
.base = -1,
.ngpio = 1,
};
--
1.8.3.2
^ permalink raw reply related
* [PATCH 07/12] mfd: syscon: Consider platform data a regmap config name
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
Use the device platform data as a regmap config
name. This is particularly useful in the regmap
debugfs when there is more than one syscon device
registered, to distinguish the register blocks.
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
Alternatively I could define a syscon platform data structure,
something like this:
struct syscon_platform_data {
const char *label;
};
drivers/mfd/syscon.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 71841f9..ea1770b 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -143,6 +143,7 @@ static int syscon_probe(struct platform_device *pdev)
return -ENOMEM;
syscon_regmap_config.max_register = res->end - res->start - 3;
+ syscon_regmap_config.name = dev_get_platdata(&pdev->dev);
syscon->regmap = devm_regmap_init_mmio(dev, base,
&syscon_regmap_config);
if (IS_ERR(syscon->regmap)) {
--
1.8.3.2
^ permalink raw reply related
* [PATCH 08/12] mfd: vexpress-sysreg: Add syscon labels as platform data
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
This patch adds label names for syscon registers as platform
data for the relevant MFD cells.
Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
drivers/mfd/vexpress-sysreg.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index ece5ac8..57c21a0 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -132,6 +132,8 @@ void __init vexpress_sysreg_early_init(void __iomem *base)
/* The sysreg block is just a random collection of various functions... */
+static const char vexpress_sysreg_sys_id_pdata[] = "sys_id";
+
static struct bgpio_pdata vexpress_sysreg_sys_led_pdata = {
.label = "sys_led",
.base = -1,
@@ -150,6 +152,10 @@ static struct bgpio_pdata vexpress_sysreg_sys_flash_pdata = {
.ngpio = 1,
};
+static const char vexpress_sysreg_sys_misc_pdata[] = "sys_misc";
+
+static const char vexpress_sysreg_sys_procid_pdata[] = "sys_procid";
+
static struct mfd_cell vexpress_sysreg_cells[] = {
{
.name = "syscon",
@@ -157,6 +163,8 @@ static struct mfd_cell vexpress_sysreg_cells[] = {
.resources = (struct resource []) {
DEFINE_RES_MEM(SYS_ID, 0x4),
},
+ .platform_data = &vexpress_sysreg_sys_id_pdata,
+ .pdata_size = sizeof(vexpress_sysreg_sys_id_pdata),
}, {
.name = "basic-mmio-gpio",
.of_compatible = "arm,vexpress-sysreg,sys_led",
@@ -190,12 +198,16 @@ static struct mfd_cell vexpress_sysreg_cells[] = {
.resources = (struct resource []) {
DEFINE_RES_MEM(SYS_MISC, 0x4),
},
+ .platform_data = &vexpress_sysreg_sys_misc_pdata,
+ .pdata_size = sizeof(vexpress_sysreg_sys_misc_pdata),
}, {
.name = "syscon",
.num_resources = 1,
.resources = (struct resource []) {
DEFINE_RES_MEM(SYS_PROCID0, 0x8),
},
+ .platform_data = &vexpress_sysreg_sys_procid_pdata,
+ .pdata_size = sizeof(vexpress_sysreg_sys_procid_pdata),
}, {
.name = "vexpress-syscfg",
.num_resources = 1,
--
1.8.3.2
^ permalink raw reply related
* [PATCH 09/12] hwmon: vexpress: Use devm helper for hwmon device registration
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
Use devm_hwmon_device_register_with_groups instead of
the old-style manual attributes and hwmon device registration.
Cc: Jean Delvare <jdelvare@suse.de>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: lm-sensors at lm-sensors.org
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
drivers/hwmon/vexpress.c | 100 ++++++++++++-----------------------------------
1 file changed, 26 insertions(+), 74 deletions(-)
diff --git a/drivers/hwmon/vexpress.c b/drivers/hwmon/vexpress.c
index d8a6113..7c3a973 100644
--- a/drivers/hwmon/vexpress.c
+++ b/drivers/hwmon/vexpress.c
@@ -29,15 +29,6 @@ struct vexpress_hwmon_data {
struct regmap *reg;
};
-static ssize_t vexpress_hwmon_name_show(struct device *dev,
- struct device_attribute *dev_attr, char *buffer)
-{
- const char *compatible = of_get_property(dev->of_node, "compatible",
- NULL);
-
- return sprintf(buffer, "%s\n", compatible);
-}
-
static ssize_t vexpress_hwmon_label_show(struct device *dev,
struct device_attribute *dev_attr, char *buffer)
{
@@ -84,77 +75,60 @@ static ssize_t vexpress_hwmon_u64_show(struct device *dev,
to_sensor_dev_attr(dev_attr)->index));
}
-static DEVICE_ATTR(name, S_IRUGO, vexpress_hwmon_name_show, NULL);
-
-#define VEXPRESS_HWMON_ATTRS(_name, _label_attr, _input_attr) \
-struct attribute *vexpress_hwmon_attrs_##_name[] = { \
- &dev_attr_name.attr, \
- &dev_attr_##_label_attr.attr, \
- &sensor_dev_attr_##_input_attr.dev_attr.attr, \
- NULL \
-}
+#define VEXPRESS_HWMON_ATTR_GROUPS(_name, _label_attr, _input_attr) \
+static struct attribute *vexpress_hwmon_##_name##_attrs[] = { \
+ &dev_attr_##_label_attr.attr, \
+ &sensor_dev_attr_##_input_attr.dev_attr.attr, \
+ NULL \
+}; \
+ATTRIBUTE_GROUPS(vexpress_hwmon_##_name)
#if !defined(CONFIG_REGULATOR_VEXPRESS)
static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show,
NULL, 1000);
-static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input);
-static struct attribute_group vexpress_hwmon_group_volt = {
- .attrs = vexpress_hwmon_attrs_volt,
-};
+VEXPRESS_HWMON_ATTR_GROUPS(volt, in1_label, in1_input);
#endif
static DEVICE_ATTR(curr1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, vexpress_hwmon_u32_show,
NULL, 1000);
-static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input);
-static struct attribute_group vexpress_hwmon_group_amp = {
- .attrs = vexpress_hwmon_attrs_amp,
-};
+VEXPRESS_HWMON_ATTR_GROUPS(amp, curr1_label, curr1_input);
static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show,
NULL, 1000);
-static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input);
-static struct attribute_group vexpress_hwmon_group_temp = {
- .attrs = vexpress_hwmon_attrs_temp,
-};
+VEXPRESS_HWMON_ATTR_GROUPS(temp, temp1_label, temp1_input);
static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show,
NULL, 1);
-static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input);
-static struct attribute_group vexpress_hwmon_group_power = {
- .attrs = vexpress_hwmon_attrs_power,
-};
+VEXPRESS_HWMON_ATTR_GROUPS(power, power1_label, power1_input);
static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show,
NULL, 1);
-static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input);
-static struct attribute_group vexpress_hwmon_group_energy = {
- .attrs = vexpress_hwmon_attrs_energy,
-};
+VEXPRESS_HWMON_ATTR_GROUPS(energy, energy1_label, energy1_input);
static struct of_device_id vexpress_hwmon_of_match[] = {
#if !defined(CONFIG_REGULATOR_VEXPRESS)
{
.compatible = "arm,vexpress-volt",
- .data = &vexpress_hwmon_group_volt,
+ .data = vexpress_hwmon_volt_groups,
},
#endif
{
.compatible = "arm,vexpress-amp",
- .data = &vexpress_hwmon_group_amp,
+ .data = vexpress_hwmon_amp_groups,
}, {
.compatible = "arm,vexpress-temp",
- .data = &vexpress_hwmon_group_temp,
+ .data = vexpress_hwmon_temp_groups,
}, {
.compatible = "arm,vexpress-power",
- .data = &vexpress_hwmon_group_power,
+ .data = vexpress_hwmon_power_groups,
}, {
.compatible = "arm,vexpress-energy",
- .data = &vexpress_hwmon_group_energy,
+ .data = vexpress_hwmon_energy_groups,
},
{}
};
@@ -162,9 +136,10 @@ MODULE_DEVICE_TABLE(of, vexpress_hwmon_of_match);
static int vexpress_hwmon_probe(struct platform_device *pdev)
{
- int err;
const struct of_device_id *match;
struct vexpress_hwmon_data *data;
+ const char *name;
+ const struct attribute_group **groups;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -176,42 +151,19 @@ static int vexpress_hwmon_probe(struct platform_device *pdev)
return -ENODEV;
data->reg = devm_regmap_init_vexpress_config(&pdev->dev);
- if (!data->reg)
- return -ENODEV;
-
- err = sysfs_create_group(&pdev->dev.kobj, match->data);
- if (err)
- goto error;
-
- data->hwmon_dev = hwmon_device_register(&pdev->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto error;
- }
-
- return 0;
-
-error:
- sysfs_remove_group(&pdev->dev.kobj, match->data);
- return err;
-}
-
-static int vexpress_hwmon_remove(struct platform_device *pdev)
-{
- struct vexpress_hwmon_data *data = platform_get_drvdata(pdev);
- const struct of_device_id *match;
-
- hwmon_device_unregister(data->hwmon_dev);
+ if (IS_ERR(data->reg))
+ return PTR_ERR(data->reg);
- match = of_match_device(vexpress_hwmon_of_match, &pdev->dev);
- sysfs_remove_group(&pdev->dev.kobj, match->data);
+ name = of_get_property(pdev->dev.of_node, "compatible", NULL);
+ groups = (const struct attribute_group **)match->data;
+ data->hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev,
+ name, data, groups);
- return 0;
+ return PTR_ERR_OR_ZERO(data->hwmon_dev);
}
static struct platform_driver vexpress_hwmon_driver = {
.probe = vexpress_hwmon_probe,
- .remove = vexpress_hwmon_remove,
.driver = {
.name = DRVNAME,
.owner = THIS_MODULE,
--
1.8.3.2
^ permalink raw reply related
* [PATCH 10/12] ARM: vexpress: remove redundant vexpress_dt_cpus_num to get cpu count
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
From: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
arm_dt_init_cpu_maps parses the device tree, validates and sets the
cpu_possible_mask appropriately. It is unnecessary to do another DT
parse to get the number of cpus, use num_possible_cpus instead.
This patch also removes setting cpu_present_mask as platforms should
only re-initialize it in smp_prepare_cpus() if present != possible.
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
arch/arm/mach-vexpress/platsmp.c | 31 +------------------------------
1 file changed, 1 insertion(+), 30 deletions(-)
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 993c9ae..12a8751 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -77,39 +77,13 @@ void __init vexpress_dt_smp_map_io(void)
WARN_ON(of_scan_flat_dt(vexpress_dt_find_scu, NULL));
}
-static int __init vexpress_dt_cpus_num(unsigned long node, const char *uname,
- int depth, void *data)
-{
- static int prev_depth = -1;
- static int nr_cpus = -1;
-
- if (prev_depth > depth && nr_cpus > 0)
- return nr_cpus;
-
- if (nr_cpus < 0 && strcmp(uname, "cpus") == 0)
- nr_cpus = 0;
-
- if (nr_cpus >= 0) {
- const char *device_type = of_get_flat_dt_prop(node,
- "device_type", NULL);
-
- if (device_type && strcmp(device_type, "cpu") == 0)
- nr_cpus++;
- }
-
- prev_depth = depth;
-
- return 0;
-}
-
static void __init vexpress_dt_smp_init_cpus(void)
{
int ncores = 0, i;
switch (vexpress_dt_scu) {
case GENERIC_SCU:
- ncores = of_scan_flat_dt(vexpress_dt_cpus_num, NULL);
- break;
+ return;
case CORTEX_A9_SCU:
ncores = scu_get_core_count(vexpress_dt_cortex_a9_scu_base);
break;
@@ -133,12 +107,9 @@ static void __init vexpress_dt_smp_init_cpus(void)
static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
switch (vexpress_dt_scu) {
case GENERIC_SCU:
- for (i = 0; i < max_cpus; i++)
- set_cpu_present(i, true);
break;
case CORTEX_A9_SCU:
scu_enable(vexpress_dt_cortex_a9_scu_base);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 11/12] ARM: vexpress: Simplify SMP operations for DT-powered system
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
As all cores must be properly described in the Device Tree,
there is no point in getting their numbers from SCU on
A5/A9 platforms. This significantly simplifies the code,
removing the need for flat-tree scanning and early static
mapping.
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
arch/arm/mach-vexpress/core.h | 3 +-
arch/arm/mach-vexpress/platsmp.c | 158 ++++++++++-----------------------------
arch/arm/mach-vexpress/v2m.c | 6 +-
3 files changed, 41 insertions(+), 126 deletions(-)
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index bde4374..152fad9 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -4,10 +4,9 @@
/* Tile's peripherals static mappings should start here */
#define V2T_PERIPH 0xf8200000
-void vexpress_dt_smp_map_io(void);
-
bool vexpress_smp_init_ops(void);
extern struct smp_operations vexpress_smp_ops;
+extern struct smp_operations vexpress_smp_dt_ops;
extern void vexpress_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 12a8751..a1f3804 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -12,8 +12,7 @@
#include <linux/errno.h>
#include <linux/smp.h>
#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
+#include <linux/of_address.h>
#include <linux/vexpress.h>
#include <asm/mcpm.h>
@@ -26,125 +25,13 @@
#include "core.h"
-#if defined(CONFIG_OF)
-
-static enum {
- GENERIC_SCU,
- CORTEX_A9_SCU,
-} vexpress_dt_scu __initdata = GENERIC_SCU;
-
-static struct map_desc vexpress_dt_cortex_a9_scu_map __initdata = {
- .virtual = V2T_PERIPH,
- /* .pfn set in vexpress_dt_init_cortex_a9_scu() */
- .length = SZ_128,
- .type = MT_DEVICE,
-};
-
-static void *vexpress_dt_cortex_a9_scu_base __initdata;
-
-const static char *vexpress_dt_cortex_a9_match[] __initconst = {
- "arm,cortex-a5-scu",
- "arm,cortex-a9-scu",
- NULL
-};
-
-static int __init vexpress_dt_find_scu(unsigned long node,
- const char *uname, int depth, void *data)
-{
- if (of_flat_dt_match(node, vexpress_dt_cortex_a9_match)) {
- phys_addr_t phys_addr;
- __be32 *reg = of_get_flat_dt_prop(node, "reg", NULL);
-
- if (WARN_ON(!reg))
- return -EINVAL;
-
- phys_addr = be32_to_cpup(reg);
- vexpress_dt_scu = CORTEX_A9_SCU;
-
- vexpress_dt_cortex_a9_scu_map.pfn = __phys_to_pfn(phys_addr);
- iotable_init(&vexpress_dt_cortex_a9_scu_map, 1);
- vexpress_dt_cortex_a9_scu_base = ioremap(phys_addr, SZ_256);
- if (WARN_ON(!vexpress_dt_cortex_a9_scu_base))
- return -EFAULT;
- }
-
- return 0;
-}
-
-void __init vexpress_dt_smp_map_io(void)
-{
- if (initial_boot_params)
- WARN_ON(of_scan_flat_dt(vexpress_dt_find_scu, NULL));
-}
-
-static void __init vexpress_dt_smp_init_cpus(void)
-{
- int ncores = 0, i;
-
- switch (vexpress_dt_scu) {
- case GENERIC_SCU:
- return;
- case CORTEX_A9_SCU:
- ncores = scu_get_core_count(vexpress_dt_cortex_a9_scu_base);
- break;
- default:
- WARN_ON(1);
- break;
- }
-
- if (ncores < 2)
- return;
-
- if (ncores > nr_cpu_ids) {
- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
- ncores, nr_cpu_ids);
- ncores = nr_cpu_ids;
- }
-
- for (i = 0; i < ncores; ++i)
- set_cpu_possible(i, true);
-}
-
-static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)
-{
-
- switch (vexpress_dt_scu) {
- case GENERIC_SCU:
- break;
- case CORTEX_A9_SCU:
- scu_enable(vexpress_dt_cortex_a9_scu_base);
- break;
- default:
- WARN_ON(1);
- break;
- }
-}
-
-#else
-
-static void __init vexpress_dt_smp_init_cpus(void)
-{
- WARN_ON(1);
-}
-
-void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus)
-{
- WARN_ON(1);
-}
-
-#endif
-
/*
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
static void __init vexpress_smp_init_cpus(void)
{
- if (ct_desc)
- ct_desc->init_cpu_map();
- else
- vexpress_dt_smp_init_cpus();
-
+ ct_desc->init_cpu_map();
}
static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus)
@@ -153,10 +40,7 @@ static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus)
* Initialise the present map, which describes the set of CPUs
* actually populated at the present time.
*/
- if (ct_desc)
- ct_desc->smp_enable(max_cpus);
- else
- vexpress_dt_smp_prepare_cpus(max_cpus);
+ ct_desc->smp_enable(max_cpus);
/*
* Write the address of secondary startup into the
@@ -194,3 +78,39 @@ bool __init vexpress_smp_init_ops(void)
#endif
return false;
}
+
+#if defined(CONFIG_OF)
+
+static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = {
+ { .compatible = "arm,cortex-a5-scu", },
+ { .compatible = "arm,cortex-a9-scu", },
+ {}
+};
+
+static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
+{
+ struct device_node *scu = of_find_matching_node(NULL,
+ vexpress_smp_dt_scu_match);
+
+ if (scu)
+ scu_enable(of_iomap(scu, 0));
+
+ /*
+ * Write the address of secondary startup into the
+ * system-wide flags register. The boot monitor waits
+ * until it receives a soft interrupt, and then the
+ * secondary CPU branches to this address.
+ */
+ vexpress_flags_set(virt_to_phys(versatile_secondary_startup));
+}
+
+struct smp_operations __initdata vexpress_smp_dt_ops = {
+ .smp_prepare_cpus = vexpress_smp_dt_prepare_cpus,
+ .smp_secondary_init = versatile_secondary_init,
+ .smp_boot_secondary = versatile_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = vexpress_cpu_die,
+#endif
+};
+
+#endif
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index d8a9fd7..d8b419b 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -400,10 +400,6 @@ void __init v2m_dt_map_io(void)
iotable_init(&v2m_rs1_io_desc, 1);
else
iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
-
-#if defined(CONFIG_SMP)
- vexpress_dt_smp_map_io();
-#endif
}
void __init v2m_dt_init_early(void)
@@ -434,7 +430,7 @@ static const char * const v2m_dt_match[] __initconst = {
DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
.dt_compat = v2m_dt_match,
- .smp = smp_ops(vexpress_smp_ops),
+ .smp = smp_ops(vexpress_smp_dt_ops),
.smp_init = smp_init_ops(vexpress_smp_init_ops),
.map_io = v2m_dt_map_io,
.init_early = v2m_dt_init_early,
--
1.8.3.2
^ permalink raw reply related
* [PATCH 12/12] ARM: vexpress: move HBI check to sysreg driver
From: Pawel Moll @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-1-git-send-email-pawel.moll@arm.com>
The last reason for static memory mapping is the HBI (board
identification number) check early in the machine code.
Moving the check to the sysreg driver makes it possible to
completely remove the early mapping and init functions.
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
arch/arm/mach-vexpress/v2m.c | 49 -------------------------------------------
drivers/mfd/vexpress-sysreg.c | 30 ++++++++++----------------
include/linux/vexpress.h | 1 -
3 files changed, 11 insertions(+), 69 deletions(-)
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index d8b419b..38f4f6f 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -370,53 +370,6 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express")
.init_machine = v2m_init,
MACHINE_END
-static struct map_desc v2m_rs1_io_desc __initdata = {
- .virtual = V2M_PERIPH,
- .pfn = __phys_to_pfn(0x1c000000),
- .length = SZ_2M,
- .type = MT_DEVICE,
-};
-
-static int __init v2m_dt_scan_memory_map(unsigned long node, const char *uname,
- int depth, void *data)
-{
- const char **map = data;
-
- if (strcmp(uname, "motherboard") != 0)
- return 0;
-
- *map = of_get_flat_dt_prop(node, "arm,v2m-memory-map", NULL);
-
- return 1;
-}
-
-void __init v2m_dt_map_io(void)
-{
- const char *map = NULL;
-
- of_scan_flat_dt(v2m_dt_scan_memory_map, &map);
-
- if (map && strcmp(map, "rs1") == 0)
- iotable_init(&v2m_rs1_io_desc, 1);
- else
- iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
-}
-
-void __init v2m_dt_init_early(void)
-{
- u32 dt_hbi;
-
- /* Confirm board type against DT property, if available */
- if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) {
- u32 hbi = vexpress_get_hbi(VEXPRESS_SITE_MASTER);
-
- if (WARN_ON(dt_hbi != hbi))
- pr_warning("vexpress: DT HBI (%x) is not matching "
- "hardware (%x)!\n", dt_hbi, hbi);
- }
-}
-
-
static void __init v2m_dt_init(void)
{
l2x0_of_init(0x00400000, 0xfe0fffff);
@@ -432,7 +385,5 @@ DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
.dt_compat = v2m_dt_match,
.smp = smp_ops(vexpress_smp_dt_ops),
.smp_init = smp_init_ops(vexpress_smp_init_ops),
- .map_io = v2m_dt_map_io,
- .init_early = v2m_dt_init_early,
.init_machine = v2m_dt_init,
MACHINE_END
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
index 57c21a0..3eb26e1 100644
--- a/drivers/mfd/vexpress-sysreg.c
+++ b/drivers/mfd/vexpress-sysreg.c
@@ -44,7 +44,6 @@
#define SYS_CFGSTAT 0x0a8
#define SYS_HBI_MASK 0xfff
-#define SYS_ID_HBI_SHIFT 16
#define SYS_PROCIDx_HBI_SHIFT 0
#define SYS_MCI_CARDIN (1 << 0)
@@ -98,24 +97,6 @@ u32 vexpress_get_procid(int site)
SYS_PROCID0 : SYS_PROCID1));
}
-u32 vexpress_get_hbi(int site)
-{
- u32 id;
-
- switch (site) {
- case VEXPRESS_SITE_MB:
- id = readl(vexpress_sysreg_base() + SYS_ID);
- return (id >> SYS_ID_HBI_SHIFT) & SYS_HBI_MASK;
- case VEXPRESS_SITE_MASTER:
- case VEXPRESS_SITE_DB1:
- case VEXPRESS_SITE_DB2:
- id = vexpress_get_procid(site);
- return (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
- }
-
- return ~0;
-}
-
void __iomem *vexpress_get_24mhz_clock_base(void)
{
return vexpress_sysreg_base() + SYS_24MHZ;
@@ -222,6 +203,7 @@ static int vexpress_sysreg_probe(struct platform_device *pdev)
struct resource *mem;
void __iomem *base;
struct bgpio_chip *mmc_gpio_chip;
+ u32 dt_hbi;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem)
@@ -233,6 +215,16 @@ static int vexpress_sysreg_probe(struct platform_device *pdev)
vexpress_config_set_master(vexpress_sysreg_get_master());
+ /* Confirm board type against DT property, if available */
+ if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) {
+ u32 id = vexpress_get_procid(VEXPRESS_SITE_MASTER);
+ u32 hbi = (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
+
+ if (WARN_ON(dt_hbi != hbi))
+ dev_warn(&pdev->dev, "DT HBI (%x) is not matching hardware (%x)!\n",
+ dt_hbi, hbi);
+ }
+
/*
* Duplicated SYS_MCI pseudo-GPIO controller for compatibility with
* older trees using sysreg node for MMC control lines.
diff --git a/include/linux/vexpress.h b/include/linux/vexpress.h
index 0aee1b9..06e1ab8 100644
--- a/include/linux/vexpress.h
+++ b/include/linux/vexpress.h
@@ -60,7 +60,6 @@ struct regmap *devm_regmap_init_vexpress_config(struct device *dev);
unsigned int vexpress_get_mci_cardin(struct device *dev);
u32 vexpress_get_procid(int site);
-u32 vexpress_get_hbi(int site);
void *vexpress_get_24mhz_clock_base(void);
void vexpress_flags_set(u32 data);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 4/8] ARM: mvebu: make use of of_find_matching_node_and_match
From: Thomas Petazzoni @ 2014-02-11 17:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140211165314.GA8533@titan.lakedaemon.net>
Dear Jason Cooper,
On Tue, 11 Feb 2014 11:53:14 -0500, Jason Cooper wrote:
> > - np = of_find_matching_node(NULL, of_system_controller_table);
> > + np = of_find_matching_node_and_match(NULL, of_system_controller_table,
> > + &match);
> > if (np) {
> > - const struct of_device_id *match =
> > - of_match_node(of_system_controller_table, np);
>
>
> > - BUG_ON(!match);
>
> Gregory, is it ok to remove this? It was added with the original code
> submission for mach-mvebu. mvebu_restart() will handle this
> gracefully...
The BUG_ON here can normally never be reached. If
of_find_matching_node() returns a non-NULL result, then of_match_node()
should also return a non-NULL result.
Or I'm missing something :)
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH 05/12] GPIO: gpio-generic: Add label to platform data
From: Lee Jones @ 2014-02-11 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-6-git-send-email-pawel.moll@arm.com>
> When registering more than one platform device, it is
> useful to set the gpio chip label in the platform data.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Alexandre Courbot <gnurou@gmail.com>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Lee Jones <lee.jones@linaro.org>
> Signed-off-by: Pawel Moll <pawel.moll@arm.com>
> ---
> This patch has been already merged by Linux; it has been included
> for completeness only.
>
> drivers/gpio/gpio-generic.c | 2 ++
> include/linux/basic_mmio_gpio.h | 1 +
> 2 files changed, 3 insertions(+)
>
> diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c
> index d2196bf..8c778af 100644
> --- a/drivers/gpio/gpio-generic.c
> +++ b/drivers/gpio/gpio-generic.c
> @@ -531,6 +531,8 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
> return err;
>
> if (pdata) {
> + if (pdata->label)
Why is this check necessary?
> + bgc->gc.label = pdata->label;
> bgc->gc.base = pdata->base;
> if (pdata->ngpio > 0)
> bgc->gc.ngpio = pdata->ngpio;
> diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h
> index d8a97ec..0e97856 100644
> --- a/include/linux/basic_mmio_gpio.h
> +++ b/include/linux/basic_mmio_gpio.h
> @@ -19,6 +19,7 @@
> #include <linux/spinlock_types.h>
>
> struct bgpio_pdata {
> + const char *label;
> int base;
> int ngpio;
> };
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 06/12] mfd: vexpress-sysreg: Add labels to gpio banks
From: Lee Jones @ 2014-02-11 17:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-7-git-send-email-pawel.moll@arm.com>
> ... so debugfs interfaces are easier to use.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Alexandre Courbot <gnurou@gmail.com>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Lee Jones <lee.jones@linaro.org>
> Signed-off-by: Pawel Moll <pawel.moll@arm.com>
> ---
> drivers/mfd/vexpress-sysreg.c | 3 +++
> 1 file changed, 3 insertions(+)
Acked-by: Lee Jones <lee.jones@linaro.org>
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 05/12] GPIO: gpio-generic: Add label to platform data
From: Pawel Moll @ 2014-02-11 17:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140211171721.GE15081@lee--X1>
On Tue, 2014-02-11 at 17:17 +0000, Lee Jones wrote:
> > When registering more than one platform device, it is
> > useful to set the gpio chip label in the platform data.
> >
> > Cc: Linus Walleij <linus.walleij@linaro.org>
> > Cc: Alexandre Courbot <gnurou@gmail.com>
> > Cc: Samuel Ortiz <sameo@linux.intel.com>
> > Cc: Lee Jones <lee.jones@linaro.org>
> > Signed-off-by: Pawel Moll <pawel.moll@arm.com>
> > ---
> > This patch has been already merged by Linux; it has been included
> > for completeness only.
> >
> > drivers/gpio/gpio-generic.c | 2 ++
> > include/linux/basic_mmio_gpio.h | 1 +
> > 2 files changed, 3 insertions(+)
> >
> > diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c
> > index d2196bf..8c778af 100644
> > --- a/drivers/gpio/gpio-generic.c
> > +++ b/drivers/gpio/gpio-generic.c
> > @@ -531,6 +531,8 @@ static int bgpio_pdev_probe(struct platform_device *pdev)
> > return err;
> >
> > if (pdata) {
> > + if (pdata->label)
>
> Why is this check necessary?
>
> > + bgc->gc.label = pdata->label;
Because bgc->gc.label is initialized to a default value in bgpio_init()
and I don't want to override it with NULL if there is no label passed in
the platform data.
Pawel
-- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
ARM Limited, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No: 2557590
ARM Holdings plc, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No: 2548782
^ permalink raw reply
* [PATCH 07/12] mfd: syscon: Consider platform data a regmap config name
From: Lee Jones @ 2014-02-11 17:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-8-git-send-email-pawel.moll@arm.com>
> Use the device platform data as a regmap config
> name. This is particularly useful in the regmap
> debugfs when there is more than one syscon device
> registered, to distinguish the register blocks.
>
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Lee Jones <lee.jones@linaro.org>
> Signed-off-by: Pawel Moll <pawel.moll@arm.com>
> ---
> Alternatively I could define a syscon platform data structure,
> something like this:
>
> struct syscon_platform_data {
> const char *label;
> };
>
> drivers/mfd/syscon.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
> index 71841f9..ea1770b 100644
> --- a/drivers/mfd/syscon.c
> +++ b/drivers/mfd/syscon.c
> @@ -143,6 +143,7 @@ static int syscon_probe(struct platform_device *pdev)
> return -ENOMEM;
>
> syscon_regmap_config.max_register = res->end - res->start - 3;
> + syscon_regmap_config.name = dev_get_platdata(&pdev->dev);
Perhaps the answer is waiting for me in the other set, but ...
Isn't this going to be NULL most of the time?
> syscon->regmap = devm_regmap_init_mmio(dev, base,
> &syscon_regmap_config);
> if (IS_ERR(syscon->regmap)) {
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH] Fix uses of dma_max_pfn() when converting to a limiting address
From: Russell King @ 2014-02-11 17:28 UTC (permalink / raw)
To: linux-arm-kernel
We must use a 64-bit for this, otherwise overflowed bits get lost, and
that can result in a lower than intended value set.
Fixes: 8e0cb8a1f6ac ("ARM: 7797/1: mmc: Use dma_max_pfn(dev) helper for bounce_limit calculations")
Fixes: 7d35496dd982 ("ARM: 7796/1: scsi: Use dma_max_pfn(dev) helper for bounce_limit calculations")
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
While poking about with the Cubox-i4 and investigating why my UHS-1
SD card wasn't achieving its full potential, I came across a slight
problem... the SDHCI host sets a mask of 0xffffffff, but with the
start of memory at pfn 0x10000, the blk code sees this when setting
the bounce limit:
max addr 0x0ffff000 bounce limit 0xffff dma 1
and this results in the bounce functions appearing in the profile:
00000000c00f8b70 copy_to_high_bio_irq 1139 2.5886
00000000c00f8d28 bounce_end_io 12 0.0714
00000000c00f8dd0 bounce_end_io_read_isa 8 0.1053
which, compared to the cost of copying the data to userland and
request handling, this is quite significant:
00000000c04b1794 sdhci_request 268 0.5447
00000000c02d0740 __copy_to_user_std 398 0.4252
With this calculation fixed, we avoid the bouncing code entirely.
max addr 0x10ffff000 bounce limit 0x10ffff dma 0
drivers/mmc/card/queue.c | 2 +-
drivers/scsi/scsi_lib.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 357bbc54fe4b..3e049c13429c 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -197,7 +197,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
struct mmc_queue_req *mqrq_prev = &mq->mqrq[1];
if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
- limit = dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
+ limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
mq->card = card;
mq->queue = blk_init_queue(mmc_request_fn, lock);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 7bd7f0d5f050..62ec84b42e31 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1684,7 +1684,7 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
host_dev = scsi_get_device(shost);
if (host_dev && host_dev->dma_mask)
- bounce_limit = dma_max_pfn(host_dev) << PAGE_SHIFT;
+ bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
return bounce_limit;
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH 08/12] mfd: vexpress-sysreg: Add syscon labels as platform data
From: Lee Jones @ 2014-02-11 17:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392138636-29240-9-git-send-email-pawel.moll@arm.com>
> This patch adds label names for syscon registers as platform
> data for the relevant MFD cells.
Okay, I see.
Hmm... not sure I like this at all. It seems awfully as though you're
bending current infrastructure to suit your needs. There must be better
ways of passing a name than through pdata, and if there isn't I'd
suggest setting up a sysconf pdata struct that others can use in case
they wish to expand the functionality further in some other
unfathomable way. :)
> Cc: Samuel Ortiz <sameo@linux.intel.com>
> Cc: Lee Jones <lee.jones@linaro.org>
> Signed-off-by: Pawel Moll <pawel.moll@arm.com>
> ---
> drivers/mfd/vexpress-sysreg.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c
> index ece5ac8..57c21a0 100644
> --- a/drivers/mfd/vexpress-sysreg.c
> +++ b/drivers/mfd/vexpress-sysreg.c
> @@ -132,6 +132,8 @@ void __init vexpress_sysreg_early_init(void __iomem *base)
>
> /* The sysreg block is just a random collection of various functions... */
>
> +static const char vexpress_sysreg_sys_id_pdata[] = "sys_id";
> +
> static struct bgpio_pdata vexpress_sysreg_sys_led_pdata = {
> .label = "sys_led",
> .base = -1,
> @@ -150,6 +152,10 @@ static struct bgpio_pdata vexpress_sysreg_sys_flash_pdata = {
> .ngpio = 1,
> };
>
> +static const char vexpress_sysreg_sys_misc_pdata[] = "sys_misc";
> +
> +static const char vexpress_sysreg_sys_procid_pdata[] = "sys_procid";
> +
> static struct mfd_cell vexpress_sysreg_cells[] = {
> {
> .name = "syscon",
> @@ -157,6 +163,8 @@ static struct mfd_cell vexpress_sysreg_cells[] = {
> .resources = (struct resource []) {
> DEFINE_RES_MEM(SYS_ID, 0x4),
> },
> + .platform_data = &vexpress_sysreg_sys_id_pdata,
> + .pdata_size = sizeof(vexpress_sysreg_sys_id_pdata),
> }, {
> .name = "basic-mmio-gpio",
> .of_compatible = "arm,vexpress-sysreg,sys_led",
> @@ -190,12 +198,16 @@ static struct mfd_cell vexpress_sysreg_cells[] = {
> .resources = (struct resource []) {
> DEFINE_RES_MEM(SYS_MISC, 0x4),
> },
> + .platform_data = &vexpress_sysreg_sys_misc_pdata,
> + .pdata_size = sizeof(vexpress_sysreg_sys_misc_pdata),
> }, {
> .name = "syscon",
> .num_resources = 1,
> .resources = (struct resource []) {
> DEFINE_RES_MEM(SYS_PROCID0, 0x8),
> },
> + .platform_data = &vexpress_sysreg_sys_procid_pdata,
> + .pdata_size = sizeof(vexpress_sysreg_sys_procid_pdata),
> }, {
> .name = "vexpress-syscfg",
> .num_resources = 1,
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 05/12] GPIO: gpio-generic: Add label to platform data
From: Pawel Moll @ 2014-02-11 17:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392139256.3380.45.camel@hornet>
On Tue, 2014-02-11 at 17:20 +0000, Pawel Moll wrote:
> -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
>
> ARM Limited, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No: 2557590
> ARM Holdings plc, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No: 2548782
Uh, sorry about this. My finger slipped...
Pawel
^ permalink raw reply
* [Patch v5 1/2] dmaengine: add Qualcomm BAM dma driver
From: Vinod Koul @ 2014-02-11 17:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391546556-27702-2-git-send-email-agross@codeaurora.org>
On Tue, Feb 04, 2014 at 02:42:35PM -0600, Andy Gross wrote:
> Add the DMA engine driver for the QCOM Bus Access Manager (BAM) DMA controller
> found in the MSM 8x74 platforms.
>
> Each BAM DMA device is associated with a specific on-chip peripheral. Each
> channel provides a uni-directional data transfer engine that is capable of
> transferring data between the peripheral and system memory (System mode), or
> between two peripherals (BAM2BAM).
>
> The initial release of this driver only supports slave transfers between
> peripherals and system memory.
>
> Signed-off-by: Andy Gross <agross@codeaurora.org>
> +++ b/drivers/dma/qcom_bam_dma.c
> @@ -0,0 +1,1066 @@
> +/*
> + * QCOM BAM DMA engine driver
> + *
> + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
This is bit strange, usually copyright is retained by your employer, but I am
fine with it :)
> +struct bam_desc_hw {
> + u32 addr; /* Buffer physical address */
this is where we might have an issue. Is this the DMA register which is 32bit
wide or you are descibing it so.
Will this work if you are in 64 bit?
> + u16 size; /* Buffer size in bytes */
> + u16 flags;
> +};
> +
> +/**
> + * bam_reset_channel - Reset individual BAM DMA channel
> + * @bchan: bam channel
> + *
> + * This function resets a specific BAM channel
> + */
> +static void bam_reset_channel(struct bam_chan *bchan)
> +{
> + struct bam_device *bdev = bchan->bdev;
> +
> + /* reset channel */
> + writel_relaxed(1, bdev->regs + BAM_P_RST(bchan->id));
> + writel_relaxed(0, bdev->regs + BAM_P_RST(bchan->id));
> +
> + /* don't allow reorder of the channel reset */
> + wmb();
Documentation/memory-barriers.txt describes wmb() as a CPU barier but based on
above you want it to be a compiler barrier then you should do 1st write,
barrier(), second write.
> +
> + /* make sure hw is initialized when channel is used the first time */
> + bchan->initialized = 0;
> +}
okay why no locks held while reset?
> +
> +/**
> + * bam_chan_init_hw - Initialize channel hardware
> + * @bchan: bam channel
> + *
> + * This function resets and initializes the BAM channel
> + */
> +static void bam_chan_init_hw(struct bam_chan *bchan,
> + enum dma_transfer_direction dir)
> +{
> + struct bam_device *bdev = bchan->bdev;
> + u32 val;
> +
> + /* Reset the channel to clear internal state of the FIFO */
> + bam_reset_channel(bchan);
> +
> + /*
> + * write out 8 byte aligned address. We have enough space for this
> + * because we allocated 1 more descriptor (8 bytes) than we can use
> + */
> + writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)),
> + bdev->regs + BAM_P_DESC_FIFO_ADDR(bchan->id));
> + writel_relaxed(BAM_DESC_FIFO_SIZE, bdev->regs +
> + BAM_P_FIFO_SIZES(bchan->id));
> +
> + /* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */
> + writel_relaxed(P_DEFAULT_IRQS_EN, bdev->regs + BAM_P_IRQ_EN(bchan->id));
> +
> + /* unmask the specific pipe and EE combo */
> + val = readl_relaxed(bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
> + val |= BIT(bchan->id);
> + writel_relaxed(val, bdev->regs + BAM_IRQ_SRCS_MSK_EE(bdev->ee));
> +
> + /* set fixed direction and mode, then enable channel */
> + val = P_EN | P_SYS_MODE;
> + if (dir == DMA_DEV_TO_MEM)
> + val |= P_DIRECTION;
> +
> + /* make sure the other stores occur before enabling channel */
> + wmb();
here again!
> + writel_relaxed(val, bdev->regs + BAM_P_CTRL(bchan->id));
> +
> + bchan->initialized = 1;
> +
> + /* init FIFO pointers */
> + bchan->head = 0;
> + bchan->tail = 0;
> +}
> +
> +/**
> + * bam_alloc_chan - Allocate channel resources for DMA channel.
> + * @chan: specified channel
> + *
> + * This function allocates the FIFO descriptor memory
> + */
> +static int bam_alloc_chan(struct dma_chan *chan)
> +{
> + struct bam_chan *bchan = to_bam_chan(chan);
> + struct bam_device *bdev = bchan->bdev;
> +
> + /* allocate FIFO descriptor space, but only if necessary */
> + if (!bchan->fifo_virt) {
> + bchan->fifo_virt = dma_alloc_writecombine(bdev->dev,
> + BAM_DESC_FIFO_SIZE, &bchan->fifo_phys,
> + GFP_KERNEL);
> +
> + if (!bchan->fifo_virt) {
> + dev_err(bdev->dev, "Failed to allocate desc fifo\n");
> + return -ENOMEM;
> + }
> + }
> +
> + return BAM_DESC_FIFO_SIZE;
But you cna have SW descriptors more than HW ones and issue new ones once HW is
done with them. Why tie the limit to what HW supports and not create a better
driver?
> +
> +/**
> + * bam_slave_config - set slave configuration for channel
> + * @chan: dma channel
> + * @cfg: slave configuration
> + *
> + * Sets slave configuration for channel
> + *
> + */
> +static void bam_slave_config(struct bam_chan *bchan,
> + struct dma_slave_config *cfg)
> +{
> + struct bam_device *bdev = bchan->bdev;
> + u32 maxburst;
> +
> + if (bchan->slave.direction == DMA_DEV_TO_MEM)
> + maxburst = bchan->slave.src_maxburst = cfg->src_maxburst;
> + else
> + maxburst = bchan->slave.dst_maxburst = cfg->dst_maxburst;
can you remove usage of slave.direction have save both. I am going to remove
this member...
> +
> + /* set desc threshold */
> + writel_relaxed(maxburst, bdev->regs + BAM_DESC_CNT_TRSHLD);
> +}
> +
> +/**
> + * bam_prep_slave_sg - Prep slave sg transaction
> + *
> + * @chan: dma channel
> + * @sgl: scatter gather list
> + * @sg_len: length of sg
> + * @direction: DMA transfer direction
> + * @flags: DMA flags
> + * @context: transfer context (unused)
> + */
> +static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan,
> + struct scatterlist *sgl, unsigned int sg_len,
> + enum dma_transfer_direction direction, unsigned long flags,
> + void *context)
> +{
> + struct bam_chan *bchan = to_bam_chan(chan);
> + struct bam_device *bdev = bchan->bdev;
> + struct bam_async_desc *async_desc;
> + struct scatterlist *sg;
> + u32 i;
> + struct bam_desc_hw *desc;
> +
> +
> + if (!is_slave_direction(direction)) {
> + dev_err(bdev->dev, "invalid dma direction\n");
> + return NULL;
> + }
> +
> +
> + /* allocate enough room to accomodate the number of entries */
> + async_desc = kzalloc(sizeof(*async_desc) +
> + (sg_len * sizeof(struct bam_desc_hw)), GFP_NOWAIT);
this seems to assume that each sg entry length will not exceed the HW capablity.
Does engine support any length descriptor, if not you may want to split to
multiple.
> +
> + if (!async_desc) {
> + dev_err(bdev->dev, "failed to allocate async descriptor\n");
> + goto err_out;
> + }
> +
> + async_desc->num_desc = sg_len;
> + async_desc->curr_desc = async_desc->desc;
> + async_desc->dir = direction;
> +
> + /* fill in descriptors, align hw descriptor to 8 bytes */
> + desc = async_desc->desc;
> + for_each_sg(sgl, sg, sg_len, i) {
> + if (sg_dma_len(sg) > BAM_MAX_DATA_SIZE) {
> + dev_err(bdev->dev, "segment exceeds max size\n");
> + goto err_out;
gottcha, okay why not split here to multiple descriptors with max size all but
last?
> + }
> +
> + desc->addr = sg_dma_address(sg);
> + desc->size = sg_dma_len(sg);
> + async_desc->length += sg_dma_len(sg);
> + desc++;
> + }
> +
> + return vchan_tx_prep(&bchan->vc, &async_desc->vd, flags);
> +
> +err_out:
> + kfree(async_desc);
> + return NULL;
> +}
> +
> +/**
> + * bam_dma_terminate_all - terminate all transactions on a channel
> + * @bchan: bam dma channel
> + *
> + * Dequeues and frees all transactions
> + * No callbacks are done
> + *
> + */
> +static void bam_dma_terminate_all(struct bam_chan *bchan)
> +{
> + unsigned long flag;
> + LIST_HEAD(head);
> +
> + /* remove all transactions, including active transaction */
> + spin_lock_irqsave(&bchan->vc.lock, flag);
> + if (bchan->curr_txd) {
> + list_add(&bchan->curr_txd->vd.node, &bchan->vc.desc_issued);
> + bchan->curr_txd = NULL;
> + }
> +
> + vchan_get_all_descriptors(&bchan->vc, &head);
> + spin_unlock_irqrestore(&bchan->vc.lock, flag);
> +
> + vchan_dma_desc_free_list(&bchan->vc, &head);
why drop the lock here, i dont think this one needs to be called with lock
dropped, didnt see it garbbing.
> +}
> +
> +/**
> + * bam_control - DMA device control
> + * @chan: dma channel
> + * @cmd: control cmd
> + * @arg: cmd argument
> + *
> + * Perform DMA control command
> + *
> + */
> +static int bam_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
> + unsigned long arg)
> +{
> + struct bam_chan *bchan = to_bam_chan(chan);
> + struct bam_device *bdev = bchan->bdev;
> + int ret = 0;
> + unsigned long flag;
> +
> + switch (cmd) {
> + case DMA_PAUSE:
> + spin_lock_irqsave(&bchan->vc.lock, flag);
> + writel_relaxed(1, bdev->regs + BAM_P_HALT(bchan->id));
> + bchan->paused = 1;
> + spin_unlock_irqrestore(&bchan->vc.lock, flag);
> + break;
> + case DMA_RESUME:
> + spin_lock_irqsave(&bchan->vc.lock, flag);
> + writel_relaxed(0, bdev->regs + BAM_P_HALT(bchan->id));
> + bchan->paused = 0;
> + spin_unlock_irqrestore(&bchan->vc.lock, flag);
> + break;
> + case DMA_TERMINATE_ALL:
> + bam_dma_terminate_all(bchan);
> + break;
> + case DMA_SLAVE_CONFIG:
> + bam_slave_config(bchan, (struct dma_slave_config *)arg);
> + break;
> + default:
> + ret = -ENXIO;
> + break;
> + }
empty line after each break would be appreciated.
> +
> + return ret;
> +}
> +
> +/**
> + * bam_start_dma - start next transaction
> + * @bchan - bam dma channel
> + *
> + * Note: must hold bam dma channel vc.lock
> + */
> +static void bam_start_dma(struct bam_chan *bchan)
> +{
> + struct virt_dma_desc *vd = vchan_next_desc(&bchan->vc);
> + struct bam_device *bdev = bchan->bdev;
> + struct bam_async_desc *async_desc;
> + struct bam_desc_hw *desc;
> + struct bam_desc_hw *fifo = PTR_ALIGN(bchan->fifo_virt,
> + sizeof(struct bam_desc_hw));
> +
> + if (!vd)
> + return;
> +
> + list_del(&vd->node);
> +
> + async_desc = container_of(vd, struct bam_async_desc, vd);
> + bchan->curr_txd = async_desc;
> +
> + /* on first use, initialize the channel hardware */
> + if (!bchan->initialized)
> + bam_chan_init_hw(bchan, async_desc->dir);
> +
> +
> + desc = bchan->curr_txd->curr_desc;
> +
> + if (async_desc->num_desc > MAX_DESCRIPTORS)
> + async_desc->xfer_len = MAX_DESCRIPTORS;
> + else
> + async_desc->xfer_len = async_desc->num_desc;
> +
> + /* set INT on last descriptor */
> + desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT;
> +
> + if (bchan->tail + async_desc->xfer_len > MAX_DESCRIPTORS) {
> + u32 partial = MAX_DESCRIPTORS - bchan->tail;
> +
> + memcpy(&fifo[bchan->tail], desc,
> + partial * sizeof(struct bam_desc_hw));
> + memcpy(fifo, &desc[partial], (async_desc->xfer_len - partial) *
> + sizeof(struct bam_desc_hw));
> + } else {
> + memcpy(&fifo[bchan->tail], desc,
> + async_desc->xfer_len * sizeof(struct bam_desc_hw));
where is the destination memeory located, device or system memory. I think
later, right?
> + }
> +
> + bchan->tail += async_desc->xfer_len;
> + bchan->tail %= MAX_DESCRIPTORS;
> +
> + /* ensure descriptor writes and dma start not reordered */
> + wmb();
> + writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw),
> + bdev->regs + BAM_P_EVNT_REG(bchan->id));
> +}
> +
Overall driver loooks fine mostly with few comments as above.
And yes for 2nd patch, would need someone to ACK it before we can appply this
--
~Vinod
^ permalink raw reply
* [PATCH 4/8] ARM: mvebu: make use of of_find_matching_node_and_match
From: Gregory CLEMENT @ 2014-02-11 17:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140211181048.6934bdd3@skate>
On 11/02/2014 18:10, Thomas Petazzoni wrote:
> Dear Jason Cooper,
>
> On Tue, 11 Feb 2014 11:53:14 -0500, Jason Cooper wrote:
>
>>> - np = of_find_matching_node(NULL, of_system_controller_table);
>>> + np = of_find_matching_node_and_match(NULL, of_system_controller_table,
>>> + &match);
>>> if (np) {
>>> - const struct of_device_id *match =
>>> - of_match_node(of_system_controller_table, np);
>>
>>
>>> - BUG_ON(!match);
>>
>> Gregory, is it ok to remove this? It was added with the original code
>> submission for mach-mvebu. mvebu_restart() will handle this
>> gracefully...
>
> The BUG_ON here can normally never be reached. If
> of_find_matching_node() returns a non-NULL result, then of_match_node()
> should also return a non-NULL result.
>
> Or I'm missing something :)
No you're almost right!
The only case we can get it, would be if we were declaring something like:
static struct of_device_id of_system_controller_table[] = {
{
.compatible = "foo,bar-controller",
},
[...]
instead of
static struct of_device_id of_system_controller_table[] = {
{
.compatible = "foo,bar",
.data = (void *) &bar_controller,
},
[...]
This test is very paranoid, so I agree to remove it.
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Thanks,
Gregory
>
> Thomas
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 08/12] mfd: vexpress-sysreg: Add syscon labels as platform data
From: Pawel Moll @ 2014-02-11 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140211172918.GH15081@lee--X1>
On Tue, 2014-02-11 at 17:29 +0000, Lee Jones wrote:
> There must be better
> ways of passing a name than through pdata, and if there isn't I'd
> suggest setting up a sysconf pdata struct that others can use in case
> they wish to expand the functionality further in some other
> unfathomable way. :)
... which I proposed in the previous patch :-)
On Tue, 2014-02-11 at 17:10 +0000, Pawel Moll wrote:
> Alternatively I could define a syscon platform data structure,
> something like this:
>
> struct syscon_platform_data {
> const char *label;
> };
Pawel
^ permalink raw reply
* [PATCH 1/3] driver core & of: Mark of_nodes of added device as populated
From: Christopher Covington @ 2014-02-11 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1392137610-27842-2-git-send-email-pawel.moll@arm.com>
Hi Pawel,
On 02/11/2014 11:53 AM, Pawel Moll wrote:
> This patch tries to solve that issue in a generic way,
> adding a "populated" flag which is set in the device_node
> structure when a device is being created in the core.
> Later, of_platform_populate() skips such nodes (and
> its children) in a similar way to the non-available ones.
Will there never be a case where it is useful for a parent node to be created
early, but not necessarily the child nodes? Might only skipping nodes
explicitly marked as populated be a more universal solution?
Regards,
Christopher
--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by the Linux Foundation.
^ permalink raw reply
* [PATCH 4/8] ARM: mvebu: make use of of_find_matching_node_and_match
From: Jason Cooper @ 2014-02-11 17:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52FA5E75.7030402@free-electrons.com>
On Tue, Feb 11, 2014 at 06:31:33PM +0100, Gregory CLEMENT wrote:
> On 11/02/2014 18:10, Thomas Petazzoni wrote:
> > Dear Jason Cooper,
> >
> > On Tue, 11 Feb 2014 11:53:14 -0500, Jason Cooper wrote:
> >
> >>> - np = of_find_matching_node(NULL, of_system_controller_table);
> >>> + np = of_find_matching_node_and_match(NULL, of_system_controller_table,
> >>> + &match);
> >>> if (np) {
> >>> - const struct of_device_id *match =
> >>> - of_match_node(of_system_controller_table, np);
> >>
> >>
> >>> - BUG_ON(!match);
> >>
> >> Gregory, is it ok to remove this? It was added with the original code
> >> submission for mach-mvebu. mvebu_restart() will handle this
> >> gracefully...
> >
> > The BUG_ON here can normally never be reached. If
> > of_find_matching_node() returns a non-NULL result, then of_match_node()
> > should also return a non-NULL result.
> >
> > Or I'm missing something :)
>
> No you're almost right!
>
> The only case we can get it, would be if we were declaring something like:
>
> static struct of_device_id of_system_controller_table[] = {
> {
> .compatible = "foo,bar-controller",
> },
> [...]
>
> instead of
>
> static struct of_device_id of_system_controller_table[] = {
> {
> .compatible = "foo,bar",
> .data = (void *) &bar_controller,
> },
> [...]
>
> This test is very paranoid, so I agree to remove it.
>
>
> Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Ok, great! Josh, do you want us to take the two mvebu patches through
mvebu/arm-soc? Or would you prefer to take them?
thx,
Jason.
^ permalink raw reply
* [PATCH] reset: Add generic GPIO reset driver.
From: Philipp Zabel @ 2014-02-11 17:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANh8QzwERe-zxCaAd4QujZJ4zcZ7SchK+w8u52fvJj0s5tx2nA@mail.gmail.com>
Hi Martin,
Am Dienstag, den 11.02.2014, 10:34 +0100 schrieb Fuzzey, Martin:
[...]
> >> 2) Allow hardware on discoverable busses to be rest via a GPIO line
> >> without driver modifications.
> >>
> >> Examples of the second use case include:
> >> * SDIO wifi modules
> >> * USB hub chips with a reset line
> >
> > Now this is interesting. But if you export it to userspace anyway, why
> > not use the existing gpio sysfs API?
> >
>
> In the normal case of reset on boot the userspace interface isn't needed.
> Setting the "auto" dt property will make the kernel do the reset by
> itself during
> early boot. This is the standard use case.
>
> The userspace interface is to let applications deal with special cases.
> It is also simpler for userspace than manlually toggling the GPIO line
> and keeps the configuration (active high / low, delay) centralised in
> the DT and consistent between the automatic on boot reset and the
> manually triggered reset.
>
> > I think a proper solution should handle this in the kernel. For SDIO
> > wifi modules you usually have a powerdown line that can be implemented
> > as an rfkill switch.
> >
>
> I think this is too specific. It's not just for SDIO wifi. We also
> have the problem
> of a USB hub needing to be reset.
>
> Also even for the SDIO wifi case rfkill doesn't ssem the right
> abstraction to say "reset me"
> (particularly when firmware fails to load on warm boot if you don't).
so long as you need to take devices out of reset before they can be
discovered, maybe the corresponding host controller would be the right
place to put the reset.
regards
Philipp
^ 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