* [RFC 05/55] KVM: arm64: Add vcpu_mode_el2 primitive to support nesting
From: Jintack Lim @ 2017-01-09 6:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483943091-1364-1-git-send-email-jintack@cs.columbia.edu>
From: Christoffer Dall <christoffer.dall@linaro.org>
When running a nested hypervisor we occasionally have to figure out if
the mode we are switching into is the virtual EL2 mode or a regular
EL0/1 mode.
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
---
arch/arm/include/asm/kvm_emulate.h | 6 ++++++
arch/arm64/include/asm/kvm_emulate.h | 12 ++++++++++++
2 files changed, 18 insertions(+)
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h
index 9a8a45a..399cd75e 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -77,6 +77,12 @@ static inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu)
return 1;
}
+/* We don't support nesting on arm */
+static inline bool vcpu_mode_el2(const struct kvm_vcpu *vcpu)
+{
+ return false;
+}
+
static inline unsigned long *vcpu_pc(struct kvm_vcpu *vcpu)
{
return &vcpu->arch.ctxt.gp_regs.usr_regs.ARM_pc;
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index f5ea0ba..830be2e 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -143,6 +143,18 @@ static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu)
return mode != PSR_MODE_EL0t;
}
+static inline bool vcpu_mode_el2(const struct kvm_vcpu *vcpu)
+{
+ u32 mode;
+
+ if (vcpu_mode_is_32bit(vcpu))
+ return false;
+
+ mode = *vcpu_cpsr(vcpu) & PSR_MODE_MASK;
+
+ return mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t;
+}
+
static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
{
return vcpu->arch.fault.esr_el2;
--
1.9.1
^ permalink raw reply related
* [RFC 04/55] KVM: arm64: Allow userspace to set PSR_MODE_EL2x
From: Jintack Lim @ 2017-01-09 6:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483943091-1364-1-git-send-email-jintack@cs.columbia.edu>
From: Christoffer Dall <christoffer.dall@linaro.org>
We were not allowing userspace to set a more privileged mode for the VCPU
than EL1, but now that we support nesting with a virtual EL2 mode, do
allow this!
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
---
arch/arm64/kvm/guest.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 3f9e157..6b9f38a 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -117,6 +117,8 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
case PSR_MODE_EL0t:
case PSR_MODE_EL1t:
case PSR_MODE_EL1h:
+ case PSR_MODE_EL2h:
+ case PSR_MODE_EL2t:
break;
default:
err = -EINVAL;
--
1.9.1
^ permalink raw reply related
* [RFC 03/55] KVM: arm64: Add KVM nesting feature
From: Jintack Lim @ 2017-01-09 6:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483943091-1364-1-git-send-email-jintack@cs.columbia.edu>
From: Christoffer Dall <christoffer.dall@linaro.org>
Set the initial exception level of the guest to EL2 if nested
virtualization feature is enabled.
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
---
arch/arm64/include/asm/kvm_host.h | 2 +-
arch/arm64/include/uapi/asm/kvm.h | 1 +
arch/arm64/kvm/reset.c | 8 ++++++++
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e505038..c0c8b02 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -41,7 +41,7 @@
#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
-#define KVM_VCPU_MAX_FEATURES 4
+#define KVM_VCPU_MAX_FEATURES 5
#define KVM_REQ_VCPU_EXIT 8
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 3051f86..78117bf 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -97,6 +97,7 @@ struct kvm_regs {
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
#define KVM_ARM_VCPU_PMU_V3 3 /* Support guest PMUv3 */
+#define KVM_ARM_VCPU_NESTED_VIRT 4 /* Support nested virtual EL2 */
struct kvm_vcpu_init {
__u32 target;
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 74322c2..e6b0b20 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -41,6 +41,11 @@
PSR_F_BIT | PSR_D_BIT),
};
+static const struct kvm_regs default_regs_reset_el2 = {
+ .regs.pstate = (PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT |
+ PSR_F_BIT | PSR_D_BIT),
+};
+
static const struct kvm_regs default_regs_reset32 = {
.regs.pstate = (COMPAT_PSR_MODE_SVC | COMPAT_PSR_A_BIT |
COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT),
@@ -124,6 +129,9 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
if (!cpu_has_32bit_el1())
return -EINVAL;
cpu_reset = &default_regs_reset32;
+ } else if (test_bit(KVM_ARM_VCPU_NESTED_VIRT,
+ vcpu->arch.features)) {
+ cpu_reset = &default_regs_reset_el2;
} else {
cpu_reset = &default_regs_reset;
}
--
1.9.1
^ permalink raw reply related
* [RFC 02/55] KVM: arm64: Add nesting config option
From: Jintack Lim @ 2017-01-09 6:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483943091-1364-1-git-send-email-jintack@cs.columbia.edu>
From: Christoffer Dall <christoffer.dall@linaro.org>
Add an option that allows nested hypervisor support.
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
---
arch/arm64/kvm/Kconfig | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6eaf12c..37263ff 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -57,6 +57,12 @@ config KVM_ARM_PMU
Adds support for a virtual Performance Monitoring Unit (PMU) in
virtual machines.
+config KVM_ARM_NESTED_HYP
+ bool "Nested Virtualization"
+ depends on KVM
+ ---help---
+ Support nested hypervisors in VMs.
+
source drivers/vhost/Kconfig
endif # VIRTUALIZATION
--
1.9.1
^ permalink raw reply related
* [RFC 01/55] arm64: Add missing TCR hw defines
From: Jintack Lim @ 2017-01-09 6:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483943091-1364-1-git-send-email-jintack@cs.columbia.edu>
From: Christoffer Dall <christoffer.dall@linaro.org>
Some bits of the TCR weren't defined and since we're about to use these
in KVM, add these defines.
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Jintack Lim <jintack@cs.columbia.edu>
---
arch/arm64/include/asm/pgtable-hwdef.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index eb0c2bd..d26cab7 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -272,9 +272,15 @@
#define TCR_TG1_4K (UL(2) << TCR_TG1_SHIFT)
#define TCR_TG1_64K (UL(3) << TCR_TG1_SHIFT)
+#define TCR_IPS_SHIFT 32
+#define TCR_IPS_MASK (UL(7) << TCR_IPS_SHIFT)
+
#define TCR_ASID16 (UL(1) << 36)
#define TCR_TBI0 (UL(1) << 37)
#define TCR_HA (UL(1) << 39)
#define TCR_HD (UL(1) << 40)
+#define TCR_EPD1 (UL(1) << 23)
+#define TCR_EPD0 (UL(1) << 7)
+
#endif
--
1.9.1
^ permalink raw reply related
* [RFC 00/55] Nested Virtualization on KVM/ARM
From: Jintack Lim @ 2017-01-09 6:23 UTC (permalink / raw)
To: linux-arm-kernel
Nested virtualization is the ability to run a virtual machine inside another
virtual machine. In other words, it???s about running a hypervisor (the guest
hypervisor) on top of another hypervisor (the host hypervisor).
This series supports nested virtualization on arm64. ARM recently announced an
extension (ARMv8.3) which has support for nested virtualization[1]. This series
is based on the ARMv8.3 specification.
Supporting nested virtualization means that the hypervisor provides not only
EL0/EL1 execution environment with VMs as it usually does, but also the
virtualization extensions including EL2 execution environment with the VMs.
Once the host hypervisor provides those execution environment with the VMs,
then the guest hypervisor can run its own VMs (nested VMs) naturally.
To support nested virtualization on ARM the hypervisor must emulate a virtual
execution environment consisting of EL2, EL1, and EL0, as the guest hypervisor
will run in a virtual EL2 mode. Normally KVM/ARM only emulated a VM supporting
EL1/0 running in their respective native CPU modes, but with nested
virtualization we deprivilege the guest hypervisor and emulate a virtual EL2
execution mode in EL1 using the hardware features provided by ARMv8.3 to trap
EL2 operations to EL1. To do that the host hypervisor needs to manage EL2
register state for the guest hypervisor, and shadow EL1 register state that
reflects the EL2 register state to run the guest hypervisor in EL1. See patch 6
through 10 for this.
For memory virtualization, the biggest issue is that we now have more than two
stages of translation when running nested VMs. We choose to merge two stage-2
page tables (one from the guest hypervisor and the other from the host
hypervisor) and create shadow stage-2 page tables, which have mappings from the
nested VM???s physical addresses to the machine physical addresses. Stage-1
translation is done by the hardware as is done for the normal VMs.
To provide VGIC support to the guest hypervisor, we emulate the GIC
virtualization extensions using trap-and-emulate to a virtual GIC Hypervisor
Control Interface. Furthermore, we can still use the GIC VE hardware features
to deliver virtual interrupts to the nested VM, by directly mapping the GIC
VCPU interface to the nested VM and switching the content of the GIC Hypervisor
Control interface when alternating between a nested VM and a normal VM. See
patches 25 through 32, and 50 through 52 for more information.
For timer virtualization, the guest hypervisor expects to have access to the
EL2 physical timer, the EL1 physical timer and the virtual timer. So, the host
hypervisor needs to provide all of them. The virtual timer is always available
to VMs. The physical timer is available to VMs via my previous patch series[3].
The EL2 physical timer is not supported yet in this RFC. We plan to support
this as it is required to run other guest hypervisors such as Xen.
Even though this work is not complete (see limitations below), I'd appreciate
early feedback on this RFC. Specifically, I'm interested in:
- Is it better to have a kernel config or to make it configurable at runtime?
- I wonder if the data structure for memory management makes sense.
- What architecture version do we support for the guest hypervisor, and how?
For example, do we always support all architecture versions or the same
architecture as the underlying hardware platform? Or is it better
to make it configurable from the userspace?
- Initial comments on the overall design?
This patch series is based on kvm-arm-for-4.9-rc7 with the patch series to provide
VMs with the EL1 physical timer[2].
Git: https://github.com/columbia/nesting-pub/tree/rfc-v1
Testing:
We have tested this on ARMv8.0 (Applied Micro X-Gene)[3] since ARMv8.3 hardware
is not available yet. We have paravirtualized the guest hypervisor to trap to
EL2 as specified in ARMv8.3 specification using hvc instruction. We plan to
test this on ARMv8.3 model, and will post the result and v2 if necessary.
Limitations:
- This patch series only supports arm64, not arm. All the patches compile on
arm, but I haven't try to boot normal VMs on it.
- The guest hypervisor with VHE (ARMv8.1) is not supported in this RFC. I have
patches for that, but they need to be cleaned up.
- Recursive nesting (i.e. emulating ARMv8.3 in the VM) is not tested yet.
- Other hypervisors (such as Xen) on KVM are not tested.
TODO:
- Test to boot normal VMs on arm architecture
- Test this on ARMv8.3 model
- Support the guest hypervisor with VHE
- Provide the guest hypervisor with the EL2 physical timer
- Run other hypervisors such as Xen on KVM
[1] https://www.community.arm.com/processors/b/blog/posts/armv8-a-architecture-2016-additions
[2] https://lists.cs.columbia.edu/pipermail/kvmarm/2016-December/022825.html
[3] https://www.cloudlab.us/hardware.php#utah
Christoffer Dall (27):
arm64: Add missing TCR hw defines
KVM: arm64: Add nesting config option
KVM: arm64: Add KVM nesting feature
KVM: arm64: Allow userspace to set PSR_MODE_EL2x
KVM: arm64: Add vcpu_mode_el2 primitive to support nesting
KVM: arm/arm64: Add virtual EL2 state emulation framework
KVM: arm64: Set virtual EL2 context depending on the guest exception
level
KVM: arm64: Set shadow EL1 registers for virtual EL2 execution
KVM: arm64: Synchronize EL1 system registers on virtual EL2 entry and
exit
KVM: arm64: Trap EL1 VM register accesses in virtual EL2
KVM: arm/arm64: Add VGIC data structures for the nesting
KVM: arm/arm64: Inject maintenance interrupts to the guest hypervisor
KVM: arm/arm64: Remove unused params in mmu functions
KVM: arm/arm64: Abstract stage-2 MMU state into a separate structure
KVM: arm/arm64: Support mmu for the virtual EL2 execution
KVM: arm64: Invalidate virtual EL2 TLB entries when needed
KVM: arm64: Setup vttbr_el2 on each VM entry
KVM: arm/arm64: Make mmu functions non-static
KVM: arm/arm64: Unmap/flush shadow stage 2 page tables
KVM: arm64: Implement nested Stage-2 page table walk logic
KVM: arm/arm64: Handle shadow stage 2 page faults
KVM: arm/arm64: Move kvm_is_write_fault to header file
KVM: arm64: KVM: Inject stage-2 page faults
KVM: arm64: Add more info to the S2 translation result
KVM: arm/arm64: Forward the guest hypervisor's stage 2 permission
faults
KVM: arm64: Emulate TLBI instruction
KVM: arm64: Fixes to toggle_cache for nesting
Jintack Lim (28):
KVM: arm64: Add EL2 execution context for nesting
KVM: arm64: Emulate taking an exception to the guest hypervisor
KVM: arm64: Handle EL2 register access traps
KVM: arm64: Handle eret instruction traps
KVM: arm64: Take account of system instruction traps
KVM: arm64: Forward VM reg traps to the guest hypervisor
KVM: arm64: Trap SPSR_EL1, ELR_EL1 and VBAR_EL1 in virtual EL2
KVM: arm64: Forward traps due to HCR_EL2.NV1 bit to the guest
hypervisor
KVM: arm64: Trap CPACR_EL1 access in virtual EL2
KVM: arm64: Forward CPACR_EL1 traps to the guest hypervisor
KVM: arm64: Forward HVC instruction to the guest hypervisor
KVM: arm64: Handle PSCI call from the guest
KVM: arm64: Forward WFX to the guest hypervisor
KVM: arm64: Forward FP exceptions to the guest hypervisor
KVM: arm/arm64: Let vcpu thread modify its own active state
KVM: arm/arm64: Emulate GICH interface on GICv2
KVM: arm/arm64: Prepare vgic state for the nested VM
KVM: arm/arm64: Set up the prepared vgic state
KVM: arm/arm64: Inject irqs to the guest hypervisor
KVM: arm/arm64: register GICH iodev for the guest hypervisor
KVM: arm/arm64: Add mmu context for the nesting
KVM: arm/arm64: Handle vttbr_el2 write operation from the guest
hypervisor
KVM: arm/arm64: Abstract kvm_phys_addr_ioremap() function
KVM: arm64: Expose physical address of vcpu interface
KVM: arm/arm64: Create a vcpu mapping for the nested VM
KVM: arm64: Reflect shadow VMPIDR_EL2 value to MPIDR_EL1
KVM: arm/arm64: Adjust virtual offset considering nesting
KVM: arm64: Enable nested virtualization
arch/arm/include/asm/kvm_asm.h | 7 +-
arch/arm/include/asm/kvm_emulate.h | 54 ++++
arch/arm/include/asm/kvm_host.h | 34 ++-
arch/arm/include/asm/kvm_mmu.h | 39 +++
arch/arm/kvm/arm.c | 79 ++++--
arch/arm/kvm/hyp/switch.c | 3 +-
arch/arm/kvm/hyp/tlb.c | 15 +-
arch/arm/kvm/mmio.c | 12 +-
arch/arm/kvm/mmu.c | 386 +++++++++++++++++--------
arch/arm64/include/asm/esr.h | 2 +
arch/arm64/include/asm/kvm_arm.h | 3 +
arch/arm64/include/asm/kvm_asm.h | 7 +-
arch/arm64/include/asm/kvm_coproc.h | 2 +-
arch/arm64/include/asm/kvm_emulate.h | 68 +++++
arch/arm64/include/asm/kvm_host.h | 96 ++++++-
arch/arm64/include/asm/kvm_mmu.h | 110 +++++++-
arch/arm64/include/asm/kvm_nested.h | 7 +
arch/arm64/include/asm/pgtable-hwdef.h | 6 +
arch/arm64/include/uapi/asm/kvm.h | 7 +
arch/arm64/kernel/asm-offsets.c | 1 +
arch/arm64/kvm/Kconfig | 6 +
arch/arm64/kvm/Makefile | 7 +-
arch/arm64/kvm/context.c | 212 ++++++++++++++
arch/arm64/kvm/emulate-nested.c | 66 +++++
arch/arm64/kvm/guest.c | 2 +
arch/arm64/kvm/handle_exit.c | 62 +++-
arch/arm64/kvm/handle_exit_nested.c | 51 ++++
arch/arm64/kvm/hyp/entry.S | 14 +
arch/arm64/kvm/hyp/hyp-entry.S | 2 +-
arch/arm64/kvm/hyp/switch.c | 15 +-
arch/arm64/kvm/hyp/sysreg-sr.c | 109 +++----
arch/arm64/kvm/hyp/tlb.c | 16 +-
arch/arm64/kvm/mmu-nested.c | 501 +++++++++++++++++++++++++++++++++
arch/arm64/kvm/reset.c | 8 +
arch/arm64/kvm/sys_regs.c | 287 ++++++++++++++++++-
arch/arm64/kvm/sys_regs.h | 7 +
arch/arm64/kvm/trace.h | 43 ++-
include/kvm/arm_vgic.h | 36 ++-
virt/kvm/arm/arch_timer.c | 3 +-
virt/kvm/arm/hyp/timer-sr.c | 5 +-
virt/kvm/arm/hyp/vgic-v2-sr.c | 15 +-
virt/kvm/arm/vgic/vgic-init.c | 3 +
virt/kvm/arm/vgic/vgic-mmio.c | 11 +-
virt/kvm/arm/vgic/vgic-v2-nested.c | 346 +++++++++++++++++++++++
virt/kvm/arm/vgic/vgic-v2.c | 13 +
virt/kvm/arm/vgic/vgic.c | 23 ++
virt/kvm/arm/vgic/vgic.h | 17 ++
47 files changed, 2542 insertions(+), 276 deletions(-)
create mode 100644 arch/arm64/include/asm/kvm_nested.h
create mode 100644 arch/arm64/kvm/context.c
create mode 100644 arch/arm64/kvm/emulate-nested.c
create mode 100644 arch/arm64/kvm/handle_exit_nested.c
create mode 100644 arch/arm64/kvm/mmu-nested.c
create mode 100644 virt/kvm/arm/vgic/vgic-v2-nested.c
--
1.9.1
^ permalink raw reply
* [PATCH v3] arm64: mm: Fix NOMAP page initialization
From: Prakash B @ 2017-01-09 6:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4fbd559b-b4f2-2c89-3024-5d1137ff170d@linaro.org>
Thanks Hanjun ,
On Mon, Jan 9, 2017 at 10:39 AM, Hanjun Guo <hanjun.guo@linaro.org> wrote:
> Hi Prakash,
> I didn't test "cpuset01" on D05 but according to the test in
> Linaro, LTP full test is passed on D05 with Ard's 2 patches.
>
>>
>> Any idea what might be causing this issue.
>
>
> Since it's not happening on D05, maybe it's related to
> the firmware? (just a wild guess...)
>
Used same firmware b/w 4.4 kernel and 4.9 (and above kernels) .
Test passed wtih 4.4 kernel and didn't generated any crashes or
dumps.
If there is more observation I will send a mail or I will start a
separate mail thread.
Thanks,
Prakash B
^ permalink raw reply
* [PATCH v4 1/2] power: reset: add linkstation-reset driver
From: Ryan Tandy @ 2017-01-09 5:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAEQ9gEkvj++e7ch40cFqBy3KXg-a=pYnH7cwErMe2RDd2qzQJg@mail.gmail.com>
On Mon, Jan 09, 2017 at 12:31:44PM +0900, Roger Shimizu wrote:
>This driver, linkstation-reset, can also handle PPC Linkstation after
>it's converted to DT.
>I already considered this and mentioned in previous reply [0].
OK. I was thinking of Sebastian's earlier comment:
On Wed, Dec 21, 2016 at 04:59:29PM +0100, Sebastian Reichel wrote:
>These models can just be added to qnap-poweroff, which handles
>exactly this special case as far as I can see.
and forgot that you planned to handle it in this driver. Sorry for the
noise.
^ permalink raw reply
* [PATCH v3] arm64: mm: Fix NOMAP page initialization
From: Hanjun Guo @ 2017-01-09 5:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8-+0LUTN0+8OGWRhd22Ls5cMQqTJcjKQK_0N=Uc-0jog@mail.gmail.com>
On 2017/1/6 16:37, Ard Biesheuvel wrote:
> On 6 January 2017 at 01:07, Hanjun Guo <hanjun.guo@linaro.org> wrote:
>> On 2017/1/5 10:03, Hanjun Guo wrote:
>>>
>>> On 2017/1/4 21:56, Ard Biesheuvel wrote:
>>>>
>>>> On 16 December 2016 at 16:54, Robert Richter <rrichter@cavium.com> wrote:
>>>>>
>>>>> On ThunderX systems with certain memory configurations we see the
>>>>> following BUG_ON():
>>>>>
>>>>> kernel BUG at mm/page_alloc.c:1848!
>>>>>
>>>>> This happens for some configs with 64k page size enabled. The BUG_ON()
>>>>> checks if start and end page of a memmap range belongs to the same
>>>>> zone.
>>>>>
>>>>> The BUG_ON() check fails if a memory zone contains NOMAP regions. In
>>>>> this case the node information of those pages is not initialized. This
>>>>> causes an inconsistency of the page links with wrong zone and node
>>>>> information for that pages. NOMAP pages from node 1 still point to the
>>>>> mem zone from node 0 and have the wrong nid assigned.
>>>>>
>>>>> The reason for the mis-configuration is a change in pfn_valid() which
>>>>> reports pages marked NOMAP as invalid:
>>>>>
>>>>> 68709f45385a arm64: only consider memblocks with NOMAP cleared for
>>>>> linear mapping
>>>>>
>>>>> This causes pages marked as nomap being no longer reassigned to the
>>>>> new zone in memmap_init_zone() by calling __init_single_pfn().
>>>>>
>>>>> Fixing this by implementing an arm64 specific early_pfn_valid(). This
>>>>> causes all pages of sections with memory including NOMAP ranges to be
>>>>> initialized by __init_single_page() and ensures consistency of page
>>>>> links to zone, node and section.
>>>>>
>>>>
>>>> I like this solution a lot better than the first one, but I am still
>>>> somewhat uneasy about having the kernel reason about attributes of
>>>> pages it should not touch in the first place. But the fact that
>>>> early_pfn_valid() is only used a single time in the whole kernel does
>>>> give some confidence that we are not simply moving the problem
>>>> elsewhere.
>>>>
>>>> Given that you are touching arch/arm/ as well as arch/arm64, could you
>>>> explain why only arm64 needs this treatment? Is it simply because we
>>>> don't have NUMA support there?
>>>>
>>>> Considering that Hisilicon D05 suffered from the same issue, I would
>>>> like to get some coverage there as well. Hanjun, is this something you
>>>> can arrange? Thanks
>>>
>>>
>>> Sure, we will test this patch with LTP MM stress test (which triggers
>>> the bug on D05), and give the feedback.
>>
>>
>> a update here, tested on 4.9,
>>
>> - Applied Ard's two patches only
>> - Applied Robert's patch only
>>
>> Both of them can work fine on D05 with NUMA enabled, which means
>> boot ok and LTP MM stress test is passed.
>>
>
> Thanks a lot Hanjun.
>
> Any comments on the performance impact (including boot time) ?
Didn't collect the performance data yet, any recommended test
suite? Is it sysbench ok? we can test it and collect the data.
Thanks
Hanjun
^ permalink raw reply
* [PATCH v3] arm64: mm: Fix NOMAP page initialization
From: Hanjun Guo @ 2017-01-09 5:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACJhumfqWkXXpbJomjJ1jM5B3kG+1Jk9EvGWR50_u-AO1ySXfg@mail.gmail.com>
Hi Prakash,
On 2017/1/6 13:22, Prakash B wrote:
> Hi Hanjun,
>
>
>> a update here, tested on 4.9,
>>
>> - Applied Ard's two patches only
>> - Applied Robert's patch only
>>
>> Both of them can work fine on D05 with NUMA enabled, which means
>> boot ok and LTP MM stress test is passed.
>
> It is not related to this patch set.
> LTP "cpuset01" test crashes with latest 4.9, 4.10-rc1 and 4.10-rc2 kernels on
> Thunderx 2S . Do you see any such behaviour on D05.
I didn't test "cpuset01" on D05 but according to the test in
Linaro, LTP full test is passed on D05 with Ard's 2 patches.
>
> Any idea what might be causing this issue.
Since it's not happening on D05, maybe it's related to
the firmware? (just a wild guess...)
Thanks
Hanjun
>
>
> 227.627546] cpuset01: page allocation stalls for 10096ms, order:0,
> mode:0x24200ca(GFP_HIGHUSER_MOVABLE)
> [ 227.627586] CPU: 53 PID: 11017 Comm: cpuset01 Not tainted 4.9.04kNUMA+ #2
> [ 227.627591] Hardware name: www.cavium.com ThunderX Unknown/ThunderX
> Unknown, BIOS 0.3 Aug 24 2016
> [ 227.627599] Call trace:
> [ 227.627623] [<ffff000008089f10>] dump_backtrace+0x0/0x238
> [ 227.627640] [<ffff00000808a16c>] show_stack+0x24/0x30
> [ 227.627656] [<ffff00000846fb50>] dump_stack+0x94/0xb4
> [ 227.627679] [<ffff0000081eb4f8>] warn_alloc+0x138/0x150
> [ 227.627686] [<ffff0000081ec0a4>] __alloc_pages_nodemask+0xb04/0xcf0
> [ 227.627697] [<ffff000008245988>] alloc_pages_vma+0xc8/0x270
> [ 227.627715] [<ffff00000821f604>] handle_mm_fault+0xc8c/0xfd8
> [ 227.627732] [<ffff00000809a488>] do_page_fault+0x2c0/0x368
> [ 227.627744] [<ffff0000080812ec>] do_mem_abort+0x6c/0xe0
> [ 227.627752] Exception stack(0xffff801f55823e00 to 0xffff801f55823f30)
> [ 227.627763] 3e00: 0000000000000000 0000ffff92682000
> ffffffffffffffff 0000ffff9252b3e8
> [ 227.627774] 3e20: 0000000020000000 0000000000000000
> 000000000000a000 0000000000000003
> [ 227.627785] 3e40: 0000000000000022 ffffffffffffffff
> 0000000000000123 00000000000000de
> [ 227.627793] 3e60: ffff000008972000 0000000000000015
> ffff801f55823e90 0000000000040900
> [ 227.627800] 3e80: 0000000000000000 ffff0000080836f0
> 0000000000000000 0000ffff92682000
> [ 227.627809] 3ea0: ffffffffffffffff 0000ffff92575d8c
> 0000000000000000 0000000000040900
> [ 227.627819] 3ec0: 0000ffff92682000 00000000000000f7
> 0000000000004fc0 0000000000000022
> [ 227.627828] 3ee0: 0000000000000000 0000000000000000
> 0000ffff925f5508 f7f7f7f7f7f7f7f7
> [ 227.627838] 3f00: 0000ffff92686ff0 0000000000002ab8
> 0101010101010101 0000000000000020
> [ 227.627847] 3f20: 0000000000000000 0000000000000000
> [ 227.627858] [<ffff000008083324>] el0_da+0x18/0x1c
> [ 227.627865] Mem-Info:
> [ 227.627899] active_anon:38613 inactive_anon:8174 isolated_anon:0
> active_file:25148 inactive_file:64173 isolated_file:0
> unevictable:742 dirty:0 writeback:0 unstable:0
> slab_reclaimable:29066 slab_unreclaimable:67304
> mapped:22876 shmem:2597 pagetables:1240 bounce:0
> free:65582521 free_pcp:1834 free_cma:0
>
^ permalink raw reply
* [PATCH v4 1/2] power: reset: add linkstation-reset driver
From: Roger Shimizu @ 2017-01-09 3:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170108170209.GD573@kiwi.nardis.ca>
Dear Ryan,
Thanks for your comments!
On Mon, Jan 9, 2017 at 2:02 AM, Ryan Tandy <ryan@nardis.ca> wrote:
> On Sun, Jan 08, 2017 at 12:04:50AM +0900, Roger Shimizu wrote:
>>
>> +config POWER_RESET_LINKSTATION
>> + bool "Buffalo Linkstation and its variants reset driver"
>> + depends on OF_GPIO && PLAT_ORION
>> + help
>> + This driver supports power off Buffalo Linkstation / KuroBox Pro
>> + NAS and their variants by sending commands to the
>> micro-controller
>> + which controls the main power.
>
> Would it make sense to mention something about these being the ARM9/orion5x
> Linkstations? If I understand correctly, the older PPC Linkstations have a
> single-byte poweroff command. (Maybe they could even be supported by
> qnap-poweroff.)
>
> See arch/powerpc/platforms/embedded6xx/linkstation.c around line 123, and
> arch/powerpc/platforms/embedded6xx/ls_uart.c.
This driver, linkstation-reset, can also handle PPC Linkstation after
it's converted to DT.
I already considered this and mentioned in previous reply [0].
[0] http://marc.info/?l=linux-pm&m=148216908031283
Cheers,
--
Roger Shimizu, GMT +9 Tokyo
PGP/GPG: 4096R/6C6ACD6417B3ACB1
^ permalink raw reply
* [PATCH 2/2] media: rc: add driver for IR remote receiver on MT7623 SoC
From: Sean Wang @ 2017-01-09 3:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170108211624.GB7866@gofer.mess.org>
On Sun, 2017-01-08 at 21:16 +0000, Sean Young wrote:
> Hi Sean,
>
> On Fri, Jan 06, 2017 at 03:31:25PM +0800, Sean Wang wrote:
> > On Thu, 2017-01-05 at 17:12 +0000, Sean Young wrote:
> > > On Fri, Jan 06, 2017 at 12:06:24AM +0800, sean.wang at mediatek.com wrote:
> > > > + /* Handle pulse and space until end of message */
> > > > + for (i = 0 ; i < MTK_CHKDATA_SZ ; i++) {
> > > > + val = mtk_r32(ir, MTK_CHKDATA_REG(i));
> > > > + dev_dbg(ir->dev, "@reg%d=0x%08x\n", i, val);
> > > > +
> > > > + for (j = 0 ; j < 4 ; j++) {
> > > > + wid = (val & (0xff << j * 8)) >> j * 8;
> > > > + rawir.pulse = !rawir.pulse;
> > > > + rawir.duration = wid * (MTK_IR_SAMPLE + 1);
> > > > + ir_raw_event_store_with_filter(ir->rc, &rawir);
> > > > +
> > > > + if (MTK_IR_END(wid))
> > > > + goto end_msg;
> > > > + }
> > > > + }
> > >
> > > If I read this correctly, there is a maximum of 17 * 4 = 68 edges per
> > > IR message. The rc6 mce key 0 (scancode 0x800f0400) is 69 edges, so that
> > > won't work.
> > >
> > Uh, this is related to hardware limitation. Maximum number hardware
> > holds indeed is only 68 edges as you said :(
> >
> > For the case, I will try change the logic into that the whole message
> > is dropped if no end of message is seen within 68 counts to avoid
> > wasting CPU for decoding.
>
> I'm not sure it is worthwhile dropping the IR in that case. The processing
> is minimal and it might be possible that we have just enough IR to decode
> a scancode even if the trailing end of message is missing. Note that
> the call to ir_raw_event_set_idle() will generate an timeout IR event, so
> there will always be an end of message marker.
1)
I agree with you :) The original logic I made already as you pointed out
is sent incomplete IR message to let ir-raw try to decode as possible.
2)
I had another question. I found multiple and same IR messages being
received when using SONY remote controller. Should driver needs to
report each message or only one of these to the upper layer ?
> All I wanted to do was point out a limitation in case there is a
> workaround; if there is not then we might as well make do with the IR
> we do have.
I also will leave some words about limitation we had in the comments.
> Thanks
> Sean
^ permalink raw reply
* [PATCH v1 3/3] thermal: zx2967: add thermal driver for ZTE's zx2967 family
From: Jun Nie @ 2017-01-09 3:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483767488-19778-3-git-send-email-baoyou.xie@linaro.org>
On 2017?01?07? 13:38, Baoyou Xie wrote:
> This patch adds thermal driver for ZTE's zx2967 family.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> ---
> drivers/thermal/Kconfig | 6 +
> drivers/thermal/Makefile | 1 +
> drivers/thermal/zx2967_thermal.c | 241 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 248 insertions(+)
> create mode 100644 drivers/thermal/zx2967_thermal.c
>
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 18f2de6..0dd597e 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -445,3 +445,9 @@ config BCM2835_THERMAL
> Support for thermal sensors on Broadcom bcm2835 SoCs.
>
> endif
> +
> +config ZX2967_THERMAL
> + tristate "Thermal sensors on zx2967 SoC"
> + depends on ARCH_ZX
> + help
> + Support for thermal sensors on ZTE zx2967 SoCs.
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 677c6d9..c00c05e 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -57,3 +57,4 @@ obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
> obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
> obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
> obj-$(CONFIG_BCM2835_THERMAL) += bcm2835_thermal.o
> +obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
> diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c
> new file mode 100644
> index 0000000..1aef070
> --- /dev/null
> +++ b/drivers/thermal/zx2967_thermal.c
> @@ -0,0 +1,241 @@
> +/*
> + * ZTE's zx2967 family thermal sensor driver
> + *
> + * Copyright (C) 2017 ZTE Ltd.
> + *
> + * Author: Baoyou Xie <baoyou.xie@linaro.org>
> + *
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +
> +#include <linux/module.h>
Please follow alphabet sequence.
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/thermal.h>
> +
> +/* DCF Control Register */
> +#define ZX2967_THERMAL_DCF 0x4
> +
> +/* Selection Register */
> +#define ZX2967_THERMAL_SEL 0x8
> +
> +/* Control Register */
> +#define ZX2967_THERMAL_CTRL 0x10
> +
> +#define ZX2967_THERMAL_ID_MASK (0x18)
> +
> +struct zx2967_thermal_sensor {
> + struct zx2967_thermal_priv *priv;
> + struct thermal_zone_device *tzd;
> + int id;
> +};
> +
> +#define NUM_SENSORS 1
> +
> +struct zx2967_thermal_priv {
> + struct zx2967_thermal_sensor sensors[NUM_SENSORS];
> + struct mutex lock;
> + struct clk *clk_gate;
> + struct clk *pclk;
> + void __iomem *regs;
> + struct pinctrl *pinmux_dvi0_d3;
> + struct pinctrl *pinmux_dvi0_d4;
> + struct pinctrl *pinmux_dvi0_d5;
I do not see usage of pinmux_div0_d*, please remove it.
> +};
> +
> +static int zx2967_thermal_suspend(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
> +
> + if (priv && priv->pclk)
> + clk_disable_unprepare(priv->pclk);
> +
> + if (priv && priv->clk_gate)
> + clk_disable_unprepare(priv->clk_gate);
> + dev_info(dev, "suspended\n");
> +
> + return 0;
> +}
> +
> +static int zx2967_thermal_resume(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
> + int error;
> +
> + error = clk_prepare_enable(priv->clk_gate);
> + if (error)
Use IS_ERR(ret) to check error.
> + return error;
> +
> + error = clk_prepare_enable(priv->pclk);
> + if (error)
Ditto.
> + return error;
> +
> + dev_info(dev, "resumed\n");
> +
> + return 0;
> +}
> +
> +static int zx2967_thermal_get_temp(void *data, int *temp)
> +{
> + void __iomem *regs;
> + struct zx2967_thermal_sensor *sensor = data;
> + struct zx2967_thermal_priv *priv = sensor->priv;
> + unsigned long timeout = jiffies + msecs_to_jiffies(100);
> + u32 val, sel_id;
> +
> + regs = priv->regs;
> + mutex_lock(&priv->lock);
> +
> + writel_relaxed(0, regs);
> + writel_relaxed(2, regs + ZX2967_THERMAL_DCF);
> +
> + val = readl_relaxed(regs + ZX2967_THERMAL_SEL);
> + val &= ~ZX2967_THERMAL_ID_MASK;
> + sel_id = sensor->id ? 8 : 0x10;
You can define a macro for 8 and 0x10. BTW: NUM_SENSORS is 1 currently,
you can change it to 2 if hardware support it. Or you can add TODO mark
for later work.
> + val |= sel_id;
> + writel_relaxed(val, regs + ZX2967_THERMAL_SEL);
> +
> + usleep_range(100, 300);
> + while (!(readl_relaxed(regs + ZX2967_THERMAL_CTRL) & 0x1000)) {
> + if (time_after(jiffies, timeout)) {
> + pr_err("*** Thermal sensor %d data timeout\n",
> + sensor->id);
> + mutex_unlock(&priv->lock);
> + return -EIO;
> + }
> + }
> +
> + writel_relaxed(3, regs + ZX2967_THERMAL_DCF);
> + val = readl_relaxed(regs + ZX2967_THERMAL_CTRL) & 0xfff;
Define 0xfff as a macro.
> + writel_relaxed(1, regs);
> +
> + /** Calculate temperature */
> + *temp = DIV_ROUND_CLOSEST((val - 922) * 1000, 1951);
> +
> + mutex_unlock(&priv->lock);
> +
> + return 0;
> +}
> +
> +static struct thermal_zone_of_device_ops zx2967_of_thermal_ops = {
> + .get_temp = zx2967_thermal_get_temp,
> +};
> +
> +static int zx2967_thermal_probe(struct platform_device *pdev)
> +{
> + struct zx2967_thermal_priv *priv;
> + struct resource *res;
> + int ret, i;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + priv->regs = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(priv->regs))
> + return PTR_ERR(priv->regs);
> +
> + priv->clk_gate = devm_clk_get(&pdev->dev, "tempsensor_gate");
> + if (IS_ERR(priv->clk_gate)) {
> + ret = PTR_ERR(priv->clk_gate);
> + dev_err(&pdev->dev, "failed to get clock gate: %d\n", ret);
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(priv->clk_gate);
> + if (ret) {
Use IS_ERR(ret) to check error.
> + dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
> + ret);
> + return ret;
> + }
> +
> + priv->pclk = devm_clk_get(&pdev->dev, "tempsensor_pclk");
> + if (IS_ERR(priv->pclk)) {
> + ret = PTR_ERR(priv->pclk);
> + dev_err(&pdev->dev, "failed to get apb clock: %d\n", ret);
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(priv->pclk);
> + if (ret) {
Ditto.
> + dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
> + ret);
> + return ret;
> + }
> +
> + mutex_init(&priv->lock);
> + for (i = 0; i < NUM_SENSORS; i++) {
> + struct zx2967_thermal_sensor *sensor = &priv->sensors[i];
> +
> + sensor->priv = priv;
> + sensor->id = i;
> + sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev,
> + i,
> + sensor,
No need to create new line.
> + &zx2967_of_thermal_ops);
> + if (IS_ERR(sensor->tzd)) {
> + ret = PTR_ERR(sensor->tzd);
> + dev_err(&pdev->dev, "failed to register sensor %d: %d\n",
> + i, ret);
> + goto remove_ts;
> + }
> + }
> + platform_set_drvdata(pdev, priv);
> +
> + return 0;
> +
> +remove_ts:
> + for (i--; i >= 0; i--)
> + thermal_zone_of_sensor_unregister(&pdev->dev,
> + priv->sensors[i].tzd);
> +
> + return ret;
> +}
> +
> +static int zx2967_thermal_exit(struct platform_device *pdev)
> +{
> + struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
> + int i;
> +
> + for (i = 0; i < NUM_SENSORS; i++) {
> + struct zx2967_thermal_sensor *sensor = &priv->sensors[i];
> +
> + thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd);
> + }
> + clk_disable_unprepare(priv->pclk);
> + clk_disable_unprepare(priv->clk_gate);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id zx2967_thermal_id_table[] = {
> + { .compatible = "zte,zx2967-thermal" },
> + { .compatible = "zte,zx296718-thermal" },
Does the sensors that maps to the two compatibles have any difference?
If yes, we can add the difference with data member. If not, we can use
the same compatible string.
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, zx2967_thermal_id_table);
> +
> +static SIMPLE_DEV_PM_OPS(zx2967_thermal_pm_ops,
> + zx2967_thermal_suspend, zx2967_thermal_resume);
> +
> +static struct platform_driver zx2967_thermal_driver = {
> + .probe = zx2967_thermal_probe,
> + .remove = zx2967_thermal_exit,
> + .driver = {
> + .name = "zx2967_thermal",
> + .of_match_table = zx2967_thermal_id_table,
> + .pm = &zx2967_thermal_pm_ops,
> + },
> +};
> +module_platform_driver(zx2967_thermal_driver);
> +
> +MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
> +MODULE_DESCRIPTION("ZTE zx2967 thermal driver");
> +MODULE_LICENSE("GPL");
>
^ permalink raw reply
* [PATCH v1 3/3] thermal: zx2967: add thermal driver for ZTE's zx2967 family
From: Shawn Guo @ 2017-01-09 3:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483767488-19778-3-git-send-email-baoyou.xie@linaro.org>
On Sat, Jan 07, 2017 at 01:38:08PM +0800, Baoyou Xie wrote:
> This patch adds thermal driver for ZTE's zx2967 family.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> ---
> drivers/thermal/Kconfig | 6 +
> drivers/thermal/Makefile | 1 +
> drivers/thermal/zx2967_thermal.c | 241 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 248 insertions(+)
> create mode 100644 drivers/thermal/zx2967_thermal.c
>
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 18f2de6..0dd597e 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -445,3 +445,9 @@ config BCM2835_THERMAL
> Support for thermal sensors on Broadcom bcm2835 SoCs.
>
> endif
> +
> +config ZX2967_THERMAL
> + tristate "Thermal sensors on zx2967 SoC"
> + depends on ARCH_ZX
> + help
> + Support for thermal sensors on ZTE zx2967 SoCs.
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index 677c6d9..c00c05e 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -57,3 +57,4 @@ obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
> obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
> obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
> obj-$(CONFIG_BCM2835_THERMAL) += bcm2835_thermal.o
> +obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
> diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c
> new file mode 100644
> index 0000000..1aef070
> --- /dev/null
> +++ b/drivers/thermal/zx2967_thermal.c
> @@ -0,0 +1,241 @@
> +/*
> + * ZTE's zx2967 family thermal sensor driver
> + *
> + * Copyright (C) 2017 ZTE Ltd.
> + *
> + * Author: Baoyou Xie <baoyou.xie@linaro.org>
> + *
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/thermal.h>
> +
> +/* DCF Control Register */
> +#define ZX2967_THERMAL_DCF 0x4
> +
> +/* Selection Register */
> +#define ZX2967_THERMAL_SEL 0x8
> +
> +/* Control Register */
> +#define ZX2967_THERMAL_CTRL 0x10
> +
> +#define ZX2967_THERMAL_ID_MASK (0x18)
> +
> +struct zx2967_thermal_sensor {
> + struct zx2967_thermal_priv *priv;
> + struct thermal_zone_device *tzd;
> + int id;
> +};
> +
> +#define NUM_SENSORS 1
> +
> +struct zx2967_thermal_priv {
> + struct zx2967_thermal_sensor sensors[NUM_SENSORS];
What's the point of defining an array with only one element?
> + struct mutex lock;
> + struct clk *clk_gate;
> + struct clk *pclk;
> + void __iomem *regs;
> + struct pinctrl *pinmux_dvi0_d3;
> + struct pinctrl *pinmux_dvi0_d4;
> + struct pinctrl *pinmux_dvi0_d5;
These three pointers are not used.
> +};
> +
> +static int zx2967_thermal_suspend(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
> +
> + if (priv && priv->pclk)
> + clk_disable_unprepare(priv->pclk);
> +
> + if (priv && priv->clk_gate)
> + clk_disable_unprepare(priv->clk_gate);
> + dev_info(dev, "suspended\n");
Noisy message.
> +
> + return 0;
> +}
> +
> +static int zx2967_thermal_resume(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
> + int error;
> +
> + error = clk_prepare_enable(priv->clk_gate);
> + if (error)
> + return error;
> +
> + error = clk_prepare_enable(priv->pclk);
> + if (error)
> + return error;
clk_disable_unprepare() should be called for priv->clk_gate before
returning here.
> +
> + dev_info(dev, "resumed\n");
> +
> + return 0;
> +}
> +
> +static int zx2967_thermal_get_temp(void *data, int *temp)
> +{
> + void __iomem *regs;
> + struct zx2967_thermal_sensor *sensor = data;
> + struct zx2967_thermal_priv *priv = sensor->priv;
> + unsigned long timeout = jiffies + msecs_to_jiffies(100);
> + u32 val, sel_id;
> +
> + regs = priv->regs;
> + mutex_lock(&priv->lock);
> +
> + writel_relaxed(0, regs);
I suggest we have a macro for register at offset 0 as well to improve
the readability.
> + writel_relaxed(2, regs + ZX2967_THERMAL_DCF);
> +
> + val = readl_relaxed(regs + ZX2967_THERMAL_SEL);
> + val &= ~ZX2967_THERMAL_ID_MASK;
> + sel_id = sensor->id ? 8 : 0x10;
> + val |= sel_id;
> + writel_relaxed(val, regs + ZX2967_THERMAL_SEL);
> +
> + usleep_range(100, 300);
> + while (!(readl_relaxed(regs + ZX2967_THERMAL_CTRL) & 0x1000)) {
> + if (time_after(jiffies, timeout)) {
> + pr_err("*** Thermal sensor %d data timeout\n",
> + sensor->id);
dev_err? And drop "*** ".
> + mutex_unlock(&priv->lock);
> + return -EIO;
-ETIMEDOUT?
> + }
> + }
> +
> + writel_relaxed(3, regs + ZX2967_THERMAL_DCF);
> + val = readl_relaxed(regs + ZX2967_THERMAL_CTRL) & 0xfff;
> + writel_relaxed(1, regs);
> +
> + /** Calculate temperature */
> + *temp = DIV_ROUND_CLOSEST((val - 922) * 1000, 1951);
> +
> + mutex_unlock(&priv->lock);
> +
> + return 0;
> +}
> +
> +static struct thermal_zone_of_device_ops zx2967_of_thermal_ops = {
> + .get_temp = zx2967_thermal_get_temp,
> +};
> +
> +static int zx2967_thermal_probe(struct platform_device *pdev)
> +{
> + struct zx2967_thermal_priv *priv;
> + struct resource *res;
> + int ret, i;
> +
> + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + priv->regs = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(priv->regs))
> + return PTR_ERR(priv->regs);
> +
> + priv->clk_gate = devm_clk_get(&pdev->dev, "tempsensor_gate");
> + if (IS_ERR(priv->clk_gate)) {
> + ret = PTR_ERR(priv->clk_gate);
> + dev_err(&pdev->dev, "failed to get clock gate: %d\n", ret);
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(priv->clk_gate);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
> + ret);
> + return ret;
> + }
> +
> + priv->pclk = devm_clk_get(&pdev->dev, "tempsensor_pclk");
> + if (IS_ERR(priv->pclk)) {
> + ret = PTR_ERR(priv->pclk);
> + dev_err(&pdev->dev, "failed to get apb clock: %d\n", ret);
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(priv->pclk);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to enable converter clock: %d\n",
> + ret);
> + return ret;
The use count of enable and prepare on priv->clk_gate will be
unbalanced.
> + }
> +
> + mutex_init(&priv->lock);
> + for (i = 0; i < NUM_SENSORS; i++) {
> + struct zx2967_thermal_sensor *sensor = &priv->sensors[i];
> +
> + sensor->priv = priv;
> + sensor->id = i;
> + sensor->tzd = thermal_zone_of_sensor_register(&pdev->dev,
> + i,
> + sensor,
> + &zx2967_of_thermal_ops);
> + if (IS_ERR(sensor->tzd)) {
> + ret = PTR_ERR(sensor->tzd);
> + dev_err(&pdev->dev, "failed to register sensor %d: %d\n",
> + i, ret);
> + goto remove_ts;
> + }
> + }
> + platform_set_drvdata(pdev, priv);
> +
> + return 0;
> +
> +remove_ts:
> + for (i--; i >= 0; i--)
> + thermal_zone_of_sensor_unregister(&pdev->dev,
> + priv->sensors[i].tzd);
> +
> + return ret;
Unbalanced clk_prepare_enable(priv->pclk).
Shawn
> +}
> +
> +static int zx2967_thermal_exit(struct platform_device *pdev)
> +{
> + struct zx2967_thermal_priv *priv = platform_get_drvdata(pdev);
> + int i;
> +
> + for (i = 0; i < NUM_SENSORS; i++) {
> + struct zx2967_thermal_sensor *sensor = &priv->sensors[i];
> +
> + thermal_zone_of_sensor_unregister(&pdev->dev, sensor->tzd);
> + }
> + clk_disable_unprepare(priv->pclk);
> + clk_disable_unprepare(priv->clk_gate);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id zx2967_thermal_id_table[] = {
> + { .compatible = "zte,zx2967-thermal" },
> + { .compatible = "zte,zx296718-thermal" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, zx2967_thermal_id_table);
> +
> +static SIMPLE_DEV_PM_OPS(zx2967_thermal_pm_ops,
> + zx2967_thermal_suspend, zx2967_thermal_resume);
> +
> +static struct platform_driver zx2967_thermal_driver = {
> + .probe = zx2967_thermal_probe,
> + .remove = zx2967_thermal_exit,
> + .driver = {
> + .name = "zx2967_thermal",
> + .of_match_table = zx2967_thermal_id_table,
> + .pm = &zx2967_thermal_pm_ops,
> + },
> +};
> +module_platform_driver(zx2967_thermal_driver);
> +
> +MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
> +MODULE_DESCRIPTION("ZTE zx2967 thermal driver");
> +MODULE_LICENSE("GPL");
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v1 1/3] dt: bindings: add thermal device driver for zx2967
From: Shawn Guo @ 2017-01-09 2:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483767488-19778-1-git-send-email-baoyou.xie@linaro.org>
On Sat, Jan 07, 2017 at 01:38:06PM +0800, Baoyou Xie wrote:
> This patch adds dt-binding documentation for zx2967 family thermal sensor.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
The patch subject is inappropriate. The patch adds a bindings not
device driver.
> ---
> .../devicetree/bindings/thermal/zx2967-thermal.txt | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/thermal/zx2967-thermal.txt
>
> diff --git a/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt b/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt
> new file mode 100644
> index 0000000..2633964
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/zx2967-thermal.txt
> @@ -0,0 +1,22 @@
> +* ZTE zx2967 family Thermal
> +
> +Required Properties:
> +- compatible: should be one of the following.
> + * zte,zx2967-thermal
> + * zte,zx296718-thermal
We usually use specific SoC name in compatible string to specify the
programming model for the hardware. That said, I do not think we need
"zte,zx2967-thermal".
> +- reg: physical base address of the controller and length of memory mapped
> + region.
> +- clocks : Pairs of phandle and specifier referencing the controller's clocks.
> +- clock-names: "tempsensor_gate" for the topcrm clock.
> + "tempsensor_pclk" for the apb clock.
In the context of tempsensor device, the "tempsensor_" in the clock
names are not really necessary.
> +- #thermal-sensor-cells: must be 0.
> +
> +Example:
> +
> + tempsensor: tempsensor at 148a000 {
> + compatible = "zte,zx2967-thermal";
"zte,zx296718-thermal"
Shawn
> + reg = <0x0148a000 0x20>;
> + clocks = <&topcrm TEMPSENSOR_GATE>, <&audiocrm AUDIO_TS_PCLK>;
> + clock-names = "tempsensor_gate", "tempsensor_pclk";
> + #thermal-sensor-cells = <0>;
> + };
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v2 05/12] Document: dt: binding: imx: update pinctrl doc for imx6sll
From: Jacky Bai @ 2017-01-09 2:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACRpkdYUME8K+JusA0ORRKqxyBuhDdyei8eg7UZbHidKw9=bQw@mail.gmail.com>
> Subject: Re: [PATCH v2 05/12] Document: dt: binding: imx: update pinctrl doc
> for imx6sll
>
> On Tue, Dec 27, 2016 at 10:47 AM, Bai Ping <ping.bai@nxp.com> wrote:
>
> > Add pinctrl binding doc update for imx6sll.
> >
> > Signed-off-by: Bai Ping <ping.bai@nxp.com>
>
> I have to push back on this a bit.
>
> > +Please refer to fsl,imx-pinctrl.txt in this directory for common
> > +binding part and usage.
>
> I understand that it is building on top of the old i.MX bindings and that it has
> some kind of "tradition" coming with it.
>
> At the same time, the i.MX bindings came about before we had the generic pin
> control bindings defined.
>
> > +CONFIG bits definition:
> > +PAD_CTL_LVE (1 << 22)
> > +PAD_CTL_HYS (1 << 16)
> > +PAD_CTL_PUS_100K_DOWN (0 << 14)
> > +PAD_CTL_PUS_47K_UP (1 << 14)
> > +PAD_CTL_PUS_100K_UP (2 << 14)
> > +PAD_CTL_PUS_22K_UP (3 << 14)
> > +PAD_CTL_PUE (1 << 13)
> > +PAD_CTL_PKE (1 << 12)
> > +PAD_CTL_ODE (1 << 11)
> > +PAD_CTL_SPEED_LOW (0 << 6)
> > +PAD_CTL_SPEED_MED (1 << 6)
> > +PAD_CTL_SPEED_HIGH (3 << 6)
> > +PAD_CTL_DSE_DISABLE (0 << 3)
> > +PAD_CTL_DSE_260ohm (1 << 3)
> > +PAD_CTL_DSE_130ohm (2 << 3)
> > +PAD_CTL_DSE_87ohm (3 << 3)
> > +PAD_CTL_DSE_65ohm (4 << 3)
> > +PAD_CTL_DSE_52ohm (5 << 3)
> > +PAD_CTL_DSE_43ohm (6 << 3)
> > +PAD_CTL_DSE_37ohm (7 << 3)
> > +PAD_CTL_SRE_FAST (1 << 0)
> > +PAD_CTL_SRE_SLOW (0 << 0)
>
> A whole slew of these if not all correspond to the generic bindings.
>
> I would consider augmenting the code in the driver to handle the generic
> bindings *in addition* to the old legacy bindings, and use those over these
> random custom bits.
>
> Read drivers using CONFIG_GENERIC_PINCONF as an inspiration.
>
> For example see commit
> cefbf1a1b29531a970bc2908a50a75d6474fcc38
> "pinctrl: sunxi: Support generic binding"
> from Maxime Ripard, where he does a similar thing for sunxi.
I have look into the above commit on using generic binding. But I think the generic pinconf
is not very easy to add in imx pinctrl Driver. imx pinctrl use a different way to parse the pin configure.
Each fsl,pin entry looks like <PIN_FUNC_ID CONFIG> in dts, the CONFIG is the pad setting value like
pull-up, open-drain, drive strength etc. The above config bit definition is specific to each SOC in the PAD CTL register.
If we want set the pin config to enable hysteresis, 47KOhm Pull Up, 50Mhz speed, 80Ohm driver strength
and Fast Slew Rate, then the CONFIG value should be 0x17059( ORs corresponding bit definition). This value will be set in
PAD CTL register to config the corresponding pin.
BR
Jacky Bai
>
> Yours,
> Linus Walleij
^ permalink raw reply
* [PATCH v7 5/5] soc: zte: pm_domains: Add support for zx296718
From: Shawn Guo @ 2017-01-09 2:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483694164-7668-5-git-send-email-baoyou.xie@linaro.org>
On Fri, Jan 06, 2017 at 05:16:04PM +0800, Baoyou Xie wrote:
> This patch introduces the power domain driver of zx296718
> which belongs to zte's zx2967 family.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> Reviewed-by: Jun Nie <jun.nie@linaro.org>
Except the need of PCU_DM_xxx enum (I'm not strong on that,so would
leave it to author's decision), the patch series looks good to me.
I'm going to queue it up for 4.11 after getting Rob's ACK on bindings.
Let me know if anyone has any objections.
Shawn
^ permalink raw reply
* [PATCH v9 3/3] iio: adc: add support for Allwinner SoCs ADC
From: Zhang Rui @ 2017-01-09 2:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <f8285a90-656f-0da4-ee81-47b79ce4cd2c@kernel.org>
Hi,
On Sun, 2017-01-08 at 11:17 +0000, Jonathan Cameron wrote:
> On 30/12/16 14:40, Jonathan Cameron wrote:
> >
> > On 13/12/16 14:33, Quentin Schulz wrote:
> > >
> > > The Allwinner SoCs all have an ADC that can also act as a
> > > touchscreen
> > > controller and a thermal sensor. This patch adds the ADC driver
> > > which is
> > > based on the MFD for the same SoCs ADC.
> > >
> > > This also registers the thermal adc channel in the iio map array
> > > so
> > > iio_hwmon could use it without modifying the Device Tree. This
> > > registers
> > > the driver in the thermal framework.
> > >
> > > The thermal sensor requires the IP to be in touchscreen mode to
> > > return
> > > correct values. Therefore, if the user is continuously reading
> > > the ADC
> > > channel(s), the thermal framework in which the thermal sensor is
> > > registered will switch the IP in touchscreen mode to get a
> > > temperature
> > > value and requires a delay of 100ms (because of the mode
> > > switching),
> > > then the ADC will switch back to ADC mode and requires also a
> > > delay of
> > > 100ms. If the ADC readings are critical to user and the SoC
> > > temperature
> > > is not, this driver is capable of not registering the thermal
> > > sensor in
> > > the thermal framework and thus, "quicken" the ADC readings.
> > >
> > > This driver probes on three different platform_device_id to take
> > > into
> > > account slight differences (registers bit and temperature
> > > computation)
> > > between Allwinner SoCs ADCs.
> > >
> > > Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> > > Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > > Acked-by: Jonathan Cameron <jic23@kernel.org>
> > > Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> > One comment inline but not a blocker.
> >
> > I would ideally like an ack from the thermal side.??The relevant
> > code
> > is small, but best to be sure and keep them in the loop as well.
> >
> > It does feel a little convoluted to have both this directly
> > providing
> > a thermal zone and being able to create one indirectly through
> > hwmon as
> > well but this solution works for me I think...
> >
> > Cc'd Zang and Eduardo.
> Nothing seems to have come through on that front.
>
> I need to get a pull request out to Greg and rebase my tree before I
> have
> the precursor patch in place. Give me a bump if you haven't heard
> anything by
> the time next week.
>
> Thanks,
>
> Jonathan
> >
> >
> >?
> > > +
> > > +static int sun4i_gpadc_probe(struct platform_device *pdev)
> > > +{
> > > + struct sun4i_gpadc_iio *info;
> > > + struct iio_dev *indio_dev;
> > > + int ret;
> > > + struct sun4i_gpadc_dev *sun4i_gpadc_dev;
> > > +
> > > + sun4i_gpadc_dev = dev_get_drvdata(pdev->dev.parent);
> > > +
> > > + indio_dev = devm_iio_device_alloc(&pdev->dev,
> > > sizeof(*info));
> > > + if (!indio_dev)
> > > + return -ENOMEM;
> > > +
> > > + info = iio_priv(indio_dev);
> > > + platform_set_drvdata(pdev, indio_dev);
> > > +
> > > + mutex_init(&info->mutex);
> > > + info->regmap = sun4i_gpadc_dev->regmap;
> > > + info->indio_dev = indio_dev;
> > > + init_completion(&info->completion);
> > > + indio_dev->name = dev_name(&pdev->dev);
> > > + indio_dev->dev.parent = &pdev->dev;
> > > + indio_dev->dev.of_node = pdev->dev.of_node;
> > > + indio_dev->info = &sun4i_gpadc_iio_info;
> > > + indio_dev->modes = INDIO_DIRECT_MODE;
> > > + indio_dev->num_channels =
> > > ARRAY_SIZE(sun4i_gpadc_channels);
> > > + indio_dev->channels = sun4i_gpadc_channels;
> > > +
> > > + info->data = (struct gpadc_data
> > > *)platform_get_device_id(pdev)->driver_data;
> > > +
> > > + /*
> > > + ?* Since the controller needs to be in touchscreen mode
> > > for its thermal
> > > + ?* sensor to operate properly, and that switching
> > > between the two modes
> > > + ?* needs a delay, always registering in the thermal
> > > framework will
> > > + ?* significantly slow down the conversion rate of the
> > > ADCs.
> > > + ?*
> > > + ?* Therefore, instead of depending on THERMAL_OF in
> > > Kconfig, we only
> > > + ?* register the sensor if that option is enabled,
> > > eventually leaving
> > > + ?* that choice to the user.
> > > + ?*/
> > > +
> > > + if (IS_ENABLED(CONFIG_THERMAL_OF)) {
> > > + /*
> > > + ?* This driver is a child of an MFD which has a
> > > node in the DT
> > > + ?* but not its children, because of DT backward
> > > compatibility
> > > + ?* for A10, A13 and A31 SoCs. Therefore, the
> > > resulting devices
> > > + ?* of this driver do not have an of_node
> > > variable.
> > > + ?* However, its parent (the MFD driver) has an
> > > of_node variable
> > > + ?* and since
> > > devm_thermal_zone_of_sensor_register uses its first
> > > + ?* argument to match the phandle defined in the
> > > node of the
> > > + ?* thermal driver with the of_node of the device
> > > passed as first
> > > + ?* argument and the third argument to call ops
> > > from
> > > + ?* thermal_zone_of_device_ops, the solution is
> > > to use the parent
> > > + ?* device as first argument to match the phandle
> > > with its
> > > + ?* of_node, and the device from this driver as
> > > third argument to
> > > + ?* return the temperature.
> > > + ?*/
I'd leave this for Eduardo.
thanks,
rui
> > > + struct thermal_zone_device *tzd;
> > > + tzd = devm_thermal_zone_of_sensor_register(pdev-
> > > >dev.parent, 0,
> > > + ???info,
> > > + ???&sun4
> > > i_ts_tz_ops);
> > > + if (IS_ERR(tzd)) {
> > > + dev_err(&pdev->dev,
> > > + "could not register thermal
> > > sensor: %ld\n",
> > > + PTR_ERR(tzd));
> > > + ret = PTR_ERR(tzd);
> > > + goto err;
> > > + }
> > > + } else {
> > > + indio_dev->num_channels =
> > > + ARRAY_SIZE(sun4i_gpadc_channels_no_temp)
> > > ;
> > > + indio_dev->channels =
> > > sun4i_gpadc_channels_no_temp;
> > > + }
> > > +
> > > + pm_runtime_set_autosuspend_delay(&pdev->dev,
> > > + ?SUN4I_GPADC_AUTOSUSPEND
> > > _DELAY);
> > > + pm_runtime_use_autosuspend(&pdev->dev);
> > > + pm_runtime_set_suspended(&pdev->dev);
> > > + pm_runtime_enable(&pdev->dev);
> > > +
> > > + if (IS_ENABLED(CONFIG_THERMAL_OF)) {
> > > + ret = sun4i_irq_init(pdev, "TEMP_DATA_PENDING",
> > > + ?????sun4i_gpadc_temp_data_irq_h
> > > andler,
> > > + ?????"temp_data", &info-
> > > >temp_data_irq,
> > > + ?????&info-
> > > >ignore_temp_data_irq);
> > > + if (ret < 0)
> > > + goto err;
> > > + }
> > > +
> > > + ret = sun4i_irq_init(pdev, "FIFO_DATA_PENDING",
> > > + ?????sun4i_gpadc_fifo_data_irq_handler,
> > > "fifo_data",
> > > + ?????&info->fifo_data_irq, &info-
> > > >ignore_fifo_data_irq);
> > > + if (ret < 0)
> > > + goto err;
> > > +
> > > + if (IS_ENABLED(CONFIG_THERMAL_OF)) {
> > > + ret = iio_map_array_register(indio_dev,
> > > sun4i_gpadc_hwmon_maps);
> > > + if (ret < 0) {
> > > + dev_err(&pdev->dev,
> > > + "failed to register iio map
> > > array\n");
> > > + goto err;
> > > + }
> > > + }
> > > +
> > > + ret = devm_iio_device_register(&pdev->dev, indio_dev);
> > > + if (ret < 0) {
> > > + dev_err(&pdev->dev, "could not register the
> > > device\n");
> > > + goto err_map;
> > > + }
> > > +
> > > + return 0;
> > > +
> > > +err_map:
> > > + if (IS_ENABLED(CONFIG_THERMAL_OF))
> > > + iio_map_array_unregister(indio_dev);
> > > +
> > > +err:
> > > + pm_runtime_put(&pdev->dev);
> > > + pm_runtime_disable(&pdev->dev);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int sun4i_gpadc_remove(struct platform_device *pdev)
> > > +{
> > > + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> > > +
> > > + pm_runtime_put(&pdev->dev);
> > > + pm_runtime_disable(&pdev->dev);
> > > + if (IS_ENABLED(CONFIG_THERMAL_OF))
> > > + iio_map_array_unregister(indio_dev);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static const struct platform_device_id sun4i_gpadc_id[] = {
> > > + { "sun4i-a10-gpadc-iio",
> > > (kernel_ulong_t)&sun4i_gpadc_data },
> > > + { "sun5i-a13-gpadc-iio",
> > > (kernel_ulong_t)&sun5i_gpadc_data },
> > > + { "sun6i-a31-gpadc-iio",
> > > (kernel_ulong_t)&sun6i_gpadc_data },
> > > + { /* sentinel */ },
> > > +};
> > > +
> > > +static struct platform_driver sun4i_gpadc_driver = {
> > > + .driver = {
> > > + .name = "sun4i-gpadc-iio",
> > > + .pm = &sun4i_gpadc_pm_ops,
> > > + },
> > > + .id_table = sun4i_gpadc_id,
> > > + .probe = sun4i_gpadc_probe,
> > > + .remove = sun4i_gpadc_remove,
> > > +};
> > > +
> > > +module_platform_driver(sun4i_gpadc_driver);
> > > +
> > > +MODULE_DESCRIPTION("ADC driver for sunxi platforms");
> > > +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com
> > > >");
> > > +MODULE_LICENSE("GPL v2");
> > > diff --git a/include/linux/mfd/sun4i-gpadc.h
> > > b/include/linux/mfd/sun4i-gpadc.h
> > > index d7a29f2..509e736 100644
> > > --- a/include/linux/mfd/sun4i-gpadc.h
> > > +++ b/include/linux/mfd/sun4i-gpadc.h
> > > @@ -28,6 +28,7 @@
> > > ?#define SUN4I_GPADC_CTRL1_TP_MODE_EN BIT(
> > > 4)
> > > ?#define SUN4I_GPADC_CTRL1_TP_ADC_SELECT B
> > > IT(3)
> > > ?#define SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GEN
> > > MASK(2, 0) & (x))
> > > +#define SUN4I_GPADC_CTRL1_ADC_CHAN_MASK G
> > > ENMASK(2, 0)
> > > ?
> > > ?/* TP_CTRL1 bits for sun6i SOCs */
> > > ?#define SUN6I_GPADC_CTRL1_TOUCH_PAN_CALI_EN BIT(7
> > > )
> > > @@ -35,6 +36,7 @@
> > > ?#define SUN6I_GPADC_CTRL1_TP_MODE_EN BIT(
> > > 5)
> > > ?#define SUN6I_GPADC_CTRL1_TP_ADC_SELECT B
> > > IT(4)
> > > ?#define SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GEN
> > > MASK(3, 0) & BIT(x))
> > > +#define SUN6I_GPADC_CTRL1_ADC_CHAN_MASK G
> > > ENMASK(3, 0)
> > > ?
> > > ?#define SUN4I_GPADC_CTRL2 0x08
> > > ?
> > >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-
> > iio" in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at??http://vger.kernel.org/majordomo-info.html
> >
^ permalink raw reply
* [PATCH v7 1/5] dt-bindings: zte: add bindings document for zx2967 power domain controller
From: Shawn Guo @ 2017-01-09 2:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483694164-7668-1-git-send-email-baoyou.xie@linaro.org>
On Fri, Jan 06, 2017 at 05:16:00PM +0800, Baoyou Xie wrote:
> This patch adds device tree bindings document for ZTE zx2967
> family power domain controller.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
Hi Rob,
Are you happy with the bindings? I plan to merge the series through
arm-soc tree with your ACK on this patch.
Shawn
^ permalink raw reply
* [PATCH 1/3] ARM: at91: flush the L2 cache before entering cpu idle
From: Wenyou.Yang at microchip.com @ 2017-01-09 1:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170106090517.txcoukisnx43cfqq@piout.net>
Hi Alexandre,
> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: 2017?1?6? 17:05
> To: Wenyou Yang - A41535 <Wenyou.Yang@microchip.com>
> Cc: Russell King <linux@arm.linux.org.uk>; Nicolas Ferre
> <nicolas.ferre@atmel.com>; Rob Herring <robh+dt@kernel.org>; Mark Rutland
> <mark.rutland@arm.com>; linux-kernel at vger.kernel.org; Wenyou Yang - A41535
> <Wenyou.Yang@microchip.com>; devicetree at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH 1/3] ARM: at91: flush the L2 cache before entering cpu idle
>
> Hi,
>
> On 06/01/2017 at 14:59:45 +0800, Wenyou Yang wrote :
> > For the SoCs such as SAMA5D2 and SAMA5D4 which have L2 cache, flush
> > the L2 cache first before entering the cpu idle.
> >
> > Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> > ---
> >
> > arch/arm/mach-at91/pm.c | 19 +++++++++++++++++++
> > drivers/memory/atmel-sdramc.c | 1 +
> > 2 files changed, 20 insertions(+)
> >
> > diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index
> > b4332b727e9c..1a60dede1a01 100644
> > --- a/arch/arm/mach-at91/pm.c
> > +++ b/arch/arm/mach-at91/pm.c
> > @@ -289,6 +289,24 @@ static void at91_ddr_standby(void)
> > at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); }
> >
> > +static void at91_ddr_cache_standby(void) {
> > + u32 saved_lpr;
> > +
> > + flush_cache_all();
> > + outer_disable();
> > +
> > + saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR);
> > + at91_ramc_write(0, AT91_DDRSDRC_LPR, (saved_lpr &
> > + (~AT91_DDRSDRC_LPCB)) |
> AT91_DDRSDRC_LPCB_SELF_REFRESH);
> > +
> > + cpu_do_idle();
> > +
> > + at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr);
> > +
> > + outer_resume();
> > +}
> > +
>
> Seems good to me. Did you measure the added latency on sama5d3 if you add the
> cache operations in at91_ddr_standby instead of having a new function?
No, I didn't. How to measure it?
Best Regards,
Wenyou Yang
^ permalink raw reply
* [linux-sunxi] [PATCH 1/2] drivers: pinctrl: add driver for Allwinner H5 SoC
From: André Przywara @ 2017-01-09 0:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170105224210.wfinfucbpkkd44om@lukather>
On 05/01/17 22:42, Maxime Ripard wrote:
> On Fri, Dec 30, 2016 at 01:55:44PM +0100, Linus Walleij wrote:
>> On Mon, Dec 26, 2016 at 3:33 PM, Andr? Przywara <andre.przywara@arm.com> wrote:
>>
>>> So while this patch technically looks correct, I was wondering if we
>>> should really explore the possibility of making the whole of sunxi
>>> pinctrl DT controlled.
>>> I brought this up a while ago, but people weren't overly enthusiastic
>>> about it, though their argument weren't really convincing to me[1].
>>>
>>> So:
>>> As this "driver" here is basically a table linking GPIO bit settings
>>> (the actual mux value) to names and every pin we care about needs to be
>>> enumerated in the DT anyway, why not just add something like:
>>> allwinner,pinmux = <4>;
>>> to each pin(group) in the DT and get rid of this "driver" file here
>>> entirely?
>>
>> I'm open to that if you can use pinctrl-single which is in the kernel
>> for this purpose only, and is used with both OMAPs and HiSilicon.
>
> I'm not open to that, and I'm getting tired of discussing it over and
> over again. Andre, if you want to be convinced again, please read the
> last discussion we had on this topic.
As I said: It didn't convince me back then. And frankly we didn't really
discuss it back then, I just refrained from entering a discussion
against _two_ maintainers at this time, since my capacity on this kind
of email threads is really very limited - especially for something that
is a hobby to me.
It isn't the highest priority on my list, but I am still planning on
sketching something, so that we can discuss about actual code.
As it seems like your new patches bring some relief to the immediate
copy&paste pain (though the actual DT aspect still remains), I will shut
up - for now ;-)
Cheers,
Andre.
^ permalink raw reply
* [PATCH 1/5] drivers: mmc: sunxi: fix A64 calibration routine
From: André Przywara @ 2017-01-08 23:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170105174725.kmr25iodjnjozqjm@lukather>
On 05/01/17 17:47, Maxime Ripard wrote:
Hi,
> On Mon, Jan 02, 2017 at 11:03:42PM +0000, Andre Przywara wrote:
>> The calibration facility in the A64 MMC block seems to have been
>> misunderstood: the result value is not the value to program into the
>> delay bits, but is the number of delay cells that result in a full clock
>> cycle delay. So this value has to be scaled by the desired phase, which
>> we still have to know and program.
>> Change the calibration routine to take a phase parameter and scale the
>> calibration value accordingly.
>> Also introduce sun50i-a64 delay parameters to store the required phase.
>> Looking at the BSP kernel the sample delay for anything below HS200 is
>> 0, so we go with that value.
>> Once the driver supports HS200 and faster modes, we can enter confirmed
>> working values in there.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>
> Exactly how that works hasn't been confirmed, and the only thing that
> this patch actually do is... nothing, since the delay is always 0. If
> and when we get HS400 to work and we know for a fact how the
> calibration works, then we'll be able to use it. Until then, we can
> just clear those bits.
Fair enough, though I am a bit puzzled as what to do here now:
Dropping this patch here entirely causes the wrong calibration settings
to degrade the BananaPi eMMC performance by up to 50% (20 MB/s vs.
40MB/s in hdparm, and 25% longer execution time for a "find / -type f |
xargs md5sum > /dev/null" run). So this is not an option.
1) Shall I simply revert Icenowy's original patch that introduced the
calibration function? That should leave the values at their reset value
of 0. But do we want to make sure that these values are set to 0 by
explicitly zeroing the bits?
Also I guess your HS-400 support will need to write some values in
there, so we will need some code later again?
2) Changing the calibration function to don't do any calibration really
and just write 0 into the delay bits seems like an option, but looks a
bit weird. Also I guess your faster transfer modes support will need to
write _something_, though I don't know what those values are and where
they will come from.
So I am leaning towards 1) for now, unless you send your MMC patches and
we at least merge the patch dealing with the calibration part for the
next release.
Any recommendations? I would love to see the MMC support go into 4.11.
Cheers,
Andre.
^ permalink raw reply
* [PATCH 2/2] staging/media/s5p-cec/exynos_hdmi_cecctrl.c Fixed blank line before closing brace '}'
From: Scott Matheina @ 2017-01-08 23:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1483916446-6418-1-git-send-email-scott@matheina.com>
Fixed checkpatch check blank line before closing brace '}'
Signed-off-by: Scott Matheina <scott@matheina.com>
---
drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c b/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c
index f2b24a4..1edf667 100644
--- a/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c
+++ b/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c
@@ -87,7 +87,6 @@ void s5p_cec_mask_tx_interrupts(struct s5p_cec_dev *cec)
reg |= S5P_CEC_IRQ_TX_DONE;
reg |= S5P_CEC_IRQ_TX_ERROR;
writeb(reg, cec->reg + S5P_CEC_IRQ_MASK);
-
}
void s5p_cec_unmask_tx_interrupts(struct s5p_cec_dev *cec)
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] staging:media:s5p-cec:exynos_hdmi_cecctrl.c Fixed Alignment should match open parenthesis
From: Scott Matheina @ 2017-01-08 23:00 UTC (permalink / raw)
To: linux-arm-kernel
Fixed Checkpatch check "Alignment should match open parenthesis"
Signed-off-by: Scott Matheina <scott@matheina.com>
---
drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c b/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c
index ce95e0f..f2b24a4 100644
--- a/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c
+++ b/drivers/staging/media/s5p-cec/exynos_hdmi_cecctrl.c
@@ -186,13 +186,13 @@ u32 s5p_cec_get_status(struct s5p_cec_dev *cec)
void s5p_clr_pending_tx(struct s5p_cec_dev *cec)
{
writeb(S5P_CEC_IRQ_TX_DONE | S5P_CEC_IRQ_TX_ERROR,
- cec->reg + S5P_CEC_IRQ_CLEAR);
+ cec->reg + S5P_CEC_IRQ_CLEAR);
}
void s5p_clr_pending_rx(struct s5p_cec_dev *cec)
{
writeb(S5P_CEC_IRQ_RX_DONE | S5P_CEC_IRQ_RX_ERROR,
- cec->reg + S5P_CEC_IRQ_CLEAR);
+ cec->reg + S5P_CEC_IRQ_CLEAR);
}
void s5p_cec_get_rx_buf(struct s5p_cec_dev *cec, u32 size, u8 *buffer)
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/8] ASoC: sunxi: Add support for audio codec in A23/H3 SoCs
From: Maxime Ripard @ 2017-01-08 21:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGb2v65mo2g90QX6DMpw4dN4=fjccP2kp-NAbUPBzXYTtF8kMg@mail.gmail.com>
On Sun, Jan 08, 2017 at 03:00:40AM +0800, Chen-Yu Tsai wrote:
> Hi Maxime,
>
> On Fri, Nov 25, 2016 at 8:34 PM, Chen-Yu Tsai <wens@csie.org> wrote:
> > Hi everyone,
> >
> > This is v2 of my Allwinner A23 and H3 audio codec support series.
> >
> > Changes since v1:
> >
> > - Use DEFINE_RES_MEM for the analog path controls block resources.
> > - Added Rob's ack.
> >
> > This series adds support for the audio codec found in Allwinner A23 and
> > H3 SoCs. The design and data paths are similar to the audio codec found
> > in earlier SoCs such as the A31. The analog audio paths are symmetrical
> > with left/right channels and down-mix selectors for mono differential
> > output.
> >
> > What deviates from previous SoCs is that the analog path controls have
> > been moved to a separate control bus, accessed through a message box
> > like register interface in the PRCM block. This necessitates writing
> > a separate component driver for it, which is then tied into the sound
> > card as an ASoC auxiliary device.
> >
> > Patch 1 adds the analog path controls block to the sun6i-prcm driver as
> > a sub-device, for the A23. The H3 currently does not use the PRCM driver.
> >
> > Patch 2 adds PCM and card support for the A23 codec to the sun4i-codec
> > driver.
> >
> > Patch 3 adds a device node for the analog path controls block to the A23
> > dtsi.
> >
> > Patch 4 adds a device node for the audio codec, and the phandle for the
> > analog path controls block to the A23 dtsi.
> >
> > Patch 5 enables the audio codec for the A23 Q8 tablets. On these tablets
> > the headphone output is driven in DC coupled, or "direct drive", mode.
> >
> > Patch 6 adds PCM and card support for the H3 codec to the sun4i-codec
> > driver.
> >
> > Patch 7 adds device nodes for the audio codec and analog path controls
> > block to the H3 dtsi.
> >
> > Patch 8 enables the audio codec on the Orange Pi PC. The audio output
> > jack on the board is tied to the line out pins on the SoC.
>
> All the driver bits are in. Can you pick up the dts patches?
I just did.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170108/da80dea7/attachment.sig>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox