* Re: [PATCH] ASoC: fsl_esai: fix register setting issue in RIGHT_J mode
From: Nicolin Chen @ 2019-02-15 18:55 UTC (permalink / raw)
To: S.j. Wang
Cc: linuxppc-dev@lists.ozlabs.org, alsa-devel@alsa-project.org,
festevam@gmail.com, timur@kernel.org, Xiubo.Lee@gmail.com
In-Reply-To: <1550228637-5675-1-git-send-email-shengjiu.wang@nxp.com>
On Fri, Feb 15, 2019 at 11:04:38AM +0000, S.j. Wang wrote:
> The ESAI_xCR_xWA is xCR's bit, not the xCCR's bit, driver set it to
> wrong register, correct it.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Would need this for stable kernel too.
Ackedy-by: Nicolin Chen <nicoleotsuka@gmail.com>
Thanks.
> ---
> sound/soc/fsl/fsl_esai.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
> index 57b484768a58..afe67c865330 100644
> --- a/sound/soc/fsl/fsl_esai.c
> +++ b/sound/soc/fsl/fsl_esai.c
> @@ -398,7 +398,8 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> break;
> case SND_SOC_DAIFMT_RIGHT_J:
> /* Data on rising edge of bclk, frame high, right aligned */
> - xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCR_xWA;
> + xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
> + xcr |= ESAI_xCR_xWA;
> break;
> case SND_SOC_DAIFMT_DSP_A:
> /* Data on rising edge of bclk, frame high, 1clk before data */
> @@ -455,12 +456,12 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> return -EINVAL;
> }
>
> - mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR;
> + mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR | ESAI_xCR_xWA;
> regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
> regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
>
> mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
> - ESAI_xCCR_xFSD | ESAI_xCCR_xCKD | ESAI_xCR_xWA;
> + ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
> regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
> regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
>
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH v4 0/3] locking/rwsem: Rwsem rearchitecture part 0
From: Will Deacon @ 2019-02-15 18:40 UTC (permalink / raw)
To: Peter Zijlstra
Cc: linux-ia64, linux-sh, linux-mips, H. Peter Anvin, sparclinux,
linux-riscv, linux-arch, linux-s390, Davidlohr Bueso,
linux-c6x-dev, linux-hexagon, x86, Ingo Molnar, Waiman Long,
uclinux-h8-devel, linux-xtensa, Arnd Bergmann, linux-um,
linux-m68k, openrisc, Borislav Petkov, Thomas Gleixner,
linux-arm-kernel, Tim Chen, linux-parisc, Linus Torvalds,
linux-kernel, linux-alpha, nios2-dev, Andrew Morton, linuxppc-dev
In-Reply-To: <20190214103715.GI32494@hirez.programming.kicks-ass.net>
On Thu, Feb 14, 2019 at 11:37:15AM +0100, Peter Zijlstra wrote:
> On Wed, Feb 13, 2019 at 05:00:14PM -0500, Waiman Long wrote:
> > v4:
> > - Remove rwsem-spinlock.c and make all archs use rwsem-xadd.c.
> >
> > v3:
> > - Optimize __down_read_trylock() for the uncontended case as suggested
> > by Linus.
> >
> > v2:
> > - Add patch 2 to optimize __down_read_trylock() as suggested by PeterZ.
> > - Update performance test data in patch 1.
> >
> > The goal of this patchset is to remove the architecture specific files
> > for rwsem-xadd to make it easer to add enhancements in the later rwsem
> > patches. It also removes the legacy rwsem-spinlock.c file and make all
> > the architectures use one single implementation of rwsem - rwsem-xadd.c.
> >
> > Waiman Long (3):
> > locking/rwsem: Remove arch specific rwsem files
> > locking/rwsem: Remove rwsem-spinlock.c & use rwsem-xadd.c for all
> > archs
> > locking/rwsem: Optimize down_read_trylock()
>
> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
>
> with the caveat that I'm happy to exchange patch 3 back to my earlier
> suggestion in case Will expesses concerns wrt the ARM64 performance of
> Linus' suggestion.
Right, the current proposal doesn't work well for us, unfortunately. Which
was your earlier suggestion?
Will
^ permalink raw reply
* Re: [PATCH v3 2/2] locking/rwsem: Optimize down_read_trylock()
From: Will Deacon @ 2019-02-15 18:35 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-arch, linux-xtensa, Davidlohr Bueso, linux-ia64, Tim Chen,
Arnd Bergmann, Linux-sh list, Peter Zijlstra, linux-hexagon,
the arch/x86 maintainers, H. Peter Anvin,
Linux List Kernel Mailing, Ingo Molnar, Borislav Petkov,
linux-alpha@vger.kernel.org, sparclinux, Waiman Long,
Thomas Gleixner, linuxppc-dev, Andrew Morton,
linux-alpha@vger.kernel.org
In-Reply-To: <CAHk-=wi03J1jurebJNHPxGCVss7ARAN+2JuVthEGoEx=qkT4dQ@mail.gmail.com>
On Thu, Feb 14, 2019 at 10:09:44AM -0800, Linus Torvalds wrote:
> On Thu, Feb 14, 2019 at 9:51 AM Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
> >
> > The arm64 numbers scaled horribly even before, and that's because
> > there is too much ping-pong, and it's probably because there is no
> > "stickiness" to the cacheline to the core, and thus adding the extra
> > loop can make the ping-pong issue even worse because now there is more
> > of it.
>
> Actually, if it's using the ll/sc, then I don't see why arm64 should
> even change. It doesn't really even change the pattern: the initial
> load of the value is just replaced with a "ll" that gets a non-zero
> value, and then we re-try without even doing the "sc" part.
So our cmpxchg() has a prefetch-with-intent-to-modify instruction before the
'll' part, which will attempt to grab the line unique the first time round.
The 'll' also has acquire semantics, so there's the chance for the
micro-architecture to handle that badly too.
I think that the problem with the proposed changed change is that whenever a
reader tries to acquire an rwsem that is already held for read, it will
always fail the first cmpxchg(), so in this situation the read path is
considerably slower than before.
> End result: exact same "load once, then do ll/sc to update". Just
> using a slightly different instruction pattern.
>
> But maybe "ll" does something different to the cacheline than a regular "ld"?
>
> Alternatively, the machine you used is using LSE, and the "swp" thing
> has some horrid behavior when it fails.
Depending on where the data is, the LSE instructions may execute outside of
the CPU (e.g. in a cache controller) and so could add latency to a failing
CAS.
Will
^ permalink raw reply
* Re: [PATCH V2 0/7] Add FOLL_LONGTERM to GUP fast and use it
From: Ira Weiny @ 2019-02-15 18:29 UTC (permalink / raw)
To: linux-mips, linux-kernel, kvm-ppc, linuxppc-dev, linux-s390,
linux-sh, sparclinux, kvm, linux-fpga, dri-devel, linux-rdma,
linux-media, linux-scsi, devel, virtualization, netdev,
linux-fbdev, xen-devel, devel, linux-mm, ceph-devel, rds-devel
> NOTE: This series depends on my clean up patch to remove the write parameter
> from gup_fast_permitted()[1]
>
> HFI1, qib, and mthca, use get_user_pages_fast() due to it performance
> advantages. These pages can be held for a significant time. But
> get_user_pages_fast() does not protect against mapping of FS DAX pages.
>
> Introduce FOLL_LONGTERM and use this flag in get_user_pages_fast() which
> retains the performance while also adding the FS DAX checks. XDP has also
> shown interest in using this functionality.[2]
>
> In addition we change get_user_pages() to use the new FOLL_LONGTERM flag and
> remove the specialized get_user_pages_longterm call.
>
> [1] https://lkml.org/lkml/2019/2/11/237
> [2] https://lkml.org/lkml/2019/2/11/1789
Any comments on this series? I've touched a lot of subsystems which I think
require review.
Thanks,
Ira
>
> Ira Weiny (7):
> mm/gup: Replace get_user_pages_longterm() with FOLL_LONGTERM
> mm/gup: Change write parameter to flags in fast walk
> mm/gup: Change GUP fast to use flags rather than a write 'bool'
> mm/gup: Add FOLL_LONGTERM capability to GUP fast
> IB/hfi1: Use the new FOLL_LONGTERM flag to get_user_pages_fast()
> IB/qib: Use the new FOLL_LONGTERM flag to get_user_pages_fast()
> IB/mthca: Use the new FOLL_LONGTERM flag to get_user_pages_fast()
>
> arch/mips/mm/gup.c | 11 +-
> arch/powerpc/kvm/book3s_64_mmu_hv.c | 4 +-
> arch/powerpc/kvm/e500_mmu.c | 2 +-
> arch/powerpc/mm/mmu_context_iommu.c | 4 +-
> arch/s390/kvm/interrupt.c | 2 +-
> arch/s390/mm/gup.c | 12 +-
> arch/sh/mm/gup.c | 11 +-
> arch/sparc/mm/gup.c | 9 +-
> arch/x86/kvm/paging_tmpl.h | 2 +-
> arch/x86/kvm/svm.c | 2 +-
> drivers/fpga/dfl-afu-dma-region.c | 2 +-
> drivers/gpu/drm/via/via_dmablit.c | 3 +-
> drivers/infiniband/core/umem.c | 5 +-
> drivers/infiniband/hw/hfi1/user_pages.c | 5 +-
> drivers/infiniband/hw/mthca/mthca_memfree.c | 3 +-
> drivers/infiniband/hw/qib/qib_user_pages.c | 8 +-
> drivers/infiniband/hw/qib/qib_user_sdma.c | 2 +-
> drivers/infiniband/hw/usnic/usnic_uiom.c | 9 +-
> drivers/media/v4l2-core/videobuf-dma-sg.c | 6 +-
> drivers/misc/genwqe/card_utils.c | 2 +-
> drivers/misc/vmw_vmci/vmci_host.c | 2 +-
> drivers/misc/vmw_vmci/vmci_queue_pair.c | 6 +-
> drivers/platform/goldfish/goldfish_pipe.c | 3 +-
> drivers/rapidio/devices/rio_mport_cdev.c | 4 +-
> drivers/sbus/char/oradax.c | 2 +-
> drivers/scsi/st.c | 3 +-
> drivers/staging/gasket/gasket_page_table.c | 4 +-
> drivers/tee/tee_shm.c | 2 +-
> drivers/vfio/vfio_iommu_spapr_tce.c | 3 +-
> drivers/vfio/vfio_iommu_type1.c | 3 +-
> drivers/vhost/vhost.c | 2 +-
> drivers/video/fbdev/pvr2fb.c | 2 +-
> drivers/virt/fsl_hypervisor.c | 2 +-
> drivers/xen/gntdev.c | 2 +-
> fs/orangefs/orangefs-bufmap.c | 2 +-
> include/linux/mm.h | 17 +-
> kernel/futex.c | 2 +-
> lib/iov_iter.c | 7 +-
> mm/gup.c | 220 ++++++++++++--------
> mm/gup_benchmark.c | 5 +-
> mm/util.c | 8 +-
> net/ceph/pagevec.c | 2 +-
> net/rds/info.c | 2 +-
> net/rds/rdma.c | 3 +-
> 44 files changed, 232 insertions(+), 180 deletions(-)
>
> --
> 2.20.1
>
^ permalink raw reply
* Re: [PATCH v3] hugetlb: allow to free gigantic pages regardless of the configuration
From: Dave Hansen @ 2019-02-15 17:34 UTC (permalink / raw)
To: Alexandre Ghiti, Vlastimil Babka, Catalin Marinas, Will Deacon,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Martin Schwidefsky, Heiko Carstens, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H . Peter Anvin, x86, Dave Hansen,
Andy Lutomirski, Peter Zijlstra, Alexander Viro, Mike Kravetz,
linux-arm-kernel, linux-kernel, linuxppc-dev, linux-s390,
linux-fsdevel, linux-mm
In-Reply-To: <20190214193100.3529-1-alex@ghiti.fr>
> -#if (defined(CONFIG_MEMORY_ISOLATION) && defined(CONFIG_COMPACTION)) || defined(CONFIG_CMA)
> +#ifdef CONFIG_CONTIG_ALLOC
> /* The below functions must be run on a range from a single zone. */
> extern int alloc_contig_range(unsigned long start, unsigned long end,
> unsigned migratetype, gfp_t gfp_mask);
> -extern void free_contig_range(unsigned long pfn, unsigned nr_pages);
> #endif
> +extern void free_contig_range(unsigned long pfn, unsigned int nr_pages);
There's a lot of stuff going on in this patch. Adding/removing config
options. Please get rid of these superfluous changes or at least break
them out.
> #ifdef CONFIG_CMA
> /* CMA stuff */
> diff --git a/mm/Kconfig b/mm/Kconfig
> index 25c71eb8a7db..138a8df9b813 100644
> --- a/mm/Kconfig
> +++ b/mm/Kconfig
> @@ -252,12 +252,17 @@ config MIGRATION
> pages as migration can relocate pages to satisfy a huge page
> allocation instead of reclaiming.
>
> +
> config ARCH_ENABLE_HUGEPAGE_MIGRATION
> bool
Like this. :)
> config ARCH_ENABLE_THP_MIGRATION
> bool
>
> +config CONTIG_ALLOC
> + def_bool y
> + depends on (MEMORY_ISOLATION && COMPACTION) || CMA
> +
> config PHYS_ADDR_T_64BIT
> def_bool 64BIT
Please think carefully though the Kconfig dependencies. 'select' is
*not* the same as 'depends on'.
This replaces a bunch of arch-specific "select ARCH_HAS_GIGANTIC_PAGE"
with a 'depends on'. I *think* that ends up being OK, but it absolutely
needs to be addressed in the changelog about why *you* think it is OK
and why it doesn't change the functionality of any of the patched
architetures.
> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index afef61656c1e..e686c92212e9 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1035,7 +1035,6 @@ static int hstate_next_node_to_free(struct hstate *h, nodemask_t *nodes_allowed)
> ((node = hstate_next_node_to_free(hs, mask)) || 1); \
> nr_nodes--)
>
> -#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
> static void destroy_compound_gigantic_page(struct page *page,
> unsigned int order)
> {
Whats the result of this #ifdef removal? A universally larger kernel
even for architectures that do not support runtime gigantic page
alloc/free? That doesn't seem like a good thing.
> @@ -1058,6 +1057,12 @@ static void free_gigantic_page(struct page *page, unsigned int order)
> free_contig_range(page_to_pfn(page), 1 << order);
> }
>
> +static inline bool gigantic_page_runtime_allocation_supported(void)
> +{
> + return IS_ENABLED(CONFIG_CONTIG_ALLOC);
> +}
Why bother having this function? Why don't the callers just check the
config option directly?
> +#ifdef CONFIG_CONTIG_ALLOC
> static int __alloc_gigantic_page(unsigned long start_pfn,
> unsigned long nr_pages, gfp_t gfp_mask)
> {
> @@ -1143,22 +1148,15 @@ static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask,
> static void prep_new_huge_page(struct hstate *h, struct page *page, int nid);
> static void prep_compound_gigantic_page(struct page *page, unsigned int order);
>
> -#else /* !CONFIG_ARCH_HAS_GIGANTIC_PAGE */
> -static inline bool gigantic_page_supported(void) { return false; }
> +#else /* !CONFIG_CONTIG_ALLOC */
> static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask,
> int nid, nodemask_t *nodemask) { return NULL; }
> -static inline void free_gigantic_page(struct page *page, unsigned int order) { }
> -static inline void destroy_compound_gigantic_page(struct page *page,
> - unsigned int order) { }
> #endif
>
> static void update_and_free_page(struct hstate *h, struct page *page)
> {
> int i;
>
> - if (hstate_is_gigantic(h) && !gigantic_page_supported())
> - return;
I don't get the point of removing this check. Logically, this reads as
checking if the architecture supports gigantic hstates and has nothing
to do with allocation.
> h->nr_huge_pages--;
> h->nr_huge_pages_node[page_to_nid(page)]--;
> for (i = 0; i < pages_per_huge_page(h); i++) {
> @@ -2276,13 +2274,20 @@ static int adjust_pool_surplus(struct hstate *h, nodemask_t *nodes_allowed,
> }
>
> #define persistent_huge_pages(h) (h->nr_huge_pages - h->surplus_huge_pages)
> -static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
> +static int set_max_huge_pages(struct hstate *h, unsigned long count,
> nodemask_t *nodes_allowed)
> {
> unsigned long min_count, ret;
>
> - if (hstate_is_gigantic(h) && !gigantic_page_supported())
> - return h->max_huge_pages;
> + if (hstate_is_gigantic(h) &&
> + !gigantic_page_runtime_allocation_supported()) {
The indentation here is wrong and reduces readability. Needs to be like
this:
if (hstate_is_gigantic(h) &&
!gigantic_page_runtime_allocation_supported()) {
> + spin_lock(&hugetlb_lock);
> + if (count > persistent_huge_pages(h)) {
> + spin_unlock(&hugetlb_lock);
> + return -EINVAL;
> + }
> + goto decrease_pool;
> + }
Needs comments.
/* Gigantic pages can be freed but not allocated */
or something.
^ permalink raw reply
* Re: [PATCH v3] hugetlb: allow to free gigantic pages regardless of the configuration
From: Vlastimil Babka @ 2019-02-15 16:48 UTC (permalink / raw)
To: Alexandre Ghiti, Catalin Marinas, Will Deacon,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Martin Schwidefsky, Heiko Carstens, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, H . Peter Anvin, x86, Dave Hansen,
Andy Lutomirski, Peter Zijlstra, Alexander Viro, Mike Kravetz,
linux-arm-kernel, linux-kernel, linuxppc-dev, linux-s390,
linux-fsdevel, linux-mm, Andrew Morton
In-Reply-To: <20190214193100.3529-1-alex@ghiti.fr>
On 2/14/19 8:31 PM, Alexandre Ghiti wrote:
> On systems without CMA or (MEMORY_ISOLATION && COMPACTION) activated but
> that support gigantic pages, boottime reserved gigantic pages can not be
> freed at all. This patch simply enables the possibility to hand back
> those pages to memory allocator.
>
> This patch also renames:
>
> - the triplet CMA or (MEMORY_ISOLATION && COMPACTION) into CONTIG_ALLOC,
> and gets rid of all use of it in architecture specific code (and then
> removes ARCH_HAS_GIGANTIC_PAGE config).
> - gigantic_page_supported to make it more accurate: this value being false
> does not mean that the system cannot use gigantic pages, it just means that
> runtime allocation of gigantic pages is not supported, one can still
> allocate boottime gigantic pages if the architecture supports it.
>
> Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Thanks!
...
> --- a/mm/Kconfig
> +++ b/mm/Kconfig
> @@ -252,12 +252,17 @@ config MIGRATION
> pages as migration can relocate pages to satisfy a huge page
> allocation instead of reclaiming.
>
> +
Stray newline? No need to resend, Andrew can fix up.
Ah, he wasn't in To:, adding.
> config ARCH_ENABLE_HUGEPAGE_MIGRATION
> bool
>
> config ARCH_ENABLE_THP_MIGRATION
> bool
>
> +config CONTIG_ALLOC
> + def_bool y
> + depends on (MEMORY_ISOLATION && COMPACTION) || CMA
> +
> config PHYS_ADDR_T_64BIT
> def_bool 64BIT
>
^ permalink raw reply
* Re: [RFC PATCH 0/5] powerpc: KASAN for 64-bit Book3E
From: Christophe Leroy @ 2019-02-15 16:39 UTC (permalink / raw)
To: Daniel Axtens, aneesh.kumar, bsingharora; +Cc: linuxppc-dev, kasan-dev
In-Reply-To: <20190215000441.14323-1-dja@axtens.net>
On 02/15/2019 12:04 AM, Daniel Axtens wrote:
> Building on the work of Christophe, Aneesh and Balbir, I've ported
> KASAN to the e6500, a 64-bit Book3E processor which doesn't have a
> hashed page table. It applies on top of Christophe's series, v5.
>
> It requires some changes to the KASAN core - please let me know if
> these are problematic and we see if an alternative approach is
> possible.
>
> The KASAN shadow area is mapped into vmemmap space:
> 0x8000 0400 0000 0000 to 0x8000 0600 0000 0000.
> To do this we require that vmemmap be disabled. (This is the default
> in the kernel config that QorIQ provides for the machine in their
> SDK anyway - they use flat memory.)
>
> Only outline instrumentation is supported and only KASAN_MINIMAL works.
> Only the kernel linear mapping (0xc000...) is checked. The vmalloc and
> ioremap areas (also in 0x800...) are all mapped to a zero page. As
> with the Book3S hash series, this requires overriding the memory <->
> shadow mapping.
>
> Also, as with both previous 64-bit series, early instrumentation is not
> supported.
>
> KVM, kexec and xmon have not been tested.
>
> Thanks to those who have done the heavy lifting over the past several years:
> - Christophe's 32 bit series: https://lists.ozlabs.org/pipermail/linuxppc-dev/2019-February/185379.html
> - Aneesh's Book3S hash series: https://lwn.net/Articles/655642/
> - Balbir's Book3S radix series: https://patchwork.ozlabs.org/patch/795211/
>
> While useful if you have an Book3E device, this is mostly intended
> as a warm-up exercise for reviving Aneesh's series for book3s hash.
> In particular, changes to the kasan core are going to be required
> for hash and radix as well.
>
> Regards,
> Daniel
Hi Daniel,
I'll look into your series in more details later, for now I just want to
let you know that I get a build failure:
LD vmlinux.o
lib/string.o: In function `memcmp':
/root/linux-powerpc/lib/string.c:857: multiple definition of `memcmp'
arch/powerpc/lib/memcmp_32.o:/root/linux-powerpc/arch/powerpc/lib/memcmp_32.S:16:
first defined here
Christophe
>
> Daniel Axtens (5):
> kasan: do not open-code addr_has_shadow
> kasan: allow architectures to manage the memory-to-shadow mapping
> kasan: allow architectures to provide an outline readiness check
> powerpc: move KASAN into its own subdirectory
> powerpc: KASAN for 64bit Book3E
>
> arch/powerpc/Kconfig | 1 +
> arch/powerpc/Makefile | 2 +
> arch/powerpc/include/asm/kasan.h | 77 +++++++++++++++++--
> arch/powerpc/include/asm/ppc_asm.h | 7 ++
> arch/powerpc/include/asm/string.h | 7 +-
> arch/powerpc/lib/mem_64.S | 6 +-
> arch/powerpc/lib/memcmp_64.S | 5 +-
> arch/powerpc/lib/memcpy_64.S | 3 +-
> arch/powerpc/lib/string.S | 15 ++--
> arch/powerpc/mm/Makefile | 4 +-
> arch/powerpc/mm/kasan/Makefile | 6 ++
> .../{kasan_init.c => kasan/kasan_init_32.c} | 0
> arch/powerpc/mm/kasan/kasan_init_book3e_64.c | 53 +++++++++++++
> arch/powerpc/purgatory/Makefile | 3 +
> arch/powerpc/xmon/Makefile | 1 +
> include/linux/kasan.h | 6 ++
> mm/kasan/generic.c | 5 +-
> mm/kasan/generic_report.c | 2 +-
> mm/kasan/kasan.h | 6 +-
> mm/kasan/report.c | 6 +-
> mm/kasan/tags.c | 3 +-
> 21 files changed, 188 insertions(+), 30 deletions(-)
> create mode 100644 arch/powerpc/mm/kasan/Makefile
> rename arch/powerpc/mm/{kasan_init.c => kasan/kasan_init_32.c} (100%)
> create mode 100644 arch/powerpc/mm/kasan/kasan_init_book3e_64.c
>
^ permalink raw reply
* Re: [PATCH 0/5] use pinned_vm instead of locked_vm to account pinned pages
From: Christopher Lameter @ 2019-02-15 15:26 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: dave, jack, kvm, atull, aik, linuxppc-dev, linux-fpga,
linux-kernel, kvm-ppc, Daniel Jordan, linux-mm, alex.williamson,
mdf, akpm, Ira Weiny, hao.wu
In-Reply-To: <20190214221629.GD1739@ziepe.ca>
On Thu, 14 Feb 2019, Jason Gunthorpe wrote:
> On Thu, Feb 14, 2019 at 01:46:51PM -0800, Ira Weiny wrote:
>
> > > > > Really unclear how to fix this. The pinned/locked split with two
> > > > > buckets may be the right way.
> > > >
> > > > Are you suggesting that we have 2 user limits?
> > >
> > > This is what RDMA has done since CL's patch.
> >
> > I don't understand? What is the other _user_ limit (other than
> > RLIMIT_MEMLOCK)?
>
> With todays implementation RLIMIT_MEMLOCK covers two user limits,
> total number of pinned pages and total number of mlocked pages. The
> two are different buckets and not summed.
Applications were failing at some point because they were effectively
summed up. If you mlocked/pinned a dataset of more than half the memory of
a system then things would get really weird.
Also there is the possibility of even more duplication because pages can
be pinned by multiple kernel subsystems. So you could get more than
doubling of the number.
The sane thing was to account them separately so that mlocking and
pinning worked without apps failing and then wait for another genius
to find out how to improve the situation by getting the pinned page mess
under control.
It is not even advisable to check pinned pages against any limit because
pages can be pinned by multiple subsystems.
The main problem here is that we only have a refcount to indicate pinning
and no way to clearly distinguish long term from short pins. In order to
really fix this issue we would need to have a list of subsystems that have
taken long term pins on a page. But doing so would waste a lot of memory
and cause a significant performance regression.
And the discussions here seem to be meandering around these issues.
Nothing really that convinces me that we have a clean solution at hand.
^ permalink raw reply
* Re: [PATCH V2 3/10] KVM/MMU: Add last_level in the struct mmu_spte_page
From: Paolo Bonzini @ 2019-02-15 15:22 UTC (permalink / raw)
To: Tianyu Lan
Cc: kvm, Radim Krcmar, catalin.marinas, will.deacon, christoffer.dall,
H. Peter Anvin, kys, kvmarm, the arch/x86 maintainers, linux,
michael.h.kelley, Ingo Molnar, jhogan, linux-mips, Lan Tianyu,
marc.zyngier, kvm-ppc, bp, Thomas Gleixner, linux-arm-kernel,
linux-kernel@vger kernel org, ralf, paul.burton, Vitaly Kuznetsov,
linuxppc-dev
In-Reply-To: <CAOLK0pzXnvk=FsfjH07jUyRJGpeiNG7-9vR9Vo0mLJtdPnt_7Q@mail.gmail.com>
On 15/02/19 16:05, Tianyu Lan wrote:
> Yes, you are right. Thanks to point out and will fix. The last_level
> flag is to avoid adding middle page node(e.g, PGD, PMD)
> into flush list. The address range will be duplicated if adding both
> leaf, node and middle node into flush list.
Hmm, that's not easy to track. One kvm_mmu_page could include both leaf
and non-leaf page (for example a huge page for 0 to 2 MB and a page
table for 2 MB to 4 MB).
Is this really needed? First, your benchmarks so far have been done
with sp->last_level always set to true. Second, you would only
encounter this optimization in kvm_mmu_commit_zap_page when zapping a 1
GB region (which then would be invalidated twice, at both the PMD and
PGD level) or bigger.
Paolo
^ permalink raw reply
* Re: [PATCH V2 3/10] KVM/MMU: Add last_level in the struct mmu_spte_page
From: Tianyu Lan @ 2019-02-15 15:05 UTC (permalink / raw)
To: Paolo Bonzini
Cc: kvm, Radim Krcmar, catalin.marinas, will.deacon, christoffer.dall,
H. Peter Anvin, kys, kvmarm, the arch/x86 maintainers, linux,
michael.h.kelley, Ingo Molnar, jhogan, linux-mips, Lan Tianyu,
marc.zyngier, kvm-ppc, bp, Thomas Gleixner, linux-arm-kernel,
linux-kernel@vger kernel org, ralf, paul.burton, Vitaly Kuznetsov,
linuxppc-dev
In-Reply-To: <572a6ce3-23f6-7b16-a070-4d4a81ee4335@redhat.com>
On Fri, Feb 15, 2019 at 12:32 AM Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 02/02/19 02:38, lantianyu1986@gmail.com wrote:
> > diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
> > index ce770b446238..70cafd3f95ab 100644
> > --- a/arch/x86/kvm/mmu.c
> > +++ b/arch/x86/kvm/mmu.c
> > @@ -2918,6 +2918,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
> >
> > if (level > PT_PAGE_TABLE_LEVEL)
> > spte |= PT_PAGE_SIZE_MASK;
> > +
> > + sp->last_level = is_last_spte(spte, level);
>
> Wait, I wasn't thinking straight. If a struct kvm_mmu_page exists, it
> is never the last level. Page table entries for the last level do not
> have a struct kvm_mmu_page.
>
> Therefore you don't need the flag after all. I suspect your
> calculations in patch 2 are off by one, and you actually need
>
> hlist_for_each_entry(sp, range->flush_list, flush_link) {
> int pages = KVM_PAGES_PER_HPAGE(sp->role.level + 1);
> ...
> }
>
> For example, if sp->role.level is 1 then the struct kvm_mmu_page is for
> a page containing PTEs and covers an area of 2 MiB.
Yes, you are right. Thanks to point out and will fix. The last_level
flag is to avoid adding middle page node(e.g, PGD, PMD)
into flush list. The address range will be duplicated if adding both
leaf, node and middle node into flush list.
>
> Thanks,
>
> Paolo
>
> > if (tdp_enabled)
> > spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn,
> > kvm_is_mmio_pfn(pfn));
>
--
Best regards
Tianyu Lan
^ permalink raw reply
* [PATCH v5 3/3] ASoC: fsl: Add Audio Mixer machine driver
From: Viorel Suman @ 2019-02-15 14:01 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
Jaroslav Kysela, Takashi Iwai, Timur Tabi, Nicolin Chen, Xiubo Li,
Fabio Estevam, Viorel Suman, S.j. Wang, Daniel Baluta,
Cosmin Samoila
Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
linux-kernel@vger.kernel.org, Viorel Suman, dl-linux-imx,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1550239285-12587-1-git-send-email-viorel.suman@nxp.com>
This patch implements Audio Mixer machine driver for NXP iMX8 SOCs.
It connects together Audio Mixer and related SAI instances.
Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
---
sound/soc/fsl/Kconfig | 9 ++
sound/soc/fsl/Makefile | 2 +
sound/soc/fsl/imx-audmix.c | 327 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 338 insertions(+)
create mode 100644 sound/soc/fsl/imx-audmix.c
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 0af2e056..d87c842 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -303,6 +303,15 @@ config SND_SOC_FSL_ASOC_CARD
CS4271, CS4272 and SGTL5000.
Say Y if you want to add support for Freescale Generic ASoC Sound Card.
+config SND_SOC_IMX_AUDMIX
+ tristate "SoC Audio support for i.MX boards with AUDMIX"
+ select SND_SOC_FSL_AUDMIX
+ select SND_SOC_FSL_SAI
+ help
+ SoC Audio support for i.MX boards with Audio Mixer
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an Audio Mixer.
+
endif # SND_IMX_SOC
endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4172d5a..c0dd044 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -62,6 +62,7 @@ snd-soc-imx-es8328-objs := imx-es8328.o
snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
snd-soc-imx-spdif-objs := imx-spdif.o
snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-audmix-objs := imx-audmix.o
obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
new file mode 100644
index 0000000..72e37ca
--- /dev/null
+++ b/sound/soc/fsl/imx-audmix.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017 NXP
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/pm_runtime.h>
+#include "fsl_sai.h"
+#include "fsl_audmix.h"
+
+struct imx_audmix {
+ struct platform_device *pdev;
+ struct snd_soc_card card;
+ struct platform_device *audmix_pdev;
+ struct platform_device *out_pdev;
+ struct clk *cpu_mclk;
+ int num_dai;
+ struct snd_soc_dai_link *dai;
+ int num_dai_conf;
+ struct snd_soc_codec_conf *dai_conf;
+ int num_dapm_routes;
+ struct snd_soc_dapm_route *dapm_routes;
+};
+
+static const u32 imx_audmix_rates[] = {
+ 8000, 12000, 16000, 24000, 32000, 48000, 64000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = {
+ .count = ARRAY_SIZE(imx_audmix_rates),
+ .list = imx_audmix_rates,
+};
+
+static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct device *dev = rtd->card->dev;
+ unsigned long clk_rate = clk_get_rate(priv->cpu_mclk);
+ int ret;
+
+ if (clk_rate % 24576000 == 0) {
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &imx_audmix_rate_constraints);
+ if (ret < 0)
+ return ret;
+ } else {
+ dev_warn(dev, "mclk may be not supported %lu\n", clk_rate);
+ }
+
+ ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
+ 1, 8);
+ if (ret < 0)
+ return ret;
+
+ return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+ FSL_AUDMIX_FORMATS);
+}
+
+static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dev = rtd->card->dev;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+ u32 channels = params_channels(params);
+ int ret, dir;
+
+ /* For playback the AUDMIX is slave, and for record is master */
+ fmt |= tx ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;
+ dir = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN;
+
+ /* set DAI configuration */
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
+ if (ret) {
+ dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, FSL_SAI_CLK_MAST1, 0, dir);
+ if (ret) {
+ dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * Per datasheet, AUDMIX expects 8 slots and 32 bits
+ * for every slot in TDM mode.
+ */
+ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, BIT(channels) - 1,
+ BIT(channels) - 1, 8, 32);
+ if (ret)
+ dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+
+ return ret;
+}
+
+static int imx_audmix_be_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct device *dev = rtd->card->dev;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+ int ret;
+
+ if (!tx)
+ return 0;
+
+ /* For playback the AUDMIX is slave */
+ fmt |= SND_SOC_DAIFMT_CBM_CFM;
+
+ /* set AUDMIX DAI configuration */
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
+ if (ret)
+ dev_err(dev, "failed to set AUDMIX DAI fmt: %d\n", ret);
+
+ return ret;
+}
+
+static struct snd_soc_ops imx_audmix_fe_ops = {
+ .startup = imx_audmix_fe_startup,
+ .hw_params = imx_audmix_fe_hw_params,
+};
+
+static struct snd_soc_ops imx_audmix_be_ops = {
+ .hw_params = imx_audmix_be_hw_params,
+};
+
+static int imx_audmix_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *audmix_np = NULL, *out_cpu_np = NULL;
+ struct platform_device *audmix_pdev = NULL;
+ struct platform_device *cpu_pdev;
+ struct of_phandle_args args;
+ struct imx_audmix *priv;
+ int i, num_dai, ret;
+ const char *fe_name_pref = "HiFi-AUDMIX-FE-";
+ char *be_name, *be_pb, *be_cp, *dai_name, *capture_dai_name;
+
+ if (pdev->dev.parent) {
+ audmix_np = pdev->dev.parent->of_node;
+ } else {
+ dev_err(&pdev->dev, "Missing parent device.\n");
+ return -EINVAL;
+ }
+
+ if (!audmix_np) {
+ dev_err(&pdev->dev, "Missign DT node for parent device.\n");
+ return -EINVAL;
+ }
+
+ audmix_pdev = of_find_device_by_node(audmix_np);
+ if (!audmix_pdev) {
+ dev_err(&pdev->dev, "Missing AUDMIX platform device for %s\n",
+ np->full_name);
+ return -EINVAL;
+ }
+
+ num_dai = of_count_phandle_with_args(audmix_np, "dais", NULL);
+ if (num_dai != FSL_AUDMIX_MAX_DAIS) {
+ dev_err(&pdev->dev, "Need 2 dais to be provided for %s\n",
+ audmix_np->full_name);
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->num_dai = 2 * num_dai;
+ priv->dai = devm_kzalloc(&pdev->dev, priv->num_dai *
+ sizeof(struct snd_soc_dai_link), GFP_KERNEL);
+ if (!priv->dai)
+ return -ENOMEM;
+
+ priv->num_dai_conf = num_dai;
+ priv->dai_conf = devm_kzalloc(&pdev->dev, priv->num_dai_conf *
+ sizeof(struct snd_soc_codec_conf),
+ GFP_KERNEL);
+ if (!priv->dai_conf)
+ return -ENOMEM;
+
+ priv->num_dapm_routes = 3 * num_dai;
+ priv->dapm_routes = devm_kzalloc(&pdev->dev, priv->num_dapm_routes *
+ sizeof(struct snd_soc_dapm_route),
+ GFP_KERNEL);
+ if (!priv->dapm_routes)
+ return -ENOMEM;
+
+ for (i = 0; i < num_dai; i++) {
+ ret = of_parse_phandle_with_args(audmix_np, "dais", NULL, i,
+ &args);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "of_parse_phandle_with_args failed\n");
+ return ret;
+ }
+
+ cpu_pdev = of_find_device_by_node(args.np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ return -EINVAL;
+ }
+
+ dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s",
+ fe_name_pref, args.np->full_name + 1);
+
+ dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
+
+ if (i == 0) {
+ out_cpu_np = args.np;
+ capture_dai_name =
+ devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
+ dai_name, "CPU-Capture");
+ }
+
+ priv->dai[i].name = dai_name;
+ priv->dai[i].stream_name = "HiFi-AUDMIX-FE";
+ priv->dai[i].codec_dai_name = "snd-soc-dummy-dai";
+ priv->dai[i].codec_name = "snd-soc-dummy";
+ priv->dai[i].cpu_of_node = args.np;
+ priv->dai[i].cpu_dai_name = dev_name(&cpu_pdev->dev);
+ priv->dai[i].platform_of_node = args.np;
+ priv->dai[i].dynamic = 1;
+ priv->dai[i].dpcm_playback = 1;
+ priv->dai[i].dpcm_capture = (i == 0 ? 1 : 0);
+ priv->dai[i].ignore_pmdown_time = 1;
+ priv->dai[i].ops = &imx_audmix_fe_ops;
+
+ /* Add AUDMIX Backend */
+ be_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+ "audmix-%d", i);
+ be_pb = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+ "AUDMIX-Playback-%d", i);
+ be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+ "AUDMIX-Capture-%d", i);
+
+ priv->dai[num_dai + i].name = be_name;
+ priv->dai[num_dai + i].codec_dai_name = "snd-soc-dummy-dai";
+ priv->dai[num_dai + i].codec_name = "snd-soc-dummy";
+ priv->dai[num_dai + i].cpu_of_node = audmix_np;
+ priv->dai[num_dai + i].cpu_dai_name = be_name;
+ priv->dai[num_dai + i].platform_name = "snd-soc-dummy";
+ priv->dai[num_dai + i].no_pcm = 1;
+ priv->dai[num_dai + i].dpcm_playback = 1;
+ priv->dai[num_dai + i].dpcm_capture = 1;
+ priv->dai[num_dai + i].ignore_pmdown_time = 1;
+ priv->dai[num_dai + i].ops = &imx_audmix_be_ops;
+
+ priv->dai_conf[i].of_node = args.np;
+ priv->dai_conf[i].name_prefix = dai_name;
+
+ priv->dapm_routes[i].source =
+ devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
+ dai_name, "CPU-Playback");
+ priv->dapm_routes[i].sink = be_pb;
+ priv->dapm_routes[num_dai + i].source = be_pb;
+ priv->dapm_routes[num_dai + i].sink = be_cp;
+ priv->dapm_routes[2 * num_dai + i].source = be_cp;
+ priv->dapm_routes[2 * num_dai + i].sink = capture_dai_name;
+ }
+
+ cpu_pdev = of_find_device_by_node(out_cpu_np);
+ if (!cpu_pdev) {
+ dev_err(&pdev->dev, "failed to find SAI platform device\n");
+ return -EINVAL;
+ }
+ priv->cpu_mclk = devm_clk_get(&cpu_pdev->dev, "mclk1");
+ if (IS_ERR(priv->cpu_mclk)) {
+ ret = PTR_ERR(priv->cpu_mclk);
+ dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret);
+ return -EINVAL;
+ }
+
+ priv->audmix_pdev = audmix_pdev;
+ priv->out_pdev = cpu_pdev;
+
+ priv->card.dai_link = priv->dai;
+ priv->card.num_links = priv->num_dai;
+ priv->card.codec_conf = priv->dai_conf;
+ priv->card.num_configs = priv->num_dai_conf;
+ priv->card.dapm_routes = priv->dapm_routes;
+ priv->card.num_dapm_routes = priv->num_dapm_routes;
+ priv->card.dev = pdev->dev.parent;
+ priv->card.owner = THIS_MODULE;
+ priv->card.name = "imx-audmix";
+
+ platform_set_drvdata(pdev, &priv->card);
+ snd_soc_card_set_drvdata(&priv->card, priv);
+
+ ret = devm_snd_soc_register_card(pdev->dev.parent, &priv->card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static struct platform_driver imx_audmix_driver = {
+ .probe = imx_audmix_probe,
+ .driver = {
+ .name = "imx-audmix",
+ .pm = &snd_soc_pm_ops,
+ },
+};
+module_platform_driver(imx_audmix_driver);
+
+MODULE_DESCRIPTION("NXP AUDMIX ASoC machine driver");
+MODULE_AUTHOR("Viorel Suman <viorel.suman@nxp.com>");
+MODULE_ALIAS("platform:imx-audmix");
+MODULE_LICENSE("GPL v2");
--
2.7.4
^ permalink raw reply related
* [PATCH v5 2/3] ASoC: add fsl_audmix DT binding documentation
From: Viorel Suman @ 2019-02-15 14:01 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
Jaroslav Kysela, Takashi Iwai, Timur Tabi, Nicolin Chen, Xiubo Li,
Fabio Estevam, Viorel Suman, S.j. Wang, Daniel Baluta,
Cosmin Samoila
Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
linux-kernel@vger.kernel.org, Viorel Suman, dl-linux-imx,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1550239285-12587-1-git-send-email-viorel.suman@nxp.com>
Add the DT binding documentation for NXP Audio Mixer
CPU DAI driver.
Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
---
.../devicetree/bindings/sound/fsl,audmix.txt | 50 ++++++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt
diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.txt b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
new file mode 100644
index 0000000..840b7e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
@@ -0,0 +1,50 @@
+NXP Audio Mixer (AUDMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two
+audio streams into a single audio stream. Audio Mixer has two input serial
+audio interfaces. These are driven by two Synchronous Audio interface
+modules (SAI). Each input serial interface carries 8 audio channels in its
+frame in TDM manner. Mixer mixes audio samples of corresponding channels
+from two interfaces into a single sample. Before mixing, audio samples of
+two inputs can be attenuated based on configuration. The output of the
+Audio Mixer is also a serial audio interface. Like input interfaces it has
+the same TDM frame format. This output is used to drive the serial DAC TDM
+interface of audio codec and also sent to the external pins along with the
+receive path of normal audio SAI module for readback by the CPU.
+
+The output of Audio Mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio
+input streams must have same audio sample rate with same number of channels
+in TDM frame to be eligible for mixing.
+
+Device driver required properties:
+=================================
+ - compatible : Compatible list, contains "fsl,imx8qm-audmix"
+
+ - reg : Offset and length of the register set for the device.
+
+ - clocks : Must contain an entry for each entry in clock-names.
+
+ - clock-names : Must include the "ipg" for register access.
+
+ - power-domains : Must contain the phandle to AUDMIX power domain node
+
+ - dais : Must contain a list of phandles to AUDMIX connected
+ DAIs. The current implementation requires two phandles
+ to SAI interfaces to be provided, the first SAI in the
+ list being used to route the AUDMIX output.
+
+Device driver configuration example:
+======================================
+ audmix: audmix@59840000 {
+ compatible = "fsl,imx8qm-audmix";
+ reg = <0x0 0x59840000 0x0 0x10000>;
+ clocks = <&clk IMX8QXP_AUD_AUDMIX_IPG>;
+ clock-names = "ipg";
+ power-domains = <&pd_audmix>;
+ dais = <&sai4>, <&sai5>;
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH v5 1/3] ASoC: fsl: Add Audio Mixer CPU DAI driver
From: Viorel Suman @ 2019-02-15 14:01 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
Jaroslav Kysela, Takashi Iwai, Timur Tabi, Nicolin Chen, Xiubo Li,
Fabio Estevam, Viorel Suman, S.j. Wang, Daniel Baluta,
Cosmin Samoila
Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
linux-kernel@vger.kernel.org, Viorel Suman, dl-linux-imx,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1550239285-12587-1-git-send-email-viorel.suman@nxp.com>
This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
The Audio Mixer is a on-chip functional module that allows mixing of
two audio streams into a single audio stream.
Audio Mixer datasheet is available here:
https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf
Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
---
sound/soc/fsl/Kconfig | 7 +
sound/soc/fsl/Makefile | 3 +
sound/soc/fsl/fsl_audmix.c | 578 +++++++++++++++++++++++++++++++++++++++++++++
sound/soc/fsl/fsl_audmix.h | 102 ++++++++
4 files changed, 690 insertions(+)
create mode 100644 sound/soc/fsl/fsl_audmix.c
create mode 100644 sound/soc/fsl/fsl_audmix.h
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 7b1d997..0af2e056 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,13 @@ config SND_SOC_FSL_SAI
This option is only useful for out-of-tree drivers since
in-tree drivers select it automatically.
+config SND_SOC_FSL_AUDMIX
+ tristate "Audio Mixer (AUDMIX) module support"
+ select REGMAP_MMIO
+ help
+ Say Y if you want to add Audio Mixer (AUDMIX)
+ support for the NXP iMX CPUs.
+
config SND_SOC_FSL_SSI
tristate "Synchronous Serial Interface module (SSI) support"
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 3c0ff31..4172d5a 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,6 +12,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
# Freescale SSI/DMA/SAI/SPDIF Support
+snd-soc-fsl-audmix-objs := fsl_audmix.o
snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
snd-soc-fsl-sai-objs := fsl_sai.o
@@ -22,6 +23,8 @@ snd-soc-fsl-esai-objs := fsl_esai.o
snd-soc-fsl-micfil-objs := fsl_micfil.o
snd-soc-fsl-utils-objs := fsl_utils.o
snd-soc-fsl-dma-objs := fsl_dma.o
+
+obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
new file mode 100644
index 0000000..07b72a3
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -0,0 +1,578 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#include "fsl_audmix.h"
+
+#define SOC_ENUM_SINGLE_S(xreg, xshift, xtexts) \
+ SOC_ENUM_SINGLE(xreg, xshift, ARRAY_SIZE(xtexts), xtexts)
+
+static const char
+ *tdm_sel[] = { "TDM1", "TDM2", },
+ *mode_sel[] = { "Disabled", "TDM1", "TDM2", "Mixed", },
+ *width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
+ *endis_sel[] = { "Disabled", "Enabled", },
+ *updn_sel[] = { "Downward", "Upward", },
+ *mask_sel[] = { "Unmask", "Mask", };
+
+static const struct soc_enum fsl_audmix_enum[] = {
+/* FSL_AUDMIX_CTR enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MIXCLK_SHIFT, tdm_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTSRC_SHIFT, mode_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTWIDTH_SHIFT, width_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKRTDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKCKDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCMODE_SHIFT, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCSRC_SHIFT, tdm_sel),
+/* FSL_AUDMIX_ATCR0 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 1, updn_sel),
+/* FSL_AUDMIX_ATCR1 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 1, updn_sel),
+};
+
+struct fsl_audmix_state {
+ u8 tdms;
+ u8 clk;
+ char msg[64];
+};
+
+static const struct fsl_audmix_state prms[4][4] = {{
+ /* DIS->DIS, do nothing */
+ { .tdms = 0, .clk = 0, .msg = "" },
+ /* DIS->TDM1*/
+ { .tdms = 1, .clk = 1, .msg = "DIS->TDM1: TDM1 not started!\n" },
+ /* DIS->TDM2*/
+ { .tdms = 2, .clk = 2, .msg = "DIS->TDM2: TDM2 not started!\n" },
+ /* DIS->MIX */
+ { .tdms = 3, .clk = 0, .msg = "DIS->MIX: Please start both TDMs!\n" }
+}, { /* TDM1->DIS */
+ { .tdms = 1, .clk = 0, .msg = "TDM1->DIS: TDM1 not started!\n" },
+ /* TDM1->TDM1, do nothing */
+ { .tdms = 0, .clk = 0, .msg = "" },
+ /* TDM1->TDM2 */
+ { .tdms = 3, .clk = 2, .msg = "TDM1->TDM2: Please start both TDMs!\n" },
+ /* TDM1->MIX */
+ { .tdms = 3, .clk = 0, .msg = "TDM1->MIX: Please start both TDMs!\n" }
+}, { /* TDM2->DIS */
+ { .tdms = 2, .clk = 0, .msg = "TDM2->DIS: TDM2 not started!\n" },
+ /* TDM2->TDM1 */
+ { .tdms = 3, .clk = 1, .msg = "TDM2->TDM1: Please start both TDMs!\n" },
+ /* TDM2->TDM2, do nothing */
+ { .tdms = 0, .clk = 0, .msg = "" },
+ /* TDM2->MIX */
+ { .tdms = 3, .clk = 0, .msg = "TDM2->MIX: Please start both TDMs!\n" }
+}, { /* MIX->DIS */
+ { .tdms = 3, .clk = 0, .msg = "MIX->DIS: Please start both TDMs!\n" },
+ /* MIX->TDM1 */
+ { .tdms = 3, .clk = 1, .msg = "MIX->TDM1: Please start both TDMs!\n" },
+ /* MIX->TDM2 */
+ { .tdms = 3, .clk = 2, .msg = "MIX->TDM2: Please start both TDMs!\n" },
+ /* MIX->MIX, do nothing */
+ { .tdms = 0, .clk = 0, .msg = "" }
+}, };
+
+static int fsl_audmix_state_trans(struct snd_soc_component *comp,
+ unsigned int *mask, unsigned int *ctr,
+ const struct fsl_audmix_state prm)
+{
+ struct fsl_audmix *priv = snd_soc_component_get_drvdata(comp);
+ /* Enforce all required TDMs are started */
+ if ((priv->tdms & prm.tdms) != prm.tdms) {
+ dev_dbg(comp->dev, prm.msg);
+ return -EINVAL;
+ }
+
+ switch (prm.clk) {
+ case 1:
+ case 2:
+ /* Set mix clock */
+ (*mask) |= FSL_AUDMIX_CTR_MIXCLK_MASK;
+ (*ctr) |= FSL_AUDMIX_CTR_MIXCLK(prm.clk - 1);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int fsl_audmix_put_mix_clk_src(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_audmix *priv = snd_soc_component_get_drvdata(comp);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ unsigned int reg_val, val, mix_clk;
+ int ret = 0;
+
+ /* Get current state */
+ ret = snd_soc_component_read(comp, FSL_AUDMIX_CTR, ®_val);
+ if (ret)
+ return ret;
+
+ mix_clk = ((reg_val & FSL_AUDMIX_CTR_MIXCLK_MASK)
+ >> FSL_AUDMIX_CTR_MIXCLK_SHIFT);
+ val = snd_soc_enum_item_to_val(e, item[0]);
+
+ dev_dbg(comp->dev, "TDMs=x%08x, val=x%08x\n", priv->tdms, val);
+
+ /**
+ * Ensure the current selected mixer clock is available
+ * for configuration propagation
+ */
+ if (!(priv->tdms & BIT(mix_clk))) {
+ dev_err(comp->dev,
+ "Started TDM%d needed for config propagation!\n",
+ mix_clk + 1);
+ return -EINVAL;
+ }
+
+ if (!(priv->tdms & BIT(val))) {
+ dev_err(comp->dev,
+ "The selected clock source has no TDM%d enabled!\n",
+ val + 1);
+ return -EINVAL;
+ }
+
+ return snd_soc_put_enum_double(kcontrol, ucontrol);
+}
+
+static int fsl_audmix_put_out_src(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct fsl_audmix *priv = snd_soc_component_get_drvdata(comp);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ u32 out_src, mix_clk;
+ unsigned int reg_val, val, mask = 0, ctr = 0;
+ int ret = 0;
+
+ /* Get current state */
+ ret = snd_soc_component_read(comp, FSL_AUDMIX_CTR, ®_val);
+ if (ret)
+ return ret;
+
+ /* "From" state */
+ out_src = ((reg_val & FSL_AUDMIX_CTR_OUTSRC_MASK)
+ >> FSL_AUDMIX_CTR_OUTSRC_SHIFT);
+ mix_clk = ((reg_val & FSL_AUDMIX_CTR_MIXCLK_MASK)
+ >> FSL_AUDMIX_CTR_MIXCLK_SHIFT);
+
+ /* "To" state */
+ val = snd_soc_enum_item_to_val(e, item[0]);
+
+ dev_dbg(comp->dev, "TDMs=x%08x, val=x%08x\n", priv->tdms, val);
+
+ /* Check if state is changing ... */
+ if (out_src == val)
+ return 0;
+ /**
+ * Ensure the current selected mixer clock is available
+ * for configuration propagation
+ */
+ if (!(priv->tdms & BIT(mix_clk))) {
+ dev_err(comp->dev,
+ "Started TDM%d needed for config propagation!\n",
+ mix_clk + 1);
+ return -EINVAL;
+ }
+
+ /* Check state transition constraints */
+ ret = fsl_audmix_state_trans(comp, &mask, &ctr, prms[out_src][val]);
+ if (ret)
+ return ret;
+
+ /* Complete transition to new state */
+ mask |= FSL_AUDMIX_CTR_OUTSRC_MASK;
+ ctr |= FSL_AUDMIX_CTR_OUTSRC(val);
+
+ return snd_soc_component_update_bits(comp, FSL_AUDMIX_CTR, mask, ctr);
+}
+
+static const struct snd_kcontrol_new fsl_audmix_snd_controls[] = {
+ /* FSL_AUDMIX_CTR controls */
+ SOC_ENUM_EXT("Mixing Clock Source", fsl_audmix_enum[0],
+ snd_soc_get_enum_double, fsl_audmix_put_mix_clk_src),
+ SOC_ENUM_EXT("Output Source", fsl_audmix_enum[1],
+ snd_soc_get_enum_double, fsl_audmix_put_out_src),
+ SOC_ENUM("Output Width", fsl_audmix_enum[2]),
+ SOC_ENUM("Frame Rate Diff Error", fsl_audmix_enum[3]),
+ SOC_ENUM("Clock Freq Diff Error", fsl_audmix_enum[4]),
+ SOC_ENUM("Sync Mode Config", fsl_audmix_enum[5]),
+ SOC_ENUM("Sync Mode Clk Source", fsl_audmix_enum[6]),
+ /* TDM1 Attenuation controls */
+ SOC_ENUM("TDM1 Attenuation", fsl_audmix_enum[7]),
+ SOC_ENUM("TDM1 Attenuation Direction", fsl_audmix_enum[8]),
+ SOC_SINGLE("TDM1 Attenuation Step Divider", FSL_AUDMIX_ATCR0,
+ 2, 0x00fff, 0),
+ SOC_SINGLE("TDM1 Attenuation Initial Value", FSL_AUDMIX_ATIVAL0,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM1 Attenuation Step Up Factor", FSL_AUDMIX_ATSTPUP0,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM1 Attenuation Step Down Factor", FSL_AUDMIX_ATSTPDN0,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM1 Attenuation Step Target", FSL_AUDMIX_ATSTPTGT0,
+ 0, 0x3ffff, 0),
+ /* TDM2 Attenuation controls */
+ SOC_ENUM("TDM2 Attenuation", fsl_audmix_enum[9]),
+ SOC_ENUM("TDM2 Attenuation Direction", fsl_audmix_enum[10]),
+ SOC_SINGLE("TDM2 Attenuation Step Divider", FSL_AUDMIX_ATCR1,
+ 2, 0x00fff, 0),
+ SOC_SINGLE("TDM2 Attenuation Initial Value", FSL_AUDMIX_ATIVAL1,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM2 Attenuation Step Up Factor", FSL_AUDMIX_ATSTPUP1,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM2 Attenuation Step Down Factor", FSL_AUDMIX_ATSTPDN1,
+ 0, 0x3ffff, 0),
+ SOC_SINGLE("TDM2 Attenuation Step Target", FSL_AUDMIX_ATSTPTGT1,
+ 0, 0x3ffff, 0),
+};
+
+static int fsl_audmix_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_component *comp = dai->component;
+ u32 mask = 0, ctr = 0;
+
+ /* AUDMIX is working in DSP_A format only */
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_DSP_A:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* For playback the AUDMIX is slave, and for record is master */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_IB_NF:
+ /* Output data will be written on positive edge of the clock */
+ ctr |= FSL_AUDMIX_CTR_OUTCKPOL(0);
+ break;
+ case SND_SOC_DAIFMT_NB_NF:
+ /* Output data will be written on negative edge of the clock */
+ ctr |= FSL_AUDMIX_CTR_OUTCKPOL(1);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mask |= FSL_AUDMIX_CTR_OUTCKPOL_MASK;
+
+ return snd_soc_component_update_bits(comp, FSL_AUDMIX_CTR, mask, ctr);
+}
+
+static int fsl_audmix_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct fsl_audmix *priv = snd_soc_dai_get_drvdata(dai);
+
+ /* Capture stream shall not be handled */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ return 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ priv->tdms |= BIT(dai->driver->id);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ priv->tdms &= ~BIT(dai->driver->id);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops fsl_audmix_dai_ops = {
+ .set_fmt = fsl_audmix_dai_set_fmt,
+ .trigger = fsl_audmix_dai_trigger,
+};
+
+static struct snd_soc_dai_driver fsl_audmix_dai[] = {
+ {
+ .id = 0,
+ .name = "audmix-0",
+ .playback = {
+ .stream_name = "AUDMIX-Playback-0",
+ .channels_min = 8,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = FSL_AUDMIX_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AUDMIX-Capture-0",
+ .channels_min = 8,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = FSL_AUDMIX_FORMATS,
+ },
+ .ops = &fsl_audmix_dai_ops,
+ },
+ {
+ .id = 1,
+ .name = "audmix-1",
+ .playback = {
+ .stream_name = "AUDMIX-Playback-1",
+ .channels_min = 8,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = FSL_AUDMIX_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AUDMIX-Capture-1",
+ .channels_min = 8,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = FSL_AUDMIX_FORMATS,
+ },
+ .ops = &fsl_audmix_dai_ops,
+ },
+};
+
+static const struct snd_soc_component_driver fsl_audmix_component = {
+ .name = "fsl-audmix-dai",
+ .controls = fsl_audmix_snd_controls,
+ .num_controls = ARRAY_SIZE(fsl_audmix_snd_controls),
+};
+
+static bool fsl_audmix_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case FSL_AUDMIX_CTR:
+ case FSL_AUDMIX_STR:
+ case FSL_AUDMIX_ATCR0:
+ case FSL_AUDMIX_ATIVAL0:
+ case FSL_AUDMIX_ATSTPUP0:
+ case FSL_AUDMIX_ATSTPDN0:
+ case FSL_AUDMIX_ATSTPTGT0:
+ case FSL_AUDMIX_ATTNVAL0:
+ case FSL_AUDMIX_ATSTP0:
+ case FSL_AUDMIX_ATCR1:
+ case FSL_AUDMIX_ATIVAL1:
+ case FSL_AUDMIX_ATSTPUP1:
+ case FSL_AUDMIX_ATSTPDN1:
+ case FSL_AUDMIX_ATSTPTGT1:
+ case FSL_AUDMIX_ATTNVAL1:
+ case FSL_AUDMIX_ATSTP1:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool fsl_audmix_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case FSL_AUDMIX_CTR:
+ case FSL_AUDMIX_ATCR0:
+ case FSL_AUDMIX_ATIVAL0:
+ case FSL_AUDMIX_ATSTPUP0:
+ case FSL_AUDMIX_ATSTPDN0:
+ case FSL_AUDMIX_ATSTPTGT0:
+ case FSL_AUDMIX_ATCR1:
+ case FSL_AUDMIX_ATIVAL1:
+ case FSL_AUDMIX_ATSTPUP1:
+ case FSL_AUDMIX_ATSTPDN1:
+ case FSL_AUDMIX_ATSTPTGT1:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct reg_default fsl_audmix_reg[] = {
+ { FSL_AUDMIX_CTR, 0x00060 },
+ { FSL_AUDMIX_STR, 0x00003 },
+ { FSL_AUDMIX_ATCR0, 0x00000 },
+ { FSL_AUDMIX_ATIVAL0, 0x3FFFF },
+ { FSL_AUDMIX_ATSTPUP0, 0x2AAAA },
+ { FSL_AUDMIX_ATSTPDN0, 0x30000 },
+ { FSL_AUDMIX_ATSTPTGT0, 0x00010 },
+ { FSL_AUDMIX_ATTNVAL0, 0x00000 },
+ { FSL_AUDMIX_ATSTP0, 0x00000 },
+ { FSL_AUDMIX_ATCR1, 0x00000 },
+ { FSL_AUDMIX_ATIVAL1, 0x3FFFF },
+ { FSL_AUDMIX_ATSTPUP1, 0x2AAAA },
+ { FSL_AUDMIX_ATSTPDN1, 0x30000 },
+ { FSL_AUDMIX_ATSTPTGT1, 0x00010 },
+ { FSL_AUDMIX_ATTNVAL1, 0x00000 },
+ { FSL_AUDMIX_ATSTP1, 0x00000 },
+};
+
+static const struct regmap_config fsl_audmix_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = FSL_AUDMIX_ATSTP1,
+ .reg_defaults = fsl_audmix_reg,
+ .num_reg_defaults = ARRAY_SIZE(fsl_audmix_reg),
+ .readable_reg = fsl_audmix_readable_reg,
+ .writeable_reg = fsl_audmix_writeable_reg,
+ .cache_type = REGCACHE_FLAT,
+};
+
+static const struct of_device_id fsl_audmix_ids[] = {
+ {
+ .compatible = "fsl,imx8qm-audmix",
+ .data = "imx-audmix",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_audmix_ids);
+
+static int fsl_audmix_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct fsl_audmix *priv;
+ struct resource *res;
+ const char *mdrv;
+ const struct of_device_id *of_id;
+ void __iomem *regs;
+ int ret;
+
+ of_id = of_match_device(fsl_audmix_ids, dev);
+ if (!of_id || !of_id->data)
+ return -EINVAL;
+
+ mdrv = of_id->data;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ /* Get the addresses */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
+
+ priv->regmap = devm_regmap_init_mmio_clk(dev, "ipg", regs,
+ &fsl_audmix_regmap_config);
+ if (IS_ERR(priv->regmap)) {
+ dev_err(dev, "failed to init regmap\n");
+ return PTR_ERR(priv->regmap);
+ }
+
+ priv->ipg_clk = devm_clk_get(dev, "ipg");
+ if (IS_ERR(priv->ipg_clk)) {
+ dev_err(dev, "failed to get ipg clock\n");
+ return PTR_ERR(priv->ipg_clk);
+ }
+
+ platform_set_drvdata(pdev, priv);
+ pm_runtime_enable(dev);
+
+ ret = devm_snd_soc_register_component(dev, &fsl_audmix_component,
+ fsl_audmix_dai,
+ ARRAY_SIZE(fsl_audmix_dai));
+ if (ret) {
+ dev_err(dev, "failed to register ASoC DAI\n");
+ return ret;
+ }
+
+ priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0);
+ if (IS_ERR(priv->pdev)) {
+ ret = PTR_ERR(priv->pdev);
+ dev_err(dev, "failed to register platform %s: %d\n", mdrv, ret);
+ }
+
+ return ret;
+}
+
+static int fsl_audmix_remove(struct platform_device *pdev)
+{
+ struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev);
+
+ if (priv->pdev)
+ platform_device_unregister(priv->pdev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_audmix_runtime_resume(struct device *dev)
+{
+ struct fsl_audmix *priv = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(priv->ipg_clk);
+ if (ret) {
+ dev_err(dev, "Failed to enable IPG clock: %d\n", ret);
+ return ret;
+ }
+
+ regcache_cache_only(priv->regmap, false);
+ regcache_mark_dirty(priv->regmap);
+
+ return regcache_sync(priv->regmap);
+}
+
+static int fsl_audmix_runtime_suspend(struct device *dev)
+{
+ struct fsl_audmix *priv = dev_get_drvdata(dev);
+
+ regcache_cache_only(priv->regmap, true);
+
+ clk_disable_unprepare(priv->ipg_clk);
+
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops fsl_audmix_pm = {
+ SET_RUNTIME_PM_OPS(fsl_audmix_runtime_suspend,
+ fsl_audmix_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
+};
+
+static struct platform_driver fsl_audmix_driver = {
+ .probe = fsl_audmix_probe,
+ .remove = fsl_audmix_remove,
+ .driver = {
+ .name = "fsl-audmix",
+ .of_match_table = fsl_audmix_ids,
+ .pm = &fsl_audmix_pm,
+ },
+};
+module_platform_driver(fsl_audmix_driver);
+
+MODULE_DESCRIPTION("NXP AUDMIX ASoC DAI driver");
+MODULE_AUTHOR("Viorel Suman <viorel.suman@nxp.com>");
+MODULE_ALIAS("platform:fsl-audmix");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_audmix.h b/sound/soc/fsl/fsl_audmix.h
new file mode 100644
index 0000000..7812ffe
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#ifndef __FSL_AUDMIX_H
+#define __FSL_AUDMIX_H
+
+#define FSL_AUDMIX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+/* AUDMIX Registers */
+#define FSL_AUDMIX_CTR 0x200 /* Control */
+#define FSL_AUDMIX_STR 0x204 /* Status */
+
+#define FSL_AUDMIX_ATCR0 0x208 /* Attenuation Control */
+#define FSL_AUDMIX_ATIVAL0 0x20c /* Attenuation Initial Value */
+#define FSL_AUDMIX_ATSTPUP0 0x210 /* Attenuation step up factor */
+#define FSL_AUDMIX_ATSTPDN0 0x214 /* Attenuation step down factor */
+#define FSL_AUDMIX_ATSTPTGT0 0x218 /* Attenuation step target */
+#define FSL_AUDMIX_ATTNVAL0 0x21c /* Attenuation Value */
+#define FSL_AUDMIX_ATSTP0 0x220 /* Attenuation step number */
+
+#define FSL_AUDMIX_ATCR1 0x228 /* Attenuation Control */
+#define FSL_AUDMIX_ATIVAL1 0x22c /* Attenuation Initial Value */
+#define FSL_AUDMIX_ATSTPUP1 0x230 /* Attenuation step up factor */
+#define FSL_AUDMIX_ATSTPDN1 0x234 /* Attenuation step down factor */
+#define FSL_AUDMIX_ATSTPTGT1 0x238 /* Attenuation step target */
+#define FSL_AUDMIX_ATTNVAL1 0x23c /* Attenuation Value */
+#define FSL_AUDMIX_ATSTP1 0x240 /* Attenuation step number */
+
+/* AUDMIX Control Register */
+#define FSL_AUDMIX_CTR_MIXCLK_SHIFT 0
+#define FSL_AUDMIX_CTR_MIXCLK_MASK BIT(FSL_AUDMIX_CTR_MIXCLK_SHIFT)
+#define FSL_AUDMIX_CTR_MIXCLK(i) ((i) << FSL_AUDMIX_CTR_MIXCLK_SHIFT)
+#define FSL_AUDMIX_CTR_OUTSRC_SHIFT 1
+#define FSL_AUDMIX_CTR_OUTSRC_MASK (0x3 << FSL_AUDMIX_CTR_OUTSRC_SHIFT)
+#define FSL_AUDMIX_CTR_OUTSRC(i) (((i) << FSL_AUDMIX_CTR_OUTSRC_SHIFT)\
+ & FSL_AUDMIX_CTR_OUTSRC_MASK)
+#define FSL_AUDMIX_CTR_OUTWIDTH_SHIFT 3
+#define FSL_AUDMIX_CTR_OUTWIDTH_MASK (0x7 << FSL_AUDMIX_CTR_OUTWIDTH_SHIFT)
+#define FSL_AUDMIX_CTR_OUTWIDTH(i) (((i) << FSL_AUDMIX_CTR_OUTWIDTH_SHIFT)\
+ & FSL_AUDMIX_CTR_OUTWIDTH_MASK)
+#define FSL_AUDMIX_CTR_OUTCKPOL_SHIFT 6
+#define FSL_AUDMIX_CTR_OUTCKPOL_MASK BIT(FSL_AUDMIX_CTR_OUTCKPOL_SHIFT)
+#define FSL_AUDMIX_CTR_OUTCKPOL(i) ((i) << FSL_AUDMIX_CTR_OUTCKPOL_SHIFT)
+#define FSL_AUDMIX_CTR_MASKRTDF_SHIFT 7
+#define FSL_AUDMIX_CTR_MASKRTDF_MASK BIT(FSL_AUDMIX_CTR_MASKRTDF_SHIFT)
+#define FSL_AUDMIX_CTR_MASKRTDF(i) ((i) << FSL_AUDMIX_CTR_MASKRTDF_SHIFT)
+#define FSL_AUDMIX_CTR_MASKCKDF_SHIFT 8
+#define FSL_AUDMIX_CTR_MASKCKDF_MASK BIT(FSL_AUDMIX_CTR_MASKCKDF_SHIFT)
+#define FSL_AUDMIX_CTR_MASKCKDF(i) ((i) << FSL_AUDMIX_CTR_MASKCKDF_SHIFT)
+#define FSL_AUDMIX_CTR_SYNCMODE_SHIFT 9
+#define FSL_AUDMIX_CTR_SYNCMODE_MASK BIT(FSL_AUDMIX_CTR_SYNCMODE_SHIFT)
+#define FSL_AUDMIX_CTR_SYNCMODE(i) ((i) << FSL_AUDMIX_CTR_SYNCMODE_SHIFT)
+#define FSL_AUDMIX_CTR_SYNCSRC_SHIFT 10
+#define FSL_AUDMIX_CTR_SYNCSRC_MASK BIT(FSL_AUDMIX_CTR_SYNCSRC_SHIFT)
+#define FSL_AUDMIX_CTR_SYNCSRC(i) ((i) << FSL_AUDMIX_CTR_SYNCSRC_SHIFT)
+
+/* AUDMIX Status Register */
+#define FSL_AUDMIX_STR_RATEDIFF BIT(0)
+#define FSL_AUDMIX_STR_CLKDIFF BIT(1)
+#define FSL_AUDMIX_STR_MIXSTAT_SHIFT 2
+#define FSL_AUDMIX_STR_MIXSTAT_MASK (0x3 << FSL_AUDMIX_STR_MIXSTAT_SHIFT)
+#define FSL_AUDMIX_STR_MIXSTAT(i) (((i) & FSL_AUDMIX_STR_MIXSTAT_MASK) \
+ >> FSL_AUDMIX_STR_MIXSTAT_SHIFT)
+/* AUDMIX Attenuation Control Register */
+#define FSL_AUDMIX_ATCR_AT_EN BIT(0)
+#define FSL_AUDMIX_ATCR_AT_UPDN BIT(1)
+#define FSL_AUDMIX_ATCR_ATSTPDIF_SHIFT 2
+#define FSL_AUDMIX_ATCR_ATSTPDFI_MASK \
+ (0xfff << FSL_AUDMIX_ATCR_ATSTPDIF_SHIFT)
+
+/* AUDMIX Attenuation Initial Value Register */
+#define FSL_AUDMIX_ATIVAL_ATINVAL_MASK 0x3FFFF
+
+/* AUDMIX Attenuation Step Up Factor Register */
+#define FSL_AUDMIX_ATSTPUP_ATSTEPUP_MASK 0x3FFFF
+
+/* AUDMIX Attenuation Step Down Factor Register */
+#define FSL_AUDMIX_ATSTPDN_ATSTEPDN_MASK 0x3FFFF
+
+/* AUDMIX Attenuation Step Target Register */
+#define FSL_AUDMIX_ATSTPTGT_ATSTPTG_MASK 0x3FFFF
+
+/* AUDMIX Attenuation Value Register */
+#define FSL_AUDMIX_ATTNVAL_ATCURVAL_MASK 0x3FFFF
+
+/* AUDMIX Attenuation Step Number Register */
+#define FSL_AUDMIX_ATSTP_STPCTR_MASK 0x3FFFF
+
+#define FSL_AUDMIX_MAX_DAIS 2
+struct fsl_audmix {
+ struct platform_device *pdev;
+ struct regmap *regmap;
+ struct clk *ipg_clk;
+ u8 tdms;
+};
+
+#endif /* __FSL_AUDMIX_H */
--
2.7.4
^ permalink raw reply related
* [PATCH v5 0/3] Add NXP AUDMIX device and machine drivers
From: Viorel Suman @ 2019-02-15 14:01 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
Jaroslav Kysela, Takashi Iwai, Timur Tabi, Nicolin Chen, Xiubo Li,
Fabio Estevam, Viorel Suman, S.j. Wang, Daniel Baluta,
Cosmin Samoila
Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
linux-kernel@vger.kernel.org, Viorel Suman, dl-linux-imx,
linuxppc-dev@lists.ozlabs.org
The patchset adds NXP Audio Mixer (AUDMIX) device and machine
drivers and related DT bindings documentation.
Changes since V4:
1. Removed "model" attribute from device driver DT bindings documentation
as suggested by Nicolin.
Changes since V3:
1. Removed machine driver DT bindings documentation.
2. Trigger machine driver probe from device driver as suggested by Nicolin.
Changes since V2:
1. Moved "dais" node from machine driver DTS node to device driver DTS node
as suggested by Rob.
Changes since V1:
1. Original patch split into distinct patches for the device driver and
DT binding documentation.
2. Replaced AMIX with AUDMIX in both code and file names as it looks more
RM-compliant.
3. Removed polarity control from CPU DAI driver as suggested by Nicolin.
4. Added machine driver and related DT binding documentation.
Viorel Suman (3):
ASoC: fsl: Add Audio Mixer CPU DAI driver
ASoC: add fsl_audmix DT binding documentation
ASoC: fsl: Add Audio Mixer machine driver
.../devicetree/bindings/sound/fsl,audmix.txt | 50 ++
sound/soc/fsl/Kconfig | 16 +
sound/soc/fsl/Makefile | 5 +
sound/soc/fsl/fsl_audmix.c | 578 +++++++++++++++++++++
sound/soc/fsl/fsl_audmix.h | 102 ++++
sound/soc/fsl/imx-audmix.c | 327 ++++++++++++
6 files changed, 1078 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt
create mode 100644 sound/soc/fsl/fsl_audmix.c
create mode 100644 sound/soc/fsl/fsl_audmix.h
create mode 100644 sound/soc/fsl/imx-audmix.c
--
2.7.4
^ permalink raw reply
* [PATCH] ASoC: fsl_esai: fix register setting issue in RIGHT_J mode
From: S.j. Wang @ 2019-02-15 11:04 UTC (permalink / raw)
To: timur@kernel.org, nicoleotsuka@gmail.com, Xiubo.Lee@gmail.com,
festevam@gmail.com
Cc: alsa-devel@alsa-project.org, linuxppc-dev@lists.ozlabs.org
The ESAI_xCR_xWA is xCR's bit, not the xCCR's bit, driver set it to
wrong register, correct it.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
sound/soc/fsl/fsl_esai.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 57b484768a58..afe67c865330 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -398,7 +398,8 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
break;
case SND_SOC_DAIFMT_RIGHT_J:
/* Data on rising edge of bclk, frame high, right aligned */
- xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCR_xWA;
+ xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
+ xcr |= ESAI_xCR_xWA;
break;
case SND_SOC_DAIFMT_DSP_A:
/* Data on rising edge of bclk, frame high, 1clk before data */
@@ -455,12 +456,12 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return -EINVAL;
}
- mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR;
+ mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR | ESAI_xCR_xWA;
regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
- ESAI_xCCR_xFSD | ESAI_xCCR_xCKD | ESAI_xCR_xWA;
+ ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
--
1.9.1
^ permalink raw reply related
* Re: Kernel panic when loading the IDE controller driver
From: sgosavi1 @ 2019-02-15 11:27 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20190214191443.5f64bb56@kitsune.suse.cz>
Hi,
> Hopefully there are examples of passing these values through ACPI.
Are you suggesting here to look at the ide-acpi.c sourc file available as
part of the driver code? In my original post I mentioned that I have
modified the ide-generic.c source file to use the IO port addresses and IRQ
number that we used in the older kernel. Also, added code in the kernel
under arch/PowerPC/mm/init_32.c source to configure the addresses required
by the driver as IO ports. But the error I am getting still continues to
suggest that probably the required address range is still setup by the
kernel as IO ports.
How can we configure a set of virtual address as IO ports in the kernel
version 4.15.13?
Sachin
--
Sent from: http://linuxppc.10917.n7.nabble.com/linuxppc-dev-f3.html
^ permalink raw reply
* Re: [PATCH] powerpc: use $(origin ARCH) to select KBUILD_DEFCONFIG
From: Mathieu Malaterre @ 2019-02-15 11:00 UTC (permalink / raw)
To: Masahiro Yamada; +Cc: linuxppc-dev, LKML, Paul Mackerras
In-Reply-To: <1550223519-18290-1-git-send-email-yamada.masahiro@socionext.com>
On Fri, Feb 15, 2019 at 10:41 AM Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:
>
> I often test all Kconfig commands for all architectures. To ease my
> workflow, I want 'make defconfig' at least working without any cross
> compiler.
>
> Currently, arch/powerpc/Makefile checks CROSS_COMPILE to decide the
> default defconfig source.
>
> If CROSS_COMPILE is unset, it is likely to be the native build, so
> 'uname -m' is useful to choose the defconfig. If CROSS_COMPILE is set,
> the user is cross-building (i.e. 'uname -m' is probably x86_64), so
> it falls back to ppc64_defconfig. Yup, make sense.
>
> However, I want to run 'make ARCH=* defconfig' without setting
> CROSS_COMPILE for each architecture.
>
> My suggestion is to check $(origin ARCH).
>
> When you cross-compile the kernel, you need to set ARCH from your
> environment or from the command line.
>
> For the native build, you do not need to set ARCH. The default in
> the top Makefile is used:
>
> ARCH ?= $(SUBARCH)
>
> Hence, $(origin ARCH) returns 'file'.
>
> Before this commit, 'make ARCH=powerpc defconfig' failed:
In case you have not seen it, please check:
http://patchwork.ozlabs.org/patch/1037835/
> $ make ARCH=powerpc defconfig
> *** Default configuration is based on target 'x86_64_defconfig'
> ***
> *** Can't find default configuration "arch/powerpc/configs/x86_64_defconfig"!
> ***
>
> After this commit, it will succeed:
>
> $ make ARCH=powerpc defconfig
> *** Default configuration is based on 'ppc64_defconfig'
> #
> # configuration written to .config
> #
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
> ---
>
> arch/powerpc/Makefile | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
> index ac03334..f989979 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -34,7 +34,7 @@ ifdef CONFIG_PPC_BOOK3S_32
> KBUILD_CFLAGS += -mcpu=powerpc
> endif
>
> -ifeq ($(CROSS_COMPILE),)
> +ifeq ($(origin ARCH), file)
> KBUILD_DEFCONFIG := $(shell uname -m)_defconfig
> else
> KBUILD_DEFCONFIG := ppc64_defconfig
> --
> 2.7.4
>
^ permalink raw reply
* Re: [PATCH v5 3/3] powerpc/32: Add KASAN support
From: Andrey Ryabinin @ 2019-02-15 10:38 UTC (permalink / raw)
To: Christophe Leroy, Daniel Axtens, Benjamin Herrenschmidt,
Paul Mackerras, Michael Ellerman, Nicholas Piggin,
Aneesh Kumar K.V, Alexander Potapenko, Dmitry Vyukov
Cc: linux-mm, linuxppc-dev, linux-kernel, kasan-dev
In-Reply-To: <cd942662-2e93-ca93-915f-c9f346317535@c-s.fr>
On 2/15/19 1:10 PM, Christophe Leroy wrote:
>
>
> Le 15/02/2019 à 11:01, Andrey Ryabinin a écrit :
>>
>>
>> On 2/15/19 11:41 AM, Christophe Leroy wrote:
>>>
>>>
>>> Le 14/02/2019 à 23:04, Daniel Axtens a écrit :
>>>> Hi Christophe,
>>>>
>>>>> --- a/arch/powerpc/include/asm/string.h
>>>>> +++ b/arch/powerpc/include/asm/string.h
>>>>> @@ -27,6 +27,20 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
>>>>> extern void * memchr(const void *,int,__kernel_size_t);
>>>>> extern void * memcpy_flushcache(void *,const void *,__kernel_size_t);
>>>>> +void *__memset(void *s, int c, __kernel_size_t count);
>>>>> +void *__memcpy(void *to, const void *from, __kernel_size_t n);
>>>>> +void *__memmove(void *to, const void *from, __kernel_size_t n);
>>>>> +
>>>>> +#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
>>>>> +/*
>>>>> + * For files that are not instrumented (e.g. mm/slub.c) we
>>>>> + * should use not instrumented version of mem* functions.
>>>>> + */
>>>>> +#define memcpy(dst, src, len) __memcpy(dst, src, len)
>>>>> +#define memmove(dst, src, len) __memmove(dst, src, len)
>>>>> +#define memset(s, c, n) __memset(s, c, n)
>>>>> +#endif
>>>>> +
>>>>
>>>> I'm finding that I miss tests like 'kasan test: kasan_memcmp
>>>> out-of-bounds in memcmp' because the uninstrumented asm version is used
>>>> instead of an instrumented C version. I ended up guarding the relevant
>>>> __HAVE_ARCH_x symbols behind a #ifndef CONFIG_KASAN and only exporting
>>>> the arch versions if we're not compiled with KASAN.
>>>>
>>>> I find I need to guard and unexport strncpy, strncmp, memchr and
>>>> memcmp. Do you need to do this on 32bit as well, or are those tests
>>>> passing anyway for some reason?
>>>
>>> Indeed, I didn't try the KASAN test module recently, because my configs don't have CONFIG_MODULE by default.
>>>
>>> Trying to test it now, I am discovering that module loading oopses with latest version of my series, I need to figure out exactly why. Here below the oops by modprobing test_module (the one supposed to just say hello to the world).
>>>
>>> What we see is an access to the RO kasan zero area.
>>>
>>> The shadow mem is 0xf7c00000..0xffc00000
>>> Linear kernel memory is shadowed by 0xf7c00000-0xf8bfffff
>>> 0xf8c00000-0xffc00000 is shadowed read only by the kasan zero page.
>>>
>>> Why is kasan trying to access that ? Isn't kasan supposed to not check stuff in vmalloc area ?
>>
>> It tries to poison global variables in modules. If module is in vmalloc, than it will try to poison vmalloc.
>> Given that the vmalloc area is not so big on 32bits, the easiest solution is to cover all vmalloc with RW shadow.
>>
>
> Euh ... Not so big ?
>
> Memory: 96448K/131072K available (8016K kernel code, 1680K rwdata
> , 2720K rodata, 624K init, 4678K bss, 34624K reserved, 0K cma-reserved)
> Kernel virtual memory layout:
> * 0xffefc000..0xffffc000 : fixmap
> * 0xf7c00000..0xffc00000 : kasan shadow mem
> * 0xf7a00000..0xf7c00000 : consistent mem
> * 0xf7a00000..0xf7a00000 : early ioremap
> * 0xc9000000..0xf7a00000 : vmalloc & ioremap
>
> Here, vmalloc area size 0x2ea00000, that is 746Mbytes. Shadow for this would be 93Mbytes and we are already using 16Mbytes to shadow the linear memory area .... this poor board has 128Mbytes RAM in total.
>
> So another solution is needed.
>
Ok.
As a temporary workaround your can make __asan_register_globals() to skip globals in vmalloc().
Obviously it means that out-of-bounds accesses to in modules will be missed.
Non temporary solution would making kasan to fully support vmalloc, i.e. remove RO shadow and allocate/free shadow on vmalloc()/vfree().
But this feels like separate task, out of scope of this patch set.
It is also possible to follow some other arches - dedicate separate address range for modules, allocate/free shadow in module_alloc/free.
But it doesn't seem worthy to implement this only for the sake of kasan, since vmalloc support needs to be done anyway.
^ permalink raw reply
* [PATCH] powerpc: drop unused GENERIC_CSUM Kconfig item
From: Christophe Leroy @ 2019-02-15 10:32 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Christoph Hellwig
Cc: Masahiro Yamada, linuxppc-dev, linux-kernel
Commit d4fde568a34a ("powerpc/64: Use optimized checksum routines on
little-endian") converted last powerpc user of GENERIC_CSUM.
This patch does a final cleanup dropping the Kconfig GENERIC_CSUM
option which is always 'n', and associated piece of code in
asm/checksum.h
Fixes: d4fde568a34a ("powerpc/64: Use optimized checksum routines on little-endian")
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/Kconfig | 3 ---
arch/powerpc/include/asm/checksum.h | 4 ----
2 files changed, 7 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 08908219fba9..849b0d5ac3d1 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -251,9 +251,6 @@ config PPC_BARRIER_NOSPEC
default y
depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E
-config GENERIC_CSUM
- def_bool n
-
config EARLY_PRINTK
bool
default y
diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h
index a78a57e5058d..72a65d744a28 100644
--- a/arch/powerpc/include/asm/checksum.h
+++ b/arch/powerpc/include/asm/checksum.h
@@ -9,9 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifdef CONFIG_GENERIC_CSUM
-#include <asm-generic/checksum.h>
-#else
#include <linux/bitops.h>
#include <linux/in6.h>
/*
@@ -217,6 +214,5 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum);
-#endif
#endif /* __KERNEL__ */
#endif
--
2.13.3
^ permalink raw reply related
* Re: [PATCH] powerpc/64s/hash: Fix assert_slb_presence() use of the slbfee. instruction
From: Aneesh Kumar K.V @ 2019-02-15 10:27 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: Nicholas Piggin
In-Reply-To: <20190215102020.24346-1-npiggin@gmail.com>
Nicholas Piggin <npiggin@gmail.com> writes:
> The slbfee. instruction must have bit 24 of RB clear, failure to do
> so can result in false negatives that result in incorrect assertions.
>
> This is not obvious from the ISA v3.0B document, which only says:
>
> The hardware ignores the contents of RB 36:38 40:63 -- p.1032
>
> This patch fixes the bug and also clears all other bits from PPC bit
> 36-63, which is good practice when dealing with reserved or ignored
> bits.
>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> Fixes: e15a4fea4d ("powerpc/64s/hash: Add some SLB debugging tests")
> Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> arch/powerpc/mm/slb.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
> index bc3914d54e26..5986df48359b 100644
> --- a/arch/powerpc/mm/slb.c
> +++ b/arch/powerpc/mm/slb.c
> @@ -69,6 +69,11 @@ static void assert_slb_presence(bool present, unsigned long ea)
> if (!cpu_has_feature(CPU_FTR_ARCH_206))
> return;
>
> + /*
> + * slbfee. requires bit 24 (PPC bit 39) be clear in RB. Hardware
> + * ignores all other bits from 0-27, so just clear them all.
> + */
> + ea &= ~((1UL << 28) - 1);
I guess these numbers '28' are derived from the size of the smallest
segment we support. If co can we use ESID_MASK?
> asm volatile(__PPC_SLBFEE_DOT(%0, %1) : "=r"(tmp) : "r"(ea) : "cr0");
>
> WARN_ON(present == (tmp == 0));
> --
> 2.18.0
^ permalink raw reply
* [PATCH] powerpc/64s/hash: Fix assert_slb_presence() use of the slbfee. instruction
From: Nicholas Piggin @ 2019-02-15 10:20 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Aneesh Kumar K . V, Nicholas Piggin
The slbfee. instruction must have bit 24 of RB clear, failure to do
so can result in false negatives that result in incorrect assertions.
This is not obvious from the ISA v3.0B document, which only says:
The hardware ignores the contents of RB 36:38 40:63 -- p.1032
This patch fixes the bug and also clears all other bits from PPC bit
36-63, which is good practice when dealing with reserved or ignored
bits.
Fixes: e15a4fea4d ("powerpc/64s/hash: Add some SLB debugging tests")
Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/mm/slb.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index bc3914d54e26..5986df48359b 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -69,6 +69,11 @@ static void assert_slb_presence(bool present, unsigned long ea)
if (!cpu_has_feature(CPU_FTR_ARCH_206))
return;
+ /*
+ * slbfee. requires bit 24 (PPC bit 39) be clear in RB. Hardware
+ * ignores all other bits from 0-27, so just clear them all.
+ */
+ ea &= ~((1UL << 28) - 1);
asm volatile(__PPC_SLBFEE_DOT(%0, %1) : "=r"(tmp) : "r"(ea) : "cr0");
WARN_ON(present == (tmp == 0));
--
2.18.0
^ permalink raw reply related
* Re: [PATCH v5 3/3] powerpc/32: Add KASAN support
From: Christophe Leroy @ 2019-02-15 10:10 UTC (permalink / raw)
To: Andrey Ryabinin, Daniel Axtens, Benjamin Herrenschmidt,
Paul Mackerras, Michael Ellerman, Nicholas Piggin,
Aneesh Kumar K.V, Alexander Potapenko, Dmitry Vyukov
Cc: linux-mm, linuxppc-dev, linux-kernel, kasan-dev
In-Reply-To: <e43e21c2-f42c-bab3-c112-2a557f3de5b1@virtuozzo.com>
Le 15/02/2019 à 11:01, Andrey Ryabinin a écrit :
>
>
> On 2/15/19 11:41 AM, Christophe Leroy wrote:
>>
>>
>> Le 14/02/2019 à 23:04, Daniel Axtens a écrit :
>>> Hi Christophe,
>>>
>>>> --- a/arch/powerpc/include/asm/string.h
>>>> +++ b/arch/powerpc/include/asm/string.h
>>>> @@ -27,6 +27,20 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
>>>> extern void * memchr(const void *,int,__kernel_size_t);
>>>> extern void * memcpy_flushcache(void *,const void *,__kernel_size_t);
>>>> +void *__memset(void *s, int c, __kernel_size_t count);
>>>> +void *__memcpy(void *to, const void *from, __kernel_size_t n);
>>>> +void *__memmove(void *to, const void *from, __kernel_size_t n);
>>>> +
>>>> +#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
>>>> +/*
>>>> + * For files that are not instrumented (e.g. mm/slub.c) we
>>>> + * should use not instrumented version of mem* functions.
>>>> + */
>>>> +#define memcpy(dst, src, len) __memcpy(dst, src, len)
>>>> +#define memmove(dst, src, len) __memmove(dst, src, len)
>>>> +#define memset(s, c, n) __memset(s, c, n)
>>>> +#endif
>>>> +
>>>
>>> I'm finding that I miss tests like 'kasan test: kasan_memcmp
>>> out-of-bounds in memcmp' because the uninstrumented asm version is used
>>> instead of an instrumented C version. I ended up guarding the relevant
>>> __HAVE_ARCH_x symbols behind a #ifndef CONFIG_KASAN and only exporting
>>> the arch versions if we're not compiled with KASAN.
>>>
>>> I find I need to guard and unexport strncpy, strncmp, memchr and
>>> memcmp. Do you need to do this on 32bit as well, or are those tests
>>> passing anyway for some reason?
>>
>> Indeed, I didn't try the KASAN test module recently, because my configs don't have CONFIG_MODULE by default.
>>
>> Trying to test it now, I am discovering that module loading oopses with latest version of my series, I need to figure out exactly why. Here below the oops by modprobing test_module (the one supposed to just say hello to the world).
>>
>> What we see is an access to the RO kasan zero area.
>>
>> The shadow mem is 0xf7c00000..0xffc00000
>> Linear kernel memory is shadowed by 0xf7c00000-0xf8bfffff
>> 0xf8c00000-0xffc00000 is shadowed read only by the kasan zero page.
>>
>> Why is kasan trying to access that ? Isn't kasan supposed to not check stuff in vmalloc area ?
>
> It tries to poison global variables in modules. If module is in vmalloc, than it will try to poison vmalloc.
> Given that the vmalloc area is not so big on 32bits, the easiest solution is to cover all vmalloc with RW shadow.
>
Euh ... Not so big ?
Memory: 96448K/131072K available (8016K kernel code, 1680K rwdata
, 2720K rodata, 624K init, 4678K bss, 34624K reserved, 0K cma-reserved)
Kernel virtual memory layout:
* 0xffefc000..0xffffc000 : fixmap
* 0xf7c00000..0xffc00000 : kasan shadow mem
* 0xf7a00000..0xf7c00000 : consistent mem
* 0xf7a00000..0xf7a00000 : early ioremap
* 0xc9000000..0xf7a00000 : vmalloc & ioremap
Here, vmalloc area size 0x2ea00000, that is 746Mbytes. Shadow for this
would be 93Mbytes and we are already using 16Mbytes to shadow the linear
memory area .... this poor board has 128Mbytes RAM in total.
So another solution is needed.
Christophe
^ permalink raw reply
* Re: [PATCH v5 3/3] powerpc/32: Add KASAN support
From: Andrey Ryabinin @ 2019-02-15 10:01 UTC (permalink / raw)
To: Christophe Leroy, Daniel Axtens, Benjamin Herrenschmidt,
Paul Mackerras, Michael Ellerman, Nicholas Piggin,
Aneesh Kumar K.V, Alexander Potapenko, Dmitry Vyukov
Cc: linux-mm, linuxppc-dev, linux-kernel, kasan-dev
In-Reply-To: <b5db7714-51e3-785c-34ca-6c358661c9e8@c-s.fr>
On 2/15/19 11:41 AM, Christophe Leroy wrote:
>
>
> Le 14/02/2019 à 23:04, Daniel Axtens a écrit :
>> Hi Christophe,
>>
>>> --- a/arch/powerpc/include/asm/string.h
>>> +++ b/arch/powerpc/include/asm/string.h
>>> @@ -27,6 +27,20 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
>>> extern void * memchr(const void *,int,__kernel_size_t);
>>> extern void * memcpy_flushcache(void *,const void *,__kernel_size_t);
>>> +void *__memset(void *s, int c, __kernel_size_t count);
>>> +void *__memcpy(void *to, const void *from, __kernel_size_t n);
>>> +void *__memmove(void *to, const void *from, __kernel_size_t n);
>>> +
>>> +#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
>>> +/*
>>> + * For files that are not instrumented (e.g. mm/slub.c) we
>>> + * should use not instrumented version of mem* functions.
>>> + */
>>> +#define memcpy(dst, src, len) __memcpy(dst, src, len)
>>> +#define memmove(dst, src, len) __memmove(dst, src, len)
>>> +#define memset(s, c, n) __memset(s, c, n)
>>> +#endif
>>> +
>>
>> I'm finding that I miss tests like 'kasan test: kasan_memcmp
>> out-of-bounds in memcmp' because the uninstrumented asm version is used
>> instead of an instrumented C version. I ended up guarding the relevant
>> __HAVE_ARCH_x symbols behind a #ifndef CONFIG_KASAN and only exporting
>> the arch versions if we're not compiled with KASAN.
>>
>> I find I need to guard and unexport strncpy, strncmp, memchr and
>> memcmp. Do you need to do this on 32bit as well, or are those tests
>> passing anyway for some reason?
>
> Indeed, I didn't try the KASAN test module recently, because my configs don't have CONFIG_MODULE by default.
>
> Trying to test it now, I am discovering that module loading oopses with latest version of my series, I need to figure out exactly why. Here below the oops by modprobing test_module (the one supposed to just say hello to the world).
>
> What we see is an access to the RO kasan zero area.
>
> The shadow mem is 0xf7c00000..0xffc00000
> Linear kernel memory is shadowed by 0xf7c00000-0xf8bfffff
> 0xf8c00000-0xffc00000 is shadowed read only by the kasan zero page.
>
> Why is kasan trying to access that ? Isn't kasan supposed to not check stuff in vmalloc area ?
It tries to poison global variables in modules. If module is in vmalloc, than it will try to poison vmalloc.
Given that the vmalloc area is not so big on 32bits, the easiest solution is to cover all vmalloc with RW shadow.
^ permalink raw reply
* Re: [PATCH] powerpc/mm: Handle mmap_min_addr correctly in get_unmapped_area callback
From: Laurent Dufour @ 2019-02-15 9:53 UTC (permalink / raw)
To: Aneesh Kumar K.V, npiggin, benh, paulus, mpe; +Cc: linuxppc-dev
In-Reply-To: <20190215081647.24876-1-aneesh.kumar@linux.ibm.com>
Le 15/02/2019 à 09:16, Aneesh Kumar K.V a écrit :
> After we ALIGN up the address we need to make sure we didn't overflow
> and resulted in zero address. In that case, we need to make sure that
> the returned address is greater than mmap_min_addr.
>
> Also when doing top-down search the low_limit is not PAGE_SIZE but rather
> max(PAGE_SIZE, mmap_min_addr). This handle cases in which mmap_min_addr >
> PAGE_SIZE.
>
> This fixes selftest va_128TBswitch --run-hugetlb reporting failures when
> run as non root user for
>
> mmap(-1, MAP_HUGETLB)
> mmap(-1, MAP_HUGETLB)
>
> We also avoid the first mmap(-1, MAP_HUGETLB) returning NULL address as mmap address
> with this change
FWIW:
Reviewed-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
> CC: Laurent Dufour <ldufour@linux.vnet.ibm.com>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
> ---
> arch/powerpc/mm/hugetlbpage-radix.c | 5 +++--
> arch/powerpc/mm/slice.c | 10 ++++++----
> 2 files changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/mm/hugetlbpage-radix.c b/arch/powerpc/mm/hugetlbpage-radix.c
> index 2486bee0f93e..97c7a39ebc00 100644
> --- a/arch/powerpc/mm/hugetlbpage-radix.c
> +++ b/arch/powerpc/mm/hugetlbpage-radix.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0
> #include <linux/mm.h>
> #include <linux/hugetlb.h>
> +#include <linux/security.h>
> #include <asm/pgtable.h>
> #include <asm/pgalloc.h>
> #include <asm/cacheflush.h>
> @@ -73,7 +74,7 @@ radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> if (addr) {
> addr = ALIGN(addr, huge_page_size(h));
> vma = find_vma(mm, addr);
> - if (high_limit - len >= addr &&
> + if (high_limit - len >= addr && addr >= mmap_min_addr &&
> (!vma || addr + len <= vm_start_gap(vma)))
> return addr;
> }
> @@ -83,7 +84,7 @@ radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
> */
> info.flags = VM_UNMAPPED_AREA_TOPDOWN;
> info.length = len;
> - info.low_limit = PAGE_SIZE;
> + info.low_limit = max(PAGE_SIZE, mmap_min_addr);
> info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW);
> info.align_mask = PAGE_MASK & ~huge_page_mask(h);
> info.align_offset = 0;
> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
> index 06898c13901d..aec91dbcdc0b 100644
> --- a/arch/powerpc/mm/slice.c
> +++ b/arch/powerpc/mm/slice.c
> @@ -32,6 +32,7 @@
> #include <linux/export.h>
> #include <linux/hugetlb.h>
> #include <linux/sched/mm.h>
> +#include <linux/security.h>
> #include <asm/mman.h>
> #include <asm/mmu.h>
> #include <asm/copro.h>
> @@ -377,6 +378,7 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm,
> int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT);
> unsigned long addr, found, prev;
> struct vm_unmapped_area_info info;
> + unsigned long min_addr = max(PAGE_SIZE, mmap_min_addr);
>
> info.flags = VM_UNMAPPED_AREA_TOPDOWN;
> info.length = len;
> @@ -393,7 +395,7 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm,
> if (high_limit > DEFAULT_MAP_WINDOW)
> addr += mm->context.slb_addr_limit - DEFAULT_MAP_WINDOW;
>
> - while (addr > PAGE_SIZE) {
> + while (addr > min_addr) {
> info.high_limit = addr;
> if (!slice_scan_available(addr - 1, available, 0, &addr))
> continue;
> @@ -405,8 +407,8 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm,
> * Check if we need to reduce the range, or if we can
> * extend it to cover the previous available slice.
> */
> - if (addr < PAGE_SIZE)
> - addr = PAGE_SIZE;
> + if (addr < min_addr)
> + addr = min_addr;
> else if (slice_scan_available(addr - 1, available, 0, &prev)) {
> addr = prev;
> goto prev_slice;
> @@ -528,7 +530,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
> addr = _ALIGN_UP(addr, page_size);
> slice_dbg(" aligned addr=%lx\n", addr);
> /* Ignore hint if it's too large or overlaps a VMA */
> - if (addr > high_limit - len ||
> + if (addr > high_limit - len || addr < mmap_min_addr ||
> !slice_area_is_free(mm, addr, len))
> addr = 0;
> }
>
^ permalink raw reply
* Re: [PATCH 02/11] riscv: remove the HAVE_KPROBES option
From: Masahiro Yamada @ 2019-02-15 9:32 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linux-xtensa, Linux Kbuild mailing list, linux-s390,
Linux Kernel Mailing List, linux-riscv, linuxppc-dev
In-Reply-To: <20190213174005.28785-3-hch@lst.de>
On Thu, Feb 14, 2019 at 2:40 AM Christoph Hellwig <hch@lst.de> wrote:
>
> HAVE_KPROBES is defined genericly in arch/Kconfig and architectures
> should just select it if supported.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Do you want this patch picked up by me?
Or, by Palmer?
> ---
> arch/riscv/Kconfig | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 515fc3cc9687..b60f4e3e36f4 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -94,9 +94,6 @@ config PGTABLE_LEVELS
> default 3 if 64BIT
> default 2
>
> -config HAVE_KPROBES
> - def_bool n
> -
> menu "Platform type"
>
> choice
> --
> 2.20.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
--
Best Regards
Masahiro Yamada
^ 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