* [GIT PULL] arm64 updates for 4.10
From: Stephen Rothwell @ 2016-12-13 23:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161213192156.GA12471@e104818-lin.cambridge.arm.com>
Hi Linus,
On Tue, 13 Dec 2016 19:21:59 +0000 Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> Please pull the arm64 updates for 4.10 below.
>
> The patches touch the generic include/linux/thread_info.h to factor out
> struct restart_block into a separate include/linux/restart_block.h file
> (needed for arm64 moving thread_info off stack; acked by Andy
> Lutomirski).
>
> There is also a small refactoring touching drivers/irqchip/irq-gic-v3.c
> and additional watchpoint lengths added to
> include/uapi/linux/hw_breakpoint.h.
I have also been carrying a merge fix up patch due to a conflict in the
merge of the arm64 tree with commit
272d01bd790f ("arm64: Fix circular include of asm/lse.h through linux/jump_label.h")
from v4.9-rc5:
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Tue, 22 Nov 2016 10:30:40 +1100
Subject: [PATCH] arm64: merge fix for code movement to cpucaps.h
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
arch/arm64/include/asm/cpucaps.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 87b446535185..4174f09678c4 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -34,7 +34,8 @@
#define ARM64_HAS_32BIT_EL0 13
#define ARM64_HYP_OFFSET_LOW 14
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
+#define ARM64_HAS_NO_FPSIMD 16
-#define ARM64_NCAPS 16
+#define ARM64_NCAPS 17
#endif /* __ASM_CPUCAPS_H */
--
2.10.2
--
Cheers,
Stephen Rothwell
^ permalink raw reply related
* [PATCH 03/11] driver: clk: imx: Add clock driver for imx6sll
From: Stephen Boyd @ 2016-12-13 23:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AM3PR04MB5302BE33BE1F2C9913FF61587980@AM3PR04MB530.eurprd04.prod.outlook.com>
On 12/12, Jacky Bai wrote:
> > On 12/02, Bai Ping wrote:
> > > diff --git a/drivers/clk/imx/clk-imx6sll.c
> > > b/drivers/clk/imx/clk-imx6sll.c new file mode 100644 index
> > > 0000000..c5219e1
> > > --- /dev/null
> > > +++ b/drivers/clk/imx/clk-imx6sll.c
> > > +0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels),
> > > +CLK_SET_RATE_PARENT);
> > > +
> > > + /* Do not bypass PLLs initially */
> > > + clk_set_parent(clks[IMX6SLL_PLL1_BYPASS], clks[IMX6SLL_CLK_PLL1]);
> > > + clk_set_parent(clks[IMX6SLL_PLL2_BYPASS], clks[IMX6SLL_CLK_PLL2]);
> > > + clk_set_parent(clks[IMX6SLL_PLL3_BYPASS], clks[IMX6SLL_CLK_PLL3]);
> > > + clk_set_parent(clks[IMX6SLL_PLL4_BYPASS], clks[IMX6SLL_CLK_PLL4]);
> > > + clk_set_parent(clks[IMX6SLL_PLL5_BYPASS], clks[IMX6SLL_CLK_PLL5]);
> > > + clk_set_parent(clks[IMX6SLL_PLL6_BYPASS], clks[IMX6SLL_CLK_PLL6]);
> > > + clk_set_parent(clks[IMX6SLL_PLL7_BYPASS], clks[IMX6SLL_CLK_PLL7]);
> >
> > Can we just put raw register writes here instead? I'd prefer we didn't use clk
> > consumer APIs to do things to the clk tree from the providers. The problem
> > there being that:
> >
> > 1) We're trying to move away from using consumer APIs in provider drivers.
> > It's ok if they're used during probe, but inside clk_ops is not preferred.
> >
> > 2) Even if you have a clk pointer, it may be "orphaned" at the time of
> > registration and so calling the APIs here works now but eventually we may
> > want to return an EPROBE_DEFER error in that case and this may block that
> > effort.
> >
> > I suppose if this is the only clk driver on this machine then this last point isn't a
> > concern and things are probably ok here.
> >
>
> Using raw register writing has an issue. The register is modified, but it seems the clock 'parent-child' relationship can
> not match the register setting. The register setting is not bypass the pll, but in debug 'clk_summary', the
> pll is bypassed.
So program the register settings before registering the clocks
with the framework?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH 2/2] kbuild: make modversion for exported asm symbols more convivial
From: Michal Marek @ 2016-12-13 23:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481171047-333-3-git-send-email-nicolas.pitre@linaro.org>
Dne 8.12.2016 v 05:24 Nicolas Pitre napsal(a):
> Rather than having an asm-prototypes.h file where C prototypes for exported
> asm symbols are centralized, let's have some macros that can be used
> directly in the code where those symbols are exported for genksyms
> consumption. Either the prototype is provided directly if no include
> files has it, or the include file containing it is specified.
>
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
> include/asm-generic/export.h | 15 +++++++++++++++
> scripts/Makefile.build | 22 +++++++++++++++-------
> 2 files changed, 30 insertions(+), 7 deletions(-)
>
> diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h
> index 39a19dc366..83dda5f840 100644
> --- a/include/asm-generic/export.h
> +++ b/include/asm-generic/export.h
> @@ -84,11 +84,26 @@ KSYM(__kcrctab_\name):
> #define __EXPORT_SYMBOL(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec
> #endif
>
> +/* in the non genksyms case those are no-ops */
> +#define SYMBOL_CPROTO(expr)
> +#define SYMBOL_CPROTO_INCLUDE(file)
Do we really _need_ the SYMBOL_CPROTO macro? The exported functions are
called from C files presumably, so there ought to be headers with the
declarations. If these headers can't be included easily, we should fix
them, but having copies of the declarations in the asm files is no big
improvement over the asm-prototypes.h approach, IMO.
Michal
^ permalink raw reply
* [linux-sunxi] Re: [PATCH v3 -next 2/2] ARM: dts: sunxi: add support for Orange Pi Zero board
From: Alexey Kardashevskiy @ 2016-12-13 23:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161207100132.1Qp0ZxGD@smtp3o.mail.yandex.net>
On 07/12/16 18:01, Icenowy Zheng wrote:
>
> 2016?12?7? 05:52? Alexey Kardashevskiy <aik@ozlabs.ru>???
>>
>> On 06/12/16 18:43, Icenowy Zheng wrote:
>>>
>>> 2016?12?6? 09:51? Alexey Kardashevskiy <aik@ozlabs.ru>???
>>>>
>>>> On 03/12/16 02:05, Icenowy Zheng wrote:
>>>>> Orange Pi Zero is a board that came with the new Allwinner H2+ SoC and a
>>>>> SDIO Wi-Fi chip by Allwinner (XR819).
>>>>>
>>>>> Add a device tree file for it.
>>>>>
>>>>> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
>>>>> ---
>>>>> Changes since v2:
>>>>> - Merged SDIO Wi-Fi patch into it.
>>>>> - SDIO Wi-Fi: add a ethernet1 alias to it, as it has no internal NVRAM.
>>>>> - SDIO Wi-Fi: changed pinctrl binding to generic pinconf
>>>>> - removed all gpio pinctrl nodes
>>>>> - changed h2plus to h2-plus
>>>>> Changes since v1:
>>>>> - Convert to generic pinconf bindings.
>>>>> - SDIO Wi-Fi: add patch.
>>>>>
>>>>> Some notes:
>>>>> - The uart1 and uart2 is available on the unsoldered gpio header.
>>>>> - The onboard USB connector has its Vbus directly connected to DCIN-5V (the
>>>>> power jack)
>>>>>
>>>>> arch/arm/boot/dts/Makefile | 1 +
>>>>> arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts | 159 ++++++++++++++++++++++
>>>>> 2 files changed, 160 insertions(+)
>>>>> create mode 100644 arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
>>>>>
>>>>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>>>>> index 6447abc..59f6e86 100644
>>>>> --- a/arch/arm/boot/dts/Makefile
>>>>> +++ b/arch/arm/boot/dts/Makefile
>>>>> @@ -844,6 +844,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
>>>>> sun8i-a33-sinlinx-sina33.dtb \
>>>>> sun8i-a83t-allwinner-h8homlet-v2.dtb \
>>>>> sun8i-a83t-cubietruck-plus.dtb \
>>>>> + sun8i-h2-plus-orangepi-zero.dtb \
>>>>> sun8i-h3-bananapi-m2-plus.dtb \
>>>>> sun8i-h3-nanopi-neo.dtb \
>>>>> sun8i-h3-orangepi-2.dtb \
>>>>> diff --git a/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
>>>>> new file mode 100644
>>>>> index 0000000..d18807f
>>>>> --- /dev/null
>>>>> +++ b/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts
>>>>> @@ -0,0 +1,159 @@
>>>>> +/*
>>>>> + * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
>>>>> + *
>>>>> + * Based on sun8i-h3-orangepi-one.dts, which is:
>>>>> + * Copyright (C) 2016 Hans de Goede <hdegoede@redhat.com>
>>>>> + *
>>>>> + * This file is dual-licensed: you can use it either under the terms
>>>>> + * of the GPL or the X11 license, at your option. Note that this dual
>>>>> + * licensing only applies to this file, and not this project as a
>>>>> + * whole.
>>>>> + *
>>>>> + * a) This file is free software; you can redistribute it and/or
>>>>> + * modify it under the terms of the GNU General Public License as
>>>>> + * published by the Free Software Foundation; either version 2 of the
>>>>> + * License, or (at your option) any later version.
>>>>> + *
>>>>> + * This file is distributed in the hope that it will be useful,
>>>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>>>> + * GNU General Public License for more details.
>>>>> + *
>>>>> + * Or, alternatively,
>>>>> + *
>>>>> + * b) Permission is hereby granted, free of charge, to any person
>>>>> + * obtaining a copy of this software and associated documentation
>>>>> + * files (the "Software"), to deal in the Software without
>>>>> + * restriction, including without limitation the rights to use,
>>>>> + * copy, modify, merge, publish, distribute, sublicense, and/or
>>>>> + * sell copies of the Software, and to permit persons to whom the
>>>>> + * Software is furnished to do so, subject to the following
>>>>> + * conditions:
>>>>> + *
>>>>> + * The above copyright notice and this permission notice shall be
>>>>> + * included in all copies or substantial portions of the Software.
>>>>> + *
>>>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>>>>> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>>>>> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>>>>> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
>>>>> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>>>>> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>>>>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>>>>> + * OTHER DEALINGS IN THE SOFTWARE.
>>>>> + */
>>>>> +
>>>>> +/dts-v1/;
>>>>> +#include "sun8i-h3.dtsi"
>>>>> +#include "sunxi-common-regulators.dtsi"
>>>>> +
>>>>> +#include <dt-bindings/gpio/gpio.h>
>>>>> +#include <dt-bindings/input/input.h>
>>>>> +#include <dt-bindings/pinctrl/sun4i-a10.h>
>>>>> +
>>>>> +/ {
>>>>> + model = "Xunlong Orange Pi Zero";
>>>>> + compatible = "xunlong,orangepi-zero", "allwinner,sun8i-h2-plus";
>>>>> +
>>>>> + aliases {
>>>>> + serial0 = &uart0;
>>>>> + /* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
>>>>
>>>>
>>>> It is not defined there as for:
>>>>
>>>> cef87e9 (tag: next-20161205) 20 hours ago Stephen Rothwell Add linux-next
>>>> specific files for 20161205
>>>
>>> The driver of H3's obfuscated DesignWare MAC is not yet mainlined, so there won't be one ethernet0 now.
>>>
>>> But it's reserved for the onboard Ethernet.
>>
>>
>> Could you please elaborate how you tested this patch (ideally some tree
>> somewhere on github)? This patch added RX819, it assumes EMAC support is
>> there, neither is there nor there is a way to test this... Thanks.
>
> It do not assume EMAC is there.
> It only assume EMAC will be there someday :-)
>
> For tree... wait for my push :-)
Has it happened yet? :)
--
Alexey
^ permalink raw reply
* [PATCHv4 00/15] clk: ti: add support for hwmod clocks
From: Tony Lindgren @ 2016-12-14 0:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <148166654419.37646.7680435609801736363@resonance>
* Michael Turquette <mturquette@baylibre.com> [161213 14:02]:
> Quoting Tony Lindgren (2016-12-13 07:37:24)
> > For the clkctrl clocks, here's what I'd like to see. The driver should be
> > just a regular device driver along the lines we did with the ADPLL as in
> > Documentation/devicetree/bindings/clock/ti/adpll.txt.
> >
> > For the binding, something like the following should work as a minimal
> > example, this follows what we have in the hardware:
> >
> > &prm {
> > ...
> >
> > /* See "CD_WKUP Clock Domain" in 4430 TRM page 393 */
> > wkup_cm: clock at 1800 {
> > compatible = "ti,clkctrl";
> > reg = <0x1800 0x100>;
> > #clock-cells = <1>;
> > clocks = <&wkup_l4_iclk2 &wkup_32k_fclk
> > &32k_fclk &gp1_fclk>;
> > clock-output-names =
> > "sysctrl_padconf_wkup",
> > "badgap",
> > "sysctrl_general_wkup",
> > "gpio1",
> > "keyboard",
> > "sar_ram",
> > "32ktimer",
> > "gptimer1";
>
> Is there a technical reason to use clock-output-names? If you share a
> header between the clock provider driver and DT with the phandle offsets
> then we should be able to avoid this property altogether. Stephen and I
> are trying to phase this one out as much as possible.
Oh OK no reason for names, defines for the offsets will work just fine.
Regards,
Tony
^ permalink raw reply
* [PATCH 2/2] kbuild: make modversion for exported asm symbols more convivial
From: Nicolas Pitre @ 2016-12-14 0:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <9b2f99ca-0ac6-12b0-e753-5ce6feec96e8@suse.com>
On Wed, 14 Dec 2016, Michal Marek wrote:
> Dne 8.12.2016 v 05:24 Nicolas Pitre napsal(a):
> > Rather than having an asm-prototypes.h file where C prototypes for exported
> > asm symbols are centralized, let's have some macros that can be used
> > directly in the code where those symbols are exported for genksyms
> > consumption. Either the prototype is provided directly if no include
> > files has it, or the include file containing it is specified.
> >
> > Signed-off-by: Nicolas Pitre <nico@linaro.org>
> > ---
> > include/asm-generic/export.h | 15 +++++++++++++++
> > scripts/Makefile.build | 22 +++++++++++++++-------
> > 2 files changed, 30 insertions(+), 7 deletions(-)
> >
> > diff --git a/include/asm-generic/export.h b/include/asm-generic/export.h
> > index 39a19dc366..83dda5f840 100644
> > --- a/include/asm-generic/export.h
> > +++ b/include/asm-generic/export.h
> > @@ -84,11 +84,26 @@ KSYM(__kcrctab_\name):
> > #define __EXPORT_SYMBOL(sym, val, sec) ___EXPORT_SYMBOL sym, val, sec
> > #endif
> >
> > +/* in the non genksyms case those are no-ops */
> > +#define SYMBOL_CPROTO(expr)
> > +#define SYMBOL_CPROTO_INCLUDE(file)
>
> Do we really _need_ the SYMBOL_CPROTO macro? The exported functions are
> called from C files presumably, so there ought to be headers with the
> declarations. If these headers can't be included easily, we should fix
> them, but having copies of the declarations in the asm files is no big
> improvement over the asm-prototypes.h approach, IMO.
On ARM there are a few symbols that are part of the gcc support library
such as division routines and so on. Those are never called directly
from C code. It is the compiler that implicitly creates references to
them. However, in order to be able to export those symbols, dummy C
prototypes were used before it was possible to export symbols from asm
code but those prototypes make no sense otherwise. So the SYMBOL_CPROTO
macro is there mainly to maintain backward compatibility with the
traditional symbol version signature for those symbols.
The SYMBOL_CPROTO macro, being close to the actual code, could mark the
intended definition for symbols in assembly code and allow for a tool to
ensure there is no mismatch with the actual declaration located
elsewhere. That could be useful for all global symbols, not just
exported ones. But that's not the primary reason why I created it.
Nicolas
^ permalink raw reply
* [GIT PULL] arm64 updates for 4.10
From: Linus Torvalds @ 2016-12-14 0:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161213192156.GA12471@e104818-lin.cambridge.arm.com>
On Tue, Dec 13, 2016 at 11:21 AM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
>
> Please pull the arm64 updates for 4.10 below.
Mind checking that I got the conflict resolution right?
The conflict looked completely trivial, but with stuff moving across
files and since I don't build the end result (much less boot it) I
could easily have missed some screw-up of mine.
Thanks,
Linus
^ permalink raw reply
* [PATCH] ipmi: bt-bmc: Use a regmap for register access
From: Joel Stanley @ 2016-12-14 1:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161206025715.2002-1-andrew@aj.id.au>
On Tue, Dec 6, 2016 at 1:27 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> The registers for the bt-bmc device live under the Aspeed LPC
> controller. Devicetree bindings have recently been introduced for the
> LPC controller where the "host" portion of the LPC register space is
> described as a syscon device. Future devicetrees describing the bt-bmc
> device should nest its node under the appropriate "simple-mfd", "syscon"
> compatible node.
>
> This change allows the bt-bmc driver to function with both syscon and
> non-syscon- based devicetree descriptions by always using a regmap for
> register access, either retrieved from the parent syscon device or
> instantiated if none exists.
>
> The patch has been tested on an OpenPOWER Palmetto machine, successfully
> booting, rebooting and powering down the host.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> ---
> drivers/char/ipmi/Kconfig | 1 +
> drivers/char/ipmi/bt-bmc.c | 82 ++++++++++++++++++++++++++++++++++------------
> 2 files changed, 62 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
> index 7f816655cbbf..b5d48d9af124 100644
> --- a/drivers/char/ipmi/Kconfig
> +++ b/drivers/char/ipmi/Kconfig
> @@ -79,6 +79,7 @@ endif # IPMI_HANDLER
>
> config ASPEED_BT_IPMI_BMC
> depends on ARCH_ASPEED
If you do a v2 of this series it would be great to add || COMPILE_TEST here.
> + depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
> tristate "BT IPMI bmc driver"
> help
> Provides a driver for the BT (Block Transfer) IPMI interface
> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> index fc9e8891eae3..ca1e20f6c6c5 100644
> --- a/drivers/char/ipmi/bt-bmc.c
> +++ b/drivers/char/ipmi/bt-bmc.c
> @@ -12,10 +12,13 @@
> #include <linux/errno.h>
> #include <linux/interrupt.h>
> #include <linux/io.h>
> +#include <linux/mfd/syscon.h>
> #include <linux/miscdevice.h>
> #include <linux/module.h>
> +#include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/poll.h>
> +#include <linux/regmap.h>
> #include <linux/sched.h>
> #include <linux/timer.h>
>
> @@ -60,7 +63,8 @@
> struct bt_bmc {
> struct device dev;
> struct miscdevice miscdev;
> - void __iomem *base;
> + struct regmap *map;
> + int offset;
> int irq;
> wait_queue_head_t queue;
> struct timer_list poll_timer;
> @@ -69,14 +73,31 @@ struct bt_bmc {
>
> static atomic_t open_count = ATOMIC_INIT(0);
>
> +static struct regmap_config bt_regmap_cfg = {
const?
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> +};
> +
> static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
> {
> - return ioread8(bt_bmc->base + reg);
> + uint32_t val = 0;
> + int rc;
> +
> + rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val);
> + WARN(rc != 0, "%s:%d: regmap_read() failed: %d\n",
> + __FILE__, __LINE__, rc);
Under what circumstances do we expect the read to fail?
This isn't much cleaner, but I prefer it slightly:
rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val);
if (rc) {
dev_warn(bt_bmc->dev, "read failed %d\n", rc);
return rc;
}
return val;
> +
> + return rc == 0 ? (u8) val : 0;
> }
>
> static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
> {
> - iowrite8(data, bt_bmc->base + reg);
> + int rc;
> +
> + rc = regmap_write(bt_bmc->map, bt_bmc->offset + reg, data);
> + WARN(rc != 0, "%s:%d: regmap_write() failed: %d\n",
> + __FILE__, __LINE__, rc);
> }
>
> static void clr_rd_ptr(struct bt_bmc *bt_bmc)
> @@ -367,14 +388,18 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
> {
> struct bt_bmc *bt_bmc = arg;
> u32 reg;
> + int rc;
> +
> + rc = regmap_read(bt_bmc->map, bt_bmc->offset + BT_CR2, ®);
> + if (rc)
> + return IRQ_NONE;
>
> - reg = ioread32(bt_bmc->base + BT_CR2);
> reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
> if (!reg)
> return IRQ_NONE;
>
> /* ack pending IRQs */
> - iowrite32(reg, bt_bmc->base + BT_CR2);
> + regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR2, reg);
>
> wake_up(&bt_bmc->queue);
> return IRQ_HANDLED;
> @@ -384,7 +409,6 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> - u32 reg;
> int rc;
>
> bt_bmc->irq = platform_get_irq(pdev, 0);
> @@ -405,18 +429,17 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> * will be cleared (along with B2H) when we can write the next
> * message to the BT buffer
> */
> - reg = ioread32(bt_bmc->base + BT_CR1);
> - reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY;
> - iowrite32(reg, bt_bmc->base + BT_CR1);
> + rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1,
> + (BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY),
> + (BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY));
You could drop the ( ) around the flags if you want.
>
> - return 0;
> + return rc;
> }
>
> static int bt_bmc_probe(struct platform_device *pdev)
> {
> struct bt_bmc *bt_bmc;
> struct device *dev;
> - struct resource *res;
> int rc;
>
> if (!pdev || !pdev->dev.of_node)
> @@ -431,10 +454,27 @@ static int bt_bmc_probe(struct platform_device *pdev)
>
> dev_set_drvdata(&pdev->dev, bt_bmc);
>
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - bt_bmc->base = devm_ioremap_resource(&pdev->dev, res);
> - if (IS_ERR(bt_bmc->base))
> - return PTR_ERR(bt_bmc->base);
> + bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
> + if (IS_ERR(bt_bmc->map)) {
> + struct resource *res;
> + void __iomem *base;
> +
> + /*
> + * Assume it's not the MFD-based devicetree description, in
> + * which case generate a regmap ourselves
> + */
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + bt_bmc->map = devm_regmap_init_mmio(dev, base, &bt_regmap_cfg);
> + bt_bmc->offset = 0;
> + } else {
> + rc = of_property_read_u32(dev->of_node, "reg", &bt_bmc->offset);
> + if (rc)
> + return rc;
> + }
>
> mutex_init(&bt_bmc->mutex);
> init_waitqueue_head(&bt_bmc->queue);
> @@ -461,12 +501,12 @@ static int bt_bmc_probe(struct platform_device *pdev)
> add_timer(&bt_bmc->poll_timer);
> }
>
> - iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) |
> - (BT_IRQ << BT_CR0_IRQ) |
> - BT_CR0_EN_CLR_SLV_RDP |
> - BT_CR0_EN_CLR_SLV_WRP |
> - BT_CR0_ENABLE_IBT,
> - bt_bmc->base + BT_CR0);
> + regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0,
> + (BT_IO_BASE << BT_CR0_IO_BASE) |
> + (BT_IRQ << BT_CR0_IRQ) |
> + BT_CR0_EN_CLR_SLV_RDP |
> + BT_CR0_EN_CLR_SLV_WRP |
> + BT_CR0_ENABLE_IBT);
>
> clr_b_busy(bt_bmc);
>
> --
> 2.9.3
>
^ permalink raw reply
* [PATCH] iopoll: include <linux/ktime.h> instead of <linux/hrtimer.h>
From: Masahiro Yamada @ 2016-12-14 1:33 UTC (permalink / raw)
To: linux-arm-kernel
The timer APIs this header needs are ktime_get(), ktime_add_us(),
and ktime_compare(). So, including <linux/ktime.h> seems enough.
This commit will cut unnecessary header file parsing.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
I was not quite sure whom I should send this patch to.
I am sending this to Will Deacon because commit 54c523127bcc
("iopoll: Introduce memory-mapped IO polling macros") was applied
by him.
include/linux/iopoll.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h
index 1c30014..d29e1e2 100644
--- a/include/linux/iopoll.h
+++ b/include/linux/iopoll.h
@@ -17,7 +17,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/hrtimer.h>
+#include <linux/ktime.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/io.h>
--
2.7.4
^ permalink raw reply related
* [PATCH] arm: Adjust memory boundaries after reservations
From: Laura Abbott @ 2016-12-14 2:11 UTC (permalink / raw)
To: linux-arm-kernel
The poorly named sanity_check_meminfo is responsible for setting up the
boundary for lowmem/highmem. This needs to be set up before memblock
reservations can occur. At the time memblock reservations can occur,
memory can also be removed from the system. This can throw off the
calculation of the lowmem/highmem boundary. On some systems this may be
harmless, on others this may result in incorrect ranges being passed to
the main memory allocator. Correct this by recalcuating the
lowmem/highmem boundary after all reservations have been made.
As part of this, rename sanity_check_meminfo to actually refect what the
function is doing.
Reported-by: Magnus Lilja <lilja.magnus@gmail.com>
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
The particular issue I reproduced for
https://marc.info/?l=linux-arm-kernel&m=148145259511248 involved the lowmem
boundary being greater than the end of ram thanks to the memblock_steal.
The re-calcuation should have no effect unless memory was actually removed
from the system. Putting it in arm_memblock_steal doesn't cover all cases
either since the devicetree memory map can also remove memory.
---
arch/arm/kernel/setup.c | 12 ++++++++++--
arch/arm/mm/mmu.c | 15 +++++++++------
arch/arm/mm/nommu.c | 2 +-
3 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 34e3f3c..62f91bd 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -81,7 +81,7 @@ __setup("fpe=", fpe_setup);
extern void init_default_cache_policy(unsigned long);
extern void paging_init(const struct machine_desc *desc);
extern void early_paging_init(const struct machine_desc *);
-extern void sanity_check_meminfo(void);
+extern void update_memory_bounds(void);
extern enum reboot_mode reboot_mode;
extern void setup_dma_zone(const struct machine_desc *desc);
@@ -1093,8 +1093,16 @@ void __init setup_arch(char **cmdline_p)
setup_dma_zone(mdesc);
xen_early_init();
efi_init();
- sanity_check_meminfo();
+ /*
+ * We need to make sure the calculation for lowmem/highmem is set
+ * appropriately before reserving/allocating any memory
+ */
+ update_memory_bounds();
arm_memblock_init(mdesc);
+ /*
+ * Memory may have been removed so the bounds need to be recalcuated.
+ */
+ update_memory_bounds();
early_ioremap_reset();
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4001dd1..666e789 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1152,13 +1152,14 @@ early_param("vmalloc", early_vmalloc);
phys_addr_t arm_lowmem_limit __initdata = 0;
-void __init sanity_check_meminfo(void)
+void __init update_memory_bounds(void)
{
phys_addr_t memblock_limit = 0;
int highmem = 0;
u64 vmalloc_limit;
struct memblock_region *reg;
bool should_use_highmem = false;
+ phys_addr_t lowmem_limit = 0;
/*
* Let's use our own (unoptimized) equivalent of __pa() that is
@@ -1196,18 +1197,18 @@ void __init sanity_check_meminfo(void)
pr_notice("Truncating RAM at %pa-%pa",
&block_start, &block_end);
block_end = vmalloc_limit;
- pr_cont(" to -%pa", &block_end);
+ pr_cont(" to -%pa\n", &block_end);
memblock_remove(vmalloc_limit, overlap_size);
should_use_highmem = true;
}
}
if (!highmem) {
- if (block_end > arm_lowmem_limit) {
+ if (block_end > lowmem_limit) {
if (reg->size > size_limit)
- arm_lowmem_limit = vmalloc_limit;
+ lowmem_limit = vmalloc_limit;
else
- arm_lowmem_limit = block_end;
+ lowmem_limit = block_end;
}
/*
@@ -1227,12 +1228,14 @@ void __init sanity_check_meminfo(void)
if (!IS_ALIGNED(block_start, PMD_SIZE))
memblock_limit = block_start;
else if (!IS_ALIGNED(block_end, PMD_SIZE))
- memblock_limit = arm_lowmem_limit;
+ memblock_limit = lowmem_limit;
}
}
}
+ arm_lowmem_limit = lowmem_limit;
+
if (should_use_highmem)
pr_notice("Consider using a HIGHMEM enabled kernel.\n");
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 2740967..e5bc874 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -295,7 +295,7 @@ void __init arm_mm_memblock_reserve(void)
#endif
}
-void __init sanity_check_meminfo(void)
+void __init update_memory_bounds(void)
{
phys_addr_t end;
sanity_check_meminfo_mpu();
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/2] FPGA: TS-7300 FPGA manager
From: Florian Fainelli @ 2016-12-14 2:28 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
This patch series adds support for loading bitstreams into the Altera Cyclone II
connected to an EP9302 on a TS-7300 board.
Changes in v2:
- rebased against fpga/for-next
- added defines for configuration bits and delays
- added error mesage if ioremap() fails
- detailed how the configuration through CPLD is done
Florian Fainelli (2):
ARM: ep93xx: Register ts73xx-fpga manager driver for TS-7300
FPGA: Add TS-7300 FPGA manager
arch/arm/mach-ep93xx/ts72xx.c | 26 +++++++
drivers/fpga/Kconfig | 7 ++
drivers/fpga/Makefile | 1 +
drivers/fpga/ts73xx-fpga.c | 162 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 196 insertions(+)
create mode 100644 drivers/fpga/ts73xx-fpga.c
--
2.9.3
^ permalink raw reply
* [PATCH v2 1/2] ARM: ep93xx: Register ts73xx-fpga manager driver for TS-7300
From: Florian Fainelli @ 2016-12-14 2:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214022845.5692-1-f.fainelli@gmail.com>
Register the TS-7300 FPGA manager device drivers which allows us to load
bitstreams into the on-board Altera Cyclone II FPGA.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
arch/arm/mach-ep93xx/ts72xx.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 3b39ea353d30..acf72ea670ef 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -230,6 +230,28 @@ static struct ep93xx_eth_data __initdata ts72xx_eth_data = {
.phy_id = 1,
};
+#if IS_ENABLED(CONFIG_FPGA_MGR_TS73XX)
+
+/* Relative to EP93XX_CS1_PHYS_BASE */
+#define TS73XX_FPGA_LOADER_BASE 0x03c00000
+
+static struct resource ts73xx_fpga_resources[] = {
+ {
+ .start = EP93XX_CS1_PHYS_BASE + TS73XX_FPGA_LOADER_BASE,
+ .end = EP93XX_CS1_PHYS_BASE + TS73XX_FPGA_LOADER_BASE + 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ts73xx_fpga_device = {
+ .name = "ts73xx-fpga-mgr",
+ .id = -1,
+ .resource = ts73xx_fpga_resources,
+ .num_resources = ARRAY_SIZE(ts73xx_fpga_resources),
+};
+
+#endif
+
static void __init ts72xx_init_machine(void)
{
ep93xx_init_devices();
@@ -238,6 +260,10 @@ static void __init ts72xx_init_machine(void)
platform_device_register(&ts72xx_wdt_device);
ep93xx_register_eth(&ts72xx_eth_data, 1);
+#if IS_ENABLED(CONFIG_FPGA_MGR_TS73XX)
+ if (board_is_ts7300())
+ platform_device_register(&ts73xx_fpga_device);
+#endif
}
MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
--
2.9.3
^ permalink raw reply related
* [PATCH v2 2/2] FPGA: Add TS-7300 FPGA manager
From: Florian Fainelli @ 2016-12-14 2:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214022845.5692-1-f.fainelli@gmail.com>
Add support for loading bitstreams on the Altera Cyclone II FPGA
populated on the TS-7300 board. This is done through the configuration
and data registers offered through a memory interface between the EP93xx
SoC and the FPGA via an intermediate CPLD device.
The EP93xx SoC on the TS-7300 does not have direct means of configuring
the on-board FPGA other than by using the special memory mapped
interface to the CPLD. No other entity on the system can control the
FPGA bitstream.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/fpga/Kconfig | 7 ++
drivers/fpga/Makefile | 1 +
drivers/fpga/ts73xx-fpga.c | 162 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 170 insertions(+)
create mode 100644 drivers/fpga/ts73xx-fpga.c
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index ce861a2853a4..d9cbef60db80 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -33,6 +33,13 @@ config FPGA_MGR_SOCFPGA_A10
help
FPGA manager driver support for Altera Arria10 SoCFPGA.
+config FPGA_MGR_TS73XX
+ tristate "Technologic Systems TS-73xx SBC FPGA Manager"
+ depends on ARCH_EP93XX && MACH_TS72XX
+ help
+ FPGA manager driver support for the Altera Cyclone II FPGA
+ present on the TS-73xx SBC boards.
+
config FPGA_MGR_ZYNQ_FPGA
tristate "Xilinx Zynq FPGA"
depends on ARCH_ZYNQ || COMPILE_TEST
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8df07bcf42a6..a1160169e6d9 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_FPGA) += fpga-mgr.o
# FPGA Manager Drivers
obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
+obj-$(CONFIG_FPGA_MGR_TS73XX) += ts73xx-fpga.o
obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o
# FPGA Bridge Drivers
diff --git a/drivers/fpga/ts73xx-fpga.c b/drivers/fpga/ts73xx-fpga.c
new file mode 100644
index 000000000000..c004be5954ae
--- /dev/null
+++ b/drivers/fpga/ts73xx-fpga.c
@@ -0,0 +1,162 @@
+/*
+ * Technologic Systems TS-73xx SBC FPGA loader
+ *
+ * Copyright (C) 2016 Florian Fainelli <f.fainelli@gmail.com>
+ *
+ * FPGA Manager Driver for the on-board Altera Cyclone II FPGA found on
+ * TS-7300, heavily based on load_fpga.c in their vendor tree.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/iopoll.h>
+#include <linux/fpga/fpga-mgr.h>
+
+#define TS73XX_FPGA_DATA_REG 0
+#define TS73XX_FPGA_CONFIG_REG 1
+
+#define TS73XX_FPGA_WRITE_DONE 0x1
+#define TS73XX_FPGA_WRITE_DONE_TIMEOUT 1000 /* us */
+#define TS73XX_FPGA_RESET 0x2
+#define TS73XX_FPGA_RESET_LOW_DELAY 30 /* us */
+#define TS73XX_FPGA_RESET_HIGH_DELAY 80 /* us */
+#define TS73XX_FPGA_LOAD_OK 0x4
+#define TS73XX_FPGA_CONFIG_LOAD 0x8
+
+struct ts73xx_fpga_priv {
+ void __iomem *io_base;
+ struct device *dev;
+};
+
+static enum fpga_mgr_states ts73xx_fpga_state(struct fpga_manager *mgr)
+{
+ return FPGA_MGR_STATE_UNKNOWN;
+}
+
+static int ts73xx_fpga_write_init(struct fpga_manager *mgr, u32 flags,
+ const char *buf, size_t count)
+{
+ struct ts73xx_fpga_priv *priv = mgr->priv;
+
+ /* Reset the FPGA */
+ writeb(0, priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ udelay(TS73XX_FPGA_RESET_LOW_DELAY);
+ writeb(TS73XX_FPGA_RESET, priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ udelay(TS73XX_FPGA_RESET_HIGH_DELAY);
+
+ return 0;
+}
+
+static int ts73xx_fpga_write(struct fpga_manager *mgr, const char *buf,
+ size_t count)
+{
+ struct ts73xx_fpga_priv *priv = mgr->priv;
+ size_t i = 0;
+ int ret;
+ u8 reg;
+
+ while (count--) {
+ ret = readb_poll_timeout(priv->io_base + TS73XX_FPGA_CONFIG_REG,
+ reg, !(reg & TS73XX_FPGA_WRITE_DONE),
+ 1, TS73XX_FPGA_WRITE_DONE_TIMEOUT);
+ if (ret < 0)
+ return ret;
+
+ writeb(buf[i], priv->io_base + TS73XX_FPGA_DATA_REG);
+ i++;
+ }
+
+ usleep_range(1000, 2000);
+ reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ reg |= TS73XX_FPGA_CONFIG_LOAD;
+ writeb(reg, priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ usleep_range(1000, 2000);
+
+ reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ reg &= ~TS73XX_FPGA_CONFIG_LOAD;
+ writeb(reg, priv->io_base + TS73XX_FPGA_CONFIG_REG);
+
+ return 0;
+}
+
+static int ts73xx_fpga_write_complete(struct fpga_manager *mgr, u32 flags)
+{
+ struct ts73xx_fpga_priv *priv = mgr->priv;
+ u8 reg;
+
+ reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ if ((reg & TS73XX_FPGA_LOAD_OK) != TS73XX_FPGA_LOAD_OK)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static const struct fpga_manager_ops ts73xx_fpga_ops = {
+ .state = ts73xx_fpga_state,
+ .write_init = ts73xx_fpga_write_init,
+ .write = ts73xx_fpga_write,
+ .write_complete = ts73xx_fpga_write_complete,
+};
+
+static int ts73xx_fpga_probe(struct platform_device *pdev)
+{
+ struct device *kdev = &pdev->dev;
+ struct ts73xx_fpga_priv *priv;
+ struct fpga_manager *mgr;
+ struct resource *res;
+ int err;
+
+ priv = devm_kzalloc(kdev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = kdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->io_base = devm_ioremap_resource(kdev, res);
+ if (IS_ERR(priv->io_base)) {
+ dev_err(kdev, "unable to remap registers\n");
+ return PTR_ERR(priv->io_base);
+ }
+
+ err = fpga_mgr_register(kdev, "TS-73xx FPGA Manager",
+ &ts73xx_fpga_ops, priv);
+ if (err) {
+ dev_err(kdev, "failed to register FPGA manager\n");
+ return err;
+ }
+
+ return err;
+}
+
+static int ts73xx_fpga_remove(struct platform_device *pdev)
+{
+ fpga_mgr_unregister(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver ts73xx_fpga_driver = {
+ .driver = {
+ .name = "ts73xx-fpga-mgr",
+ },
+ .probe = ts73xx_fpga_probe,
+ .remove = ts73xx_fpga_remove,
+};
+module_platform_driver(ts73xx_fpga_driver);
+
+MODULE_AUTHOR("Florian Fainelli <f.fainelli@gmail.com>");
+MODULE_DESCRIPTION("TS-73xx FPGA Manager driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
^ permalink raw reply related
* [PATCH v2 0/2] FPGA: TS-7300 FPGA manager
From: Florian Fainelli @ 2016-12-14 2:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214022845.5692-1-f.fainelli@gmail.com>
On 12/13/2016 06:28 PM, Florian Fainelli wrote:
> Hi all,
>
> This patch series adds support for loading bitstreams into the Altera Cyclone II
> connected to an EP9302 on a TS-7300 board.
>
> Changes in v2:
>
> - rebased against fpga/for-next
> - added defines for configuration bits and delays
> - added error mesage if ioremap() fails
> - detailed how the configuration through CPLD is done
I forgot to fix a function signature while rebasing, let me resubmit this.
>
> Florian Fainelli (2):
> ARM: ep93xx: Register ts73xx-fpga manager driver for TS-7300
> FPGA: Add TS-7300 FPGA manager
>
> arch/arm/mach-ep93xx/ts72xx.c | 26 +++++++
> drivers/fpga/Kconfig | 7 ++
> drivers/fpga/Makefile | 1 +
> drivers/fpga/ts73xx-fpga.c | 162 ++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 196 insertions(+)
> create mode 100644 drivers/fpga/ts73xx-fpga.c
>
--
Florian
^ permalink raw reply
* [PATCH v3 0/2] FPGA: TS-7300 FPGA manager
From: Florian Fainelli @ 2016-12-14 2:35 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
This patch series adds support for loading bitstreams into the Altera Cyclone II
connected to an EP9302 on a TS-7300 board.
Changes in v3:
- fix write_init and write_complete signatures
Changes in v2:
- rebased against fpga/for-next
- added defines for configuration bits and delays
- added error mesage if ioremap() fails
- detailed how the configuration through CPLD is done
Florian Fainelli (2):
ARM: ep93xx: Register ts73xx-fpga manager driver for TS-7300
FPGA: Add TS-7300 FPGA manager
arch/arm/mach-ep93xx/ts72xx.c | 26 +++++++
drivers/fpga/Kconfig | 7 ++
drivers/fpga/Makefile | 1 +
drivers/fpga/ts73xx-fpga.c | 163 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 197 insertions(+)
create mode 100644 drivers/fpga/ts73xx-fpga.c
--
2.9.3
^ permalink raw reply
* [PATCH v3 1/2] ARM: ep93xx: Register ts73xx-fpga manager driver for TS-7300
From: Florian Fainelli @ 2016-12-14 2:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214023553.9377-1-f.fainelli@gmail.com>
Register the TS-7300 FPGA manager device drivers which allows us to load
bitstreams into the on-board Altera Cyclone II FPGA.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
arch/arm/mach-ep93xx/ts72xx.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 3b39ea353d30..acf72ea670ef 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -230,6 +230,28 @@ static struct ep93xx_eth_data __initdata ts72xx_eth_data = {
.phy_id = 1,
};
+#if IS_ENABLED(CONFIG_FPGA_MGR_TS73XX)
+
+/* Relative to EP93XX_CS1_PHYS_BASE */
+#define TS73XX_FPGA_LOADER_BASE 0x03c00000
+
+static struct resource ts73xx_fpga_resources[] = {
+ {
+ .start = EP93XX_CS1_PHYS_BASE + TS73XX_FPGA_LOADER_BASE,
+ .end = EP93XX_CS1_PHYS_BASE + TS73XX_FPGA_LOADER_BASE + 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ts73xx_fpga_device = {
+ .name = "ts73xx-fpga-mgr",
+ .id = -1,
+ .resource = ts73xx_fpga_resources,
+ .num_resources = ARRAY_SIZE(ts73xx_fpga_resources),
+};
+
+#endif
+
static void __init ts72xx_init_machine(void)
{
ep93xx_init_devices();
@@ -238,6 +260,10 @@ static void __init ts72xx_init_machine(void)
platform_device_register(&ts72xx_wdt_device);
ep93xx_register_eth(&ts72xx_eth_data, 1);
+#if IS_ENABLED(CONFIG_FPGA_MGR_TS73XX)
+ if (board_is_ts7300())
+ platform_device_register(&ts73xx_fpga_device);
+#endif
}
MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
--
2.9.3
^ permalink raw reply related
* [PATCH v3 2/2] FPGA: Add TS-7300 FPGA manager
From: Florian Fainelli @ 2016-12-14 2:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214023553.9377-1-f.fainelli@gmail.com>
Add support for loading bitstreams on the Altera Cyclone II FPGA
populated on the TS-7300 board. This is done through the configuration
and data registers offered through a memory interface between the EP93xx
SoC and the FPGA via an intermediate CPLD device.
The EP93xx SoC on the TS-7300 does not have direct means of configuring
the on-board FPGA other than by using the special memory mapped
interface to the CPLD. No other entity on the system can control the
FPGA bitstream.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/fpga/Kconfig | 7 ++
drivers/fpga/Makefile | 1 +
drivers/fpga/ts73xx-fpga.c | 163 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 171 insertions(+)
create mode 100644 drivers/fpga/ts73xx-fpga.c
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index ce861a2853a4..d9cbef60db80 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -33,6 +33,13 @@ config FPGA_MGR_SOCFPGA_A10
help
FPGA manager driver support for Altera Arria10 SoCFPGA.
+config FPGA_MGR_TS73XX
+ tristate "Technologic Systems TS-73xx SBC FPGA Manager"
+ depends on ARCH_EP93XX && MACH_TS72XX
+ help
+ FPGA manager driver support for the Altera Cyclone II FPGA
+ present on the TS-73xx SBC boards.
+
config FPGA_MGR_ZYNQ_FPGA
tristate "Xilinx Zynq FPGA"
depends on ARCH_ZYNQ || COMPILE_TEST
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8df07bcf42a6..a1160169e6d9 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_FPGA) += fpga-mgr.o
# FPGA Manager Drivers
obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
+obj-$(CONFIG_FPGA_MGR_TS73XX) += ts73xx-fpga.o
obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o
# FPGA Bridge Drivers
diff --git a/drivers/fpga/ts73xx-fpga.c b/drivers/fpga/ts73xx-fpga.c
new file mode 100644
index 000000000000..38d78d8c6b1e
--- /dev/null
+++ b/drivers/fpga/ts73xx-fpga.c
@@ -0,0 +1,163 @@
+/*
+ * Technologic Systems TS-73xx SBC FPGA loader
+ *
+ * Copyright (C) 2016 Florian Fainelli <f.fainelli@gmail.com>
+ *
+ * FPGA Manager Driver for the on-board Altera Cyclone II FPGA found on
+ * TS-7300, heavily based on load_fpga.c in their vendor tree.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/iopoll.h>
+#include <linux/fpga/fpga-mgr.h>
+
+#define TS73XX_FPGA_DATA_REG 0
+#define TS73XX_FPGA_CONFIG_REG 1
+
+#define TS73XX_FPGA_WRITE_DONE 0x1
+#define TS73XX_FPGA_WRITE_DONE_TIMEOUT 1000 /* us */
+#define TS73XX_FPGA_RESET 0x2
+#define TS73XX_FPGA_RESET_LOW_DELAY 30 /* us */
+#define TS73XX_FPGA_RESET_HIGH_DELAY 80 /* us */
+#define TS73XX_FPGA_LOAD_OK 0x4
+#define TS73XX_FPGA_CONFIG_LOAD 0x8
+
+struct ts73xx_fpga_priv {
+ void __iomem *io_base;
+ struct device *dev;
+};
+
+static enum fpga_mgr_states ts73xx_fpga_state(struct fpga_manager *mgr)
+{
+ return FPGA_MGR_STATE_UNKNOWN;
+}
+
+static int ts73xx_fpga_write_init(struct fpga_manager *mgr,
+ struct fpga_image_info *info,
+ const char *buf, size_t count)
+{
+ struct ts73xx_fpga_priv *priv = mgr->priv;
+
+ /* Reset the FPGA */
+ writeb(0, priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ udelay(TS73XX_FPGA_RESET_LOW_DELAY);
+ writeb(TS73XX_FPGA_RESET, priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ udelay(TS73XX_FPGA_RESET_HIGH_DELAY);
+
+ return 0;
+}
+
+static int ts73xx_fpga_write(struct fpga_manager *mgr, const char *buf,
+ size_t count)
+{
+ struct ts73xx_fpga_priv *priv = mgr->priv;
+ size_t i = 0;
+ int ret;
+ u8 reg;
+
+ while (count--) {
+ ret = readb_poll_timeout(priv->io_base + TS73XX_FPGA_CONFIG_REG,
+ reg, !(reg & TS73XX_FPGA_WRITE_DONE),
+ 1, TS73XX_FPGA_WRITE_DONE_TIMEOUT);
+ if (ret < 0)
+ return ret;
+
+ writeb(buf[i], priv->io_base + TS73XX_FPGA_DATA_REG);
+ i++;
+ }
+
+ usleep_range(1000, 2000);
+ reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ reg |= TS73XX_FPGA_CONFIG_LOAD;
+ writeb(reg, priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ usleep_range(1000, 2000);
+
+ reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ reg &= ~TS73XX_FPGA_CONFIG_LOAD;
+ writeb(reg, priv->io_base + TS73XX_FPGA_CONFIG_REG);
+
+ return 0;
+}
+
+static int ts73xx_fpga_write_complete(struct fpga_manager *mgr,
+ struct fpga_image_info *info)
+{
+ struct ts73xx_fpga_priv *priv = mgr->priv;
+ u8 reg;
+
+ reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
+ if ((reg & TS73XX_FPGA_LOAD_OK) != TS73XX_FPGA_LOAD_OK)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static const struct fpga_manager_ops ts73xx_fpga_ops = {
+ .state = ts73xx_fpga_state,
+ .write_init = ts73xx_fpga_write_init,
+ .write = ts73xx_fpga_write,
+ .write_complete = ts73xx_fpga_write_complete,
+};
+
+static int ts73xx_fpga_probe(struct platform_device *pdev)
+{
+ struct device *kdev = &pdev->dev;
+ struct ts73xx_fpga_priv *priv;
+ struct resource *res;
+ int err;
+
+ priv = devm_kzalloc(kdev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = kdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->io_base = devm_ioremap_resource(kdev, res);
+ if (IS_ERR(priv->io_base)) {
+ dev_err(kdev, "unable to remap registers\n");
+ return PTR_ERR(priv->io_base);
+ }
+
+ err = fpga_mgr_register(kdev, "TS-73xx FPGA Manager",
+ &ts73xx_fpga_ops, priv);
+ if (err) {
+ dev_err(kdev, "failed to register FPGA manager\n");
+ return err;
+ }
+
+ return err;
+}
+
+static int ts73xx_fpga_remove(struct platform_device *pdev)
+{
+ fpga_mgr_unregister(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver ts73xx_fpga_driver = {
+ .driver = {
+ .name = "ts73xx-fpga-mgr",
+ },
+ .probe = ts73xx_fpga_probe,
+ .remove = ts73xx_fpga_remove,
+};
+module_platform_driver(ts73xx_fpga_driver);
+
+MODULE_AUTHOR("Florian Fainelli <f.fainelli@gmail.com>");
+MODULE_DESCRIPTION("TS-73xx FPGA Manager driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
^ permalink raw reply related
* [PATCH] media: platform: exynos4-is: constify v4l2_subdev_ops strcutures
From: Bhumika Goyal @ 2016-12-14 3:55 UTC (permalink / raw)
To: linux-arm-kernel
Check for v4l2_subdev_ops structures that are only passed as an
argument to the function v4l2_subdev_init. This argument is of type
const, so v4l2_subdev_ops structures having this property can also be
declared const.
Done using Coccinelle:
@r1 disable optional_qualifier @
identifier i;
position p;
@@
static struct v4l2_subdev_ops i at p = {...};
@ok1@
identifier r1.i;
position p;
@@
v4l2_subdev_init(...,&i at p)
@bad@
position p!={r1.p,ok1.p};
identifier r1.i;
@@
i at p
@depends on !bad disable optional_qualifier@
identifier r1.i;
@@
+const
struct v4l2_subdev_ops i;
Before and after size details:
text data bss dec hex filename
6743 152 20 6915 1b03 platform/exynos4-is/fimc-isp.o
6807 88 20 6915 1b03 platform/exynos4-is/fimc-isp.o
15653 392 36 16081 3ed1 platform/exynos4-is/fimc-lite.o
15717 308 36 16061 3ebd platform/exynos4-is/fimc-lite.o
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
drivers/media/platform/exynos4-is/fimc-isp.c | 2 +-
drivers/media/platform/exynos4-is/fimc-lite.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 8efe916..fd793d3 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -433,7 +433,7 @@ static void fimc_isp_subdev_unregistered(struct v4l2_subdev *sd)
.s_power = fimc_isp_subdev_s_power,
};
-static struct v4l2_subdev_ops fimc_is_subdev_ops = {
+static const struct v4l2_subdev_ops fimc_is_subdev_ops = {
.core = &fimc_is_core_ops,
.video = &fimc_is_subdev_video_ops,
.pad = &fimc_is_subdev_pad_ops,
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index b91abf1..18b6aaa 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1361,7 +1361,7 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
.log_status = fimc_lite_log_status,
};
-static struct v4l2_subdev_ops fimc_lite_subdev_ops = {
+static const struct v4l2_subdev_ops fimc_lite_subdev_ops = {
.core = &fimc_lite_core_ops,
.video = &fimc_lite_subdev_video_ops,
.pad = &fimc_lite_subdev_pad_ops,
--
1.9.1
^ permalink raw reply related
* [PATCH v7 2/5] drm: bridge: add DT bindings for TI ths8135
From: Archit Taneja @ 2016-12-14 5:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481623759-12786-3-git-send-email-bgolaszewski@baylibre.com>
Hi,
On 12/13/2016 03:39 PM, Bartosz Golaszewski wrote:
> THS8135 is a configurable video DAC. Add DT bindings for this chip.
Queued to drm-misc-next
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Acked-by: Rob Herring <robh@kernel.org>
> ---
> .../bindings/display/bridge/ti,ths8135.txt | 46 ++++++++++++++++++++++
> 1 file changed, 46 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt
>
> diff --git a/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt b/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt
> new file mode 100644
> index 0000000..6ec1a88
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/bridge/ti,ths8135.txt
> @@ -0,0 +1,46 @@
> +THS8135 Video DAC
> +-----------------
> +
> +This is the binding for Texas Instruments THS8135 Video DAC bridge.
> +
> +Required properties:
> +
> +- compatible: Must be "ti,ths8135"
> +
> +Required nodes:
> +
> +This device has two video ports. Their connections are modelled using the OF
> +graph bindings specified in Documentation/devicetree/bindings/graph.txt.
> +
> +- Video port 0 for RGB input
> +- Video port 1 for VGA output
> +
> +Example
> +-------
> +
> +vga-bridge {
> + compatible = "ti,ths8135";
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port at 0 {
> + reg = <0>;
> +
> + vga_bridge_in: endpoint {
> + remote-endpoint = <&lcdc_out_vga>;
> + };
> + };
> +
> + port at 1 {
> + reg = <1>;
> +
> + vga_bridge_out: endpoint {
> + remote-endpoint = <&vga_con_in>;
> + };
> + };
> + };
> +};
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH v7 3/5] drm: bridge: add support for TI ths8135
From: Archit Taneja @ 2016-12-14 5:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481623759-12786-4-git-send-email-bgolaszewski@baylibre.com>
On 12/13/2016 03:39 PM, Bartosz Golaszewski wrote:
> THS8135 is a configurable video DAC, but no configuration is actually
> necessary to make it work.
>
> For now use the dumb-vga-dac driver to support it.
Queued to drm-misc-next
Archit
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> drivers/gpu/drm/bridge/dumb-vga-dac.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c
> index e570698..86e9f9c 100644
> --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
> +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
> @@ -237,6 +237,7 @@ static int dumb_vga_remove(struct platform_device *pdev)
>
> static const struct of_device_id dumb_vga_match[] = {
> { .compatible = "dumb-vga-dac" },
> + { .compatible = "ti,ths8135" },
> {},
> };
> MODULE_DEVICE_TABLE(of, dumb_vga_match);
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH v2] crypto: sun4i-ss: support the Security System PRNG
From: Herbert Xu @ 2016-12-14 5:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161213141059.GB10647@Red>
On Tue, Dec 13, 2016 at 03:10:59PM +0100, Corentin Labbe wrote:
>
> I have found two solutions:
No we already have algif_rng so let's not confuse things even
further by making hwrng take PRNGs.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH] drm/mediatek: Support UYVY and YUYV format for overlay
From: Bibby Hsieh @ 2016-12-14 5:14 UTC (permalink / raw)
To: linux-arm-kernel
MT8173 overlay can support UYVY and YUYV format,
we add the format in DRM driver.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 6 ++++++
drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 ++
2 files changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 019b7ca..0a340f3 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -44,6 +44,8 @@
#define OVL_CON_CLRFMT_RGB888 (1 << 12)
#define OVL_CON_CLRFMT_RGBA8888 (2 << 12)
#define OVL_CON_CLRFMT_ARGB8888 (3 << 12)
+#define OVL_CON_CLRFMT_UYVY (4 << 12)
+#define OVL_CON_CLRFMT_YUYV (5 << 12)
#define OVL_CON_AEN BIT(8)
#define OVL_CON_ALPHA 0xff
@@ -161,6 +163,10 @@ static unsigned int ovl_fmt_convert(unsigned int fmt)
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ABGR8888:
return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP;
+ case DRM_FORMAT_YUYV:
+ return OVL_CON_CLRFMT_YUYV;
+ case DRM_FORMAT_UYVY:
+ return OVL_CON_CLRFMT_UYVY;
}
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index c461a23..b94c6ee 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -28,6 +28,8 @@
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_RGB565,
+ DRM_FORMAT_YUYV,
+ DRM_FORMAT_UYVY,
};
static void mtk_plane_reset(struct drm_plane *plane)
--
1.9.1
^ permalink raw reply related
* [PATCH] ipmi: bt-bmc: Use a regmap for register access
From: Andrew Jeffery @ 2016-12-14 5:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACPK8XezqdO3HQBBtQmFLNEbG0Ykq1EppFE_B7CjARRqw-f1vQ@mail.gmail.com>
On Wed, 2016-12-14 at 11:59 +1030, Joel Stanley wrote:
> > On Tue, Dec 6, 2016 at 1:27 PM, Andrew Jeffery <andrew@aj.id.au> wrote:
> > The registers for the bt-bmc device live under the Aspeed LPC
> > controller. Devicetree bindings have recently been introduced for the
> > LPC controller where the "host" portion of the LPC register space is
> > described as a syscon device. Future devicetrees describing the bt-bmc
> > device should nest its node under the appropriate "simple-mfd", "syscon"
> > compatible node.
> >
> > This change allows the bt-bmc driver to function with both syscon and
> > non-syscon- based devicetree descriptions by always using a regmap for
> > register access, either retrieved from the parent syscon device or
> > instantiated if none exists.
> >
> > The patch has been tested on an OpenPOWER Palmetto machine, successfully
> > booting, rebooting and powering down the host.
> >
> > > > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> > ---
> > ?drivers/char/ipmi/Kconfig??|??1 +
> > ?drivers/char/ipmi/bt-bmc.c | 82 ++++++++++++++++++++++++++++++++++------------
> > ?2 files changed, 62 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
> > index 7f816655cbbf..b5d48d9af124 100644
> > --- a/drivers/char/ipmi/Kconfig
> > +++ b/drivers/char/ipmi/Kconfig
> > @@ -79,6 +79,7 @@ endif # IPMI_HANDLER
> >
> > ?config ASPEED_BT_IPMI_BMC
> > ????????depends on ARCH_ASPEED
>
> If you do a v2 of this series it would be great to add || COMPILE_TEST here.
>
> > +????????depends on REGMAP && REGMAP_MMIO && MFD_SYSCON
> > ????????tristate "BT IPMI bmc driver"
> > ????????help
> > ??????????Provides a driver for the BT (Block Transfer) IPMI interface
> > diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
> > index fc9e8891eae3..ca1e20f6c6c5 100644
> > --- a/drivers/char/ipmi/bt-bmc.c
> > +++ b/drivers/char/ipmi/bt-bmc.c
> > @@ -12,10 +12,13 @@
> > ?#include <linux/errno.h>
> > ?#include <linux/interrupt.h>
> > ?#include <linux/io.h>
> > +#include <linux/mfd/syscon.h>
> > ?#include <linux/miscdevice.h>
> > ?#include <linux/module.h>
> > +#include <linux/of.h>
> > ?#include <linux/platform_device.h>
> > ?#include <linux/poll.h>
> > +#include <linux/regmap.h>
> > ?#include <linux/sched.h>
> > ?#include <linux/timer.h>
> >
> > @@ -60,7 +63,8 @@
> > ?struct bt_bmc {
> > ????????struct device???????????dev;
> > ????????struct miscdevice???????miscdev;
> > -???????void __iomem????????????*base;
> > +???????struct regmap???????????*map;
> > +???????int?????????????????????offset;
> > ????????int?????????????????????irq;
> > ????????wait_queue_head_t???????queue;
> > ????????struct timer_list???????poll_timer;
> > @@ -69,14 +73,31 @@ struct bt_bmc {
> >
> > ?static atomic_t open_count = ATOMIC_INIT(0);
> >
> > +static struct regmap_config bt_regmap_cfg = {
>
> const?
Good point. Is it worth a v2?
>
> > +???????.reg_bits = 32,
> > +???????.val_bits = 32,
> > +???????.reg_stride = 4,
> > +};
> > +
> > ?static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
> > ?{
> > -???????return ioread8(bt_bmc->base + reg);
> > +???????uint32_t val = 0;
> > +???????int rc;
> > +
> > +???????rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val);
> > +???????WARN(rc != 0, "%s:%d: regmap_read() failed: %d\n",
> > +???????????????????????__FILE__, __LINE__, rc);
>
> Under what circumstances do we expect the read to fail?
By the regmap_read() implementation for MMIO it should never fail. If
it does, then we should tell someone about it.
>
> This isn't much cleaner, but I prefer it slightly:
>
> rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val);
> if (rc) {
> ???dev_warn(bt_bmc->dev, "read failed %d\n", rc);
> ???return rc;
> }
>
> return val;
bt_inb() currently returns a u8 type, and as such no caller performs
error checking. While your suggestion might seem slightly preferable,
it feels likely "slightly preferable" might fail to take into account
the cascading effect of changing the return type and testing for errors
at each of the (transitive) call-sites.
I think the additional code required makes your suggestion less
attractive given that the call should never fail.
If you decide you feel strongly about it I can make the change.
>
> > +
> > +???????return rc == 0 ? (u8) val : 0;
> > ?}
> >
> > ?static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
> > ?{
> > -???????iowrite8(data, bt_bmc->base + reg);
> > +???????int rc;
> > +
> > +???????rc = regmap_write(bt_bmc->map, bt_bmc->offset + reg, data);
> > +???????WARN(rc != 0, "%s:%d: regmap_write() failed: %d\n",
> > +???????????????????????__FILE__, __LINE__, rc);
> > ?}
> >
> > ?static void clr_rd_ptr(struct bt_bmc *bt_bmc)
> > @@ -367,14 +388,18 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
> > ?{
> > ????????struct bt_bmc *bt_bmc = arg;
> > ????????u32 reg;
> > +???????int rc;
> > +
> > +???????rc = regmap_read(bt_bmc->map, bt_bmc->offset + BT_CR2, ®);
> > +???????if (rc)
> > +???????????????return IRQ_NONE;
> >
> > -???????reg = ioread32(bt_bmc->base + BT_CR2);
> > ????????reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
> > ????????if (!reg)
> > ????????????????return IRQ_NONE;
> >
> > ????????/* ack pending IRQs */
> > -???????iowrite32(reg, bt_bmc->base + BT_CR2);
> > +???????regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR2, reg);
> >
> > ????????wake_up(&bt_bmc->queue);
> > ????????return IRQ_HANDLED;
> > @@ -384,7 +409,6 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> > ?????????????????????????????struct platform_device *pdev)
> > ?{
> > ????????struct device *dev = &pdev->dev;
> > -???????u32 reg;
> > ????????int rc;
> >
> > ????????bt_bmc->irq = platform_get_irq(pdev, 0);
> > @@ -405,18 +429,17 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
> > ?????????* will be cleared (along with B2H) when we can write the next
> > ?????????* message to the BT buffer
> > ?????????*/
> > -???????reg = ioread32(bt_bmc->base + BT_CR1);
> > -???????reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY;
> > -???????iowrite32(reg, bt_bmc->base + BT_CR1);
> > +???????rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1,
> > +???????????????????????????????(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY),
> > +???????????????????????????????(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY));
>
> You could drop the ( ) around the flags if you want.
I think I wrote it this way when I was toying with different line-
wraps, but regardless I think they are a nice visual queue.
Andrew
>
> >
> > -???????return 0;
> > +???????return rc;
> > ?}
> >
> > ?static int bt_bmc_probe(struct platform_device *pdev)
> > ?{
> > ????????struct bt_bmc *bt_bmc;
> > ????????struct device *dev;
> > -???????struct resource *res;
> > ????????int rc;
> >
> > ????????if (!pdev || !pdev->dev.of_node)
> > @@ -431,10 +454,27 @@ static int bt_bmc_probe(struct platform_device *pdev)
> >
> > ????????dev_set_drvdata(&pdev->dev, bt_bmc);
> >
> > -???????res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > -???????bt_bmc->base = devm_ioremap_resource(&pdev->dev, res);
> > -???????if (IS_ERR(bt_bmc->base))
> > -???????????????return PTR_ERR(bt_bmc->base);
> > +???????bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
> > +???????if (IS_ERR(bt_bmc->map)) {
> > +???????????????struct resource *res;
> > +???????????????void __iomem *base;
> > +
> > +???????????????/*
> > +????????????????* Assume it's not the MFD-based devicetree description, in
> > +????????????????* which case generate a regmap ourselves
> > +????????????????*/
> > +???????????????res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +???????????????base = devm_ioremap_resource(&pdev->dev, res);
> > +???????????????if (IS_ERR(base))
> > +???????????????????????return PTR_ERR(base);
> > +
> > +???????????????bt_bmc->map = devm_regmap_init_mmio(dev, base, &bt_regmap_cfg);
> > +???????????????bt_bmc->offset = 0;
> > +???????} else {
> > +???????????????rc = of_property_read_u32(dev->of_node, "reg", &bt_bmc->offset);
> > +???????????????if (rc)
> > +???????????????????????return rc;
> > +???????}
> >
> > ????????mutex_init(&bt_bmc->mutex);
> > ????????init_waitqueue_head(&bt_bmc->queue);
> > @@ -461,12 +501,12 @@ static int bt_bmc_probe(struct platform_device *pdev)
> > ????????????????add_timer(&bt_bmc->poll_timer);
> > ????????}
> >
> > -???????iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) |
> > -?????????????????(BT_IRQ << BT_CR0_IRQ) |
> > -?????????????????BT_CR0_EN_CLR_SLV_RDP |
> > -?????????????????BT_CR0_EN_CLR_SLV_WRP |
> > -?????????????????BT_CR0_ENABLE_IBT,
> > -?????????????????bt_bmc->base + BT_CR0);
> > +???????regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0,
> > +????????????????????(BT_IO_BASE << BT_CR0_IO_BASE) |
> > +????????????????????(BT_IRQ << BT_CR0_IRQ) |
> > +????????????????????BT_CR0_EN_CLR_SLV_RDP |
> > +????????????????????BT_CR0_EN_CLR_SLV_WRP |
> > +????????????????????BT_CR0_ENABLE_IBT);
> >
> > ????????clr_b_busy(bt_bmc);
> >
> > --
> > 2.9.3
> >
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161214/bbfc992c/attachment-0001.sig>
^ permalink raw reply
* [PATCH v2] crypto: sun4i-ss: support the Security System PRNG
From: Corentin Labbe @ 2016-12-14 6:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214050551.GD9592@gondor.apana.org.au>
On Wed, Dec 14, 2016 at 01:05:51PM +0800, Herbert Xu wrote:
> On Tue, Dec 13, 2016 at 03:10:59PM +0100, Corentin Labbe wrote:
> >
> > I have found two solutions:
>
> No we already have algif_rng so let's not confuse things even
> further by making hwrng take PRNGs.
>
But algif_rng is not accessible from user space without any coding.
So no easy "random" data with some cat /dev/xxxx.
Clearly users of the 3 already intree hw_random PRNG will see that like a regresion.
Regards
Corentin Labbe
^ permalink raw reply
* [PATCH v3 2/2] FPGA: Add TS-7300 FPGA manager
From: Moritz Fischer @ 2016-12-14 6:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214023553.9377-3-f.fainelli@gmail.com>
Hi Florian,
On Tue, Dec 13, 2016 at 6:35 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
> Add support for loading bitstreams on the Altera Cyclone II FPGA
> populated on the TS-7300 board. This is done through the configuration
> and data registers offered through a memory interface between the EP93xx
> SoC and the FPGA via an intermediate CPLD device.
>
> The EP93xx SoC on the TS-7300 does not have direct means of configuring
> the on-board FPGA other than by using the special memory mapped
> interface to the CPLD. No other entity on the system can control the
> FPGA bitstream.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/fpga/Kconfig | 7 ++
> drivers/fpga/Makefile | 1 +
> drivers/fpga/ts73xx-fpga.c | 163 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 171 insertions(+)
> create mode 100644 drivers/fpga/ts73xx-fpga.c
>
> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index ce861a2853a4..d9cbef60db80 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -33,6 +33,13 @@ config FPGA_MGR_SOCFPGA_A10
> help
> FPGA manager driver support for Altera Arria10 SoCFPGA.
>
> +config FPGA_MGR_TS73XX
> + tristate "Technologic Systems TS-73xx SBC FPGA Manager"
> + depends on ARCH_EP93XX && MACH_TS72XX
> + help
> + FPGA manager driver support for the Altera Cyclone II FPGA
> + present on the TS-73xx SBC boards.
> +
> config FPGA_MGR_ZYNQ_FPGA
> tristate "Xilinx Zynq FPGA"
> depends on ARCH_ZYNQ || COMPILE_TEST
> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
> index 8df07bcf42a6..a1160169e6d9 100644
> --- a/drivers/fpga/Makefile
> +++ b/drivers/fpga/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_FPGA) += fpga-mgr.o
> # FPGA Manager Drivers
> obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
> obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
> +obj-$(CONFIG_FPGA_MGR_TS73XX) += ts73xx-fpga.o
> obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o
>
> # FPGA Bridge Drivers
> diff --git a/drivers/fpga/ts73xx-fpga.c b/drivers/fpga/ts73xx-fpga.c
> new file mode 100644
> index 000000000000..38d78d8c6b1e
> --- /dev/null
> +++ b/drivers/fpga/ts73xx-fpga.c
> @@ -0,0 +1,163 @@
> +/*
> + * Technologic Systems TS-73xx SBC FPGA loader
> + *
> + * Copyright (C) 2016 Florian Fainelli <f.fainelli@gmail.com>
> + *
> + * FPGA Manager Driver for the on-board Altera Cyclone II FPGA found on
> + * TS-7300, heavily based on load_fpga.c in their vendor tree.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/string.h>
> +#include <linux/iopoll.h>
> +#include <linux/fpga/fpga-mgr.h>
> +
> +#define TS73XX_FPGA_DATA_REG 0
> +#define TS73XX_FPGA_CONFIG_REG 1
> +
> +#define TS73XX_FPGA_WRITE_DONE 0x1
> +#define TS73XX_FPGA_WRITE_DONE_TIMEOUT 1000 /* us */
> +#define TS73XX_FPGA_RESET 0x2
> +#define TS73XX_FPGA_RESET_LOW_DELAY 30 /* us */
> +#define TS73XX_FPGA_RESET_HIGH_DELAY 80 /* us */
> +#define TS73XX_FPGA_LOAD_OK 0x4
> +#define TS73XX_FPGA_CONFIG_LOAD 0x8
> +
> +struct ts73xx_fpga_priv {
> + void __iomem *io_base;
> + struct device *dev;
> +};
> +
> +static enum fpga_mgr_states ts73xx_fpga_state(struct fpga_manager *mgr)
> +{
> + return FPGA_MGR_STATE_UNKNOWN;
> +}
> +
> +static int ts73xx_fpga_write_init(struct fpga_manager *mgr,
> + struct fpga_image_info *info,
> + const char *buf, size_t count)
> +{
> + struct ts73xx_fpga_priv *priv = mgr->priv;
> +
> + /* Reset the FPGA */
> + writeb(0, priv->io_base + TS73XX_FPGA_CONFIG_REG);
> + udelay(TS73XX_FPGA_RESET_LOW_DELAY);
> + writeb(TS73XX_FPGA_RESET, priv->io_base + TS73XX_FPGA_CONFIG_REG);
> + udelay(TS73XX_FPGA_RESET_HIGH_DELAY);
> +
> + return 0;
> +}
> +
> +static int ts73xx_fpga_write(struct fpga_manager *mgr, const char *buf,
> + size_t count)
> +{
> + struct ts73xx_fpga_priv *priv = mgr->priv;
> + size_t i = 0;
> + int ret;
> + u8 reg;
> +
> + while (count--) {
> + ret = readb_poll_timeout(priv->io_base + TS73XX_FPGA_CONFIG_REG,
> + reg, !(reg & TS73XX_FPGA_WRITE_DONE),
> + 1, TS73XX_FPGA_WRITE_DONE_TIMEOUT);
> + if (ret < 0)
> + return ret;
> +
> + writeb(buf[i], priv->io_base + TS73XX_FPGA_DATA_REG);
> + i++;
> + }
> +
<snip>
> + usleep_range(1000, 2000);
> + reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
> + reg |= TS73XX_FPGA_CONFIG_LOAD;
> + writeb(reg, priv->io_base + TS73XX_FPGA_CONFIG_REG);
> + usleep_range(1000, 2000);
</snip>
Just to clarify is this block what triggers the actual write? I'm asking because
I'm wondering if in the current implementation the ts73xx_fpga_write() function
can be called multiple times in your implementation before you finally get to
the write complete callback.
> +
> + reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
> + reg &= ~TS73XX_FPGA_CONFIG_LOAD;
> + writeb(reg, priv->io_base + TS73XX_FPGA_CONFIG_REG);
> +
> + return 0;
> +}
> +
> +static int ts73xx_fpga_write_complete(struct fpga_manager *mgr,
> + struct fpga_image_info *info)
> +{
> + struct ts73xx_fpga_priv *priv = mgr->priv;
> + u8 reg;
> +
> + reg = readb(priv->io_base + TS73XX_FPGA_CONFIG_REG);
> + if ((reg & TS73XX_FPGA_LOAD_OK) != TS73XX_FPGA_LOAD_OK)
> + return -ETIMEDOUT;
> +
> + return 0;
> +}
> +
> +static const struct fpga_manager_ops ts73xx_fpga_ops = {
> + .state = ts73xx_fpga_state,
> + .write_init = ts73xx_fpga_write_init,
> + .write = ts73xx_fpga_write,
> + .write_complete = ts73xx_fpga_write_complete,
> +};
> +
> +static int ts73xx_fpga_probe(struct platform_device *pdev)
> +{
> + struct device *kdev = &pdev->dev;
> + struct ts73xx_fpga_priv *priv;
> + struct resource *res;
> + int err;
> +
> + priv = devm_kzalloc(kdev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + priv->dev = kdev;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + priv->io_base = devm_ioremap_resource(kdev, res);
> + if (IS_ERR(priv->io_base)) {
> + dev_err(kdev, "unable to remap registers\n");
> + return PTR_ERR(priv->io_base);
> + }
> +
> + err = fpga_mgr_register(kdev, "TS-73xx FPGA Manager",
> + &ts73xx_fpga_ops, priv);
> + if (err) {
> + dev_err(kdev, "failed to register FPGA manager\n");
> + return err;
> + }
> +
> + return err;
> +}
> +
> +static int ts73xx_fpga_remove(struct platform_device *pdev)
> +{
> + fpga_mgr_unregister(&pdev->dev);
> +
> + return 0;
> +}
> +
> +static struct platform_driver ts73xx_fpga_driver = {
> + .driver = {
> + .name = "ts73xx-fpga-mgr",
> + },
> + .probe = ts73xx_fpga_probe,
> + .remove = ts73xx_fpga_remove,
> +};
> +module_platform_driver(ts73xx_fpga_driver);
> +
> +MODULE_AUTHOR("Florian Fainelli <f.fainelli@gmail.com>");
> +MODULE_DESCRIPTION("TS-73xx FPGA Manager driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>
Thanks,
Moritz
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox