Blackfin arch: rename blackfin_sram.c to sram-alloc.c
rename blackfin_sram.c to sram-alloc.c (we know it is a blackfin file, since it is in arch/blackfin) - and there is no "driver" code in there, it is just an allocator/deallocator for L1 and L2 sram. Also fix a problem that checkpatch pointed out Signed-off-by: Robin Getz <rgetz@blackfin.uclinux.org> Signed-off-by: Bryan Wu <cooloney@kernel.org>
This commit is contained in:
809
arch/blackfin/mm/sram-alloc.c
Normal file
809
arch/blackfin/mm/sram-alloc.c
Normal file
@ -0,0 +1,809 @@
|
||||
/*
|
||||
* File: arch/blackfin/mm/sram-alloc.c
|
||||
* Based on:
|
||||
* Author:
|
||||
*
|
||||
* Created:
|
||||
* Description: SRAM allocator for Blackfin L1 and L2 memory
|
||||
*
|
||||
* Modified:
|
||||
* Copyright 2004-2008 Analog Devices Inc.
|
||||
*
|
||||
* Bugs: Enter bugs at http://blackfin.uclinux.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see the file COPYING, or write
|
||||
* to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <asm/blackfin.h>
|
||||
#include "blackfin_sram.h"
|
||||
|
||||
static spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock;
|
||||
static spinlock_t l2_sram_lock;
|
||||
|
||||
/* the data structure for L1 scratchpad and DATA SRAM */
|
||||
struct sram_piece {
|
||||
void *paddr;
|
||||
int size;
|
||||
pid_t pid;
|
||||
struct sram_piece *next;
|
||||
};
|
||||
|
||||
static struct sram_piece free_l1_ssram_head, used_l1_ssram_head;
|
||||
|
||||
#if L1_DATA_A_LENGTH != 0
|
||||
static struct sram_piece free_l1_data_A_sram_head, used_l1_data_A_sram_head;
|
||||
#endif
|
||||
|
||||
#if L1_DATA_B_LENGTH != 0
|
||||
static struct sram_piece free_l1_data_B_sram_head, used_l1_data_B_sram_head;
|
||||
#endif
|
||||
|
||||
#if L1_CODE_LENGTH != 0
|
||||
static struct sram_piece free_l1_inst_sram_head, used_l1_inst_sram_head;
|
||||
#endif
|
||||
|
||||
#if L2_LENGTH != 0
|
||||
static struct sram_piece free_l2_sram_head, used_l2_sram_head;
|
||||
#endif
|
||||
|
||||
static struct kmem_cache *sram_piece_cache;
|
||||
|
||||
/* L1 Scratchpad SRAM initialization function */
|
||||
static void __init l1sram_init(void)
|
||||
{
|
||||
free_l1_ssram_head.next =
|
||||
kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
|
||||
if (!free_l1_ssram_head.next) {
|
||||
printk(KERN_INFO "Failed to initialize Scratchpad data SRAM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
free_l1_ssram_head.next->paddr = (void *)L1_SCRATCH_START;
|
||||
free_l1_ssram_head.next->size = L1_SCRATCH_LENGTH;
|
||||
free_l1_ssram_head.next->pid = 0;
|
||||
free_l1_ssram_head.next->next = NULL;
|
||||
|
||||
used_l1_ssram_head.next = NULL;
|
||||
|
||||
/* mutex initialize */
|
||||
spin_lock_init(&l1sram_lock);
|
||||
|
||||
printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n",
|
||||
L1_SCRATCH_LENGTH >> 10);
|
||||
}
|
||||
|
||||
static void __init l1_data_sram_init(void)
|
||||
{
|
||||
#if L1_DATA_A_LENGTH != 0
|
||||
free_l1_data_A_sram_head.next =
|
||||
kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
|
||||
if (!free_l1_data_A_sram_head.next) {
|
||||
printk(KERN_INFO "Failed to initialize L1 Data A SRAM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
free_l1_data_A_sram_head.next->paddr =
|
||||
(void *)L1_DATA_A_START + (_ebss_l1 - _sdata_l1);
|
||||
free_l1_data_A_sram_head.next->size =
|
||||
L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1);
|
||||
free_l1_data_A_sram_head.next->pid = 0;
|
||||
free_l1_data_A_sram_head.next->next = NULL;
|
||||
|
||||
used_l1_data_A_sram_head.next = NULL;
|
||||
|
||||
printk(KERN_INFO "Blackfin L1 Data A SRAM: %d KB (%d KB free)\n",
|
||||
L1_DATA_A_LENGTH >> 10,
|
||||
free_l1_data_A_sram_head.next->size >> 10);
|
||||
#endif
|
||||
#if L1_DATA_B_LENGTH != 0
|
||||
free_l1_data_B_sram_head.next =
|
||||
kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
|
||||
if (!free_l1_data_B_sram_head.next) {
|
||||
printk(KERN_INFO "Failed to initialize L1 Data B SRAM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
free_l1_data_B_sram_head.next->paddr =
|
||||
(void *)L1_DATA_B_START + (_ebss_b_l1 - _sdata_b_l1);
|
||||
free_l1_data_B_sram_head.next->size =
|
||||
L1_DATA_B_LENGTH - (_ebss_b_l1 - _sdata_b_l1);
|
||||
free_l1_data_B_sram_head.next->pid = 0;
|
||||
free_l1_data_B_sram_head.next->next = NULL;
|
||||
|
||||
used_l1_data_B_sram_head.next = NULL;
|
||||
|
||||
printk(KERN_INFO "Blackfin L1 Data B SRAM: %d KB (%d KB free)\n",
|
||||
L1_DATA_B_LENGTH >> 10,
|
||||
free_l1_data_B_sram_head.next->size >> 10);
|
||||
#endif
|
||||
|
||||
/* mutex initialize */
|
||||
spin_lock_init(&l1_data_sram_lock);
|
||||
}
|
||||
|
||||
static void __init l1_inst_sram_init(void)
|
||||
{
|
||||
#if L1_CODE_LENGTH != 0
|
||||
free_l1_inst_sram_head.next =
|
||||
kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
|
||||
if (!free_l1_inst_sram_head.next) {
|
||||
printk(KERN_INFO "Failed to initialize L1 Instruction SRAM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
free_l1_inst_sram_head.next->paddr =
|
||||
(void *)L1_CODE_START + (_etext_l1 - _stext_l1);
|
||||
free_l1_inst_sram_head.next->size =
|
||||
L1_CODE_LENGTH - (_etext_l1 - _stext_l1);
|
||||
free_l1_inst_sram_head.next->pid = 0;
|
||||
free_l1_inst_sram_head.next->next = NULL;
|
||||
|
||||
used_l1_inst_sram_head.next = NULL;
|
||||
|
||||
printk(KERN_INFO "Blackfin L1 Instruction SRAM: %d KB (%d KB free)\n",
|
||||
L1_CODE_LENGTH >> 10,
|
||||
free_l1_inst_sram_head.next->size >> 10);
|
||||
#endif
|
||||
|
||||
/* mutex initialize */
|
||||
spin_lock_init(&l1_inst_sram_lock);
|
||||
}
|
||||
|
||||
static void __init l2_sram_init(void)
|
||||
{
|
||||
#if L2_LENGTH != 0
|
||||
free_l2_sram_head.next =
|
||||
kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
|
||||
if (!free_l2_sram_head.next) {
|
||||
printk(KERN_INFO "Failed to initialize L2 SRAM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
free_l2_sram_head.next->paddr = (void *)L2_START +
|
||||
(_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2);
|
||||
free_l2_sram_head.next->size = L2_LENGTH -
|
||||
(_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2);
|
||||
free_l2_sram_head.next->pid = 0;
|
||||
free_l2_sram_head.next->next = NULL;
|
||||
|
||||
used_l2_sram_head.next = NULL;
|
||||
|
||||
printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n",
|
||||
L2_LENGTH >> 10,
|
||||
free_l2_sram_head.next->size >> 10);
|
||||
#endif
|
||||
|
||||
/* mutex initialize */
|
||||
spin_lock_init(&l2_sram_lock);
|
||||
}
|
||||
void __init bfin_sram_init(void)
|
||||
{
|
||||
sram_piece_cache = kmem_cache_create("sram_piece_cache",
|
||||
sizeof(struct sram_piece),
|
||||
0, SLAB_PANIC, NULL);
|
||||
|
||||
l1sram_init();
|
||||
l1_data_sram_init();
|
||||
l1_inst_sram_init();
|
||||
l2_sram_init();
|
||||
}
|
||||
|
||||
/* SRAM allocate function */
|
||||
static void *_sram_alloc(size_t size, struct sram_piece *pfree_head,
|
||||
struct sram_piece *pused_head)
|
||||
{
|
||||
struct sram_piece *pslot, *plast, *pavail;
|
||||
|
||||
if (size <= 0 || !pfree_head || !pused_head)
|
||||
return NULL;
|
||||
|
||||
/* Align the size */
|
||||
size = (size + 3) & ~3;
|
||||
|
||||
pslot = pfree_head->next;
|
||||
plast = pfree_head;
|
||||
|
||||
/* search an available piece slot */
|
||||
while (pslot != NULL && size > pslot->size) {
|
||||
plast = pslot;
|
||||
pslot = pslot->next;
|
||||
}
|
||||
|
||||
if (!pslot)
|
||||
return NULL;
|
||||
|
||||
if (pslot->size == size) {
|
||||
plast->next = pslot->next;
|
||||
pavail = pslot;
|
||||
} else {
|
||||
pavail = kmem_cache_alloc(sram_piece_cache, GFP_KERNEL);
|
||||
|
||||
if (!pavail)
|
||||
return NULL;
|
||||
|
||||
pavail->paddr = pslot->paddr;
|
||||
pavail->size = size;
|
||||
pslot->paddr += size;
|
||||
pslot->size -= size;
|
||||
}
|
||||
|
||||
pavail->pid = current->pid;
|
||||
|
||||
pslot = pused_head->next;
|
||||
plast = pused_head;
|
||||
|
||||
/* insert new piece into used piece list !!! */
|
||||
while (pslot != NULL && pavail->paddr < pslot->paddr) {
|
||||
plast = pslot;
|
||||
pslot = pslot->next;
|
||||
}
|
||||
|
||||
pavail->next = pslot;
|
||||
plast->next = pavail;
|
||||
|
||||
return pavail->paddr;
|
||||
}
|
||||
|
||||
/* Allocate the largest available block. */
|
||||
static void *_sram_alloc_max(struct sram_piece *pfree_head,
|
||||
struct sram_piece *pused_head,
|
||||
unsigned long *psize)
|
||||
{
|
||||
struct sram_piece *pslot, *pmax;
|
||||
|
||||
if (!pfree_head || !pused_head)
|
||||
return NULL;
|
||||
|
||||
pmax = pslot = pfree_head->next;
|
||||
|
||||
/* search an available piece slot */
|
||||
while (pslot != NULL) {
|
||||
if (pslot->size > pmax->size)
|
||||
pmax = pslot;
|
||||
pslot = pslot->next;
|
||||
}
|
||||
|
||||
if (!pmax)
|
||||
return NULL;
|
||||
|
||||
*psize = pmax->size;
|
||||
|
||||
return _sram_alloc(*psize, pfree_head, pused_head);
|
||||
}
|
||||
|
||||
/* SRAM free function */
|
||||
static int _sram_free(const void *addr,
|
||||
struct sram_piece *pfree_head,
|
||||
struct sram_piece *pused_head)
|
||||
{
|
||||
struct sram_piece *pslot, *plast, *pavail;
|
||||
|
||||
if (!pfree_head || !pused_head)
|
||||
return -1;
|
||||
|
||||
/* search the relevant memory slot */
|
||||
pslot = pused_head->next;
|
||||
plast = pused_head;
|
||||
|
||||
/* search an available piece slot */
|
||||
while (pslot != NULL && pslot->paddr != addr) {
|
||||
plast = pslot;
|
||||
pslot = pslot->next;
|
||||
}
|
||||
|
||||
if (!pslot)
|
||||
return -1;
|
||||
|
||||
plast->next = pslot->next;
|
||||
pavail = pslot;
|
||||
pavail->pid = 0;
|
||||
|
||||
/* insert free pieces back to the free list */
|
||||
pslot = pfree_head->next;
|
||||
plast = pfree_head;
|
||||
|
||||
while (pslot != NULL && addr > pslot->paddr) {
|
||||
plast = pslot;
|
||||
pslot = pslot->next;
|
||||
}
|
||||
|
||||
if (plast != pfree_head && plast->paddr + plast->size == pavail->paddr) {
|
||||
plast->size += pavail->size;
|
||||
kmem_cache_free(sram_piece_cache, pavail);
|
||||
} else {
|
||||
pavail->next = plast->next;
|
||||
plast->next = pavail;
|
||||
plast = pavail;
|
||||
}
|
||||
|
||||
if (pslot && plast->paddr + plast->size == pslot->paddr) {
|
||||
plast->size += pslot->size;
|
||||
plast->next = pslot->next;
|
||||
kmem_cache_free(sram_piece_cache, pslot);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sram_free(const void *addr)
|
||||
{
|
||||
|
||||
#if L1_CODE_LENGTH != 0
|
||||
if (addr >= (void *)L1_CODE_START
|
||||
&& addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
|
||||
return l1_inst_sram_free(addr);
|
||||
else
|
||||
#endif
|
||||
#if L1_DATA_A_LENGTH != 0
|
||||
if (addr >= (void *)L1_DATA_A_START
|
||||
&& addr < (void *)(L1_DATA_A_START + L1_DATA_A_LENGTH))
|
||||
return l1_data_A_sram_free(addr);
|
||||
else
|
||||
#endif
|
||||
#if L1_DATA_B_LENGTH != 0
|
||||
if (addr >= (void *)L1_DATA_B_START
|
||||
&& addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH))
|
||||
return l1_data_B_sram_free(addr);
|
||||
else
|
||||
#endif
|
||||
#if L2_LENGTH != 0
|
||||
if (addr >= (void *)L2_START
|
||||
&& addr < (void *)(L2_START + L2_LENGTH))
|
||||
return l2_sram_free(addr);
|
||||
else
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL(sram_free);
|
||||
|
||||
void *l1_data_A_sram_alloc(size_t size)
|
||||
{
|
||||
unsigned long flags;
|
||||
void *addr = NULL;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1_data_sram_lock, flags);
|
||||
|
||||
#if L1_DATA_A_LENGTH != 0
|
||||
addr = _sram_alloc(size, &free_l1_data_A_sram_head,
|
||||
&used_l1_data_A_sram_head);
|
||||
#endif
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1_data_sram_lock, flags);
|
||||
|
||||
pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n",
|
||||
(long unsigned int)addr, size);
|
||||
|
||||
return addr;
|
||||
}
|
||||
EXPORT_SYMBOL(l1_data_A_sram_alloc);
|
||||
|
||||
int l1_data_A_sram_free(const void *addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1_data_sram_lock, flags);
|
||||
|
||||
#if L1_DATA_A_LENGTH != 0
|
||||
ret = _sram_free(addr, &free_l1_data_A_sram_head,
|
||||
&used_l1_data_A_sram_head);
|
||||
#else
|
||||
ret = -1;
|
||||
#endif
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1_data_sram_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(l1_data_A_sram_free);
|
||||
|
||||
void *l1_data_B_sram_alloc(size_t size)
|
||||
{
|
||||
#if L1_DATA_B_LENGTH != 0
|
||||
unsigned long flags;
|
||||
void *addr;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1_data_sram_lock, flags);
|
||||
|
||||
addr = _sram_alloc(size, &free_l1_data_B_sram_head,
|
||||
&used_l1_data_B_sram_head);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1_data_sram_lock, flags);
|
||||
|
||||
pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n",
|
||||
(long unsigned int)addr, size);
|
||||
|
||||
return addr;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(l1_data_B_sram_alloc);
|
||||
|
||||
int l1_data_B_sram_free(const void *addr)
|
||||
{
|
||||
#if L1_DATA_B_LENGTH != 0
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1_data_sram_lock, flags);
|
||||
|
||||
ret = _sram_free(addr, &free_l1_data_B_sram_head,
|
||||
&used_l1_data_B_sram_head);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1_data_sram_lock, flags);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(l1_data_B_sram_free);
|
||||
|
||||
void *l1_data_sram_alloc(size_t size)
|
||||
{
|
||||
void *addr = l1_data_A_sram_alloc(size);
|
||||
|
||||
if (!addr)
|
||||
addr = l1_data_B_sram_alloc(size);
|
||||
|
||||
return addr;
|
||||
}
|
||||
EXPORT_SYMBOL(l1_data_sram_alloc);
|
||||
|
||||
void *l1_data_sram_zalloc(size_t size)
|
||||
{
|
||||
void *addr = l1_data_sram_alloc(size);
|
||||
|
||||
if (addr)
|
||||
memset(addr, 0x00, size);
|
||||
|
||||
return addr;
|
||||
}
|
||||
EXPORT_SYMBOL(l1_data_sram_zalloc);
|
||||
|
||||
int l1_data_sram_free(const void *addr)
|
||||
{
|
||||
int ret;
|
||||
ret = l1_data_A_sram_free(addr);
|
||||
if (ret == -1)
|
||||
ret = l1_data_B_sram_free(addr);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(l1_data_sram_free);
|
||||
|
||||
void *l1_inst_sram_alloc(size_t size)
|
||||
{
|
||||
#if L1_CODE_LENGTH != 0
|
||||
unsigned long flags;
|
||||
void *addr;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1_inst_sram_lock, flags);
|
||||
|
||||
addr = _sram_alloc(size, &free_l1_inst_sram_head,
|
||||
&used_l1_inst_sram_head);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1_inst_sram_lock, flags);
|
||||
|
||||
pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n",
|
||||
(long unsigned int)addr, size);
|
||||
|
||||
return addr;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(l1_inst_sram_alloc);
|
||||
|
||||
int l1_inst_sram_free(const void *addr)
|
||||
{
|
||||
#if L1_CODE_LENGTH != 0
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1_inst_sram_lock, flags);
|
||||
|
||||
ret = _sram_free(addr, &free_l1_inst_sram_head,
|
||||
&used_l1_inst_sram_head);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1_inst_sram_lock, flags);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(l1_inst_sram_free);
|
||||
|
||||
/* L1 Scratchpad memory allocate function */
|
||||
void *l1sram_alloc(size_t size)
|
||||
{
|
||||
unsigned long flags;
|
||||
void *addr;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1sram_lock, flags);
|
||||
|
||||
addr = _sram_alloc(size, &free_l1_ssram_head,
|
||||
&used_l1_ssram_head);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1sram_lock, flags);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* L1 Scratchpad memory allocate function */
|
||||
void *l1sram_alloc_max(size_t *psize)
|
||||
{
|
||||
unsigned long flags;
|
||||
void *addr;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1sram_lock, flags);
|
||||
|
||||
addr = _sram_alloc_max(&free_l1_ssram_head,
|
||||
&used_l1_ssram_head, psize);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1sram_lock, flags);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* L1 Scratchpad memory free function */
|
||||
int l1sram_free(const void *addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l1sram_lock, flags);
|
||||
|
||||
ret = _sram_free(addr, &free_l1_ssram_head,
|
||||
&used_l1_ssram_head);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l1sram_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *l2_sram_alloc(size_t size)
|
||||
{
|
||||
#if L2_LENGTH != 0
|
||||
unsigned long flags;
|
||||
void *addr;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l2_sram_lock, flags);
|
||||
|
||||
addr = _sram_alloc(size, &free_l2_sram_head,
|
||||
&used_l2_sram_head);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l2_sram_lock, flags);
|
||||
|
||||
pr_debug("Allocated address in l2_sram_alloc is 0x%lx+0x%lx\n",
|
||||
(long unsigned int)addr, size);
|
||||
|
||||
return addr;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(l2_sram_alloc);
|
||||
|
||||
void *l2_sram_zalloc(size_t size)
|
||||
{
|
||||
void *addr = l2_sram_alloc(size);
|
||||
|
||||
if (addr)
|
||||
memset(addr, 0x00, size);
|
||||
|
||||
return addr;
|
||||
}
|
||||
EXPORT_SYMBOL(l2_sram_zalloc);
|
||||
|
||||
int l2_sram_free(const void *addr)
|
||||
{
|
||||
#if L2_LENGTH != 0
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/* add mutex operation */
|
||||
spin_lock_irqsave(&l2_sram_lock, flags);
|
||||
|
||||
ret = _sram_free(addr, &free_l2_sram_head,
|
||||
&used_l2_sram_head);
|
||||
|
||||
/* add mutex operation */
|
||||
spin_unlock_irqrestore(&l2_sram_lock, flags);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(l2_sram_free);
|
||||
|
||||
int sram_free_with_lsl(const void *addr)
|
||||
{
|
||||
struct sram_list_struct *lsl, **tmp;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
for (tmp = &mm->context.sram_list; *tmp; tmp = &(*tmp)->next)
|
||||
if ((*tmp)->addr == addr)
|
||||
goto found;
|
||||
return -1;
|
||||
found:
|
||||
lsl = *tmp;
|
||||
sram_free(addr);
|
||||
*tmp = lsl->next;
|
||||
kfree(lsl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(sram_free_with_lsl);
|
||||
|
||||
void *sram_alloc_with_lsl(size_t size, unsigned long flags)
|
||||
{
|
||||
void *addr = NULL;
|
||||
struct sram_list_struct *lsl = NULL;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
lsl = kzalloc(sizeof(struct sram_list_struct), GFP_KERNEL);
|
||||
if (!lsl)
|
||||
return NULL;
|
||||
|
||||
if (flags & L1_INST_SRAM)
|
||||
addr = l1_inst_sram_alloc(size);
|
||||
|
||||
if (addr == NULL && (flags & L1_DATA_A_SRAM))
|
||||
addr = l1_data_A_sram_alloc(size);
|
||||
|
||||
if (addr == NULL && (flags & L1_DATA_B_SRAM))
|
||||
addr = l1_data_B_sram_alloc(size);
|
||||
|
||||
if (addr == NULL && (flags & L2_SRAM))
|
||||
addr = l2_sram_alloc(size);
|
||||
|
||||
if (addr == NULL) {
|
||||
kfree(lsl);
|
||||
return NULL;
|
||||
}
|
||||
lsl->addr = addr;
|
||||
lsl->length = size;
|
||||
lsl->next = mm->context.sram_list;
|
||||
mm->context.sram_list = lsl;
|
||||
return addr;
|
||||
}
|
||||
EXPORT_SYMBOL(sram_alloc_with_lsl);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/* Once we get a real allocator, we'll throw all of this away.
|
||||
* Until then, we need some sort of visibility into the L1 alloc.
|
||||
*/
|
||||
/* Need to keep line of output the same. Currently, that is 44 bytes
|
||||
* (including newline).
|
||||
*/
|
||||
static int _sram_proc_read(char *buf, int *len, int count, const char *desc,
|
||||
struct sram_piece *pfree_head,
|
||||
struct sram_piece *pused_head)
|
||||
{
|
||||
struct sram_piece *pslot;
|
||||
|
||||
if (!pfree_head || !pused_head)
|
||||
return -1;
|
||||
|
||||
*len += sprintf(&buf[*len], "--- SRAM %-14s Size PID State \n", desc);
|
||||
|
||||
/* search the relevant memory slot */
|
||||
pslot = pused_head->next;
|
||||
|
||||
while (pslot != NULL) {
|
||||
*len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
|
||||
pslot->paddr, pslot->paddr + pslot->size,
|
||||
pslot->size, pslot->pid, "ALLOCATED");
|
||||
|
||||
pslot = pslot->next;
|
||||
}
|
||||
|
||||
pslot = pfree_head->next;
|
||||
|
||||
while (pslot != NULL) {
|
||||
*len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
|
||||
pslot->paddr, pslot->paddr + pslot->size,
|
||||
pslot->size, pslot->pid, "FREE");
|
||||
|
||||
pslot = pslot->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int sram_proc_read(char *buf, char **start, off_t offset, int count,
|
||||
int *eof, void *data)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if (_sram_proc_read(buf, &len, count, "Scratchpad",
|
||||
&free_l1_ssram_head, &used_l1_ssram_head))
|
||||
goto not_done;
|
||||
#if L1_DATA_A_LENGTH != 0
|
||||
if (_sram_proc_read(buf, &len, count, "L1 Data A",
|
||||
&free_l1_data_A_sram_head,
|
||||
&used_l1_data_A_sram_head))
|
||||
goto not_done;
|
||||
#endif
|
||||
#if L1_DATA_B_LENGTH != 0
|
||||
if (_sram_proc_read(buf, &len, count, "L1 Data B",
|
||||
&free_l1_data_B_sram_head,
|
||||
&used_l1_data_B_sram_head))
|
||||
goto not_done;
|
||||
#endif
|
||||
#if L1_CODE_LENGTH != 0
|
||||
if (_sram_proc_read(buf, &len, count, "L1 Instruction",
|
||||
&free_l1_inst_sram_head, &used_l1_inst_sram_head))
|
||||
goto not_done;
|
||||
#endif
|
||||
#if L2_LENGTH != 0
|
||||
if (_sram_proc_read(buf, &len, count, "L2",
|
||||
&free_l2_sram_head, &used_l2_sram_head))
|
||||
goto not_done;
|
||||
#endif
|
||||
|
||||
*eof = 1;
|
||||
not_done:
|
||||
return len;
|
||||
}
|
||||
|
||||
static int __init sram_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *ptr;
|
||||
ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL);
|
||||
if (!ptr) {
|
||||
printk(KERN_WARNING "unable to create /proc/sram\n");
|
||||
return -1;
|
||||
}
|
||||
ptr->owner = THIS_MODULE;
|
||||
ptr->read_proc = sram_proc_read;
|
||||
return 0;
|
||||
}
|
||||
late_initcall(sram_proc_init);
|
||||
#endif
|
Reference in New Issue
Block a user