.. | .. |
---|
38 | 38 | |
---|
39 | 39 | static void __iomem *l2x0_base; |
---|
40 | 40 | static const struct l2c_init_data *l2x0_data; |
---|
41 | | -static DEFINE_RAW_SPINLOCK(l2x0_lock); |
---|
| 41 | +static DEFINE_HARD_SPINLOCK(l2x0_lock); |
---|
42 | 42 | static u32 l2x0_way_mask; /* Bitmask of active ways */ |
---|
43 | 43 | static u32 l2x0_size; |
---|
44 | 44 | static unsigned long sync_reg_offset = L2X0_CACHE_SYNC; |
---|
.. | .. |
---|
47 | 47 | |
---|
48 | 48 | static bool l2x0_bresp_disable; |
---|
49 | 49 | 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 |
---|
50 | 63 | |
---|
51 | 64 | /* |
---|
52 | 65 | * Common code for all cache controllers. |
---|
.. | .. |
---|
120 | 133 | |
---|
121 | 134 | l2x0_data->unlock(base, num_lock); |
---|
122 | 135 | |
---|
123 | | - local_irq_save(flags); |
---|
| 136 | + flags = hard_local_irq_save(); |
---|
124 | 137 | __l2c_op_way(base + L2X0_INV_WAY); |
---|
125 | 138 | writel_relaxed(0, base + sync_reg_offset); |
---|
126 | 139 | l2c_wait_mask(base + sync_reg_offset, 1); |
---|
127 | | - local_irq_restore(flags); |
---|
| 140 | + hard_local_irq_restore(flags); |
---|
128 | 141 | |
---|
129 | 142 | l2c_write_sec(L2X0_CTRL_EN, base, L2X0_CTRL); |
---|
130 | 143 | } |
---|
.. | .. |
---|
225 | 238 | { |
---|
226 | 239 | void __iomem *base = l2x0_base; |
---|
227 | 240 | |
---|
228 | | - BUG_ON(!irqs_disabled()); |
---|
| 241 | + BUG_ON(!hard_irqs_disabled()); |
---|
229 | 242 | |
---|
230 | 243 | __l2c_op_way(base + L2X0_CLEAN_INV_WAY); |
---|
231 | 244 | __l2c210_cache_sync(base); |
---|
.. | .. |
---|
284 | 297 | static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long start, |
---|
285 | 298 | unsigned long end, unsigned long flags) |
---|
286 | 299 | { |
---|
287 | | - raw_spinlock_t *lock = &l2x0_lock; |
---|
| 300 | + typeof(l2x0_lock) *lock = &l2x0_lock; |
---|
288 | 301 | |
---|
289 | 302 | 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); |
---|
291 | 304 | |
---|
292 | 305 | while (start < blk_end) { |
---|
293 | 306 | l2c_wait_mask(reg, 1); |
---|
.. | .. |
---|
498 | 511 | |
---|
499 | 512 | static void l2c310_flush_range_erratum(unsigned long start, unsigned long end) |
---|
500 | 513 | { |
---|
501 | | - raw_spinlock_t *lock = &l2x0_lock; |
---|
| 514 | + typeof(l2x0_lock) *lock = &l2x0_lock; |
---|
502 | 515 | unsigned long flags; |
---|
503 | 516 | void __iomem *base = l2x0_base; |
---|
504 | 517 | |
---|
505 | 518 | raw_spin_lock_irqsave(lock, flags); |
---|
506 | 519 | 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); |
---|
508 | 521 | |
---|
509 | 522 | l2c_set_debug(base, 0x03); |
---|
510 | 523 | while (start < blk_end) { |
---|
.. | .. |
---|
800 | 813 | if (aux_val & aux_mask) |
---|
801 | 814 | pr_alert("L2C: platform provided aux values permit register corruption.\n"); |
---|
802 | 815 | |
---|
| 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 | + |
---|
803 | 834 | old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); |
---|
804 | 835 | aux &= aux_mask; |
---|
805 | 836 | aux |= aux_val; |
---|