Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 163309
b: refs/heads/master
c: 79714ac
h: refs/heads/master
i:
  163307: 976ece4
v: v3
  • Loading branch information
Magnus Damm authored and Paul Mundt committed Jul 4, 2009
1 parent 46ac653 commit f330831
Show file tree
Hide file tree
Showing 30 changed files with 1,049 additions and 663 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4048e5ca29afbd747a16245f2bc4d1d521a6d0d0
refs/heads/master: 79714acbab080ad351acf4bba9a2bbc21d65c93c
1 change: 0 additions & 1 deletion trunk/arch/sh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ config SUPERH
select EMBEDDED
select HAVE_CLK
select HAVE_IDE
select HAVE_LMB
select HAVE_OPROFILE
select HAVE_GENERIC_DMA_COHERENT
select HAVE_IOREMAP_PROT if MMU
Expand Down
61 changes: 61 additions & 0 deletions trunk/arch/sh/include/asm/hwblk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef __ASM_SH_HWBLK_H
#define __ASM_SH_HWBLK_H

#include <asm/clock.h>
#include <asm/io.h>

#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */

#define HWBLK_AREA(_flags, _parent) \
{ \
.flags = _flags, \
.parent = _parent, \
}

struct hwblk_area {
unsigned long cnt;
unsigned char parent;
unsigned char flags;
};

#define HWBLK(_mstp, _bit, _area) \
{ \
.mstp = (void __iomem *)_mstp, \
.bit = _bit, \
.area = _area, \
}

struct hwblk {
void __iomem *mstp;
unsigned char bit;
unsigned char area;
unsigned long cnt;
};

struct hwblk_info {
struct hwblk_area *areas;
int nr_areas;
struct hwblk *hwblks;
int nr_hwblks;
};

/* Should be defined by processor-specific code */
int arch_hwblk_init(void);
int arch_hwblk_sleep_mode(void);

int hwblk_register(struct hwblk_info *info);
int hwblk_init(void);

/* allow clocks to enable and disable hardware blocks */
#define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags) \
{ \
.name = _name, \
.id = _id, \
.parent = _parent, \
.arch_flags = _hwblk, \
.flags = _flags, \
}

int sh_hwblk_clk_register(struct clk *clks, int nr);

#endif /* __ASM_SH_HWBLK_H */
6 changes: 0 additions & 6 deletions trunk/arch/sh/include/asm/lmb.h

This file was deleted.

2 changes: 0 additions & 2 deletions trunk/arch/sh/include/asm/perf_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@
/* SH only supports software counters through this interface. */
static inline void set_perf_counter_pending(void) {}

#define PERF_COUNTER_INDEX_OFFSET 0

#endif /* __ASM_SH_PERF_COUNTER_H */
2 changes: 1 addition & 1 deletion trunk/arch/sh/kernel/cpu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ obj-$(CONFIG_UBC_WAKEUP) += ubc.o
obj-$(CONFIG_SH_ADC) += adc.o
obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o

obj-y += irq/ init.o clock.o
obj-y += irq/ init.o clock.o hwblk.o
130 changes: 130 additions & 0 deletions trunk/arch/sh/kernel/cpu/hwblk.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include <linux/clk.h>
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm/suspend.h>
#include <asm/hwblk.h>
#include <asm/clock.h>

static DEFINE_SPINLOCK(hwblk_lock);

static void hwblk_area_inc(struct hwblk_info *info, int area)
{
struct hwblk_area *hap = info->areas + area;

hap->cnt++;
if (hap->cnt == 1)
if (hap->flags & HWBLK_AREA_FLAG_PARENT)
hwblk_area_inc(info, hap->parent);
}

static void hwblk_area_dec(struct hwblk_info *info, int area)
{
struct hwblk_area *hap = info->areas + area;

if (hap->cnt == 1)
if (hap->flags & HWBLK_AREA_FLAG_PARENT)
hwblk_area_dec(info, hap->parent);
hap->cnt--;
}

static void hwblk_enable(struct hwblk_info *info, int hwblk)
{
struct hwblk *hp = info->hwblks + hwblk;
unsigned long tmp;
unsigned long flags;

spin_lock_irqsave(&hwblk_lock, flags);

hp->cnt++;
if (hp->cnt == 1) {
hwblk_area_inc(info, hp->area);

tmp = __raw_readl(hp->mstp);
tmp &= ~(1 << hp->bit);
__raw_writel(tmp, hp->mstp);
}

spin_unlock_irqrestore(&hwblk_lock, flags);
}

static void hwblk_disable(struct hwblk_info *info, int hwblk)
{
struct hwblk *hp = info->hwblks + hwblk;
unsigned long tmp;
unsigned long flags;

spin_lock_irqsave(&hwblk_lock, flags);

if (hp->cnt == 1) {
hwblk_area_dec(info, hp->area);

tmp = __raw_readl(hp->mstp);
tmp |= 1 << hp->bit;
__raw_writel(tmp, hp->mstp);
}
hp->cnt--;

spin_unlock_irqrestore(&hwblk_lock, flags);
}

static struct hwblk_info *hwblk_info;

int __init hwblk_register(struct hwblk_info *info)
{
hwblk_info = info;
return 0;
}

int __init __weak arch_hwblk_init(void)
{
return 0;
}

int __weak arch_hwblk_sleep_mode(void)
{
return SUSP_SH_SLEEP;
}

int __init hwblk_init(void)
{
return arch_hwblk_init();
}

/* allow clocks to enable and disable hardware blocks */
static int sh_hwblk_clk_enable(struct clk *clk)
{
if (!hwblk_info)
return -ENOENT;

hwblk_enable(hwblk_info, clk->arch_flags);
return 0;
}

static void sh_hwblk_clk_disable(struct clk *clk)
{
if (hwblk_info)
hwblk_disable(hwblk_info, clk->arch_flags);
}

static struct clk_ops sh_hwblk_clk_ops = {
.enable = sh_hwblk_clk_enable,
.disable = sh_hwblk_clk_disable,
.recalc = followparent_recalc,
};

int __init sh_hwblk_clk_register(struct clk *clks, int nr)
{
struct clk *clkp;
int ret = 0;
int k;

for (k = 0; !ret && (k < nr); k++) {
clkp = clks + k;
clkp->ops = &sh_hwblk_clk_ops;
ret |= clk_register(clkp);
}

return ret;
}
71 changes: 19 additions & 52 deletions trunk/arch/sh/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/lmb.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/page.h>
Expand Down Expand Up @@ -234,45 +233,39 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
void __init setup_bootmem_allocator(unsigned long free_pfn)
{
unsigned long bootmap_size;
unsigned long bootmap_pages, bootmem_paddr;
u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT;
int i;

bootmap_pages = bootmem_bootmap_pages(total_pages);

bootmem_paddr = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);

/*
* Find a proper area for the bootmem bitmap. After this
* bootstrap step all allocations (until the page allocator
* is intact) must be done via bootmem_alloc().
*/
bootmap_size = init_bootmem_node(NODE_DATA(0),
bootmem_paddr >> PAGE_SHIFT,
bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
min_low_pfn, max_low_pfn);

/* Add active regions with valid PFNs. */
for (i = 0; i < lmb.memory.cnt; i++) {
unsigned long start_pfn, end_pfn;
start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
__add_active_range(0, start_pfn, end_pfn);
}
__add_active_range(0, min_low_pfn, max_low_pfn);
register_bootmem_low_pages();

node_set_online(0);

/*
* Add all physical memory to the bootmem map and mark each
* area as present.
* Reserve the kernel text and
* Reserve the bootmem bitmap. We do this in two steps (first step
* was init_bootmem()), because this catches the (definitely buggy)
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area.
*/
register_bootmem_low_pages();
reserve_bootmem(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
(PFN_PHYS(free_pfn) + bootmap_size + PAGE_SIZE - 1) -
(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET),
BOOTMEM_DEFAULT);

/* Reserve the sections we're already using. */
for (i = 0; i < lmb.reserved.cnt; i++)
reserve_bootmem(lmb.reserved.region[i].base,
lmb_size_bytes(&lmb.reserved, i),
/*
* Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
*/
if (CONFIG_ZERO_PAGE_OFFSET != 0)
reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
BOOTMEM_DEFAULT);

node_set_online(0);

sparse_memory_present_with_active_regions(0);

#ifdef CONFIG_BLK_DEV_INITRD
Expand Down Expand Up @@ -303,37 +296,12 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
static void __init setup_memory(void)
{
unsigned long start_pfn;
u64 base = min_low_pfn << PAGE_SHIFT;
u64 size = (max_low_pfn << PAGE_SHIFT) - base;

/*
* Partially used pages are not usable - thus
* we are rounding upwards:
*/
start_pfn = PFN_UP(__pa(_end));

lmb_add(base, size);

/*
* Reserve the kernel text and
* Reserve the bootmem bitmap. We do this in two steps (first step
* was init_bootmem()), because this catches the (definitely buggy)
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area.
*/
lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
(PFN_PHYS(start_pfn) + PAGE_SIZE - 1) -
(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));

/*
* Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
*/
if (CONFIG_ZERO_PAGE_OFFSET != 0)
lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);

lmb_analyze();
lmb_dump_all();

setup_bootmem_allocator(start_pfn);
}
#else
Expand Down Expand Up @@ -434,7 +402,6 @@ void __init setup_arch(char **cmdline_p)
nodes_clear(node_online_map);

/* Setup bootmem with available RAM */
lmb_init();
setup_memory();
sparse_init();

Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/sh/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/smp.h>
#include <linux/rtc.h>
#include <asm/clock.h>
#include <asm/hwblk.h>
#include <asm/rtc.h>

/* Dummy RTC ops */
Expand Down Expand Up @@ -96,6 +97,7 @@ void __init time_init(void)
if (board_time_init)
board_time_init();

hwblk_init();
clk_init();

rtc_sh_get_time(&xtime);
Expand Down
Loading

0 comments on commit f330831

Please sign in to comment.