162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Broadcom Brahma-B15 CPU read-ahead cache management functions 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015-2016 Broadcom 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/err.h> 962306a36Sopenharmony_ci#include <linux/spinlock.h> 1062306a36Sopenharmony_ci#include <linux/io.h> 1162306a36Sopenharmony_ci#include <linux/bitops.h> 1262306a36Sopenharmony_ci#include <linux/of_address.h> 1362306a36Sopenharmony_ci#include <linux/notifier.h> 1462306a36Sopenharmony_ci#include <linux/cpu.h> 1562306a36Sopenharmony_ci#include <linux/syscore_ops.h> 1662306a36Sopenharmony_ci#include <linux/reboot.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <asm/cacheflush.h> 1962306a36Sopenharmony_ci#include <asm/hardware/cache-b15-rac.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciextern void v7_flush_kern_cache_all(void); 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* RAC register offsets, relative to the HIF_CPU_BIUCTRL register base */ 2462306a36Sopenharmony_ci#define RAC_CONFIG0_REG (0x78) 2562306a36Sopenharmony_ci#define RACENPREF_MASK (0x3) 2662306a36Sopenharmony_ci#define RACPREFINST_SHIFT (0) 2762306a36Sopenharmony_ci#define RACENINST_SHIFT (2) 2862306a36Sopenharmony_ci#define RACPREFDATA_SHIFT (4) 2962306a36Sopenharmony_ci#define RACENDATA_SHIFT (6) 3062306a36Sopenharmony_ci#define RAC_CPU_SHIFT (8) 3162306a36Sopenharmony_ci#define RACCFG_MASK (0xff) 3262306a36Sopenharmony_ci#define RAC_CONFIG1_REG (0x7c) 3362306a36Sopenharmony_ci/* Brahma-B15 is a quad-core only design */ 3462306a36Sopenharmony_ci#define B15_RAC_FLUSH_REG (0x80) 3562306a36Sopenharmony_ci/* Brahma-B53 is an octo-core design */ 3662306a36Sopenharmony_ci#define B53_RAC_FLUSH_REG (0x84) 3762306a36Sopenharmony_ci#define FLUSH_RAC (1 << 0) 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* Bitmask to enable instruction and data prefetching with a 256-bytes stride */ 4062306a36Sopenharmony_ci#define RAC_DATA_INST_EN_MASK (1 << RACPREFINST_SHIFT | \ 4162306a36Sopenharmony_ci RACENPREF_MASK << RACENINST_SHIFT | \ 4262306a36Sopenharmony_ci 1 << RACPREFDATA_SHIFT | \ 4362306a36Sopenharmony_ci RACENPREF_MASK << RACENDATA_SHIFT) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define RAC_ENABLED 0 4662306a36Sopenharmony_ci/* Special state where we want to bypass the spinlock and call directly 4762306a36Sopenharmony_ci * into the v7 cache maintenance operations during suspend/resume 4862306a36Sopenharmony_ci */ 4962306a36Sopenharmony_ci#define RAC_SUSPENDED 1 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic void __iomem *b15_rac_base; 5262306a36Sopenharmony_cistatic DEFINE_SPINLOCK(rac_lock); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic u32 rac_config0_reg; 5562306a36Sopenharmony_cistatic u32 rac_flush_offset; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci/* Initialization flag to avoid checking for b15_rac_base, and to prevent 5862306a36Sopenharmony_ci * multi-platform kernels from crashing here as well. 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_cistatic unsigned long b15_rac_flags; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistatic inline u32 __b15_rac_disable(void) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci u32 val = __raw_readl(b15_rac_base + RAC_CONFIG0_REG); 6562306a36Sopenharmony_ci __raw_writel(0, b15_rac_base + RAC_CONFIG0_REG); 6662306a36Sopenharmony_ci dmb(); 6762306a36Sopenharmony_ci return val; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic inline void __b15_rac_flush(void) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci u32 reg; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci __raw_writel(FLUSH_RAC, b15_rac_base + rac_flush_offset); 7562306a36Sopenharmony_ci do { 7662306a36Sopenharmony_ci /* This dmb() is required to force the Bus Interface Unit 7762306a36Sopenharmony_ci * to clean outstanding writes, and forces an idle cycle 7862306a36Sopenharmony_ci * to be inserted. 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_ci dmb(); 8162306a36Sopenharmony_ci reg = __raw_readl(b15_rac_base + rac_flush_offset); 8262306a36Sopenharmony_ci } while (reg & FLUSH_RAC); 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic inline u32 b15_rac_disable_and_flush(void) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci u32 reg; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci reg = __b15_rac_disable(); 9062306a36Sopenharmony_ci __b15_rac_flush(); 9162306a36Sopenharmony_ci return reg; 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic inline void __b15_rac_enable(u32 val) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci __raw_writel(val, b15_rac_base + RAC_CONFIG0_REG); 9762306a36Sopenharmony_ci /* dsb() is required here to be consistent with __flush_icache_all() */ 9862306a36Sopenharmony_ci dsb(); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#define BUILD_RAC_CACHE_OP(name, bar) \ 10262306a36Sopenharmony_civoid b15_flush_##name(void) \ 10362306a36Sopenharmony_ci{ \ 10462306a36Sopenharmony_ci unsigned int do_flush; \ 10562306a36Sopenharmony_ci u32 val = 0; \ 10662306a36Sopenharmony_ci \ 10762306a36Sopenharmony_ci if (test_bit(RAC_SUSPENDED, &b15_rac_flags)) { \ 10862306a36Sopenharmony_ci v7_flush_##name(); \ 10962306a36Sopenharmony_ci bar; \ 11062306a36Sopenharmony_ci return; \ 11162306a36Sopenharmony_ci } \ 11262306a36Sopenharmony_ci \ 11362306a36Sopenharmony_ci spin_lock(&rac_lock); \ 11462306a36Sopenharmony_ci do_flush = test_bit(RAC_ENABLED, &b15_rac_flags); \ 11562306a36Sopenharmony_ci if (do_flush) \ 11662306a36Sopenharmony_ci val = b15_rac_disable_and_flush(); \ 11762306a36Sopenharmony_ci v7_flush_##name(); \ 11862306a36Sopenharmony_ci if (!do_flush) \ 11962306a36Sopenharmony_ci bar; \ 12062306a36Sopenharmony_ci else \ 12162306a36Sopenharmony_ci __b15_rac_enable(val); \ 12262306a36Sopenharmony_ci spin_unlock(&rac_lock); \ 12362306a36Sopenharmony_ci} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci#define nobarrier 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci/* The readahead cache present in the Brahma-B15 CPU is a special piece of 12862306a36Sopenharmony_ci * hardware after the integrated L2 cache of the B15 CPU complex whose purpose 12962306a36Sopenharmony_ci * is to prefetch instruction and/or data with a line size of either 64 bytes 13062306a36Sopenharmony_ci * or 256 bytes. The rationale is that the data-bus of the CPU interface is 13162306a36Sopenharmony_ci * optimized for 256-bytes transactions, and enabling the readahead cache 13262306a36Sopenharmony_ci * provides a significant performance boost we want it enabled (typically 13362306a36Sopenharmony_ci * twice the performance for a memcpy benchmark application). 13462306a36Sopenharmony_ci * 13562306a36Sopenharmony_ci * The readahead cache is transparent for Modified Virtual Addresses 13662306a36Sopenharmony_ci * cache maintenance operations: ICIMVAU, DCIMVAC, DCCMVAC, DCCMVAU and 13762306a36Sopenharmony_ci * DCCIMVAC. 13862306a36Sopenharmony_ci * 13962306a36Sopenharmony_ci * It is however not transparent for the following cache maintenance 14062306a36Sopenharmony_ci * operations: DCISW, DCCSW, DCCISW, ICIALLUIS and ICIALLU which is precisely 14162306a36Sopenharmony_ci * what we are patching here with our BUILD_RAC_CACHE_OP here. 14262306a36Sopenharmony_ci */ 14362306a36Sopenharmony_ciBUILD_RAC_CACHE_OP(kern_cache_all, nobarrier); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic void b15_rac_enable(void) 14662306a36Sopenharmony_ci{ 14762306a36Sopenharmony_ci unsigned int cpu; 14862306a36Sopenharmony_ci u32 enable = 0; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci for_each_possible_cpu(cpu) 15162306a36Sopenharmony_ci enable |= (RAC_DATA_INST_EN_MASK << (cpu * RAC_CPU_SHIFT)); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci b15_rac_disable_and_flush(); 15462306a36Sopenharmony_ci __b15_rac_enable(enable); 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_cistatic int b15_rac_reboot_notifier(struct notifier_block *nb, 15862306a36Sopenharmony_ci unsigned long action, 15962306a36Sopenharmony_ci void *data) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci /* During kexec, we are not yet migrated on the boot CPU, so we need to 16262306a36Sopenharmony_ci * make sure we are SMP safe here. Once the RAC is disabled, flag it as 16362306a36Sopenharmony_ci * suspended such that the hotplug notifier returns early. 16462306a36Sopenharmony_ci */ 16562306a36Sopenharmony_ci if (action == SYS_RESTART) { 16662306a36Sopenharmony_ci spin_lock(&rac_lock); 16762306a36Sopenharmony_ci b15_rac_disable_and_flush(); 16862306a36Sopenharmony_ci clear_bit(RAC_ENABLED, &b15_rac_flags); 16962306a36Sopenharmony_ci set_bit(RAC_SUSPENDED, &b15_rac_flags); 17062306a36Sopenharmony_ci spin_unlock(&rac_lock); 17162306a36Sopenharmony_ci } 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci return NOTIFY_DONE; 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic struct notifier_block b15_rac_reboot_nb = { 17762306a36Sopenharmony_ci .notifier_call = b15_rac_reboot_notifier, 17862306a36Sopenharmony_ci}; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci/* The CPU hotplug case is the most interesting one, we basically need to make 18162306a36Sopenharmony_ci * sure that the RAC is disabled for the entire system prior to having a CPU 18262306a36Sopenharmony_ci * die, in particular prior to this dying CPU having exited the coherency 18362306a36Sopenharmony_ci * domain. 18462306a36Sopenharmony_ci * 18562306a36Sopenharmony_ci * Once this CPU is marked dead, we can safely re-enable the RAC for the 18662306a36Sopenharmony_ci * remaining CPUs in the system which are still online. 18762306a36Sopenharmony_ci * 18862306a36Sopenharmony_ci * Offlining a CPU is the problematic case, onlining a CPU is not much of an 18962306a36Sopenharmony_ci * issue since the CPU and its cache-level hierarchy will start filling with 19062306a36Sopenharmony_ci * the RAC disabled, so L1 and L2 only. 19162306a36Sopenharmony_ci * 19262306a36Sopenharmony_ci * In this function, we should NOT have to verify any unsafe setting/condition 19362306a36Sopenharmony_ci * b15_rac_base: 19462306a36Sopenharmony_ci * 19562306a36Sopenharmony_ci * It is protected by the RAC_ENABLED flag which is cleared by default, and 19662306a36Sopenharmony_ci * being cleared when initial procedure is done. b15_rac_base had been set at 19762306a36Sopenharmony_ci * that time. 19862306a36Sopenharmony_ci * 19962306a36Sopenharmony_ci * RAC_ENABLED: 20062306a36Sopenharmony_ci * There is a small timing windows, in b15_rac_init(), between 20162306a36Sopenharmony_ci * cpuhp_setup_state_*() 20262306a36Sopenharmony_ci * ... 20362306a36Sopenharmony_ci * set RAC_ENABLED 20462306a36Sopenharmony_ci * However, there is no hotplug activity based on the Linux booting procedure. 20562306a36Sopenharmony_ci * 20662306a36Sopenharmony_ci * Since we have to disable RAC for all cores, we keep RAC on as long as as 20762306a36Sopenharmony_ci * possible (disable it as late as possible) to gain the cache benefit. 20862306a36Sopenharmony_ci * 20962306a36Sopenharmony_ci * Thus, dying/dead states are chosen here 21062306a36Sopenharmony_ci * 21162306a36Sopenharmony_ci * We are choosing not do disable the RAC on a per-CPU basis, here, if we did 21262306a36Sopenharmony_ci * we would want to consider disabling it as early as possible to benefit the 21362306a36Sopenharmony_ci * other active CPUs. 21462306a36Sopenharmony_ci */ 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci/* Running on the dying CPU */ 21762306a36Sopenharmony_cistatic int b15_rac_dying_cpu(unsigned int cpu) 21862306a36Sopenharmony_ci{ 21962306a36Sopenharmony_ci /* During kexec/reboot, the RAC is disabled via the reboot notifier 22062306a36Sopenharmony_ci * return early here. 22162306a36Sopenharmony_ci */ 22262306a36Sopenharmony_ci if (test_bit(RAC_SUSPENDED, &b15_rac_flags)) 22362306a36Sopenharmony_ci return 0; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci spin_lock(&rac_lock); 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci /* Indicate that we are starting a hotplug procedure */ 22862306a36Sopenharmony_ci __clear_bit(RAC_ENABLED, &b15_rac_flags); 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci /* Disable the readahead cache and save its value to a global */ 23162306a36Sopenharmony_ci rac_config0_reg = b15_rac_disable_and_flush(); 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci spin_unlock(&rac_lock); 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci return 0; 23662306a36Sopenharmony_ci} 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci/* Running on a non-dying CPU */ 23962306a36Sopenharmony_cistatic int b15_rac_dead_cpu(unsigned int cpu) 24062306a36Sopenharmony_ci{ 24162306a36Sopenharmony_ci /* During kexec/reboot, the RAC is disabled via the reboot notifier 24262306a36Sopenharmony_ci * return early here. 24362306a36Sopenharmony_ci */ 24462306a36Sopenharmony_ci if (test_bit(RAC_SUSPENDED, &b15_rac_flags)) 24562306a36Sopenharmony_ci return 0; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci spin_lock(&rac_lock); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci /* And enable it */ 25062306a36Sopenharmony_ci __b15_rac_enable(rac_config0_reg); 25162306a36Sopenharmony_ci __set_bit(RAC_ENABLED, &b15_rac_flags); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci spin_unlock(&rac_lock); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci return 0; 25662306a36Sopenharmony_ci} 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic int b15_rac_suspend(void) 25962306a36Sopenharmony_ci{ 26062306a36Sopenharmony_ci /* Suspend the read-ahead cache oeprations, forcing our cache 26162306a36Sopenharmony_ci * implementation to fallback to the regular ARMv7 calls. 26262306a36Sopenharmony_ci * 26362306a36Sopenharmony_ci * We are guaranteed to be running on the boot CPU at this point and 26462306a36Sopenharmony_ci * with every other CPU quiesced, so setting RAC_SUSPENDED is not racy 26562306a36Sopenharmony_ci * here. 26662306a36Sopenharmony_ci */ 26762306a36Sopenharmony_ci rac_config0_reg = b15_rac_disable_and_flush(); 26862306a36Sopenharmony_ci set_bit(RAC_SUSPENDED, &b15_rac_flags); 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci return 0; 27162306a36Sopenharmony_ci} 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cistatic void b15_rac_resume(void) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci /* Coming out of a S3 suspend/resume cycle, the read-ahead cache 27662306a36Sopenharmony_ci * register RAC_CONFIG0_REG will be restored to its default value, make 27762306a36Sopenharmony_ci * sure we re-enable it and set the enable flag, we are also guaranteed 27862306a36Sopenharmony_ci * to run on the boot CPU, so not racy again. 27962306a36Sopenharmony_ci */ 28062306a36Sopenharmony_ci __b15_rac_enable(rac_config0_reg); 28162306a36Sopenharmony_ci clear_bit(RAC_SUSPENDED, &b15_rac_flags); 28262306a36Sopenharmony_ci} 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_cistatic struct syscore_ops b15_rac_syscore_ops = { 28562306a36Sopenharmony_ci .suspend = b15_rac_suspend, 28662306a36Sopenharmony_ci .resume = b15_rac_resume, 28762306a36Sopenharmony_ci}; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic int __init b15_rac_init(void) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci struct device_node *dn, *cpu_dn; 29262306a36Sopenharmony_ci int ret = 0, cpu; 29362306a36Sopenharmony_ci u32 reg, en_mask = 0; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci dn = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl"); 29662306a36Sopenharmony_ci if (!dn) 29762306a36Sopenharmony_ci return -ENODEV; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci if (WARN(num_possible_cpus() > 4, "RAC only supports 4 CPUs\n")) 30062306a36Sopenharmony_ci goto out; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci b15_rac_base = of_iomap(dn, 0); 30362306a36Sopenharmony_ci if (!b15_rac_base) { 30462306a36Sopenharmony_ci pr_err("failed to remap BIU control base\n"); 30562306a36Sopenharmony_ci ret = -ENOMEM; 30662306a36Sopenharmony_ci goto out; 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci cpu_dn = of_get_cpu_node(0, NULL); 31062306a36Sopenharmony_ci if (!cpu_dn) { 31162306a36Sopenharmony_ci ret = -ENODEV; 31262306a36Sopenharmony_ci goto out; 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci if (of_device_is_compatible(cpu_dn, "brcm,brahma-b15")) 31662306a36Sopenharmony_ci rac_flush_offset = B15_RAC_FLUSH_REG; 31762306a36Sopenharmony_ci else if (of_device_is_compatible(cpu_dn, "brcm,brahma-b53")) 31862306a36Sopenharmony_ci rac_flush_offset = B53_RAC_FLUSH_REG; 31962306a36Sopenharmony_ci else { 32062306a36Sopenharmony_ci pr_err("Unsupported CPU\n"); 32162306a36Sopenharmony_ci of_node_put(cpu_dn); 32262306a36Sopenharmony_ci ret = -EINVAL; 32362306a36Sopenharmony_ci goto out; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci of_node_put(cpu_dn); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci ret = register_reboot_notifier(&b15_rac_reboot_nb); 32862306a36Sopenharmony_ci if (ret) { 32962306a36Sopenharmony_ci pr_err("failed to register reboot notifier\n"); 33062306a36Sopenharmony_ci iounmap(b15_rac_base); 33162306a36Sopenharmony_ci goto out; 33262306a36Sopenharmony_ci } 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) { 33562306a36Sopenharmony_ci ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DEAD, 33662306a36Sopenharmony_ci "arm/cache-b15-rac:dead", 33762306a36Sopenharmony_ci NULL, b15_rac_dead_cpu); 33862306a36Sopenharmony_ci if (ret) 33962306a36Sopenharmony_ci goto out_unmap; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DYING, 34262306a36Sopenharmony_ci "arm/cache-b15-rac:dying", 34362306a36Sopenharmony_ci NULL, b15_rac_dying_cpu); 34462306a36Sopenharmony_ci if (ret) 34562306a36Sopenharmony_ci goto out_cpu_dead; 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_PM_SLEEP)) 34962306a36Sopenharmony_ci register_syscore_ops(&b15_rac_syscore_ops); 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci spin_lock(&rac_lock); 35262306a36Sopenharmony_ci reg = __raw_readl(b15_rac_base + RAC_CONFIG0_REG); 35362306a36Sopenharmony_ci for_each_possible_cpu(cpu) 35462306a36Sopenharmony_ci en_mask |= ((1 << RACPREFDATA_SHIFT) << (cpu * RAC_CPU_SHIFT)); 35562306a36Sopenharmony_ci WARN(reg & en_mask, "Read-ahead cache not previously disabled\n"); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci b15_rac_enable(); 35862306a36Sopenharmony_ci set_bit(RAC_ENABLED, &b15_rac_flags); 35962306a36Sopenharmony_ci spin_unlock(&rac_lock); 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci pr_info("%pOF: Broadcom Brahma-B15 readahead cache\n", dn); 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci goto out; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ciout_cpu_dead: 36662306a36Sopenharmony_ci cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DYING); 36762306a36Sopenharmony_ciout_unmap: 36862306a36Sopenharmony_ci unregister_reboot_notifier(&b15_rac_reboot_nb); 36962306a36Sopenharmony_ci iounmap(b15_rac_base); 37062306a36Sopenharmony_ciout: 37162306a36Sopenharmony_ci of_node_put(dn); 37262306a36Sopenharmony_ci return ret; 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ciarch_initcall(b15_rac_init); 375