* [PATCH 4/8] dma-mapping: add a dma_can_mmap helper
From: Christoph Hellwig @ 2019-08-08 16:00 UTC (permalink / raw)
To: iommu, Marek Szyprowski
Cc: linux-xtensa, Michal Simek, Vladimir Murzin, linux-parisc,
linux-sh, Takashi Iwai, linuxppc-dev, Helge Deller, x86,
linux-kernel, linux-m68k, Robin Murphy, linux-arm-kernel
In-Reply-To: <20190808160005.10325-1-hch@lst.de>
Add a helper to check if DMA allocations for a specific device can be
mapped to userspace using dma_mmap_*.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/dma-mapping.h | 5 +++++
kernel/dma/mapping.c | 23 +++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f7d1eea32c78..17271857be5d 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -462,6 +462,7 @@ int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt,
int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs);
+bool dma_can_mmap(struct device *dev);
int dma_supported(struct device *dev, u64 mask);
int dma_set_mask(struct device *dev, u64 mask);
int dma_set_coherent_mask(struct device *dev, u64 mask);
@@ -552,6 +553,10 @@ static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
{
return -ENXIO;
}
+static inline bool dma_can_mmap(struct device *dev)
+{
+ return false;
+}
static inline int dma_supported(struct device *dev, u64 mask)
{
return 0;
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 67b900ad0836..64d1de59e133 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -220,6 +220,29 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
#endif /* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */
}
+/**
+ * dma_can_mmap - check if a given device supports dma_mmap_*
+ * @dev: device to check
+ *
+ * Returns %true if @dev supports dma_mmap_coherent() and dma_mmap_attrs() to
+ * map DMA allocations to userspace.
+ */
+bool dma_can_mmap(struct device *dev)
+{
+ const struct dma_map_ops *ops = get_dma_ops(dev);
+
+ if (IS_ENABLED(CONFIG_ARCH_NO_COHERENT_DMA_MMAP))
+ return false;
+
+ if (dma_is_direct(ops)) {
+ return dev_is_dma_coherent(dev) ||
+ IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN);
+ }
+
+ return ops->mmap != NULL;
+}
+EXPORT_SYMBOL_GPL(dma_can_mmap);
+
/**
* dma_mmap_attrs - map a coherent DMA allocation into user space
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 3/8] dma-mapping: explicitly wire up ->mmap and ->get_sgtable
From: Christoph Hellwig @ 2019-08-08 16:00 UTC (permalink / raw)
To: iommu, Marek Szyprowski
Cc: linux-xtensa, Michal Simek, Vladimir Murzin, linux-parisc,
linux-sh, Takashi Iwai, linuxppc-dev, Helge Deller, x86,
linux-kernel, linux-m68k, Robin Murphy, linux-arm-kernel
In-Reply-To: <20190808160005.10325-1-hch@lst.de>
While the default ->mmap and ->get_sgtable implementations work for the
majority of our dma_map_ops impementations they are inherently safe
for others that don't use the page allocator or CMA and/or use their
own way of remapping not covered by the common code. So remove the
defaults if these methods are not wired up, but instead wire up the
default implementations for all safe instances.
Fixes: e1c7e324539a ("dma-mapping: always provide the dma_map_ops based implementation")
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/alpha/kernel/pci_iommu.c | 2 ++
arch/ia64/hp/common/sba_iommu.c | 2 ++
arch/ia64/sn/pci/pci_dma.c | 2 ++
arch/mips/jazz/jazzdma.c | 2 ++
arch/powerpc/kernel/dma-iommu.c | 2 ++
arch/powerpc/platforms/ps3/system-bus.c | 4 ++++
arch/powerpc/platforms/pseries/vio.c | 2 ++
arch/s390/pci/pci_dma.c | 2 ++
arch/x86/kernel/amd_gart_64.c | 2 ++
arch/x86/kernel/pci-calgary_64.c | 2 ++
drivers/iommu/amd_iommu.c | 2 ++
drivers/iommu/intel-iommu.c | 2 ++
drivers/parisc/ccio-dma.c | 2 ++
drivers/parisc/sba_iommu.c | 2 ++
kernel/dma/mapping.c | 20 ++++++++++++--------
15 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 242108439f42..7f1925a32c99 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -955,5 +955,7 @@ const struct dma_map_ops alpha_pci_ops = {
.map_sg = alpha_pci_map_sg,
.unmap_sg = alpha_pci_unmap_sg,
.dma_supported = alpha_pci_supported,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
EXPORT_SYMBOL(alpha_pci_ops);
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 3d24cc43385b..4c0ea6c2833d 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -2183,6 +2183,8 @@ const struct dma_map_ops sba_dma_ops = {
.map_sg = sba_map_sg_attrs,
.unmap_sg = sba_unmap_sg_attrs,
.dma_supported = sba_dma_supported,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
void sba_dma_init(void)
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index b7d42e4edc1f..12ffb9c0d738 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -438,6 +438,8 @@ static struct dma_map_ops sn_dma_ops = {
.unmap_sg = sn_dma_unmap_sg,
.dma_supported = sn_dma_supported,
.get_required_mask = sn_dma_get_required_mask,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
void sn_dma_init(void)
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index 1804dc9d8136..a01e14955187 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -682,5 +682,7 @@ const struct dma_map_ops jazz_dma_ops = {
.sync_sg_for_device = jazz_dma_sync_sg_for_device,
.dma_supported = dma_direct_supported,
.cache_sync = arch_dma_cache_sync,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
EXPORT_SYMBOL(jazz_dma_ops);
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index a0879674a9c8..2f5a53874f6d 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -208,4 +208,6 @@ const struct dma_map_ops dma_iommu_ops = {
.sync_single_for_device = dma_iommu_sync_for_device,
.sync_sg_for_cpu = dma_iommu_sync_sg_for_cpu,
.sync_sg_for_device = dma_iommu_sync_sg_for_device,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 6818317073b9..3542b7bd6a46 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -694,6 +694,8 @@ static const struct dma_map_ops ps3_sb_dma_ops = {
.dma_supported = ps3_dma_supported,
.map_page = ps3_sb_map_page,
.unmap_page = ps3_unmap_page,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
static const struct dma_map_ops ps3_ioc0_dma_ops = {
@@ -704,6 +706,8 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = {
.dma_supported = ps3_dma_supported,
.map_page = ps3_ioc0_map_page,
.unmap_page = ps3_unmap_page,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
/**
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index 6601b9d404dc..3473eef7628c 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -605,6 +605,8 @@ static const struct dma_map_ops vio_dma_mapping_ops = {
.unmap_page = vio_dma_iommu_unmap_page,
.dma_supported = dma_iommu_dma_supported,
.get_required_mask = dma_iommu_get_required_mask,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
/**
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index 9e52d1527f71..03d8c1c9f82f 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -668,6 +668,8 @@ const struct dma_map_ops s390_pci_dma_ops = {
.unmap_sg = s390_dma_unmap_sg,
.map_page = s390_dma_map_pages,
.unmap_page = s390_dma_unmap_pages,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
/* dma_supported is unconditionally true without a callback */
};
EXPORT_SYMBOL_GPL(s390_pci_dma_ops);
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index 03ed9675f954..a6ac3712db8b 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -677,6 +677,8 @@ static const struct dma_map_ops gart_dma_ops = {
.unmap_page = gart_unmap_page,
.alloc = gart_alloc_coherent,
.free = gart_free_coherent,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
.dma_supported = dma_direct_supported,
.get_required_mask = dma_direct_get_required_mask,
};
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 9d4343aa481b..23fdec030c37 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -468,6 +468,8 @@ static const struct dma_map_ops calgary_dma_ops = {
.map_page = calgary_map_page,
.unmap_page = calgary_unmap_page,
.dma_supported = dma_direct_supported,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
static inline void __iomem * busno_to_bbar(unsigned char num)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index b607a92791d3..2e74ad659985 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2722,6 +2722,8 @@ static const struct dma_map_ops amd_iommu_dma_ops = {
.map_sg = map_sg,
.unmap_sg = unmap_sg,
.dma_supported = amd_iommu_dma_supported,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
static int init_reserved_iova_ranges(void)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index bdaed2da8a55..7505c5d9cf78 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3737,6 +3737,8 @@ static const struct dma_map_ops intel_dma_ops = {
.map_resource = intel_map_resource,
.unmap_resource = intel_unmap_resource,
.dma_supported = dma_direct_supported,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
static inline int iommu_domain_cache_init(void)
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 217f15aafa4a..1d7125d29bee 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1024,6 +1024,8 @@ static const struct dma_map_ops ccio_ops = {
.unmap_page = ccio_unmap_page,
.map_sg = ccio_map_sg,
.unmap_sg = ccio_unmap_sg,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
#ifdef CONFIG_PROC_FS
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 296668caf7e5..fa4df65b7e28 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1084,6 +1084,8 @@ static const struct dma_map_ops sba_ops = {
.unmap_page = sba_unmap_page,
.map_sg = sba_map_sg,
.unmap_sg = sba_unmap_sg,
+ .mmap = dma_common_mmap,
+ .get_sgtable = dma_common_get_sgtable,
};
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 41590d003465..67b900ad0836 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -153,11 +153,12 @@ int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt,
{
const struct dma_map_ops *ops = get_dma_ops(dev);
- if (!dma_is_direct(ops) && ops->get_sgtable)
- return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
- attrs);
- return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr, size,
- attrs);
+ if (dma_is_direct(ops))
+ return dma_common_get_sgtable(dev, sgt, cpu_addr, dma_addr,
+ size, attrs);
+ if (!ops->get_sgtable)
+ return -ENXIO;
+ return ops->get_sgtable(dev, sgt, cpu_addr, dma_addr, size, attrs);
}
EXPORT_SYMBOL(dma_get_sgtable_attrs);
@@ -238,9 +239,12 @@ int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
{
const struct dma_map_ops *ops = get_dma_ops(dev);
- if (!dma_is_direct(ops) && ops->mmap)
- return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
- return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
+ if (dma_is_direct(ops))
+ return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size,
+ attrs);
+ if (!ops->mmap)
+ return -ENXIO;
+ return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
}
EXPORT_SYMBOL(dma_mmap_attrs);
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 2/8] dma-mapping: move the dma_get_sgtable API comments from arm to common code
From: Christoph Hellwig @ 2019-08-08 15:59 UTC (permalink / raw)
To: iommu, Marek Szyprowski
Cc: linux-xtensa, Michal Simek, Vladimir Murzin, linux-parisc,
linux-sh, Takashi Iwai, linuxppc-dev, Helge Deller, x86,
linux-kernel, linux-m68k, Robin Murphy, linux-arm-kernel
In-Reply-To: <20190808160005.10325-1-hch@lst.de>
The comments are spot on and should be near the central API, not just
near a single implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/mm/dma-mapping.c | 11 -----------
kernel/dma/mapping.c | 11 +++++++++++
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ad64d32fb39a..b4d65da76393 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -880,17 +880,6 @@ static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_add
__arm_dma_free(dev, size, cpu_addr, handle, attrs, true);
}
-/*
- * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
- * that the intention is to allow exporting memory allocated via the
- * coherent DMA APIs through the dma_buf API, which only accepts a
- * scattertable. This presents a couple of problems:
- * 1. Not all memory allocated via the coherent DMA APIs is backed by
- * a struct page
- * 2. Passing coherent DMA memory into the streaming APIs is not allowed
- * as we will try to flush the memory through a different alias to that
- * actually being used (and the flushes are redundant.)
- */
int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t handle, size_t size,
unsigned long attrs)
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 9c0f6a8eb5cb..41590d003465 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -136,6 +136,17 @@ int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
return ret;
}
+/*
+ * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems
+ * that the intention is to allow exporting memory allocated via the
+ * coherent DMA APIs through the dma_buf API, which only accepts a
+ * scattertable. This presents a couple of problems:
+ * 1. Not all memory allocated via the coherent DMA APIs is backed by
+ * a struct page
+ * 2. Passing coherent DMA memory into the streaming APIs is not allowed
+ * as we will try to flush the memory through a different alias to that
+ * actually being used (and the flushes are redundant.)
+ */
int dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs)
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 1/8] dma-mapping: provide a better default ->get_required_mask
From: Christoph Hellwig @ 2019-08-08 15:59 UTC (permalink / raw)
To: iommu, Marek Szyprowski
Cc: linux-xtensa, Michal Simek, Vladimir Murzin, linux-parisc,
linux-sh, Takashi Iwai, linuxppc-dev, Helge Deller, x86,
linux-kernel, linux-m68k, Robin Murphy, linux-arm-kernel
In-Reply-To: <20190808160005.10325-1-hch@lst.de>
Most dma_map_ops instances are IOMMUs that work perfectly fine in 32-bits
of IOVA space, and the generic direct mapping code already provides its
own routines that is intelligent based on the amount of memory actually
present. Wire up the dma-direct routine for the ARM direct mapping code
as well, and otherwise default to the constant 32-bit mask. This way
we only need to override it for the occasional odd IOMMU that requires
64-bit IOVA support, or IOMMU drivers that are more efficient if they
can fall back to the direct mapping.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/mm/dma-mapping.c | 3 +++
arch/powerpc/platforms/ps3/system-bus.c | 7 ------
arch/x86/kernel/amd_gart_64.c | 1 +
kernel/dma/mapping.c | 30 +++++++++----------------
4 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 8c0b0baeb398..ad64d32fb39a 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -14,6 +14,7 @@
#include <linux/list.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/dma-direct.h>
#include <linux/dma-mapping.h>
#include <linux/dma-noncoherent.h>
#include <linux/dma-contiguous.h>
@@ -192,6 +193,7 @@ const struct dma_map_ops arm_dma_ops = {
.sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
.sync_sg_for_device = arm_dma_sync_sg_for_device,
.dma_supported = arm_dma_supported,
+ .get_required_mask = dma_direct_get_required_mask,
};
EXPORT_SYMBOL(arm_dma_ops);
@@ -212,6 +214,7 @@ const struct dma_map_ops arm_coherent_dma_ops = {
.map_sg = arm_dma_map_sg,
.map_resource = dma_direct_map_resource,
.dma_supported = arm_dma_supported,
+ .get_required_mask = dma_direct_get_required_mask,
};
EXPORT_SYMBOL(arm_coherent_dma_ops);
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 98410119c47b..6818317073b9 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -686,18 +686,12 @@ static int ps3_dma_supported(struct device *_dev, u64 mask)
return mask >= DMA_BIT_MASK(32);
}
-static u64 ps3_dma_get_required_mask(struct device *_dev)
-{
- return DMA_BIT_MASK(32);
-}
-
static const struct dma_map_ops ps3_sb_dma_ops = {
.alloc = ps3_alloc_coherent,
.free = ps3_free_coherent,
.map_sg = ps3_sb_map_sg,
.unmap_sg = ps3_sb_unmap_sg,
.dma_supported = ps3_dma_supported,
- .get_required_mask = ps3_dma_get_required_mask,
.map_page = ps3_sb_map_page,
.unmap_page = ps3_unmap_page,
};
@@ -708,7 +702,6 @@ static const struct dma_map_ops ps3_ioc0_dma_ops = {
.map_sg = ps3_ioc0_map_sg,
.unmap_sg = ps3_ioc0_unmap_sg,
.dma_supported = ps3_dma_supported,
- .get_required_mask = ps3_dma_get_required_mask,
.map_page = ps3_ioc0_map_page,
.unmap_page = ps3_unmap_page,
};
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index a585ea6f686a..03ed9675f954 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -678,6 +678,7 @@ static const struct dma_map_ops gart_dma_ops = {
.alloc = gart_alloc_coherent,
.free = gart_free_coherent,
.dma_supported = dma_direct_supported,
+ .get_required_mask = dma_direct_get_required_mask,
};
static void gart_iommu_shutdown(void)
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index b0038ca3aa92..9c0f6a8eb5cb 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -233,25 +233,6 @@ int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
}
EXPORT_SYMBOL(dma_mmap_attrs);
-static u64 dma_default_get_required_mask(struct device *dev)
-{
- u32 low_totalram = ((max_pfn - 1) << PAGE_SHIFT);
- u32 high_totalram = ((max_pfn - 1) >> (32 - PAGE_SHIFT));
- u64 mask;
-
- if (!high_totalram) {
- /* convert to mask just covering totalram */
- low_totalram = (1 << (fls(low_totalram) - 1));
- low_totalram += low_totalram - 1;
- mask = low_totalram;
- } else {
- high_totalram = (1 << (fls(high_totalram) - 1));
- high_totalram += high_totalram - 1;
- mask = (((u64)high_totalram) << 32) + 0xffffffff;
- }
- return mask;
-}
-
u64 dma_get_required_mask(struct device *dev)
{
const struct dma_map_ops *ops = get_dma_ops(dev);
@@ -260,7 +241,16 @@ u64 dma_get_required_mask(struct device *dev)
return dma_direct_get_required_mask(dev);
if (ops->get_required_mask)
return ops->get_required_mask(dev);
- return dma_default_get_required_mask(dev);
+
+ /*
+ * We require every DMA ops implementation to at least support a 32-bit
+ * DMA mask (and use bounce buffering if that isn't supported in
+ * hardware). As the direct mapping code has its own routine to
+ * actually report an optimal mask we default to 32-bit here as that
+ * is the right thing for most IOMMUs, and at least not actively
+ * harmful in general.
+ */
+ return DMA_BIT_MASK(32);
}
EXPORT_SYMBOL_GPL(dma_get_required_mask);
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* remove default fallbacks in dma_map_ops v3
From: Christoph Hellwig @ 2019-08-08 15:59 UTC (permalink / raw)
To: iommu, Marek Szyprowski
Cc: linux-xtensa, Michal Simek, Vladimir Murzin, linux-parisc,
linux-sh, Takashi Iwai, linuxppc-dev, Helge Deller, x86,
linux-kernel, linux-m68k, Robin Murphy, linux-arm-kernel
Hi all,
we have a few places where the DMA mapping layer has non-trivial default
actions that are questionable and/or dangerous.
This series instead wires up the mmap, get_sgtable and get_required_mask
methods explicitly and cleans up some surrounding areas. This also means
we could get rid of the ARCH_NO_COHERENT_DMA_MMAP kconfig option, as we
now require a mmap method wired up, or in case of non-coherent dma-direct
the presence of the arch_dma_coherent_to_pfn hook. The only interesting
case is that the sound code also checked the ARCH_NO_COHERENT_DMA_MMAP
symbol in somewhat odd ways, so I'd like to see a review of the sound
situation before going forward with that patch.
Changes since v2:
- fix use of dma_can_mmap in alsa
- improve the CONFIG_* mess a little more
Changes since v1:
- add a dma_can_mmap helper for alsa
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 9/9] arm64: Retrieve stolen time as paravirtualized guest
From: Marc Zyngier @ 2019-08-08 15:49 UTC (permalink / raw)
To: Steven Price
Cc: kvm, Radim Krčmář, Catalin Marinas,
Suzuki K Pouloze, linux-doc, Russell King, linux-kernel,
James Morse, linux-arm-kernel, Paolo Bonzini, Will Deacon, kvmarm,
Julien Thierry
In-Reply-To: <dc8a1e56-7b52-cc8f-265d-27eb5f458613@arm.com>
On 08/08/2019 16:29, Steven Price wrote:
> On 04/08/2019 10:53, Marc Zyngier wrote:
>> On Fri, 2 Aug 2019 15:50:17 +0100
>> Steven Price <steven.price@arm.com> wrote:
>>
>>> Enable paravirtualization features when running under a hypervisor
>>> supporting the PV_TIME_ST hypercall.
>>>
>>> For each (v)CPU, we ask the hypervisor for the location of a shared
>>> page which the hypervisor will use to report stolen time to us. We set
>>> pv_time_ops to the stolen time function which simply reads the stolen
>>> value from the shared page for a VCPU. We guarantee single-copy
>>> atomicity using READ_ONCE which means we can also read the stolen
>>> time for another VCPU than the currently running one while it is
>>> potentially being updated by the hypervisor.
>>>
>>> Signed-off-by: Steven Price <steven.price@arm.com>
>>> ---
>>> arch/arm64/kernel/Makefile | 1 +
>>> arch/arm64/kernel/kvm.c | 155 +++++++++++++++++++++++++++++++++++++
[...]
>>> +static int __init kvm_guest_init(void)
>>> +{
>>> + int ret = 0;
>>> +
>>> + if (!has_kvm_steal_clock())
>>> + return 0;
>>> +
>>> + ret = kvm_arm_init_stolen_time();
>>> + if (ret)
>>> + return ret;
>>> +
>>> + pv_ops.time.steal_clock = kvm_steal_clock;
>>> +
>>> + static_key_slow_inc(¶virt_steal_enabled);
>>> + if (steal_acc)
>>> + static_key_slow_inc(¶virt_steal_rq_enabled);
>>> +
>>> + pr_info("using stolen time PV\n");
>>> +
>>> + return 0;
>>> +}
>>> +early_initcall(kvm_guest_init);
>>
>> Is there any reason why we wouldn't directly call into this rather than
>> using an initcall?
>
> I'm not sure where the direct call would go - any pointers?
I'd be temped to say arch/arm64/kernel/time.c:time_init(), provided that
there is no issue with the CPU hotplug lock (I remember hitting that a
while ago).
M.
--
Jazz is not dead, it just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 0/6] hwspinlock: allow sharing of hwspinlocks
From: Bjorn Andersson @ 2019-08-08 15:37 UTC (permalink / raw)
To: Fabien DESSENNE
Cc: Ohad Ben-Cohen, Mark Rutland, Alexandre TORGUE, Jonathan Corbet,
linux-doc@vger.kernel.org, linux-remoteproc@vger.kernel.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
Rob Herring, Maxime Coquelin,
linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org, Benjamin GAIGNARD
In-Reply-To: <d8d4a172-ec18-a758-d994-8e05bb6a1f48@st.com>
On Thu 08 Aug 05:52 PDT 2019, Fabien DESSENNE wrote:
>
> On 07/08/2019 6:19 PM, Suman Anna wrote:
> > Hi Fabien,
> >
> > On 8/7/19 3:39 AM, Fabien DESSENNE wrote:
> >> Hi
> >>
> >> On 06/08/2019 11:30 PM, Suman Anna wrote:
> >>> On 8/6/19 1:21 PM, Bjorn Andersson wrote:
> >>>> On Tue 06 Aug 10:38 PDT 2019, Suman Anna wrote:
> >>>>
> >>>>> Hi Fabien,
> >>>>>
> >>>>> On 8/5/19 12:46 PM, Bjorn Andersson wrote:
> >>>> I agree that we shouldn't specify this property in DT - if anything it
> >>>> should be a variant of the API.
> >>
> >> If we decide to add a 'shared' API, then, what about the generic regmap
> >> driver?
> >>
> >> In the context of above example1, this would require to update the
> >> regmap driver.
> >>
> >> But would this be acceptable for any driver using syscon/regmap?
> >>
> >>
> >> I think it is better to keep the existing API (modifying it so it always
> >> allows
> >>
> >> hwlocks sharing, so no need for bindings update) than adding another API.
> > For your usecases, you would definitely need the syscon/regmap behavior
> > to be shared right. Whether we introduce a 'shared' API or an
> > 'exclusive' API and change the current API behavior to shared, it is
> > definitely a case-by-case usage scenario for the existing drivers and
> > usage right. The main contention point is what to do with the
> > unprotected usecases like Bjorn originally pointed out.
>
> OK, I see : the hwspinlock framework does not offer any lock protection
> with the RAW/IN_ATOMIC modes.
> This is an issue if several different 'local' drivers try to get a
> shared lock in the same time.
> And this is a personal problem since I need to use shared locks in
> ...atomic mode.
>
Why can't you use HWLOCK_IRQSTATE in this mode?
> I have tried to see how it is possible to put a constraint on the
> callers, just like this is documented for the RAW mode which is:
> "Caution: If the mode is HWLOCK_RAW, that means user must protect
> the routine
> of getting hardware lock with mutex or spinlock.."
> I do not think that it is acceptable to ask several drivers to share a
> common mutex/spinlock for shared locks.
No it's not.
> But I think about another option: the driver implementing the trylock
> ops may offer such protection. This is the case if the driver returns
> "busy" if the lock is already taken, not only by the remote processor,
> but also by the local host.
>
I think it's typical for hwspinlock hardware to not be able to
distinguish between different clients within Linux, so we would need to
wrap the usage in some construct that ensures mutual exclusion in Linux
- like a spinlock...
> So what do you think about adding such a documentation note :
> "Caution : the HWLOCK_RAW / HWLOCK_IN_ATOMIC modes shall not be used
> with shared locks unless the hwspinlock driver supports local lock
> protection"
>
But having local lock protection in the hwspinlock driver would defeat
the purpose of HWLOCK_RAW.
Also this kind of warning will at best be consumed by the client driver
authors, it will not be read by the dts authors.
Regards,
Bjorn
> Optionally, we may add a "local_lock_protection" flag in the
> hwspinlock_device struct, set by the driver before it calls
> hwspin_lock_register().
> This flag can then be checked by hwspinlock core to allow/deny use of
> shared locks in the raw/atomic modes.
>
> Let me know what you think about it.
>
> BR
>
> Fabien
>
> >
> > regards
> > Suman
> >
> >>
> >>
> >>>>> If you are sharing a hwlock on the Linux side, surely your driver should
> >>>>> be aware that it is a shared lock. The tag can be set during the first
> >>>>> request API, and you look through both tags when giving out a handle.
> >>>>>
> >>>> Why would the driver need to know about it?
> >>> Just the semantics if we were to support single user vs multiple users
> >>> on Linux-side to even get a handle. Your point is that this may be moot
> >>> since we have protection anyway other than the raw cases. But we need to
> >>> be able to have the same API work across all cases.
> >>>
> >>> So far, it had mostly been that there would be one user on Linux
> >>> competing with other equivalent peer entities on different processors.
> >>> It is not common to have multiple users since these protection schemes
> >>> are usually needed only at the lowest levels of a stack, so the
> >>> exclusive handle stuff had been sufficient.
> >>>
> >>>>> Obviously, the hwspin_lock_request() API usage semantics always had the
> >>>>> implied additional need for communicating the lock id to the other peer
> >>>>> entity, so a realistic usage is most always the specific API variant. I
> >>>>> doubt this API would be of much use for the shared driver usage. This
> >>>>> also implies that the client user does not care about specifying a lock
> >>>>> in DT.
> >>>>>
> >>>> Afaict if the lock are shared then there shouldn't be a problem with
> >>>> some clients using the request API and others request_specific(). As any
> >>>> collisions would simply mean that there are more contention on the lock.
> >>>>
> >>>> With the current exclusive model that is not possible and the success of
> >>>> the request_specific will depend on probe order.
> >>>>
> >>>> But perhaps it should be explicitly prohibited to use both APIs on the
> >>>> same hwspinlock instance?
> >>> Yeah, they are meant to be complimentary usage, though I doubt we will
> >>> ever have any realistic users for the generic API if we haven't had a
> >>> usage so far. I had posted a concept of reserved locks long back [1] to
> >>> keep away certain locks from the generic requestor, but dropped it since
> >>> we did not have an actual use-case needing it.
> >>>
> >>> regards
> >>> Suman
> >>>
> >>> [1] https://lwn.net/Articles/611944/
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 6/6] PSCI: cpuidle: Refactor CPU suspend power_state parameter handling
From: Ulf Hansson @ 2019-08-08 15:29 UTC (permalink / raw)
To: Sudeep Holla
Cc: Mark Rutland, Lorenzo Pieralisi, Linux PM, Catalin Marinas,
Daniel Lezcano, Rafael J. Wysocki, LKML, Will Deacon, LAKML
In-Reply-To: <20190808125516.GA2246@e107155-lin>
On Thu, 8 Aug 2019 at 14:55, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
> On Mon, Jul 22, 2019 at 04:37:45PM +0100, Lorenzo Pieralisi wrote:
> > Current PSCI code handles idle state entry through the
> > psci_cpu_suspend_enter() API, that takes an idle state index as a
> > parameter and convert the index into a previously initialized
> > power_state parameter before calling the PSCI.CPU_SUSPEND() with it.
> >
> > This is unwieldly, since it forces the PSCI firmware layer to keep track
> > of power_state parameter for every idle state so that the
> > index->power_state conversion can be made in the PSCI firmware layer
> > instead of the CPUidle driver implementations.
> >
> > Move the power_state handling out of drivers/firmware/psci
> > into the respective ACPI/DT PSCI CPUidle backends and convert
> > the psci_cpu_suspend_enter() API to get the power_state
> > parameter as input, which makes it closer to its firmware
> > interface PSCI.CPU_SUSPEND() API.
> >
> > A notable side effect is that the PSCI ACPI/DT CPUidle backends
> > now can directly handle (and if needed update) power_state
> > parameters before handing them over to the PSCI firmware
> > interface to trigger PSCI.CPU_SUSPEND() calls.
> >
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Ulf Hansson <ulf.hansson@linaro.org>
> > Cc: Sudeep Holla <sudeep.holla@arm.com>
>
> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
>
> > +static __init int psci_cpu_init_idle(unsigned int cpu)
> > +{
> > + struct device_node *cpu_node;
> > + int ret;
> > +
> > + /*
> > + * If the PSCI cpu_suspend function hook has not been initialized
> > + * idle states must not be enabled, so bail out
> > + */
> > + if (!psci_ops.cpu_suspend)
> > + return -EOPNOTSUPP;
> > +
> > + cpu_node = of_get_cpu_node(cpu, NULL);
>
> [nit] You could use of_cpu_device_node_get in linux/of_device.h as
> it may avoid parsing if used later during the boot(i.e. after
> cpu->of_node is populated). I think there's another instance in
> psci_idle_init_cpu
Good idea!
However, as $subject patch more or less just moves code from the
current psci firmware directory into cpuidle, perhaps it's better to
defer improvements to be made on top?
Kind regards
Uffe
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 9/9] arm64: Retrieve stolen time as paravirtualized guest
From: Steven Price @ 2019-08-08 15:29 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvm, Radim Krčmář, Catalin Marinas,
Suzuki K Pouloze, linux-doc, Russell King, linux-kernel,
James Morse, linux-arm-kernel, Paolo Bonzini, Will Deacon, kvmarm,
Julien Thierry
In-Reply-To: <20190804105353.5e9824dc@why>
On 04/08/2019 10:53, Marc Zyngier wrote:
> On Fri, 2 Aug 2019 15:50:17 +0100
> Steven Price <steven.price@arm.com> wrote:
>
>> Enable paravirtualization features when running under a hypervisor
>> supporting the PV_TIME_ST hypercall.
>>
>> For each (v)CPU, we ask the hypervisor for the location of a shared
>> page which the hypervisor will use to report stolen time to us. We set
>> pv_time_ops to the stolen time function which simply reads the stolen
>> value from the shared page for a VCPU. We guarantee single-copy
>> atomicity using READ_ONCE which means we can also read the stolen
>> time for another VCPU than the currently running one while it is
>> potentially being updated by the hypervisor.
>>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>> ---
>> arch/arm64/kernel/Makefile | 1 +
>> arch/arm64/kernel/kvm.c | 155 +++++++++++++++++++++++++++++++++++++
>
> nit: Why not using paravirt.c, which clearly states what it does? The
> alternative would be to name it kvm-pv.c.
I can move it to paravirt.c - seems reasonable.
>> include/linux/cpuhotplug.h | 1 +
>> 3 files changed, 157 insertions(+)
>> create mode 100644 arch/arm64/kernel/kvm.c
>>
>> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
>> index 478491f07b4f..eb36edf9b930 100644
>> --- a/arch/arm64/kernel/Makefile
>> +++ b/arch/arm64/kernel/Makefile
>> @@ -63,6 +63,7 @@ obj-$(CONFIG_CRASH_CORE) += crash_core.o
>> obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
>> obj-$(CONFIG_ARM64_SSBD) += ssbd.o
>> obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
>> +obj-$(CONFIG_PARAVIRT) += kvm.o
>>
>> obj-y += vdso/ probes/
>> obj-$(CONFIG_COMPAT_VDSO) += vdso32/
>> diff --git a/arch/arm64/kernel/kvm.c b/arch/arm64/kernel/kvm.c
>> new file mode 100644
>> index 000000000000..245398c79dae
>> --- /dev/null
>> +++ b/arch/arm64/kernel/kvm.c
>> @@ -0,0 +1,155 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Copyright (C) 2019 Arm Ltd.
>> +
>> +#define pr_fmt(fmt) "kvmarm-pv: " fmt
>> +
>> +#include <linux/arm-smccc.h>
>> +#include <linux/cpuhotplug.h>
>> +#include <linux/io.h>
>> +#include <linux/printk.h>
>> +#include <linux/psci.h>
>> +#include <linux/reboot.h>
>> +#include <linux/slab.h>
>> +
>> +#include <asm/paravirt.h>
>> +#include <asm/pvclock-abi.h>
>> +#include <asm/smp_plat.h>
>> +
>> +struct kvmarm_stolen_time_region {
>> + struct pvclock_vcpu_stolen_time_info *kaddr;
>> +};
>> +
>> +static DEFINE_PER_CPU(struct kvmarm_stolen_time_region, stolen_time_region);
>> +
>> +static bool steal_acc = true;
>> +static int __init parse_no_stealacc(char *arg)
>> +{
>> + steal_acc = false;
>> + return 0;
>> +}
>> +early_param("no-steal-acc", parse_no_stealacc);
>> +
>> +/* return stolen time in ns by asking the hypervisor */
>> +static u64 kvm_steal_clock(int cpu)
>> +{
>> + struct kvmarm_stolen_time_region *reg;
>> +
>> + reg = per_cpu_ptr(&stolen_time_region, cpu);
>> + if (!reg->kaddr) {
>> + pr_warn_once("stolen time enabled but not configured for cpu %d\n",
>> + cpu);
>> + return 0;
>> + }
>> +
>> + return le64_to_cpu(READ_ONCE(reg->kaddr->stolen_time));
>> +}
>> +
>> +static int disable_stolen_time_current_cpu(void)
>> +{
>> + struct kvmarm_stolen_time_region *reg;
>> +
>> + reg = this_cpu_ptr(&stolen_time_region);
>> + if (!reg->kaddr)
>> + return 0;
>> +
>> + memunmap(reg->kaddr);
>> + memset(reg, 0, sizeof(*reg));
>> +
>> + return 0;
>> +}
>> +
>> +static int stolen_time_dying_cpu(unsigned int cpu)
>> +{
>> + return disable_stolen_time_current_cpu();
>> +}
>> +
>> +static int init_stolen_time_cpu(unsigned int cpu)
>> +{
>> + struct kvmarm_stolen_time_region *reg;
>> + struct arm_smccc_res res;
>> +
>> + reg = this_cpu_ptr(&stolen_time_region);
>> +
>> + if (reg->kaddr)
>> + return 0;
>
> Can this actually happen? It'd take two CPU_UP calls from the HP
> notifiers to get in that situation...
Yes, something would have to be very broken for that to happen - I'll
remove this check.
>> +
>> + arm_smccc_1_1_invoke(ARM_SMCCC_HV_PV_TIME_ST, &res);
>> +
>> + if ((long)res.a0 < 0)
>> + return -EINVAL;
>> +
>> + reg->kaddr = memremap(res.a0,
>> + sizeof(struct pvclock_vcpu_stolen_time_info),
>> + MEMREMAP_WB);
>> +
>> + if (reg->kaddr == NULL) {
>> + pr_warn("Failed to map stolen time data structure\n");
>> + return -EINVAL;
>
> -ENOMEM is the expected return code.
Ok
>> + }
>> +
>> + if (le32_to_cpu(reg->kaddr->revision) != 0 ||
>> + le32_to_cpu(reg->kaddr->attributes) != 0) {
>> + pr_warn("Unexpected revision or attributes in stolen time data\n");
>> + return -ENXIO;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int kvm_arm_init_stolen_time(void)
>> +{
>> + int ret;
>> +
>> + ret = cpuhp_setup_state(CPUHP_AP_ARM_KVMPV_STARTING,
>> + "hypervisor/kvmarm/pv:starting",
>> + init_stolen_time_cpu, stolen_time_dying_cpu);
>> + if (ret < 0)
>> + return ret;
>> + return 0;
>> +}
>> +
>> +static bool has_kvm_steal_clock(void)
>> +{
>> + struct arm_smccc_res res;
>> +
>> + /* To detect the presence of PV time support we require SMCCC 1.1+ */
>> + if (psci_ops.smccc_version < SMCCC_VERSION_1_1)
>> + return false;
>> +
>> + arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
>> + ARM_SMCCC_HV_PV_FEATURES, &res);
>> +
>> + if (res.a0 != SMCCC_RET_SUCCESS)
>> + return false;
>> +
>> + arm_smccc_1_1_invoke(ARM_SMCCC_HV_PV_FEATURES,
>> + ARM_SMCCC_HV_PV_TIME_ST, &res);
>> +
>> + if (res.a0 != SMCCC_RET_SUCCESS)
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> +static int __init kvm_guest_init(void)
>> +{
>> + int ret = 0;
>> +
>> + if (!has_kvm_steal_clock())
>> + return 0;
>> +
>> + ret = kvm_arm_init_stolen_time();
>> + if (ret)
>> + return ret;
>> +
>> + pv_ops.time.steal_clock = kvm_steal_clock;
>> +
>> + static_key_slow_inc(¶virt_steal_enabled);
>> + if (steal_acc)
>> + static_key_slow_inc(¶virt_steal_rq_enabled);
>> +
>> + pr_info("using stolen time PV\n");
>> +
>> + return 0;
>> +}
>> +early_initcall(kvm_guest_init);
>
> Is there any reason why we wouldn't directly call into this rather than
> using an initcall?
I'm not sure where the direct call would go - any pointers?
Thanks,
Steve
>> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
>> index 068793a619ca..89d75edb5750 100644
>> --- a/include/linux/cpuhotplug.h
>> +++ b/include/linux/cpuhotplug.h
>> @@ -136,6 +136,7 @@ enum cpuhp_state {
>> /* Must be the last timer callback */
>> CPUHP_AP_DUMMY_TIMER_STARTING,
>> CPUHP_AP_ARM_XEN_STARTING,
>> + CPUHP_AP_ARM_KVMPV_STARTING,
>> CPUHP_AP_ARM_CORESIGHT_STARTING,
>> CPUHP_AP_ARM64_ISNDEP_STARTING,
>> CPUHP_AP_SMPCFD_DYING,
>
>
> Thanks,
>
> M.
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/2] mmc: sdhci-of-at91: add quirk for broken HS200
From: Ulf Hansson @ 2019-08-08 15:23 UTC (permalink / raw)
To: Eugen.Hristev
Cc: DTML, Alexandre Belloni, Linux Kernel Mailing List,
linux-mmc@vger.kernel.org, Adrian Hunter, Ludovic Desroches,
Linux ARM
In-Reply-To: <1565252928-28994-1-git-send-email-eugen.hristev@microchip.com>
On Thu, 8 Aug 2019 at 10:35, <Eugen.Hristev@microchip.com> wrote:
>
> From: Eugen Hristev <eugen.hristev@microchip.com>
>
> HS200 is not implemented in the driver, but the controller claims it
> through caps.
> Remove it via quirk.
> Without this quirk, the mmc core will try to enable hs200, which will fail,
> and the eMMC initialization will fail.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
Should this be applied as a fix and possibly tagged for stable?
In such case, do you have a specific commit that it fixes?
Kind regards
Uffe
> ---
> drivers/mmc/host/sdhci-of-at91.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
> index 57fe3b2..3a8c6d8 100644
> --- a/drivers/mmc/host/sdhci-of-at91.c
> +++ b/drivers/mmc/host/sdhci-of-at91.c
> @@ -370,6 +370,9 @@ static int sdhci_at91_probe(struct platform_device *pdev)
> pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
> pm_runtime_use_autosuspend(&pdev->dev);
>
> + /* HS200 is broken at this moment */
> + host->quirks2 = SDHCI_QUIRK2_BROKEN_HS200;
> +
> ret = sdhci_add_host(host);
> if (ret)
> goto pm_runtime_disable;
> --
> 2.7.4
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5,2/2] clk: reset: Modify reset-controller driver
From: Stephen Boyd @ 2019-08-08 15:18 UTC (permalink / raw)
To: Yong Liang, chunhui.dai, drinkcat, eddie.huang, erin.lo,
jamesjj.liao, jasu, mark.rutland, matthias.bgg, mturquette,
owen.chen, robh+dt, weiyi.lu
Cc: yong.liang, linux-mediatek, linux-clk, linux-arm-kernel
In-Reply-To: <20190726070135.14347-2-yong.liang@mediatek.com>
Quoting Yong Liang (2019-07-26 00:01:35)
> From: "yong.liang" <yong.liang@mediatek.com>
>
> Set reset signal by a register and
> clear reset signal by another register for 8183.
>
> Signed-off-by: yong.liang <yong.liang@mediatek.com>
> ---
Applied to clk-next with this squashed in
diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c
index 3f1428ed619b..94bbadc0d259 100644
--- a/drivers/clk/mediatek/clk-mt8183.c
+++ b/drivers/clk/mediatek/clk-mt8183.c
@@ -1198,8 +1198,8 @@ static int clk_mt8183_infra_probe(struct platform_device *pdev)
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
if (r) {
dev_err(&pdev->dev,
- "%s(): could not register clock provider: %d\n"
- ,__func__, r);
+ "%s(): could not register clock provider: %d\n",
+ __func__, r);
return r;
}
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
index 17df8f8b57ea..cb939c071b0c 100644
--- a/drivers/clk/mediatek/reset.c
+++ b/drivers/clk/mediatek/reset.c
@@ -90,7 +90,7 @@ static const struct reset_control_ops mtk_reset_ops_set_clr = {
.reset = mtk_reset_set_clr,
};
-void mtk_register_reset_controller_common(struct device_node *np,
+static void mtk_register_reset_controller_common(struct device_node *np,
unsigned int num_regs, int regofs,
const struct reset_control_ops *reset_ops)
{
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] ARM: defconfig: lpc32xx: enable lpc32xx GPIO driver
From: Arnd Bergmann @ 2019-08-08 15:06 UTC (permalink / raw)
To: Sylvain Lemieux; +Cc: Sylvain Lemieux, Linux ARM, Vladimir Zapolskiy
In-Reply-To: <1565186675-1856-1-git-send-email-slemieux.tyco@gmail.com>
On Wed, Aug 7, 2019 at 4:06 PM Sylvain Lemieux <slemieux.tyco@gmail.com> wrote:
>
> From: Sylvain Lemieux <slemieux@tycoint.com>
>
> The change that allow the multiplatform build for the lpc32xx
> platform add a new kernel config for the LPC32XX GPIO driver.
>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Sylvain Lemieux <slemieux@tycoint.com>
> ---
> Note:
> * This patch depend on the following patchset:
> ARM: move lpc32xx and dove to multiplatform
> https://www.spinics.net/lists/linux-usb/msg183095.html
I did not think this was needed, as I added
config GPIO_LPC32XX
tristate "NXP LPC32XX GPIO support"
default ARCH_LPC32XX
depends on OF_GPIO && (ARCH_LPC32XX || COMPILE_TEST)
so when running 'make lpc32xx_defconfig', I expected the
driver to already be enabled. Did I miss something?
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 3/8] of/fdt: add function to get the SoC wide DMA addressable memory size
From: Rob Herring @ 2019-08-08 15:02 UTC (permalink / raw)
To: Nicolas Saenz Julienne
Cc: phill, devicetree,
moderated list:BROADCOM BCM2835 ARM ARCHITECTURE,
Florian Fainelli, Will Deacon, Eric Anholt, Marc Zyngier,
Catalin Marinas, Frank Rowand, linux-kernel@vger.kernel.org,
linux-mm, Linux IOMMU, Matthias Brugger, wahrenst, Andrew Morton,
Robin Murphy, Christoph Hellwig,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Marek Szyprowski
In-Reply-To: <12eb3aba207c552e5eb727535e7c4f08673c4c80.camel@suse.de>
On Tue, Aug 6, 2019 at 12:12 PM Nicolas Saenz Julienne
<nsaenzjulienne@suse.de> wrote:
>
> Hi Rob,
>
> On Mon, 2019-08-05 at 13:23 -0600, Rob Herring wrote:
> > On Mon, Aug 5, 2019 at 10:03 AM Nicolas Saenz Julienne
> > <nsaenzjulienne@suse.de> wrote:
> > > Hi Rob,
> > > Thanks for the review!
> > >
> > > On Fri, 2019-08-02 at 11:17 -0600, Rob Herring wrote:
> > > > On Wed, Jul 31, 2019 at 9:48 AM Nicolas Saenz Julienne
> > > > <nsaenzjulienne@suse.de> wrote:
> > > > > Some SoCs might have multiple interconnects each with their own DMA
> > > > > addressing limitations. This function parses the 'dma-ranges' on each of
> > > > > them and tries to guess the maximum SoC wide DMA addressable memory
> > > > > size.
> > > > >
> > > > > This is specially useful for arch code in order to properly setup CMA
> > > > > and memory zones.
> > > >
> > > > We already have a way to setup CMA in reserved-memory, so why is this
> > > > needed for that?
> > >
> > > Correct me if I'm wrong but I got the feeling you got the point of the patch
> > > later on.
> >
> > No, for CMA I don't. Can't we already pass a size and location for CMA
> > region under /reserved-memory. The only advantage here is perhaps the
> > CMA range could be anywhere in the DMA zone vs. a fixed location.
>
> Now I get it, sorry I wasn't aware of that interface.
>
> Still, I'm not convinced it matches RPi's use case as this would hard-code
> CMA's size. Most people won't care, but for the ones that do, it's nicer to
> change the value from the kernel command line than editing the dtb.
Sure, I fully agree and am not a fan of the CMA DT overlays I've seen.
> I get that
> if you need to, for example, reserve some memory for the video to work, it's
> silly not to hard-code it. Yet due to the board's nature and users base I say
> it's important to favor flexibility. It would also break compatibility with
> earlier versions of the board and diverge from the downstream kernel behaviour.
> Which is a bigger issue than it seems as most users don't always understand
> which kernel they are running and unknowingly copy configuration options from
> forums.
>
> As I also need to know the DMA addressing limitations to properly configure
> memory zones and dma-direct. Setting up the proper CMA constraints during the
> arch's init will be trivial anyway.
It was really just commentary on commit text as for CMA alone we have
a solution already. I agree on the need for zones.
>
> > > > IMO, I'd just do:
> > > >
> > > > if (of_fdt_machine_is_compatible(blob, "brcm,bcm2711"))
> > > > dma_zone_size = XX;
> > > >
> > > > 2 lines of code is much easier to maintain than 10s of incomplete code
> > > > and is clearer who needs this. Maybe if we have dozens of SoCs with
> > > > this problem we should start parsing dma-ranges.
> > >
> > > FYI that's what arm32 is doing at the moment and was my first instinct. But
> > > it
> > > seems that arm64 has been able to survive so far without any machine
> > > specific
> > > code and I have the feeling Catalin and Will will not be happy about this
> > > solution. Am I wrong?
> >
> > No doubt. I'm fine if the 2 lines live in drivers/of/.
> >
> > Note that I'm trying to reduce the number of early_init_dt_scan_*
> > calls from arch code into the DT code so there's more commonality
> > across architectures in the early DT scans. So ideally, this can all
> > be handled under early_init_dt_scan() call.
>
> How does this look? (I'll split it in two patches and add a comment explaining
> why dt_dma_zone_size is needed)
>
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index f2444c61a136..1395be40b722 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -30,6 +30,8 @@
>
> #include "of_private.h"
>
> +u64 dt_dma_zone_size __ro_after_init;
Avoiding a call from arch code by just having a variable isn't really
better. I'd rather see a common, non DT specific variable that can be
adjusted. Something similar to initrd_start/end. Then the arch code
doesn't have to care what hardware description code adjusted the
value.
Rob
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC PATCH 09/11] devfreq: exynos-bus: Add interconnect functionality to exynos-bus
From: Leonard Crestez @ 2019-08-08 15:00 UTC (permalink / raw)
To: Chanwoo Choi, Artur Świgoń, georgi.djakov@linaro.org,
Viresh Kumar
Cc: devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org,
Saravana Kannan, linux-pm@vger.kernel.org, Rafael J. Wysocki,
sw0312.kim@samsung.com, linux-kernel@vger.kernel.org,
dri-devel@lists.freedesktop.org, Lukasz Luba,
inki.dae@samsung.com, myungjoo.ham@samsung.com, krzk@kernel.org,
linux-arm-kernel@lists.infradead.org, m.szyprowski@samsung.com
In-Reply-To: <5a82bf8a-d925-ba54-a26f-98b64bedc6e1@samsung.com>
On 29.07.2019 04:49, Chanwoo Choi wrote:
> On 19. 7. 23. 오후 9:20, Artur Świgoń wrote:
>> This patch adds interconnect functionality to the exynos-bus devfreq
>> driver.
>>
>> The devfreq target() callback provided by exynos-bus now selects either the
>> frequency calculated by the devfreq governor or the frequency requested via
>> the interconnect API for the given node, whichever is higher.
>
> Basically, I agree to support the QoS requirement between devices.
> But, I think that need to consider the multiple cases.
>
> 1. When changing the devfreq governor by user,
> For example of the connection between bus_dmc/leftbus/display on patch8,
> there are possible multiple cases with various devfreq governor
> which is changed on the runtime by user through sysfs interface.
>
> If users changes the devfreq governor as following:
> Before,
> - bus_dmc (simple_ondemand, available frequency 100/200/300/400 MHz)
> --> bus_leftbus(simple_ondemand, available frequency 100/200/300/400 MHz)
> ----> bus_display(passive)
>
> After changed governor of bus_dmc,
> if the min_freq by interconnect requirement is 400Mhz,
> - bus_dmc (powersave) : min_freq and max_freq and cur_freq is 100MHz
> --> bus_leftbus(simple_ondemand) : cur_freq is 400Mhz
> ----> bus_display(passive)
>
> The final frequency is 400MHz of bus_dmc
> even if the min_freq/max_freq/cur_freq is 100MHz.
> It cannot show the correct min_freq/max_freq through
> devfreq sysfs interface.
>
>
> 2. When disabling the some frequency by devfreq-thermal throttling,
> This patch checks the min_freq of interconnect requirement
> in the exynos_bus_target() and exynos_bus_passive_target().
> Also, it cannot show the correct min_freq/max_freq through
> devfreq sysfs interface.
>
> For example of bus_dmc bus,
> - The available frequencies are 100MHz, 200MHz, 300MHz, 400MHz
> - Disable 400MHz by devfreq-thermal throttling
> - min_freq is 100MHz
> - max_freq is 300MHz
> - min_freq of interconnect is 400MHz
>
> In result, the final frequency is 400MHz by exynos_bus_target()
> There are no problem for working. But, the user cannot know
> reason why cur_freq is 400MHz even if max_freq is 300MHz.
>
> Basically, update_devfreq() considers the all constraints
> of min_freq/max_freq to decide the proper target frequency.
I think that applying the interconnect min_freq via dev_pm_qos can help
with many of these concerns: update_devfreq controls all the min/max
handling, sysfs is accurate and better decisions can be made regarding
thermal. Enforcing constraints in the core is definitely better.
This wouldn't even be a very big change, you don't need to actually move
the interconnect code outside of devfreq. Just make every devfreq/icc
node register a dev_pm_qos_request for itself during registration and
call dev_pm_qos_update_request inside exynos_bus_icc_set.
See: https://patchwork.kernel.org/patch/11084279/
--
Regards,
Leonard
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 2/2] clk: Assert prepare_lock in clk_core_get_boundaries
From: Stephen Boyd @ 2019-08-08 15:00 UTC (permalink / raw)
To: Geert Uytterhoeven, Leonard Crestez
Cc: Michael Turquette, linux-clk, linux-arm-kernel
In-Reply-To: <29453ee8e820457d87a8faf9d496390e59c6826f.1562073871.git.leonard.crestez@nxp.com>
Quoting Leonard Crestez (2019-07-02 06:27:10)
> This function iterates the clk consumer list on clk_core so it must be
> called under prepare_lock. This is already done by all callers but add a
> lockdep assert to check anyway.
>
> Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
>
> ---
Applied to clk-next
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 1/2] clk: Add clk_min/max_rate entries in debugfs
From: Stephen Boyd @ 2019-08-08 15:00 UTC (permalink / raw)
To: Geert Uytterhoeven, Leonard Crestez
Cc: Michael Turquette, linux-clk, linux-arm-kernel
In-Reply-To: <68e96af2df96512300604d797ade2088d7e6e496.1562073871.git.leonard.crestez@nxp.com>
Quoting Leonard Crestez (2019-07-02 06:27:09)
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index c0990703ce54..e4e224982ae3 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2894,19 +2894,26 @@ static int clk_summary_show(struct seq_file *s, void *data)
> }
> DEFINE_SHOW_ATTRIBUTE(clk_summary);
>
> static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
> {
> + unsigned long min_rate, max_rate;
> +
> if (!c)
> return;
>
> /* This should be JSON format, i.e. elements separated with a comma */
> seq_printf(s, "\"%s\": { ", c->name);
> seq_printf(s, "\"enable_count\": %d,", c->enable_count);
> seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
> seq_printf(s, "\"protect_count\": %d,", c->protect_count);
> seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
> + clk_core_get_boundaries(c, &min_rate, &max_rate);
> + if (min_rate != 0)
> + seq_printf(s, "\"min_rate\": %lu,", min_rate);
> + if (max_rate != ULONG_MAX)
> + seq_printf(s, "\"max_rate\": %lu,", max_rate);
What are the if conditions about? We always output the values in the
individual files, but for some reason we don't want to do that in the
json output?
> seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
> seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c));
> seq_printf(s, "\"duty_cycle\": %u",
> clk_core_get_scaled_duty_cycle(c, 100000));
> }
Everything else looks fine, so maybe I'll just remove the if statements
if you don't mind.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] pinctrl: freescale: imx: Add of_node_put() before return
From: Philipp Zabel @ 2019-08-08 14:56 UTC (permalink / raw)
To: Nishka Dasgupta, aisheng.dong, festevam, shawnguo, stefan, kernel,
linus.walleij, s.hauer, linux-imx, linux-gpio, linux-arm-kernel
In-Reply-To: <20190808074720.15754-1-nishkadg.linux@gmail.com>
On Thu, 2019-08-08 at 13:17 +0530, Nishka Dasgupta wrote:
> Each iteration of for_each_child_of_node() puts the previous node;
> however, in the case of a return from the middle of the loop, there is no
> put, thus causing a memory leak. Hence put of_node_put() statements as
> required before two mid-loop return statements.
> Issue found with Coccinelle.
>
> Signed-off-by: Nishka Dasgupta <nishkadg.linux@gmail.com>
> ---
> drivers/pinctrl/freescale/pinctrl-imx.c | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
> index 83ff9532bae6..9f42036c5fbb 100644
> --- a/drivers/pinctrl/freescale/pinctrl-imx.c
> +++ b/drivers/pinctrl/freescale/pinctrl-imx.c
> @@ -672,8 +672,10 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
>
> grp = devm_kzalloc(ipctl->dev, sizeof(struct group_desc),
> GFP_KERNEL);
This looks to me like it could just allocate an array of struct
group_desc upfront, just like the group_names array. Same for the
functions in imx_pinctrl_probe_dt(). Not an issue with this patch
though.
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
> - if (!grp)
> + if (!grp) {
> + of_node_put(child);
> return -ENOMEM;
> + }
>
> mutex_lock(&ipctl->mutex);
> radix_tree_insert(&pctl->pin_group_tree,
> @@ -697,12 +699,17 @@ static bool imx_pinctrl_dt_is_flat_functions(struct device_node *np)
> struct device_node *pinctrl_np;
>
> for_each_child_of_node(np, function_np) {
> - if (of_property_read_bool(function_np, "fsl,pins"))
> + if (of_property_read_bool(function_np, "fsl,pins")) {
> + of_node_put(function_np);
> return true;
> + }
>
> for_each_child_of_node(function_np, pinctrl_np) {
> - if (of_property_read_bool(pinctrl_np, "fsl,pins"))
> + if (of_property_read_bool(pinctrl_np, "fsl,pins")) {
> + of_node_put(pinctrl_np);
> + of_node_put(function_np);
> return false;
> + }
> }
> }
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [linux-sunxi] [PATCH] ARM64: dts: allwinner: Add devicetree for pine H64 modelA evaluation board
From: Clément Péron @ 2019-08-08 14:50 UTC (permalink / raw)
To: clabbe.montjoie
Cc: Mark Rutland, devicetree, linux-sunxi, linux-kernel, mripard,
Chen-Yu Tsai, Rob Herring, linux-arm-kernel
In-Reply-To: <20190808084253.10573-1-clabbe.montjoie@gmail.com>
Hi,
On Thu, 8 Aug 2019 at 10:42, Corentin Labbe <clabbe.montjoie@gmail.com> wrote:
>
> This patch adds the evaluation variant of the model A of the PineH64.
> The model A has the same size of the pine64 and has a PCIE slot.
>
> The only devicetree difference with current pineH64, is the PHY
> regulator.
You also need to add the board in
"Documentation/devicetree/bindings/arm/sunxi.yaml"
Regards,
Clément
>
> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> ---
> arch/arm64/boot/dts/allwinner/Makefile | 1 +
> .../sun50i-h6-pine-h64-modelA-eval.dts | 26 +++++++++++++++++++
> 2 files changed, 27 insertions(+)
> create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-modelA-eval.dts
>
> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
> index f6db0611cb85..9a02166cbf72 100644
> --- a/arch/arm64/boot/dts/allwinner/Makefile
> +++ b/arch/arm64/boot/dts/allwinner/Makefile
> @@ -25,3 +25,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-3.dtb
> dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-lite2.dtb
> dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
> dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-modelA-eval.dtb
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-modelA-eval.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-modelA-eval.dts
> new file mode 100644
> index 000000000000..d8ff02747efe
> --- /dev/null
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-modelA-eval.dts
> @@ -0,0 +1,26 @@
> +// SPDX-License-Identifier: (GPL-2.0+ or MIT)
> +/*
> + * Copyright (C) 2019 Corentin Labbe <clabbe.montjoie@gmail.com>
> + */
> +
> +#include "sun50i-h6-pine-h64.dts"
> +
> +/ {
> + model = "Pine H64 model A evaluation board";
> + compatible = "pine64,pine-h64-modelA-eval", "allwinner,sun50i-h6";
> +
> + reg_gmac_3v3: gmac-3v3 {
> + compatible = "regulator-fixed";
> + regulator-name = "vcc-gmac-3v3";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + startup-delay-us = <100000>;
> + gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
> + };
> +
> +};
> +
> +&emac {
> + phy-supply = <®_gmac_3v3>;
> +};
> --
> 2.21.0
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20190808084253.10573-1-clabbe.montjoie%40gmail.com.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 1/2] arm64: dts: ti: k3-am65-main: Fix gic-its node unit-address
From: Suman Anna @ 2019-08-08 14:39 UTC (permalink / raw)
To: Tero Kristo, Nishanth Menon; +Cc: devicetree, Robert Tivy, linux-arm-kernel
In-Reply-To: <20190808143929.11148-1-s-anna@ti.com>
The gic-its node unit-address has an additional zero compared
to the actual reg value. Fix it.
Fixes: ea47eed33a3f ("arm64: dts: ti: Add Support for AM654 SoC")
Reported-by: Robert Tivy <rtivy@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
---
arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index ca70ff73f171..38c75fb3f232 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -42,7 +42,7 @@
*/
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
- gic_its: gic-its@18200000 {
+ gic_its: gic-its@1820000 {
compatible = "arm,gic-v3-its";
reg = <0x00 0x01820000 0x00 0x10000>;
socionext,synquacer-pre-its = <0x1000000 0x400000>;
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 2/2] arm64: dts: ti: k3-j721e-main: Fix gic-its node unit-address
From: Suman Anna @ 2019-08-08 14:39 UTC (permalink / raw)
To: Tero Kristo, Nishanth Menon; +Cc: devicetree, Robert Tivy, linux-arm-kernel
In-Reply-To: <20190808143929.11148-1-s-anna@ti.com>
The gic-its node unit-address has an additional zero compared
to the actual reg value. Fix it.
Fixes: 2d87061e70de ("arm64: dts: ti: Add Support for J721E SoC")
Reported-by: Robert Tivy <rtivy@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
---
arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index a01308142f77..ea5c0fd42baf 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -31,7 +31,7 @@
/* vcpumntirq: virtual CPU interface maintenance interrupt */
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
- gic_its: gic-its@18200000 {
+ gic_its: gic-its@1820000 {
compatible = "arm,gic-v3-its";
reg = <0x00 0x01820000 0x00 0x10000>;
socionext,synquacer-pre-its = <0x1000000 0x400000>;
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 0/2] K3 dts minor typo fixes
From: Suman Anna @ 2019-08-08 14:39 UTC (permalink / raw)
To: Tero Kristo, Nishanth Menon; +Cc: devicetree, linux-arm-kernel
Hi Tero, Nishanth,
The following 2 patches are minor typo fixes in git-its nodes
on both AM65x and J721E SoCs. Patches done on top of the latest
master.
regards
Suman
Suman Anna (2):
arm64: dts: ti: k3-am65-main: Fix gic-its node unit-address
arm64: dts: ti: k3-j721e-main: Fix gic-its node unit-address
arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 2 +-
arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--
2.22.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCHv2] PM / devfreq: Add dev_pm_qos support
From: Leonard Crestez @ 2019-08-08 14:39 UTC (permalink / raw)
To: MyungJoo Ham, Viresh Kumar, Saravana Kannan
Cc: Artur Świgoń, linux-pm, Rafael J. Wysocki,
Krzysztof Kozlowski, Lukasz Luba, Chanwoo Choi, Kyungmin Park,
Alexandre Bailon, Georgi Djakov, linux-arm-kernel
Add dev_pm_qos notifies to devfreq core in order to support frequency
limits via the dev_pm_qos_add_request.
Unlike the rest of devfreq the dev_pm_qos frequency is measured Khz:
this is consistent with current dev_pm_qos usage for cpufreq and allows
frequencies above 2Ghz (pm_qos expresses limits as s32).
Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
---
Changes since v1:
* Add doxygen comments for min_nb/max_nb
* Remove notifiers on error/cleanup paths. Keep gotos simple by relying
on dev_pm_qos_remove_notifier ignoring notifiers which were not added.
Link to v1: https://patchwork.kernel.org/patch/11078475/
drivers/devfreq/devfreq.c | 83 ++++++++++++++++++++++++++++++++++-----
include/linux/devfreq.h | 5 +++
2 files changed, 79 insertions(+), 9 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 784c08e4f931..7f1f273562f4 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -22,10 +22,11 @@
#include <linux/platform_device.h>
#include <linux/list.h>
#include <linux/printk.h>
#include <linux/hrtimer.h>
#include <linux/of.h>
+#include <linux/pm_qos.h>
#include "governor.h"
#define CREATE_TRACE_POINTS
#include <trace/events/devfreq.h>
@@ -96,10 +97,26 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq)
dev_pm_opp_put(opp);
return max_freq;
}
+static unsigned long get_effective_min_freq(struct devfreq *devfreq)
+{
+ return max3(devfreq->scaling_min_freq, devfreq->min_freq,
+ 1000 * (unsigned long)dev_pm_qos_read_value(
+ devfreq->dev.parent,
+ DEV_PM_QOS_MIN_FREQUENCY));
+}
+
+static unsigned long get_effective_max_freq(struct devfreq *devfreq)
+{
+ return min3(devfreq->scaling_max_freq, devfreq->max_freq,
+ 1000 * (unsigned long)dev_pm_qos_read_value(
+ devfreq->dev.parent,
+ DEV_PM_QOS_MAX_FREQUENCY));
+}
+
/**
* devfreq_get_freq_level() - Lookup freq_table for the frequency
* @devfreq: the devfreq instance
* @freq: the target frequency
*/
@@ -356,12 +373,12 @@ int update_devfreq(struct devfreq *devfreq)
*
* List from the highest priority
* max_freq
* min_freq
*/
- max_freq = min(devfreq->scaling_max_freq, devfreq->max_freq);
- min_freq = max(devfreq->scaling_min_freq, devfreq->min_freq);
+ max_freq = get_effective_max_freq(devfreq);
+ min_freq = get_effective_min_freq(devfreq);
if (freq < min_freq) {
freq = min_freq;
flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
}
@@ -570,10 +587,31 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
mutex_unlock(&devfreq->lock);
return ret;
}
+static int devfreq_qos_notifier_call(struct devfreq *devfreq)
+{
+ int ret;
+
+ mutex_lock(&devfreq->lock);
+ ret = update_devfreq(devfreq);
+ mutex_unlock(&devfreq->lock);
+
+ return ret;
+}
+
+static int devfreq_qos_min_notifier_call(struct notifier_block *nb, unsigned long val, void *ptr)
+{
+ return devfreq_qos_notifier_call(container_of(nb, struct devfreq, nb_min));
+}
+
+static int devfreq_qos_max_notifier_call(struct notifier_block *nb, unsigned long val, void *ptr)
+{
+ return devfreq_qos_notifier_call(container_of(nb, struct devfreq, nb_max));
+}
+
/**
* devfreq_dev_release() - Callback for struct device to release the device.
* @dev: the devfreq device
*
* Remove devfreq from the list and release its resources.
@@ -592,10 +630,14 @@ static void devfreq_dev_release(struct device *dev)
mutex_unlock(&devfreq_list_lock);
if (devfreq->profile->exit)
devfreq->profile->exit(devfreq->dev.parent);
+ dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_max,
+ DEV_PM_QOS_MAX_FREQUENCY);
+ dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_min,
+ DEV_PM_QOS_MIN_FREQUENCY);
mutex_destroy(&devfreq->lock);
kfree(devfreq);
}
/**
@@ -636,21 +678,44 @@ struct devfreq *devfreq_add_device(struct device *dev,
err = -ENOMEM;
goto err_out;
}
mutex_init(&devfreq->lock);
- mutex_lock(&devfreq->lock);
devfreq->dev.parent = dev;
devfreq->dev.class = devfreq_class;
devfreq->dev.release = devfreq_dev_release;
devfreq->profile = profile;
strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN);
devfreq->previous_freq = profile->initial_freq;
devfreq->last_status.current_frequency = profile->initial_freq;
devfreq->data = data;
devfreq->nb.notifier_call = devfreq_notifier_call;
+ /*
+ * notifier from pm_qos
+ *
+ * initialized outside of devfreq->lock to avoid circular warning
+ * between devfreq->lock and dev_pm_qos_mtx
+ */
+ devfreq->nb_min.notifier_call = devfreq_qos_min_notifier_call;
+ devfreq->nb_max.notifier_call = devfreq_qos_max_notifier_call;
+
+ err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_min,
+ DEV_PM_QOS_MIN_FREQUENCY);
+ if (err) {
+ dev_err(dev, "Failed to register MIN QoS notifier: %d\n", err);
+ goto err_dev;
+ }
+
+ err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_max,
+ DEV_PM_QOS_MAX_FREQUENCY);
+ if (err) {
+ dev_err(dev, "Failed to register MAX QoS notifier: %d\n", err);
+ goto err_dev;
+ }
+
+ mutex_lock(&devfreq->lock);
if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
mutex_unlock(&devfreq->lock);
err = set_freq_table(devfreq);
if (err < 0)
goto err_dev;
@@ -741,10 +806,14 @@ struct devfreq *devfreq_add_device(struct device *dev,
mutex_unlock(&devfreq_list_lock);
err_devfreq:
devfreq_remove_device(devfreq);
devfreq = NULL;
err_dev:
+ dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_max,
+ DEV_PM_QOS_MAX_FREQUENCY);
+ dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_min,
+ DEV_PM_QOS_MIN_FREQUENCY);
kfree(devfreq);
err_out:
return ERR_PTR(err);
}
EXPORT_SYMBOL(devfreq_add_device);
@@ -1311,13 +1380,11 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
}
static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct devfreq *df = to_devfreq(dev);
-
- return sprintf(buf, "%lu\n", max(df->scaling_min_freq, df->min_freq));
+ return sprintf(buf, "%lu\n", get_effective_min_freq(to_devfreq(dev)));
}
static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -1356,13 +1423,11 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR_RW(min_freq);
static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct devfreq *df = to_devfreq(dev);
-
- return sprintf(buf, "%lu\n", min(df->scaling_max_freq, df->max_freq));
+ return sprintf(buf, "%lu\n", get_effective_max_freq(to_devfreq(dev)));
}
static DEVICE_ATTR_RW(max_freq);
static ssize_t available_frequencies_show(struct device *d,
struct device_attribute *attr,
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 2bae9ed3c783..8b92ccbd1962 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -134,10 +134,12 @@ struct devfreq_dev_profile {
* @total_trans: Number of devfreq transitions
* @trans_table: Statistics of devfreq transitions
* @time_in_state: Statistics of devfreq states
* @last_stat_updated: The last time stat updated
* @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier
+ * @nb_min: Notifier block for DEV_PM_QOS_MIN_FREQUENCY
+ * @nb_max: Notifier block for DEV_PM_QOS_MAX_FREQUENCY
*
* This structure stores the devfreq information for a give device.
*
* Note that when a governor accesses entries in struct devfreq in its
* functions except for the context of callbacks defined in struct
@@ -176,10 +178,13 @@ struct devfreq {
unsigned int *trans_table;
unsigned long *time_in_state;
unsigned long last_stat_updated;
struct srcu_notifier_head transition_notifier_list;
+
+ struct notifier_block nb_min;
+ struct notifier_block nb_max;
};
struct devfreq_freqs {
unsigned long old;
unsigned long new;
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v2] arm64: dts: rockchip: Add dts for Leez RK3399 P710 SBC
From: Rob Herring @ 2019-08-08 14:24 UTC (permalink / raw)
To: Andy Yan
Cc: devicetree, linux-kernel@vger.kernel.org, heiko@sntech.de,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
open list:ARM/Rockchip SoC...
In-Reply-To: <CANbgqATvVSo_D-n_mW2hK2KEK_8cs3374ddB6C8GcZZwjMSoRQ@mail.gmail.com>
On Wed, Aug 7, 2019 at 12:14 AM Andy Yan <andyshrk@gmail.com> wrote:
>
> Hi Rob:
>
> Rob Herring <robh+dt@kernel.org> 于2019年8月6日周二 下午10:48写道:
>>
>> On Mon, Aug 5, 2019 at 6:40 AM Andy Yan <andyshrk@gmail.com> wrote:
>> >
>> > P710 is a RK3399 based SBC, designed by Leez [0].
>> >
>> > Specification
>> > - Rockchip RK3399
>> > - 4/2GB LPDDR4
>> > - TF sd scard slot
>> > - eMMC
>> > - M.2 B-Key for 4G LTE
>> > - AP6256 for WiFi + BT
>> > - Gigabit ethernet
>> > - HDMI out
>> > - 40 pin header
>> > - USB 2.0 x 2
>> > - USB 3.0 x 1
>> > - USB 3.0 Type-C x 1
>> > - TYPE-C Power supply
>> >
>> > [0]https://leez.lenovo.com
>>
>> I'm not really convinced Leez is a vendor. Looks like branding to me.
>> We have enough with company names changing, we don't need changing
>> brands too. Use 'lenovo'.
>>
>
> I had checked with Leez people before V1, they said Leez will run as an independent company, so they don't want to
> give a lenovo label for this board.
Okay.
Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: i2c: imx: support slave mode for imx I2C driver
From: Sascha Hauer @ 2019-08-08 14:18 UTC (permalink / raw)
To: Biwen Li
Cc: wsa, shawnguo, linux-kernel, linux-i2c, kernel, laurentiu.tudor,
festevam, linux-arm-kernel, linux-imx
In-Reply-To: <20190808035343.34120-1-biwen.li@nxp.com>
Hi,
On Thu, Aug 08, 2019 at 11:53:43AM +0800, Biwen Li wrote:
> The patch supports slave mode for imx I2C driver
>
> Signed-off-by: Biwen Li <biwen.li@nxp.com>
> ---
> drivers/i2c/busses/i2c-imx.c | 199 ++++++++++++++++++++++++++++++++---
> 1 file changed, 185 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
> index b1b8b938d7f4..f7583a9fa56f 100644
> --- a/drivers/i2c/busses/i2c-imx.c
> +++ b/drivers/i2c/busses/i2c-imx.c
> @@ -202,6 +202,9 @@ struct imx_i2c_struct {
> struct pinctrl_state *pinctrl_pins_gpio;
>
> struct imx_i2c_dma *dma;
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> + struct i2c_client *slave;
> +#endif /* CONFIG_I2C_SLAVE */
Other drivers just do a "select I2C_SLAVE" in Kconfig to get rid of
these #ifs. We should do the same.
> };
>
> static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
> @@ -583,23 +586,40 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
> imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
> }
>
> -static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
> +/* Clear interrupt flag bit */
> +static void i2c_imx_clr_if_bit(struct imx_i2c_struct *i2c_imx)
> {
> - struct imx_i2c_struct *i2c_imx = dev_id;
> - unsigned int temp;
> + unsigned int status;
>
> - temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> - if (temp & I2SR_IIF) {
> - /* save status register */
> - i2c_imx->i2csr = temp;
> - temp &= ~I2SR_IIF;
> - temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
> - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
> - wake_up(&i2c_imx->queue);
> - return IRQ_HANDLED;
> - }
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + status &= ~I2SR_IIF;
> + status |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
> + imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
> +}
> +
> +/* Clear arbitration lost bit */
> +static void i2c_imx_clr_al_bit(struct imx_i2c_struct *i2c_imx)
> +{
> + unsigned int status;
> +
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + status &= ~I2SR_IAL;
> + imx_i2c_write_reg(status, i2c_imx, IMX_I2C_I2SR);
> +}
>
> - return IRQ_NONE;
> +static irqreturn_t i2c_imx_master_isr(struct imx_i2c_struct *i2c_imx)
> +{
> + unsigned int status;
> +
> + dev_dbg(&i2c_imx->adapter.dev, "<%s>: master interrupt\n", __func__);
Generally this driver has way too many dev_dbg spread around in hot
pathes already. IMO adding more doesn't make the output more useful.
> +
> + /* Save status register */
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + i2c_imx->i2csr = status | I2SR_IIF;
> +
> + wake_up(&i2c_imx->queue);
> +
> + return IRQ_HANDLED;
> }
>
> static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
> @@ -1043,11 +1063,162 @@ static u32 i2c_imx_func(struct i2c_adapter *adapter)
> | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
> }
>
> +#if IS_ENABLED(CONFIG_I2C_SLAVE)
> +static void i2c_imx_slave_init(struct imx_i2c_struct *i2c_imx)
> +{
> + unsigned int temp;
> +
> + dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
> +
> + /* Set slave addr. */
> + imx_i2c_write_reg((i2c_imx->slave->addr << 1), i2c_imx, IMX_I2C_IADR);
> +
> + /* Disable i2c module */
> + temp = i2c_imx->hwdata->i2cr_ien_opcode
> + ^ I2CR_IEN;
unnecessary line break.
> + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
> +
> + /* Reset status register */
> + imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx,
> + IMX_I2C_I2SR);
> +
> + /* Enable module and enable interrupt from i2c module */
> + temp = i2c_imx->hwdata->i2cr_ien_opcode
> + | I2CR_IIEN;
ditto.
> + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
> +
> + /* Wait controller to be stable */
> + usleep_range(50, 150);
> +}
> +
> +static irqreturn_t i2c_imx_slave_isr(struct imx_i2c_struct *i2c_imx)
> +{
> + unsigned int status, ctl;
> + u8 value;
> +
> + if (!i2c_imx->slave) {
> + dev_err(&i2c_imx->adapter.dev, "cannot deal with slave irq,i2c_imx->slave is null");
> + return IRQ_NONE;
> + }
> +
> + status = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
> + ctl = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
> + if (status & I2SR_IAL) { /* Arbitration lost */
> + i2c_imx_clr_al_bit(i2c_imx);
> + } else if (status & I2SR_IAAS) { /* Addressed as a slave */
> + if (status & I2SR_SRW) { /* Master wants to read from us*/
> + dev_dbg(&i2c_imx->adapter.dev, "read requested");
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_READ_REQUESTED, &value);
> +
> + /* Slave transimt */
s/transimt/transmit/
> + ctl |= I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> +
> + /* Send data */
> + imx_i2c_write_reg(value, i2c_imx, IMX_I2C_I2DR);
> + } else { /* Master wants to write to us */
> + dev_dbg(&i2c_imx->adapter.dev, "write requested");
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
> +
> + /* Slave receive */
> + ctl &= ~I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> + /* Dummy read */
> + value = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
value is unused, no need to assign a value to it.
> + }
> + } else {
> + if (!(ctl & I2CR_MTX)) { /* Receive mode */
Since you have an 'else' path please convert this to positive logic.
This makes it easier to read.
> + if (status & I2SR_IBB) { /* No STOP signal detected */
> + ctl &= ~I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> +
> + value = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
> + } else { /* STOP signal is detected */
> + dev_dbg(&i2c_imx->adapter.dev,
> + "STOP signal detected");
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_STOP, &value);
> + }
> + } else { /* Transmit mode */
> + if (!(status & I2SR_RXAK)) { /* Received ACK */
Same here.
> + ctl |= I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> +
> + i2c_slave_event(i2c_imx->slave, I2C_SLAVE_READ_PROCESSED, &value);
> +
> + imx_i2c_write_reg(value, i2c_imx, IMX_I2C_I2DR);
> + } else { /* Received NAK */
> + ctl &= ~I2CR_MTX;
> + imx_i2c_write_reg(ctl, i2c_imx, IMX_I2C_I2CR);
> + value = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
Also value unused.
> + }
> + }
> + }
> + return IRQ_HANDLED;
> +}
> +
> +static int i2c_imx_reg_slave(struct i2c_client *client)
> +{
> + struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(client->adapter);
> +
> + if (i2c_imx->slave)
> + return -EINVAL;
Better -EBUSY?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 0/9] drm: meson: global clean-up (use proper macros, update comments ...)
From: Neil Armstrong @ 2019-08-08 14:12 UTC (permalink / raw)
To: Kevin Hilman, Julien Masson
Cc: linux-amlogic, dri-devel, linux-arm-kernel, linux-kernel
In-Reply-To: <7ho92mwor0.fsf@baylibre.com>
On 25/06/2019 01:24, Kevin Hilman wrote:
> Julien Masson <jmasson@baylibre.com> writes:
>
>> This patch series aims to clean-up differents parts of the drm meson
>> code source.
>>
>> Couple macros have been defined and used to set several registers
>> instead of using magic constants.
>>
>> I also took the opportunity to:
>> - add/remove/update comments
>> - remove useless code
>> - minor fix/improvment
>
> Nice set of cleanups, thanks! I especially like the extra in-code
> comments.
>
> Could you also add to the cover-letter how this was tested, and on what
> platforms so we know it's not going to introduce any regressions.
>
> Thanks,
>
> Kevin
>
Apart the wrong magic value in patch 4 that I'll fix while applying,
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
I'll run a few tests on all the supported SoC versions:
- GXBB
- GXL
- GXM
- G12A/G12B
and push to drm-misc-next.
Neil
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ 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