* [PATCH] PM / Domains: Fix compatible for domain idle state
From: Lina Iyer @ 2016-11-03 21:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478210075-92045-1-git-send-email-lina.iyer@linaro.org>
Re-using idle state definition provided by arm,idle-state for domain
idle states creates a lot of confusion and limits further evolution of
the domain idle definition. To keep things clear and simple, define a
idle states for domain using a new compatible "domain-idle-state".
Fix existing PM domains code to look for the newly defined compatible.
Cc: <devicetree@vger.kernel.org>
Cc: Rob Herring <robh@kernel.org>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
.../bindings/power/domain-idle-state.txt | 33 ++++++++++++++++++++++
.../devicetree/bindings/power/power_domain.txt | 8 +++---
drivers/base/power/domain.c | 2 +-
3 files changed, 38 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/power/domain-idle-state.txt
diff --git a/Documentation/devicetree/bindings/power/domain-idle-state.txt b/Documentation/devicetree/bindings/power/domain-idle-state.txt
new file mode 100644
index 0000000..eefc7ed
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/domain-idle-state.txt
@@ -0,0 +1,33 @@
+PM Domain Idle State Node:
+
+A domain idle state node represents the state parameters that will be used to
+select the state when there are no active components in the domain.
+
+The state node has the following parameters -
+
+- compatible:
+ Usage: Required
+ Value type: <string>
+ Definition: Must be "domain-idle-state".
+
+- entry-latency-us
+ Usage: Required
+ Value type: <prop-encoded-array>
+ Definition: u32 value representing worst case latency in
+ microseconds required to enter the idle state.
+ The exit-latency-us duration may be guaranteed
+ only after entry-latency-us has passed.
+
+- exit-latency-us
+ Usage: Required
+ Value type: <prop-encoded-array>
+ Definition: u32 value representing worst case latency
+ in microseconds required to exit the idle state.
+
+- min-residency-us
+ Usage: Required
+ Value type: <prop-encoded-array>
+ Definition: u32 value representing minimum residency duration
+ in microseconds after which the idle state will yield
+ power benefits after overcoming the overhead in entering
+i the idle state.
diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
index e165036..723e1ad 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -31,7 +31,7 @@ Optional properties:
- domain-idle-states : A phandle of an idle-state that shall be soaked into a
generic domain power state. The idle state definitions are
- compatible with arm,idle-state specified in [1].
+ compatible with domain-idle-state specified in [1].
The domain-idle-state property reflects the idle state of this PM domain and
not the idle states of the devices or sub-domains in the PM domain. Devices
and sub-domains have their own idle-states independent of the parent
@@ -85,7 +85,7 @@ Example 3:
};
DOMAIN_RET: state at 0 {
- compatible = "arm,idle-state";
+ compatible = "domain-idle-state";
reg = <0x0>;
entry-latency-us = <1000>;
exit-latency-us = <2000>;
@@ -93,7 +93,7 @@ Example 3:
};
DOMAIN_PWR_DN: state at 1 {
- compatible = "arm,idle-state";
+ compatible = "domain-idle-state";
reg = <0x1>;
entry-latency-us = <5000>;
exit-latency-us = <8000>;
@@ -118,4 +118,4 @@ The node above defines a typical PM domain consumer device, which is located
inside a PM domain with index 0 of a power controller represented by a node
with the label "power".
-[1]. Documentation/devicetree/bindings/arm/idle-states.txt
+[1]. Documentation/devicetree/bindings/power/domain-idle-state.txt
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 661737c..f0bc672 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -2048,7 +2048,7 @@ int genpd_dev_pm_attach(struct device *dev)
EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
static const struct of_device_id idle_state_match[] = {
- { .compatible = "arm,idle-state", },
+ { .compatible = "domain-idle-state", },
{ }
};
--
2.7.4
^ permalink raw reply related
* [PATCH 3/3] ARM: dts: Add gyro and accel to APQ8060 Dragonboard
From: Bjorn Andersson @ 2016-11-03 21:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478164390-21613-3-git-send-email-linus.walleij@linaro.org>
On Thu 03 Nov 02:13 PDT 2016, Linus Walleij wrote:
> This adds the MPU-3050 gyroscope and the KXSD9 accelerometer to
> the Qualcomm APQ8060 Dragonboard. The KXSD9 is mounted beyond the
> MPU-3050 and appear as a subdevice beyond it. We set up the
> required GPIO and interrupt lines to make the devices work.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
I still would have preferred you using interrupts-extended when you're
specifying both parent and irq specifier anyways, but I'm ok with this.
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Regards,
Bjorn
> ---
> ChangeLog v2->v3:
> - Move the interrupt to the pm8058 alias to reflect the two patches
> properly specifying the PMIC as interrupt parent.
> ChangeLog v1->v2:
> - Use the new I2C mux gate bindings from Peter Rosin (merged to
> the I2C subsystem)
> ---
> arch/arm/boot/dts/qcom-apq8060-dragonboard.dts | 53 ++++++++++++++++++++++++++
> 1 file changed, 53 insertions(+)
>
> diff --git a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> index ea660ffa03ea..c1b99c9cb318 100644
> --- a/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> +++ b/arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
> @@ -220,6 +220,14 @@
> function = "ebi2";
> };
> };
> +
> + /* Interrupt line for the KXSD9 accelerometer */
> + dragon_kxsd9_gpios: kxsd9 {
> + irq {
> + pins = "gpio57"; /* IRQ line */
> + bias-pull-up;
> + };
> + };
> };
>
> qcom,ssbi at 500000 {
> @@ -272,6 +280,15 @@
> power-source = <PM8058_GPIO_S3>;
> };
> };
> + dragon_mpu3050_gpios: mpu3050-gpios {
> + pinconf {
> + pins = "gpio17";
> + function = "normal";
> + input-enable;
> + bias-disable;
> + power-source = <PM8058_GPIO_S3>;
> + };
> + };
> dragon_sdcc3_gpios: sdcc3-gpios {
> pinconf {
> pins = "gpio22";
> @@ -389,6 +406,42 @@
> vddd-supply = <&pm8058_lvs0>; // 1.8V
> vdda-supply = <&pm8058_l14>; // 2.85V
> };
> + mpu3050 at 68 {
> + compatible = "invensense,mpu3050";
> + reg = <0x68>;
> + /*
> + * GPIO17 has interrupt 208 on the
> + * PM8058, it is pulled high by a 10k
> + * resistor to VLOGIC so needs to be
> + * active low/falling edge.
> + */
> + interrupt-parent = <&pm8058>;
> + interrupts = <208 IRQ_TYPE_EDGE_FALLING>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&dragon_mpu3050_gpios>;
> + vlogic-supply = <&pm8058_lvs0>; // 1.8V
> + vdd-supply = <&pm8058_l14>; // 2.85V
> +
> + /*
> + * The MPU-3050 acts as a hub for the
> + * accelerometer.
> + */
> + i2c-gate {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + kxsd9 at 18 {
> + compatible = "kionix,kxsd9";
> + reg = <0x18>;
> + interrupt-parent = <&tlmm>;
> + interrupts = <57 IRQ_TYPE_EDGE_FALLING>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&dragon_kxsd9_gpios>;
> + iovdd-supply = <&pm8058_lvs0>; // 1.8V
> + vdd-supply = <&pm8058_l14>; // 2.85V
> + };
> + };
> + };
> };
> };
>
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH V3 0/8] IOMMU probe deferral support
From: Sricharan @ 2016-11-03 22:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <421e2b14-0231-d376-02a0-097423120b3d@arm.com>
Hi Robin,
>>>> [ 39.901592] iommu: Removing device 0000:08:00.0 from group 0
>>
>>Yikes, on second look, that definitely shouldn't be happening.
>>Everything below is probably the resulting fallout.
>
>[ 40.206703] vfio-pci 0000:08:00.0: Failed to setup iommu ops
>
>I think the above print which says "failed to setup iommu_ops"
>because the call ops->add_device failed in of_pci_iommu_configure
>is the reason for the failure, in my case i simply do not get this even with
>your scripts. ops->add_device succeeds in the rebind as well. So still
>checking what could be happening in your case.
I was looking at your code base from [1].The ops->add_device
callback from of_pci_iommu_configure on the rebind is the
one which is causing the failure. But not able to spot out
from code which point is causing the failure. It would be very helpful
if i can know which is the return value from the add_device callback
or point inside add_device callback which fails in your setup.
[1] git://linux-arm.org/linux-rm iommu/misc
>
>
>Regards,
> Sricharan
>
^ permalink raw reply
* [PATCH v3] arm/arm64: KVM: Perform local TLB invalidation when multiplexing vcpus on a single CPU
From: Marc Zyngier @ 2016-11-03 22:27 UTC (permalink / raw)
To: linux-arm-kernel
Architecturally, TLBs are private to the (physical) CPU they're
associated with. But when multiple vcpus from the same VM are
being multiplexed on the same CPU, the TLBs are not private
to the vcpus (and are actually shared across the VMID).
Let's consider the following scenario:
- vcpu-0 maps PA to VA
- vcpu-1 maps PA' to VA
If run on the same physical CPU, vcpu-1 can hit TLB entries generated
by vcpu-0 accesses, and access the wrong physical page.
The solution to this is to keep a per-VM map of which vcpu ran last
on each given physical CPU, and invalidate local TLBs when switching
to a different vcpu from the same VM.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
- From v2:
* Fixed the horrible sched_in vs load bug
* Now performing immediate invalidation instead of defering it
* Squashed a buglet in the kern_hyp_va macro
* Dropped Mark's RB since the code has substantially changed
* Only lightly tested on 32bit (I'm travelling)
arch/arm/include/asm/kvm_asm.h | 1 +
arch/arm/include/asm/kvm_host.h | 3 +++
arch/arm/include/asm/kvm_hyp.h | 1 +
arch/arm/kvm/arm.c | 27 ++++++++++++++++++++++++++-
arch/arm/kvm/hyp/tlb.c | 15 +++++++++++++++
arch/arm64/include/asm/kvm_asm.h | 1 +
arch/arm64/include/asm/kvm_host.h | 3 +++
arch/arm64/include/asm/kvm_mmu.h | 2 +-
arch/arm64/kvm/hyp/tlb.c | 15 +++++++++++++++
9 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index d7ea6bcb29bf..8ef05381984b 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -66,6 +66,7 @@ extern char __kvm_hyp_vector[];
extern void __kvm_flush_vm_context(void);
extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
+extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 2d19e02d03fd..d5423ab15ed5 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -57,6 +57,9 @@ struct kvm_arch {
/* VTTBR value associated with below pgd and vmid */
u64 vttbr;
+ /* The last vcpu id that ran on each physical CPU */
+ int __percpu *last_vcpu_ran;
+
/* Timer */
struct arch_timer_kvm timer;
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
index 343135ede5fa..58508900c4bb 100644
--- a/arch/arm/include/asm/kvm_hyp.h
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -71,6 +71,7 @@
#define ICIALLUIS __ACCESS_CP15(c7, 0, c1, 0)
#define ATS1CPR __ACCESS_CP15(c7, 0, c8, 0)
#define TLBIALLIS __ACCESS_CP15(c8, 0, c3, 0)
+#define TLBIALL __ACCESS_CP15(c8, 0, c7, 0)
#define TLBIALLNSNHIS __ACCESS_CP15(c8, 4, c3, 4)
#define PRRR __ACCESS_CP15(c10, 0, c2, 0)
#define NMRR __ACCESS_CP15(c10, 0, c2, 1)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 08bb84f2ad58..19b5f5c1c0ff 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -114,11 +114,18 @@ void kvm_arch_check_processor_compat(void *rtn)
*/
int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
{
- int ret = 0;
+ int ret, cpu;
if (type)
return -EINVAL;
+ kvm->arch.last_vcpu_ran = alloc_percpu(typeof(*kvm->arch.last_vcpu_ran));
+ if (!kvm->arch.last_vcpu_ran)
+ return -ENOMEM;
+
+ for_each_possible_cpu(cpu)
+ *per_cpu_ptr(kvm->arch.last_vcpu_ran, cpu) = -1;
+
ret = kvm_alloc_stage2_pgd(kvm);
if (ret)
goto out_fail_alloc;
@@ -141,6 +148,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
out_free_stage2_pgd:
kvm_free_stage2_pgd(kvm);
out_fail_alloc:
+ free_percpu(kvm->arch.last_vcpu_ran);
+ kvm->arch.last_vcpu_ran = NULL;
return ret;
}
@@ -168,6 +177,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
{
int i;
+ free_percpu(kvm->arch.last_vcpu_ran);
+ kvm->arch.last_vcpu_ran = NULL;
+
for (i = 0; i < KVM_MAX_VCPUS; ++i) {
if (kvm->vcpus[i]) {
kvm_arch_vcpu_free(kvm->vcpus[i]);
@@ -312,6 +324,19 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
+ int *last_ran;
+
+ last_ran = this_cpu_ptr(vcpu->kvm->arch.last_vcpu_ran);
+
+ /*
+ * We might get preempted before the vCPU actually runs, but
+ * over-invalidation doesn't affect correctness.
+ */
+ if (*last_ran != vcpu->vcpu_id) {
+ kvm_call_hyp(__kvm_tlb_flush_local_vmid, vcpu);
+ *last_ran = vcpu->vcpu_id;
+ }
+
vcpu->cpu = cpu;
vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
diff --git a/arch/arm/kvm/hyp/tlb.c b/arch/arm/kvm/hyp/tlb.c
index 729652854f90..6d810af2d9fd 100644
--- a/arch/arm/kvm/hyp/tlb.c
+++ b/arch/arm/kvm/hyp/tlb.c
@@ -55,6 +55,21 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
__kvm_tlb_flush_vmid(kvm);
}
+void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
+
+ /* Switch to requested VMID */
+ write_sysreg(kvm->arch.vttbr, VTTBR);
+ isb();
+
+ write_sysreg(0, TLBIALL);
+ dsb(nsh);
+ isb();
+
+ write_sysreg(0, VTTBR);
+}
+
void __hyp_text __kvm_flush_vm_context(void)
{
write_sysreg(0, TLBIALLNSNHIS);
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 18f746551bf6..ec3553eb9349 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -54,6 +54,7 @@ extern char __kvm_hyp_vector[];
extern void __kvm_flush_vm_context(void);
extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
+extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index bd94e6766759..e5050388e062 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -62,6 +62,9 @@ struct kvm_arch {
/* VTTBR value associated with above pgd and vmid */
u64 vttbr;
+ /* The last vcpu id that ran on each physical CPU */
+ int __percpu *last_vcpu_ran;
+
/* The maximum number of vCPUs depends on the used GIC model */
int max_vcpus;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index a79b969c26fc..6f72fe8b0e3e 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -128,7 +128,7 @@ static inline unsigned long __kern_hyp_va(unsigned long v)
return v;
}
-#define kern_hyp_va(v) (typeof(v))(__kern_hyp_va((unsigned long)(v)))
+#define kern_hyp_va(v) ((typeof(v))(__kern_hyp_va((unsigned long)(v))))
/*
* We currently only support a 40bit IPA.
diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
index 9cc0ea784ae6..88e2f2b938f0 100644
--- a/arch/arm64/kvm/hyp/tlb.c
+++ b/arch/arm64/kvm/hyp/tlb.c
@@ -64,6 +64,21 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
write_sysreg(0, vttbr_el2);
}
+void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
+
+ /* Switch to requested VMID */
+ write_sysreg(kvm->arch.vttbr, vttbr_el2);
+ isb();
+
+ asm volatile("tlbi vmalle1" : : );
+ dsb(nsh);
+ isb();
+
+ write_sysreg(0, vttbr_el2);
+}
+
void __hyp_text __kvm_flush_vm_context(void)
{
dsb(ishst);
--
2.10.1
^ permalink raw reply related
* [PATCH 0/2] ARM64: meson-gxbb: SCPI Fixup
From: Kevin Hilman @ 2016-11-03 22:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478164284-24958-1-git-send-email-narmstrong@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> This patchset updates the GXBB dtsi and the ARM64 defconfig in order
> to make SCPI work following the Legacy SCPI rework from Sudeep Hola at [1].
>
> The rework introduced a generic "arm,legacy-scpi" compatible string.
> The second patch enables the necessary Platform MHU in defconfig.
I folded PATCH 1/2 into the original, and (re)pushed both the amlogic
v4.10/dt64 branch.
Kevin
> [1] http://lkml.kernel.org/r/1478148731-11712-1-git-send-email-sudeep.holla at arm.com
>
> Neil Armstrong (2):
> ARM64: dts: meson-gxbb: Add generic legacy scpi compatible
> ARM64: configs: Add Platform MHU in defconfig
>
> arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 2 +-
> arch/arm64/configs/defconfig | 1 +
> 2 files changed, 2 insertions(+), 1 deletion(-)
^ permalink raw reply
* [PATCH] ARM: cache-uniphier: include <linux/errno.h> instead of <linux/types.h>
From: Masahiro Yamada @ 2016-11-03 22:57 UTC (permalink / raw)
To: linux-arm-kernel
Nothing in this header file depends on <linux/types.h>.
Rather, <linux/errno.h> should be included for -ENODEV.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
arch/arm/include/asm/hardware/cache-uniphier.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/hardware/cache-uniphier.h b/arch/arm/include/asm/hardware/cache-uniphier.h
index eaa60da..0ef42ae 100644
--- a/arch/arm/include/asm/hardware/cache-uniphier.h
+++ b/arch/arm/include/asm/hardware/cache-uniphier.h
@@ -16,7 +16,7 @@
#ifndef __CACHE_UNIPHIER_H
#define __CACHE_UNIPHIER_H
-#include <linux/types.h>
+#include <linux/errno.h>
#ifdef CONFIG_CACHE_UNIPHIER
int uniphier_cache_init(void);
--
1.9.1
^ permalink raw reply related
* [PATCH v2 1/6] pinctrl-aspeed-g5: Never set SCU90[6]
From: Joel Stanley @ 2016-11-03 22:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478097481-14895-2-git-send-email-andrew@aj.id.au>
On Thu, Nov 3, 2016 at 1:07 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> If a pin depending on bit 6 in SCU90 is requested for GPIO, the export
> will succeed but changes to the GPIO's value will not be accepted by the
> hardware. This is because the pinmux driver has misconfigured the SCU by
> writing 1 to the reserved bit.
>
> The description of SCU90[6] from the datasheet is 'Reserved, must keep
> at value ?0?'. The fix is to switch pinmux from the bit-flipping macro
> to explicitly configuring the .enable and .disable values to zero.
>
> The patch has been tested on an AST2500 EVB.
>
> Fixes: 56e57cb6c07f (pinctrl: Add pinctrl-aspeed-g5 driver)
> Reported-by: Uma Yadlapati <yadlapat@us.ibm.com>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Reviewed-by: Joel Stanley <joel@jms.id.au>
And tested-by.
> This patch should be applied for 4.9.
In the future I think we should send fixes separately from the rest of
the series, so it's clear to Linus where we expect patches to end up.
Perhaps Linus can share his preference with us?
Cheers,
Joel
> drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> index c8c72e8259d3..87b46390b695 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> @@ -26,7 +26,7 @@
>
> #define ASPEED_G5_NR_PINS 228
>
> -#define COND1 SIG_DESC_BIT(SCU90, 6, 0)
> +#define COND1 { SCU90, BIT(6), 0, 0 }
> #define COND2 { SCU94, GENMASK(1, 0), 0, 0 }
>
> #define B14 0
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH v2 3/6] mfd: dt: Add bindings for the Aspeed LPC Host Controller (LPCHC)
From: Joel Stanley @ 2016-11-03 23:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478097481-14895-4-git-send-email-andrew@aj.id.au>
On Thu, Nov 3, 2016 at 1:07 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> The Aspeed LPC Host Controller is presented as a syscon device to
> arbitrate access by LPC and pinmux drivers. LPC pinmux configuration on
> fifth generation SoCs depends on bits in both the System Control Unit
> and the LPC Host Controller.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
> ---
> Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt b/Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt
> new file mode 100644
> index 000000000000..792651488c3d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/aspeed-lpchc.txt
> @@ -0,0 +1,17 @@
> +* Device tree bindings for the Aspeed LPC Host Controller (LPCHC)
I had to check the data sheet for that acronym. They call the
registers LHC. I somewhat prefer that name, but if you're happy with
it as-is then that's fine.
I assume this is not an issue on the g4/ast2400?
> +
> +The LPCHC registers configure LPC behaviour between the BMC and the host
> +system. The LPCHC also participates in pinmux requests on g5 SoCs and is
> +therefore considered a syscon device.
> +
> +Required properties:
> +- compatible: "aspeed,ast2500-lpchc", "syscon"
> +- reg: contains offset/length value of the LPCHC memory
> + region.
> +
> +Example:
> +
> +lpchc: lpchc at 1e7890a0 {
> + compatible = "aspeed,ast2500-lpchc", "syscon";
> + reg = <0x1e7890a0 0xc4>;
Where's the 0xc4 come from? I can see 9 registers, which would mean
the length should be 0x24?
Cheers,
Joel
^ permalink raw reply
* [PATCH v2 4/6] pinctrl: aspeed: Read and write bits in LPCHC and GFX controllers
From: Joel Stanley @ 2016-11-03 23:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478097481-14895-5-git-send-email-andrew@aj.id.au>
On Thu, Nov 3, 2016 at 1:07 AM, Andrew Jeffery <andrew@aj.id.au> wrote:
> The System Control Unit IP block in the Aspeed SoCs is typically where
> the pinmux configuration is found, but not always. A number of pins
> depend on state in one of LPC Host Control (LPCHC) or SoC Display
> Controller (GFX) IP blocks, so the Aspeed pinmux drivers should have the
> means to adjust these as necessary.
>
> We use syscon to cast a regmap over the GFX and LPCHCR blocks, which is
> used as an arbitration layer between the relevant driver and the pinctrl
> subsystem. The regmaps are then exposed to the SoC-specific pinctrl
> drivers by phandles in the devicetree, and are selected during a mux
> request by querying a new 'ip' member in struct aspeed_sig_desc.
>
> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
I like this a lot more than the first go. Good work.
Some minor comments below.
> ---
> Since v1:
>
> The change is now proactive: instead of reporting that we need to flip bits in
> controllers we can't access, the patch provides access via regmaps for the
> relevant controllers. The implementation also splits out the IP block ID into
> its own variable rather than packing the value into the upper bits of the reg
> member of struct aspeed_sig_desc. This drives some churn in the diff, but I've
> tried to minimise it.
>
> .../devicetree/bindings/pinctrl/pinctrl-aspeed.txt | 50 +++++++++++++---
> drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c | 18 +++---
> drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 39 ++++++++++---
> drivers/pinctrl/aspeed/pinctrl-aspeed.c | 66 +++++++++++++---------
> drivers/pinctrl/aspeed/pinctrl-aspeed.h | 32 ++++++++---
> 5 files changed, 144 insertions(+), 61 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> index 2ad18c4ea55c..115b0cce6c1c 100644
> --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt
> @@ -4,12 +4,19 @@ Aspeed Pin Controllers
> The Aspeed SoCs vary in functionality inside a generation but have a common mux
> device register layout.
>
> -Required properties:
> -- compatible : Should be any one of the following:
> - "aspeed,ast2400-pinctrl"
> - "aspeed,g4-pinctrl"
> - "aspeed,ast2500-pinctrl"
> - "aspeed,g5-pinctrl"
> +Required properties for g4:
> +- compatible : Should be any one of the following:
> + "aspeed,ast2400-pinctrl"
> + "aspeed,g4-pinctrl"
> +
> +Required properties for g5:
> +- compatible : Should be any one of the following:
> + "aspeed,ast2500-pinctrl"
> + "aspeed,g5-pinctrl"
> +
> +- aspeed,external-nodes: A cell of phandles to external controller nodes:
> + 0: compatible with "aspeed,ast2500-gfx", "syscon"
> + 1: compatible with "aspeed,ast2500-lpchc", "syscon"
>
> The pin controller node should be a child of a syscon node with the required
> property:
> @@ -47,7 +54,7 @@ RGMII1 RGMII2 RMII1 RMII2 SD1 SPI1 SPI1DEBUG SPI1PASSTHRU TIMER4 TIMER5 TIMER6
> TIMER7 TIMER8 VGABIOSROM
>
>
> -Examples:
> +g4 Example:
>
> syscon: scu at 1e6e2000 {
> compatible = "syscon", "simple-mfd";
> @@ -63,5 +70,34 @@ syscon: scu at 1e6e2000 {
> };
> };
>
> +g5 Example:
> +
> +apb {
> + gfx: display at 1e6e6000 {
> + compatible = "aspeed,ast2500-gfx", "syscon";
> + reg = <0x1e6e6000 0x1000>;
> + };
> +
> + lpchc: lpchc at 1e7890a0 {
> + compatible = "aspeed,ast2500-lpchc", "syscon";
> + reg = <0x1e7890a0 0xc4>;
> + };
> +
> + syscon: scu at 1e6e2000 {
> + compatible = "syscon", "simple-mfd";
> + reg = <0x1e6e2000 0x1a8>;
> +
> + pinctrl: pinctrl {
> + compatible = "aspeed,g5-pinctrl";
> + aspeed,external-nodes = <&gfx, &lpchc>;
> +
> + pinctrl_i2c3_default: i2c3_default {
> + function = "I2C3";
> + groups = "I2C3";
> + };
> + };
> + };
> +};
> +
> Please refer to pinctrl-bindings.txt in this directory for details of the
> common pinctrl bindings used by client devices.
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> index a21b071ff290..558bd102416c 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c
> @@ -292,7 +292,7 @@ SSSF_PIN_DECL(U18, GPIOG7, FLWP, SIG_DESC_SET(SCU84, 7));
> #define UART6_DESC SIG_DESC_SET(SCU90, 7)
> #define ROM16_DESC SIG_DESC_SET(SCU90, 6)
> #define FLASH_WIDE SIG_DESC_SET(HW_STRAP1, 4)
> -#define BOOT_SRC_NOR { HW_STRAP1, GENMASK(1, 0), 0, 0 }
> +#define BOOT_SRC_NOR { ASPEED_IP_SCU, HW_STRAP1, GENMASK(1, 0), 0, 0 }
>
> #define A8 56
> SIG_EXPR_DECL(ROMD8, ROM16, ROM16_DESC);
> @@ -418,9 +418,9 @@ FUNC_GROUP_DECL(I2C8, G5, F3);
> #define U1 88
> SSSF_PIN_DECL(U1, GPIOL0, NCTS1, SIG_DESC_SET(SCU84, 16));
>
> -#define VPI18_DESC { SCU90, GENMASK(5, 4), 1, 0 }
> -#define VPI24_DESC { SCU90, GENMASK(5, 4), 2, 0 }
> -#define VPI30_DESC { SCU90, GENMASK(5, 4), 3, 0 }
> +#define VPI18_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 1, 0 }
> +#define VPI24_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 2, 0 }
> +#define VPI30_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 3, 0 }
>
> #define T5 89
> #define T5_DESC SIG_DESC_SET(SCU84, 17)
> @@ -641,11 +641,11 @@ SSSF_PIN_DECL(Y22, GPIOR2, ROMCS3, SIG_DESC_SET(SCU88, 26));
> #define U19 139
> SSSF_PIN_DECL(U19, GPIOR3, ROMCS4, SIG_DESC_SET(SCU88, 27));
>
> -#define VPOOFF0_DESC { SCU94, GENMASK(1, 0), 0, 0 }
> -#define VPO12_DESC { SCU94, GENMASK(1, 0), 1, 0 }
> -#define VPO24_DESC { SCU94, GENMASK(1, 0), 2, 0 }
> -#define VPOOFF1_DESC { SCU94, GENMASK(1, 0), 3, 0 }
> -#define VPO_OFF_12 { SCU94, 0x2, 0, 0 }
> +#define VPOOFF0_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 0, 0 }
> +#define VPO12_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 1, 0 }
> +#define VPO24_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 2, 0 }
> +#define VPOOFF1_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 3, 0 }
> +#define VPO_OFF_12 { ASPEED_IP_SCU, SCU94, 0x2, 0, 0 }
> #define VPO_24_OFF SIG_DESC_SET(SCU94, 1)
>
> #define V21 140
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> index 87b46390b695..99c4fa9bf861 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
> @@ -10,6 +10,7 @@
> #include <linux/init.h>
> #include <linux/io.h>
> #include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> #include <linux/mutex.h>
> #include <linux/of.h>
> #include <linux/platform_device.h>
> @@ -26,8 +27,8 @@
>
> #define ASPEED_G5_NR_PINS 228
>
> -#define COND1 { SCU90, BIT(6), 0, 0 }
> -#define COND2 { SCU94, GENMASK(1, 0), 0, 0 }
> +#define COND1 { ASPEED_IP_SCU, SCU90, BIT(6), 0, 0 }
> +#define COND2 { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 0, 0 }
>
> #define B14 0
> SSSF_PIN_DECL(B14, GPIOA0, MAC1LINK, SIG_DESC_SET(SCU80, 0));
> @@ -186,9 +187,12 @@ MS_PIN_DECL(C20, GPIOE1, NDCD3, GPIE0OUT);
>
> FUNC_GROUP_DECL(GPIE0, B20, C20);
>
> -#define SPI1_DESC { HW_STRAP1, GENMASK(13, 12), 1, 0 }
> -#define SPI1DEBUG_DESC { HW_STRAP1, GENMASK(13, 12), 2, 0 }
> -#define SPI1PASSTHRU_DESC { HW_STRAP1, GENMASK(13, 12), 3, 0 }
> +#define SPI1_DESC \
> + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 1, 0 }
> +#define SPI1DEBUG_DESC \
> + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 2, 0 }
> +#define SPI1PASSTHRU_DESC \
> + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 3, 0 }
>
> #define C18 64
> SIG_EXPR_DECL(SYSCS, SPI1DEBUG, COND1, SPI1DEBUG_DESC);
> @@ -325,10 +329,11 @@ SS_PIN_DECL(R1, GPIOK7, SDA8);
>
> FUNC_GROUP_DECL(I2C8, P2, R1);
>
> -#define VPIOFF0_DESC { SCU90, GENMASK(5, 4), 0, 0 }
> -#define VPIOFF1_DESC { SCU90, GENMASK(5, 4), 1, 0 }
> -#define VPI24_DESC { SCU90, GENMASK(5, 4), 2, 0 }
> -#define VPIRSVD_DESC { SCU90, GENMASK(5, 4), 3, 0 }
> +#define VPIOFF0_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 0, 0 }
> +#define VPIOFF1_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 1, 0 }
> +#define VPI24_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 2, 0 }
> +#define VPIRSVD_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 3, 0 }
> +
>
> #define V2 104
> #define V2_DESC SIG_DESC_SET(SCU88, 0)
> @@ -848,10 +853,26 @@ static struct pinctrl_desc aspeed_g5_pinctrl_desc = {
> static int aspeed_g5_pinctrl_probe(struct platform_device *pdev)
> {
> int i;
> + struct regmap **map;
> + struct device_node *node;
>
> for (i = 0; i < ARRAY_SIZE(aspeed_g5_pins); i++)
> aspeed_g5_pins[i].number = i;
>
> + map = &aspeed_g5_pinctrl_data.maps[ASPEED_IP_GFX];
> + node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 0);
> + *map = syscon_node_to_regmap(node);
I think you can use syscon_regmap_lookup_by_phandle to replace both of
these lines.
> + of_node_put(node);
> + if (IS_ERR(*map))
> + return PTR_ERR(*map);
Do we want to fail, or warn and continue?
The sequence is a bit messy. How about:
struct regmap *map;
map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
"aspeed,external-nodes");
if (IS_ERR(map))
return PTR_ERR(map);
aspeed_g5_pinctrl_data.maps[ASPEED_IP_GFX] = map;
> +
> + map = &aspeed_g5_pinctrl_data.maps[ASPEED_IP_LPCHC];
> + node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 1);
> + *map = syscon_node_to_regmap(node);
> + of_node_put(node);
> + if (IS_ERR(*map))
> + return PTR_ERR(*map);
> +
Same comments as above.
> return aspeed_pinctrl_probe(pdev, &aspeed_g5_pinctrl_desc,
> &aspeed_g5_pinctrl_data);
> }
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> index 49aeba912531..23586aac7a5a 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
> @@ -14,6 +14,12 @@
> #include "../core.h"
> #include "pinctrl-aspeed.h"
>
> +static const char *const aspeed_pinmux_ips[] = {
> + [ASPEED_IP_SCU] = "SCU",
> + [ASPEED_IP_GFX] = "GFX",
> + [ASPEED_IP_LPCHC] = "LHCR",
We've got both LPCHC and LHCR here. As I said when commenting on the
regmap bindings, I like LHC(R) better.
> +};
> +
> int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
> {
> struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
> @@ -78,7 +84,8 @@ int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
> static inline void aspeed_sig_desc_print_val(
> const struct aspeed_sig_desc *desc, bool enable, u32 rv)
What's a rv? Perhaps "reg" or "value"?
> {
> - pr_debug("SCU%x[0x%08x]=0x%x, got 0x%x from 0x%08x\n", desc->reg,
> + pr_debug("Want %s%X[0x%08X]=0x%X, got 0x%X from 0x%08X\n",
> + aspeed_pinmux_ips[desc->ip], desc->reg,
> desc->mask, enable ? desc->enable : desc->disable,
> (rv & desc->mask) >> __ffs(desc->mask), rv);
> }
> @@ -88,7 +95,7 @@ static inline void aspeed_sig_desc_print_val(
> *
> * @desc: The signal descriptor of interest
> * @enabled: True to query the enabled state, false to query disabled state
> - * @regmap: The SCU regmap instance
> + * @regmap: The IP block's regmap instance
> *
> * @return True if the descriptor's bitfield is configured to the state
> * selected by @enabled, false otherwise
> @@ -119,7 +126,7 @@ static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
> *
> * @expr: An expression controlling the signal for a mux function on a pin
> * @enabled: True to query the enabled state, false to query disabled state
> - * @regmap: The SCU regmap instance
> + * @maps: The list of regmap instances
> *
> * @return True if the expression composed by @enabled evaluates true, false
> * otherwise
> @@ -136,15 +143,16 @@ static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
> * either condition as required.
> */
> static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr,
> - bool enabled, struct regmap *map)
> + bool enabled, struct regmap * const *maps)
> {
> int i;
>
> for (i = 0; i < expr->ndescs; i++) {
> const struct aspeed_sig_desc *desc = &expr->descs[i];
>
> - if (!aspeed_sig_desc_eval(desc, enabled, map))
> + if (!aspeed_sig_desc_eval(desc, enabled, maps[desc->ip]))
> return false;
> +
> }
>
> return true;
> @@ -158,12 +166,12 @@ static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr,
> * configured
> * @enable: true to enable an function's signal through a pin's signal
> * expression, false to disable the function's signal
> - * @map: The SCU's regmap instance for pinmux register access.
> + * @maps: The list of regmap instances for pinmux register access.
> *
> * @return true if the expression is configured as requested, false otherwise
> */
> static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> - bool enable, struct regmap *map)
> + bool enable, struct regmap * const *maps)
> {
> int i;
>
> @@ -171,6 +179,7 @@ static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> bool ret;
> const struct aspeed_sig_desc *desc = &expr->descs[i];
> u32 pattern = enable ? desc->enable : desc->disable;
> + u32 val = (pattern << __ffs(desc->mask));
>
> /*
> * Strap registers are configured in hardware or by early-boot
> @@ -179,48 +188,49 @@ static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
> * deconfigured and is the reason we re-evaluate after writing
> * all descriptor bits.
> */
> - if (desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2)
> + if ((desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2) &&
> + desc->ip == ASPEED_IP_SCU)
> continue;
>
> - ret = regmap_update_bits(map, desc->reg, desc->mask,
> - pattern << __ffs(desc->mask)) == 0;
> + ret = regmap_update_bits(maps[desc->ip], desc->reg,
> + desc->mask, val) == 0;
>
> if (!ret)
> return ret;
> }
>
> - return aspeed_sig_expr_eval(expr, enable, map);
> + return aspeed_sig_expr_eval(expr, enable, maps);
> }
>
> static bool aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr,
> - struct regmap *map)
> + struct regmap * const *maps)
> {
> - if (aspeed_sig_expr_eval(expr, true, map))
> + if (aspeed_sig_expr_eval(expr, true, maps))
> return true;
>
> - return aspeed_sig_expr_set(expr, true, map);
> + return aspeed_sig_expr_set(expr, true, maps);
> }
>
> static bool aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr,
> - struct regmap *map)
> + struct regmap * const *maps)
> {
> - if (!aspeed_sig_expr_eval(expr, true, map))
> + if (!aspeed_sig_expr_eval(expr, true, maps))
> return true;
>
> - return aspeed_sig_expr_set(expr, false, map);
> + return aspeed_sig_expr_set(expr, false, maps);
> }
>
> /**
> * Disable a signal on a pin by disabling all provided signal expressions.
> *
> * @exprs: The list of signal expressions (from a priority level on a pin)
> - * @map: The SCU's regmap instance for pinmux register access.
> + * @maps: The list of regmap instances for pinmux register access.
> *
> * @return true if all expressions in the list are successfully disabled, false
> * otherwise
> */
> static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs,
> - struct regmap *map)
> + struct regmap * const *maps)
> {
> bool disabled = true;
>
> @@ -230,7 +240,7 @@ static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs,
> while (*exprs) {
> bool ret;
>
> - ret = aspeed_sig_expr_disable(*exprs, map);
> + ret = aspeed_sig_expr_disable(*exprs, maps);
> disabled = disabled && ret;
>
> exprs++;
> @@ -343,6 +353,8 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> const struct aspeed_sig_expr **funcs;
> const struct aspeed_sig_expr ***prios;
>
> + pr_debug("Muxing pin %d for %s\n", pin, pfunc->name);
> +
> if (!pdesc)
> return -EINVAL;
>
> @@ -358,7 +370,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> if (expr)
> break;
>
> - if (!aspeed_disable_sig(funcs, pdata->map))
> + if (!aspeed_disable_sig(funcs, pdata->maps))
> return -EPERM;
>
> prios++;
> @@ -377,7 +389,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
> return -ENXIO;
> }
>
> - if (!aspeed_sig_expr_enable(expr, pdata->map))
> + if (!aspeed_sig_expr_enable(expr, pdata->maps))
> return -EPERM;
> }
>
> @@ -432,7 +444,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
> if (aspeed_gpio_in_exprs(funcs))
> break;
>
> - if (!aspeed_disable_sig(funcs, pdata->map))
> + if (!aspeed_disable_sig(funcs, pdata->maps))
> return -EPERM;
>
> prios++;
> @@ -462,7 +474,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
> * If GPIO is not the lowest priority signal type, assume there is only
> * one expression defined to enable the GPIO function
> */
> - if (!aspeed_sig_expr_enable(expr, pdata->map))
> + if (!aspeed_sig_expr_enable(expr, pdata->maps))
> return -EPERM;
>
> return 0;
> @@ -481,10 +493,10 @@ int aspeed_pinctrl_probe(struct platform_device *pdev,
> return -ENODEV;
> }
>
> - pdata->map = syscon_node_to_regmap(parent->of_node);
> - if (IS_ERR(pdata->map)) {
> + pdata->maps[ASPEED_IP_SCU] = syscon_node_to_regmap(parent->of_node);
> + if (IS_ERR(pdata->maps[ASPEED_IP_SCU])) {
> dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
> - return PTR_ERR(pdata->map);
> + return PTR_ERR(pdata->maps[ASPEED_IP_SCU]);
> }
>
> pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
> diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.h b/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> index 3e72ef8c54bf..727728b86c07 100644
> --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.h
> @@ -232,6 +232,11 @@
> * group.
> */
>
> +#define ASPEED_IP_SCU 0
> +#define ASPEED_IP_GFX 1
> +#define ASPEED_IP_LPCHC 2
> +#define ASPEED_NR_PINMUX_IPS 3
> +
> /*
> * The "Multi-function Pins Mapping and Control" table in the SoC datasheet
> * references registers by the device/offset mnemonic. The register macros
> @@ -261,7 +266,9 @@
> * A signal descriptor, which describes the register, bits and the
> * enable/disable values that should be compared or written.
> *
> - * @reg: The register offset from base in bytes
> + * @ip: The IP block identifier, used as an index into the regmap array in
> + * struct aspeed_pinctrl_data
> + * @reg: The register offset with respect to the base address of the IP block
> * @mask: The mask to apply to the register. The lowest set bit of the mask is
> * used to derive the shift value.
> * @enable: The value that enables the function. Value should be in the LSBs,
> @@ -270,6 +277,7 @@
> * LSBs, not at the position of the mask.
> */
> struct aspeed_sig_desc {
> + unsigned int ip;
> unsigned int reg;
> u32 mask;
> u32 enable;
> @@ -313,24 +321,30 @@ struct aspeed_pin_desc {
>
> /* Macro hell */
>
> +#define SIG_DESC_IP_BIT(ip, reg, idx, val) \
> + { ip, reg, BIT_MASK(idx), val, (((val) + 1) & 1) }
> +
> /**
> - * Short-hand macro for describing a configuration enabled by the state of one
> - * bit. The disable value is derived.
> + * Short-hand macro for describing an SCU descriptor enabled by the state of
> + * one bit. The disable value is derived.
> *
> * @reg: The signal's associated register, offset from base
> * @idx: The signal's bit index in the register
> * @val: The value (0 or 1) that enables the function
> */
> #define SIG_DESC_BIT(reg, idx, val) \
> - { reg, BIT_MASK(idx), val, (((val) + 1) & 1) }
> + SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, val)
> +
> +#define SIG_DESC_IP_SET(ip, reg, idx) SIG_DESC_IP_BIT(ip, reg, idx, 1)
>
> /**
> - * A further short-hand macro describing a configuration enabled with a set bit.
> + * A further short-hand macro expanding to an SCU descriptor enabled by a set
> + * bit.
> *
> - * @reg: The configuration's associated register, offset from base
> - * @idx: The configuration's bit index in the register
> + * @reg: The register, offset from base
> + * @idx: The bit index in the register
> */
> -#define SIG_DESC_SET(reg, idx) SIG_DESC_BIT(reg, idx, 1)
> +#define SIG_DESC_SET(reg, idx) SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, 1)
>
> #define SIG_DESC_LIST_SYM(sig, func) sig_descs_ ## sig ## _ ## func
> #define SIG_DESC_LIST_DECL(sig, func, ...) \
> @@ -500,7 +514,7 @@ struct aspeed_pin_desc {
> MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(gpio))
>
> struct aspeed_pinctrl_data {
> - struct regmap *map;
> + struct regmap *maps[ASPEED_NR_PINMUX_IPS];
>
> const struct pinctrl_pin_desc *pins;
> const unsigned int npins;
> --
> 2.7.4
>
^ permalink raw reply
* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Sinan Kaya @ 2016-11-03 23:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103204349.GA4132@bhelgaas-glaptop.roam.corp.google.com>
On 11/3/2016 4:43 PM, Bjorn Helgaas wrote:
> On Thu, Nov 03, 2016 at 12:58:10PM -0400, Sinan Kaya wrote:
>>
>> On 11/3/2016 10:00 AM, Bjorn Helgaas wrote:
>>> On Wed, Nov 02, 2016 at 12:36:16PM -0400, Sinan Kaya wrote:
>>>> Hi Bjorn,
>>>>
>>>> On 11/2/2016 12:08 PM, Bjorn Helgaas wrote:
>>>>> On Tue, Nov 01, 2016 at 07:06:31AM -0600, cov at codeaurora.org wrote:
>>>>>> Hi Bjorn,
>>>>>>
>>>>>> On 2016-10-31 15:48, Bjorn Helgaas wrote:
>>>>>>> On Wed, Sep 21, 2016 at 06:38:05PM -0400, Christopher Covington wrote:
>>>>>>>> The Qualcomm Technologies QDF2432 SoC does not support accesses
>>>>>>>> smaller
>>>>>>>> than 32 bits to the PCI configuration space. Register the appropriate
>>>>>>>> quirk.
>>>>>>>>
>>>>>>>> Signed-off-by: Christopher Covington <cov@codeaurora.org>
>>>>>>>
>>>>>>> Hi Christopher,
>>>>>>>
>>>>>>> Can you rebase this against v4.9-rc1? It no longer applies to my tree.
>>>>>>
>>>>>> I apologize for not being clearer. This patch depends on:
>>>>>>
>>>>>> PCI/ACPI: Extend pci_mcfg_lookup() responsibilities
>>>>>> PCI/ACPI: Check platform-specific ECAM quirks
>>>>>>
>>>>>> These patches from Tomasz Nowicki were previously in your pci/ecam-v6
>>>>>> branch, but that seems to have come and gone. How would you like to
>>>>>> proceed?
>>>>>
>>>>> Oh yes, that's right, I forgot that connection. I'm afraid I kind of
>>>>> dropped the ball on that thread, so I went back and read through it
>>>>> again.
>>>>>
>>>>> I *think* the current state is:
>>>>>
>>>>> - I'm OK with the first two patches that add the quirk
>>>>> infrastructure.
>>>>>
>>>>> - My issue with the last three patches that add ThunderX quirks is
>>>>> that there's no generic description of the ECAM address space.
>>>>>
>>>>> So if I understand correctly, your Qualcomm patch depends only on the
>>>>> first two patches.
>>>>>
>>>>> Then the question is how the Qualcomm ECAM address space is described.
>>>>> Your quirk overrides the default pci_generic_ecam_ops with the
>>>>> &pci_32b_ops, but it doesn't touch the address space part, so I assume
>>>>> the bus ranges and corresponding address space in your MCFG is
>>>>> correct. So far, so good.
>>>>
>>>> Qualcomm ECAM space includes both the root port and the endpoint address
>>>> space with a single contiguous 256 MB address space described in MCFG table.
>>>> There is no need to describe additional resources like PNP0C02.
>>>
>>> This is the crucial point I have failed to communicate clearly: the
>>> PNP0C02 resource is *always* required, even if the MCFG is correct.
>>>
>>
>> Interesting...
>>
>> It looks like there is a lot of lessons learnt here from history.
>>
>> I think this requirement is only true if your system DDR space and PCIe
>> space overlaps in the memory map. I understand that Intel systems allow
>> sharing of these two memory ranges. An OS could potentially reclaim this
>> address range.
>>
>> If there is no overlap and PCI is not enabled, there can't be any SW entity
>> to reclaim this space.
>
> No, this isn't really anything to do with DDR/PCIe overlaps. This is
> just a fundamental part of the ACPI model: the firmware should
> communicate all address space usage to the OS either via ACPI or via
> standard self-describing mechanisms like PCI BARs.
>
> You can argue that this isn't "necessary", but that's an assumption
> based on your knowledge of this particular system, and we don't want
> the OS to have to make that assumption. For example, ACPI allows the
> hot-addition of new ACPI devices, and we may have to assign address
> space for them, and we don't want to collide with existing devices.
Thanks for the description.
>
> Bjorn
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH] clk: sunxi: Fix M factor computation for APB1
From: Stéphan Rafin @ 2016-11-03 23:53 UTC (permalink / raw)
To: linux-arm-kernel
commit cfa636886033 ("clk: sunxi: factors: Consolidate get_factors
parameters into a struct") introduced a regression for m factor
computation in sun4i_get_apb1_factors function.
The old code reassigned the "parent_rate" parameter to the targeted
divisor value and was buggy for the returned frequency but not for the
computed factors. Now, returned frequency is good but m factor is
incorrectly computed (its max value 31 is always set resulting in a
significantly slower frequency than the requested one...)
This patch simply restores the original proper computation for m while
keeping the good changes for returned rate.
Signed-off-by: St?phan Rafin <stephan@soliotek.com>
---
drivers/clk/sunxi/clk-sunxi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 838b22a..f2c9274 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -373,7 +373,7 @@ static void sun4i_get_apb1_factors(struct factors_request *req)
else
calcp = 3;
- calcm = (req->parent_rate >> calcp) - 1;
+ calcm = (div >> calcp) - 1;
req->rate = (req->parent_rate >> calcp) / (calcm + 1);
req->m = calcm;
--
2.6.6
^ permalink raw reply related
* [PATCH v2 0/3] Remove clocks dependency from SCM driver
From: Sarangdhar Joshi @ 2016-11-04 0:10 UTC (permalink / raw)
To: linux-arm-kernel
On earlier chiptsets (APQ8064, MSM8660, MSM8690, MSM8916,
APQ8084, MSM8974) crypto operations of TZ were depends on crypto
clocks controlled by users/clients. However on MSM8996 crypto clocks
control is handled internally in TZ itself. The current series of
patches handle this clock dependency in SCM driver.
Changes since v1:
- Added Rob's Acked-by
- Removed of_device_is_compatible check from probe (Stephen)
- Modified typecast to take care of 32-bit pointer
Sarangdhar Joshi (3):
dt-bindings: firmware: scm: Add MSM8996 DT bindings
firmware: qcom: scm: Remove core, iface and bus clocks dependency
firmware: qcom: scm: Return PTR_ERR when devm_clk_get fails
.../devicetree/bindings/firmware/qcom,scm.txt | 2 +
drivers/firmware/qcom_scm.c | 49 ++++++++++++++++------
2 files changed, 39 insertions(+), 12 deletions(-)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH v2 1/3] dt-bindings: firmware: scm: Add MSM8996 DT bindings
From: Sarangdhar Joshi @ 2016-11-04 0:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478218237-1737-1-git-send-email-spjoshi@codeaurora.org>
Add SCM DT bindings for Qualcomm's MSM8996 platform.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sarangdhar Joshi <spjoshi@codeaurora.org>
---
Documentation/devicetree/bindings/firmware/qcom,scm.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
index 3b4436e..20f26fb 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.txt
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
@@ -10,8 +10,10 @@ Required properties:
* "qcom,scm-apq8064" for APQ8064 platforms
* "qcom,scm-msm8660" for MSM8660 platforms
* "qcom,scm-msm8690" for MSM8690 platforms
+ * "qcom,scm-msm8996" for MSM8996 platforms
* "qcom,scm" for later processors (MSM8916, APQ8084, MSM8974, etc)
- clocks: One to three clocks may be required based on compatible.
+ * No clock required for "qcom,scm-msm8996"
* Only core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660", and "qcom,scm-msm8960"
* Core, iface, and bus clocks required for "qcom,scm"
- clock-names: Must contain "core" for the core clock, "iface" for the interface
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* [PATCH 1/2] arm64: hugetlb: remove the wrong pmd check in find_num_contig()
From: Catalin Marinas @ 2016-11-04 0:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478140059-13829-2-git-send-email-shijie.huang@arm.com>
On Thu, Nov 03, 2016 at 10:27:38AM +0800, Huang Shijie wrote:
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 2e49bd2..4811ef1 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -61,10 +61,6 @@ static int find_num_contig(struct mm_struct *mm, unsigned long addr,
> return 1;
> }
> pmd = pmd_offset(pud, addr);
> - if (!pmd_present(*pmd)) {
> - VM_BUG_ON(!pmd_present(*pmd));
> - return 1;
> - }
> if ((pte_t *)pmd == ptep) {
> *pgsize = PMD_SIZE;
> return CONT_PMDS;
BTW, for the !pud_present() and !pgd_present() cases, shouldn't
find_num_contig() actually return 0? These are more likely real bugs, so
no point in setting the huge pte.
--
Catalin
^ permalink raw reply
* [PATCH] iommu: arm-smmu: Set SMTNMB_TLBEN in ACR to enable caching of bypass entries
From: Nipun Gupta @ 2016-11-04 0:27 UTC (permalink / raw)
To: linux-arm-kernel
The SMTNMB_TLBEN in the Auxiliary Configuration Register (ACR) provides an
option to enable the updation of TLB in case of bypass transactions due to
no stream match in the stream match table. This reduces the latencies of
the subsequent transactions with the same stream-id which bypasses the SMMU.
This provides a significant performance benefit for certain networking
workloads.
With this change substantial performance improvement of ~9% is observed with
DPDK l3fwd application (http://dpdk.org/doc/guides/sample_app_ug/l3_forward.html)
on NXP's LS2088a platform.
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
Changes for v2:
- Incorporated Robin's comments on v1 related to
Setting SMTNMB_TLBEN in ACR only for MMU-500 as ACR is implementation dependent
Code comments and Naming convention
drivers/iommu/arm-smmu.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index ce2a9d4..05901be 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -247,6 +247,7 @@ enum arm_smmu_s2cr_privcfg {
#define ARM_MMU500_ACTLR_CPRE (1 << 1)
#define ARM_MMU500_ACR_CACHE_LOCK (1 << 26)
+#define ARM_MMU500_ACR_SMTNMB_TLBEN (1 << 8)
#define CB_PAR_F (1 << 0)
@@ -1569,16 +1570,22 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
for (i = 0; i < smmu->num_mapping_groups; ++i)
arm_smmu_write_sme(smmu, i);
- /*
- * Before clearing ARM_MMU500_ACTLR_CPRE, need to
- * clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK
- * bit is only present in MMU-500r2 onwards.
- */
- reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
- major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
- if ((smmu->model == ARM_MMU500) && (major >= 2)) {
+ if (smmu->model == ARM_MMU500) {
+ /*
+ * Before clearing ARM_MMU500_ACTLR_CPRE, need to
+ * clear CACHE_LOCK bit of ACR first. And, CACHE_LOCK
+ * bit is only present in MMU-500r2 onwards.
+ */
+ reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID7);
+ major = (reg >> ID7_MAJOR_SHIFT) & ID7_MAJOR_MASK;
reg = readl_relaxed(gr0_base + ARM_SMMU_GR0_sACR);
- reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
+ if (major >= 2)
+ reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
+ /*
+ * Allow unmatched Stream IDs to allocate bypass
+ * TLB entries for reduced latency.
+ */
+ reg |= ARM_MMU500_ACR_SMTNMB_TLBEN;
writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR);
}
--
1.9.1
^ permalink raw reply related
* [PATCH] clk: rockchip: fix some clocks' name to be more standard style
From: jay.xu @ 2016-11-04 0:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <44798035.VNVnDcOLnj@diego>
Hi Heiko and Shawn:
ok, I agree with you, and the root fix seems to fix it in the TRM first.
I'll feedback to TRM makers.
Thanks.
On 2016?11?03? 22:32, Heiko St?bner wrote:
> Am Donnerstag, 3. November 2016, 16:52:48 schrieb Shawn Lin:
>> On 2016/11/2 15:04, Jianqun Xu wrote:
>>> Fix aclk_emmcgrf to aclk_emmc_grf, and fix aclk_emmccore to be
>>> aclk_emmc_core.
>>
>> What is the standard style should be?
>>
>> TRM uses aclk_emmccore but not aclk_emmc_core, so should it be more
>> standrad to keep it as-is?
>
> I tend to agree with Shawn. While it looks like the missing "_" is some sort
> of mistake, we should strive to follow TRM naming, so grepping so it becomes
> easier to look for informations in these things in the TRM.
>
> Same reason for naming our regulators and pinctrl after the names used in
> device schematics, if available.
>
>
> Heiko
>
>
>
^ permalink raw reply
* [PATCH v2 06/14] ASoC: sun4i-codec: Add support for A31 playback through headphone output
From: Chen-Yu Tsai @ 2016-11-04 1:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161103173602.zchyciwj66zdibc7@lukather>
On Fri, Nov 4, 2016 at 1:36 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Thu, Nov 03, 2016 at 03:55:48PM +0800, Chen-Yu Tsai wrote:
>> +/* headphone controls */
>> +static const char * const sun6i_codec_hp_src_enum_text[] = {
>> + "DAC", "Mixer",
>> +};
>> +
>> +static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum,
>> + SUN6I_CODEC_OM_DACA_CTRL,
>> + SUN6I_CODEC_OM_DACA_CTRL_LHPIS,
>> + SUN6I_CODEC_OM_DACA_CTRL_RHPIS,
>> + sun6i_codec_hp_src_enum_text);
>> +
>> +static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
>> + SOC_DAPM_ENUM("Headphone Source Playback Route",
>> + sun6i_codec_hp_src_enum),
>> +};
>
> What is that route exactly? A muxer?
Yup. The following is part of the widgets list later in the code:
+ /* Headphone output path */
+ SND_SOC_DAPM_MUX("Headphone Source Playback Route",
+ SND_SOC_NOPM, 0, 0, sun6i_codec_hp_src),
ChenYu
^ permalink raw reply
* [PATCH 0/2] mm: fix the "counter.sh" failure for libhugetlbfs
From: Huang Shijie @ 2016-11-04 1:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0a660010-5083-476a-b2c5-88d822089000@infradead.org>
On Thu, Nov 03, 2016 at 10:22:39AM -0700, Randy Dunlap wrote:
> On 11/02/16 19:51, Huang Shijie wrote:
> >
> > (2) The bug
> > After I tested the libhugetlbfs, I found the test case "counter.sh"
> > will fail with the gigantic page (32M page in arm64 board).
> >
> > This patch set adds support for gigantic surplus hugetlb pages,
> > allowing the counter.sh unit test to pass.
>
> Hi,
> Where is the counter.sh test? Where can I find it?
You can get the libhugetlbfs from:
https://github.com/libhugetlbfs/libhugetlbfs.git
Use the "make func" to test it, but the default libhugetlbfs can not run
for the 32M page hugetlbfs, there are several bugs in it. I have an
extra patch set to fix the libhugetlbfs bugs. Maybe I can send them out
later.
But for the 2M page size, you can test the "counter.sh" with "make
func".
thanks
Huang Shijie
^ permalink raw reply
* [PATCH 3/6] clk: rockchip: add clock controller for rk1108
From: Shawn Lin @ 2016-11-04 2:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478176713-12066-1-git-send-email-andy.yan@rock-chips.com>
Hi Andy,
On 2016/11/3 20:38, Andy Yan wrote:
> From: Shawn Lin <shawn.lin@rock-chips.com>
>
> Add the clock tree definition and driver for rk1108 SoC.
>
We should spilt out another patch for adding clock/rst ID
as it should be in a shared branch. :)
You could respin it after Heiko reviews the other parts of
your patchset.
> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
> ---
>
> drivers/clk/rockchip/Makefile | 1 +
> drivers/clk/rockchip/clk-rk1108.c | 463 +++++++++++++++++++++++++++++++++
> drivers/clk/rockchip/clk.h | 14 +
> include/dt-bindings/clock/rk1108-cru.h | 308 ++++++++++++++++++++++
> 4 files changed, 786 insertions(+)
> create mode 100644 drivers/clk/rockchip/clk-rk1108.c
> create mode 100644 include/dt-bindings/clock/rk1108-cru.h
>
> diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
> index b5f2c8e..16e098c 100644
> --- a/drivers/clk/rockchip/Makefile
> +++ b/drivers/clk/rockchip/Makefile
> @@ -11,6 +11,7 @@ obj-y += clk-mmc-phase.o
> obj-y += clk-ddr.o
> obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
>
> +obj-y += clk-rk1108.o
> obj-y += clk-rk3036.o
> obj-y += clk-rk3188.o
> obj-y += clk-rk3228.o
> diff --git a/drivers/clk/rockchip/clk-rk1108.c b/drivers/clk/rockchip/clk-rk1108.c
> new file mode 100644
> index 0000000..eafc623
> --- /dev/null
> +++ b/drivers/clk/rockchip/clk-rk1108.c
> @@ -0,0 +1,463 @@
> +/*
> + * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
> + * Author: Shawn Lin <shawn.lin@rock-chips.com>
> + * Andy Yan <andy.yan@rock-chips.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/syscore_ops.h>
> +#include <dt-bindings/clock/rk1108-cru.h>
> +#include "clk.h"
> +
> +#define RK1108_GRF_SOC_STATUS0 0x480
> +
> +enum rk1108_plls {
> + apll, dpll, gpll,
> +};
> +
> +static struct rockchip_pll_rate_table rk1108_pll_rates[] = {
> + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
> + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
> + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
> + RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0),
> + RK3036_PLL_RATE( 594000000, 2, 99, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0),
> + RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0),
> + RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0),
> + RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0),
> + RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
> + RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0),
> + { /* sentinel */ },
> +};
> +
> +
> +#define RK1108_DIV_CORE_MASK 0xf
> +#define RK1108_DIV_CORE_SHIFT 4
> +
> +#define RK1108_CLKSEL0(_core_peri_div) \
> + { \
> + .reg = RK1108_CLKSEL_CON(1), \
> + .val = HIWORD_UPDATE(_core_peri_div, RK1108_DIV_CORE_MASK, \
> + RK1108_DIV_CORE_SHIFT) \
> + }
> +
> +#define RK1108_CPUCLK_RATE(_prate, _core_peri_div) \
> + { \
> + .prate = _prate, \
> + .divs = { \
> + RK1108_CLKSEL0(_core_peri_div), \
> + }, \
> + }
> +
> +static struct rockchip_cpuclk_rate_table rk1108_cpuclk_rates[] __initdata = {
> + RK1108_CPUCLK_RATE(816000000, 4),
> + RK1108_CPUCLK_RATE(600000000, 4),
> + RK1108_CPUCLK_RATE(312000000, 4),
> +};
> +
> +static const struct rockchip_cpuclk_reg_data rk1108_cpuclk_data = {
> + .core_reg = RK1108_CLKSEL_CON(0),
> + .div_core_shift = 0,
> + .div_core_mask = 0x1f,
> + .mux_core_alt = 1,
> + .mux_core_main = 0,
> + .mux_core_shift = 8,
> + .mux_core_mask = 0x1,
> +};
> +
> +PNAME(mux_pll_p) = { "xin24m", "xin24m"};
> +
> +PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr", "apll_ddr" };
> +PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" };
> +PNAME(mux_pmu_1f) = { "xin24m", "pmu_24m"};
> +PNAME(mux_usb480m_phy_p) = { "usb480m_phy0", "usb480m_phy1" };
> +PNAME(mux_usb480m_p) = { "usb480m_phy", "xin24m" };
> +PNAME(mux_hdmiphy_p) = { "hdmiphy_phy", "pclk_top_pre", "xin24m" };
> +
> +PNAME(mux_pll_src_4plls_p) = { "dpll", "hdmiphy", "gpll", "usb480m" };
> +PNAME(mux_pll_src_3plls_p) = { "apll", "gpll", "dpll" };
> +PNAME(mux_pll_src_2plls_p) = { "dpll", "gpll" };
> +
> +PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_dpll", "aclk_peri_src_gpll" };
> +PNAME(mux_aclk_bus_src_p) = { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" };
> +
> +PNAME(mux_mmc_src_p) = { "dpll", "gpll", "xin24m", "usb480m" };
> +PNAME(mux_pll_src_dpll_gpll_usb480m_p) = { "dpll", "gpll", "usb480m" };
> +
> +
> +PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
> +PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
> +PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
> +
> +
> +static struct rockchip_pll_clock rk1108_pll_clks[] __initdata = {
> + [apll] = PLL(pll_rk3399, RK1108_APLL_ID, "apll", mux_pll_p, 0, RK1108_PLL_CON(0),
> + RK1108_PLL_CON(3), 8, 31, 0, rk1108_pll_rates),
> + [dpll] = PLL(pll_rk3399, RK1108_DPLL_ID, "dpll", mux_pll_p, 0, RK1108_PLL_CON(8),
> + RK1108_PLL_CON(11), 8, 31, 0, NULL),
> + [gpll] = PLL(pll_rk3399, RK1108_GPLL_ID, "gpll", mux_pll_p, 0, RK1108_PLL_CON(16),
> + RK1108_PLL_CON(19), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk1108_pll_rates),
> +};
> +
> +#define MFLAGS CLK_MUX_HIWORD_MASK
> +#define DFLAGS CLK_DIVIDER_HIWORD_MASK
> +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
> +
> +
> +static struct rockchip_clk_branch rk1108_uart0_fracmux __initdata =
> + MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
> + RK1108_CLKSEL_CON(13), 8, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk1108_uart1_fracmux __initdata =
> + MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
> + RK1108_CLKSEL_CON(14), 8, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk1108_uart2_fracmux __initdata =
> + MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
> + RK1108_CLKSEL_CON(15), 8, 2, MFLAGS);
> +
> +static struct rockchip_clk_branch rk1108_clk_branches[] __initdata = {
> + /*
> + * Clock-Architecture Diagram 2
> + */
> +
> + /* PD_CORE */
> + GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(0), 1, GFLAGS),
> + GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(0), 0, GFLAGS),
> + GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(0), 2, GFLAGS),
> + COMPOSITE_NOMUX(0, "pclken_dbg", "armclk", CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(1), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
> + RK1108_CLKGATE_CON(0), 5, GFLAGS),
> + COMPOSITE_NOMUX(ACLK_ENMCORE, "aclkenm_core", "armclk", CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(1), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
> + RK1108_CLKGATE_CON(0), 4, GFLAGS),
> + GATE(ACLK_CORE, "aclk_core", "aclkenm_core", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(11), 0, GFLAGS),
> + GATE(0, "pclk_dbg", "pclken_dbg", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(11), 1, GFLAGS),
> +
> + /* PD_RKVENC */
> +
> + /* PD_RKVDEC */
> +
> + /* PD_PMU_wrapper */
> + COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(38), 0, 5, DFLAGS,
> + RK1108_CLKGATE_CON(8), 12, GFLAGS),
> + GATE(0, "pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(10), 0, GFLAGS),
> + GATE(0, "intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(10), 1, GFLAGS),
> + GATE(0, "gpio0_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(10), 2, GFLAGS),
> + GATE(0, "pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(10), 3, GFLAGS),
> + GATE(0, "pmu_noc", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(10), 4, GFLAGS),
> + GATE(0, "i2c0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(10), 5, GFLAGS),
> + GATE(0, "pwm0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(10), 6, GFLAGS),
> + COMPOSITE(0, "pwm0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS,
> + RK1108_CLKGATE_CON(8), 15, GFLAGS),
> + COMPOSITE(0, "i2c0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS,
> + RK1108_CLKGATE_CON(8), 14, GFLAGS),
> + GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(8), 13, GFLAGS),
> +
> +
> +
> + /*
> + * Clock-Architecture Diagram 4
> + */
> + COMPOSITE(0, "aclk_vio0_2wrap_occ", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS,
> + RK1108_CLKGATE_CON(6), 0, GFLAGS),
> + GATE(0, "aclk_vio0_pre", "aclk_vio0_2wrap_occ", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(17), 0, GFLAGS),
> + COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0,
> + RK1108_CLKSEL_CON(29), 0, 5, DFLAGS,
> + RK1108_CLKGATE_CON(7), 2, GFLAGS),
> + COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0,
> + RK1108_CLKSEL_CON(29), 8, 5, DFLAGS,
> + RK1108_CLKGATE_CON(7), 3, GFLAGS),
> +
> +
> + /*
> + * Clock-Architecture Diagram 5
> + */
> +
> + /* PD_BUS */
> + GATE(0, "aclk_bus_src_gpll", "gpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(1), 0, GFLAGS),
> + GATE(0, "aclk_bus_src_apll", "apll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(1), 1, GFLAGS),
> + GATE(0, "aclk_bus_src_dpll", "dpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(1), 2, GFLAGS),
> + COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0,
> + RK1108_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 5, DFLAGS),
> + COMPOSITE_NOMUX(0, "hclk_bus_pre", "aclk_bus_2wrap_occ", 0,
> + RK1108_CLKSEL_CON(3), 0, 5, DFLAGS,
> + RK1108_CLKGATE_CON(1), 4, GFLAGS),
> + COMPOSITE_NOMUX(0, "pclken_bus", "aclk_bus_2wrap_occ", 0,
> + RK1108_CLKSEL_CON(3), 8, 5, DFLAGS,
> + RK1108_CLKGATE_CON(1), 5, GFLAGS),
> + GATE(0, "pclk_bus_pre", "pclken_bus", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(1), 6, GFLAGS),
> + GATE(0, "pclk_top_pre", "pclken_bus", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(1), 7, GFLAGS),
> + GATE(0, "pclk_ddr_pre", "pclken_bus", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(1), 8, GFLAGS),
> + GATE(0, "clk_timer0", "mux_pll_p", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(1), 9, GFLAGS),
> + GATE(0, "clk_timer1", "mux_pll_p", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(1), 10, GFLAGS),
> + GATE(0, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 4, GFLAGS),
> +
> + COMPOSITE(0, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS,
> + RK1108_CLKGATE_CON(3), 1, GFLAGS),
> + COMPOSITE(0, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS,
> + RK1108_CLKGATE_CON(3), 3, GFLAGS),
> + COMPOSITE(0, "uart21_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS,
> + RK1108_CLKGATE_CON(3), 5, GFLAGS),
> +
> + COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
> + RK1108_CLKSEL_CON(16), 0,
> + RK1108_CLKGATE_CON(3), 2, GFLAGS,
> + &rk1108_uart0_fracmux),
> + COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
> + RK1108_CLKSEL_CON(17), 0,
> + RK1108_CLKGATE_CON(3), 4, GFLAGS,
> + &rk1108_uart1_fracmux),
> + COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
> + RK1108_CLKSEL_CON(18), 0,
> + RK1108_CLKGATE_CON(3), 6, GFLAGS,
> + &rk1108_uart2_fracmux),
> + GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 10, GFLAGS),
> + GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 11, GFLAGS),
> + GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 12, GFLAGS),
> +
> +
> + COMPOSITE(0, "clk_i2c1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(19), 15, 2, MFLAGS, 8, 7, DFLAGS,
> + RK1108_CLKGATE_CON(3), 7, GFLAGS),
> + COMPOSITE(0, "clk_i2c2", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(20), 7, 2, MFLAGS, 0, 7, DFLAGS,
> + RK1108_CLKGATE_CON(3), 8, GFLAGS),
> + COMPOSITE(0, "clk_i2c3", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(20), 15, 2, MFLAGS, 8, 7, DFLAGS,
> + RK1108_CLKGATE_CON(3), 9, GFLAGS),
> + GATE(0, "pclk_i2c1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 0, GFLAGS),
> + GATE(0, "pclk_i2c2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 1, GFLAGS),
> + GATE(0, "pclk_i2c3", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 2, GFLAGS),
> + COMPOSITE(0, "clk_pwm1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS,
> + RK1108_CLKGATE_CON(3), 10, GFLAGS),
> + GATE(0, "pclk_pwm1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 6, GFLAGS),
> + GATE(0, "pclk_wdt", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 3, GFLAGS),
> + GATE(0, "pclk_gpio1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 7, GFLAGS),
> + GATE(0, "pclk_gpio2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 8, GFLAGS),
> + GATE(0, "pclk_gpio3", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(13), 9, GFLAGS),
> +
> + GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(14), 0, GFLAGS),
> +
> + GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0,
> + RK1108_CLKGATE_CON(12), 2, GFLAGS),
> + GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(12), 3, GFLAGS),
> + GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(12), 1, GFLAGS),
> +
> + /* PD_DDR */
> + GATE(0, "apll_ddr", "apll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(0), 8, GFLAGS),
> + GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(0), 9, GFLAGS),
> + GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(0), 10, GFLAGS),
> + COMPOSITE(0, "ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
> + RK1108_CLKGATE_CON(10), 9, GFLAGS),
> + GATE(0, "ddrupctl", "ddrphy_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(12), 4, GFLAGS),
> + GATE(0, "ddrc", "ddrphy", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(12), 5, GFLAGS),
> + GATE(0, "ddrmon", "ddrphy_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(12), 6, GFLAGS),
> + GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(0), 11, GFLAGS),
> +
> + /*
> + * Clock-Architecture Diagram 6
> + */
> +
> + /* PD_PERI */
> + COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0,
> + RK1108_CLKSEL_CON(23), 10, 5, DFLAGS,
> + RK1108_CLKGATE_CON(4), 5, GFLAGS),
> + GATE(0, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(15), 13, GFLAGS),
> + COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0,
> + RK1108_CLKSEL_CON(23), 5, 5, DFLAGS,
> + RK1108_CLKGATE_CON(4), 4, GFLAGS),
> + GATE(0, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(15), 12, GFLAGS),
> +
> + GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(4), 1, GFLAGS),
> + GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED,
> + RK1108_CLKGATE_CON(4), 2, GFLAGS),
> + COMPOSITE(0, "aclk_periph", mux_aclk_peri_src_p, CLK_IGNORE_UNUSED,
> + RK1108_CLKSEL_CON(23), 15, 2, MFLAGS, 0, 5, DFLAGS,
> + RK1108_CLKGATE_CON(15), 11, GFLAGS),
> +
> + COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0,
> + RK1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS,
> + RK1108_CLKGATE_CON(5), 0, GFLAGS),
> +
> + COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
> + RK1108_CLKSEL_CON(25), 10, 2, MFLAGS,
> + RK1108_CLKGATE_CON(5), 2, GFLAGS),
> + DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
> + RK1108_CLKSEL_CON(26), 0, 8, DFLAGS),
> +
> + COMPOSITE_NODIV(0, "sclk_emmc_src", mux_mmc_src_p, 0,
> + RK1108_CLKSEL_CON(25), 12, 2, MFLAGS,
> + RK1108_CLKGATE_CON(5), 1, GFLAGS),
> + DIV(SCLK_EMMC, "sclk_emmc", "sclk_emmc_src", 0,
> + RK2928_CLKSEL_CON(26), 8, 8, DFLAGS),
> + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 0, GFLAGS),
> + GATE(HCLK_SDIO, "hclk_sdio", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 1, GFLAGS),
> + GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 2, GFLAGS),
> +
> + COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0,
> + RK1108_CLKSEL_CON(27), 14, 2, MFLAGS, 8, 5, DFLAGS,
> + RK1108_CLKGATE_CON(5), 3, GFLAGS),
> + GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 3, GFLAGS),
> +
> + COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_2plls_p, 0,
> + RK1108_CLKSEL_CON(27), 7, 2, MFLAGS, 0, 7, DFLAGS,
> + RK1108_CLKGATE_CON(5), 4, GFLAGS),
> + GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 10, GFLAGS),
> + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK1108_SDMMC_CON0, 1),
> + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK1108_SDMMC_CON1, 1),
> +
> + MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK1108_SDIO_CON0, 1),
> + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK1108_SDIO_CON1, 1),
> +
> + MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK1108_EMMC_CON0, 1),
> + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK1108_EMMC_CON1, 1),
> +};
> +
> +static const char *const rk1108_critical_clocks[] __initconst = {
> + "aclk_core",
> + "aclk_bus_src_gpll",
> + "aclk_periph",
> + "hclk_periph",
> + "pclk_periph",
> +};
> +
> +static void __init rk1108_clk_init(struct device_node *np)
> +{
> + struct rockchip_clk_provider *ctx;
> + void __iomem *reg_base;
> +
> + reg_base = of_iomap(np, 0);
> + if (!reg_base) {
> + pr_err("%s: could not map cru region\n", __func__);
> + return;
> + }
> +
> + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
> + if (IS_ERR(ctx)) {
> + pr_err("%s: rockchip clk init failed\n", __func__);
> + iounmap(reg_base);
> + return;
> + }
> +
> + rockchip_clk_register_plls(ctx, rk1108_pll_clks,
> + ARRAY_SIZE(rk1108_pll_clks),
> + RK1108_GRF_SOC_STATUS0);
> + rockchip_clk_register_branches(ctx, rk1108_clk_branches,
> + ARRAY_SIZE(rk1108_clk_branches));
> + rockchip_clk_protect_critical(rk1108_critical_clocks,
> + ARRAY_SIZE(rk1108_critical_clocks));
> +
> + rockchip_clk_register_armclk(ctx, RK1108_ARMCLK, "armclk",
> + mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
> + &rk1108_cpuclk_data, rk1108_cpuclk_rates,
> + ARRAY_SIZE(rk1108_cpuclk_rates));
> +
> + rockchip_register_softrst(np, 13, reg_base + RK1108_SOFTRST_CON(0),
> + ROCKCHIP_SOFTRST_HIWORD_MASK);
> +
> + rockchip_register_restart_notifier(ctx, RK1108_GLB_SRST_FST, NULL);
> +
> + rockchip_clk_of_add_provider(np, ctx);
> +}
> +CLK_OF_DECLARE(rk1108_cru, "rockchip,rk1108-cru", rk1108_clk_init);
> diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
> index 1653edd..90c580a 100644
> --- a/drivers/clk/rockchip/clk.h
> +++ b/drivers/clk/rockchip/clk.h
> @@ -34,6 +34,20 @@ struct clk;
> #define HIWORD_UPDATE(val, mask, shift) \
> ((val) << (shift) | (mask) << ((shift) + 16))
>
> +/* register positions shared by RK1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
> +#define RK1108_PLL_CON(x) ((x) * 0x4)
> +#define RK1108_CLKSEL_CON(x) ((x) * 0x4 + 0x60)
> +#define RK1108_CLKGATE_CON(x) ((x) * 0x4 + 0x120)
> +#define RK1108_SOFTRST_CON(x) ((x) * 0x4 + 0x180)
> +#define RK1108_GLB_SRST_FST 0x1c0
> +#define RK1108_GLB_SRST_SND 0x1c4
> +#define RK1108_SDMMC_CON0 0x1d8
> +#define RK1108_SDMMC_CON1 0x1dc
> +#define RK1108_SDIO_CON0 0x1e0
> +#define RK1108_SDIO_CON1 0x1e4
> +#define RK1108_EMMC_CON0 0x1e8
> +#define RK1108_EMMC_CON1 0x1ec
> +
> #define RK2928_PLL_CON(x) ((x) * 0x4)
> #define RK2928_MODE_CON 0x40
> #define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44)
> diff --git a/include/dt-bindings/clock/rk1108-cru.h b/include/dt-bindings/clock/rk1108-cru.h
> new file mode 100644
> index 0000000..e731cc8
> --- /dev/null
> +++ b/include/dt-bindings/clock/rk1108-cru.h
> @@ -0,0 +1,308 @@
> +/*
> + * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
> + * Author:
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H
> +#define _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H
> +
> +/* pll id */
> +#define RK1108_APLL_ID 0
> +#define RK1108_DPLL_ID 1
> +#define RK1108_GPLL_ID 2
> +#define RK1108_ARMCLK 3
> +#define RK1108_END_PLL_ID 4
> +
> +/* sclk gates (special clocks) */
> +#define SCLK_SPI0 65
> +#define SCLK_NANDC 67
> +#define SCLK_SDMMC 68
> +#define SCLK_SDIO 69
> +#define SCLK_EMMC 71
> +#define SCLK_UART0 72
> +#define SCLK_UART1 73
> +#define SCLK_UART2 74
> +#define SCLK_I2S0 75
> +#define SCLK_I2S1 76
> +#define SCLK_I2S2 77
> +#define SCLK_TIMER0 78
> +#define SCLK_TIMER1 79
> +#define SCLK_SFC 80
> +#define SCLK_SDMMC_DRV 81
> +#define SCLK_SDIO_DRV 82
> +#define SCLK_EMMC_DRV 83
> +#define SCLK_SDMMC_SAMPLE 84
> +#define SCLK_SDIO_SAMPLE 85
> +#define SCLK_EMMC_SAMPLE 86
> +
> +/* aclk gates */
> +#define ACLK_DMAC 251
> +#define ACLK_PRE 252
> +#define ACLK_CORE 253
> +#define ACLK_ENMCORE 254
> +
> +/* pclk gates */
> +#define PCLK_GPIO1 321
> +#define PCLK_GPIO2 322
> +#define PCLK_GPIO3 323
> +#define PCLK_GRF 329
> +#define PCLK_I2C1 333
> +#define PCLK_I2C2 334
> +#define PCLK_I2C3 335
> +#define PCLK_SPI 338
> +#define PCLK_SFC 339
> +#define PCLK_UART0 341
> +#define PCLK_UART1 342
> +#define PCLK_UART2 343
> +#define PCLK_TSADC 344
> +#define PCLK_PWM 350
> +#define PCLK_TIMER 353
> +#define PCLK_PERI 363
> +
> +/* hclk gates */
> +#define HCLK_I2S0_8CH 442
> +#define HCLK_I2S1_8CH 443
> +#define HCLK_I2S2_2CH 444
> +#define HCLK_NANDC 453
> +#define HCLK_SDMMC 456
> +#define HCLK_SDIO 457
> +#define HCLK_EMMC 459
> +#define HCLK_PERI 478
> +#define HCLK_SFC 479
> +
> +#define CLK_NR_CLKS (HCLK_SFC + 1)
> +
> +/* reset id */
> +#define SRST_CORE_PO_AD 0
> +#define SRST_CORE_AD 1
> +#define SRST_L2_AD 2
> +#define SRST_CPU_NIU_AD 3
> +#define SRST_CORE_PO 4
> +#define SRST_CORE 5
> +#define SRST_L2 6
> +#define RST_0RES7 7
> +#define SRST_CORE_DBG 8
> +#define PRST_DBG 9
> +#define RST_DAP 10
> +#define PRST_DBG_NIU 11
> +#define RST_0RES12 12
> +#define RST_0RES13 13
> +#define RST_0RES14 14
> +#define ARST_STRC_SYS_AD 15
> +
> +#define SRST_DDRPHY_CLKDIV 16
> +#define SRST_DDRPHY 17
> +#define PRST_DDRPHY 18
> +#define PRST_HDMIPHY 19
> +#define PRST_VDACPHY 20
> +#define PRST_VADCPHY 21
> +#define PRST_MIPI_CSI_PHY 22
> +#define PRST_MIPI_DSI_PHY 23
> +#define PRST_ACODEC 24
> +#define ARST_BUS_NIU 25
> +#define PRST_TOP_NIU 26
> +#define ARST_INTMEM 27
> +#define HRST_ROM 28
> +#define ARST_DMAC 29
> +#define SRST_MSCH_NIU 30
> +#define PRST_MSCH_NIU 31
> +
> +#define PRST_DDRUPCTL 32
> +#define NRST_DDRUPCTL 33
> +#define PRST_DDRMON 34
> +#define HRST_I2S0_8CH 35
> +#define MRST_I2S0_8CH 36
> +#define HRST_I2S1_2CH 37
> +#define MRST_IS21_2CH 38
> +#define HRST_I2S2_2CH 39
> +#define MRST_I2S2_2CH 40
> +#define HRST_CRYPTO 41
> +#define SRST_CRYPTO 42
> +#define PRST_SPI 43
> +#define SRST_SPI 44
> +#define PRST_UART0 45
> +#define PRST_UART1 46
> +#define PRST_UART2 47
> +
> +#define SRST_UART0 48
> +#define SRST_UART1 49
> +#define SRST_UART2 50
> +#define PRST_I2C1 51
> +#define PRST_I2C2 52
> +#define PRST_I2C3 53
> +#define SRST_I2C1 54
> +#define SRST_I2C2 55
> +#define SRST_I2C3 56
> +#define RST_3RES9 57
> +#define PRST_PWM1 58
> +#define RST_3RES11 59
> +#define SRST_PWM1 60
> +#define PRST_WDT 61
> +#define PRST_GPIO1 62
> +#define PRST_GPIO2 63
> +
> +#define PRST_GPIO3 64
> +#define PRST_GRF 65
> +#define PRST_EFUSE 66
> +#define PRST_EFUSE512 67
> +#define PRST_TIMER0 68
> +#define SRST_TIMER0 69
> +#define SRST_TIMER1 70
> +#define PRST_TSADC 71
> +#define SRST_TSADC 72
> +#define PRST_SARADC 73
> +#define SRST_SARADC 74
> +#define HRST_SYSBUS 75
> +#define PRST_USBGRF 76
> +#define RST_4RES13 77
> +#define RST_4RES14 78
> +#define RST_4RES15 79
> +
> +#define ARST_PERIPH_NIU 80
> +#define HRST_PERIPH_NIU 81
> +#define PRST_PERIPH_NIU 82
> +#define HRST_PERIPH 83
> +#define HRST_SDMMC 84
> +#define HRST_SDIO 85
> +#define HRST_EMMC 86
> +#define HRST_NANDC 87
> +#define NRST_NANDC 88
> +#define HRST_SFC 89
> +#define SRST_SFC 90
> +#define ARST_GMAC 91
> +#define HRST_OTG 92
> +#define SRST_OTG 93
> +#define SRST_OTG_ADP 94
> +#define HRST_HOST0 95
> +
> +#define HRST_HOST0_AUX 96
> +#define HRST_HOST0_ARB 97
> +#define SRST_HOST0_EHCIPHY 98
> +#define SRST_HOST0_UTMI 99
> +#define SRST_USBPOR 100
> +#define SRST_UTMI0 101
> +#define SRST_UTMI1 102
> +#define RST_6RES7 103
> +#define RST_6RES8 104
> +#define RST_6RES9 105
> +#define RST_6RES10 106
> +#define RST_6RES11 107
> +#define RST_6RES12 108
> +#define RST_6RES13 109
> +#define RST_6RES14 110
> +#define RST_6RES15 101
> +
> +#define ARST_VIO0_NIU 102
> +#define ARST_VIO1_NIU 103
> +#define HRST_VIO_NIU 104
> +#define PRST_VIO_NIU 105
> +#define ARST_VOP 106
> +#define HRST_VOP 107
> +#define DRST_VOP 108
> +#define ARST_IEP 109
> +#define HRST_IEP 110
> +#define ARST_RGA 111
> +#define HRST_RGA 112
> +#define SRST_RGA 113
> +#define PRST_CVBS 114
> +#define PRST_HDMI 115
> +#define SRST_HDMI 116
> +#define PRST_MIPI_DSI 117
> +
> +#define ARST_ISP_NIU 118
> +#define HRST_ISP_NIU 119
> +#define HRST_ISP 120
> +#define SRST_ISP 121
> +#define ARST_VIP0 122
> +#define HRST_VIP0 123
> +#define PRST_VIP0 124
> +#define ARST_VIP1 125
> +#define HRST_VIP1 126
> +#define PRST_VIP1 127
> +#define ARST_VIP2 128
> +#define HRST_VIP2 129
> +#define PRST_VIP2 120
> +#define ARST_VIP3 121
> +#define HRST_VIP3 122
> +#define PRST_VIP4 123
> +
> +#define PRST_CIF1TO4 124
> +#define SRST_CVBS_CLK 125
> +#define HRST_CVBS 126
> +#define RST_9RES3 127
> +#define RST_9RES4 128
> +#define RST_9RES5 129
> +#define RST_9RES6 130
> +#define RST_9RES7 131
> +#define RST_9RES8 132
> +#define RST_9RES9 133
> +#define RST_9RES10 134
> +#define RST_9RES11 134
> +#define RST_9RES12 136
> +#define RST_9RES13 137
> +#define RST_9RES14 138
> +#define RST_9RES15 139
> +
> +#define ARST_VPU_NIU 140
> +#define HRST_VPU_NIU 141
> +#define ARST_VPU 142
> +#define HRST_VPU 143
> +#define ARST_RKVDEC_NIU 144
> +#define HRST_RKVDEC_NIU 145
> +#define ARST_RKVDEC 146
> +#define HRST_RKVDEC 147
> +#define SRST_RKVDEC_CABAC 148
> +#define SRST_RKVDEC_CORE 149
> +#define ARST_RKVENC_NIU 150
> +#define HRST_RKVENC_NIU 151
> +#define ARST_RKVENC 152
> +#define HRST_RKVENC 153
> +#define SRST_RKVENC_CORE 154
> +#define RST_10RES15 155
> +
> +#define SRST_DSP_CORE 156
> +#define SRST_DSP_SYS 157
> +#define SRST_DSP_GLOBAL 158
> +#define SRST_DSP_OECM 159
> +#define PRST_DSP_IOP_NIU 160
> +#define ARST_DSP_EPP_NIU 161
> +#define ARST_DSP_EDP_NIU 162
> +#define PRST_DSP_DBG_NIU 163
> +#define PRST_DSP_CFG_NIU 164
> +#define PRST_DSP_GRF 165
> +#define PRST_DSP_MAILBOX 166
> +#define PRST_DSP_INTC 167
> +#define RST_11RES12 168
> +#define PRST_DSP_PFM_MON 169
> +#define SRST_DSP_PFM_MON 170
> +#define ARST_DSP_EDAP_NIU 171
> +
> +#define SRST_PMU 172
> +#define SRST_PMU_I2C0 173
> +#define PRST_PMU_I2C0 174
> +#define PRST_PMU_GPIO0 175
> +#define PRST_PMU_INTMEM 176
> +#define PRST_PMU_PWM0 177
> +#define SRST_PMU_PWM0 178
> +#define PRST_PMU_GRF 179
> +#define SRST_PMU_NIU 180
> +#define SRST_PMU_PVTM 181
> +#define RST_12RES10 182
> +#define RST_12RES11 183
> +#define ARST_DSP_EDP_PERF 184
> +#define ARST_DSP_EPP_PERF 185
> +#define RST_12RES114 186
> +#define RST_12RES15 187
> +
> +#endif /* _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H */
> +
>
--
Best Regards
Shawn Lin
^ permalink raw reply
* [PATCH 1/2] arm64: hugetlb: remove the wrong pmd check in find_num_contig()
From: Huang Shijie @ 2016-11-04 2:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161104001616.ssjbemliorxi6evl@localhost>
On Thu, Nov 03, 2016 at 06:16:16PM -0600, Catalin Marinas wrote:
> On Thu, Nov 03, 2016 at 10:27:38AM +0800, Huang Shijie wrote:
> > diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> > index 2e49bd2..4811ef1 100644
> > --- a/arch/arm64/mm/hugetlbpage.c
> > +++ b/arch/arm64/mm/hugetlbpage.c
> > @@ -61,10 +61,6 @@ static int find_num_contig(struct mm_struct *mm, unsigned long addr,
> > return 1;
> > }
> > pmd = pmd_offset(pud, addr);
> > - if (!pmd_present(*pmd)) {
> > - VM_BUG_ON(!pmd_present(*pmd));
> > - return 1;
> > - }
> > if ((pte_t *)pmd == ptep) {
> > *pgsize = PMD_SIZE;
> > return CONT_PMDS;
>
> BTW, for the !pud_present() and !pgd_present() cases, shouldn't
The kernel will not call the find_num_contig() if the PGD/PUD are empty.
Please see the code in the hugetlb_fault().
------------------------------------------------------
ptep = huge_pte_offset(mm, address);
if (ptep) {
...............................
} else {
ptep = huge_pte_alloc(mm, address, huge_page_size(h));
if (!ptep)
return VM_FAULT_OOM;
}
------------------------------------------------------
Thanks
Huang Shijie
> find_num_contig() actually return 0? These are more likely real bugs, so
> no point in setting the huge pte.
^ permalink raw reply
* [PATCH v27 0/9] arm64: add kdump support
From: AKASHI Takahiro @ 2016-11-04 3:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161102044959.11954-1-takahiro.akashi@linaro.org>
For easier testing, I pushed my patches to:
https://git.linaro.org/people/takahiro.akashi/linux-aarch64.git arm64/kdump
https://git.linaro.org/people/takahiro.akashi/kexec-tools.git arm64/kdump
If anybody tries my patches, please let me know the result.
(Pratyush, thank you for your test.)
Thanks,
-Takahiro AKASHI
On Wed, Nov 02, 2016 at 01:49:59PM +0900, AKASHI Takahiro wrote:
> v27-specific note: In this version, the change made in v26 was reverted
> because I've got a comment that /reserved-memory DT property should
> not be used on UEFI/ACPI systems, even though it is workable under
> the current implementation. I've also confirmed that Rob doesn't argue
> any more against using "linux,usable-memory-range".
> So v27 is essentially the same as v25.
>
> This patch series adds kdump support on arm64.
>
> To load a crash-dump kernel to the systems, a series of patches to
> kexec-tools[1] are also needed. Please use the latest one, v4 [2].
>
> To examine vmcore (/proc/vmcore) on a crash-dump kernel, you can use
> - crash utility (v7.1.6 or later) [3]
>
>
> [1] https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
> [1] http://lists.infradead.org/pipermail/kexec/2016-November/017555.html
> [2] https://github.com/crash-utility/crash.git
>
> Changes for v27 (Nov 2, 2016)
> o rebased to Linux-v4.9-rc3
> o revert v26 change, i.e. revive "linux,usable-memory-range" property
> (patch #2/#3, updating patch #9)
> o minor fixes per review comments (patch #3/#4/#6/#8)
> o re-order patches and improve commit messages for readability
>
> Changes for v26 (Sep 7, 2016):
> o Use /reserved-memory instead of "linux,usable-memory-range" property
> (dropping v25's patch#2 and #3, updating ex-patch#9.)
>
> Changes for v25 (Aug 29, 2016):
> o Rebase to Linux-4.8-rc4
> o Use memremap() instead of ioremap_cache() [patch#5]
>
> Changes for v24 (Aug 9, 2016):
> o Rebase to Linux-4.8-rc1
> o Update descriptions about newly added DT proerties
>
> Changes for v23 (July 26, 2016):
>
> o Move memblock_reserve() to a single place in reserve_crashkernel()
> o Use cpu_park_loop() in ipi_cpu_crash_stop()
> o Always enforce ARCH_LOW_ADDRESS_LIMIT to the memory range of crash kernel
> o Re-implement fdt_enforce_memory_region() to remove non-reserve regions
> (for ACPI) from usable memory at crash kernel
>
> Changes for v22 (July 12, 2016):
>
> o Export "crashkernel-base" and "crashkernel-size" via device-tree,
> and add some descriptions about them in chosen.txt
> o Rename "usable-memory" to "usable-memory-range" to avoid inconsistency
> with powerpc's "usable-memory"
> o Make cosmetic changes regarding "ifdef" usage
> o Correct some wordings in kdump.txt
>
> Changes for v21 (July 6, 2016):
>
> o Remove kexec patches.
> o Rebase to arm64's for-next/core (Linux-4.7-rc4 based).
> o Clarify the description about kvm in kdump.txt.
>
> See the following link [3] for older changes:
> [3] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-June/438780.html
>
> AKASHI Takahiro (8):
> memblock: add memblock_cap_memory_range()
> arm64: limit memory regions based on DT property, usable-memory-range
> arm64: kdump: reserve memory for crash dump kernel
> arm64: kdump: implement machine_crash_shutdown()
> arm64: kdump: add VMCOREINFO's for user-space tools
> arm64: kdump: provide /proc/vmcore file
> arm64: kdump: enable kdump in defconfig
> Documentation: kdump: describe arm64 port
>
> James Morse (1):
> Documentation: dt: chosen properties for arm64 kdump
>
> Documentation/devicetree/bindings/chosen.txt | 50 +++++++
> Documentation/kdump/kdump.txt | 16 ++-
> arch/arm64/Kconfig | 11 ++
> arch/arm64/configs/defconfig | 1 +
> arch/arm64/include/asm/hardirq.h | 2 +-
> arch/arm64/include/asm/kexec.h | 42 +++++-
> arch/arm64/include/asm/smp.h | 2 +
> arch/arm64/kernel/Makefile | 1 +
> arch/arm64/kernel/crash_dump.c | 71 ++++++++++
> arch/arm64/kernel/machine_kexec.c | 67 ++++++++-
> arch/arm64/kernel/setup.c | 7 +-
> arch/arm64/kernel/smp.c | 63 +++++++++
> arch/arm64/mm/init.c | 199 +++++++++++++++++++++++++++
> include/linux/memblock.h | 1 +
> mm/memblock.c | 28 ++++
> 15 files changed, 554 insertions(+), 7 deletions(-)
> create mode 100644 arch/arm64/kernel/crash_dump.c
>
> --
> 2.10.0
>
^ permalink raw reply
* [PATCH] mm: hugetlb: rename some allocation functions
From: Huang Shijie @ 2016-11-04 3:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478141499-13825-2-git-send-email-shijie.huang@arm.com>
After a future patch, the __alloc_buddy_huge_page() will not necessarily
use the buddy allocator.
So this patch removes the "buddy" from these functions:
__alloc_buddy_huge_page -> __alloc_huge_page
__alloc_buddy_huge_page_no_mpol -> __alloc_huge_page_no_mpol
__alloc_buddy_huge_page_with_mpol -> __alloc_huge_page_with_mpol
This patch makes preparation for the later patch.
Acked-by: Steve Capper <steve.capper@arm.com>
Signed-off-by: Huang Shijie <shijie.huang@arm.com>
---
Fix the build error in the x86 platform.
---
mm/hugetlb.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 32594f1..9fdfc24 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1163,6 +1163,10 @@ static inline void destroy_compound_gigantic_page(struct page *page,
unsigned int order) { }
static inline int alloc_fresh_gigantic_page(struct hstate *h,
nodemask_t *nodes_allowed) { return 0; }
+static struct page *alloc_gigantic_page(int nid, unsigned int order)
+{
+ return NULL;
+}
#endif
static void update_and_free_page(struct hstate *h, struct page *page)
@@ -1568,7 +1572,7 @@ static struct page *__hugetlb_alloc_buddy_huge_page(struct hstate *h,
* For (2), we ignore 'vma' and 'addr' and use 'nid' exclusively. This
* implies that memory policies will not be taken in to account.
*/
-static struct page *__alloc_buddy_huge_page(struct hstate *h,
+static struct page *__alloc_huge_page(struct hstate *h,
struct vm_area_struct *vma, unsigned long addr, int nid)
{
struct page *page;
@@ -1649,21 +1653,21 @@ static struct page *__alloc_buddy_huge_page(struct hstate *h,
* anywhere.
*/
static
-struct page *__alloc_buddy_huge_page_no_mpol(struct hstate *h, int nid)
+struct page *__alloc_huge_page_no_mpol(struct hstate *h, int nid)
{
unsigned long addr = -1;
- return __alloc_buddy_huge_page(h, NULL, addr, nid);
+ return __alloc_huge_page(h, NULL, addr, nid);
}
/*
* Use the VMA's mpolicy to allocate a huge page from the buddy.
*/
static
-struct page *__alloc_buddy_huge_page_with_mpol(struct hstate *h,
+struct page *__alloc_huge_page_with_mpol(struct hstate *h,
struct vm_area_struct *vma, unsigned long addr)
{
- return __alloc_buddy_huge_page(h, vma, addr, NUMA_NO_NODE);
+ return __alloc_huge_page(h, vma, addr, NUMA_NO_NODE);
}
/*
@@ -1681,7 +1685,7 @@ struct page *alloc_huge_page_node(struct hstate *h, int nid)
spin_unlock(&hugetlb_lock);
if (!page)
- page = __alloc_buddy_huge_page_no_mpol(h, nid);
+ page = __alloc_huge_page_no_mpol(h, nid);
return page;
}
@@ -1711,7 +1715,7 @@ static int gather_surplus_pages(struct hstate *h, int delta)
retry:
spin_unlock(&hugetlb_lock);
for (i = 0; i < needed; i++) {
- page = __alloc_buddy_huge_page_no_mpol(h, NUMA_NO_NODE);
+ page = __alloc_huge_page_no_mpol(h, NUMA_NO_NODE);
if (!page) {
alloc_ok = false;
break;
@@ -1963,7 +1967,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve, gbl_chg);
if (!page) {
spin_unlock(&hugetlb_lock);
- page = __alloc_buddy_huge_page_with_mpol(h, vma, addr);
+ page = __alloc_huge_page_with_mpol(h, vma, addr);
if (!page)
goto out_uncharge_cgroup;
if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) {
@@ -2221,7 +2225,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
* First take pages out of surplus state. Then make up the
* remaining difference by allocating fresh huge pages.
*
- * We might race with __alloc_buddy_huge_page() here and be unable
+ * We might race with __alloc_huge_page() here and be unable
* to convert a surplus huge page to a normal huge page. That is
* not critical, though, it just means the overall size of the
* pool might be one hugepage larger than it needs to be, but
@@ -2267,7 +2271,7 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
* By placing pages into the surplus state independent of the
* overcommit value, we are allowing the surplus pool size to
* exceed overcommit. There are few sane options here. Since
- * __alloc_buddy_huge_page() is checking the global counter,
+ * __alloc_huge_page() is checking the global counter,
* though, we'll note that we're not allowed to exceed surplus
* and won't grow the pool anywhere else. Not until one of the
* sysctls are changed, or the surplus pages go out of use.
--
2.5.5
^ permalink raw reply related
* [PATCH 0/4] Add SCU device node support for Exynos4
From: Pankaj Dubey @ 2016-11-04 3:39 UTC (permalink / raw)
To: linux-arm-kernel
This patch series does some cleanup for Exynos4 SoC based boards.
We are currently statically mapping SCU SFRs in mach-exynos/exynos.c
which can be avoided and related dependencies can be removed by introduction
of SCU device node.
This patch series is tested on Exynos4210 based Origen board for SMP boot.
Pankaj Dubey (4):
ARM: EXYNOS: Remove smp_init_cpus hook from platsmp.c
ARM: dts: exynos: Add SCU device node to exynos4.dtsi
ARM: EXYNOS: Remove static mapping of SCU SFR
ARM: EXYNOS: Remove unused soc_is_exynos{4,5}
arch/arm/boot/dts/exynos4.dtsi | 5 +++
arch/arm/mach-exynos/common.h | 5 ---
arch/arm/mach-exynos/exynos.c | 22 -------------
arch/arm/mach-exynos/include/mach/map.h | 2 --
arch/arm/mach-exynos/platsmp.c | 49 +++++++---------------------
arch/arm/mach-exynos/pm.c | 14 ++++++--
arch/arm/mach-exynos/suspend.c | 15 ++++++---
arch/arm/plat-samsung/include/plat/map-s5p.h | 4 ---
8 files changed, 38 insertions(+), 78 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH 1/4] ARM: EXYNOS: Remove smp_init_cpus hook from platsmp.c
From: Pankaj Dubey @ 2016-11-04 3:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478230764-13748-1-git-send-email-pankaj.dubey@samsung.com>
We can safely remove exynos_smp_init_cpus() hook from mach-exynos/platsmp.c,
as all SMP platforms in mach-exynos can rely on DT for CPU core description
instead of determining number of cores from the SCU.
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
arch/arm/mach-exynos/platsmp.c | 31 -------------------------------
1 file changed, 31 deletions(-)
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 98ffe1e..a5d6841 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -385,36 +385,6 @@ fail:
return pen_release != -1 ? ret : 0;
}
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-
-static void __init exynos_smp_init_cpus(void)
-{
- void __iomem *scu_base = scu_base_addr();
- unsigned int i, ncores;
-
- if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
- ncores = scu_base ? scu_get_core_count(scu_base) : 1;
- else
- /*
- * CPU Nodes are passed thru DT and set_cpu_possible
- * is set by "arm_dt_init_cpu_maps".
- */
- return;
-
- /* sanity check */
- if (ncores > nr_cpu_ids) {
- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
- ncores, nr_cpu_ids);
- ncores = nr_cpu_ids;
- }
-
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-}
-
static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
{
int i;
@@ -479,7 +449,6 @@ static void exynos_cpu_die(unsigned int cpu)
#endif /* CONFIG_HOTPLUG_CPU */
const struct smp_operations exynos_smp_ops __initconst = {
- .smp_init_cpus = exynos_smp_init_cpus,
.smp_prepare_cpus = exynos_smp_prepare_cpus,
.smp_secondary_init = exynos_secondary_init,
.smp_boot_secondary = exynos_boot_secondary,
--
2.7.4
^ permalink raw reply related
* [PATCH 2/4] ARM: dts: exynos: Add SCU device node to exynos4.dtsi
From: Pankaj Dubey @ 2016-11-04 3:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1478230764-13748-1-git-send-email-pankaj.dubey@samsung.com>
Exynos4 like other Cortex-A9 SoC's has a Snoop Control Unit(SCU)
and its SFR are used during SMP boot and S2R. Add SCU node to the device tree.
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
arch/arm/boot/dts/exynos4.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 5f034eb..6865ca9 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -78,6 +78,11 @@
reg = <0x10000000 0x100>;
};
+ scu: snoop-control-unit at 10500000 {
+ compatible = "arm,cortex-a9-scu";
+ reg = <0x10500000 0x2000>;
+ };
+
memory-controller at 12570000 {
compatible = "samsung,exynos4210-srom";
reg = <0x12570000 0x14>;
--
2.7.4
^ 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