In Commit a8f5738779a9 ("drm/panthor: Pass an iomem pointer to GPU
register access helpers"), the gpu register access helpers were changed
from taking a pointer to a struct panthor_device in their first
argument, to taking a void pointer.

This can cause problems, as patches based on panthor before this change
will still compile fine after it. struct panthor_device * implicitly
casts to a void pointer, resulting in completely wrong semantics.

Prevent this problem by wrapping the affected functions with macros that
specifically check for and reject the struct panthor_device * type as
the first argument.

Signed-off-by: Nicolas Frattaroli <[email protected]>
---
 drivers/gpu/drm/panthor/panthor_device.h | 68 +++++++++++++++++++++++++-------
 1 file changed, 53 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/panthor/panthor_device.h 
b/drivers/gpu/drm/panthor/panthor_device.h
index 4e4607bca7cc..91e9f499bf69 100644
--- a/drivers/gpu/drm/panthor/panthor_device.h
+++ b/drivers/gpu/drm/panthor/panthor_device.h
@@ -630,49 +630,87 @@ static inline void panthor_ ## __name ## 
_irq_disable_events(struct panthor_irq
 
 extern struct workqueue_struct *panthor_cleanup_wq;
 
-static inline void gpu_write(void __iomem *iomem, u32 reg, u32 data)
+static inline void _gpu_write(void __iomem *iomem, u32 reg, u32 data)
 {
        writel(data, iomem + reg);
 }
 
-static inline u32 gpu_read(void __iomem *iomem, u32 reg)
+static inline u32 _gpu_read(void __iomem *iomem, u32 reg)
 {
        return readl(iomem + reg);
 }
 
-static inline u32 gpu_read_relaxed(void __iomem *iomem, u32 reg)
+static inline u32 _gpu_read_relaxed(void __iomem *iomem, u32 reg)
 {
        return readl_relaxed(iomem + reg);
 }
 
-static inline void gpu_write64(void __iomem *iomem, u32 reg, u64 data)
+/*
+ * The function signature of gpu_read/gpu_write/gpu_read_relaxed/... used to
+ * take a &struct panthor_device* as the first parameter. During the split of
+ * iomem ranges into individual sub-components, this was changed to take a
+ * void __iomem* instead. These wrappers exists Tto avoid situations wherein
+ * pre-refactor patches are applied in error, as they'd compile fine. That's
+ * because the old calling convention's first parameter implicitly casts to a
+ * void pointer.
+ */
+
+#define gpu_write(iomem, reg, data) ({                                 \
+       static_assert(!__same_type((iomem), struct panthor_device *));  \
+       _gpu_write((iomem), (reg), (data)); })
+
+#define gpu_read(iomem, reg) ({                                                
\
+       static_assert(!__same_type((iomem), struct panthor_device *));  \
+       _gpu_read((iomem), (reg)); })
+
+#define gpu_read_relaxed(iomem, reg) ({                                        
\
+       static_assert(!__same_type((iomem), struct panthor_device *));  \
+       _gpu_read_relaxed((iomem), (reg)); })
+
+static inline void _gpu_write64(void __iomem *iomem, u32 reg, u64 data)
 {
-       gpu_write(iomem, reg, lower_32_bits(data));
-       gpu_write(iomem, reg + 4, upper_32_bits(data));
+       _gpu_write(iomem, reg, lower_32_bits(data));
+       _gpu_write(iomem, reg + 4, upper_32_bits(data));
 }
 
-static inline u64 gpu_read64(void __iomem *iomem, u32 reg)
+#define gpu_write64(iomem, reg, data) ({                               \
+       static_assert(!__same_type((iomem), struct panthor_device *));  \
+       _gpu_write64((iomem), (reg), (data)); })
+
+static inline u64 _gpu_read64(void __iomem *iomem, u32 reg)
 {
-       return (gpu_read(iomem, reg) | ((u64)gpu_read(iomem, reg + 4) << 32));
+       return (_gpu_read(iomem, reg) | ((u64)_gpu_read(iomem, reg + 4) << 32));
 }
 
-static inline u64 gpu_read64_relaxed(void __iomem *iomem, u32 reg)
+#define gpu_read64(iomem, reg) ({                                      \
+       static_assert(!__same_type((iomem), struct panthor_device *));  \
+       _gpu_read64((iomem), (reg)); })
+
+static inline u64 _gpu_read64_relaxed(void __iomem *iomem, u32 reg)
 {
-       return (gpu_read_relaxed(iomem, reg) |
-               ((u64)gpu_read_relaxed(iomem, reg + 4) << 32));
+       return (_gpu_read_relaxed(iomem, reg) |
+               ((u64)_gpu_read_relaxed(iomem, reg + 4) << 32));
 }
 
-static inline u64 gpu_read64_counter(void __iomem *iomem, u32 reg)
+#define gpu_read64_relaxed(iomem, reg) ({                              \
+       static_assert(!__same_type((iomem), struct panthor_device *));  \
+       _gpu_read64_relaxed((iomem), (reg)); })
+
+static inline u64 _gpu_read64_counter(void __iomem *iomem, u32 reg)
 {
        u32 lo, hi1, hi2;
        do {
-               hi1 = gpu_read(iomem, reg + 4);
-               lo = gpu_read(iomem, reg);
-               hi2 = gpu_read(iomem, reg + 4);
+               hi1 = _gpu_read(iomem, reg + 4);
+               lo = _gpu_read(iomem, reg);
+               hi2 = _gpu_read(iomem, reg + 4);
        } while (hi1 != hi2);
        return lo | ((u64)hi2 << 32);
 }
 
+#define gpu_read64_counter(iomem, reg) ({                              \
+       static_assert(!__same_type((iomem), struct panthor_device *));  \
+       _gpu_read64_counter((iomem), (reg)); })
+
 #define gpu_read_poll_timeout(iomem, reg, val, cond, delay_us, timeout_us)     
\
        read_poll_timeout(gpu_read, val, cond, delay_us, timeout_us, false,     
\
                          iomem, reg)

---
base-commit: 3c253a3bef01b39d4640cfe3dfd38d8d5557ae0c
change-id: 20260508-panthor-gpu-read-type-7ac3fffd124c

Best regards,
--  
Nicolas Frattaroli <[email protected]>

Reply via email to