hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
kernel/arch/arm/mm/cache-l2x0.c
....@@ -38,7 +38,7 @@
3838
3939 static void __iomem *l2x0_base;
4040 static const struct l2c_init_data *l2x0_data;
41
-static DEFINE_RAW_SPINLOCK(l2x0_lock);
41
+static DEFINE_HARD_SPINLOCK(l2x0_lock);
4242 static u32 l2x0_way_mask; /* Bitmask of active ways */
4343 static u32 l2x0_size;
4444 static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
....@@ -47,6 +47,19 @@
4747
4848 static bool l2x0_bresp_disable;
4949 static bool l2x0_flz_disable;
50
+
51
+#ifdef CONFIG_IRQ_PIPELINE
52
+#define CACHE_RANGE_ATOMIC_MAX 512UL
53
+static int l2x0_wa = -1;
54
+static int __init l2x0_setup_wa(char *str)
55
+{
56
+ l2x0_wa = !!simple_strtol(str, NULL, 0);
57
+ return 0;
58
+}
59
+early_param("l2x0_write_allocate", l2x0_setup_wa);
60
+#else
61
+#define CACHE_RANGE_ATOMIC_MAX 4096UL
62
+#endif
5063
5164 /*
5265 * Common code for all cache controllers.
....@@ -120,11 +133,11 @@
120133
121134 l2x0_data->unlock(base, num_lock);
122135
123
- local_irq_save(flags);
136
+ flags = hard_local_irq_save();
124137 __l2c_op_way(base + L2X0_INV_WAY);
125138 writel_relaxed(0, base + sync_reg_offset);
126139 l2c_wait_mask(base + sync_reg_offset, 1);
127
- local_irq_restore(flags);
140
+ hard_local_irq_restore(flags);
128141
129142 l2c_write_sec(L2X0_CTRL_EN, base, L2X0_CTRL);
130143 }
....@@ -225,7 +238,7 @@
225238 {
226239 void __iomem *base = l2x0_base;
227240
228
- BUG_ON(!irqs_disabled());
241
+ BUG_ON(!hard_irqs_disabled());
229242
230243 __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
231244 __l2c210_cache_sync(base);
....@@ -284,10 +297,10 @@
284297 static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start,
285298 unsigned long end, unsigned long flags)
286299 {
287
- raw_spinlock_t *lock = &l2x0_lock;
300
+ typeof(l2x0_lock) *lock = &l2x0_lock;
288301
289302 while (start < end) {
290
- unsigned long blk_end = start + min(end - start, 4096UL);
303
+ unsigned long blk_end = start + min(end - start, CACHE_RANGE_ATOMIC_MAX);
291304
292305 while (start < blk_end) {
293306 l2c_wait_mask(reg, 1);
....@@ -498,13 +511,13 @@
498511
499512 static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
500513 {
501
- raw_spinlock_t *lock = &l2x0_lock;
514
+ typeof(l2x0_lock) *lock = &l2x0_lock;
502515 unsigned long flags;
503516 void __iomem *base = l2x0_base;
504517
505518 raw_spin_lock_irqsave(lock, flags);
506519 while (start < end) {
507
- unsigned long blk_end = start + min(end - start, 4096UL);
520
+ unsigned long blk_end = start + min(end - start, CACHE_RANGE_ATOMIC_MAX);
508521
509522 l2c_set_debug(base, 0x03);
510523 while (start < blk_end) {
....@@ -800,6 +813,24 @@
800813 if (aux_val & aux_mask)
801814 pr_alert("L2C: platform provided aux values permit register corruption.\n");
802815
816
+#ifdef CONFIG_IRQ_PIPELINE
817
+ if (!l2x0_wa) {
818
+ /*
819
+ * Disable WA by setting bit 23 in the auxiliary
820
+ * control register.
821
+ */
822
+ aux_mask &= ~L220_AUX_CTRL_FWA_MASK;
823
+ aux_val &= ~L220_AUX_CTRL_FWA_MASK;
824
+ aux_val |= 1 << L220_AUX_CTRL_FWA_SHIFT;
825
+ pr_warn("%s: irq_pipeline: write-allocate disabled via command line\n",
826
+ data->type);
827
+ } else if ((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L220 ||
828
+ ((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310 &&
829
+ (cache_id & L2X0_CACHE_ID_RTL_MASK) < L310_CACHE_ID_RTL_R3P2))
830
+ pr_alert("%s: irq_pipeline: write-allocate enabled, may induce high latency\n",
831
+ data->type);
832
+#endif
833
+
803834 old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
804835 aux &= aux_mask;
805836 aux |= aux_val;