mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 08:14:15 +08:00
d9c58aeb40
The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Acked-by: Andrew Donnellan <ajd@linux.ibm.com> # cxl Signed-off-by: Rob Herring <robh@kernel.org> Link: https://lore.kernel.org/r/20230718143102.1065481-1-robh@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
127 lines
2.5 KiB
C
127 lines
2.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright 2014 IBM Corp.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/rcupdate.h>
|
|
#include <asm/errno.h>
|
|
#include <misc/cxl-base.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_platform.h>
|
|
#include "cxl.h"
|
|
|
|
/* protected by rcu */
|
|
static struct cxl_calls *cxl_calls;
|
|
|
|
atomic_t cxl_use_count = ATOMIC_INIT(0);
|
|
EXPORT_SYMBOL(cxl_use_count);
|
|
|
|
#ifdef CONFIG_CXL_MODULE
|
|
|
|
static inline struct cxl_calls *cxl_calls_get(void)
|
|
{
|
|
struct cxl_calls *calls = NULL;
|
|
|
|
rcu_read_lock();
|
|
calls = rcu_dereference(cxl_calls);
|
|
if (calls && !try_module_get(calls->owner))
|
|
calls = NULL;
|
|
rcu_read_unlock();
|
|
|
|
return calls;
|
|
}
|
|
|
|
static inline void cxl_calls_put(struct cxl_calls *calls)
|
|
{
|
|
BUG_ON(calls != cxl_calls);
|
|
|
|
/* we don't need to rcu this, as we hold a reference to the module */
|
|
module_put(cxl_calls->owner);
|
|
}
|
|
|
|
#else /* !defined CONFIG_CXL_MODULE */
|
|
|
|
static inline struct cxl_calls *cxl_calls_get(void)
|
|
{
|
|
return cxl_calls;
|
|
}
|
|
|
|
static inline void cxl_calls_put(struct cxl_calls *calls) { }
|
|
|
|
#endif /* CONFIG_CXL_MODULE */
|
|
|
|
/* AFU refcount management */
|
|
struct cxl_afu *cxl_afu_get(struct cxl_afu *afu)
|
|
{
|
|
return (get_device(&afu->dev) == NULL) ? NULL : afu;
|
|
}
|
|
EXPORT_SYMBOL_GPL(cxl_afu_get);
|
|
|
|
void cxl_afu_put(struct cxl_afu *afu)
|
|
{
|
|
put_device(&afu->dev);
|
|
}
|
|
EXPORT_SYMBOL_GPL(cxl_afu_put);
|
|
|
|
void cxl_slbia(struct mm_struct *mm)
|
|
{
|
|
struct cxl_calls *calls;
|
|
|
|
calls = cxl_calls_get();
|
|
if (!calls)
|
|
return;
|
|
|
|
if (cxl_ctx_in_use())
|
|
calls->cxl_slbia(mm);
|
|
|
|
cxl_calls_put(calls);
|
|
}
|
|
|
|
int register_cxl_calls(struct cxl_calls *calls)
|
|
{
|
|
if (cxl_calls)
|
|
return -EBUSY;
|
|
|
|
rcu_assign_pointer(cxl_calls, calls);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(register_cxl_calls);
|
|
|
|
void unregister_cxl_calls(struct cxl_calls *calls)
|
|
{
|
|
BUG_ON(cxl_calls->owner != calls->owner);
|
|
RCU_INIT_POINTER(cxl_calls, NULL);
|
|
synchronize_rcu();
|
|
}
|
|
EXPORT_SYMBOL_GPL(unregister_cxl_calls);
|
|
|
|
int cxl_update_properties(struct device_node *dn,
|
|
struct property *new_prop)
|
|
{
|
|
return of_update_property(dn, new_prop);
|
|
}
|
|
EXPORT_SYMBOL_GPL(cxl_update_properties);
|
|
|
|
static int __init cxl_base_init(void)
|
|
{
|
|
struct device_node *np;
|
|
struct platform_device *dev;
|
|
int count = 0;
|
|
|
|
/*
|
|
* Scan for compatible devices in guest only
|
|
*/
|
|
if (cpu_has_feature(CPU_FTR_HVMODE))
|
|
return 0;
|
|
|
|
for_each_compatible_node(np, NULL, "ibm,coherent-platform-facility") {
|
|
dev = of_platform_device_create(np, NULL, NULL);
|
|
if (dev)
|
|
count++;
|
|
}
|
|
pr_devel("Found %d cxl device(s)\n", count);
|
|
return 0;
|
|
}
|
|
device_initcall(cxl_base_init);
|