提交 698158c7 编写于 作者: M Mauro Carvalho Chehab

Merge ../linux-2.6

......@@ -2034,6 +2034,9 @@ and is between 256 and 4096 characters. It is defined in the file
snd-ymfpci= [HW,ALSA]
softlockup_panic=
[KNL] Should the soft-lockup detector generate panics.
sonypi.*= [HW] Sony Programmable I/O Control Device driver
See Documentation/sonypi.txt
......
......@@ -441,10 +441,7 @@ M: spyro@f2s.com
S: Maintained
ARM PRIMECELL MMCI PL180/1 DRIVER
P: Russell King
M: rmk@arm.linux.org.uk
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
S: Orphan
ARM/ADI ROADRUNNER MACHINE SUPPORT
P: Lennert Buytenhek
......@@ -483,11 +480,28 @@ M: kernel@wantstofly.org
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
ARM/COMPULAB CM-X270/EM-X270 MACHINE SUPPORT
P: Mike Rapoport
M: mike@compulab.co.il
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
ARM/CORGI MACHINE SUPPORT
P: Richard Purdie
M: rpurdie@rpsys.net
S: Maintained
ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
P: Daniel Ribeiro
M: drwyrm@gmail.com
P: Stefan Schmidt
M: stefan@openezx.org
P: Harald Welte
M: laforge@openezx.org
L: openezx-devel@lists.openezx.org (subscribers-only)
W: http://www.openezx.org/
S: Maintained
ARM/GLOMATION GESBC9312SX MACHINE SUPPORT
P: Lennert Buytenhek
M: kernel@wantstofly.org
......@@ -575,10 +589,18 @@ L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
ARM/TOSA MACHINE SUPPORT
P: Dmitry Baryshkov
M: dbaryshkov@gmail.com
P: Dirk Opfer
M: dirk@opfer-online.de
S: Maintained
ARM/PALMTX SUPPORT
P: Marek Vasut
M: marek.vasut@gmail.com
W: http://hackndev.com
S: Maintained
ARM/PLEB SUPPORT
P: Peter Chubb
M: pleb@gelato.unsw.edu.au
......
......@@ -12,6 +12,7 @@ config ARM
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
select HAVE_OPROFILE
select HAVE_ARCH_KGDB
select HAVE_KPROBES if (!XIP_KERNEL)
select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FTRACE if (!XIP_KERNEL)
......
......@@ -627,7 +627,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
if (!sachip)
return -ENOMEM;
sachip->clk = clk_get(me, "GPIO27_CLK");
sachip->clk = clk_get(me, "SA1111_CLK");
if (!sachip->clk) {
ret = PTR_ERR(sachip->clk);
goto err_free;
......
此差异已折叠。
......@@ -28,6 +28,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o
obj-$(CONFIG_ATAGS_PROC) += atags.o
obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
......
/*
* arch/arm/kernel/kgdb.c
*
* ARM KGDB support
*
* Copyright (c) 2002-2004 MontaVista Software, Inc
* Copyright (c) 2008 Wind River Systems, Inc.
*
* Authors: George Davis <davis_g@mvista.com>
* Deepak Saxena <dsaxena@plexity.net>
*/
#include <linux/kgdb.h>
#include <asm/traps.h>
/* Make a local copy of the registers passed into the handler (bletch) */
void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
{
int regno;
/* Initialize all to zero. */
for (regno = 0; regno < GDB_MAX_REGS; regno++)
gdb_regs[regno] = 0;
gdb_regs[_R0] = kernel_regs->ARM_r0;
gdb_regs[_R1] = kernel_regs->ARM_r1;
gdb_regs[_R2] = kernel_regs->ARM_r2;
gdb_regs[_R3] = kernel_regs->ARM_r3;
gdb_regs[_R4] = kernel_regs->ARM_r4;
gdb_regs[_R5] = kernel_regs->ARM_r5;
gdb_regs[_R6] = kernel_regs->ARM_r6;
gdb_regs[_R7] = kernel_regs->ARM_r7;
gdb_regs[_R8] = kernel_regs->ARM_r8;
gdb_regs[_R9] = kernel_regs->ARM_r9;
gdb_regs[_R10] = kernel_regs->ARM_r10;
gdb_regs[_FP] = kernel_regs->ARM_fp;
gdb_regs[_IP] = kernel_regs->ARM_ip;
gdb_regs[_SPT] = kernel_regs->ARM_sp;
gdb_regs[_LR] = kernel_regs->ARM_lr;
gdb_regs[_PC] = kernel_regs->ARM_pc;
gdb_regs[_CPSR] = kernel_regs->ARM_cpsr;
}
/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
{
kernel_regs->ARM_r0 = gdb_regs[_R0];
kernel_regs->ARM_r1 = gdb_regs[_R1];
kernel_regs->ARM_r2 = gdb_regs[_R2];
kernel_regs->ARM_r3 = gdb_regs[_R3];
kernel_regs->ARM_r4 = gdb_regs[_R4];
kernel_regs->ARM_r5 = gdb_regs[_R5];
kernel_regs->ARM_r6 = gdb_regs[_R6];
kernel_regs->ARM_r7 = gdb_regs[_R7];
kernel_regs->ARM_r8 = gdb_regs[_R8];
kernel_regs->ARM_r9 = gdb_regs[_R9];
kernel_regs->ARM_r10 = gdb_regs[_R10];
kernel_regs->ARM_fp = gdb_regs[_FP];
kernel_regs->ARM_ip = gdb_regs[_IP];
kernel_regs->ARM_sp = gdb_regs[_SPT];
kernel_regs->ARM_lr = gdb_regs[_LR];
kernel_regs->ARM_pc = gdb_regs[_PC];
kernel_regs->ARM_cpsr = gdb_regs[_CPSR];
}
void
sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
{
struct pt_regs *thread_regs;
int regno;
/* Just making sure... */
if (task == NULL)
return;
/* Initialize to zero */
for (regno = 0; regno < GDB_MAX_REGS; regno++)
gdb_regs[regno] = 0;
/* Otherwise, we have only some registers from switch_to() */
thread_regs = task_pt_regs(task);
gdb_regs[_R0] = thread_regs->ARM_r0;
gdb_regs[_R1] = thread_regs->ARM_r1;
gdb_regs[_R2] = thread_regs->ARM_r2;
gdb_regs[_R3] = thread_regs->ARM_r3;
gdb_regs[_R4] = thread_regs->ARM_r4;
gdb_regs[_R5] = thread_regs->ARM_r5;
gdb_regs[_R6] = thread_regs->ARM_r6;
gdb_regs[_R7] = thread_regs->ARM_r7;
gdb_regs[_R8] = thread_regs->ARM_r8;
gdb_regs[_R9] = thread_regs->ARM_r9;
gdb_regs[_R10] = thread_regs->ARM_r10;
gdb_regs[_FP] = thread_regs->ARM_fp;
gdb_regs[_IP] = thread_regs->ARM_ip;
gdb_regs[_SPT] = thread_regs->ARM_sp;
gdb_regs[_LR] = thread_regs->ARM_lr;
gdb_regs[_PC] = thread_regs->ARM_pc;
gdb_regs[_CPSR] = thread_regs->ARM_cpsr;
}
static int compiled_break;
int kgdb_arch_handle_exception(int exception_vector, int signo,
int err_code, char *remcom_in_buffer,
char *remcom_out_buffer,
struct pt_regs *linux_regs)
{
unsigned long addr;
char *ptr;
switch (remcom_in_buffer[0]) {
case 'D':
case 'k':
case 'c':
kgdb_contthread = NULL;
/*
* Try to read optional parameter, pc unchanged if no parm.
* If this was a compiled breakpoint, we need to move
* to the next instruction or we will just breakpoint
* over and over again.
*/
ptr = &remcom_in_buffer[1];
if (kgdb_hex2long(&ptr, &addr))
linux_regs->ARM_pc = addr;
else if (compiled_break == 1)
linux_regs->ARM_pc += 4;
compiled_break = 0;
return 0;
}
return -1;
}
static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
{
kgdb_handle_exception(1, SIGTRAP, 0, regs);
return 0;
}
static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
{
compiled_break = 1;
kgdb_handle_exception(1, SIGTRAP, 0, regs);
return 0;
}
static struct undef_hook kgdb_brkpt_hook = {
.instr_mask = 0xffffffff,
.instr_val = KGDB_BREAKINST,
.fn = kgdb_brk_fn
};
static struct undef_hook kgdb_compiled_brkpt_hook = {
.instr_mask = 0xffffffff,
.instr_val = KGDB_COMPILED_BREAK,
.fn = kgdb_compiled_brk_fn
};
/**
* kgdb_arch_init - Perform any architecture specific initalization.
*
* This function will handle the initalization of any architecture
* specific callbacks.
*/
int kgdb_arch_init(void)
{
register_undef_hook(&kgdb_brkpt_hook);
register_undef_hook(&kgdb_compiled_brkpt_hook);
return 0;
}
/**
* kgdb_arch_exit - Perform any architecture specific uninitalization.
*
* This function will handle the uninitalization of any architecture
* specific callbacks, for dynamic registration and unregistration.
*/
void kgdb_arch_exit(void)
{
unregister_undef_hook(&kgdb_brkpt_hook);
unregister_undef_hook(&kgdb_compiled_brkpt_hook);
}
/*
* Register our undef instruction hooks with ARM undef core.
* We regsiter a hook specifically looking for the KGB break inst
* and we handle the normal undef case within the do_undefinstr
* handler.
*/
struct kgdb_arch arch_kgdb_ops = {
#ifndef __ARMEB__
.gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
#else /* ! __ARMEB__ */
.gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}
#endif
};
......@@ -36,6 +36,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/traps.h>
#include "compat.h"
#include "atags.h"
......@@ -853,6 +854,7 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
#endif
early_trap_init();
}
......
......@@ -707,6 +707,11 @@ void abort(void)
EXPORT_SYMBOL(abort);
void __init trap_init(void)
{
return;
}
void __init early_trap_init(void)
{
unsigned long vectors = CONFIG_VECTORS_BASE;
extern char __stubs_start[], __stubs_end[];
......
......@@ -16,18 +16,24 @@ config CPU_PXA310
config CPU_PXA320
bool "PXA320 (codename Monahans-P)"
config CPU_PXA930
bool "PXA930 (codename Tavor-P)"
endmenu
endif
menu "Select target boards"
config ARCH_GUMSTIX
bool "Gumstix XScale boards"
help
Say Y here if you intend to run this kernel on a
Gumstix Full Function Minature Computer.
config MACH_GUMSTIX_F
bool "Basix, Connex, ws-200ax, ws-400ax systems"
depends on ARCH_GUMSTIX
select PXA25x
config ARCH_LUBBOCK
bool "Intel DBPXA250 Development Platform"
select PXA25x
......@@ -58,6 +64,57 @@ config PXA_SHARPSL
SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
handheld computer.
config MACH_POODLE
bool "Enable Sharp SL-5600 (Poodle) Support"
depends on PXA_SHARPSL
select PXA25x
select SHARP_LOCOMO
select PXA_SSP
config MACH_CORGI
bool "Enable Sharp SL-C700 (Corgi) Support"
depends on PXA_SHARPSL
select PXA25x
select PXA_SHARP_C7xx
config MACH_SHEPHERD
bool "Enable Sharp SL-C750 (Shepherd) Support"
depends on PXA_SHARPSL
select PXA25x
select PXA_SHARP_C7xx
config MACH_HUSKY
bool "Enable Sharp SL-C760 (Husky) Support"
depends on PXA_SHARPSL
select PXA25x
select PXA_SHARP_C7xx
config MACH_AKITA
bool "Enable Sharp SL-1000 (Akita) Support"
depends on PXA_SHARPSL
select PXA27x
select PXA_SHARP_Cxx00
select MACH_SPITZ
select I2C
select I2C_PXA
config MACH_SPITZ
bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
depends on PXA_SHARPSL
select PXA27x
select PXA_SHARP_Cxx00
config MACH_BORZOI
bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
depends on PXA_SHARPSL
select PXA27x
select PXA_SHARP_Cxx00
config MACH_TOSA
bool "Enable Sharp SL-6000x (Tosa) Support"
depends on PXA_SHARPSL
select PXA25x
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
select PXA25x
......@@ -70,10 +127,19 @@ config MACH_E330
Say Y here if you intend to run this kernel on a Toshiba
e330 family PDA.
config MACH_E350
bool "Toshiba e350"
default y
depends on ARCH_PXA_ESERIES
help
Say Y here if you intend to run this kernel on a Toshiba
e350 family PDA.
config MACH_E740
bool "Toshiba e740"
default y
depends on ARCH_PXA_ESERIES
select FB_W100
help
Say Y here if you intend to run this kernel on a Toshiba
e740 family PDA.
......@@ -82,6 +148,7 @@ config MACH_E750
bool "Toshiba e750"
default y
depends on ARCH_PXA_ESERIES
select FB_W100
help
Say Y here if you intend to run this kernel on a Toshiba
e750 family PDA.
......@@ -98,6 +165,7 @@ config MACH_E800
bool "Toshiba e800"
default y
depends on ARCH_PXA_ESERIES
select FB_W100
help
Say Y here if you intend to run this kernel on a Toshiba
e800 family PDA.
......@@ -106,6 +174,10 @@ config MACH_TRIZEPS4
bool "Keith und Koep Trizeps4 DIMM-Module"
select PXA27x
config MACH_TRIZEPS4_CONXS
bool "ConXS Eval Board"
depends on MACH_TRIZEPS4
config MACH_EM_X270
bool "CompuLab EM-x270 platform"
select PXA27x
......@@ -115,7 +187,7 @@ config MACH_COLIBRI
select PXA27x
config MACH_ZYLONITE
bool "PXA3xx Development Platform"
bool "PXA3xx Development Platform (aka Zylonite)"
select PXA3xx
select HAVE_PWM
......@@ -124,6 +196,16 @@ config MACH_LITTLETON
select PXA3xx
select PXA_SSP
config MACH_TAVOREVB
bool "PXA930 Evaluation Board (aka TavorEVB)"
select PXA3xx
select PXA930
config MACH_SAAR
bool "PXA930 Handheld Platform (aka SAAR)"
select PXA3xx
select PXA930
config MACH_ARMCORE
bool "CompuLab CM-X270 modules"
select PXA27x
......@@ -131,7 +213,6 @@ config MACH_ARMCORE
config MACH_MAGICIAN
bool "Enable HTC Magician Support"
depends on ARCH_PXA
select PXA27x
select IWMMXT
......@@ -139,18 +220,26 @@ config MACH_PCM027
bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
select PXA27x
select IWMMXT
select PXA_SSP
endmenu
config ARCH_PXA_PALM
bool "PXA based Palm PDAs"
select HAVE_PWM
choice
prompt "Used baseboard"
depends on MACH_PCM027
config MACH_PALMTX
bool "Palm T|X"
default y
depends on ARCH_PXA_PALM
select PXA27x
select IWMMXT
help
Say Y here if you intend to run this kernel on a Palm T|X
handheld computer.
config MACH_PCM990_BASEBOARD
bool "PHYTEC PCM-990 development board"
select HAVE_PWM
endchoice
depends on MACH_PCM027
choice
prompt "display on pcm990"
......@@ -167,88 +256,45 @@ config PCM990_DISPLAY_NONE
endchoice
if ARCH_GUMSTIX
choice
prompt "Select target Gumstix board"
config MACH_GUMSTIX_F
bool "Basix, Connex, ws-200ax, ws-400ax systems"
select PXA25x
endchoice
endif
config PXA_EZX
bool "Motorola EZX Platform"
select PXA27x
select IWMMXT
select HAVE_PWM
if MACH_TRIZEPS4
config MACH_EZX_A780
bool "Motorola EZX A780"
default y
depends on PXA_EZX
choice
prompt "Select base board for Trizeps 4 module"
config MACH_EZX_E680
bool "Motorola EZX E680"
default y
depends on PXA_EZX
config MACH_TRIZEPS4_CONXS
bool "ConXS Eval Board"
config MACH_EZX_A1200
bool "Motorola EZX A1200"
default y
depends on PXA_EZX
config MACH_TRIZEPS4_ANY
bool "another Board"
config MACH_EZX_A910
bool "Motorola EZX A910"
default y
depends on PXA_EZX
endchoice
config MACH_EZX_E6
bool "Motorola EZX E6"
default y
depends on PXA_EZX
endif
config MACH_EZX_E2
bool "Motorola EZX E2"
default y
depends on PXA_EZX
endmenu
config MACH_POODLE
bool "Enable Sharp SL-5600 (Poodle) Support"
depends on PXA_SHARPSL
select PXA25x
select SHARP_LOCOMO
select PXA_SSP
config MACH_CORGI
bool "Enable Sharp SL-C700 (Corgi) Support"
depends on PXA_SHARPSL
select PXA25x
select PXA_SHARP_C7xx
config MACH_SHEPHERD
bool "Enable Sharp SL-C750 (Shepherd) Support"
depends on PXA_SHARPSL
select PXA25x
select PXA_SHARP_C7xx
config MACH_HUSKY
bool "Enable Sharp SL-C760 (Husky) Support"
depends on PXA_SHARPSL
select PXA25x
select PXA_SHARP_C7xx
config MACH_AKITA
bool "Enable Sharp SL-1000 (Akita) Support"
depends on PXA_SHARPSL
select PXA27x
select PXA_SHARP_Cxx00
select MACH_SPITZ
select I2C
select I2C_PXA
config MACH_SPITZ
bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
depends on PXA_SHARPSL
select PXA27x
select PXA_SHARP_Cxx00
config MACH_BORZOI
bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
depends on PXA_SHARPSL
select PXA27x
select PXA_SHARP_Cxx00
config MACH_TOSA
bool "Enable Sharp SL-6000x (Tosa) Support"
depends on PXA_SHARPSL
select PXA25x
config PXA25x
bool
help
......@@ -288,4 +334,13 @@ config PXA_PWM
default BACKLIGHT_PWM
help
Enable support for PXA2xx/PXA3xx PWM controllers
config TOSA_BT
tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
depends on MACH_TOSA
select RFKILL
help
This is a simple driver that is able to control
the state of built in bluetooth chip on tosa.
endif
......@@ -4,7 +4,7 @@
# Common support (must be linked before board specific support)
obj-y += clock.o devices.o generic.o irq.o dma.o \
time.o gpio.o
time.o gpio.o reset.o
obj-$(CONFIG_PM) += pm.o sleep.o standby.o
obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
......@@ -18,6 +18,7 @@ obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o
obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o
obj-$(CONFIG_CPU_PXA300) += pxa300.o
obj-$(CONFIG_CPU_PXA320) += pxa320.o
obj-$(CONFIG_CPU_PXA930) += pxa930.o
# Specific board support
obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
......@@ -36,7 +37,12 @@ obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o
obj-$(CONFIG_MACH_TOSA) += tosa.o
obj-$(CONFIG_MACH_EM_X270) += em-x270.o
obj-$(CONFIG_MACH_MAGICIAN) += magician.o
obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o
obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o eseries_udc.o
obj-$(CONFIG_MACH_E740) += e740_lcd.o
obj-$(CONFIG_MACH_E750) += e750_lcd.o
obj-$(CONFIG_MACH_E400) += e400_lcd.o
obj-$(CONFIG_MACH_E800) += e800_lcd.o
obj-$(CONFIG_MACH_PALMTX) += palmtx.o
ifeq ($(CONFIG_MACH_ZYLONITE),y)
obj-y += zylonite.o
......@@ -44,8 +50,11 @@ ifeq ($(CONFIG_MACH_ZYLONITE),y)
obj-$(CONFIG_CPU_PXA320) += zylonite_pxa320.o
endif
obj-$(CONFIG_MACH_LITTLETON) += littleton.o
obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
obj-$(CONFIG_MACH_SAAR) += saar.o
obj-$(CONFIG_MACH_ARMCORE) += cm-x270.o
obj-$(CONFIG_PXA_EZX) += ezx.o
# Support for blinky lights
led-y := leds.o
......@@ -59,3 +68,5 @@ obj-$(CONFIG_LEDS) += $(led-y)
ifeq ($(CONFIG_PCI),y)
obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o
endif
obj-$(CONFIG_TOSA_BT) += tosa-bt.o
......@@ -101,21 +101,6 @@ unsigned long clk_get_rate(struct clk *clk)
EXPORT_SYMBOL(clk_get_rate);
static void clk_gpio27_enable(struct clk *clk)
{
pxa_gpio_mode(GPIO11_3_6MHz_MD);
}
static void clk_gpio27_disable(struct clk *clk)
{
}
static const struct clkops clk_gpio27_ops = {
.enable = clk_gpio27_enable,
.disable = clk_gpio27_disable,
};
void clk_cken_enable(struct clk *clk)
{
CKEN |= 1 << clk->cken;
......@@ -131,14 +116,6 @@ const struct clkops clk_cken_ops = {
.disable = clk_cken_disable,
};
static struct clk common_clks[] = {
{
.name = "GPIO27_CLK",
.ops = &clk_gpio27_ops,
.rate = 3686400,
},
};
void clks_register(struct clk *clks, size_t num)
{
int i;
......@@ -148,10 +125,3 @@ void clks_register(struct clk *clks, size_t num)
list_add(&clks[i].node, &clocks);
mutex_unlock(&clocks_mutex);
}
static int __init clk_init(void)
{
clks_register(common_clks, ARRAY_SIZE(common_clks));
return 0;
}
arch_initcall(clk_init);
......@@ -47,9 +47,42 @@ struct clk {
.other = _other, \
}
#define INIT_CLK(_name, _ops, _rate, _delay, _dev) \
{ \
.name = _name, \
.dev = _dev, \
.ops = _ops, \
.rate = _rate, \
.delay = _delay, \
}
extern const struct clkops clk_cken_ops;
void clk_cken_enable(struct clk *clk);
void clk_cken_disable(struct clk *clk);
#ifdef CONFIG_PXA3xx
#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \
{ \
.name = _name, \
.dev = _dev, \
.ops = &clk_pxa3xx_cken_ops, \
.rate = _rate, \
.cken = CKEN_##_cken, \
.delay = _delay, \
}
#define PXA3xx_CK(_name, _cken, _ops, _dev) \
{ \
.name = _name, \
.dev = _dev, \
.ops = _ops, \
.cken = CKEN_##_cken, \
}
extern const struct clkops clk_pxa3xx_cken_ops;
extern void clk_pxa3xx_cken_enable(struct clk *);
extern void clk_pxa3xx_cken_disable(struct clk *);
#endif
void clks_register(struct clk *clks, size_t num);
......@@ -5,7 +5,7 @@
*
* Bits taken from various places.
*
* Copyright (C) 2007 Compulab, Ltd.
* Copyright (C) 2007, 2008 Compulab, Ltd.
* Mike Rapoport <mike@compulab.co.il>
*
* This program is free software; you can redistribute it and/or modify
......@@ -19,16 +19,16 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <asm/mach/pci.h>
#include <asm/arch/cm-x270.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa2xx-gpio.h>
#include <asm/mach-types.h>
#include <asm/hardware/it8152.h>
unsigned long it8152_base_address = CMX270_IT8152_VIRT;
unsigned long it8152_base_address;
static int cmx270_it8152_irq_gpio;
/*
* Only first 64MB of memory can be accessed via PCI.
......@@ -42,7 +42,7 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size,
unsigned int sz = SZ_64M >> PAGE_SHIFT;
if (machine_is_armcore()) {
pr_info("Adjusting zones for CM-x270\n");
pr_info("Adjusting zones for CM-X270\n");
/*
* Only adjust if > 64M on current system
......@@ -60,19 +60,20 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size,
static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
{
/* clear our parent irq */
GEDR(GPIO_IT8152_IRQ) = GPIO_bit(GPIO_IT8152_IRQ);
GEDR(cmx270_it8152_irq_gpio) = GPIO_bit(cmx270_it8152_irq_gpio);
it8152_irq_demux(irq, desc);
}
void __cmx270_pci_init_irq(void)
void __cmx270_pci_init_irq(int irq_gpio)
{
it8152_init_irq();
pxa_gpio_mode(IRQ_TO_GPIO(GPIO_IT8152_IRQ));
set_irq_type(IRQ_GPIO(GPIO_IT8152_IRQ), IRQT_RISING);
set_irq_chained_handler(IRQ_GPIO(GPIO_IT8152_IRQ),
cmx270_it8152_irq_demux);
cmx270_it8152_irq_gpio = irq_gpio;
set_irq_type(gpio_to_irq(irq_gpio), IRQT_RISING);
set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx270_it8152_irq_demux);
}
#ifdef CONFIG_PM
......@@ -115,8 +116,8 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
/*
Here comes the ugly part. The routing is baseboard specific,
but defining a platform for each possible base of CM-x270 is
unrealistic. Here we keep mapping for ATXBase and SB-x270.
but defining a platform for each possible base of CM-X270 is
unrealistic. Here we keep mapping for ATXBase and SB-X270.
*/
/* ATXBASE PCI slot */
if (slot == 7)
......
extern void __cmx270_pci_init_irq(void);
extern void __cmx270_pci_init_irq(int irq_gpio);
extern void __cmx270_pci_suspend(void);
extern void __cmx270_pci_resume(void);
#ifdef CONFIG_PCI
#define cmx270_pci_init_irq __cmx270_pci_init_irq
#define cmx270_pci_suspend __cmx270_pci_suspend
#define cmx270_pci_resume __cmx270_pci_resume
#define cmx270_pci_init_irq(x) __cmx270_pci_init_irq(x)
#define cmx270_pci_suspend(x) __cmx270_pci_suspend(x)
#define cmx270_pci_resume(x) __cmx270_pci_resume(x)
#else
#define cmx270_pci_init_irq() do {} while (0)
#define cmx270_pci_suspend() do {} while (0)
#define cmx270_pci_resume() do {} while (0)
#define cmx270_pci_init_irq(x) do {} while (0)
#define cmx270_pci_suspend(x) do {} while (0)
#define cmx270_pci_resume(x) do {} while (0)
#endif
/*
* linux/arch/arm/mach-pxa/cm-x270.c
*
* Copyright (C) 2007 CompuLab, Ltd.
* Copyright (C) 2007, 2008 CompuLab, Ltd.
* Mike Rapoport <mike@compulab.co.il>
*
* This program is free software; you can redistribute it and/or modify
......@@ -9,44 +9,156 @@
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/pm.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/sysdev.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/dm9000.h>
#include <linux/rtc-v3020.h>
#include <linux/serial_8250.h>
#include <video/mbxfb.h>
#include <linux/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa2xx-regs.h>
#include <asm/arch/pxa2xx-gpio.h>
#include <asm/arch/mfp-pxa27x.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/audio.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/ohci.h>
#include <asm/arch/mmc.h>
#include <asm/arch/bitfield.h>
#include <asm/arch/cm-x270.h>
#include <asm/hardware/it8152.h>
#include "generic.h"
#include "cm-x270-pci.h"
/* virtual addresses for statically mapped regions */
#define CMX270_VIRT_BASE (0xe8000000)
#define CMX270_IT8152_VIRT (CMX270_VIRT_BASE)
#define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22))
#define DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22))
static struct resource cmx270_dm9k_resource[] = {
/* GPIO IRQ usage */
#define GPIO10_ETHIRQ (10)
#define GPIO22_IT8152_IRQ (22)
#define GPIO83_MMC_IRQ (83)
#define GPIO95_GFXIRQ (95)
#define CMX270_ETHIRQ IRQ_GPIO(GPIO10_ETHIRQ)
#define CMX270_IT8152_IRQ IRQ_GPIO(GPIO22_IT8152_IRQ)
#define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ)
#define CMX270_GFXIRQ IRQ_GPIO(GPIO95_GFXIRQ)
/* MMC power enable */
#define GPIO105_MMC_POWER (105)
static unsigned long cmx270_pin_config[] = {
/* AC'97 */
GPIO28_AC97_BITCLK,
GPIO29_AC97_SDATA_IN_0,
GPIO30_AC97_SDATA_OUT,
GPIO31_AC97_SYNC,
GPIO98_AC97_SYSCLK,
GPIO113_AC97_nRESET,
/* BTUART */
GPIO42_BTUART_RXD,
GPIO43_BTUART_TXD,
GPIO44_BTUART_CTS,
GPIO45_BTUART_RTS,
/* STUART */
GPIO46_STUART_RXD,
GPIO47_STUART_TXD,
/* MCI controller */
GPIO32_MMC_CLK,
GPIO112_MMC_CMD,
GPIO92_MMC_DAT_0,
GPIO109_MMC_DAT_1,
GPIO110_MMC_DAT_2,
GPIO111_MMC_DAT_3,
/* LCD */
GPIO58_LCD_LDD_0,
GPIO59_LCD_LDD_1,
GPIO60_LCD_LDD_2,
GPIO61_LCD_LDD_3,
GPIO62_LCD_LDD_4,
GPIO63_LCD_LDD_5,
GPIO64_LCD_LDD_6,
GPIO65_LCD_LDD_7,
GPIO66_LCD_LDD_8,
GPIO67_LCD_LDD_9,
GPIO68_LCD_LDD_10,
GPIO69_LCD_LDD_11,
GPIO70_LCD_LDD_12,
GPIO71_LCD_LDD_13,
GPIO72_LCD_LDD_14,
GPIO73_LCD_LDD_15,
GPIO74_LCD_FCLK,
GPIO75_LCD_LCLK,
GPIO76_LCD_PCLK,
GPIO77_LCD_BIAS,
/* I2C */
GPIO117_I2C_SCL,
GPIO118_I2C_SDA,
/* SSP1 */
GPIO23_SSP1_SCLK,
GPIO24_SSP1_SFRM,
GPIO25_SSP1_TXD,
GPIO26_SSP1_RXD,
/* SSP2 */
GPIO19_SSP2_SCLK,
GPIO14_SSP2_SFRM,
GPIO87_SSP2_TXD,
GPIO88_SSP2_RXD,
/* PC Card */
GPIO48_nPOE,
GPIO49_nPWE,
GPIO50_nPIOR,
GPIO51_nPIOW,
GPIO85_nPCE_1,
GPIO54_nPCE_2,
GPIO55_nPREG,
GPIO56_nPWAIT,
GPIO57_nIOIS16,
/* SDRAM and local bus */
GPIO15_nCS_1,
GPIO78_nCS_2,
GPIO79_nCS_3,
GPIO80_nCS_4,
GPIO33_nCS_5,
GPIO49_nPWE,
GPIO18_RDY,
/* GPIO */
GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,
GPIO105_GPIO | MFP_LPM_DRIVE_HIGH, /* MMC/SD power */
GPIO53_GPIO, /* PC card reset */
/* NAND controls */
GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */
GPIO89_GPIO, /* NAND Ready/Busy */
/* interrupts */
GPIO10_GPIO, /* DM9000 interrupt */
GPIO83_GPIO, /* MMC card detect */
};
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
static struct resource cmx270_dm9000_resource[] = {
[0] = {
.start = DM9000_PHYS_BASE,
.end = DM9000_PHYS_BASE + 4,
......@@ -64,31 +176,45 @@ static struct resource cmx270_dm9k_resource[] = {
}
};
/* for the moment we limit ourselves to 32bit IO until some
* better IO routines can be written and tested
*/
static struct dm9000_plat_data cmx270_dm9k_platdata = {
static struct dm9000_plat_data cmx270_dm9000_platdata = {
.flags = DM9000_PLATF_32BITONLY,
};
/* Ethernet device */
static struct platform_device cmx270_device_dm9k = {
static struct platform_device cmx270_dm9000_device = {
.name = "dm9000",
.id = 0,
.num_resources = ARRAY_SIZE(cmx270_dm9k_resource),
.resource = cmx270_dm9k_resource,
.num_resources = ARRAY_SIZE(cmx270_dm9000_resource),
.resource = cmx270_dm9000_resource,
.dev = {
.platform_data = &cmx270_dm9k_platdata,
.platform_data = &cmx270_dm9000_platdata,
}
};
/* touchscreen controller */
static void __init cmx270_init_dm9000(void)
{
platform_device_register(&cmx270_dm9000_device);
}
#else
static inline void cmx270_init_dm9000(void) {}
#endif
/* UCB1400 touchscreen controller */
#if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
static struct platform_device cmx270_ts_device = {
.name = "ucb1400_ts",
.id = -1,
};
/* RTC */
static void __init cmx270_init_touchscreen(void)
{
platform_device_register(&cmx270_ts_device);
}
#else
static inline void cmx270_init_touchscreen(void) {}
#endif
/* V3020 RTC */
#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
static struct resource cmx270_v3020_resource[] = {
[0] = {
.start = RTC_PHYS_BASE,
......@@ -111,28 +237,67 @@ static struct platform_device cmx270_rtc_device = {
}
};
/*
* CM-X270 LEDs
*/
static void __init cmx270_init_rtc(void)
{
platform_device_register(&cmx270_rtc_device);
}
#else
static inline void cmx270_init_rtc(void) {}
#endif
/* CM-X270 LEDs */
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
static struct gpio_led cmx270_leds[] = {
[0] = {
.name = "cm-x270:red",
.default_trigger = "nand-disk",
.gpio = 93,
.active_low = 1,
},
[1] = {
.name = "cm-x270:green",
.default_trigger = "heartbeat",
.gpio = 94,
.active_low = 1,
},
};
static struct gpio_led_platform_data cmx270_gpio_led_pdata = {
.num_leds = ARRAY_SIZE(cmx270_leds),
.leds = cmx270_leds,
};
static struct platform_device cmx270_led_device = {
.name = "cm-x270-led",
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &cmx270_gpio_led_pdata,
},
};
static void __init cmx270_init_leds(void)
{
platform_device_register(&cmx270_led_device);
}
#else
static inline void cmx270_init_leds(void) {}
#endif
/* 2700G graphics */
#if defined(CONFIG_FB_MBX) || defined(CONFIG_FB_MBX_MODULE)
static u64 fb_dma_mask = ~(u64)0;
static struct resource cmx270_2700G_resource[] = {
/* frame buffer memory including ODFB and External SDRAM */
[0] = {
.start = MARATHON_PHYS,
.end = MARATHON_PHYS + 0x02000000,
.start = PXA_CS2_PHYS,
.end = PXA_CS2_PHYS + 0x01ffffff,
.flags = IORESOURCE_MEM,
},
/* Marathon registers */
[1] = {
.start = MARATHON_PHYS + 0x03fe0000,
.end = MARATHON_PHYS + 0x03ffffff,
.start = PXA_CS2_PHYS + 0x03fe0000,
.end = PXA_CS2_PHYS + 0x03ffffff,
.flags = IORESOURCE_MEM,
},
};
......@@ -200,43 +365,15 @@ static struct platform_device cmx270_2700G = {
.id = -1,
};
static u64 ata_dma_mask = ~(u64)0;
static struct platform_device cmx270_ata = {
.name = "pata_cm_x270",
.id = -1,
.dev = {
.dma_mask = &ata_dma_mask,
.coherent_dma_mask = 0xffffffff,
},
};
/* platform devices */
static struct platform_device *platform_devices[] __initdata = {
&cmx270_device_dm9k,
&cmx270_rtc_device,
&cmx270_2700G,
&cmx270_led_device,
&cmx270_ts_device,
&cmx270_ata,
};
/* Map PCI companion and IDE/General Purpose CS statically */
static struct map_desc cmx270_io_desc[] __initdata = {
[0] = { /* IDE/general purpose space */
.virtual = CMX270_IDE104_VIRT,
.pfn = __phys_to_pfn(CMX270_IDE104_PHYS),
.length = SZ_64M - SZ_8M,
.type = MT_DEVICE
},
[1] = { /* PCI bridge */
.virtual = CMX270_IT8152_VIRT,
.pfn = __phys_to_pfn(CMX270_IT8152_PHYS),
.length = SZ_64M,
.type = MT_DEVICE
},
};
static void __init cmx270_init_2700G(void)
{
platform_device_register(&cmx270_2700G);
}
#else
static inline void cmx270_init_2700G(void) {}
#endif
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
/*
Display definitions
keep these for backwards compatibility, although symbolic names (as
......@@ -446,7 +583,16 @@ static int __init cmx270_set_display(char *str)
*/
__setup("monitor=", cmx270_set_display);
static void __init cmx270_init_display(void)
{
set_pxa_fb_info(cmx270_display);
}
#else
static inline void cmx270_init_display(void) {}
#endif
/* PXA27x OHCI controller setup */
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static int cmx270_ohci_init(struct device *dev)
{
/* Set the Power Control Polarity Low */
......@@ -461,35 +607,37 @@ static struct pxaohci_platform_data cmx270_ohci_platform_data = {
.init = cmx270_ohci_init,
};
static void __init cmx270_init_ohci(void)
{
pxa_set_ohci_info(&cmx270_ohci_platform_data);
}
#else
static inline void cmx270_init_ohci(void) {}
#endif
#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
static int cmx270_mci_init(struct device *dev,
irq_handler_t cmx270_detect_int,
void *data)
{
int err;
/*
* setup GPIO for PXA27x MMC controller
*/
pxa_gpio_mode(GPIO32_MMCCLK_MD);
pxa_gpio_mode(GPIO112_MMCCMD_MD);
pxa_gpio_mode(GPIO92_MMCDAT0_MD);
pxa_gpio_mode(GPIO109_MMCDAT1_MD);
pxa_gpio_mode(GPIO110_MMCDAT2_MD);
pxa_gpio_mode(GPIO111_MMCDAT3_MD);
/* SB-X270 uses GPIO105 as SD power enable */
pxa_gpio_mode(105 | GPIO_OUT);
err = gpio_request(GPIO105_MMC_POWER, "MMC/SD power");
if (err) {
dev_warn(dev, "power gpio unavailable\n");
return err;
}
/* card detect IRQ on GPIO 83 */
pxa_gpio_mode(IRQ_TO_GPIO(CMX270_MMC_IRQ));
gpio_direction_output(GPIO105_MMC_POWER, 0);
err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int,
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
"MMC card detect", data);
if (err)
printk(KERN_ERR "cmx270_mci_init: MMC/SD: can't"
" request MMC card detect IRQ\n");
if (err) {
gpio_free(GPIO105_MMC_POWER);
dev_err(dev, "cmx270_mci_init: MMC/SD: can't"
" request MMC card detect IRQ\n");
}
return err;
}
......@@ -499,17 +647,18 @@ static void cmx270_mci_setpower(struct device *dev, unsigned int vdd)
struct pxamci_platform_data *p_d = dev->platform_data;
if ((1 << vdd) & p_d->ocr_mask) {
printk(KERN_DEBUG "%s: on\n", __func__);
GPCR(105) = GPIO_bit(105);
dev_dbg(dev, "power on\n");
gpio_set_value(GPIO105_MMC_POWER, 0);
} else {
GPSR(105) = GPIO_bit(105);
printk(KERN_DEBUG "%s: off\n", __func__);
gpio_set_value(GPIO105_MMC_POWER, 1);
dev_dbg(dev, "power off\n");
}
}
static void cmx270_mci_exit(struct device *dev, void *data)
{
free_irq(CMX270_MMC_IRQ, data);
gpio_free(GPIO105_MMC_POWER);
}
static struct pxamci_platform_data cmx270_mci_platform_data = {
......@@ -519,6 +668,14 @@ static struct pxamci_platform_data cmx270_mci_platform_data = {
.exit = cmx270_mci_exit,
};
static void __init cmx270_init_mmc(void)
{
pxa_set_mci_info(&cmx270_mci_platform_data);
}
#else
static inline void cmx270_init_mmc(void) {}
#endif
#ifdef CONFIG_PM
static unsigned long sleep_save_msc[10];
......@@ -580,53 +737,63 @@ static int __init cmx270_pm_init(void)
static int __init cmx270_pm_init(void) { return 0; }
#endif
static void __init cmx270_init(void)
#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
static void __init cmx270_init_ac97(void)
{
cmx270_pm_init();
set_pxa_fb_info(cmx270_display);
/* register CM-X270 platform devices */
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
pxa_set_ac97_info(NULL);
}
#else
static inline void cmx270_init_ac97(void) {}
#endif
/* set MCI and OHCI platform parameters */
pxa_set_mci_info(&cmx270_mci_platform_data);
pxa_set_ohci_info(&cmx270_ohci_platform_data);
/* This enables the STUART */
pxa_gpio_mode(GPIO46_STRXD_MD);
pxa_gpio_mode(GPIO47_STTXD_MD);
static void __init cmx270_init(void)
{
cmx270_pm_init();
/* This enables the BTUART */
pxa_gpio_mode(GPIO42_BTRXD_MD);
pxa_gpio_mode(GPIO43_BTTXD_MD);
pxa_gpio_mode(GPIO44_BTCTS_MD);
pxa_gpio_mode(GPIO45_BTRTS_MD);
pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config));
cmx270_init_dm9000();
cmx270_init_rtc();
cmx270_init_display();
cmx270_init_mmc();
cmx270_init_ohci();
cmx270_init_ac97();
cmx270_init_touchscreen();
cmx270_init_leds();
cmx270_init_2700G();
}
static void __init cmx270_init_irq(void)
{
pxa27x_init_irq();
cmx270_pci_init_irq(GPIO22_IT8152_IRQ);
}
cmx270_pci_init_irq();
#ifdef CONFIG_PCI
/* Map PCI companion statically */
static struct map_desc cmx270_io_desc[] __initdata = {
[0] = { /* PCI bridge */
.virtual = CMX270_IT8152_VIRT,
.pfn = __phys_to_pfn(PXA_CS4_PHYS),
.length = SZ_64M,
.type = MT_DEVICE
},
};
/* Setup interrupt for dm9000 */
pxa_gpio_mode(IRQ_TO_GPIO(CMX270_ETHIRQ));
set_irq_type(CMX270_ETHIRQ, IRQT_RISING);
static void __init cmx270_map_io(void)
{
pxa_map_io();
iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc));
/* Setup interrupt for 2700G */
pxa_gpio_mode(IRQ_TO_GPIO(CMX270_GFXIRQ));
set_irq_type(CMX270_GFXIRQ, IRQT_FALLING);
it8152_base_address = CMX270_IT8152_VIRT;
}
#else
static void __init cmx270_map_io(void)
{
pxa_map_io();
iotable_init(cmx270_io_desc, ARRAY_SIZE(cmx270_io_desc));
}
#endif
MACHINE_START(ARMCORE, "Compulab CM-x270")
.boot_params = 0xa0000100,
......
......@@ -465,6 +465,7 @@ static void corgi_irda_transceiver_mode(struct device *dev, int mode)
GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
else
GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
pxa2xx_transceiver_mode(dev, mode);
}
static struct pxaficp_platform_data corgi_ficp_platform_data = {
......
......@@ -13,8 +13,10 @@
#include <asm/arch/mfp-pxa27x.h>
#include <asm/arch/ohci.h>
#include <asm/arch/pxa27x_keypad.h>
#include <asm/arch/pxa2xx_spi.h>
#include <asm/arch/camera.h>
#include <asm/arch/audio.h>
#include <asm/arch/pxa3xx_nand.h>
#include "devices.h"
#include "generic.h"
......@@ -830,4 +832,63 @@ void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
pxa_register_device(&pxa3xx_device_mci3, info);
}
static struct resource pxa3xx_resources_nand[] = {
[0] = {
.start = 0x43100000,
.end = 0x43100053,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_NAND,
.end = IRQ_NAND,
.flags = IORESOURCE_IRQ,
},
[2] = {
/* DRCMR for Data DMA */
.start = 97,
.end = 97,
.flags = IORESOURCE_DMA,
},
[3] = {
/* DRCMR for Command DMA */
.start = 99,
.end = 99,
.flags = IORESOURCE_DMA,
},
};
static u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32);
struct platform_device pxa3xx_device_nand = {
.name = "pxa3xx-nand",
.id = -1,
.dev = {
.dma_mask = &pxa3xx_nand_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(pxa3xx_resources_nand),
.resource = pxa3xx_resources_nand,
};
void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info)
{
pxa_register_device(&pxa3xx_device_nand, info);
}
#endif /* CONFIG_PXA3xx */
/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
* See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info)
{
struct platform_device *pd;
pd = platform_device_alloc("pxa2xx-spi", id);
if (pd == NULL) {
printk(KERN_ERR "pxa2xx-spi: failed to allocate device id %d\n",
id);
return;
}
pd->dev.platform_data = info;
platform_device_add(pd);
}
......@@ -31,4 +31,6 @@ extern struct platform_device pxa25x_device_pwm1;
extern struct platform_device pxa27x_device_pwm0;
extern struct platform_device pxa27x_device_pwm1;
extern struct platform_device pxa3xx_device_nand;
void __init pxa_register_device(struct platform_device *dev, void *data);
/*
* e400_lcd.c
*
* (c) 2005 Ian Molton <spyro@f2s.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/mach-types.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxafb.h>
static struct pxafb_mode_info e400_pxafb_mode_info = {
.pixclock = 140703,
.xres = 240,
.yres = 320,
.bpp = 16,
.hsync_len = 4,
.left_margin = 28,
.right_margin = 8,
.vsync_len = 3,
.upper_margin = 5,
.lower_margin = 6,
.sync = 0,
};
static struct pxafb_mach_info e400_pxafb_mach_info = {
.modes = &e400_pxafb_mode_info,
.num_modes = 1,
.lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
.lccr3 = 0,
.pxafb_backlight_power = NULL,
};
static int __init e400_lcd_init(void)
{
if (!machine_is_e400())
return -ENODEV;
set_pxa_fb_info(&e400_pxafb_mach_info);
return 0;
}
module_init(e400_lcd_init);
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("e400 lcd driver");
MODULE_LICENSE("GPLv2");
/* e740_lcd.c
*
* This file contains the definitions for the LCD timings and functions
* to control the LCD power / frontlighting via the w100fb driver.
*
* (c) 2005 Ian Molton <spyro@f2s.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <video/w100fb.h>
/*
**potential** shutdown routine - to be investigated
devmem2 0x0c010528 w 0xff3fff00
devmem2 0x0c010190 w 0x7FFF8000
devmem2 0x0c0101b0 w 0x00FF0000
devmem2 0x0c01008c w 0x00000000
devmem2 0x0c010080 w 0x000000bf
devmem2 0x0c010098 w 0x00000015
devmem2 0x0c010088 w 0x4b000204
devmem2 0x0c010098 w 0x0000001d
*/
static struct w100_gen_regs e740_lcd_regs = {
.lcd_format = 0x00008023,
.lcdd_cntl1 = 0x0f000000,
.lcdd_cntl2 = 0x0003ffff,
.genlcd_cntl1 = 0x00ffff03,
.genlcd_cntl2 = 0x003c0f03,
.genlcd_cntl3 = 0x000143aa,
};
static struct w100_mode e740_lcd_mode = {
.xres = 240,
.yres = 320,
.left_margin = 20,
.right_margin = 28,
.upper_margin = 9,
.lower_margin = 8,
.crtc_ss = 0x80140013,
.crtc_ls = 0x81150110,
.crtc_gs = 0x80050005,
.crtc_vpos_gs = 0x000a0009,
.crtc_rev = 0x0040010a,
.crtc_dclk = 0xa906000a,
.crtc_gclk = 0x80050108,
.crtc_goe = 0x80050108,
.pll_freq = 57,
.pixclk_divider = 4,
.pixclk_divider_rotated = 4,
.pixclk_src = CLK_SRC_XTAL,
.sysclk_divider = 1,
.sysclk_src = CLK_SRC_PLL,
.crtc_ps1_active = 0x41060010,
};
static struct w100_gpio_regs e740_w100_gpio_info = {
.init_data1 = 0x21002103,
.gpio_dir1 = 0xffffdeff,
.gpio_oe1 = 0x03c00643,
.init_data2 = 0x003f003f,
.gpio_dir2 = 0xffffffff,
.gpio_oe2 = 0x000000ff,
};
static struct w100fb_mach_info e740_fb_info = {
.modelist = &e740_lcd_mode,
.num_modes = 1,
.regs = &e740_lcd_regs,
.gpio = &e740_w100_gpio_info,
.xtal_freq = 14318000,
.xtal_dbl = 1,
};
static struct resource e740_fb_resources[] = {
[0] = {
.start = 0x0c000000,
.end = 0x0cffffff,
.flags = IORESOURCE_MEM,
},
};
/* ----------------------- device declarations -------------------------- */
static struct platform_device e740_fb_device = {
.name = "w100fb",
.id = -1,
.dev = {
.platform_data = &e740_fb_info,
},
.num_resources = ARRAY_SIZE(e740_fb_resources),
.resource = e740_fb_resources,
};
static int e740_lcd_init(void)
{
int ret;
if (!machine_is_e740())
return -ENODEV;
return platform_device_register(&e740_fb_device);
}
module_init(e740_lcd_init);
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("e740 lcd driver");
MODULE_LICENSE("GPLv2");
/* e750_lcd.c
*
* This file contains the definitions for the LCD timings and functions
* to control the LCD power / frontlighting via the w100fb driver.
*
* (c) 2005 Ian Molton <spyro@f2s.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <video/w100fb.h>
static struct w100_gen_regs e750_lcd_regs = {
.lcd_format = 0x00008003,
.lcdd_cntl1 = 0x00000000,
.lcdd_cntl2 = 0x0003ffff,
.genlcd_cntl1 = 0x00fff003,
.genlcd_cntl2 = 0x003c0f03,
.genlcd_cntl3 = 0x000143aa,
};
static struct w100_mode e750_lcd_mode = {
.xres = 240,
.yres = 320,
.left_margin = 21,
.right_margin = 22,
.upper_margin = 5,
.lower_margin = 4,
.crtc_ss = 0x80150014,
.crtc_ls = 0x8014000d,
.crtc_gs = 0xc1000005,
.crtc_vpos_gs = 0x00020147,
.crtc_rev = 0x0040010a,
.crtc_dclk = 0xa1700030,
.crtc_gclk = 0x80cc0015,
.crtc_goe = 0x80cc0015,
.crtc_ps1_active = 0x61060017,
.pll_freq = 57,
.pixclk_divider = 4,
.pixclk_divider_rotated = 4,
.pixclk_src = CLK_SRC_XTAL,
.sysclk_divider = 1,
.sysclk_src = CLK_SRC_PLL,
};
static struct w100_gpio_regs e750_w100_gpio_info = {
.init_data1 = 0x01192f1b,
.gpio_dir1 = 0xd5ffdeff,
.gpio_oe1 = 0x000020bf,
.init_data2 = 0x010f010f,
.gpio_dir2 = 0xffffffff,
.gpio_oe2 = 0x000001cf,
};
static struct w100fb_mach_info e750_fb_info = {
.modelist = &e750_lcd_mode,
.num_modes = 1,
.regs = &e750_lcd_regs,
.gpio = &e750_w100_gpio_info,
.xtal_freq = 14318000,
.xtal_dbl = 1,
};
static struct resource e750_fb_resources[] = {
[0] = {
.start = 0x0c000000,
.end = 0x0cffffff,
.flags = IORESOURCE_MEM,
},
};
/* ----------------------- device declarations -------------------------- */
static struct platform_device e750_fb_device = {
.name = "w100fb",
.id = -1,
.dev = {
.platform_data = &e750_fb_info,
},
.num_resources = ARRAY_SIZE(e750_fb_resources),
.resource = e750_fb_resources,
};
static int e750_lcd_init(void)
{
if (!machine_is_e750())
return -ENODEV;
return platform_device_register(&e750_fb_device);
}
module_init(e750_lcd_init);
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("e750 lcd driver");
MODULE_LICENSE("GPLv2");
/* e800_lcd.c
*
* This file contains the definitions for the LCD timings and functions
* to control the LCD power / frontlighting via the w100fb driver.
*
* (c) 2005 Ian Molton <spyro@f2s.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <asm/mach-types.h>
#include <video/w100fb.h>
static struct w100_gen_regs e800_lcd_regs = {
.lcd_format = 0x00008003,
.lcdd_cntl1 = 0x02a00000,
.lcdd_cntl2 = 0x0003ffff,
.genlcd_cntl1 = 0x000ff2a3,
.genlcd_cntl2 = 0x000002a3,
.genlcd_cntl3 = 0x000102aa,
};
static struct w100_mode e800_lcd_mode[2] = {
[0] = {
.xres = 480,
.yres = 640,
.left_margin = 52,
.right_margin = 148,
.upper_margin = 2,
.lower_margin = 6,
.crtc_ss = 0x80350034,
.crtc_ls = 0x802b0026,
.crtc_gs = 0x80160016,
.crtc_vpos_gs = 0x00020003,
.crtc_rev = 0x0040001d,
.crtc_dclk = 0xe0000000,
.crtc_gclk = 0x82a50049,
.crtc_goe = 0x80ee001c,
.crtc_ps1_active = 0x00000000,
.pll_freq = 128,
.pixclk_divider = 4,
.pixclk_divider_rotated = 6,
.pixclk_src = CLK_SRC_PLL,
.sysclk_divider = 0,
.sysclk_src = CLK_SRC_PLL,
},
[1] = {
.xres = 240,
.yres = 320,
.left_margin = 15,
.right_margin = 88,
.upper_margin = 0,
.lower_margin = 7,
.crtc_ss = 0xd010000f,
.crtc_ls = 0x80070003,
.crtc_gs = 0x80000000,
.crtc_vpos_gs = 0x01460147,
.crtc_rev = 0x00400003,
.crtc_dclk = 0xa1700030,
.crtc_gclk = 0x814b0008,
.crtc_goe = 0x80cc0015,
.crtc_ps1_active = 0x00000000,
.pll_freq = 100,
.pixclk_divider = 6, /* Wince uses 14 which gives a 7MHz pclk. */
.pixclk_divider_rotated = 6, /* we want a 14MHz one (much nicer to look at) */
.pixclk_src = CLK_SRC_PLL,
.sysclk_divider = 0,
.sysclk_src = CLK_SRC_PLL,
}
};
static struct w100_gpio_regs e800_w100_gpio_info = {
.init_data1 = 0xc13fc019,
.gpio_dir1 = 0x3e40df7f,
.gpio_oe1 = 0x003c3000,
.init_data2 = 0x00000000,
.gpio_dir2 = 0x00000000,
.gpio_oe2 = 0x00000000,
};
static struct w100_mem_info e800_w100_mem_info = {
.ext_cntl = 0x09640011,
.sdram_mode_reg = 0x00600021,
.ext_timing_cntl = 0x10001545,
.io_cntl = 0x7ddd7333,
.size = 0x1fffff,
};
static void e800_tg_change(struct w100fb_par *par)
{
unsigned long tmp;
tmp = w100fb_gpio_read(W100_GPIO_PORT_A);
if (par->mode->xres == 480)
tmp |= 0x100;
else
tmp &= ~0x100;
w100fb_gpio_write(W100_GPIO_PORT_A, tmp);
}
static struct w100_tg_info e800_tg_info = {
.change = e800_tg_change,
};
static struct w100fb_mach_info e800_fb_info = {
.modelist = e800_lcd_mode,
.num_modes = 2,
.regs = &e800_lcd_regs,
.gpio = &e800_w100_gpio_info,
.mem = &e800_w100_mem_info,
.tg = &e800_tg_info,
.xtal_freq = 16000000,
};
static struct resource e800_fb_resources[] = {
[0] = {
.start = 0x0c000000,
.end = 0x0cffffff,
.flags = IORESOURCE_MEM,
},
};
/* ----------------------- device declarations -------------------------- */
static struct platform_device e800_fb_device = {
.name = "w100fb",
.id = -1,
.dev = {
.platform_data = &e800_fb_info,
},
.num_resources = ARRAY_SIZE(e800_fb_resources),
.resource = e800_fb_resources,
};
static int e800_lcd_init(void)
{
if (!machine_is_e800())
return -ENODEV;
return platform_device_register(&e800_fb_device);
}
module_init(e800_lcd_init);
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("e800 lcd driver");
MODULE_LICENSE("GPLv2");
/*
* Support for CompuLab EM-x270 platform
* Support for CompuLab EM-X270 platform
*
* Copyright (C) 2007 CompuLab, Ltd.
* Copyright (C) 2007, 2008 CompuLab, Ltd.
* Author: Mike Rapoport <mike@compulab.co.il>
*
* This program is free software; you can redistribute it and/or modify
......@@ -14,31 +14,159 @@
#include <linux/dm9000.h>
#include <linux/rtc-v3020.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/arch/mfp-pxa27x.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa2xx-gpio.h>
#include <asm/arch/pxa27x-udc.h>
#include <asm/arch/audio.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/ohci.h>
#include <asm/arch/mmc.h>
#include <asm/arch/bitfield.h>
#include <asm/arch/pxa27x_keypad.h>
#include "generic.h"
/* GPIO IRQ usage */
#define EM_X270_MMC_PD (105)
#define EM_X270_ETHIRQ IRQ_GPIO(41)
#define EM_X270_MMC_IRQ IRQ_GPIO(13)
#define GPIO41_ETHIRQ (41)
#define GPIO13_MMC_CD (13)
#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ)
#define EM_X270_MMC_CD IRQ_GPIO(GPIO13_MMC_CD)
/* NAND control GPIOs */
#define GPIO11_NAND_CS (11)
#define GPIO56_NAND_RB (56)
static unsigned long em_x270_pin_config[] = {
/* AC'97 */
GPIO28_AC97_BITCLK,
GPIO29_AC97_SDATA_IN_0,
GPIO30_AC97_SDATA_OUT,
GPIO31_AC97_SYNC,
GPIO98_AC97_SYSCLK,
GPIO113_AC97_nRESET,
/* BTUART */
GPIO42_BTUART_RXD,
GPIO43_BTUART_TXD,
GPIO44_BTUART_CTS,
GPIO45_BTUART_RTS,
/* STUART */
GPIO46_STUART_RXD,
GPIO47_STUART_TXD,
/* MCI controller */
GPIO32_MMC_CLK,
GPIO112_MMC_CMD,
GPIO92_MMC_DAT_0,
GPIO109_MMC_DAT_1,
GPIO110_MMC_DAT_2,
GPIO111_MMC_DAT_3,
/* LCD */
GPIO58_LCD_LDD_0,
GPIO59_LCD_LDD_1,
GPIO60_LCD_LDD_2,
GPIO61_LCD_LDD_3,
GPIO62_LCD_LDD_4,
GPIO63_LCD_LDD_5,
GPIO64_LCD_LDD_6,
GPIO65_LCD_LDD_7,
GPIO66_LCD_LDD_8,
GPIO67_LCD_LDD_9,
GPIO68_LCD_LDD_10,
GPIO69_LCD_LDD_11,
GPIO70_LCD_LDD_12,
GPIO71_LCD_LDD_13,
GPIO72_LCD_LDD_14,
GPIO73_LCD_LDD_15,
GPIO74_LCD_FCLK,
GPIO75_LCD_LCLK,
GPIO76_LCD_PCLK,
GPIO77_LCD_BIAS,
/* QCI */
GPIO84_CIF_FV,
GPIO25_CIF_LV,
GPIO53_CIF_MCLK,
GPIO54_CIF_PCLK,
GPIO81_CIF_DD_0,
GPIO55_CIF_DD_1,
GPIO51_CIF_DD_2,
GPIO50_CIF_DD_3,
GPIO52_CIF_DD_4,
GPIO48_CIF_DD_5,
GPIO17_CIF_DD_6,
GPIO12_CIF_DD_7,
/* I2C */
GPIO117_I2C_SCL,
GPIO118_I2C_SDA,
/* Keypad */
GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
GPIO39_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
GPIO91_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH,
GPIO36_KP_MKIN_7 | WAKEUP_ON_LEVEL_HIGH,
GPIO103_KP_MKOUT_0,
GPIO104_KP_MKOUT_1,
GPIO105_KP_MKOUT_2,
GPIO106_KP_MKOUT_3,
GPIO107_KP_MKOUT_4,
GPIO108_KP_MKOUT_5,
GPIO96_KP_MKOUT_6,
GPIO22_KP_MKOUT_7,
/* SSP1 */
GPIO26_SSP1_RXD,
GPIO23_SSP1_SCLK,
GPIO24_SSP1_SFRM,
GPIO57_SSP1_TXD,
/* SSP2 */
GPIO19_SSP2_SCLK,
GPIO14_SSP2_SFRM,
GPIO89_SSP2_TXD,
GPIO88_SSP2_RXD,
/* SDRAM and local bus */
GPIO15_nCS_1,
GPIO78_nCS_2,
GPIO79_nCS_3,
GPIO80_nCS_4,
GPIO49_nPWE,
GPIO18_RDY,
/* GPIO */
GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
/* power controls */
GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */
GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */
/* NAND controls */
GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */
GPIO56_GPIO, /* NAND Ready/Busy */
/* interrupts */
GPIO13_GPIO, /* MMC card detect */
GPIO41_GPIO, /* DM9000 interrupt */
};
static struct resource em_x270_dm9k_resource[] = {
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
static struct resource em_x270_dm9000_resource[] = {
[0] = {
.start = PXA_CS2_PHYS,
.end = PXA_CS2_PHYS + 3,
......@@ -56,32 +184,30 @@ static struct resource em_x270_dm9k_resource[] = {
}
};
/* for the moment we limit ourselves to 32bit IO until some
* better IO routines can be written and tested
*/
static struct dm9000_plat_data em_x270_dm9k_platdata = {
static struct dm9000_plat_data em_x270_dm9000_platdata = {
.flags = DM9000_PLATF_32BITONLY,
};
/* Ethernet device */
static struct platform_device em_x270_dm9k = {
static struct platform_device em_x270_dm9000 = {
.name = "dm9000",
.id = 0,
.num_resources = ARRAY_SIZE(em_x270_dm9k_resource),
.resource = em_x270_dm9k_resource,
.num_resources = ARRAY_SIZE(em_x270_dm9000_resource),
.resource = em_x270_dm9000_resource,
.dev = {
.platform_data = &em_x270_dm9k_platdata,
.platform_data = &em_x270_dm9000_platdata,
}
};
/* WM9712 touchscreen controller. Hopefully the driver will make it to
* the mainstream sometime */
static struct platform_device em_x270_ts = {
.name = "wm97xx-ts",
.id = -1,
};
static void __init em_x270_init_dm9000(void)
{
platform_device_register(&em_x270_dm9000);
}
#else
static inline void em_x270_init_dm9000(void) {}
#endif
/* RTC */
/* V3020 RTC */
#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
static struct resource em_x270_v3020_resource[] = {
[0] = {
.start = PXA_CS4_PHYS,
......@@ -104,20 +230,26 @@ static struct platform_device em_x270_rtc = {
}
};
/* NAND flash */
#define GPIO_NAND_CS (11)
#define GPIO_NAND_RB (56)
static void __init em_x270_init_rtc(void)
{
platform_device_register(&em_x270_rtc);
}
#else
static inline void em_x270_init_rtc(void) {}
#endif
/* NAND flash */
#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
static inline void nand_cs_on(void)
{
GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
gpio_set_value(GPIO11_NAND_CS, 0);
}
static void nand_cs_off(void)
{
dsb();
GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
gpio_set_value(GPIO11_NAND_CS, 1);
}
/* hardware specific access to control-lines */
......@@ -157,7 +289,7 @@ static int em_x270_nand_device_ready(struct mtd_info *mtd)
{
dsb();
return GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB);
return gpio_get_value(GPIO56_NAND_RB);
}
static struct mtd_partition em_x270_partition_info[] = {
......@@ -210,16 +342,35 @@ static struct platform_device em_x270_nand = {
}
};
/* platform devices */
static struct platform_device *platform_devices[] __initdata = {
&em_x270_dm9k,
&em_x270_ts,
&em_x270_rtc,
&em_x270_nand,
};
static void __init em_x270_init_nand(void)
{
int err;
err = gpio_request(GPIO11_NAND_CS, "NAND CS");
if (err) {
pr_warning("EM-X270: failed to request NAND CS gpio\n");
return;
}
gpio_direction_output(GPIO11_NAND_CS, 1);
err = gpio_request(GPIO56_NAND_RB, "NAND R/B");
if (err) {
pr_warning("EM-X270: failed to request NAND R/B gpio\n");
gpio_free(GPIO11_NAND_CS);
return;
}
gpio_direction_input(GPIO56_NAND_RB);
platform_device_register(&em_x270_nand);
}
#else
static inline void em_x270_init_nand(void) {}
#endif
/* PXA27x OHCI controller setup */
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static int em_x270_ohci_init(struct device *dev)
{
/* Set the Power Control Polarity Low */
......@@ -237,27 +388,23 @@ static struct pxaohci_platform_data em_x270_ohci_platform_data = {
.init = em_x270_ohci_init,
};
static void __init em_x270_init_ohci(void)
{
pxa_set_ohci_info(&em_x270_ohci_platform_data);
}
#else
static inline void em_x270_init_ohci(void) {}
#endif
/* MCI controller setup */
#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
static int em_x270_mci_init(struct device *dev,
irq_handler_t em_x270_detect_int,
void *data)
{
int err;
/* setup GPIO for PXA27x MMC controller */
pxa_gpio_mode(GPIO32_MMCCLK_MD);
pxa_gpio_mode(GPIO112_MMCCMD_MD);
pxa_gpio_mode(GPIO92_MMCDAT0_MD);
pxa_gpio_mode(GPIO109_MMCDAT1_MD);
pxa_gpio_mode(GPIO110_MMCDAT2_MD);
pxa_gpio_mode(GPIO111_MMCDAT3_MD);
/* EM-X270 uses GPIO13 as SD power enable */
pxa_gpio_mode(EM_X270_MMC_PD | GPIO_OUT);
err = request_irq(EM_X270_MMC_IRQ, em_x270_detect_int,
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
"MMC card detect", data);
int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int,
IRQF_DISABLED | IRQF_TRIGGER_FALLING,
"MMC card detect", data);
if (err) {
printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
__func__, err);
......@@ -279,7 +426,8 @@ static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
static void em_x270_mci_exit(struct device *dev, void *data)
{
free_irq(EM_X270_MMC_IRQ, data);
int irq = gpio_to_irq(GPIO13_MMC_CD);
free_irq(irq, data);
}
static struct pxamci_platform_data em_x270_mci_platform_data = {
......@@ -289,7 +437,16 @@ static struct pxamci_platform_data em_x270_mci_platform_data = {
.exit = em_x270_mci_exit,
};
static void __init em_x270_init_mmc(void)
{
pxa_set_mci_info(&em_x270_mci_platform_data);
}
#else
static inline void em_x270_init_mmc(void) {}
#endif
/* LCD 480x640 */
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
static struct pxafb_mode_info em_x270_lcd_mode = {
.pixclock = 50000,
.bpp = 16,
......@@ -307,40 +464,96 @@ static struct pxafb_mode_info em_x270_lcd_mode = {
static struct pxafb_mach_info em_x270_lcd = {
.modes = &em_x270_lcd_mode,
.num_modes = 1,
.cmap_inverse = 0,
.cmap_static = 0,
.lccr0 = LCCR0_PAS,
.lccr3 = LCCR3_PixClkDiv(0x01) | LCCR3_Acb(0xff),
.lcd_conn = LCD_COLOR_TFT_16BPP,
};
static void __init em_x270_init(void)
static void __init em_x270_init_lcd(void)
{
/* setup LCD */
set_pxa_fb_info(&em_x270_lcd);
}
#else
static inline void em_x270_init_lcd(void) {}
#endif
/* register EM-X270 platform devices */
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
static void __init em_x270_init_ac97(void)
{
pxa_set_ac97_info(NULL);
}
#else
static inline void em_x270_init_ac97(void) {}
#endif
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static unsigned int em_x270_matrix_keys[] = {
KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
};
/* set MCI and OHCI platform parameters */
pxa_set_mci_info(&em_x270_mci_platform_data);
pxa_set_ohci_info(&em_x270_ohci_platform_data);
struct pxa27x_keypad_platform_data em_x270_keypad_info = {
/* code map for the matrix keys */
.matrix_key_rows = 3,
.matrix_key_cols = 3,
.matrix_key_map = em_x270_matrix_keys,
.matrix_key_map_size = ARRAY_SIZE(em_x270_matrix_keys),
};
static void __init em_x270_init_keypad(void)
{
pxa_set_keypad_info(&em_x270_keypad_info);
}
#else
static inline void em_x270_init_keypad(void) {}
#endif
/* setup STUART GPIOs */
pxa_gpio_mode(GPIO46_STRXD_MD);
pxa_gpio_mode(GPIO47_STTXD_MD);
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button gpio_keys_button[] = {
[0] = {
.desc = "sleep/wakeup",
.code = KEY_SUSPEND,
.type = EV_PWR,
.gpio = 1,
.wakeup = 1,
},
};
/* setup BTUART GPIOs */
pxa_gpio_mode(GPIO42_BTRXD_MD);
pxa_gpio_mode(GPIO43_BTTXD_MD);
pxa_gpio_mode(GPIO44_BTCTS_MD);
pxa_gpio_mode(GPIO45_BTRTS_MD);
static struct gpio_keys_platform_data em_x270_gpio_keys_data = {
.buttons = gpio_keys_button,
.nbuttons = 1,
};
/* Setup interrupt for dm9000 */
set_irq_type(EM_X270_ETHIRQ, IRQT_RISING);
static struct platform_device em_x270_gpio_keys = {
.name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &em_x270_gpio_keys_data,
},
};
static void __init em_x270_init_gpio_keys(void)
{
platform_device_register(&em_x270_gpio_keys);
}
#else
static inline void em_x270_init_gpio_keys(void) {}
#endif
static void __init em_x270_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config));
em_x270_init_dm9000();
em_x270_init_rtc();
em_x270_init_nand();
em_x270_init_lcd();
em_x270_init_mmc();
em_x270_init_ohci();
em_x270_init_keypad();
em_x270_init_gpio_keys();
em_x270_init_ac97();
}
MACHINE_START(EM_X270, "Compulab EM-x270")
MACHINE_START(EM_X270, "Compulab EM-X270")
.boot_params = 0xa0000100,
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
......
......@@ -17,7 +17,7 @@
#include <asm/arch/hardware.h>
#include <asm/mach-types.h>
#include <generic.h>
#include "generic.h"
/* Only e800 has 128MB RAM */
static void __init eseries_fixup(struct machine_desc *desc,
......@@ -47,6 +47,19 @@ MACHINE_START(E330, "Toshiba e330")
MACHINE_END
#endif
#ifdef CONFIG_MACH_E350
MACHINE_START(E350, "Toshiba e350")
/* Maintainer: Ian Molton (spyro@f2s.com) */
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
.fixup = eseries_fixup,
.timer = &pxa_timer,
MACHINE_END
#endif
#ifdef CONFIG_MACH_E740
MACHINE_START(E740, "Toshiba e740")
/* Maintainer: Ian Molton (spyro@f2s.com) */
......
/*
* UDC functions for the Toshiba e-series PDAs
*
* Copyright (c) Ian Molton 2003
*
* This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <asm/arch/udc.h>
#include <asm/arch/eseries-gpio.h>
#include <asm/arch/hardware.h>
#include <asm/arch/pxa-regs.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/domain.h>
/* local PXA generic code */
#include "generic.h"
static struct pxa2xx_udc_mach_info e7xx_udc_mach_info = {
.gpio_vbus = GPIO_E7XX_USB_DISC,
.gpio_pullup = GPIO_E7XX_USB_PULLUP,
.gpio_pullup_inverted = 1
};
static struct pxa2xx_udc_mach_info e800_udc_mach_info = {
.gpio_vbus = GPIO_E800_USB_DISC,
.gpio_pullup = GPIO_E800_USB_PULLUP,
.gpio_pullup_inverted = 1
};
static int __init eseries_udc_init(void)
{
if (machine_is_e330() || machine_is_e350() ||
machine_is_e740() || machine_is_e750() ||
machine_is_e400())
pxa_set_udc_info(&e7xx_udc_mach_info);
else if (machine_is_e800())
pxa_set_udc_info(&e800_udc_mach_info);
return 0;
}
module_init(eseries_udc_init);
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
MODULE_DESCRIPTION("eseries UDC support");
MODULE_LICENSE("GPLv2");
/*
* ezx.c - Common code for the EZX platform.
*
* Copyright (C) 2005-2006 Harald Welte <laforge@openezx.org>,
* 2007-2008 Daniel Ribeiro <drwyrm@gmail.com>,
* 2007-2008 Stefan Schmidt <stefan@datenfreihafen.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/pwm_backlight.h>
#include <asm/setup.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/ohci.h>
#include <asm/arch/i2c.h>
#include <asm/arch/mfp-pxa27x.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa2xx-regs.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include "devices.h"
#include "generic.h"
static struct platform_pwm_backlight_data ezx_backlight_data = {
.pwm_id = 0,
.max_brightness = 1023,
.dft_brightness = 1023,
.pwm_period_ns = 78770,
};
static struct platform_device ezx_backlight_device = {
.name = "pwm-backlight",
.dev = {
.parent = &pxa27x_device_pwm0.dev,
.platform_data = &ezx_backlight_data,
},
};
static struct pxafb_mode_info mode_ezx_old = {
.pixclock = 150000,
.xres = 240,
.yres = 320,
.bpp = 16,
.hsync_len = 10,
.left_margin = 20,
.right_margin = 10,
.vsync_len = 2,
.upper_margin = 3,
.lower_margin = 2,
.sync = 0,
};
static struct pxafb_mach_info ezx_fb_info_1 = {
.modes = &mode_ezx_old,
.num_modes = 1,
.lcd_conn = LCD_COLOR_TFT_16BPP,
};
static struct pxafb_mode_info mode_72r89803y01 = {
.pixclock = 192308,
.xres = 240,
.yres = 320,
.bpp = 32,
.depth = 18,
.hsync_len = 10,
.left_margin = 20,
.right_margin = 10,
.vsync_len = 2,
.upper_margin = 3,
.lower_margin = 2,
.sync = 0,
};
static struct pxafb_mach_info ezx_fb_info_2 = {
.modes = &mode_72r89803y01,
.num_modes = 1,
.lcd_conn = LCD_COLOR_TFT_18BPP,
};
static struct platform_device *devices[] __initdata = {
&ezx_backlight_device,
};
static unsigned long ezx_pin_config[] __initdata = {
/* PWM backlight */
GPIO16_PWM0_OUT,
/* BTUART */
GPIO42_BTUART_RXD,
GPIO43_BTUART_TXD,
GPIO44_BTUART_CTS,
GPIO45_BTUART_RTS,
/* STUART */
GPIO46_STUART_RXD,
GPIO47_STUART_TXD,
/* For A780 support (connected with Neptune GSM chip) */
GPIO30_USB_P3_2, /* ICL_TXENB */
GPIO31_USB_P3_6, /* ICL_VPOUT */
GPIO90_USB_P3_5, /* ICL_VPIN */
GPIO91_USB_P3_1, /* ICL_XRXD */
GPIO56_USB_P3_4, /* ICL_VMOUT */
GPIO113_USB_P3_3, /* /ICL_VMIN */
};
static void __init ezx_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
pxa_set_i2c_info(NULL);
if (machine_is_ezx_a780() || machine_is_ezx_e680())
set_pxa_fb_info(&ezx_fb_info_1);
else
set_pxa_fb_info(&ezx_fb_info_2);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
static void __init ezx_fixup(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
/* We have two ram chips. First one with 32MB at 0xA0000000 and a second
* 16MB one at 0xAC000000
*/
mi->nr_banks = 2;
mi->bank[0].start = 0xa0000000;
mi->bank[0].node = 0;
mi->bank[0].size = (32*1024*1024);
mi->bank[1].start = 0xac000000;
mi->bank[1].node = 1;
mi->bank[1].size = (16*1024*1024);
}
#ifdef CONFIG_MACH_EZX_A780
MACHINE_START(EZX_A780, "Motorola EZX A780")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = ezx_fixup,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = &ezx_init,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_E680
MACHINE_START(EZX_E680, "Motorola EZX E680")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = ezx_fixup,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = &ezx_init,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_A1200
MACHINE_START(EZX_A1200, "Motorola EZX A1200")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = ezx_fixup,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = &ezx_init,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_A910
MACHINE_START(EZX_A910, "Motorola EZX A910")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = ezx_fixup,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = &ezx_init,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_E6
MACHINE_START(EZX_E6, "Motorola EZX E6")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = ezx_fixup,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = &ezx_init,
MACHINE_END
#endif
#ifdef CONFIG_MACH_EZX_E2
MACHINE_START(EZX_E2, "Motorola EZX E2")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = ezx_fixup,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = &ezx_init,
MACHINE_END
#endif
......@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/smc91x.h>
#include <asm/types.h>
#include <asm/setup.h>
......@@ -38,6 +39,7 @@
#include <asm/arch/pxafb.h>
#include <asm/arch/ssp.h>
#include <asm/arch/pxa27x_keypad.h>
#include <asm/arch/pxa3xx_nand.h>
#include <asm/arch/littleton.h>
#include "generic.h"
......@@ -101,18 +103,26 @@ static struct resource smc91x_resources[] = {
[1] = {
.start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
.end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
}
};
static struct smc91x_platdata littleton_smc91x_info = {
.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT |
SMC91X_NOWAIT | SMC91X_USE_DMA,
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
.dev = {
.platform_data = &littleton_smc91x_info,
},
};
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULES)
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
/* use bit 30, 31 as the indicator of command parameter number */
#define CMD0(x) ((0x00000000) | ((x) << 9))
#define CMD1(x, x1) ((0x40000000) | ((x) << 9) | 0x100 | (x1))
......@@ -311,9 +321,9 @@ static void littleton_init_lcd(void)
}
#else
static inline void littleton_init_lcd(void) {};
#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULES */
#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES)
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static unsigned int littleton_matrix_key_map[] = {
/* KEY(row, col, key_code) */
KEY(1, 3, KEY_0), KEY(0, 0, KEY_1), KEY(1, 0, KEY_2), KEY(2, 0, KEY_3),
......@@ -361,6 +371,57 @@ static void __init littleton_init_keypad(void)
static inline void littleton_init_keypad(void) {}
#endif
#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
static struct mtd_partition littleton_nand_partitions[] = {
[0] = {
.name = "Bootloader",
.offset = 0,
.size = 0x060000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
[1] = {
.name = "Kernel",
.offset = 0x060000,
.size = 0x200000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
[2] = {
.name = "Filesystem",
.offset = 0x0260000,
.size = 0x3000000, /* 48M - rootfs */
},
[3] = {
.name = "MassStorage",
.offset = 0x3260000,
.size = 0x3d40000,
},
[4] = {
.name = "BBT",
.offset = 0x6FA0000,
.size = 0x80000,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
/* NOTE: we reserve some blocks at the end of the NAND flash for
* bad block management, and the max number of relocation blocks
* differs on different platforms. Please take care with it when
* defining the partition table.
*/
};
static struct pxa3xx_nand_platform_data littleton_nand_info = {
.enable_arbiter = 1,
.parts = littleton_nand_partitions,
.nr_parts = ARRAY_SIZE(littleton_nand_partitions),
};
static void __init littleton_init_nand(void)
{
pxa3xx_set_nand_info(&littleton_nand_info);
}
#else
static inline void littleton_init_nand(void) {}
#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
static void __init littleton_init(void)
{
/* initialize MFP configurations */
......@@ -374,6 +435,7 @@ static void __init littleton_init(void)
littleton_init_lcd();
littleton_init_keypad();
littleton_init_nand();
}
MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)")
......
......@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/smc91x.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
......@@ -226,14 +227,6 @@ static struct pxa2xx_spi_master pxa_ssp_master_info = {
.num_chipselect = 0,
};
static struct platform_device pxa_ssp = {
.name = "pxa2xx-spi",
.id = 1,
.dev = {
.platform_data = &pxa_ssp_master_info,
},
};
static int lubbock_ads7846_pendown_state(void)
{
/* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */
......@@ -292,11 +285,18 @@ static struct resource smc91x_resources[] = {
},
};
static struct smc91x_platdata lubbock_smc91x_info = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_2,
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
.dev = {
.platform_data = &lubbock_smc91x_info,
},
};
static struct resource flash_resources[] = {
......@@ -367,7 +367,6 @@ static struct platform_device *devices[] __initdata = {
&smc91x_device,
&lubbock_flash_device[0],
&lubbock_flash_device[1],
&pxa_ssp,
};
static struct pxafb_mode_info sharp_lm8v31_mode = {
......@@ -471,6 +470,7 @@ static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
} else if (mode & IR_FIRMODE) {
LUB_MISC_WR |= 1 << 4;
}
pxa2xx_transceiver_mode(dev, mode);
local_irq_restore(flags);
}
......@@ -501,6 +501,7 @@ static void __init lubbock_init(void)
lubbock_flash_data[flashboot].name = "boot-rom";
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
}
......
......@@ -17,17 +17,15 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/mfd/htc-egpio.h>
#include <linux/mfd/htc-pasic3.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <asm/gpio.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
......@@ -44,7 +42,7 @@
#include "devices.h"
#include "generic.h"
static unsigned long magician_pin_config[] = {
static unsigned long magician_pin_config[] __initdata = {
/* SDRAM and Static Memory I/O Signals */
GPIO20_nSDCS_2,
......@@ -134,6 +132,7 @@ static unsigned long magician_pin_config[] = {
static void magician_irda_transceiver_mode(struct device *dev, int mode)
{
gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF);
pxa2xx_transceiver_mode(dev, mode);
}
static struct pxaficp_platform_data magician_ficp_info = {
......@@ -399,6 +398,7 @@ static struct platform_pwm_backlight_data backlight_data = {
static struct platform_device backlight = {
.name = "pwm-backlight",
.id = -1,
.dev = {
.parent = &pxa27x_device_pwm0.dev,
.platform_data = &backlight_data,
......@@ -511,6 +511,37 @@ static struct platform_device pasic3 = {
* External power
*/
static int power_supply_init(struct device *dev)
{
int ret;
ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
if (ret)
goto err_cs_ac;
ret = gpio_request(EGPIO_MAGICIAN_CABLE_STATE_USB, "CABLE_STATE_USB");
if (ret)
goto err_cs_usb;
ret = gpio_request(EGPIO_MAGICIAN_CHARGE_EN, "CHARGE_EN");
if (ret)
goto err_chg_en;
ret = gpio_request(GPIO30_MAGICIAN_nCHARGE_EN, "nCHARGE_EN");
if (!ret)
ret = gpio_direction_output(GPIO30_MAGICIAN_nCHARGE_EN, 0);
if (ret)
goto err_nchg_en;
return 0;
err_nchg_en:
gpio_free(EGPIO_MAGICIAN_CHARGE_EN);
err_chg_en:
gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB);
err_cs_usb:
gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
err_cs_ac:
return ret;
}
static int magician_is_ac_online(void)
{
return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
......@@ -527,14 +558,24 @@ static void magician_set_charge(int flags)
gpio_set_value(EGPIO_MAGICIAN_CHARGE_EN, flags);
}
static void power_supply_exit(struct device *dev)
{
gpio_free(GPIO30_MAGICIAN_nCHARGE_EN);
gpio_free(EGPIO_MAGICIAN_CHARGE_EN);
gpio_free(EGPIO_MAGICIAN_CABLE_STATE_USB);
gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
}
static char *magician_supplicants[] = {
"ds2760-battery.0", "backup-battery"
};
static struct pda_power_pdata power_supply_info = {
.init = power_supply_init,
.is_ac_online = magician_is_ac_online,
.is_usb_online = magician_is_usb_online,
.set_charge = magician_set_charge,
.exit = power_supply_exit,
.supplied_to = magician_supplicants,
.num_supplicants = ARRAY_SIZE(magician_supplicants),
};
......
......@@ -26,6 +26,7 @@
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/pwm_backlight.h>
#include <linux/smc91x.h>
#include <asm/types.h>
#include <asm/setup.h>
......@@ -110,9 +111,9 @@ static unsigned long mainstone_pin_config[] = {
GPIO45_AC97_SYSCLK,
/* Keypad */
GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,
GPIO94_KP_DKIN_1 | WAKEUP_ON_LEVEL_HIGH,
GPIO95_KP_DKIN_2 | WAKEUP_ON_LEVEL_HIGH,
GPIO93_KP_DKIN_0,
GPIO94_KP_DKIN_1,
GPIO95_KP_DKIN_2,
GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
......@@ -240,11 +241,19 @@ static struct resource smc91x_resources[] = {
}
};
static struct smc91x_platdata mainstone_smc91x_info = {
.flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
SMC91X_NOWAIT | SMC91X_USE_DMA,
};
static struct platform_device smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
.dev = {
.platform_data = &mainstone_smc91x_info,
},
};
static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
......@@ -455,6 +464,7 @@ static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
} else if (mode & IR_FIRMODE) {
MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
}
pxa2xx_transceiver_mode(dev, mode);
if (mode & IR_OFF) {
MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
} else {
......@@ -513,7 +523,7 @@ static struct pxaohci_platform_data mainstone_ohci_platform_data = {
.init = mainstone_ohci_init,
};
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULES)
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
static unsigned int mainstone_matrix_keys[] = {
KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C),
KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F),
......
......@@ -39,6 +39,28 @@ struct gpio_desc {
static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
static int __mfp_config_lpm(unsigned gpio, unsigned long lpm)
{
unsigned mask = GPIO_bit(gpio);
/* low power state */
switch (lpm) {
case MFP_LPM_DRIVE_HIGH:
PGSR(gpio) |= mask;
break;
case MFP_LPM_DRIVE_LOW:
PGSR(gpio) &= ~mask;
break;
case MFP_LPM_INPUT:
break;
default:
pr_warning("%s: invalid low power state for GPIO%d\n",
__func__, gpio);
return -EINVAL;
}
return 0;
}
static int __mfp_config_gpio(unsigned gpio, unsigned long c)
{
unsigned long gafr, mask = GPIO_bit(gpio);
......@@ -57,21 +79,8 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
else
GPDR(gpio) &= ~mask;
/* low power state */
switch (c & MFP_LPM_STATE_MASK) {
case MFP_LPM_DRIVE_HIGH:
PGSR(gpio) |= mask;
break;
case MFP_LPM_DRIVE_LOW:
PGSR(gpio) &= ~mask;
break;
case MFP_LPM_INPUT:
break;
default:
pr_warning("%s: invalid low power state for GPIO%d\n",
__func__, gpio);
if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK))
return -EINVAL;
}
/* give early warning if MFP_LPM_CAN_WAKEUP is set on the
* configurations of those pins not able to wakeup
......@@ -91,6 +100,18 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
return 0;
}
static inline int __mfp_validate(int mfp)
{
int gpio = mfp_to_gpio(mfp);
if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
return -1;
}
return gpio;
}
void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
{
unsigned long flags;
......@@ -99,13 +120,9 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
gpio = mfp_to_gpio(MFP_PIN(*c));
if (!gpio_desc[gpio].valid) {
pr_warning("%s: GPIO%d is invalid pin\n",
__func__, gpio);
gpio = __mfp_validate(MFP_PIN(*c));
if (gpio < 0)
continue;
}
local_irq_save(flags);
......@@ -116,6 +133,20 @@ void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
}
}
void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
{
unsigned long flags;
int gpio;
gpio = __mfp_validate(mfp);
if (gpio < 0)
return;
local_irq_save(flags);
__mfp_config_lpm(gpio, lpm);
local_irq_restore(flags);
}
int gpio_set_wake(unsigned int gpio, unsigned int on)
{
struct gpio_desc *d;
......
此差异已折叠。
......@@ -24,7 +24,9 @@
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/spi/spi.h>
#include <linux/spi/max7301.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/arch/hardware.h>
......@@ -108,6 +110,32 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
/*
* SPI host and devices
*/
static struct pxa2xx_spi_master pxa_ssp_master_info = {
.num_chipselect = 1,
};
static struct max7301_platform_data max7301_info = {
.base = -1,
};
/* bus_num must match id in pxa2xx_set_spi_info() call */
static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "max7301",
.platform_data = &max7301_info,
.max_speed_hz = 13000000,
.bus_num = 1,
.chip_select = 0,
.mode = SPI_MODE_0,
},
};
/*
* NOR flash
*/
static struct physmap_flash_data pcm027_flash_data = {
.width = 4,
};
......@@ -190,6 +218,9 @@ static void __init pcm027_init(void)
#ifdef CONFIG_MACH_PCM990_BASEBOARD
pcm990_baseboard_init();
#endif
pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
}
static void __init pcm027_map_io(void)
......
......@@ -33,14 +33,30 @@
#include <asm/arch/camera.h>
#include <asm/mach/map.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa2xx-gpio.h>
#include <asm/arch/audio.h>
#include <asm/arch/mmc.h>
#include <asm/arch/ohci.h>
#include <asm/arch/pcm990_baseboard.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mfp-pxa27x.h>
#include "devices.h"
#include "generic.h"
static unsigned long pcm990_pin_config[] __initdata = {
/* MMC */
GPIO32_MMC_CLK,
GPIO112_MMC_CMD,
GPIO92_MMC_DAT_0,
GPIO109_MMC_DAT_1,
GPIO110_MMC_DAT_2,
GPIO111_MMC_DAT_3,
/* USB */
GPIO88_USBH1_PWR,
GPIO89_USBH1_PEN,
/* PWM0 */
GPIO16_PWM0_OUT,
};
/*
* pcm990_lcd_power - control power supply to the LCD
......@@ -277,16 +293,6 @@ static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
{
int err;
/*
* enable GPIO for PXA27x MMC controller
*/
pxa_gpio_mode(GPIO32_MMCCLK_MD);
pxa_gpio_mode(GPIO112_MMCCMD_MD);
pxa_gpio_mode(GPIO92_MMCDAT0_MD);
pxa_gpio_mode(GPIO109_MMCDAT1_MD);
pxa_gpio_mode(GPIO110_MMCDAT2_MD);
pxa_gpio_mode(GPIO111_MMCDAT3_MD);
err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED,
"MMC card detect", data);
if (err)
......@@ -333,8 +339,6 @@ static struct pxamci_platform_data pcm990_mci_platform_data = {
*/
static int pcm990_ohci_init(struct device *dev)
{
pxa_gpio_mode(PCM990_USB_OVERCURRENT);
pxa_gpio_mode(PCM990_USB_PWR_EN);
/*
* disable USB port 2 and 3
* power sense is active low
......@@ -361,23 +365,27 @@ static struct pxaohci_platform_data pcm990_ohci_platform_data = {
* PXA27x Camera specific stuff
*/
#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
static unsigned long pcm990_camera_pin_config[] = {
/* CIF */
GPIO98_CIF_DD_0,
GPIO105_CIF_DD_1,
GPIO104_CIF_DD_2,
GPIO103_CIF_DD_3,
GPIO95_CIF_DD_4,
GPIO94_CIF_DD_5,
GPIO93_CIF_DD_6,
GPIO108_CIF_DD_7,
GPIO107_CIF_DD_8,
GPIO106_CIF_DD_9,
GPIO42_CIF_MCLK,
GPIO45_CIF_PCLK,
GPIO43_CIF_FV,
GPIO44_CIF_LV,
};
static int pcm990_pxacamera_init(struct device *dev)
{
pxa_gpio_mode(GPIO98_CIF_DD_0_MD);
pxa_gpio_mode(GPIO105_CIF_DD_1_MD);
pxa_gpio_mode(GPIO104_CIF_DD_2_MD);
pxa_gpio_mode(GPIO103_CIF_DD_3_MD);
pxa_gpio_mode(GPIO95_CIF_DD_4_MD);
pxa_gpio_mode(GPIO94_CIF_DD_5_MD);
pxa_gpio_mode(GPIO93_CIF_DD_6_MD);
pxa_gpio_mode(GPIO108_CIF_DD_7_MD);
pxa_gpio_mode(GPIO107_CIF_DD_8_MD);
pxa_gpio_mode(GPIO106_CIF_DD_9_MD);
pxa_gpio_mode(GPIO42_CIF_MCLK_MD);
pxa_gpio_mode(GPIO45_CIF_PCLK_MD);
pxa_gpio_mode(GPIO43_CIF_FV_MD);
pxa_gpio_mode(GPIO44_CIF_LV_MD);
pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config));
return 0;
}
......@@ -449,8 +457,10 @@ static struct map_desc pcm990_io_desc[] __initdata = {
*/
void __init pcm990_baseboard_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config));
/* register CPLD access */
iotable_init(pcm990_io_desc, ARRAY_SIZE(pcm990_io_desc));
iotable_init(ARRAY_AND_SIZE(pcm990_io_desc));
/* register CPLD's IRQ controller */
pcm990_init_irq();
......@@ -458,7 +468,6 @@ void __init pcm990_baseboard_init(void)
#ifndef CONFIG_PCM990_DISPLAY_NONE
set_pxa_fb_info(&pcm990_fbinfo);
#endif
pxa_gpio_mode(GPIO16_PWM0_MD);
platform_device_register(&pcm990_backlight_device);
/* MMC */
......@@ -473,9 +482,8 @@ void __init pcm990_baseboard_init(void)
#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
pxa_set_camera_info(&pcm990_pxacamera_platform_data);
i2c_register_board_info(0, pcm990_i2c_devices,
ARRAY_SIZE(pcm990_i2c_devices));
i2c_register_board_info(0, ARRAY_AND_SIZE(pcm990_i2c_devices));
#endif
printk(KERN_INFO"PCM-990 Evaluation baseboard initialized\n");
printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");
}
......@@ -267,6 +267,7 @@ static void poodle_irda_transceiver_mode(struct device *dev, int mode)
} else {
GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
}
pxa2xx_transceiver_mode(dev, mode);
}
static struct pxaficp_platform_data poodle_ficp_platform_data = {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -254,6 +254,7 @@ static void board_irda_mode(struct device *dev, int mode)
/* Fast mode */
trizeps_conxs_ircr |= ConXS_IRCR_MODE;
}
pxa2xx_transceiver_mode(dev, mode);
if (mode & IR_OFF) {
trizeps_conxs_ircr |= ConXS_IRCR_SD;
} else {
......
此差异已折叠。
此差异已折叠。
......@@ -116,6 +116,10 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
GPIO27_MMC2_DAT3,
GPIO28_MMC2_CLK,
GPIO29_MMC2_CMD,
/* Debug LEDs */
GPIO1_2_GPIO | MFP_LPM_DRIVE_HIGH,
GPIO4_2_GPIO | MFP_LPM_DRIVE_HIGH,
};
#define NUM_LCD_DETECT_PINS 7
......@@ -189,6 +193,8 @@ void __init zylonite_pxa320_init(void)
/* GPIO pin assignment */
gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9);
gpio_debug_led1 = mfp_to_gpio(MFP_PIN_GPIO1_2);
gpio_debug_led2 = mfp_to_gpio(MFP_PIN_GPIO4_2);
/* MMC card detect & write protect for controller 0 */
zylonite_mmc_slot[0].gpio_cd = mfp_to_gpio(MFP_PIN_GPIO1);
......
......@@ -103,7 +103,7 @@ static void clk_gpio27_disable(void)
}
static struct clk clk_gpio27 = {
.name = "GPIO27_CLK",
.name = "SA1111_CLK",
.rate = 3686400,
.enable = clk_gpio27_enable,
.disable = clk_gpio27_disable,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册