* [PATCH v9 6/6] DO NOT MERGE: full sensehat device tree overlay for raspberry pi 4
From: Charles Mirabile @ 2022-04-19 20:51 UTC (permalink / raw)
To: linux-kernel
Cc: Charles Mirabile, Serge Schneider, Stefan Wahren,
Nicolas Saenz Julienne, Mattias Brugger, linux-rpi-kernel,
linux-arm-kernel, fedora-rpi, Mwesigwa Guma, Joel Savitz
In-Reply-To: <20220419205158.28088-1-cmirabil@redhat.com>
This patch shold not be merged - dtbs files are not stored in the
kernel tree. We just provide this file so the code can be tested.
This overlay is suitable for testing the driver, it can be compiled with
dtc and put in the /boot/overlays/ folder then specified in config.txt
by putting the lines:
dtoverlay= #suppress loading of default overlay for HAT
dtoverlay=sensehat #load custom overlay
at the beginning before any other lines in config.txt
Co-developed-by: Mwesigwa Guma <mguma@redhat.com>
Signed-off-by: Mwesigwa Guma <mguma@redhat.com>
Co-developed-by: Joel Savitz <jsavitz@redhat.com>
Signed-off-by: Joel Savitz <jsavitz@redhat.com>
Signed-off-by: Charles Mirabile <cmirabil@redhat.com>
---
sensehat.dtbs | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 sensehat.dtbs
diff --git a/sensehat.dtbs b/sensehat.dtbs
new file mode 100644
index 000000000000..9e5a6d9229b1
--- /dev/null
+++ b/sensehat.dtbs
@@ -0,0 +1,52 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2835";
+};
+
+&i2c1 {
+ #address-cells = <0x01>;
+ #size-cells = <0x00>;
+ status = "okay";
+
+ sensehat@46 {
+ compatible = "raspberrypi,sensehat";
+ reg = <0x46>;
+ interrupt-parent = <&gpio>;
+ status = "okay";
+ display {
+ compatible = "raspberrypi,sensehat-display";
+ status = "okay";
+ };
+ joystick {
+ compatible = "raspberrypi,sensehat-joystick";
+ interrupts = <23 1>;
+ status = "okay";
+ };
+ };
+
+ lsm9ds1-magn@1c {
+ compatible = "st,lsm9ds1-magn";
+ reg = <0x1c>;
+ status = "okay";
+ };
+
+ lsm9ds1-accel@6a {
+ compatible = "st,lsm9ds1-accel";
+ reg = <0x6a>;
+ status = "okay";
+ };
+
+ lps25h-press@5c {
+ compatible = "st,lps25h-press";
+ reg = <0x5c>;
+ status = "okay";
+ };
+
+ hts221-humid@5f {
+ compatible = "st,hts221-humid\0st,hts221";
+ reg = <0x5f>;
+ status = "okay";
+ };
+};
--
2.31.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 v9 5/6] MAINTAINERS: Add sensehat driver authors to MAINTAINERS
From: Charles Mirabile @ 2022-04-19 20:51 UTC (permalink / raw)
To: linux-kernel
Cc: Charles Mirabile, Serge Schneider, Stefan Wahren,
Nicolas Saenz Julienne, Mattias Brugger, linux-rpi-kernel,
linux-arm-kernel, fedora-rpi, Mwesigwa Guma, Joel Savitz
In-Reply-To: <20220419205158.28088-1-cmirabil@redhat.com>
This patch adds the driver authors to MAINAINERS.
Co-developed-by: Mwesigwa Guma <mguma@redhat.com>
Signed-off-by: Mwesigwa Guma <mguma@redhat.com>
Co-developed-by: Joel Savitz <jsavitz@redhat.com>
Signed-off-by: Joel Savitz <jsavitz@redhat.com>
Signed-off-by: Charles Mirabile <cmirabil@redhat.com>
---
MAINTAINERS | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 40fa1955ca3f..b93f060322a3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17747,6 +17747,17 @@ F: Documentation/ABI/testing/sysfs-bus-iio-chemical-sunrise-co2
F: Documentation/devicetree/bindings/iio/chemical/senseair,sunrise.yaml
F: drivers/iio/chemical/sunrise_co2.c
+SENSEHAT DRIVER
+M: Charles Mirabile <cmirabil@redhat.com>
+M: Mwesigwa Guma <mguma@redhat.com>
+M: Joel Savitz <jsavitz@redhat.com>
+S: Maintained
+F: Documentation/devicetree/bindings/auxdisplay/raspberrypi,sensehat-display.yaml
+F: Documentation/devicetree/bindings/input/raspberrypi,sensehat-joystick.yaml
+F: Documentation/devicetree/bindings/mfd/raspberrypi,sensehat.yaml
+F: drivers/auxdisplay/sensehat-display.c
+F: drivers/input/joystick/sensehat-joystick.c
+
SENSIRION SCD30 CARBON DIOXIDE SENSOR DRIVER
M: Tomasz Duszynski <tomasz.duszynski@octakon.com>
S: Maintained
--
2.31.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/2] ACPICA: Add support for ARM Performance Monitoring Unit Table.
From: Besar Wicaksono @ 2022-04-19 20:54 UTC (permalink / raw)
To: rafael, lenb, robert.moore, catalin.marinas, will,
lorenzo.pieralisi, guohanjun, sudeep.holla
Cc: linux-tegra, treding, jonathanh, linux-acpi, devel, linux-kernel,
linux-arm-kernel, Besar Wicaksono
In-Reply-To: <20220419205432.46021-1-bwicaksono@nvidia.com>
ACPICA commit 002165ecc0a3dc703bb24c789aaa02fdada01675
The specification of this table is described in
"ARM Performance Monitoring Unit Architecture 1.0 Platform Design Document"
ARM DEN0117.
This patch adds the necessary types and support for
compiling/disassembling APMT.
Link: https://github.com/acpica/acpica/commit/002165ec
Signed-off-by: Besar Wicaksono <bwicaksono@nvidia.com>
---
include/acpi/actbl2.h | 81 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index 16847c8d9d5f..8fc5cf318c15 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -25,6 +25,7 @@
* the wrong signature.
*/
#define ACPI_SIG_AGDI "AGDI" /* Arm Generic Diagnostic Dump and Reset Device Interface */
+#define ACPI_SIG_APMT "APMT" /* Arm Performance Monitoring Unit table */
#define ACPI_SIG_BDAT "BDAT" /* BIOS Data ACPI Table */
#define ACPI_SIG_IORT "IORT" /* IO Remapping Table */
#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */
@@ -258,6 +259,86 @@ struct acpi_table_agdi {
#define ACPI_AGDI_SIGNALING_MODE (1)
+/*******************************************************************************
+ *
+ * APMT - ARM Performance Monitoring Unit Table
+ *
+ * Conforms to:
+ * ARM Performance Monitoring Unit Architecture 1.0 Platform Design Document
+ * ARM DEN0117 v1.0 November 25, 2021
+ *
+ ******************************************************************************/
+
+struct acpi_table_apmt {
+ struct acpi_table_header header; /* Common ACPI table header */
+};
+
+#define ACPI_APMT_NODE_ID_LENGTH 4
+
+/*
+ * APMT subtables
+ */
+struct acpi_apmt_node {
+ u16 length;
+ u8 flags;
+ u8 type;
+ u32 id;
+ u64 inst_primary;
+ u32 inst_secondary;
+ u64 base_address0;
+ u64 base_address1;
+ u32 ovflw_irq;
+ u32 reserved;
+ u32 ovflw_irq_flags;
+ u32 proc_affinity;
+ u32 impl_id;
+};
+
+/* Masks for Flags field above */
+
+#define ACPI_APMT_FLAGS_DUAL_PAGE (1<<0)
+#define ACPI_APMT_FLAGS_AFFINITY (1<<1)
+#define ACPI_APMT_FLAGS_ATOMIC (1<<2)
+
+/* Values for Flags dual page field above */
+
+#define ACPI_APMT_FLAGS_DUAL_PAGE_NSUPP (0<<0)
+#define ACPI_APMT_FLAGS_DUAL_PAGE_SUPP (1<<0)
+
+/* Values for Flags processor affinity field above */
+#define ACPI_APMT_FLAGS_AFFINITY_PROC (0<<1)
+#define ACPI_APMT_FLAGS_AFFINITY_PROC_CONTAINER (1<<1)
+
+/* Values for Flags 64-bit atomic field above */
+#define ACPI_APMT_FLAGS_ATOMIC_NSUPP (0<<2)
+#define ACPI_APMT_FLAGS_ATOMIC_SUPP (1<<2)
+
+/* Values for Type field above */
+
+enum acpi_apmt_node_type {
+ ACPI_APMT_NODE_TYPE_MC = 0x00,
+ ACPI_APMT_NODE_TYPE_SMMU = 0x01,
+ ACPI_APMT_NODE_TYPE_PCIE_ROOT = 0x02,
+ ACPI_APMT_NODE_TYPE_ACPI = 0x03,
+ ACPI_APMT_NODE_TYPE_CACHE = 0x04,
+ ACPI_APMT_NODE_TYPE_COUNT
+};
+
+/* Masks for ovflw_irq_flags field above */
+
+#define ACPI_APMT_OVFLW_IRQ_FLAGS_MODE (1<<0)
+#define ACPI_APMT_OVFLW_IRQ_FLAGS_TYPE (1<<1)
+
+/* Values for ovflw_irq_flags mode field above */
+
+#define ACPI_APMT_OVFLW_IRQ_FLAGS_MODE_LEVEL (0<<0)
+#define ACPI_APMT_OVFLW_IRQ_FLAGS_MODE_EDGE (1<<0)
+
+/* Values for ovflw_irq_flags type field above */
+
+#define ACPI_APMT_OVFLW_IRQ_FLAGS_TYPE_WIRED (0<<1)
+
+
/*******************************************************************************
*
* BDAT - BIOS Data ACPI Table
--
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
* [PATCH 2/2] ACPI: ARM Performance Monitoring Unit Table (APMT) initial support
From: Besar Wicaksono @ 2022-04-19 20:54 UTC (permalink / raw)
To: rafael, lenb, robert.moore, catalin.marinas, will,
lorenzo.pieralisi, guohanjun, sudeep.holla
Cc: linux-tegra, treding, jonathanh, linux-acpi, devel, linux-kernel,
linux-arm-kernel, Besar Wicaksono
In-Reply-To: <20220419205432.46021-1-bwicaksono@nvidia.com>
ARM Performance Monitoring Unit Table describes the properties of PMU
support in ARM-based system. The APMT table contains a list of nodes,
each represents a PMU in the system that conforms to ARM CoreSight PMU
architecture. The properties of each node include information required
to access the PMU (e.g. MMIO base address, interrupt number) and also
identification. For more detailed information, please refer to the
specification below:
* APMT: https://developer.arm.com/documentation/den0117/latest
* ARM Coresight PMU:
https://developer.arm.com/documentation/ihi0091/latest
The initial support adds the detection of APMT table and generic
infrastructure to create platform devices for ARM CoreSight PMUs.
Similar to IORT the root pointer of APMT is preserved during runtime
and each PMU platform device is given a pointer to the corresponding
APMT node.
Signed-off-by: Besar Wicaksono <bwicaksono@nvidia.com>
---
arch/arm64/Kconfig | 1 +
drivers/acpi/arm64/Kconfig | 3 +
drivers/acpi/arm64/Makefile | 1 +
drivers/acpi/arm64/apmt.c | 176 ++++++++++++++++++++++++++++++++++++
drivers/acpi/bus.c | 2 +
include/linux/acpi_apmt.h | 19 ++++
6 files changed, 202 insertions(+)
create mode 100644 drivers/acpi/arm64/apmt.c
create mode 100644 include/linux/acpi_apmt.h
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e80fd2372f02..49e01c4377f2 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config ARM64
def_bool y
+ select ACPI_APMT if ACPI
select ACPI_CCA_REQUIRED if ACPI
select ACPI_GENERIC_GSI if ACPI
select ACPI_GTDT if ACPI
diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
index d4a72835f328..b3ed6212244c 100644
--- a/drivers/acpi/arm64/Kconfig
+++ b/drivers/acpi/arm64/Kconfig
@@ -18,3 +18,6 @@ config ACPI_AGDI
reset command.
If set, the kernel parses AGDI table and listens for the command.
+
+config ACPI_APMT
+ bool
diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
index 7b9e4045659d..e21a9e84e394 100644
--- a/drivers/acpi/arm64/Makefile
+++ b/drivers/acpi/arm64/Makefile
@@ -2,4 +2,5 @@
obj-$(CONFIG_ACPI_AGDI) += agdi.o
obj-$(CONFIG_ACPI_IORT) += iort.o
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
+obj-$(CONFIG_ACPI_APMT) += apmt.o
obj-y += dma.o
diff --git a/drivers/acpi/arm64/apmt.c b/drivers/acpi/arm64/apmt.c
new file mode 100644
index 000000000000..8b8b9f480548
--- /dev/null
+++ b/drivers/acpi/arm64/apmt.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM APMT table support.
+ * Design document number: ARM DEN0117.
+ *
+ * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
+ *
+ */
+
+#define pr_fmt(fmt) "ACPI: APMT: " fmt
+
+#include <linux/acpi.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#define DEV_NAME "arm-csite-pmu"
+
+/* There can be up to 3 resources: page 0 and 1 address, and interrupt. */
+#define DEV_MAX_RESOURCE_COUNT 3
+
+/* Root pointer to the mapped APMT table */
+static struct acpi_table_header *apmt_table;
+
+static int __init apmt_init_resources(struct resource *res,
+ struct acpi_apmt_node *node)
+{
+ int irq, trigger;
+ int num_res = 0;
+
+ res[num_res].start = node->base_address0;
+ res[num_res].end = node->base_address0 + SZ_4K - 1;
+ res[num_res].flags = IORESOURCE_MEM;
+
+ num_res++;
+
+ res[num_res].start = node->base_address1;
+ res[num_res].end = node->base_address1 + SZ_4K - 1;
+ res[num_res].flags = IORESOURCE_MEM;
+
+ num_res++;
+
+ if (node->ovflw_irq != 0) {
+ trigger = (node->ovflw_irq_flags & ACPI_APMT_OVFLW_IRQ_FLAGS_MODE);
+ trigger = (trigger == ACPI_APMT_OVFLW_IRQ_FLAGS_MODE_LEVEL) ?
+ ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+ irq = acpi_register_gsi(NULL, node->ovflw_irq, trigger,
+ ACPI_ACTIVE_HIGH);
+
+ if (irq <= 0) {
+ pr_warn("APMT could not register gsi hwirq %d\n", irq);
+ return num_res;
+ }
+
+ res[num_res].start = irq;
+ res[num_res].end = irq;
+ res[num_res].flags = IORESOURCE_IRQ;
+
+ num_res++;
+ }
+
+ return num_res;
+}
+
+/**
+ * apmt_add_platform_device() - Allocate a platform device for APMT node
+ * @node: Pointer to device ACPI APMT node
+ *
+ * Returns: 0 on success, <0 failure
+ */
+static int __init apmt_add_platform_device(struct acpi_apmt_node *node,
+ struct fwnode_handle *fwnode)
+{
+ struct platform_device *pdev;
+ int ret, count;
+ struct resource res[DEV_MAX_RESOURCE_COUNT];
+
+ pdev = platform_device_alloc(DEV_NAME, PLATFORM_DEVID_AUTO);
+ if (!pdev)
+ return -ENOMEM;
+
+ memset(res, 0, sizeof(res));
+
+ count = apmt_init_resources(res, node);
+
+ ret = platform_device_add_resources(pdev, res, count);
+ if (ret)
+ goto dev_put;
+
+ /*
+ * Add a copy of APMT node pointer to platform_data to be used to
+ * retrieve APMT data information.
+ */
+ ret = platform_device_add_data(pdev, &node, sizeof(node));
+ if (ret)
+ goto dev_put;
+
+ pdev->dev.fwnode = fwnode;
+
+ ret = platform_device_add(pdev);
+
+ if (ret)
+ goto dev_put;
+
+ return 0;
+
+dev_put:
+ platform_device_put(pdev);
+
+ return ret;
+}
+
+static int __init apmt_init_platform_devices(void)
+{
+ struct acpi_apmt_node *apmt_node;
+ struct acpi_table_apmt *apmt;
+ struct fwnode_handle *fwnode;
+ u64 offset, end;
+ int ret;
+
+ /*
+ * apmt_table and apmt both point to the start of APMT table, but
+ * have different struct types
+ */
+ apmt = (struct acpi_table_apmt *)apmt_table;
+ offset = sizeof(*apmt);
+ end = apmt->header.length;
+
+ while (offset < end) {
+ apmt_node = ACPI_ADD_PTR(struct acpi_apmt_node, apmt,
+ offset);
+
+ fwnode = acpi_alloc_fwnode_static();
+ if (!fwnode)
+ return -ENOMEM;
+
+ ret = apmt_add_platform_device(apmt_node, fwnode);
+ if (ret) {
+ acpi_free_fwnode_static(fwnode);
+ return ret;
+ }
+
+ offset += apmt_node->length;
+ }
+
+ return 0;
+}
+
+void __init acpi_apmt_init(void)
+{
+ acpi_status status;
+ int ret;
+
+ /**
+ * APMT table nodes will be used at runtime after the apmt init,
+ * so we don't need to call acpi_put_table() to release
+ * the APMT table mapping.
+ */
+ status = acpi_get_table(ACPI_SIG_APMT, 0, &apmt_table);
+
+ if (ACPI_FAILURE(status)) {
+ if (status != AE_NOT_FOUND) {
+ const char *msg = acpi_format_exception(status);
+
+ pr_err("Failed to get APMT table, %s\n", msg);
+ }
+
+ return;
+ }
+
+ ret = apmt_init_platform_devices();
+ if (ret) {
+ pr_err("Failed to initialize APMT platform devices, ret: %d\n", ret);
+ acpi_put_table(apmt_table);
+ }
+}
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 3e58b613a2c4..25ddd9f300e7 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -27,6 +27,7 @@
#include <linux/dmi.h>
#endif
#include <linux/acpi_agdi.h>
+#include <linux/acpi_apmt.h>
#include <linux/acpi_iort.h>
#include <linux/acpi_viot.h>
#include <linux/pci.h>
@@ -1367,6 +1368,7 @@ static int __init acpi_init(void)
acpi_setup_sb_notify_handler();
acpi_viot_init();
acpi_agdi_init();
+ acpi_apmt_init();
return 0;
}
diff --git a/include/linux/acpi_apmt.h b/include/linux/acpi_apmt.h
new file mode 100644
index 000000000000..40bd634d082f
--- /dev/null
+++ b/include/linux/acpi_apmt.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * ARM CoreSight PMU driver.
+ * Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
+ *
+ */
+
+#ifndef __ACPI_APMT_H__
+#define __ACPI_APMT_H__
+
+#include <linux/acpi.h>
+
+#ifdef CONFIG_ACPI_APMT
+void acpi_apmt_init(void);
+#else
+static inline void acpi_apmt_init(void) { }
+#endif /* CONFIG_ACPI_APMT */
+
+#endif /* __ACPI_APMT_H__ */
--
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
* [PATCH] iommu/arm-smmu-v3: Fix size calculation in arm_smmu_mm_invalidate_range()
From: Nicolin Chen @ 2022-04-19 21:01 UTC (permalink / raw)
To: jgg, will, robin.murphy, joro, jean-philippe
Cc: jacob.jun.pan, baolu.lu, fenghua.yu, rikard.falkeborn,
linux-arm-kernel, iommu, linux-kernel, stable
The arm_smmu_mm_invalidate_range function is designed to be called
by mm core for Shared Virtual Addressing purpose between IOMMU and
CPU MMU. However, the ways of two subsystems defining their "end"
addresses are slightly different. IOMMU defines its "end" address
using the last address of an address range, while mm core defines
that using the following address of an address range:
include/linux/mm_types.h:
unsigned long vm_end;
/* The first byte after our end address ...
This mismatch resulted in an incorrect calculation for size so it
failed to be page-size aligned. Further, it caused a dead loop at
"while (iova < end)" check in __arm_smmu_tlb_inv_range function.
This patch fixes the issue by doing the calculation correctly.
Fixes: 2f7e8c553e98d ("iommu/arm-smmu-v3: Hook up ATC invalidation to mm ops")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 22ddd05bbdcd..c623dae1e115 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -183,7 +183,14 @@ static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn,
{
struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn);
struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
- size_t size = end - start + 1;
+ size_t size;
+
+ /*
+ * The mm_types defines vm_end as the first byte after the end address,
+ * different from IOMMU subsystem using the last address of an address
+ * range. So do a simple translation here by calculating size correctly.
+ */
+ size = end - start;
if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM))
arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid,
--
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] iommu/arm-smmu-v3: Fix size calculation in arm_smmu_mm_invalidate_range()
From: Robin Murphy @ 2022-04-19 21:05 UTC (permalink / raw)
To: Nicolin Chen, jgg, will, joro, jean-philippe
Cc: jacob.jun.pan, baolu.lu, fenghua.yu, rikard.falkeborn,
linux-arm-kernel, iommu, linux-kernel, stable
In-Reply-To: <20220419210158.21320-1-nicolinc@nvidia.com>
On 2022-04-19 22:01, Nicolin Chen wrote:
> The arm_smmu_mm_invalidate_range function is designed to be called
> by mm core for Shared Virtual Addressing purpose between IOMMU and
> CPU MMU. However, the ways of two subsystems defining their "end"
> addresses are slightly different. IOMMU defines its "end" address
> using the last address of an address range, while mm core defines
> that using the following address of an address range:
>
> include/linux/mm_types.h:
> unsigned long vm_end;
> /* The first byte after our end address ...
>
> This mismatch resulted in an incorrect calculation for size so it
> failed to be page-size aligned. Further, it caused a dead loop at
> "while (iova < end)" check in __arm_smmu_tlb_inv_range function.
>
> This patch fixes the issue by doing the calculation correctly.
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> Fixes: 2f7e8c553e98d ("iommu/arm-smmu-v3: Hook up ATC invalidation to mm ops")
> Cc: stable@vger.kernel.org
> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
> ---
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> index 22ddd05bbdcd..c623dae1e115 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -183,7 +183,14 @@ static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn,
> {
> struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn);
> struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
> - size_t size = end - start + 1;
> + size_t size;
> +
> + /*
> + * The mm_types defines vm_end as the first byte after the end address,
> + * different from IOMMU subsystem using the last address of an address
> + * range. So do a simple translation here by calculating size correctly.
> + */
> + size = end - start;
>
> if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM))
> arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid,
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 0/2] ACPI: ARM CoreSight Performance Monitoring Unit
From: Besar Wicaksono @ 2022-04-19 20:54 UTC (permalink / raw)
To: rafael, lenb, robert.moore, catalin.marinas, will,
lorenzo.pieralisi, guohanjun, sudeep.holla
Cc: linux-tegra, treding, jonathanh, linux-acpi, devel, linux-kernel,
linux-arm-kernel, Besar Wicaksono
This patchset adds support for ARM CoreSight PMU device.
Specifications for ARM Performance Monitoring Unit table (APMT) and
ARM CoreSight PMU:
* APMT: https://developer.arm.com/documentation/den0117/latest
* ARM Coresight PMU:
https://developer.arm.com/documentation/ihi0091/latest
The patchset applies on top of
git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
Besar Wicaksono (2):
ACPICA: Add support for ARM Performance Monitoring Unit Table.
ACPI: ARM Performance Monitoring Unit Table (APMT) initial support
arch/arm64/Kconfig | 1 +
drivers/acpi/arm64/Kconfig | 3 +
drivers/acpi/arm64/Makefile | 1 +
drivers/acpi/arm64/apmt.c | 176 ++++++++++++++++++++++++++++++++++++
drivers/acpi/bus.c | 2 +
include/acpi/actbl2.h | 81 +++++++++++++++++
include/linux/acpi_apmt.h | 19 ++++
7 files changed, 283 insertions(+)
create mode 100644 drivers/acpi/arm64/apmt.c
create mode 100644 include/linux/acpi_apmt.h
--
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
* Re: [PATCH v1 1/4] dt-bindings: pinctrl: mt8192: Add wrapping node for pin configurations
From: Linus Walleij @ 2022-04-19 21:12 UTC (permalink / raw)
To: Nícolas F. R. A. Prado
Cc: Rob Herring, kernel, AngeloGioacchino Del Regno, Matthias Brugger,
Sean Wang, devicetree, linux-arm-kernel, linux-gpio, linux-kernel,
linux-mediatek
In-Reply-To: <20220315211936.442708-2-nfraprado@collabora.com>
On Tue, Mar 15, 2022 at 10:20 PM Nícolas F. R. A. Prado
<nfraprado@collabora.com> wrote:
> On mt8192, the pinctrl node has pinctrl groups to group pin
> configurations. Each pinctrl group contains one or more pinmux subnodes
> to list needed pins and their configurations. By supporting multiple
> subnodes, we can configure different pin characteristics
> (driving/pull-up/pull-down/etc.) in a pinctrl group.
>
> Update the mt8192 pinctrl dt-binding to add the missing pinctrl group
> node that wraps the pinmux subnodes and update the example at the end.
> While at it, also remove the example embedded in the description since
> it is redundant to the already supplied example at the end.
>
> This same change was done for mt8195 in commit 79dcd4e840cc ("dt-bindings:
> pinctrl: mt8195: add wrapping node of pin configurations").
>
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
This patch 1/4 applied to the pinctrl tree.
Yours,
Linus Walleij
_______________________________________________
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 v1 2/4] dt-bindings: pinctrl: mt8192: Add mediatek,drive-strength-adv property
From: Linus Walleij @ 2022-04-19 21:13 UTC (permalink / raw)
To: Nícolas F. R. A. Prado
Cc: Rob Herring, kernel, AngeloGioacchino Del Regno, Matthias Brugger,
Sean Wang, devicetree, linux-arm-kernel, linux-gpio, linux-kernel,
linux-mediatek
In-Reply-To: <20220315211936.442708-3-nfraprado@collabora.com>
On Tue, Mar 15, 2022 at 10:20 PM Nícolas F. R. A. Prado
<nfraprado@collabora.com> wrote:
> Add the mediatek,drive-strength-adv property to the pinctrl-mt8192
> dt-binding to allow further drive current adjustments for I2C nodes on
> MT8192. It is the same as in mt8183-pinctrl.
>
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Patch applied!
Yours,
Linus Walleij
_______________________________________________
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 v1 3/4] dt-bindings: pinctrl: mt8192: Add mediatek,pull-up-adv property
From: Linus Walleij @ 2022-04-19 21:14 UTC (permalink / raw)
To: Nícolas F. R. A. Prado
Cc: Rob Herring, kernel, AngeloGioacchino Del Regno, Matthias Brugger,
Sean Wang, devicetree, linux-arm-kernel, linux-gpio, linux-kernel,
linux-mediatek
In-Reply-To: <20220315211936.442708-4-nfraprado@collabora.com>
On Tue, Mar 15, 2022 at 10:20 PM Nícolas F. R. A. Prado
<nfraprado@collabora.com> wrote:
> Add the mediatek,pull-up-adv property to the pinctrl-mt8192 dt-binding
> to allow configuring pull-up resistors on the pins of MT8192. It is the
> same as in mt8183-pinctrl.
>
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Patch applied!
Yours,
Linus Walleij
_______________________________________________
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 v1 4/4] dt-bindings: pinctrl: mt8192: Add gpio-line-names property
From: Linus Walleij @ 2022-04-19 21:15 UTC (permalink / raw)
To: Nícolas F. R. A. Prado
Cc: Rob Herring, kernel, AngeloGioacchino Del Regno, Matthias Brugger,
Sean Wang, devicetree, linux-arm-kernel, linux-gpio, linux-kernel,
linux-mediatek
In-Reply-To: <20220315211936.442708-5-nfraprado@collabora.com>
On Tue, Mar 15, 2022 at 10:20 PM Nícolas F. R. A. Prado
<nfraprado@collabora.com> wrote:
> Add the gpio-line-names optional property to the pinctrl-mt8192 binding
> to prevent dt_binding_check warnings when it is present in the pinctrl
> node in the Devicetree.
>
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Patch applied!
Yours,
Linus Walleij
_______________________________________________
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/2] gpiolib: of: Introduce hook for missing gpio-ranges
From: Linus Walleij @ 2022-04-19 21:18 UTC (permalink / raw)
To: Stefan Wahren
Cc: Bartosz Golaszewski, Florian Fainelli, Ray Jui, Scott Branden,
bcm-kernel-feedback-list, Nicolas Saenz Julienne, Phil Elwell,
Krzysztof Kozlowski, linux-gpio, linux-kernel, linux-rpi-kernel,
linux-arm-kernel
In-Reply-To: <20220409095129.45786-1-stefan.wahren@i2se.com>
On Sat, Apr 9, 2022 at 11:52 AM Stefan Wahren <stefan.wahren@i2se.com> wrote:
> This patch series tries to provide backward compatibility for DTB which
> lacks the gpio-ranges property.
>
> The commit ("pinctrl: msm: fix gpio-hog related boot issues") by Christian
> Lamparter already contains a fallback in case the gpio-ranges property
> is missing. But this approach doesn't work on BCM2835 with a gpio-hog
> defined for the SoC GPIOs.
>
> Based Christian's on explanation i conclude that the fallback must happen
> during the gpiochip_add() call and not afterwards. So the approach is to
> call an optional hook, which can be implemented in the platform driver.
>
> This series has been tested on Raspberry Pi 3 B Plus.
>
> Changes since RFC:
> - just add all collected Fixes, Reviewed-by, Tested-by and Acked-by
Patches applied!
Sorry for being a bit slow on this :/
Yours,
Linus Walleij
_______________________________________________
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 07/10] crypto: Use ARCH_DMA_MINALIGN instead of ARCH_KMALLOC_MINALIGN
From: Ard Biesheuvel @ 2022-04-19 21:50 UTC (permalink / raw)
To: Catalin Marinas
Cc: Herbert Xu, Will Deacon, Marc Zyngier, Arnd Bergmann,
Greg Kroah-Hartman, Andrew Morton, Linus Torvalds,
Linux Memory Management List, Linux ARM,
Linux Kernel Mailing List, David S. Miller
In-Reply-To: <Yl2Vda/8S7qAvMjC@arm.com>
On Mon, 18 Apr 2022 at 18:44, Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Mon, Apr 18, 2022 at 04:37:17PM +0800, Herbert Xu wrote:
> > On Sun, Apr 17, 2022 at 05:30:27PM +0100, Catalin Marinas wrote:
> > > Do you mean as per Ard's proposal here:
> > >
> > > https://lore.kernel.org/r/CAMj1kXH0x5Va7Wgs+mU1ONDwwsazOBuN4z4ihVzO2uG-n41Kbg@mail.gmail.com
> > >
> > > struct crypto_request {
> > > union {
> > > struct {
> > > ... fields ...
> > > };
> > > u8 __padding[ARCH_DMA_MINALIGN];
> > > };
> > > void __ctx[] __aligned(CRYPTO_MINALIGN);
> > > };
> > >
> > > If CRYPTO_MINALIGN is lowered to, say, 8 (to be the same as lowest
> > > ARCH_KMALLOC_MINALIGN), the __alignof__(req->__ctx) would be 8.
> > > Functions like crypto_tfm_ctx_alignment() will return 8 when what you
> > > need is 128. We can change those functions to return ARCH_DMA_MINALIGN
> > > instead or always bump cra_alignmask to ARCH_DMA_MINALIGN-1.
> >
> > OK, at this point I think we need to let the code do the talking :)
> >
> > I've seen Ard's patches already and I think I understand what your
> > needs are. So let me whip up some code to show you guys what I
> > think needs to be done.
>
> BTW before you have a go at this, there's also Linus' idea that does not
> change the crypto code (at least not functionally). Of course, you and
> Ard can still try to figure out how to reduce the padding but if we go
> with Linus' idea of a new GFP_NODMA flag, there won't be any changes to
> the crypto code as long as it doesn't pass such flag. So, the options:
>
> 1. Change ARCH_KMALLOC_MINALIGN to 8 (or ARCH_SLAB_MINALIGN if higher)
> while keeping ARCH_DMA_MINALIGN to 128. By default kmalloc() will
> honour the 128-byte alignment, unless GDP_NODMA is passed. This still
> requires changing CRYPTO_MINALIGN to ARCH_DMA_MINALIGN but there is
> no functional change, kmalloc() without the new flag will return
> CRYPTO_MINALIGN-aligned pointers.
>
> 2. Leave ARCH_KMALLOC_MINALIGN as ARCH_DMA_MINALIGN (128) and introduce
> a new GFP_PACKED (I think it fits better than 'NODMA') flag that
> reduces the minimum kmalloc() below ARCH_KMALLOC_MINALIGN (and
> probably at least ARCH_SLAB_MINALIGN). It's equivalent to (1) but
> does not touch the crypto code at all.
>
> (1) and (2) are the same, just minor naming difference. Happy to go with
> any of them. They still have the downside that we need to add the new
> GFP_ flag to those hotspots that allocate small objects (Arnd provided
> an idea on how to find them with ftrace) but at least we know it won't
> inadvertently break anything.
>
I'm not sure GFP_NODMA adds much here.
The way I see it, the issue in the crypto code is that we are relying
on a ARCH_KMALLOC_ALIGN aligned zero length __ctx[] array for three
different things:
- ensuring/informing the compiler that top-level request/TFM
structures are aligned to ARCH_KMALLOC_ALIGN,
- adding padding to ensure that driver context structures that are
embedded in those top-level request/TFM structures are sufficiently
aligned so that any member C types appear at the expected alignment
(but those structures are not usually defined as being aligned to
ARCH_KMALLOC_ALIGN)
- adding padding to ensure that these driver context structures do not
share cache lines with the preceding top-level struct.
One thing to note here is that the padding is only necessary when the
driver context size > 0, and has nothing to do with the alignment of
the top-level struct.
Using a single aligned ctx member was a nice way to accomplish all of
these when it was introduced, but I think it might be better to get
rid of it, and move the padding logic to the static inline helpers
instead.
So something like
struct skcipher_request {
...
} CRYPTO_MINALIGN_ATTR;
which states/ensures the alignment of the struct, and
void *skcipher_request_ctx(struct skcipher_request *req) {
return (void *)PTR_ALIGN(req + 1, ARCH_DMA_MINALIGN);
}
to get at the context struct, instead of using a struct field.
Then, we could update skcipher_request_alloc() to only round up
sizeof(struct skipher_request) to ARCH_DMA_MINALIGN if the reqsize is
>0 to begin with, and if it is, to also round reqsize up to
ARCH_DMA_MINALIGN when accessed. That way, we spell out the DMA
padding requirements with relying on aligned struct members.
If we do it this way, we have a clear distinction between expectations
about what kmalloc returns in terms of alignment, and adding padding
to influence the placement of the context struct. It also makes it
easier to either apply the changes I proposed in the series I sent out
a couple of weeks ago, or get rid of DMA alignment for request/TFM
structures altogether, if we manage to identify and fix the drivers
that are relying on this. In any case, it decouples these two things
in a way that allows Catalin to make his kmalloc changes without
having to redefine CRYPTO_MINALIGN to ARCH_DMA_MINALIGN.
--
Ard.
_______________________________________________
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 0/6] gpiolib: more helpers and fwnode conversion
From: Linus Walleij @ 2022-04-19 21:51 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Neil Armstrong, linux-gpio, linux-arm-kernel, linux-amlogic,
linux-kernel, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Andrew Lunn, Gregory Clement, Sebastian Hesselbarth,
Bartosz Golaszewski, Marek Szyprowski
In-Reply-To: <20220414190242.22178-1-andriy.shevchenko@linux.intel.com>
On Thu, Apr 14, 2022 at 9:02 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> This is a spin-off (*) of the previous work of switching GPIO library
> to use fwnode instead of of_node. Here we introduce a couple of
> a new macro helpers, which allows to switch some of the drivers
> to use fwnode and partially fwnode APIs. As a result of this cleanup
> a few drivers switched to use GPIO fwnode instead of of_node.
>
> *) it's subset of it with a new (patch 1) helper.
>
> Marek, Martin, can you give this a try?
> This requires at least two patches for GPIO library to be applied.
>
> Bart, Linus, I can take it thru my tree with an immutable branch if
> it's the way you prefer, otherwise please suggest on how to proceed.
Hmmm that sounds best, patch 1 does not apply to the pinctrl
tree so I suppose there are already dependencies in the GPIO
tree?
FWIW, the series:
Acked-by: Linus Walleij <linus.walleij@linaro.org>
I'm of course a fan of this nice refactoring series.
Yours,
Linus Walleij
_______________________________________________
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] net: ethernet: mtk_eth_soc: fix error check return value of debugfs_create_dir()
From: Andrew Lunn @ 2022-04-19 21:55 UTC (permalink / raw)
To: cgel.zte
Cc: nbd, john, sean.wang, Mark-MC.Lee, davem, kuba, pabeni,
matthias.bgg, netdev, linux-arm-kernel, linux-mediatek,
linux-kernel, Lv Ruyi, Zeal Robot
In-Reply-To: <20220419015832.2562366-1-lv.ruyi@zte.com.cn>
On Tue, Apr 19, 2022 at 01:58:32AM +0000, cgel.zte@gmail.com wrote:
> From: Lv Ruyi <lv.ruyi@zte.com.cn>
>
> If an error occurs, debugfs_create_file() will return ERR_PTR(-ERROR),
> so use IS_ERR() to check it.
Please take a look at for example:
https://lkml.iu.edu/hypermail/linux/kernel/1901.2/06005.html
https://lkml.iu.edu/hypermail/linux/kernel/1901.2/06006.html
https://lkml.iu.edu/hypermail/linux/kernel/1901.2/05993.html
This is the author of debugfs remove exactly the sort of code you are
adding.
Please teach the Zeal Bot that such code is wrong, and you should be
submitting patches to actually remove testing the return values for
anything which starts with debugfs_
Andrew
_______________________________________________
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 v2 00/10] gpiolib: Handle immutable irq_chip structures
From: Linus Walleij @ 2022-04-19 21:56 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-kernel, Bartosz Golaszewski, Thierry Reding, Joey Gouly,
Jonathan Hunter, Hector Martin, Sven Peter, Alyssa Rosenzweig,
Bjorn Andersson, Andy Gross, Jeffrey Hugo, Thomas Gleixner,
Basavaraj Natikar, Shyam Sundar S K, linux-gpio, linux-tegra,
linux-arm-kernel, linux-arm-msm, kernel-team
In-Reply-To: <20220405135444.199295-1-maz@kernel.org>
On Tue, Apr 5, 2022 at 3:55 PM Marc Zyngier <maz@kernel.org> wrote:
> Not only this breaks when an irq_chip structure is made const (which
> really should be the default case), but it also forces this structure
> to be copied at nauseam for each instance of the GPIO block, which is
> a waste of memory.
>
> My current approach is to add a new irq_chip flag (IRQCHIP_IMMUTABLE)
> which does what it says on the tin: don't you dare writing to them.
> Gpiolib is further updated not to install its own callbacks, and it
> becomes the responsibility of the driver to call into the gpiolib when
> required. This is similar to what we do for other subsystems such as
> PCI-MSI.
>
> 5 drivers are updated to this new model: M1, QC, Tegra, pl061 and AMD
> (as I actively use them) keeping a single irq_chip structure, marking
> it const, and exposing the new flag.
>
> Nothing breaks, the volume of change is small, the memory usage goes
> down and we have fewer callbacks that can be used as attack vectors.
> What's not to love?
>
> * From v1 [1]:
> - pl061 and AMD drivers converted
> - New helpers to keep the changes small
> - New warning for non-converted drivers
> - Documentation and TODO updates
>
> [1] https://lore.kernel.org/r/20220223154405.54912-1-maz@kernel.org
>
> Marc Zyngier (10):
> gpio: Don't fiddle with irqchips marked as immutable
> gpio: Expose the gpiochip_irq_re[ql]res helpers
> gpio: Add helpers to ease the transition towards immutable irq_chip
> gpio: tegra186: Make the irqchip immutable
> gpio: pl061: Make the irqchip immutable
> pinctrl: apple-gpio: Make the irqchip immutable
> pinctrl: msmgpio: Make the irqchip immutable
> pinctrl: amd: Make the irqchip immutable
> gpio: Update TODO to mention immutable irq_chip structures
> Documentation: Update the recommended pattern for GPIO irqchips
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
_______________________________________________
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] gpio: use raw spinlock for gpio chip shadowed data
From: Linus Walleij @ 2022-04-19 21:57 UTC (permalink / raw)
To: Schspa Shi
Cc: brgl, andy.shevchenko, f.fainelli, fancer.lancer, hoan,
linux-arm-kernel, linux-gpio, linux-kernel, opendmb
In-Reply-To: <20220419012810.88417-1-schspa@gmail.com>
On Tue, Apr 19, 2022 at 3:28 AM Schspa Shi <schspa@gmail.com> wrote:
> In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency
> as the lockdep report shows.
>
> __irq_set_handler
> irq_get_desc_buslock
> __irq_get_desc_lock
> raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here
> __irq_do_set_handler
> mask_ack_irq
> dwapb_irq_ack
> spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock
> irq_put_desc_busunlock
>
> Replace with a raw lock to avoid BUGs. This lock is only used to access
> registers, and It's safe to replace with the raw lock without bad
> influence.
>
> [ 15.090359][ T1] =============================
> [ 15.090365][ T1] [ BUG: Invalid wait context ]
> [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted
> [ 15.090386][ T1] -----------------------------
> [ 15.090392][ T1] swapper/0/1 is trying to lock:
> [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28
> [ 15.090470][ T1] other info that might help us debug this:
> [ 15.090477][ T1] context-{5:5}
> [ 15.090485][ T1] 3 locks held by swapper/0/1:
> [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104
> [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4
> [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28
> [ 15.090654][ T1] stack backtrace:
> [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3
> [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT)
> [ 15.090692][ T1] Call trace:
> ......
> [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28
> [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300
> [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c
> [ 15.090864][ T1] __irq_set_handler+0x74/0x114
> [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58
> [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644
>
> Signed-off-by: Schspa Shi <schspa@gmail.com>
LGTM
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Mostly hits drivers/gpio so this seems like something Bartosz
should merge.
Yours,
Linus Walleij
_______________________________________________
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 v10 06/14] mm: multi-gen LRU: minimal implementation
From: Yu Zhao @ 2022-04-19 22:20 UTC (permalink / raw)
To: Barry Song
Cc: Stephen Rothwell, Linux-MM, Andi Kleen, Andrew Morton,
Aneesh Kumar, Catalin Marinas, Dave Hansen, Hillf Danton,
Jens Axboe, Jesse Barnes, Johannes Weiner, Jonathan Corbet,
Linus Torvalds, Matthew Wilcox, Mel Gorman, Michael Larabel,
Michal Hocko, Mike Rapoport, Rik van Riel, Vlastimil Babka,
Will Deacon, Ying Huang, LAK, Linux Doc Mailing List, LKML,
Kernel Page Reclaim v2, x86, Brian Geffon, Jan Alexander Steffens,
Oleksandr Natalenko, Steven Barrett, Suleiman Souhlal,
Daniel Byrne, Donald Carr, Holger Hoffstätte,
Konstantin Kharlamov, Shuang Zhai, Sofia Trinh, Vaibhav Jain
In-Reply-To: <CAGsJ_4wj2mbqSoT3sXHVU+ouCpTPyOXAu9wZS+2U_T5LtN97dA@mail.gmail.com>
On Mon, Apr 18, 2022 at 10:26 PM Barry Song <21cnbao@gmail.com> wrote:
>
> On Tue, Apr 19, 2022 at 12:54 PM Yu Zhao <yuzhao@google.com> wrote:
> >
> > On Mon, Apr 18, 2022 at 3:58 AM Barry Song <21cnbao@gmail.com> wrote:
> > >
> > > On Thu, Apr 7, 2022 at 3:16 PM Yu Zhao <yuzhao@google.com> wrote:
> > > >
> > > > To avoid confusion, the terms "promotion" and "demotion" will be
> > > > applied to the multi-gen LRU, as a new convention; the terms
> > > > "activation" and "deactivation" will be applied to the active/inactive
> > > > LRU, as usual.
> > > >
> > > > The aging produces young generations. Given an lruvec, it increments
> > > > max_seq when max_seq-min_seq+1 approaches MIN_NR_GENS. The aging
> > > > promotes hot pages to the youngest generation when it finds them
> > > > accessed through page tables; the demotion of cold pages happens
> > > > consequently when it increments max_seq. The aging has the complexity
> > > > O(nr_hot_pages), since it is only interested in hot pages. Promotion
> > > > in the aging path does not require any LRU list operations, only the
> > > > updates of the gen counter and lrugen->nr_pages[]; demotion, unless as
> > > > the result of the increment of max_seq, requires LRU list operations,
> > > > e.g., lru_deactivate_fn().
> > > >
> > > > The eviction consumes old generations. Given an lruvec, it increments
> > > > min_seq when the lists indexed by min_seq%MAX_NR_GENS become empty. A
> > > > feedback loop modeled after the PID controller monitors refaults over
> > > > anon and file types and decides which type to evict when both types
> > > > are available from the same generation.
> > > >
> > > > Each generation is divided into multiple tiers. Tiers represent
> > > > different ranges of numbers of accesses through file descriptors. A
> > > > page accessed N times through file descriptors is in tier
> > > > order_base_2(N). Tiers do not have dedicated lrugen->lists[], only
> > > > bits in folio->flags. In contrast to moving across generations, which
> > > > requires the LRU lock, moving across tiers only involves operations on
> > > > folio->flags. The feedback loop also monitors refaults over all tiers
> > > > and decides when to protect pages in which tiers (N>1), using the
> > > > first tier (N=0,1) as a baseline. The first tier contains single-use
> > > > unmapped clean pages, which are most likely the best choices. The
> > > > eviction moves a page to the next generation, i.e., min_seq+1, if the
> > > > feedback loop decides so. This approach has the following advantages:
> > > > 1. It removes the cost of activation in the buffered access path by
> > > > inferring whether pages accessed multiple times through file
> > > > descriptors are statistically hot and thus worth protecting in the
> > > > eviction path.
> > > > 2. It takes pages accessed through page tables into account and avoids
> > > > overprotecting pages accessed multiple times through file
> > > > descriptors. (Pages accessed through page tables are in the first
> > > > tier, since N=0.)
> > > > 3. More tiers provide better protection for pages accessed more than
> > > > twice through file descriptors, when under heavy buffered I/O
> > > > workloads.
> > > >
> > >
> > > Hi Yu,
> > > As I told you before, I tried to change the current LRU (not MGLRU) by only
> > > promoting unmapped file pages to the head of the inactive head rather than
> > > the active head on its second access:
> > > https://lore.kernel.org/lkml/CAGsJ_4y=TkCGoWWtWSAptW4RDFUEBeYXwfwu=fUFvV4Sa4VA4A@mail.gmail.com/
> > > I have already seen some very good results by the decease of cpu consumption of
> > > kswapd and direct reclamation in the testing.
> >
> > Glad to hear. I suspected you'd see some good results with that change :)
> >
> > > in mglru, it seems "twice" isn't a concern at all, one unmapped file
> > > page accessed
> > > twice has no much difference with those ones which are accessed once as you
> > > only begin to increase refs from the third time:
> >
> > refs are *additional* accesses:
> > PG_referenced: N=1
> > PG_referenced+PG_workingset: N=2
> > PG_referenced+PG_workingset+refs: N=3,4,5
> >
> > When N=2, order_base_2(N)=1. So pages accessed twice are in the second
> > tier. Therefore they are "different".
> >
> > More details [1]:
> >
> > +/*
> > + * Each generation is divided into multiple tiers. Tiers represent different
> > + * ranges of numbers of accesses through file descriptors. A page accessed N
> > + * times through file descriptors is in tier order_base_2(N). A page in the
> > + * first tier (N=0,1) is marked by PG_referenced unless it was faulted in
> > + * though page tables or read ahead. A page in any other tier (N>1) is marked
> > + * by PG_referenced and PG_workingset.
> > + *
> > + * In contrast to moving across generations which requires the LRU lock, moving
> > + * across tiers only requires operations on folio->flags and therefore has a
> > + * negligible cost in the buffered access path. In the eviction path,
> > + * comparisons of refaulted/(evicted+protected) from the first tier and the
> > + * rest infer whether pages accessed multiple times through file descriptors
> > + * are statistically hot and thus worth protecting.
> > + *
> > + * MAX_NR_TIERS is set to 4 so that the multi-gen LRU can support twice of the
> > + * categories of the active/inactive LRU when keeping track of accesses through
> > + * file descriptors. It requires MAX_NR_TIERS-2 additional bits in
> > folio->flags.
> > + */
> > +#define MAX_NR_TIERS 4U
> >
> > [1] https://lore.kernel.org/linux-mm/20220407031525.2368067-7-yuzhao@google.com/
> >
> > > +static void folio_inc_refs(struct folio *folio)
> > > +{
> > > + unsigned long refs;
> > > + unsigned long old_flags, new_flags;
> > > +
> > > + if (folio_test_unevictable(folio))
> > > + return;
> > > +
> > > + /* see the comment on MAX_NR_TIERS */
> > > + do {
> > > + new_flags = old_flags = READ_ONCE(folio->flags);
> > > +
> > > + if (!(new_flags & BIT(PG_referenced))) {
> > > + new_flags |= BIT(PG_referenced);
> > > + continue;
> > > + }
> > > +
> > > + if (!(new_flags & BIT(PG_workingset))) {
> > > + new_flags |= BIT(PG_workingset);
> > > + continue;
> > > + }
> > > +
> > > + refs = new_flags & LRU_REFS_MASK;
> > > + refs = min(refs + BIT(LRU_REFS_PGOFF), LRU_REFS_MASK);
> > > +
> > > + new_flags &= ~LRU_REFS_MASK;
> > > + new_flags |= refs;
> > > + } while (new_flags != old_flags &&
> > > + cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);
> > > +}
> > >
> > > So my question is what makes you so confident that twice doesn't need
> > > any special treatment while the vanilla kernel is upgrading this kind of page
> > > to the head of the active instead? I am asking this because I am considering
> > > reclaiming unmapped file pages which are only accessed twice when they
> > > get to the tail of the inactive list.
> >
> > Per above, pages accessed twice are in their own tier. Hope this clarifies it.
>
> Yep, I found the trick here , "+1" is magic behind the code, haha.
>
> +static int folio_lru_tier(struct folio *folio)
> +{
> + int refs;
> + unsigned long flags = READ_ONCE(folio->flags);
> +
> + refs = (flags & LRU_REFS_FLAGS) == LRU_REFS_FLAGS ?
> + ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + 1 : 0;
> +
> + return lru_tier_from_refs(refs);
> +}
> +
>
> TBH, this might need some comments, otherwise, it is easy to misunderstand
> we are beginning to have protection from 3rd access :-)
Agreed. Let me rework this function. I don't know how yet but I'll
think of something.
_______________________________________________
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 v10 06/14] mm: multi-gen LRU: minimal implementation
From: Yu Zhao @ 2022-04-19 22:25 UTC (permalink / raw)
To: Barry Song
Cc: Stephen Rothwell, Linux-MM, Andi Kleen, Andrew Morton,
Aneesh Kumar, Catalin Marinas, Dave Hansen, Hillf Danton,
Jens Axboe, Jesse Barnes, Johannes Weiner, Jonathan Corbet,
Linus Torvalds, Matthew Wilcox, Mel Gorman, Michael Larabel,
Michal Hocko, Mike Rapoport, Rik van Riel, Vlastimil Babka,
Will Deacon, Ying Huang, LAK, Linux Doc Mailing List, LKML,
Kernel Page Reclaim v2, x86, Brian Geffon, Jan Alexander Steffens,
Oleksandr Natalenko, Steven Barrett, Suleiman Souhlal,
Daniel Byrne, Donald Carr, Holger Hoffstätte,
Konstantin Kharlamov, Shuang Zhai, Sofia Trinh, Vaibhav Jain
In-Reply-To: <CAGsJ_4ys6FmwvKkNVpD9Jv_DxG+82oRBc6y9FGGo+POfMEEaUw@mail.gmail.com>
On Mon, Apr 18, 2022 at 10:36 PM Barry Song <21cnbao@gmail.com> wrote:
>
> On Tue, Apr 19, 2022 at 4:25 PM Barry Song <21cnbao@gmail.com> wrote:
> >
> > On Tue, Apr 19, 2022 at 12:54 PM Yu Zhao <yuzhao@google.com> wrote:
> > >
> > > On Mon, Apr 18, 2022 at 3:58 AM Barry Song <21cnbao@gmail.com> wrote:
> > > >
> > > > On Thu, Apr 7, 2022 at 3:16 PM Yu Zhao <yuzhao@google.com> wrote:
> > > > >
> > > > > To avoid confusion, the terms "promotion" and "demotion" will be
> > > > > applied to the multi-gen LRU, as a new convention; the terms
> > > > > "activation" and "deactivation" will be applied to the active/inactive
> > > > > LRU, as usual.
> > > > >
> > > > > The aging produces young generations. Given an lruvec, it increments
> > > > > max_seq when max_seq-min_seq+1 approaches MIN_NR_GENS. The aging
> > > > > promotes hot pages to the youngest generation when it finds them
> > > > > accessed through page tables; the demotion of cold pages happens
> > > > > consequently when it increments max_seq. The aging has the complexity
> > > > > O(nr_hot_pages), since it is only interested in hot pages. Promotion
> > > > > in the aging path does not require any LRU list operations, only the
> > > > > updates of the gen counter and lrugen->nr_pages[]; demotion, unless as
> > > > > the result of the increment of max_seq, requires LRU list operations,
> > > > > e.g., lru_deactivate_fn().
> > > > >
> > > > > The eviction consumes old generations. Given an lruvec, it increments
> > > > > min_seq when the lists indexed by min_seq%MAX_NR_GENS become empty. A
> > > > > feedback loop modeled after the PID controller monitors refaults over
> > > > > anon and file types and decides which type to evict when both types
> > > > > are available from the same generation.
> > > > >
> > > > > Each generation is divided into multiple tiers. Tiers represent
> > > > > different ranges of numbers of accesses through file descriptors. A
> > > > > page accessed N times through file descriptors is in tier
> > > > > order_base_2(N). Tiers do not have dedicated lrugen->lists[], only
> > > > > bits in folio->flags. In contrast to moving across generations, which
> > > > > requires the LRU lock, moving across tiers only involves operations on
> > > > > folio->flags. The feedback loop also monitors refaults over all tiers
> > > > > and decides when to protect pages in which tiers (N>1), using the
> > > > > first tier (N=0,1) as a baseline. The first tier contains single-use
> > > > > unmapped clean pages, which are most likely the best choices. The
> > > > > eviction moves a page to the next generation, i.e., min_seq+1, if the
> > > > > feedback loop decides so. This approach has the following advantages:
> > > > > 1. It removes the cost of activation in the buffered access path by
> > > > > inferring whether pages accessed multiple times through file
> > > > > descriptors are statistically hot and thus worth protecting in the
> > > > > eviction path.
> > > > > 2. It takes pages accessed through page tables into account and avoids
> > > > > overprotecting pages accessed multiple times through file
> > > > > descriptors. (Pages accessed through page tables are in the first
> > > > > tier, since N=0.)
> > > > > 3. More tiers provide better protection for pages accessed more than
> > > > > twice through file descriptors, when under heavy buffered I/O
> > > > > workloads.
> > > > >
> > > >
> > > > Hi Yu,
> > > > As I told you before, I tried to change the current LRU (not MGLRU) by only
> > > > promoting unmapped file pages to the head of the inactive head rather than
> > > > the active head on its second access:
> > > > https://lore.kernel.org/lkml/CAGsJ_4y=TkCGoWWtWSAptW4RDFUEBeYXwfwu=fUFvV4Sa4VA4A@mail.gmail.com/
> > > > I have already seen some very good results by the decease of cpu consumption of
> > > > kswapd and direct reclamation in the testing.
> > >
> > > Glad to hear. I suspected you'd see some good results with that change :)
> > >
> > > > in mglru, it seems "twice" isn't a concern at all, one unmapped file
> > > > page accessed
> > > > twice has no much difference with those ones which are accessed once as you
> > > > only begin to increase refs from the third time:
> > >
> > > refs are *additional* accesses:
> > > PG_referenced: N=1
> > > PG_referenced+PG_workingset: N=2
> > > PG_referenced+PG_workingset+refs: N=3,4,5
> > >
> > > When N=2, order_base_2(N)=1. So pages accessed twice are in the second
> > > tier. Therefore they are "different".
> > >
> > > More details [1]:
> > >
> > > +/*
> > > + * Each generation is divided into multiple tiers. Tiers represent different
> > > + * ranges of numbers of accesses through file descriptors. A page accessed N
> > > + * times through file descriptors is in tier order_base_2(N). A page in the
> > > + * first tier (N=0,1) is marked by PG_referenced unless it was faulted in
> > > + * though page tables or read ahead. A page in any other tier (N>1) is marked
> > > + * by PG_referenced and PG_workingset.
> > > + *
> > > + * In contrast to moving across generations which requires the LRU lock, moving
> > > + * across tiers only requires operations on folio->flags and therefore has a
> > > + * negligible cost in the buffered access path. In the eviction path,
> > > + * comparisons of refaulted/(evicted+protected) from the first tier and the
> > > + * rest infer whether pages accessed multiple times through file descriptors
> > > + * are statistically hot and thus worth protecting.
> > > + *
> > > + * MAX_NR_TIERS is set to 4 so that the multi-gen LRU can support twice of the
> > > + * categories of the active/inactive LRU when keeping track of accesses through
> > > + * file descriptors. It requires MAX_NR_TIERS-2 additional bits in
> > > folio->flags.
> > > + */
> > > +#define MAX_NR_TIERS 4U
> > >
> > > [1] https://lore.kernel.org/linux-mm/20220407031525.2368067-7-yuzhao@google.com/
> > >
> > > > +static void folio_inc_refs(struct folio *folio)
> > > > +{
> > > > + unsigned long refs;
> > > > + unsigned long old_flags, new_flags;
> > > > +
> > > > + if (folio_test_unevictable(folio))
> > > > + return;
> > > > +
> > > > + /* see the comment on MAX_NR_TIERS */
> > > > + do {
> > > > + new_flags = old_flags = READ_ONCE(folio->flags);
> > > > +
> > > > + if (!(new_flags & BIT(PG_referenced))) {
> > > > + new_flags |= BIT(PG_referenced);
> > > > + continue;
> > > > + }
> > > > +
> > > > + if (!(new_flags & BIT(PG_workingset))) {
> > > > + new_flags |= BIT(PG_workingset);
> > > > + continue;
> > > > + }
> > > > +
> > > > + refs = new_flags & LRU_REFS_MASK;
> > > > + refs = min(refs + BIT(LRU_REFS_PGOFF), LRU_REFS_MASK);
> > > > +
> > > > + new_flags &= ~LRU_REFS_MASK;
> > > > + new_flags |= refs;
> > > > + } while (new_flags != old_flags &&
> > > > + cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);
> > > > +}
> > > >
> > > > So my question is what makes you so confident that twice doesn't need
> > > > any special treatment while the vanilla kernel is upgrading this kind of page
> > > > to the head of the active instead? I am asking this because I am considering
> > > > reclaiming unmapped file pages which are only accessed twice when they
> > > > get to the tail of the inactive list.
> > >
> > > Per above, pages accessed twice are in their own tier. Hope this clarifies it.
> >
> > Yep, I found the trick here , "+1" is magic behind the code, haha.
> >
> > +static int folio_lru_tier(struct folio *folio)
> > +{
> > + int refs;
> > + unsigned long flags = READ_ONCE(folio->flags);
> > +
> > + refs = (flags & LRU_REFS_FLAGS) == LRU_REFS_FLAGS ?
> > + ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + 1 : 0;
> > +
> > + return lru_tier_from_refs(refs);
> > +}
> > +
> >
> > TBH, this might need some comments, otherwise, it is easy to misunderstand
> > we are beginning to have protection from 3rd access :-)
>
> as anyway, it would be much more straightforward to have the below if
> we can also
> increase refs for the 1st and 2nd access in folio_inc_refs():
It would if there were abundant spare bits in page->flags. On some
machines, we don't, so we have to reuse PG_referenced and
PG_workingset.
> +static int folio_lru_tier(struct folio *folio)
> +{
> + int refs;
> + unsigned long flags = READ_ONCE(folio->flags);
> +
> + refs = (flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF;
> +
> + return lru_tier_from_refs(refs);
> +}
_______________________________________________
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 0/6] pinctrl: ocelot: convert to YAML format
From: Linus Walleij @ 2022-04-19 22:28 UTC (permalink / raw)
To: Michael Walle
Cc: devicetree, Thomas Bogendoerfer, linux-mips, Quentin Schulz,
Paul Burton, Krzysztof Kozlowski, linux-kernel, Gregory CLEMENT,
David S . Miller, linux-gpio, Rob Herring, linux-arm-kernel,
Kavyasree Kotagiri, Antoine Tenart, UNGLinuxDriver,
Steen Hegelund, Lars Povlsen
In-Reply-To: <20220319204628.1759635-1-michael@walle.cc>
On Sat, Mar 19, 2022 at 9:46 PM Michael Walle <michael@walle.cc> wrote:
> dt-bindings: pinctrl: convert ocelot-pinctrl to YAML format
This patch applied to the pinctrl tree, please send the rest
through the SoC tree.
Yours,
Linus Walleij
_______________________________________________
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] gpio: use raw spinlock for gpio chip shadowed data
From: Doug Berger @ 2022-04-19 22:30 UTC (permalink / raw)
To: Schspa Shi, brgl, andy.shevchenko, linus.walleij
Cc: f.fainelli, fancer.lancer, hoan, linux-arm-kernel, linux-gpio,
linux-kernel
In-Reply-To: <20220419012810.88417-1-schspa@gmail.com>
On 4/18/2022 6:28 PM, Schspa Shi wrote:
> In case of PREEMPT_RT, there is a raw_spinlock -> spinlock dependency
> as the lockdep report shows.
>
> __irq_set_handler
> irq_get_desc_buslock
> __irq_get_desc_lock
> raw_spin_lock_irqsave(&desc->lock, *flags); // raw spinlock get here
> __irq_do_set_handler
> mask_ack_irq
> dwapb_irq_ack
> spin_lock_irqsave(&gc->bgpio_lock, flags); // sleep able spinlock
> irq_put_desc_busunlock
>
> Replace with a raw lock to avoid BUGs. This lock is only used to access
> registers, and It's safe to replace with the raw lock without bad
> influence.
>
> [ 15.090359][ T1] =============================
> [ 15.090365][ T1] [ BUG: Invalid wait context ]
> [ 15.090373][ T1] 5.10.59-rt52-00983-g186a6841c682-dirty #3 Not tainted
> [ 15.090386][ T1] -----------------------------
> [ 15.090392][ T1] swapper/0/1 is trying to lock:
> [ 15.090402][ T1] 70ff00018507c188 (&gc->bgpio_lock){....}-{3:3}, at: _raw_spin_lock_irqsave+0x1c/0x28
> [ 15.090470][ T1] other info that might help us debug this:
> [ 15.090477][ T1] context-{5:5}
> [ 15.090485][ T1] 3 locks held by swapper/0/1:
> [ 15.090497][ T1] #0: c2ff0001816de1a0 (&dev->mutex){....}-{4:4}, at: __device_driver_lock+0x98/0x104
> [ 15.090553][ T1] #1: ffff90001485b4b8 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0xbc/0x6d4
> [ 15.090606][ T1] #2: 4bff000185d7a8e0 (lock_class){....}-{2:2}, at: _raw_spin_lock_irqsave+0x1c/0x28
> [ 15.090654][ T1] stack backtrace:
> [ 15.090661][ T1] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.10.59-rt52-00983-g186a6841c682-dirty #3
> [ 15.090682][ T1] Hardware name: Horizon Robotics Journey 5 DVB (DT)
> [ 15.090692][ T1] Call trace:
> ......
> [ 15.090811][ T1] _raw_spin_lock_irqsave+0x1c/0x28
> [ 15.090828][ T1] dwapb_irq_ack+0xb4/0x300
> [ 15.090846][ T1] __irq_do_set_handler+0x494/0xb2c
> [ 15.090864][ T1] __irq_set_handler+0x74/0x114
> [ 15.090881][ T1] irq_set_chip_and_handler_name+0x44/0x58
> [ 15.090900][ T1] gpiochip_irq_map+0x210/0x644
>
> Signed-off-by: Schspa Shi <schspa@gmail.com>
>
> ---
>
> Changelog:
> v1 -> v2:
> - Reduce the useless stacktrace.
> - Split to series of patches
> v2 -> v3:
> - Restore to a single patch as Andy and Bartosz's suggest
> - add cutter ‘--- ‘ line for Change log
> ---
> drivers/gpio/gpio-amdpt.c | 10 +++----
> drivers/gpio/gpio-brcmstb.c | 12 ++++----
> drivers/gpio/gpio-cadence.c | 12 ++++----
> drivers/gpio/gpio-dwapb.c | 36 +++++++++++------------
> drivers/gpio/gpio-grgpio.c | 30 +++++++++----------
> drivers/gpio/gpio-hlwd.c | 18 ++++++------
> drivers/gpio/gpio-idt3243x.c | 12 ++++----
> drivers/gpio/gpio-ixp4xx.c | 4 +--
> drivers/gpio/gpio-loongson1.c | 8 ++---
> drivers/gpio/gpio-menz127.c | 8 ++---
> drivers/gpio/gpio-mlxbf2.c | 18 ++++++------
> drivers/gpio/gpio-mmio.c | 22 +++++++-------
> drivers/gpio/gpio-sifive.c | 12 ++++----
> drivers/gpio/gpio-tb10x.c | 4 +--
> drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 8 ++---
> include/linux/gpio/driver.h | 2 +-
> 16 files changed, 108 insertions(+), 108 deletions(-)
>
> diff --git a/drivers/gpio/gpio-amdpt.c b/drivers/gpio/gpio-amdpt.c
> index 8cfb353c3abb..07c6d090058d 100644
> --- a/drivers/gpio/gpio-amdpt.c
> +++ b/drivers/gpio/gpio-amdpt.c
> @@ -36,19 +36,19 @@ static int pt_gpio_request(struct gpio_chip *gc, unsigned offset)
>
> dev_dbg(gc->parent, "pt_gpio_request offset=%x\n", offset);
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG);
> if (using_pins & BIT(offset)) {
> dev_warn(gc->parent, "PT GPIO pin %x reconfigured\n",
> offset);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> return -EINVAL;
> }
>
> writel(using_pins | BIT(offset), pt_gpio->reg_base + PT_SYNC_REG);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> return 0;
> }
> @@ -59,13 +59,13 @@ static void pt_gpio_free(struct gpio_chip *gc, unsigned offset)
> unsigned long flags;
> u32 using_pins;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> using_pins = readl(pt_gpio->reg_base + PT_SYNC_REG);
> using_pins &= ~BIT(offset);
> writel(using_pins, pt_gpio->reg_base + PT_SYNC_REG);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> dev_dbg(gc->parent, "pt_gpio_free offset=%x\n", offset);
> }
> diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
> index 74ef89248867..6b7439b44690 100644
> --- a/drivers/gpio/gpio-brcmstb.c
> +++ b/drivers/gpio/gpio-brcmstb.c
> @@ -92,9 +92,9 @@ brcmstb_gpio_get_active_irqs(struct brcmstb_gpio_bank *bank)
> unsigned long status;
> unsigned long flags;
>
> - spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
> status = __brcmstb_gpio_get_active_irqs(bank);
> - spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
>
> return status;
> }
> @@ -114,14 +114,14 @@ static void brcmstb_gpio_set_imask(struct brcmstb_gpio_bank *bank,
> u32 imask;
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> imask = gc->read_reg(priv->reg_base + GIO_MASK(bank->id));
> if (enable)
> imask |= mask;
> else
> imask &= ~mask;
> gc->write_reg(priv->reg_base + GIO_MASK(bank->id), imask);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static int brcmstb_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
> @@ -204,7 +204,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> return -EINVAL;
> }
>
> - spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&bank->gc.bgpio_lock, flags);
>
> iedge_config = bank->gc.read_reg(priv->reg_base +
> GIO_EC(bank->id)) & ~mask;
> @@ -220,7 +220,7 @@ static int brcmstb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> bank->gc.write_reg(priv->reg_base + GIO_LEVEL(bank->id),
> ilevel | level);
>
> - spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&bank->gc.bgpio_lock, flags);
> return 0;
> }
>
> diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c
> index 562f8f7e7d1f..137aea49ba02 100644
> --- a/drivers/gpio/gpio-cadence.c
> +++ b/drivers/gpio/gpio-cadence.c
> @@ -41,12 +41,12 @@ static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset)
> struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
> unsigned long flags;
>
> - spin_lock_irqsave(&chip->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
>
> iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) & ~BIT(offset),
> cgpio->regs + CDNS_GPIO_BYPASS_MODE);
>
> - spin_unlock_irqrestore(&chip->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
> return 0;
> }
>
> @@ -55,13 +55,13 @@ static void cdns_gpio_free(struct gpio_chip *chip, unsigned int offset)
> struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
> unsigned long flags;
>
> - spin_lock_irqsave(&chip->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
>
> iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) |
> (BIT(offset) & cgpio->bypass_orig),
> cgpio->regs + CDNS_GPIO_BYPASS_MODE);
>
> - spin_unlock_irqrestore(&chip->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
> }
>
> static void cdns_gpio_irq_mask(struct irq_data *d)
> @@ -90,7 +90,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> u32 mask = BIT(d->hwirq);
> int ret = 0;
>
> - spin_lock_irqsave(&chip->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&chip->bgpio_lock, flags);
>
> int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask;
> int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask;
> @@ -115,7 +115,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE);
>
> err_irq_type:
> - spin_unlock_irqrestore(&chip->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags);
> return ret;
> }
>
> diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
> index b0f3aca61974..7130195da48d 100644
> --- a/drivers/gpio/gpio-dwapb.c
> +++ b/drivers/gpio/gpio-dwapb.c
> @@ -243,9 +243,9 @@ static void dwapb_irq_ack(struct irq_data *d)
> u32 val = BIT(irqd_to_hwirq(d));
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> dwapb_write(gpio, GPIO_PORTA_EOI, val);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void dwapb_irq_mask(struct irq_data *d)
> @@ -255,10 +255,10 @@ static void dwapb_irq_mask(struct irq_data *d)
> unsigned long flags;
> u32 val;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> val = dwapb_read(gpio, GPIO_INTMASK) | BIT(irqd_to_hwirq(d));
> dwapb_write(gpio, GPIO_INTMASK, val);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void dwapb_irq_unmask(struct irq_data *d)
> @@ -268,10 +268,10 @@ static void dwapb_irq_unmask(struct irq_data *d)
> unsigned long flags;
> u32 val;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(irqd_to_hwirq(d));
> dwapb_write(gpio, GPIO_INTMASK, val);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void dwapb_irq_enable(struct irq_data *d)
> @@ -281,11 +281,11 @@ static void dwapb_irq_enable(struct irq_data *d)
> unsigned long flags;
> u32 val;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> val = dwapb_read(gpio, GPIO_INTEN);
> val |= BIT(irqd_to_hwirq(d));
> dwapb_write(gpio, GPIO_INTEN, val);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void dwapb_irq_disable(struct irq_data *d)
> @@ -295,11 +295,11 @@ static void dwapb_irq_disable(struct irq_data *d)
> unsigned long flags;
> u32 val;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> val = dwapb_read(gpio, GPIO_INTEN);
> val &= ~BIT(irqd_to_hwirq(d));
> dwapb_write(gpio, GPIO_INTEN, val);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static int dwapb_irq_set_type(struct irq_data *d, u32 type)
> @@ -309,7 +309,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
> irq_hw_number_t bit = irqd_to_hwirq(d);
> unsigned long level, polarity, flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> level = dwapb_read(gpio, GPIO_INTTYPE_LEVEL);
> polarity = dwapb_read(gpio, GPIO_INT_POLARITY);
>
> @@ -344,7 +344,7 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
> dwapb_write(gpio, GPIO_INTTYPE_LEVEL, level);
> if (type != IRQ_TYPE_EDGE_BOTH)
> dwapb_write(gpio, GPIO_INT_POLARITY, polarity);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> return 0;
> }
> @@ -374,7 +374,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
> unsigned long flags, val_deb;
> unsigned long mask = BIT(offset);
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> val_deb = dwapb_read(gpio, GPIO_PORTA_DEBOUNCE);
> if (debounce)
> @@ -383,7 +383,7 @@ static int dwapb_gpio_set_debounce(struct gpio_chip *gc,
> val_deb &= ~mask;
> dwapb_write(gpio, GPIO_PORTA_DEBOUNCE, val_deb);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> return 0;
> }
> @@ -738,7 +738,7 @@ static int dwapb_gpio_suspend(struct device *dev)
> unsigned long flags;
> int i;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> for (i = 0; i < gpio->nr_ports; i++) {
> unsigned int offset;
> unsigned int idx = gpio->ports[i].idx;
> @@ -765,7 +765,7 @@ static int dwapb_gpio_suspend(struct device *dev)
> dwapb_write(gpio, GPIO_INTMASK, ~ctx->wake_en);
> }
> }
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
>
> @@ -785,7 +785,7 @@ static int dwapb_gpio_resume(struct device *dev)
> return err;
> }
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> for (i = 0; i < gpio->nr_ports; i++) {
> unsigned int offset;
> unsigned int idx = gpio->ports[i].idx;
> @@ -812,7 +812,7 @@ static int dwapb_gpio_resume(struct device *dev)
> dwapb_write(gpio, GPIO_PORTA_EOI, 0xffffffff);
> }
> }
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> return 0;
> }
> diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c
> index 23d447e17a67..df563616f943 100644
> --- a/drivers/gpio/gpio-grgpio.c
> +++ b/drivers/gpio/gpio-grgpio.c
> @@ -145,7 +145,7 @@ static int grgpio_irq_set_type(struct irq_data *d, unsigned int type)
> return -EINVAL;
> }
>
> - spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
>
> ipol = priv->gc.read_reg(priv->regs + GRGPIO_IPOL) & ~mask;
> iedge = priv->gc.read_reg(priv->regs + GRGPIO_IEDGE) & ~mask;
> @@ -153,7 +153,7 @@ static int grgpio_irq_set_type(struct irq_data *d, unsigned int type)
> priv->gc.write_reg(priv->regs + GRGPIO_IPOL, ipol | pol);
> priv->gc.write_reg(priv->regs + GRGPIO_IEDGE, iedge | edge);
>
> - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
>
> return 0;
> }
> @@ -164,11 +164,11 @@ static void grgpio_irq_mask(struct irq_data *d)
> int offset = d->hwirq;
> unsigned long flags;
>
> - spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
>
> grgpio_set_imask(priv, offset, 0);
>
> - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> }
>
> static void grgpio_irq_unmask(struct irq_data *d)
> @@ -177,11 +177,11 @@ static void grgpio_irq_unmask(struct irq_data *d)
> int offset = d->hwirq;
> unsigned long flags;
>
> - spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
>
> grgpio_set_imask(priv, offset, 1);
>
> - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> }
>
> static struct irq_chip grgpio_irq_chip = {
> @@ -199,7 +199,7 @@ static irqreturn_t grgpio_irq_handler(int irq, void *dev)
> int i;
> int match = 0;
>
> - spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
>
> /*
> * For each gpio line, call its interrupt handler if it its underlying
> @@ -215,7 +215,7 @@ static irqreturn_t grgpio_irq_handler(int irq, void *dev)
> }
> }
>
> - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
>
> if (!match)
> dev_warn(priv->dev, "No gpio line matched irq %d\n", irq);
> @@ -247,13 +247,13 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
> dev_dbg(priv->dev, "Mapping irq %d for gpio line %d\n",
> irq, offset);
>
> - spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
>
> /* Request underlying irq if not already requested */
> lirq->irq = irq;
> uirq = &priv->uirqs[lirq->index];
> if (uirq->refcnt == 0) {
> - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> ret = request_irq(uirq->uirq, grgpio_irq_handler, 0,
> dev_name(priv->dev), priv);
> if (ret) {
> @@ -262,11 +262,11 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq,
> uirq->uirq);
> return ret;
> }
> - spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
> }
> uirq->refcnt++;
>
> - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
>
> /* Setup irq */
> irq_set_chip_data(irq, priv);
> @@ -290,7 +290,7 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
> irq_set_chip_and_handler(irq, NULL, NULL);
> irq_set_chip_data(irq, NULL);
>
> - spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags);
>
> /* Free underlying irq if last user unmapped */
> index = -1;
> @@ -309,13 +309,13 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq)
> uirq = &priv->uirqs[lirq->index];
> uirq->refcnt--;
> if (uirq->refcnt == 0) {
> - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> free_irq(uirq->uirq, priv);
> return;
> }
> }
>
> - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags);
> }
>
> static const struct irq_domain_ops grgpio_irq_domain_ops = {
> diff --git a/drivers/gpio/gpio-hlwd.c b/drivers/gpio/gpio-hlwd.c
> index 641719a96a1a..4e13e937f832 100644
> --- a/drivers/gpio/gpio-hlwd.c
> +++ b/drivers/gpio/gpio-hlwd.c
> @@ -65,7 +65,7 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)
> int hwirq;
> u32 emulated_pending;
>
> - spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
> pending = ioread32be(hlwd->regs + HW_GPIOB_INTFLAG);
> pending &= ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
>
> @@ -93,7 +93,7 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)
> /* Mark emulated interrupts as pending */
> pending |= rising | falling;
> }
> - spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
>
> chained_irq_enter(chip, desc);
>
> @@ -118,11 +118,11 @@ static void hlwd_gpio_irq_mask(struct irq_data *data)
> unsigned long flags;
> u32 mask;
>
> - spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
> mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
> mask &= ~BIT(data->hwirq);
> iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK);
> - spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> }
>
> static void hlwd_gpio_irq_unmask(struct irq_data *data)
> @@ -132,11 +132,11 @@ static void hlwd_gpio_irq_unmask(struct irq_data *data)
> unsigned long flags;
> u32 mask;
>
> - spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
> mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
> mask |= BIT(data->hwirq);
> iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK);
> - spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> }
>
> static void hlwd_gpio_irq_enable(struct irq_data *data)
> @@ -173,7 +173,7 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
> unsigned long flags;
> u32 level;
>
> - spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
>
> hlwd->edge_emulation &= ~BIT(data->hwirq);
>
> @@ -194,11 +194,11 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
> hlwd_gpio_irq_setup_emulation(hlwd, data->hwirq, flow_type);
> break;
> default:
> - spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> return -EINVAL;
> }
>
> - spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
> return 0;
> }
>
> diff --git a/drivers/gpio/gpio-idt3243x.c b/drivers/gpio/gpio-idt3243x.c
> index 52b8b72ded77..1cafdf46f875 100644
> --- a/drivers/gpio/gpio-idt3243x.c
> +++ b/drivers/gpio/gpio-idt3243x.c
> @@ -57,7 +57,7 @@ static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
> if (sense == IRQ_TYPE_NONE || (sense & IRQ_TYPE_EDGE_BOTH))
> return -EINVAL;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> ilevel = readl(ctrl->gpio + IDT_GPIO_ILEVEL);
> if (sense & IRQ_TYPE_LEVEL_HIGH)
> @@ -68,7 +68,7 @@ static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
> writel(ilevel, ctrl->gpio + IDT_GPIO_ILEVEL);
> irq_set_handler_locked(d, handle_level_irq);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> return 0;
> }
>
> @@ -86,12 +86,12 @@ static void idt_gpio_mask(struct irq_data *d)
> struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> ctrl->mask_cache |= BIT(d->hwirq);
> writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void idt_gpio_unmask(struct irq_data *d)
> @@ -100,12 +100,12 @@ static void idt_gpio_unmask(struct irq_data *d)
> struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> ctrl->mask_cache &= ~BIT(d->hwirq);
> writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static int idt_gpio_irq_init_hw(struct gpio_chip *gc)
> diff --git a/drivers/gpio/gpio-ixp4xx.c b/drivers/gpio/gpio-ixp4xx.c
> index b3b050604e0b..6b184502fa3f 100644
> --- a/drivers/gpio/gpio-ixp4xx.c
> +++ b/drivers/gpio/gpio-ixp4xx.c
> @@ -128,7 +128,7 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> int_reg = IXP4XX_REG_GPIT1;
> }
>
> - spin_lock_irqsave(&g->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&g->gc.bgpio_lock, flags);
>
> /* Clear the style for the appropriate pin */
> val = __raw_readl(g->base + int_reg);
> @@ -147,7 +147,7 @@ static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
> val |= BIT(d->hwirq);
> __raw_writel(val, g->base + IXP4XX_REG_GPOE);
>
> - spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);
>
> /* This parent only accept level high (asserted) */
> return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
> diff --git a/drivers/gpio/gpio-loongson1.c b/drivers/gpio/gpio-loongson1.c
> index 1b1ee94eeab4..5d90b3bc5a25 100644
> --- a/drivers/gpio/gpio-loongson1.c
> +++ b/drivers/gpio/gpio-loongson1.c
> @@ -25,10 +25,10 @@ static int ls1x_gpio_request(struct gpio_chip *gc, unsigned int offset)
> {
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> __raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) | BIT(offset),
> gpio_reg_base + GPIO_CFG);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> return 0;
> }
> @@ -37,10 +37,10 @@ static void ls1x_gpio_free(struct gpio_chip *gc, unsigned int offset)
> {
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> __raw_writel(__raw_readl(gpio_reg_base + GPIO_CFG) & ~BIT(offset),
> gpio_reg_base + GPIO_CFG);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static int ls1x_gpio_probe(struct platform_device *pdev)
> diff --git a/drivers/gpio/gpio-menz127.c b/drivers/gpio/gpio-menz127.c
> index 1e21c661d79d..a035a9bcb57c 100644
> --- a/drivers/gpio/gpio-menz127.c
> +++ b/drivers/gpio/gpio-menz127.c
> @@ -64,7 +64,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
> debounce /= 50;
> }
>
> - spin_lock(&gc->bgpio_lock);
> + raw_spin_lock(&gc->bgpio_lock);
>
> db_en = readl(priv->reg_base + MEN_Z127_DBER);
>
> @@ -79,7 +79,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio,
> writel(db_en, priv->reg_base + MEN_Z127_DBER);
> writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio));
>
> - spin_unlock(&gc->bgpio_lock);
> + raw_spin_unlock(&gc->bgpio_lock);
>
> return 0;
> }
> @@ -91,7 +91,7 @@ static int men_z127_set_single_ended(struct gpio_chip *gc,
> struct men_z127_gpio *priv = gpiochip_get_data(gc);
> u32 od_en;
>
> - spin_lock(&gc->bgpio_lock);
> + raw_spin_lock(&gc->bgpio_lock);
> od_en = readl(priv->reg_base + MEN_Z127_ODER);
>
> if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN)
> @@ -101,7 +101,7 @@ static int men_z127_set_single_ended(struct gpio_chip *gc,
> od_en &= ~BIT(offset);
>
> writel(od_en, priv->reg_base + MEN_Z127_ODER);
> - spin_unlock(&gc->bgpio_lock);
> + raw_spin_unlock(&gc->bgpio_lock);
>
> return 0;
> }
> diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c
> index 3d89912a05b8..64cb060d9d75 100644
> --- a/drivers/gpio/gpio-mlxbf2.c
> +++ b/drivers/gpio/gpio-mlxbf2.c
> @@ -131,7 +131,7 @@ static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)
> u32 arm_gpio_lock_val;
>
> mutex_lock(yu_arm_gpio_lock_param.lock);
> - spin_lock(&gs->gc.bgpio_lock);
> + raw_spin_lock(&gs->gc.bgpio_lock);
>
> arm_gpio_lock_val = readl(yu_arm_gpio_lock_param.io);
>
> @@ -139,7 +139,7 @@ static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs)
> * When lock active bit[31] is set, ModeX is write enabled
> */
> if (YU_LOCK_ACTIVE_BIT(arm_gpio_lock_val)) {
> - spin_unlock(&gs->gc.bgpio_lock);
> + raw_spin_unlock(&gs->gc.bgpio_lock);
> mutex_unlock(yu_arm_gpio_lock_param.lock);
> return -EINVAL;
> }
> @@ -157,7 +157,7 @@ static void mlxbf2_gpio_lock_release(struct mlxbf2_gpio_context *gs)
> __releases(yu_arm_gpio_lock_param.lock)
> {
> writel(YU_ARM_GPIO_LOCK_RELEASE, yu_arm_gpio_lock_param.io);
> - spin_unlock(&gs->gc.bgpio_lock);
> + raw_spin_unlock(&gs->gc.bgpio_lock);
> mutex_unlock(yu_arm_gpio_lock_param.lock);
> }
>
> @@ -237,7 +237,7 @@ static void mlxbf2_gpio_irq_enable(struct irq_data *irqd)
> unsigned long flags;
> u32 val;
>
> - spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
> val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE);
> val |= BIT(offset);
> writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_CLRCAUSE);
> @@ -245,7 +245,7 @@ static void mlxbf2_gpio_irq_enable(struct irq_data *irqd)
> val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
> val |= BIT(offset);
> writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
> - spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
> }
>
> static void mlxbf2_gpio_irq_disable(struct irq_data *irqd)
> @@ -256,11 +256,11 @@ static void mlxbf2_gpio_irq_disable(struct irq_data *irqd)
> unsigned long flags;
> u32 val;
>
> - spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
> val = readl(gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
> val &= ~BIT(offset);
> writel(val, gs->gpio_io + YU_GPIO_CAUSE_OR_EVTEN0);
> - spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
> }
>
> static irqreturn_t mlxbf2_gpio_irq_handler(int irq, void *ptr)
> @@ -307,7 +307,7 @@ mlxbf2_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
> return -EINVAL;
> }
>
> - spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
> if (fall) {
> val = readl(gs->gpio_io + YU_GPIO_CAUSE_FALL_EN);
> val |= BIT(offset);
> @@ -319,7 +319,7 @@ mlxbf2_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
> val |= BIT(offset);
> writel(val, gs->gpio_io + YU_GPIO_CAUSE_RISE_EN);
> }
> - spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
>
> return 0;
> }
> diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
> index c335a0309ba3..d9dff3dc92ae 100644
> --- a/drivers/gpio/gpio-mmio.c
> +++ b/drivers/gpio/gpio-mmio.c
> @@ -220,7 +220,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
> unsigned long mask = bgpio_line2mask(gc, gpio);
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> if (val)
> gc->bgpio_data |= mask;
> @@ -229,7 +229,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
>
> gc->write_reg(gc->reg_dat, gc->bgpio_data);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
> @@ -248,7 +248,7 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
> unsigned long mask = bgpio_line2mask(gc, gpio);
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> if (val)
> gc->bgpio_data |= mask;
> @@ -257,7 +257,7 @@ static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
>
> gc->write_reg(gc->reg_set, gc->bgpio_data);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void bgpio_multiple_get_masks(struct gpio_chip *gc,
> @@ -286,7 +286,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,
> unsigned long flags;
> unsigned long set_mask, clear_mask;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> bgpio_multiple_get_masks(gc, mask, bits, &set_mask, &clear_mask);
>
> @@ -295,7 +295,7 @@ static void bgpio_set_multiple_single_reg(struct gpio_chip *gc,
>
> gc->write_reg(reg, gc->bgpio_data);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void bgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
> @@ -347,7 +347,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
> {
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
>
> @@ -356,7 +356,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
> if (gc->reg_dir_out)
> gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> return 0;
> }
> @@ -387,7 +387,7 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
> {
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
>
> @@ -396,7 +396,7 @@ static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
> if (gc->reg_dir_out)
> gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio,
> @@ -610,7 +610,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,
> if (gc->bgpio_bits > BITS_PER_LONG)
> return -EINVAL;
>
> - spin_lock_init(&gc->bgpio_lock);
> + raw_spin_lock_init(&gc->bgpio_lock);
> gc->parent = dev;
> gc->label = dev_name(dev);
> gc->base = -1;
> diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
> index 7d82388b4ab7..03b8c4de2e91 100644
> --- a/drivers/gpio/gpio-sifive.c
> +++ b/drivers/gpio/gpio-sifive.c
> @@ -44,7 +44,7 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
> unsigned long flags;
> unsigned int trigger;
>
> - spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
> trigger = (chip->irq_state & BIT(offset)) ? chip->trigger[offset] : 0;
> regmap_update_bits(chip->regs, SIFIVE_GPIO_RISE_IE, BIT(offset),
> (trigger & IRQ_TYPE_EDGE_RISING) ? BIT(offset) : 0);
> @@ -54,7 +54,7 @@ static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
> (trigger & IRQ_TYPE_LEVEL_HIGH) ? BIT(offset) : 0);
> regmap_update_bits(chip->regs, SIFIVE_GPIO_LOW_IE, BIT(offset),
> (trigger & IRQ_TYPE_LEVEL_LOW) ? BIT(offset) : 0);
> - spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
> }
>
> static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger)
> @@ -84,13 +84,13 @@ static void sifive_gpio_irq_enable(struct irq_data *d)
> /* Switch to input */
> gc->direction_input(gc, offset);
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> /* Clear any sticky pending interrupts */
> regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
> regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
> regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
> regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> /* Enable interrupts */
> assign_bit(offset, &chip->irq_state, 1);
> @@ -116,13 +116,13 @@ static void sifive_gpio_irq_eoi(struct irq_data *d)
> u32 bit = BIT(offset);
> unsigned long flags;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
> /* Clear all pending interrupts */
> regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
> regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
> regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
> regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
>
> irq_chip_eoi_parent(d);
> }
> diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c
> index 718a508d3b2f..de6afa3f9716 100644
> --- a/drivers/gpio/gpio-tb10x.c
> +++ b/drivers/gpio/gpio-tb10x.c
> @@ -62,14 +62,14 @@ static inline void tb10x_set_bits(struct tb10x_gpio *gpio, unsigned int offs,
> u32 r;
> unsigned long flags;
>
> - spin_lock_irqsave(&gpio->gc.bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gpio->gc.bgpio_lock, flags);
>
> r = tb10x_reg_read(gpio, offs);
> r = (r & ~mask) | (val & mask);
>
> tb10x_reg_write(gpio, offs, r);
>
> - spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags);
> }
>
> static int tb10x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
> diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> index 9557fac5d11c..b2a0f11a658b 100644
> --- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> +++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> @@ -104,12 +104,12 @@ static void npcm_gpio_set(struct gpio_chip *gc, void __iomem *reg,
> unsigned long flags;
> unsigned long val;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> val = ioread32(reg) | pinmask;
> iowrite32(val, reg);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void npcm_gpio_clr(struct gpio_chip *gc, void __iomem *reg,
> @@ -118,12 +118,12 @@ static void npcm_gpio_clr(struct gpio_chip *gc, void __iomem *reg,
> unsigned long flags;
> unsigned long val;
>
> - spin_lock_irqsave(&gc->bgpio_lock, flags);
> + raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
>
> val = ioread32(reg) & ~pinmask;
> iowrite32(val, reg);
>
> - spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
> }
>
> static void npcmgpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
> diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
> index 874aabd270c9..ff8247a19f57 100644
> --- a/include/linux/gpio/driver.h
> +++ b/include/linux/gpio/driver.h
> @@ -445,7 +445,7 @@ struct gpio_chip {
> void __iomem *reg_dir_in;
> bool bgpio_dir_unreadable;
> int bgpio_bits;
> - spinlock_t bgpio_lock;
> + raw_spinlock_t bgpio_lock;
> unsigned long bgpio_data;
> unsigned long bgpio_dir;
> #endif /* CONFIG_GPIO_GENERIC */
For gpio-brcmstb.c changes:
Acked-by: Doug Berger <opendmb@gmail.com>
_______________________________________________
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/6] dt-bindings: auxdisplay: Add Titan Micro Electronics TM1628
From: Robin Murphy @ 2022-04-19 22:31 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Heiner Kallweit, Rob Herring, Krzysztof Kozlowski,
Andreas Färber, Miguel Ojeda, linux-spi@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
open list:ARM/Amlogic Meson..., Jerome Brunet,
Martin Blumenstingl, Kevin Hilman, Neil Armstrong,
Geert Uytterhoeven
In-Reply-To: <CAMuHMdV8iy4vMASuUgeQmjHdAMNzvCikwheyQO1-AQH0yYk0RQ@mail.gmail.com>
On 2022-03-21 08:12, Geert Uytterhoeven wrote:
> Hi Robin,
>
> On Fri, Mar 18, 2022 at 9:50 PM Robin Murphy <robin.murphy@arm.com> wrote:
>> On 2022-02-25 21:13, Heiner Kallweit wrote:
>>> Add a YAML schema binding for TM1628 auxdisplay
>>> (7/11-segment LED) controller.
>>>
>>> This patch is partially based on previous work from
>>> Andreas Färber <afaerber@suse.de>.
>>>
>>> Co-developed-by: Andreas Färber <afaerber@suse.de>
>>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>>> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
>
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm1628.yaml
>
>>> +
>>> +patternProperties:
>>> + "^.*@[1-7],([1-9]|1[0-6])$":
>>> + type: object
>>> + $ref: /schemas/leds/common.yaml#
>>> + unevaluatedProperties: false
>>> + description: |
>>> + Properties for a single LED.
>>> +
>>> + properties:
>>> + reg:
>>> + description: |
>>> + 1-based grid number, followed by 1-based segment bit number.
>>> + maxItems: 1
>>> +
>>> + required:
>>> + - reg
>>
>> I'm concerned that this leaves us no room to support the additional
>> keypad functionality in future. Having now double-checked a datasheet,
>> the inputs are also a two-dimensional mux (sharing the segment lines),
>> so the device effectively has two distinct but numerically-overlapping
>> child address spaces - one addressed by (grid,segment) and the other by
>> (segment,key).
>
> Sounds similar to HT16K33?
/me searches up a datasheet...
Keypad-wise, it appears so, however the display side of this
1618/1628/1638 family is very much tuned for 7-segment displays rather
than arbitrary dot-matrix ones.
I do recall when I was digging a few years ago, turning up an old Holtek
VFD driver which looked suspiciously like it might be the origin of the
particular 3-wire protocol and command set (including weird non-linear
brightness scale) which all these LED driver clones seem to borrow from,
but I can't now remember the part number :(
>> Rob, Krysztof, any thoughts on the best DT idiom to leave accommodation
>> for that? I'm thinking either require an intermediate node to contain
>> each notional address space, or perhaps add another leading address cell
>> to select between them? I don't believe any of these things have further
>> functionality beyond that.
>
> The problem with these devices is that there are thousands of different
> ways to wire them, and coming up with a generic wiring description in
> DT and writing code to handle that can be very hard.
>
> For HT16K33 non-dot-matrix wirings, I just added extra compatible
> values matching the wiring of a few known devices[1]. That way the
> driver can handle them efficiently.
> It does have the disadvantage that adding support for new devices
> means introducing more compatible values, and adding more code.
>
> Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
I think the display side of Heiner's binding is fine for what these
chips can do - I've finally had a bit more time to play with this
series, and (with minor driver hacks) it works just fine to describe my
TM1638 breakout board with an 8-digit display, where segments 8 and 9 of
each grid are respectively a decimal point and a discrete indicator LED,
managed as separate LED nodes.
However, I think you've indirectly addressed my outstanding concern
there - I wasn't aware of the "linux,keymap" property, but since that
brings its own implicit (row,column) addresses distinct from the DT
address space, it looks like that might be sufficient as a neat standard
way to extend this binding in future *without* any other changes.
Thanks,
Robin.
_______________________________________________
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 v10 08/14] mm: multi-gen LRU: support page table walks
From: Yu Zhao @ 2022-04-19 22:32 UTC (permalink / raw)
To: Justin Forbes
Cc: Andrew Morton, Stephen Rothwell, Linux-MM, Andi Kleen,
Aneesh Kumar, Barry Song, Catalin Marinas, Dave Hansen,
Hillf Danton, Jens Axboe, Jesse Barnes, Johannes Weiner,
Jonathan Corbet, Linus Torvalds, Matthew Wilcox, Mel Gorman,
Michael Larabel, Michal Hocko, Mike Rapoport, Rik van Riel,
Vlastimil Babka, Will Deacon, Ying Huang, Linux ARM,
open list:DOCUMENTATION, linux-kernel, Kernel Page Reclaim v2,
the arch/x86 maintainers, Brian Geffon, Jan Alexander Steffens,
Oleksandr Natalenko, Steven Barrett, Suleiman Souhlal,
Daniel Byrne, Donald Carr, Holger Hoffstätte,
Konstantin Kharlamov, Shuang Zhai, Sofia Trinh, Vaibhav Jain
In-Reply-To: <CAFbkSA3jdtDrWz9-i2ZED5k8uBx6nwrikSO6x22qGeWqj8bgHg@mail.gmail.com>
On Sat, Apr 16, 2022 at 10:32 AM Justin Forbes
<jforbes@fedoraproject.org> wrote:
>
> On Fri, Apr 15, 2022 at 4:33 PM Andrew Morton <akpm@linux-foundation.org> wrote:
> >
> > On Fri, 15 Apr 2022 14:11:32 -0600 Yu Zhao <yuzhao@google.com> wrote:
> >
> > > >
> > > > I grabbed
> > > > https://kojipkgs.fedoraproject.org//packages/kernel/5.18.0/0.rc2.23.fc37/src/kernel-5.18.0-0.rc2.23.fc37.src.rpm
> > > > and
> > >
> > > Yes, Fedora/RHEL is one concrete example of the model I mentioned
> > > above (experimental/stable). I added Justin, the Fedora kernel
> > > maintainer, and he can further clarify.
>
> We almost split into 3 scenarios. In rawhide we run a standard Fedora
> config for rcX releases and .0, but git snapshots are built with debug
> configs only. The trade off is that we can't turn on certain options
> which kill performance, but we do get more users running these kernels
> which expose real bugs. The rawhide kernel follows Linus' tree and is
> rebuilt most weekdays. Stable Fedora is not a full debug config, but
> in cases where we can keep a debug feature on without it much getting
> in the way of performance, as is the case with CONFIG_DEBUG_VM, I
> think there is value in keeping those on, until there is not. And of
> course RHEL is a much more conservative config, and a much more
> conservative rebase/backport codebase.
>
> > > If we don't want more VM_BUG_ONs, I'll remove them. But (let me
> > > reiterate) it seems to me that just defeats the purpose of having
> > > CONFIG_DEBUG_VM.
> > >
> >
> > Well, I feel your pain. It was never expected that VM_BUG_ON() would
> > get subverted in this fashion.
>
> Fedora is not trying to subvert anything. If keeping the option on
> becomes problematic, we can simply turn it off. Fedora certainly has
> a more diverse installed base than typical enterprise distributions,
> and much more diverse than most QA pools. Both in the array of
> hardware, and in the use patterns, so things do get uncovered that
> would not be seen otherwise.
>
> > We could create a new MM-developer-only assertion. Might even call it
> > MM_BUG_ON(). With compile-time enablement but perhaps not a runtime
> > switch.
> >
> > With nice simple semantics, please. Like "it returns void" and "if you
> > pass an expression with side-effects then you lose". And "if you send
> > a patch which produces warnings when CONFIG_MM_BUG_ON=n then you get to
> > switch to windows95 for a month".
> >
> > Let's leave the mglru assertions in place for now and let's think about
> > creating something more suitable, with a view to switching mglru over
> > to that at a later time.
> >
> >
> >
> > But really, none of this addresses the core problem: *_BUG_ON() often
> > kills the kernel. So guess what we just did? We killed the user's
> > kernel at the exact time when we least wished to do so: when they have
> > a bug to report to us. So the thing is self-defeating.
> >
> > It's much much better to WARN and to attempt to continue. This makes
> > it much more likely that we'll get to hear about the kernel flaw.
>
> I agree very much with this. We hear about warnings from users, they
> don't go unnoticed, and several of these users are willing to spend
> time to help get to the bottom of an issue. They may not know the
> code, but plenty are willing to test various patches or scenarios.
Thanks, Justin. Glad to hear warnings are collected from the field.
Based on all the feedback, my action item is to replace all VM_BUG_ONs
with VM_WARN_ON_ONCEs.
_______________________________________________
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 6/6] dt-bindings: pinctrl: convert ocelot-pinctrl to YAML format
From: Linus Walleij @ 2022-04-19 22:33 UTC (permalink / raw)
To: Michael Walle
Cc: devicetree, Thomas Bogendoerfer, linux-mips, Quentin Schulz,
Paul Burton, linux-kernel, Gregory CLEMENT, Krzysztof Kozlowski,
David S . Miller, linux-gpio, Rob Herring, linux-arm-kernel,
Kavyasree Kotagiri, Antoine Tenart, UNGLinuxDriver,
Steen Hegelund, Lars Povlsen
In-Reply-To: <735863d6476605e4ff72032d8971ac0d@walle.cc>
On Mon, Apr 18, 2022 at 2:04 PM Michael Walle <michael@walle.cc> wrote:
> Am 2022-04-18 13:13, schrieb Krzysztof Kozlowski:
> > I think you got all necessary acks for this pinctrl bindings change and
> > the dependency ("add reset property"), so both can go via Linus' tree.
> > That's preferred.
> >
> > DTS patches goes through your SoC maintainer tree.
>
> Ah, ok, I wasn't aware of that. Then yes, please go ahead and
> pick this and the first patch of [1] up, Linus.
I picked up this patch but:
> [1]
> https://lore.kernel.org/linux-gpio/20220313154640.63813-1-michael@walle.cc/
These patches don't apply to my tree. Please rebase on
the pinctrl "devel" branch and resend!
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git/log/?h=devel
Yours,
Linus Walleij
_______________________________________________
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/4] rockchip: support configuring pins as input
From: Linus Walleij @ 2022-04-19 22:37 UTC (permalink / raw)
To: Caleb Connolly
Cc: Rob Herring, Heiko Stuebner, Bartosz Golaszewski, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, linux-gpio,
~postmarketos/upstreaming, martijn, Arnaud Ferraris
In-Reply-To: <20220328005005.72492-1-kc@postmarketos.org>
Hi Caleb,
On Mon, Mar 28, 2022 at 2:50 AM Caleb Connolly <kc@postmarketos.org> wrote:
Caleb Connolly (4):
> pinctrl/rockchip: support deferring other gpio params
> pinctrl/rockchip: support setting input-enable param
> gpio/rockchip: handle deferring input-enable pinconfs
Those three applied to the pinctrl tree.
> arm64: dts: rockchip: rk3399: add an input enable pinconf
Please submit this through the SoC tree.
Yours,
Linus Walleij
_______________________________________________
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