* [PATCH v4 2/2] usb: musb: dsps, use devm_kzalloc
From: Markus Pargmann @ 2014-01-17 9:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389950556-6453-1-git-send-email-mpa@pengutronix.de>
Replace kzalloc by devm_kzalloc and remove the kfree() calls.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/usb/musb/musb_dsps.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index d0a97d6..6cae0c8 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -668,7 +668,7 @@ static int dsps_probe(struct platform_device *pdev)
wrp = match->data;
/* allocate glue */
- glue = kzalloc(sizeof(*glue), GFP_KERNEL);
+ glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
if (!glue) {
dev_err(&pdev->dev, "unable to allocate glue memory\n");
return -ENOMEM;
@@ -696,7 +696,6 @@ err3:
pm_runtime_put(&pdev->dev);
err2:
pm_runtime_disable(&pdev->dev);
- kfree(glue);
return ret;
}
@@ -709,7 +708,6 @@ static int dsps_remove(struct platform_device *pdev)
/* disable usbss clocks */
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- kfree(glue);
debugfs_remove_recursive(glue->dbgfs_root);
--
1.8.5.2
^ permalink raw reply related
* [PATCH v4 1/2] usb: musb: dsps, debugfs files
From: Markus Pargmann @ 2014-01-17 9:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389950556-6453-1-git-send-email-mpa@pengutronix.de>
debugfs files to show the contents of important dsps registers.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/usb/musb/musb_dsps.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 593d3c9..d0a97d6 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -46,6 +46,8 @@
#include <linux/of_irq.h>
#include <linux/usb/of.h>
+#include <linux/debugfs.h>
+
#include "musb_core.h"
static const struct of_device_id musb_dsps_of_match[];
@@ -137,6 +139,26 @@ struct dsps_glue {
unsigned long last_timer; /* last timer data for each instance */
struct dsps_context context;
+ struct debugfs_regset32 regset;
+ struct dentry *dbgfs_root;
+};
+
+static const struct debugfs_reg32 dsps_musb_regs[] = {
+ { "revision", 0x00 },
+ { "control", 0x14 },
+ { "status", 0x18 },
+ { "eoi", 0x24 },
+ { "intr0_stat", 0x30 },
+ { "intr1_stat", 0x34 },
+ { "intr0_set", 0x38 },
+ { "intr1_set", 0x3c },
+ { "txmode", 0x70 },
+ { "rxmode", 0x74 },
+ { "autoreq", 0xd0 },
+ { "srpfixtime", 0xd4 },
+ { "tdown", 0xd8 },
+ { "phy_utmi", 0xe0 },
+ { "mode", 0xe8 },
};
static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
@@ -369,6 +391,30 @@ out:
return ret;
}
+static int dsps_musb_dbg_init(struct musb *musb, struct dsps_glue *glue)
+{
+ struct dentry *root;
+ struct dentry *file;
+ char buf[128];
+
+ sprintf(buf, "%s.dsps", dev_name(musb->controller));
+ root = debugfs_create_dir(buf, NULL);
+ if (!root)
+ return -ENOMEM;
+ glue->dbgfs_root = root;
+
+ glue->regset.regs = dsps_musb_regs;
+ glue->regset.nregs = ARRAY_SIZE(dsps_musb_regs);
+ glue->regset.base = musb->ctrl_base;
+
+ file = debugfs_create_regset32("regdump", S_IRUGO, root, &glue->regset);
+ if (!file) {
+ debugfs_remove_recursive(root);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
static int dsps_musb_init(struct musb *musb)
{
struct device *dev = musb->controller;
@@ -378,6 +424,7 @@ static int dsps_musb_init(struct musb *musb)
void __iomem *reg_base;
struct resource *r;
u32 rev, val;
+ int ret;
r = platform_get_resource_byname(parent, IORESOURCE_MEM, "control");
if (!r)
@@ -411,6 +458,10 @@ static int dsps_musb_init(struct musb *musb)
val &= ~(1 << wrp->otg_disable);
dsps_writel(musb->ctrl_base, wrp->phy_utmi, val);
+ ret = dsps_musb_dbg_init(musb, glue);
+ if (ret)
+ return ret;
+
return 0;
}
@@ -659,6 +710,9 @@ static int dsps_remove(struct platform_device *pdev)
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
kfree(glue);
+
+ debugfs_remove_recursive(glue->dbgfs_root);
+
return 0;
}
--
1.8.5.2
^ permalink raw reply related
* [PATCH v4 0/2] usb: musb dsps updates
From: Markus Pargmann @ 2014-01-17 9:22 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
The two remaining patches from the previous series "usb: musb bugfixes". In v4
I used the device name for the debugfs root dir and added a commit message to
the second patch.
Regards,
Markus
Markus Pargmann (2):
usb: musb: dsps, debugfs files
usb: musb: dsps, use devm_kzalloc
drivers/usb/musb/musb_dsps.c | 58 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 55 insertions(+), 3 deletions(-)
--
1.8.5.2
^ permalink raw reply
* [PATCH] arch_timer: Move delay timer to drivers clocksource
From: Daniel Lezcano @ 2014-01-17 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <878uufyo13.fsf@iki.fi>
On 01/17/2014 10:07 AM, Antti Miettinen wrote:
> Will Deacon <will.deacon@arm.com> writes:
>> Why can't you use the C3STOP feature so that the arch-timer isn't used when
>> you go idle?
>
> That would mean falling back to broadcast timer, right? That's not
> necessarily on the local CPU so wakeups would often wake two CPUs.
You can prevent that if the hardware supports it with the
CLOCK_EVT_DYNIRQ flag on the broadcast timer.
> Does
> anyone have patches for using a CPU local timer as a fallback for
> C3STOP timers?
--
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply
* [PATCH v2] ARM: dts: imx6: Add DFI FS700-M60 board support
From: Sascha Hauer @ 2014-01-17 9:09 UTC (permalink / raw)
To: linux-arm-kernel
The DFI FS700-M60 is a q7 board with i.MX6 quad, dual, duallite or solo
SoC. This adds support for it.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
changes since v1:
- addressed Shawns comments
arch/arm/boot/dts/Makefile | 2 +
arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts | 23 +++++
arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts | 23 +++++
arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi | 149 +++++++++++++++++++++++++++
4 files changed, 197 insertions(+)
create mode 100644 arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
create mode 100644 arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
create mode 100644 arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index aeb8053..485ed47 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -158,6 +158,7 @@ dtb-$(CONFIG_ARCH_MXC) += \
imx53-qsrb.dtb \
imx53-smd.dtb \
imx53-voipac-bsb.dtb \
+ imx6dl-dfi-fs700-m60.dtb \
imx6dl-gw51xx.dtb \
imx6dl-gw52xx.dtb \
imx6dl-gw53xx.dtb \
@@ -170,6 +171,7 @@ dtb-$(CONFIG_ARCH_MXC) += \
imx6dl-wandboard.dtb \
imx6q-arm2.dtb \
imx6q-cm-fx6.dtb \
+ imx6q-dfi-fs700-m60.dtb \
imx6q-dmo-edmqmx6.dtb \
imx6q-gw51xx.dtb \
imx6q-gw52xx.dtb \
diff --git a/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts b/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
new file mode 100644
index 0000000..994f96a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6dl-dfi-fs700-m60.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DTS_V1__
+#define __DTS_V1__
+/dts-v1/;
+#endif
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-dfi-fs700-m60.dtsi"
+
+/ {
+ model = "DFI FS700-M60-6DL i.MX6dl Q7 Board";
+ compatible = "dfi,fs700-m60-6dl", "dfi,fs700e-m60", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts b/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
new file mode 100644
index 0000000..fd0ad9a
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-dfi-fs700-m60.dts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DTS_V1__
+#define __DTS_V1__
+/dts-v1/;
+#endif
+
+#include "imx6q.dtsi"
+#include "imx6qdl-dfi-fs700-m60.dtsi"
+
+/ {
+ model = "DFI FS700-M60-6QD i.MX6qd Q7 Board";
+ compatible = "dfi,fs700-m60-6qd", "dfi,fs700e-m60", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
new file mode 100644
index 0000000..2ef3b49
--- /dev/null
+++ b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
@@ -0,0 +1,149 @@
+/ {
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dummy_reg: regulator at 0 {
+ compatible = "regulator-fixed";
+ reg = <0>;
+ regulator-name = "dummy-supply";
+ };
+
+ reg_usb_otg_vbus: regulator at 1 {
+ compatible = "regulator-fixed";
+ reg = <1>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio3 22 0>;
+ enable-active-high;
+ };
+ };
+
+ chosen {
+ linux,stdout-path = &uart1;
+ };
+};
+
+&ecspi3 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio4 24 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ status = "okay";
+
+ flash: m25p80 at 0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25vf040b", "m25p80";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ status = "okay";
+ phy-mode = "rgmii";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ imx6qdl-dfi-fs700-m60 {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
+ MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x80000000 /* PMIC irq */
+ MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000 /* MAX11801 irq */
+ MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000030b0 /* Backlight enable */
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <MX6QDL_ENET_PINGRP1>;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <MX6QDL_I2C2_PINGRP1>;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <MX6QDL_UART1_PINGRP1>;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <MX6QDL_USBOTG_PINGRP2>;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX6QDL_USDHC2_PINGRP_D4
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000 /* card detect */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
+ };
+
+ pinctrl_usdhc4: usdhc4grp {
+ fsl,pins = <MX6QDL_USDHC4_PINGRP_D8>;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX6QDL_ECSPI3_PINGRP1
+ MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
+ >;
+ };
+ };
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <®_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ disable-over-current;
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usdhc2 { /* module slot */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ cd-gpios = <&gpio2 2 0>;
+ status = "okay";
+};
+
+&usdhc3 { /* baseboard slot */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+};
+
+&usdhc4 { /* eMMC */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
--
1.8.5.2
^ permalink raw reply related
* [PATCH] ARM: dts: imx6: Add DFI FS700-M60 board support
From: Sascha Hauer @ 2014-01-17 9:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140117063929.GF1565@shlinux1.ap.freescale.net>
On Fri, Jan 17, 2014 at 02:39:31PM +0800, Shawn Guo wrote:
> On Thu, Jan 16, 2014 at 01:45:54PM +0100, Sascha Hauer wrote:
> > diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
> > new file mode 100644
> > index 0000000..ca3c748
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
> > @@ -0,0 +1,145 @@
> > +/ {
> > + regulators {
> > + compatible = "simple-bus";
> > +
> > + dummy_reg: fixed at 0 {
>
> regulator at 0
>
> > + compatible = "regulator-fixed";
>
> reg = <0>;
>
> > + regulator-name = "dummy-supply";
> > + };
> > +
> > + reg_usb_otg_vbus: usb_otg_vbus {
>
> regulator at 1
>
> > + compatible = "regulator-fixed";
>
> reg = <1>;
>
> > + regulator-name = "usb_otg_vbus";
> > + regulator-min-microvolt = <5000000>;
> > + regulator-max-microvolt = <5000000>;
> > + gpio = <&gpio3 22 0>;
> > + enable-active-high;
> > + };
> > + };
> > +
> > + chosen {
> > + linux,stdout-path = &uart1;
> > + };
> > +};
> > +
> > +&ecspi3 {
> > + fsl,spi-num-chipselects = <1>;
> > + cs-gpios = <&gpio4 24 0>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_ecspi3>;
> > + status = "okay";
> > +
> > + flash: m25p80 at 0 {
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + compatible = "sst,sst25vf040b", "m25p80";
> > + spi-max-frequency = <20000000>;
> > + reg = <0>;
> > + };
> > +};
> > +
> > +&fec {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_enet>;
> > + status = "okay";
> > + phy-mode = "rgmii";
> > +};
> > +
> > +&iomuxc {
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_hog>;
> > +
> > + imx6qdl-dfi-fs700-m60 {
> > + pinctrl_hog: hoggrp {
> > + fsl,pins = <
> > + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x80000000
> > + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x80000000 /* PMIC irq */
> > + MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x80000000 /* MAX11801 irq */
> > + MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x000030b0 /* Backlight enable */
> > + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x80000000 /* SD2 card detect */
>
> Can we minimize the pins in hog group by moving the client device's pins
> into device's pin entry, just like what you do for
> MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24?
>
> > + >;
> > + };
> > +
> > + pinctrl_enet: enetgrp {
> > + fsl,pins = <MX6QDL_ENET_PINGRP1>;
> > + };
> > +
> > + pinctrl_i2c2: i2c2grp {
> > + fsl,pins = <MX6QDL_I2C2_PINGRP1>;
> > + };
> > +
> > + pinctrl_uart1: uart1grp {
> > + fsl,pins = <MX6QDL_UART1_PINGRP1>;
> > + };
> > +
> > + pinctrl_usbotg: usbotggrp {
> > + fsl,pins = <MX6QDL_USBOTG_PINGRP2>;
> > + };
> > +
> > + pinctrl_usdhc2: usdhc2grp {
> > + fsl,pins = <MX6QDL_USDHC2_PINGRP_D4>;
> > + };
> > +
> > + pinctrl_usdhc3: usdhc3grp {
> > + fsl,pins = <MX6QDL_USDHC3_PINGRP_D4>;
> > + };
> > +
> > + pinctrl_usdhc4: usdhc4grp {
> > + fsl,pins = <MX6QDL_USDHC4_PINGRP_D8>;
> > + };
> > + };
> > +
> > + ecspi3 {
> > + pinctrl_ecspi3: ecspi3_csgrp {
>
> s/ecspi3_csgrp/ecspi3grp
>
> And just move the node into imx6qdl-dfi-fs700-m60?
Makes sense. Addressed all comments in v2.
Thanks for reviewing.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH v5] ARM: DTS: imx5* imx6*, use imx51-ssi
From: Markus Pargmann @ 2014-01-17 9:07 UTC (permalink / raw)
To: linux-arm-kernel
imx51-ssi and imx21-ssi are different IPs. imx51-ssi supports online
reconfiguration and needs this for correct interaction with SDMA. This
patch adds imx51-ssi before each imx21-ssi for all imx5/imx6 SoCs.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
Hi Shawn,
This is the patch including the two added compatibles in imx50.dtsi for
fsl,imx51-ssi. That is the only change in v5.
Regards,
Markus
arch/arm/boot/dts/imx50.dtsi | 6 +++++-
arch/arm/boot/dts/imx53.dtsi | 10 +++++++---
arch/arm/boot/dts/imx6qdl.dtsi | 12 +++++++++---
arch/arm/boot/dts/imx6sl.dtsi | 12 +++++++++---
4 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi
index 01c0499..47df15f 100644
--- a/arch/arm/boot/dts/imx50.dtsi
+++ b/arch/arm/boot/dts/imx50.dtsi
@@ -140,7 +140,9 @@
};
ssi2: ssi at 50014000 {
- compatible = "fsl,imx50-ssi", "fsl,imx21-ssi";
+ compatible = "fsl,imx50-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x50014000 0x4000>;
interrupts = <30>;
clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
@@ -446,6 +448,8 @@
ssi1: ssi at 63fcc000 {
compatible = "fsl,imx50-ssi", "fsl,imx21-ssi";
+ compatible = "fsl,imx50-ssi", "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x63fcc000 0x4000>;
interrupts = <29>;
clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 4dbde25..73e103b 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -171,7 +171,9 @@
};
ssi2: ssi at 50014000 {
- compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ compatible = "fsl,imx53-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x50014000 0x4000>;
interrupts = <30>;
clocks = <&clks IMX5_CLK_SSI2_IPG_GATE>;
@@ -590,7 +592,8 @@
};
ssi1: ssi at 63fcc000 {
- compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ compatible = "fsl,imx53-ssi", "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x63fcc000 0x4000>;
interrupts = <29>;
clocks = <&clks IMX5_CLK_SSI1_IPG_GATE>;
@@ -617,7 +620,8 @@
};
ssi3: ssi at 63fe8000 {
- compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ compatible = "fsl,imx53-ssi", "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x63fe8000 0x4000>;
interrupts = <96>;
clocks = <&clks IMX5_CLK_SSI3_IPG_GATE>;
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 8a86502..cf7956e 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -247,7 +247,9 @@
};
ssi1: ssi at 02028000 {
- compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x02028000 0x4000>;
interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks 178>;
@@ -260,7 +262,9 @@
};
ssi2: ssi at 0202c000 {
- compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x0202c000 0x4000>;
interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks 179>;
@@ -273,7 +277,9 @@
};
ssi3: ssi at 02030000 {
- compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6q-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x02030000 0x4000>;
interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks 180>;
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index a449c4f..95bb37b 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -226,7 +226,9 @@
};
ssi1: ssi at 02028000 {
- compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x02028000 0x4000>;
interrupts = <0 46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SL_CLK_SSI1>;
@@ -238,7 +240,9 @@
};
ssi2: ssi at 0202c000 {
- compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x0202c000 0x4000>;
interrupts = <0 47 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SL_CLK_SSI2>;
@@ -250,7 +254,9 @@
};
ssi3: ssi at 02030000 {
- compatible = "fsl,imx6sl-ssi","fsl,imx21-ssi";
+ compatible = "fsl,imx6sl-ssi",
+ "fsl,imx51-ssi",
+ "fsl,imx21-ssi";
reg = <0x02030000 0x4000>;
interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SL_CLK_SSI3>;
--
1.8.5.2
^ permalink raw reply related
* [PATCH] arch_timer: Move delay timer to drivers clocksource
From: Antti Miettinen @ 2014-01-17 9:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140116121649.GG30257@mudshark.cambridge.arm.com>
Will Deacon <will.deacon@arm.com> writes:
> Why can't you use the C3STOP feature so that the arch-timer isn't used when
> you go idle?
That would mean falling back to broadcast timer, right? That's not
necessarily on the local CPU so wakeups would often wake two CPUs. Does
anyone have patches for using a CPU local timer as a fallback for
C3STOP timers?
--Antti
^ permalink raw reply
* How to support SDIO wifi/bt in DT
From: Alexandre Belloni @ 2014-01-17 9:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOesGMgzi5Buduo2pd0PP8CvKVir69yZ-jjX0Gbda871GiD8rg@mail.gmail.com>
On Thu, Jan 16, 2014 at 09:15:17AM -0800, Olof Johansson wrote :
> "for SDIO slots" is somewhat misleading; nearly all controllers only
> do one slot/device per controller. The designware controller can do
> multiple slots, and that adds a bit of driver and binding complexity
> for something that seemingly not a single vendor has actually
> implemented.
>
> So we can likely assume to keep these reset/power/clock lines per host
> controller, no need to add a slot construct.
>
Actually, the atmel chips have two slots per controller so it would
probably be better to think about that now.
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140117/7e539c1a/attachment.sig>
^ permalink raw reply
* [PATCH 13/15] fbdev: sh-mobile-lcdcfb: Enable driver compilation with COMPILE_TEST
From: Tomi Valkeinen @ 2014-01-17 9:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52CD0CBB.3070801@ti.com>
Hi,
On 2014-01-08 10:30, Tomi Valkeinen wrote:
> On 2014-01-07 17:15, Laurent Pinchart wrote:
>> On Wednesday 11 December 2013 13:51:18 Laurent Pinchart wrote:
>>> Hi Jean-Christophe and Tomi,
>>>
>>> Could you please pick this patch up for v3.14 ?
>>
>> Ping ?
>
> Queued for 3.14.
I'll drop this patch, as it causes compile break (from kbuild test robot):
All error/warnings:
drivers/built-in.o: In function `sh_mobile_lcdc_pan':
>> sh_mobile_lcdcfb.c:(.text+0x77373): undefined reference to
`sh_mobile_meram_cache_update'
drivers/built-in.o: In function `sh_mobile_lcdc_start':
>> sh_mobile_lcdcfb.c:(.text+0x79320): undefined reference to
`sh_mobile_meram_cache_free'
>> sh_mobile_lcdcfb.c:(.text+0x79394): undefined reference to
`sh_mobile_meram_cache_alloc'
>> sh_mobile_lcdcfb.c:(.text+0x793d4): undefined reference to
`sh_mobile_meram_cache_update'
drivers/built-in.o: In function `sh_mobile_lcdc_stop':
>> sh_mobile_lcdcfb.c:(.text+0x79616): undefined reference to
`sh_mobile_meram_cache_free'
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140117/cb1f7878/attachment.sig>
^ permalink raw reply
* [PATCH] ARM64: perf: support dwarf unwinding in compat mode
From: Jean Pihet @ 2014-01-17 9:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAFrcx1npWFs3=rooqiGKSv-p7ivcG1J7SCvcmsz-hd3waXBfdA@mail.gmail.com>
Hi Will,
Some more thoughts below
On 16 January 2014 14:47, Jean Pihet <jean.pihet@linaro.org> wrote:
> Will,
>
> On 16 January 2014 13:57, Will Deacon <will.deacon@arm.com> wrote:
>> On Thu, Jan 16, 2014 at 12:26:53PM +0000, Jean Pihet wrote:
>>> On 16 January 2014 12:56, Will Deacon <will.deacon@arm.com> wrote:
>>> > In your previous series, compat backtracing is actually split out into a
>>> > separate function (compat_user_backtrace), so it would be more consistent to
>>> > have a compat_user_stack_pointer macro, rather than add this check here.
> The compat_user_backtrace function is used to unwind using the frame
> pointer, it is not used to unwind using the dwarf info (which uses the
> user stack pointer).
>
>>>
>>> Do you mean this change instead?
>>
>> I don't think so...
>>
>>> diff --git a/kernel/events/internal.h b/kernel/events/internal.h
>>> index 569b2187..9b88d2e 100644
>>> --- a/kernel/events/internal.h
>>> +++ b/kernel/events/internal.h
>>> @@ -185,7 +185,8 @@ static inline bool arch_perf_have_user_stack_dump(void)
>>> return true;
>>> }
>>>
>>> -#define perf_user_stack_pointer(regs) user_stack_pointer(regs)
>>> +#define perf_user_stack_pointer(regs) \
>>> + (!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp)
>>
>> This doesn't belong in core code; compat_user_mode and the fields of regs
>> are arm64-specific.
> Right.
>
>> So I suppose you need to rework your original patch to
>> call compat_user_stack_pointer (which we already define in compat.h for
>> arm64) if compat_user_mode(regs)).
> The perf core code calls perf_user_stack_pointer(regs) to retrieve the
> stack pointer, with perf_user_stack_pointer(regs) defined as
> user_stack_pointer(regs).
> The problem is that perf is not aware of the compat mode, so every
> arch has to implement user_stack_pointer(regs) correctly.
>
> For this reason I think the first patch proposal is the right one
> unless the perf core code is redesigned to handle different ABIs. Do
> you see a better implementation?
>
>>
>> The problem there is the inconsistency with respect to the regs argument:
>>
>> user_stack_pointer(regs) // Returns user stack pointer for regs
>> current_user_stack_pointer() // Returns current user stack pointer
>> compat_user_stack_pointer() // Doesn't take a regs argument!
>>
>> On top of that, x86 treats those last two functions differently when current
>> is a compat task.
>>
>> So the simplest thing would be to make compat_user_stack_pointer expand to
>> user_stack_pointer(current_pt_regs()) on arm64 and merge that in with your
>> original patch fixing user_stack_pointer.
I see 2 issues in your proposal:
1) user_stack_pointer(regs) calls compat_user_stack_pointer if
compat_user_mode(regs)) and compat_user_stack_pointer expands to
user_stack_pointer. I see a circular dependency in the macros.
2) current_pt_regs() returns the current task regs although perf
passes a regs struct that had been recorded previously.
Am I missing something?
Thx,
Jean
>>
>> Will
>
> Thx!
> Jean
^ permalink raw reply
* [PATCH v3 1/3] ARM: sun7i/sun6i: irqchip: Add irqchip driver for NMI controller
From: Carlo Caione @ 2014-01-17 8:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140116123940.GE31779@lukather>
On Thu, Jan 16, 2014 at 1:39 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi Carlo,
>
> On Sat, Jan 11, 2014 at 04:19:06PM +0100, Carlo Caione wrote:
>> Allwinner A20/A31 SoCs have special registers to control / (un)mask /
>> acknowledge NMI. This NMI controller is separated and independent from GIC.
>> This patch adds a new irqchip to manage NMI.
>>
>> Signed-off-by: Carlo Caione <carlo.caione@gmail.com>
>> ---
>> drivers/irqchip/Makefile | 1 +
>> drivers/irqchip/irq-sunxi-nmi.c | 228 ++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 229 insertions(+)
>> create mode 100644 drivers/irqchip/irq-sunxi-nmi.c
>>
>> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
>> index c60b901..e31d4d6 100644
>> --- a/drivers/irqchip/Makefile
>> +++ b/drivers/irqchip/Makefile
>> @@ -11,6 +11,7 @@ obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
>> obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o
>> obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o
>> obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o
>> +obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o
>> obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o
>> obj-$(CONFIG_ARM_GIC) += irq-gic.o
>> obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
>> diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c
>> new file mode 100644
>> index 0000000..a2b7373
>> --- /dev/null
>> +++ b/drivers/irqchip/irq-sunxi-nmi.c
>> @@ -0,0 +1,228 @@
>> +/*
>> + * Allwinner A20/A31 SoCs NMI IRQ chip driver.
>> + *
>> + * Carlo Caione <carlo.caione@gmail.com>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2. This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#include <linux/bitops.h>
>> +#include <linux/device.h>
>> +#include <linux/io.h>
>> +#include <linux/irq.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irqdomain.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/irqchip/chained_irq.h>
>> +#include "irqchip.h"
>> +
>> +#define SUNXI_NMI_SRC_TYPE_MASK 0x00000003
>> +
>> +enum {
>> + SUNXI_SRC_TYPE_LEVEL_LOW = 0,
>> + SUNXI_SRC_TYPE_EDGE_FALLING,
>> + SUNXI_SRC_TYPE_LEVEL_HIGH,
>> + SUNXI_SRC_TYPE_EDGE_RISING,
>> +};
>> +
>> +struct sunxi_sc_nmi_reg_offs {
>> + u32 ctrl;
>> + u32 pend;
>> + u32 enable;
>> +};
>> +
>> +static struct sunxi_sc_nmi_reg_offs sun7i_reg_offs = {
>> + .ctrl = 0x00,
>> + .pend = 0x04,
>> + .enable = 0x08,
>> +};
>> +
>> +static struct sunxi_sc_nmi_reg_offs sun6i_reg_offs = {
>> + .ctrl = 0x00,
>> + .pend = 0x04,
>> + .enable = 0x34,
>> +};
>> +
>> +/*
>> + * Ack level interrupts right before unmask
>> + *
>> + * In case of level-triggered interrupt, IRQ line must be acked before it
>> + * is unmasked or else a double-interrupt is triggered
>> + */
>> +
>> +static void sunxi_sc_nmi_ack_and_unmask(struct irq_data *d)
>> +{
>> + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
>> + struct irq_chip_type *ct = irq_data_get_chip_type(d);
>> + u32 mask = d->mask;
>> +
>> + if (irqd_get_trigger_type(d) & IRQ_TYPE_LEVEL_MASK)
>> + ct->chip.irq_ack(d);
>> +
>> + irq_gc_lock(gc);
>> + irq_reg_writel(mask, gc->reg_base + ct->regs.mask);
>> + irq_gc_unlock(gc);
>> +}
>
> Hmmm, handle_level_irq seems to be doing exactly that already. It
> first masks and acks the interrupts, and then unmask it, so we should
> be fine, don't we?
We don't, or at least handle_level_irq doesn't work for all the cases.
Let's say (i.e. this is the cubieboard2 case) that to the irqchip is
connected to the IRQ line of a PMIC accessed by I2C. In this case we
cannot mask/ack the interrupt on the originating device in the hard
interrupt handler (in which handle_level_irq is) since we need to
access the I2C bus in an non-interrupt context. ACKing the IRQ in
handle_level_irq at this point is pretty much useless since we still
have to ACK the IRQs on the originating device and this will be done
in a IRQ thread started after the hard IRQ handler.
sunxi_sc_nmi_ack_and_unmask is therefore called (by
irq_finalize_oneshot) after the IRQ thread has been executed. After
the IRQ thread has ACKed the IRQs on the originating device we can
finally ACK and unmask again the NMI.
>> +static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off,
>> + u32 val)
>> +{
>> + irq_reg_writel(val, gc->reg_base + off);
>> +}
>> +
>> +static inline u32 sunxi_sc_nmi_read(struct irq_chip_generic *gc, u32 off)
>> +{
>> + return irq_reg_readl(gc->reg_base + off);
>> +}
>> +
>> +static void sunxi_sc_nmi_handle_irq(unsigned int irq, struct irq_desc *desc)
>> +{
>> + struct irq_domain *domain = irq_desc_get_handler_data(desc);
>> + struct irq_chip *chip = irq_get_chip(irq);
>> + unsigned int virq = irq_find_mapping(domain, 0);
>> +
>> + chained_irq_enter(chip, desc);
>> + generic_handle_irq(virq);
>> + chained_irq_exit(chip, desc);
>> +}
>> +
>> +static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type)
>> +{
>> + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
>> + struct irq_chip_type *ct = gc->chip_types;
>> + u32 src_type_reg;
>> + u32 ctrl_off = ct->regs.type;
>> + unsigned int src_type;
>> + unsigned int i;
>> +
>> + irq_gc_lock(gc);
>> +
>> + switch (flow_type & IRQF_TRIGGER_MASK) {
>> + case IRQ_TYPE_EDGE_FALLING:
>> + src_type = SUNXI_SRC_TYPE_EDGE_FALLING;
>> + break;
>> + case IRQ_TYPE_EDGE_RISING:
>> + src_type = SUNXI_SRC_TYPE_EDGE_RISING;
>> + break;
>> + case IRQ_TYPE_LEVEL_HIGH:
>> + src_type = SUNXI_SRC_TYPE_LEVEL_HIGH;
>> + break;
>> + case IRQ_TYPE_NONE:
>> + case IRQ_TYPE_LEVEL_LOW:
>> + src_type = SUNXI_SRC_TYPE_LEVEL_LOW;
>> + break;
>> + default:
>> + irq_gc_unlock(gc);
>> + pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n",
>> + __func__, data->irq);
>> + return -EBADR;
>> + }
>> +
>> + irqd_set_trigger_type(data, flow_type);
>> + irq_setup_alt_chip(data, flow_type);
>> +
>> + for (i = 0; i <= gc->num_ct; i++, ct++)
>> + if (ct->type & flow_type)
>> + ctrl_off = ct->regs.type;
>> +
>> + src_type_reg = sunxi_sc_nmi_read(gc, ctrl_off);
>> + src_type_reg &= ~SUNXI_NMI_SRC_TYPE_MASK;
>> + src_type_reg |= src_type;
>> + sunxi_sc_nmi_write(gc, ctrl_off, src_type_reg);
>> +
>> + irq_gc_unlock(gc);
>> +
>> + return IRQ_SET_MASK_OK;
>> +}
>> +
>> +static int __init sunxi_sc_nmi_irq_init(struct device_node *node,
>> + struct sunxi_sc_nmi_reg_offs *reg_offs)
>> +{
>> + struct irq_domain *domain;
>> + struct irq_chip_generic *gc;
>> + unsigned int irq;
>> + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
>> + int ret;
>> +
>> +
>> + domain = irq_domain_add_linear(node, 1, &irq_generic_chip_ops, NULL);
>> + if (!domain) {
>> + pr_err("%s: Could not register interrupt domain.\n", node->name);
>> + return -ENOMEM;
>> + }
>> +
>> + ret = irq_alloc_domain_generic_chips(domain, 1, 2, node->name,
>> + handle_level_irq, clr, 0,
>> + IRQ_GC_INIT_MASK_CACHE);
>> + if (ret) {
>> + pr_err("%s: Could not allocate generic interrupt chip.\n",
>> + node->name);
>> + goto fail_irqd_remove;
>> + }
>> +
>> + irq = irq_of_parse_and_map(node, 0);
>> + if (irq <= 0) {
>> + pr_err("%s: unable to parse irq\n", node->name);
>> + ret = -EINVAL;
>> + goto fail_irqd_remove;
>> + }
>> +
>> + gc = irq_get_domain_generic_chip(domain, 0);
>> + gc->reg_base = of_iomap(node, 0);
>> + if (!gc->reg_base) {
>> + pr_err("%s: unable to map resource\n", node->name);
>> + ret = -ENOMEM;
>> + goto fail_irqd_remove;
>> + }
>> +
>> + gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK;
>> + gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
>> + gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
>> + gc->chip_types[0].chip.irq_unmask = sunxi_sc_nmi_ack_and_unmask;
>> + gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type;
>> + gc->chip_types[0].regs.ack = reg_offs->pend;
>> + gc->chip_types[0].regs.mask = reg_offs->enable;
>> + gc->chip_types[0].regs.type = reg_offs->ctrl;
>> +
>> + gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH;
>> + gc->chip_types[1].chip.name = gc->chip_types[0].chip.name;
>> + gc->chip_types[1].chip.irq_ack = irq_gc_ack_set_bit;
>> + gc->chip_types[1].chip.irq_mask = irq_gc_mask_clr_bit;
>> + gc->chip_types[1].chip.irq_unmask = sunxi_sc_nmi_ack_and_unmask;
>> + gc->chip_types[1].chip.irq_set_type = sunxi_sc_nmi_set_type;
>> + gc->chip_types[1].regs.ack = reg_offs->pend;
>> + gc->chip_types[1].regs.mask = reg_offs->enable;
>> + gc->chip_types[1].regs.type = reg_offs->ctrl;
>> + gc->chip_types[1].handler = handle_edge_irq;
>> +
>> + irq_set_handler_data(irq, domain);
>> + irq_set_chained_handler(irq, sunxi_sc_nmi_handle_irq);
>> +
>> + sunxi_sc_nmi_write(gc, reg_offs->enable, 0);
>> + sunxi_sc_nmi_write(gc, reg_offs->pend, 0x1);
>
> I really wonder whether it makes sense to have a generic chip here. It
> seems to be much more complicated than it should. It's only about a
> single interrupt interrupt chip here.
I agree but is there any other way to manage the NMI without the
driver of the device connected to NMI having to worry about
acking/masking/unmasking/ etc..?
>> +
>> + return 0;
>> +
>> +fail_irqd_remove:
>> + irq_domain_remove(domain);
>> +
>> + return ret;
>> +}
>> +
>> +static int __init sun6i_sc_nmi_irq_init(struct device_node *node,
>> + struct device_node *parent)
>> +{
>> + return sunxi_sc_nmi_irq_init(node, &sun6i_reg_offs);
>> +}
>> +IRQCHIP_DECLARE(sun6i_sc_nmi, "allwinner,sun6i-sc-nmi", sun6i_sc_nmi_irq_init);
>
> I'm curious, where did you get these infos on the A31? :)
Ehm actually it was in the mail exchange we have had with the
Allwinner engineers :)
>
>> +static int __init sun7i_sc_nmi_irq_init(struct device_node *node,
>> + struct device_node *parent)
>> +{
>> + return sunxi_sc_nmi_irq_init(node, &sun7i_reg_offs);
>> +}
>> +IRQCHIP_DECLARE(sun7i_sc_nmi, "allwinner,sun7i-sc-nmi", sun7i_sc_nmi_irq_init);
>
> The compatibles should be sun6i-a31-* and sun7i-a20-*.
Fix in v4.
Thanks,
--
Carlo Caione
^ permalink raw reply
* [PATCH] ARM: dma-mapping: fix GFP_ATOMIC macro usage
From: Marek Szyprowski @ 2014-01-17 8:46 UTC (permalink / raw)
To: linux-arm-kernel
GFP_ATOMIC is not a single gfp flag, but a macro which expands to the other
flags and LACK of __GFP_WAIT flag. To check if caller wanted to perform an
atomic allocation, the code must test __GFP_WAIT flag presence. This patch
fixes the issue introduced in v3.6-rc5
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
CC: stable at vger.kernel.org
---
arch/arm/mm/dma-mapping.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f61a570..5fe4d72 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1358,7 +1358,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
*handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
- if (gfp & GFP_ATOMIC)
+ if (!(gfp & __GFP_WAIT))
return __iommu_alloc_atomic(dev, size, handle);
/*
--
1.7.9.5
^ permalink raw reply related
* [PATCH v16] dmaengine: Add MOXA ART DMA engine driver
From: Jonas Jensen @ 2014-01-17 8:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1387189499-26300-1-git-send-email-jonas.jensen@gmail.com>
The MOXA ART SoC has a DMA controller capable of offloading expensive
memory operations, such as large copies. This patch adds support for
the controller including four channels. Two of these are used to
handle MMC copy on the UC-7112-LX hardware. The remaining two can be
used in a future audio driver or client application.
Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---
Notes:
Changes since v15:
1. rebase drivers/dma/Kconfig to next-20140117
Applies to next-20140117
.../devicetree/bindings/dma/moxa,moxart-dma.txt | 45 ++
drivers/dma/Kconfig | 8 +
drivers/dma/Makefile | 1 +
drivers/dma/moxart-dma.c | 699 +++++++++++++++++++++
4 files changed, 753 insertions(+)
create mode 100644 Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt
create mode 100644 drivers/dma/moxart-dma.c
diff --git a/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt b/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt
new file mode 100644
index 0000000..8a9f355
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt
@@ -0,0 +1,45 @@
+MOXA ART DMA Controller
+
+See dma.txt first
+
+Required properties:
+
+- compatible : Must be "moxa,moxart-dma"
+- reg : Should contain registers location and length
+- interrupts : Should contain an interrupt-specifier for the sole
+ interrupt generated by the device
+- #dma-cells : Should be 1, a single cell holding a line request number
+
+Example:
+
+ dma: dma at 90500000 {
+ compatible = "moxa,moxart-dma";
+ reg = <0x90500080 0x40>;
+ interrupts = <24 0>;
+ #dma-cells = <1>;
+ };
+
+
+Clients:
+
+DMA clients connected to the MOXA ART DMA controller must use the format
+described in the dma.txt file, using a two-cell specifier for each channel:
+a phandle plus one integer cells.
+The two cells in order are:
+
+1. A phandle pointing to the DMA controller.
+2. Peripheral identifier for the hardware handshaking interface.
+
+Example:
+Use specific request line passing from dma
+For example, MMC request line is 5
+
+ sdhci: sdhci at 98e00000 {
+ compatible = "moxa,moxart-sdhci";
+ reg = <0x98e00000 0x5C>;
+ interrupts = <5 0>;
+ clocks = <&clk_apb>;
+ dmas = <&dma 5>,
+ <&dma 5>;
+ dma-names = "tx", "rx";
+ };
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 9ae6f54..9bed1a2 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -342,6 +342,14 @@ config K3_DMA
Support the DMA engine for Hisilicon K3 platform
devices.
+config MOXART_DMA
+ tristate "MOXART DMA support"
+ depends on ARCH_MOXART
+ select DMA_ENGINE
+ select DMA_VIRTUAL_CHANNELS
+ help
+ Enable support for the MOXA ART SoC DMA controller.
+
config DMA_ENGINE
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 0a6f08e..a029d0f4 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -43,3 +43,4 @@ obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
obj-$(CONFIG_TI_CPPI41) += cppi41.o
obj-$(CONFIG_K3_DMA) += k3dma.o
+obj-$(CONFIG_MOXART_DMA) += moxart-dma.o
diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c
new file mode 100644
index 0000000..3258e48
--- /dev/null
+++ b/drivers/dma/moxart-dma.c
@@ -0,0 +1,699 @@
+/*
+ * MOXA ART SoCs DMA Engine support.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_dma.h>
+#include <linux/bitops.h>
+
+#include <asm/cacheflush.h>
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define APB_DMA_MAX_CHANNEL 4
+
+#define REG_OFF_ADDRESS_SOURCE 0
+#define REG_OFF_ADDRESS_DEST 4
+#define REG_OFF_CYCLES 8
+#define REG_OFF_CTRL 12
+#define REG_OFF_CHAN_SIZE 16
+
+#define APB_DMA_ENABLE BIT(0)
+#define APB_DMA_FIN_INT_STS BIT(1)
+#define APB_DMA_FIN_INT_EN BIT(2)
+#define APB_DMA_BURST_MODE BIT(3)
+#define APB_DMA_ERR_INT_STS BIT(4)
+#define APB_DMA_ERR_INT_EN BIT(5)
+
+/*
+ * Unset: APB
+ * Set: AHB
+ */
+#define APB_DMA_SOURCE_SELECT 0x40
+#define APB_DMA_DEST_SELECT 0x80
+
+#define APB_DMA_SOURCE 0x100
+#define APB_DMA_DEST 0x1000
+
+#define APB_DMA_SOURCE_MASK 0x700
+#define APB_DMA_DEST_MASK 0x7000
+
+/*
+ * 000: No increment
+ * 001: +1 (Burst=0), +4 (Burst=1)
+ * 010: +2 (Burst=0), +8 (Burst=1)
+ * 011: +4 (Burst=0), +16 (Burst=1)
+ * 101: -1 (Burst=0), -4 (Burst=1)
+ * 110: -2 (Burst=0), -8 (Burst=1)
+ * 111: -4 (Burst=0), -16 (Burst=1)
+ */
+#define APB_DMA_SOURCE_INC_0 0
+#define APB_DMA_SOURCE_INC_1_4 0x100
+#define APB_DMA_SOURCE_INC_2_8 0x200
+#define APB_DMA_SOURCE_INC_4_16 0x300
+#define APB_DMA_SOURCE_DEC_1_4 0x500
+#define APB_DMA_SOURCE_DEC_2_8 0x600
+#define APB_DMA_SOURCE_DEC_4_16 0x700
+#define APB_DMA_DEST_INC_0 0
+#define APB_DMA_DEST_INC_1_4 0x1000
+#define APB_DMA_DEST_INC_2_8 0x2000
+#define APB_DMA_DEST_INC_4_16 0x3000
+#define APB_DMA_DEST_DEC_1_4 0x5000
+#define APB_DMA_DEST_DEC_2_8 0x6000
+#define APB_DMA_DEST_DEC_4_16 0x7000
+
+/*
+ * Request signal select source/destination address for DMA hardware handshake.
+ *
+ * The request line number is a property of the DMA controller itself,
+ * e.g. MMC must always request channels where dma_slave_config->slave_id is 5.
+ *
+ * 0: No request / Grant signal
+ * 1-15: Request / Grant signal
+ */
+#define APB_DMA_SOURCE_REQ_NO 0x1000000
+#define APB_DMA_SOURCE_REQ_NO_MASK 0xf000000
+#define APB_DMA_DEST_REQ_NO 0x10000
+#define APB_DMA_DEST_REQ_NO_MASK 0xf0000
+
+#define APB_DMA_DATA_WIDTH 0x100000
+#define APB_DMA_DATA_WIDTH_MASK 0x300000
+/*
+ * Data width of transfer:
+ *
+ * 00: Word
+ * 01: Half
+ * 10: Byte
+ */
+#define APB_DMA_DATA_WIDTH_4 0
+#define APB_DMA_DATA_WIDTH_2 0x100000
+#define APB_DMA_DATA_WIDTH_1 0x200000
+
+#define APB_DMA_CYCLES_MASK 0x00ffffff
+
+#define MOXART_DMA_DATA_TYPE_S8 0x00
+#define MOXART_DMA_DATA_TYPE_S16 0x01
+#define MOXART_DMA_DATA_TYPE_S32 0x02
+
+struct moxart_sg {
+ dma_addr_t addr;
+ uint32_t len;
+};
+
+struct moxart_desc {
+ enum dma_transfer_direction dma_dir;
+ dma_addr_t dev_addr;
+ unsigned int sglen;
+ unsigned int dma_cycles;
+ struct virt_dma_desc vd;
+ uint8_t es;
+ struct moxart_sg sg[0];
+};
+
+struct moxart_chan {
+ struct virt_dma_chan vc;
+
+ void __iomem *base;
+ struct moxart_desc *desc;
+
+ struct dma_slave_config cfg;
+
+ bool allocated;
+ bool error;
+ int ch_num;
+ unsigned int line_reqno;
+ unsigned int sgidx;
+};
+
+struct moxart_dmadev {
+ struct dma_device dma_slave;
+ struct moxart_chan slave_chans[APB_DMA_MAX_CHANNEL];
+};
+
+struct moxart_filter_data {
+ struct moxart_dmadev *mdc;
+ struct of_phandle_args *dma_spec;
+};
+
+static const unsigned int es_bytes[] = {
+ [MOXART_DMA_DATA_TYPE_S8] = 1,
+ [MOXART_DMA_DATA_TYPE_S16] = 2,
+ [MOXART_DMA_DATA_TYPE_S32] = 4,
+};
+
+static struct device *chan2dev(struct dma_chan *chan)
+{
+ return &chan->dev->device;
+}
+
+static inline struct moxart_chan *to_moxart_dma_chan(struct dma_chan *c)
+{
+ return container_of(c, struct moxart_chan, vc.chan);
+}
+
+static inline struct moxart_desc *to_moxart_dma_desc(
+ struct dma_async_tx_descriptor *t)
+{
+ return container_of(t, struct moxart_desc, vd.tx);
+}
+
+static void moxart_dma_desc_free(struct virt_dma_desc *vd)
+{
+ kfree(container_of(vd, struct moxart_desc, vd));
+}
+
+static int moxart_terminate_all(struct dma_chan *chan)
+{
+ struct moxart_chan *ch = to_moxart_dma_chan(chan);
+ unsigned long flags;
+ LIST_HEAD(head);
+ u32 ctrl;
+
+ dev_dbg(chan2dev(chan), "%s: ch=%p\n", __func__, ch);
+
+ spin_lock_irqsave(&ch->vc.lock, flags);
+
+ if (ch->desc)
+ ch->desc = NULL;
+
+ ctrl = readl(ch->base + REG_OFF_CTRL);
+ ctrl &= ~(APB_DMA_ENABLE | APB_DMA_FIN_INT_EN | APB_DMA_ERR_INT_EN);
+ writel(ctrl, ch->base + REG_OFF_CTRL);
+
+ vchan_get_all_descriptors(&ch->vc, &head);
+ spin_unlock_irqrestore(&ch->vc.lock, flags);
+ vchan_dma_desc_free_list(&ch->vc, &head);
+
+ return 0;
+}
+
+static int moxart_slave_config(struct dma_chan *chan,
+ struct dma_slave_config *cfg)
+{
+ struct moxart_chan *ch = to_moxart_dma_chan(chan);
+ u32 ctrl;
+
+ ch->cfg = *cfg;
+
+ ctrl = readl(ch->base + REG_OFF_CTRL);
+ ctrl |= APB_DMA_BURST_MODE;
+ ctrl &= ~(APB_DMA_DEST_MASK | APB_DMA_SOURCE_MASK);
+ ctrl &= ~(APB_DMA_DEST_REQ_NO_MASK | APB_DMA_SOURCE_REQ_NO_MASK);
+
+ switch (ch->cfg.src_addr_width) {
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ ctrl |= APB_DMA_DATA_WIDTH_1;
+ if (ch->cfg.direction != DMA_MEM_TO_DEV)
+ ctrl |= APB_DMA_DEST_INC_1_4;
+ else
+ ctrl |= APB_DMA_SOURCE_INC_1_4;
+ break;
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ ctrl |= APB_DMA_DATA_WIDTH_2;
+ if (ch->cfg.direction != DMA_MEM_TO_DEV)
+ ctrl |= APB_DMA_DEST_INC_2_8;
+ else
+ ctrl |= APB_DMA_SOURCE_INC_2_8;
+ break;
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ ctrl &= ~APB_DMA_DATA_WIDTH;
+ if (ch->cfg.direction != DMA_MEM_TO_DEV)
+ ctrl |= APB_DMA_DEST_INC_4_16;
+ else
+ ctrl |= APB_DMA_SOURCE_INC_4_16;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (ch->cfg.direction == DMA_MEM_TO_DEV) {
+ ctrl &= ~APB_DMA_DEST_SELECT;
+ ctrl |= APB_DMA_SOURCE_SELECT;
+ ctrl |= (ch->line_reqno << 16 &
+ APB_DMA_DEST_REQ_NO_MASK);
+ } else {
+ ctrl |= APB_DMA_DEST_SELECT;
+ ctrl &= ~APB_DMA_SOURCE_SELECT;
+ ctrl |= (ch->line_reqno << 24 &
+ APB_DMA_SOURCE_REQ_NO_MASK);
+ }
+
+ writel(ctrl, ch->base + REG_OFF_CTRL);
+
+ return 0;
+}
+
+static int moxart_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg)
+{
+ int ret = 0;
+
+ switch (cmd) {
+ case DMA_PAUSE:
+ case DMA_RESUME:
+ return -EINVAL;
+ case DMA_TERMINATE_ALL:
+ moxart_terminate_all(chan);
+ break;
+ case DMA_SLAVE_CONFIG:
+ ret = moxart_slave_config(chan, (struct dma_slave_config *)arg);
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+
+ return ret;
+}
+
+static struct dma_async_tx_descriptor *moxart_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_transfer_direction dir,
+ unsigned long tx_flags, void *context)
+{
+ struct moxart_chan *ch = to_moxart_dma_chan(chan);
+ struct moxart_desc *d;
+ enum dma_slave_buswidth dev_width;
+ dma_addr_t dev_addr;
+ struct scatterlist *sgent;
+ unsigned int es;
+ unsigned int i;
+
+ if (!is_slave_direction(dir)) {
+ dev_err(chan2dev(chan), "%s: invalid DMA direction\n",
+ __func__);
+ return NULL;
+ }
+
+ if (dir == DMA_DEV_TO_MEM) {
+ dev_addr = ch->cfg.src_addr;
+ dev_width = ch->cfg.src_addr_width;
+ } else {
+ dev_addr = ch->cfg.dst_addr;
+ dev_width = ch->cfg.dst_addr_width;
+ }
+
+ switch (dev_width) {
+ case DMA_SLAVE_BUSWIDTH_1_BYTE:
+ es = MOXART_DMA_DATA_TYPE_S8;
+ break;
+ case DMA_SLAVE_BUSWIDTH_2_BYTES:
+ es = MOXART_DMA_DATA_TYPE_S16;
+ break;
+ case DMA_SLAVE_BUSWIDTH_4_BYTES:
+ es = MOXART_DMA_DATA_TYPE_S32;
+ break;
+ default:
+ dev_err(chan2dev(chan), "%s: unsupported data width (%u)\n",
+ __func__, dev_width);
+ return NULL;
+ }
+
+ d = kzalloc(sizeof(*d) + sg_len * sizeof(d->sg[0]), GFP_ATOMIC);
+ if (!d)
+ return NULL;
+
+ d->dma_dir = dir;
+ d->dev_addr = dev_addr;
+ d->es = es;
+
+ for_each_sg(sgl, sgent, sg_len, i) {
+ d->sg[i].addr = sg_dma_address(sgent);
+ d->sg[i].len = sg_dma_len(sgent);
+ }
+
+ d->sglen = sg_len;
+
+ ch->error = 0;
+
+ return vchan_tx_prep(&ch->vc, &d->vd, tx_flags);
+}
+
+static struct dma_chan *moxart_of_xlate(struct of_phandle_args *dma_spec,
+ struct of_dma *ofdma)
+{
+ struct moxart_dmadev *mdc = ofdma->of_dma_data;
+ struct dma_chan *chan;
+ struct moxart_chan *ch;
+
+ chan = dma_get_any_slave_channel(&mdc->dma_slave);
+ if (!chan)
+ return NULL;
+
+ ch = to_moxart_dma_chan(chan);
+ ch->line_reqno = dma_spec->args[0];
+
+ return chan;
+}
+
+static int moxart_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct moxart_chan *ch = to_moxart_dma_chan(chan);
+
+ dev_dbg(chan2dev(chan), "%s: allocating channel #%u\n",
+ __func__, ch->ch_num);
+ ch->allocated = 1;
+
+ return 0;
+}
+
+static void moxart_free_chan_resources(struct dma_chan *chan)
+{
+ struct moxart_chan *ch = to_moxart_dma_chan(chan);
+
+ vchan_free_chan_resources(&ch->vc);
+
+ dev_dbg(chan2dev(chan), "%s: freeing channel #%u\n",
+ __func__, ch->ch_num);
+ ch->allocated = 0;
+}
+
+static void moxart_dma_set_params(struct moxart_chan *ch, dma_addr_t src_addr,
+ dma_addr_t dst_addr)
+{
+ writel(src_addr, ch->base + REG_OFF_ADDRESS_SOURCE);
+ writel(dst_addr, ch->base + REG_OFF_ADDRESS_DEST);
+}
+
+static void moxart_set_transfer_params(struct moxart_chan *ch, unsigned int len)
+{
+ struct moxart_desc *d = ch->desc;
+ unsigned int sglen_div = es_bytes[d->es];
+
+ d->dma_cycles = len >> sglen_div;
+
+ /*
+ * There are 4 cycles on 64 bytes copied, i.e. one cycle copies 16
+ * bytes ( when width is APB_DMAB_DATA_WIDTH_4 ).
+ */
+ writel(d->dma_cycles, ch->base + REG_OFF_CYCLES);
+
+ dev_dbg(chan2dev(&ch->vc.chan), "%s: set %u DMA cycles (len=%u)\n",
+ __func__, d->dma_cycles, len);
+}
+
+static void moxart_start_dma(struct moxart_chan *ch)
+{
+ u32 ctrl;
+
+ ctrl = readl(ch->base + REG_OFF_CTRL);
+ ctrl |= (APB_DMA_ENABLE | APB_DMA_FIN_INT_EN | APB_DMA_ERR_INT_EN);
+ writel(ctrl, ch->base + REG_OFF_CTRL);
+}
+
+static void moxart_dma_start_sg(struct moxart_chan *ch, unsigned int idx)
+{
+ struct moxart_desc *d = ch->desc;
+ struct moxart_sg *sg = ch->desc->sg + idx;
+
+ if (ch->desc->dma_dir == DMA_MEM_TO_DEV)
+ moxart_dma_set_params(ch, sg->addr, d->dev_addr);
+ else if (ch->desc->dma_dir == DMA_DEV_TO_MEM)
+ moxart_dma_set_params(ch, d->dev_addr, sg->addr);
+
+ moxart_set_transfer_params(ch, sg->len);
+
+ moxart_start_dma(ch);
+}
+
+static void moxart_dma_start_desc(struct dma_chan *chan)
+{
+ struct moxart_chan *ch = to_moxart_dma_chan(chan);
+ struct virt_dma_desc *vd;
+
+ vd = vchan_next_desc(&ch->vc);
+
+ if (!vd) {
+ ch->desc = NULL;
+ return;
+ }
+
+ list_del(&vd->node);
+
+ ch->desc = to_moxart_dma_desc(&vd->tx);
+ ch->sgidx = 0;
+
+ moxart_dma_start_sg(ch, 0);
+}
+
+static void moxart_issue_pending(struct dma_chan *chan)
+{
+ struct moxart_chan *ch = to_moxart_dma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ch->vc.lock, flags);
+ if (vchan_issue_pending(&ch->vc) && !ch->desc)
+ moxart_dma_start_desc(chan);
+ spin_unlock_irqrestore(&ch->vc.lock, flags);
+}
+
+static size_t moxart_dma_desc_size(struct moxart_desc *d,
+ unsigned int completed_sgs)
+{
+ unsigned int i;
+ size_t size;
+
+ for (size = i = completed_sgs; i < d->sglen; i++)
+ size += d->sg[i].len;
+
+ return size;
+}
+
+static size_t moxart_dma_desc_size_in_flight(struct moxart_chan *ch)
+{
+ size_t size;
+ unsigned int completed_cycles, cycles;
+
+ size = moxart_dma_desc_size(ch->desc, ch->sgidx);
+ cycles = readl(ch->base + REG_OFF_CYCLES);
+ completed_cycles = (ch->desc->dma_cycles - cycles);
+ size -= completed_cycles << es_bytes[ch->desc->es];
+
+ dev_dbg(chan2dev(&ch->vc.chan), "%s: size=%zu\n", __func__, size);
+
+ return size;
+}
+
+static enum dma_status moxart_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct moxart_chan *ch = to_moxart_dma_chan(chan);
+ struct virt_dma_desc *vd;
+ struct moxart_desc *d;
+ enum dma_status ret;
+ unsigned long flags;
+
+ /*
+ * dma_cookie_status() assigns initial residue value.
+ */
+ ret = dma_cookie_status(chan, cookie, txstate);
+
+ spin_lock_irqsave(&ch->vc.lock, flags);
+ vd = vchan_find_desc(&ch->vc, cookie);
+ if (vd) {
+ d = to_moxart_dma_desc(&vd->tx);
+ txstate->residue = moxart_dma_desc_size(d, 0);
+ } else if (ch->desc && ch->desc->vd.tx.cookie == cookie) {
+ txstate->residue = moxart_dma_desc_size_in_flight(ch);
+ }
+ spin_unlock_irqrestore(&ch->vc.lock, flags);
+
+ if (ch->error)
+ return DMA_ERROR;
+
+ return ret;
+}
+
+static void moxart_dma_init(struct dma_device *dma, struct device *dev)
+{
+ dma->device_prep_slave_sg = moxart_prep_slave_sg;
+ dma->device_alloc_chan_resources = moxart_alloc_chan_resources;
+ dma->device_free_chan_resources = moxart_free_chan_resources;
+ dma->device_issue_pending = moxart_issue_pending;
+ dma->device_tx_status = moxart_tx_status;
+ dma->device_control = moxart_control;
+ dma->dev = dev;
+
+ INIT_LIST_HEAD(&dma->channels);
+}
+
+static irqreturn_t moxart_dma_interrupt(int irq, void *devid)
+{
+ struct moxart_dmadev *mc = devid;
+ struct moxart_chan *ch = &mc->slave_chans[0];
+ unsigned int i;
+ unsigned long flags;
+ u32 ctrl;
+
+ dev_dbg(chan2dev(&ch->vc.chan), "%s\n", __func__);
+
+ for (i = 0; i < APB_DMA_MAX_CHANNEL; i++, ch++) {
+ if (!ch->allocated)
+ continue;
+
+ ctrl = readl(ch->base + REG_OFF_CTRL);
+
+ dev_dbg(chan2dev(&ch->vc.chan), "%s: ch=%p ch->base=%p ctrl=%x\n",
+ __func__, ch, ch->base, ctrl);
+
+ if (ctrl & APB_DMA_FIN_INT_STS) {
+ ctrl &= ~APB_DMA_FIN_INT_STS;
+ if (ch->desc) {
+ spin_lock_irqsave(&ch->vc.lock, flags);
+ if (++ch->sgidx < ch->desc->sglen) {
+ moxart_dma_start_sg(ch, ch->sgidx);
+ } else {
+ vchan_cookie_complete(&ch->desc->vd);
+ moxart_dma_start_desc(&ch->vc.chan);
+ }
+ spin_unlock_irqrestore(&ch->vc.lock, flags);
+ }
+ }
+
+ if (ctrl & APB_DMA_ERR_INT_STS) {
+ ctrl &= ~APB_DMA_ERR_INT_STS;
+ ch->error = 1;
+ }
+
+ writel(ctrl, ch->base + REG_OFF_CTRL);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int moxart_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct resource *res;
+ static void __iomem *dma_base_addr;
+ int ret, i;
+ unsigned int irq;
+ struct moxart_chan *ch;
+ struct moxart_dmadev *mdc;
+
+ mdc = devm_kzalloc(dev, sizeof(*mdc), GFP_KERNEL);
+ if (!mdc) {
+ dev_err(dev, "can't allocate DMA container\n");
+ return -ENOMEM;
+ }
+
+ irq = irq_of_parse_and_map(node, 0);
+ if (irq == NO_IRQ) {
+ dev_err(dev, "no IRQ resource\n");
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dma_base_addr = devm_ioremap_resource(dev, res);
+ if (IS_ERR(dma_base_addr))
+ return PTR_ERR(dma_base_addr);
+
+ dma_cap_zero(mdc->dma_slave.cap_mask);
+ dma_cap_set(DMA_SLAVE, mdc->dma_slave.cap_mask);
+ dma_cap_set(DMA_PRIVATE, mdc->dma_slave.cap_mask);
+
+ moxart_dma_init(&mdc->dma_slave, dev);
+
+ ch = &mdc->slave_chans[0];
+ for (i = 0; i < APB_DMA_MAX_CHANNEL; i++, ch++) {
+ ch->ch_num = i;
+ ch->base = dma_base_addr + i * REG_OFF_CHAN_SIZE;
+ ch->allocated = 0;
+
+ ch->vc.desc_free = moxart_dma_desc_free;
+ vchan_init(&ch->vc, &mdc->dma_slave);
+
+ dev_dbg(dev, "%s: chs[%d]: ch->ch_num=%u ch->base=%p\n",
+ __func__, i, ch->ch_num, ch->base);
+ }
+
+ platform_set_drvdata(pdev, mdc);
+
+ ret = devm_request_irq(dev, irq, moxart_dma_interrupt, 0,
+ "moxart-dma-engine", mdc);
+ if (ret) {
+ dev_err(dev, "devm_request_irq failed\n");
+ return ret;
+ }
+
+ ret = dma_async_device_register(&mdc->dma_slave);
+ if (ret) {
+ dev_err(dev, "dma_async_device_register failed\n");
+ return ret;
+ }
+
+ ret = of_dma_controller_register(node, moxart_of_xlate, mdc);
+ if (ret) {
+ dev_err(dev, "of_dma_controller_register failed\n");
+ dma_async_device_unregister(&mdc->dma_slave);
+ return ret;
+ }
+
+ dev_dbg(dev, "%s: IRQ=%u\n", __func__, irq);
+
+ return 0;
+}
+
+static int moxart_remove(struct platform_device *pdev)
+{
+ struct moxart_dmadev *m = platform_get_drvdata(pdev);
+
+ dma_async_device_unregister(&m->dma_slave);
+
+ if (pdev->dev.of_node)
+ of_dma_controller_free(pdev->dev.of_node);
+
+ return 0;
+}
+
+static const struct of_device_id moxart_dma_match[] = {
+ { .compatible = "moxa,moxart-dma" },
+ { }
+};
+
+static struct platform_driver moxart_driver = {
+ .probe = moxart_probe,
+ .remove = moxart_remove,
+ .driver = {
+ .name = "moxart-dma-engine",
+ .owner = THIS_MODULE,
+ .of_match_table = moxart_dma_match,
+ },
+};
+
+static int moxart_init(void)
+{
+ return platform_driver_register(&moxart_driver);
+}
+subsys_initcall(moxart_init);
+
+static void __exit moxart_exit(void)
+{
+ platform_driver_unregister(&moxart_driver);
+}
+module_exit(moxart_exit);
+
+MODULE_AUTHOR("Jonas Jensen <jonas.jensen@gmail.com>");
+MODULE_DESCRIPTION("MOXART DMA engine driver");
+MODULE_LICENSE("GPL v2");
--
1.8.2.1
^ permalink raw reply related
* [PATCH v4 0/7] mtd: spi-nor: add a new framework for SPI NOR
From: Jagan Teki @ 2014-01-17 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140117065401.GA6140@shlinux2.ap.freescale.net>
On Fri, Jan 17, 2014 at 12:24 PM, Huang Shijie <b32955@freescale.com> wrote:
> On Fri, Jan 17, 2014 at 12:36:08PM +0530, Jagan Teki wrote:
>> >> My basic question is like I have a qspi spi controller in my SOC and I
>> >> designed two boards B1 and B2
>> >
>> > okay.
>> >
>> >> B1 with quad spi controller connected with non-flash as a slave and B2
>> >> with quad spi controller connected
>> >> with quad flash as a slave.
>> > You can use the framework for B2. But for B1, you should not use the framework,
>> > since this framework is just for the SPI-NOR. If you do not connected with
>> > a NOR, i think it's better to code another driver for your controller.
>>
>> Means we have two separate controller drivers for same controller one
>> with spi-nor and
>> another with spi is it?
> Take drivers/spi/spi-imx.c for example, if you connect a NOR to it, you only
> need to add a NOR device node in the device tree. In the probe, it will call
> the m25p80.c to probe the NOR device.
>
> But if we connect other device to it. you should set another device node for it.
>
> I am not sure if your controller driver can works as the spi-imx.c
My question here was - this new framework suggest to write a two
different controller
drivers one is for non spi-nor and spi-nor models? do you agree that?
And also one important note from your design was spi-nor mode is
completely bypassing
Linux spi core is that the good idea?
--
Thanks,
Jagan.
^ permalink raw reply
* [BUG] FL1009: xHCI host not responding to stop endpoint command.
From: Bjørn Mork @ 2014-01-17 8:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87fvon2khn.fsf@natisbad.org>
arno at natisbad.org (Arnaud Ebalard) writes:
> Sarah Sharp <sarah.a.sharp@linux.intel.com> writes:
>
>>> ... AFAICT, this is exactly what commit 35773dac5f86 does and reverting
>>> it does not help. If I am mistaken, can you point which part you want me
>>> to remove in the code to test?
>>>
>>> I am slowly starting to see a bisect session coming ;-)
>>
>> Try reverting commit 60e102ac73cd40069d077014c93c86dc7205cb68.
>
> AFAICT, this commit does not exist in master (Linus tree), i.e. it is
> not in 3.13.0-rc8.
That commit is a stable backport of 9df89d85b407690afa46ddfbccc80bec6869971d
which is in v3.13-rc8:
bjorn at nemi:/usr/local/src/git/linux$ git tag --contains 9df89d85b407690afa46ddfbccc80bec6869971d
usb-3.13-rc1
usb-3.13-rc3
usb-3.13-rc5
v3.13-rc1
v3.13-rc2
v3.13-rc3
v3.13-rc4
v3.13-rc5
v3.13-rc6
v3.13-rc7
v3.13-rc8
The stable backport is in all v3.12.x releases:
bjorn at nemi:/usr/local/src/git/linux$ git tag --contains 60e102ac73cd40069d077014c93c86dc7205cb68
v3.12.1
v3.12.2
v3.12.3
v3.12.4
v3.12.5
v3.12.6
v3.12.7
v3.12.8
Bj?rn
^ permalink raw reply
* [PATCH -trivial 4/4] thermal: rcar: Spelling s/delaye/delay/g
From: Zhang Rui @ 2014-01-17 8:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389121036-3555-5-git-send-email-geert@linux-m68k.org>
On Tue, 2014-01-07 at 19:57 +0100, Geert Uytterhoeven wrote:
> From: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
> Cc: Jiri Kosina <trivial@kernel.org>
applied.
thanks,
rui
> ---
> drivers/thermal/rcar_thermal.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
> index a5629500723a..32d591087307 100644
> --- a/drivers/thermal/rcar_thermal.c
> +++ b/drivers/thermal/rcar_thermal.c
> @@ -427,7 +427,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
> /* enable temperature comparation */
> rcar_thermal_common_write(common, ENR, 0x00030303);
>
> - idle = 0; /* polling delaye is not needed */
> + idle = 0; /* polling delay is not needed */
> }
>
> for (i = 0;; i++) {
^ permalink raw reply
* [PATCH v2 6/6] arm64: audit: Add audit hook in ptrace/syscall_trace
From: AKASHI Takahiro @ 2014-01-17 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389946399-4525-1-git-send-email-takahiro.akashi@linaro.org>
This patch adds auditing functions on entry to or exit from
every system call invocation.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
arch/arm64/include/asm/thread_info.h | 1 +
arch/arm64/kernel/entry.S | 3 +++
arch/arm64/kernel/ptrace.c | 12 ++++++++++++
3 files changed, 16 insertions(+)
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 720e70b..7468388 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -101,6 +101,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 1
#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
#define TIF_SYSCALL_TRACE 8
+#define TIF_SYSCALL_AUDIT 9
#define TIF_POLLING_NRFLAG 16
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FREEZE 19
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 4d2c6f3..5bb2c26 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -631,6 +631,9 @@ el0_svc_naked: // compat entry point
get_thread_info tsk
ldr x16, [tsk, #TI_FLAGS] // check for syscall tracing
tbnz x16, #TIF_SYSCALL_TRACE, __sys_trace // are we tracing syscalls?
+#ifdef CONFIG_AUDITSYSCALL
+ tbnz x16, #TIF_SYSCALL_AUDIT, __sys_trace // auditing syscalls?
+#endif
adr lr, ret_fast_syscall // return address
cmp scno, sc_nr // check upper syscall limit
b.hs ni_sys
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 6777a21..2ca169b 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/audit.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -38,6 +39,7 @@
#include <asm/compat.h>
#include <asm/debug-monitors.h>
#include <asm/pgtable.h>
+#include <asm/syscall.h>
#include <asm/traps.h>
#include <asm/system_misc.h>
@@ -1064,6 +1066,16 @@ asmlinkage int syscall_trace(int dir, struct pt_regs *regs)
{
unsigned long saved_reg;
+#ifdef CONFIG_AUDITSYSCALL
+ if (dir)
+ audit_syscall_exit(regs);
+ else
+ audit_syscall_entry(syscall_get_arch(current, regs),
+ (int)regs->syscallno,
+ regs->orig_x0, regs->regs[1],
+ regs->regs[2], regs->regs[3]);
+#endif /* CONFIG_AUDITSYSCALL */
+
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return regs->syscallno;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 5/6] arm64: audit: Add makefile rule to create unistd_32.h for compat syscalls
From: AKASHI Takahiro @ 2014-01-17 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389946399-4525-1-git-send-email-takahiro.akashi@linaro.org>
generic compat sycall audit (lib/compat_audit.c) requires unistd_32.h
for __NR_xyx compat syscall numbers. This is a different file from unistd32.h
on arm64 and so it must be generated from unistd32.h.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
arch/arm64/Makefile | 4 ++++
arch/arm64/kernel/syscalls/Makefile | 20 ++++++++++++++++++++
2 files changed, 24 insertions(+)
create mode 100644 arch/arm64/kernel/syscalls/Makefile
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 2fceb71..6d24f92 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -72,6 +72,10 @@ PHONY += vdso_install
vdso_install:
$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso $@
+# Compat syscall header generation
+archheaders:
+ $(Q)$(MAKE) $(build)=arch/arm64/kernel/syscalls $@
+
# We use MRPROPER_FILES and CLEAN_FILES now
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
diff --git a/arch/arm64/kernel/syscalls/Makefile b/arch/arm64/kernel/syscalls/Makefile
new file mode 100644
index 0000000..7661113
--- /dev/null
+++ b/arch/arm64/kernel/syscalls/Makefile
@@ -0,0 +1,20 @@
+out := $(obj)/../../include/generated/asm
+
+# Create output directory if not already present
+_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
+
+syshdr-$(CONFIG_COMPAT) += unistd_32.h
+
+targets += $(syshdr-y)
+
+quiet_cmd_syshdr = SYSHDR $@
+ cmd_syshdr = cat $< | sed -r \
+ -e 's/compat_//' \
+ -e 's/_wrapper//' \
+ -e 's/^__SYSCALL\((.*),[ ]*sys_([^)].*)\).*/\#define __NR_\2 \1/p;d' \
+ | grep -v __NR_ni_syscall > $@
+
+archheaders: $(addprefix $(out)/,$(syshdr-y))
+
+$(out)/unistd_32.h: $(src)/../../include/asm/unistd32.h
+ $(call if_changed,syshdr)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 4/6] arm64: audit: Add 32-bit (compat) syscall support
From: AKASHI Takahiro @ 2014-01-17 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389946399-4525-1-git-send-email-takahiro.akashi@linaro.org>
Generic audit code also support compat system calls now.
This patch adds a small piece of architecture dependent code.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
arch/arm64/include/asm/audit.h | 20 ++++++++++++++++++++
arch/arm64/include/asm/syscall.h | 10 ++++++++++
2 files changed, 30 insertions(+)
create mode 100644 arch/arm64/include/asm/audit.h
diff --git a/arch/arm64/include/asm/audit.h b/arch/arm64/include/asm/audit.h
new file mode 100644
index 0000000..70eef50
--- /dev/null
+++ b/arch/arm64/include/asm/audit.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm64/include/asm/audit.h
+ *
+ * Copyright (C) 2013 Linaro Limited
+ * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_AUDIT_H
+#define __ASM_AUDIT_H
+
+#include <linux/audit.h>
+
+#define audit_is_compat(arch) \
+ ((arch == AUDIT_ARCH_ARM) || (arch == AUDIT_ARCH_ARMEB))
+
+#endif /* __ASM_AUDIT_H */
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 3361fec..d7660e9 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -19,6 +19,7 @@
#include <linux/audit.h>
#include <linux/err.h>
#include <linux/sched.h>
+#include <asm/compat.h>
static inline int syscall_get_nr(struct task_struct *task,
@@ -109,6 +110,15 @@ static inline void syscall_set_arguments(struct task_struct *task,
static inline int syscall_get_arch(struct task_struct *task,
struct pt_regs *regs)
{
+#ifdef CONFIG_COMPAT
+ if (is_compat_thread(task_thread_info(task)))
+#ifdef __AARCH64EB__
+ return AUDIT_ARCH_ARMEB; /* only BE on BE */
+#else
+ return AUDIT_ARCH_ARM;
+#endif
+#endif
+
#ifdef __AARCH64EB__
return AUDIT_ARCH_AARCH64EB;
#else
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 3/6] arm64: Add audit support
From: AKASHI Takahiro @ 2014-01-17 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389946399-4525-1-git-send-email-takahiro.akashi@linaro.org>
On AArch64, audit can be enabled with CONFIG_AUDIT_GENERIC.
Most of audit features are implemented in generic way. This patch
adds a small piece of architecture dependent code.
syscall_get_arch(), which is used in seccomp, should just return
AUDIT_ARCH_*.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
arch/arm64/include/asm/syscall.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 70ba9d4..3361fec 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -16,7 +16,9 @@
#ifndef __ASM_SYSCALL_H
#define __ASM_SYSCALL_H
+#include <linux/audit.h>
#include <linux/err.h>
+#include <linux/sched.h>
static inline int syscall_get_nr(struct task_struct *task,
@@ -104,4 +106,14 @@ static inline void syscall_set_arguments(struct task_struct *task,
memcpy(®s->regs[i], args, n * sizeof(args[0]));
}
+static inline int syscall_get_arch(struct task_struct *task,
+ struct pt_regs *regs)
+{
+#ifdef __AARCH64EB__
+ return AUDIT_ARCH_AARCH64EB;
+#else
+ return AUDIT_ARCH_AARCH64;
+#endif
+}
+
#endif /* __ASM_SYSCALL_H */
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 2/6] arm64: Add regs_return_value() in syscall.h
From: AKASHI Takahiro @ 2014-01-17 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389946399-4525-1-git-send-email-takahiro.akashi@linaro.org>
This macro is used mainly for audit to record system call's results, but
may also be used in test_kprobes.c.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
arch/arm64/include/asm/ptrace.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0e7fa49..5800ec1 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -134,6 +134,11 @@ struct pt_regs {
#define user_stack_pointer(regs) \
((regs)->sp)
+static inline unsigned long regs_return_value(struct pt_regs *regs)
+{
+ return regs->regs[0];
+}
+
/*
* Are the current registers suitable for user mode? (used to maintain
* security in signal handlers)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 1/6] audit: Enable arm64 support
From: AKASHI Takahiro @ 2014-01-17 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1389946399-4525-1-git-send-email-takahiro.akashi@linaro.org>
This patch adds AUDIT_ARCH_* identifiers for arm64(AArch64), and
makes CONFIG_AUDITSYSCALL selectable.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
include/uapi/linux/audit.h | 2 ++
init/Kconfig | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 44b05a0..e39635b 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -327,6 +327,8 @@ enum {
/* distinguish syscall tables */
#define __AUDIT_ARCH_64BIT 0x80000000
#define __AUDIT_ARCH_LE 0x40000000
+#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_AARCH64EB (EM_AARCH64|__AUDIT_ARCH_64BIT)
#define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_ARMEB (EM_ARM)
diff --git a/init/Kconfig b/init/Kconfig
index 79383d3..3aae602 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -284,7 +284,7 @@ config AUDIT
config AUDITSYSCALL
bool "Enable system-call auditing support"
- depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT))
+ depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT) || ARM64)
default y if SECURITY_SELINUX
help
Enable low-overhead system-call auditing infrastructure that
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 0/6] arm64: Add audit support
From: AKASHI Takahiro @ 2014-01-17 8:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1383733546-2846-1-git-send-email-takahiro.akashi@linaro.org>
This patchset adds system call audit support on arm64.
Both 32-bit (AUIDT_ARCH_ARM[EB]) and 64-bit tasks (AUDIT_ARCH_AARCH64[EB])
are supported, but presuming 32-LE on 64-LE or 32-BE on 64-BE.
There are some prerequisites for this patch to work correctly:
* "generic compat system call audit support" patch
* "correct a type mismatch in audit_syscall_exit()" patch
(already accepted and queued in 3.14)
* "Modify a set of system calls in audit class" patch
* userspace audit tool (v2.3.2 + my patch for arm64)
All those were already or will be soon posted separately.
Please review them as well for better understandings.
This code was tested on both 32-bit and 64-bit LE userland
in the following two ways:
1) basic operations with auditctl/autrace
# auditctl -a exit,always -S openat -F path=/etc/inittab
# auditctl -a exit,always -F dir=/tmp -F perm=rw
# auditctl -a task,always
# autrace /bin/ls
by comparing output from autrace with one from strace
2) audit-test-code (+ my workarounds for arm/arm64)
by running "audit-tool", "filter" and "syscalls" test categories.
Changes v1 -> v2:
* Modified to utilize "generic compat system call audit" [3/6, 4/6, 5/6]
Please note that a required header, unistd_32.h, is automatically
generated from unistd32.h.
* Refer to regs->orig_x0 instead of regs->x0 as the first argument of
system call in audit_syscall_entry() [6/6]
* Include "Add regs_return_value() in syscall.h" patch [2/6],
which was not intentionally included in v1 because it could be added
by "kprobes support".
AKASHI Takahiro (6):
audit: Enable arm64 support
arm64: Add regs_return_value() in syscall.h
arm64: Add audit support
arm64: audit: Add 32-bit (compat) syscall support
arm64: audit: Add makefile rule to create unistd_32.h for compat
syscalls
arm64: audit: Add audit hook in ptrace/syscall_trace
arch/arm64/Makefile | 4 ++++
arch/arm64/include/asm/audit.h | 20 ++++++++++++++++++++
arch/arm64/include/asm/ptrace.h | 5 +++++
arch/arm64/include/asm/syscall.h | 22 ++++++++++++++++++++++
arch/arm64/include/asm/thread_info.h | 1 +
arch/arm64/kernel/entry.S | 3 +++
arch/arm64/kernel/ptrace.c | 12 ++++++++++++
arch/arm64/kernel/syscalls/Makefile | 20 ++++++++++++++++++++
include/uapi/linux/audit.h | 2 ++
init/Kconfig | 2 +-
10 files changed, 90 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/include/asm/audit.h
create mode 100644 arch/arm64/kernel/syscalls/Makefile
--
1.7.9.5
^ permalink raw reply
* [PATCH] audit: Modify a set of system calls in audit class definitions
From: AKASHI Takahiro @ 2014-01-17 8:05 UTC (permalink / raw)
To: linux-arm-kernel
Each asm-generic/audit_xx.h defines a set of system calls for respective
audit permssion class (read, write, change attribute or exec).
This patch changes two entries:
1) fchown in audit_change_attr.h
Make fchown included by its own because in asm-generic/unistd.h, for example,
fchown always exists while chown is optional. This change is necessary at
least for arm64.
2) truncate64 in audit_write.h
Add missing truncate64/ftruncate64 as well as truncate/ftruncate
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
include/asm-generic/audit_change_attr.h | 4 +++-
include/asm-generic/audit_write.h | 6 ++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/include/asm-generic/audit_change_attr.h b/include/asm-generic/audit_change_attr.h
index 89b73e5..a186553 100644
--- a/include/asm-generic/audit_change_attr.h
+++ b/include/asm-generic/audit_change_attr.h
@@ -4,9 +4,11 @@ __NR_chmod,
__NR_fchmod,
#ifdef __NR_chown
__NR_chown,
-__NR_fchown,
__NR_lchown,
#endif
+#ifdef __NR_fchown
+__NR_fchown,
+#endif
__NR_setxattr,
__NR_lsetxattr,
__NR_fsetxattr,
diff --git a/include/asm-generic/audit_write.h b/include/asm-generic/audit_write.h
index e7020c5..274575d 100644
--- a/include/asm-generic/audit_write.h
+++ b/include/asm-generic/audit_write.h
@@ -10,6 +10,12 @@ __NR_truncate,
#ifdef __NR_truncate64
__NR_truncate64,
#endif
+#ifdef __NR_ftruncate
+__NR_ftruncate,
+#endif
+#ifdef __NR_ftruncate64
+__NR_ftruncate64,
+#endif
#ifdef __NR_bind
__NR_bind, /* bind can affect fs object only in one way... */
#endif
--
1.7.9.5
^ permalink raw reply related
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