* [PATCH v3 07/13] clocksource/drivers/rockchip_timer: low level routines take rk_timer as parameter
From: Alexander Kochetkov @ 2016-11-29 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-1-git-send-email-al.kochet@gmail.com>
Pass rk_timer instead of clock_event_device to low lever timer routines.
So that code could be reused by clocksource implementation.
This is refactoring step without functional changes.
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
---
drivers/clocksource/rockchip_timer.c | 47 +++++++++++++++++++---------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index 6d68d4c..aa9ccd1 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -63,60 +63,67 @@ static inline void __iomem *rk_ctrl(struct clock_event_device *ce)
return rk_timer(ce)->ctrl;
}
-static inline void rk_timer_disable(struct clock_event_device *ce)
+static inline void rk_timer_disable(struct rk_timer *timer)
{
- writel_relaxed(TIMER_DISABLE, rk_ctrl(ce));
+ writel_relaxed(TIMER_DISABLE, timer->ctrl);
}
-static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags)
+static inline void rk_timer_enable(struct rk_timer *timer, u32 flags)
{
writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags,
- rk_ctrl(ce));
+ timer->ctrl);
}
static void rk_timer_update_counter(unsigned long cycles,
- struct clock_event_device *ce)
+ struct rk_timer *timer)
{
- writel_relaxed(cycles, rk_base(ce) + TIMER_LOAD_COUNT0);
- writel_relaxed(0, rk_base(ce) + TIMER_LOAD_COUNT1);
+ writel_relaxed(cycles, timer->base + TIMER_LOAD_COUNT0);
+ writel_relaxed(0, timer->base + TIMER_LOAD_COUNT1);
}
-static void rk_timer_interrupt_clear(struct clock_event_device *ce)
+static void rk_timer_interrupt_clear(struct rk_timer *timer)
{
- writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS);
+ writel_relaxed(1, timer->base + TIMER_INT_STATUS);
}
static inline int rk_timer_set_next_event(unsigned long cycles,
struct clock_event_device *ce)
{
- rk_timer_disable(ce);
- rk_timer_update_counter(cycles, ce);
- rk_timer_enable(ce, TIMER_MODE_USER_DEFINED_COUNT);
+ struct rk_timer *timer = rk_timer(ce);
+
+ rk_timer_disable(timer);
+ rk_timer_update_counter(cycles, timer);
+ rk_timer_enable(timer, TIMER_MODE_USER_DEFINED_COUNT);
return 0;
}
static int rk_timer_shutdown(struct clock_event_device *ce)
{
- rk_timer_disable(ce);
+ struct rk_timer *timer = rk_timer(ce);
+
+ rk_timer_disable(timer);
return 0;
}
static int rk_timer_set_periodic(struct clock_event_device *ce)
{
- rk_timer_disable(ce);
- rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce);
- rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING);
+ struct rk_timer *timer = rk_timer(ce);
+
+ rk_timer_disable(timer);
+ rk_timer_update_counter(timer->freq / HZ - 1, timer);
+ rk_timer_enable(timer, TIMER_MODE_FREE_RUNNING);
return 0;
}
static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *ce = dev_id;
+ struct rk_timer *timer = rk_timer(ce);
- rk_timer_interrupt_clear(ce);
+ rk_timer_interrupt_clear(timer);
if (clockevent_state_oneshot(ce))
- rk_timer_disable(ce);
+ rk_timer_disable(timer);
ce->event_handler(ce);
@@ -183,8 +190,8 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
ce->cpumask = cpu_possible_mask;
ce->rating = 250;
- rk_timer_interrupt_clear(ce);
- rk_timer_disable(ce);
+ rk_timer_interrupt_clear(timer);
+ rk_timer_disable(timer);
ret = request_irq(irq, rk_timer_interrupt, IRQF_TIMER, TIMER_NAME, ce);
if (ret) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 06/13] clocksource/drivers/rockchip_timer: split bc_timer into rk_timer and rk_clock_event_device
From: Alexander Kochetkov @ 2016-11-29 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-1-git-send-email-al.kochet@gmail.com>
The patch move ce field out of struct bc_timer into struct
rk_clock_event_device and rename struct bc_timer to struct rk_timer.
This is refactoring step without functional changes.
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
---
drivers/clocksource/rockchip_timer.c | 33 ++++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index 23e267a..6d68d4c 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -29,18 +29,28 @@
#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
#define TIMER_INT_UNMASK (1 << 2)
-struct bc_timer {
- struct clock_event_device ce;
+struct rk_timer {
void __iomem *base;
void __iomem *ctrl;
u32 freq;
};
-static struct bc_timer bc_timer;
+struct rk_clock_event_device {
+ struct clock_event_device ce;
+ struct rk_timer timer;
+};
+
+static struct rk_clock_event_device bc_timer;
+
+static inline struct rk_clock_event_device*
+rk_clock_event_device(struct clock_event_device *ce)
+{
+ return container_of(ce, struct rk_clock_event_device, ce);
+}
-static inline struct bc_timer *rk_timer(struct clock_event_device *ce)
+static inline struct rk_timer *rk_timer(struct clock_event_device *ce)
{
- return container_of(ce, struct bc_timer, ce);
+ return &rk_clock_event_device(ce)->timer;
}
static inline void __iomem *rk_base(struct clock_event_device *ce)
@@ -116,16 +126,17 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
{
struct clock_event_device *ce = &bc_timer.ce;
+ struct rk_timer *timer = &bc_timer.timer;
struct clk *timer_clk;
struct clk *pclk;
int ret = -EINVAL, irq;
- bc_timer.base = of_iomap(np, 0);
- if (!bc_timer.base) {
+ timer->base = of_iomap(np, 0);
+ if (!timer->base) {
pr_err("Failed to get base address for '%s'\n", TIMER_NAME);
return -ENXIO;
}
- bc_timer.ctrl = bc_timer.base + ctrl_reg;
+ timer->ctrl = timer->base + ctrl_reg;
pclk = of_clk_get_by_name(np, "pclk");
if (IS_ERR(pclk)) {
@@ -153,7 +164,7 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
goto out_timer_clk;
}
- bc_timer.freq = clk_get_rate(timer_clk);
+ timer->freq = clk_get_rate(timer_clk);
irq = irq_of_parse_and_map(np, 0);
if (!irq) {
@@ -181,7 +192,7 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
goto out_irq;
}
- clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX);
+ clockevents_config_and_register(ce, timer->freq, 1, UINT_MAX);
return 0;
@@ -190,7 +201,7 @@ out_irq:
out_timer_clk:
clk_disable_unprepare(pclk);
out_unmap:
- iounmap(bc_timer.base);
+ iounmap(timer->base);
return ret;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 05/13] ARM: dts: rockchip: disable arm-global-timer for rk3188
From: Alexander Kochetkov @ 2016-11-29 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-1-git-send-email-al.kochet@gmail.com>
arm-global-timer can provide clockevents, clocksource and shed_clock. But
on rk3188 platform it provide only clocksource and shed_clock. clockevents
from arm-global-timer is not used by kernel because there is another
clockevent provider with higher rating (smp-twd).
My commit from the series implement clocksource and shed_clock using
rockchip_timer. But sched clock from rk_timer is not selected by kernel
due to lower frequency than arm-global-timer, and clocksource from
rk_timer is not selected by kernel due to lower rating than
arm-global-timer. And I don't want to increase clocksource rating
because ratings greater than 300 used for high frequency clocksources.
clocksource and shed_clock is quite unstable, because their rate depends
on cpu frequency. So disable arm-global-timer and use clocksource and
sched_clock from rockchip_timer.
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
---
arch/arm/boot/dts/rk3188.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 0dc52fe..44da3d42 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -546,6 +546,7 @@
&global_timer {
interrupts = <GIC_PPI 11 0xf04>;
+ status = "disabled";
};
&local_timer {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 04/13] ARM: dts: rockchip: add timer entries to rk3188 dtsi
From: Alexander Kochetkov @ 2016-11-29 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-1-git-send-email-al.kochet@gmail.com>
The patch add two timers to all rk3188 based boards.
The first timer is from alive subsystem and it act as a backup
for the local timers at sleep time. It act the same as timers
on other rockchip chips already present in kernel.
The second timer is from CPU subsystem and act as replacement
for the arm-global-timer clocksource. It run as stable frequency
24MHz.
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
---
arch/arm/boot/dts/rk3188.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 31f81b2..0dc52fe 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -106,6 +106,22 @@
};
};
+ timer3: timer at 2000e000 {
+ compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer";
+ reg = <0x2000e000 0x20>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_TIMER3>, <&cru PCLK_TIMER3>;
+ clock-names = "timer", "pclk";
+ };
+
+ timer6: timer at 200380a0 {
+ compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer";
+ reg = <0x200380a0 0x20>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_TIMER6>, <&cru PCLK_TIMER0>;
+ clock-names = "timer", "pclk";
+ };
+
i2s0: i2s at 1011a000 {
compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s";
reg = <0x1011a000 0x2000>;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 03/13] ARM: dts: rockchip: update compatible property for rk3229 timer
From: Alexander Kochetkov @ 2016-11-29 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-1-git-send-email-al.kochet@gmail.com>
Property set to '"rockchip,rk3229-timer", "rockchip,rk3288-timer"'
to match devicetree bindings.
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
---
arch/arm/boot/dts/rk3229-evb.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/rk3229-evb.dts b/arch/arm/boot/dts/rk3229-evb.dts
index b6a1203..6629769 100644
--- a/arch/arm/boot/dts/rk3229-evb.dts
+++ b/arch/arm/boot/dts/rk3229-evb.dts
@@ -88,3 +88,7 @@
&uart2 {
status = "okay";
};
+
+&timer {
+ compatible = "rockchip,rk3229-timer", "rockchip,rk3288-timer";
+};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 02/13] ARM: dts: rockchip: update compatible property for rk3228 timer
From: Alexander Kochetkov @ 2016-11-29 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-1-git-send-email-al.kochet@gmail.com>
Property set to '"rockchip,rk3228-timer", "rockchip,rk3288-timer"'
to match devicetree bindings.
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
---
arch/arm/boot/dts/rk3228-evb.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 904668e..38eab87 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -70,3 +70,7 @@
&uart2 {
status = "okay";
};
+
+&timer {
+ compatible = "rockchip,rk3228-timer", "rockchip,rk3288-timer";
+};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 01/13] dt-bindings: clarify compatible property for rockchip timers
From: Alexander Kochetkov @ 2016-11-29 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480427118-5126-1-git-send-email-al.kochet@gmail.com>
Make all properties description in form '"rockchip,<chip>-timer",
"rockchip,rk3288-timer"' for all chips found in linux kernel.
Suggested-by: Heiko St?bner <heiko@sntech.de>
Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
---
.../bindings/timer/rockchip,rk-timer.txt | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt
index a41b184..16a5f45 100644
--- a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt
@@ -1,9 +1,15 @@
Rockchip rk timer
Required properties:
-- compatible: shall be one of:
- "rockchip,rk3288-timer" - for rk3066, rk3036, rk3188, rk322x, rk3288, rk3368
- "rockchip,rk3399-timer" - for rk3399
+- compatible: should be:
+ "rockchip,rk3036-timer", "rockchip,rk3288-timer": for Rockchip RK3036
+ "rockchip,rk3066-timer", "rockchip,rk3288-timer": for Rockchip RK3066
+ "rockchip,rk3188-timer", "rockchip,rk3288-timer": for Rockchip RK3188
+ "rockchip,rk3228-timer", "rockchip,rk3288-timer": for Rockchip RK3228
+ "rockchip,rk3229-timer", "rockchip,rk3288-timer": for Rockchip RK3229
+ "rockchip,rk3288-timer": for Rockchip RK3288
+ "rockchip,rk3368-timer", "rockchip,rk3288-timer": for Rockchip RK3368
+ "rockchip,rk3399-timer": for Rockchip RK3399
- reg: base address of the timer register starting with TIMERS CONTROL register
- interrupts: should contain the interrupts for Timer0
- clocks : must contain an entry for each entry in clock-names
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 00/13] Implement clocksource for rockchip SoC using rockchip timer
From: Alexander Kochetkov @ 2016-11-29 13:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480343486-25539-1-git-send-email-al.kochet@gmail.com>
Hello,
This patch series contain:
- devicetree bindings clarification for rockchip timers
- dts files fixes for rk3228-evb, rk3229-evb and rk3188
- implementation of clocksource for rockchip SoC
The clock supplying the arm-global-timer on the rk3188 is coming from the
the cpu clock itself and thus changes its rate everytime cpufreq adjusts
the cpu frequency making this timer unsuitable as a stable clocksource.
The rk3188, rk3288 and following socs share a separate timer block already
handled by the rockchip-timer driver. Therefore adapt this driver to also
be able to act as clocksource on rk3188.
In order to test clocksource you can run following commands and check
how much time it take in real. On rk3188 it take about ~45 seconds.
Such error cannot be fixed using NTP. Haven't test clocksource
on rk3288 and onwards. Guess they can also have unstable clocksource.
cpufreq-set -f 1.6GHZ
date; sleep 60; date
Regards,
Alexander.
Changes in v3:
added patches:
ARM: dts: rockchip: disable arm-global-timer for rk3188
clocksource/drivers/rockchip_timer: Prevent ftrace recursion
This is try 3. Please discard all v1 patches:
devicetree:
https://patchwork.ozlabs.org/patch/699019/
https://patchwork.ozlabs.org/patch/699020/
kernel:
https://patchwork.kernel.org/patch/9443975/
https://patchwork.kernel.org/patch/9443971/
https://patchwork.kernel.org/patch/9443959/
https://patchwork.kernel.org/patch/9443963/
https://patchwork.kernel.org/patch/9443979/
https://patchwork.kernel.org/patch/9443989/
https://patchwork.kernel.org/patch/9443987/
https://patchwork.kernel.org/patch/9443977/
https://patchwork.kernel.org/patch/9443991/
Old thread:
http://lists.infradead.org/pipermail/linux-rockchip/2016-November/013147.html
Alexander Kochetkov (13):
dt-bindings: clarify compatible property for rockchip timers
ARM: dts: rockchip: update compatible property for rk3228 timer
ARM: dts: rockchip: update compatible property for rk3229 timer
ARM: dts: rockchip: add timer entries to rk3188 dtsi
ARM: dts: rockchip: disable arm-global-timer for rk3188
clocksource/drivers/rockchip_timer: split bc_timer into rk_timer and
rk_clock_event_device
clocksource/drivers/rockchip_timer: low level routines take rk_timer
as parameter
clocksource/drivers/rockchip_timer: drop unused rk_base() and
rk_ctrl()
clocksource/drivers/rockchip_timer: move TIMER_INT_UNMASK out of
rk_timer_enable()
clocksource/drivers/rockchip_timer: implement loading 64bit value
into timer
clocksource/drivers/rockchip_timer: implement reading 64bit value
from timer
clocksource/drivers/rockchip_timer: implement clocksource timer
clocksource/drivers/rockchip_timer: Prevent ftrace recursion
.../bindings/timer/rockchip,rk-timer.txt | 12 +-
arch/arm/boot/dts/rk3188.dtsi | 17 ++
arch/arm/boot/dts/rk3228-evb.dts | 4 +
arch/arm/boot/dts/rk3229-evb.dts | 4 +
drivers/clocksource/rockchip_timer.c | 207 +++++++++++++++-----
5 files changed, 190 insertions(+), 54 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH] clocksource/arm_global_timer: reconfigure clockevents after cpufreq change
From: Thomas Gleixner @ 2016-11-29 13:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480421716-30782-2-git-send-email-al.kochet@gmail.com>
On Tue, 29 Nov 2016, Alexander Kochetkov wrote:
> After a cpufreq transition, update the clockevent's frequency
> by fetching the new clock rate from the clock framework and
> reprogram the next clock event.
The frequency change would not only affect the clockevent device, it also
would affect the clocksource. So the patch is incomplete, but see below.
> The clock supplying the arm-global-timer on the rk3188 is coming
> from the the cpu clock itself and thus changes its rate everytime
> cpufreq adjusts the cpu frequency.
That's broken and the clk framework should keep the CORE_PERI clock at a
constant rate by reprogramming the divider of the CPU clock.
> Found by code review, real impact not known. Assume what actual
> HZ value will be different from expected on platforms using
> arm-global-timer as clockevent.
Assumptions w/o real impact are a perfect reason not to apply that
patch. This want's a proper proof that the global timer really changes and
this hackery is required, which I seriously doubt.
Thanks,
tglx
^ permalink raw reply
* [PATCH v4 11/11] msi: platform: make platform_msi_create_device_domain() ACPI aware
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
With the platform msi domain created for ITS, irqchip such as
mbi-gen connecting ITS, which needs ctreate its own irqdomain.
Fortunately with the platform msi support upstreamed by Marc,
we just need to add minor code to make it run properly.
platform_msi_create_device_domain() is almost ready for ACPI use
except of_node_to_fwnode() is for dt only, make it ACPI aware then
things will work in both DTS and ACPI.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Greg KH <gregkh@linuxfoundation.org>
---
drivers/base/platform-msi.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c
index be6a599..035ca3b 100644
--- a/drivers/base/platform-msi.c
+++ b/drivers/base/platform-msi.c
@@ -345,8 +345,7 @@ struct irq_domain *
data->host_data = host_data;
domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec,
- of_node_to_fwnode(dev->of_node),
- ops, data);
+ dev->fwnode, ops, data);
if (!domain)
goto free_priv;
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 10/11] ACPI: ARM64: IORT: rework iort_node_get_id() for NC->SMMU->ITS case
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
iort_node_get_id() for now only support NC(named componant)->SMMU
or NC->ITS cases, we also have other device topology such NC->
SMMU->ITS, so rework iort_node_get_id() for those cases.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
drivers/acpi/arm64/iort.c | 59 ++++++++++++++++++++++++++---------------------
1 file changed, 33 insertions(+), 26 deletions(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 8714f70..2e2d231 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -292,22 +292,28 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
return status;
}
-static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
- u32 *rid_out)
+static int iort_id_single_map(struct acpi_iort_id_mapping *map, u8 type,
+ u32 *rid_out)
{
/* Single mapping does not care for input id */
if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) {
if (type == ACPI_IORT_NODE_NAMED_COMPONENT ||
type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
- *rid_out = map->output_base;
+ if (rid_out)
+ *rid_out = map->output_base;
return 0;
}
pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n",
map, type);
- return -ENXIO;
}
+ return -ENXIO;
+}
+
+static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
+ u32 *rid_out)
+{
if (rid_in < map->input_base ||
(rid_in >= map->input_base + map->id_count))
return -ENXIO;
@@ -324,33 +330,34 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
struct acpi_iort_node *parent;
struct acpi_iort_id_mapping *map;
- if (!node->mapping_offset || !node->mapping_count ||
- index >= node->mapping_count)
- return NULL;
-
- map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
- node->mapping_offset);
+ while (node) {
+ if (!node->mapping_offset || !node->mapping_count ||
+ index >= node->mapping_count)
+ return NULL;
- /* Firmware bug! */
- if (!map->output_reference) {
- pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
- node, node->type);
- return NULL;
- }
+ map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
+ node->mapping_offset);
- parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
- map->output_reference);
+ /* Firmware bug! */
+ if (!map->output_reference) {
+ pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
+ node, node->type);
+ return NULL;
+ }
- if (!(IORT_TYPE_MASK(parent->type) & type_mask))
- return NULL;
+ parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
+ map->output_reference);
- if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) {
- if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
- node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
- if (id_out)
- *id_out = map[index].output_base;
- return parent;
+ /* go upstream to find its parent */
+ if (!(IORT_TYPE_MASK(parent->type) & type_mask)) {
+ node = parent;
+ continue;
}
+
+ if (iort_id_single_map(&map[index], node->type, id_out))
+ break;
+
+ return parent;
}
return NULL;
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 09/11] ACPI: platform: setup MSI domain for ACPI based platform device
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
With the platform msi domain created, we can set up the msi domain
for a platform device when it's probed.
In order to do that, we need to get the domain that the platform
device connecting to, so the iort_get_platform_device_domain() is
introduced to retrieve the domain from iort.
After the domain is retrieved, we need a proper way to set the
domain to paltform device, as some platform devices such as an
irqchip needs the msi irqdomain to be the interrupt parent domain,
we need to get irqdomain before platform device is probed but after
the platform device is allocated, so introduce a callback (pre_add_cb)
in pdevinfo to prepare firmware related information which is needed
for device probe, then set the msi domain in that callback.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/acpi/acpi_platform.c | 11 +++++++++++
drivers/acpi/arm64/iort.c | 43 +++++++++++++++++++++++++++++++++++++++++
drivers/base/platform.c | 3 +++
include/linux/acpi_iort.h | 3 +++
include/linux/platform_device.h | 3 +++
5 files changed, 63 insertions(+)
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index b4c1a6a..5d8d61b4 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -12,6 +12,7 @@
*/
#include <linux/acpi.h>
+#include <linux/acpi_iort.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kernel.h>
@@ -48,6 +49,15 @@ static void acpi_platform_fill_resource(struct acpi_device *adev,
}
/**
+ * acpi_platform_pre_add_cb - callback before platform device is added, to
+ * prepare firmware related information which is needed for device probe
+ */
+static void acpi_platform_pre_add_cb(struct device *dev)
+{
+ acpi_configure_pmsi_domain(dev);
+}
+
+/**
* acpi_create_platform_device - Create platform device for ACPI device node
* @adev: ACPI device node to create a platform device for.
* @properties: Optional collection of build-in properties.
@@ -109,6 +119,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
pdevinfo.num_res = count;
pdevinfo.fwnode = acpi_fwnode_handle(adev);
pdevinfo.properties = properties;
+ pdevinfo.pre_add_cb = acpi_platform_pre_add_cb;
if (acpi_dma_supported(adev))
pdevinfo.dma_mask = DMA_BIT_MASK(32);
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 788f445..8714f70 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -527,6 +527,49 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
}
+/**
+ * iort_get_platform_device_domain() - Find MSI domain related to a
+ * platform device
+ * @dev: the dev pointer associated with the platform device
+ *
+ * Returns: the MSI domain for this device, NULL otherwise
+ */
+static struct irq_domain *iort_get_platform_device_domain(struct device *dev)
+{
+ struct acpi_iort_node *node, *msi_parent;
+ struct fwnode_handle *iort_fwnode;
+ struct acpi_iort_its_group *its;
+
+ /* find its associated iort node */
+ node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
+ iort_match_node_callback, dev);
+ if (!node)
+ return NULL;
+
+ /* then find its msi parent node */
+ msi_parent = iort_node_get_id(node, NULL, IORT_MSI_TYPE, 0);
+ if (!msi_parent)
+ return NULL;
+
+ /* Move to ITS specific data */
+ its = (struct acpi_iort_its_group *)msi_parent->node_data;
+
+ iort_fwnode = iort_find_domain_token(its->identifiers[0]);
+ if (!iort_fwnode)
+ return NULL;
+
+ return irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI);
+}
+
+void acpi_configure_pmsi_domain(struct device *dev)
+{
+ struct irq_domain *msi_domain;
+
+ msi_domain = iort_get_platform_device_domain(dev);
+ if (msi_domain)
+ dev_set_msi_domain(dev, msi_domain);
+}
+
static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
{
u32 *rid = data;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index c4af003..3e68f31 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -537,6 +537,9 @@ struct platform_device *platform_device_register_full(
goto err;
}
+ if (pdevinfo->pre_add_cb)
+ pdevinfo->pre_add_cb(&pdev->dev);
+
ret = platform_device_add(pdev);
if (ret) {
err:
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 3f717cc..21e33b6 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -37,6 +37,7 @@
struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
/* IOMMU interface */
const struct iommu_ops *iort_iommu_configure(struct device *dev);
+void acpi_configure_pmsi_domain(struct device *dev);
#else
static inline void acpi_iort_init(void) { }
static inline bool iort_node_match(u8 type) { return false; }
@@ -56,6 +57,8 @@ static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
static inline
const struct iommu_ops *iort_iommu_configure(struct device *dev)
{ return NULL; }
+
+static inline void acpi_configure_pmsi_domain(struct device *dev) { }
#endif
#define IORT_ACPI_DECLARE(name, table_id, fn) \
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 98c2a7c..280d366fb 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -74,6 +74,9 @@ struct platform_device_info {
u64 dma_mask;
struct property_entry *properties;
+
+ /* preparation callback before the platform device is added */
+ void (*pre_add_cb)(struct device *);
};
extern struct platform_device *platform_device_register_full(
const struct platform_device_info *pdevinfo);
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 08/11] ACPI: ARM64: IORT: rework iort_node_get_id()
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
iort_node_get_id() has two output, one is the mapped ids,
the other is the referenced parent node which is returned
from the function.
For now we need a API just return its parent node for
single mapping, so just update this function slightly then
reuse it later.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
drivers/acpi/arm64/iort.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 7b78282a..788f445 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -347,7 +347,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) {
if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
- *id_out = map[index].output_base;
+ if (id_out)
+ *id_out = map[index].output_base;
return parent;
}
}
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 07/11] irqchip: gicv3-its: platform-msi: scan MADT to create platform msi domain
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
With the introduction of its_pmsi_init_one(), we can add some code
on top for ACPI support of platform MSI.
We are scanning the MADT table to get the ITS entry(ies), then use
the information to create the platform msi domain for devices connect
to it, just like the PCI MSI for ITS did.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 36 +++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index ff72704..0be0437 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -105,6 +105,41 @@ static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
return 0;
}
+#ifdef CONFIG_ACPI
+static int __init
+its_pmsi_parse_madt(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_madt_generic_translator *its_entry;
+ struct fwnode_handle *domain_handle;
+ const char *node_name;
+ int err = -ENXIO;
+
+ its_entry = (struct acpi_madt_generic_translator *)header;
+ node_name = kasprintf(GFP_KERNEL, "ITS at 0x%lx",
+ (long)its_entry->base_address);
+ domain_handle = iort_find_domain_token(its_entry->translation_id);
+ if (!domain_handle) {
+ pr_err("%s: Unable to locate ITS domain handle\n", node_name);
+ goto out;
+ }
+
+ err = its_pmsi_init_one(domain_handle, node_name);
+
+out:
+ kfree(node_name);
+ return err;
+}
+
+static void __init its_acpi_pmsi_init(void)
+{
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+ its_pmsi_parse_madt, 0);
+}
+#else
+static inline void its_acpi_pmsi_init(void) { }
+#endif
+
static void __init its_pmsi_of_init(void)
{
struct device_node *np;
@@ -121,6 +156,7 @@ static void __init its_pmsi_of_init(void)
static int __init its_pmsi_init(void)
{
its_pmsi_of_init();
+ its_acpi_pmsi_init();
return 0;
}
early_initcall(its_pmsi_init);
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 06/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare for ACPI
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
Introduce its_pmsi_init_one() to refactor the code to isolate
ACPI&DT common code to prepare for ACPI later.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 45 ++++++++++++++++-----------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 16587a9..ff72704 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -84,34 +84,43 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
{},
};
-static int __init its_pmsi_init(void)
+static int __init its_pmsi_init_one(struct fwnode_handle *fwnode,
+ const char *name)
{
- struct device_node *np;
struct irq_domain *parent;
+ parent = irq_find_matching_fwnode(fwnode, DOMAIN_BUS_NEXUS);
+ if (!parent || !msi_get_domain_info(parent)) {
+ pr_err("%s: unable to locate ITS domain\n", name);
+ return -ENXIO;
+ }
+
+ if (!platform_msi_create_irq_domain(fwnode, &its_pmsi_domain_info,
+ parent)) {
+ pr_err("%s: unable to create platform domain\n", name);
+ return -ENXIO;
+ }
+
+ pr_info("Platform MSI: %s domain created\n", name);
+ return 0;
+}
+
+static void __init its_pmsi_of_init(void)
+{
+ struct device_node *np;
+
for (np = of_find_matching_node(NULL, its_device_id); np;
np = of_find_matching_node(np, its_device_id)) {
if (!of_property_read_bool(np, "msi-controller"))
continue;
- parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
- if (!parent || !msi_get_domain_info(parent)) {
- pr_err("%s: unable to locate ITS domain\n",
- np->full_name);
- continue;
- }
-
- if (!platform_msi_create_irq_domain(of_node_to_fwnode(np),
- &its_pmsi_domain_info,
- parent)) {
- pr_err("%s: unable to create platform domain\n",
- np->full_name);
- continue;
- }
-
- pr_info("Platform MSI: %s domain created\n", np->full_name);
+ its_pmsi_init_one(of_node_to_fwnode(np), np->full_name);
}
+}
+static int __init its_pmsi_init(void)
+{
+ its_pmsi_of_init();
return 0;
}
early_initcall(its_pmsi_init);
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 05/11] ACPI: platform-msi: retrieve dev id from IORT
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
For devices connecting to ITS, it needs dev id to identify
itself, and this dev id is represented in the IORT table in
named componant node [1] for platform devices, so in this
patch we will scan the IORT to retrieve device's dev id.
Introduce iort_pmsi_get_dev_id() with pointer dev passed
in for that purpose.
[1]: https://static.docs.arm.com/den0049/b/DEN0049B_IO_Remapping_Table.pdf
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/acpi/arm64/iort.c | 26 ++++++++++++++++++++++++++
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 4 +++-
include/linux/acpi_iort.h | 8 ++++++++
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index c1405e5..7b78282a 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -444,6 +444,32 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
}
/**
+ * iort_pmsi_get_dev_id() - Get the device id for a device
+ * @dev: The device for which the mapping is to be done.
+ * @dev_id: The device ID found.
+ *
+ * Returns: 0 for successful find a dev id, errors otherwise
+ */
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+ struct acpi_iort_node *node;
+
+ if (!iort_table)
+ return -ENODEV;
+
+ node = iort_find_dev_node(dev);
+ if (!node) {
+ dev_err(dev, "can't find related IORT node\n");
+ return -ENODEV;
+ }
+
+ if(!iort_node_get_id(node, dev_id, IORT_MSI_TYPE, 0))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
* iort_dev_find_its_id() - Find the ITS identifier for a device
* @dev: The device.
* @req_id: Device's Requster ID
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 3c94278..16587a9 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/acpi_iort.h>
#include <linux/device.h>
#include <linux/msi.h>
#include <linux/of.h>
@@ -56,7 +57,8 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
msi_info = msi_get_domain_info(domain->parent);
- ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
+ ret = dev->of_node ? of_pmsi_get_dev_id(domain, dev, &dev_id) :
+ iort_pmsi_get_dev_id(dev, &dev_id);
if (ret)
return ret;
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index dcb2b60..3f717cc 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -33,6 +33,7 @@
void acpi_iort_init(void);
bool iort_node_match(u8 type);
u32 iort_msi_map_rid(struct device *dev, u32 req_id);
+int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id);
struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id);
/* IOMMU interface */
const struct iommu_ops *iort_iommu_configure(struct device *dev);
@@ -41,9 +42,16 @@ static inline void acpi_iort_init(void) { }
static inline bool iort_node_match(u8 type) { return false; }
static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id)
{ return req_id; }
+
static inline struct irq_domain *iort_get_device_domain(struct device *dev,
u32 req_id)
{ return NULL; }
+
+static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id)
+{
+ return -ENODEV;
+}
+
/* IOMMU interface */
static inline
const struct iommu_ops *iort_iommu_configure(struct device *dev)
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 04/11] irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
Adding ACPI support for platform MSI, we need to retrieve the
dev id in ACPI way instead of device tree, we already have
a well formed function its_pmsi_prepare() to get the dev id
but it's OF dependent, so collect OF related code and put them
into a single function to make its_pmsi_prepare() more friendly
to ACPI later.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Tested-by: Sinan Kaya <okaya@codeaurora.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
index 470b4aa..3c94278 100644
--- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c
@@ -24,15 +24,11 @@
.name = "ITS-pMSI",
};
-static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
- int nvec, msi_alloc_info_t *info)
+static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
+ u32 *dev_id)
{
- struct msi_domain_info *msi_info;
- u32 dev_id;
int ret, index = 0;
- msi_info = msi_get_domain_info(domain->parent);
-
/* Suck the DeviceID out of the msi-parent property */
do {
struct of_phandle_args args;
@@ -43,11 +39,24 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
if (args.np == irq_domain_get_of_node(domain)) {
if (WARN_ON(args.args_count != 1))
return -EINVAL;
- dev_id = args.args[0];
+ *dev_id = args.args[0];
break;
}
} while (!ret);
+ return ret;
+}
+
+static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
+ int nvec, msi_alloc_info_t *info)
+{
+ struct msi_domain_info *msi_info;
+ u32 dev_id;
+ int ret;
+
+ msi_info = msi_get_domain_info(domain->parent);
+
+ ret = of_pmsi_get_dev_id(domain, dev, &dev_id);
if (ret)
return ret;
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 03/11] ACPI: ARM64: IORT: add missing comment for iort_dev_find_its_id()
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
We are missing req_id's comment for iort_dev_find_its_id(),
add it back.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
drivers/acpi/arm64/iort.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index a52fc7e..c1405e5 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -446,6 +446,7 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
/**
* iort_dev_find_its_id() - Find the ITS identifier for a device
* @dev: The device.
+ * @req_id: Device's Requster ID
* @idx: Index of the ITS identifier list.
* @its_id: ITS identifier.
*
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 02/11] irqchip: gic-v3-its: keep the head file include in alphabetic order
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
The head file is strictly in alphabetic order now, so let's
be the rule breaker. As acpi_iort.h includes acpi.h so remove
the duplidate acpi.h inclusion as well.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
drivers/irqchip/irq-gic-v3-its.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index c5dee30..1508bf4 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -15,14 +15,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/acpi.h>
+#include <linux/acpi_iort.h>
#include <linux/bitmap.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/dma-iommu.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
-#include <linux/acpi_iort.h>
#include <linux/log2.h>
#include <linux/mm.h>
#include <linux/msi.h>
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 01/11] ACPI: ARM64: IORT: minor cleanup for iort_match_node_callback()
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480426779-31387-1-git-send-email-guohanjun@huawei.com>
From: Hanjun Guo <hanjun.guo@linaro.org>
Cleanup iort_match_node_callback() a little bit to reduce
some lines of code, aslo fix the indentation in iort_scan_node().
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Tomasz Nowicki <tn@semihalf.com>
---
drivers/acpi/arm64/iort.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 47bace8..a52fc7e 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -225,7 +225,7 @@ static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,
if (iort_node->type == type &&
ACPI_SUCCESS(callback(iort_node, context)))
- return iort_node;
+ return iort_node;
iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
iort_node->length);
@@ -253,17 +253,15 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
void *context)
{
struct device *dev = context;
- acpi_status status;
+ acpi_status status = AE_NOT_FOUND;
if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) {
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_device *adev = to_acpi_device_node(dev->fwnode);
struct acpi_iort_named_component *ncomp;
- if (!adev) {
- status = AE_NOT_FOUND;
+ if (!adev)
goto out;
- }
status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf);
if (ACPI_FAILURE(status)) {
@@ -289,8 +287,6 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
*/
status = pci_rc->pci_segment_number == pci_domain_nr(bus) ?
AE_OK : AE_NOT_FOUND;
- } else {
- status = AE_NOT_FOUND;
}
out:
return status;
--
1.7.12.4
^ permalink raw reply related
* [PATCH v4 00/11] ACPI platform MSI support
From: Hanjun Guo @ 2016-11-29 13:39 UTC (permalink / raw)
To: linux-arm-kernel
From: Hanjun Guo <hanjun.guo@linaro.org>
v3 -> v4:
- Drop mbi-gen patches to just submit platform msi support because
will rebase mbi-gen patches on top of Agustin's patchset, and discusion
is going there.
- Add a patch to support device topology such as NC(named componant, paltform device)
->SMMU->ITS which suggested by Lorenzo;
- rebased on top of Lorenzo's v9 of ACPI IORT ARM SMMU support;
- rebased on top of 4.9-rc7
v2 -> v3:
- Drop RFC tag
- Rebase against v4.9-rc2 and Lorenzo's v6 of ACPI IORT ARM SMMU support [1]
- Add 3 cleanup patches (patch 1, 2, 3)
- Drop arch_init call patch from last version
- Introduce a callback for platform device to set msi domain
- Introduce a new API to get paltform device's domain instead of
reusing the PCI one in previous version
- Add a patch to rework iort_node_get_id()
[1]: http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1251993.html
v1 -> v2:
- Fix the bug of if multi Interrupt() resoures in single _PRS,
we need to calculate all the irq numbers (I missed it in previous
version);
- Rebased on Marc's irq/irqchip-4.9 branch and Lorenzo's v5
SMMU patches (also Robin's SMMu patches)
- Add patch irqchip: mbigen: promote mbigen init.
With platform msi support landed in the kernel, and the introduction
of IORT for GICv3 ITS (PCI MSI), the framework for platform msi
is ready, this patch set add few patches to enable the ACPI platform
msi support.
For platform device connecting to ITS on arm platform, we have IORT
table with the named componant node to describe the mappings of paltform
device and ITS, so we can retrieve the dev id and find its parent
irqdomain (ITS) from IORT table (simlar with the ACPI ITS support).
The fisrt 3 patches are cleanups;
Patch 4,5 are refactoring its_pmsi_prepare() for both DT and ACPI
then retrieve the dev id from iort;
Patch 6,7 to create platform msi domain to ACPI case which scanned
the MADT table;
Patch 8,9,10,11 to setup the msi domain for platform device based
on IORT table.
Teasted on Hisilicon D03.
Thanks
Hanjun
Hanjun Guo (11):
ACPI: ARM64: IORT: minor cleanup for iort_match_node_callback()
irqchip: gic-v3-its: keep the head file include in alphabetic order
ACPI: ARM64: IORT: add missing comment for iort_dev_find_its_id()
irqchip: gicv3-its: platform-msi: refactor its_pmsi_prepare()
ACPI: platform-msi: retrieve dev id from IORT
irqchip: gicv3-its: platform-msi: refactor its_pmsi_init() to prepare
for ACPI
irqchip: gicv3-its: platform-msi: scan MADT to create platform msi
domain
ACPI: ARM64: IORT: rework iort_node_get_id()
ACPI: platform: setup MSI domain for ACPI based platform device
ACPI: ARM64: IORT: rework iort_node_get_id() for NC->SMMU->ITS case
msi: platform: make platform_msi_create_device_domain() ACPI aware
drivers/acpi/acpi_platform.c | 11 ++
drivers/acpi/arm64/iort.c | 138 ++++++++++++++++++++------
drivers/base/platform-msi.c | 3 +-
drivers/base/platform.c | 3 +
drivers/irqchip/irq-gic-v3-its-platform-msi.c | 106 +++++++++++++++-----
drivers/irqchip/irq-gic-v3-its.c | 3 +-
include/linux/acpi_iort.h | 11 ++
include/linux/platform_device.h | 3 +
8 files changed, 217 insertions(+), 61 deletions(-)
--
1.7.12.4
^ permalink raw reply
* [PATCH 4/4] crypto: arm64/aes-ce-ctr: fix skcipher conversion
From: Ard Biesheuvel @ 2016-11-29 13:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480424733-10797-1-git-send-email-ard.biesheuvel@linaro.org>
Fix a missing statement that got lost in the skcipher conversion of
the CTR transform.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/crypto/aes-glue.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
index 5c43b92b3714..4e3f8adb1793 100644
--- a/arch/arm64/crypto/aes-glue.c
+++ b/arch/arm64/crypto/aes-glue.c
@@ -206,6 +206,7 @@ static int ctr_encrypt(struct skcipher_request *req)
(u8 *)ctx->key_enc, rounds, blocks, walk.iv,
first);
err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
+ first = 0;
}
if (walk.nbytes) {
u8 __aligned(8) tail[AES_BLOCK_SIZE];
--
2.7.4
^ permalink raw reply related
* [PATCH 3/4] crypto: arm64/aes-ce-ccm - fix decrypt path with new skcipher interface
From: Ard Biesheuvel @ 2016-11-29 13:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480424733-10797-1-git-send-email-ard.biesheuvel@linaro.org>
The new skcipher walk interface does not take into account whether we
are encrypting or decrypting. In the latter case, the walk should
disregard the MAC. Fix this in the arm64 CE driver.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/crypto/aes-ce-ccm-glue.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
index d4f35685363b..1a011d658387 100644
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
@@ -204,10 +204,10 @@ static int ccm_decrypt(struct aead_request *req)
struct skcipher_walk walk;
u8 __aligned(8) mac[AES_BLOCK_SIZE];
u8 buf[AES_BLOCK_SIZE];
- u32 len = req->cryptlen - authsize;
int err;
- err = ccm_init_mac(req, mac, len);
+ req->cryptlen -= authsize;
+ err = ccm_init_mac(req, mac, req->cryptlen);
if (err)
return err;
@@ -242,8 +242,7 @@ static int ccm_decrypt(struct aead_request *req)
return err;
/* compare calculated auth tag with the stored one */
- scatterwalk_map_and_copy(buf, req->src,
- req->assoclen + req->cryptlen - authsize,
+ scatterwalk_map_and_copy(buf, req->src, req->assoclen + req->cryptlen,
authsize, 0);
if (crypto_memneq(mac, buf, authsize))
--
2.7.4
^ permalink raw reply related
* [PATCH 2/4] crypto: skcipher - fix crash in skcipher_walk_aead()
From: Ard Biesheuvel @ 2016-11-29 13:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480424733-10797-1-git-send-email-ard.biesheuvel@linaro.org>
The new skcipher_walk_aead() may crash in the following way due to
the walk flag SKCIPHER_WALK_PHYS not being cleared at the start of the
walk:
Unable to handle kernel NULL pointer dereference at virtual address 00000001
[..]
Internal error: Oops: 96000044 [#1] PREEMPT SMP
[..]
PC is at skcipher_walk_next+0x208/0x450
LR is at skcipher_walk_next+0x1e4/0x450
pc : [<ffff2b93b7104e20>] lr : [<ffff2b93b7104dfc>] pstate: 40000045
sp : ffffb925fa517940
[...]
[<ffff2b93b7104e20>] skcipher_walk_next+0x208/0x450
[<ffff2b93b710535c>] skcipher_walk_first+0x54/0x148
[<ffff2b93b7105664>] skcipher_walk_aead+0xd4/0x108
[<ffff2b93b6e77928>] ccm_encrypt+0x68/0x158
So clear the flag at the appropriate time.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
crypto/skcipher.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 0f3071991b13..5367f817b40e 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -506,6 +506,8 @@ int skcipher_walk_aead(struct skcipher_walk *walk, struct aead_request *req,
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
int err;
+ walk->flags &= ~SKCIPHER_WALK_PHYS;
+
scatterwalk_start(&walk->in, req->src);
scatterwalk_start(&walk->out, req->dst);
--
2.7.4
^ permalink raw reply related
* [PATCH 1/4] crypto: arm/aes-ce: fix broken monolithic build
From: Ard Biesheuvel @ 2016-11-29 13:05 UTC (permalink / raw)
To: linux-arm-kernel
When building the arm64 kernel with both CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
and CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y configured, the build breaks with
the following error:
arch/arm64/crypto/aes-neon-blk.o:(.bss+0x0): multiple definition of `aes_simd_algs'
arch/arm64/crypto/aes-ce-blk.o:(.bss+0x0): first defined here
Fix this by making aes_simd_algs 'static'.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm64/crypto/aes-glue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
index 24f6137c1a6e..5c43b92b3714 100644
--- a/arch/arm64/crypto/aes-glue.c
+++ b/arch/arm64/crypto/aes-glue.c
@@ -343,7 +343,7 @@ static struct skcipher_alg aes_algs[] = { {
.decrypt = xts_decrypt,
} };
-struct simd_skcipher_alg *aes_simd_algs[ARRAY_SIZE(aes_algs)];
+static struct simd_skcipher_alg *aes_simd_algs[ARRAY_SIZE(aes_algs)];
static void aes_exit(void)
{
--
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