linux/arch/arm/kernel/pj4-cp0.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/kernel/pj4-cp0.c
   3 *
   4 * PJ4 iWMMXt coprocessor context switching and handling
   5 *
   6 * Copyright (c) 2010 Marvell International Inc.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/types.h>
  14#include <linux/kernel.h>
  15#include <linux/signal.h>
  16#include <linux/sched.h>
  17#include <linux/init.h>
  18#include <linux/io.h>
  19#include <asm/thread_notify.h>
  20
  21static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
  22{
  23        struct thread_info *thread = t;
  24
  25        switch (cmd) {
  26        case THREAD_NOTIFY_FLUSH:
  27                /*
  28                 * flush_thread() zeroes thread->fpstate, so no need
  29                 * to do anything here.
  30                 *
  31                 * FALLTHROUGH: Ensure we don't try to overwrite our newly
  32                 * initialised state information on the first fault.
  33                 */
  34
  35        case THREAD_NOTIFY_EXIT:
  36                iwmmxt_task_release(thread);
  37                break;
  38
  39        case THREAD_NOTIFY_SWITCH:
  40                iwmmxt_task_switch(thread);
  41                break;
  42        }
  43
  44        return NOTIFY_DONE;
  45}
  46
  47static struct notifier_block iwmmxt_notifier_block = {
  48        .notifier_call  = iwmmxt_do,
  49};
  50
  51
  52static u32 __init pj4_cp_access_read(void)
  53{
  54        u32 value;
  55
  56        __asm__ __volatile__ (
  57                "mrc    p15, 0, %0, c1, c0, 2\n\t"
  58                : "=r" (value));
  59        return value;
  60}
  61
  62static void __init pj4_cp_access_write(u32 value)
  63{
  64        u32 temp;
  65
  66        __asm__ __volatile__ (
  67                "mcr    p15, 0, %1, c1, c0, 2\n\t"
  68                "mrc    p15, 0, %0, c1, c0, 2\n\t"
  69                "mov    %0, %0\n\t"
  70                "sub    pc, pc, #4\n\t"
  71                : "=r" (temp) : "r" (value));
  72}
  73
  74
  75/*
  76 * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
  77 * switch code handle iWMMXt context switching.
  78 */
  79static int __init pj4_cp0_init(void)
  80{
  81        u32 cp_access;
  82
  83        cp_access = pj4_cp_access_read() & ~0xf;
  84        pj4_cp_access_write(cp_access);
  85
  86        printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n");
  87        elf_hwcap |= HWCAP_IWMMXT;
  88        thread_register_notifier(&iwmmxt_notifier_block);
  89
  90        return 0;
  91}
  92
  93late_initcall(pj4_cp0_init);
  94