1/** 2 * \file 3 * \brief kernel driver for the spinlock module, used for serial output 4 * see OMAP4460 TRM chapter 21 for a functional description 5 */ 6 7/* 8 * Copyright (c) 2013, ETH Zurich. 9 * All rights reserved. 10 * 11 * This file is distributed under the terms in the attached LICENSE file. 12 * If you do not find this file, copies can be found by writing to: 13 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 14 */ 15 16#include <kernel.h> 17#include <paging_kernel_arch.h> 18#include <omap44xx_spinlock.h> 19#include <dev/omap/omap44xx_spinlock_dev.h> 20#include <maps/omap44xx_map.h> 21 22 23#define MSG(format, ...) printk( LOG_NOTE, "OMAP44xx spinlock: "format, ## __VA_ARGS__ ) 24 25static omap44xx_spinlock_t spinlock; 26static bool locks_initialized; //allows early initialization 27 28/** 29 * \brief Map the OMAP44xx spinlock device into kernel virtual memory 30 * and reset it. 31 */ 32 33errval_t omap44xx_spinlock_init(void) 34{ 35 if (locks_initialized) { 36 MSG("already initialized; skipping.\n"); 37 return SYS_ERR_OK; 38 } 39 40 lvaddr_t base = paging_map_device(OMAP44XX_MAP_L4_CFG_SPINLOCK, 41 OMAP44XX_MAP_L4_CFG_SPINLOCK_SIZE); 42 MSG("init base = 0x%"PRIxLVADDR"\n", base); 43 omap44xx_spinlock_initialize(&spinlock, (mackerel_addr_t)base); 44 45 // This next line to rest the module is probably not needed. 46 omap44xx_spinlock_sysconfig_softreset_wrf(&spinlock, 1); 47 48 MSG("testing spinlock: first read (should be 0): 0x%x\n", 49 omap44xx_spinlock_lock_reg_i_taken_rdf(&spinlock, 2)); 50 51 MSG("testing spinlock: second read (should be 1): 0x%x\n", 52 omap44xx_spinlock_lock_reg_i_taken_rdf(&spinlock, 2)); 53 54 omap44xx_spinlock_lock_reg_i_taken_wrf(&spinlock, 2, 0);//clear lock 55 locks_initialized = true; 56 MSG("init done.\n"); 57 return SYS_ERR_OK; 58} 59 60/** 61 * \brief acquire an OMAP44xx spinlock. We repeatedly read the 62 * register; 0 means we have the lock, 1 means we have to try again. 63 */ 64void omap44xx_spinlock_acquire( unsigned locknumber ) { 65 assert( locknumber < OMAP44XX_SPINLOCK_NUM_LOCKS ); 66 while( omap44xx_spinlock_lock_reg_i_taken_rdf(&spinlock, locknumber)) { } 67} 68 69/** 70 * \brief release an OMAP44xx spinlock. 71 */ 72void omap44xx_spinlock_release( unsigned locknumber ) { 73 assert( locknumber < OMAP44XX_SPINLOCK_NUM_LOCKS ); 74 omap44xx_spinlock_lock_reg_i_taken_wrf(&spinlock, locknumber, 0); 75} 76 77