From 701027a9e43f724ed7efa871a0411c8b5a4d8412 Mon Sep 17 00:00:00 2001 From: Li Guohui Date: Fri, 25 Apr 2025 11:38:24 +0800 Subject: [PATCH] Base_ctrl: phytium: Add driver for base controller phytium inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC3URS CVE: NA ----------------------------------------------------- This driver provides interface functions for reading and writing base controller address. Signed-off-by: Li Guohui Signed-off-by: Li Yuze Signed-off-by: Wang Yinfeng --- arch/arm64/configs/openeuler_defconfig | 1 + drivers/acpi/Kconfig | 10 +- drivers/acpi/Makefile | 1 + drivers/acpi/phytium_base_ctrl.c | 210 +++++++++++++++++++++++++ drivers/acpi/phytium_base_ctrl.h | 27 ++++ 5 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 drivers/acpi/phytium_base_ctrl.c create mode 100644 drivers/acpi/phytium_base_ctrl.h diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index fd947e6b2421..e03e89ec99e8 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -693,6 +693,7 @@ CONFIG_ARM_SCPI_CPUFREQ=m CONFIG_ARCH_SUPPORTS_ACPI=y CONFIG_ACPI=y +CONFIG_PHYTIUM_BASE_CTRL=y CONFIG_ACPI_GENERIC_GSI=y CONFIG_ACPI_CCA_REQUIRED=y CONFIG_ACPI_TABLE_LIB=y diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index c4746869d67b..8212510ebbcb 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0 +# SPDX-License-Identifier: GPL-1.0 # # ACPI Configuration # @@ -45,6 +45,14 @@ if ACPI config ACPI_LEGACY_TABLES_LOOKUP bool +config PHYTIUM_BASE_CTRL + bool "Phytium base ctrl driver" + depends on ARM64 && ARCH_PHYTIUM + default y + help + This driver provides interface functions for reading and + writing phytium base controller device address. + config ARCH_MIGHT_HAVE_ACPI_PDC bool diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index eaa09bf52f17..e483aa370c2e 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -42,6 +42,7 @@ acpi-y += resource.o acpi-y += acpi_processor.o acpi-y += processor_core.o acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o +acpi-$(CONFIG_PHYTIUM_BASE_CTRL) += phytium_base_ctrl.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-$(CONFIG_PCI) += pci_root.o pci_link.o pci_irq.o diff --git a/drivers/acpi/phytium_base_ctrl.c b/drivers/acpi/phytium_base_ctrl.c new file mode 100644 index 000000000000..5ebfd0794a45 --- /dev/null +++ b/drivers/acpi/phytium_base_ctrl.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * base_ctrl driver for Phytium. + * + * Copyright (C) 2021-2024, Phytium Technology Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phytium_base_ctrl.h" + +#define BASE_CTRL_DRIVER_VERSION "1.1.0" + +static struct phytium_base_ctrl *boot_base_ctrl; + +int phytium_base_ctrl_irq(void) +{ + if (!boot_base_ctrl) + return -ENODEV; + + return boot_base_ctrl->irq; +} +EXPORT_SYMBOL(phytium_base_ctrl_irq); + +int base_ctrl_read_int_status(void) +{ + unsigned long flags; + u16 value; + + if (!boot_base_ctrl) + return 0; + + spin_lock_irqsave(&boot_base_ctrl->lock, flags); + value = readw(boot_base_ctrl->base + boot_base_ctrl->int_status_reg); + spin_unlock_irqrestore(&boot_base_ctrl->lock, flags); + + return value; +} +EXPORT_SYMBOL(base_ctrl_read_int_status); + +void base_ctrl_write_int_clear(int val) +{ + unsigned long flags; + + if (!boot_base_ctrl) + return; + + spin_lock_irqsave(&boot_base_ctrl->lock, flags); + writew(val, boot_base_ctrl->base + boot_base_ctrl->int_clear_reg); + spin_unlock_irqrestore(&boot_base_ctrl->lock, flags); +} +EXPORT_SYMBOL(base_ctrl_write_int_clear); + +bool phytium_check_cpu(void) +{ +#ifdef CONFIG_ARCH_PHYTIUM + if (read_cpuid_implementor() == ARM_CPU_IMP_PHYTIUM) + return true; +#endif + return false; +} +EXPORT_SYMBOL(phytium_check_cpu); + +u8 base_ctrl_readb(unsigned long offset) +{ + unsigned long flags; + u8 value; + + if (!boot_base_ctrl) + return 1; + + spin_lock_irqsave(&boot_base_ctrl->lock, flags); + value = readb(boot_base_ctrl->base + offset); + spin_unlock_irqrestore(&boot_base_ctrl->lock, flags); + return value; +} +EXPORT_SYMBOL(base_ctrl_readb); + +u32 base_ctrl_readl(unsigned long offset) +{ + unsigned long flags; + u32 value; + + if (!boot_base_ctrl) + return 1; + + spin_lock_irqsave(&boot_base_ctrl->lock, flags); + value = readl(boot_base_ctrl->base + offset); + spin_unlock_irqrestore(&boot_base_ctrl->lock, flags); + + return value; +} +EXPORT_SYMBOL(base_ctrl_readl); + +int base_ctrl_writeb(unsigned long offset, u8 value) +{ + unsigned long flags; + + if (!boot_base_ctrl) + return 0; + + spin_lock_irqsave(&boot_base_ctrl->lock, flags); + writeb(value, boot_base_ctrl->base + offset); + spin_unlock_irqrestore(&boot_base_ctrl->lock, flags); + + return 0; +} +EXPORT_SYMBOL(base_ctrl_writeb); + +int base_ctrl_writel(unsigned long offset, u32 value) +{ + unsigned long flags; + + if (!boot_base_ctrl) + return 0; + + spin_lock_irqsave(&boot_base_ctrl->lock, flags); + writel(value, boot_base_ctrl->base + offset); + spin_unlock_irqrestore(&boot_base_ctrl->lock, flags); + + return 0; +} +EXPORT_SYMBOL(base_ctrl_writel); + +static int phytium_base_ctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *res; + struct phytium_base_ctrl *base_ctrl; + int error = -1; + + base_ctrl = devm_kzalloc(dev, sizeof(*base_ctrl), GFP_KERNEL); + if (!base_ctrl) + return -ENOMEM; + + base_ctrl->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOENT; + + base_ctrl->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base_ctrl->base)) { + dev_err(&pdev->dev, "region map failed\n"); + return PTR_ERR(base_ctrl->base); + } + + base_ctrl->irq = platform_get_irq(pdev, 0); + if (base_ctrl->irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + return base_ctrl->irq; + } + + error = device_property_read_u32(&pdev->dev, "int_state", + &base_ctrl->int_status_reg); + if (error) + base_ctrl->int_status_reg = base_ctrl_INT_STATE; + + error = device_property_read_u32(&pdev->dev, "clr_int", + &base_ctrl->int_clear_reg); + if (error) + base_ctrl->int_clear_reg = base_ctrl_CLR_INT; + + spin_lock_init(&base_ctrl->lock); + boot_base_ctrl = base_ctrl; + platform_set_drvdata(pdev, base_ctrl); + + return 0; +} + +static const struct acpi_device_id base_ctrl_acpi_match[] = { + { "PHYT0007", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, base_ctrl_acpi_match); + +static struct platform_driver phytium_base_ctrl_driver = { + .probe = phytium_base_ctrl_probe, + .driver = { + .name = "phytium_base_ctrl", + .acpi_match_table = ACPI_PTR(base_ctrl_acpi_match), + }, +}; + +module_platform_driver(phytium_base_ctrl_driver); + +static int __init phytium_base_ctrl_init(void) +{ + platform_driver_register(&phytium_base_ctrl_driver); + return 0; +} + +static void __exit phytium_base_ctrl_exit(void) +{ + platform_driver_unregister(&phytium_base_ctrl_driver); +} + +early_initcall(phytium_base_ctrl_init); +MODULE_AUTHOR("Li Yuze "); +MODULE_DESCRIPTION("Phytium base_ctrl driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(BASE_CTRL_DRIVER_VERSION); diff --git a/drivers/acpi/phytium_base_ctrl.h b/drivers/acpi/phytium_base_ctrl.h new file mode 100644 index 000000000000..017f21e5ac6a --- /dev/null +++ b/drivers/acpi/phytium_base_ctrl.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * acpi/phytium_base_ctrl.h + * + * Copyright (C) 2021-2024, Phytium Technology Co., Ltd. + */ + +#define base_ctrl_INT_STATE 0x7FFFFC4 +#define base_ctrl_CLR_INT 0x7FFFFC0 + +struct phytium_base_ctrl { + struct device *dev; + void __iomem *base; + int irq; + spinlock_t lock; + u32 int_status_reg; + u32 int_clear_reg; +}; + +int phytium_base_ctrl_irq(void); +u8 base_ctrl_readb(unsigned long offset); +u32 base_ctrl_readl(unsigned long offset); +bool phytium_check_cpu(void); +int base_ctrl_writeb(unsigned long offset, u8 value); +int base_ctrl_writel(unsigned long offset, u32 value); +int base_ctrl_read_int_status(void); +void base_ctrl_write_int_clear(int val); -- Gitee