mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6: [AVR32] Fix random segfault with preemption [AVR32] Don't use __builtin_xchg() [AVR32] ngw100 i2c-gpio tweaks [AVR32] Ignore a few irrelevant syscalls [AVR32] SMC configuration in clock cycles [AVR32] Drop support for redundant "keepinitrd" boot-time parm. [AVR32] Make dma_sync_*_for_cpu no-ops [AVR32] Remove unneeded 8K alignment of .text section [AVR32] Kill a few hardcoded constants in vmlinux.lds [AVR32] rename vmlinux.lds [AVR32] fix command line parsing in early_parse_fbmem [AVR32] checkstack support [AVR32] Wire up USBA device [AVR32] add multidrive support for pio driver [AVR32] /sys/kernel/debug/at32ap_clk [AVR32] Move AT32_PM_BASE definition into pm.h
This commit is contained in:
commit
55982fd184
21 changed files with 448 additions and 74 deletions
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include <asm/arch/smc.h>
|
||||
|
||||
static struct smc_config flash_config __initdata = {
|
||||
static struct smc_timing flash_timing __initdata = {
|
||||
.ncs_read_setup = 0,
|
||||
.nrd_setup = 40,
|
||||
.ncs_write_setup = 0,
|
||||
|
@ -28,7 +28,9 @@ static struct smc_config flash_config __initdata = {
|
|||
|
||||
.read_cycle = 120,
|
||||
.write_cycle = 120,
|
||||
};
|
||||
|
||||
static struct smc_config flash_config __initdata = {
|
||||
.bus_width = 2,
|
||||
.nrd_controlled = 1,
|
||||
.nwe_controlled = 1,
|
||||
|
@ -82,6 +84,7 @@ static int __init atngw100_flash_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
smc_set_timing(&flash_config, &flash_timing);
|
||||
ret = smc_set_configuration(0, &flash_config);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "atngw100: failed to set NOR flash timing\n");
|
||||
|
|
|
@ -125,8 +125,11 @@ static struct platform_device ngw_gpio_leds = {
|
|||
};
|
||||
|
||||
static struct i2c_gpio_platform_data i2c_gpio_data = {
|
||||
.sda_pin = GPIO_PIN_PA(6),
|
||||
.scl_pin = GPIO_PIN_PA(7),
|
||||
.sda_pin = GPIO_PIN_PA(6),
|
||||
.scl_pin = GPIO_PIN_PA(7),
|
||||
.sda_is_open_drain = 1,
|
||||
.scl_is_open_drain = 1,
|
||||
.udelay = 2, /* close to 100 kHz */
|
||||
};
|
||||
|
||||
static struct platform_device i2c_gpio_device = {
|
||||
|
@ -154,6 +157,7 @@ static int __init atngw100_init(void)
|
|||
set_hw_addr(at32_add_device_eth(1, ð_data[1]));
|
||||
|
||||
at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
|
||||
at32_add_device_usba(0, NULL);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) {
|
||||
at32_select_gpio(ngw_leds[i].gpio,
|
||||
|
@ -161,8 +165,10 @@ static int __init atngw100_init(void)
|
|||
}
|
||||
platform_device_register(&ngw_gpio_leds);
|
||||
|
||||
at32_select_gpio(i2c_gpio_data.sda_pin, 0);
|
||||
at32_select_gpio(i2c_gpio_data.scl_pin, 0);
|
||||
at32_select_gpio(i2c_gpio_data.sda_pin,
|
||||
AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
|
||||
at32_select_gpio(i2c_gpio_data.scl_pin,
|
||||
AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
|
||||
platform_device_register(&i2c_gpio_device);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -241,6 +241,7 @@ static int __init atstk1002_init(void)
|
|||
at32_add_device_lcdc(0, &atstk1000_lcdc_data,
|
||||
fbmem_start, fbmem_size);
|
||||
#endif
|
||||
at32_add_device_usba(0, NULL);
|
||||
#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
|
||||
at32_add_device_ssc(0, ATMEL_SSC_TX);
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include <asm/arch/smc.h>
|
||||
|
||||
static struct smc_config flash_config __initdata = {
|
||||
static struct smc_timing flash_timing __initdata = {
|
||||
.ncs_read_setup = 0,
|
||||
.nrd_setup = 40,
|
||||
.ncs_write_setup = 0,
|
||||
|
@ -28,7 +28,9 @@ static struct smc_config flash_config __initdata = {
|
|||
|
||||
.read_cycle = 120,
|
||||
.write_cycle = 120,
|
||||
};
|
||||
|
||||
static struct smc_config flash_config __initdata = {
|
||||
.bus_width = 2,
|
||||
.nrd_controlled = 1,
|
||||
.nwe_controlled = 1,
|
||||
|
@ -82,6 +84,7 @@ static int __init atstk1000_flash_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
smc_set_timing(&flash_config, &flash_timing);
|
||||
ret = smc_set_configuration(0, &flash_config);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "atstk1000: failed to set NOR flash timing\n");
|
||||
|
|
|
@ -11,8 +11,3 @@ obj-y += signal.o sys_avr32.o process.o time.o
|
|||
obj-y += init_task.o switch_to.o cpu.o
|
||||
obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o
|
||||
|
||||
USE_STANDARD_AS_RULE := true
|
||||
|
||||
%.lds: %.lds.c FORCE
|
||||
$(call if_changed_dep,cpp_lds_S)
|
||||
|
|
|
@ -159,11 +159,18 @@ handle_vmalloc_miss:
|
|||
|
||||
.section .scall.text,"ax",@progbits
|
||||
system_call:
|
||||
#ifdef CONFIG_PREEMPT
|
||||
mask_interrupts
|
||||
#endif
|
||||
pushm r12 /* r12_orig */
|
||||
stmts --sp, r0-lr
|
||||
zero_fp
|
||||
|
||||
mfsr r0, SYSREG_RAR_SUP
|
||||
mfsr r1, SYSREG_RSR_SUP
|
||||
#ifdef CONFIG_PREEMPT
|
||||
unmask_interrupts
|
||||
#endif
|
||||
zero_fp
|
||||
stm --sp, r0-r1
|
||||
|
||||
/* check for syscall tracing */
|
||||
|
@ -638,6 +645,13 @@ irq_level\level:
|
|||
stmts --sp,r0-lr
|
||||
mfsr r8, rar_int\level
|
||||
mfsr r9, rsr_int\level
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
sub r11, pc, (. - system_call)
|
||||
cp.w r11, r8
|
||||
breq 4f
|
||||
#endif
|
||||
|
||||
pushm r8-r9
|
||||
|
||||
mov r11, sp
|
||||
|
@ -668,6 +682,16 @@ irq_level\level:
|
|||
sub sp, -4 /* ignore r12_orig */
|
||||
rete
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
4: mask_interrupts
|
||||
mfsr r8, rsr_int\level
|
||||
sbr r8, 16
|
||||
mtsr rsr_int\level, r8
|
||||
ldmts sp++, r0-lr
|
||||
sub sp, -4 /* ignore r12_orig */
|
||||
rete
|
||||
#endif
|
||||
|
||||
2: get_thread_info r0
|
||||
ld.w r1, r0[TI_flags]
|
||||
bld r1, TIF_CPU_GOING_TO_SLEEP
|
||||
|
|
|
@ -248,7 +248,7 @@ static int __init early_parse_fbmem(char *p)
|
|||
|
||||
fbmem_size = memparse(p, &p);
|
||||
if (*p == '@') {
|
||||
fbmem_start = memparse(p, &p);
|
||||
fbmem_start = memparse(p + 1, &p);
|
||||
ret = add_reserved_region(fbmem_start,
|
||||
fbmem_start + fbmem_size - 1,
|
||||
"Framebuffer");
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
*/
|
||||
#define LOAD_OFFSET 0x00000000
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32")
|
||||
OUTPUT_ARCH(avr32)
|
||||
|
@ -58,11 +60,10 @@ SECTIONS
|
|||
*(.init.ramfs)
|
||||
__initramfs_end = .;
|
||||
#endif
|
||||
. = ALIGN(4096);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
}
|
||||
|
||||
. = ALIGN(8192);
|
||||
.text : AT(ADDR(.text) - LOAD_OFFSET) {
|
||||
_evba = .;
|
||||
_text = .;
|
||||
|
@ -96,7 +97,7 @@ SECTIONS
|
|||
|
||||
RODATA
|
||||
|
||||
. = ALIGN(8192);
|
||||
. = ALIGN(THREAD_SIZE);
|
||||
|
||||
.data : AT(ADDR(.data) - LOAD_OFFSET) {
|
||||
_data = .;
|
||||
|
@ -107,7 +108,7 @@ SECTIONS
|
|||
*(.data.init_task)
|
||||
|
||||
/* Then, the cacheline aligned data */
|
||||
. = ALIGN(32);
|
||||
. = ALIGN(L1_CACHE_BYTES);
|
||||
*(.data.cacheline_aligned)
|
||||
|
||||
/* And the rest... */
|
|
@ -25,12 +25,6 @@
|
|||
#include "pio.h"
|
||||
#include "pm.h"
|
||||
|
||||
/*
|
||||
* We can reduce the code size a bit by using a constant here. Since
|
||||
* this file is completely chip-specific, it's safe to not use
|
||||
* ioremap. Generic drivers should of course never do this.
|
||||
*/
|
||||
#define AT32_PM_BASE 0xfff00000
|
||||
|
||||
#define PBMEM(base) \
|
||||
{ \
|
||||
|
@ -1167,6 +1161,72 @@ at32_add_device_ssc(unsigned int id, unsigned int flags)
|
|||
return pdev;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* USB Device Controller
|
||||
* -------------------------------------------------------------------- */
|
||||
static struct resource usba0_resource[] __initdata = {
|
||||
{
|
||||
.start = 0xff300000,
|
||||
.end = 0xff3fffff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}, {
|
||||
.start = 0xfff03000,
|
||||
.end = 0xfff033ff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
IRQ(31),
|
||||
};
|
||||
static struct clk usba0_pclk = {
|
||||
.name = "pclk",
|
||||
.parent = &pbb_clk,
|
||||
.mode = pbb_clk_mode,
|
||||
.get_rate = pbb_clk_get_rate,
|
||||
.index = 12,
|
||||
};
|
||||
static struct clk usba0_hclk = {
|
||||
.name = "hclk",
|
||||
.parent = &hsb_clk,
|
||||
.mode = hsb_clk_mode,
|
||||
.get_rate = hsb_clk_get_rate,
|
||||
.index = 6,
|
||||
};
|
||||
|
||||
struct platform_device *__init
|
||||
at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
|
||||
if (id != 0)
|
||||
return NULL;
|
||||
|
||||
pdev = platform_device_alloc("atmel_usba_udc", 0);
|
||||
if (!pdev)
|
||||
return NULL;
|
||||
|
||||
if (platform_device_add_resources(pdev, usba0_resource,
|
||||
ARRAY_SIZE(usba0_resource)))
|
||||
goto out_free_pdev;
|
||||
|
||||
if (data) {
|
||||
if (platform_device_add_data(pdev, data, sizeof(*data)))
|
||||
goto out_free_pdev;
|
||||
|
||||
if (data->vbus_pin != GPIO_PIN_NONE)
|
||||
at32_select_gpio(data->vbus_pin, 0);
|
||||
}
|
||||
|
||||
usba0_pclk.dev = &pdev->dev;
|
||||
usba0_hclk.dev = &pdev->dev;
|
||||
|
||||
platform_device_add(pdev);
|
||||
|
||||
return pdev;
|
||||
|
||||
out_free_pdev:
|
||||
platform_device_put(pdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* GCLK
|
||||
* -------------------------------------------------------------------- */
|
||||
|
@ -1252,6 +1312,8 @@ struct clk *at32_clock_list[] = {
|
|||
&ssc0_pclk,
|
||||
&ssc1_pclk,
|
||||
&ssc2_pclk,
|
||||
&usba0_hclk,
|
||||
&usba0_pclk,
|
||||
&gclk0,
|
||||
&gclk1,
|
||||
&gclk2,
|
||||
|
|
|
@ -150,3 +150,119 @@ struct clk *clk_get_parent(struct clk *clk)
|
|||
return clk->parent;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_parent);
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
/* /sys/kernel/debug/at32ap_clk */
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include "pm.h"
|
||||
|
||||
|
||||
#define NEST_DELTA 2
|
||||
#define NEST_MAX 6
|
||||
|
||||
struct clkinf {
|
||||
struct seq_file *s;
|
||||
unsigned nest;
|
||||
};
|
||||
|
||||
static void
|
||||
dump_clock(struct clk *parent, struct clkinf *r)
|
||||
{
|
||||
unsigned nest = r->nest;
|
||||
char buf[16 + NEST_MAX];
|
||||
struct clk *clk;
|
||||
unsigned i;
|
||||
|
||||
/* skip clocks coupled to devices that aren't registered */
|
||||
if (parent->dev && !parent->dev->bus_id[0] && !parent->users)
|
||||
return;
|
||||
|
||||
/* <nest spaces> name <pad to end> */
|
||||
memset(buf, ' ', sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
i = strlen(parent->name);
|
||||
memcpy(buf + nest, parent->name,
|
||||
min(i, (unsigned)(sizeof(buf) - 1 - nest)));
|
||||
|
||||
seq_printf(r->s, "%s%c users=%2d %-3s %9ld Hz",
|
||||
buf, parent->set_parent ? '*' : ' ',
|
||||
parent->users,
|
||||
parent->users ? "on" : "off", /* NOTE: not-paranoid!! */
|
||||
clk_get_rate(parent));
|
||||
if (parent->dev)
|
||||
seq_printf(r->s, ", for %s", parent->dev->bus_id);
|
||||
seq_printf(r->s, "\n");
|
||||
|
||||
/* cost of this scan is small, but not linear... */
|
||||
r->nest = nest + NEST_DELTA;
|
||||
for (i = 3; i < at32_nr_clocks; i++) {
|
||||
clk = at32_clock_list[i];
|
||||
if (clk->parent == parent)
|
||||
dump_clock(clk, r);
|
||||
}
|
||||
r->nest = nest;
|
||||
}
|
||||
|
||||
static int clk_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
struct clkinf r;
|
||||
int i;
|
||||
|
||||
/* show all the power manager registers */
|
||||
seq_printf(s, "MCCTRL = %8x\n", pm_readl(MCCTRL));
|
||||
seq_printf(s, "CKSEL = %8x\n", pm_readl(CKSEL));
|
||||
seq_printf(s, "CPUMASK = %8x\n", pm_readl(CPU_MASK));
|
||||
seq_printf(s, "HSBMASK = %8x\n", pm_readl(HSB_MASK));
|
||||
seq_printf(s, "PBAMASK = %8x\n", pm_readl(PBA_MASK));
|
||||
seq_printf(s, "PBBMASK = %8x\n", pm_readl(PBB_MASK));
|
||||
seq_printf(s, "PLL0 = %8x\n", pm_readl(PLL0));
|
||||
seq_printf(s, "PLL1 = %8x\n", pm_readl(PLL1));
|
||||
seq_printf(s, "IMR = %8x\n", pm_readl(IMR));
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i == 5)
|
||||
continue;
|
||||
seq_printf(s, "GCCTRL%d = %8x\n", i, pm_readl(GCCTRL(i)));
|
||||
}
|
||||
|
||||
seq_printf(s, "\n");
|
||||
|
||||
/* show clock tree as derived from the three oscillators
|
||||
* we "know" are at the head of the list
|
||||
*/
|
||||
r.s = s;
|
||||
r.nest = 0;
|
||||
dump_clock(at32_clock_list[0], &r);
|
||||
dump_clock(at32_clock_list[1], &r);
|
||||
dump_clock(at32_clock_list[2], &r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, clk_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations clk_operations = {
|
||||
.open = clk_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init clk_debugfs_init(void)
|
||||
{
|
||||
(void) debugfs_create_file("at32ap_clk", S_IFREG | S_IRUGO,
|
||||
NULL, NULL, &clk_operations);
|
||||
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(clk_debugfs_init);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,16 +29,25 @@ struct hsmc {
|
|||
|
||||
static struct hsmc *hsmc;
|
||||
|
||||
int smc_set_configuration(int cs, const struct smc_config *config)
|
||||
void smc_set_timing(struct smc_config *config,
|
||||
const struct smc_timing *timing)
|
||||
{
|
||||
unsigned long mul;
|
||||
unsigned long offset;
|
||||
u32 setup, pulse, cycle, mode;
|
||||
int recover;
|
||||
int cycle;
|
||||
|
||||
if (!hsmc)
|
||||
return -ENODEV;
|
||||
if (cs >= NR_CHIP_SELECTS)
|
||||
return -EINVAL;
|
||||
unsigned long mul;
|
||||
|
||||
/* Reset all SMC timings */
|
||||
config->ncs_read_setup = 0;
|
||||
config->nrd_setup = 0;
|
||||
config->ncs_write_setup = 0;
|
||||
config->nwe_setup = 0;
|
||||
config->ncs_read_pulse = 0;
|
||||
config->nrd_pulse = 0;
|
||||
config->ncs_write_pulse = 0;
|
||||
config->nwe_pulse = 0;
|
||||
config->read_cycle = 0;
|
||||
config->write_cycle = 0;
|
||||
|
||||
/*
|
||||
* cycles = x / T = x * f
|
||||
|
@ -50,16 +59,102 @@ int smc_set_configuration(int cs, const struct smc_config *config)
|
|||
|
||||
#define ns2cyc(x) ((((x) * mul) + 65535) >> 16)
|
||||
|
||||
setup = (HSMC_BF(NWE_SETUP, ns2cyc(config->nwe_setup))
|
||||
| HSMC_BF(NCS_WR_SETUP, ns2cyc(config->ncs_write_setup))
|
||||
| HSMC_BF(NRD_SETUP, ns2cyc(config->nrd_setup))
|
||||
| HSMC_BF(NCS_RD_SETUP, ns2cyc(config->ncs_read_setup)));
|
||||
pulse = (HSMC_BF(NWE_PULSE, ns2cyc(config->nwe_pulse))
|
||||
| HSMC_BF(NCS_WR_PULSE, ns2cyc(config->ncs_write_pulse))
|
||||
| HSMC_BF(NRD_PULSE, ns2cyc(config->nrd_pulse))
|
||||
| HSMC_BF(NCS_RD_PULSE, ns2cyc(config->ncs_read_pulse)));
|
||||
cycle = (HSMC_BF(NWE_CYCLE, ns2cyc(config->write_cycle))
|
||||
| HSMC_BF(NRD_CYCLE, ns2cyc(config->read_cycle)));
|
||||
if (timing->ncs_read_setup > 0)
|
||||
config->ncs_read_setup = ns2cyc(timing->ncs_read_setup);
|
||||
|
||||
if (timing->nrd_setup > 0)
|
||||
config->nrd_setup = ns2cyc(timing->nrd_setup);
|
||||
|
||||
if (timing->ncs_write_setup > 0)
|
||||
config->ncs_write_setup = ns2cyc(timing->ncs_write_setup);
|
||||
|
||||
if (timing->nwe_setup > 0)
|
||||
config->nwe_setup = ns2cyc(timing->nwe_setup);
|
||||
|
||||
if (timing->ncs_read_pulse > 0)
|
||||
config->ncs_read_pulse = ns2cyc(timing->ncs_read_pulse);
|
||||
|
||||
if (timing->nrd_pulse > 0)
|
||||
config->nrd_pulse = ns2cyc(timing->nrd_pulse);
|
||||
|
||||
if (timing->ncs_write_pulse > 0)
|
||||
config->ncs_write_pulse = ns2cyc(timing->ncs_write_pulse);
|
||||
|
||||
if (timing->nwe_pulse > 0)
|
||||
config->nwe_pulse = ns2cyc(timing->nwe_pulse);
|
||||
|
||||
if (timing->read_cycle > 0)
|
||||
config->read_cycle = ns2cyc(timing->read_cycle);
|
||||
|
||||
if (timing->write_cycle > 0)
|
||||
config->write_cycle = ns2cyc(timing->write_cycle);
|
||||
|
||||
/* Extend read cycle in needed */
|
||||
if (timing->ncs_read_recover > 0)
|
||||
recover = ns2cyc(timing->ncs_read_recover);
|
||||
else
|
||||
recover = 1;
|
||||
|
||||
cycle = config->ncs_read_setup + config->ncs_read_pulse + recover;
|
||||
|
||||
if (config->read_cycle < cycle)
|
||||
config->read_cycle = cycle;
|
||||
|
||||
/* Extend read cycle in needed */
|
||||
if (timing->nrd_recover > 0)
|
||||
recover = ns2cyc(timing->nrd_recover);
|
||||
else
|
||||
recover = 1;
|
||||
|
||||
cycle = config->nrd_setup + config->nrd_pulse + recover;
|
||||
|
||||
if (config->read_cycle < cycle)
|
||||
config->read_cycle = cycle;
|
||||
|
||||
/* Extend write cycle in needed */
|
||||
if (timing->ncs_write_recover > 0)
|
||||
recover = ns2cyc(timing->ncs_write_recover);
|
||||
else
|
||||
recover = 1;
|
||||
|
||||
cycle = config->ncs_write_setup + config->ncs_write_pulse + recover;
|
||||
|
||||
if (config->write_cycle < cycle)
|
||||
config->write_cycle = cycle;
|
||||
|
||||
/* Extend write cycle in needed */
|
||||
if (timing->nwe_recover > 0)
|
||||
recover = ns2cyc(timing->nwe_recover);
|
||||
else
|
||||
recover = 1;
|
||||
|
||||
cycle = config->nwe_setup + config->nwe_pulse + recover;
|
||||
|
||||
if (config->write_cycle < cycle)
|
||||
config->write_cycle = cycle;
|
||||
}
|
||||
EXPORT_SYMBOL(smc_set_timing);
|
||||
|
||||
int smc_set_configuration(int cs, const struct smc_config *config)
|
||||
{
|
||||
unsigned long offset;
|
||||
u32 setup, pulse, cycle, mode;
|
||||
|
||||
if (!hsmc)
|
||||
return -ENODEV;
|
||||
if (cs >= NR_CHIP_SELECTS)
|
||||
return -EINVAL;
|
||||
|
||||
setup = (HSMC_BF(NWE_SETUP, config->nwe_setup)
|
||||
| HSMC_BF(NCS_WR_SETUP, config->ncs_write_setup)
|
||||
| HSMC_BF(NRD_SETUP, config->nrd_setup)
|
||||
| HSMC_BF(NCS_RD_SETUP, config->ncs_read_setup));
|
||||
pulse = (HSMC_BF(NWE_PULSE, config->nwe_pulse)
|
||||
| HSMC_BF(NCS_WR_PULSE, config->ncs_write_pulse)
|
||||
| HSMC_BF(NRD_PULSE, config->nrd_pulse)
|
||||
| HSMC_BF(NCS_RD_PULSE, config->ncs_read_pulse));
|
||||
cycle = (HSMC_BF(NWE_CYCLE, config->write_cycle)
|
||||
| HSMC_BF(NRD_CYCLE, config->read_cycle));
|
||||
|
||||
switch (config->bus_width) {
|
||||
case 1:
|
||||
|
|
|
@ -110,6 +110,10 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags)
|
|||
pio_writel(pio, SODR, mask);
|
||||
else
|
||||
pio_writel(pio, CODR, mask);
|
||||
if (flags & AT32_GPIOF_MULTIDRV)
|
||||
pio_writel(pio, MDER, mask);
|
||||
else
|
||||
pio_writel(pio, MDDR, mask);
|
||||
pio_writel(pio, PUDR, mask);
|
||||
pio_writel(pio, OER, mask);
|
||||
} else {
|
||||
|
|
|
@ -4,6 +4,14 @@
|
|||
#ifndef __ARCH_AVR32_MACH_AT32AP_PM_H__
|
||||
#define __ARCH_AVR32_MACH_AT32AP_PM_H__
|
||||
|
||||
/*
|
||||
* We can reduce the code size a bit by using a constant here. Since
|
||||
* this file is only used on AVR32 AP CPUs with segmentation enabled,
|
||||
* it's safe to not use ioremap. Generic drivers should of course
|
||||
* never do this.
|
||||
*/
|
||||
#define AT32_PM_BASE 0xfff00000
|
||||
|
||||
/* PM register offsets */
|
||||
#define PM_MCCTRL 0x0000
|
||||
#define PM_CKSEL 0x0004
|
||||
|
|
|
@ -224,19 +224,9 @@ void free_initmem(void)
|
|||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
|
||||
static int keep_initrd;
|
||||
|
||||
void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
{
|
||||
if (!keep_initrd)
|
||||
free_area(start, end, "initrd");
|
||||
free_area(start, end, "initrd");
|
||||
}
|
||||
|
||||
static int __init keepinitrd_setup(char *__unused)
|
||||
{
|
||||
keep_initrd = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("keepinitrd", keepinitrd_setup);
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define GPIO_PIN_NONE (-1)
|
||||
|
||||
/* Add basic devices: system manager, interrupt controller, portmuxes, etc. */
|
||||
void at32_add_system_devices(void);
|
||||
|
||||
|
@ -36,6 +38,12 @@ struct platform_device *
|
|||
at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
|
||||
unsigned long fbmem_start, unsigned long fbmem_len);
|
||||
|
||||
struct usba_platform_data {
|
||||
int vbus_pin;
|
||||
};
|
||||
struct platform_device *
|
||||
at32_add_device_usba(unsigned int id, struct usba_platform_data *data);
|
||||
|
||||
/* depending on what's hooked up, not all SSC pins will be used */
|
||||
#define ATMEL_SSC_TK 0x01
|
||||
#define ATMEL_SSC_TF 0x02
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define AT32_GPIOF_OUTPUT 0x00000002 /* (OUT) Enable output driver */
|
||||
#define AT32_GPIOF_HIGH 0x00000004 /* (OUT) Set output high */
|
||||
#define AT32_GPIOF_DEGLITCH 0x00000008 /* (IN) Filter glitches */
|
||||
#define AT32_GPIOF_MULTIDRV 0x00000010 /* Enable multidriver option */
|
||||
|
||||
void at32_select_periph(unsigned int pin, unsigned int periph,
|
||||
unsigned long flags);
|
||||
|
|
|
@ -15,22 +15,50 @@
|
|||
/*
|
||||
* All timing parameters are in nanoseconds.
|
||||
*/
|
||||
struct smc_config {
|
||||
struct smc_timing {
|
||||
/* Delay from address valid to assertion of given strobe */
|
||||
u16 ncs_read_setup;
|
||||
u16 nrd_setup;
|
||||
u16 ncs_write_setup;
|
||||
u16 nwe_setup;
|
||||
int ncs_read_setup;
|
||||
int nrd_setup;
|
||||
int ncs_write_setup;
|
||||
int nwe_setup;
|
||||
|
||||
/* Pulse length of given strobe */
|
||||
u16 ncs_read_pulse;
|
||||
u16 nrd_pulse;
|
||||
u16 ncs_write_pulse;
|
||||
u16 nwe_pulse;
|
||||
int ncs_read_pulse;
|
||||
int nrd_pulse;
|
||||
int ncs_write_pulse;
|
||||
int nwe_pulse;
|
||||
|
||||
/* Total cycle length of given operation */
|
||||
u16 read_cycle;
|
||||
u16 write_cycle;
|
||||
int read_cycle;
|
||||
int write_cycle;
|
||||
|
||||
/* Minimal recovery times, will extend cycle if needed */
|
||||
int ncs_read_recover;
|
||||
int nrd_recover;
|
||||
int ncs_write_recover;
|
||||
int nwe_recover;
|
||||
};
|
||||
|
||||
/*
|
||||
* All timing parameters are in clock cycles.
|
||||
*/
|
||||
struct smc_config {
|
||||
|
||||
/* Delay from address valid to assertion of given strobe */
|
||||
u8 ncs_read_setup;
|
||||
u8 nrd_setup;
|
||||
u8 ncs_write_setup;
|
||||
u8 nwe_setup;
|
||||
|
||||
/* Pulse length of given strobe */
|
||||
u8 ncs_read_pulse;
|
||||
u8 nrd_pulse;
|
||||
u8 ncs_write_pulse;
|
||||
u8 nwe_pulse;
|
||||
|
||||
/* Total cycle length of given operation */
|
||||
u8 read_cycle;
|
||||
u8 write_cycle;
|
||||
|
||||
/* Bus width in bytes */
|
||||
u8 bus_width;
|
||||
|
@ -76,6 +104,9 @@ struct smc_config {
|
|||
unsigned int tdf_mode:1;
|
||||
};
|
||||
|
||||
extern void smc_set_timing(struct smc_config *config,
|
||||
const struct smc_timing *timing);
|
||||
|
||||
extern int smc_set_configuration(int cs, const struct smc_config *config);
|
||||
extern struct smc_config *smc_get_configuration(int cs);
|
||||
|
||||
|
|
|
@ -264,7 +264,11 @@ static inline void
|
|||
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction);
|
||||
/*
|
||||
* No need to do anything since the CPU isn't supposed to
|
||||
* touch this memory after we flushed it at mapping- or
|
||||
* sync-for-device time.
|
||||
*/
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -309,12 +313,11 @@ static inline void
|
|||
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction direction)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nents; i++) {
|
||||
dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
|
||||
sg[i].length, direction);
|
||||
}
|
||||
/*
|
||||
* No need to do anything since the CPU isn't supposed to
|
||||
* touch this memory after we flushed it at mapping- or
|
||||
* sync-for-device time.
|
||||
*/
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
@ -73,11 +73,16 @@ extern struct task_struct *__switch_to(struct task_struct *,
|
|||
|
||||
extern void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
#ifdef __CHECKER__
|
||||
extern unsigned long __builtin_xchg(void *ptr, unsigned long x);
|
||||
#endif
|
||||
static inline unsigned long xchg_u32(u32 val, volatile u32 *m)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
#define xchg_u32(val, m) __builtin_xchg((void *)m, val)
|
||||
asm volatile("xchg %[ret], %[m], %[val]"
|
||||
: [ret] "=&r"(ret), "=m"(*m)
|
||||
: "m"(*m), [m] "r"(m), [val] "r"(val)
|
||||
: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline unsigned long __xchg(unsigned long x,
|
||||
volatile void *ptr,
|
||||
|
|
|
@ -303,6 +303,19 @@
|
|||
#ifdef __KERNEL__
|
||||
#define NR_syscalls 282
|
||||
|
||||
/* Old stuff */
|
||||
#define __IGNORE_uselib
|
||||
#define __IGNORE_mmap
|
||||
|
||||
/* NUMA stuff */
|
||||
#define __IGNORE_mbind
|
||||
#define __IGNORE_get_mempolicy
|
||||
#define __IGNORE_set_mempolicy
|
||||
#define __IGNORE_migrate_pages
|
||||
#define __IGNORE_move_pages
|
||||
|
||||
/* SMP stuff */
|
||||
#define __IGNORE_getcpu
|
||||
|
||||
#define __ARCH_WANT_IPC_PARSE_VERSION
|
||||
#define __ARCH_WANT_STAT64
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# sh64 port by Paul Mundt
|
||||
# Random bits by Matt Mackall <mpm@selenic.com>
|
||||
# M68k port by Geert Uytterhoeven and Andreas Schwab
|
||||
# AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
|
||||
#
|
||||
# Usage:
|
||||
# objdump -d vmlinux | stackcheck.pl [arch]
|
||||
|
@ -37,6 +38,10 @@ my (@stack, $re, $x, $xs);
|
|||
if ($arch eq 'arm') {
|
||||
#c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
|
||||
$re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
|
||||
} elsif ($arch eq 'avr32') {
|
||||
#8000008a: 20 1d sub sp,4
|
||||
#80000ca8: fa cd 05 b0 sub sp,sp,1456
|
||||
$re = qr/^.*sub.*sp.*,([0-9]{1,8})/o;
|
||||
} elsif ($arch =~ /^i[3456]86$/) {
|
||||
#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
|
||||
$re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%esp$/o;
|
||||
|
|
Loading…
Reference in a new issue