mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 10:01:39 -05:00
Merge tag 'soc-drivers-6.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull more SoC driver updates from Arnd Bergmann:
"These updates came a little late, or were based on a later 6.18-rc tag
than the others:
- A new driver for cache management on cxl devices with memory shared
in a coherent cluster. This is part of the drivers/cache/ tree, but
unlike the other drivers that back the dma-mapping interfaces, this
one is needed only during CPU hotplug.
- A shared branch for reset controllers using swnode infrastructure
- Added support for new SoC variants in the Amlogic soc_device
identification
- Minor updates in Freescale, Microchip, Samsung, and Apple SoC
drivers"
* tag 'soc-drivers-6.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (24 commits)
soc: samsung: exynos-pmu: fix device leak on regmap lookup
soc: samsung: exynos-pmu: Fix structure initialization
soc: fsl: qbman: use kmalloc_array() instead of kmalloc()
soc: fsl: qbman: add WQ_PERCPU to alloc_workqueue users
MAINTAINERS: Update email address for Christophe Leroy
MAINTAINERS: refer to intended file in STANDALONE CACHE CONTROLLER DRIVERS
cache: Support cache maintenance for HiSilicon SoC Hydra Home Agent
cache: Make top level Kconfig menu a boolean dependent on RISCV
MAINTAINERS: Add Jonathan Cameron to drivers/cache and add lib/cache_maint.c + header
arm64: Select GENERIC_CPU_CACHE_MAINTENANCE
lib: Support ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
soc: amlogic: meson-gx-socinfo: add new SoCs id
dt-bindings: arm: amlogic: meson-gx-ao-secure: support more SoCs
memregion: Support fine grained invalidate by cpu_cache_invalidate_memregion()
memregion: Drop unused IORES_DESC_* parameter from cpu_cache_invalidate_memregion()
dt-bindings: cache: sifive,ccache0: add a pic64gx compatible
MAINTAINERS: rename Microchip RISC-V entry
MAINTAINERS: add new soc drivers to Microchip RISC-V entry
soc: microchip: add mfd drivers for two syscon regions on PolarFire SoC
dt-bindings: soc: microchip: document the simple-mfd syscon on PolarFire SoC
...
This commit is contained in:
@@ -542,6 +542,9 @@ config MEMREGION
|
||||
config ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
|
||||
bool
|
||||
|
||||
config GENERIC_CPU_CACHE_MAINTENANCE
|
||||
bool
|
||||
|
||||
config ARCH_HAS_MEMREMAP_COMPAT_ALIGN
|
||||
bool
|
||||
|
||||
|
||||
@@ -127,6 +127,8 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
|
||||
obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o
|
||||
obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
|
||||
|
||||
obj-$(CONFIG_GENERIC_CPU_CACHE_MAINTENANCE) += cache_maint.o
|
||||
|
||||
lib-y += logic_pio.o
|
||||
|
||||
lib-$(CONFIG_INDIRECT_IOMEM) += logic_iomem.o
|
||||
|
||||
138
lib/cache_maint.c
Normal file
138
lib/cache_maint.c
Normal file
@@ -0,0 +1,138 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Generic support for Memory System Cache Maintenance operations.
|
||||
*
|
||||
* Coherency maintenance drivers register with this simple framework that will
|
||||
* iterate over each registered instance to first kick off invalidation and
|
||||
* then to wait until it is complete.
|
||||
*
|
||||
* If no implementations are registered yet cpu_cache_has_invalidate_memregion()
|
||||
* will return false. If this runs concurrently with unregistration then a
|
||||
* race exists but this is no worse than the case where the operations instance
|
||||
* responsible for a given memory region has not yet registered.
|
||||
*/
|
||||
#include <linux/cache_coherency.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/memregion.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static LIST_HEAD(cache_ops_instance_list);
|
||||
static DECLARE_RWSEM(cache_ops_instance_list_lock);
|
||||
|
||||
static void __cache_coherency_ops_instance_free(struct kref *kref)
|
||||
{
|
||||
struct cache_coherency_ops_inst *cci =
|
||||
container_of(kref, struct cache_coherency_ops_inst, kref);
|
||||
kfree(cci);
|
||||
}
|
||||
|
||||
void cache_coherency_ops_instance_put(struct cache_coherency_ops_inst *cci)
|
||||
{
|
||||
kref_put(&cci->kref, __cache_coherency_ops_instance_free);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cache_coherency_ops_instance_put);
|
||||
|
||||
static int cache_inval_one(struct cache_coherency_ops_inst *cci, void *data)
|
||||
{
|
||||
if (!cci->ops)
|
||||
return -EINVAL;
|
||||
|
||||
return cci->ops->wbinv(cci, data);
|
||||
}
|
||||
|
||||
static int cache_inval_done_one(struct cache_coherency_ops_inst *cci)
|
||||
{
|
||||
if (!cci->ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!cci->ops->done)
|
||||
return 0;
|
||||
|
||||
return cci->ops->done(cci);
|
||||
}
|
||||
|
||||
static int cache_invalidate_memregion(phys_addr_t addr, size_t size)
|
||||
{
|
||||
int ret;
|
||||
struct cache_coherency_ops_inst *cci;
|
||||
struct cc_inval_params params = {
|
||||
.addr = addr,
|
||||
.size = size,
|
||||
};
|
||||
|
||||
guard(rwsem_read)(&cache_ops_instance_list_lock);
|
||||
list_for_each_entry(cci, &cache_ops_instance_list, node) {
|
||||
ret = cache_inval_one(cci, ¶ms);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
list_for_each_entry(cci, &cache_ops_instance_list, node) {
|
||||
ret = cache_inval_done_one(cci);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cache_coherency_ops_inst *
|
||||
_cache_coherency_ops_instance_alloc(const struct cache_coherency_ops *ops,
|
||||
size_t size)
|
||||
{
|
||||
struct cache_coherency_ops_inst *cci;
|
||||
|
||||
if (!ops || !ops->wbinv)
|
||||
return NULL;
|
||||
|
||||
cci = kzalloc(size, GFP_KERNEL);
|
||||
if (!cci)
|
||||
return NULL;
|
||||
|
||||
cci->ops = ops;
|
||||
INIT_LIST_HEAD(&cci->node);
|
||||
kref_init(&cci->kref);
|
||||
|
||||
return cci;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(_cache_coherency_ops_instance_alloc, "CACHE_COHERENCY");
|
||||
|
||||
int cache_coherency_ops_instance_register(struct cache_coherency_ops_inst *cci)
|
||||
{
|
||||
guard(rwsem_write)(&cache_ops_instance_list_lock);
|
||||
list_add(&cci->node, &cache_ops_instance_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cache_coherency_ops_instance_register, "CACHE_COHERENCY");
|
||||
|
||||
void cache_coherency_ops_instance_unregister(struct cache_coherency_ops_inst *cci)
|
||||
{
|
||||
guard(rwsem_write)(&cache_ops_instance_list_lock);
|
||||
list_del(&cci->node);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cache_coherency_ops_instance_unregister, "CACHE_COHERENCY");
|
||||
|
||||
int cpu_cache_invalidate_memregion(phys_addr_t start, size_t len)
|
||||
{
|
||||
return cache_invalidate_memregion(start, len);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cpu_cache_invalidate_memregion, "DEVMEM");
|
||||
|
||||
/*
|
||||
* Used for optimization / debug purposes only as removal can race
|
||||
*
|
||||
* Machines that do not support invalidation, e.g. VMs, will not have any
|
||||
* operations instance to register and so this will always return false.
|
||||
*/
|
||||
bool cpu_cache_has_invalidate_memregion(void)
|
||||
{
|
||||
guard(rwsem_read)(&cache_ops_instance_list_lock);
|
||||
return !list_empty(&cache_ops_instance_list);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cpu_cache_has_invalidate_memregion, "DEVMEM");
|
||||
Reference in New Issue
Block a user