* [PATCH] Adding basic support for the INet-97F_Rev_02 board
From: David Lanzendörfer @ 2014-02-07 14:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F4E83A.1060109@redhat.com>
Hi Hans
> Thanks for the patch, I've added it to my sunxi-devel tree.
Great!
> It seems this has been missed by Maxime, because you did not send it
> directly to him. Can you please rebase it one 3.14-rc1, and then send it
> directly to Maxime Ripard, with the relevant mailinglists in the CC?
Yes. I can and I will.
cheers
David
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140207/119b5cbd/attachment.sig>
^ permalink raw reply
* [PATCH] clk: respect the clock dependencies in of_clk_init
From: Jason Cooper @ 2014-02-07 14:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F4DA40.4090804@elopez.com.ar>
On Fri, Feb 07, 2014 at 10:06:08AM -0300, Emilio L?pez wrote:
[snip a great explanation]
Guys, can I get some Tested-by's on this?
thx,
Jason.
> -----8<------
>
> From ffdb49506e3ce92090c15e1f9b37f4d465097ac1 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
> Date: Thu, 6 Feb 2014 18:07:07 -0300
> Subject: [PATCH] clk: mvebu: fix name dependency during registration time
>
> Currently, mvebu_clk_gating_setup has a silly dependency on clock
> registration order just to gather the parent clock name. This is
> completely unnecesary, as it supports using an already provided name
> via the clk_gating_soc_desc structs, and we can therefore solve this
> issue with a 69+/- line patch. But, given that the parent name is
> always "tclk" as default-hardcoded on mvebu_coreclk_setup(), we can
> just default-hardcode it here too and get away with solving this
> problem with a one-liner.
> ---
> drivers/clk/mvebu/common.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c
> index 25ceccf..6c63b43 100644
> --- a/drivers/clk/mvebu/common.c
> +++ b/drivers/clk/mvebu/common.c
> @@ -121,7 +121,7 @@ void __init mvebu_clk_gating_setup(struct
> device_node *np,
> struct clk_gating_ctrl *ctrl;
> struct clk *clk;
> void __iomem *base;
> - const char *default_parent = NULL;
> + const char *default_parent = "tclk";
> int n;
>
> base = of_iomap(np, 0);
> --
> 1.8.5.3
^ permalink raw reply
* [PATCH 10/21] ARM: MM: Add DT binding for Feroceon L2 cache
From: Jason Cooper @ 2014-02-07 14:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207093206.GE17758@lunn.ch>
On Fri, Feb 07, 2014 at 10:32:06AM +0100, Andrew Lunn wrote:
> On Thu, Feb 06, 2014 at 08:27:52PM -0500, Jason Cooper wrote:
> > On Fri, Feb 07, 2014 at 12:42:06AM +0100, Andrew Lunn wrote:
> > > Instantiate the L2 cache from DT. Indicate in DT where the cache
> > > control register is and if write through should be made.
> > >
> > > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> > > ---
> > > .../devicetree/bindings/arm/mrvl/foroceon.txt | 19 +++++++++
> > > arch/arm/boot/dts/kirkwood.dtsi | 5 +++
> > > arch/arm/include/asm/hardware/cache-feroceon-l2.h | 2 +
> > > arch/arm/mach-kirkwood/board-dt.c | 15 +------
> > > arch/arm/mm/cache-feroceon-l2.c | 46 ++++++++++++++++++++++
> > > 5 files changed, 73 insertions(+), 14 deletions(-)
> > > create mode 100644 Documentation/devicetree/bindings/arm/mrvl/foroceon.txt
> >
> > for the next revision, please split out the dtsi changes into a separate
> > patch.
> >
> > >
> > > diff --git a/Documentation/devicetree/bindings/arm/mrvl/foroceon.txt b/Documentation/devicetree/bindings/arm/mrvl/foroceon.txt
> > > new file mode 100644
> > > index 000000000000..8058676d1476
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/arm/mrvl/foroceon.txt
> >
> > name typo.
> >
> > > @@ -0,0 +1,19 @@
> > > +* Marvell Feroceon Cache
> > > +
> > > +Required properties:
> > > +- compatible : Should be "marvell,feroceon-kirkwood".
> >
> > This is a little ambiguous, I'd like to see 'l2' in the compatible string.
>
> I will take Jason's advice on naming and change this..
Ack. (I assume you meant JasonG)
> > > +#ifdef CONFIG_OF
> > > +static const struct of_device_id feroceon_ids[] __initconst = {
> > > + { .compatible = "marvell,feroceon-kirkwood"},
> > > + {}
> > > +};
> > > +
> > > +int __init feroceon_of_init(void)
> > > +{
> > > + struct device_node *node;
> > > + void __iomem *base;
> > > + bool writethrough = false;
> > > + struct resource res;
> > > +
> > > + node = of_find_matching_node(NULL, feroceon_ids);
> > > + if (!node) {
> > > + pr_info("Didn't find marvell,feroceon-*, not enabling it\n");
> > > + return -ENODEV;
> > > + }
> >
> > I'd prefer to fallback to hardcoded register address here. We know
> > we're on kirkwood at this point.
>
> We could also be on mv78xx0, sometime in the future. So we need to at
> least look at the compatible string to see what SoC we are. It is also
> rather ugly having hard coded addresses. We might as well go back to
> platform devices.
reverting to default behavior for missing dt information is an
acceptable compromise to the evolving DT landscape. However...
> I would prefer upping this to pr_err(FW_INFO, and not falling back to
> hard coded values. This is not a fatal error, the machine continues to
> run, just a bit slower.
You are correct, and it would encourage the user to update their DT
blob. So I'm fine with the way you have it.
thx,
Jason.
^ permalink raw reply
* [PATCH v3 0/5] clk: sunxi usb clks support
From: Hans de Goede @ 2014-02-07 14:32 UTC (permalink / raw)
To: linux-arm-kernel
Hi All,
Here is v3 of my sunxi usb clks support series.
Changes since v2:
-rename the compatibilty strings from foo-usb-gates-clk to foo-usb-clk
Note the dts bits (patches 3-5) of this series depends on Chen-Yu Tsai's clk
rename series.
Emilio, should Mike pick patches 1-2 up directly, or should they go through
your tree?
Maxime, can you please add patches 3-5 to your dts tree ? Assuming that
wens clk rename patches are already there.
Thanks & Regards,
Hans
^ permalink raw reply
* [PATCH v3 1/5] clk: sunxi: Add support for USB clock-register reset bits
From: Hans de Goede @ 2014-02-07 14:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391783553-8096-1-git-send-email-hdegoede@redhat.com>
The usb-clk register is special in that it not only contains clk gate bits,
but also has a few reset bits. This commit adds support for this by allowing
gates type sunxi clks to also register a reset controller.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/clk/sunxi/clk-sunxi.c | 71 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 64bda21..1e15e4c 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -18,6 +18,7 @@
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/reset-controller.h>
#include "clk-factors.h"
@@ -838,6 +839,59 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
/**
+ * sunxi_gates_reset... - reset bits in leaf gate clk registers handling
+ */
+
+struct gates_reset_data {
+ void __iomem *reg;
+ spinlock_t *lock;
+ struct reset_controller_dev rcdev;
+};
+
+static int sunxi_gates_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct gates_reset_data *data = container_of(rcdev,
+ struct gates_reset_data,
+ rcdev);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(data->lock, flags);
+
+ reg = readl(data->reg);
+ writel(reg & ~BIT(id), data->reg);
+
+ spin_unlock_irqrestore(data->lock, flags);
+
+ return 0;
+}
+
+static int sunxi_gates_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct gates_reset_data *data = container_of(rcdev,
+ struct gates_reset_data,
+ rcdev);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(data->lock, flags);
+
+ reg = readl(data->reg);
+ writel(reg | BIT(id), data->reg);
+
+ spin_unlock_irqrestore(data->lock, flags);
+
+ return 0;
+}
+
+static struct reset_control_ops sunxi_gates_reset_ops = {
+ .assert = sunxi_gates_reset_assert,
+ .deassert = sunxi_gates_reset_deassert,
+};
+
+/**
* sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
*/
@@ -845,6 +899,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
struct gates_data {
DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
+ u32 reset_mask;
};
static const struct gates_data sun4i_axi_gates_data __initconst = {
@@ -915,6 +970,7 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
struct gates_data *data)
{
struct clk_onecell_data *clk_data;
+ struct gates_reset_data *reset_data;
const char *clk_parent;
const char *clk_name;
void *reg;
@@ -958,6 +1014,21 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
clk_data->clk_num = i;
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+ /* Register a reset controler for gates with reset bits */
+ if (data->reset_mask == 0)
+ return;
+
+ reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
+ if (!reset_data)
+ return;
+
+ reset_data->reg = reg;
+ reset_data->lock = &clk_lock;
+ reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1;
+ reset_data->rcdev.ops = &sunxi_gates_reset_ops;
+ reset_data->rcdev.of_node = node;
+ reset_controller_register(&reset_data->rcdev);
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3 2/5] clk: sunxi: Add USB clock register defintions
From: Hans de Goede @ 2014-02-07 14:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391783553-8096-1-git-send-email-hdegoede@redhat.com>
From: Roman Byshko <rbyshko@gmail.com>
Add register definitions for the usb-clk register found on sun4i, sun5i and
sun7i SoCs.
Signed-off-by: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 5 +++++
drivers/clk/sunxi/clk-sunxi.c | 12 ++++++++++++
2 files changed, 17 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 27f19f1..e368a86c 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -38,6 +38,8 @@ Required properties:
"allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
"allwinner,sun7i-a20-out-clk" - for the external output clocks
"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
+ "allwinner,sun4i-usb-clk" - for usb gates + resets on A10 / A20
+ "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
Required properties for all clocks:
- reg : shall be the control register address for the clock.
@@ -54,6 +56,9 @@ Required properties for all clocks:
For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
dummy clocks at 25 MHz and 125 MHz, respectively. See example.
+And "allwinner,*-usb-clk" clocks also require:
+- reset-cells : shall be set to 1
+
Clock consumers should specify the desired clocks they use with a
"clocks" phandle cell. Consumers that are using a gated clock should
provide an additional ID in their clock property. This ID is the
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 1e15e4c..3ba1402 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -910,6 +910,16 @@ static const struct gates_data sun4i_ahb_gates_data __initconst = {
.mask = {0x7F77FFF, 0x14FB3F},
};
+static const struct gates_data sun4i_usb_gates_data __initconst = {
+ .mask = {0x1C0},
+ .reset_mask = 0x07,
+};
+
+static const struct gates_data sun5i_a13_usb_gates_data __initconst = {
+ .mask = {0x140},
+ .reset_mask = 0x03,
+};
+
static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
.mask = {0x147667e7, 0x185915},
};
@@ -1257,6 +1267,8 @@ static const struct of_device_id clk_gates_match[] __initconst = {
{.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
{.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
{.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
+ {.compatible = "allwinner,sun4i-usb-clk", .data = &sun4i_usb_gates_data,},
+ {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,},
{}
};
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3 3/5] ARM: sun4i: dt: Add bindings for USB clocks
From: Hans de Goede @ 2014-02-07 14:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391783553-8096-1-git-send-email-hdegoede@redhat.com>
From: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index ebb4cd0..c57df3e 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -301,6 +301,15 @@
clock-output-names = "ir1";
};
+ usb_clk: clk at 01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+ };
+
spi3_clk: clk at 01c200d4 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3 4/5] ARM: sun5i: dt: Add bindings for USB clocks
From: Hans de Goede @ 2014-02-07 14:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391783553-8096-1-git-send-email-hdegoede@redhat.com>
From: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun5i-a10s.dtsi | 9 +++++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 9 +++++++++
2 files changed, 18 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index 38d01bd..2ed7429 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -264,6 +264,15 @@
clock-output-names = "ir0";
};
+ usb_clk: clk at 01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun5i-a13-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_phy";
+ };
+
mbus_clk: clk at 01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index ddd39d3..30ece67 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -261,6 +261,15 @@
clock-output-names = "ir0";
};
+ usb_clk: clk at 01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun5i-a13-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_phy";
+ };
+
mbus_clk: clk at 01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3 5/5] ARM: sun7i: dt: Add bindings for USB clocks
From: Hans de Goede @ 2014-02-07 14:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391783553-8096-1-git-send-email-hdegoede@redhat.com>
From: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Roman Byshko <rbyshko@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
arch/arm/boot/dts/sun7i-a20.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 316cab8..6550e07c 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -289,6 +289,15 @@
clock-output-names = "ir1";
};
+ usb_clk: clk at 01c200cc {
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ compatible = "allwinner,sun4i-usb-clk";
+ reg = <0x01c200cc 0x4>;
+ clocks = <&pll6 1>;
+ clock-output-names = "usb_ohci0", "usb_ohci1", "usb_phy";
+ };
+
spi3_clk: clk at 01c200d4 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
--
1.8.4.2
^ permalink raw reply related
* [PATCH 16/21] drivers: Enable building of Kirkwood drivers for mach-mvebu
From: Jason Cooper @ 2014-02-07 14:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207091336.GC17758@lunn.ch>
On Fri, Feb 07, 2014 at 10:13:36AM +0100, Andrew Lunn wrote:
> On Thu, Feb 06, 2014 at 08:59:15PM -0500, Jason Cooper wrote:
> > On Fri, Feb 07, 2014 at 12:42:12AM +0100, Andrew Lunn wrote:
> > > With the move to mach-mvebu, drivers Kconfig need tweeking to allow
> > > the kirkwood specific drivers to be built.
> > >
> > > Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> > > ---
> > > drivers/cpufreq/Kconfig.arm | 2 +-
> > > drivers/cpuidle/Kconfig.arm | 2 +-
> > > drivers/leds/Kconfig | 4 ++--
> > > drivers/phy/Kconfig | 2 +-
> > > drivers/thermal/Kconfig | 2 +-
> > > sound/soc/kirkwood/Kconfig | 2 +-
> > > 6 files changed, 7 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> > > index 31297499a60a..de931081fd01 100644
> > > --- a/drivers/cpufreq/Kconfig.arm
> > > +++ b/drivers/cpufreq/Kconfig.arm
> > > @@ -113,7 +113,7 @@ config ARM_INTEGRATOR
> > > If in doubt, say Y.
> > >
> > > config ARM_KIRKWOOD_CPUFREQ
> > > - def_bool ARCH_KIRKWOOD && OF
> > > + def_bool (ARCH_KIRKWOOD || MACH_KIRKWOOD) && OF
> >
> > I agree with creating MACH_KIRKWOOD underneath ARCH_MVEBU earlier in
> > this series, but the 'ARCH_KIRKWOOD || MACH_KIRKWOOD' just looks
> > confusing.
Hmm, I was tired last night. I should've offered a suggestion with my
complaint :) Unfortunately, the only thing I can come up with is a
oneline comment explaining DT/non-DT... other ideas? Or, not worth the
effort?
thx,
Jason.
^ permalink raw reply
* [PATCH v2] ARM: at91: add Atmel's SAMA5D3 Xplained board
From: Nicolas Ferre @ 2014-02-07 14:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207080142.GR9558@ns203013.ovh.net>
On 07/02/2014 09:01, Jean-Christophe PLAGNIOL-VILLARD :
> On 09:35 Wed 05 Feb , Nicolas Ferre wrote:
>> Add DT file for new SAMA5D3 Xpained board.
>> This board is based on Atmel's SAMA5D36 Cortex-A5 SoC.
>>
>> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
>> ---
>> arch/arm/boot/dts/Makefile | 1 +
>> arch/arm/boot/dts/at91-sama5d3_xplained.dts | 233 ++++++++++++++++++++++++++++
>> 2 files changed, 234 insertions(+)
>> create mode 100644 arch/arm/boot/dts/at91-sama5d3_xplained.dts
>>
>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> index b9d6a8b485e0..6d1e43d46187 100644
>> --- a/arch/arm/boot/dts/Makefile
>> +++ b/arch/arm/boot/dts/Makefile
>> @@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
>> dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
>> dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
>> # sama5d3
>> +dtb-$(CONFIG_ARCH_AT91) += at91-sama5d3_xplained.dtb
>> dtb-$(CONFIG_ARCH_AT91) += sama5d31ek.dtb
>> dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb
>> dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb
>> diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
>> new file mode 100644
>> index 000000000000..fb1349ca60a4
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
>> @@ -0,0 +1,233 @@
>> +/*
>> + * at91-sama5d3_xplained.dts - Device Tree file for the SAMA5D3 Xplained board
>> + *
>> + * Copyright (C) 2014 Atmel,
>> + * 2014 Nicolas Ferre <nicolas.ferre@atmel.com>
>> + *
>> + * Licensed under GPLv2 or later.
>> + */
>> +/dts-v1/;
>> +#include "sama5d36.dtsi"
>> +
>> +/ {
>> + model = "SAMA5D3 Xplained";
>> + compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5";
>> +
>> + chosen {
>> + bootargs = "console=ttyS0,115200";
> can you describe it via linux,stdout
Well I would have liked, but the code in the serial driver is not there yet.
So, I keep it like this for the moment.
>> + };
>> +
>> + memory {
>> + reg = <0x20000000 0x10000000>;
>> + };
>> +
>> + ahb {
>> + apb {
>> + mmc0: mmc at f0000000 {
>> + pinc?trl-names = "default";
> ?? this is SoC should never been seen here
>> + pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>;
>> + status = "okay";
>> + slot at 0 {
>> + reg = <0>;
>> + bus-width = <8>;
>> + cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>;
>> + };
>> + };
>> +
>> + spi0: spi at f0004000 {
>> + cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
> if you use only one CS no need to specified all
>
> we need to add macro per SoC for the hw CS used as GPIO so it's more clear
No, I do not think so.
>> + status = "okay";
>> + };
>> +
>> + can0: can at f000c000 {
>> + status = "okay";
>> + };
>> +
>> + i2c0: i2c at f0014000 {
>> + status = "okay";
>> + };
>> +
>> + i2c1: i2c at f0018000 {
>> + status = "okay";
>> + };
>> +
>> + macb0: ethernet at f0028000 {
>> + phy-mode = "rgmii";
>> + status = "okay";
>> + };
>> +
>> + usart0: serial at f001c000 {
>> + status = "okay";
>> + };
>> +
>> + usart1: serial at f0020000 {
>> + pinctrl-names = "default";
> same as mmc
>> + pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
>> + status = "okay";
>> + };
>> +
>> + uart0: serial at f0024000 {
>> + status = "okay";
>> + };
>> +
>> + mmc1: mmc at f8000000 {
>> + pinctrl-names = "default";
> ditto
>> + pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
>> + status = "okay";
>> + slot at 0 {
>> + reg = <0>;
>> + bus-width = <4>;
>> + cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>;
>> + };
>> + };
>> +
>> + spi1: spi at f8008000 {
>> + cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>;
>> + status = "okay";
>> + };
>> +
>> + adc0: adc at f8018000 {
>> + pinctrl-names = "default";
> ditto
>> + pinctrl-0 = <
>> + &pinctrl_adc0_adtrg
>> + &pinctrl_adc0_ad0
>> + &pinctrl_adc0_ad1
>> + &pinctrl_adc0_ad2
>> + &pinctrl_adc0_ad3
>> + &pinctrl_adc0_ad4
>> + &pinctrl_adc0_ad5
>> + &pinctrl_adc0_ad6
>> + &pinctrl_adc0_ad7
>> + &pinctrl_adc0_ad8
>> + &pinctrl_adc0_ad9
>> + >;
>> + status = "okay";
>> + };
>> +
>> + i2c2: i2c at f801c000 {
>> + dmas = <0>, <0>; /* Do not use DMA for i2c2 */
> why?
Because we use the channels for other peripherals
>> + status = "okay";
>> + };
>> +
>> + macb1: ethernet at f802c000 {
>> + phy-mode = "rmii";
>> + status = "okay";
>> + };
>> +
>> + dbgu: serial at ffffee00 {
>> + status = "okay";
>> + };
>> +
>> + pinctrl at fffff200 {
>> + board {
>> + pinctrl_mmc0_cd: mmc0_cd {
>> + atmel,pins =
>> + <AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
>> + };
>> +
>> + pinctrl_mmc1_cd: mmc1_cd {
>> + atmel,pins =
>> + <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
>> + };
>> +
>> + pinctrl_usba_vbus: usba_vbus {
>> + atmel,pins =
>> + <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */
> in this case we should have ifdef so we could choose what we want via make
> file
No, we choose by modifying the DTS.
>> + };
>> + };
>> + };
>> +
>> + pmc: pmc at fffffc00 {
>> + main: mainck {
>> + clock-frequency = <12000000>;
>> + };
>> + };
>> + };
>> +
>> + nand0: nand at 60000000 {
>> + nand-bus-width = <8>;
>> + nand-ecc-mode = "hw";
>> + atmel,has-pmecc;
>> + atmel,pmecc-cap = <4>;
>> + atmel,pmecc-sector-size = <512>;
>> + nand-on-flash-bbt;
>> + status = "okay";
>> +
>> + at91bootstrap at 0 {
>> + label = "at91bootstrap";
>> + reg = <0x0 0x40000>;
>> + };
>> +
>> + bootloader at 40000 {
>> + label = "bootloader";
>> + reg = <0x40000 0x80000>;
>> + };
>> +
>> + bootloaderenv at c0000 {
>> + label = "bootloader env";
>> + reg = <0xc0000 0xc0000>;
>> + };
>> +
>> + dtb at 180000 {
>> + label = "device tree";
>> + reg = <0x180000 0x80000>;
>> + };
>> +
>> + kernel at 200000 {
>> + label = "kernel";
>> + reg = <0x200000 0x600000>;
>> + };
>> +
>> + rootfs at 800000 {
>> + label = "rootfs";
>> + reg = <0x800000 0x0f800000>;
>> + };
> more I read this partition more it's seems wrong those days
>
> we really need to switch to UBI
I am using UBI with this layout.
>> + };
>> +
>> + usb0: gadget at 00500000 {
>> + atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_usba_vbus>;
>> + status = "okay";
>> + };
>> +
>> + usb1: ohci at 00600000 {
>> + num-ports = <3>;
>> + atmel,vbus-gpio = <0
>> + &pioE 3 GPIO_ACTIVE_LOW
>> + &pioE 4 GPIO_ACTIVE_LOW
>> + >;
>> + status = "okay";
>> + };
>> +
>> + usb2: ehci at 00700000 {
>> + status = "okay";
>> + };
>> + };
>> +
>> + gpio_keys {
>> + compatible = "gpio-keys";
>> +
>> + bp3 {
>> + label = "PB_USER";
>> + gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
>> + linux,code = <0x104>;
>> + gpio-key,wakeup;
>> + };
>> + };
>> +
>> + leds {
>> + compatible = "gpio-leds";
>> +
>> + d2 {
>> + label = "d2";
>> + gpios = <&pioE 23 GPIO_ACTIVE_LOW>; /* PE23, conflicts with A23, CTS2 */
>> + linux,default-trigger = "heartbeat";
>> + };
>> +
>> + d3 {
>> + label = "d3";
>> + gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
>> + };
>> + };
>> +};
>> --
>> 1.8.2.2
>>
>
--
Nicolas Ferre
^ permalink raw reply
* [PATCH] clk: respect the clock dependencies in of_clk_init
From: Ezequiel Garcia @ 2014-02-07 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207142430.GU8533@titan.lakedaemon.net>
On Fri, Feb 07, 2014 at 09:24:30AM -0500, Jason Cooper wrote:
> On Fri, Feb 07, 2014 at 10:06:08AM -0300, Emilio L?pez wrote:
>
> [snip a great explanation]
>
> Guys, can I get some Tested-by's on this?
>
In case someone missed Emilio's comment about it, I gave his oneliner
a test on A370 Reference Design. It worked just as well as Sebastian's.
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> > -----8<------
> >
> > From ffdb49506e3ce92090c15e1f9b37f4d465097ac1 Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
> > Date: Thu, 6 Feb 2014 18:07:07 -0300
> > Subject: [PATCH] clk: mvebu: fix name dependency during registration time
> >
> > Currently, mvebu_clk_gating_setup has a silly dependency on clock
> > registration order just to gather the parent clock name. This is
> > completely unnecesary, as it supports using an already provided name
> > via the clk_gating_soc_desc structs, and we can therefore solve this
> > issue with a 69+/- line patch. But, given that the parent name is
> > always "tclk" as default-hardcoded on mvebu_coreclk_setup(), we can
> > just default-hardcode it here too and get away with solving this
> > problem with a one-liner.
> > ---
> > drivers/clk/mvebu/common.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c
> > index 25ceccf..6c63b43 100644
> > --- a/drivers/clk/mvebu/common.c
> > +++ b/drivers/clk/mvebu/common.c
> > @@ -121,7 +121,7 @@ void __init mvebu_clk_gating_setup(struct
> > device_node *np,
> > struct clk_gating_ctrl *ctrl;
> > struct clk *clk;
> > void __iomem *base;
> > - const char *default_parent = NULL;
> > + const char *default_parent = "tclk";
> > int n;
> >
> > base = of_iomap(np, 0);
> > --
> > 1.8.5.3
--
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH 1/2] arm64: Add seccomp support
From: Arnd Bergmann @ 2014-02-07 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391767892-5395-2-git-send-email-takahiro.akashi@linaro.org>
On Friday 07 February 2014 19:11:31 AKASHI Takahiro wrote:
> diff --git a/arch/arm64/include/asm/seccomp.h b/arch/arm64/include/asm/seccomp.h
> new file mode 100644
> index 0000000..3482155
> --- /dev/null
> +++ b/arch/arm64/include/asm/seccomp.h
> @@ -0,0 +1,28 @@
> +/*
> + * arch/arm64/include/asm/seccomp.h
> + *
> + * Copyright (C) 2014 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_SECCOMP_H
> +#define _ASM_SECCOMP_H
> +
> +#include <asm/unistd.h>
> +
> +#ifdef CONFIG_COMPAT
> +#define __NR_seccomp_read_32 __NR_compat_read
> +#define __NR_seccomp_write_32 __NR_compat_write
> +#define __NR_seccomp_exit_32 __NR_compat_exit
> +#define __NR_seccomp_sigreturn_32 __NR_compat_sigreturn
> +#endif /* CONFIG_COMPAT */
> +
> +#define __NR_seccomp_read __NR_read
> +#define __NR_seccomp_write __NR_write
> +#define __NR_seccomp_exit __NR_exit
> +#define __NR_seccomp_sigreturn __NR_rt_sigreturn
> +
> +#endif /* _ASM_SECCOMP_H */
>
This file looks extremely generic and can be shared by every
architecture other than MIPS for all I can tell.
Please add it to include/asm-generic instead of arch/arm64,
and add a line to arch/arm64/include/asm/Kbuild.
Arnd
^ permalink raw reply
* [PATCH v3 2/5] clk: sunxi: Add USB clock register defintions
From: Maxime Ripard @ 2014-02-07 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391783553-8096-3-git-send-email-hdegoede@redhat.com>
Hi,
On Fri, Feb 07, 2014 at 03:32:30PM +0100, Hans de Goede wrote:
> From: Roman Byshko <rbyshko@gmail.com>
>
> Add register definitions for the usb-clk register found on sun4i, sun5i and
> sun7i SoCs.
>
> Signed-off-by: Roman Byshko <rbyshko@gmail.com>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Documentation/devicetree/bindings/clock/sunxi.txt | 5 +++++
> drivers/clk/sunxi/clk-sunxi.c | 12 ++++++++++++
> 2 files changed, 17 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index 27f19f1..e368a86c 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -38,6 +38,8 @@ Required properties:
> "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
> "allwinner,sun7i-a20-out-clk" - for the external output clocks
> "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
> + "allwinner,sun4i-usb-clk" - for usb gates + resets on A10 / A20
I know I asked you otherwise, but since we're moving to sun4i-a10-*
compatibles, can you do it here too ? :)
Thanks!
Maxime
> + "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
>
> Required properties for all clocks:
> - reg : shall be the control register address for the clock.
> @@ -54,6 +56,9 @@ Required properties for all clocks:
> For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
> dummy clocks at 25 MHz and 125 MHz, respectively. See example.
>
> +And "allwinner,*-usb-clk" clocks also require:
> +- reset-cells : shall be set to 1
> +
> Clock consumers should specify the desired clocks they use with a
> "clocks" phandle cell. Consumers that are using a gated clock should
> provide an additional ID in their clock property. This ID is the
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 1e15e4c..3ba1402 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -910,6 +910,16 @@ static const struct gates_data sun4i_ahb_gates_data __initconst = {
> .mask = {0x7F77FFF, 0x14FB3F},
> };
>
> +static const struct gates_data sun4i_usb_gates_data __initconst = {
> + .mask = {0x1C0},
> + .reset_mask = 0x07,
> +};
> +
> +static const struct gates_data sun5i_a13_usb_gates_data __initconst = {
> + .mask = {0x140},
> + .reset_mask = 0x03,
> +};
> +
> static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
> .mask = {0x147667e7, 0x185915},
> };
> @@ -1257,6 +1267,8 @@ static const struct of_device_id clk_gates_match[] __initconst = {
> {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
> {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
> {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
> + {.compatible = "allwinner,sun4i-usb-clk", .data = &sun4i_usb_gates_data,},
> + {.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,},
> {}
> };
>
> --
> 1.8.4.2
>
--
Maxime Ripard, 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/20140207/370f530c/attachment-0001.sig>
^ permalink raw reply
* [PATCH 10/21] ARM: MM: Add DT binding for Feroceon L2 cache
From: Sudeep Holla @ 2014-02-07 14:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391730137-14814-11-git-send-email-andrew@lunn.ch>
On 06/02/14 23:42, Andrew Lunn wrote:
> Instantiate the L2 cache from DT. Indicate in DT where the cache
> control register is and if write through should be made.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> .../devicetree/bindings/arm/mrvl/foroceon.txt | 19 +++++++++
> arch/arm/boot/dts/kirkwood.dtsi | 5 +++
> arch/arm/include/asm/hardware/cache-feroceon-l2.h | 2 +
> arch/arm/mach-kirkwood/board-dt.c | 15 +------
> arch/arm/mm/cache-feroceon-l2.c | 46 ++++++++++++++++++++++
> 5 files changed, 73 insertions(+), 14 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/mrvl/foroceon.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/mrvl/foroceon.txt b/Documentation/devicetree/bindings/arm/mrvl/foroceon.txt
> new file mode 100644
> index 000000000000..8058676d1476
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/mrvl/foroceon.txt
> @@ -0,0 +1,19 @@
> +* Marvell Feroceon Cache
> +
> +Required properties:
> +- compatible : Should be "marvell,feroceon-kirkwood".
> +- reg : Address of the L2 cache control register
> +
> +Optional properties:
> +- writethrough : only if present, the cache will be used in write through mode.
> +
Looks more like a software configuration for me unless I am missing something.
It should not be here IMO if its pure software construct, may be you can use
already existing cachepolicy kernel parameter instead.
Also its better to Cc DT mailing list for any binding updates.
Regards,
Sudeep
^ permalink raw reply
* [PATCH] clk: respect the clock dependencies in of_clk_init
From: Gregory CLEMENT @ 2014-02-07 14:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207144325.GA8218@localhost>
On 07/02/2014 15:43, Ezequiel Garcia wrote:
> On Fri, Feb 07, 2014 at 09:24:30AM -0500, Jason Cooper wrote:
>> On Fri, Feb 07, 2014 at 10:06:08AM -0300, Emilio L?pez wrote:
>>
>> [snip a great explanation]
>>
>> Guys, can I get some Tested-by's on this?
>>
>
> In case someone missed Emilio's comment about it, I gave his oneliner
> a test on A370 Reference Design. It worked just as well as Sebastian's.
Well ok it's working but this patch is not better than Sebastian, it is
even worth. I don't think it is a good idea at all to totally ignore the
information given by the device tree.
>
> Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
>
>>> -----8<------
>>>
>>> From ffdb49506e3ce92090c15e1f9b37f4d465097ac1 Mon Sep 17 00:00:00 2001
>>> From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar>
>>> Date: Thu, 6 Feb 2014 18:07:07 -0300
>>> Subject: [PATCH] clk: mvebu: fix name dependency during registration time
>>>
>>> Currently, mvebu_clk_gating_setup has a silly dependency on clock
>>> registration order just to gather the parent clock name. This is
>>> completely unnecesary, as it supports using an already provided name
>>> via the clk_gating_soc_desc structs, and we can therefore solve this
>>> issue with a 69+/- line patch. But, given that the parent name is
>>> always "tclk" as default-hardcoded on mvebu_coreclk_setup(), we can
>>> just default-hardcode it here too and get away with solving this
>>> problem with a one-liner.
>>> ---
>>> drivers/clk/mvebu/common.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c
>>> index 25ceccf..6c63b43 100644
>>> --- a/drivers/clk/mvebu/common.c
>>> +++ b/drivers/clk/mvebu/common.c
>>> @@ -121,7 +121,7 @@ void __init mvebu_clk_gating_setup(struct
>>> device_node *np,
>>> struct clk_gating_ctrl *ctrl;
>>> struct clk *clk;
>>> void __iomem *base;
>>> - const char *default_parent = NULL;
>>> + const char *default_parent = "tclk";
>>> int n;
>>>
>>> base = of_iomap(np, 0);
>>> --
>>> 1.8.5.3
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 0/8] tty/serial: at91: Add missing modem signals to atmel_serial.
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
The USART controller on sam9x5 chips (and also all AT91/SAMA5 chips
but at91rm9200) are not capable of handling DTR/DSR/DCD/RI signal.
Moreover, even if the controller can handle CTS/RTS, the dedicated
CTS/RTS pins are already muxed for other peripherals (LCDC/EMAC/MMC).
So this patchset adds the possibility to control those lines via GPIO,
as it is done for RTS in the patch "switch atmel serial to use gpiolib"
With all those signals, you'll finally get the best out of your brand
new 33600 baud modem \o/.
And with the Ring Indicator, Atmel boards can now answer the phone !
This is based on 3.14-rc1 + Linus Walleij/Nicolas Ferre's patch:
354e57f3a0a2 ARM/serial: at91: switch atmel serial to use gpiolib
(in Uwe's tree git://git.pengutronix.de/git/ukl/linux.git dropmachtimexh )
Tested on at91sam9g35, with a null modem cable between 2 serial ports,
one with CTS/RTS controlled by the USART controller, the other via GPIO,
full duplex transfers.
Did some tests also with null modem cables on a PC.
Richard Genoud (8):
tty/serial: at91: use dev_err instead of printk
tty/serial: at91: remove unused open/close hooks
tty/serial: at91: prepare for more gpio lines to come
tty/serial: at91: add cts control via gpio
tty/serial: at91: add dtr control via gpio
tty/serial: at91: add dsr control via gpio
tty/serial: at91: add ring control via gpio
tty/serial: at91: add dcd control via gpio
.../devicetree/bindings/serial/atmel-usart.txt | 15 +
arch/arm/mach-at91/at91rm9200_devices.c | 25 ++
arch/arm/mach-at91/at91sam9260_devices.c | 35 +++
arch/arm/mach-at91/at91sam9261_devices.c | 20 ++
arch/arm/mach-at91/at91sam9263_devices.c | 20 ++
arch/arm/mach-at91/at91sam9g45_devices.c | 25 ++
arch/arm/mach-at91/at91sam9rl_devices.c | 25 ++
drivers/tty/serial/atmel_serial.c | 324 +++++++++++++++++----
include/linux/platform_data/atmel.h | 5 +
9 files changed, 441 insertions(+), 53 deletions(-)
--
1.8.5
^ permalink raw reply
* [PATCH 1/8] tty/serial: at91: use dev_err instead of printk
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
For better consistency.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
drivers/tty/serial/atmel_serial.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 91c0d8839570..ed9621a21d67 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -1549,7 +1549,7 @@ static int atmel_startup(struct uart_port *port)
retval = request_irq(port->irq, atmel_interrupt, IRQF_SHARED,
tty ? tty->name : "atmel_serial", port);
if (retval) {
- printk("atmel_serial: atmel_startup - Can't get irq\n");
+ dev_err(port->dev, "atmel_startup - Can't get irq\n");
return retval;
}
@@ -1732,7 +1732,7 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state,
clk_disable_unprepare(atmel_port->clk);
break;
default:
- printk(KERN_ERR "atmel_serial: unknown pm %d\n", state);
+ dev_err(port->dev, "atmel_serial: unknown pm %d\n", state);
}
}
--
1.8.5
^ permalink raw reply related
* [PATCH 2/8] tty/serial: at91: remove unused open/close hooks
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
commit 95e629b761ce36996d1befe2824d5346b5a220b9 removed the use of board
specific hooks in serial_at91.h, so now, the open/close hook are just
dead code.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
drivers/tty/serial/atmel_serial.c | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index ed9621a21d67..a51b3a762948 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -112,9 +112,6 @@ static void atmel_stop_rx(struct uart_port *port);
#define UART_PUT_TCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TCR)
#define UART_GET_TCR(port) __raw_readl((port)->membase + ATMEL_PDC_TCR)
-static int (*atmel_open_hook)(struct uart_port *);
-static void (*atmel_close_hook)(struct uart_port *);
-
struct atmel_dma_buffer {
unsigned char *buf;
dma_addr_t dma_addr;
@@ -1569,17 +1566,6 @@ static int atmel_startup(struct uart_port *port)
if (retval < 0)
atmel_set_ops(port);
}
- /*
- * If there is a specific "open" function (to register
- * control line interrupts)
- */
- if (atmel_open_hook) {
- retval = atmel_open_hook(port);
- if (retval) {
- free_irq(port->irq, port);
- return retval;
- }
- }
/* Save current CSR for comparison in atmel_tasklet_func() */
atmel_port->irq_status_prev = UART_GET_CSR(port);
@@ -1678,13 +1664,6 @@ static void atmel_shutdown(struct uart_port *port)
* Free the interrupt
*/
free_irq(port->irq, port);
-
- /*
- * If there is a specific "close" function (to unregister
- * control line interrupts)
- */
- if (atmel_close_hook)
- atmel_close_hook(port);
}
/*
--
1.8.5
^ permalink raw reply related
* [PATCH 3/8] tty/serial: at91: prepare for more gpio lines to come
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
There's no functionnal change, it will just be easier to review the
next patches.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
drivers/tty/serial/atmel_serial.c | 73 ++++++++++++++++++++++++++++-----------
1 file changed, 53 insertions(+), 20 deletions(-)
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index a51b3a762948..7ef99d7e070b 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -126,6 +126,10 @@ struct atmel_uart_char {
#define ATMEL_SERIAL_RINGSIZE 1024
+struct gpio_lines {
+ int rts; /* optional RTS GPIO */
+};
+
/*
* We wrap our port structure around the generic uart_port.
*/
@@ -162,7 +166,7 @@ struct atmel_uart_port {
struct circ_buf rx_ring;
struct serial_rs485 rs485; /* rs485 settings */
- int rts_gpio; /* optional RTS GPIO */
+ struct gpio_lines gpio;
unsigned int tx_done_mask;
bool is_usart; /* usart or uart */
struct timer_list uart_timer; /* uart timer */
@@ -300,11 +304,11 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
* AT91RM9200 Errata #39: RTS0 is not internally connected
* to PA21. We need to drive the pin as a GPIO.
*/
- if (gpio_is_valid(atmel_port->rts_gpio)) {
+ if (gpio_is_valid(atmel_port->gpio.rts)) {
if (mctrl & TIOCM_RTS)
- gpio_set_value(atmel_port->rts_gpio, 0);
+ gpio_set_value(atmel_port->gpio.rts, 0);
else
- gpio_set_value(atmel_port->rts_gpio, 1);
+ gpio_set_value(atmel_port->gpio.rts, 1);
}
if (mctrl & TIOCM_RTS)
@@ -2327,6 +2331,45 @@ static int atmel_serial_resume(struct platform_device *pdev)
#define atmel_serial_resume NULL
#endif
+static int atmel_request_gpio(struct device *dev, int gpio,
+ const char *label, int *irq)
+{
+ int ret = 0;
+
+ if (gpio_is_valid(gpio)) {
+ ret = devm_gpio_request(dev, gpio, label);
+ if (ret) {
+ dev_err(dev, "error requesting %s GPIO\n", label);
+ goto err;
+ }
+
+ if (irq == NULL) {
+ /* Default to 1 as all signals are active low */
+ ret = gpio_direction_output(gpio, 1);
+ } else {
+ ret = gpio_direction_input(gpio);
+ *irq = gpio_to_irq(gpio);
+ }
+ if (ret) {
+ dev_err(dev, "error setting up %s GPIO\n", label);
+ goto err;
+ }
+ }
+
+err:
+ return ret;
+}
+
+static int atmel_init_gpios(struct atmel_uart_port *atmel_port,
+ struct platform_device *pdev)
+{
+ int ret;
+
+ ret = atmel_request_gpio(&pdev->dev, atmel_port->gpio.rts,
+ "RTS", NULL);
+ return ret;
+}
+
static int atmel_serial_probe(struct platform_device *pdev)
{
struct atmel_uart_port *port;
@@ -2362,25 +2405,15 @@ static int atmel_serial_probe(struct platform_device *pdev)
port = &atmel_ports[ret];
port->backup_imr = 0;
port->uart.line = ret;
- port->rts_gpio = -EINVAL; /* Invalid, zero could be valid */
+ port->gpio.rts = -EINVAL; /* Invalid, zero could be valid */
if (pdata)
- port->rts_gpio = pdata->rts_gpio;
+ port->gpio.rts = pdata->rts_gpio;
else if (np)
- port->rts_gpio = of_get_named_gpio(np, "rts-gpios", 0);
+ port->gpio.rts = of_get_named_gpio(np, "rts-gpios", 0);
- if (gpio_is_valid(port->rts_gpio)) {
- ret = devm_gpio_request(&pdev->dev, port->rts_gpio, "RTS");
- if (ret) {
- dev_err(&pdev->dev, "error requesting RTS GPIO\n");
- goto err;
- }
- /* Default to 1 as RTS is active low */
- ret = gpio_direction_output(port->rts_gpio, 1);
- if (ret) {
- dev_err(&pdev->dev, "error setting up RTS GPIO\n");
- goto err;
- }
- }
+ ret = atmel_init_gpios(port, pdev);
+ if (ret)
+ goto err;
ret = atmel_init_port(port, pdev);
if (ret)
--
1.8.5
^ permalink raw reply related
* [PATCH 4/8] tty/serial: at91: add cts control via gpio
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
On sam9x5, dedicated CTS (and RTS) pins are unusable together with the
LCDC, the EMAC, or the MMC because they share the same line.
This patch permits to use a GPIO to control the CTS line.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
.../devicetree/bindings/serial/atmel-usart.txt | 3 +
arch/arm/mach-at91/at91rm9200_devices.c | 5 +
arch/arm/mach-at91/at91sam9260_devices.c | 7 ++
arch/arm/mach-at91/at91sam9261_devices.c | 4 +
arch/arm/mach-at91/at91sam9263_devices.c | 4 +
arch/arm/mach-at91/at91sam9g45_devices.c | 5 +
arch/arm/mach-at91/at91sam9rl_devices.c | 5 +
drivers/tty/serial/atmel_serial.c | 112 +++++++++++++++++++--
include/linux/platform_data/atmel.h | 1 +
9 files changed, 136 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/serial/atmel-usart.txt
index 17c1042b2df8..6c0898e4b58e 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/serial/atmel-usart.txt
@@ -15,6 +15,8 @@ Optional properties:
- atmel,use-dma-tx: use of PDC or DMA for transmitting data
- rts-gpios: specify a GPIO for RTS line. It will use specified PIO instead of the peripheral
function pin for the USART RTS feature. If unsure, don't specify this property.
+- cts-gpios: specify a GPIO for CTS line. It will use specified PIO instead of the peripheral
+ function pin for the USART CTS feature. If unsure, don't specify this property.
- add dma bindings for dma transfer:
- dmas: DMA specifier, consisting of a phandle to DMA controller node,
memory peripheral interface and USART DMA channel ID, FIFO configuration.
@@ -36,6 +38,7 @@ Example:
atmel,use-dma-rx;
atmel,use-dma-tx;
rts-gpios = <&pioD 15 0>;
+ cts-gpios = <&pioD 16 0>;
};
- use DMA:
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 605add05af7e..4688a85cabc4 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -923,6 +923,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -962,6 +963,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1013,6 +1015,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1065,6 +1068,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1109,6 +1113,7 @@ static struct atmel_uart_data uart3_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index b52527c78b12..5e8f0d1add1d 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -820,6 +820,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -859,6 +860,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -911,6 +913,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -955,6 +958,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -999,6 +1003,7 @@ static struct atmel_uart_data uart3_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
@@ -1043,6 +1048,7 @@ static struct atmel_uart_data uart4_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart4_dmamask = DMA_BIT_MASK(32);
@@ -1082,6 +1088,7 @@ static struct atmel_uart_data uart5_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart5_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 6c1a2ecc306f..f0ccc835e331 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -881,6 +881,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -920,6 +921,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -964,6 +966,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1008,6 +1011,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 97cc2a0d6f90..1e696ceacfaf 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -1325,6 +1325,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1364,6 +1365,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1408,6 +1410,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1452,6 +1455,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index c10149588e21..b75eb826b803 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1588,6 +1588,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1627,6 +1628,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1671,6 +1673,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1715,6 +1718,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1759,6 +1763,7 @@ static struct atmel_uart_data uart3_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 4120af972b61..67bf5811b38f 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -957,6 +957,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_tx = 0,
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -996,6 +997,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1048,6 +1050,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1092,6 +1095,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1136,6 +1140,7 @@ static struct atmel_uart_data uart3_data = {
.use_dma_tx = 1,
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
+ .cts_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 7ef99d7e070b..7a6b0506c050 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -43,6 +43,7 @@
#include <linux/platform_data/atmel.h>
#include <linux/timer.h>
#include <linux/gpio.h>
+#include <linux/irq.h>
#include <asm/io.h>
#include <asm/ioctls.h>
@@ -55,6 +56,8 @@
#define SUPPORT_SYSRQ
#endif
+#define INVALID_IRQ ((unsigned)-1)
+
#include <linux/serial_core.h>
static void atmel_start_rx(struct uart_port *port);
@@ -128,6 +131,8 @@ struct atmel_uart_char {
struct gpio_lines {
int rts; /* optional RTS GPIO */
+ int cts; /* optional CTS GPIO */
+ int cts_irq;
};
/*
@@ -168,6 +173,7 @@ struct atmel_uart_port {
struct serial_rs485 rs485; /* rs485 settings */
struct gpio_lines gpio;
unsigned int tx_done_mask;
+ bool ms_irq_enabled;
bool is_usart; /* usart or uart */
struct timer_list uart_timer; /* uart timer */
int (*prepare_rx)(struct uart_port *port);
@@ -241,6 +247,23 @@ static bool atmel_use_dma_rx(struct uart_port *port)
return atmel_port->use_dma_rx;
}
+static unsigned int atmel_get_lines_status(struct uart_port *port)
+{
+ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+ unsigned int status = 0;
+
+ status = UART_GET_CSR(port);
+
+ if (gpio_is_valid(atmel_port->gpio.cts)) {
+ if (gpio_get_value(atmel_port->gpio.cts))
+ status |= ATMEL_US_CTS;
+ else
+ status &= ~ATMEL_US_CTS;
+ }
+
+ return status;
+}
+
/* Enable or disable the rs485 support */
void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
{
@@ -352,7 +375,7 @@ static u_int atmel_get_mctrl(struct uart_port *port)
{
unsigned int status, ret = 0;
- status = UART_GET_CSR(port);
+ status = atmel_get_lines_status(port);
/*
* The control signals are active low.
@@ -453,8 +476,25 @@ static void atmel_stop_rx(struct uart_port *port)
*/
static void atmel_enable_ms(struct uart_port *port)
{
- UART_PUT_IER(port, ATMEL_US_RIIC | ATMEL_US_DSRIC
- | ATMEL_US_DCDIC | ATMEL_US_CTSIC);
+ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+ uint32_t ier;
+
+ /*
+ * Interrupt should not be enabled twice
+ */
+ if (atmel_port->ms_irq_enabled)
+ return;
+
+ atmel_port->ms_irq_enabled = true;
+
+ ier = ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC;
+
+ if (atmel_port->gpio.cts_irq != INVALID_IRQ)
+ enable_irq(atmel_port->gpio.cts_irq);
+ else
+ ier |= ATMEL_US_CTSIC;
+
+ UART_PUT_IER(port, ier);
}
/*
@@ -522,7 +562,7 @@ static void atmel_rx_chars(struct uart_port *port)
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
unsigned int status, ch;
- status = UART_GET_CSR(port);
+ status = atmel_get_lines_status(port);
while (status & ATMEL_US_RXRDY) {
ch = UART_GET_CHAR(port);
@@ -556,7 +596,7 @@ static void atmel_rx_chars(struct uart_port *port)
}
atmel_buffer_rx_char(port, status, ch);
- status = UART_GET_CSR(port);
+ status = atmel_get_lines_status(port);
}
tasklet_schedule(&atmel_port->tasklet);
@@ -1043,11 +1083,22 @@ atmel_handle_status(struct uart_port *port, unsigned int pending,
static irqreturn_t atmel_interrupt(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
+ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
unsigned int status, pending, pass_counter = 0;
+ bool gpio_handled = false;
do {
- status = UART_GET_CSR(port);
+ status = atmel_get_lines_status(port);
pending = status & UART_GET_IMR(port);
+ if (!gpio_handled) {
+ /*
+ * Dealing with GPIO interrupt
+ */
+ if ((irq != INVALID_IRQ) &&
+ (irq == atmel_port->gpio.cts_irq))
+ pending |= ATMEL_US_CTSIC;
+ gpio_handled = true;
+ }
if (!pending)
break;
@@ -1527,6 +1578,22 @@ static void atmel_get_ip_name(struct uart_port *port)
}
}
+static int atmel_request_gpio_irq(struct uart_port *port, int irq,
+ const char *name)
+{
+ int err = 0;
+
+ if (irq == INVALID_IRQ)
+ goto out;
+
+ irq_set_status_flags(irq, IRQ_NOAUTOEN);
+ err = request_irq(irq, atmel_interrupt, IRQ_TYPE_EDGE_BOTH, name, port);
+ if (err)
+ dev_err(port->dev, "atmel_startup - Can't get %s\n", name);
+out:
+ return err;
+}
+
/*
* Perform initialization and enable port for reception
*/
@@ -1543,6 +1610,7 @@ static int atmel_startup(struct uart_port *port)
* handle an unexpected interrupt
*/
UART_PUT_IDR(port, -1);
+ atmel_port->ms_irq_enabled = false;
/*
* Allocate the IRQ
@@ -1555,6 +1623,14 @@ static int atmel_startup(struct uart_port *port)
}
/*
+ * Get the GPIO lines IRQ
+ */
+ retval = atmel_request_gpio_irq(port, atmel_port->gpio.cts_irq,
+ "atmel_cts_irq");
+ if (retval)
+ goto free_ctrl_irq;
+
+ /*
* Initialize DMA (if necessary)
*/
atmel_init_property(atmel_port, pdev);
@@ -1572,7 +1648,7 @@ static int atmel_startup(struct uart_port *port)
}
/* Save current CSR for comparison in atmel_tasklet_func() */
- atmel_port->irq_status_prev = UART_GET_CSR(port);
+ atmel_port->irq_status_prev = atmel_get_lines_status(port);
atmel_port->irq_status = atmel_port->irq_status_prev;
/*
@@ -1618,6 +1694,11 @@ static int atmel_startup(struct uart_port *port)
}
return 0;
+
+free_ctrl_irq:
+ free_irq(port->irq, port);
+
+ return retval;
}
/*
@@ -1665,9 +1746,13 @@ static void atmel_shutdown(struct uart_port *port)
atmel_port->rx_ring.tail = 0;
/*
- * Free the interrupt
+ * Free the interrupts
*/
free_irq(port->irq, port);
+ if (atmel_port->gpio.cts_irq != INVALID_IRQ)
+ free_irq(atmel_port->gpio.cts_irq, port);
+
+ atmel_port->ms_irq_enabled = false;
}
/*
@@ -2367,6 +2452,8 @@ static int atmel_init_gpios(struct atmel_uart_port *atmel_port,
ret = atmel_request_gpio(&pdev->dev, atmel_port->gpio.rts,
"RTS", NULL);
+ ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.cts,
+ "CTS", &atmel_port->gpio.cts_irq);
return ret;
}
@@ -2406,10 +2493,15 @@ static int atmel_serial_probe(struct platform_device *pdev)
port->backup_imr = 0;
port->uart.line = ret;
port->gpio.rts = -EINVAL; /* Invalid, zero could be valid */
- if (pdata)
+ port->gpio.cts = -EINVAL;
+ port->gpio.cts_irq = INVALID_IRQ;
+ if (pdata) {
port->gpio.rts = pdata->rts_gpio;
- else if (np)
+ port->gpio.cts = pdata->cts_gpio;
+ } else if (np) {
port->gpio.rts = of_get_named_gpio(np, "rts-gpios", 0);
+ port->gpio.cts = of_get_named_gpio(np, "cts-gpios", 0);
+ }
ret = atmel_init_gpios(port, pdev);
if (ret)
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index e26b0c14edea..166a99ca911f 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -85,6 +85,7 @@ struct atmel_uart_data {
void __iomem *regs; /* virt. base address, if any */
struct serial_rs485 rs485; /* rs485 settings */
int rts_gpio; /* optional RTS GPIO */
+ int cts_gpio; /* optional CTS GPIO */
};
/* Touchscreen Controller */
--
1.8.5
^ permalink raw reply related
* [PATCH 5/8] tty/serial: at91: add dtr control via gpio
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
On sam9x5, the USART controller doesn't handle DTR/DSR/DCD/RI signals,
so we have to control them via GPIO.
This patch permits to use a GPIO to control the DTR signal.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
Documentation/devicetree/bindings/serial/atmel-usart.txt | 3 +++
arch/arm/mach-at91/at91rm9200_devices.c | 5 +++++
arch/arm/mach-at91/at91sam9260_devices.c | 7 +++++++
arch/arm/mach-at91/at91sam9261_devices.c | 4 ++++
arch/arm/mach-at91/at91sam9263_devices.c | 4 ++++
arch/arm/mach-at91/at91sam9g45_devices.c | 5 +++++
arch/arm/mach-at91/at91sam9rl_devices.c | 5 +++++
drivers/tty/serial/atmel_serial.c | 13 +++++++++++++
include/linux/platform_data/atmel.h | 1 +
9 files changed, 47 insertions(+)
diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/serial/atmel-usart.txt
index 6c0898e4b58e..77d45c88b494 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/serial/atmel-usart.txt
@@ -17,6 +17,8 @@ Optional properties:
function pin for the USART RTS feature. If unsure, don't specify this property.
- cts-gpios: specify a GPIO for CTS line. It will use specified PIO instead of the peripheral
function pin for the USART CTS feature. If unsure, don't specify this property.
+- dtr-gpios: specify a GPIO for DTR line. It will use specified PIO instead of the peripheral
+ function pin for the USART DTR feature. If unsure, don't specify this property.
- add dma bindings for dma transfer:
- dmas: DMA specifier, consisting of a phandle to DMA controller node,
memory peripheral interface and USART DMA channel ID, FIFO configuration.
@@ -39,6 +41,7 @@ Example:
atmel,use-dma-tx;
rts-gpios = <&pioD 15 0>;
cts-gpios = <&pioD 16 0>;
+ dtr-gpios = <&pioD 17 0>;
};
- use DMA:
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 4688a85cabc4..d8523cc05157 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -924,6 +924,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -964,6 +965,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1016,6 +1018,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1069,6 +1072,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1114,6 +1118,7 @@ static struct atmel_uart_data uart3_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 5e8f0d1add1d..b8e325b00e1a 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -821,6 +821,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -861,6 +862,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -914,6 +916,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -959,6 +962,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1004,6 +1008,7 @@ static struct atmel_uart_data uart3_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
@@ -1049,6 +1054,7 @@ static struct atmel_uart_data uart4_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart4_dmamask = DMA_BIT_MASK(32);
@@ -1089,6 +1095,7 @@ static struct atmel_uart_data uart5_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart5_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index f0ccc835e331..3a05d9f09b0d 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -882,6 +882,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -922,6 +923,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -967,6 +969,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1012,6 +1015,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 1e696ceacfaf..d26255ba3907 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -1326,6 +1326,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1366,6 +1367,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1411,6 +1413,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1456,6 +1459,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index b75eb826b803..67e9f7f259e1 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1589,6 +1589,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_rx = 0,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1629,6 +1630,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1674,6 +1676,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1719,6 +1722,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1764,6 +1768,7 @@ static struct atmel_uart_data uart3_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 67bf5811b38f..94fecc40dbba 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -958,6 +958,7 @@ static struct atmel_uart_data dbgu_data = {
.use_dma_rx = 0, /* DBGU not capable of receive DMA */
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -998,6 +999,7 @@ static struct atmel_uart_data uart0_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1051,6 +1053,7 @@ static struct atmel_uart_data uart1_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1096,6 +1099,7 @@ static struct atmel_uart_data uart2_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1141,6 +1145,7 @@ static struct atmel_uart_data uart3_data = {
.use_dma_rx = 1,
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
+ .dtr_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 7a6b0506c050..f5bdb84aed53 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -133,6 +133,7 @@ struct gpio_lines {
int rts; /* optional RTS GPIO */
int cts; /* optional CTS GPIO */
int cts_irq;
+ int dtr; /* optional DTR GPIO */
};
/*
@@ -339,6 +340,13 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
else
control |= ATMEL_US_RTSDIS;
+ if (gpio_is_valid(atmel_port->gpio.dtr)) {
+ if (mctrl & TIOCM_DTR)
+ gpio_set_value(atmel_port->gpio.dtr, 0);
+ else
+ gpio_set_value(atmel_port->gpio.dtr, 1);
+ }
+
if (mctrl & TIOCM_DTR)
control |= ATMEL_US_DTREN;
else
@@ -2454,6 +2462,8 @@ static int atmel_init_gpios(struct atmel_uart_port *atmel_port,
"RTS", NULL);
ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.cts,
"CTS", &atmel_port->gpio.cts_irq);
+ ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.dtr,
+ "DTR", NULL);
return ret;
}
@@ -2494,13 +2504,16 @@ static int atmel_serial_probe(struct platform_device *pdev)
port->uart.line = ret;
port->gpio.rts = -EINVAL; /* Invalid, zero could be valid */
port->gpio.cts = -EINVAL;
+ port->gpio.dtr = -EINVAL;
port->gpio.cts_irq = INVALID_IRQ;
if (pdata) {
port->gpio.rts = pdata->rts_gpio;
port->gpio.cts = pdata->cts_gpio;
+ port->gpio.dtr = pdata->dtr_gpio;
} else if (np) {
port->gpio.rts = of_get_named_gpio(np, "rts-gpios", 0);
port->gpio.cts = of_get_named_gpio(np, "cts-gpios", 0);
+ port->gpio.dtr = of_get_named_gpio(np, "dtr-gpios", 0);
}
ret = atmel_init_gpios(port, pdev);
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 166a99ca911f..8472b6f3c618 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -86,6 +86,7 @@ struct atmel_uart_data {
struct serial_rs485 rs485; /* rs485 settings */
int rts_gpio; /* optional RTS GPIO */
int cts_gpio; /* optional CTS GPIO */
+ int dtr_gpio; /* optional DTR GPIO */
};
/* Touchscreen Controller */
--
1.8.5
^ permalink raw reply related
* [PATCH 6/8] tty/serial: at91: add dsr control via gpio
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
On sam9x5, the USART controller doesn't handle DTR/DSR/DCD/RI signals,
so we have to control them via GPIO.
This patch permits to use a GPIO to control the DSR signal.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
.../devicetree/bindings/serial/atmel-usart.txt | 3 ++
arch/arm/mach-at91/at91rm9200_devices.c | 5 +++
arch/arm/mach-at91/at91sam9260_devices.c | 7 ++++
arch/arm/mach-at91/at91sam9261_devices.c | 4 +++
arch/arm/mach-at91/at91sam9263_devices.c | 4 +++
arch/arm/mach-at91/at91sam9g45_devices.c | 5 +++
arch/arm/mach-at91/at91sam9rl_devices.c | 5 +++
drivers/tty/serial/atmel_serial.c | 37 +++++++++++++++++++++-
include/linux/platform_data/atmel.h | 1 +
9 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/serial/atmel-usart.txt
index 77d45c88b494..3b90795ee641 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/serial/atmel-usart.txt
@@ -19,6 +19,8 @@ Optional properties:
function pin for the USART CTS feature. If unsure, don't specify this property.
- dtr-gpios: specify a GPIO for DTR line. It will use specified PIO instead of the peripheral
function pin for the USART DTR feature. If unsure, don't specify this property.
+- dsr-gpios: specify a GPIO for DSR line. It will use specified PIO instead of the peripheral
+ function pin for the USART DSR feature. If unsure, don't specify this property.
- add dma bindings for dma transfer:
- dmas: DMA specifier, consisting of a phandle to DMA controller node,
memory peripheral interface and USART DMA channel ID, FIFO configuration.
@@ -42,6 +44,7 @@ Example:
rts-gpios = <&pioD 15 0>;
cts-gpios = <&pioD 16 0>;
dtr-gpios = <&pioD 17 0>;
+ dsr-gpios = <&pioD 18 0>;
};
- use DMA:
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index d8523cc05157..980ea65142b4 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -925,6 +925,7 @@ static struct atmel_uart_data dbgu_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -966,6 +967,7 @@ static struct atmel_uart_data uart0_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1019,6 +1021,7 @@ static struct atmel_uart_data uart1_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1073,6 +1076,7 @@ static struct atmel_uart_data uart2_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1119,6 +1123,7 @@ static struct atmel_uart_data uart3_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index b8e325b00e1a..c11d1225a75c 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -822,6 +822,7 @@ static struct atmel_uart_data dbgu_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -863,6 +864,7 @@ static struct atmel_uart_data uart0_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -917,6 +919,7 @@ static struct atmel_uart_data uart1_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -963,6 +966,7 @@ static struct atmel_uart_data uart2_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1009,6 +1013,7 @@ static struct atmel_uart_data uart3_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
@@ -1055,6 +1060,7 @@ static struct atmel_uart_data uart4_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart4_dmamask = DMA_BIT_MASK(32);
@@ -1096,6 +1102,7 @@ static struct atmel_uart_data uart5_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart5_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 3a05d9f09b0d..ea35af48a2e2 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -883,6 +883,7 @@ static struct atmel_uart_data dbgu_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -924,6 +925,7 @@ static struct atmel_uart_data uart0_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -970,6 +972,7 @@ static struct atmel_uart_data uart1_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1016,6 +1019,7 @@ static struct atmel_uart_data uart2_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index d26255ba3907..c8833ebd4fcb 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -1327,6 +1327,7 @@ static struct atmel_uart_data dbgu_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1368,6 +1369,7 @@ static struct atmel_uart_data uart0_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1414,6 +1416,7 @@ static struct atmel_uart_data uart1_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1460,6 +1463,7 @@ static struct atmel_uart_data uart2_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 67e9f7f259e1..76772d12acfd 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1590,6 +1590,7 @@ static struct atmel_uart_data dbgu_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1631,6 +1632,7 @@ static struct atmel_uart_data uart0_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1677,6 +1679,7 @@ static struct atmel_uart_data uart1_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1723,6 +1726,7 @@ static struct atmel_uart_data uart2_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1769,6 +1773,7 @@ static struct atmel_uart_data uart3_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 94fecc40dbba..2aa6f8ddcd53 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -959,6 +959,7 @@ static struct atmel_uart_data dbgu_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1000,6 +1001,7 @@ static struct atmel_uart_data uart0_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1054,6 +1056,7 @@ static struct atmel_uart_data uart1_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1100,6 +1103,7 @@ static struct atmel_uart_data uart2_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1146,6 +1150,7 @@ static struct atmel_uart_data uart3_data = {
.rts_gpio = -EINVAL,
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
+ .dsr_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index f5bdb84aed53..28b3636135cd 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -134,6 +134,8 @@ struct gpio_lines {
int cts; /* optional CTS GPIO */
int cts_irq;
int dtr; /* optional DTR GPIO */
+ int dsr; /* optional DSR GPIO */
+ int dsr_irq;
};
/*
@@ -262,6 +264,13 @@ static unsigned int atmel_get_lines_status(struct uart_port *port)
status &= ~ATMEL_US_CTS;
}
+ if (gpio_is_valid(atmel_port->gpio.dsr)) {
+ if (gpio_get_value(atmel_port->gpio.dsr))
+ status |= ATMEL_US_DSR;
+ else
+ status &= ~ATMEL_US_DSR;
+ }
+
return status;
}
@@ -495,13 +504,18 @@ static void atmel_enable_ms(struct uart_port *port)
atmel_port->ms_irq_enabled = true;
- ier = ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC;
+ ier = ATMEL_US_RIIC | ATMEL_US_DCDIC;
if (atmel_port->gpio.cts_irq != INVALID_IRQ)
enable_irq(atmel_port->gpio.cts_irq);
else
ier |= ATMEL_US_CTSIC;
+ if (atmel_port->gpio.dsr_irq != INVALID_IRQ)
+ enable_irq(atmel_port->gpio.dsr_irq);
+ else
+ ier |= ATMEL_US_DSRIC;
+
UART_PUT_IER(port, ier);
}
@@ -1105,6 +1119,11 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
if ((irq != INVALID_IRQ) &&
(irq == atmel_port->gpio.cts_irq))
pending |= ATMEL_US_CTSIC;
+
+ if ((irq != INVALID_IRQ) &&
+ (irq == atmel_port->gpio.dsr_irq))
+ pending |= ATMEL_US_DSRIC;
+
gpio_handled = true;
}
if (!pending)
@@ -1638,6 +1657,11 @@ static int atmel_startup(struct uart_port *port)
if (retval)
goto free_ctrl_irq;
+ retval = atmel_request_gpio_irq(port, atmel_port->gpio.dsr_irq,
+ "atmel_dsr_irq");
+ if (retval)
+ goto free_cts_irq;
+
/*
* Initialize DMA (if necessary)
*/
@@ -1703,6 +1727,9 @@ static int atmel_startup(struct uart_port *port)
return 0;
+free_cts_irq:
+ free_irq(atmel_port->gpio.cts_irq, port);
+
free_ctrl_irq:
free_irq(port->irq, port);
@@ -1759,6 +1786,8 @@ static void atmel_shutdown(struct uart_port *port)
free_irq(port->irq, port);
if (atmel_port->gpio.cts_irq != INVALID_IRQ)
free_irq(atmel_port->gpio.cts_irq, port);
+ if (atmel_port->gpio.dsr_irq != INVALID_IRQ)
+ free_irq(atmel_port->gpio.dsr_irq, port);
atmel_port->ms_irq_enabled = false;
}
@@ -2464,6 +2493,8 @@ static int atmel_init_gpios(struct atmel_uart_port *atmel_port,
"CTS", &atmel_port->gpio.cts_irq);
ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.dtr,
"DTR", NULL);
+ ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.dsr,
+ "DSR", &atmel_port->gpio.dsr_irq);
return ret;
}
@@ -2505,15 +2536,19 @@ static int atmel_serial_probe(struct platform_device *pdev)
port->gpio.rts = -EINVAL; /* Invalid, zero could be valid */
port->gpio.cts = -EINVAL;
port->gpio.dtr = -EINVAL;
+ port->gpio.dsr = -EINVAL;
port->gpio.cts_irq = INVALID_IRQ;
+ port->gpio.dsr_irq = INVALID_IRQ;
if (pdata) {
port->gpio.rts = pdata->rts_gpio;
port->gpio.cts = pdata->cts_gpio;
port->gpio.dtr = pdata->dtr_gpio;
+ port->gpio.dsr = pdata->dsr_gpio;
} else if (np) {
port->gpio.rts = of_get_named_gpio(np, "rts-gpios", 0);
port->gpio.cts = of_get_named_gpio(np, "cts-gpios", 0);
port->gpio.dtr = of_get_named_gpio(np, "dtr-gpios", 0);
+ port->gpio.dsr = of_get_named_gpio(np, "dsr-gpios", 0);
}
ret = atmel_init_gpios(port, pdev);
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 8472b6f3c618..81f2c658c996 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -87,6 +87,7 @@ struct atmel_uart_data {
int rts_gpio; /* optional RTS GPIO */
int cts_gpio; /* optional CTS GPIO */
int dtr_gpio; /* optional DTR GPIO */
+ int dsr_gpio; /* optional DSR GPIO */
};
/* Touchscreen Controller */
--
1.8.5
^ permalink raw reply related
* [PATCH 7/8] tty/serial: at91: add ring control via gpio
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
On sam9x5, the USART controller doesn't handle DTR/DSR/DCD/RI signals,
so we have to control them via GPIO.
This patch permits to use a GPIO to control the RI signal.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
.../devicetree/bindings/serial/atmel-usart.txt | 3 ++
arch/arm/mach-at91/at91rm9200_devices.c | 5 +++
arch/arm/mach-at91/at91sam9260_devices.c | 7 +++++
arch/arm/mach-at91/at91sam9261_devices.c | 4 +++
arch/arm/mach-at91/at91sam9263_devices.c | 4 +++
arch/arm/mach-at91/at91sam9g45_devices.c | 5 +++
arch/arm/mach-at91/at91sam9rl_devices.c | 5 +++
drivers/tty/serial/atmel_serial.c | 36 +++++++++++++++++++++-
include/linux/platform_data/atmel.h | 1 +
9 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/serial/atmel-usart.txt
index 3b90795ee641..11d033649b19 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/serial/atmel-usart.txt
@@ -21,6 +21,8 @@ Optional properties:
function pin for the USART DTR feature. If unsure, don't specify this property.
- dsr-gpios: specify a GPIO for DSR line. It will use specified PIO instead of the peripheral
function pin for the USART DSR feature. If unsure, don't specify this property.
+- ri-gpios: specify a GPIO for Ring line. It will use specified PIO instead of the peripheral
+ function pin for the USART Ring feature. If unsure, don't specify this property.
- add dma bindings for dma transfer:
- dmas: DMA specifier, consisting of a phandle to DMA controller node,
memory peripheral interface and USART DMA channel ID, FIFO configuration.
@@ -45,6 +47,7 @@ Example:
cts-gpios = <&pioD 16 0>;
dtr-gpios = <&pioD 17 0>;
dsr-gpios = <&pioD 18 0>;
+ ri-gpios = <&pioD 19 0>;
};
- use DMA:
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 980ea65142b4..11c5c7f5b067 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -926,6 +926,7 @@ static struct atmel_uart_data dbgu_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -968,6 +969,7 @@ static struct atmel_uart_data uart0_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1022,6 +1024,7 @@ static struct atmel_uart_data uart1_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1077,6 +1080,7 @@ static struct atmel_uart_data uart2_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1124,6 +1128,7 @@ static struct atmel_uart_data uart3_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index c11d1225a75c..f8ccdbe2bcbc 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -823,6 +823,7 @@ static struct atmel_uart_data dbgu_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -865,6 +866,7 @@ static struct atmel_uart_data uart0_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -920,6 +922,7 @@ static struct atmel_uart_data uart1_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -967,6 +970,7 @@ static struct atmel_uart_data uart2_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1014,6 +1018,7 @@ static struct atmel_uart_data uart3_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
@@ -1061,6 +1066,7 @@ static struct atmel_uart_data uart4_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart4_dmamask = DMA_BIT_MASK(32);
@@ -1103,6 +1109,7 @@ static struct atmel_uart_data uart5_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart5_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index ea35af48a2e2..c40aa819cfac 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -884,6 +884,7 @@ static struct atmel_uart_data dbgu_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -926,6 +927,7 @@ static struct atmel_uart_data uart0_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -973,6 +975,7 @@ static struct atmel_uart_data uart1_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1020,6 +1023,7 @@ static struct atmel_uart_data uart2_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index c8833ebd4fcb..1da08465d952 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -1328,6 +1328,7 @@ static struct atmel_uart_data dbgu_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1370,6 +1371,7 @@ static struct atmel_uart_data uart0_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1417,6 +1419,7 @@ static struct atmel_uart_data uart1_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1464,6 +1467,7 @@ static struct atmel_uart_data uart2_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 76772d12acfd..4520d8f70cff 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1591,6 +1591,7 @@ static struct atmel_uart_data dbgu_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1633,6 +1634,7 @@ static struct atmel_uart_data uart0_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1680,6 +1682,7 @@ static struct atmel_uart_data uart1_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1727,6 +1730,7 @@ static struct atmel_uart_data uart2_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1774,6 +1778,7 @@ static struct atmel_uart_data uart3_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 2aa6f8ddcd53..5916d65b6362 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -960,6 +960,7 @@ static struct atmel_uart_data dbgu_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1002,6 +1003,7 @@ static struct atmel_uart_data uart0_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1057,6 +1059,7 @@ static struct atmel_uart_data uart1_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1104,6 +1107,7 @@ static struct atmel_uart_data uart2_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1151,6 +1155,7 @@ static struct atmel_uart_data uart3_data = {
.cts_gpio = -EINVAL,
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
+ .ri_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 28b3636135cd..9d47497713ab 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -136,6 +136,8 @@ struct gpio_lines {
int dtr; /* optional DTR GPIO */
int dsr; /* optional DSR GPIO */
int dsr_irq;
+ int ri; /* optional Ring GPIO */
+ int ri_irq;
};
/*
@@ -271,6 +273,13 @@ static unsigned int atmel_get_lines_status(struct uart_port *port)
status &= ~ATMEL_US_DSR;
}
+ if (gpio_is_valid(atmel_port->gpio.ri)) {
+ if (gpio_get_value(atmel_port->gpio.ri))
+ status |= ATMEL_US_RI;
+ else
+ status &= ~ATMEL_US_RI;
+ }
+
return status;
}
@@ -504,7 +513,7 @@ static void atmel_enable_ms(struct uart_port *port)
atmel_port->ms_irq_enabled = true;
- ier = ATMEL_US_RIIC | ATMEL_US_DCDIC;
+ ier = ATMEL_US_DCDIC;
if (atmel_port->gpio.cts_irq != INVALID_IRQ)
enable_irq(atmel_port->gpio.cts_irq);
@@ -516,6 +525,11 @@ static void atmel_enable_ms(struct uart_port *port)
else
ier |= ATMEL_US_DSRIC;
+ if (atmel_port->gpio.ri_irq != INVALID_IRQ)
+ enable_irq(atmel_port->gpio.ri_irq);
+ else
+ ier |= ATMEL_US_RIIC;
+
UART_PUT_IER(port, ier);
}
@@ -1124,6 +1138,10 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
(irq == atmel_port->gpio.dsr_irq))
pending |= ATMEL_US_DSRIC;
+ if ((irq != INVALID_IRQ) &&
+ (irq == atmel_port->gpio.ri_irq))
+ pending |= ATMEL_US_RIIC;
+
gpio_handled = true;
}
if (!pending)
@@ -1662,6 +1680,11 @@ static int atmel_startup(struct uart_port *port)
if (retval)
goto free_cts_irq;
+ retval = atmel_request_gpio_irq(port, atmel_port->gpio.ri_irq,
+ "atmel_ri_irq");
+ if (retval)
+ goto free_dsr_irq;
+
/*
* Initialize DMA (if necessary)
*/
@@ -1727,6 +1750,9 @@ static int atmel_startup(struct uart_port *port)
return 0;
+free_dsr_irq:
+ free_irq(atmel_port->gpio.dsr_irq, port);
+
free_cts_irq:
free_irq(atmel_port->gpio.cts_irq, port);
@@ -1788,6 +1814,8 @@ static void atmel_shutdown(struct uart_port *port)
free_irq(atmel_port->gpio.cts_irq, port);
if (atmel_port->gpio.dsr_irq != INVALID_IRQ)
free_irq(atmel_port->gpio.dsr_irq, port);
+ if (atmel_port->gpio.ri_irq != INVALID_IRQ)
+ free_irq(atmel_port->gpio.ri_irq, port);
atmel_port->ms_irq_enabled = false;
}
@@ -2495,6 +2523,8 @@ static int atmel_init_gpios(struct atmel_uart_port *atmel_port,
"DTR", NULL);
ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.dsr,
"DSR", &atmel_port->gpio.dsr_irq);
+ ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.ri,
+ "RI", &atmel_port->gpio.ri_irq);
return ret;
}
@@ -2537,18 +2567,22 @@ static int atmel_serial_probe(struct platform_device *pdev)
port->gpio.cts = -EINVAL;
port->gpio.dtr = -EINVAL;
port->gpio.dsr = -EINVAL;
+ port->gpio.ri = -EINVAL;
port->gpio.cts_irq = INVALID_IRQ;
port->gpio.dsr_irq = INVALID_IRQ;
+ port->gpio.ri_irq = INVALID_IRQ;
if (pdata) {
port->gpio.rts = pdata->rts_gpio;
port->gpio.cts = pdata->cts_gpio;
port->gpio.dtr = pdata->dtr_gpio;
port->gpio.dsr = pdata->dsr_gpio;
+ port->gpio.ri = pdata->ri_gpio;
} else if (np) {
port->gpio.rts = of_get_named_gpio(np, "rts-gpios", 0);
port->gpio.cts = of_get_named_gpio(np, "cts-gpios", 0);
port->gpio.dtr = of_get_named_gpio(np, "dtr-gpios", 0);
port->gpio.dsr = of_get_named_gpio(np, "dsr-gpios", 0);
+ port->gpio.ri = of_get_named_gpio(np, "ri-gpios", 0);
}
ret = atmel_init_gpios(port, pdev);
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 81f2c658c996..ce6ca1b8aef3 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -88,6 +88,7 @@ struct atmel_uart_data {
int cts_gpio; /* optional CTS GPIO */
int dtr_gpio; /* optional DTR GPIO */
int dsr_gpio; /* optional DSR GPIO */
+ int ri_gpio; /* optional Ring GPIO */
};
/* Touchscreen Controller */
--
1.8.5
^ permalink raw reply related
* [PATCH 8/8] tty/serial: at91: add dcd control via gpio
From: Richard Genoud @ 2014-02-07 14:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391785155-18525-1-git-send-email-richard.genoud@gmail.com>
On sam9x5, the USART controller doesn't handle DTR/DSR/DCD/RI signals,
so we have to control them via GPIO.
This patch permits to use a GPIO to control the DCD signal.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
---
.../devicetree/bindings/serial/atmel-usart.txt | 3 ++
arch/arm/mach-at91/at91rm9200_devices.c | 5 +++
arch/arm/mach-at91/at91sam9260_devices.c | 7 ++++
arch/arm/mach-at91/at91sam9261_devices.c | 4 +++
arch/arm/mach-at91/at91sam9263_devices.c | 4 +++
arch/arm/mach-at91/at91sam9g45_devices.c | 5 +++
arch/arm/mach-at91/at91sam9rl_devices.c | 5 +++
drivers/tty/serial/atmel_serial.c | 38 ++++++++++++++++++++--
include/linux/platform_data/atmel.h | 1 +
9 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/serial/atmel-usart.txt
index 11d033649b19..4ff660e1487f 100644
--- a/Documentation/devicetree/bindings/serial/atmel-usart.txt
+++ b/Documentation/devicetree/bindings/serial/atmel-usart.txt
@@ -23,6 +23,8 @@ Optional properties:
function pin for the USART DSR feature. If unsure, don't specify this property.
- ri-gpios: specify a GPIO for Ring line. It will use specified PIO instead of the peripheral
function pin for the USART Ring feature. If unsure, don't specify this property.
+- dcd-gpios: specify a GPIO for DCD line. It will use specified PIO instead of the peripheral
+ function pin for the USART DCD feature. If unsure, don't specify this property.
- add dma bindings for dma transfer:
- dmas: DMA specifier, consisting of a phandle to DMA controller node,
memory peripheral interface and USART DMA channel ID, FIFO configuration.
@@ -48,6 +50,7 @@ Example:
dtr-gpios = <&pioD 17 0>;
dsr-gpios = <&pioD 18 0>;
ri-gpios = <&pioD 19 0>;
+ dcd-gpios = <&pioD 20 0>;
};
- use DMA:
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 11c5c7f5b067..288421f38b42 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -927,6 +927,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -970,6 +971,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1025,6 +1027,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1081,6 +1084,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1129,6 +1133,7 @@ static struct atmel_uart_data uart3_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index f8ccdbe2bcbc..0e20ba04d43f 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -824,6 +824,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -867,6 +868,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -923,6 +925,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -971,6 +974,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1019,6 +1023,7 @@ static struct atmel_uart_data uart3_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
@@ -1067,6 +1072,7 @@ static struct atmel_uart_data uart4_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart4_dmamask = DMA_BIT_MASK(32);
@@ -1110,6 +1116,7 @@ static struct atmel_uart_data uart5_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart5_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index c40aa819cfac..d3d7a546db9b 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -885,6 +885,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -928,6 +929,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -976,6 +978,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1024,6 +1027,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 1da08465d952..5fcb2a0383d1 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -1329,6 +1329,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1372,6 +1373,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1420,6 +1422,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1468,6 +1471,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 4520d8f70cff..bd44970403e5 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1592,6 +1592,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1635,6 +1636,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1683,6 +1685,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1731,6 +1734,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1779,6 +1783,7 @@ static struct atmel_uart_data uart3_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 5916d65b6362..e43623dc1c9e 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -961,6 +961,7 @@ static struct atmel_uart_data dbgu_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 dbgu_dmamask = DMA_BIT_MASK(32);
@@ -1004,6 +1005,7 @@ static struct atmel_uart_data uart0_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart0_dmamask = DMA_BIT_MASK(32);
@@ -1060,6 +1062,7 @@ static struct atmel_uart_data uart1_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart1_dmamask = DMA_BIT_MASK(32);
@@ -1108,6 +1111,7 @@ static struct atmel_uart_data uart2_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart2_dmamask = DMA_BIT_MASK(32);
@@ -1156,6 +1160,7 @@ static struct atmel_uart_data uart3_data = {
.dtr_gpio = -EINVAL,
.dsr_gpio = -EINVAL,
.ri_gpio = -EINVAL,
+ .dcd_gpio = -EINVAL,
};
static u64 uart3_dmamask = DMA_BIT_MASK(32);
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 9d47497713ab..926f77e6bde5 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -138,6 +138,8 @@ struct gpio_lines {
int dsr_irq;
int ri; /* optional Ring GPIO */
int ri_irq;
+ int dcd; /* optional DCD GPIO */
+ int dcd_irq;
};
/*
@@ -280,6 +282,13 @@ static unsigned int atmel_get_lines_status(struct uart_port *port)
status &= ~ATMEL_US_RI;
}
+ if (gpio_is_valid(atmel_port->gpio.dcd)) {
+ if (gpio_get_value(atmel_port->gpio.dcd))
+ status |= ATMEL_US_DCD;
+ else
+ status &= ~ATMEL_US_DCD;
+ }
+
return status;
}
@@ -503,7 +512,7 @@ static void atmel_stop_rx(struct uart_port *port)
static void atmel_enable_ms(struct uart_port *port)
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- uint32_t ier;
+ uint32_t ier = 0;
/*
* Interrupt should not be enabled twice
@@ -513,8 +522,6 @@ static void atmel_enable_ms(struct uart_port *port)
atmel_port->ms_irq_enabled = true;
- ier = ATMEL_US_DCDIC;
-
if (atmel_port->gpio.cts_irq != INVALID_IRQ)
enable_irq(atmel_port->gpio.cts_irq);
else
@@ -530,6 +537,11 @@ static void atmel_enable_ms(struct uart_port *port)
else
ier |= ATMEL_US_RIIC;
+ if (atmel_port->gpio.dcd_irq != INVALID_IRQ)
+ enable_irq(atmel_port->gpio.dcd_irq);
+ else
+ ier |= ATMEL_US_DCDIC;
+
UART_PUT_IER(port, ier);
}
@@ -1142,6 +1154,10 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
(irq == atmel_port->gpio.ri_irq))
pending |= ATMEL_US_RIIC;
+ if ((irq != INVALID_IRQ) &&
+ (irq == atmel_port->gpio.dcd_irq))
+ pending |= ATMEL_US_DCDIC;
+
gpio_handled = true;
}
if (!pending)
@@ -1685,6 +1701,11 @@ static int atmel_startup(struct uart_port *port)
if (retval)
goto free_dsr_irq;
+ retval = atmel_request_gpio_irq(port, atmel_port->gpio.dcd_irq,
+ "atmel_dcd_irq");
+ if (retval)
+ goto free_ri_irq;
+
/*
* Initialize DMA (if necessary)
*/
@@ -1750,6 +1771,9 @@ static int atmel_startup(struct uart_port *port)
return 0;
+free_ri_irq:
+ free_irq(atmel_port->gpio.ri_irq, port);
+
free_dsr_irq:
free_irq(atmel_port->gpio.dsr_irq, port);
@@ -1816,6 +1840,8 @@ static void atmel_shutdown(struct uart_port *port)
free_irq(atmel_port->gpio.dsr_irq, port);
if (atmel_port->gpio.ri_irq != INVALID_IRQ)
free_irq(atmel_port->gpio.ri_irq, port);
+ if (atmel_port->gpio.dcd_irq != INVALID_IRQ)
+ free_irq(atmel_port->gpio.dcd_irq, port);
atmel_port->ms_irq_enabled = false;
}
@@ -2525,6 +2551,8 @@ static int atmel_init_gpios(struct atmel_uart_port *atmel_port,
"DSR", &atmel_port->gpio.dsr_irq);
ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.ri,
"RI", &atmel_port->gpio.ri_irq);
+ ret += atmel_request_gpio(&pdev->dev, atmel_port->gpio.dcd,
+ "DCD", &atmel_port->gpio.dcd_irq);
return ret;
}
@@ -2568,21 +2596,25 @@ static int atmel_serial_probe(struct platform_device *pdev)
port->gpio.dtr = -EINVAL;
port->gpio.dsr = -EINVAL;
port->gpio.ri = -EINVAL;
+ port->gpio.dcd = -EINVAL;
port->gpio.cts_irq = INVALID_IRQ;
port->gpio.dsr_irq = INVALID_IRQ;
port->gpio.ri_irq = INVALID_IRQ;
+ port->gpio.dcd_irq = INVALID_IRQ;
if (pdata) {
port->gpio.rts = pdata->rts_gpio;
port->gpio.cts = pdata->cts_gpio;
port->gpio.dtr = pdata->dtr_gpio;
port->gpio.dsr = pdata->dsr_gpio;
port->gpio.ri = pdata->ri_gpio;
+ port->gpio.dcd = pdata->dcd_gpio;
} else if (np) {
port->gpio.rts = of_get_named_gpio(np, "rts-gpios", 0);
port->gpio.cts = of_get_named_gpio(np, "cts-gpios", 0);
port->gpio.dtr = of_get_named_gpio(np, "dtr-gpios", 0);
port->gpio.dsr = of_get_named_gpio(np, "dsr-gpios", 0);
port->gpio.ri = of_get_named_gpio(np, "ri-gpios", 0);
+ port->gpio.dcd = of_get_named_gpio(np, "dcd-gpios", 0);
}
ret = atmel_init_gpios(port, pdev);
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index ce6ca1b8aef3..565c5c693c7f 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -88,6 +88,7 @@ struct atmel_uart_data {
int cts_gpio; /* optional CTS GPIO */
int dtr_gpio; /* optional DTR GPIO */
int dsr_gpio; /* optional DSR GPIO */
+ int dcd_gpio; /* optional DCD GPIO */
int ri_gpio; /* optional Ring GPIO */
};
--
1.8.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