* [PATCH 2/9] armv8: pm: Fix issue of rcpm driver wrongly program other IP control bits
From: Yinbo Zhu @ 2018-05-11 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-1-yinbo.zhu@nxp.com>
From: Ran Wang <ran.wang_1@nxp.com>
When rcpm driver get target register data from DTS property 'fsl,
rcpm-wakeup' (second value), it directly write that data to register
RCPM_IPPDEXPCRx rather than 'OR' the value read from it before. This
operation will over-write those non-related IP control bit which
might have been programmed, should be prevented.
Signed-off-by: Ran Wang <ran.wang_1@nxp.com>
Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com>
---
drivers/soc/fsl/rcpm.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c
index ff0477b..39eabfb 100644
--- a/drivers/soc/fsl/rcpm.c
+++ b/drivers/soc/fsl/rcpm.c
@@ -75,6 +75,7 @@ static void rcpm_wakeup_fixup(struct device *dev, void *data)
static int rcpm_suspend_prepare(void)
{
int i;
+ u32 val;
WARN_ON(!rcpm);
@@ -84,9 +85,12 @@ static int rcpm_suspend_prepare(void)
dpm_for_each_dev(NULL, rcpm_wakeup_fixup);
for (i = 0; i < rcpm->ipp_num; i++) {
- rcpm_reg_write(rcpm->ippdexpcr_offset + 4 * i,
- rcpm->ippdexpcr[i]);
- pr_debug("ippdexpcr%d = 0x%x\n", i, rcpm->ippdexpcr[i]);
+ if (rcpm->ippdexpcr[i]) {
+ val = rcpm_reg_read(rcpm->ippdexpcr_offset + 4 * i);
+ rcpm_reg_write(rcpm->ippdexpcr_offset + 4 * i,
+ val | rcpm->ippdexpcr[i]);
+ pr_debug("ippdexpcr%d = 0x%x\n", i, rcpm->ippdexpcr[i]);
+ }
}
return 0;
--
1.7.1
^ permalink raw reply related
* [PATCH 3/9] soc: fsl: set rcpm bit for FTM
From: Yinbo Zhu @ 2018-05-11 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-1-yinbo.zhu@nxp.com>
From: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Set RCPM for FTM when using FTM as wakeup source. Because the RCPM
module of each platform has different big-end and little-end mode,
there need to set RCPM depending on the platform.
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com>
---
.../devicetree/bindings/timer/fsl,ftm-timer.txt | 7 ++
drivers/soc/fsl/layerscape/ftm_alarm.c | 92 ++++++++++++++++++-
2 files changed, 94 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
index aa8c402..15ead58 100644
--- a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
+++ b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
@@ -3,6 +3,13 @@ Freescale FlexTimer Module (FTM) Timer
Required properties:
- compatible : should be "fsl,ftm-timer"
+ Possible compatibles for ARM:
+ "fsl,ls1012a-ftm"
+ "fsl,ls1021a-ftm"
+ "fsl,ls1043a-ftm"
+ "fsl,ls1046a-ftm"
+ "fsl,ls1088a-ftm"
+ "fsl,ls208xa-ftm"
- reg : Specifies base physical address and size of the register sets for the
clock event device and clock source device.
- interrupts : Should be the clock event device interrupt.
diff --git a/drivers/soc/fsl/layerscape/ftm_alarm.c b/drivers/soc/fsl/layerscape/ftm_alarm.c
index 6f9882f..811dcfa 100644
--- a/drivers/soc/fsl/layerscape/ftm_alarm.c
+++ b/drivers/soc/fsl/layerscape/ftm_alarm.c
@@ -16,6 +16,9 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/libata.h>
#define FTM_SC 0x00
#define FTM_SC_CLK_SHIFT 3
@@ -40,6 +43,59 @@
static u32 alarm_freq;
static bool big_endian;
+enum pmu_endian_type {
+ BIG_ENDIAN,
+ LITTLE_ENDIAN,
+};
+
+struct rcpm_cfg {
+ enum pmu_endian_type big_endian; /* Big/Little endian of PMU module */
+
+ /* FlexTimer1 is not powerdown during device LPM20 */
+ u32 flextimer_set_bit;
+};
+
+static struct rcpm_cfg ls1012a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1021a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1043a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1046a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1088a_rcpm_cfg = {
+ .big_endian = LITTLE_ENDIAN,
+ .flextimer_set_bit = 0x4000,
+};
+
+static struct rcpm_cfg ls208xa_rcpm_cfg = {
+ .big_endian = LITTLE_ENDIAN,
+ .flextimer_set_bit = 0x4000,
+};
+
+static const struct of_device_id ippdexpcr_of_match[] = {
+ { .compatible = "fsl,ls1012a-ftm", .data = &ls1012a_rcpm_cfg},
+ { .compatible = "fsl,ls1021a-ftm", .data = &ls1021a_rcpm_cfg},
+ { .compatible = "fsl,ls1043a-ftm", .data = &ls1043a_rcpm_cfg},
+ { .compatible = "fsl,ls1046a-ftm", .data = &ls1046a_rcpm_cfg},
+ { .compatible = "fsl,ls1088a-ftm", .data = &ls1088a_rcpm_cfg},
+ { .compatible = "fsl,ls208xa-ftm", .data = &ls208xa_rcpm_cfg},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ippdexpcr_of_match);
+
static inline u32 ftm_readl(void __iomem *addr)
{
if (big_endian)
@@ -214,7 +270,10 @@ static int ftm_alarm_probe(struct platform_device *pdev)
struct resource *r;
int irq;
int ret;
- u32 ippdexpcr;
+ struct rcpm_cfg *rcpm_cfg;
+ u32 ippdexpcr, flextimer;
+ const struct of_device_id *of_id;
+ enum pmu_endian_type endian;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
@@ -224,14 +283,32 @@ static int ftm_alarm_probe(struct platform_device *pdev)
if (IS_ERR(ftm1_base))
return PTR_ERR(ftm1_base);
+ of_id = of_match_node(ippdexpcr_of_match, np);
+ if (!of_id)
+ return -ENODEV;
+
+ rcpm_cfg = devm_kzalloc(&pdev->dev, sizeof(*rcpm_cfg), GFP_KERNEL);
+ if (!rcpm_cfg)
+ return -ENOMEM;
+
+ rcpm_cfg = (struct rcpm_cfg *)of_id->data;
+ endian = rcpm_cfg->big_endian;
+ flextimer = rcpm_cfg->flextimer_set_bit;
+
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "FlexTimer1");
if (r) {
rcpm_ftm_addr = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(rcpm_ftm_addr))
return PTR_ERR(rcpm_ftm_addr);
- ippdexpcr = ioread32be(rcpm_ftm_addr);
- ippdexpcr |= 0x20000;
- iowrite32be(ippdexpcr, rcpm_ftm_addr);
+ if (endian == BIG_ENDIAN)
+ ippdexpcr = ioread32be(rcpm_ftm_addr);
+ else
+ ippdexpcr = ioread32(rcpm_ftm_addr);
+ ippdexpcr |= flextimer;
+ if (endian == BIG_ENDIAN)
+ iowrite32be(ippdexpcr, rcpm_ftm_addr);
+ else
+ iowrite32(ippdexpcr, rcpm_ftm_addr);
}
irq = irq_of_parse_and_map(np, 0);
@@ -265,7 +342,12 @@ static int ftm_alarm_probe(struct platform_device *pdev)
}
static const struct of_device_id ftm_alarm_match[] = {
- { .compatible = "fsl,ftm-alarm", },
+ { .compatible = "fsl,ls1012a-ftm", },
+ { .compatible = "fsl,ls1021a-ftm", },
+ { .compatible = "fsl,ls1043a-ftm", },
+ { .compatible = "fsl,ls1046a-ftm", },
+ { .compatible = "fsl,ls1088a-ftm", },
+ { .compatible = "fsl,ls208xa-ftm", },
{ .compatible = "fsl,ftm-timer", },
{ },
};
--
1.7.1
^ permalink raw reply related
* [PATCH 4/9] arm64: dts: ls208xa: Add the identify of the platform to support to set rcpm bit
From: Yinbo Zhu @ 2018-05-11 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-1-yinbo.zhu@nxp.com>
From: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Add the identify of the platform to support set the rcpm with
big-endian or little-endian.
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
---
arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
index fec61af..973e646 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
@@ -896,9 +896,11 @@
};
ftm0: ftm0 at 2800000 {
- compatible = "fsl,ftm-alarm";
- reg = <0x0 0x2800000 0x0 0x10000>;
+ compatible = "fsl,ls208xa-ftm";
+ reg = <0x0 0x2800000 0x0 0x10000>,
+ <0x0 0x1e34050 0x0 0x4>;
interrupts = <0 44 4>;
+ reg-names = "ftm", "FlexTimer1";
};
};
--
1.7.1
^ permalink raw reply related
* [PATCH 5/9] drivers: firmware: psci: use psci v0.2 to implement sleep
From: Yinbo Zhu @ 2018-05-11 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-1-yinbo.zhu@nxp.com>
From: Yuantian Tang <andy.tang@nxp.com>
Technically psci v0.2 can not support system sleep. Unfortunately
our PPA only supports psci v0.2. So workaround this by changing
psci v1.0 to v0.2 call to implement system sleep.
Signed-off-by: Tang Yuantian <andy.tang@nxp.com>
Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com>
---
drivers/firmware/psci.c | 16 ++++++++++++++--
1 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index c80ec1d..0bd795f 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -437,8 +437,18 @@ int psci_cpu_suspend_enter(unsigned long index)
static int psci_system_suspend(unsigned long unused)
{
- return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
- __pa_symbol(cpu_resume), 0, 0);
+ u32 state;
+ u32 ver = psci_get_version();
+
+ if (PSCI_VERSION_MAJOR(ver) >= 1) {
+ return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
+ virt_to_phys(cpu_resume), 0, 0);
+ } else {
+ state = (2 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) |
+ (1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT);
+
+ return psci_cpu_suspend(state, virt_to_phys(cpu_resume));
+ }
}
static int psci_system_suspend_enter(suspend_state_t state)
@@ -562,6 +572,8 @@ static void __init psci_0_2_set_functions(void)
arm_pm_restart = psci_sys_reset;
pm_power_off = psci_sys_poweroff;
+
+ suspend_set_ops(&psci_suspend_ops);
}
/*
--
1.7.1
^ permalink raw reply related
* [PATCH 6/9] soc: fsl: fix the compilation issue
From: Yinbo Zhu @ 2018-05-11 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-1-yinbo.zhu@nxp.com>
From: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
---
drivers/soc/fsl/layerscape/ftm_alarm.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/soc/fsl/layerscape/ftm_alarm.c b/drivers/soc/fsl/layerscape/ftm_alarm.c
index 811dcfa..c22ef49 100644
--- a/drivers/soc/fsl/layerscape/ftm_alarm.c
+++ b/drivers/soc/fsl/layerscape/ftm_alarm.c
@@ -19,6 +19,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/libata.h>
+#include <linux/module.h>
#define FTM_SC 0x00
#define FTM_SC_CLK_SHIFT 3
--
1.7.1
^ permalink raw reply related
* [PATCH 7/9] arm64: dts: ls1043a: Add the identify of the platform to support to set rcpm bit
From: Yinbo Zhu @ 2018-05-11 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-1-yinbo.zhu@nxp.com>
From: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Add the identify of the platform to support set the rcpm with
big-endian or little-endian.
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
---
arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
index ffea97a..754ce0d 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
@@ -679,7 +679,7 @@
};
ftm0: ftm0 at 29d0000 {
- compatible = "fsl,ftm-alarm";
+ compatible = "fsl,ls1043a-ftm";
reg = <0x0 0x29d0000 0x0 0x10000>,
<0x0 0x1ee2140 0x0 0x4>;
reg-names = "ftm", "FlexTimer1";
--
1.7.1
^ permalink raw reply related
* [PATCH 8/9] arm64: dts: ls1046a: Add the identify of the platform to support to set rcpm bit
From: Yinbo Zhu @ 2018-05-11 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-1-yinbo.zhu@nxp.com>
From: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Add the identify of the platform to support set the rcpm with
big-endian or little-endian.
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
---
arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 3e09bcb..1ce1153 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -575,7 +575,7 @@
};
ftm0: ftm0 at 29d0000 {
- compatible = "fsl,ftm-alarm";
+ compatible = "fsl,ls1046a-ftm";
reg = <0x0 0x29d0000 0x0 0x10000>,
<0x0 0x1ee2140 0x0 0x4>;
reg-names = "ftm", "FlexTimer1";
--
1.7.1
^ permalink raw reply related
* [PATCH 9/9] armv8: add psci 0.2 stardard support
From: Yinbo Zhu @ 2018-05-11 3:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-1-yinbo.zhu@nxp.com>
From: Yuantian Tang <andy.tang@nxp.com>
In current kernel, only psci v1.0 is supported. But our psci firmware
only support psci v0.2. So update psci driver to support psci v0.2.
Signed-off-by: Tang Yuantian <andy.tang@nxp.com>
---
drivers/firmware/psci.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 0bd795f..c9ed9fb 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -468,6 +468,8 @@ static void __init psci_init_system_suspend(void)
if (!IS_ENABLED(CONFIG_SUSPEND))
return;
+ suspend_set_ops(&psci_suspend_ops);
+
ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND));
if (ret != PSCI_RET_NOT_SUPPORTED)
@@ -573,6 +575,8 @@ static void __init psci_0_2_set_functions(void)
pm_power_off = psci_sys_poweroff;
+ psci_init_system_suspend();
+
suspend_set_ops(&psci_suspend_ops);
}
--
1.7.1
^ permalink raw reply related
* [PATCH v1 3/5] arm64: dts: rockchip: Add gpio-syscon10 to rk3328
From: Levin Du @ 2018-05-11 3:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <76f2bbde-e158-a186-f136-9fb610a810c5@arm.com>
On 2018-05-10 8:50 PM, Robin Murphy wrote:
> On 10/05/18 10:16, djw at t-chip.com.cn wrote:
>> From: Levin Du <djw@t-chip.com.cn>
>>
>> Adding a new gpio controller named "gpio-syscon10" to rk3328, providing
>> access to the pins defined in the syscon GRF_SOC_CON10.
>
> This is the GPIO_MUTE pin, right? The public TRM is rather vague, but
> cross-referencing against the datasheet and schematics implies that
> it's the "gpiomut_*" part of the GRF bit names which is most significant.
>
> It might be worth using a more descriptive name here, since "syscon10"
> is pretty much meaningless at the board level.
>
> Robin.
>
Previously I though other bits might be able to reference from syscon10,
other than GPIO_MUTE alone.
If it is renamed to gpio-mute, then the GPIO_MUTE pin is accessed as
`<&gpio-mute 1>`. Yet other
bits in syscon10 can also be referenced, say, `<&gpio-mute 10>`, which
is not good.
I'd like to add a `gpio,syscon-bit` property to gpio-syscon, which
overrides the properties
of bit_count,? data_bit_offset and dir_bit_offset in the driver. For
example:
??????????????? gpio_mute: gpio-mute {
??????????????????????? compatible = "rockchip,gpio-syscon";
??????????????????????? gpio-controller;
??????????????????????? #gpio-cells = <2>;
??????????????????????? gpio,syscon-dev = <0 0x0428 0>;
??????????????????????? gpio,syscon-bit = <1 1 0>;
??????????????? };
That way, the mute pin is strictly specified as <&gpio_mute 0>, and
<&gpio_mute 1> will be invalid.
I think that is neat, and consistent with the gpio_mute name.
Thanks
Levin
^ permalink raw reply
* [GIT PULL] arm64: updates for 4.17
From: Yang Li @ 2018-05-11 4:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180404143239.GA18238@arm.com>
On Wed, Apr 4, 2018 at 9:32 AM, Will Deacon <will.deacon@arm.com> wrote:
> Hi Linus,
>
> Please pull these arm64 updates for 4.17. Note that I've pulled in a
> stable branch from Eric Biederman here to fulfil some siginfo dependencies,
> so the diffstat strays slightly out of arm64 due to his changes.
{snip}
>
> Catalin Marinas (1):
> arm64: Revert L1_CACHE_SHIFT back to 6 (64-byte cache line size)
>
{snip}
>
> Will Deacon (20):
> arm64: signal: Make force_signal_inject more robust
> arm64: signal: Force SIGKILL for unknown signals in force_signal_inject
> arm64: Introduce arm64_force_sig_info and hook up in arm64_notify_die
> arm64: signal: Don't print anything directly in force_signal_inject
> arm64: Pass user fault info to arm64_notify_die instead of printing it
> arm64: mm: Rework unhandled user pagefaults to call arm64_force_sig_info
> arm64: signal: Call arm64_notify_segfault when failing to deliver signal
> arm64: Move show_unhandled_signals_ratelimited into traps.c
> arm64: Use arm64_force_sig_info instead of force_sig_info
> arm64: lse: Pass -fomit-frame-pointer to out-of-line ll/sc atomics
> arm64: kaslr: Set TCR_EL1.NFD1 when CONFIG_RANDOMIZE_BASE=y
> Merge tag 'acpi/iort-for-v4.17' of git://git.kernel.org/.../lpieralisi/linux into aarch64/for-next/core
> Merge branch 'siginfo-next' of git://git.kernel.org/.../ebiederm/user-namespace into aarch64/for-next/core
> arm64: cpufeature: Avoid warnings due to unused symbols
> Revert "arm64: Revert L1_CACHE_SHIFT back to 6 (64-byte cache line size)"
Hi Will,
I'm wondering if we are changing the L1_CACHE_SHIFT to 6 in 4.17?
This is causing big performance differences for us now.
Regards,
Leo
^ permalink raw reply
* [GIT PULL] omap-gpmc updates for v4.18
From: Roger Quadros @ 2018-05-11 4:28 UTC (permalink / raw)
To: linux-arm-kernel
Hi Olof/Arnd,
The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
are available in the git repository at:
https://github.com/rogerq/linux.git tags/gpmc-omap-for-v4.18
for you to fetch changes up to d507178f2ebb7bde5b3f64557f1c8f80e7b82541:
memory: omap-gpmc: Avoid redundant NULL check (2018-04-24 10:30:52 +0300)
----------------------------------------------------------------
OMAP-GPMC: driver updates for v4.18
* get rid of a redundant NULL check in gpmc_probe_dt_children()
----------------------------------------------------------------
Roger Quadros (1):
memory: omap-gpmc: Avoid redundant NULL check
drivers/memory/omap-gpmc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--
cheers,
-roger
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
^ permalink raw reply
* [PATCH v3 02/14] drivers: soc: sunxi: Add dedicated compatibles for the A13, A20 and A33
From: Chen-Yu Tsai @ 2018-05-11 5:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180507124500.20434-3-paul.kocialkowski@bootlin.com>
On Mon, May 7, 2018 at 5:44 AM, Paul Kocialkowski
<paul.kocialkowski@bootlin.com> wrote:
> This introduces platform-specific compatibles for the A13, A20 and A33
> SRAM driver. No particular adaptation for these platforms is required at
> this point, although this might become the case in the future.
>
> Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
> ---
> drivers/soc/sunxi/sunxi_sram.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c
> index 74cb81f37bd6..43ebc3bd33f2 100644
> --- a/drivers/soc/sunxi/sunxi_sram.c
> +++ b/drivers/soc/sunxi/sunxi_sram.c
> @@ -315,6 +315,9 @@ static int sunxi_sram_probe(struct platform_device *pdev)
>
> static const struct of_device_id sunxi_sram_dt_match[] = {
> { .compatible = "allwinner,sun4i-a10-sram-controller" },
> + { .compatible = "allwinner,sun5i-a13-sram-controller" },
> + { .compatible = "allwinner,sun7i-a20-sram-controller" },
> + { .compatible = "allwinner,sun8i-a33-sram-controller" },
We should probably name these "system-controller". Maxime?
ChenYu
> { .compatible = "allwinner,sun50i-a64-sram-controller" },
> { },
> };
> --
> 2.16.3
>
^ permalink raw reply
* [PATCH v2] arm64: allwinner: a64: Add Amarula A64 Relic initial support
From: Jagan Teki @ 2018-05-11 5:43 UTC (permalink / raw)
To: linux-arm-kernel
Amarula A64 Relic is Allwinner A64 based IoT device, which support
- Allwinner A64 Cortex-A53
- Mali-400MP2 GPU
- AXP803 PMIC
- 1GB DDR3 RAM
- 8GB eMMC
- AP6330 Wifi/BLE
- MIPI-DSI
- CSI: OV5640 sensor
- USB OTG
- 12V DC power supply
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v2:
- Rename dts name to sun50i-a64-relic.dts which is simple to use
- Update dldo4 min voltage as 1.8
- Use licence year as 2018
arch/arm64/boot/dts/allwinner/Makefile | 1 +
arch/arm64/boot/dts/allwinner/sun50i-a64-relic.dts | 182 +++++++++++++++++++++
2 files changed, 183 insertions(+)
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-relic.dts
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index c31f90a49481..9b4417f00b68 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -6,6 +6,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-relic.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-libretech-all-h3-cc.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo2.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo-plus2.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-relic.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-relic.dts
new file mode 100644
index 000000000000..7dd6f8b03503
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-relic.dts
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Amarula Solutions B.V.
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+/dts-v1/;
+
+#include "sun50i-a64.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Amarula A64 Relic";
+ compatible = "amarula,a64-relic", "allwinner,sun50i-a64";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <®_dcdc1>;
+ bus-width = <8>;
+ non-removable;
+ cap-mmc-hw-reset;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&r_rsb {
+ status = "okay";
+
+ axp803: pmic at 3a3 {
+ compatible = "x-powers,axp803";
+ reg = <0x3a3>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ x-powers,drive-vbus-en; /* set N_VBUSEN as output pin */
+ };
+};
+
+#include "axp803.dtsi"
+
+®_aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "avdd-csi";
+};
+
+®_aldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-pl";
+};
+
+®_aldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "vcc-pll-avcc";
+};
+
+®_dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3";
+};
+
+®_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1040000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+®_dcdc5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vcc-dram";
+};
+
+®_dcdc6 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vdd-sys";
+};
+
+®_dldo1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-hdmi-dsi-sensor";
+};
+
+®_dldo2 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-mipi";
+};
+
+®_dldo3 {
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-name = "vcc-gen";
+};
+
+®_dldo4 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-io";
+};
+
+®_drivevbus {
+ regulator-name = "usb0-vbus";
+ status = "okay";
+};
+
+®_eldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "cpvdd";
+};
+
+®_fldo1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "vcc-1v2-hsic";
+};
+
+/*
+ * The A64 chip cannot work without this regulator off, although
+ * it seems to be only driving the AR100 core.
+ * Maybe we don't still know well about CPUs domain.
+ */
+®_fldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vdd-cpus";
+};
+
+®_rtc_ldo {
+ regulator-name = "vcc-rtc";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ usb0_id_det-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
+ usb0_vbus-supply = <®_drivevbus>;
+ status = "okay";
+};
--
2.14.3
^ permalink raw reply related
* [PATCH 1/2] ARM: dts: imx28-cfa10049: Remove unnecessary #address/#size-cells
From: Shawn Guo @ 2018-05-11 5:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525655020-31260-1-git-send-email-festevam@gmail.com>
On Sun, May 06, 2018 at 10:03:39PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@nxp.com>
>
> Remove unnecessary #address-cells/#size-cells to fix the following
> DTC warnings:
>
> arch/arm/boot/dts/imx28-cfa10049.dtb: Warning (avoid_unnecessary_addr_size): /gpio_keys: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
>
> Cc: Maxime Ripard <maxime.ripard@bootlin.com>
> Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Applied both, thanks.
^ permalink raw reply
* [PATCH] ARM: dts: imx51-zii-rdu1: fix touchscreen bindings
From: Shawn Guo @ 2018-05-11 5:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180507135309.32580-1-nikita.yoush@cogentembedded.com>
On Mon, May 07, 2018 at 04:53:09PM +0300, Nikita Yushchenko wrote:
> This fixes errors in RDU1 device tree that cause touch screens not
> working.
>
> Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Applied, thanks.
^ permalink raw reply
* [PATCH v2] arm64: allwinner: a64: Add Amarula A64 Relic initial support
From: Chen-Yu Tsai @ 2018-05-11 5:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511054307.3410-1-jagan@amarulasolutions.com>
On Thu, May 10, 2018 at 10:43 PM, Jagan Teki <jagan@amarulasolutions.com> wrote:
> Amarula A64 Relic is Allwinner A64 based IoT device, which support
> - Allwinner A64 Cortex-A53
> - Mali-400MP2 GPU
> - AXP803 PMIC
> - 1GB DDR3 RAM
> - 8GB eMMC
> - AP6330 Wifi/BLE
> - MIPI-DSI
> - CSI: OV5640 sensor
> - USB OTG
> - 12V DC power supply
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> ---
> Changes for v2:
> - Rename dts name to sun50i-a64-relic.dts which is simple to use
This is subjective. For other users this hardly qualifies to
identify the board. Please keep the vendor / brand name in
the file name.
ChenYu
^ permalink raw reply
* [PATCH v2] arm64: allwinner: a64: Add Amarula A64 Relic initial support
From: Jagan Teki @ 2018-05-11 6:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGb2v67ZDUqLGiWfocZXzGY54dYcSVUMC-xz87xaJQs88-nqyw@mail.gmail.com>
On Fri, May 11, 2018 at 11:20 AM, Chen-Yu Tsai <wens@csie.org> wrote:
> On Thu, May 10, 2018 at 10:43 PM, Jagan Teki <jagan@amarulasolutions.com> wrote:
>> Amarula A64 Relic is Allwinner A64 based IoT device, which support
>> - Allwinner A64 Cortex-A53
>> - Mali-400MP2 GPU
>> - AXP803 PMIC
>> - 1GB DDR3 RAM
>> - 8GB eMMC
>> - AP6330 Wifi/BLE
>> - MIPI-DSI
>> - CSI: OV5640 sensor
>> - USB OTG
>> - 12V DC power supply
>>
>> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
>> ---
>> Changes for v2:
>> - Rename dts name to sun50i-a64-relic.dts which is simple to use
>
> This is subjective. For other users this hardly qualifies to
> identify the board. Please keep the vendor / brand name in
> the file name.
Which I thought initially, but adding vendor makes long string which
become lengthy for next boards to add it in future. So we make
notation with <SOC_name>_<board_name> like sun50i-a64-teres-i.dts
does.
^ permalink raw reply
* [PATCH v2 26/26] drm/bridge: establish a link between the bridge supplier and consumer
From: Peter Rosin @ 2018-05-11 7:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <a723ad4a-8caa-4ff5-d39d-52db98a56d7b@samsung.com>
On 2018-05-10 10:10, Andrzej Hajda wrote:
> On 04.05.2018 15:52, Peter Rosin wrote:
>> If the bridge supplier is unbound, this will bring the bridge consumer
>> down along with the bridge. Thus, there will no longer linger any
>> dangling pointers from the bridge consumer (the drm_device) to some
>> non-existent bridge supplier.
>>
>> Signed-off-by: Peter Rosin <peda@axentia.se>
>> ---
>> drivers/gpu/drm/drm_bridge.c | 18 ++++++++++++++++++
>> include/drm/drm_bridge.h | 2 ++
>> 2 files changed, 20 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>> index 78d186b6831b..0259f0a3ff27 100644
>> --- a/drivers/gpu/drm/drm_bridge.c
>> +++ b/drivers/gpu/drm/drm_bridge.c
>> @@ -26,6 +26,7 @@
>> #include <linux/mutex.h>
>>
>> #include <drm/drm_bridge.h>
>> +#include <drm/drm_device.h>
>> #include <drm/drm_encoder.h>
>>
>> #include "drm_crtc_internal.h"
>> @@ -127,12 +128,25 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
>> if (bridge->dev)
>> return -EBUSY;
>>
>> + if (encoder->dev->dev != bridge->odev) {
>
> I wonder why device_link_add does not handle this case (self dependency)
> silently as noop, as it seems to be a correct behavior.
It's kind-of a silly corner-case though, so perfectly understandable
that it isn't handled.
>> + bridge->link = device_link_add(encoder->dev->dev,
>> + bridge->odev, 0);
>> + if (!bridge->link) {
>> + dev_err(bridge->odev, "failed to link bridge to %s\n",
>> + dev_name(encoder->dev->dev));
>> + return -EINVAL;
>> + }
>> + }
>> +
>> bridge->dev = encoder->dev;
>> bridge->encoder = encoder;
>>
>> if (bridge->funcs->attach) {
>> ret = bridge->funcs->attach(bridge);
>> if (ret < 0) {
>> + if (bridge->link)
>> + device_link_del(bridge->link);
>> + bridge->link = NULL;
>> bridge->dev = NULL;
>> bridge->encoder = NULL;
>> return ret;
>> @@ -159,6 +173,10 @@ void drm_bridge_detach(struct drm_bridge *bridge)
>> if (bridge->funcs->detach)
>> bridge->funcs->detach(bridge);
>>
>> + if (bridge->link)
>> + device_link_del(bridge->link);
>> + bridge->link = NULL;
>> +
>> bridge->dev = NULL;
>> }
>>
>> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
>> index b656e505d11e..804189c63a4c 100644
>> --- a/include/drm/drm_bridge.h
>> +++ b/include/drm/drm_bridge.h
>> @@ -261,6 +261,7 @@ struct drm_bridge_timings {
>> * @list: to keep track of all added bridges
>> * @timings: the timing specification for the bridge, if any (may
>> * be NULL)
>> + * @link: drm consumer <-> bridge supplier
>
> Nitpick: "<->" suggests symmetry, maybe "device link from drm consumer
> to the bridge" would be better.
I meant "<->" to indicate that the link is bidirectional, not that the
relationship is in any way symmetric. I wasn't aware of any implication
of a symmetric relationship when using "<->", do you have a reference?
But I guess the different arrow notations in math are somewhat overloaded
and that someone at some point must have used "<->" to indicate a
symmetric relationship...
> Anyway:
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Thanks!
Cheers,
Peter
> ?--
> Regards
> Andrzej
>
>> * @funcs: control functions
>> * @driver_private: pointer to the bridge driver's internal context
>> */
>> @@ -271,6 +272,7 @@ struct drm_bridge {
>> struct drm_bridge *next;
>> struct list_head list;
>> const struct drm_bridge_timings *timings;
>> + struct device_link *link;
>>
>> const struct drm_bridge_funcs *funcs;
>> void *driver_private;
>
>
^ permalink raw reply
* [PATCH 01/11] irqchip: stm32: Optimizes and cleans up stm32-exti irq_domain
From: Ludovic BARRE @ 2018-05-11 7:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20a1b5f0-7494-01a9-635f-c46c337a23b3@arm.com>
On 05/08/2018 04:47 PM, Marc Zyngier wrote:
> On 26/04/18 17:18, Ludovic Barre wrote:
>> From: radek <radoslaw.pietrzyk@gmail.com>
>>
>> - In stm32_exti_alloc function, discards irq_domain_set_info
>> with handle_simple_irq. This overwrite the setting defined while init
>> of generic chips. Exti controller manages edge irq type.
>> - Removes acking in chained irq handler as this is done by
>> irq_chip itself inside handle_edge_irq
>> - removes unneeded irq_domain_ops.xlate callback
>>
>> Signed-off-by: Radoslaw Pietrzyk <radoslaw.pietrzyk@gmail.com>
>> Acked-by: Ludovic Barre <ludovic.barre@st.com>
>> Tested-by: Ludovic Barre <ludovic.barre@st.com>
>> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
>
> Nit: the "From:" should match the SoB line (the address does, but not
> the name). I can fix that up when I apply the series.
>
Thanks
> Thanks,
>
> M.
>
^ permalink raw reply
* common non-cache coherent direct dma mapping ops
From: Christoph Hellwig @ 2018-05-11 7:59 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
this series continues consolidating the dma-mapping code, with a focus
on architectures that do not (always) provide cache coherence for DMA.
Three architectures (arm, mips and powerpc) are still left to be
converted later due to complexity of their dma ops selection.
The dma-noncoherent ops calls the dma-direct ops for the actual
translation of streaming mappins and allow the architecture to provide
any cache flushing required for cpu to device and/or device to cpu
ownership transfers. The dma coherent allocator is for now still left
entirely to architecture supplied implementations due the amount of
variations. Hopefully we can do some consolidation for them later on
as well.
A lot of architectures are currently doing very questionable things
in their dma mapping routines, which are documented in the changelogs
for each patch. Please review them very careful and correct me on
incorrect assumptions.
Because this series sits on top of two previously submitted series
a git tree might be useful to actually test it. It is provided here:
git://git.infradead.org/users/hch/misc.git generic-dma-noncoherent
Gitweb:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/generic-dma-noncoherent
Changes since RFC:
- fix a typo accidentally disabling the device to cpu transfer sync
- fixed a few compile failures
^ permalink raw reply
* [PATCH 01/20] dma-mapping: simplify Kconfig dependencies
From: Christoph Hellwig @ 2018-05-11 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511075945.16548-1-hch@lst.de>
ARCH_DMA_ADDR_T_64BIT is always true for 64-bit architectures now, so we
can skip the clause requiring it. 'n' is the default default, so no need
to explicitly state it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
lib/Kconfig | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/lib/Kconfig b/lib/Kconfig
index 1d84e61cccfe..6c4e9d0ce5d1 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -443,13 +443,11 @@ config IOMMU_HELPER
config DMA_DIRECT_OPS
bool
- depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT)
- default n
+ depends on HAS_DMA
config DMA_VIRT_OPS
bool
- depends on HAS_DMA && (!64BIT || ARCH_DMA_ADDR_T_64BIT)
- default n
+ depends on HAS_DMA
config SWIOTLB
bool
--
2.17.0
^ permalink raw reply related
* [PATCH 02/20] dma-mapping: provide a generic dma-noncoherent implementation
From: Christoph Hellwig @ 2018-05-11 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511075945.16548-1-hch@lst.de>
Add a new dma_map_ops implementation that uses dma-direct for the
address mapping of streaming mappings, and which requires arch-specific
implemenations of coherent allocate/free.
Architectures have to provide flushing helpers to ownership trasnfers
to the device and/or CPU, and can provide optional implementations of
the coherent mmap functionality, and the cache_flush routines for
non-coherent long term allocations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
MAINTAINERS | 2 +
include/asm-generic/dma-mapping.h | 9 +++
include/linux/dma-direct.h | 7 ++-
include/linux/dma-mapping.h | 1 +
include/linux/dma-noncoherent.h | 47 ++++++++++++++
lib/Kconfig | 20 ++++++
lib/Makefile | 1 +
lib/dma-direct.c | 8 +--
lib/dma-noncoherent.c | 101 ++++++++++++++++++++++++++++++
9 files changed, 191 insertions(+), 5 deletions(-)
create mode 100644 include/linux/dma-noncoherent.h
create mode 100644 lib/dma-noncoherent.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 79bb02ff812f..08d0d15d4958 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4334,12 +4334,14 @@ W: http://git.infradead.org/users/hch/dma-mapping.git
S: Supported
F: lib/dma-debug.c
F: lib/dma-direct.c
+F: lib/dma-noncoherent.c
F: lib/dma-virt.c
F: drivers/base/dma-mapping.c
F: drivers/base/dma-coherent.c
F: include/asm-generic/dma-mapping.h
F: include/linux/dma-direct.h
F: include/linux/dma-mapping.h
+F: include/linux/dma-noncoherent.h
DME1737 HARDWARE MONITOR DRIVER
M: Juerg Haefliger <juergh@gmail.com>
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 880a292d792f..ad2868263867 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -4,7 +4,16 @@
static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
{
+ /*
+ * Use the non-coherent ops if available. If an architecture wants a
+ * more fine-grained selection of operations it will have to implement
+ * get_arch_dma_ops itself or use the per-device dma_ops.
+ */
+#ifdef CONFIG_DMA_NONCOHERENT_OPS
+ return &dma_noncoherent_ops;
+#else
return &dma_direct_ops;
+#endif
}
#endif /* _ASM_GENERIC_DMA_MAPPING_H */
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 53ad6a47f513..8d9f33febde5 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -59,6 +59,11 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t gfp, unsigned long attrs);
void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_addr, unsigned long attrs);
+dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ unsigned long attrs);
+int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
+ enum dma_data_direction dir, unsigned long attrs);
int dma_direct_supported(struct device *dev, u64 mask);
-
+int dma_direct_mapping_error(struct device *dev, dma_addr_t dma_addr);
#endif /* _LINUX_DMA_DIRECT_H */
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 25a9a2b04f78..4be070df5fc5 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -136,6 +136,7 @@ struct dma_map_ops {
};
extern const struct dma_map_ops dma_direct_ops;
+extern const struct dma_map_ops dma_noncoherent_ops;
extern const struct dma_map_ops dma_virt_ops;
#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
new file mode 100644
index 000000000000..10b2654d549b
--- /dev/null
+++ b/include/linux/dma-noncoherent.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_DMA_NONCOHERENT_H
+#define _LINUX_DMA_NONCOHERENT_H 1
+
+#include <linux/dma-mapping.h>
+
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs);
+void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t dma_addr, unsigned long attrs);
+
+#ifdef CONFIG_DMA_NONCOHERENT_MMAP
+int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ unsigned long attrs);
+#else
+#define arch_dma_mmap NULL
+#endif /* CONFIG_DMA_NONCOHERENT_MMAP */
+
+#ifdef CONFIG_DMA_NONCOHERENT_CACHE_SYNC
+void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction);
+#else
+#define arch_dma_cache_sync NULL
+#endif /* CONFIG_DMA_NONCOHERENT_CACHE_SYNC */
+
+#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir);
+#else
+static inline void arch_sync_dma_for_device(struct device *dev,
+ phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+}
+#endif /* ARCH_HAS_SYNC_DMA_FOR_DEVICE */
+
+#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir);
+#else
+static inline void arch_sync_dma_for_cpu(struct device *dev,
+ phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+}
+#endif /* ARCH_HAS_SYNC_DMA_FOR_CPU */
+
+#endif /* _LINUX_DMA_NONCOHERENT_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 6c4e9d0ce5d1..7a913937888b 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -441,10 +441,30 @@ config ARCH_DMA_ADDR_T_64BIT
config IOMMU_HELPER
bool
+config ARCH_HAS_SYNC_DMA_FOR_DEVICE
+ bool
+
+config ARCH_HAS_SYNC_DMA_FOR_CPU
+ bool
+ select NEED_DMA_MAP_STATE
+
config DMA_DIRECT_OPS
bool
depends on HAS_DMA
+config DMA_NONCOHERENT_OPS
+ bool
+ depends on HAS_DMA
+ select DMA_DIRECT_OPS
+
+config DMA_NONCOHERENT_MMAP
+ bool
+ depends on DMA_NONCOHERENT_OPS
+
+config DMA_NONCOHERENT_CACHE_SYNC
+ bool
+ depends on DMA_NONCOHERENT_OPS
+
config DMA_VIRT_OPS
bool
depends on HAS_DMA
diff --git a/lib/Makefile b/lib/Makefile
index 94203b5eecd4..9f18c8152281 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -30,6 +30,7 @@ lib-$(CONFIG_PRINTK) += dump_stack.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
lib-$(CONFIG_DMA_DIRECT_OPS) += dma-direct.o
+lib-$(CONFIG_DMA_NONCOHERENT_OPS) += dma-noncoherent.o
lib-$(CONFIG_DMA_VIRT_OPS) += dma-virt.o
lib-y += kobject.o klist.o
diff --git a/lib/dma-direct.c b/lib/dma-direct.c
index df9e726e0712..b824eb218782 100644
--- a/lib/dma-direct.c
+++ b/lib/dma-direct.c
@@ -128,7 +128,7 @@ void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
free_pages((unsigned long)cpu_addr, page_order);
}
-static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
+dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir,
unsigned long attrs)
{
@@ -139,8 +139,8 @@ static dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
return dma_addr;
}
-static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction dir, unsigned long attrs)
+int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
+ enum dma_data_direction dir, unsigned long attrs)
{
int i;
struct scatterlist *sg;
@@ -175,7 +175,7 @@ int dma_direct_supported(struct device *dev, u64 mask)
return 1;
}
-static int dma_direct_mapping_error(struct device *dev, dma_addr_t dma_addr)
+int dma_direct_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
return dma_addr == DIRECT_MAPPING_ERROR;
}
diff --git a/lib/dma-noncoherent.c b/lib/dma-noncoherent.c
new file mode 100644
index 000000000000..a2c192b3508d
--- /dev/null
+++ b/lib/dma-noncoherent.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Christoph Hellwig.
+ *
+ * DMA operations that map physical memory directly without providing cache
+ * coherence.
+ */
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/dma-direct.h>
+#include <linux/dma-noncoherent.h>
+#include <linux/scatterlist.h>
+
+static void dma_noncoherent_sync_single_for_device(struct device *dev,
+ dma_addr_t addr, size_t size, enum dma_data_direction dir)
+{
+ arch_sync_dma_for_device(dev, dma_to_phys(dev, addr), size, dir);
+}
+
+static void dma_noncoherent_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sgl, int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sgl, sg, nents, i)
+ arch_sync_dma_for_device(dev, sg_phys(sg), sg->length, dir);
+}
+
+static dma_addr_t dma_noncoherent_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ dma_addr_t addr;
+
+ addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
+ if (!dma_mapping_error(dev, addr) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+ arch_sync_dma_for_device(dev, page_to_phys(page), size, dir);
+ return addr;
+}
+
+static int dma_noncoherent_map_sg(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction dir, unsigned long attrs)
+{
+ nents = dma_direct_map_sg(dev, sgl, nents, dir, attrs);
+ if (nents > 0 && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+ dma_noncoherent_sync_sg_for_device(dev, sgl, nents, dir);
+ return nents;
+}
+
+#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
+static void dma_noncoherent_sync_single_for_cpu(struct device *dev,
+ dma_addr_t addr, size_t size, enum dma_data_direction dir)
+{
+ arch_sync_dma_for_cpu(dev, dma_to_phys(dev, addr), size, dir);
+}
+
+static void dma_noncoherent_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sgl, int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sgl, sg, nents, i)
+ arch_sync_dma_for_cpu(dev, sg_phys(sg), sg->length, dir);
+}
+
+static void dma_noncoherent_unmap_page(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir, unsigned long attrs)
+{
+ if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+ dma_noncoherent_sync_single_for_cpu(dev, addr, size, dir);
+}
+
+static void dma_noncoherent_unmap_sg(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction dir, unsigned long attrs)
+{
+ if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+ dma_noncoherent_sync_sg_for_cpu(dev, sgl, nents, dir);
+}
+#endif
+
+const struct dma_map_ops dma_noncoherent_ops = {
+ .alloc = arch_dma_alloc,
+ .free = arch_dma_free,
+ .mmap = arch_dma_mmap,
+ .sync_single_for_device = dma_noncoherent_sync_single_for_device,
+ .sync_sg_for_device = dma_noncoherent_sync_sg_for_device,
+ .map_page = dma_noncoherent_map_page,
+ .map_sg = dma_noncoherent_map_sg,
+#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU
+ .sync_single_for_cpu = dma_noncoherent_sync_single_for_cpu,
+ .sync_sg_for_cpu = dma_noncoherent_sync_sg_for_cpu,
+ .unmap_page = dma_noncoherent_unmap_page,
+ .unmap_sg = dma_noncoherent_unmap_sg,
+#endif
+ .dma_supported = dma_direct_supported,
+ .mapping_error = dma_direct_mapping_error,
+ .cache_sync = arch_dma_cache_sync,
+};
+EXPORT_SYMBOL(dma_noncoherent_ops);
--
2.17.0
^ permalink raw reply related
* [PATCH 03/20] arc: use generic dma_noncoherent_ops
From: Christoph Hellwig @ 2018-05-11 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511075945.16548-1-hch@lst.de>
Switch to the generic noncoherent direct mapping implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arc/Kconfig | 4 +
arch/arc/include/asm/Kbuild | 1 +
arch/arc/include/asm/dma-mapping.h | 21 -----
arch/arc/mm/dma.c | 141 +++--------------------------
4 files changed, 19 insertions(+), 148 deletions(-)
delete mode 100644 arch/arc/include/asm/dma-mapping.h
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 7498aca4b887..89d47eac18b2 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -9,11 +9,15 @@
config ARC
def_bool y
select ARC_TIMERS
+ select ARCH_HAS_SYNC_DMA_FOR_CPU
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_SG_CHAIN
select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
select BUILDTIME_EXTABLE_SORT
select CLONE_BACKWARDS
select COMMON_CLK
+ select DMA_NONCOHERENT_OPS
+ select DMA_NONCOHERENT_MMAP
select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
select GENERIC_CLOCKEVENTS
select GENERIC_FIND_FIRST_BIT
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
index 4bd5d4369e05..bbdcb955e18f 100644
--- a/arch/arc/include/asm/Kbuild
+++ b/arch/arc/include/asm/Kbuild
@@ -2,6 +2,7 @@
generic-y += bugs.h
generic-y += device.h
generic-y += div64.h
+generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += extable.h
generic-y += fb.h
diff --git a/arch/arc/include/asm/dma-mapping.h b/arch/arc/include/asm/dma-mapping.h
deleted file mode 100644
index 7a16824bfe98..000000000000
--- a/arch/arc/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * DMA Mapping glue for ARC
- *
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef ASM_ARC_DMA_MAPPING_H
-#define ASM_ARC_DMA_MAPPING_H
-
-extern const struct dma_map_ops arc_dma_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
- return &arc_dma_ops;
-}
-
-#endif
diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 1dcc404b5aec..e4cd485517b4 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -16,13 +16,12 @@
* The default DMA address == Phy address which is 0x8000_0000 based.
*/
-#include <linux/dma-mapping.h>
+#include <linux/dma-noncoherent.h>
#include <asm/cache.h>
#include <asm/cacheflush.h>
-
-static void *arc_dma_alloc(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs)
{
unsigned long order = get_order(size);
struct page *page;
@@ -89,7 +88,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,
return kvaddr;
}
-static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, unsigned long attrs)
{
phys_addr_t paddr = dma_handle;
@@ -105,9 +104,9 @@ static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
__free_pages(page, get_order(size));
}
-static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size,
- unsigned long attrs)
+int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ unsigned long attrs)
{
unsigned long user_count = vma_pages(vma);
unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
@@ -135,7 +134,7 @@ static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
* CPU accesses page via normal paddr, thus needs to explicitly made
* consistent before each use
*/
-static void _dma_cache_sync(phys_addr_t paddr, size_t size,
+static void _dma_cache_sync(struct device *dev, phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
{
switch (dir) {
@@ -153,126 +152,14 @@ static void _dma_cache_sync(phys_addr_t paddr, size_t size,
}
}
-/*
- * arc_dma_map_page - map a portion of a page for streaming DMA
- *
- * Ensure that any data held in the cache is appropriately discarded
- * or written back.
- *
- * The device owns this memory once this call has completed. The CPU
- * can regain ownership by calling dma_unmap_page().
- *
- * Note: while it takes struct page as arg, caller can "abuse" it to pass
- * a region larger than PAGE_SIZE, provided it is physically contiguous
- * and this still works correctly
- */
-static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction dir,
- unsigned long attrs)
-{
- phys_addr_t paddr = page_to_phys(page) + offset;
-
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- _dma_cache_sync(paddr, size, dir);
-
- return paddr;
-}
-
-/*
- * arc_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- *
- * Note: historically this routine was not implemented for ARC
- */
-static void arc_dma_unmap_page(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir,
- unsigned long attrs)
-{
- phys_addr_t paddr = handle;
-
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- _dma_cache_sync(paddr, size, dir);
-}
-
-static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir, unsigned long attrs)
-{
- struct scatterlist *s;
- int i;
-
- for_each_sg(sg, s, nents, i)
- s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
- s->length, dir);
-
- return nents;
-}
-
-static void arc_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
-{
- struct scatterlist *s;
- int i;
-
- for_each_sg(sg, s, nents, i)
- arc_dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir,
- attrs);
-}
-
-static void arc_dma_sync_single_for_cpu(struct device *dev,
- dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
-{
- _dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE);
-}
-
-static void arc_dma_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle, size_t size, enum dma_data_direction dir)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
- _dma_cache_sync(dma_handle, size, DMA_TO_DEVICE);
+ return _dma_cache_sync(dev, paddr, size, dir);
}
-static void arc_dma_sync_sg_for_cpu(struct device *dev,
- struct scatterlist *sglist, int nelems,
- enum dma_data_direction dir)
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nelems, i)
- _dma_cache_sync(sg_phys(sg), sg->length, dir);
+ return _dma_cache_sync(dev, paddr, size, dir);
}
-
-static void arc_dma_sync_sg_for_device(struct device *dev,
- struct scatterlist *sglist, int nelems,
- enum dma_data_direction dir)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sglist, sg, nelems, i)
- _dma_cache_sync(sg_phys(sg), sg->length, dir);
-}
-
-static int arc_dma_supported(struct device *dev, u64 dma_mask)
-{
- /* Support 32 bit DMA mask exclusively */
- return dma_mask == DMA_BIT_MASK(32);
-}
-
-const struct dma_map_ops arc_dma_ops = {
- .alloc = arc_dma_alloc,
- .free = arc_dma_free,
- .mmap = arc_dma_mmap,
- .map_page = arc_dma_map_page,
- .unmap_page = arc_dma_unmap_page,
- .map_sg = arc_dma_map_sg,
- .unmap_sg = arc_dma_unmap_sg,
- .sync_single_for_device = arc_dma_sync_single_for_device,
- .sync_single_for_cpu = arc_dma_sync_single_for_cpu,
- .sync_sg_for_cpu = arc_dma_sync_sg_for_cpu,
- .sync_sg_for_device = arc_dma_sync_sg_for_device,
- .dma_supported = arc_dma_supported,
-};
-EXPORT_SYMBOL(arc_dma_ops);
--
2.17.0
^ permalink raw reply related
* [PATCH 04/20] arm-nommu: use generic dma_noncoherent_ops
From: Christoph Hellwig @ 2018-05-11 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511075945.16548-1-hch@lst.de>
Switch to the generic noncoherent direct mapping implementation for
the nommu dma map implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arc/Kconfig | 1 +
arch/arm/Kconfig | 4 +
arch/arm/mm/dma-mapping-nommu.c | 139 +++++---------------------------
3 files changed, 23 insertions(+), 121 deletions(-)
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 89d47eac18b2..3a492a9aeaad 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -9,6 +9,7 @@
config ARC
def_bool y
select ARC_TIMERS
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_SG_CHAIN
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c43f5bb55ac8..76ddd0064f87 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -12,6 +12,8 @@ config ARM
select ARCH_HAS_PHYS_TO_DMA
select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL
select ARCH_HAS_STRICT_MODULE_RWX if MMU
+ select ARCH_HAS_SYNC_DMA_FOR_CPU if !MMU
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE if !MMU
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAVE_CUSTOM_GPIO_H
select ARCH_HAS_GCOV_PROFILE_ALL
@@ -27,6 +29,8 @@ config ARM
select CPU_PM if (SUSPEND || CPU_IDLE)
select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
select DMA_DIRECT_OPS if !MMU
+ select DMA_NONCOHERENT_OPS if !MMU
+ select DMA_NONCOHERENT_MMAP if !MMU
select EDAC_SUPPORT
select EDAC_ATOMIC_SCRUB
select GENERIC_ALLOCATOR
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
index f448a0663b10..a74ed6632982 100644
--- a/arch/arm/mm/dma-mapping-nommu.c
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -12,6 +12,7 @@
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/dma-direct.h>
+#include <linux/dma-noncoherent.h>
#include <linux/scatterlist.h>
#include <asm/cachetype.h>
@@ -26,18 +27,16 @@
* - MMU/MPU is off
* - cpu is v7m w/o cache support
* - device is coherent
- * otherwise arm_nommu_dma_ops is used.
+ * otherwise dma_noncoherent_ops is used.
*
- * arm_nommu_dma_ops rely on consistent DMA memory (please, refer to
+ * dma_noncoherent_ops rely on consistent DMA memory (please, refer to
* [1] on how to declare such memory).
*
* [1] Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
*/
-static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp,
- unsigned long attrs)
-
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs)
{
void *ret;
@@ -65,9 +64,8 @@ static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
return ret;
}
-static void arm_nommu_dma_free(struct device *dev, size_t size,
- void *cpu_addr, dma_addr_t dma_addr,
- unsigned long attrs)
+void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t dma_addr, unsigned long attrs)
{
if (attrs & DMA_ATTR_NON_CONSISTENT) {
dma_direct_free(dev, size, cpu_addr, dma_addr, attrs);
@@ -81,9 +79,9 @@ static void arm_nommu_dma_free(struct device *dev, size_t size,
return;
}
-static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size,
- unsigned long attrs)
+int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ unsigned long attrs)
{
int ret;
@@ -93,9 +91,8 @@ static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
}
-
-static void __dma_page_cpu_to_dev(phys_addr_t paddr, size_t size,
- enum dma_data_direction dir)
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
dmac_map_area(__va(paddr), size, dir);
@@ -105,8 +102,8 @@ static void __dma_page_cpu_to_dev(phys_addr_t paddr, size_t size,
outer_clean_range(paddr, paddr + size);
}
-static void __dma_page_dev_to_cpu(phys_addr_t paddr, size_t size,
- enum dma_data_direction dir)
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
{
if (dir != DMA_TO_DEVICE) {
outer_inv_range(paddr, paddr + size);
@@ -114,110 +111,9 @@ static void __dma_page_dev_to_cpu(phys_addr_t paddr, size_t size,
}
}
-static dma_addr_t arm_nommu_dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir,
- unsigned long attrs)
-{
- dma_addr_t handle = page_to_phys(page) + offset;
-
- __dma_page_cpu_to_dev(handle, size, dir);
-
- return handle;
-}
-
-static void arm_nommu_dma_unmap_page(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir,
- unsigned long attrs)
-{
- __dma_page_dev_to_cpu(handle, size, dir);
-}
-
-
-static int arm_nommu_dma_map_sg(struct device *dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
-{
- int i;
- struct scatterlist *sg;
-
- for_each_sg(sgl, sg, nents, i) {
- sg_dma_address(sg) = sg_phys(sg);
- sg_dma_len(sg) = sg->length;
- __dma_page_cpu_to_dev(sg_dma_address(sg), sg_dma_len(sg), dir);
- }
-
- return nents;
-}
-
-static void arm_nommu_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction dir,
- unsigned long attrs)
-{
- struct scatterlist *sg;
- int i;
-
- for_each_sg(sgl, sg, nents, i)
- __dma_page_dev_to_cpu(sg_dma_address(sg), sg_dma_len(sg), dir);
-}
-
-static void arm_nommu_dma_sync_single_for_device(struct device *dev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- __dma_page_cpu_to_dev(handle, size, dir);
-}
-
-static void arm_nommu_dma_sync_single_for_cpu(struct device *dev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- __dma_page_cpu_to_dev(handle, size, dir);
-}
-
-static void arm_nommu_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction dir)
-{
- struct scatterlist *sg;
- int i;
-
- for_each_sg(sgl, sg, nents, i)
- __dma_page_cpu_to_dev(sg_dma_address(sg), sg_dma_len(sg), dir);
-}
-
-static void arm_nommu_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
- int nents, enum dma_data_direction dir)
-{
- struct scatterlist *sg;
- int i;
-
- for_each_sg(sgl, sg, nents, i)
- __dma_page_dev_to_cpu(sg_dma_address(sg), sg_dma_len(sg), dir);
-}
-
-const struct dma_map_ops arm_nommu_dma_ops = {
- .alloc = arm_nommu_dma_alloc,
- .free = arm_nommu_dma_free,
- .mmap = arm_nommu_dma_mmap,
- .map_page = arm_nommu_dma_map_page,
- .unmap_page = arm_nommu_dma_unmap_page,
- .map_sg = arm_nommu_dma_map_sg,
- .unmap_sg = arm_nommu_dma_unmap_sg,
- .sync_single_for_device = arm_nommu_dma_sync_single_for_device,
- .sync_single_for_cpu = arm_nommu_dma_sync_single_for_cpu,
- .sync_sg_for_device = arm_nommu_dma_sync_sg_for_device,
- .sync_sg_for_cpu = arm_nommu_dma_sync_sg_for_cpu,
-};
-EXPORT_SYMBOL(arm_nommu_dma_ops);
-
-static const struct dma_map_ops *arm_nommu_get_dma_map_ops(bool coherent)
-{
- return coherent ? &dma_direct_ops : &arm_nommu_dma_ops;
-}
-
void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
const struct iommu_ops *iommu, bool coherent)
{
- const struct dma_map_ops *dma_ops;
-
if (IS_ENABLED(CONFIG_CPU_V7M)) {
/*
* Cache support for v7m is optional, so can be treated as
@@ -233,9 +129,10 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
dev->archdata.dma_coherent = (get_cr() & CR_M) ? coherent : true;
}
- dma_ops = arm_nommu_get_dma_map_ops(dev->archdata.dma_coherent);
-
- set_dma_ops(dev, dma_ops);
+ if (dev->archdata.dma_coherent)
+ set_dma_ops(dev, &dma_direct_ops);
+ else
+ set_dma_ops(dev, &dma_noncoherent_ops);
}
void arch_teardown_dma_ops(struct device *dev)
--
2.17.0
^ permalink raw reply related
* [PATCH 05/20] c6x: use generic dma_noncoherent_ops
From: Christoph Hellwig @ 2018-05-11 7:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511075945.16548-1-hch@lst.de>
Switch to the generic noncoherent direct mapping implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/c6x/Kconfig | 3 +
arch/c6x/include/asm/Kbuild | 1 +
arch/c6x/include/asm/dma-mapping.h | 28 ------
arch/c6x/include/asm/setup.h | 2 +
arch/c6x/kernel/Makefile | 2 +-
arch/c6x/kernel/dma.c | 138 -----------------------------
arch/c6x/mm/dma-coherent.c | 40 ++++++++-
7 files changed, 44 insertions(+), 170 deletions(-)
delete mode 100644 arch/c6x/include/asm/dma-mapping.h
delete mode 100644 arch/c6x/kernel/dma.c
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 8c088b96e372..bf59855628ac 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -6,7 +6,10 @@
config C6X
def_bool y
+ select ARCH_HAS_SYNC_DMA_FOR_CPU
+ select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select CLKDEV_LOOKUP
+ select DMA_NONCOHERENT_OPS
select GENERIC_ATOMIC64
select GENERIC_IRQ_SHOW
select HAVE_ARCH_TRACEHOOK
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index fd4c840de837..434600e47662 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -5,6 +5,7 @@ generic-y += current.h
generic-y += device.h
generic-y += div64.h
generic-y += dma.h
+generic-y += dma-mapping.h
generic-y += emergency-restart.h
generic-y += exec.h
generic-y += extable.h
diff --git a/arch/c6x/include/asm/dma-mapping.h b/arch/c6x/include/asm/dma-mapping.h
deleted file mode 100644
index 05daf1038111..000000000000
--- a/arch/c6x/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Port on Texas Instruments TMS320C6x architecture
- *
- * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
- * Author: Aurelien Jacquiot <aurelien.jacquiot@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#ifndef _ASM_C6X_DMA_MAPPING_H
-#define _ASM_C6X_DMA_MAPPING_H
-
-extern const struct dma_map_ops c6x_dma_ops;
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
- return &c6x_dma_ops;
-}
-
-extern void coherent_mem_init(u32 start, u32 size);
-void *c6x_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
- gfp_t gfp, unsigned long attrs);
-void c6x_dma_free(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle, unsigned long attrs);
-
-#endif /* _ASM_C6X_DMA_MAPPING_H */
diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h
index 852afb209afb..350f34debb19 100644
--- a/arch/c6x/include/asm/setup.h
+++ b/arch/c6x/include/asm/setup.h
@@ -28,5 +28,7 @@ extern unsigned char c6x_fuse_mac[6];
extern void machine_init(unsigned long dt_ptr);
extern void time_init(void);
+extern void coherent_mem_init(u32 start, u32 size);
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_C6X_SETUP_H */
diff --git a/arch/c6x/kernel/Makefile b/arch/c6x/kernel/Makefile
index 02f340d7b8fe..fbe74174de87 100644
--- a/arch/c6x/kernel/Makefile
+++ b/arch/c6x/kernel/Makefile
@@ -8,6 +8,6 @@ extra-y := head.o vmlinux.lds
obj-y := process.o traps.o irq.o signal.o ptrace.o
obj-y += setup.o sys_c6x.o time.o devicetree.o
obj-y += switch_to.o entry.o vectors.o c6x_ksyms.o
-obj-y += soc.o dma.o
+obj-y += soc.o
obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/c6x/kernel/dma.c b/arch/c6x/kernel/dma.c
deleted file mode 100644
index 31e1a9ec3a9c..000000000000
--- a/arch/c6x/kernel/dma.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2011 Texas Instruments Incorporated
- * Author: Mark Salter <msalter@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/mm_types.h>
-#include <linux/scatterlist.h>
-
-#include <asm/cacheflush.h>
-
-static void c6x_dma_sync(dma_addr_t handle, size_t size,
- enum dma_data_direction dir)
-{
- unsigned long paddr = handle;
-
- BUG_ON(!valid_dma_direction(dir));
-
- switch (dir) {
- case DMA_FROM_DEVICE:
- L2_cache_block_invalidate(paddr, paddr + size);
- break;
- case DMA_TO_DEVICE:
- L2_cache_block_writeback(paddr, paddr + size);
- break;
- case DMA_BIDIRECTIONAL:
- L2_cache_block_writeback_invalidate(paddr, paddr + size);
- break;
- default:
- break;
- }
-}
-
-static dma_addr_t c6x_dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction dir,
- unsigned long attrs)
-{
- dma_addr_t handle = virt_to_phys(page_address(page) + offset);
-
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- c6x_dma_sync(handle, size, dir);
-
- return handle;
-}
-
-static void c6x_dma_unmap_page(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir, unsigned long attrs)
-{
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- c6x_dma_sync(handle, size, dir);
-}
-
-static int c6x_dma_map_sg(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir, unsigned long attrs)
-{
- struct scatterlist *sg;
- int i;
-
- for_each_sg(sglist, sg, nents, i) {
- sg->dma_address = sg_phys(sg);
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
- c6x_dma_sync(sg->dma_address, sg->length, dir);
- }
-
- return nents;
-}
-
-static void c6x_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
- int nents, enum dma_data_direction dir, unsigned long attrs)
-{
- struct scatterlist *sg;
- int i;
-
- if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
- return;
-
- for_each_sg(sglist, sg, nents, i)
- c6x_dma_sync(sg_dma_address(sg), sg->length, dir);
-}
-
-static void c6x_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- c6x_dma_sync(handle, size, dir);
-
-}
-
-static void c6x_dma_sync_single_for_device(struct device *dev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- c6x_dma_sync(handle, size, dir);
-
-}
-
-static void c6x_dma_sync_sg_for_cpu(struct device *dev,
- struct scatterlist *sglist, int nents,
- enum dma_data_direction dir)
-{
- struct scatterlist *sg;
- int i;
-
- for_each_sg(sglist, sg, nents, i)
- c6x_dma_sync_single_for_cpu(dev, sg_dma_address(sg),
- sg->length, dir);
-
-}
-
-static void c6x_dma_sync_sg_for_device(struct device *dev,
- struct scatterlist *sglist, int nents,
- enum dma_data_direction dir)
-{
- struct scatterlist *sg;
- int i;
-
- for_each_sg(sglist, sg, nents, i)
- c6x_dma_sync_single_for_device(dev, sg_dma_address(sg),
- sg->length, dir);
-
-}
-
-const struct dma_map_ops c6x_dma_ops = {
- .alloc = c6x_dma_alloc,
- .free = c6x_dma_free,
- .map_page = c6x_dma_map_page,
- .unmap_page = c6x_dma_unmap_page,
- .map_sg = c6x_dma_map_sg,
- .unmap_sg = c6x_dma_unmap_sg,
- .sync_single_for_device = c6x_dma_sync_single_for_device,
- .sync_single_for_cpu = c6x_dma_sync_single_for_cpu,
- .sync_sg_for_device = c6x_dma_sync_sg_for_device,
- .sync_sg_for_cpu = c6x_dma_sync_sg_for_cpu,
-};
-EXPORT_SYMBOL(c6x_dma_ops);
diff --git a/arch/c6x/mm/dma-coherent.c b/arch/c6x/mm/dma-coherent.c
index 95e38ad27c69..d0a8e0c4b27e 100644
--- a/arch/c6x/mm/dma-coherent.c
+++ b/arch/c6x/mm/dma-coherent.c
@@ -19,10 +19,12 @@
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-noncoherent.h>
#include <linux/memblock.h>
+#include <asm/cacheflush.h>
#include <asm/page.h>
+#include <asm/setup.h>
/*
* DMA coherent memory management, can be redefined using the memdma=
@@ -73,7 +75,7 @@ static void __free_dma_pages(u32 addr, int order)
* Allocate DMA coherent memory space and return both the kernel
* virtual and DMA address for that space.
*/
-void *c6x_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t gfp, unsigned long attrs)
{
u32 paddr;
@@ -98,7 +100,7 @@ void *c6x_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
/*
* Free DMA coherent memory as defined by the above mapping.
*/
-void c6x_dma_free(struct device *dev, size_t size, void *vaddr,
+void arch_dma_free(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle, unsigned long attrs)
{
int order;
@@ -139,3 +141,35 @@ void __init coherent_mem_init(phys_addr_t start, u32 size)
dma_bitmap = phys_to_virt(bitmap_phys);
memset(dma_bitmap, 0, dma_pages * PAGE_SIZE);
}
+
+static void c6x_dma_sync(struct device *dev, phys_addr_t paddr, size_t size,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+
+ switch (dir) {
+ case DMA_FROM_DEVICE:
+ L2_cache_block_invalidate(paddr, paddr + size);
+ break;
+ case DMA_TO_DEVICE:
+ L2_cache_block_writeback(paddr, paddr + size);
+ break;
+ case DMA_BIDIRECTIONAL:
+ L2_cache_block_writeback_invalidate(paddr, paddr + size);
+ break;
+ default:
+ break;
+ }
+}
+
+void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
+{
+ return c6x_dma_sync(dev, paddr, size, dir);
+}
+
+void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
+ size_t size, enum dma_data_direction dir)
+{
+ return c6x_dma_sync(dev, paddr, size, dir);
+}
--
2.17.0
^ 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