Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 968e75fc authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k:
  m68k/math-emu: Remove unnecessary code
  m68k/math-emu: Remove commented out old code
  m68k: Kill warning in setup_arch() when compiling for Sun3
  m68k/atari: Prefix GPIO_{IN,OUT} with CODEC_
  sparc: iounmap() and *_free_coherent() - Use lookup_resource()
  m68k/atari: Reserve some ST-RAM early on for device buffer use
  m68k/amiga: Chip RAM - Use lookup_resource()
  resources: Add lookup_resource()
  sparc: _sparc_find_resource() should check for exact matches
  m68k/amiga: Chip RAM - Offset resource end by CHIP_PHYSADDR
  m68k/amiga: Chip RAM - Use resource_size() to fix off-by-one error
  m68k/amiga: Chip RAM - Change chipavail to an atomic_t
  m68k/amiga: Chip RAM - Always allocate from the start of memory
  m68k/amiga: Chip RAM - Convert from printk() to pr_*()
  m68k/amiga: Chip RAM - Use tabs for indentation
parents a00ed25c d3690f8b
Loading
Loading
Loading
Loading
+0 −6
Original line number Original line Diff line number Diff line
@@ -372,12 +372,6 @@ config AMIGA_PCMCIA
	  Include support in the kernel for pcmcia on Amiga 1200 and Amiga
	  Include support in the kernel for pcmcia on Amiga 1200 and Amiga
	  600. If you intend to use pcmcia cards say Y; otherwise say N.
	  600. If you intend to use pcmcia cards say Y; otherwise say N.


config STRAM_PROC
	bool "ST-RAM statistics in /proc"
	depends on ATARI
	help
	  Say Y here to report ST-RAM usage statistics in /proc/stram.

config HEARTBEAT
config HEARTBEAT
	bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
	bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
	default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300
	default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300
+63 −73
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/module.h>


#include <asm/atomic.h>
#include <asm/page.h>
#include <asm/page.h>
#include <asm/amigahw.h>
#include <asm/amigahw.h>


@@ -25,7 +26,7 @@ EXPORT_SYMBOL(amiga_chip_size);
static struct resource chipram_res = {
static struct resource chipram_res = {
	.name = "Chip RAM", .start = CHIP_PHYSADDR
	.name = "Chip RAM", .start = CHIP_PHYSADDR
};
};
static unsigned long chipavail;
static atomic_t chipavail;




void __init amiga_chip_init(void)
void __init amiga_chip_init(void)
@@ -33,101 +34,90 @@ void __init amiga_chip_init(void)
	if (!AMIGAHW_PRESENT(CHIP_RAM))
	if (!AMIGAHW_PRESENT(CHIP_RAM))
		return;
		return;


    chipram_res.end = amiga_chip_size-1;
	chipram_res.end = CHIP_PHYSADDR + amiga_chip_size - 1;
	request_resource(&iomem_resource, &chipram_res);
	request_resource(&iomem_resource, &chipram_res);


    chipavail = amiga_chip_size;
	atomic_set(&chipavail, amiga_chip_size);
}
}




void *amiga_chip_alloc(unsigned long size, const char *name)
void *amiga_chip_alloc(unsigned long size, const char *name)
{
{
	struct resource *res;
	struct resource *res;
	void *p;


    /* round up */
    size = PAGE_ALIGN(size);

#ifdef DEBUG
    printk("amiga_chip_alloc: allocate %ld bytes\n", size);
#endif
	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
	if (!res)
	if (!res)
		return NULL;
		return NULL;
    res->name = name;


    if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) {
	res->name = name;
	p = amiga_chip_alloc_res(size, res);
	if (!p) {
		kfree(res);
		kfree(res);
		return NULL;
		return NULL;
	}
	}
    chipavail -= size;

#ifdef DEBUG
	return p;
    printk("amiga_chip_alloc: returning %lx\n", res->start);
#endif
    return (void *)ZTWO_VADDR(res->start);
}
}
EXPORT_SYMBOL(amiga_chip_alloc);
EXPORT_SYMBOL(amiga_chip_alloc);




	/*
	/*
	 *  Warning:
	 *  Warning:
     *  amiga_chip_alloc_res is meant only for drivers that need to allocate
	 *  amiga_chip_alloc_res is meant only for drivers that need to
     *  Chip RAM before kmalloc() is functional. As a consequence, those
	 *  allocate Chip RAM before kmalloc() is functional. As a consequence,
     *  drivers must not free that Chip RAM afterwards.
	 *  those drivers must not free that Chip RAM afterwards.
	 */
	 */


void * __init amiga_chip_alloc_res(unsigned long size, struct resource *res)
void *amiga_chip_alloc_res(unsigned long size, struct resource *res)
{
{
    unsigned long start;
	int error;


	/* round up */
	/* round up */
	size = PAGE_ALIGN(size);
	size = PAGE_ALIGN(size);
    /* dmesg into chipmem prefers memory at the safe end */

    start = CHIP_PHYSADDR + chipavail - size;
	pr_debug("amiga_chip_alloc_res: allocate %lu bytes\n", size);

	error = allocate_resource(&chipram_res, res, size, 0, UINT_MAX,
#ifdef DEBUG
				  PAGE_SIZE, NULL, NULL);
    printk("amiga_chip_alloc_res: allocate %ld bytes\n", size);
	if (error < 0) {
#endif
		pr_err("amiga_chip_alloc_res: allocate_resource() failed %d!\n",
    if (allocate_resource(&chipram_res, res, size, start, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) {
		       error);
	printk("amiga_chip_alloc_res: first alloc failed!\n");
	if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0)
		return NULL;
		return NULL;
	}
	}
    chipavail -= size;

#ifdef DEBUG
	atomic_sub(size, &chipavail);
    printk("amiga_chip_alloc_res: returning %lx\n", res->start);
	pr_debug("amiga_chip_alloc_res: returning %pR\n", res);
#endif
	return (void *)ZTWO_VADDR(res->start);
	return (void *)ZTWO_VADDR(res->start);
}
}


void amiga_chip_free(void *ptr)
void amiga_chip_free(void *ptr)
{
{
	unsigned long start = ZTWO_PADDR(ptr);
	unsigned long start = ZTWO_PADDR(ptr);
    struct resource **p, *res;
	struct resource *res;
	unsigned long size;
	unsigned long size;


    for (p = &chipram_res.child; (res = *p); p = &res->sibling) {
	res = lookup_resource(&chipram_res, start);
	if (res->start != start)
	if (!res) {
	    continue;
		pr_err("amiga_chip_free: trying to free nonexistent region at "
	*p = res->sibling;
		       "%p\n", ptr);
	size = res->end-start;
#ifdef DEBUG
	printk("amiga_chip_free: free %ld bytes at %p\n", size, ptr);
#endif
	chipavail += size;
	kfree(res);
		return;
		return;
	}
	}
    printk("amiga_chip_free: trying to free nonexistent region at %p\n", ptr);

	size = resource_size(res);
	pr_debug("amiga_chip_free: free %lu bytes at %p\n", size, ptr);
	atomic_add(size, &chipavail);
	release_resource(res);
	kfree(res);
}
}
EXPORT_SYMBOL(amiga_chip_free);
EXPORT_SYMBOL(amiga_chip_free);




unsigned long amiga_chip_avail(void)
unsigned long amiga_chip_avail(void)
{
{
#ifdef DEBUG
	unsigned long n = atomic_read(&chipavail);
	printk("amiga_chip_avail : %ld bytes\n", chipavail);

#endif
	pr_debug("amiga_chip_avail : %lu bytes\n", n);
	return chipavail;
	return n;
}
}
EXPORT_SYMBOL(amiga_chip_avail);
EXPORT_SYMBOL(amiga_chip_avail);
+69 −285
Original line number Original line Diff line number Diff line
/*
/*
 * arch/m68k/atari/stram.c: Functions for ST-RAM allocations
 * Functions for ST-RAM allocations
 *
 *
 * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
 * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
 *
 *
@@ -30,91 +30,35 @@
#include <asm/atari_stram.h>
#include <asm/atari_stram.h>
#include <asm/io.h>
#include <asm/io.h>


#undef DEBUG

#ifdef DEBUG
#define	DPRINTK(fmt,args...) printk( fmt, ##args )
#else
#define DPRINTK(fmt,args...)
#endif

#if defined(CONFIG_PROC_FS) && defined(CONFIG_STRAM_PROC)
/* abbrev for the && above... */
#define DO_PROC
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#endif


/*
/*
 * ++roman:
 * The ST-RAM allocator allocates memory from a pool of reserved ST-RAM of
 *
 * configurable size, set aside on ST-RAM init.
 * New version of ST-Ram buffer allocation. Instead of using the
 * As long as this pool is not exhausted, allocation of real ST-RAM can be
 * 1 MB - 4 KB that remain when the ST-Ram chunk starts at $1000
 * guaranteed.
 * (1 MB granularity!), such buffers are reserved like this:
 *
 *  - If the kernel resides in ST-Ram anyway, we can take the buffer
 *    from behind the current kernel data space the normal way
 *    (incrementing start_mem).
 *
 *  - If the kernel is in TT-Ram, stram_init() initializes start and
 *    end of the available region. Buffers are allocated from there
 *    and mem_init() later marks the such used pages as reserved.
 *    Since each TT-Ram chunk is at least 4 MB in size, I hope there
 *    won't be an overrun of the ST-Ram region by normal kernel data
 *    space.
 *
 * For that, ST-Ram may only be allocated while kernel initialization
 * is going on, or exactly: before mem_init() is called. There is also
 * no provision now for freeing ST-Ram buffers. It seems that isn't
 * really needed.
 *
 */
 */


/* Start and end (virtual) of ST-RAM */
static void *stram_start, *stram_end;

/* set after memory_init() executed and allocations via start_mem aren't
 * possible anymore */
static int mem_init_done;

/* set if kernel is in ST-RAM */
/* set if kernel is in ST-RAM */
static int kernel_in_stram;
static int kernel_in_stram;


typedef struct stram_block {
static struct resource stram_pool = {
	struct stram_block *next;
	.name = "ST-RAM Pool"
	void *start;
};
	unsigned long size;
	unsigned flags;
	const char *owner;
} BLOCK;

/* values for flags field */
#define BLOCK_FREE	0x01	/* free structure in the BLOCKs pool */
#define BLOCK_KMALLOCED	0x02	/* structure allocated by kmalloc() */
#define BLOCK_GFP	0x08	/* block allocated with __get_dma_pages() */


/* list of allocated blocks */
static unsigned long pool_size = 1024*1024;
static BLOCK *alloc_list;


/* We can't always use kmalloc() to allocate BLOCK structures, since
 * stram_alloc() can be called rather early. So we need some pool of
 * statically allocated structures. 20 of them is more than enough, so in most
 * cases we never should need to call kmalloc(). */
#define N_STATIC_BLOCKS	20
static BLOCK static_blocks[N_STATIC_BLOCKS];


/***************************** Prototypes *****************************/
static int __init atari_stram_setup(char *arg)
{
	if (!MACH_IS_ATARI)
		return 0;


static BLOCK *add_region( void *addr, unsigned long size );
	pool_size = memparse(arg, NULL);
static BLOCK *find_region( void *addr );
	return 0;
static int remove_region( BLOCK *block );
}


/************************* End of Prototypes **************************/
early_param("stram_pool", atari_stram_setup);



/* ------------------------------------------------------------------------ */
/*							   Public Interface								*/
/* ------------------------------------------------------------------------ */


/*
/*
 * This init function is called very early by atari/config.c
 * This init function is called very early by atari/config.c
@@ -123,23 +67,21 @@ static int remove_region( BLOCK *block );
void __init atari_stram_init(void)
void __init atari_stram_init(void)
{
{
	int i;
	int i;
	void *stram_start;


	/* initialize static blocks */
	/*
	for( i = 0; i < N_STATIC_BLOCKS; ++i )
	 * determine whether kernel code resides in ST-RAM
		static_blocks[i].flags = BLOCK_FREE;
	 * (then ST-RAM is the first memory block at virtual 0x0)

	 */
	/* determine whether kernel code resides in ST-RAM (then ST-RAM is the
	 * first memory block at virtual 0x0) */
	stram_start = phys_to_virt(0);
	stram_start = phys_to_virt(0);
	kernel_in_stram = (stram_start == 0);
	kernel_in_stram = (stram_start == 0);


	for (i = 0; i < m68k_num_memory; ++i) {
	for (i = 0; i < m68k_num_memory; ++i) {
		if (m68k_memory[i].addr == 0) {
		if (m68k_memory[i].addr == 0) {
			/* skip first 2kB or page (supervisor-only!) */
			stram_end = stram_start + m68k_memory[i].size;
			return;
			return;
		}
		}
	}
	}

	/* Should never come here! (There is always ST-Ram!) */
	/* Should never come here! (There is always ST-Ram!) */
	panic("atari_stram_init: no ST-RAM found!");
	panic("atari_stram_init: no ST-RAM found!");
}
}
@@ -151,226 +93,68 @@ void __init atari_stram_init(void)
 */
 */
void __init atari_stram_reserve_pages(void *start_mem)
void __init atari_stram_reserve_pages(void *start_mem)
{
{
	/* always reserve first page of ST-RAM, the first 2 kB are
	/*
	 * supervisor-only! */
	 * always reserve first page of ST-RAM, the first 2 KiB are
	 * supervisor-only!
	 */
	if (!kernel_in_stram)
	if (!kernel_in_stram)
		reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);
		reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT);


}
	stram_pool.start = (resource_size_t)alloc_bootmem_low_pages(pool_size);
	stram_pool.end = stram_pool.start + pool_size - 1;
	request_resource(&iomem_resource, &stram_pool);


void atari_stram_mem_init_hook (void)
	pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
{
		 pool_size, &stram_pool);
	mem_init_done = 1;
}
}




/*
void *atari_stram_alloc(unsigned long size, const char *owner)
 * This is main public interface: somehow allocate a ST-RAM block
 *
 *  - If we're before mem_init(), we have to make a static allocation. The
 *    region is taken in the kernel data area (if the kernel is in ST-RAM) or
 *    from the start of ST-RAM (if the kernel is in TT-RAM) and added to the
 *    rsvd_stram_* region. The ST-RAM is somewhere in the middle of kernel
 *    address space in the latter case.
 *
 *  - If mem_init() already has been called, try with __get_dma_pages().
 *    This has the disadvantage that it's very hard to get more than 1 page,
 *    and it is likely to fail :-(
 *
 */
void *atari_stram_alloc(long size, const char *owner)
{
{
	void *addr = NULL;
	struct resource *res;
	BLOCK *block;
	int error;
	int flags;


	DPRINTK("atari_stram_alloc(size=%08lx,owner=%s)\n", size, owner);
	pr_debug("atari_stram_alloc: allocate %lu bytes\n", size);


	if (!mem_init_done)
	/* round up */
		return alloc_bootmem_low(size);
	size = PAGE_ALIGN(size);
	else {
		/* After mem_init(): can only resort to __get_dma_pages() */
		addr = (void *)__get_dma_pages(GFP_KERNEL, get_order(size));
		flags = BLOCK_GFP;
		DPRINTK( "atari_stram_alloc: after mem_init, "
				 "get_pages=%p\n", addr );
	}


	if (addr) {
	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
		if (!(block = add_region( addr, size ))) {
	if (!res)
			/* out of memory for BLOCK structure :-( */
		return NULL;
			DPRINTK( "atari_stram_alloc: out of mem for BLOCK -- "

					 "freeing again\n" );
	res->name = owner;
			free_pages((unsigned long)addr, get_order(size));
	error = allocate_resource(&stram_pool, res, size, 0, UINT_MAX,
			return( NULL );
				  PAGE_SIZE, NULL, NULL);
		}
	if (error < 0) {
		block->owner = owner;
		pr_err("atari_stram_alloc: allocate_resource() failed %d!\n",
		block->flags |= flags;
		       error);
		kfree(res);
		return NULL;
	}
	}
	return( addr );

	pr_debug("atari_stram_alloc: returning %pR\n", res);
	return (void *)res->start;
}
}
EXPORT_SYMBOL(atari_stram_alloc);
EXPORT_SYMBOL(atari_stram_alloc);


void atari_stram_free( void *addr )


void atari_stram_free(void *addr)
{
{
	BLOCK *block;
	unsigned long start = (unsigned long)addr;

	struct resource *res;
	DPRINTK( "atari_stram_free(addr=%p)\n", addr );
	unsigned long size;


	if (!(block = find_region( addr ))) {
	res = lookup_resource(&stram_pool, start);
		printk( KERN_ERR "Attempt to free non-allocated ST-RAM block at %p "
	if (!res) {
				"from %p\n", addr, __builtin_return_address(0) );
		pr_err("atari_stram_free: trying to free nonexistent region "
		       "at %p\n", addr);
		return;
		return;
	}
	}
	DPRINTK( "atari_stram_free: found block (%p): size=%08lx, owner=%s, "
			 "flags=%02x\n", block, block->size, block->owner, block->flags );

	if (!(block->flags & BLOCK_GFP))
		goto fail;

	DPRINTK("atari_stram_free: is kmalloced, order_size=%d\n",
		get_order(block->size));
	free_pages((unsigned long)addr, get_order(block->size));
	remove_region( block );
	return;


  fail:
	size = resource_size(res);
	printk( KERN_ERR "atari_stram_free: cannot free block at %p "
	pr_debug("atari_stram_free: free %lu bytes at %p\n", size, addr);
			"(called from %p)\n", addr, __builtin_return_address(0) );
	release_resource(res);
	kfree(res);
}
}
EXPORT_SYMBOL(atari_stram_free);
EXPORT_SYMBOL(atari_stram_free);


/* ------------------------------------------------------------------------ */
/*							  Region Management								*/
/* ------------------------------------------------------------------------ */


/* insert a region into the alloced list (sorted) */
static BLOCK *add_region( void *addr, unsigned long size )
{
	BLOCK **p, *n = NULL;
	int i;

	for( i = 0; i < N_STATIC_BLOCKS; ++i ) {
		if (static_blocks[i].flags & BLOCK_FREE) {
			n = &static_blocks[i];
			n->flags = 0;
			break;
		}
	}
	if (!n && mem_init_done) {
		/* if statics block pool exhausted and we can call kmalloc() already
		 * (after mem_init()), try that */
		n = kmalloc( sizeof(BLOCK), GFP_KERNEL );
		if (n)
			n->flags = BLOCK_KMALLOCED;
	}
	if (!n) {
		printk( KERN_ERR "Out of memory for ST-RAM descriptor blocks\n" );
		return( NULL );
	}
	n->start = addr;
	n->size  = size;

	for( p = &alloc_list; *p; p = &((*p)->next) )
		if ((*p)->start > addr) break;
	n->next = *p;
	*p = n;

	return( n );
}


/* find a region (by start addr) in the alloced list */
static BLOCK *find_region( void *addr )
{
	BLOCK *p;

	for( p = alloc_list; p; p = p->next ) {
		if (p->start == addr)
			return( p );
		if (p->start > addr)
			break;
	}
	return( NULL );
}


/* remove a block from the alloced list */
static int remove_region( BLOCK *block )
{
	BLOCK **p;

	for( p = &alloc_list; *p; p = &((*p)->next) )
		if (*p == block) break;
	if (!*p)
		return( 0 );

	*p = block->next;
	if (block->flags & BLOCK_KMALLOCED)
		kfree( block );
	else
		block->flags |= BLOCK_FREE;
	return( 1 );
}



/* ------------------------------------------------------------------------ */
/*						 /proc statistics file stuff						*/
/* ------------------------------------------------------------------------ */

#ifdef DO_PROC

#define	PRINT_PROC(fmt,args...) seq_printf( m, fmt, ##args )

static int stram_proc_show(struct seq_file *m, void *v)
{
	BLOCK *p;

	PRINT_PROC("Total ST-RAM:      %8u kB\n",
			   (stram_end - stram_start) >> 10);
	PRINT_PROC( "Allocated regions:\n" );
	for( p = alloc_list; p; p = p->next ) {
		PRINT_PROC("0x%08lx-0x%08lx: %s (",
			   virt_to_phys(p->start),
			   virt_to_phys(p->start+p->size-1),
			   p->owner);
		if (p->flags & BLOCK_GFP)
			PRINT_PROC( "page-alloced)\n" );
		else
			PRINT_PROC( "??)\n" );
	}

	return 0;
}

static int stram_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, stram_proc_show, NULL);
}

static const struct file_operations stram_proc_fops = {
	.open		= stram_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int __init proc_stram_init(void)
{
	proc_create("stram", 0, NULL, &stram_proc_fops);
	return 0;
}
module_init(proc_stram_init);
#endif


/*
 * Local variables:
 *  c-indent-level: 4
 *  tab-width: 4
 * End:
 */
+1 −2
Original line number Original line Diff line number Diff line
@@ -6,12 +6,11 @@
 */
 */


/* public interface */
/* public interface */
void *atari_stram_alloc(long size, const char *owner);
void *atari_stram_alloc(unsigned long size, const char *owner);
void atari_stram_free(void *);
void atari_stram_free(void *);


/* functions called internally by other parts of the kernel */
/* functions called internally by other parts of the kernel */
void atari_stram_init(void);
void atari_stram_init(void);
void atari_stram_reserve_pages(void *start_mem);
void atari_stram_reserve_pages(void *start_mem);
void atari_stram_mem_init_hook (void);


#endif /*_M68K_ATARI_STRAM_H */
#endif /*_M68K_ATARI_STRAM_H */
+2 −2
Original line number Original line Diff line number Diff line
@@ -399,8 +399,8 @@ struct CODEC
#define CODEC_OVERFLOW_LEFT     2
#define CODEC_OVERFLOW_LEFT     2
  u_char unused2, unused3, unused4, unused5;
  u_char unused2, unused3, unused4, unused5;
  u_char gpio_directions;
  u_char gpio_directions;
#define GPIO_IN                 0
#define CODEC_GPIO_IN           0
#define GPIO_OUT                1
#define CODEC_GPIO_OUT          1
  u_char unused6;
  u_char unused6;
  u_char gpio_data;
  u_char gpio_data;
};
};
Loading