#define CACHE_LINE_SIZE 32
static void __iomem *l2x0_base;
+static DEFINE_SPINLOCK(l2x0_lock);
static uint32_t l2x0_way_mask; /* Bitmask of active ways */
-bool l2x0_disabled;
-static inline void cache_wait_always(void __iomem *reg, unsigned long mask)
+static inline void cache_wait(void __iomem *reg, unsigned long mask)
{
/* wait for the operation to complete */
while (readl_relaxed(reg) & mask)
;
}
-#ifdef CONFIG_CACHE_PL310
-
-static inline void cache_wait(void __iomem *reg, unsigned long mask)
-{
- /* cache operations are atomic */
-}
-
-#define _l2x0_lock(lock, flags) ((void)(flags))
-#define _l2x0_unlock(lock, flags) ((void)(flags))
-
-#define block_end(start, end) (end)
-
-#define L2CC_TYPE "PL310/L2C-310"
-
-#else /* !CONFIG_CACHE_PL310 */
-
-#define cache_wait cache_wait_always
-
-static DEFINE_SPINLOCK(l2x0_lock);
-#define _l2x0_lock(lock, flags) spin_lock_irqsave(lock, flags)
-#define _l2x0_unlock(lock, flags) spin_unlock_irqrestore(lock, flags)
-
-#define block_end(start, end) ((start) + min((end) - (start), 4096UL))
-
-#define L2CC_TYPE "L2x0"
-
-#endif /* CONFIG_CACHE_PL310 */
-
static inline void cache_sync(void)
{
void __iomem *base = l2x0_base;
{
unsigned long flags;
- _l2x0_lock(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
cache_sync();
- _l2x0_unlock(&l2x0_lock, flags);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
}
static inline void l2x0_inv_all(void)
unsigned long flags;
/* invalidate all ways */
- _l2x0_lock(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
- cache_wait_always(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+ cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
cache_sync();
- _l2x0_unlock(&l2x0_lock, flags);
-}
-
-static inline void l2x0_flush_all(void)
-{
- unsigned long flags;
-
- /* flush all ways */
- _l2x0_lock(&l2x0_lock, flags);
- writel(0xff, l2x0_base + L2X0_CLEAN_INV_WAY);
- cache_wait_always(l2x0_base + L2X0_CLEAN_INV_WAY, 0xff);
- cache_sync();
- _l2x0_unlock(&l2x0_lock, flags);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
}
static void l2x0_inv_range(unsigned long start, unsigned long end)
void __iomem *base = l2x0_base;
unsigned long flags;
- _l2x0_lock(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
if (start & (CACHE_LINE_SIZE - 1)) {
start &= ~(CACHE_LINE_SIZE - 1);
debug_writel(0x03);
}
while (start < end) {
- unsigned long blk_end = block_end(start, end);
+ unsigned long blk_end = start + min(end - start, 4096UL);
while (start < blk_end) {
l2x0_inv_line(start);
}
if (blk_end < end) {
- _l2x0_unlock(&l2x0_lock, flags);
- _l2x0_lock(&l2x0_lock, flags);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
}
}
cache_wait(base + L2X0_INV_LINE_PA, 1);
cache_sync();
- _l2x0_unlock(&l2x0_lock, flags);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
}
static void l2x0_clean_range(unsigned long start, unsigned long end)
void __iomem *base = l2x0_base;
unsigned long flags;
- _l2x0_lock(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
- unsigned long blk_end = block_end(start, end);
+ unsigned long blk_end = start + min(end - start, 4096UL);
while (start < blk_end) {
l2x0_clean_line(start);
}
if (blk_end < end) {
- _l2x0_unlock(&l2x0_lock, flags);
- _l2x0_lock(&l2x0_lock, flags);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
}
}
cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
cache_sync();
- _l2x0_unlock(&l2x0_lock, flags);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
}
static void l2x0_flush_range(unsigned long start, unsigned long end)
void __iomem *base = l2x0_base;
unsigned long flags;
- _l2x0_lock(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
- unsigned long blk_end = block_end(start, end);
+ unsigned long blk_end = start + min(end - start, 4096UL);
debug_writel(0x03);
while (start < blk_end) {
debug_writel(0x00);
if (blk_end < end) {
- _l2x0_unlock(&l2x0_lock, flags);
- _l2x0_lock(&l2x0_lock, flags);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
}
}
cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
cache_sync();
- _l2x0_unlock(&l2x0_lock, flags);
+ spin_unlock_irqrestore(&l2x0_lock, flags);
}
-void l2x0_shutdown(void)
-{
- unsigned long flags;
-
- if (l2x0_disabled)
- return;
-
- BUG_ON(num_online_cpus() > 1);
-
- local_irq_save(flags);
-
- if (readl(l2x0_base + L2X0_CTRL) & 1) {
- int m;
- /* lockdown all ways, all masters to prevent new line
- * allocation during maintenance */
- for (m=0; m<8; m++) {
- writel(l2x0_way_mask,
- l2x0_base + L2X0_LOCKDOWN_WAY_D + (m*8));
- writel(l2x0_way_mask,
- l2x0_base + L2X0_LOCKDOWN_WAY_I + (m*8));
- }
- l2x0_flush_all();
- writel(0, l2x0_base + L2X0_CTRL);
- /* unlock cache ways */
- for (m=0; m<8; m++) {
- writel(0, l2x0_base + L2X0_LOCKDOWN_WAY_D + (m*8));
- writel(0, l2x0_base + L2X0_LOCKDOWN_WAY_I + (m*8));
- }
- }
-
- local_irq_restore(flags);
-}
-
-static void l2x0_enable(__u32 aux_val, __u32 aux_mask)
+void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
{
__u32 aux;
__u32 cache_id;
int ways;
const char *type;
- if (l2x0_disabled)
- return;
+ l2x0_base = base;
cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
writel_relaxed(1, l2x0_base + L2X0_CTRL);
}
- /*printk(KERN_INFO "%s cache controller enabled\n", type);
- printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
- ways, cache_id, aux);*/
-}
-
-void l2x0_restart(void)
-{
- l2x0_enable(0, ~0ul);
-}
-
-void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
-{
- if (l2x0_disabled) {
- pr_info(L2CC_TYPE " cache controller disabled\n");
- return;
- }
-
- l2x0_base = base;
-
- l2x0_enable(aux_val, aux_mask);
-
outer_cache.inv_range = l2x0_inv_range;
outer_cache.clean_range = l2x0_clean_range;
outer_cache.flush_range = l2x0_flush_range;
outer_cache.sync = l2x0_cache_sync;
-}
-static int __init l2x0_disable(char *unused)
-{
- l2x0_disabled = 1;
- return 0;
+ printk(KERN_INFO "%s cache controller enabled\n", type);
+ printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
+ ways, cache_id, aux);
}
-early_param("nol2x0", l2x0_disable);