* [PATCH v2 03/20] powerpc/47x: Use pm_power_off rather than ppc_md.power_off
From: Alexander Graf @ 2014-10-13 14:01 UTC (permalink / raw)
To: linuxppc-dev; +Cc: arnd, geoff, alistair, scottwood, agust, linux
In-Reply-To: <1413208888-49211-1-git-send-email-agraf@suse.de>
The generic power off callback is pm_power_off. Use that one rather than
the powerpc specific ppc_md.power_off.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- fix typo
---
arch/powerpc/platforms/44x/ppc476.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c
index 58db9d0..c11ce65 100644
--- a/arch/powerpc/platforms/44x/ppc476.c
+++ b/arch/powerpc/platforms/44x/ppc476.c
@@ -94,7 +94,7 @@ static int avr_probe(struct i2c_client *client,
{
avr_i2c_client = client;
ppc_md.restart = avr_reset_system;
- ppc_md.power_off = avr_power_off_system;
+ pm_power_off = avr_power_off_system;
return 0;
}
--
1.8.1.4
^ permalink raw reply related
* [PATCH v2 08/20] powerpc/celleb: Use pm_power_off rather than ppc_md.power_off
From: Alexander Graf @ 2014-10-13 14:01 UTC (permalink / raw)
To: linuxppc-dev; +Cc: arnd, geoff, alistair, scottwood, agust, linux
In-Reply-To: <1413208888-49211-1-git-send-email-agraf@suse.de>
The generic power off callback is pm_power_off. Use that one rather than
the powerpc specific ppc_md.power_off.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- write pm_power_off in probe function
---
arch/powerpc/platforms/cell/celleb_setup.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c
index 34e8ce2..90be8ec 100644
--- a/arch/powerpc/platforms/cell/celleb_setup.c
+++ b/arch/powerpc/platforms/cell/celleb_setup.c
@@ -142,6 +142,7 @@ static int __init celleb_probe_beat(void)
powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS
| FW_FEATURE_BEAT | FW_FEATURE_LPAR;
hpte_init_beat_v3();
+ pm_power_off = beat_power_off;
return 1;
}
@@ -190,6 +191,7 @@ static int __init celleb_probe_native(void)
powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS;
hpte_init_native();
+ pm_power_off = rtas_power_off;
return 1;
}
@@ -204,7 +206,6 @@ define_machine(celleb_beat) {
.setup_arch = celleb_setup_arch_beat,
.show_cpuinfo = celleb_show_cpuinfo,
.restart = beat_restart,
- .power_off = beat_power_off,
.halt = beat_halt,
.get_rtc_time = beat_get_rtc_time,
.set_rtc_time = beat_set_rtc_time,
@@ -230,7 +231,6 @@ define_machine(celleb_native) {
.setup_arch = celleb_setup_arch_native,
.show_cpuinfo = celleb_show_cpuinfo,
.restart = rtas_restart,
- .power_off = rtas_power_off,
.halt = rtas_halt,
.get_boot_time = rtas_get_boot_time,
.get_rtc_time = rtas_get_rtc_time,
--
1.8.1.4
^ permalink raw reply related
* [PATCH v2 00/20] powerpc: Convert power off logic to pm_power_off
From: Alexander Graf @ 2014-10-13 14:01 UTC (permalink / raw)
To: linuxppc-dev; +Cc: arnd, geoff, alistair, scottwood, agust, linux
The generic Linux framework to power off the machine is a function pointer
called pm_power_off. The trick about this pointer is that device drivers can
potentially implement it rather than board files.
Today on PowerPC we set pm_power_off to invoke our generic full machine power
off logic which then calls ppc_md.power_off to invoke machine specific power
off.
However, when we want to add a power off GPIO via the "gpio-poweroff" driver,
this card house falls apart. That driver only registers itself if pm_power_off
is NULL to ensure it doesn't override board specific logic. However, since we
always set pm_power_off to the generic power off logic (which will just not
power off the machine if no ppc_md.power_off call is implemented), we can't
implement power off via the generic GPIO power off driver.
To fix this up, let's get rid of the ppc_md.power_off logic and just always use
pm_power_off as was intended. Then individual drivers such as the GPIO power off
driver can implement power off logic via that function pointer.
With this patch set applied and a few patches on top of QEMU that implement a
power off GPIO on the virt e500 machine, I can successfully turn off my virtual
machine after halt.
Michael / Ben, you can find this patch set as a git branch at the URL below.
When applying it, please use that one to ensure that Guenter can easily merge
his work with my work.
git://github.com/agraf/linux-2.6.git pm_power_off-v2
Alex
---
v1 -> v2:
- fix typo in 47x
- put ppc_md static replacement setters into probe function
Alexander Graf (20):
powerpc: Support override of pm_power_off
powerpc/xmon: Support either ppc_md.power_off or pm_power_off
powerpc/47x: Use pm_power_off rather than ppc_md.power_off
powerpc/52xx/efika: Use pm_power_off rather than ppc_md.power_off
powerpc/mpc8349emitx: Use pm_power_off rather than ppc_md.power_off
powerpc/corenet: Use pm_power_off rather than ppc_md.power_off
powerpc/85xx/sgy_cts1000: Use pm_power_off rather than
ppc_md.power_off
powerpc/celleb: Use pm_power_off rather than ppc_md.power_off
powerpc/cell/qpace: Use pm_power_off rather than ppc_md.power_off
powerpc/cell: Use pm_power_off rather than ppc_md.power_off
powerpc/chrp: Use pm_power_off rather than ppc_md.power_off
powerpc/6xx/gamecube: Use pm_power_off rather than ppc_md.power_off
powerpc/6xx/linkstation: Use pm_power_off rather than ppc_md.power_off
powerpc/6xx/wii: Use pm_power_off rather than ppc_md.power_off
powerpc/maple: Use pm_power_off rather than ppc_md.power_off
powerpc/powermac: Use pm_power_off rather than ppc_md.power_off
powerpc/powernv: Use pm_power_off rather than ppc_md.power_off
powerpc/ps3: Use pm_power_off rather than ppc_md.power_off
powerpc/pseries: Use pm_power_off rather than ppc_md.power_off
powerpc: Remove ppc_md.power_off
arch/powerpc/include/asm/machdep.h | 1 -
arch/powerpc/kernel/setup-common.c | 6 +-
arch/powerpc/platforms/44x/ppc476.c | 2 +-
arch/powerpc/platforms/52xx/efika.c | 3 +-
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | 8 +-
arch/powerpc/platforms/85xx/corenet_generic.c | 2 +-
arch/powerpc/platforms/85xx/sgy_cts1000.c | 4 +-
arch/powerpc/platforms/cell/celleb_setup.c | 4 +-
arch/powerpc/platforms/cell/qpace_setup.c | 2 +-
arch/powerpc/platforms/cell/setup.c | 2 +-
arch/powerpc/platforms/chrp/setup.c | 3 +-
arch/powerpc/platforms/embedded6xx/gamecube.c | 3 +-
arch/powerpc/platforms/embedded6xx/linkstation.c | 4 +-
arch/powerpc/platforms/embedded6xx/wii.c | 3 +-
arch/powerpc/platforms/maple/setup.c | 4 +-
arch/powerpc/platforms/powermac/setup.c | 147 ++++++++++++-----------
arch/powerpc/platforms/powernv/setup.c | 4 +-
arch/powerpc/platforms/ps3/setup.c | 2 +-
arch/powerpc/platforms/pseries/setup.c | 59 ++++-----
arch/powerpc/sysdev/fsl_soc.c | 2 +-
arch/powerpc/xmon/xmon.c | 3 +-
21 files changed, 138 insertions(+), 130 deletions(-)
--
1.8.1.4
^ permalink raw reply
* [PATCH v2 02/20] powerpc/xmon: Support either ppc_md.power_off or pm_power_off
From: Alexander Graf @ 2014-10-13 14:01 UTC (permalink / raw)
To: linuxppc-dev; +Cc: arnd, geoff, alistair, scottwood, agust, linux
In-Reply-To: <1413208888-49211-1-git-send-email-agraf@suse.de>
Xmon can manually turn off the machine. We now have 2 code paths for this:
1) ppc_md.power_off
2) pm_power_off
This patch allows xmon to support both and makes sure it graciously allows
a path to not be implemented.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
arch/powerpc/xmon/xmon.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index b988b5a..531f649 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -981,7 +981,10 @@ static void bootcmds(void)
else if (cmd == 'h')
ppc_md.halt();
else if (cmd == 'p')
- ppc_md.power_off();
+ if (ppc_md.power_off)
+ ppc_md.power_off();
+ if (pm_power_off)
+ pm_power_off();
}
static int cpu_cmd(void)
--
1.8.1.4
^ permalink raw reply related
* [PATCH v2 04/20] powerpc/52xx/efika: Use pm_power_off rather than ppc_md.power_off
From: Alexander Graf @ 2014-10-13 14:01 UTC (permalink / raw)
To: linuxppc-dev; +Cc: arnd, geoff, alistair, scottwood, agust, linux
In-Reply-To: <1413208888-49211-1-git-send-email-agraf@suse.de>
The generic power off callback is pm_power_off. Use that one rather than
the powerpc specific ppc_md.power_off.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
v1 -> v2:
- write pm_power_off in probe function
---
arch/powerpc/platforms/52xx/efika.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index 3feffde..6af651e 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -212,6 +212,8 @@ static int __init efika_probe(void)
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ pm_power_off = rtas_power_off;
+
return 1;
}
@@ -225,7 +227,6 @@ define_machine(efika)
.init_IRQ = mpc52xx_init_irq,
.get_irq = mpc52xx_get_irq,
.restart = rtas_restart,
- .power_off = rtas_power_off,
.halt = rtas_halt,
.set_rtc_time = rtas_set_rtc_time,
.get_rtc_time = rtas_get_rtc_time,
--
1.8.1.4
^ permalink raw reply related
* Re: powerpc32: add support for csum_add()
From: leroy christophe @ 2014-10-13 11:17 UTC (permalink / raw)
To: Jochen Rollwagen; +Cc: linuxppc-dev
In-Reply-To: <543AAADB.1070304@t-online.de>
[-- Attachment #1: Type: text/plain, Size: 1511 bytes --]
Le 12/10/2014 18:22, Jochen Rollwagen a écrit :
> This patch
>
> https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-September/121144.html
>
> only compiles after putting an #ifndef ARCH_HAS_CSUM_ADD around the
> definition in include/net/checksum.h
>
> This is missing from the patch
>
>
This is already included upstream since May 2014, see patch below
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=07064c6e022ba8dc0c86ce12f7851a1de24e04fc
From 07064c6e022ba8dc0c86ce12f7851a1de24e04fc Mon Sep 17 00:00:00 2001
From: Tom Herbert <therbert@google.com>
Date: Fri, 2 May 2014 16:28:03 -0700
Subject: net: Allow csum_add to be provided in arch
csum_add is really nothing more then add-with-carry which
can be implemented efficiently in some architectures.
Allow architecture to define this protected by HAVE_ARCH_CSUM_ADD.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/include/net/checksum.h b/include/net/checksum.h
index a28f4e0..87cb190 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -57,12 +57,14 @@ static __inline__ __wsum csum_and_copy_to_user
}
#endif
+#ifndef HAVE_ARCH_CSUM_ADD
static inline __wsum csum_add(__wsum csum, __wsum addend)
{
u32 res = (__force u32)csum;
res += (__force u32)addend;
return (__force __wsum)(res + (res < (__force u32)addend));
}
+#endif
static inline __wsum csum_sub(__wsum csum, __wsum addend)
{
--
cgit v0.10.1
[-- Attachment #2: Type: text/html, Size: 3020 bytes --]
^ permalink raw reply related
* [PATCH] powerpc: Use probe_kernel_address in show_instructions
From: Anton Blanchard @ 2014-10-13 9:27 UTC (permalink / raw)
To: benh, paulus, mpe; +Cc: linuxppc-dev
We really don't want to take a pagefault in show_instructions,
so use probe_kernel_address instead of __get_user.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/process.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 923cd2d..e5698f1 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -37,9 +37,9 @@
#include <linux/personality.h>
#include <linux/random.h>
#include <linux/hw_breakpoint.h>
+#include <linux/uaccess.h>
#include <asm/pgtable.h>
-#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/mmu.h>
@@ -921,12 +921,8 @@ static void show_instructions(struct pt_regs *regs)
pc = (unsigned long)phys_to_virt(pc);
#endif
- /* We use __get_user here *only* to avoid an OOPS on a
- * bad address because the pc *should* only be a
- * kernel address.
- */
if (!__kernel_text_address(pc) ||
- __get_user(instr, (unsigned int __user *)pc)) {
+ probe_kernel_address((unsigned int __user *)pc, instr)) {
printk(KERN_CONT "XXXXXXXX ");
} else {
if (regs->nip == pc)
--
1.9.1
^ permalink raw reply related
* [PATCH] powerpc: Add printk levels to setup_system output
From: Anton Blanchard @ 2014-10-13 9:21 UTC (permalink / raw)
To: benh, paulus, mpe; +Cc: linuxppc-dev
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/setup_64.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index cd07d79..4f3cfe1 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -522,36 +522,36 @@ void __init setup_system(void)
smp_release_cpus();
#endif
- printk("Starting Linux PPC64 %s\n", init_utsname()->version);
+ pr_info("Starting Linux PPC64 %s\n", init_utsname()->version);
- printk("-----------------------------------------------------\n");
- printk("ppc64_pft_size = 0x%llx\n", ppc64_pft_size);
- printk("phys_mem_size = 0x%llx\n", memblock_phys_mem_size());
+ pr_info("-----------------------------------------------------\n");
+ pr_info("ppc64_pft_size = 0x%llx\n", ppc64_pft_size);
+ pr_info("phys_mem_size = 0x%llx\n", memblock_phys_mem_size());
if (ppc64_caches.dline_size != 0x80)
- printk("dcache_line_size = 0x%x\n", ppc64_caches.dline_size);
+ pr_info("dcache_line_size = 0x%x\n", ppc64_caches.dline_size);
if (ppc64_caches.iline_size != 0x80)
- printk("icache_line_size = 0x%x\n", ppc64_caches.iline_size);
+ pr_info("icache_line_size = 0x%x\n", ppc64_caches.iline_size);
- printk("cpu_features = 0x%016lx\n", cur_cpu_spec->cpu_features);
- printk(" possible = 0x%016lx\n", CPU_FTRS_POSSIBLE);
- printk(" always = 0x%016lx\n", CPU_FTRS_ALWAYS);
- printk("cpu_user_features = 0x%08x 0x%08x\n", cur_cpu_spec->cpu_user_features,
+ pr_info("cpu_features = 0x%016lx\n", cur_cpu_spec->cpu_features);
+ pr_info(" possible = 0x%016lx\n", CPU_FTRS_POSSIBLE);
+ pr_info(" always = 0x%016lx\n", CPU_FTRS_ALWAYS);
+ pr_info("cpu_user_features = 0x%08x 0x%08x\n", cur_cpu_spec->cpu_user_features,
cur_cpu_spec->cpu_user_features2);
- printk("mmu_features = 0x%08x\n", cur_cpu_spec->mmu_features);
- printk("firmware_features = 0x%016lx\n", powerpc_firmware_features);
+ pr_info("mmu_features = 0x%08x\n", cur_cpu_spec->mmu_features);
+ pr_info("firmware_features = 0x%016lx\n", powerpc_firmware_features);
#ifdef CONFIG_PPC_STD_MMU_64
if (htab_address)
- printk("htab_address = 0x%p\n", htab_address);
+ pr_info("htab_address = 0x%p\n", htab_address);
- printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
+ pr_info("htab_hash_mask = 0x%lx\n", htab_hash_mask);
#endif
if (PHYSICAL_START > 0)
- printk("physical_start = 0x%llx\n",
+ pr_info("physical_start = 0x%llx\n",
(unsigned long long)PHYSICAL_START);
- printk("-----------------------------------------------------\n");
+ pr_info("-----------------------------------------------------\n");
DBG(" <- setup_system()\n");
}
--
1.9.1
^ permalink raw reply related
* [PATCH] powerpc: sync pseries_le_defconfig with pseries_defconfig
From: Anton Blanchard @ 2014-10-13 9:17 UTC (permalink / raw)
To: benh, paulus, mpe; +Cc: linuxppc-dev
Now KVM is working on LE, enable it. Also enable transarent
hugepage which has already been enabled on BE.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/configs/pseries_le_defconfig | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/configs/pseries_le_defconfig b/arch/powerpc/configs/pseries_le_defconfig
index 4428ee4..96a230c 100644
--- a/arch/powerpc/configs/pseries_le_defconfig
+++ b/arch/powerpc/configs/pseries_le_defconfig
@@ -48,7 +48,6 @@ CONFIG_KEXEC=y
CONFIG_IRQ_ALL_CPUS=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
-CONFIG_CMA=y
CONFIG_PPC_64K_PAGES=y
CONFIG_PPC_SUBPAGE_PROT=y
CONFIG_SCHED_SMT=y
@@ -137,6 +136,7 @@ CONFIG_NETCONSOLE=y
CONFIG_NETPOLL_TRAP=y
CONFIG_TUN=m
CONFIG_VIRTIO_NET=m
+CONFIG_VHOST_NET=m
CONFIG_VORTEX=y
CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
@@ -302,4 +302,9 @@ CONFIG_CRYPTO_LZO=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_DEV_NX=y
CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM_BOOK3S_64=m
+CONFIG_KVM_BOOK3S_64_HV=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] ipr: set coherent DMA mask
From: Anton Blanchard @ 2014-10-13 9:14 UTC (permalink / raw)
To: benh, paulus, mpe, wenxiong, brking, scottwood; +Cc: linuxppc-dev, linux-scsi
In-Reply-To: <1413191676-1663-1-git-send-email-anton@samba.org>
Use dma_set_mask_and_coherent() to set both the DMA and coherent
DMA mask.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
drivers/scsi/ipr.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 3aa28bd..15f4575 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -9611,16 +9611,17 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
ipr_init_regs(ioa_cfg);
if (ioa_cfg->sis64) {
- rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
+ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (rc < 0) {
- dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n");
- rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ dev_dbg(&pdev->dev, "Failed to set 64 bit DMA mask\n");
+ rc = dma_set_mask_and_coherent(&pdev->dev,
+ DMA_BIT_MASK(32));
}
} else
- rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (rc < 0) {
- dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
+ dev_err(&pdev->dev, "Failed to set DMA mask\n");
goto cleanup_nomem;
}
--
1.9.1
^ permalink raw reply related
* [PATCH 1/2] ipr: Convert to generic DMA API
From: Anton Blanchard @ 2014-10-13 9:14 UTC (permalink / raw)
To: benh, paulus, mpe, wenxiong, brking, scottwood; +Cc: linuxppc-dev, linux-scsi
Even though the ipr driver is only used on PCI, convert it
to use the generic DMA API.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
drivers/scsi/ipr.c | 101 +++++++++++++++++++++++++++--------------------------
drivers/scsi/ipr.h | 2 +-
2 files changed, 53 insertions(+), 50 deletions(-)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 924b0ba..3aa28bd 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3932,8 +3932,9 @@ static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg,
return -EIO;
}
- sglist->num_dma_sg = pci_map_sg(ioa_cfg->pdev, sglist->scatterlist,
- sglist->num_sg, DMA_TO_DEVICE);
+ sglist->num_dma_sg = dma_map_sg(&ioa_cfg->pdev->dev,
+ sglist->scatterlist, sglist->num_sg,
+ DMA_TO_DEVICE);
if (!sglist->num_dma_sg) {
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
@@ -5575,7 +5576,7 @@ static int ipr_build_ioadl64(struct ipr_ioa_cfg *ioa_cfg,
nseg = scsi_dma_map(scsi_cmd);
if (nseg < 0) {
if (printk_ratelimit())
- dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
+ dev_err(&ioa_cfg->pdev->dev, "scsi_dma_map failed!\n");
return -1;
}
@@ -5626,7 +5627,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
nseg = scsi_dma_map(scsi_cmd);
if (nseg < 0) {
- dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
+ dev_err(&ioa_cfg->pdev->dev, "scsi_dma_map failed!\n");
return -1;
}
@@ -8421,7 +8422,7 @@ static int ipr_reset_ucode_download_done(struct ipr_cmnd *ipr_cmd)
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
struct ipr_sglist *sglist = ioa_cfg->ucode_sglist;
- pci_unmap_sg(ioa_cfg->pdev, sglist->scatterlist,
+ dma_unmap_sg(&ioa_cfg->pdev->dev, sglist->scatterlist,
sglist->num_sg, DMA_TO_DEVICE);
ipr_cmd->job_step = ipr_reset_alert;
@@ -8861,7 +8862,7 @@ static void ipr_free_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
for (i = 0; i < IPR_NUM_CMD_BLKS; i++) {
if (ioa_cfg->ipr_cmnd_list[i])
- pci_pool_free(ioa_cfg->ipr_cmd_pool,
+ dma_pool_free(ioa_cfg->ipr_cmd_pool,
ioa_cfg->ipr_cmnd_list[i],
ioa_cfg->ipr_cmnd_list_dma[i]);
@@ -8869,7 +8870,7 @@ static void ipr_free_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
}
if (ioa_cfg->ipr_cmd_pool)
- pci_pool_destroy(ioa_cfg->ipr_cmd_pool);
+ dma_pool_destroy(ioa_cfg->ipr_cmd_pool);
kfree(ioa_cfg->ipr_cmnd_list);
kfree(ioa_cfg->ipr_cmnd_list_dma);
@@ -8890,25 +8891,24 @@ static void ipr_free_mem(struct ipr_ioa_cfg *ioa_cfg)
int i;
kfree(ioa_cfg->res_entries);
- pci_free_consistent(ioa_cfg->pdev, sizeof(struct ipr_misc_cbs),
- ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
+ dma_free_coherent(&ioa_cfg->pdev->dev, sizeof(struct ipr_misc_cbs),
+ ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
ipr_free_cmd_blks(ioa_cfg);
for (i = 0; i < ioa_cfg->hrrq_num; i++)
- pci_free_consistent(ioa_cfg->pdev,
- sizeof(u32) * ioa_cfg->hrrq[i].size,
- ioa_cfg->hrrq[i].host_rrq,
- ioa_cfg->hrrq[i].host_rrq_dma);
+ dma_free_coherent(&ioa_cfg->pdev->dev,
+ sizeof(u32) * ioa_cfg->hrrq[i].size,
+ ioa_cfg->hrrq[i].host_rrq,
+ ioa_cfg->hrrq[i].host_rrq_dma);
- pci_free_consistent(ioa_cfg->pdev, ioa_cfg->cfg_table_size,
- ioa_cfg->u.cfg_table,
- ioa_cfg->cfg_table_dma);
+ dma_free_coherent(&ioa_cfg->pdev->dev, ioa_cfg->cfg_table_size,
+ ioa_cfg->u.cfg_table, ioa_cfg->cfg_table_dma);
for (i = 0; i < IPR_NUM_HCAMS; i++) {
- pci_free_consistent(ioa_cfg->pdev,
- sizeof(struct ipr_hostrcb),
- ioa_cfg->hostrcb[i],
- ioa_cfg->hostrcb_dma[i]);
+ dma_free_coherent(&ioa_cfg->pdev->dev,
+ sizeof(struct ipr_hostrcb),
+ ioa_cfg->hostrcb[i],
+ ioa_cfg->hostrcb_dma[i]);
}
ipr_free_dump(ioa_cfg);
@@ -8969,7 +8969,7 @@ static int ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
dma_addr_t dma_addr;
int i, entries_each_hrrq, hrrq_id = 0;
- ioa_cfg->ipr_cmd_pool = pci_pool_create(IPR_NAME, ioa_cfg->pdev,
+ ioa_cfg->ipr_cmd_pool = dma_pool_create(IPR_NAME, &ioa_cfg->pdev->dev,
sizeof(struct ipr_cmnd), 512, 0);
if (!ioa_cfg->ipr_cmd_pool)
@@ -9019,7 +9019,7 @@ static int ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg)
}
for (i = 0; i < IPR_NUM_CMD_BLKS; i++) {
- ipr_cmd = pci_pool_alloc(ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr);
+ ipr_cmd = dma_pool_alloc(ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr);
if (!ipr_cmd) {
ipr_free_cmd_blks(ioa_cfg);
@@ -9090,9 +9090,10 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
ioa_cfg->res_entries[i].ioa_cfg = ioa_cfg;
}
- ioa_cfg->vpd_cbs = pci_alloc_consistent(ioa_cfg->pdev,
- sizeof(struct ipr_misc_cbs),
- &ioa_cfg->vpd_cbs_dma);
+ ioa_cfg->vpd_cbs = dma_alloc_coherent(&pdev->dev,
+ sizeof(struct ipr_misc_cbs),
+ &ioa_cfg->vpd_cbs_dma,
+ GFP_KERNEL);
if (!ioa_cfg->vpd_cbs)
goto out_free_res_entries;
@@ -9101,13 +9102,14 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
goto out_free_vpd_cbs;
for (i = 0; i < ioa_cfg->hrrq_num; i++) {
- ioa_cfg->hrrq[i].host_rrq = pci_alloc_consistent(ioa_cfg->pdev,
+ ioa_cfg->hrrq[i].host_rrq = dma_alloc_coherent(&pdev->dev,
sizeof(u32) * ioa_cfg->hrrq[i].size,
- &ioa_cfg->hrrq[i].host_rrq_dma);
+ &ioa_cfg->hrrq[i].host_rrq_dma,
+ GFP_KERNEL);
if (!ioa_cfg->hrrq[i].host_rrq) {
while (--i > 0)
- pci_free_consistent(pdev,
+ dma_free_coherent(&pdev->dev,
sizeof(u32) * ioa_cfg->hrrq[i].size,
ioa_cfg->hrrq[i].host_rrq,
ioa_cfg->hrrq[i].host_rrq_dma);
@@ -9116,17 +9118,19 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg)
ioa_cfg->hrrq[i].ioa_cfg = ioa_cfg;
}
- ioa_cfg->u.cfg_table = pci_alloc_consistent(ioa_cfg->pdev,
- ioa_cfg->cfg_table_size,
- &ioa_cfg->cfg_table_dma);
+ ioa_cfg->u.cfg_table = dma_alloc_coherent(&pdev->dev,
+ ioa_cfg->cfg_table_size,
+ &ioa_cfg->cfg_table_dma,
+ GFP_KERNEL);
if (!ioa_cfg->u.cfg_table)
goto out_free_host_rrq;
for (i = 0; i < IPR_NUM_HCAMS; i++) {
- ioa_cfg->hostrcb[i] = pci_alloc_consistent(ioa_cfg->pdev,
- sizeof(struct ipr_hostrcb),
- &ioa_cfg->hostrcb_dma[i]);
+ ioa_cfg->hostrcb[i] = dma_alloc_coherent(&pdev->dev,
+ sizeof(struct ipr_hostrcb),
+ &ioa_cfg->hostrcb_dma[i],
+ GFP_KERNEL);
if (!ioa_cfg->hostrcb[i])
goto out_free_hostrcb_dma;
@@ -9150,25 +9154,24 @@ out:
out_free_hostrcb_dma:
while (i-- > 0) {
- pci_free_consistent(pdev, sizeof(struct ipr_hostrcb),
- ioa_cfg->hostrcb[i],
- ioa_cfg->hostrcb_dma[i]);
+ dma_free_coherent(&pdev->dev, sizeof(struct ipr_hostrcb),
+ ioa_cfg->hostrcb[i],
+ ioa_cfg->hostrcb_dma[i]);
}
- pci_free_consistent(pdev, ioa_cfg->cfg_table_size,
- ioa_cfg->u.cfg_table,
- ioa_cfg->cfg_table_dma);
+ dma_free_coherent(&pdev->dev, ioa_cfg->cfg_table_size,
+ ioa_cfg->u.cfg_table, ioa_cfg->cfg_table_dma);
out_free_host_rrq:
for (i = 0; i < ioa_cfg->hrrq_num; i++) {
- pci_free_consistent(pdev,
- sizeof(u32) * ioa_cfg->hrrq[i].size,
- ioa_cfg->hrrq[i].host_rrq,
- ioa_cfg->hrrq[i].host_rrq_dma);
+ dma_free_coherent(&pdev->dev,
+ sizeof(u32) * ioa_cfg->hrrq[i].size,
+ ioa_cfg->hrrq[i].host_rrq,
+ ioa_cfg->hrrq[i].host_rrq_dma);
}
out_ipr_free_cmd_blocks:
ipr_free_cmd_blks(ioa_cfg);
out_free_vpd_cbs:
- pci_free_consistent(pdev, sizeof(struct ipr_misc_cbs),
- ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
+ dma_free_coherent(&pdev->dev, sizeof(struct ipr_misc_cbs),
+ ioa_cfg->vpd_cbs, ioa_cfg->vpd_cbs_dma);
out_free_res_entries:
kfree(ioa_cfg->res_entries);
goto out;
@@ -9608,13 +9611,13 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
ipr_init_regs(ioa_cfg);
if (ioa_cfg->sis64) {
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+ rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
if (rc < 0) {
dev_dbg(&pdev->dev, "Failed to set 64 bit PCI DMA mask\n");
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
}
} else
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (rc < 0) {
dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 31ed126..14f62c8 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1548,7 +1548,7 @@ struct ipr_ioa_cfg {
struct ipr_misc_cbs *vpd_cbs;
dma_addr_t vpd_cbs_dma;
- struct pci_pool *ipr_cmd_pool;
+ struct dma_pool *ipr_cmd_pool;
struct ipr_cmnd *reset_cmd;
int (*reset) (struct ipr_cmnd *);
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 1/4] powerpc: Dynamic DMA zone limits
From: Michael Ellerman @ 2014-10-13 9:00 UTC (permalink / raw)
To: Anton Blanchard; +Cc: Scott Wood, linuxppc-dev, Shaohui Xie
In-Reply-To: <20141013181436.300988c8@kryten>
On Mon, 2014-10-13 at 18:14 +1100, Anton Blanchard wrote:
> Hi Scott,
>
> > Platform code can call limit_zone_pfn() to set appropriate limits
> > for ZONE_DMA and ZONE_DMA32, and dma_direct_alloc_coherent() will
> > select a suitable zone based on a device's mask and the pfn limits
> > that platform code has configured.
>
> This patch breaks my POWER8 box:
>
> ipr 0001:08:00.0: Using 64-bit DMA iommu bypass
> ipr 0001:08:00.0: dma_direct_alloc_coherent: No suitable zone for pfn 0x10000
> ipr 0001:08:00.0: Couldn't allocate enough memory for device driver!
> ipr: probe of 0001:08:00.0 failed with error -12
>
> ipr isn't setting a coherent mask, but we shouldn't care on these boxes.
> Could we ignore the coherent mask or copy the dma mask to it?
Talking to Ben the answer seems to be "it's complicated".
We shouldn't be ignoring the coherent mask, but we have been, and have been
getting away with it.
The PCI code sets a default 32-bit mask, so we can't even detect when a device
hasn't set it. Though maybe the powernv PCI code could be initialising it to
64-bit ?
For this cycle I'm thinking of the below patch.
Scott & Anton can you test please?
Also the depends on FSL_PCI was totally a guess, so please correct that if it's
wrong Scott.
cheers
[PATCH] powerpc: Only do dynamic DMA zone limits on platforms that need it
Scott's patch 1c98025c6c95 "Dynamic DMA zone limits" changed
dma_direct_alloc_coherent() to start using dev->coherent_dma_mask.
That seems fair enough, but it exposes the fact that some of the drivers
we care about on IBM platforms aren't setting the coherent mask.
The proper fix is to have drivers set the coherent mask and also have
the platform code honor it.
For now, just restrict the dynamic DMA zone limits to the platforms that
need it, which is those using FSL_PCI.
Fixes: 1c98025c6c95 ("powerpc: Dynamic DMA zone limits")
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/Kconfig | 2 +-
arch/powerpc/kernel/dma.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 88eace4e28c3..9b9044aec217 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -290,7 +290,7 @@ config PPC_EMULATE_SSTEP
config ZONE_DMA32
bool
- default y if PPC64
+ default y if PPC64 && FSL_PCI
source "init/Kconfig"
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index adac9dc54aee..bd443a2e4426 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -53,6 +53,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size,
#else
struct page *page;
int node = dev_to_node(dev);
+#ifdef CONFIG_ZONE_DMA32
u64 pfn = get_pfn_limit(dev);
int zone;
@@ -67,12 +68,11 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size,
case ZONE_DMA:
flag |= GFP_DMA;
break;
-#ifdef CONFIG_ZONE_DMA32
case ZONE_DMA32:
flag |= GFP_DMA32;
break;
-#endif
};
+#endif /* CONFIG_ZONE_DMA32 */
/* ignore region specifiers */
flag &= ~(__GFP_HIGHMEM);
--
1.9.1
^ permalink raw reply related
* [PATCH 3/3] powerpc/pseries: Use dump_stack instead of show_stack
From: Anton Blanchard @ 2014-10-13 8:41 UTC (permalink / raw)
To: benh, paulus, mpe, zhong; +Cc: linuxppc-dev
In-Reply-To: <1413189700-30322-1-git-send-email-anton@samba.org>
We can use the simpler dump_stack() instead of
show_stack(current, __get_SP())
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/platforms/pseries/iommu.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index de1ec54..e32e009 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -30,7 +30,6 @@
#include <linux/mm.h>
#include <linux/memblock.h>
#include <linux/spinlock.h>
-#include <linux/sched.h> /* for show_stack */
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
@@ -168,7 +167,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
printk("\tindex = 0x%llx\n", (u64)tbl->it_index);
printk("\ttcenum = 0x%llx\n", (u64)tcenum);
printk("\ttce val = 0x%llx\n", tce );
- show_stack(current, (unsigned long *)__get_SP());
+ dump_stack();
}
tcenum++;
@@ -257,7 +256,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
printk("\tindex = 0x%llx\n", (u64)tbl->it_index);
printk("\tnpages = 0x%llx\n", (u64)npages);
printk("\ttce[0] val = 0x%llx\n", tcep[0]);
- show_stack(current, (unsigned long *)__get_SP());
+ dump_stack();
}
return ret;
}
@@ -273,7 +272,7 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages
printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
printk("\tindex = 0x%llx\n", (u64)tbl->it_index);
printk("\ttcenum = 0x%llx\n", (u64)tcenum);
- show_stack(current, (unsigned long *)__get_SP());
+ dump_stack();
}
tcenum++;
@@ -292,7 +291,7 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
printk("\trc = %lld\n", rc);
printk("\tindex = 0x%llx\n", (u64)tbl->it_index);
printk("\tnpages = 0x%llx\n", (u64)npages);
- show_stack(current, (unsigned long *)__get_SP());
+ dump_stack();
}
}
@@ -307,7 +306,7 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum)
printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%lld\n", rc);
printk("\tindex = 0x%llx\n", (u64)tbl->it_index);
printk("\ttcenum = 0x%llx\n", (u64)tcenum);
- show_stack(current, (unsigned long *)__get_SP());
+ dump_stack();
}
return tce_ret;
--
1.9.1
^ permalink raw reply related
* [PATCH 2/3] powerpc: Rename __get_SP() to current_stack_pointer()
From: Anton Blanchard @ 2014-10-13 8:41 UTC (permalink / raw)
To: benh, paulus, mpe, zhong; +Cc: linuxppc-dev
In-Reply-To: <1413189700-30322-1-git-send-email-anton@samba.org>
Michael points out that __get_SP() is a pretty horrible
function name. Let's give it a better name.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/include/asm/perf_event.h | 2 +-
arch/powerpc/include/asm/reg.h | 2 +-
arch/powerpc/kernel/irq.c | 2 +-
arch/powerpc/kernel/misc.S | 2 +-
arch/powerpc/kernel/ppc_ksyms.c | 2 +-
arch/powerpc/kernel/process.c | 2 +-
arch/powerpc/kernel/stacktrace.c | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h
index b058568..8bf1b63 100644
--- a/arch/powerpc/include/asm/perf_event.h
+++ b/arch/powerpc/include/asm/perf_event.h
@@ -34,7 +34,7 @@
do { \
(regs)->result = 0; \
(regs)->nip = __ip; \
- (regs)->gpr[1] = __get_SP(); \
+ (regs)->gpr[1] = current_stack_pointer(); \
asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \
} while (0)
#endif
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index e539d7e..c998279 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1265,7 +1265,7 @@ static inline unsigned long mfvtb (void)
#define proc_trap() asm volatile("trap")
-extern unsigned long __get_SP(void);
+extern unsigned long current_stack_pointer(void);
extern unsigned long scom970_read(unsigned int address);
extern void scom970_write(unsigned int address, unsigned long value);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 8eb857f..c143835 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -466,7 +466,7 @@ static inline void check_stack_overflow(void)
#ifdef CONFIG_DEBUG_STACKOVERFLOW
long sp;
- sp = __get_SP() & (THREAD_SIZE-1);
+ sp = current_stack_pointer() & (THREAD_SIZE-1);
/* check for stack overflow: is there less than 2KB free? */
if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index 120deb7..0d43219 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -115,6 +115,6 @@ _GLOBAL(longjmp)
mr r3,r4
blr
-_GLOBAL(__get_SP)
+_GLOBAL(current_stack_pointer)
PPC_LL r3,0(r1)
blr
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 9d84efb..202963e 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -42,4 +42,4 @@ EXPORT_SYMBOL(giveup_spe);
EXPORT_SYMBOL(epapr_hypercall_start);
#endif
-EXPORT_SYMBOL(__get_SP);
+EXPORT_SYMBOL(current_stack_pointer);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 3cc6439..923cd2d 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1545,7 +1545,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
tsk = current;
if (sp == 0) {
if (tsk == current)
- sp = __get_SP();
+ sp = current_stack_pointer();
else
sp = tsk->thread.ksp;
}
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index 7f65bae..ea43a34 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -50,7 +50,7 @@ void save_stack_trace(struct stack_trace *trace)
{
unsigned long sp;
- sp = __get_SP();
+ sp = current_stack_pointer();
save_context_stack(trace, sp, current, 1);
}
--
1.9.1
^ permalink raw reply related
* [PATCH 1/3] powerpc: Reimplement __get_SP() as a function not a define
From: Anton Blanchard @ 2014-10-13 8:41 UTC (permalink / raw)
To: benh, paulus, mpe, zhong; +Cc: linuxppc-dev
Li Zhong points out an issue with our current __get_SP()
implementation. If ftrace function tracing is enabled (ie -pg
profiling using _mcount) we spill a stack frame on 64bit all the
time.
If a function calls __get_SP() and later calls a function that is
tail call optimised, we will pop the stack frame and the value
returned by __get_SP() is no longer valid. An example from Li can
be found in save_stack_trace -> save_context_stack:
c0000000000432c0 <.save_stack_trace>:
c0000000000432c0: mflr r0
c0000000000432c4: std r0,16(r1)
c0000000000432c8: stdu r1,-128(r1) <-- stack frame for _mcount
c0000000000432cc: std r3,112(r1)
c0000000000432d0: bl <._mcount>
c0000000000432d4: nop
c0000000000432d8: mr r4,r1 <-- __get_SP()
c0000000000432dc: ld r5,632(r13)
c0000000000432e0: ld r3,112(r1)
c0000000000432e4: li r6,1
c0000000000432e8: addi r1,r1,128 <-- pop stack frame
c0000000000432ec: ld r0,16(r1)
c0000000000432f0: mtlr r0
c0000000000432f4: b <.save_context_stack> <-- tail call optimized
save_context_stack ends up with a stack pointer below the current
one, and it is likely to be scribbled over.
Fix this by making __get_SP() a function which returns the
callers stack frame. Also replace inline assembly which grabs
the stack pointer in save_stack_trace and show_stack with
__get_SP().
This also fixes an issue with perf_arch_fetch_caller_regs().
It currently unwinds the stack once, which will skip a
valid stack frame on a leaf function. With the __get_SP() fixes
in this patch, we never need to unwind the stack frame to get
to the first interesting frame.
We have to export __get_SP() because perf_arch_fetch_caller_regs()
(which is used in modules) calls it from a header file.
Reported-by: Li Zhong <zhong@linux.vnet.ibm.com>
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/include/asm/perf_event.h | 2 +-
arch/powerpc/include/asm/reg.h | 3 +--
arch/powerpc/kernel/misc.S | 4 ++++
arch/powerpc/kernel/ppc_ksyms.c | 2 ++
arch/powerpc/kernel/process.c | 2 +-
arch/powerpc/kernel/stacktrace.c | 2 +-
6 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h
index 0bb2372..b058568 100644
--- a/arch/powerpc/include/asm/perf_event.h
+++ b/arch/powerpc/include/asm/perf_event.h
@@ -34,7 +34,7 @@
do { \
(regs)->result = 0; \
(regs)->nip = __ip; \
- (regs)->gpr[1] = *(unsigned long *)__get_SP(); \
+ (regs)->gpr[1] = __get_SP(); \
asm volatile("mfmsr %0" : "=r" ((regs)->msr)); \
} while (0)
#endif
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index fe3f948..e539d7e 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1265,8 +1265,7 @@ static inline unsigned long mfvtb (void)
#define proc_trap() asm volatile("trap")
-#define __get_SP() ({unsigned long sp; \
- asm volatile("mr %0,1": "=r" (sp)); sp;})
+extern unsigned long __get_SP(void);
extern unsigned long scom970_read(unsigned int address);
extern void scom970_write(unsigned int address, unsigned long value);
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index 7ce26d4..120deb7 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -114,3 +114,7 @@ _GLOBAL(longjmp)
mtlr r0
mr r3,r4
blr
+
+_GLOBAL(__get_SP)
+ PPC_LL r3,0(r1)
+ blr
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index c4dfff6..9d84efb 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -41,3 +41,5 @@ EXPORT_SYMBOL(giveup_spe);
#ifdef CONFIG_EPAPR_PARAVIRT
EXPORT_SYMBOL(epapr_hypercall_start);
#endif
+
+EXPORT_SYMBOL(__get_SP);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index aa1df89..3cc6439 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1545,7 +1545,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
tsk = current;
if (sp == 0) {
if (tsk == current)
- asm("mr %0,1" : "=r" (sp));
+ sp = __get_SP();
else
sp = tsk->thread.ksp;
}
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index 3d30ef1..7f65bae 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -50,7 +50,7 @@ void save_stack_trace(struct stack_trace *trace)
{
unsigned long sp;
- asm("mr %0,1" : "=r" (sp));
+ sp = __get_SP();
save_context_stack(trace, sp, current, 1);
}
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 1/4] powerpc: Dynamic DMA zone limits
From: Benjamin Herrenschmidt @ 2014-10-13 7:30 UTC (permalink / raw)
To: Anton Blanchard; +Cc: Scott Wood, linuxppc-dev, Shaohui Xie
In-Reply-To: <20141013181436.300988c8@kryten>
On Mon, 2014-10-13 at 18:14 +1100, Anton Blanchard wrote:
> Hi Scott,
>
> > Platform code can call limit_zone_pfn() to set appropriate limits
> > for ZONE_DMA and ZONE_DMA32, and dma_direct_alloc_coherent() will
> > select a suitable zone based on a device's mask and the pfn limits
> > that platform code has configured.
>
> This patch breaks my POWER8 box:
>
> ipr 0001:08:00.0: Using 64-bit DMA iommu bypass
> ipr 0001:08:00.0: dma_direct_alloc_coherent: No suitable zone for pfn 0x10000
> ipr 0001:08:00.0: Couldn't allocate enough memory for device driver!
> ipr: probe of 0001:08:00.0 failed with error -12
>
> ipr isn't setting a coherent mask, but we shouldn't care on these boxes.
> Could we ignore the coherent mask or copy the dma mask to it?
So this depends what the coherent_mask actually means vs. the dma_mask.
I've always been extremely confused by the distinction. Since the
coherent_mask is set by the driver, I assume it represents a driver
limitation on coherent memory which might be *different* from the
restriction on streaming mappings, in which case we might have to honor
it...
The problem is that our whole mechanism for switching dma_ops is based
on having one mask.
So even if we somewhat "fix" IPR, we still have an issue in that we
don't honor the coherent mask properly in case a driver really wants a
different mask.
If we new have two, I think we need to (in the long run that is, for
3.18 we can probably find an ifdef based band-aid):
- Either have a ppc_md hook for set_coherent_mask along with
dma_set_mask and make the decision to flip based on the AND of both
masks (gross)
- Or, since that's basically what some of our HW can do, basically make
the decision on a per-hook basis. That is, something like powernv would
no longer need to hook dma_set_mask to switch the ops. Instead, it could
permanently set a set of pnv_dma_ops that for each hook chose the
"right" mask and route the mapping toward either the iommu or the bypass
accordingly.
Both seem like quite a bit of refactoring and the latter would be tricky
for some pseries cases where we actually *remove* the 32-bit window to
establish the 64-bit one (DDW cases).
Any better idea ? Are there any drivers that don't actually have the
same mask for both that we care about ?
Ben.
> Anton
> --
>
> > Signed-off-by: Scott Wood <scottwood@freescale.com>
> > Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
> > ---
> > arch/powerpc/Kconfig | 4 +++
> > arch/powerpc/include/asm/pgtable.h | 3 ++
> > arch/powerpc/kernel/dma.c | 20 +++++++++++++
> > arch/powerpc/mm/mem.c | 61
> > ++++++++++++++++++++++++++++++++++---- 4 files changed, 83
> > insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index 80b94b0..56dc47a 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -286,6 +286,10 @@ config PPC_EMULATE_SSTEP
> > bool
> > default y if KPROBES || UPROBES || XMON || HAVE_HW_BREAKPOINT
> >
> > +config ZONE_DMA32
> > + bool
> > + default y if PPC64
> > +
> > source "init/Kconfig"
> >
> > source "kernel/Kconfig.freezer"
> > diff --git a/arch/powerpc/include/asm/pgtable.h
> > b/arch/powerpc/include/asm/pgtable.h index d98c1ec..6d74167 100644
> > --- a/arch/powerpc/include/asm/pgtable.h
> > +++ b/arch/powerpc/include/asm/pgtable.h
> > @@ -4,6 +4,7 @@
> >
> > #ifndef __ASSEMBLY__
> > #include <linux/mmdebug.h>
> > +#include <linux/mmzone.h>
> > #include <asm/processor.h> /* For TASK_SIZE */
> > #include <asm/mmu.h>
> > #include <asm/page.h>
> > @@ -281,6 +282,8 @@ extern unsigned long empty_zero_page[];
> >
> > extern pgd_t swapper_pg_dir[];
> >
> > +void limit_zone_pfn(enum zone_type zone, unsigned long max_pfn);
> > +int dma_pfn_limit_to_zone(u64 pfn_limit);
> > extern void paging_init(void);
> >
> > /*
> > diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
> > index ee78f6e..dfd99ef 100644
> > --- a/arch/powerpc/kernel/dma.c
> > +++ b/arch/powerpc/kernel/dma.c
> > @@ -40,6 +40,26 @@ void *dma_direct_alloc_coherent(struct device
> > *dev, size_t size, #else
> > struct page *page;
> > int node = dev_to_node(dev);
> > + u64 pfn = (dev->coherent_dma_mask >> PAGE_SHIFT) + 1;
> > + int zone;
> > +
> > + zone = dma_pfn_limit_to_zone(pfn);
> > + if (zone < 0) {
> > + dev_err(dev, "%s: No suitable zone for pfn %#llx\n",
> > + __func__, pfn);
> > + return NULL;
> > + }
> > +
> > + switch (zone) {
> > + case ZONE_DMA:
> > + flag |= GFP_DMA;
> > + break;
> > +#ifdef CONFIG_ZONE_DMA32
> > + case ZONE_DMA32:
> > + flag |= GFP_DMA32;
> > + break;
> > +#endif
> > + };
> >
> > /* ignore region specifiers */
> > flag &= ~(__GFP_HIGHMEM);
> > diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> > index e0f7a18..3b23e17 100644
> > --- a/arch/powerpc/mm/mem.c
> > +++ b/arch/powerpc/mm/mem.c
> > @@ -261,6 +261,54 @@ static int __init mark_nonram_nosave(void)
> > return 0;
> > }
> >
> > +static bool zone_limits_final;
> > +
> > +static unsigned long max_zone_pfns[MAX_NR_ZONES] = {
> > + [0 ... MAX_NR_ZONES - 1] = ~0UL
> > +};
> > +
> > +/*
> > + * Restrict the specified zone and all more restrictive zones
> > + * to be below the specified pfn. May not be called after
> > + * paging_init().
> > + */
> > +void __init limit_zone_pfn(enum zone_type zone, unsigned long
> > pfn_limit) +{
> > + int i;
> > +
> > + if (WARN_ON(zone_limits_final))
> > + return;
> > +
> > + for (i = zone; i >= 0; i--) {
> > + if (max_zone_pfns[i] > pfn_limit)
> > + max_zone_pfns[i] = pfn_limit;
> > + }
> > +}
> > +
> > +/*
> > + * Find the least restrictive zone that is entirely below the
> > + * specified pfn limit. Returns < 0 if no suitable zone is found.
> > + *
> > + * pfn_limit must be u64 because it can exceed 32 bits even on 32-bit
> > + * systems -- the DMA limit can be higher than any possible real pfn.
> > + */
> > +int dma_pfn_limit_to_zone(u64 pfn_limit)
> > +{
> > + enum zone_type top_zone = ZONE_NORMAL;
> > + int i;
> > +
> > +#ifdef CONFIG_HIGHMEM
> > + top_zone = ZONE_HIGHMEM;
> > +#endif
> > +
> > + for (i = top_zone; i >= 0; i--) {
> > + if (max_zone_pfns[i] <= pfn_limit)
> > + return i;
> > + }
> > +
> > + return -EPERM;
> > +}
> > +
> > /*
> > * paging_init() sets up the page tables - in fact we've already
> > done this. */
> > @@ -268,7 +316,7 @@ void __init paging_init(void)
> > {
> > unsigned long long total_ram = memblock_phys_mem_size();
> > phys_addr_t top_of_ram = memblock_end_of_DRAM();
> > - unsigned long max_zone_pfns[MAX_NR_ZONES];
> > + enum zone_type top_zone;
> >
> > #ifdef CONFIG_PPC32
> > unsigned long v = __fix_to_virt(__end_of_fixed_addresses -
> > 1); @@ -290,13 +338,16 @@ void __init paging_init(void)
> > (unsigned long long)top_of_ram, total_ram);
> > printk(KERN_DEBUG "Memory hole size: %ldMB\n",
> > (long int)((top_of_ram - total_ram) >> 20));
> > - memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
> > +
> > #ifdef CONFIG_HIGHMEM
> > - max_zone_pfns[ZONE_DMA] = lowmem_end_addr >> PAGE_SHIFT;
> > - max_zone_pfns[ZONE_HIGHMEM] = top_of_ram >> PAGE_SHIFT;
> > + top_zone = ZONE_HIGHMEM;
> > + limit_zone_pfn(ZONE_NORMAL, lowmem_end_addr >> PAGE_SHIFT);
> > #else
> > - max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
> > + top_zone = ZONE_NORMAL;
> > #endif
> > +
> > + limit_zone_pfn(top_zone, top_of_ram >> PAGE_SHIFT);
> > + zone_limits_final = true;
> > free_area_init_nodes(max_zone_pfns);
> >
> > mark_nonram_nosave();
^ permalink raw reply
* Re: [PATCH 1/4] powerpc: Dynamic DMA zone limits
From: Anton Blanchard @ 2014-10-13 7:14 UTC (permalink / raw)
To: Scott Wood, Benjamin Herrenschmidt, Shaohui Xie, Michael Ellerman
Cc: linuxppc-dev
In-Reply-To: <1407541245-27617-1-git-send-email-scottwood@freescale.com>
Hi Scott,
> Platform code can call limit_zone_pfn() to set appropriate limits
> for ZONE_DMA and ZONE_DMA32, and dma_direct_alloc_coherent() will
> select a suitable zone based on a device's mask and the pfn limits
> that platform code has configured.
This patch breaks my POWER8 box:
ipr 0001:08:00.0: Using 64-bit DMA iommu bypass
ipr 0001:08:00.0: dma_direct_alloc_coherent: No suitable zone for pfn 0x10000
ipr 0001:08:00.0: Couldn't allocate enough memory for device driver!
ipr: probe of 0001:08:00.0 failed with error -12
ipr isn't setting a coherent mask, but we shouldn't care on these boxes.
Could we ignore the coherent mask or copy the dma mask to it?
Anton
--
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
> ---
> arch/powerpc/Kconfig | 4 +++
> arch/powerpc/include/asm/pgtable.h | 3 ++
> arch/powerpc/kernel/dma.c | 20 +++++++++++++
> arch/powerpc/mm/mem.c | 61
> ++++++++++++++++++++++++++++++++++---- 4 files changed, 83
> insertions(+), 5 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 80b94b0..56dc47a 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -286,6 +286,10 @@ config PPC_EMULATE_SSTEP
> bool
> default y if KPROBES || UPROBES || XMON || HAVE_HW_BREAKPOINT
>
> +config ZONE_DMA32
> + bool
> + default y if PPC64
> +
> source "init/Kconfig"
>
> source "kernel/Kconfig.freezer"
> diff --git a/arch/powerpc/include/asm/pgtable.h
> b/arch/powerpc/include/asm/pgtable.h index d98c1ec..6d74167 100644
> --- a/arch/powerpc/include/asm/pgtable.h
> +++ b/arch/powerpc/include/asm/pgtable.h
> @@ -4,6 +4,7 @@
>
> #ifndef __ASSEMBLY__
> #include <linux/mmdebug.h>
> +#include <linux/mmzone.h>
> #include <asm/processor.h> /* For TASK_SIZE */
> #include <asm/mmu.h>
> #include <asm/page.h>
> @@ -281,6 +282,8 @@ extern unsigned long empty_zero_page[];
>
> extern pgd_t swapper_pg_dir[];
>
> +void limit_zone_pfn(enum zone_type zone, unsigned long max_pfn);
> +int dma_pfn_limit_to_zone(u64 pfn_limit);
> extern void paging_init(void);
>
> /*
> diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
> index ee78f6e..dfd99ef 100644
> --- a/arch/powerpc/kernel/dma.c
> +++ b/arch/powerpc/kernel/dma.c
> @@ -40,6 +40,26 @@ void *dma_direct_alloc_coherent(struct device
> *dev, size_t size, #else
> struct page *page;
> int node = dev_to_node(dev);
> + u64 pfn = (dev->coherent_dma_mask >> PAGE_SHIFT) + 1;
> + int zone;
> +
> + zone = dma_pfn_limit_to_zone(pfn);
> + if (zone < 0) {
> + dev_err(dev, "%s: No suitable zone for pfn %#llx\n",
> + __func__, pfn);
> + return NULL;
> + }
> +
> + switch (zone) {
> + case ZONE_DMA:
> + flag |= GFP_DMA;
> + break;
> +#ifdef CONFIG_ZONE_DMA32
> + case ZONE_DMA32:
> + flag |= GFP_DMA32;
> + break;
> +#endif
> + };
>
> /* ignore region specifiers */
> flag &= ~(__GFP_HIGHMEM);
> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index e0f7a18..3b23e17 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -261,6 +261,54 @@ static int __init mark_nonram_nosave(void)
> return 0;
> }
>
> +static bool zone_limits_final;
> +
> +static unsigned long max_zone_pfns[MAX_NR_ZONES] = {
> + [0 ... MAX_NR_ZONES - 1] = ~0UL
> +};
> +
> +/*
> + * Restrict the specified zone and all more restrictive zones
> + * to be below the specified pfn. May not be called after
> + * paging_init().
> + */
> +void __init limit_zone_pfn(enum zone_type zone, unsigned long
> pfn_limit) +{
> + int i;
> +
> + if (WARN_ON(zone_limits_final))
> + return;
> +
> + for (i = zone; i >= 0; i--) {
> + if (max_zone_pfns[i] > pfn_limit)
> + max_zone_pfns[i] = pfn_limit;
> + }
> +}
> +
> +/*
> + * Find the least restrictive zone that is entirely below the
> + * specified pfn limit. Returns < 0 if no suitable zone is found.
> + *
> + * pfn_limit must be u64 because it can exceed 32 bits even on 32-bit
> + * systems -- the DMA limit can be higher than any possible real pfn.
> + */
> +int dma_pfn_limit_to_zone(u64 pfn_limit)
> +{
> + enum zone_type top_zone = ZONE_NORMAL;
> + int i;
> +
> +#ifdef CONFIG_HIGHMEM
> + top_zone = ZONE_HIGHMEM;
> +#endif
> +
> + for (i = top_zone; i >= 0; i--) {
> + if (max_zone_pfns[i] <= pfn_limit)
> + return i;
> + }
> +
> + return -EPERM;
> +}
> +
> /*
> * paging_init() sets up the page tables - in fact we've already
> done this. */
> @@ -268,7 +316,7 @@ void __init paging_init(void)
> {
> unsigned long long total_ram = memblock_phys_mem_size();
> phys_addr_t top_of_ram = memblock_end_of_DRAM();
> - unsigned long max_zone_pfns[MAX_NR_ZONES];
> + enum zone_type top_zone;
>
> #ifdef CONFIG_PPC32
> unsigned long v = __fix_to_virt(__end_of_fixed_addresses -
> 1); @@ -290,13 +338,16 @@ void __init paging_init(void)
> (unsigned long long)top_of_ram, total_ram);
> printk(KERN_DEBUG "Memory hole size: %ldMB\n",
> (long int)((top_of_ram - total_ram) >> 20));
> - memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
> +
> #ifdef CONFIG_HIGHMEM
> - max_zone_pfns[ZONE_DMA] = lowmem_end_addr >> PAGE_SHIFT;
> - max_zone_pfns[ZONE_HIGHMEM] = top_of_ram >> PAGE_SHIFT;
> + top_zone = ZONE_HIGHMEM;
> + limit_zone_pfn(ZONE_NORMAL, lowmem_end_addr >> PAGE_SHIFT);
> #else
> - max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
> + top_zone = ZONE_NORMAL;
> #endif
> +
> + limit_zone_pfn(top_zone, top_of_ram >> PAGE_SHIFT);
> + zone_limits_final = true;
> free_area_init_nodes(max_zone_pfns);
>
> mark_nonram_nosave();
^ permalink raw reply
* Re: powerpc32: add support for csum_add()
From: Jochen Rollwagen @ 2014-10-12 16:22 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 226 bytes --]
This patch
https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-September/121144.html
only compiles after putting an #ifndef ARCH_HAS_CSUM_ADD around the
definition in include/net/checksum.h
This is missing from the patch
[-- Attachment #2: Type: text/html, Size: 681 bytes --]
^ permalink raw reply
* [PATCH 6/6] dmaengine: remove FSLDMA_EXTERNAL_START
From: Vinod Koul @ 2014-10-11 15:46 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul, Zhang Wei, linuxppc-dev, linux-kernel
In-Reply-To: <1413042408-28491-1-git-send-email-vinod.koul@intel.com>
as users have been converted, so no need of this custom method
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
include/linux/dmaengine.h | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index ce8a08e..3254a03 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -199,15 +199,12 @@ enum dma_ctrl_flags {
* configuration data in statically from the platform). An additional
* argument of struct dma_slave_config must be passed in with this
* command.
- * @FSLDMA_EXTERNAL_START: this command will put the Freescale DMA controller
- * into external start mode.
*/
enum dma_ctrl_cmd {
DMA_TERMINATE_ALL,
DMA_PAUSE,
DMA_RESUME,
DMA_SLAVE_CONFIG,
- FSLDMA_EXTERNAL_START,
};
/**
--
1.7.0.4
^ permalink raw reply related
* [PATCH 5/6] dmaengine: freescale: remove FSLDMA_EXTERNAL_START control method
From: Vinod Koul @ 2014-10-11 15:46 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul, Zhang Wei, linuxppc-dev, linux-kernel
In-Reply-To: <1413042408-28491-1-git-send-email-vinod.koul@intel.com>
since users have been move to fsl_dma_external_start() API, so remove this
now
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
drivers/dma/fsldma.c | 9 ---------
1 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 0cded86..994bcb2 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -1012,15 +1012,6 @@ static int fsl_dma_device_control(struct dma_chan *dchan,
chan->set_request_count(chan, size);
return 0;
- case FSLDMA_EXTERNAL_START:
-
- /* make sure the channel supports external start */
- if (!chan->toggle_ext_start)
- return -ENXIO;
-
- chan->toggle_ext_start(chan, arg);
- return 0;
-
default:
return -ENXIO;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 4/6] carma-fpga: move to fsl_dma_external_start()
From: Vinod Koul @ 2014-10-11 15:46 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul, Zhang Wei, linuxppc-dev, linux-kernel
In-Reply-To: <1413042408-28491-1-git-send-email-vinod.koul@intel.com>
carma-fpga driver uses device control with custom FSLDMA_EXTERNAL_START
command. Since we wnat to deprecate the device control, move this driver to
use new fsl_dma_external_start() API
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
drivers/misc/carma/carma-fpga-program.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c
index fd0cb8b..298f912 100644
--- a/drivers/misc/carma/carma-fpga-program.c
+++ b/drivers/misc/carma/carma-fpga-program.c
@@ -16,6 +16,7 @@
#include <linux/completion.h>
#include <linux/miscdevice.h>
#include <linux/dmaengine.h>
+#include <linux/fsldma.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/kernel.h>
@@ -524,7 +525,7 @@ static noinline int fpga_program_dma(struct fpga_dev *priv)
goto out_dma_unmap;
}
- ret = chan->device->device_control(chan, FSLDMA_EXTERNAL_START, 1);
+ ret = fsl_dma_external_start(chan, 1)
if (ret) {
dev_err(priv->dev, "DMA external control setup failed\n");
goto out_dma_unmap;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/6] carma-fpga: use dmaengine_xxx() API
From: Vinod Koul @ 2014-10-11 15:46 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul, Zhang Wei, linuxppc-dev, linux-kernel
In-Reply-To: <1413042408-28491-1-git-send-email-vinod.koul@intel.com>
The drivers should use dmaengine_slave_config() and dmaengine_prep_dma_sg()
API instead of accessing the device_control which will be deprecated soon
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
drivers/misc/carma/carma-fpga-program.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/misc/carma/carma-fpga-program.c b/drivers/misc/carma/carma-fpga-program.c
index 7be8983..fd0cb8b 100644
--- a/drivers/misc/carma/carma-fpga-program.c
+++ b/drivers/misc/carma/carma-fpga-program.c
@@ -518,8 +518,7 @@ static noinline int fpga_program_dma(struct fpga_dev *priv)
config.direction = DMA_MEM_TO_DEV;
config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
config.dst_maxburst = fpga_fifo_size(priv->regs) / 2 / 4;
- ret = chan->device->device_control(chan, DMA_SLAVE_CONFIG,
- (unsigned long)&config);
+ ret = dmaengine_slave_config(chan, &config);
if (ret) {
dev_err(priv->dev, "DMA slave configuration failed\n");
goto out_dma_unmap;
@@ -532,9 +531,9 @@ static noinline int fpga_program_dma(struct fpga_dev *priv)
}
/* setup and submit the DMA transaction */
- tx = chan->device->device_prep_dma_sg(chan,
- table.sgl, num_pages,
- vb->sglist, vb->sglen, 0);
+
+ tx = dmaengine_prep_dma_sg(chan, table.sgl, num_pages,
+ vb->sglist, vb->sglen, 0);
if (!tx) {
dev_err(priv->dev, "Unable to prep DMA transaction\n");
ret = -ENOMEM;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/6] dmaengine: freescale: add and export fsl_dma_external_start()
From: Vinod Koul @ 2014-10-11 15:46 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul, Zhang Wei, linuxppc-dev, linux-kernel
In-Reply-To: <1413042408-28491-1-git-send-email-vinod.koul@intel.com>
The freescale driver uses custom device control FSLDMA_EXTERNAL_START to
put the controller in external start mode.
Since we are planning to deprecate the device control, move this to exported
API. Subsequent patches will remove the FSLDMA_EXTERNAL_START
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
drivers/dma/fsldma.c | 16 +++++++++++++++-
include/linux/fsldma.h | 13 +++++++++++++
2 files changed, 28 insertions(+), 1 deletions(-)
create mode 100644 include/linux/fsldma.h
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index d5d6885..0cded86 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -36,7 +36,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
-
+#include <linux/fsldma.h>
#include "dmaengine.h"
#include "fsldma.h"
@@ -367,6 +367,20 @@ static void fsl_chan_toggle_ext_start(struct fsldma_chan *chan, int enable)
chan->feature &= ~FSL_DMA_CHAN_START_EXT;
}
+int fsl_dma_external_start(struct dma_chan *dchan, int enable)
+{
+ struct fsldma_chan *chan;
+
+ if (!dchan)
+ return -EINVAL;
+
+ chan = to_fsl_chan(dchan);
+
+ fsl_chan_toggle_ext_start(chan, enable);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fsl_dma_external_start);
+
static void append_ld_queue(struct fsldma_chan *chan, struct fsl_desc_sw *desc)
{
struct fsl_desc_sw *tail = to_fsl_desc(chan->ld_pending.prev);
diff --git a/include/linux/fsldma.h b/include/linux/fsldma.h
new file mode 100644
index 0000000..b213c02
--- /dev/null
+++ b/include/linux/fsldma.h
@@ -0,0 +1,13 @@
+/*
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef FSL_DMA_H
+#define FSL_DMA_H
+/* fsl dma API for enxternal start */
+int fsl_dma_external_start(struct dma_chan *dchan, int enable);
+
+#endif
--
1.7.0.4
^ permalink raw reply related
* [PATCH 1/6] dmaengine: add dmaengine_prep_dma_sg() helper
From: Vinod Koul @ 2014-10-11 15:46 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul, Zhang Wei, linuxppc-dev, linux-kernel
In-Reply-To: <1413042408-28491-1-git-send-email-vinod.koul@intel.com>
This was only prep API which didnt have an helper
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
include/linux/dmaengine.h | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 3d291f5..ce8a08e 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -757,6 +757,16 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
return chan->device->device_prep_interleaved_dma(chan, xt, flags);
}
+static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg(
+ struct dma_chan *chan,
+ struct scatterlist *dst_sg, unsigned int dst_nents,
+ struct scatterlist *src_sg, unsigned int src_nents,
+ unsigned long flags)
+{
+ return chan->device->device_prep_dma_sg(chan, dst_sg, dst_nents,
+ src_sg, src_nents, flags);
+}
+
static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
{
if (!chan || !caps)
--
1.7.0.4
^ permalink raw reply related
* [PATCH 0/6] dmaengine: remove FSLDMA_EXTERNAL_START
From: Vinod Koul @ 2014-10-11 15:46 UTC (permalink / raw)
To: dmaengine; +Cc: Vinod Koul, Zhang Wei, linuxppc-dev, linux-kernel
FSLDMA_EXTERNAL_START is one of the custom methods in device_control. Since
we are planning to deprecate device_control, we should move this to an API.
This serries adds the fsl_dma_external_start() API for users and also
converts the users.
I would like this to be merged thru dmanegine tree due to new dependency.
Vinod Koul (6):
dmaengine: add dmaengine_prep_dma_sg() helper
dmaengine: freescale: add and export fsl_dma_external_start()
carma-fpga: use dmaengine_xxx() API
carma-fpga: move to fsl_dma_external_start()
dmaengine: freescale: remove FSLDMA_EXTERNAL_START control method
dmaengine: remove FSLDMA_EXTERNAL_START
drivers/dma/fsldma.c | 25 +++++++++++++++----------
drivers/misc/carma/carma-fpga-program.c | 12 ++++++------
include/linux/dmaengine.h | 13 ++++++++++---
include/linux/fsldma.h | 13 +++++++++++++
4 files changed, 44 insertions(+), 19 deletions(-)
create mode 100644 include/linux/fsldma.h
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox