0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <asm/cop2.h>
0010 #include <linux/export.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/sched/task_stack.h>
0013
0014 #include "octeon-crypto.h"
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 unsigned long octeon_crypto_enable(struct octeon_cop2_state *state)
0028 {
0029 int status;
0030 unsigned long flags;
0031
0032 preempt_disable();
0033 local_irq_save(flags);
0034 status = read_c0_status();
0035 write_c0_status(status | ST0_CU2);
0036 if (KSTK_STATUS(current) & ST0_CU2) {
0037 octeon_cop2_save(&(current->thread.cp2));
0038 KSTK_STATUS(current) &= ~ST0_CU2;
0039 status &= ~ST0_CU2;
0040 } else if (status & ST0_CU2) {
0041 octeon_cop2_save(state);
0042 }
0043 local_irq_restore(flags);
0044 return status & ST0_CU2;
0045 }
0046 EXPORT_SYMBOL_GPL(octeon_crypto_enable);
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 void octeon_crypto_disable(struct octeon_cop2_state *state,
0057 unsigned long crypto_flags)
0058 {
0059 unsigned long flags;
0060
0061 local_irq_save(flags);
0062 if (crypto_flags & ST0_CU2)
0063 octeon_cop2_restore(state);
0064 else
0065 write_c0_status(read_c0_status() & ~ST0_CU2);
0066 local_irq_restore(flags);
0067 preempt_enable();
0068 }
0069 EXPORT_SYMBOL_GPL(octeon_crypto_disable);