* [PATCH 1/2] ARM: hyp-stub: improve ABI
From: Mark Rutland @ 2016-12-14 11:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <E1cH74w-0003ke-Qp@rmk-PC.armlinux.org.uk>
On Wed, Dec 14, 2016 at 10:46:30AM +0000, Russell King wrote:
> Improve the hyp-stub ABI to allow it to do more than just get/set the
> vectors. We follow the example in ARM64, where r0 is used as an opcode
> with the other registers as an argument.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
This looks good to me, though I'd suggest s/ABI/calling convention/, as
this isn't strictly speaking an ABI. So FWIW:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Thanks,
Mark.
> ---
> arch/arm/kernel/hyp-stub.S | 27 ++++++++++++++++++++++-----
> 1 file changed, 22 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> index 15d073ae5da2..f3e9ba5fb642 100644
> --- a/arch/arm/kernel/hyp-stub.S
> +++ b/arch/arm/kernel/hyp-stub.S
> @@ -22,6 +22,9 @@
> #include <asm/assembler.h>
> #include <asm/virt.h>
>
> +#define HVC_GET_VECTORS 0
> +#define HVC_SET_VECTORS 1
> +
> #ifndef ZIMAGE
> /*
> * For the kernel proper, we need to find out the CPU boot mode long after
> @@ -202,9 +205,19 @@ ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE
> ENDPROC(__hyp_stub_install_secondary)
>
> __hyp_stub_do_trap:
> - cmp r0, #-1
> - mrceq p15, 4, r0, c12, c0, 0 @ get HVBAR
> - mcrne p15, 4, r0, c12, c0, 0 @ set HVBAR
> + teq r0, #HVC_GET_VECTORS
> + bne 1f
> + mrc p15, 4, r0, c12, c0, 0 @ get HVBAR
> + b __hyp_stub_exit
> +
> +1: teq r0, #HVC_SET_VECTORS
> + bne 1f
> + mcr p15, 4, r1, c12, c0, 0 @ set HVBAR
> + b __hyp_stub_exit
> +
> +1: mov r0, #-1
> +
> +__hyp_stub_exit:
> __ERET
> ENDPROC(__hyp_stub_do_trap)
>
> @@ -231,10 +244,14 @@ ENDPROC(__hyp_stub_do_trap)
> * initialisation entry point.
> */
> ENTRY(__hyp_get_vectors)
> - mov r0, #-1
> + mov r0, #HVC_GET_VECTORS
> + __HVC(0)
> + ret lr
> ENDPROC(__hyp_get_vectors)
> - @ fall through
> +
> ENTRY(__hyp_set_vectors)
> + mov r1, r0
> + mov r0, #HVC_SET_VECTORS
> __HVC(0)
> ret lr
> ENDPROC(__hyp_set_vectors)
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH 2/2] ARM: soft-reboot into same mode that we entered the kernel
From: Mark Rutland @ 2016-12-14 11:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <E1cH751-0003kk-Ts@rmk-PC.armlinux.org.uk>
On Wed, Dec 14, 2016 at 10:46:35AM +0000, Russell King wrote:
> When we soft-reboot (eg, kexec) from one kernel into the next, we need
> to ensure that we enter the new kernel in the same processor mode as
> when we were entered, so that (eg) the new kernel can install its own
> hypervisor - the old kernel's hypervisor will have been overwritten.
>
> In order to do this, we need to pass a flag to cpu_reset() so it knows
> what to do, and we need to modify the kernel's own hypervisor stub to
> allow it to handle a soft-reboot.
>
> As we are always guaranteed to install our own hypervisor if we're
> entered in HYP32 mode, and KVM will have moved itself out of the way
> on kexec/normal reboot, we can assume that our hypervisor is in place
> when we want to kexec, so changing our hypervisor API should not be a
> problem.
Just to check, does that also hold true for kdump?
I haven't gone digging yet, but it looks like KVM might still be
installed, rather than the hyp stub, and we might need some logic to
ensure that it's torn down...
[...]
> @@ -51,7 +52,9 @@ static void __soft_restart(void *addr)
>
> /* Switch to the identity mapping. */
> phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
> - phys_reset((unsigned long)addr);
> +
> + /* original stub should be restored by kvm */
> + phys_reset((unsigned long)addr, is_hyp_mode_available());
... otherwise here we'd call into the KVM hyp code in a potentially
confusing manner.
Otherwise, this looks fine to me.
Thanks,
Mark.
^ permalink raw reply
* [PATCH 2/2] ARM: soft-reboot into same mode that we entered the kernel
From: Russell King - ARM Linux @ 2016-12-14 12:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214115648.GG17982@leverpostej>
On Wed, Dec 14, 2016 at 11:56:49AM +0000, Mark Rutland wrote:
> On Wed, Dec 14, 2016 at 10:46:35AM +0000, Russell King wrote:
> > When we soft-reboot (eg, kexec) from one kernel into the next, we need
> > to ensure that we enter the new kernel in the same processor mode as
> > when we were entered, so that (eg) the new kernel can install its own
> > hypervisor - the old kernel's hypervisor will have been overwritten.
> >
> > In order to do this, we need to pass a flag to cpu_reset() so it knows
> > what to do, and we need to modify the kernel's own hypervisor stub to
> > allow it to handle a soft-reboot.
> >
> > As we are always guaranteed to install our own hypervisor if we're
> > entered in HYP32 mode, and KVM will have moved itself out of the way
> > on kexec/normal reboot, we can assume that our hypervisor is in place
> > when we want to kexec, so changing our hypervisor API should not be a
> > problem.
>
> Just to check, does that also hold true for kdump?
>
> I haven't gone digging yet, but it looks like KVM might still be
> installed, rather than the hyp stub, and we might need some logic to
> ensure that it's torn down...
The same problem will be true of ARM64 - I don't see any solution to
that in the present state.
> > @@ -51,7 +52,9 @@ static void __soft_restart(void *addr)
> >
> > /* Switch to the identity mapping. */
> > phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
> > - phys_reset((unsigned long)addr);
> > +
> > + /* original stub should be restored by kvm */
> > + phys_reset((unsigned long)addr, is_hyp_mode_available());
>
> ... otherwise here we'd call into the KVM hyp code in a potentially
> confusing manner.
>
> Otherwise, this looks fine to me.
The only thing that I can think which would resolve that would be to
lay down a standard API for the hyp code, so things like reboot into
hyp mode can work irrespective of the hyp stub in place.
The issue here is that a panic can happen at any time from any context
with any hyp stub in place, so there _needs_ to be a uniform way to do
this. It's very bad that we've got this far without this point having
been considered - all we can do right now is to try and fix the issues
as they come up.
Right now, let's fix this so we get some kind of improvement, and later
try to sort out some kind of uniform interface for this task.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: James Morse @ 2016-12-14 12:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214113701.GE17982@leverpostej>
Hi Mark,
On 14/12/16 11:37, Mark Rutland wrote:
> On Wed, Dec 14, 2016 at 11:16:17AM +0000, James Morse wrote:
>> On 14/12/16 10:12, Pratyush Anand wrote:
>>> On Wednesday 14 December 2016 03:08 PM, Pratyush Anand wrote:
>>>>> I would go as far as to generate the page tables at 'kexec -l' time,
>>>>> and only if
>>>>
>>>> Ok..So you mean that I create a new section which will have page table
>>>> entries mapping physicalmemory represented by remaining section, and
>>>> then purgatory can just enable mmu with page table from that section,
>>>> right? Seems doable. can do that.
>>>
>>> I see a problem here. If we create page table as a new segment then, how can we
>>> verify in purgatory that sha for page table is correct? We need page table
>>> before sha verification start,and we can not rely the page table created by
>>> first kernel until it's sha is verified. So a chicken-egg problem.
>>
>> There is more than one of those! What happens if your sha256 calculation code is
>> corrupted? You have to run it before you know. The same goes for all the
>> purgatory code.
>>
>> This is why I think its better to do this in the kernel before we exit to
>> purgatory, but obviously that doesn't work for kdump.
>
> I see in an earlier message that the need for sha256 was being discussed
> in another thread. Do either of you happen to have a pointer to that.
https://www.spinics.net/lists/arm-kernel/msg544472.html
Thanks,
James
^ permalink raw reply
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: Pratyush Anand @ 2016-12-14 12:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <58512A01.70101@arm.com>
Hi James,
Thanks for your input !!
On Wednesday 14 December 2016 04:46 PM, James Morse wrote:
> Hi Pratyush,
>
> On 14/12/16 10:12, Pratyush Anand wrote:
>> > On Wednesday 14 December 2016 03:08 PM, Pratyush Anand wrote:
>>>> >>> I would go as far as to generate the page tables at 'kexec -l' time,
>>>> >>> and only if
>>> >>
>>> >> Ok..So you mean that I create a new section which will have page table
>>> >> entries mapping physicalmemory represented by remaining section, and
>>> >> then purgatory can just enable mmu with page table from that section,
>>> >> right? Seems doable. can do that.
>> >
>> > I see a problem here. If we create page table as a new segment then, how can we
>> > verify in purgatory that sha for page table is correct? We need page table
>> > before sha verification start,and we can not rely the page table created by
>> > first kernel until it's sha is verified. So a chicken-egg problem.
> There is more than one of those! What happens if your sha256 calculation code is
> corrupted? You have to run it before you know. The same goes for all the
> purgatory code.
>
OK, seems reasonable... will do it in kexec code.
> This is why I think its better to do this in the kernel before we exit to
> purgatory, but obviously that doesn't work for kdump.
>
>
>> > I think, creating page table will just take fraction of second and should be
>> > good even in purgatory, What do you say?
> If it's for kdump its best-effort. I think its easier/simpler to generate and
> debug them at 'kexec -l' time, but if you're worried about the increased area
> that could be corrupted then do it in purgatory.
>
~Pratyush
^ permalink raw reply
* [RFC PATCH] Memory hotplug support for arm64 platform
From: Maciej Bielski @ 2016-12-14 12:16 UTC (permalink / raw)
To: linux-arm-kernel
This patch relates to the work previously announced in [1]. This builds on the
work by Scott Branden [2] and, henceforth, it needs to be applied on top of
Scott's patches [2]. Comments are very welcome.
Changes from the original patchset and known issues:
- Compared to Scott's original patchset, this work adds the mapping of
the new hotplugged pages into the kernel page tables. This is done by
copying the old swapper_pg_dir over a new page, adding the new mappings,
and then switching to the newly built pg_dir (see `hotplug_paging` in
arch/arm64/mmu.c). There might be better ways to to this: suggestions
are more than welcome.
- The stub function for `arch_remove_memory` has been removed for now; we
are working in parallel on memory hot remove, and we plan to contribute
it as a separate patch.
- Corresponding Kconfig flags have been added;
- Note that this patch does not work when NUMA is enabled; in fact,
the function `memory_add_physaddr_to_nid` does not have an
implementation when the NUMA flag is on: this function is supposed to
return the nid the hotplugged memory should be associated with. However
it is not really clear to us yet what the semantics of this function
in the context of a NUMA system should be. A quick and dirty fix would
be to always attach to the first available NUMA node.
- In arch/arm64/mm/init.c `arch_add_memory`, we are doing a hack with the
nomap memory block flags to satisfy preconditions and postconditions of
`__add_pages` and postconditions of `arch_add_memory`. Compared to
memory hotplug implementation for other architectures, the "issue"
seems to be in the implemenation of `pfn_valid`. Suggestions on how
to cleanly avoid this hack are welcome.
This patchset can be tested by starting the kernel with the `mem=X` flag, where
X is less than the total available physical memory and has to be multiple of
MIN_MEMORY_BLOCK_SIZE. We also tested it on a customised version of QEMU
capable to emulate physical hotplug on arm64 platform.
To enable the feature the CONFIG_MEMORY_HOTPLUG compilation flag
needs to be set to true. Then, after memory is physically hotplugged,
the standard two steps to make it available (as also documented in
Documentation/memory-hotplug.txt) are:
(1) Notify memory hot-add
echo '0xYY000000' > /sys/devices/system/memory/probe
where 0xYY000000 is the first physical address of the new memory section.
(2) Online new memory block(s)
echo online > /sys/devices/system/memory/memoryXXX/state
where XXX corresponds to the ids of newly added blocks.
Onlining can optionally be automatic at hot-add notification by enabling
the global flag:
echo online > /sys/devices/system/memory/auto_online_blocks
or by setting the corresponding config flag in the kernel build.
Again, any comment is highly appreciated.
[1] https://lkml.org/lkml/2016/11/17/49
[2] https://lkml.org/lkml/2016/12/1/811
Signed-off-by: Maciej Bielski <m.bielski@virtualopensystems.com>
Signed-off-by: Andrea Reale <ar@linux.vnet.ibm.com>
---
arch/arm64/Kconfig | 4 +--
arch/arm64/include/asm/mmu.h | 3 +++
arch/arm64/mm/init.c | 58 +++++++++++++++++++++++++++++++-------------
arch/arm64/mm/mmu.c | 24 ++++++++++++++++++
include/linux/memblock.h | 1 +
mm/memblock.c | 10 ++++++++
6 files changed, 80 insertions(+), 20 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 2482fdd..bd8ddf2 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -577,9 +577,7 @@ config HOTPLUG_CPU
can be controlled through /sys/devices/system/cpu.
config ARCH_ENABLE_MEMORY_HOTPLUG
- def_bool y
-
-config ARCH_ENABLE_MEMORY_HOTREMOVE
+ depends on !NUMA
def_bool y
# Common NUMA Features
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 8d9fce0..2499745 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -36,5 +36,8 @@ extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot, bool allow_block_mappings);
extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
+#ifdef CONFIG_MEMORY_HOTPLUG
+extern void hotplug_paging(phys_addr_t start, phys_addr_t size);
+#endif
#endif
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 687d087..a7c740e 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -544,37 +544,61 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
struct zone *zone;
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
+ unsigned long end_pfn = start_pfn + nr_pages;
+ unsigned long max_sparsemem_pfn = 1UL << (MAX_PHYSMEM_BITS-PAGE_SHIFT);
+ unsigned long pfn;
int ret;
+ if (end_pfn > max_sparsemem_pfn) {
+ pr_err("end_pfn too big");
+ return -1;
+ }
+ hotplug_paging(start, size);
+
+ /*
+ * Mark all the page range as unsuable.
+ * This is needed because __add_section (within __add_pages)
+ * wants pfn_valid to be false, and in arm64 pfn falid is implemented
+ * by just checking at the nomap flag for existing blocks
+ */
+ memblock_mark_nomap(start, size);
+
pgdat = NODE_DATA(nid);
zone = pgdat->node_zones +
zone_for_memory(nid, start, size, ZONE_NORMAL, for_device);
ret = __add_pages(nid, zone, start_pfn, nr_pages);
- if (ret)
- pr_warn("%s: Problem encountered in __add_pages() ret=%d\n",
- __func__, ret);
+ /*
+ * Make the pages usable after they have been added.
+ * This will make pfn_valid return true
+ */
+ memblock_clear_nomap(start, size);
- return ret;
-}
+ /*
+ * This is a hack to avoid having to mix arch specific code into arch
+ * independent code. SetPageReserved is supposed to be called by __add_zone
+ * (within __add_section, within __add_pages). However, when it is called
+ * there, it assumes that pfn_valid returns true. For the way pfn_valid is
+ * implemented in arm64 (a check on the nomap flag), the only way to make
+ * this evaluate true inside __add_zone is to clear the nomap flags of
+ * blocks in architecture independent code.
+ *
+ * To avoid this, we set the Reserved flag here after we cleared the nomap
+ * flag in the line above.
+ */
+ for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
+ if (!pfn_valid(pfn))
+ continue;
-#ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
-{
- unsigned long start_pfn = start >> PAGE_SHIFT;
- unsigned long nr_pages = size >> PAGE_SHIFT;
- struct zone *zone;
- int ret;
+ SetPageReserved(pfn_to_page(pfn));
+ }
- zone = page_zone(pfn_to_page(start_pfn));
- ret = __remove_pages(zone, start_pfn, nr_pages);
if (ret)
- pr_warn("%s: Problem encountered in __remove_pages() ret=%d\n",
+ pr_warn("%s: Problem encountered in __add_pages() ret=%d\n",
__func__, ret);
return ret;
}
#endif
-#endif
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 05615a3..9efa7d1 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -493,6 +493,30 @@ void __init paging_init(void)
SWAPPER_DIR_SIZE - PAGE_SIZE);
}
+#ifdef CONFIG_MEMORY_HOTPLUG
+/*
+ * hotplug_paging() is used by memory hotplug to build new page tables
+ * for hot added memory.
+ */
+void hotplug_paging(phys_addr_t start, phys_addr_t size)
+{
+ phys_addr_t pgd_phys = pgd_pgtable_alloc();
+ pgd_t *pgd = pgd_set_fixmap(pgd_phys);
+
+ memcpy(pgd, swapper_pg_dir, PAGE_SIZE);
+
+ __create_pgd_mapping(pgd, start, __phys_to_virt(start), size,
+ PAGE_KERNEL, pgd_pgtable_alloc, false);
+
+ cpu_replace_ttbr1(__va(pgd_phys));
+ memcpy(swapper_pg_dir, pgd, PAGE_SIZE);
+ cpu_replace_ttbr1(swapper_pg_dir);
+
+ pgd_clear_fixmap();
+ memblock_free(pgd_phys, PAGE_SIZE);
+}
+#endif
+
/*
* Check whether a kernel address is valid (derived from arch/x86/).
*/
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 5b759c9..5f78257 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -92,6 +92,7 @@ int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
+int memblock_clear_nomap(phys_addr_t base, phys_addr_t size);
ulong choose_memblock_flags(void);
/* Low level functions */
diff --git a/mm/memblock.c b/mm/memblock.c
index 7608bc3..05e7676 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -814,6 +814,16 @@ int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)
}
/**
+ * memblock_clear_nomap - Clear a flag of MEMBLOCK_NOMAP memory region
+ * @base: the base phys addr of the region
+ * @size: the size of the region
+ */
+int __init_memblock memblock_clear_nomap(phys_addr_t base, phys_addr_t size)
+{
+ return memblock_setclr_flag(base, size, 0, MEMBLOCK_NOMAP);
+}
+
+/**
* __next_reserved_mem_region - next function for for_each_reserved_region()
* @idx: pointer to u64 loop variable
* @out_start: ptr to phys_addr_t for start address of the region, can be %NULL
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] ARM: soft-reboot into same mode that we entered the kernel
From: Mark Rutland @ 2016-12-14 12:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214120541.GD14217@n2100.armlinux.org.uk>
On Wed, Dec 14, 2016 at 12:05:41PM +0000, Russell King - ARM Linux wrote:
> On Wed, Dec 14, 2016 at 11:56:49AM +0000, Mark Rutland wrote:
> > On Wed, Dec 14, 2016 at 10:46:35AM +0000, Russell King wrote:
> > > When we soft-reboot (eg, kexec) from one kernel into the next, we need
> > > to ensure that we enter the new kernel in the same processor mode as
> > > when we were entered, so that (eg) the new kernel can install its own
> > > hypervisor - the old kernel's hypervisor will have been overwritten.
> > >
> > > In order to do this, we need to pass a flag to cpu_reset() so it knows
> > > what to do, and we need to modify the kernel's own hypervisor stub to
> > > allow it to handle a soft-reboot.
> > >
> > > As we are always guaranteed to install our own hypervisor if we're
> > > entered in HYP32 mode, and KVM will have moved itself out of the way
> > > on kexec/normal reboot, we can assume that our hypervisor is in place
> > > when we want to kexec, so changing our hypervisor API should not be a
> > > problem.
> >
> > Just to check, does that also hold true for kdump?
> >
> > I haven't gone digging yet, but it looks like KVM might still be
> > installed, rather than the hyp stub, and we might need some logic to
> > ensure that it's torn down...
>
> The same problem will be true of ARM64 - I don't see any solution to
> that in the present state.
Sure. We don't have kdump suppoort yet, and I intend for that to be
addressed before kdump support is merged.
> > > @@ -51,7 +52,9 @@ static void __soft_restart(void *addr)
> > >
> > > /* Switch to the identity mapping. */
> > > phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
> > > - phys_reset((unsigned long)addr);
> > > +
> > > + /* original stub should be restored by kvm */
> > > + phys_reset((unsigned long)addr, is_hyp_mode_available());
> >
> > ... otherwise here we'd call into the KVM hyp code in a potentially
> > confusing manner.
> >
> > Otherwise, this looks fine to me.
>
> The only thing that I can think which would resolve that would be to
> lay down a standard API for the hyp code, so things like reboot into
> hyp mode can work irrespective of the hyp stub in place.
Sure; having the KVM hyp code also implement HVC_SOFT_RESTART seems
sensible. This would also work for arm64.
> The issue here is that a panic can happen at any time from any context
> with any hyp stub in place, so there _needs_ to be a uniform way to do
> this. It's very bad that we've got this far without this point having
> been considered - all we can do right now is to try and fix the issues
> as they come up.
>
> Right now, let's fix this so we get some kind of improvement, and later
> try to sort out some kind of uniform interface for this task.
Sure, that's a bigger task, and this is definitely a step in the right
direction.
We need to avoid the kdump regression somehow though; can we somehow
detect if KVM is active and avoid issuing the HVC_SOFT_RESTART?
Thanks,
Mark.
^ permalink raw reply
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: Pratyush Anand @ 2016-12-14 12:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214113701.GE17982@leverpostej>
On Wednesday 14 December 2016 05:07 PM, Mark Rutland wrote:
> On Wed, Dec 14, 2016 at 11:16:17AM +0000, James Morse wrote:
>> Hi Pratyush,
>>
>> On 14/12/16 10:12, Pratyush Anand wrote:
>>> On Wednesday 14 December 2016 03:08 PM, Pratyush Anand wrote:
>>>>> I would go as far as to generate the page tables at 'kexec -l' time,
>>>>> and only if
>>>>
>>>> Ok..So you mean that I create a new section which will have page table
>>>> entries mapping physicalmemory represented by remaining section, and
>>>> then purgatory can just enable mmu with page table from that section,
>>>> right? Seems doable. can do that.
>>>
>>> I see a problem here. If we create page table as a new segment then, how can we
>>> verify in purgatory that sha for page table is correct? We need page table
>>> before sha verification start,and we can not rely the page table created by
>>> first kernel until it's sha is verified. So a chicken-egg problem.
>>
>> There is more than one of those! What happens if your sha256 calculation code is
>> corrupted? You have to run it before you know. The same goes for all the
>> purgatory code.
>>
>> This is why I think its better to do this in the kernel before we exit to
>> purgatory, but obviously that doesn't work for kdump.
>
> I see in an earlier message that the need for sha256 was being discussed
> in another thread. Do either of you happen to have a pointer to that.
>
patch 0/2 of this series.
> To me, it seems like it doesn't come with much benefit for the kdump
> case given that's best-effort anyway, and as above the verification code
> could have been be corrupted. In the non-kdump case it's not strictly
> necessary and seems like a debugging aid rather than a necessary piece
> of functionality -- if that's the case, a 20 second delay isn't the end
> of the world...
Even for the non-kdump ie `kexec -l` case we do not have a functionality
to bypass sha verification in kexec-tools. --lite option with the
kexec-tools was discouraged and not accepted. So,it is 20s for both
`kexec -l` and `kexec -p`.
Also other arch like x86_64 takes negligible time in sha verification.
~Pratyush
^ permalink raw reply
* [GIT PULL] arm64 updates for 4.10
From: Catalin Marinas @ 2016-12-14 12:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+55aFxxJy_xkGva8uX8LeFaBgb48mRpO05sJdGveBvRnK0uvg@mail.gmail.com>
On Tue, Dec 13, 2016 at 04:58:33PM -0800, Linus Torvalds wrote:
> On Tue, Dec 13, 2016 at 11:21 AM, Catalin Marinas
> <catalin.marinas@arm.com> wrote:
> >
> > Please pull the arm64 updates for 4.10 below.
>
> Mind checking that I got the conflict resolution right?
>
> The conflict looked completely trivial, but with stuff moving across
> files and since I don't build the end result (much less boot it) I
> could easily have missed some screw-up of mine.
The conflict resolution is fine. Sorry, I forgot to mention it in the
pull request.
Thanks.
--
Catalin
^ permalink raw reply
* partial bluetooth success on n900 [was Re: bluetooth/uart timeout handling]
From: Pali Rohár @ 2016-12-14 12:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161019092506.GA1461@amd>
On Wednesday 19 October 2016 11:25:06 Pavel Machek wrote:
> Hi!
>
> [Ccing lists.]
>
> > Can you push the patch, which gets further than negotiation into
> > some git branch available to me? I tried to apply your patch to
> > my code, but it did not work for me.
>
> Ok, I've pushed the branch to kernel.org:
>
> git push
> git at gitolite.kernel.org:pub/scm/linux/kernel/git/pavel/linux-n900.gi
> t bt-2-v4.9:bt-2-v4.9
>
> In retrospect, I did make some changes to dts, they may be
> neccessary, too.
>
> If it still does not work, please try with my .config. I'm using
> modules here, using this script:
>
> pavel at n900:/my/modules$ cat run2
> echo removing...
> sudo killall a.out
> rmmod nokia_h4p
> #rmmod omap_serial
> #rmmod serial_core
> rmmod hci_uart.ko
> #rmmod bcm2048.ko
> echo installing...
> insmod serial_core.ko
> insmod omap-serial.ko
> insmod bcm2048.ko
> insmod hci_uart.ko
> ls -al /dev/ttyO1
> sleep 1
> stty crtscts < /dev/ttyO1
> /my/tui/ofone/a.out &
>
> For the record, dmesg says:
>
> Good luck,
> Pavel
>
> [ 30.694274] g_ether gadget: notify connect true
> [ 30.714080] g_ether gadget: notify speed 425984000
> [ 127.719146] ssi-protocol ssi-protocol: WAKELINES TEST OK
> [ 218.542694] of_get_named_gpiod_flags: can't parse 'rts-gpio'
> property of node '/ocp at 68000000/serial at 4806c000[0]'
> [ 218.546264] 4806c000.serial: ttyO1 at MMIO 0x4806c000 (irq = 89,
> base_baud = 3000000) is a OMAP UART1
> [ 218.574157] of_get_named_gpiod_flags: can't parse 'rts-gpio'
> property of node '/ocp at 68000000/serial at 49020000[0]'
> [ 218.574340] 49020000.serial: ttyO2 at MMIO 0x49020000 (irq = 90,
> base_baud = 3000000) is a OMAP UART2
> [ 218.650115] bcm2048: probe
> [ 218.650177] bcm2048 4806c000.serial:bluetooth: GPIO lookup for
> consumer reset
> [ 218.650177] bcm2048 4806c000.serial:bluetooth: using device tree
> for GPIO lookup
> [ 218.650360] of_get_named_gpiod_flags: parsed 'reset-gpios'
> property of node '/ocp at 68000000/serial at 4806c000/bluetooth[0]' -
> status (0) [ 218.650390] bcm2048 4806c000.serial:bluetooth: GPIO
> lookup for consumer host-wakeup
> [ 218.650421] bcm2048 4806c000.serial:bluetooth: using device tree
> for GPIO lookup
> [ 218.650482] of_get_named_gpiod_flags: parsed 'host-wakeup-gpios'
> property of node '/ocp at 68000000/serial at 4806c000/bluetooth[0]' -
> status (0)
> [ 218.650512] bcm2048 4806c000.serial:bluetooth: GPIO lookup for
> consumer bluetooth-wakeup
> [ 218.650543] bcm2048 4806c000.serial:bluetooth: using device tree
> for GPIO lookup
> [ 218.650604] of_get_named_gpiod_flags: parsed
> 'bluetooth-wakeup-gpios' property of node
> '/ocp at 68000000/serial at 4806c000/bluetooth[0]' - status (0)
> [ 218.650817] bcm2048 4806c000.serial:bluetooth: parent uart: ttyO1
> [ 218.650817] bcm2048 4806c000.serial:bluetooth: sysclk speed: 38400
> kHz
> [ 218.650848] bcm2048 4806c000.serial:bluetooth: probe: 0
> [ 218.774139] Bluetooth: HCI UART driver ver 2.3
> [ 218.774169] Bluetooth: HCI UART protocol H4 registered
> [ 218.774169] Bluetooth: HCI UART protocol H4+ registered
> [ 218.774169] Bluetooth: HCI UART protocol BCSP registered
> [ 218.774200] Bluetooth: HCI UART protocol LL registered
> [ 218.774200] Bluetooth: HCI UART protocol ATH3K registered
> [ 218.774200] Bluetooth: HCI UART protocol Three-wire (H5)
> registered [ 219.904876] tty ttyO1: Nokia H4+ protocol initialized
> with 4806c000.serial:bluetooth!
> [ 219.921112] tty ttyO1: Nokia H4+ protocol setup...
> [ 219.921142] h4p_reset: reset
> [ 219.921142] hci_uart_init_tty
> [ 219.983520] h4p_reset: flush
> [ 219.983551] h4p_reset: speed
> [ 219.983581] tty ttyO1: setting speed to 120000 baud
> [ 219.983673] h4p_reset: safety
> [ 219.986480] tty ttyO1: wakeup received: 0 -> 1
> [ 220.013488] tty ttyO1: wait for cts... received!
> [ 220.013519] h4p_reset: flow
> [ 220.013549] tty ttyO1: Sending negotiation...
> [ 220.013580] tty ttyO1: gpio state: reset=1 wakehost=1 wakebt=1
> [ 220.013610] enqueue: hu c304cc80 skb cd4da000
> [ 220.017425] tty ttyO1: H4P negotiation:
> [ 220.017456] tty ttyO1: baudrate = 416
> [ 220.017486] tty ttyO1: system clock = 38400
> [ 220.017486] tty ttyO1: manufacturer id = 4
> [ 220.017486] tty ttyO1: version id = 11
> [ 220.017578] tty ttyO1: setting speed to 921600 baud
> [ 220.043457] tty ttyO1: wait for cts... received!
> [ 220.043548] tty ttyO1: Negotiation successful...
> [ 220.043579] tty ttyO1: Sending alive packet...
> [ 220.043579] enqueue: hu c304cc80 skb cd4dacc0
> [ 220.043853] tty ttyO1: Received alive packet!
> [ 220.047851] tty ttyO1: FW: Skip negotion packet!
> [ 220.047882] tty ttyO1: FW: Skip alive packet!
> [ 220.052185] enqueue: hu c304cc80 skb cd4da480
> [ 220.055175] enqueue: hu c304cc80 skb cd4dae40
> [ 220.058776] enqueue: hu c304cc80 skb cd4da6c0
> [ 220.058898] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.058929] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.064605] enqueue: hu c304cc80 skb cd4daf00
> [ 220.068389] enqueue: hu c304cc80 skb cd4da0c0
> [ 220.068542] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.068542] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.071960] enqueue: hu c304cc80 skb cd4da840
> [ 220.072082] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.072082] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.075592] enqueue: hu c304cc80 skb cd4da180
> [ 220.079803] enqueue: hu c304cc80 skb cd479cc0
> [ 220.084381] enqueue: hu c304cc80 skb cd479180
> [ 220.087982] enqueue: hu c304cc80 skb cd4793c0
> [ 220.088104] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.088134] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.091522] enqueue: hu c304cc80 skb cd479e40
> [ 220.095336] enqueue: hu c304cc80 skb cd479540
> [ 220.098876] enqueue: hu c304cc80 skb cd479000
> [ 220.102386] enqueue: hu c304cc80 skb cd479600
> [ 220.102478] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.102508] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.105987] enqueue: hu c304cc80 skb cd479780
> [ 220.109527] enqueue: hu c304cc80 skb cd450cc0
> [ 220.109619] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.109649] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.113098] enqueue: hu c304cc80 skb cd484600
> [ 220.113220] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.113250] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.116760] enqueue: hu c304cc80 skb cd4a9b40
> [ 220.120300] enqueue: hu c304cc80 skb cd77c840
> [ 220.124786] enqueue: hu c304cc80 skb cd4f7900
> [ 220.128387] enqueue: hu c304cc80 skb c4fb2180
> [ 220.131896] enqueue: hu c304cc80 skb c4fb23c0
> [ 220.135498] enqueue: hu c304cc80 skb c4fb2cc0
> [ 220.139007] enqueue: hu c304cc80 skb c4fb2000
> [ 220.142486] enqueue: hu c304cc80 skb cd44fcc0
> [ 220.146118] enqueue: hu c304cc80 skb cd4b60c0
> [ 220.149627] enqueue: hu c304cc80 skb cf1986c0
> [ 220.153106] enqueue: hu c304cc80 skb cf198480
> [ 220.156738] enqueue: hu c304cc80 skb cf1980c0
> [ 220.160278] enqueue: hu c304cc80 skb cf198240
> [ 220.164733] enqueue: hu c304cc80 skb cd49f780
> [ 220.168365] enqueue: hu c304cc80 skb cd4daf00
> [ 220.171844] enqueue: hu c304cc80 skb cd4da6c0
> [ 220.175445] enqueue: hu c304cc80 skb cd4dab40
> [ 220.175567] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.175567] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.178955] enqueue: hu c304cc80 skb cd479780
> [ 220.182434] enqueue: hu c304cc80 skb cd479540
> [ 220.182525] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.182556] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.186035] enqueue: hu c304cc80 skb cd4793c0
> [ 220.188140] enqueue: hu c304cc80 skb cd479b40
> [ 220.188537] enqueue: hu c304cc80 skb cd484600
> [ 220.236480] enqueue: hu c304cc80 skb cd4a9f00
> [ 220.237701] enqueue: hu c304cc80 skb cd4f7900
> [ 220.238830] enqueue: hu c304cc80 skb c4fb23c0
> [ 220.239959] enqueue: hu c304cc80 skb c4fb2b40
> [ 220.241119] enqueue: hu c304cc80 skb c3107000
> [ 220.242187] enqueue: hu c304cc80 skb cd724240
> [ 220.243286] enqueue: hu c304cc80 skb cf198540
> [ 220.244781] enqueue: hu c304cc80 skb cf198540
> [ 220.245758] enqueue: hu c304cc80 skb cd49f780
> [ 220.246612] enqueue: hu c304cc80 skb cd4daf00
> [ 220.247436] enqueue: hu c304cc80 skb cd479540
> [ 220.248535] tty ttyO1: Sending radio packet...
> [ 220.248565] enqueue: hu c304cc80 skb cd479cc0
> [ 220.248596] tty ttyO1: Radio packet sent
> [ 220.249328] Bluetooth: hci0: Frame reassembly failed (-84)
> [ 220.272949] tty ttyO1: wakeup received: 1 -> 0
> [ 221.283477] tty ttyO1: radio packet timeout!
> [ 221.283630] enqueue: hu c304cc80 skb cd4a9b40
> [ 223.363372] Bluetooth: hci0 command 0xfc18 tx timeout
> pavel at n900:~$
In log are still some failures, but ... is bluetooth working now?
I see that you applied this patch:
https://git.kernel.org/cgit/linux/kernel/git/pavel/linux-n900.git/commit/?id=051aa3fbf03ac770d8344690f5a936a7f04c6884
Looks like that pinmux is in DTS file incorrect. Can somebody verify it?
Maybe Tony?
--
Pali Roh?r
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161214/d223c86e/attachment.sig>
^ permalink raw reply
* [PATCH] n900 device tree: cleanup
From: Pali Rohár @ 2016-12-14 12:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161207031048.pi7j4dms5uuco3yf@earth>
On Wednesday 07 December 2016 04:10:48 Sebastian Reichel wrote:
> Hi Tony,
>
> It looks like this fell through the cracks. Apart from inconsistent
> patch subject:
>
> Reviewed-By: Sebastian Reichel <sre@kernel.org>
Fine for me too. Reviewed-By: Pali Roh?r <pali.rohar@gmail.com>
> -- Sebastian
>
> On Tue, Oct 11, 2016 at 10:12:43AM +0200, Pavel Machek wrote:
> > Fix GPIO comment to be consistent with rest of file and add comment
> > what tpa6130 is.
> >
> > Signed-off-by: Pavel Machek <pavel@ucw.cz>
> >
> > diff --git a/arch/arm/boot/dts/omap3-n900.dts
> > b/arch/arm/boot/dts/omap3-n900.dts index bfffd6c..ca9fe8c 100644
> > --- a/arch/arm/boot/dts/omap3-n900.dts
> > +++ b/arch/arm/boot/dts/omap3-n900.dts
> > @@ -47,7 +47,7 @@
> >
> > compatible = "gpio-leds";
> > heartbeat {
> >
> > label = "debug::sleep";
> >
> > - gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* gpio162 */
> > + gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* 162 */
> >
> > linux,default-trigger = "default-on";
> > pinctrl-names = "default";
> > pinctrl-0 = <&debug_leds>;
> >
> > @@ -637,6 +637,7 @@
> >
> > reg = <0x55>;
> >
> > };
> >
> > + /* Stereo headphone amplifier */
> >
> > tpa6130a2: tpa6130a2 at 60 {
> >
> > compatible = "ti,tpa6130a2";
> > reg = <0x60>;
--
Pali Roh?r
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161214/38ca0953/attachment.sig>
^ permalink raw reply
* [PATCH 2/2] ARM: soft-reboot into same mode that we entered the kernel
From: Russell King - ARM Linux @ 2016-12-14 12:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214121747.GH17982@leverpostej>
On Wed, Dec 14, 2016 at 12:17:47PM +0000, Mark Rutland wrote:
> On Wed, Dec 14, 2016 at 12:05:41PM +0000, Russell King - ARM Linux wrote:
> > The issue here is that a panic can happen at any time from any context
> > with any hyp stub in place, so there _needs_ to be a uniform way to do
> > this. It's very bad that we've got this far without this point having
> > been considered - all we can do right now is to try and fix the issues
> > as they come up.
> >
> > Right now, let's fix this so we get some kind of improvement, and later
> > try to sort out some kind of uniform interface for this task.
>
> Sure, that's a bigger task, and this is definitely a step in the right
> direction.
>
> We need to avoid the kdump regression somehow though; can we somehow
> detect if KVM is active and avoid issuing the HVC_SOFT_RESTART?
That's a question for KVM people.
However, there's a bigger question, which is: what do we want to happen
in the case of kdump - do we want to be entering the kdump kernel in
HYP or SVC mode? As the kdump kernel exists to be able to save the
state of a crashing system, the kdump kernel should do that and then
restart the system in a clean way (iow, not via yet another kexec.)
So maybe the right answer is that kdump should always invoke the kernel
in SVC mode.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH linux v1 2/4] drivers: misc: Character device driver for seven segment display
From: Russell King - ARM Linux @ 2016-12-14 12:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481702104-8617-3-git-send-email-jaghu@google.com>
On Tue, Dec 13, 2016 at 11:55:02PM -0800, Jaghathiswari Rankappagounder Natarajan wrote:
> +int seven_seg_setup_cdev(struct seven_seg_disp_dev *disp_dev,
> + void (*update_disp_data)(struct device *, u16 data))
> +{
> + struct device *dev;
> + int err;
> +
> + dev = device_create(seven_seg_disp_class, &disp_dev->parent,
> + seven_seg_devno,
> + NULL, "seven_seg_disp_val");
> + if (dev == NULL)
> + return -1;
Do not use return -1 in kernel code.
> + disp_dev->dev = dev;
> + disp_dev->update_seven_seg_data = update_disp_data;
> + disp_dev->disp_data_valid = false;
> +
> + cdev_init(&disp_dev->cdev, &seven_seg_disp_fops);
> + err = cdev_add(&disp_dev->cdev, seven_seg_devno, 1);
> + if (err)
> + device_destroy(seven_seg_disp_class, seven_seg_devno);
> + return err;
> +}
> +
> +static int __init seven_seg_disp_init(void)
> +{
> + if (alloc_chrdev_region(&seven_seg_devno, 0, 1, "disp_state") < 0)
> + return -1;
Do not use return -1 in kernel code.
> +
> + seven_seg_disp_class = class_create(THIS_MODULE, "disp_state");
> + if (seven_seg_disp_class == NULL)
> + goto unreg_chrdev;
> +
> +unreg_chrdev:
> + unregister_chrdev_region(seven_seg_devno, 1);
> + return -1;
Do not use return -1 in kernel code.
(Look up what an errno value of '1' means. Negative values returned from
functions are interpreted as negated errno values.)
Always propagate error codes, or select an appropriate errno value to
return.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH] ARM: dts: dra72-evm-tps65917: Add voltage supplies to usb_phy, mmc, dss
From: Lokesh Vutla @ 2016-12-14 12:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2bb73170-dbb5-01a3-5b3a-4d5d9414e3a9@ti.com>
On Wednesday 14 December 2016 04:30 PM, Roger Quadros wrote:
> Lokesh,
>
> On 14/12/16 10:57, Lokesh Vutla wrote:
>> Commit 5d080aa30681 ("ARM: dts: dra72: Add separate dtsi for tps65917")
>> added a separate dtsi for dra72-evm-tps65917 moving all the voltage supplies
>> to this file. But it missed adding voltage supplies to usb_phy, mmc,
>> dss and deleted from dra72-evm-common.dtsi. Adding the voltage supply
>> phandles to these nodes in dra72-evm-tps65917.dtsi
>>
>> Fixes: 5d080aa30681 ("ARM: dts: dra72: Add separate dtsi for tps65917")
>> Reported-by: Carlos Hernandez <ceh@ti.com>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
>> ---
>> Logs:
>> - DRA72-evm revC: http://pastebin.ubuntu.com/23627665/
>> - DRA72-evm revB: http://pastebin.ubuntu.com/23627658/
>> arch/arm/boot/dts/dra72-evm-tps65917.dtsi | 16 ++++++++++++++++
>> 1 file changed, 16 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
>> index ee6dac44edf1..e6df676886c0 100644
>> --- a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
>> +++ b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
>> @@ -132,3 +132,19 @@
>> ti,palmas-long-press-seconds = <6>;
>> };
>> };
>> +
>> +&usb2_phy1 {
>> + phy-supply = <&ldo4_reg>;
>> +};
>> +
>> +&usb2_phy2 {
>> + phy-supply = <&ldo4_reg>;
>> +};
>> +
>> +&dss {
>> + vdda_video-supply = <&ldo5_reg>;
>> +};
>> +
>> +&mmc1 {
>> + vmmc_aux-supply = <&ldo1_reg>;
>> +};
>>
>
> Are you sure that all future users of dra72-evm-tps65917.dtsi will use this same configuration?
> If not I'd rather put this in the board dts files.
hmm..This debate already happened when creating dra72-evm-tps65917 file
and concluded that all the common regulator stuff on dra72 evm revA,B,C
should go in this file. Any new board which is not similar to dra72-evm
will not be using this file.
Thanks and regards,
Lokesh
>
> cheers,
> -roger
>
^ permalink raw reply
* [PATCH 2/2] ARM: soft-reboot into same mode that we entered the kernel
From: Mark Rutland @ 2016-12-14 12:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214122945.GE14217@n2100.armlinux.org.uk>
On Wed, Dec 14, 2016 at 12:29:45PM +0000, Russell King - ARM Linux wrote:
> On Wed, Dec 14, 2016 at 12:17:47PM +0000, Mark Rutland wrote:
> > On Wed, Dec 14, 2016 at 12:05:41PM +0000, Russell King - ARM Linux wrote:
> > > The issue here is that a panic can happen at any time from any context
> > > with any hyp stub in place, so there _needs_ to be a uniform way to do
> > > this. It's very bad that we've got this far without this point having
> > > been considered - all we can do right now is to try and fix the issues
> > > as they come up.
> > >
> > > Right now, let's fix this so we get some kind of improvement, and later
> > > try to sort out some kind of uniform interface for this task.
> >
> > Sure, that's a bigger task, and this is definitely a step in the right
> > direction.
> >
> > We need to avoid the kdump regression somehow though; can we somehow
> > detect if KVM is active and avoid issuing the HVC_SOFT_RESTART?
>
> That's a question for KVM people.
>
> However, there's a bigger question, which is: what do we want to happen
> in the case of kdump - do we want to be entering the kdump kernel in
> HYP or SVC mode? As the kdump kernel exists to be able to save the
> state of a crashing system, the kdump kernel should do that and then
> restart the system in a clean way (iow, not via yet another kexec.)
>
> So maybe the right answer is that kdump should always invoke the kernel
> in SVC mode.
Personally, my view is the opposite -- we should always exit the way we
came, and kdump can go from there. Otherwise we're leaving context
active in hyp mode that might hinder kdump (or would otherwise be useful
for kdump to be able to access).
For example, we might want to do something like kernel guard, where even
the host kernel would have a stage-2 translation active in hyp that we'd
need to tear down. That, or the hyp page table might have been
corrupted, and tearing down ASAP might save us from asynchrnous issues
from page table walks. It's all a trade-off, either way -- the hyp code
could also be corrupt.
Certainly I would expect that once kdump's logged what it can, it should
trigger a real reboot.
Thanks,
Mark.
[1] https://01.org/intel-kgt
^ permalink raw reply
* [PATCH linux v1 0/4] Seven segment display support
From: Thomas Petazzoni @ 2016-12-14 12:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481702104-8617-1-git-send-email-jaghu@google.com>
Hello,
On Tue, 13 Dec 2016 23:55:00 -0800, Jaghathiswari Rankappagounder
Natarajan wrote:
> Documentation for the binding which provides an interface for adding clock,
> data and clear signal GPIO lines to control seven segment display.
>
> The platform device driver provides an API for displaying on two 7-segment
> displays, and implements the required bit-banging. The hardware assumed is
> 74HC164 wired to two 7-segment displays.
>
> The character device driver implements the user-space API for letting a user
> write to two 7-segment displays including any conversion methods necessary
> to map the user input to two 7-segment displays.
>
> Adding clock, data and clear signal GPIO lines in the devicetree to control
> seven segment display on zaius platform.
>
> The platform driver matches on the device tree node; the platform driver also
> initializes the character device.
>
> Tested that the seven segment display works properly by writing to the
> character device file on a EVB AST2500 board which also has 74HC164 wired
> to two 7-segment displays.
FWIW, I proposed a driver for seven segment displays back in 2013:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-January/139986.html
And the feedback from Greg KH was: we don't need a driver for that, do
it from userspace. See:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-January/139992.html
So: good luck :-)
Best regards,
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH] ARM: dts: dra72-evm-tps65917: Add voltage supplies to usb_phy, mmc, dss
From: Roger Quadros @ 2016-12-14 12:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <972859e0-30ff-8170-d5d3-af9b8591276b@ti.com>
On 14/12/16 14:35, Lokesh Vutla wrote:
>
>
> On Wednesday 14 December 2016 04:30 PM, Roger Quadros wrote:
>> Lokesh,
>>
>> On 14/12/16 10:57, Lokesh Vutla wrote:
>>> Commit 5d080aa30681 ("ARM: dts: dra72: Add separate dtsi for tps65917")
>>> added a separate dtsi for dra72-evm-tps65917 moving all the voltage supplies
>>> to this file. But it missed adding voltage supplies to usb_phy, mmc,
>>> dss and deleted from dra72-evm-common.dtsi. Adding the voltage supply
>>> phandles to these nodes in dra72-evm-tps65917.dtsi
>>>
>>> Fixes: 5d080aa30681 ("ARM: dts: dra72: Add separate dtsi for tps65917")
>>> Reported-by: Carlos Hernandez <ceh@ti.com>
>>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>>> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
>>> ---
>>> Logs:
>>> - DRA72-evm revC: http://pastebin.ubuntu.com/23627665/
>>> - DRA72-evm revB: http://pastebin.ubuntu.com/23627658/
>>> arch/arm/boot/dts/dra72-evm-tps65917.dtsi | 16 ++++++++++++++++
>>> 1 file changed, 16 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
>>> index ee6dac44edf1..e6df676886c0 100644
>>> --- a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
>>> +++ b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
>>> @@ -132,3 +132,19 @@
>>> ti,palmas-long-press-seconds = <6>;
>>> };
>>> };
>>> +
>>> +&usb2_phy1 {
>>> + phy-supply = <&ldo4_reg>;
>>> +};
>>> +
>>> +&usb2_phy2 {
>>> + phy-supply = <&ldo4_reg>;
>>> +};
>>> +
>>> +&dss {
>>> + vdda_video-supply = <&ldo5_reg>;
>>> +};
>>> +
>>> +&mmc1 {
>>> + vmmc_aux-supply = <&ldo1_reg>;
>>> +};
>>>
>>
>> Are you sure that all future users of dra72-evm-tps65917.dtsi will use this same configuration?
>> If not I'd rather put this in the board dts files.
>
> hmm..This debate already happened when creating dra72-evm-tps65917 file
> and concluded that all the common regulator stuff on dra72 evm revA,B,C
> should go in this file. Any new board which is not similar to dra72-evm
> will not be using this file.
OK, then it is fine. Thanks for clarifying.
cheers,
-roger
^ permalink raw reply
* [PATCH 2/2] ARM: soft-reboot into same mode that we entered the kernel
From: Russell King - ARM Linux @ 2016-12-14 12:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214124056.GI17982@leverpostej>
On Wed, Dec 14, 2016 at 12:40:56PM +0000, Mark Rutland wrote:
> On Wed, Dec 14, 2016 at 12:29:45PM +0000, Russell King - ARM Linux wrote:
> > On Wed, Dec 14, 2016 at 12:17:47PM +0000, Mark Rutland wrote:
> > > On Wed, Dec 14, 2016 at 12:05:41PM +0000, Russell King - ARM Linux wrote:
> > > > The issue here is that a panic can happen at any time from any context
> > > > with any hyp stub in place, so there _needs_ to be a uniform way to do
> > > > this. It's very bad that we've got this far without this point having
> > > > been considered - all we can do right now is to try and fix the issues
> > > > as they come up.
> > > >
> > > > Right now, let's fix this so we get some kind of improvement, and later
> > > > try to sort out some kind of uniform interface for this task.
> > >
> > > Sure, that's a bigger task, and this is definitely a step in the right
> > > direction.
> > >
> > > We need to avoid the kdump regression somehow though; can we somehow
> > > detect if KVM is active and avoid issuing the HVC_SOFT_RESTART?
> >
> > That's a question for KVM people.
> >
> > However, there's a bigger question, which is: what do we want to happen
> > in the case of kdump - do we want to be entering the kdump kernel in
> > HYP or SVC mode? As the kdump kernel exists to be able to save the
> > state of a crashing system, the kdump kernel should do that and then
> > restart the system in a clean way (iow, not via yet another kexec.)
> >
> > So maybe the right answer is that kdump should always invoke the kernel
> > in SVC mode.
>
> Personally, my view is the opposite -- we should always exit the way we
> came, and kdump can go from there. Otherwise we're leaving context
> active in hyp mode that might hinder kdump (or would otherwise be useful
> for kdump to be able to access).
>
> For example, we might want to do something like kernel guard, where even
> the host kernel would have a stage-2 translation active in hyp that we'd
> need to tear down. That, or the hyp page table might have been
> corrupted, and tearing down ASAP might save us from asynchrnous issues
> from page table walks. It's all a trade-off, either way -- the hyp code
> could also be corrupt.
However, the issue there is that if there is a hyp page table present,
it means that we're no longer saving out a true image of the running
system - the core dump expects to be an image as seen from previously
running kernel, which would be in SVC mode.
If we save out the view of memory from HYP mode, we're no longer saving
out the same thing - and the physical addresses which are stored within
kdump for things like the CPU states (which are physical addresses as
seen in SVC mode) are no longer valid.
So, to make kdump work in this situation probably needs a significant
rework of kdump's idea of what a physical address is.
In the mean time, I think the approach I've put forward is the only
sensible one until we can be sure that a HYP mode core-dump really does
make sense.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* partial bluetooth success on n900 [was Re: bluetooth/uart timeout handling]
From: Pavel Machek @ 2016-12-14 12:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201612141321.30181@pali>
Hi!
> > [ 220.248596] tty ttyO1: Radio packet sent
> > [ 220.249328] Bluetooth: hci0: Frame reassembly failed (-84)
> > [ 220.272949] tty ttyO1: wakeup received: 1 -> 0
> > [ 221.283477] tty ttyO1: radio packet timeout!
> > [ 221.283630] enqueue: hu c304cc80 skb cd4a9b40
> > [ 223.363372] Bluetooth: hci0 command 0xfc18 tx timeout
> > pavel at n900:~$
>
> In log are still some failures, but ... is bluetooth working now?
It is... for Sebastian. I'm playing with camera now.
> I see that you applied this patch:
> https://git.kernel.org/cgit/linux/kernel/git/pavel/linux-n900.git/commit/?id=051aa3fbf03ac770d8344690f5a936a7f04c6884
>
> Looks like that pinmux is in DTS file incorrect. Can somebody verify it?
> Maybe Tony?
Yes, it is. Sebastian was pretty certain about that.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161214/615b77da/attachment-0001.sig>
^ permalink raw reply
* [RFC PATCH net-next v4 1/2] macb: Add 1588 support in Cadence GEM.
From: Andrei Pistirica @ 2016-12-14 12:56 UTC (permalink / raw)
To: linux-arm-kernel
Cadence GEM provides a 102 bit time counter with 48 bits for seconds,
30 bits for nsecs and 24 bits for sub-nsecs to control 1588 timestamping.
This patch does the following:
- Registers to ptp clock framework
- Timer initialization is done by writing time of day to the timer counter.
- ns increment register is programmed as NSEC_PER_SEC/tsu-clock-rate.
For a 16 bit subns precision, the subns increment equals
remainder of (NS_PER_SEC/TSU_CLK) * (2^16).
- Timestamps are obtained from the TX/RX PTP event/PEER registers.
The timestamp obtained thus is updated in skb for upper layers to access.
- The drivers register functions with ptp to perform time and frequency
adjustment.
- Time adjustment is done by writing to the 1558_ADJUST register.
The controller will read the delta in this register and update the timer
counter register. Alternatively, for large time offset adjustments,
the driver reads the secs and nsecs counter values, adds/subtracts the
delta and updates the timer counter.
- Frequency is adjusted by adjusting addend (8bit nanosecond increment) and
addendsub (16bit increment nanosecond fractions).
The 102bit counter is incremented at nominal frequency with addend and
addendsub values. Each period addend and addendsub values are adjusted
based on ppm drift.
Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
Signed-off-by: Harini Katakam <harinik@xilinx.com>
---
Patch history:
Version 1:
This patch is based on original Harini's patch, implemented in a
separate file to ease the review/maintanance and integration with
other platforms (e.g. Zynq Ultrascale+ MPSoC).
Feature was tested on SAMA5D2 platform using ptp4l v1.6 from linuxptp
project and also with ptpd2 version 2.3.1. PTP was tested over
IPv4,IPv6 and 802.3 protocols.
In case that macb is compiled as a module, it has been renamed to
cadence-macb.ko to avoid naming confusion in Makefile.
Version 2 modifications:
- bitfields for TSU are named according to SAMA5D2 data sheet
- identify GEM-PTP support based on platform capability
- add spinlock for TSU access
- change macb_ptp_adjfreq and use fewer 64bit divisions
Version 3 modifications:
- new adjfine api with one 64 division for frequency adjustment
(based on Richard's input)
- add maximum adjustment frequency (ppb) based on nominal frequency
- per platform PTP configuration
- cosmetic changes
Note 1: Kbuild uses "select" instead of "imply", and the macb maintainer agreed
to make the change when it will be available in net-next.
Version 4 modifications:
- update adjfine for a better approximation
- add maximum adjustment frequency callback to PTP platform configuraion
Note 1: This driver does not support GEM-GXL!
Note 2: Patch on net-next, on December 14th.
drivers/net/ethernet/cadence/Kconfig | 10 +-
drivers/net/ethernet/cadence/Makefile | 8 +-
drivers/net/ethernet/cadence/macb.h | 118 ++++++++++
drivers/net/ethernet/cadence/macb_ptp.c | 366 ++++++++++++++++++++++++++++++++
4 files changed, 500 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/ethernet/cadence/macb_ptp.c
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig
index f0bcb15..ebbc65f 100644
--- a/drivers/net/ethernet/cadence/Kconfig
+++ b/drivers/net/ethernet/cadence/Kconfig
@@ -29,6 +29,14 @@ config MACB
support for the MACB/GEM chip.
To compile this driver as a module, choose M here: the module
- will be called macb.
+ will be called cadence-macb.
+
+config MACB_USE_HWSTAMP
+ bool "Use IEEE 1588 hwstamp"
+ depends on MACB
+ default y
+ select PTP_1588_CLOCK
+ ---help---
+ Enable IEEE 1588 Precision Time Protocol (PTP) support for MACB.
endif # NET_CADENCE
diff --git a/drivers/net/ethernet/cadence/Makefile b/drivers/net/ethernet/cadence/Makefile
index 91f79b1..4402d42 100644
--- a/drivers/net/ethernet/cadence/Makefile
+++ b/drivers/net/ethernet/cadence/Makefile
@@ -2,4 +2,10 @@
# Makefile for the Atmel network device drivers.
#
-obj-$(CONFIG_MACB) += macb.o
+cadence-macb-y := macb.o
+
+ifeq ($(CONFIG_MACB_USE_HWSTAMP),y)
+cadence-macb-y += macb_ptp.o
+endif
+
+obj-$(CONFIG_MACB) += cadence-macb.o
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index d67adad..e65e985 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -10,6 +10,9 @@
#ifndef _MACB_H
#define _MACB_H
+#include <linux/ptp_clock.h>
+#include <linux/ptp_clock_kernel.h>
+
#define MACB_GREGS_NBR 16
#define MACB_GREGS_VERSION 2
#define MACB_MAX_QUEUES 8
@@ -131,6 +134,20 @@
#define GEM_RXIPCCNT 0x01a8 /* IP header Checksum Error Counter */
#define GEM_RXTCPCCNT 0x01ac /* TCP Checksum Error Counter */
#define GEM_RXUDPCCNT 0x01b0 /* UDP Checksum Error Counter */
+#define GEM_TISUBN 0x01bc /* 1588 Timer Increment Sub-ns */
+#define GEM_TSH 0x01c0 /* 1588 Timer Seconds High */
+#define GEM_TSL 0x01d0 /* 1588 Timer Seconds Low */
+#define GEM_TN 0x01d4 /* 1588 Timer Nanoseconds */
+#define GEM_TA 0x01d8 /* 1588 Timer Adjust */
+#define GEM_TI 0x01dc /* 1588 Timer Increment */
+#define GEM_EFTSL 0x01e0 /* PTP Event Frame Tx Seconds Low */
+#define GEM_EFTN 0x01e4 /* PTP Event Frame Tx Nanoseconds */
+#define GEM_EFRSL 0x01e8 /* PTP Event Frame Rx Seconds Low */
+#define GEM_EFRN 0x01ec /* PTP Event Frame Rx Nanoseconds */
+#define GEM_PEFTSL 0x01f0 /* PTP Peer Event Frame Tx Secs Low */
+#define GEM_PEFTN 0x01f4 /* PTP Peer Event Frame Tx Ns */
+#define GEM_PEFRSL 0x01f8 /* PTP Peer Event Frame Rx Sec Low */
+#define GEM_PEFRN 0x01fc /* PTP Peer Event Frame Rx Ns */
#define GEM_DCFG1 0x0280 /* Design Config 1 */
#define GEM_DCFG2 0x0284 /* Design Config 2 */
#define GEM_DCFG3 0x0288 /* Design Config 3 */
@@ -174,6 +191,7 @@
#define MACB_NCR_TPF_SIZE 1
#define MACB_TZQ_OFFSET 12 /* Transmit zero quantum pause frame */
#define MACB_TZQ_SIZE 1
+#define MACB_SRTSM_OFFSET 15
/* Bitfields in NCFGR */
#define MACB_SPD_OFFSET 0 /* Speed */
@@ -319,6 +337,32 @@
#define MACB_PTZ_SIZE 1
#define MACB_WOL_OFFSET 14 /* Enable wake-on-lan interrupt */
#define MACB_WOL_SIZE 1
+#define MACB_DRQFR_OFFSET 18 /* PTP Delay Request Frame Received */
+#define MACB_DRQFR_SIZE 1
+#define MACB_SFR_OFFSET 19 /* PTP Sync Frame Received */
+#define MACB_SFR_SIZE 1
+#define MACB_DRQFT_OFFSET 20 /* PTP Delay Request Frame Transmitted */
+#define MACB_DRQFT_SIZE 1
+#define MACB_SFT_OFFSET 21 /* PTP Sync Frame Transmitted */
+#define MACB_SFT_SIZE 1
+#define MACB_PDRQFR_OFFSET 22 /* PDelay Request Frame Received */
+#define MACB_PDRQFR_SIZE 1
+#define MACB_PDRSFR_OFFSET 23 /* PDelay Response Frame Received */
+#define MACB_PDRSFR_SIZE 1
+#define MACB_PDRQFT_OFFSET 24 /* PDelay Request Frame Transmitted */
+#define MACB_PDRQFT_SIZE 1
+#define MACB_PDRSFT_OFFSET 25 /* PDelay Response Frame Transmitted */
+#define MACB_PDRSFT_SIZE 1
+#define MACB_SRI_OFFSET 26 /* TSU Seconds Register Increment */
+#define MACB_SRI_SIZE 1
+
+/* Timer increment fields */
+#define MACB_TI_CNS_OFFSET 0
+#define MACB_TI_CNS_SIZE 8
+#define MACB_TI_ACNS_OFFSET 8
+#define MACB_TI_ACNS_SIZE 8
+#define MACB_TI_NIT_OFFSET 16
+#define MACB_TI_NIT_SIZE 8
/* Bitfields in MAN */
#define MACB_DATA_OFFSET 0 /* data */
@@ -386,6 +430,17 @@
#define GEM_PBUF_LSO_OFFSET 27
#define GEM_PBUF_LSO_SIZE 1
+/* Bitfields in TISUBN */
+#define GEM_SUBNSINCR_OFFSET 0
+#define GEM_SUBNSINCR_SIZE 16
+
+/* Bitfields in TI */
+#define GEM_NSINCR_OFFSET 0
+#define GEM_NSINCR_SIZE 8
+
+/* Bitfields in ADJ */
+#define GEM_ADDSUB_OFFSET 31
+#define GEM_ADDSUB_SIZE 1
/* Constants for CLK */
#define MACB_CLK_DIV8 0
#define MACB_CLK_DIV16 1
@@ -417,6 +472,7 @@
#define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000
#define MACB_CAPS_SG_DISABLED 0x40000000
#define MACB_CAPS_MACB_IS_GEM 0x80000000
+#define MACB_CAPS_GEM_HAS_PTP 0x00000020
/* LSO settings */
#define MACB_LSO_UFO_ENABLE 0x01
@@ -782,6 +838,20 @@ struct macb_or_gem_ops {
int (*mog_rx)(struct macb *bp, int budget);
};
+/* MACB-PTP interface: adapt to platform needs and GEM (e.g. GXL). */
+struct macb_ptp_info {
+ void (*ptp_init)(struct net_device *ndev);
+ void (*ptp_remove)(struct net_device *ndev);
+ s32 (*get_ptp_max_adj)(void);
+ unsigned int (*get_tsu_rate)(struct macb *bp);
+ int (*get_ts_info)(struct net_device *dev,
+ struct ethtool_ts_info *info);
+ int (*get_hwtst)(struct net_device *netdev,
+ struct ifreq *ifr);
+ int (*set_hwtst)(struct net_device *netdev,
+ struct ifreq *ifr, int cmd);
+};
+
struct macb_config {
u32 caps;
unsigned int dma_burst_length;
@@ -874,11 +944,59 @@ struct macb {
unsigned int jumbo_max_len;
u32 wol;
+
+ struct macb_ptp_info *ptp_info;
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ bool hwts_tx_en;
+ bool hwts_rx_en;
+ spinlock_t tsu_clk_lock; /* gem tsu clock locking */
+ unsigned int tsu_rate;
+
+ struct ptp_clock *ptp_clock;
+ struct ptp_clock_info ptp_caps;
+ u32 ns_incr;
+ u32 subns_incr;
+#endif
};
+#ifdef CONFIG_MACB_USE_HWSTAMP
+void gem_ptp_init(struct net_device *ndev);
+void gem_ptp_remove(struct net_device *ndev);
+void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb);
+void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb);
+
+static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb)
+{
+ if (!bp->hwts_tx_en)
+ return;
+
+ return gem_ptp_txstamp(bp, skb);
+}
+
+static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb)
+{
+ if (!bp->hwts_rx_en)
+ return;
+
+ return gem_ptp_rxstamp(bp, skb);
+}
+
+#else
+static inline void gem_ptp_init(struct net_device *ndev) { }
+static inline void gem_ptp_remove(struct net_device *ndev) { }
+
+static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb) { }
+static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb) { }
+#endif
+
static inline bool macb_is_gem(struct macb *bp)
{
return !!(bp->caps & MACB_CAPS_MACB_IS_GEM);
}
+static inline bool gem_has_ptp(struct macb *bp)
+{
+ return !!(bp->caps & MACB_CAPS_GEM_HAS_PTP);
+}
+
#endif /* _MACB_H */
diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
new file mode 100644
index 0000000..6121b2a
--- /dev/null
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -0,0 +1,366 @@
+/*
+ * 1588 PTP support for GEM device.
+ *
+ * Copyright (C) 2016 Microchip Technology
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/time64.h>
+#include <linux/ptp_classify.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/net_tstamp.h>
+
+#include "macb.h"
+
+#define GEM_PTP_TIMER_NAME "gem-ptp-timer"
+
+static inline void gem_tsu_get_time(struct macb *bp,
+ struct timespec64 *ts)
+{
+ u64 sec, sech, secl;
+
+ spin_lock(&bp->tsu_clk_lock);
+
+ /* GEM's internal time */
+ sech = gem_readl(bp, TSH);
+ secl = gem_readl(bp, TSL);
+ ts->tv_nsec = gem_readl(bp, TN);
+ ts->tv_sec = (sech << 32) | secl;
+
+ /* minimize error */
+ sech = gem_readl(bp, TSH);
+ secl = gem_readl(bp, TSL);
+ sec = (sech << 32) | secl;
+ if (ts->tv_sec != sec) {
+ ts->tv_sec = sec;
+ ts->tv_nsec = gem_readl(bp, TN);
+ }
+
+ spin_unlock(&bp->tsu_clk_lock);
+}
+
+static inline void gem_tsu_set_time(struct macb *bp,
+ const struct timespec64 *ts)
+{
+ u32 ns, sech, secl;
+ s64 word_mask = 0xffffffff;
+
+ sech = (u32)ts->tv_sec;
+ secl = (u32)ts->tv_sec;
+ ns = ts->tv_nsec;
+ if (ts->tv_sec > word_mask)
+ sech = (ts->tv_sec >> 32);
+
+ spin_lock(&bp->tsu_clk_lock);
+
+ /* TSH doesn't latch the time and no atomicity! */
+ gem_writel(bp, TN, 0); /* clear to avoid overflow */
+ gem_writel(bp, TSH, sech);
+ gem_writel(bp, TSL, secl);
+ gem_writel(bp, TN, ns);
+
+ spin_unlock(&bp->tsu_clk_lock);
+}
+
+static int gem_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_caps);
+ u32 word, diff;
+ u64 adj, rate;
+ int neg_adj = 0;
+
+ if (scaled_ppm < 0) {
+ neg_adj = 1;
+ scaled_ppm = -scaled_ppm;
+ }
+ rate = scaled_ppm;
+
+ /* word: unused(8bit) | ns(8bit) | fractions(16bit) */
+ word = (bp->ns_incr << 16) + bp->subns_incr;
+
+ adj = word;
+ adj *= rate;
+ adj += 500000UL << 16;
+ adj >>= 16; /* remove fractions */
+ diff = div_u64(adj, 1000000UL);
+ word = neg_adj ? word - diff : word + diff;
+
+ spin_lock(&bp->tsu_clk_lock);
+
+ gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, (word & 0xffff)));
+ gem_writel(bp, TI, GEM_BF(NSINCR, (word >> 16)));
+
+ spin_unlock(&bp->tsu_clk_lock);
+ return 0;
+}
+
+static int gem_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_caps);
+ struct timespec64 now, then = ns_to_timespec64(delta);
+ u32 adj, sign = 0;
+
+ if (delta < 0) {
+ delta = -delta;
+ sign = 1;
+ }
+
+ if (delta > 0x3FFFFFFF) {
+ gem_tsu_get_time(bp, &now);
+
+ if (sign)
+ now = timespec64_sub(now, then);
+ else
+ now = timespec64_add(now, then);
+
+ gem_tsu_set_time(bp, (const struct timespec64 *)&now);
+ } else {
+ adj = delta;
+ if (sign)
+ adj |= GEM_BIT(ADDSUB);
+
+ gem_writel(bp, TA, adj);
+ }
+
+ return 0;
+}
+
+static int gem_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_caps);
+
+ gem_tsu_get_time(bp, ts);
+
+ return 0;
+}
+
+static int gem_ptp_settime(struct ptp_clock_info *ptp,
+ const struct timespec64 *ts)
+{
+ struct macb *bp = container_of(ptp, struct macb, ptp_caps);
+
+ gem_tsu_set_time(bp, ts);
+
+ return 0;
+}
+
+static int gem_ptp_enable(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq, int on)
+{
+ return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info gem_ptp_caps_template = {
+ .owner = THIS_MODULE,
+ .name = GEM_PTP_TIMER_NAME,
+ .max_adj = 0,
+ .n_alarm = 0,
+ .n_ext_ts = 0,
+ .n_per_out = 0,
+ .n_pins = 0,
+ .pps = 0,
+ .adjfine = gem_ptp_adjfine,
+ .adjtime = gem_ptp_adjtime,
+ .gettime64 = gem_ptp_gettime,
+ .settime64 = gem_ptp_settime,
+ .enable = gem_ptp_enable,
+};
+
+static void gem_ptp_init_timer(struct macb *bp)
+{
+ struct timespec64 now;
+ u32 rem = 0;
+
+ getnstimeofday64(&now);
+ gem_tsu_set_time(bp, (const struct timespec64 *)&now);
+
+ bp->ns_incr = div_u64_rem(NSEC_PER_SEC, bp->tsu_rate, &rem);
+ if (rem) {
+ u64 adj = rem;
+
+ adj <<= 16; /* 16 bits nsec fragments */
+ bp->subns_incr = div_u64(adj, bp->tsu_rate);
+ } else {
+ bp->subns_incr = 0;
+ }
+
+ gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, bp->subns_incr));
+ gem_writel(bp, TI, GEM_BF(NSINCR, bp->ns_incr));
+ gem_writel(bp, TA, 0);
+}
+
+static void gem_ptp_clear_timer(struct macb *bp)
+{
+ bp->ns_incr = 0;
+ bp->subns_incr = 0;
+
+ gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, 0));
+ gem_writel(bp, TI, GEM_BF(NSINCR, 0));
+ gem_writel(bp, TA, 0);
+}
+
+/* While GEM can timestamp PTP packets, it does not mark the RX descriptor
+ * to identify them. UDP packets must be parsed to identify PTP packets.
+ *
+ * Note: Inspired from drivers/net/ethernet/ti/cpts.c
+ */
+static int gem_get_ptp_peer(struct sk_buff *skb, int ptp_class)
+{
+ unsigned int offset = 0;
+ u8 *msgtype, *data = skb->data;
+
+ /* PTP frames are rare! */
+ if (likely(ptp_class == PTP_CLASS_NONE))
+ return -1;
+
+ if (ptp_class & PTP_CLASS_VLAN)
+ offset += VLAN_HLEN;
+
+ switch (ptp_class & PTP_CLASS_PMASK) {
+ case PTP_CLASS_IPV4:
+ offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN;
+ break;
+ case PTP_CLASS_IPV6:
+ offset += ETH_HLEN + IP6_HLEN + UDP_HLEN;
+ break;
+ case PTP_CLASS_L2:
+ offset += ETH_HLEN;
+ break;
+
+ /* something went wrong! */
+ default:
+ return -1;
+ }
+
+ if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID)
+ return -1;
+
+ if (unlikely(ptp_class & PTP_CLASS_V1))
+ msgtype = data + offset + OFF_PTP_CONTROL;
+ else
+ msgtype = data + offset;
+
+ return (*msgtype) & 0x2;
+}
+
+static void gem_ptp_tx_hwtstamp(struct macb *bp, struct sk_buff *skb,
+ int peer_ev)
+{
+ struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
+ struct timespec64 ts;
+ u64 ns;
+
+ /* PTP Peer Event Frame packets */
+ if (peer_ev) {
+ ts.tv_sec = gem_readl(bp, PEFTSL);
+ ts.tv_nsec = gem_readl(bp, PEFTN);
+
+ /* PTP Event Frame packets */
+ } else {
+ ts.tv_sec = gem_readl(bp, EFTSL);
+ ts.tv_nsec = gem_readl(bp, EFTN);
+ }
+ ns = timespec64_to_ns(&ts);
+
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+ skb_tstamp_tx(skb, skb_hwtstamps(skb));
+}
+
+static void gem_ptp_rx_hwtstamp(struct macb *bp, struct sk_buff *skb,
+ int peer_ev)
+{
+ struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
+ struct timespec64 ts;
+ u64 ns;
+
+ if (peer_ev) {
+ /* PTP Peer Event Frame packets */
+ ts.tv_sec = gem_readl(bp, PEFRSL);
+ ts.tv_nsec = gem_readl(bp, PEFRN);
+ } else {
+ /* PTP Event Frame packets */
+ ts.tv_sec = gem_readl(bp, EFRSL);
+ ts.tv_nsec = gem_readl(bp, EFRN);
+ }
+ ns = timespec64_to_ns(&ts);
+
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+}
+
+/* no static, GEM PTP interface functions */
+void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb)
+{
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ int class = ptp_classify_raw(skb);
+ int peer;
+
+ peer = gem_get_ptp_peer(skb, class);
+ if (peer < 0)
+ return;
+
+ /* Timestamp this packet */
+ gem_ptp_tx_hwtstamp(bp, skb, peer);
+ }
+}
+
+void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb)
+{
+ int class, peer;
+
+ __skb_push(skb, ETH_HLEN);
+ class = ptp_classify_raw(skb);
+ __skb_pull(skb, ETH_HLEN);
+
+ peer = gem_get_ptp_peer(skb, class);
+ if (peer < 0)
+ return;
+
+ gem_ptp_rx_hwtstamp(bp, skb, peer);
+}
+
+void gem_ptp_init(struct net_device *ndev)
+{
+ struct macb *bp = netdev_priv(ndev);
+
+ spin_lock_init(&bp->tsu_clk_lock);
+ bp->ptp_caps = gem_ptp_caps_template;
+
+ /* nominal frequency and maximum adjustment in ppb */
+ bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp);
+ bp->ptp_caps.max_adj = bp->ptp_info->get_ptp_max_adj();
+
+ gem_ptp_init_timer(bp);
+
+ bp->ptp_clock = ptp_clock_register(&bp->ptp_caps, NULL);
+ if (IS_ERR(&bp->ptp_clock)) {
+ bp->ptp_clock = NULL;
+ pr_err("ptp clock register failed\n");
+ return;
+ }
+
+ dev_info(&bp->pdev->dev, "%s ptp clock registered.\n",
+ GEM_PTP_TIMER_NAME);
+}
+
+void gem_ptp_remove(struct net_device *ndev)
+{
+ struct macb *bp = netdev_priv(ndev);
+
+ if (bp->ptp_clock)
+ ptp_clock_unregister(bp->ptp_clock);
+
+ gem_ptp_clear_timer(bp);
+
+ dev_info(&bp->pdev->dev, "%s ptp clock unregistered.\n",
+ GEM_PTP_TIMER_NAME);
+}
--
2.7.4
^ permalink raw reply related
* [RFC PATCH net-next v4 2/2] macb: Enable 1588 support in SAMA5Dx platforms.
From: Andrei Pistirica @ 2016-12-14 12:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481720175-12703-1-git-send-email-andrei.pistirica@microchip.com>
This patch does the following:
- Enable HW time stamp for the following platforms: SAMA5D2, SAMA5D3 and
SAMA5D4.
- HW time stamp capabilities are advertised via ethtool and macb ioctl is
updated accordingly.
- HW time stamp on the PTP Ethernet packets are received using the
SO_TIMESTAMPING API. Where timers are obtained from the PTP event/peer
registers.
Note: Patch on net-next, on December 7th.
Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
---
Patch history:
Version 1:
Integration with SAMA5D2 only. This feature wasn't tested on any
other platform that might use cadence/gem.
Patch is not completely ported to the very latest version of net-next,
and it will be after review.
Version 2 modifications:
- add PTP caps for SAMA5D2/3/4 platforms
- and cosmetic changes
Version 3 modifications:
- add support for sama5D2/3/4 platforms using GEM-PTP interface.
Version 4 modifications:
- time stamp only PTP_V2 events
- maximum adjustment value is set based on Richard's input
Note: Patch on net-next, on December 14th.
drivers/net/ethernet/cadence/macb.c | 168 ++++++++++++++++++++++++++++++++++--
1 file changed, 163 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 538544a..8d5c976 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -714,6 +714,8 @@ static void macb_tx_interrupt(struct macb_queue *queue)
/* First, update TX stats if needed */
if (skb) {
+ gem_ptp_do_txstamp(bp, skb);
+
netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
macb_tx_ring_wrap(bp, tail),
skb->data);
@@ -878,6 +880,8 @@ static int gem_rx(struct macb *bp, int budget)
GEM_BFEXT(RX_CSUM, ctrl) & GEM_RX_CSUM_CHECKED_MASK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
+ gem_ptp_do_rxstamp(bp, skb);
+
bp->stats.rx_packets++;
bp->stats.rx_bytes += skb->len;
@@ -2080,6 +2084,9 @@ static int macb_open(struct net_device *dev)
netif_tx_start_all_queues(dev);
+ if (bp->ptp_info)
+ bp->ptp_info->ptp_init(dev);
+
return 0;
}
@@ -2101,6 +2108,9 @@ static int macb_close(struct net_device *dev)
macb_free_consistent(bp);
+ if (bp->ptp_info)
+ bp->ptp_info->ptp_remove(dev);
+
return 0;
}
@@ -2374,6 +2384,133 @@ static int macb_set_ringparam(struct net_device *netdev,
return 0;
}
+#ifdef CONFIG_MACB_USE_HWSTAMP
+static unsigned int gem_get_tsu_rate(struct macb *bp)
+{
+ /* Note: TSU rate is hardwired to PCLK. */
+ return clk_get_rate(bp->pclk);
+}
+
+static s32 gem_get_ptp_max_adj(void)
+{
+ return 3921508;
+}
+
+static int gem_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ struct macb *bp = netdev_priv(dev);
+
+ ethtool_op_get_ts_info(dev, info);
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->phc_index = -1;
+
+ if (bp->ptp_clock)
+ info->phc_index = ptp_clock_index(bp->ptp_clock);
+
+ return 0;
+}
+
+static int gem_set_hwtst(struct net_device *netdev,
+ struct ifreq *ifr, int cmd)
+{
+ struct hwtstamp_config config;
+ struct macb *priv = netdev_priv(netdev);
+ u32 regval;
+
+ netdev_vdbg(netdev, "macb_hwtstamp_ioctl\n");
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ priv->hwts_tx_en = false;
+ break;
+ case HWTSTAMP_TX_ON:
+ priv->hwts_tx_en = true;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ if (priv->hwts_rx_en)
+ priv->hwts_rx_en = false;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ regval = macb_readl(priv, NCR);
+ macb_writel(priv, NCR, (regval | MACB_BIT(SRTSM)));
+
+ if (!priv->hwts_rx_en)
+ priv->hwts_rx_en = true;
+ break;
+ default:
+ config.rx_filter = HWTSTAMP_FILTER_NONE;
+ return -ERANGE;
+ }
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
+static int gem_get_hwtst(struct net_device *netdev,
+ struct ifreq *ifr)
+{
+ struct hwtstamp_config config;
+ struct macb *priv = netdev_priv(netdev);
+
+ config.flags = 0;
+ config.tx_type = priv->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+ config.rx_filter = (priv->hwts_rx_en ?
+ HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE);
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
+static struct macb_ptp_info gem_ptp_info = {
+ .ptp_init = gem_ptp_init,
+ .ptp_remove = gem_ptp_remove,
+ .get_ptp_max_adj = gem_get_ptp_max_adj,
+ .get_tsu_rate = gem_get_tsu_rate,
+ .get_ts_info = gem_get_ts_info,
+ .get_hwtst = gem_get_hwtst,
+ .set_hwtst = gem_set_hwtst,
+};
+#endif
+
+static int macb_get_ts_info(struct net_device *netdev,
+ struct ethtool_ts_info *info)
+{
+ struct macb *bp = netdev_priv(netdev);
+
+ if (bp->ptp_info)
+ return bp->ptp_info->get_ts_info(netdev, info);
+
+ return ethtool_op_get_ts_info(netdev, info);
+}
+
static const struct ethtool_ops macb_ethtool_ops = {
.get_regs_len = macb_get_regs_len,
.get_regs = macb_get_regs,
@@ -2391,7 +2528,7 @@ static const struct ethtool_ops gem_ethtool_ops = {
.get_regs_len = macb_get_regs_len,
.get_regs = macb_get_regs,
.get_link = ethtool_op_get_link,
- .get_ts_info = ethtool_op_get_ts_info,
+ .get_ts_info = macb_get_ts_info,
.get_ethtool_stats = gem_get_ethtool_stats,
.get_strings = gem_get_ethtool_strings,
.get_sset_count = gem_get_sset_count,
@@ -2404,6 +2541,7 @@ static const struct ethtool_ops gem_ethtool_ops = {
static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct phy_device *phydev = dev->phydev;
+ struct macb *bp = netdev_priv(dev);
if (!netif_running(dev))
return -EINVAL;
@@ -2411,7 +2549,20 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (!phydev)
return -ENODEV;
- return phy_mii_ioctl(phydev, rq, cmd);
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ if (bp->ptp_info)
+ return bp->ptp_info->set_hwtst(dev, rq, cmd);
+
+ return -EOPNOTSUPP;
+ case SIOCGHWTSTAMP:
+ if (bp->ptp_info)
+ return bp->ptp_info->get_hwtst(dev, rq);
+
+ return -EOPNOTSUPP;
+ default:
+ return phy_mii_ioctl(phydev, rq, cmd);
+ }
}
static int macb_set_features(struct net_device *netdev,
@@ -2485,6 +2636,12 @@ static void macb_configure_caps(struct macb *bp,
dcfg = gem_readl(bp, DCFG2);
if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
bp->caps |= MACB_CAPS_FIFO_MODE;
+
+ /* iff HWSTAMP is configure and gem has the capability */
+#ifdef CONFIG_MACB_USE_HWSTAMP
+ if (gem_has_ptp(bp))
+ bp->ptp_info = &gem_ptp_info;
+#endif
}
dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps);
@@ -3041,7 +3198,7 @@ static const struct macb_config pc302gem_config = {
};
static const struct macb_config sama5d2_config = {
- .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
@@ -3049,14 +3206,15 @@ static const struct macb_config sama5d2_config = {
static const struct macb_config sama5d3_config = {
.caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE
- | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII
+ | MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
};
static const struct macb_config sama5d4_config = {
- .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII,
+ .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_GEM_HAS_PTP,
.dma_burst_length = 4,
.clk_init = macb_clk_init,
.init = macb_init,
--
2.7.4
^ permalink raw reply related
* [PATCH linux v1 0/4] Seven segment display support
From: Greg KH @ 2016-12-14 12:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214134530.2bd54a4e@free-electrons.com>
On Wed, Dec 14, 2016 at 01:45:30PM +0100, Thomas Petazzoni wrote:
> Hello,
>
> On Tue, 13 Dec 2016 23:55:00 -0800, Jaghathiswari Rankappagounder
> Natarajan wrote:
>
> > Documentation for the binding which provides an interface for adding clock,
> > data and clear signal GPIO lines to control seven segment display.
> >
> > The platform device driver provides an API for displaying on two 7-segment
> > displays, and implements the required bit-banging. The hardware assumed is
> > 74HC164 wired to two 7-segment displays.
> >
> > The character device driver implements the user-space API for letting a user
> > write to two 7-segment displays including any conversion methods necessary
> > to map the user input to two 7-segment displays.
> >
> > Adding clock, data and clear signal GPIO lines in the devicetree to control
> > seven segment display on zaius platform.
> >
> > The platform driver matches on the device tree node; the platform driver also
> > initializes the character device.
> >
> > Tested that the seven segment display works properly by writing to the
> > character device file on a EVB AST2500 board which also has 74HC164 wired
> > to two 7-segment displays.
>
> FWIW, I proposed a driver for seven segment displays back in 2013:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2013-January/139986.html
>
> And the feedback from Greg KH was: we don't need a driver for that, do
> it from userspace. See:
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2013-January/139992.html
>
> So: good luck :-)
Did anyone ever write a library for this type of thing?
Again, I don't want to see one-off drivers for random devices like this
that should be able to all be controlled from userspace in a common
manner. Much like we did for fingerprint readers a long long time
ago...
thanks,
greg k-h
^ permalink raw reply
* [PATCH 0/2] video/sti/cec: add HDMI notifier support
From: Benjamin Gaignard @ 2016-12-14 12:57 UTC (permalink / raw)
To: linux-arm-kernel
Following (copying !) what Hans have done in this serie of patches
http://www.spinics.net/lists/linux-media/msg109141.html
I have implemented hdmi notifier in hdmi controled and stih-cec drivers.
Those patches should be applied on top of Hans patches for exynos.
I have tested hdmi notifier by pluging/unpluging HDMI cable and check
the value of the physical address with "cec-ctl --tuner".
"cec-compliance -A" is also functional.
Hans, I haven't move stih-cec out of staging because I don't have the
exact branch to test it, can you do the move for stih-cec after applying
those patches ?
Regards,
Benjamin
Benjamin Gaignard (2):
sti: hdmi: add HDMI notifier support
stih-cec: add hdmi-notifier support
.../devicetree/bindings/media/stih-cec.txt | 2 ++
arch/arm/boot/dts/stih407-family.dtsi | 12 ---------
arch/arm/boot/dts/stih410.dtsi | 15 ++++++++++-
drivers/gpu/drm/sti/Kconfig | 1 +
drivers/gpu/drm/sti/sti_hdmi.c | 15 +++++++++++
drivers/gpu/drm/sti/sti_hdmi.h | 2 ++
drivers/staging/media/st-cec/Kconfig | 1 +
drivers/staging/media/st-cec/stih-cec.c | 29 +++++++++++++++++++++-
8 files changed, 63 insertions(+), 14 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH 1/2] sti: hdmi: add HDMI notifier support
From: Benjamin Gaignard @ 2016-12-14 12:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481720229-7587-1-git-send-email-benjamin.gaignard@linaro.org>
Implement the HDMI notifier support to allow CEC drivers to
be informed when there is a new EDID and when a connect or
disconnect happens.
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
---
drivers/gpu/drm/sti/Kconfig | 1 +
drivers/gpu/drm/sti/sti_hdmi.c | 15 +++++++++++++++
drivers/gpu/drm/sti/sti_hdmi.h | 2 ++
3 files changed, 18 insertions(+)
diff --git a/drivers/gpu/drm/sti/Kconfig b/drivers/gpu/drm/sti/Kconfig
index acd7286..59ceffc 100644
--- a/drivers/gpu/drm/sti/Kconfig
+++ b/drivers/gpu/drm/sti/Kconfig
@@ -8,5 +8,6 @@ config DRM_STI
select DRM_PANEL
select FW_LOADER
select SND_SOC_HDMI_CODEC if SND_SOC
+ select HDMI_NOTIFIERS
help
Choose this option to enable DRM on STM stiH4xx chipset
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 376b076..6667371 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -786,6 +786,8 @@ static void sti_hdmi_disable(struct drm_bridge *bridge)
clk_disable_unprepare(hdmi->clk_pix);
hdmi->enabled = false;
+
+ hdmi_event_disconnect(hdmi->notifier);
}
static void sti_hdmi_pre_enable(struct drm_bridge *bridge)
@@ -892,6 +894,10 @@ static int sti_hdmi_connector_get_modes(struct drm_connector *connector)
if (!edid)
goto fail;
+ hdmi_event_connect(hdmi->notifier);
+ hdmi_event_new_edid(hdmi->notifier, edid,
+ EDID_LENGTH * (edid->extensions + 1));
+
count = drm_add_edid_modes(connector, edid);
drm_mode_connector_update_edid_property(connector, edid);
drm_edid_to_eld(connector, edid);
@@ -949,10 +955,12 @@ struct drm_connector_helper_funcs sti_hdmi_connector_helper_funcs = {
if (hdmi->hpd) {
DRM_DEBUG_DRIVER("hdmi cable connected\n");
+ hdmi_event_connect(hdmi->notifier);
return connector_status_connected;
}
DRM_DEBUG_DRIVER("hdmi cable disconnected\n");
+ hdmi_event_disconnect(hdmi->notifier);
return connector_status_disconnected;
}
@@ -1464,6 +1472,10 @@ static int sti_hdmi_probe(struct platform_device *pdev)
goto release_adapter;
}
+ hdmi->notifier = hdmi_notifier_get(&pdev->dev);
+ if (!hdmi->notifier)
+ goto release_adapter;
+
hdmi->reset = devm_reset_control_get(dev, "hdmi");
/* Take hdmi out of reset */
if (!IS_ERR(hdmi->reset))
@@ -1483,11 +1495,14 @@ static int sti_hdmi_remove(struct platform_device *pdev)
{
struct sti_hdmi *hdmi = dev_get_drvdata(&pdev->dev);
+ hdmi_event_disconnect(hdmi->notifier);
+
i2c_put_adapter(hdmi->ddc_adapt);
if (hdmi->audio_pdev)
platform_device_unregister(hdmi->audio_pdev);
component_del(&pdev->dev, &sti_hdmi_ops);
+ hdmi_notifier_put(hdmi->notifier);
return 0;
}
diff --git a/drivers/gpu/drm/sti/sti_hdmi.h b/drivers/gpu/drm/sti/sti_hdmi.h
index 119bc35..70aac98 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.h
+++ b/drivers/gpu/drm/sti/sti_hdmi.h
@@ -8,6 +8,7 @@
#define _STI_HDMI_H_
#include <linux/hdmi.h>
+#include <linux/hdmi-notifier.h>
#include <linux/platform_device.h>
#include <drm/drmP.h>
@@ -102,6 +103,7 @@ struct sti_hdmi {
struct platform_device *audio_pdev;
struct hdmi_audio_params audio;
struct drm_connector *drm_connector;
+ struct hdmi_notifier *notifier;
};
u32 hdmi_read(struct sti_hdmi *hdmi, int offset);
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] stih-cec: add hdmi-notifier support
From: Benjamin Gaignard @ 2016-12-14 12:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481720229-7587-1-git-send-email-benjamin.gaignard@linaro.org>
By using the HDMI notifier framework there is no longer any reason
to manually set the physical address. This was the one blocking
issue that prevented this driver from going out of staging, so do
this move as well.
Update the bindings documenting the new hdmi phandle and
update stih410.dtsi and stih407-family.dtsi accordingly.
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
---
.../devicetree/bindings/media/stih-cec.txt | 2 ++
arch/arm/boot/dts/stih407-family.dtsi | 12 ---------
arch/arm/boot/dts/stih410.dtsi | 15 ++++++++++-
drivers/staging/media/st-cec/Kconfig | 1 +
drivers/staging/media/st-cec/stih-cec.c | 29 +++++++++++++++++++++-
5 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/stih-cec.txt b/Documentation/devicetree/bindings/media/stih-cec.txt
index 71c4b2f..7d82121 100644
--- a/Documentation/devicetree/bindings/media/stih-cec.txt
+++ b/Documentation/devicetree/bindings/media/stih-cec.txt
@@ -9,6 +9,7 @@ Required properties:
- pinctrl-names: Contains only one value - "default"
- pinctrl-0: Specifies the pin control groups used for CEC hardware.
- resets: Reference to a reset controller
+ - st,hdmi-handle: Phandle to the HMDI controller
Example for STIH407:
@@ -22,4 +23,5 @@ sti-cec at 094a087c {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_cec0_default>;
resets = <&softreset STIH407_LPM_SOFTRESET>;
+ st,hdmi-handle = <&hdmi>;
};
diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 8f79b41..ef7c79a 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -756,18 +756,6 @@
<&clk_s_c0_flexgen CLK_ETH_PHY>;
};
- cec: sti-cec at 094a087c {
- compatible = "st,stih-cec";
- reg = <0x94a087c 0x64>;
- clocks = <&clk_sysin>;
- clock-names = "cec-clk";
- interrupts = <GIC_SPI 140 IRQ_TYPE_NONE>;
- interrupt-names = "cec-irq";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_cec0_default>;
- resets = <&softreset STIH407_LPM_SOFTRESET>;
- };
-
rng10: rng at 08a89000 {
compatible = "st,rng";
reg = <0x08a89000 0x1000>;
diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index a3ef734..c98d86e 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -193,7 +193,7 @@
<&clk_s_d2_quadfs 0>;
};
- sti-hdmi at 8d04000 {
+ hdmi: sti-hdmi at 8d04000 {
compatible = "st,stih407-hdmi";
reg = <0x8d04000 0x1000>;
reg-names = "hdmi-reg";
@@ -259,5 +259,18 @@
clocks = <&clk_sysin>;
interrupts = <GIC_SPI 205 IRQ_TYPE_EDGE_RISING>;
};
+
+ sti-cec at 094a087c {
+ compatible = "st,stih-cec";
+ reg = <0x94a087c 0x64>;
+ clocks = <&clk_sysin>;
+ clock-names = "cec-clk";
+ interrupts = <GIC_SPI 140 IRQ_TYPE_NONE>;
+ interrupt-names = "cec-irq";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_cec0_default>;
+ resets = <&softreset STIH407_LPM_SOFTRESET>;
+ st,hdmi-handle = <&hdmi>;
+ };
};
};
diff --git a/drivers/staging/media/st-cec/Kconfig b/drivers/staging/media/st-cec/Kconfig
index 784d2c6..3072387 100644
--- a/drivers/staging/media/st-cec/Kconfig
+++ b/drivers/staging/media/st-cec/Kconfig
@@ -1,6 +1,7 @@
config VIDEO_STI_HDMI_CEC
tristate "STMicroelectronics STiH4xx HDMI CEC driver"
depends on VIDEO_DEV && MEDIA_CEC && (ARCH_STI || COMPILE_TEST)
+ select HDMI_NOTIFIERS
---help---
This is a driver for STIH4xx HDMI CEC interface. It uses the
generic CEC framework interface.
diff --git a/drivers/staging/media/st-cec/stih-cec.c b/drivers/staging/media/st-cec/stih-cec.c
index 2143448..ce94097 100644
--- a/drivers/staging/media/st-cec/stih-cec.c
+++ b/drivers/staging/media/st-cec/stih-cec.c
@@ -10,11 +10,13 @@
* (at your option) any later version.
*/
#include <linux/clk.h>
+#include <linux/hdmi-notifier.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/version.h>
@@ -130,6 +132,7 @@ struct stih_cec {
void __iomem *regs;
int irq;
u32 irq_status;
+ struct hdmi_notifier *notifier;
};
static int stih_cec_adap_enable(struct cec_adapter *adap, bool enable)
@@ -304,12 +307,29 @@ static int stih_cec_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct resource *res;
struct stih_cec *cec;
+ struct device_node *np;
+ struct platform_device *hdmi_dev;
int ret;
cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
if (!cec)
return -ENOMEM;
+ np = of_parse_phandle(pdev->dev.of_node, "st,hdmi-handle", 0);
+
+ if (!np) {
+ dev_err(&pdev->dev, "Failed to find hdmi node in device tree\n");
+ return -ENODEV;
+ }
+
+ hdmi_dev = of_find_device_by_node(np);
+ if (!hdmi_dev)
+ return -EPROBE_DEFER;
+
+ cec->notifier = hdmi_notifier_get(&hdmi_dev->dev);
+ if (!cec->notifier)
+ return -ENOMEM;
+
cec->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -336,7 +356,7 @@ static int stih_cec_probe(struct platform_device *pdev)
cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec,
CEC_NAME,
CEC_CAP_LOG_ADDRS | CEC_CAP_PASSTHROUGH |
- CEC_CAP_PHYS_ADDR | CEC_CAP_TRANSMIT,
+ CEC_CAP_TRANSMIT,
1, &pdev->dev);
ret = PTR_ERR_OR_ZERO(cec->adap);
if (ret)
@@ -348,12 +368,19 @@ static int stih_cec_probe(struct platform_device *pdev)
return ret;
}
+ cec_register_hdmi_notifier(cec->adap, cec->notifier);
+
platform_set_drvdata(pdev, cec);
return 0;
}
static int stih_cec_remove(struct platform_device *pdev)
{
+ struct stih_cec *cec = platform_get_drvdata(pdev);
+
+ cec_unregister_adapter(cec->adap);
+ hdmi_notifier_put(cec->notifier);
+
return 0;
}
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox