driver inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/10043 ---------------------------------------------------------------------- Signed-off-by: Yushan Wang <wangyushan12@huawei.com> Signed-off-by: Hongye Lin <linhongye@h-partners.com> --- drivers/soc/hisilicon/Kconfig | 12 -- drivers/soc/hisilicon/Makefile | 1 - .../soc/hisilicon/hisi_soc_cache_framework.c | 112 ---------- .../soc/hisilicon/hisi_soc_cache_framework.h | 10 - drivers/soc/hisilicon/hisi_soc_hha.c | 194 ------------------ .../uapi/misc/hisi_soc_cache/hisi_soc_cache.h | 37 ---- 6 files changed, 366 deletions(-) delete mode 100644 drivers/soc/hisilicon/hisi_soc_hha.c delete mode 100644 include/uapi/misc/hisi_soc_cache/hisi_soc_cache.h diff --git a/drivers/soc/hisilicon/Kconfig b/drivers/soc/hisilicon/Kconfig index 4d501a4c4c5b..b2b2403d7ac2 100644 --- a/drivers/soc/hisilicon/Kconfig +++ b/drivers/soc/hisilicon/Kconfig @@ -78,16 +78,4 @@ config HISI_SOC_L3C This driver can be built as a module. If so, the module will be called hisi_soc_l3c. - -config HISI_SOC_HHA - tristate "HiSilicon Hydra Home Agent (HHA) device driver" - depends on ARM64 && ACPI || COMPILE_TEST - depends on HISI_SOC_CACHE - help - The Hydra Home Agent (HHA) is responsible of cache coherency - on SoC. This drivers provides cache maintenance functions of HHA. - - This driver can be built as a module. If so, the module will be - called hisi_soc_hha. - endmenu diff --git a/drivers/soc/hisilicon/Makefile b/drivers/soc/hisilicon/Makefile index 21f4bdb277ff..d53d5c5f2cb2 100644 --- a/drivers/soc/hisilicon/Makefile +++ b/drivers/soc/hisilicon/Makefile @@ -5,5 +5,4 @@ obj-$(CONFIG_HISI_HBMDEV) += hisi_hbmdev.o obj-$(CONFIG_HISI_HBMCACHE) += hisi_hbmcache.o obj-$(CONFIG_HISI_SOC_CACHE) += hisi_soc_cache_framework.o -obj-$(CONFIG_HISI_SOC_HHA) += hisi_soc_hha.o obj-$(CONFIG_HISI_SOC_L3C) += hisi_soc_l3c.o diff --git a/drivers/soc/hisilicon/hisi_soc_cache_framework.c b/drivers/soc/hisilicon/hisi_soc_cache_framework.c index fc19f72e2843..669caff157dc 100644 --- a/drivers/soc/hisilicon/hisi_soc_cache_framework.c +++ b/drivers/soc/hisilicon/hisi_soc_cache_framework.c @@ -119,60 +119,6 @@ static int hisi_soc_cache_unlock(int cpu, phys_addr_t addr) return ret; } -int hisi_soc_cache_maintain(phys_addr_t addr, size_t size, - enum hisi_soc_cache_maint_type mnt_type) -{ - struct hisi_soc_comp_inst *inst; - struct list_head *head; - int ret = -EOPNOTSUPP; - - if (mnt_type >= HISI_CACHE_MAINT_MAX) - return -EINVAL; - - guard(spinlock)(&soc_cache_devs[HISI_SOC_HHA].lock); - - head = &soc_cache_devs[HISI_SOC_HHA].node; - list_for_each_entry(inst, head, node) { - ret = inst->comp->ops->do_maintain(inst->comp, addr, size, - mnt_type); - if (ret) - return ret; - } - - list_for_each_entry(inst, head, node) { - ret = inst->comp->ops->poll_maintain_done(inst->comp, addr, - size, mnt_type); - if (ret) - return ret; - } - - return ret; -} -EXPORT_SYMBOL_GPL(hisi_soc_cache_maintain); - -static int hisi_soc_cache_maint_pte_entry(pte_t *pte, unsigned long addr, - unsigned long next, struct mm_walk *walk) -{ -#ifdef HISI_SOC_CACHE_LLT - struct hisi_soc_cache_ioctl_param *param = walk->priv; -#else - struct hisi_soc_cache_ioctl_param *param = walk->private; -#endif - size_t size = min(next - addr, param->size + param->addr - addr); - unsigned long offset = offset_in_page(max(addr, param->addr)); - phys_addr_t paddr = PFN_PHYS(pte_pfn(*pte)) + offset; - - if (!pte_present(ptep_get(pte))) - return -EINVAL; - - return hisi_soc_cache_maintain(paddr, size, param->op_type); -} - -static const struct mm_walk_ops hisi_soc_cache_maint_walk = { - .pte_entry = hisi_soc_cache_maint_pte_entry, - .walk_lock = PGWALK_RDLOCK, -}; - static int hisi_soc_cache_inst_check(const struct hisi_soc_comp *comp, enum hisi_soc_comp_type comp_type) { @@ -455,66 +401,8 @@ static int hisi_soc_cache_mmap(struct file *file, struct vm_area_struct *vma) return ret; } -static int __hisi_soc_cache_maintain(struct hisi_soc_cache_ioctl_param *param) -{ - unsigned long start = untagged_addr(param->addr); - struct vm_area_struct *vma; - int ret = 0; - - /* MakeInvalid is not allowed for calls from userspace. */ - if (param->op_type >= HISI_CACHE_MAINT_MAKEINVALID) - return -EINVAL; - - /* Prevent overflow of vaddr + size. */ - if (!param->size || start + param->size < start) - return -EINVAL; - - if (mmap_read_lock_killable(current->mm)) - return -EINTR; - - vma = vma_lookup(current->mm, param->addr); - if (!range_in_vma(vma, start, start + param->size)) { - ret = -EINVAL; - goto out; - } - - /* User should have the write permission of target memory */ - if (!(vma->vm_flags & VM_WRITE)) { - ret = -EINVAL; - goto out; - } - - ret = walk_page_range(current->mm, PAGE_ALIGN_DOWN(start), - PAGE_ALIGN(start + param->size), - &hisi_soc_cache_maint_walk, param); -out: - mmap_read_unlock(current->mm); - return ret; -} - -static long hisi_soc_cache_mgmt_ioctl(struct file *file, u32 cmd, unsigned long arg) -{ - struct hisi_soc_cache_ioctl_param param; - long ret; - - if (copy_from_user(¶m, (void __user *)arg, sizeof(param))) - return -EFAULT; - - switch (cmd) { - case HISI_CACHE_MAINTAIN: - ret = __hisi_soc_cache_maintain(¶m); - break; - default: - ret = -EINVAL; - break; - } - - return ret; -} - static const struct file_operations soc_cache_dev_fops = { .owner = THIS_MODULE, - .unlocked_ioctl = hisi_soc_cache_mgmt_ioctl, .mmap = hisi_soc_cache_mmap, }; diff --git a/drivers/soc/hisilicon/hisi_soc_cache_framework.h b/drivers/soc/hisilicon/hisi_soc_cache_framework.h index 67ee9a33f382..c711d1f9d75c 100644 --- a/drivers/soc/hisilicon/hisi_soc_cache_framework.h +++ b/drivers/soc/hisilicon/hisi_soc_cache_framework.h @@ -14,8 +14,6 @@ #include <linux/bits.h> #include <linux/types.h> -#include <uapi/misc/hisi_soc_cache/hisi_soc_cache.h> - enum hisi_soc_comp_type { HISI_SOC_L3C, HISI_SOC_HHA, @@ -56,12 +54,6 @@ struct hisi_soc_comp_ops { phys_addr_t addr); int (*poll_unlock_done)(struct hisi_soc_comp *comp, phys_addr_t addr); - int (*do_maintain)(struct hisi_soc_comp *comp, - phys_addr_t addr, size_t size, - enum hisi_soc_cache_maint_type mnt_type); - int (*poll_maintain_done)(struct hisi_soc_comp *comp, - phys_addr_t addr, size_t size, - enum hisi_soc_cache_maint_type mnt_type); }; /** @@ -86,7 +78,5 @@ struct hisi_soc_comp { int hisi_soc_comp_inst_add(struct hisi_soc_comp *comp); int hisi_soc_comp_inst_del(struct hisi_soc_comp *comp); -int hisi_soc_cache_maintain(phys_addr_t addr, size_t size, - enum hisi_soc_cache_maint_type mnt_type); #endif diff --git a/drivers/soc/hisilicon/hisi_soc_hha.c b/drivers/soc/hisilicon/hisi_soc_hha.c deleted file mode 100644 index 22a1ec8b8fc9..000000000000 --- a/drivers/soc/hisilicon/hisi_soc_hha.c +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Driver for HiSilicon Hydra Home Agent (HHA). - * - * Copyright (c) 2024 HiSilicon Technologies Co., Ltd. - * Author: Yicong Yang <yangyicong@hisilicon.com> - * Yushan Wang <wangyushan12@huawei.com> - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/bitfield.h> -#include <linux/cpumask.h> -#include <linux/device.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/iopoll.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/mod_devicetable.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> - -#include "hisi_soc_cache_framework.h" - -#define HISI_HHA_CTRL 0x5004 -#define HISI_HHA_CTRL_EN BIT(0) -#define HISI_HHA_CTRL_RANGE BIT(1) -#define HISI_HHA_CTRL_TYPE GENMASK(3, 2) -#define HISI_HHA_START_L 0x5008 -#define HISI_HHA_START_H 0x500c -#define HISI_HHA_LEN_L 0x5010 -#define HISI_HHA_LEN_H 0x5014 - -/* The maintain operation performs in a 128 Byte granularity */ -#define HISI_HHA_MAINT_ALIGN 128 - -#define HISI_HHA_POLL_GAP_US 10 - -struct hisi_soc_hha { - struct hisi_soc_comp comp; - /* Locks HHA instance to forbid overlapping access. */ - spinlock_t lock; - struct device *dev; - void __iomem *base; -}; - -static bool hisi_hha_cache_maintain_wait_finished(struct hisi_soc_hha *soc_hha) -{ - u32 val; - - return !readl_poll_timeout_atomic(soc_hha->base + HISI_HHA_CTRL, val, - !(val & HISI_HHA_CTRL_EN), - HISI_HHA_POLL_GAP_US, - jiffies_to_usecs(HZ)); -} - -static int hisi_hha_cache_do_maintain(struct hisi_soc_comp *comp, - phys_addr_t addr, size_t size, - enum hisi_soc_cache_maint_type mnt_type) -{ - struct hisi_soc_hha *soc_hha = container_of(comp, struct hisi_soc_hha, - comp); - phys_addr_t top; - int ret = 0; - u32 reg; - - if (!size) - return -EINVAL; - - addr = ALIGN_DOWN(addr, HISI_HHA_MAINT_ALIGN); - top = ALIGN(addr + size, HISI_HHA_MAINT_ALIGN); - size = top - addr; - - if (mnt_type < 0 || mnt_type >= HISI_CACHE_MAINT_MAX) - return -EOPNOTSUPP; - - /* - * Hardware will search for addresses ranging [addr, addr + size -1], - * last byte included, and perform maintain in 128 byte granule - * on those which contain the addresses. - */ - size -= 1; - - guard(spinlock)(&soc_hha->lock); - - if (!hisi_hha_cache_maintain_wait_finished(soc_hha)) - return -EBUSY; - - writel(lower_32_bits(addr), soc_hha->base + HISI_HHA_START_L); - writel(upper_32_bits(addr), soc_hha->base + HISI_HHA_START_H); - writel(lower_32_bits(size), soc_hha->base + HISI_HHA_LEN_L); - writel(upper_32_bits(size), soc_hha->base + HISI_HHA_LEN_H); - - reg = FIELD_PREP(HISI_HHA_CTRL_TYPE, mnt_type); - reg |= HISI_HHA_CTRL_RANGE | HISI_HHA_CTRL_EN; - writel(reg, soc_hha->base + HISI_HHA_CTRL); - - return ret; -} - -static int hisi_hha_cache_poll_maintain_done(struct hisi_soc_comp *comp, - phys_addr_t addr, size_t size, - enum hisi_soc_cache_maint_type mnt_type) -{ - struct hisi_soc_hha *soc_hha = container_of(comp, struct hisi_soc_hha, - comp); - - guard(spinlock)(&soc_hha->lock); - - if (!hisi_hha_cache_maintain_wait_finished(soc_hha)) - return -ETIMEDOUT; - - return 0; -} - -static struct hisi_soc_comp_ops hisi_soc_hha_comp_ops = { - .do_maintain = hisi_hha_cache_do_maintain, - .poll_maintain_done = hisi_hha_cache_poll_maintain_done, -}; - -static void hisi_hha_comp_inst_del(void *priv) -{ - struct hisi_soc_hha *soc_hha = priv; - - hisi_soc_comp_inst_del(&soc_hha->comp); -} - -static int hisi_soc_hha_probe(struct platform_device *pdev) -{ - struct hisi_soc_hha *soc_hha; - struct resource *mem; - int ret; - - soc_hha = devm_kzalloc(&pdev->dev, sizeof(*soc_hha), GFP_KERNEL); - if (!soc_hha) - return -ENOMEM; - - platform_set_drvdata(pdev, soc_hha); - soc_hha->dev = &pdev->dev; - - spin_lock_init(&soc_hha->lock); - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -ENODEV; - - /* - * HHA cache driver share the same register region with HHA uncore PMU - * driver in hardware's perspective, none of them should reserve the - * resource to itself only. Here exclusive access verification is - * avoided by calling devm_ioremap instead of devm_ioremap_resource to - * allow both drivers to exist at the same time. - */ - soc_hha->base = devm_ioremap(&pdev->dev, mem->start, - resource_size(mem)); - if (IS_ERR_OR_NULL(soc_hha->base)) { - return dev_err_probe(&pdev->dev, PTR_ERR(soc_hha->base), - "failed to remap io memory"); - } - - soc_hha->comp.ops = &hisi_soc_hha_comp_ops; - soc_hha->comp.comp_type = BIT(HISI_SOC_HHA); - cpumask_copy(&soc_hha->comp.affinity_mask, cpu_possible_mask); - - ret = hisi_soc_comp_inst_add(&soc_hha->comp); - if (ret) - return dev_err_probe(&pdev->dev, ret, - "failed to register maintain inst"); - - return devm_add_action_or_reset(&pdev->dev, hisi_hha_comp_inst_del, - soc_hha); -} - -static const struct acpi_device_id hisi_soc_hha_ids[] = { - { "HISI0511", }, - { } -}; -MODULE_DEVICE_TABLE(acpi, hisi_soc_hha_ids); - -static struct platform_driver hisi_soc_hha_driver = { - .driver = { - .name = "hisi_soc_hha", - .acpi_match_table = hisi_soc_hha_ids, - }, - .probe = hisi_soc_hha_probe, -}; - -module_platform_driver(hisi_soc_hha_driver); - -MODULE_DESCRIPTION("Hisilicon Hydra Home Agent driver supporting cache maintenance"); -MODULE_AUTHOR("Yicong Yang <yangyicong@hisilicon.com>"); -MODULE_AUTHOR("Yushan Wang <wangyushan12@huawei.com>"); -MODULE_LICENSE("GPL"); diff --git a/include/uapi/misc/hisi_soc_cache/hisi_soc_cache.h b/include/uapi/misc/hisi_soc_cache/hisi_soc_cache.h deleted file mode 100644 index 8b190941c805..000000000000 --- a/include/uapi/misc/hisi_soc_cache/hisi_soc_cache.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */ -/* Copyright (c) 2024-2024 HiSilicon Limited. */ -#ifndef _UAPI_HISI_SOC_CACHE_H -#define _UAPI_HISI_SOC_CACHE_H - -#include <linux/types.h> - -/* HISI_CACHE_MAINTAIN: cache maintain operation for HiSilicon SoC */ -#define HISI_CACHE_MAINTAIN _IOW('C', 1, unsigned long) - -/* - * Further information of these operations can be found at: - * https://developer.arm.com/documentation/ihi0050/latest/ - */ -enum hisi_soc_cache_maint_type { - HISI_CACHE_MAINT_CLEANSHARED, - HISI_CACHE_MAINT_CLEANINVALID, -#ifdef __KERNEL__ - HISI_CACHE_MAINT_MAKEINVALID, -#endif - - HISI_CACHE_MAINT_MAX -}; - -/** - * struct hisi_soc_cache_ioctl_param - User data for hisi cache operates. - * @op_type: cache maintain type - * @addr: cache maintain address - * @size: cache maintain size - */ -struct hisi_soc_cache_ioctl_param { - enum hisi_soc_cache_maint_type op_type; - unsigned long addr; - unsigned long size; -}; - -#endif -- 2.33.0