* [PATCH V6 04/10] arm64: exception: handle Synchronous External Abort
From: Will Deacon @ 2017-01-04 13:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481147303-7979-5-git-send-email-tbaicar@codeaurora.org>
On Wed, Dec 07, 2016 at 02:48:17PM -0700, Tyler Baicar wrote:
> SEA exceptions are often caused by an uncorrected hardware
> error, and are handled when data abort and instruction abort
> exception classes have specific values for their Fault Status
> Code.
> When SEA occurs, before killing the process, go through
> the handlers registered in the notification list.
> Update fault_info[] with specific SEA faults so that the
> new SEA handler is used.
>
> Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org>
> Signed-off-by: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
> Signed-off-by: Naveen Kaje <nkaje@codeaurora.org>
> ---
> arch/arm64/include/asm/system_misc.h | 13 ++++++++
> arch/arm64/mm/fault.c | 58 +++++++++++++++++++++++++++++-------
> 2 files changed, 61 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
> index 57f110b..9040e1d 100644
> --- a/arch/arm64/include/asm/system_misc.h
> +++ b/arch/arm64/include/asm/system_misc.h
> @@ -64,4 +64,17 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
>
> #endif /* __ASSEMBLY__ */
>
> +/*
> + * The functions below are used to register and unregister callbacks
> + * that are to be invoked when a Synchronous External Abort (SEA)
> + * occurs. An SEA is raised by certain fault status codes that have
> + * either data or instruction abort as the exception class, and
> + * callbacks may be registered to parse or handle such hardware errors.
> + *
> + * Registered callbacks are run in an interrupt/atomic context. They
> + * are not allowed to block or sleep.
> + */
> +int register_synchronous_ext_abort_notifier(struct notifier_block *nb);
> +void unregister_synchronous_ext_abort_notifier(struct notifier_block *nb);
I think that we may as well use the "SEA" acronym consistently in code,
expanding it only for strings and comments, so these can be renamed to
{register,unregister}_sea_notifier. That said, what is the use of having a
notifier chain here as well as in the ghes code? If the ghes code is the
only place to register a notifier, we may as well start simple and call that
code directly, like we call handle_mm_fault directly for data aborts.
> static const struct fault_info {
> int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
> int sig;
> @@ -502,22 +540,22 @@ static const struct fault_info {
> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
> { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
> - { do_bad, SIGBUS, 0, "synchronous external abort" },
> + { do_synch_ext_abort, SIGBUS, 0, "synchronous external abort" },
Again, just stick with do_sea for the function name...
> { do_bad, SIGBUS, 0, "unknown 17" },
> { do_bad, SIGBUS, 0, "unknown 18" },
> { do_bad, SIGBUS, 0, "unknown 19" },
> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous parity error" },
> + { do_synch_ext_abort, SIGBUS, 0, "level 0 SEA (trans tbl walk)" },
... but there's no need to abbreviate "translation table walk" here. Long
strings that run over 80 chars are fine. Similarly for "SEA".
> + { do_synch_ext_abort, SIGBUS, 0, "level 1 SEA (trans tbl walk)" },
> + { do_synch_ext_abort, SIGBUS, 0, "level 2 SEA (trans tbl walk)" },
> + { do_synch_ext_abort, SIGBUS, 0, "level 3 SEA (trans tbl walk)" },
> + { do_synch_ext_abort, SIGBUS, 0, "synchronous parity or ECC err" },
> { do_bad, SIGBUS, 0, "unknown 25" },
> { do_bad, SIGBUS, 0, "unknown 26" },
> { do_bad, SIGBUS, 0, "unknown 27" },
> - { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
> - { do_bad, SIGBUS, 0, "synchronous parity error (translation table walk)" },
> + { do_synch_ext_abort, SIGBUS, 0, "level 0 synch parity error" },
> + { do_synch_ext_abort, SIGBUS, 0, "level 1 synch parity error" },
> + { do_synch_ext_abort, SIGBUS, 0, "level 2 synch parity error" },
> + { do_synch_ext_abort, SIGBUS, 0, "level 3 synch parity error" },
Please keep mention of "translation table walk", since we have exception
levels too and it's confusing just saying "level n".
Will
^ permalink raw reply
* [RFC, PATCHv2 29/29] mm, x86: introduce RLIMIT_VADDR
From: Arnd Bergmann @ 2017-01-04 13:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CALCETrXmdAnbgjsxw=qTbP2PhVCzE8v3y5XMt8DVa4P9DowsGA@mail.gmail.com>
On Tuesday, January 3, 2017 2:09:16 PM CET Andy Lutomirski wrote:
> >
> >> When
> >> ADDR_LIMIT_EXPLICIT is in effect, prctl can set a 64-bit numeric
> >> limit. If ADDR_LIMIT_EXPLICIT is cleared, the prctl value stops being
> >> settable and reading it via prctl returns whatever is implied by the
> >> other personality bits.
> >
> > I don't see anything wrong with it, but I'm a bit confused now
> > what this would be good for, compared to using just prctl.
> >
> > Is this about setuid clearing the personality but not the prctl,
> > or something else?
>
> It's to avid ambiguity as to what happens if you set ADDR_LIMIT_32BIT
> and use the prctl. ISTM it would be nice for the semantics to be
> fully defined in all cases.
>
Ok, got it.
Arnd
^ permalink raw reply
* [PATCH v3] arm64: mm: Fix NOMAP page initialization
From: Ard Biesheuvel @ 2017-01-04 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161216165437.21612-1-rrichter@cavium.com>
On 16 December 2016 at 16:54, Robert Richter <rrichter@cavium.com> wrote:
> On ThunderX systems with certain memory configurations we see the
> following BUG_ON():
>
> kernel BUG at mm/page_alloc.c:1848!
>
> This happens for some configs with 64k page size enabled. The BUG_ON()
> checks if start and end page of a memmap range belongs to the same
> zone.
>
> The BUG_ON() check fails if a memory zone contains NOMAP regions. In
> this case the node information of those pages is not initialized. This
> causes an inconsistency of the page links with wrong zone and node
> information for that pages. NOMAP pages from node 1 still point to the
> mem zone from node 0 and have the wrong nid assigned.
>
> The reason for the mis-configuration is a change in pfn_valid() which
> reports pages marked NOMAP as invalid:
>
> 68709f45385a arm64: only consider memblocks with NOMAP cleared for linear mapping
>
> This causes pages marked as nomap being no longer reassigned to the
> new zone in memmap_init_zone() by calling __init_single_pfn().
>
> Fixing this by implementing an arm64 specific early_pfn_valid(). This
> causes all pages of sections with memory including NOMAP ranges to be
> initialized by __init_single_page() and ensures consistency of page
> links to zone, node and section.
>
I like this solution a lot better than the first one, but I am still
somewhat uneasy about having the kernel reason about attributes of
pages it should not touch in the first place. But the fact that
early_pfn_valid() is only used a single time in the whole kernel does
give some confidence that we are not simply moving the problem
elsewhere.
Given that you are touching arch/arm/ as well as arch/arm64, could you
explain why only arm64 needs this treatment? Is it simply because we
don't have NUMA support there?
Considering that Hisilicon D05 suffered from the same issue, I would
like to get some coverage there as well. Hanjun, is this something you
can arrange? Thanks
> The HAVE_ARCH_PFN_VALID config option now requires an explicit
> definiton of early_pfn_valid() in the same way as pfn_valid(). This
> allows a customized implementation of early_pfn_valid() which
> redirects to valid_section() for arm64. This is the same as for the
> generic pfn_valid() implementation.
>
> v3:
>
> * Use valid_section() which is the same as the default pfn_valid()
> implementation to initialize
> * Added Ack for arm/ changes.
>
> v2:
>
> * Use pfn_present() instead of memblock_is_memory() to support also
> non-memory NOMAP holes
>
> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Robert Richter <rrichter@cavium.com>
> ---
> arch/arm/include/asm/page.h | 1 +
> arch/arm64/include/asm/page.h | 2 ++
> arch/arm64/mm/init.c | 15 +++++++++++++++
> include/linux/mmzone.h | 5 ++++-
> 4 files changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
> index 4355f0ec44d6..79761bd55f94 100644
> --- a/arch/arm/include/asm/page.h
> +++ b/arch/arm/include/asm/page.h
> @@ -158,6 +158,7 @@ typedef struct page *pgtable_t;
>
> #ifdef CONFIG_HAVE_ARCH_PFN_VALID
> extern int pfn_valid(unsigned long);
> +#define early_pfn_valid(pfn) pfn_valid(pfn)
> #endif
>
> #include <asm/memory.h>
> diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
> index 8472c6def5ef..17ceb7435ded 100644
> --- a/arch/arm64/include/asm/page.h
> +++ b/arch/arm64/include/asm/page.h
> @@ -49,6 +49,8 @@ typedef struct page *pgtable_t;
>
> #ifdef CONFIG_HAVE_ARCH_PFN_VALID
> extern int pfn_valid(unsigned long);
> +extern int early_pfn_valid(unsigned long);
> +#define early_pfn_valid early_pfn_valid
> #endif
>
> #include <asm/memory.h>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 212c4d1e2f26..8ff62a7ff634 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -145,11 +145,26 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
> #endif /* CONFIG_NUMA */
>
> #ifdef CONFIG_HAVE_ARCH_PFN_VALID
> +
> int pfn_valid(unsigned long pfn)
> {
> return memblock_is_map_memory(pfn << PAGE_SHIFT);
> }
> EXPORT_SYMBOL(pfn_valid);
> +
> +/*
> + * This is the same as the generic pfn_valid() implementation. We use
> + * valid_section() here to make sure all pages of a section including
> + * NOMAP pages are initialized with __init_single_page().
> + */
> +int early_pfn_valid(unsigned long pfn)
> +{
> + if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
> + return 0;
> + return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
> +}
> +EXPORT_SYMBOL(early_pfn_valid);
> +
> #endif
>
> #ifndef CONFIG_SPARSEMEM
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index 0f088f3a2fed..bedcf8a95881 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -1170,12 +1170,16 @@ static inline struct mem_section *__pfn_to_section(unsigned long pfn)
> }
>
> #ifndef CONFIG_HAVE_ARCH_PFN_VALID
> +
> static inline int pfn_valid(unsigned long pfn)
> {
> if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
> return 0;
> return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
> }
> +
> +#define early_pfn_valid(pfn) pfn_valid(pfn)
> +
> #endif
>
> static inline int pfn_present(unsigned long pfn)
> @@ -1200,7 +1204,6 @@ static inline int pfn_present(unsigned long pfn)
> #define pfn_to_nid(pfn) (0)
> #endif
>
> -#define early_pfn_valid(pfn) pfn_valid(pfn)
> void sparse_init(void);
> #else
> #define sparse_init() do {} while (0)
> --
> 2.11.0
>
^ permalink raw reply
* [PATCH 15/20] ARM/hw_breakpoint: Convert to hotplug state machine
From: Mark Rutland @ 2017-01-04 13:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170103093335.GA5605@leverpostej>
On Tue, Jan 03, 2017 at 09:33:36AM +0000, Mark Rutland wrote:
> Hi,
>
> On Mon, Jan 02, 2017 at 09:15:29PM +0100, Linus Walleij wrote:
> > On Mon, Jan 2, 2017 at 4:00 PM, Russell King - ARM Linux
> > <linux@armlinux.org.uk> wrote:
> > > On Mon, Jan 02, 2017 at 03:34:32PM +0100, Linus Walleij wrote:
> > >> in the first line of arch_hw_breakpoint_init() in
> > >> arch/arm/kernel/hw_breakpoint.c
> > >>
> > >> I suspect that is not an accepable solution ...
> > >>
> > >> It hangs at PC is at write_wb_reg+0x20c/0x330
> > >> Which is c03101dc, and looks like this in objdump -d:
> > >>
> > >> c031020c: ee001eba mcr 14, 0, r1, cr0, cr10, {5}
> > >> c0310210: eaffffb3 b c03100e4 <write_wb_reg+0x114>
> > >
> > > ... and this is several instructions after the address you mention above.
> > > Presumably c03101dc is accessing a higher numbered register?
> >
> > Ah sorry. It looks like this:
> >
> > c03101dc: ee001ed0 mcr 14, 0, r1, cr0, cr0, {6}
> > c03101e0: eaffffbf b c03100e4 <write_wb_reg+0x114>
> > c03101e4: ee001ebf mcr 14, 0, r1, cr0, cr15, {5}
> > c03101e8: eaffffbd b c03100e4 <write_wb_reg+0x114>
> > c03101ec: ee001ebe mcr 14, 0, r1, cr0, cr14, {5}
> > c03101f0: eaffffbb b c03100e4 <write_wb_reg+0x114>
> > c03101f4: ee001ebd mcr 14, 0, r1, cr0, cr13, {5}
> > c03101f8: eaffffb9 b c03100e4 <write_wb_reg+0x114>
>
> FWIW, I was tracking an issue in this area before the holiday.
>
> It looked like DBGPRSR.SPD is set unexpectedly over the default idle
> path (i.e. WFI), causing the (otherwise valid) register accesses above
> to be handled as undefined.
>
> I haven't looked at the patch in detail, but I guess that it allows idle
> to occur between reset_ctrl_regs() and arch_hw_breakpoint_init().
I've just reproduced this locally on my dragonboard APQ8060.
It looks like the write_wb_reg() call that's exploding is from
get_max_wp_len(), which we call immediately after registering the
dbg_reset_online callback. Clearing DBGPRSR.SPD before the write_wb_reg() hides
the problem, so I suspect we're seeing the issue I mentioned above -- it just
so happens that we go idle in a new place.
The below hack allows boot to continue, but is not a real fix. I'm not
immediately sure what to do.
Linus, I wasn't able to get ethernet working. Do I need anything on top
of v4.10-rc2 && multi_v7_defconfig?
Thanks,
Mark.
---->8----
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 188180b..a0982ab 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -302,7 +302,7 @@ int hw_breakpoint_slots(int type)
*/
static u8 get_max_wp_len(void)
{
- u32 ctrl_reg;
+ u32 ctrl_reg, val;
struct arch_hw_breakpoint_ctrl ctrl;
u8 size = 4;
@@ -313,6 +313,9 @@ static u8 get_max_wp_len(void)
ctrl.len = ARM_BREAKPOINT_LEN_8;
ctrl_reg = encode_ctrl_reg(ctrl);
+ /* HACK: CLEAR SPD */
+ ARM_DBG_READ(c1, c5, 4, val);
+
write_wb_reg(ARM_BASE_WVR, 0);
write_wb_reg(ARM_BASE_WCR, ctrl_reg);
if ((read_wb_reg(ARM_BASE_WCR) & ctrl_reg) == ctrl_reg)
^ permalink raw reply related
* [PATCH 2/2] arm64: mm: enable CONFIG_HOLES_IN_ZONE for NUMA
From: Will Deacon @ 2017-01-04 14:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8MdpVDCSjfum7AMtbgR6cTP5H+67svhDSu6bkaijvvyg@mail.gmail.com>
On Wed, Jan 04, 2017 at 01:50:20PM +0000, Ard Biesheuvel wrote:
> On 4 January 2017 at 13:28, Will Deacon <will.deacon@arm.com> wrote:
> > On Wed, Dec 14, 2016 at 09:11:47AM +0000, Ard Biesheuvel wrote:
> >> The NUMA code may get confused by the presence of NOMAP regions within
> >> zones, resulting in spurious BUG() checks where the node id deviates
> >> from the containing zone's node id.
> >>
> >> Since the kernel has no business reasoning about node ids of pages it
> >> does not own in the first place, enable CONFIG_HOLES_IN_ZONE to ensure
> >> that such pages are disregarded.
> >>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >> ---
> >> arch/arm64/Kconfig | 4 ++++
> >> 1 file changed, 4 insertions(+)
> >>
> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> >> index 111742126897..0472afe64d55 100644
> >> --- a/arch/arm64/Kconfig
> >> +++ b/arch/arm64/Kconfig
> >> @@ -614,6 +614,10 @@ config NEED_PER_CPU_EMBED_FIRST_CHUNK
> >> def_bool y
> >> depends on NUMA
> >>
> >> +config HOLES_IN_ZONE
> >> + def_bool y
> >> + depends on NUMA
> >> +
> >> source kernel/Kconfig.preempt
> >> source kernel/Kconfig.hz
> >
> > I'm happy to apply this, but I'll hold off until the first patch is queued
> > somewhere, since this doesn't help without the VM_BUG_ON being moved.
> >
> > Alternatively, I can queue both if somebody from the mm camp acks the
> > first patch.
> >
>
> Actually, I am not convinced the discussion is finalized. These
> patches do fix the issue, but Robert also suggested an alternative fix
> which may be preferable.
>
> http://marc.info/?l=linux-arm-kernel&m=148190753510107&w=2
>
> I haven't responded to it yet, due to the holidays, but I'd like to
> explore that solution a bit further before applying anything, if you
> don't mind.
Using early_pfn_valid feels like a bodge to me, since having pfn_valid
return false for something that early_pfn_valid says is valid (and is
therefore initialised in the memmap) makes the NOMAP semantics even more
confusing.
But there's no rush, so I'll hold off for the moment. I was under the
impression that things had stalled.
Will
^ permalink raw reply
* [RFC PATCH] usb: dwc3: gadget: add support for OTG in gadget framework
From: Felipe Balbi @ 2017-01-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483536181-22356-4-git-send-email-mnarani@xilinx.com>
Hi,
Manish Narani <manish.narani@xilinx.com> writes:
> This patch adds support for OTG in DWC3 gadget framework. This
> also adds support for HNP polling by host while in OTG mode.
>
> Modifications in couple of functions to make it in sync with
> OTG driver while keeping its original functionality intact.
>
> Signed-off-by: Manish Narani <mnarani@xilinx.com>
> ---
> drivers/usb/dwc3/ep0.c | 49 +++++++++++++++++++++++---
> drivers/usb/dwc3/gadget.c | 87 +++++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 116 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
> index 4878d18..aa78c1b 100644
> --- a/drivers/usb/dwc3/ep0.c
> +++ b/drivers/usb/dwc3/ep0.c
> @@ -334,6 +334,8 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
> usb_status |= 1 << USB_DEV_STAT_U2_ENABLED;
> }
>
> + usb_status |= dwc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP;
> +
> break;
>
> case USB_RECIP_INTERFACE:
> @@ -448,11 +450,45 @@ static int dwc3_ep0_handle_device(struct dwc3 *dwc,
>
> switch (wValue) {
> case USB_DEVICE_REMOTE_WAKEUP:
> + if (set)
> + dwc->remote_wakeup = 1;
> + else
> + dwc->remote_wakeup = 0;
> break;
> - /*
> - * 9.4.1 says only only for SS, in AddressState only for
> - * default control pipe
> - */
> + case USB_DEVICE_B_HNP_ENABLE:
> + dev_dbg(dwc->dev,
> + "SET_FEATURE: USB_DEVICE_B_HNP_ENABLE\n");
sorry, but no thanks. It has taken me a lot of work to come up with
proper tracers so I could get rid of all dev_dbg() calls here. I'm not
accepting any new one :-)
> + if (set && dwc->gadget.is_otg) {
> + if (dwc->gadget.host_request_flag) {
> + struct usb_phy *phy =
> + usb_get_phy(USB_PHY_TYPE_USB3);
> +
> + dwc->gadget.b_hnp_enable = 0;
> + dwc->gadget.host_request_flag = 0;
> + otg_start_hnp(phy->otg);
> + usb_put_phy(phy);
> + } else {
> + dwc->gadget.b_hnp_enable = 1;
> + }
> + } else
> + return -EINVAL;
> + break;
> +
> + case USB_DEVICE_A_HNP_SUPPORT:
> + /* RH port supports HNP */
> + dev_dbg(dwc->dev,
> + "SET_FEATURE: USB_DEVICE_A_HNP_SUPPORT\n");
ditto
> + break;
> +
> + case USB_DEVICE_A_ALT_HNP_SUPPORT:
> + /* other RH port does */
> + dev_dbg(dwc->dev,
> + "SET_FEATURE: USB_DEVICE_A_ALT_HNP_SUPPORT\n");
ditto
> + break;
> + /*
> + * 9.4.1 says only only for SS, in AddressState only for
> + * default control pipe
> + */
> case USB_DEVICE_U1_ENABLE:
> ret = dwc3_ep0_handle_u1(dwc, state, set);
> break;
> @@ -759,7 +795,10 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
>
> switch (ctrl->bRequest) {
> case USB_REQ_GET_STATUS:
> - ret = dwc3_ep0_handle_status(dwc, ctrl);
> + if (le16_to_cpu(ctrl->wIndex) == OTG_STS_SELECTOR)
> + ret = dwc3_ep0_delegate_req(dwc, ctrl);
> + else
> + ret = dwc3_ep0_handle_status(dwc, ctrl);
> break;
> case USB_REQ_CLEAR_FEATURE:
> ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 6785595..3b0b771 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -34,6 +34,7 @@
> #include "core.h"
> #include "gadget.h"
> #include "io.h"
> +#include "otg.h"
>
> /**
> * dwc3_gadget_set_test_mode - Enables USB2 Test Modes
> @@ -1792,25 +1793,51 @@ static int dwc3_gadget_start(struct usb_gadget *g,
> int ret = 0;
> int irq;
>
> - irq = dwc->irq_gadget;
> - ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
> - IRQF_SHARED, "dwc3", dwc->ev_buf);
> - if (ret) {
> - dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
> - irq, ret);
> - goto err0;
> - }
> -
> spin_lock_irqsave(&dwc->lock, flags);
> if (dwc->gadget_driver) {
> dev_err(dwc->dev, "%s is already bound to %s\n",
> dwc->gadget.name,
> dwc->gadget_driver->driver.name);
> ret = -EBUSY;
> - goto err1;
> + goto err0;
> }
>
> - dwc->gadget_driver = driver;
> + if (g->is_otg) {
> + static struct usb_gadget_driver *prev_driver;
hehe, there's no way I'm taking this. There are platforms with more than
one dwc3 instance. Please go back to drawing board.
> + /* There are two instances where OTG functionality is enabled :
> + * 1. This function will be called from OTG driver to start the
> + * gadget
> + * 2. This function will be called by the Linux Class Driver to
> + * start the gadget
> + * Below code will keep synchronization between these calls. The
> + * "driver" argument will be NULL when it is called from the OTG
> + * driver, so we are maintaning a global variable "prev_driver"
> + * to assign value of argument "driver" (from class driver) to
> + * dwc->gadget_driver when it is called from OTG.
> + */
> + if (driver) {
> + prev_driver = driver;
> + if (dwc->otg) {
> + struct dwc3_otg *otg = dwc->otg;
> +
> + if ((otg->host_started ||
> + (!otg->peripheral_started)))
> + goto err0;
> + }
> + dwc->gadget_driver = driver;
> + } else
> + dwc->gadget_driver = prev_driver;
> + } else
> + dwc->gadget_driver = driver;
> +
> + irq = dwc->irq_gadget;
> + ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
> + IRQF_SHARED, "dwc3", dwc->ev_buf);
> + if (ret) {
> + dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
> + irq, ret);
> + goto err0;
> + }
>
> if (pm_runtime_active(dwc->dev))
> __dwc3_gadget_start(dwc);
> @@ -1819,11 +1846,9 @@ static int dwc3_gadget_start(struct usb_gadget *g,
>
> return 0;
>
> -err1:
> - spin_unlock_irqrestore(&dwc->lock, flags);
> - free_irq(irq, dwc);
> -
> err0:
> + dwc->gadget_driver = NULL;
> + spin_unlock_irqrestore(&dwc->lock, flags);
> return ret;
> }
you shouldn't have to change anything in this file to add OTG. If you
are changing then it's likely something's wrong with your approach. I
need further clarification as to why you think this change is necessary.
> @@ -2977,6 +3002,18 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>
> dwc->irq_gadget = irq;
>
> + if (dwc->dr_mode == USB_DR_MODE_OTG) {
> + struct usb_phy *phy;
> + /* Switch otg to peripheral mode */
> + phy = usb_get_phy(USB_PHY_TYPE_USB3);
serioulsy? Did you not notice we already *HAVE* a handle to the PHY
which we get during probe?? You don't need to contantly get the PHY like this.
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 832 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170104/97549732/attachment-0001.sig>
^ permalink raw reply
* arm64: virt_to_page() does not return right page for a kernel image address
From: Pratyush Anand @ 2017-01-04 14:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu_CRKb2TCKf+cC_SYMOg8o=tcOj6oj2CpO2rUXciDMK1A@mail.gmail.com>
On Wednesday 04 January 2017 06:54 PM, Ard Biesheuvel wrote:
>> sg_init_one(&src, ctemplate[i].input, ilen);
>>
> This is the bug right here, and it is fixed already upstream. The
> crypto test vectors are part of the kernel image, and should not be
> used in scatterlists.
>
Thanks a lot Ard for bringing it. I see the following commit now in
4.10-rc2.
02608e02fbec crypto: testmgr - Use heap buffer for acomp test input
CONFIG_DEBUG_SG enabled kernel would have blown it right here.
~Pratyush
^ permalink raw reply
* [PATCH v2 3/3] ARM: dts: imx: Add ocotp node for imx6ul
From: Srinivas Kandagatla @ 2017-01-04 14:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161230022527.GH6177@dragon>
On 30/12/16 02:25, Shawn Guo wrote:
> On Thu, Nov 17, 2016 at 09:08:19AM +0800, Bai Ping wrote:
>> Add ocotp node for i.MX6UL SOC.
>>
>> Signed-off-by: Bai Ping <ping.bai@nxp.com>
>
> The DTS change looks good to me. But I cannot apply it until the driver
> and bindings part get accepted. You should figure out who is collecting
> nvmem patches. It seems to be Greg Kroah-Hartman, who is not on copy.
Sorry for delay in response,
I will take care of the 1/3 and 2/3 nvmem patches.
Thanks,
srini
>
> Shawn
>
>> ---
>> arch/arm/boot/dts/imx6ul.dtsi | 6 ++++++
>> 1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
>> index c5c05fd..c6f6613 100644
>> --- a/arch/arm/boot/dts/imx6ul.dtsi
>> +++ b/arch/arm/boot/dts/imx6ul.dtsi
>> @@ -849,6 +849,12 @@
>> reg = <0x021b0000 0x4000>;
>> };
>>
>> + ocotp: ocotp-ctrl at 021bc000 {
>> + compatible = "fsl,imx6ul-ocotp", "syscon";
>> + reg = <0x021bc000 0x4000>;
>> + clocks = <&clks IMX6UL_CLK_OCOTP>;
>> + };
>> +
>> lcdif: lcdif at 021c8000 {
>> compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
>> reg = <0x021c8000 0x4000>;
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 2/5] drivers: mmc: sunxi: limit A64 MMC2 to 8K DMA buffer
From: Rob Herring @ 2017-01-04 14:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483398226-29321-3-git-send-email-andre.przywara@arm.com>
On Mon, Jan 02, 2017 at 11:03:43PM +0000, Andre Przywara wrote:
> From: Maxime Ripard <maxime.ripard@free-electrons.com>
>
> Unlike the A64 user manual reports, the third MMC controller on the
> A64 (and the only one capable of 8-bit HS400 eMMC transfers) has a
> DMA buffer size limit of 8KB (much like the very old Allwinner SoCs).
> This does not affect the other two controllers, so introduce a new
> DT compatible string to let the driver use different settings for that
> particular device. This will also help to enable the high-speed transfer
> modes of that controller later.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
> Documentation/devicetree/bindings/mmc/sunxi-mmc.txt | 1 +
> drivers/mmc/host/sunxi-mmc.c | 7 +++++++
> 2 files changed, 8 insertions(+)
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH v5 13/17] irqdomain: irq_domain_check_msi_remap
From: Auger Eric @ 2017-01-04 14:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <ecb7ddf6-074f-50e4-6402-d59ceb1edd1d@arm.com>
Hi Marc,
On 04/01/2017 14:46, Marc Zyngier wrote:
> Hi Eric,
>
> On 04/01/17 13:32, Eric Auger wrote:
>> This new function checks whether all platform and PCI
>> MSI domains implement IRQ remapping. This is useful to
>> understand whether VFIO passthrough is safe with respect
>> to interrupts.
>>
>> On ARM typically an MSI controller can sit downstream
>> to the IOMMU without preventing VFIO passthrough.
>> As such any assigned device can write into the MSI doorbell.
>> In case the MSI controller implements IRQ remapping, assigned
>> devices will not be able to trigger interrupts towards the
>> host. On the contrary, the assignment must be emphasized as
>> unsafe with respect to interrupts.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>
>> ---
>>
>> v4 -> v5:
>> - Handle DOMAIN_BUS_FSL_MC_MSI domains
>> - Check parents
>> ---
>> include/linux/irqdomain.h | 1 +
>> kernel/irq/irqdomain.c | 41 +++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 42 insertions(+)
>>
>> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
>> index ab017b2..281a40f 100644
>> --- a/include/linux/irqdomain.h
>> +++ b/include/linux/irqdomain.h
>> @@ -219,6 +219,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
>> void *host_data);
>> extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
>> enum irq_domain_bus_token bus_token);
>> +extern bool irq_domain_check_msi_remap(void);
>> extern void irq_set_default_host(struct irq_domain *host);
>> extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
>> irq_hw_number_t hwirq, int node,
>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>> index 8c0a0ae..700caea 100644
>> --- a/kernel/irq/irqdomain.c
>> +++ b/kernel/irq/irqdomain.c
>> @@ -278,6 +278,47 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
>> EXPORT_SYMBOL_GPL(irq_find_matching_fwspec);
>>
>> /**
>> + * irq_domain_is_msi_remap - Check if @domain or any parent
>> + * has MSI remapping support
>> + * @domain: domain pointer
>> + */
>> +static bool irq_domain_is_msi_remap(struct irq_domain *domain)
>> +{
>> + struct irq_domain *h = domain;
>> +
>> + for (; h; h = h->parent) {
>> + if (h->flags & IRQ_DOMAIN_FLAG_MSI_REMAP)
>> + return true;
>> + }
>> + return false;
>> +}
>> +
>> +/**
>> + * irq_domain_check_msi_remap() - Checks whether all MSI
>> + * irq domains implement IRQ remapping
>> + */
>> +bool irq_domain_check_msi_remap(void)
>> +{
>> + struct irq_domain *h;
>> + bool ret = true;
>> +
>> + mutex_lock(&irq_domain_mutex);
>> + list_for_each_entry(h, &irq_domain_list, link) {
>> + if (((h->bus_token & DOMAIN_BUS_PCI_MSI) ||
>> + (h->bus_token & DOMAIN_BUS_PLATFORM_MSI) ||
>> + (h->bus_token & DOMAIN_BUS_FSL_MC_MSI)) &&
>> + !irq_domain_is_msi_remap(h)) {
>
> (h->bus_token & DOMAIN_BUS_PCI_MSI) and co looks quite wrong. bus_token
> is not a bitmap, and DOMAIN_BUS_* not a single bit value (see enum
> irq_domain_bus_token). Surely this should read
> (h->bus_token == DOMAIN_BUS_PCI_MSI).
Oh I did not notice that. Thanks.
Any other comments on the irqdomain side? Do you think the current
approach consisting in looking at those bus tokens and their parents
looks good?
Thanks
Eric
>
> Thanks,
>
> M.
>
^ permalink raw reply
* [PATCH 1/3] nvmem: imx-ocotp: Add support for i.MX6UL
From: Srinivas Kandagatla @ 2017-01-04 14:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480689949-17957-1-git-send-email-d.schultz@phytec.de>
On 02/12/16 14:45, Daniel Schultz wrote:
> This patch adds OCOTP support for the i.MX6UL SoC.
>
> Signed-off-by: Daniel Schultz <d.schultz@phytec.de>
As Shawn said, there is already a similar patch in the mailing list
http://www.spinics.net/lists/arm-kernel/msg543203.html
http://www.spinics.net/lists/arm-kernel/msg543204.html
I will pick that patch + I will queue up fix from you "[PATCH 3/3]
nvmem: imx-ocotp: Fix wrong register size"
thanks,
srini
> ---
> Documentation/devicetree/bindings/nvmem/imx-ocotp.txt | 5 +++--
> drivers/nvmem/imx-ocotp.c | 1 +
> 2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
> index 383d588..fcb1a48 100644
> --- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
> +++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
> @@ -1,13 +1,14 @@
> Freescale i.MX6 On-Chip OTP Controller (OCOTP) device tree bindings
>
> This binding represents the on-chip eFuse OTP controller found on
> -i.MX6Q/D, i.MX6DL/S, i.MX6SL, and i.MX6SX SoCs.
> +i.MX6Q/D, i.MX6DL/S, i.MX6SL, i.MX6SX and i.MX6UL SoCs.
>
> Required properties:
> - compatible: should be one of
> "fsl,imx6q-ocotp" (i.MX6Q/D/DL/S),
> "fsl,imx6sl-ocotp" (i.MX6SL), or
> - "fsl,imx6sx-ocotp" (i.MX6SX), followed by "syscon".
> + "fsl,imx6sx-ocotp" (i.MX6SX), or
> + "fsl,imx6ul-ocotp" (i.MX6UL), followed by "syscon".
> - reg: Should contain the register base and length.
> - clocks: Should contain a phandle pointing to the gated peripheral clock.
>
> diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
> index ac27b9b..d2f78d3 100644
> --- a/drivers/nvmem/imx-ocotp.c
> +++ b/drivers/nvmem/imx-ocotp.c
> @@ -71,6 +71,7 @@ static int imx_ocotp_read(void *context, unsigned int offset,
>
> static const struct of_device_id imx_ocotp_dt_ids[] = {
> { .compatible = "fsl,imx6q-ocotp", (void *)128 },
> + { .compatible = "fsl,imx6ul-ocotp", (void *)128 },
> { .compatible = "fsl,imx6sl-ocotp", (void *)32 },
> { .compatible = "fsl,imx6sx-ocotp", (void *)128 },
> { },
>
^ permalink raw reply
* [PATCH 1/4] input: Add support for the tm2 touchkey device driver
From: Rob Herring @ 2017-01-04 14:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483430237-26823-2-git-send-email-jcsing.lee@samsung.com>
On Tue, Jan 03, 2017 at 04:57:14PM +0900, Jaechul Lee wrote:
> This patch adds the binding description of the tm2 touchkey
> device driver.
>
> Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
> ---
> .../bindings/input/samsung,tm2-touchkey.txt | 27 ++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH v3 1/2] Doc: devicetree: bindings: Add vendor prefix entry - lwn
From: Rob Herring @ 2017-01-04 14:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483440381-24268-1-git-send-email-lukma@denx.de>
On Tue, Jan 03, 2017 at 11:46:20AM +0100, Lukasz Majewski wrote:
> This patch adds entry for LWN - the Liebherr-Werk Nenzing GmbH company to
> vendor-prefixes.txt file.
>
> Signed-off-by: Lukasz Majewski <lukma@denx.de>
> ---
> Changes for v3:
> - Update to v4.10-rc2
>
> Changes for v2:
> - New patch
> ---
> Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
> 1 file changed, 1 insertion(+)
I guess LWN.net will never make any devices...
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [RFC, PATCHv2 29/29] mm, x86: introduce RLIMIT_VADDR
From: Kirill A. Shutemov @ 2017-01-04 14:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CALCETrW3=SsQeC-gWOVqwTtg022+gHei=xfUc2ei3kkX0CACpg@mail.gmail.com>
On Tue, Jan 03, 2017 at 10:27:22AM -0800, Andy Lutomirski wrote:
> On Tue, Jan 3, 2017 at 8:04 AM, Kirill A. Shutemov <kirill@shutemov.name> wrote:
> > And what about stack? I'm not sure that everybody would be happy with
> > stack in the middle of address space.
>
> I would, personally. I think that, for very large address spaces, we
> should allocate a large block of stack and get rid of the "stack grows
> down forever" legacy idea. Then we would never need to worry about
> the stack eventually hitting some other allocation. And 2^57 bytes is
> hilariously large for a default stack.
The stack in the middle of address space can prevent creating other huuuge
contiguous mapping. Databases may want this.
--
Kirill A. Shutemov
^ permalink raw reply
* [PATCH 1/2] ARM: dts: sun7i: Add wifi dt node on Banana Pro
From: Jörg Krause @ 2017-01-04 14:22 UTC (permalink / raw)
To: linux-arm-kernel
The Banana Pro has an AMPAK AP6181 WiFi+Bluetooth module. The WiFi part
is a BCM43362 IC connected to MMC3 of the A20 SoC via SDIO. The IC also
takes a power enable signal via GPIO.
This commit adds a device-tree node to power it up, so the mmc subsys
can scan it, and enables the mmc controller which is connected to it.
As the wifi enable pin of the AP6181 module is not really a regulator,
switch the mmc3 node to the mmc-pwrseq framework for controlling it.
This more accurately reflectes how the hardware actually works.
Signed-off-by: J?rg Krause <joerg.krause@embedded.rocks>
---
arch/arm/boot/dts/sun7i-a20-bananapro.dts | 35 ++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapro.dts b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
index 19d63d4049de..439ad50dcd4a 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
@@ -76,6 +76,13 @@
};
};
+ mmc3_pwrseq: mmc3_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vmmc3_pin_bananapro>;
+ reset-gpios = <&pio 7 22 GPIO_ACTIVE_LOW>;
+ };
+
reg_gmac_3v3: gmac-3v3 {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -87,17 +94,6 @@
enable-active-high;
gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>;
};
-
- reg_vmmc3: vmmc3 {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&vmmc3_pin_bananapro>;
- regulator-name = "vmmc3";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- enable-active-high;
- gpio = <&pio 7 22 GPIO_ACTIVE_HIGH>;
- };
};
&ahci {
@@ -166,10 +162,25 @@
&mmc3 {
pinctrl-names = "default";
pinctrl-0 = <&mmc3_pins_a>;
- vmmc-supply = <®_vmmc3>;
+ vmmc-supply = <®_vcc3v3>;
+ mmc-pwrseq = <&mmc3_pwrseq>;
bus-width = <4>;
non-removable;
+ wakeup-source;
status = "okay";
+
+ brcmf: bcrmf at 1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ interrupt-parent = <&pio>;
+ interrupts = <7 15 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "host-wake";
+ };
+};
+
+&mmc3_pins_a {
+ /* AP6181 requires pull-up */
+ allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
&ohci0 {
--
2.11.0
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: sun7i: Enable audio codec on Banana Pro
From: Jörg Krause @ 2017-01-04 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170104142250.22171-1-joerg.krause@embedded.rocks>
This commit enables the on-chip audio codec present on the A20 SoC
on the Banana Pro board.
Signed-off-by: J?rg Krause <joerg.krause@embedded.rocks>
---
arch/arm/boot/dts/sun7i-a20-bananapro.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapro.dts b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
index 439ad50dcd4a..797de4c352a5 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapro.dts
@@ -100,6 +100,10 @@
status = "okay";
};
+&codec {
+ status = "okay";
+};
+
&ehci0 {
status = "okay";
};
--
2.11.0
^ permalink raw reply related
* [PATCH v2 12/19] media: imx: Add SMFC subdev driver
From: Vladimir Zapolskiy @ 2017-01-04 14:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483477049-19056-13-git-send-email-steve_longerbeam@mentor.com>
On 01/03/2017 10:57 PM, Steve Longerbeam wrote:
> This is a media entity subdevice driver for the i.MX Sensor Multi-FIFO
> Controller module. Video frames are received from the CSI and can
> be routed to various sinks including the i.MX Image Converter for
> scaling, color-space conversion, motion compensated deinterlacing,
> and image rotation.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
> ---
> drivers/staging/media/imx/Makefile | 1 +
> drivers/staging/media/imx/imx-smfc.c | 739 +++++++++++++++++++++++++++++++++++
> 2 files changed, 740 insertions(+)
> create mode 100644 drivers/staging/media/imx/imx-smfc.c
>
> diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile
> index 133672a..3559d7b 100644
> --- a/drivers/staging/media/imx/Makefile
> +++ b/drivers/staging/media/imx/Makefile
> @@ -5,4 +5,5 @@ obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media.o
> obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-common.o
>
> obj-$(CONFIG_VIDEO_IMX_CAMERA) += imx-csi.o
> +obj-$(CONFIG_VIDEO_IMX_CAMERA) += imx-smfc.o
May be
obj-$(CONFIG_VIDEO_IMX_CAMERA) += imx-csi.o imx-smfc.o
>
> diff --git a/drivers/staging/media/imx/imx-smfc.c b/drivers/staging/media/imx/imx-smfc.c
> new file mode 100644
> index 0000000..565048c
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-smfc.c
> @@ -0,0 +1,739 @@
> +/*
> + * V4L2 Capture SMFC Subdev for Freescale i.MX5/6 SOC
> + *
> + * This subdevice handles capture of raw/unconverted video frames
> + * from the CSI, directly to memory via the Sensor Multi-FIFO Controller.
> + *
> + * Copyright (c) 2012-2016 Mentor Graphics Inc.
> + *
> + * 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; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/fs.h>
> +#include <linux/timer.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/interrupt.h>
> +#include <linux/spinlock.h>
> +#include <linux/platform_device.h>
> +#include <linux/pinctrl/consumer.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/v4l2-of.h>
> +#include <media/v4l2-ctrls.h>
Please sort the list of headers alphabetically.
> +#include <media/imx.h>
> +#include "imx-media.h"
> +
[snip]
> +static irqreturn_t imx_smfc_eof_interrupt(int irq, void *dev_id)
> +{
> + struct imx_smfc_priv *priv = dev_id;
> + struct imx_media_dma_buf *done, *next;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&priv->irqlock, flags);
spin_lock(&priv->irqlock) should be sufficient.
> +
> + if (priv->last_eof) {
> + complete(&priv->last_eof_comp);
> + priv->last_eof = false;
> + goto unlock;
> + }
> +
> + /* inform CSI of this EOF so it can monitor frame intervals */
> + v4l2_subdev_call(priv->src_sd, core, interrupt_service_routine,
> + 0, NULL);
> +
> + done = imx_media_dma_buf_get_active(priv->out_ring);
> + /* give the completed buffer to the sink */
> + if (!WARN_ON(!done))
> + imx_media_dma_buf_done(done, IMX_MEDIA_BUF_STATUS_DONE);
> +
> + /* priv->next buffer is now the active one */
> + imx_media_dma_buf_set_active(priv->next);
> +
> + /* bump the EOF timeout timer */
> + mod_timer(&priv->eof_timeout_timer,
> + jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
> +
> + if (ipu_idmac_buffer_is_ready(priv->smfc_ch, priv->ipu_buf_num))
> + ipu_idmac_clear_buffer(priv->smfc_ch, priv->ipu_buf_num);
> +
> + /* get next queued buffer */
> + next = imx_media_dma_buf_get_next_queued(priv->out_ring);
> +
> + ipu_cpmem_set_buffer(priv->smfc_ch, priv->ipu_buf_num, next->phys);
> + ipu_idmac_select_buffer(priv->smfc_ch, priv->ipu_buf_num);
> +
> + /* toggle IPU double-buffer index */
> + priv->ipu_buf_num ^= 1;
> + priv->next = next;
> +
> +unlock:
> + spin_unlock_irqrestore(&priv->irqlock, flags);
> + return IRQ_HANDLED;
> +}
> +
[snip]
> +
> +static const struct platform_device_id imx_smfc_ids[] = {
> + { .name = "imx-ipuv3-smfc" },
> + { },
> +};
> +MODULE_DEVICE_TABLE(platform, imx_smfc_ids);
> +
> +static struct platform_driver imx_smfc_driver = {
> + .probe = imx_smfc_probe,
> + .remove = imx_smfc_remove,
> + .id_table = imx_smfc_ids,
> + .driver = {
> + .name = "imx-ipuv3-smfc",
> + .owner = THIS_MODULE,
You can drop owner assignment.
> + },
> +};
> +module_platform_driver(imx_smfc_driver);
> +
> +MODULE_DESCRIPTION("i.MX SMFC subdev driver");
> +MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:imx-ipuv3-smfc");
>
--
With best wishes,
Vladimir
^ permalink raw reply
* [PATCH 1/2] arm64: dma_mapping: allow PCI host driver to limit DMA mask
From: Nikita Yushchenko @ 2017-01-04 14:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2104402.puPT8SttTe@wuerfel>
>> For OF platforms, this is called via of_dma_configure(), that checks
>> dma-ranges of node that is *parent* for host bridge. Host bridge
>> currently does not control this at all.
>
> We need to think about this a bit. Is it actually the PCI host
> bridge that limits the ranges here, or the bus that it is connected
> to. In the latter case, the caller needs to be adapted to handle
> both.
In r-car case, I'm not sure what is the source of limitation at physical
level.
pcie-rcar driver configures ranges for PCIe inbound transactions based
on dma-ranges property in it's device tree node. In the current device
tree for this platform, that only contains one range and it is in lower
memory.
NVMe driver tries i/o to kmalloc()ed area. That returns 0x5xxxxxxxx
addresses here. As a quick experiment, I tried to add second range to
pcie-rcar's dma-ranges to cover 0x5xxxxxxxx area - but that did not make
DMA to high addresses working.
My current understanding is that host bridge hardware module can't
handle inbound transactions to PCI addresses above 4G - and this
limitations comes from host bridge itself.
I've read somewhere in the lists that pcie-rcar hardware is "32-bit" -
but I don't remember where, and don't know lowlevel details. Maybe
somebody from linux-renesas can elaborate?
>> In current device trees no dma-ranges is defined for nodes that are
>> parents to pci host bridges. This will make of_dma_configure() to fall
>> back to 32-bit size for all devices on all current platforms. Thus
>> applying this patch will immediately break 64-bit dma masks on all
>> hardware that supports it.
>
> No, it won't break it, it will just fall back to swiotlb for all the
> ones that are lacking the dma-ranges property. I think this is correct
> behavior.
I'd say - for all ones that have parents without dma-ranges property.
As of 4.10-rc2, I see only two definitions of wide parent dma-ranges
under arch/arm64/boot/dts/ - in amd/amd-seattle-soc.dtsi and
apm/apm-storm.dtsi
Are these the only arm64 platforms that can to DMA to high addresses?
I'm not arm64 expert but I'd be surprised if that's the case.
>> Also related: dma-ranges property used by several pci host bridges is
>> *not* compatible with "legacy" dma-ranges parsed by of_get_dma_range() -
>> former uses additional flags word at beginning.
>
> Can you elaborate? Do we have PCI host bridges that use wrongly formatted
> dma-ranges properties?
of_dma_get_range() expects <dma_addr cpu_addr size> format.
pcie-rcar.c, pci-rcar-gen2.c, pci-xgene.c and pcie-iproc.c from
drivers/pci/host/ all parse dma-ranges using of_pci_range_parser that
uses <flags pci-addr cpu-addr size> format - i.e. something different
from what of_dma_get_range() uses.
Nikita
^ permalink raw reply
* [PATCH 15/20] ARM/hw_breakpoint: Convert to hotplug state machine
From: Will Deacon @ 2017-01-04 14:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170104135644.GA29212@leverpostej>
On Wed, Jan 04, 2017 at 01:56:44PM +0000, Mark Rutland wrote:
> On Tue, Jan 03, 2017 at 09:33:36AM +0000, Mark Rutland wrote:
> > On Mon, Jan 02, 2017 at 09:15:29PM +0100, Linus Walleij wrote:
> > > On Mon, Jan 2, 2017 at 4:00 PM, Russell King - ARM Linux
> > > <linux@armlinux.org.uk> wrote:
> > > > On Mon, Jan 02, 2017 at 03:34:32PM +0100, Linus Walleij wrote:
> > > >> in the first line of arch_hw_breakpoint_init() in
> > > >> arch/arm/kernel/hw_breakpoint.c
> > > >>
> > > >> I suspect that is not an accepable solution ...
> > > >>
> > > >> It hangs at PC is at write_wb_reg+0x20c/0x330
> > > >> Which is c03101dc, and looks like this in objdump -d:
> > > >>
> > > >> c031020c: ee001eba mcr 14, 0, r1, cr0, cr10, {5}
> > > >> c0310210: eaffffb3 b c03100e4 <write_wb_reg+0x114>
> > > >
> > > > ... and this is several instructions after the address you mention above.
> > > > Presumably c03101dc is accessing a higher numbered register?
> > >
> > > Ah sorry. It looks like this:
> > >
> > > c03101dc: ee001ed0 mcr 14, 0, r1, cr0, cr0, {6}
> > > c03101e0: eaffffbf b c03100e4 <write_wb_reg+0x114>
> > > c03101e4: ee001ebf mcr 14, 0, r1, cr0, cr15, {5}
> > > c03101e8: eaffffbd b c03100e4 <write_wb_reg+0x114>
> > > c03101ec: ee001ebe mcr 14, 0, r1, cr0, cr14, {5}
> > > c03101f0: eaffffbb b c03100e4 <write_wb_reg+0x114>
> > > c03101f4: ee001ebd mcr 14, 0, r1, cr0, cr13, {5}
> > > c03101f8: eaffffb9 b c03100e4 <write_wb_reg+0x114>
> >
> > FWIW, I was tracking an issue in this area before the holiday.
> >
> > It looked like DBGPRSR.SPD is set unexpectedly over the default idle
> > path (i.e. WFI), causing the (otherwise valid) register accesses above
> > to be handled as undefined.
> >
> > I haven't looked at the patch in detail, but I guess that it allows idle
> > to occur between reset_ctrl_regs() and arch_hw_breakpoint_init().
>
> I've just reproduced this locally on my dragonboard APQ8060.
>
> It looks like the write_wb_reg() call that's exploding is from
> get_max_wp_len(), which we call immediately after registering the
> dbg_reset_online callback. Clearing DBGPRSR.SPD before the write_wb_reg() hides
> the problem, so I suspect we're seeing the issue I mentioned above -- it just
> so happens that we go idle in a new place.
When you say "go idle", are we just executing a WFI, or is the power
controller coming into play and we're actually powering down the non-debug
logic? In the case of the latter, the PM notifier should clear SPD in
reset_ctrl_regs, so this sounds like a hardware bug where the SPD bit is
set unconditionally on WFI.
In that case, this code has always been dodgy -- what happens if you try
to use hardware breakpoints in GDB in the face of WFI-based idle?
> The below hack allows boot to continue, but is not a real fix. I'm not
> immediately sure what to do.
If it's never worked, I suggest we blacklist the MIDR until somebody from
Qualcomm can help us further.
Will
^ permalink raw reply
* [PATCH v6 03/14] ACPI: ARM64: IORT: add missing comment for iort_dev_find_its_id()
From: Lorenzo Pieralisi @ 2017-01-04 14:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483363905-2806-4-git-send-email-hanjun.guo@linaro.org>
On Mon, Jan 02, 2017 at 09:31:34PM +0800, Hanjun Guo wrote:
> We are missing req_id's comment for iort_dev_find_its_id(),
> add it back.
"Add missing req_id parameter to the iort_dev_find_its_id() function
kernel-doc comment."
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Tested-by: Majun <majun258@huawei.com>
> Tested-by: Xinwei Kong <kong.kongxinwei@hisilicon.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Tomasz Nowicki <tn@semihalf.com>
> ---
> drivers/acpi/arm64/iort.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 46e2d82..174e983 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -446,6 +446,7 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
> /**
> * iort_dev_find_its_id() - Find the ITS identifier for a device
> * @dev: The device.
> + * @req_id: Device's Requster ID
s/Requster/Requester
We can send it upstream independently along with some other patches
in this series but I will have a look at the whole series first.
Lorenzo
> * @idx: Index of the ITS identifier list.
> * @its_id: ITS identifier.
> *
> --
> 1.9.1
>
^ permalink raw reply
* [PATCH v3 2/2] dt-bindings: Add DT bindings info for FlexRM ring manager
From: Rob Herring @ 2017-01-04 14:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483508082-7008-3-git-send-email-anup.patel@broadcom.com>
On Wed, Jan 04, 2017 at 11:04:42AM +0530, Anup Patel wrote:
> This patch adds device tree bindings document for the FlexRM
> ring manager found on Broadcom iProc SoCs.
>
> Reviewed-by: Ray Jui <ray.jui@broadcom.com>
> Reviewed-by: Scott Branden <scott.branden@broadcom.com>
> Signed-off-by: Anup Patel <anup.patel@broadcom.com>
> ---
> .../bindings/mailbox/brcm,iproc-flexrm-mbox.txt | 60 ++++++++++++++++++++++
> 1 file changed, 60 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mailbox/brcm,iproc-flexrm-mbox.txt
>
> diff --git a/Documentation/devicetree/bindings/mailbox/brcm,iproc-flexrm-mbox.txt b/Documentation/devicetree/bindings/mailbox/brcm,iproc-flexrm-mbox.txt
> new file mode 100644
> index 0000000..ca51a39
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/brcm,iproc-flexrm-mbox.txt
> @@ -0,0 +1,60 @@
> +Broadcom FlexRM Ring Manager
> +============================
> +The Broadcom FlexRM ring manager provides a set of rings which can be
> +used to submit work to offload engines. An SoC may have multiple FlexRM
> +hardware blocks. There is one device tree entry per FlexRM block. The
> +FlexRM driver will create a mailbox-controller instance for given FlexRM
> +hardware block where each mailbox channel is a separate FlexRM ring.
> +
> +Required properties:
> +--------------------
> +- compatible: Should be "brcm,iproc-flexrm-mbox"
> +- reg: Specifies base physical address and size of the FlexRM
> + ring registers
> +- msi-parent: Phandles (and potential Device IDs) to MSI controllers
> + The FlexRM engine will send MSIs (instead of wired
> + interrupts) to CPU. There is one MSI for each FlexRM ring.
> + Refer devicetree/bindings/interrupt-controller/msi.txt
> +- #mbox-cells: Specifies the number of cells needed to encode a mailbox
> + channel. This should be 3.
> +
> + The 1st cell is the mailbox channel number.
> +
> + The 2nd cell contains MSI completion threshold. This is the
> + number of completion messages for which FlexRM will inject
> + one MSI interrupt to CPU.
> +
> + The 3nd cell contains MSI timer value representing time for
> + which FlexRM will wait to accumulate N completion messages
> + where N is the value specified by 2nd cell above. If FlexRM
> + does not get required number of completion messages in time
> + specified by this cell then it will inject one MSI interrupt
> + to CPU provided atleast one completion message is available.
> +
> +Optional properties:
> +--------------------
> +- dma-coherent: Present if DMA operations made by the FlexRM engine (such
> + as DMA descriptor access, access to buffers pointed by DMA
> + descriptors and read/write pointer updates to DDR) are
> + cache coherent with the CPU.
> +
> +Example:
> +--------
> +crypto_mbox: mbox at 67000000 {
> + compatible = "brcm,iproc-flexrm-mbox";
> + reg = <0x67000000 0x200000>;
> + msi-parent = <&gic_its 0x7f00>;
> + #mbox-cells = <3>;
> +};
> +
> +crypto_client {
crypto@<addr>
> + ...
> + mboxes = <&crypto_mbox 0 0x1 0xffff>,
> + <&crypto_mbox 1 0x1 0xffff>,
> + <&crypto_mbox 16 0x1 0xffff>,
> + <&crypto_mbox 17 0x1 0xffff>,
> + <&crypto_mbox 30 0x1 0xffff>,
> + <&crypto_mbox 31 0x1 0xffff>;
> + };
> + ...
Please somewhat fully list the contents for node.
Rob
^ permalink raw reply
* [PATCH resend v4 2/3] ARM: dts: imx6: Support Savageboard dual
From: Rob Herring @ 2017-01-04 14:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170104070436.3425-1-woogyom.kim@gmail.com>
On Wed, Jan 04, 2017 at 04:04:36PM +0900, Milo Kim wrote:
> Common savageboard DT file is used for board support.
> Add the vendor name and specify the dtb file for i.MX6Q build.
>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> Signed-off-by: Milo Kim <woogyom.kim@gmail.com>
> ---
> .../devicetree/bindings/vendor-prefixes.txt | 1 +
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/imx6dl-savageboard.dts | 51 ++++++++++++++++++++++
> 3 files changed, 53 insertions(+)
> create mode 100644 arch/arm/boot/dts/imx6dl-savageboard.dts
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH 1/2] arm64: dma_mapping: allow PCI host driver to limit DMA mask
From: Arnd Bergmann @ 2017-01-04 14:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <412396ac-4535-08a3-e4c7-dd8d0078a518@cogentembedded.com>
On Wednesday, January 4, 2017 5:30:19 PM CET Nikita Yushchenko wrote:
> >> For OF platforms, this is called via of_dma_configure(), that checks
> >> dma-ranges of node that is *parent* for host bridge. Host bridge
> >> currently does not control this at all.
> >
> > We need to think about this a bit. Is it actually the PCI host
> > bridge that limits the ranges here, or the bus that it is connected
> > to. In the latter case, the caller needs to be adapted to handle
> > both.
>
> In r-car case, I'm not sure what is the source of limitation at physical
> level.
>
> pcie-rcar driver configures ranges for PCIe inbound transactions based
> on dma-ranges property in it's device tree node. In the current device
> tree for this platform, that only contains one range and it is in lower
> memory.
>
> NVMe driver tries i/o to kmalloc()ed area. That returns 0x5xxxxxxxx
> addresses here. As a quick experiment, I tried to add second range to
> pcie-rcar's dma-ranges to cover 0x5xxxxxxxx area - but that did not make
> DMA to high addresses working.
>
> My current understanding is that host bridge hardware module can't
> handle inbound transactions to PCI addresses above 4G - and this
> limitations comes from host bridge itself.
>
> I've read somewhere in the lists that pcie-rcar hardware is "32-bit" -
> but I don't remember where, and don't know lowlevel details. Maybe
> somebody from linux-renesas can elaborate?
Just a guess, but if the inbound translation windows in the host
bridge are wider than 32-bit, the reason for setting up a single
32-bit window is probably because that is what the parent bus supports.
> >> In current device trees no dma-ranges is defined for nodes that are
> >> parents to pci host bridges. This will make of_dma_configure() to fall
> >> back to 32-bit size for all devices on all current platforms. Thus
> >> applying this patch will immediately break 64-bit dma masks on all
> >> hardware that supports it.
> >
> > No, it won't break it, it will just fall back to swiotlb for all the
> > ones that are lacking the dma-ranges property. I think this is correct
> > behavior.
>
> I'd say - for all ones that have parents without dma-ranges property.
>
> As of 4.10-rc2, I see only two definitions of wide parent dma-ranges
> under arch/arm64/boot/dts/ - in amd/amd-seattle-soc.dtsi and
> apm/apm-storm.dtsi
>
> Are these the only arm64 platforms that can to DMA to high addresses?
> I'm not arm64 expert but I'd be surprised if that's the case.
It's likely that a few others also do high DMA, but a lot of arm64
chips are actually derived from earlier 32-bit chips and don't
even support any RAM above 4GB, as well as having a lot of 32-bit
DMA masters.
> >> Also related: dma-ranges property used by several pci host bridges is
> >> *not* compatible with "legacy" dma-ranges parsed by of_get_dma_range() -
> >> former uses additional flags word at beginning.
> >
> > Can you elaborate? Do we have PCI host bridges that use wrongly formatted
> > dma-ranges properties?
>
> of_dma_get_range() expects <dma_addr cpu_addr size> format.
>
> pcie-rcar.c, pci-rcar-gen2.c, pci-xgene.c and pcie-iproc.c from
> drivers/pci/host/ all parse dma-ranges using of_pci_range_parser that
> uses <flags pci-addr cpu-addr size> format - i.e. something different
> from what of_dma_get_range() uses.
The "dma_addr" here is expressed in terms of #address-cells of the
bus it is in, and that is "3" in case of PCI, where the first 32-bit
word is a bit pattern containing various things, and the other two
cells are a 64-bit address. I think this is correct, but we may
need to add some special handling for parsing PCI host bridges
in of_dma_get_range, to ensure we actually look at translations for
the memory space.
Arnd
^ permalink raw reply
* [PATCH v2 13/19] media: imx: Add IC subdev drivers
From: Vladimir Zapolskiy @ 2017-01-04 14:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483477049-19056-14-git-send-email-steve_longerbeam@mentor.com>
On 01/03/2017 10:57 PM, Steve Longerbeam wrote:
> This is a set of three media entity subdevice drivers for the i.MX
> Image Converter. The i.MX IC module contains three independent
> "tasks":
>
> - Pre-processing Encode task: video frames are routed directly from
> the CSI and can be scaled, color-space converted, and rotated.
> Scaled output is limited to 1024x1024 resolution. Output frames
> are routed to the camera interface entities (camif).
>
> - Pre-processing Viewfinder task: this task can perform the same
> conversions as the pre-process encode task, but in addition can
> be used for hardware motion compensated deinterlacing. Frames can
> come either directly from the CSI or from the SMFC entities (memory
> buffers via IDMAC channels). Scaled output is limited to 1024x1024
> resolution. Output frames can be routed to various sinks including
> the post-processing task entities.
>
> - Post-processing task: same conversions as pre-process encode. However
> this entity sends frames to the i.MX IPU image converter which supports
> image tiling, which allows scaled output up to 4096x4096 resolution.
> Output frames can be routed to the camera interfaces.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
> ---
[snip]
> +static int imx_ic_probe(struct platform_device *pdev)
> +{
> + struct imx_media_internal_sd_platformdata *pdata;
> + struct imx_ic_priv *priv;
> + int ret;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, &priv->sd);
> + priv->dev = &pdev->dev;
> +
> + /* get our ipu_id, grp_id and IC task id */
> + pdata = priv->dev->platform_data;
> + priv->ipu_id = pdata->ipu_id;
> + switch (pdata->grp_id) {
> + case IMX_MEDIA_GRP_ID_IC_PRPENC:
> + priv->task_id = IC_TASK_ENCODER;
> + break;
> + case IMX_MEDIA_GRP_ID_IC_PRPVF:
> + priv->task_id = IC_TASK_VIEWFINDER;
> + break;
> + case IMX_MEDIA_GRP_ID_IC_PP0...IMX_MEDIA_GRP_ID_IC_PP3:
> + priv->task_id = IC_TASK_POST_PROCESSOR;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + v4l2_subdev_init(&priv->sd, ic_ops[priv->task_id]->subdev_ops);
> + v4l2_set_subdevdata(&priv->sd, priv);
> + priv->sd.internal_ops = ic_ops[priv->task_id]->internal_ops;
> + priv->sd.entity.ops = ic_ops[priv->task_id]->entity_ops;
> + priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
> + priv->sd.dev = &pdev->dev;
> + priv->sd.owner = THIS_MODULE;
> + priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
> + priv->sd.grp_id = pdata->grp_id;
> + strncpy(priv->sd.name, pdata->sd_name, sizeof(priv->sd.name));
> +
> + ret = ic_ops[priv->task_id]->init(priv);
> + if (ret)
> + return ret;
> +
> + ret = v4l2_async_register_subdev(&priv->sd);
> + if (ret)
> + goto remove;
> +
> + return 0;
> +remove:
> + ic_ops[priv->task_id]->remove(priv);
> + return ret;
if (ret)
ic_ops[priv->task_id]->remove(priv);
return ret;
as an alternative.
[snip]
> +static const struct platform_device_id imx_ic_ids[] = {
> + { .name = "imx-ipuv3-ic" },
> + { },
> +};
> +MODULE_DEVICE_TABLE(platform, imx_ic_ids);
> +
> +static struct platform_driver imx_ic_driver = {
> + .probe = imx_ic_probe,
> + .remove = imx_ic_remove,
> + .id_table = imx_ic_ids,
> + .driver = {
> + .name = "imx-ipuv3-ic",
> + .owner = THIS_MODULE,
Please drop .owner assignment.
> + },
> +};
> +module_platform_driver(imx_ic_driver);
> +
> +MODULE_DESCRIPTION("i.MX IC subdev driver");
> +MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:imx-ipuv3-ic");
> diff --git a/drivers/staging/media/imx/imx-ic-pp.c b/drivers/staging/media/imx/imx-ic-pp.c
> new file mode 100644
> index 0000000..5ef0581
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-ic-pp.c
> @@ -0,0 +1,636 @@
> +/*
> + * V4L2 IC Post-Processor Subdev for Freescale i.MX5/6 SOC
> + *
> + * Copyright (c) 2014-2016 Mentor Graphics Inc.
> + *
> + * 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; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/fs.h>
> +#include <linux/timer.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/interrupt.h>
> +#include <linux/platform_device.h>
> +#include <linux/pinctrl/consumer.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/v4l2-of.h>
> +#include <media/v4l2-ctrls.h>
Please sort the list of headers alphabetically.
> +#include <media/imx.h>
> +#include <video/imx-ipu-image-convert.h>
> +#include "imx-media.h"
> +#include "imx-ic.h"
> +
[snip]
> +
> +static int pp_start(struct pp_priv *priv)
> +{
> + struct imx_ic_priv *ic_priv = priv->ic_priv;
> + struct ipu_image image_in, image_out;
> + const struct imx_media_pixfmt *incc;
> + struct v4l2_mbus_framefmt *infmt;
> + int i, in_size, ret;
> +
> + /* ask the sink for the buffer ring */
> + ret = v4l2_subdev_call(priv->sink_sd, core, ioctl,
> + IMX_MEDIA_REQ_DMA_BUF_SINK_RING,
> + &priv->out_ring);
> + if (ret)
> + return ret;
> +
> + imx_media_mbus_fmt_to_ipu_image(&image_in,
> + &priv->format_mbus[priv->input_pad]);
> + imx_media_mbus_fmt_to_ipu_image(&image_out,
> + &priv->format_mbus[priv->output_pad]);
> +
> + priv->ipu = priv->md->ipu[ic_priv->ipu_id];
> + priv->ic_ctx = ipu_image_convert_prepare(priv->ipu,
> + IC_TASK_POST_PROCESSOR,
> + &image_in, &image_out,
> + priv->rot_mode,
> + pp_convert_complete, priv);
> + if (IS_ERR(priv->ic_ctx))
> + return PTR_ERR(priv->ic_ctx);
> +
> + infmt = &priv->format_mbus[priv->input_pad];
> + incc = priv->cc[priv->input_pad];
> + in_size = (infmt->width * incc->bpp * infmt->height) >> 3;
> +
> + if (priv->in_ring) {
> + v4l2_warn(&ic_priv->sd, "%s: dma-buf ring was not freed\n",
> + __func__);
> + imx_media_free_dma_buf_ring(priv->in_ring);
> + }
> +
> + priv->in_ring = imx_media_alloc_dma_buf_ring(priv->md,
> + &priv->src_sd->entity,
> + &ic_priv->sd.entity,
> + in_size,
> + IMX_MEDIA_MIN_RING_BUFS,
> + true);
> + if (IS_ERR(priv->in_ring)) {
> + v4l2_err(&ic_priv->sd,
> + "failed to alloc dma-buf ring\n");
> + ret = PTR_ERR(priv->in_ring);
> + priv->in_ring = NULL;
> + goto out_unprep;
> + }
> +
> + for (i = 0; i < IMX_MEDIA_MIN_RING_BUFS; i++)
> + imx_media_dma_buf_queue(priv->in_ring, i);
> +
> + priv->out_run = kzalloc(IMX_MEDIA_MAX_RING_BUFS *
> + sizeof(*priv->out_run), GFP_KERNEL);
> + if (!priv->out_run) {
> + v4l2_err(&ic_priv->sd, "failed to alloc src ring runs\n");
In OOM situation the core will report it, probably you can drop the message.
> + ret = -ENOMEM;
> + goto out_free_ring;
> + }
> +
> + priv->stop = false;
> +
> + return 0;
> +
> +out_free_ring:
> + imx_media_free_dma_buf_ring(priv->in_ring);
> + priv->in_ring = NULL;
> +out_unprep:
> + ipu_image_convert_unprepare(priv->ic_ctx);
> + return ret;
> +}
> +
[snip]
> diff --git a/drivers/staging/media/imx/imx-ic-prpenc.c b/drivers/staging/media/imx/imx-ic-prpenc.c
> new file mode 100644
> index 0000000..e17216b
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-ic-prpenc.c
> @@ -0,0 +1,1037 @@
> +/*
> + * V4L2 Capture IC Encoder Subdev for Freescale i.MX5/6 SOC
> + *
> + * This subdevice handles capture of video frames from the CSI, which
> + * are routed directly to the Image Converter preprocess encode task,
> + * for resizing, colorspace conversion, and rotation.
> + *
> + * Copyright (c) 2012-2016 Mentor Graphics Inc.
> + *
> + * 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; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/fs.h>
> +#include <linux/timer.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/interrupt.h>
> +#include <linux/spinlock.h>
> +#include <linux/platform_device.h>
> +#include <linux/pinctrl/consumer.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/v4l2-of.h>
> +#include <media/v4l2-ctrls.h>
Please sort the list of headers alphabetically.
> +#include <media/imx.h>
> +#include "imx-media.h"
> +#include "imx-ic.h"
> +
[snip]
> +static irqreturn_t prpenc_eof_interrupt(int irq, void *dev_id)
> +{
> + struct prpenc_priv *priv = dev_id;
> + struct imx_media_dma_buf *done, *next;
> + struct ipuv3_channel *channel;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&priv->irqlock, flags);
Here spin_lock(&priv->irqlock) should be sufficient.
> +
> + if (priv->last_eof) {
> + complete(&priv->last_eof_comp);
> + priv->last_eof = false;
> + goto unlock;
> + }
> +
> + /* inform CSI of this EOF so it can monitor frame intervals */
> + v4l2_subdev_call(priv->src_sd, core, interrupt_service_routine,
> + 0, NULL);
> +
> + channel = (ipu_rot_mode_is_irt(priv->rot_mode)) ?
> + priv->enc_rot_out_ch : priv->enc_ch;
> +
> + done = imx_media_dma_buf_get_active(priv->out_ring);
> + /* give the completed buffer to the sink */
> + if (!WARN_ON(!done))
> + imx_media_dma_buf_done(done, IMX_MEDIA_BUF_STATUS_DONE);
> +
> + /* priv->next buffer is now the active one */
> + imx_media_dma_buf_set_active(priv->next);
> +
> + /* bump the EOF timeout timer */
> + mod_timer(&priv->eof_timeout_timer,
> + jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
> +
> + if (ipu_idmac_buffer_is_ready(channel, priv->ipu_buf_num))
> + ipu_idmac_clear_buffer(channel, priv->ipu_buf_num);
> +
> + /* get next queued buffer */
> + next = imx_media_dma_buf_get_next_queued(priv->out_ring);
> +
> + ipu_cpmem_set_buffer(channel, priv->ipu_buf_num, next->phys);
> + ipu_idmac_select_buffer(channel, priv->ipu_buf_num);
> +
> + /* toggle IPU double-buffer index */
> + priv->ipu_buf_num ^= 1;
> + priv->next = next;
> +
> +unlock:
> + spin_unlock_irqrestore(&priv->irqlock, flags);
> + return IRQ_HANDLED;
> +}
[snip]
> +static int prpenc_registered(struct v4l2_subdev *sd)
> +{
> + struct prpenc_priv *priv = sd_to_priv(sd);
> + struct imx_media_subdev *imxsd;
> + struct imx_media_pad *pad;
> + int i, ret;
> +
> + /* get media device */
> + priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
> +
> + imxsd = imx_media_find_subdev_by_sd(priv->md, sd);
> + if (IS_ERR(imxsd))
> + return PTR_ERR(imxsd);
> +
> + if (imxsd->num_sink_pads != 1 || imxsd->num_src_pads != 1)
> + return -EINVAL;
> +
> + for (i = 0; i < PRPENC_NUM_PADS; i++) {
> + pad = &imxsd->pad[i];
> + priv->pad[i] = pad->pad;
> + if (priv->pad[i].flags & MEDIA_PAD_FL_SINK)
> + priv->input_pad = i;
> + else
> + priv->output_pad = i;
> +
> + /* set a default mbus format */
> + ret = imx_media_init_mbus_fmt(&priv->format_mbus[i],
> + 640, 480, 0, V4L2_FIELD_NONE,
> + &priv->cc[i]);
> + if (ret)
> + return ret;
> + }
> +
> + ret = prpenc_init_controls(priv);
> + if (ret)
> + return ret;
> +
> + ret = media_entity_pads_init(&sd->entity, PRPENC_NUM_PADS, priv->pad);
> + if (ret)
> + goto free_ctrls;
> +
> + return 0;
> +free_ctrls:
> + v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
> + return ret;
if (ret)
v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
return ret;
version is shorter.
> +}
[snip]
> diff --git a/drivers/staging/media/imx/imx-ic-prpvf.c b/drivers/staging/media/imx/imx-ic-prpvf.c
> new file mode 100644
> index 0000000..53ce006
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-ic-prpvf.c
> @@ -0,0 +1,1180 @@
> +/*
> + * V4L2 IC Deinterlacer Subdev for Freescale i.MX5/6 SOC
> + *
> + * Copyright (c) 2014-2016 Mentor Graphics Inc.
> + *
> + * 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; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/fs.h>
> +#include <linux/timer.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/interrupt.h>
> +#include <linux/platform_device.h>
> +#include <linux/pinctrl/consumer.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/v4l2-subdev.h>
> +#include <media/v4l2-of.h>
> +#include <media/v4l2-ctrls.h>
Please sort the list of headers alphabetically.
> +#include <media/imx.h>
> +#include "imx-media.h"
> +#include "imx-ic.h"
> +
> +/*
[snip]
> +/* prpvf_out_ch EOF interrupt (progressive frame ready) */
> +static irqreturn_t prpvf_out_eof_interrupt(int irq, void *dev_id)
> +{
> + struct prpvf_priv *priv = dev_id;
> + struct imx_media_dma_buf *done;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&priv->irqlock, flags);
Here spin_lock(&priv->irqlock) should be sufficient.
> +
> + if (priv->last_eof) {
> + complete(&priv->last_eof_comp);
> + priv->last_eof = false;
> + goto unlock;
> + }
> +
> + if (priv->csi_direct) {
> + /* inform CSI of this EOF so it can monitor frame intervals */
> + /* FIXME: frames are coming in twice as fast in direct path! */
> + v4l2_subdev_call(priv->src_sd, core, interrupt_service_routine,
> + 0, NULL);
> + }
> +
> + done = imx_media_dma_buf_get_active(priv->out_ring);
> + /* give the completed buffer to the sink */
> + if (!WARN_ON(!done))
> + imx_media_dma_buf_done(done, IMX_MEDIA_BUF_STATUS_DONE);
> +
> + if (!priv->csi_direct) {
> + /* we're done with the input buffer, queue it back */
> + imx_media_dma_buf_queue(priv->in_ring,
> + priv->curr_in_buf->index);
> +
> + /* current input buffer is now last */
> + priv->last_in_buf = priv->curr_in_buf;
> + } else {
> + /*
> + * priv->next buffer is now the active one due
> + * to IPU double-buffering
> + */
> + imx_media_dma_buf_set_active(priv->next_out_buf);
> + }
> +
> + /* bump the EOF timeout timer */
> + mod_timer(&priv->eof_timeout_timer,
> + jiffies + msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT));
> +
> + if (priv->csi_direct) {
> + prepare_prpvf_out_buffer(priv);
> + /* toggle IPU double-buffer index */
> + priv->ipu_buf_num ^= 1;
> + }
> +
> +unlock:
> + spin_unlock_irqrestore(&priv->irqlock, flags);
> + return IRQ_HANDLED;
> +}
> +
[snip]
> diff --git a/drivers/staging/media/imx/imx-ic.h b/drivers/staging/media/imx/imx-ic.h
> new file mode 100644
> index 0000000..9aed5f5
> --- /dev/null
> +++ b/drivers/staging/media/imx/imx-ic.h
> @@ -0,0 +1,36 @@
> +/*
> + * V4L2 Image Converter Subdev for Freescale i.MX5/6 SOC
> + *
> + * Copyright (c) 2016 Mentor Graphics Inc.
> + *
> + * 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; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#ifndef _IMX_IC_H
> +#define _IMX_IC_H
> +
Please add header files or declarations of all used structs.
> +struct imx_ic_priv {
> + struct device *dev;
> + struct v4l2_subdev sd;
> + int ipu_id;
> + int task_id;
> + void *task_priv;
> +};
> +
> +struct imx_ic_ops {
> + struct v4l2_subdev_ops *subdev_ops;
> + struct v4l2_subdev_internal_ops *internal_ops;
> + struct media_entity_operations *entity_ops;
> +
> + int (*init)(struct imx_ic_priv *ic_priv);
> + void (*remove)(struct imx_ic_priv *ic_priv);
> +};
> +
> +extern struct imx_ic_ops imx_ic_prpenc_ops;
> +extern struct imx_ic_ops imx_ic_prpvf_ops;
> +extern struct imx_ic_ops imx_ic_pp_ops;
> +
> +#endif
> +
>
--
With best wishes,
Vladimir
^ permalink raw reply
* [PATCH v6 1/5] dt-bindings: zte: documents zx2967 power domain driver bindings
From: Rob Herring @ 2017-01-04 14:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483530494-14177-1-git-send-email-baoyou.xie@linaro.org>
On Wed, Jan 04, 2017 at 07:48:10PM +0800, Baoyou Xie wrote:
> This patch documents devicetree tree bindings for the ZTE zx2967
> power domain driver.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> ---
> Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt
>
> diff --git a/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt b/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt
> new file mode 100644
> index 0000000..1476318
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/zte/pd-2967xx.txt
> @@ -0,0 +1,17 @@
> +* ZTE 2967 SoC Power Domains
> +
> +2967 processors include support for multiple power domains which are used
> +to gate power to one or more peripherals on the processor.
> +
> +Required Properties:
> +- compatible: should be one of the following.
> + * zte,zx296718-pcu - for zx296718 board's power domain.
board? I'd expect this is for an SoC?
> +- reg: physical base address of the controller and length of memory mapped
> + region.
#power-domain-cells needed?
> +
> +Example:
> +
> + pcu_domain: pcu at 0x00117000 {
pcu at 117000
> + compatible = "zte,zx296718-pcu";
> + reg = <0x00117000 0x1000>;
> + };
> --
> 2.7.4
>
^ 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