* Linux on ppc440gp
From: Gorelik, Jacob (335F) @ 2010-10-06 14:35 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <75413B9E73E7F04B96503BC6DAF2C5D19054A3F20E@ALTPHYEMBEVSP30.RES.AD.JPL>
[-- Attachment #1.1: Type: text/plain, Size: 260 bytes --]
Hello,
I am trying to run linux on a custom PPC440GP board; however, something goes wrong early in the boot process. I am not sure if the problem is in the device tree or in the memory map.
I've attached the log and the config files.
Thank you,
Jacob
[-- Attachment #1.2: Type: text/html, Size: 468 bytes --]
[-- Attachment #2: log.txt --]
[-- Type: application/octet-stream, Size: 2720 bytes --]
Using Starter440 machine description
Linux version 2.6.36-rc5 (jacob@jacob-laptop) (gcc version 4.2.2) #6 Tue Oct 5 15:42:56 PDT 2010
Found initrd at 0xcee3a000:0xcefff155
bootconsole [udbg0] enabled
setup_arch: bootmem
arch: exit
Zone PFN ranges:
DMA 0x00000000 -> 0x0000f000
Normal empty
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
0: 0x00000000 -> 0x0000f000
MMU: Allocated 1088 bytes of context maps for 255 contexts
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 60960
Kernel command line: root=/dev/ram rw ip=137.79.31.87:137.79.31.21:137.79.31.1:255.255.255.0:starter440:eth0:off panic=1 console=ttyS0,57600
PID hash table entries: 1024 (order: 0, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 238492k/245760k available (3060k kernel code, 7268k reserved, 100k data, 107k bss, 136k init)
Kernel virtual memory layout:
* 0xfffdf000..0xfffff000 : fixmap
* 0x0ee00000..0x0f000000 : consistent mem
* 0x0edfe000..0x0ee00000 : early ioremap
* 0xd1000000..0x0edfe000 : vmalloc & ioremap
SLUB: Genslabs=11, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical RCU implementation.
RCU-based detection of stalled CPUs is disabled.
Verbose stalled-CPUs detection is disabled.
NR_IRQS:512 nr_irqs:512
UIC0 (32 IRQ sources) at DCR 0xc0
UIC1 (32 IRQ sources) at DCR 0xd0
clocksource: timebase mult[d55555] shift[22] registered
Data machine check in kernel mode.
Oops: Machine check, sig: 7 [#1]
Starter440
last sysfs file:
Modules linked in:
NIP: c0009320 LR: c000c9d4 CTR: c00088e8
REGS: cee35f10 TRAP: 0202 Not tainted (2.6.36-rc5)
MSR: 00021000 <ME,CE> CR: 42f22f22 XER: 00000000
TASK = c0300350[0] 'swapper' THREAD: c0310000
GPR00: 08000000 c0311f00 c0300350 c0311f10 c0301110 00000000 00000077 c0303be8
GPR08: c0301110 c000c9d4 00021002 c0009320 c0300530 00000000 00000000 00000000
GPR16: 0ffe2864 0ffe7600 00000000 00000000 00000000 00000000 c0000020 00000001
GPR24: 00000000 00000000 00000e60 c03174d8 c0310000 c02f7878 c02f7668 c0316320
NIP [c0009320] timer_interrupt+0x0/0x118
LR [c000c9d4] ret_from_except+0x0/0x18
Call Trace:
[c0311f00] [c0050130] notifier_call_chain+0x60/0xac (unreliable)
--- Exception: 901 at start_kernel+0x194/0x2a4
LR = start_kernel+0x184/0x2a4
[c0311ff0] [c0000060] _start+0x60/0xbc
Instruction dump:
409efff0 7d6a5b78 7d495378 39400000 7d404378 39600000 3d00c030 39081110
7d295b78 90080064 91280060 4e800020 <9421fff0> 7c0802a6 bfc10008 90010014
---[ end trace 31fd0ba7d8756001 ]---
Kernel panic - not syncing: Attempted to kill the idle task!
Call Trace:
Rebooting in 1 seconds..
[-- Attachment #3: auto.conf --]
[-- Type: application/octet-stream, Size: 7502 bytes --]
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.36-rc5
# Tue Oct 5 14:23:31 2010
#
CONFIG_CRC32=y
CONFIG_SECCOMP=y
CONFIG_FLATMEM_MANUAL=y
CONFIG_INOTIFY_USER=y
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NET_ETHERNET=y
CONFIG_EXPERIMENTAL=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_SSB_POSSIBLE=y
CONFIG_CHELSIO_T4_DEPENDS=y
CONFIG_FSNOTIFY=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_NETDEV_1000=y
CONFIG_AUDIT_ARCH=y
CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_IBM_NEW_EMAC=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_WLAN=y
CONFIG_CONNECTOR=y
CONFIG_LEGACY_PTYS=y
CONFIG_SERIAL_8250=y
CONFIG_OF_DEVICE=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_BRANCH_PROFILE_NONE=y
CONFIG_VGA_ARB=y
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_MTD_PARTITIONS=y
CONFIG_PRINTK=y
CONFIG_TIMERFD=y
CONFIG_MTD_CFI_I2=y
CONFIG_BOUNCE=y
CONFIG_SHMEM=y
CONFIG_MTD=y
CONFIG_DNOTIFY=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_NR_IRQS=512
CONFIG_BOOKE=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_CHELSIO_T3_DEPENDS=y
CONFIG_ZLIB_INFLATE=y
CONFIG_IP_PNP=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_ARCH_HAS_WALK_MEMORY=y
CONFIG_LOCKD=y
CONFIG_JFFS2_FS=y
CONFIG_PPC_OF=y
CONFIG_MTD_CFI_UTIL=y
CONFIG_PPC_ADV_DEBUG_DVCS=2
CONFIG_STANDALONE=y
CONFIG_BLOCK=y
CONFIG_HAVE_IDE=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_ROOT_NFS=y
CONFIG_BUG=y
CONFIG_OF_IRQ=y
CONFIG_DEVKMEM=y
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
CONFIG_DTC=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_WORD_SIZE=32
CONFIG_MFD_SUPPORT=y
CONFIG_ZONE_DMA=y
CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_VGA_ARB_MAX_GPUS=16
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_PPC_MMU_NOHASH=y
CONFIG_EXTRA_TARGETS=""
CONFIG_NETDEVICES=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_EVENTFD=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_MTD_OF_PARTS=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_MTD_CFI=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_SPARSE_IRQ=y
CONFIG_DEFAULT_CFQ=y
CONFIG_MAX_ACTIVE_REGIONS=32
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_IOSCHED_CFQ=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_PPC_UDBG_16550=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_RD_GZIP=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_TREE_RCU=y
CONFIG_LBDAF=y
CONFIG_KERNEL_START=0xc0000000
CONFIG_PPC=y
CONFIG_BINFMT_ELF=y
CONFIG_HOTPLUG=y
CONFIG_SLABINFO=y
CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
CONFIG_440GP=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_TMPFS=y
CONFIG_ANON_INODES=y
CONFIG_FUTEX=y
CONFIG_IP_PNP_DHCP=y
CONFIG_PPC_ADV_DEBUG_IACS=4
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SLUB_DEBUG=y
CONFIG_SYSVIPC=y
CONFIG_MODULES=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_UNIX=y
CONFIG_NETDEV_10000=y
CONFIG_NFS_FS=y
CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
CONFIG_MISC_DEVICES=y
CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_MTD_CFI_I1=y
CONFIG_NFS_COMMON=y
CONFIG_PPC_WERROR=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_EXTRA_FIRMWARE=""
CONFIG_PROC_EVENTS=y
CONFIG_VIRT_TO_BUS=y
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_IBM_NEW_EMAC_TXB=64
CONFIG_SLUB=y
CONFIG_JFFS2_ZLIB=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_DEBUG_FS=y
CONFIG_BASE_FULL=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_SUNRPC=y
CONFIG_FW_LOADER=y
CONFIG_KALLSYMS=y
CONFIG_PCI=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_MATH_EMULATION=y
CONFIG_PCI_QUIRKS=y
CONFIG_SIGNALFD=y
CONFIG_LOCKD_V4=y
CONFIG_HAS_IOMEM=y
CONFIG_PROC_DEVICETREE=y
CONFIG_PPC_PCI_CHOICE=y
CONFIG_PROC_KCORE=y
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_CONSTRUCTORS=y
CONFIG_EPOLL=y
CONFIG_PPC_ADV_DEBUG_DACS=2
CONFIG_NET=y
CONFIG_EXT2_FS=y
CONFIG_MTD_GEN_PROBE=y
CONFIG_PACKET=y
CONFIG_NFS_V3=y
CONFIG_INET=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_PCI_DOMAINS=y
CONFIG_IRQ_PER_CPU=y
CONFIG_HAVE_KPROBES=y
CONFIG_PPC32=y
CONFIG_IBM_NEW_EMAC_RXB=128
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_POSIX_MQUEUE=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_MTD_BLKDEVS=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_PAGE_OFFSET=0xc0000000
CONFIG_PREEMPT_NONE=y
CONFIG_KALLSYMS_ALL=y
CONFIG_GENERIC_BUG=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_INET_TCP_DIAG=y
CONFIG_IOSCHED_NOOP=y
CONFIG_PTE_64BIT=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_DEBUG_KERNEL=y
CONFIG_COMPAT_BRK=y
CONFIG_LOCALVERSION=""
CONFIG_SCHED_DEBUG=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_SCSI_MOD=y
CONFIG_SERIAL_CORE=y
CONFIG_EMBEDDED=y
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_CHELSIO_T4VF_DEPENDS=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_HAS_DMA=y
CONFIG_LOWMEM_SIZE=0x0f000000
CONFIG_LOCALVERSION_AUTO=y
CONFIG_JFFS2_RTIME=y
CONFIG_MISC_FILESYSTEMS=y
CONFIG_FTRACE=y
CONFIG_OF_DYNAMIC=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_PPC_DCR_NATIVE=y
CONFIG_PHYS_64BIT=y
CONFIG_TASK_SIZE=0x00200000
CONFIG_RT_MUTEXES=y
CONFIG_PCI_SYSCALL=y
CONFIG_WIRELESS=y
CONFIG_HZ_250=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_FRAME_WARN=1024
CONFIG_GENERIC_HWEIGHT=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INLINE_SPIN_UNLOCK=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_HAS_IOPORT=y
CONFIG_HZ=250
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_NLATTR=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_IBM_NEW_EMAC_ZMII=y
CONFIG_SYSFS=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_MSDOS_PARTITION=y
CONFIG_HAVE_OPROFILE=y
CONFIG_THERMAL=y
CONFIG_4xx=y
CONFIG_PPC_MMU_NOHASH_32=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_IP_FIB_HASH=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_CONSISTENT_SIZE=0x00200000
CONFIG_STARTER440=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_EARLY_PRINTK=y
CONFIG_PPC_ADV_DEBUG_REGS=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_BASE_SMALL=0
CONFIG_PPC_4K_PAGES=y
CONFIG_PROC_FS=y
CONFIG_MTD_BLOCK=y
CONFIG_FLATMEM=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SYSCTL=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_CRAMFS=y
CONFIG_PPC_DCR=y
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_BLK_DEV=y
CONFIG_OF_FLATTREE=y
CONFIG_TRACING_SUPPORT=y
CONFIG_UNIX98_PTYS=y
CONFIG_4xx_SOC=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_INET_DIAG=y
CONFIG_ELF_CORE=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_USB_SUPPORT=y
CONFIG_MTD_CHAR=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_ARCH_HAS_ILOG2_U32=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_OF_ADDRESS=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_CROSS_COMPILE=""
CONFIG_44x=y
CONFIG_PRINT_STACK_DEPTH=64
CONFIG_SWAP=y
CONFIG_MODULE_UNLOAD=y
CONFIG_RCU_FANOUT=32
CONFIG_BITREVERSE=y
CONFIG_DEVPORT=y
CONFIG_STDBINUTILS=y
CONFIG_BLK_DEV_RAM_SIZE=35000
CONFIG_FILE_LOCKING=y
CONFIG_AIO=y
CONFIG_OF=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
CONFIG_PHYSICAL_START=0x00000000
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_PROC_SYSCTL=y
CONFIG_MMU=y
CONFIG_INLINE_WRITE_UNLOCK=y
[-- Attachment #4: starter440.dts --]
[-- Type: application/octet-stream, Size: 7845 bytes --]
/*
* Device Tree Source for BRE Starter440
*
* Copyright (c) 2006, 2007 IBM Corp.
* Josh Boyer <jwboyer@linux.vnet.ibm.com>, David Gibson <dwg@au1.ibm.com>
*
* 2010 JPL
*
* 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.
*/
/dts-v1/;
/ {
#address-cells = <2>;
#size-cells = <1>;
model = "ibm,starter440";
compatible = "ibm,starter440";
dcr-parent = <&{/cpus/cpu@0}>;
aliases {
ethernet0 = &EMAC0;
ethernet1 = &EMAC1;
serial0 = &UART0;
serial1 = &UART1;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
model = "PowerPC,440GP";
reg = <0x00000000>;
clock-frequency = <0>; // Filled in by zImage
timebase-frequency = <0>; // Filled in by zImage
i-cache-line-size = <32>;
d-cache-line-size = <32>;
i-cache-size = <32768>; /* 32 kB */
d-cache-size = <32768>; /* 32 kB */
dcr-controller;
dcr-access-method = "native";
};
};
memory {
device_type = "memory";
reg = <0x00000000 0x00000000 0x00000000>; // Filled in by zImage
};
UIC0: interrupt-controller0 {
compatible = "ibm,uic-440gp", "ibm,uic";
interrupt-controller;
cell-index = <0>;
dcr-reg = <0x0c0 0x009>;
#address-cells = <0>;
#size-cells = <0>;
#interrupt-cells = <2>;
};
UIC1: interrupt-controller1 {
compatible = "ibm,uic-440gp", "ibm,uic";
interrupt-controller;
cell-index = <1>;
dcr-reg = <0x0d0 0x009>;
#address-cells = <0>;
#size-cells = <0>;
#interrupt-cells = <2>;
interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
interrupt-parent = <&UIC0>;
};
CPC0: cpc {
compatible = "ibm,cpc-440gp";
dcr-reg = <0x0b0 0x003 0x0e0 0x010>;
// FIXME: anything else?
};
plb {
compatible = "ibm,plb-440gp", "ibm,plb4";
#address-cells = <2>;
#size-cells = <1>;
ranges;
clock-frequency = <0>; // Filled in by zImage
SDRAM0: memory-controller {
compatible = "ibm,sdram-440gp";
dcr-reg = <0x010 0x002>;
// FIXME: anything else?
};
SRAM0: sram {
compatible = "ibm,sram-440gp";
dcr-reg = <0x020 0x008 0x00a 0x001>;
};
DMA0: dma {
// FIXME: ???
compatible = "ibm,dma-440gp";
dcr-reg = <0x100 0x027>;
};
MAL0: mcmal {
compatible = "ibm,mcmal-440gp", "ibm,mcmal";
dcr-reg = <0x180 0x062>;
num-tx-chans = <4>;
num-rx-chans = <4>;
interrupt-parent = <&MAL0>;
interrupts = <0x0 0x1 0x2 0x3 0x4>;
#interrupt-cells = <1>;
#address-cells = <0>;
#size-cells = <0>;
interrupt-map = </*TXEOB*/ 0x0 &UIC0 0xa 0x4
/*RXEOB*/ 0x1 &UIC0 0xb 0x4
/*SERR*/ 0x2 &UIC1 0x0 0x4
/*TXDE*/ 0x3 &UIC1 0x1 0x4
/*RXDE*/ 0x4 &UIC1 0x2 0x4>;
interrupt-map-mask = <0xffffffff>;
};
OPB0: opb {
compatible = "ibm,opb-440gp", "ibm,opb";
#address-cells = <1>;
#size-cells = <1>;
/* Wish there was a nicer way of specifying a full 32-bit
range */
ranges = <0x00000000 0x00000001 0x00000000 0x80000000
0x80000000 0x00000001 0x80000000 0x80000000>;
dcr-reg = <0x090 0x00b>;
interrupt-parent = <&UIC1>;
interrupts = <0x7 0x4>;
clock-frequency = <0>; // Filled in by zImage
EBC0: ebc {
compatible = "ibm,ebc-440gp", "ibm,ebc";
dcr-reg = <0x012 0x002>;
#address-cells = <2>;
#size-cells = <1>;
clock-frequency = <0>; // Filled in by zImage
// ranges property is supplied by zImage
// based on firmware's configuration of the
// EBC bridge
interrupts = <0x5 0x4>;
interrupt-parent = <&UIC1>;
flash@0,0 {
compatible = "jedec-flash";
bank-width = <1>;
reg = <0x00000000 0x00000000 0x00400000>;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "bank1";
reg = <0x00000000 0x00200000>;
};
partition@200000 {
label = "bank2";
reg = <0x00200000 0x00200000>;
};
};
ir@1,0 {
reg = <0x00000001 0x00000000 0x00000010>;
};
};
UART0: serial@40000200 {
device_type = "serial";
compatible = "ns16550";
reg = <0x40000200 0x00000008>;
virtual-reg = <0xe0000200>;
clock-frequency = <0x388394>;
current-speed = <0xe100>;
interrupt-parent = <&UIC0>;
interrupts = <0x0 0x4>;
};
UART1: serial@40000300 {
device_type = "serial";
compatible = "ns16550";
reg = <0x40000300 0x00000008>;
virtual-reg = <0xe0000300>;
clock-frequency = <0x388394>;
current-speed = <0xe100>;
interrupt-parent = <&UIC0>;
interrupts = <0x1 0x4>;
};
IIC0: i2c@40000400 {
/* FIXME */
compatible = "ibm,iic-440gp", "ibm,iic";
reg = <0x40000400 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
};
IIC1: i2c@40000500 {
/* FIXME */
compatible = "ibm,iic-440gp", "ibm,iic";
reg = <0x40000500 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x3 0x4>;
};
GPIO0: gpio@40000700 {
/* FIXME */
compatible = "ibm,gpio-440gp";
reg = <0x40000700 0x00000020>;
};
ZMII0: emac-zmii@40000780 {
compatible = "ibm,zmii-440gp", "ibm,zmii";
reg = <0x40000780 0x0000000c>;
};
EMAC0: ethernet@40000800 {
device_type = "network";
compatible = "ibm,emac-440gp", "ibm,emac";
interrupt-parent = <&UIC1>;
interrupts = <0x1c 0x4 0x1d 0x4>;
reg = <0x40000800 0x00000070>;
local-mac-address = [000000000000]; // Filled in by zImage
mal-device = <&MAL0>;
mal-tx-channel = <0 1>;
mal-rx-channel = <0>;
cell-index = <0>;
max-frame-size = <1500>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
phy-mode = "rmii";
phy-map = <0x00000001>;
zmii-device = <&ZMII0>;
zmii-channel = <0>;
};
EMAC1: ethernet@40000900 {
device_type = "network";
compatible = "ibm,emac-440gp", "ibm,emac";
interrupt-parent = <&UIC1>;
interrupts = <0x1e 0x4 0x1f 0x4>;
reg = <0x40000900 0x00000070>;
local-mac-address = [000000000000]; // Filled in by zImage
mal-device = <&MAL0>;
mal-tx-channel = <2 3>;
mal-rx-channel = <1>;
cell-index = <1>;
max-frame-size = <1500>;
rx-fifo-size = <4096>;
tx-fifo-size = <2048>;
phy-mode = "rmii";
phy-map = <0x00000001>;
zmii-device = <&ZMII0>;
zmii-channel = <1>;
};
GPT0: gpt@40000a00 {
/* FIXME */
reg = <0x40000a00 0x000000d4>;
interrupt-parent = <&UIC0>;
interrupts = <0x12 0x4 0x13 0x4 0x14 0x4 0x15 0x4 0x16 0x4>;
};
};
PCIX0: pci@20ec00000 {
device_type = "pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix";
primary;
reg = <0x00000002 0x0ec00000 0x00000008 /* Config space access */
0x00000000 0x00000000 0x00000000 /* no IACK cycles */
0x00000002 0x0ed00000 0x00000004 /* Special cycles */
0x00000002 0x0ec80000 0x000000f0 /* Internal registers */
0x00000002 0x0ec80100 0x000000fc>; /* Internal messaging registers */
/* Outbound ranges, one memory and one IO,
* later cannot be changed
*/
ranges = <0x02000000 0x00000000 0x80000000 0x00000003 0x80000000 0x00000000 0x80000000
0x01000000 0x00000000 0x00000000 0x00000002 0x08000000 0x00000000 0x00010000>;
/* Inbound 2GB range starting at 0 */
dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>;
/* Ebony has all 4 IRQ pins tied together per slot */
interrupt-map-mask = <0xf800 0x0 0x0 0x0>;
interrupt-map = <
/* IDSEL 1 */
0x800 0x0 0x0 0x0 &UIC0 0x17 0x8
/* IDSEL 2 */
0x1000 0x0 0x0 0x0 &UIC0 0x18 0x8
/* IDSEL 3 */
0x1800 0x0 0x0 0x0 &UIC0 0x19 0x8
/* IDSEL 4 */
0x2000 0x0 0x0 0x0 &UIC0 0x1a 0x8
>;
};
};
chosen {
linux,stdout-path = "/plb/opb/serial@40000200";
};
};
^ permalink raw reply
* Re: powerpc, fs_enet: scanning PHY after Linux is up
From: Heiko Schocher @ 2010-10-06 9:53 UTC (permalink / raw)
To: Grant Likely
Cc: linuxppc-dev, devicetree-discuss, Holger Brunck, Detlev Zundel,
netdev
In-Reply-To: <AANLkTinSersREjDnvg=8Gvpa6YmLuzgF1H8eEXRyCpW0@mail.gmail.com>
Hello Grant,
Thanks for your answer!
Grant Likely wrote:
> On Mon, Oct 4, 2010 at 1:32 AM, Heiko Schocher <hs@denx.de> wrote:
>> Hello all,
>>
>> we have on the mgcoge arch/powerpc/boot/dts/mgcoge.dts 3 fs_enet
>> devices. The first is accessible on boot, and so get correct
>> probed and works fine. For the other two fs_enet devices the PHYs
>> are on startup in reset, and gets later, through userapplikations,
>> out of reset ... so, on bootup, this 2 fs_enet devices could
>> not detect the PHY in drivers/of/of_mdio.c of_mdiobus_register(),
>> and if we want to use them later, we get for example:
>>
>> -bash-3.2# ifconfig eth2 172.31.31.33
>> net eth2: Could not attach to PHY
>> SIOCSIFFLAGS: No such device
>>
>> So the problem is, that we cannot rescan the PHYs, if they are
>> accessible. Also we could not load the fs_enet driver as a module,
>> because the first port is used fix.
>>
>> So, first question which comes in my mind, is:
>>
>> Is detecting the phy in drivers/of/of_mdio.c of_mdiobus_register()
>> the right place, or should it not better be done, when really
>> using the port?
>>
>> But we found another way to solve this issue:
>>
>> After the PHYs are out of reset, we just have to rescan the PHYs
>> with (for example PHY with addr 1)
>>
>> err = mdiobus_scan(bus, 1);
>>
>> and
>>
>> of_find_node_by_path("/soc@f0000000/cpm@119c0/mdio@10d40/ethernet-phy@1");
>> of_node_get(np);
>> dev_archdata_set_node(&err->dev.archdata, np);
>>
>> but thats just a hack ...
>
> Yeah, that's a hack. It really needs to be done via the of_mdio
> mechanisms so that dt <--> phy_device linkages remain consistent.
Yep, I know, thats the reason why I ask ;-)
>> So, the question is, is there a possibility to solve this problem?
>>
>> If there is no standard option, what would be with adding a
>> "scan_phy" file in
>>
>> /proc/device-tree/soc\@f0000000/cpm\@119c0/mdio\@10d40
>> (or better destination?)
>>
>> which with we could rescan a PHY with
>> "echo addr > /proc/device-tree/soc\@f0000000/cpm\@119c0/mdio\@10d40/scan_phy"
>> (so there is no need for using of_find_node_by_path(), as we should
>> have the associated device node here, and can step through the child
>> nodes with "for_each_child_of_node(np, child)" and check if reg == addr)
>>
>> or shouldn;t be at least, if the phy couldn;t be found when opening
>> the port, retrigger a scanning, if the phy now is accessible?
>
> One option would be to still register a phy_device for each phy
> described in the device tree, but defer binding a driver to each phy
> that doesn't respond. Then at of_phy_find_device() time, if it
Maybe I din;t get the trick, but the problem is, that
you can;t register a phy_device in drivers/of/of_mdio.c
of_mdiobus_register(), if the phy didn;t respond with the
phy_id ... and of_phy_find_device() is not (yet) used in fs_enet
> matches with a phy_device that isn't bound to a driver yet, then
> re-trigger the binding operation. At which point the phy id can be
> probed and the correct driver can be chosen. If binding succeeds,
> then return the phy_device handle. If not, then fail as it currently
> does.
Wouldn;t it be good, just if we need a PHY (on calling fs_enet_open)
to look if there is one?
Something like that (not tested):
in drivers/net/fs_enet/fs_enet-main.c in fs_init_phy()
called from fs_enet_open():
Do first:
phydev = of_phy_find_device(fep->fpi->phy_node);
Look if there is a driver (phy_dev->drv == NULL ?)
If not, call new function
of_mdiobus_register_phy(mii_bus, fep->fpi->phy_node)
see below patch for it.
If this succeeds, all is OK, and we can use this phy,
else ethernet not work.
!!just no idea, how to get mii_bus pointer ...
here the patch for the new function of_mdiobus_register_phy():
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index b474833..7afbb0b 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -21,6 +21,51 @@
MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
MODULE_LICENSE("GPL");
+int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *child)
+{
+ struct phy_device *phy;
+ const __be32 *addr;
+ int len;
+ int rc;
+
+ /* A PHY must have a reg property in the range [0-31] */
+ addr = of_get_property(child, "reg", &len);
+ if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) {
+ dev_err(&mdio->dev, "%s has invalid PHY address\n",
+ child->full_name);
+ return -1;
+ }
+
+ if (mdio->irq) {
+ mdio->irq[*addr] = irq_of_parse_and_map(child, 0);
+ if (!mdio->irq[*addr])
+ mdio->irq[*addr] = PHY_POLL;
+ }
+
+ phy = get_phy_device(mdio, be32_to_cpup(addr));
+ if (!phy || IS_ERR(phy)) {
+ dev_err(&mdio->dev, "error probing PHY at address %i\n",
+ *addr);
+ return -2;
+ }
+ phy_scan_fixups(phy);
+ /* Associate the OF node with the device structure so it
+ * can be looked up later */
+ of_node_get(child);
+ dev_archdata_set_node(&phy->dev.archdata, child);
+
+ /* All data is now stored in the phy struct; register it */
+ rc = phy_device_register(phy);
+ if (rc) {
+ phy_device_free(phy);
+ of_node_put(child);
+ return -3;
+ }
+
+ dev_dbg(&mdio->dev, "registered phy %s at address %i\n",
+ child->name, *addr);
+}
+
/**
* of_mdiobus_register - Register mii_bus and create PHYs from the device tree
* @mdio: pointer to mii_bus structure
@@ -31,7 +76,6 @@ MODULE_LICENSE("GPL");
*/
int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
{
- struct phy_device *phy;
struct device_node *child;
int rc, i;
@@ -51,46 +95,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
/* Loop over the child nodes and register a phy_device for each one */
for_each_child_of_node(np, child) {
- const __be32 *addr;
- int len;
-
- /* A PHY must have a reg property in the range [0-31] */
- addr = of_get_property(child, "reg", &len);
- if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) {
- dev_err(&mdio->dev, "%s has invalid PHY address\n",
- child->full_name);
- continue;
- }
-
- if (mdio->irq) {
- mdio->irq[*addr] = irq_of_parse_and_map(child, 0);
- if (!mdio->irq[*addr])
- mdio->irq[*addr] = PHY_POLL;
- }
-
- phy = get_phy_device(mdio, be32_to_cpup(addr));
- if (!phy || IS_ERR(phy)) {
- dev_err(&mdio->dev, "error probing PHY at address %i\n",
- *addr);
- continue;
- }
- phy_scan_fixups(phy);
-
- /* Associate the OF node with the device structure so it
- * can be looked up later */
- of_node_get(child);
- dev_archdata_set_node(&phy->dev.archdata, child);
-
- /* All data is now stored in the phy struct; register it */
- rc = phy_device_register(phy);
- if (rc) {
- phy_device_free(phy);
- of_node_put(child);
- continue;
- }
-
- dev_dbg(&mdio->dev, "registered phy %s at address %i\n",
- child->name, *addr);
+ of_mdiobus_register_phy(mdio, child);
}
return 0;
With this change, it would work on boot as actual (phy_device_register()
will fail for the PHYs who don;t work when booting).
Later, when opening the ethernet device, fs_init_phy, will look, if
we have a valid phy with driver, if not we try to register it again.
If this is successfull, we can use the device, if not we will fail,
as now ... what do you think?
bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply related
* Re: [PATCH 05/18] powerpc: Wire up 44x little endian boot for remaining 44x targets
From: Sean MacLennan @ 2010-10-06 2:10 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev, paulus, Ian Munsie, linux-kernel
In-Reply-To: <AANLkTimNeWEo5P0wXzszBiSYdh81=uhARA8KZPr7rcPf@mail.gmail.com>
On Tue, 5 Oct 2010 21:55:35 -0400
Josh Boyer <jwboyer@gmail.com> wrote:
> Well, Warp and Sam440EP are production boards for actual companies.
> The rest are all just eval boards. I don't know if the board
> maintainers care either way, I was just using them as examples of
> cases where someone might.
In the warp case, I basically don't care. I know LE would break some of
our telephony drivers since we assume PPC is BE. But on the other hand,
realistically, it will never get turned on by customers anyway.
We have to provide our own .config anyway, so it really don't hurt us
as long as it doesn't break BE support.
Cheers,
Sean
^ permalink raw reply
* Re: [PATCH 05/18] powerpc: Wire up 44x little endian boot for remaining 44x targets
From: Josh Boyer @ 2010-10-06 1:55 UTC (permalink / raw)
To: Ian Munsie; +Cc: paulus, linuxppc-dev, linux-kernel
In-Reply-To: <1286327715-sup-584@au1.ibm.com>
On Tue, Oct 5, 2010 at 9:28 PM, Ian Munsie <imunsie@au1.ibm.com> wrote:
> Excerpts from Josh Boyer's message of Fri Oct 01 21:27:37 +1000 2010:
>> > From: Ian Munsie <imunsie@au1.ibm.com>
>> >
>> > I haven't tested booting a little endian kernel on any of these target=
s,
>> > but they all claim to be 44x so my little endian trampoline should wor=
k
>> > on all of them, so wire it up on:
>> >
>> > bamboo
>> > katmai
>> > kilauea
>> > rainer
>> > sam440ep
>> > sequoia
>> > warp
>> > yosemite
>> > ebony
>>
>> I see no reason to do this at all. =A0If you haven't tested them and
>> there is no demand, there's no reason to wire them up. =A0Some might
>> actively want to disallow LE mode anyway, like the Warp or Sam440EP.
>
> I wasn't aware that the Warp and Sam440EP disallowed LE mode - I'll
> definitely unwire them and move the ARCH_SUPPORTS_LITTLE_ENDIAN to just
> the sub-arch's that support it.
Well, Warp and Sam440EP are production boards for actual companies.
The rest are all just eval boards. I don't know if the board
maintainers care either way, I was just using them as examples of
cases where someone might.
> As for the other boards, I would like to wire them up if they are able
> to support LE mode - If anyone has one handy I would love to hear if
> they are able to begin booting a LE kernel with these patches, or when &
> how they fail.
I'd avoid anything with an FPU until that gets tested. So no bamboo,
sequoia, canyonlands, etc.
I noticed that canyonlands isn't even covered. I'm guessing that's
because we don't need to create a wrapper for it because U-Boot does
direct loading of vmlinux and the DTB itself. Has anyone done any
work with getting U-Boot to work in LE mode or at least load LE
vmlinux images? The majority of new boards are going to be using
U-Boot and it's ability to load the DTB/FDT, so that would be
something that needs addressing.
josh
^ permalink raw reply
* Re: [PATCH 05/18] powerpc: Wire up 44x little endian boot for remaining 44x targets
From: Ian Munsie @ 2010-10-06 1:28 UTC (permalink / raw)
To: Josh Boyer; +Cc: paulus, linuxppc-dev, linux-kernel
In-Reply-To: <AANLkTins34TrEWj618_4XBRwGGFqRSehwWEp7jBubvsu@mail.gmail.com>
Excerpts from Josh Boyer's message of Fri Oct 01 21:27:37 +1000 2010:
> > From: Ian Munsie <imunsie@au1.ibm.com>
> >
> > I haven't tested booting a little endian kernel on any of these targets,
> > but they all claim to be 44x so my little endian trampoline should work
> > on all of them, so wire it up on:
> >
> > bamboo
> > katmai
> > kilauea
> > rainer
> > sam440ep
> > sequoia
> > warp
> > yosemite
> > ebony
>
> I see no reason to do this at all. If you haven't tested them and
> there is no demand, there's no reason to wire them up. Some might
> actively want to disallow LE mode anyway, like the Warp or Sam440EP.
I wasn't aware that the Warp and Sam440EP disallowed LE mode - I'll
definitely unwire them and move the ARCH_SUPPORTS_LITTLE_ENDIAN to just
the sub-arch's that support it.
As for the other boards, I would like to wire them up if they are able
to support LE mode - If anyone has one handy I would love to hear if
they are able to begin booting a LE kernel with these patches, or when &
how they fail.
Cheers,
-Ian
^ permalink raw reply
* Re: Introduce support for little endian PowerPC
From: Ian Munsie @ 2010-10-06 1:04 UTC (permalink / raw)
To: Josh Boyer; +Cc: paulus, linuxppc-dev, linux-kernel
In-Reply-To: <AANLkTikHcoccu-WGtSOSdkwU6Tw_An_VFkUcEoY==8=c@mail.gmail.com>
Hi Josh,
Excerpts from Josh Boyer's message of Fri Oct 01 21:36:35 +1000 2010:
> Aside from my general "uh, why?" stance, I'm very very hesitant to
> integrate anything in the kernel that doesn'.t have released patches
> on the toolchain side.
As I said the kernel can be built today with an unpatched toolchain
targetted at powerpcle-elf, the new powerpcle-linux target is mainly
required for userspace, but yes I want to get those patches out as soon
as possible.
> Also, which uClibc? The old and crusty uClibc that uses the horrible
> linuxthreads, or the somewhat less crusty that just switched to NPTL
> (which hasn't been verified on normal PowerPC that I recall). Why not
> use glibc...
As Ben said this was for a proof of concept and changing uClibc to
support it was quite literally a one line change.
I've been using stable packages as my base on the toolchain side of
things (gcc 4.4.4, binutils 2.20.1 and uClibc 0.9.31) so uClibc is still
using linuxthreads since they haven't released a version with NPTL yet.
> I'm not meeting to detract here, but the Kconfig should be dependent
> on && BROKEN until the above is fixed.
Good point.
Cheers,
-Ian
^ permalink raw reply
* linux-next: build failure in Linus' tree
From: Stephen Rothwell @ 2010-10-06 0:09 UTC (permalink / raw)
To: Linus; +Cc: linux-next, ppc-dev, linux-kernel
Hi Linus,
Today's linux-next initial build (powerpc ppc64_defconfig) failed like
this:
cc1: warnings being treated as errors
arch/powerpc/kernel/module.c: In function 'module_finalize':
arch/powerpc/kernel/module.c:66: error: unused variable 'err'
Caused by commit 5336377d6225959624146629ce3fc88ee8ecda3d ("modules: Fix
module_bug_list list corruption race").
I added the following patch for today:
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Wed, 6 Oct 2010 11:06:44 +1100
Subject: [PATCH] powerpc: remove unused variable
Since powerpc uses -Werror on arch powerpc, the build was broken like
this:
cc1: warnings being treated as errors
arch/powerpc/kernel/module.c: In function 'module_finalize':
arch/powerpc/kernel/module.c:66: error: unused variable 'err'
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
arch/powerpc/kernel/module.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 4ef93ae..49cee9d 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -63,7 +63,6 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, struct module *me)
{
const Elf_Shdr *sect;
- int err;
/* Apply feature fixups */
sect = find_section(hdr, sechdrs, "__ftr_fixup");
--
1.7.1
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply related
* [PATCH] powerpc/module: Remove unused variable err
From: Matthew McClintock @ 2010-10-05 22:26 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Matthew McClintock
Commit 5336377d6225959624146629ce3fc88ee8ecda3d removed
the need for err, remove the variable
Signed-off-by: Matthew McClintock <msm@freescale.com>
---
arch/powerpc/kernel/module.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 4ef93ae..49cee9d 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -63,7 +63,6 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, struct module *me)
{
const Elf_Shdr *sect;
- int err;
/* Apply feature fixups */
sect = find_section(hdr, sechdrs, "__ftr_fixup");
--
1.6.6.1
^ permalink raw reply related
* MSI-X vector allocation failure in upstream kernel
From: Anirban Chakraborty @ 2010-10-05 17:18 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org; +Cc: Ameen Rahman
Hi All,
I am trying to test qlcnic driver (for 10Gb QLogic network adapter) on a Po=
wer 6 system=20
(IBM P 520, System type 8203) with upstream kernel and I do see that the ke=
rnel is=20
not able to allocate any MSI-X vectors. The driver requests for 4 vectors i=
n pci_enable_msix,
which returns 2. The driver again attempts, this time for 2 vectors but the=
kernel can't allocate=20
and it returns a value of 0xfffffffd. I upgraded the system FW to 01EL350 (=
from 01EL340)
just to make sure if MSI-X is enabled in the system. Is there anything tha=
t I am missing?=20
Any pointers will be highly appreciated.
thanks,
Anirban Chakraborty=
^ permalink raw reply
* Re: use of BAT before taking over the MMU
From: Segher Boessenkool @ 2010-10-05 15:31 UTC (permalink / raw)
To: Albert Cahalan; +Cc: linuxppc-dev
In-Reply-To: <AANLkTik9KeVzc6T7U=TX1bSA934Wmtbt4cjHrWSgWtLn@mail.gmail.com>
>>> The PowerPC OF binding requires the firmware to save and restore
>>> the BATs on entry to / exit from the firmware.
>
> That would defeat the purpose of setting them.
> They are used to provide Linux with mappings.
The initial state the OS has for the BATs is what the firmware
provides it with, sure.
An OS shouldn't expect to have more than its own program image
RAM mapped, in general.
> Of course that faults immediately, so I have a handler that
> loads IBAT0 with a 128 KiB mapping. I treat the BAT like a
> direct-mapped software-loaded TLB. (like MIPS arch MMU)
Just map the first 256MB and don't worry about anything else?
Seems a lot simpler to me ;-)
> Note that Linux can fail even with a firmware that doesn't touch
> the BAT registers. The MMU is on,
You can boot Linux with the MMU off as well.
> and 0xc0000000 may be
> where the firmware expects to have... MMIO for the console,
> the client interface entry point, a forth stack, whatever.
> The BAT takes priority, and thus the firmware splatters stuff
> right onto the kernel or dies trying to read something it left there.
Like I said, you're supposed to swap OS BATs with firmware BATs
in your client interface entry and exit. You have to switch
a lot of other registers there as well already, so that's no
big deal.
Segher
^ permalink raw reply
* RE: Serial RapidIO Maintaintance read causes lock up
From: Bounine, Alexandre @ 2010-10-05 15:11 UTC (permalink / raw)
To: Bastiaan Nijkamp, John Traill; +Cc: linuxppc-dev
In-Reply-To: <AANLkTik46NsiMhWo=GkHz4UbdDJeBLwFATJzhk-M3hSP@mail.gmail.com>
Bastiaan Nijkamp <bastiaan.nijkamp@gmail.com> wrote:=20
=A0
>A interesting thing that i found out is that when the agent is reset =
while the host is >locked up (eg. it cannot be stopped nor can i read =
the registers and memory trough a JTAG >Interface), the host comes back =
online and just continues booting linux with a RapidIO >error. See the =
log below.
... skip ...=A0
>fsl_rio_config_read: going to request to read data at d1080068
>RIO: cfg_read error -14 for ff:0:68
... skip ...
>RIO: master port 0 device has lost enumeration to a remote host
Looks like during agent reset your SRIO link becomes good and host's =
requests go ahead.
After that you get a machine check (response time out): link is OK but =
agent is not configured.
Can you check/print 0xC_0148 and 0xC_0158 registers of SRIO block before =
the first maintenance read.
Alex.
=20
^ permalink raw reply
* Re: use of BAT before taking over the MMU
From: Segher Boessenkool @ 2010-10-05 15:22 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Albert Cahalan, linuxppc-dev
In-Reply-To: <1286266201.2463.336.camel@pasglop>
>> The PowerPC OF binding requires the firmware to save and restore
>> the BATs on entry to / exit from the firmware.
>
> I'm not sure he was talking about OF here...
Yeah, I thought I was on a different mailing list. It's still
sort-of relevant though.
> In any case, we don't muck
> around with BATs until after we're done with OF anyways.
"Lower than the lowest common divider", yeah ;-)
Segher
^ permalink raw reply
* Re: Serial RapidIO Maintaintance read causes lock up
From: John Traill @ 2010-10-05 14:45 UTC (permalink / raw)
To: Bastiaan Nijkamp; +Cc: Bounine, Alexandre, linuxppc-dev
In-Reply-To: <AANLkTik46NsiMhWo=GkHz4UbdDJeBLwFATJzhk-M3hSP@mail.gmail.com>
Bastiaan,
On 05/10/10 15:28, Bastiaan Nijkamp wrote:
> Hi John,
> 1. Yes, they are both running the exact same kernel and both are
> configured in the same way. With the exception that one is set as host
> and the other as a agent.
> 2. Accept All is set for both boards.
> 3. As i understand, the agent cannot send anything before it is
> enumerated, so it would be safe to first reset the agent and right after
> that the host. In either case, thats the way i am using. The full kernel
> log until the discovery times out after 30 seconds is shown below:
> Using SBC8548 machine description
<snip>
In which case could you check the lawbar initialisation in u-boot for conflicts.
Would you post a dump of the lawbar registers from uboot.
The TLB's aren't important in this case as linux will reprogram as required.
Cheers
--
John Traill
Systems Engineer
Network and Computing Systems Group
Freescale Semiconductor UK LTD
Colvilles Road
East Kilbride
Glasgow G75 0TG, Scotland
Tel: +44 (0) 1355 355494
Fax: +44 (0) 1355 261790
E-mail: john.traill@freescale.com
Registration Number: SC262720
VAT Number: GB831329053
[ ] General Business Use
[ ] Freescale Internal Use Only
[ ] Freescale Confidential Proprietary
^ permalink raw reply
* Re: Serial RapidIO Maintaintance read causes lock up
From: Bastiaan Nijkamp @ 2010-10-05 14:30 UTC (permalink / raw)
To: Bounine, Alexandre; +Cc: linuxppc-dev
In-Reply-To: <0CE8B6BE3C4AD74AB97D9D29BD24E552013B9A9D@CORPEXCH1.na.ads.idt.com>
[-- Attachment #1: Type: text/plain, Size: 899 bytes --]
Hi Alex,
Yes, Sorry, that was a typo. The correct address that is printed is
0xd1080068.
And i did not disable the error handler, CONFIG_E500 is set at compile time.
Regards,
Bastiaan
2010/10/5 Bounine, Alexandre <Alexandre.Bounine@idt.com>
> Hi Bastiaan,
>
>
> Bastiaan Nijkamp <bastiaan.nijkamp@gmail.com> wrote:
>
> >fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, RIO
> Maintainance Window Size >0x400000,New Main Start: 0xd1080000
> >RIO: enumerate master port 0, RIO0 mport
> >fsl_rio_config_read: index 0 destid 255 hopcount 0 offset 00000068 len
> 4
> ... skip ....
> >fsl_rio_config_read: triggering '__fsl_read_rio_config'
> >fsl_rio_config_read: going to request to read data at d108006
>
> An address printed in the last line looks strange - is this typo or real
> value?
> I would expect to see d1080068 here if your maintenance window starts at
> 0xd1080000.
>
> Alex.
>
[-- Attachment #2: Type: text/html, Size: 1392 bytes --]
^ permalink raw reply
* Re: Serial RapidIO Maintaintance read causes lock up
From: Bastiaan Nijkamp @ 2010-10-05 14:28 UTC (permalink / raw)
To: John Traill; +Cc: Bounine, Alexandre, linuxppc-dev
In-Reply-To: <4CAB2729.6080402@freescale.com>
[-- Attachment #1: Type: text/plain, Size: 11945 bytes --]
Hi John,
1. Yes, they are both running the exact same kernel and both are configured
in the same way. With the exception that one is set as host and the other as
a agent.
2. Accept All is set for both boards.
3. As i understand, the agent cannot send anything before it is enumerated,
so it would be safe to first reset the agent and right after that the host.
In either case, thats the way i am using. The full kernel log until the
discovery times out after 30 seconds is shown below:
Using SBC8548 machine description
Memory CAM mapping: 256 Mb, residual: 0Mb
Linux version 2.6.35.6 (dl704@lxws006) (gcc version 4.4.1 (Wind River Linux
Sour
cery G++ 4.4-250) ) #3 Tue Oct 5 13:24:45 CEST 2010
bootconsole [udbg0] enabled
setup_arch: bootmem
sbc8548_setup_arch()
arch: exit
Zone PFN ranges:
DMA 0x00000000 -> 0x00010000
Normal empty
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
0: 0x00000000 -> 0x00010000
MMU: Allocated 1088 bytes of context maps for 255 contexts
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024
Kernel command line: root=/dev/nfs rw nfsroot=192.168.100.21:
/thales/target/rfs/
sbc8548_wrlinux4 ip=192.168.100.151:192.168.100.21:192.168.100.21:255
.255.255.0:
sbc8548_1:eth0:off console=ttyS0,115200
PID hash table entries: 1024 (order: 0, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 256996k/262144k available (2644k kernel code, 5148k reserved, 108k
data,
77k bss, 136k init)
Kernel virtual memory layout:
* 0xfffdf000..0xfffff000 : fixmap
* 0xfdffd000..0xfe000000 : early ioremap
* 0xd1000000..0xfdffd000 : vmalloc & ioremap
Hierarchical RCU implementation.
RCU-based detection of stalled CPUs is disabled.
Verbose stalled-CPUs detection is disabled.
NR_IRQS:512 nr_irqs:512
mpic: Setting up MPIC " OpenPIC " version 1.2 at e0040000, max 1 CPUs
mpic: ISU size: 80, shift: 7, mask: 7f
mpic: Initializing for 80 sources
clocksource: timebase mult[50cede6] shift[22] registered
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
NET: Registered protocol family 16
PCI: Probing PCI hardware
bio: create slab <bio-0> at 0
vgaarb: loaded
Switching to clocksource timebase
NET: Registered protocol family 2
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 4, 65536 bytes)
TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 8192 bind 8192)
TCP reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
Setting up RapidIO peer-to-peer network /soc8548@e0000000/rapidio@c0000
fsl-of-rio e00c0000.rapidio: Of-device full name
/soc8548@e0000000/rapidio@c0000
fsl-of-rio e00c0000.rapidio: Regs: [mem 0xe00c0000-0xe00dffff]
fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, size
0x0000000020000000.
fsl-of-rio e00c0000.rapidio: pwirq: 48, bellirq: 50, txirq: 53, rxirq 54
fsl-of-rio e00c0000.rapidio: DeviceID is 0xffffffff
fsl-of-rio e00c0000.rapidio: Configured as AGENT
fsl-of-rio e00c0000.rapidio: Overriding RIO_PORT setting to single lane 0
fsl-of-rio e00c0000.rapidio: RapidIO PHY type: serial
fsl-of-rio e00c0000.rapidio: Hardware port width: 4
fsl-of-rio e00c0000.rapidio: Training connection status: Single-lane 0
fsl-of-rio e00c0000.rapidio: RapidIO Common Transport System size: 256
fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, RIO Maintainance
Window Size 0x400000,New Main Start: 0xd1080000
RIO: discover master port 0, RIO0 mport
A interesting thing that i found out is that when the agent is reset while
the host is locked up (eg. it cannot be stopped nor can i read the registers
and memory trough a JTAG Interface), the host comes back online and just
continues booting linux with a RapidIO error. See the log below.
Setting up RapidIO peer-to-peer network /soc8548@e0000000/rapidio@c0000
fsl-of-rio e00c0000.rapidio: Of-device full name
/soc8548@e0000000/rapidio@c0000
fsl-of-rio e00c0000.rapidio: Regs: [mem 0xe00c0000-0xe00dffff]
fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, size
0x0000000020000000.
fsl-of-rio e00c0000.rapidio: pwirq: 48, bellirq: 50, txirq: 53, rxirq 54
fsl-of-rio e00c0000.rapidio: DeviceID is 0x0
fsl-of-rio e00c0000.rapidio: Configured as HOST
fsl-of-rio e00c0000.rapidio: Overriding RIO_PORT setting to single lane 0
fsl-of-rio e00c0000.rapidio: RapidIO PHY type: serial
fsl-of-rio e00c0000.rapidio: Hardware port width: 4
fsl-of-rio e00c0000.rapidio: Training connection status: Single-lane 0
fsl-of-rio e00c0000.rapidio: RapidIO Common Transport System size: 256
fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, RIO Maintainance
Window Size 0x400000,New Main Start: 0xd1080000
RIO: enumerate master port 0, RIO0 mport
fsl_rio_config_read: index 0 destid 255 hopcount 0 offset 00000068 len 4
fsl_rio_config_read: Passed IS_ALIGNED.
fsl_rio_config_read: Passed 'out_be32_1'
fsl_rio_config_read: Passed 'out_be32_2'
fsl_rio_config_read: len is 4
fsl_rio_config_read: triggering '__fsl_read_rio_config'
fsl_rio_config_read: going to request to read data at d1080068
RIO: cfg_read error -14 for ff:0:68
fsl_rio_config_read: index 0 destid 255 hopcount 0 offset 00000068 len 4
fsl_rio_config_read: Passed IS_ALIGNED.
fsl_rio_config_read: Passed 'out_be32_1'
fsl_rio_config_read: Passed 'out_be32_2'
fsl_rio_config_read: len is 4
fsl_rio_config_read: triggering '__fsl_read_rio_config'
fsl_rio_config_read: going to request to read data at d1080068
RIO: cfg_read error -14 for ff:0:68
fsl_rio_config_read: index 0 destid 255 hopcount 0 offset 00000068 len 4
fsl_rio_config_read: Passed IS_ALIGNED.
fsl_rio_config_read: Passed 'out_be32_1'
fsl_rio_config_read: Passed 'out_be32_2'
fsl_rio_config_read: len is 4
fsl_rio_config_read: triggering '__fsl_read_rio_config'
fsl_rio_config_read: going to request to read data at d1080068
RIO: cfg_read error -14 for ff:0:68
RIO: master port 0 device has lost enumeration to a remote host
Regards,
Bastiaan
2010/10/5 John Traill <john.traill@freescale.com>
> Bastiaan,
>
> A few things to check.
>
> 1. Is the target board also set up for small common transport system size
> ie 256.
>
> 2. Make sure the target has "Accept All" set - in fsl_rio.c look for
>
>> /* Set to receive any dist ID for serial RapidIO controller. */
>> if (port->phy_type == RIO_PHY_SERIAL)
>> out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA);
>>
>
> 3. How do you synchronise reset between both systems ? Both need to be
> reset to insure the inbound/outbound ackid's remain in sync. If you only
> reset one then you have the potential for the ackid's to get out of sync.
> Also what is the kernel log on the agent system ?
>
> Cheers.
>
>
>
> On 05/10/10 09:56, Bastiaan Nijkamp wrote:
>
>>
>> Hi Alex,
>>
>> Thanks for your advice. We are trying to make a board-to-board
>> connection without any additional hardware (eg. a switch). The boards
>> use a 50-pin, right-angle MEC8-125-02-L-D-RA1 connector from SAMTEC and
>> are connected trough a EEDP-016-12.00-RA1-RA2-2 cross cable from SAMTEC.
>> I hope this information is sufficient since there is not much one can
>> find about it on Google. In addition, you can see a picture of the board
>> including the connector in the datasheet located at
>> http://www.windriver.com/products/product-notes/SBC8548E-product-note.pdf
>> .
>> It is the connector on the left side of the PCI-EX slot.
>>
>> We have tried your suggestion but the situation does not change other
>> than the lane-mode being set to single lane 0, it still locks up when
>> trying to generate a maintenance transaction. I still think it is memory
>> related since the lock up occurs when accessing the maintenance window.
>> Although all memory related settings seems to be alright.
>>
>> The kernel output is as follows:
>>
>> Setting up RapidIO peer-to-peer network /soc8548@e0000000/rapidio@c0000
>> fsl-of-rio e00c0000.rapidio: Of-device full name
>> /soc8548@e0000000/rapidio@c0000
>> fsl-of-rio e00c0000.rapidio: Regs: [mem 0xe00c0000-0xe00dffff]
>> fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, size
>> 0x0000000010000000.
>> fsl-of-rio e00c0000.rapidio: pwirq: 48, bellirq: 50, txirq: 53, rxirq 54
>> fsl-of-rio e00c0000.rapidio: DeviceID is 0x0
>> fsl-of-rio e00c0000.rapidio: Configured as HOST
>> fsl-of-rio e00c0000.rapidio: Overriding RIO_PORT setting to single lane 0
>> fsl-of-rio e00c0000.rapidio: RapidIO PHY type: serial
>> fsl-of-rio e00c0000.rapidio: Hardware port width: 4
>> fsl-of-rio e00c0000.rapidio: Training connection status: Single-lane 0
>> fsl-of-rio e00c0000.rapidio: RapidIO Common Transport System size: 256
>> fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, RIO
>> Maintainance Window Size 0x400000,New Main Start: 0xd1080000
>> RIO: enumerate master port 0, RIO0 mport
>> fsl_rio_config_read: index 0 destid 255 hopcount 0 offset 00000068 len 4
>> fsl_rio_config_read: Passed IS_ALIGNED.
>> fsl_rio_config_read: Passed 'out_be32_1'
>> fsl_rio_config_read: Passed 'out_be32_2'
>> fsl_rio_config_read: len is 4
>> fsl_rio_config_read: triggering '__fsl_read_rio_config'
>> fsl_rio_config_read: going to request to read data at d108006
>>
>> Regards,
>> Bastiaan
>>
>> 2010/10/4 Bounine, Alexandre <Alexandre.Bounine@idt.com
>> <mailto:Alexandre.Bounine@idt.com>>
>>
>>
>> Hi Bastiaan,
>>
>> Are you trying board-to-board connection?
>> I am not familiar with WRS SBC8548 board - which type of connector they
>> use for SRIO?
>>
>> Assuming that all configuration is correct,
>> I would recommend first to try setting up x1 link mode at the lowest
>> link speed.
>> The x4 mode may present challenges in some cases.
>>
>> For quick test you may just add port width override into fsl_rio.c
>> like shown below (ugly but sometimes it helps ;) ):
>>
>> @@ -1461,10 +1461,16 @@ int fsl_rio_setup(struct platform_device *dev)
>> rio_register_mport(port);
>>
>> priv->regs_win = ioremap(regs.start, regs.end - regs.start +
>> 1);
>> rio_regs_win = priv->regs_win;
>>
>> +dev_info(&dev->dev, "Overriding RIO_PORT setting to single lane 0\n");
>> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) |
>> 0x800000);
>> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) |
>> 0x2000000);
>> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) &
>> ~0x800000);
>> +msleep(100);
>> +
>> /* Probe the master port phy type */
>> ccsr = in_be32(priv->regs_win + RIO_CCSR);
>> port->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL :
>> RIO_PHY_PARALLEL;
>> dev_info(&dev->dev, "RapidIO PHY type: %s\n",
>> (port->phy_type == RIO_PHY_PARALLEL) ?
>> "parallel" :
>>
>>
>> Let me know what happens.
>> Please keep me in the CC: list next time when posting RapidIO questions
>> to the linuxppc-dev or kernel mailing lists.
>>
>> Regards,
>>
>> Alex.
>>
>>
>>
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>
>
> --
> John Traill
> Systems Engineer
> Network and Computing Systems Group
>
> Freescale Semiconductor UK LTD
> Colvilles Road
> East Kilbride
> Glasgow G75 0TG, Scotland
>
> Tel: +44 (0) 1355 355494
> Fax: +44 (0) 1355 261790
>
> E-mail: john.traill@freescale.com
>
> Registration Number: SC262720
> VAT Number: GB831329053
>
> [ ] General Business Use
> [ ] Freescale Internal Use Only
> [ ] Freescale Confidential Proprietary
>
>
[-- Attachment #2: Type: text/html, Size: 14103 bytes --]
^ permalink raw reply
* RE: Serial RapidIO Maintaintance read causes lock up
From: Bounine, Alexandre @ 2010-10-05 13:49 UTC (permalink / raw)
To: John Traill, Bastiaan Nijkamp; +Cc: linuxppc-dev
In-Reply-To: <4CAB2729.6080402@freescale.com>
Hi John,
John Traill <john.traill@freescale.com> wrote:
> 2. Make sure the target has "Accept All" set - in fsl_rio.c look for
> > /* Set to receive any dist ID for serial RapidIO controller.
*/
> > if (port->phy_type =3D=3D RIO_PHY_SERIAL)
> > out_be32((priv->regs_win + RIO_ISR_AACR),
RIO_ISR_AACR_AA);
>
Looks like in Bastiaan's case request cannot leave the SRIO controller.
Otherwise he would get a machine check if a response is timed out
(assuming that he did not disable it).
Alex.
=20
=20
^ permalink raw reply
* RE: Serial RapidIO Maintaintance read causes lock up
From: Bounine, Alexandre @ 2010-10-05 13:34 UTC (permalink / raw)
To: Bastiaan Nijkamp; +Cc: linuxppc-dev
In-Reply-To: <AANLkTimCiHWRR-kVuT0ift3CH63Xk_XcaXS22qmVh6fr@mail.gmail.com>
Hi Bastiaan,
=20
Bastiaan Nijkamp <bastiaan.nijkamp@gmail.com> wrote:=20
>fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, RIO
Maintainance Window Size >0x400000,New Main Start: 0xd1080000
>RIO: enumerate master port 0, RIO0 mport
>fsl_rio_config_read: index 0 destid 255 hopcount 0 offset 00000068 len
4
... skip ....
>fsl_rio_config_read: triggering '__fsl_read_rio_config'
>fsl_rio_config_read: going to request to read data at d108006
An address printed in the last line looks strange - is this typo or real
value?
I would expect to see d1080068 here if your maintenance window starts at
0xd1080000.
Alex.
^ permalink raw reply
* Re: Serial RapidIO Maintaintance read causes lock up
From: John Traill @ 2010-10-05 13:24 UTC (permalink / raw)
To: Bastiaan Nijkamp; +Cc: Bounine, Alexandre, linuxppc-dev
In-Reply-To: <AANLkTimCiHWRR-kVuT0ift3CH63Xk_XcaXS22qmVh6fr@mail.gmail.com>
Bastiaan,
A few things to check.
1. Is the target board also set up for small common transport system size ie 256.
2. Make sure the target has "Accept All" set - in fsl_rio.c look for
> /* Set to receive any dist ID for serial RapidIO controller. */
> if (port->phy_type == RIO_PHY_SERIAL)
> out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA);
3. How do you synchronise reset between both systems ? Both need to be reset to
insure the inbound/outbound ackid's remain in sync. If you only reset one then
you have the potential for the ackid's to get out of sync. Also what is the
kernel log on the agent system ?
Cheers.
On 05/10/10 09:56, Bastiaan Nijkamp wrote:
>
> Hi Alex,
>
> Thanks for your advice. We are trying to make a board-to-board
> connection without any additional hardware (eg. a switch). The boards
> use a 50-pin, right-angle MEC8-125-02-L-D-RA1 connector from SAMTEC and
> are connected trough a EEDP-016-12.00-RA1-RA2-2 cross cable from SAMTEC.
> I hope this information is sufficient since there is not much one can
> find about it on Google. In addition, you can see a picture of the board
> including the connector in the datasheet located at
> http://www.windriver.com/products/product-notes/SBC8548E-product-note.pdf.
> It is the connector on the left side of the PCI-EX slot.
>
> We have tried your suggestion but the situation does not change other
> than the lane-mode being set to single lane 0, it still locks up when
> trying to generate a maintenance transaction. I still think it is memory
> related since the lock up occurs when accessing the maintenance window.
> Although all memory related settings seems to be alright.
>
> The kernel output is as follows:
>
> Setting up RapidIO peer-to-peer network /soc8548@e0000000/rapidio@c0000
> fsl-of-rio e00c0000.rapidio: Of-device full name
> /soc8548@e0000000/rapidio@c0000
> fsl-of-rio e00c0000.rapidio: Regs: [mem 0xe00c0000-0xe00dffff]
> fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, size
> 0x0000000010000000.
> fsl-of-rio e00c0000.rapidio: pwirq: 48, bellirq: 50, txirq: 53, rxirq 54
> fsl-of-rio e00c0000.rapidio: DeviceID is 0x0
> fsl-of-rio e00c0000.rapidio: Configured as HOST
> fsl-of-rio e00c0000.rapidio: Overriding RIO_PORT setting to single lane 0
> fsl-of-rio e00c0000.rapidio: RapidIO PHY type: serial
> fsl-of-rio e00c0000.rapidio: Hardware port width: 4
> fsl-of-rio e00c0000.rapidio: Training connection status: Single-lane 0
> fsl-of-rio e00c0000.rapidio: RapidIO Common Transport System size: 256
> fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, RIO
> Maintainance Window Size 0x400000,New Main Start: 0xd1080000
> RIO: enumerate master port 0, RIO0 mport
> fsl_rio_config_read: index 0 destid 255 hopcount 0 offset 00000068 len 4
> fsl_rio_config_read: Passed IS_ALIGNED.
> fsl_rio_config_read: Passed 'out_be32_1'
> fsl_rio_config_read: Passed 'out_be32_2'
> fsl_rio_config_read: len is 4
> fsl_rio_config_read: triggering '__fsl_read_rio_config'
> fsl_rio_config_read: going to request to read data at d108006
>
> Regards,
> Bastiaan
>
> 2010/10/4 Bounine, Alexandre <Alexandre.Bounine@idt.com
> <mailto:Alexandre.Bounine@idt.com>>
>
> Hi Bastiaan,
>
> Are you trying board-to-board connection?
> I am not familiar with WRS SBC8548 board - which type of connector they
> use for SRIO?
>
> Assuming that all configuration is correct,
> I would recommend first to try setting up x1 link mode at the lowest
> link speed.
> The x4 mode may present challenges in some cases.
>
> For quick test you may just add port width override into fsl_rio.c
> like shown below (ugly but sometimes it helps ;) ):
>
> @@ -1461,10 +1461,16 @@ int fsl_rio_setup(struct platform_device *dev)
> rio_register_mport(port);
>
> priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
> rio_regs_win = priv->regs_win;
>
> +dev_info(&dev->dev, "Overriding RIO_PORT setting to single lane 0\n");
> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) |
> 0x800000);
> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) |
> 0x2000000);
> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) &
> ~0x800000);
> +msleep(100);
> +
> /* Probe the master port phy type */
> ccsr = in_be32(priv->regs_win + RIO_CCSR);
> port->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL : RIO_PHY_PARALLEL;
> dev_info(&dev->dev, "RapidIO PHY type: %s\n",
> (port->phy_type == RIO_PHY_PARALLEL) ?
> "parallel" :
>
>
> Let me know what happens.
> Please keep me in the CC: list next time when posting RapidIO questions
> to the linuxppc-dev or kernel mailing lists.
>
> Regards,
>
> Alex.
>
>
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
--
John Traill
Systems Engineer
Network and Computing Systems Group
Freescale Semiconductor UK LTD
Colvilles Road
East Kilbride
Glasgow G75 0TG, Scotland
Tel: +44 (0) 1355 355494
Fax: +44 (0) 1355 261790
E-mail: john.traill@freescale.com
Registration Number: SC262720
VAT Number: GB831329053
[ ] General Business Use
[ ] Freescale Internal Use Only
[ ] Freescale Confidential Proprietary
^ permalink raw reply
* Re: use of BAT before taking over the MMU
From: Benjamin Herrenschmidt @ 2010-10-05 12:28 UTC (permalink / raw)
To: Albert Cahalan; +Cc: linuxppc-dev
In-Reply-To: <AANLkTik9KeVzc6T7U=TX1bSA934Wmtbt4cjHrWSgWtLn@mail.gmail.com>
> >> The PowerPC OF binding requires the firmware to save and restore
> >> the BATs on entry to / exit from the firmware.
>
> That would defeat the purpose of setting them.
> They are used to provide Linux with mappings.
How so ? As long as they are present when executing Linux code,
I don't see the problem if they contain different mappings while
inside FW...
> > I'm not sure he was talking about OF here... In any case, we don't muck
> > around with BATs until after we're done with OF anyways.
>
> It's the Open Firmware client interface, not Firmworks code.
> I wrote it. It just does hypervisor-like calls to an emulator which
> does the real work. Essentially I have a prom_call opcode
> and a handle_exception opcode. I claim to be an MPC7400.
>
> The kernel is sitting at address 0, MSR becomes 0x70 when
> an rfi goes to address 0. This will be head_32.S with r5 set,
> so Linux will call prom_init to fetch the device tree.
Right. Within prom_init we don't touch the BATs, we are still under FW
control at this stage.
> Of course that faults immediately,
It shouldn't but it can. When you enter Linux with an OF "client
interface" entry, you are responsible for having reasonable mappings for
executing the client code. You are allowed to fault these if you want
to, and do whatever you want, as long as the prom_init code can execute.
IE. Linux hasn't set any mappings nor BATs at this stage, it's operating
as a client program of the FW and entirely relies on the FW to provide
the necessary MMU setup until the end of prom_init.
> so I have a handler that
> loads IBAT0 with a 128 KiB mapping. I treat the BAT like a
> direct-mapped software-loaded TLB. (like MIPS arch MMU)
>
> I threw in a hack to skip to the next BAT when the chosen
> one is not a 128 KiB 1:1 mapping. That seems to work, but
> sure doesn't feel right.
Why would you need to do that ? Linux hasn't done anything to mappings
yet and only cares about what you have setup...
Linux will throw away your BATs etc... only after it returns from
prom_init at which point it won't call your FW anymore anyways.
> Note that Linux can fail even with a firmware that doesn't touch
> the BAT registers. The MMU is on, and 0xc0000000 may be
> where the firmware expects to have... MMIO for the console,
> the client interface entry point, a forth stack, whatever.
Right, but Linux doesn't establish nor relies on mappings at c0000000 at
this point. prom_init is relocatable code that can execute from any
address.
> The BAT takes priority, and thus the firmware splatters stuff
> right onto the kernel or dies trying to read something it left there.
I'm not entirely sure what you are doing but it certainly sounds
wrong :-)
As I said, at this stage, Linux is just a "normal" client interface
program. It's happy to run from any address you put it with any mapping
you provide until it returns from prom_init at which point it takes over
the MMU.
Ben.
^ permalink raw reply
* Re: use of BAT before taking over the MMU
From: Albert Cahalan @ 2010-10-05 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1286266201.2463.336.camel@pasglop>
On Tue, Oct 5, 2010 at 4:10 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Mon, 2010-10-04 at 06:25 +0200, Segher Boessenkool wrote:
>> > On the prom boot path, with the firmware supposed to
>> > be managing the MMU, there is a case where:
>> >
>> > 1. Linux changes some BAT registers.
>> > 2. Bits 0x00000070 are/become set in the MSR.
>> > 3. Linux takes an MMU fault.
>> > 4. The firmware handles it.
>> >
>> > AFAIK, you can't expect the firmware to leave the BAT alone.
>> > If the firmware provides mapping services by using the BAT
>> > as a software-filled TLB, Linux's BAT changes may be lost.
>> >
>> > You also can't expect that your BAT changes will not conflict
>> > with mappings that the firmware uses for itself. The firmware
>> > might write to your new BAT mapping, relying on those virtual
>> > addresses to be something else entirely.
>>
>> The PowerPC OF binding requires the firmware to save and restore
>> the BATs on entry to / exit from the firmware.
That would defeat the purpose of setting them.
They are used to provide Linux with mappings.
> I'm not sure he was talking about OF here... In any case, we don't muck
> around with BATs until after we're done with OF anyways.
It's the Open Firmware client interface, not Firmworks code.
I wrote it. It just does hypervisor-like calls to an emulator which
does the real work. Essentially I have a prom_call opcode
and a handle_exception opcode. I claim to be an MPC7400.
The kernel is sitting at address 0, MSR becomes 0x70 when
an rfi goes to address 0. This will be head_32.S with r5 set,
so Linux will call prom_init to fetch the device tree.
Of course that faults immediately, so I have a handler that
loads IBAT0 with a 128 KiB mapping. I treat the BAT like a
direct-mapped software-loaded TLB. (like MIPS arch MMU)
I threw in a hack to skip to the next BAT when the chosen
one is not a 128 KiB 1:1 mapping. That seems to work, but
sure doesn't feel right.
Note that Linux can fail even with a firmware that doesn't touch
the BAT registers. The MMU is on, and 0xc0000000 may be
where the firmware expects to have... MMIO for the console,
the client interface entry point, a forth stack, whatever.
The BAT takes priority, and thus the firmware splatters stuff
right onto the kernel or dies trying to read something it left there.
^ permalink raw reply
* [PATCH] Move ams driver to macintosh
From: Jean Delvare @ 2010-10-05 10:10 UTC (permalink / raw)
To: LM Sensors, linuxppc-dev; +Cc: Stelian Pop, Michael Hanselmann, Guenter Roeck
The ams driver isn't a hardware monitoring driver, so it shouldn't
live under driver/hwmon. drivers/macintosh seems much more
appropriate, as the driver is only useful on PowerBooks and iBooks.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Guenter Roeck <guenter.roeck@ericsson.com>
Cc: Stelian Pop <stelian@popies.net>
Cc: Michael Hanselmann <linux-kernel@hansmi.ch>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
MAINTAINERS | 2
drivers/hwmon/Kconfig | 26 ---
drivers/hwmon/Makefile | 1
drivers/hwmon/ams/Makefile | 8 -
drivers/hwmon/ams/ams-core.c | 250 ---------------------------------
drivers/hwmon/ams/ams-i2c.c | 277 -------------------------------------
drivers/hwmon/ams/ams-input.c | 157 --------------------
drivers/hwmon/ams/ams-pmu.c | 201 --------------------------
drivers/hwmon/ams/ams.h | 70 ---------
drivers/macintosh/Kconfig | 26 +++
drivers/macintosh/Makefile | 2
drivers/macintosh/ams/Makefile | 8 +
drivers/macintosh/ams/ams-core.c | 250 +++++++++++++++++++++++++++++++++
drivers/macintosh/ams/ams-i2c.c | 277 +++++++++++++++++++++++++++++++++++++
drivers/macintosh/ams/ams-input.c | 157 ++++++++++++++++++++
drivers/macintosh/ams/ams-pmu.c | 201 ++++++++++++++++++++++++++
drivers/macintosh/ams/ams.h | 70 +++++++++
17 files changed, 992 insertions(+), 991 deletions(-)
--- linux-2.6.36-rc6.orig/drivers/hwmon/ams/Makefile 2010-08-02 00:11:14.000000000 +0200
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-#
-# Makefile for Apple Motion Sensor driver
-#
-
-ams-y := ams-core.o ams-input.o
-ams-$(CONFIG_SENSORS_AMS_PMU) += ams-pmu.o
-ams-$(CONFIG_SENSORS_AMS_I2C) += ams-i2c.o
-obj-$(CONFIG_SENSORS_AMS) += ams.o
--- linux-2.6.36-rc6.orig/drivers/hwmon/ams/ams-core.c 2010-08-02 00:11:14.000000000 +0200
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,250 +0,0 @@
-/*
- * Apple Motion Sensor driver
- *
- * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
- * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/of_platform.h>
-#include <asm/pmac_pfunc.h>
-
-#include "ams.h"
-
-/* There is only one motion sensor per machine */
-struct ams ams_info;
-
-static unsigned int verbose;
-module_param(verbose, bool, 0644);
-MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output");
-
-/* Call with ams_info.lock held! */
-void ams_sensors(s8 *x, s8 *y, s8 *z)
-{
- u32 orient = ams_info.vflag? ams_info.orient1 : ams_info.orient2;
-
- if (orient & 0x80)
- /* X and Y swapped */
- ams_info.get_xyz(y, x, z);
- else
- ams_info.get_xyz(x, y, z);
-
- if (orient & 0x04)
- *z = ~(*z);
- if (orient & 0x02)
- *y = ~(*y);
- if (orient & 0x01)
- *x = ~(*x);
-}
-
-static ssize_t ams_show_current(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- s8 x, y, z;
-
- mutex_lock(&ams_info.lock);
- ams_sensors(&x, &y, &z);
- mutex_unlock(&ams_info.lock);
-
- return snprintf(buf, PAGE_SIZE, "%d %d %d\n", x, y, z);
-}
-
-static DEVICE_ATTR(current, S_IRUGO, ams_show_current, NULL);
-
-static void ams_handle_irq(void *data)
-{
- enum ams_irq irq = *((enum ams_irq *)data);
-
- spin_lock(&ams_info.irq_lock);
-
- ams_info.worker_irqs |= irq;
- schedule_work(&ams_info.worker);
-
- spin_unlock(&ams_info.irq_lock);
-}
-
-static enum ams_irq ams_freefall_irq_data = AMS_IRQ_FREEFALL;
-static struct pmf_irq_client ams_freefall_client = {
- .owner = THIS_MODULE,
- .handler = ams_handle_irq,
- .data = &ams_freefall_irq_data,
-};
-
-static enum ams_irq ams_shock_irq_data = AMS_IRQ_SHOCK;
-static struct pmf_irq_client ams_shock_client = {
- .owner = THIS_MODULE,
- .handler = ams_handle_irq,
- .data = &ams_shock_irq_data,
-};
-
-/* Once hard disk parking is implemented in the kernel, this function can
- * trigger it.
- */
-static void ams_worker(struct work_struct *work)
-{
- unsigned long flags;
- u8 irqs_to_clear;
-
- mutex_lock(&ams_info.lock);
-
- spin_lock_irqsave(&ams_info.irq_lock, flags);
- irqs_to_clear = ams_info.worker_irqs;
-
- if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) {
- if (verbose)
- printk(KERN_INFO "ams: freefall detected!\n");
-
- ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL;
- }
-
- if (ams_info.worker_irqs & AMS_IRQ_SHOCK) {
- if (verbose)
- printk(KERN_INFO "ams: shock detected!\n");
-
- ams_info.worker_irqs &= ~AMS_IRQ_SHOCK;
- }
-
- spin_unlock_irqrestore(&ams_info.irq_lock, flags);
-
- ams_info.clear_irq(irqs_to_clear);
-
- mutex_unlock(&ams_info.lock);
-}
-
-/* Call with ams_info.lock held! */
-int ams_sensor_attach(void)
-{
- int result;
- const u32 *prop;
-
- /* Get orientation */
- prop = of_get_property(ams_info.of_node, "orientation", NULL);
- if (!prop)
- return -ENODEV;
- ams_info.orient1 = *prop;
- ams_info.orient2 = *(prop + 1);
-
- /* Register freefall interrupt handler */
- result = pmf_register_irq_client(ams_info.of_node,
- "accel-int-1",
- &ams_freefall_client);
- if (result < 0)
- return -ENODEV;
-
- /* Reset saved irqs */
- ams_info.worker_irqs = 0;
-
- /* Register shock interrupt handler */
- result = pmf_register_irq_client(ams_info.of_node,
- "accel-int-2",
- &ams_shock_client);
- if (result < 0)
- goto release_freefall;
-
- /* Create device */
- ams_info.of_dev = of_platform_device_create(ams_info.of_node, "ams", NULL);
- if (!ams_info.of_dev) {
- result = -ENODEV;
- goto release_shock;
- }
-
- /* Create attributes */
- result = device_create_file(&ams_info.of_dev->dev, &dev_attr_current);
- if (result)
- goto release_of;
-
- ams_info.vflag = !!(ams_info.get_vendor() & 0x10);
-
- /* Init input device */
- result = ams_input_init();
- if (result)
- goto release_device_file;
-
- return result;
-release_device_file:
- device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
-release_of:
- of_device_unregister(ams_info.of_dev);
-release_shock:
- pmf_unregister_irq_client(&ams_shock_client);
-release_freefall:
- pmf_unregister_irq_client(&ams_freefall_client);
- return result;
-}
-
-int __init ams_init(void)
-{
- struct device_node *np;
-
- spin_lock_init(&ams_info.irq_lock);
- mutex_init(&ams_info.lock);
- INIT_WORK(&ams_info.worker, ams_worker);
-
-#ifdef CONFIG_SENSORS_AMS_I2C
- np = of_find_node_by_name(NULL, "accelerometer");
- if (np && of_device_is_compatible(np, "AAPL,accelerometer_1"))
- /* Found I2C motion sensor */
- return ams_i2c_init(np);
-#endif
-
-#ifdef CONFIG_SENSORS_AMS_PMU
- np = of_find_node_by_name(NULL, "sms");
- if (np && of_device_is_compatible(np, "sms"))
- /* Found PMU motion sensor */
- return ams_pmu_init(np);
-#endif
- return -ENODEV;
-}
-
-void ams_sensor_detach(void)
-{
- /* Remove input device */
- ams_input_exit();
-
- /* Remove attributes */
- device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
-
- /* Flush interrupt worker
- *
- * We do this after ams_info.exit(), because an interrupt might
- * have arrived before disabling them.
- */
- flush_scheduled_work();
-
- /* Remove device */
- of_device_unregister(ams_info.of_dev);
-
- /* Remove handler */
- pmf_unregister_irq_client(&ams_shock_client);
- pmf_unregister_irq_client(&ams_freefall_client);
-}
-
-static void __exit ams_exit(void)
-{
- /* Shut down implementation */
- ams_info.exit();
-}
-
-MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
-MODULE_DESCRIPTION("Apple Motion Sensor driver");
-MODULE_LICENSE("GPL");
-
-module_init(ams_init);
-module_exit(ams_exit);
--- linux-2.6.36-rc6.orig/drivers/hwmon/ams/ams-i2c.c 2010-08-02 00:11:14.000000000 +0200
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,277 +0,0 @@
-/*
- * Apple Motion Sensor driver (I2C variant)
- *
- * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
- * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
- *
- * Clean room implementation based on the reverse engineered Mac OS X driver by
- * Johannes Berg <johannes@sipsolutions.net>, documentation available at
- * http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include "ams.h"
-
-/* AMS registers */
-#define AMS_COMMAND 0x00 /* command register */
-#define AMS_STATUS 0x01 /* status register */
-#define AMS_CTRL1 0x02 /* read control 1 (number of values) */
-#define AMS_CTRL2 0x03 /* read control 2 (offset?) */
-#define AMS_CTRL3 0x04 /* read control 3 (size of each value?) */
-#define AMS_DATA1 0x05 /* read data 1 */
-#define AMS_DATA2 0x06 /* read data 2 */
-#define AMS_DATA3 0x07 /* read data 3 */
-#define AMS_DATA4 0x08 /* read data 4 */
-#define AMS_DATAX 0x20 /* data X */
-#define AMS_DATAY 0x21 /* data Y */
-#define AMS_DATAZ 0x22 /* data Z */
-#define AMS_FREEFALL 0x24 /* freefall int control */
-#define AMS_SHOCK 0x25 /* shock int control */
-#define AMS_SENSLOW 0x26 /* sensitivity low limit */
-#define AMS_SENSHIGH 0x27 /* sensitivity high limit */
-#define AMS_CTRLX 0x28 /* control X */
-#define AMS_CTRLY 0x29 /* control Y */
-#define AMS_CTRLZ 0x2A /* control Z */
-#define AMS_UNKNOWN1 0x2B /* unknown 1 */
-#define AMS_UNKNOWN2 0x2C /* unknown 2 */
-#define AMS_UNKNOWN3 0x2D /* unknown 3 */
-#define AMS_VENDOR 0x2E /* vendor */
-
-/* AMS commands - use with the AMS_COMMAND register */
-enum ams_i2c_cmd {
- AMS_CMD_NOOP = 0,
- AMS_CMD_VERSION,
- AMS_CMD_READMEM,
- AMS_CMD_WRITEMEM,
- AMS_CMD_ERASEMEM,
- AMS_CMD_READEE,
- AMS_CMD_WRITEEE,
- AMS_CMD_RESET,
- AMS_CMD_START,
-};
-
-static int ams_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int ams_i2c_remove(struct i2c_client *client);
-
-static const struct i2c_device_id ams_id[] = {
- { "ams", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ams_id);
-
-static struct i2c_driver ams_i2c_driver = {
- .driver = {
- .name = "ams",
- .owner = THIS_MODULE,
- },
- .probe = ams_i2c_probe,
- .remove = ams_i2c_remove,
- .id_table = ams_id,
-};
-
-static s32 ams_i2c_read(u8 reg)
-{
- return i2c_smbus_read_byte_data(ams_info.i2c_client, reg);
-}
-
-static int ams_i2c_write(u8 reg, u8 value)
-{
- return i2c_smbus_write_byte_data(ams_info.i2c_client, reg, value);
-}
-
-static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
-{
- s32 result;
- int count = 3;
-
- ams_i2c_write(AMS_COMMAND, cmd);
- msleep(5);
-
- while (count--) {
- result = ams_i2c_read(AMS_COMMAND);
- if (result == 0 || result & 0x80)
- return 0;
-
- schedule_timeout_uninterruptible(HZ / 20);
- }
-
- return -1;
-}
-
-static void ams_i2c_set_irq(enum ams_irq reg, char enable)
-{
- if (reg & AMS_IRQ_FREEFALL) {
- u8 val = ams_i2c_read(AMS_CTRLX);
- if (enable)
- val |= 0x80;
- else
- val &= ~0x80;
- ams_i2c_write(AMS_CTRLX, val);
- }
-
- if (reg & AMS_IRQ_SHOCK) {
- u8 val = ams_i2c_read(AMS_CTRLY);
- if (enable)
- val |= 0x80;
- else
- val &= ~0x80;
- ams_i2c_write(AMS_CTRLY, val);
- }
-
- if (reg & AMS_IRQ_GLOBAL) {
- u8 val = ams_i2c_read(AMS_CTRLZ);
- if (enable)
- val |= 0x80;
- else
- val &= ~0x80;
- ams_i2c_write(AMS_CTRLZ, val);
- }
-}
-
-static void ams_i2c_clear_irq(enum ams_irq reg)
-{
- if (reg & AMS_IRQ_FREEFALL)
- ams_i2c_write(AMS_FREEFALL, 0);
-
- if (reg & AMS_IRQ_SHOCK)
- ams_i2c_write(AMS_SHOCK, 0);
-}
-
-static u8 ams_i2c_get_vendor(void)
-{
- return ams_i2c_read(AMS_VENDOR);
-}
-
-static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z)
-{
- *x = ams_i2c_read(AMS_DATAX);
- *y = ams_i2c_read(AMS_DATAY);
- *z = ams_i2c_read(AMS_DATAZ);
-}
-
-static int ams_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int vmaj, vmin;
- int result;
-
- /* There can be only one */
- if (unlikely(ams_info.has_device))
- return -ENODEV;
-
- ams_info.i2c_client = client;
-
- if (ams_i2c_cmd(AMS_CMD_RESET)) {
- printk(KERN_INFO "ams: Failed to reset the device\n");
- return -ENODEV;
- }
-
- if (ams_i2c_cmd(AMS_CMD_START)) {
- printk(KERN_INFO "ams: Failed to start the device\n");
- return -ENODEV;
- }
-
- /* get version/vendor information */
- ams_i2c_write(AMS_CTRL1, 0x02);
- ams_i2c_write(AMS_CTRL2, 0x85);
- ams_i2c_write(AMS_CTRL3, 0x01);
-
- ams_i2c_cmd(AMS_CMD_READMEM);
-
- vmaj = ams_i2c_read(AMS_DATA1);
- vmin = ams_i2c_read(AMS_DATA2);
- if (vmaj != 1 || vmin != 52) {
- printk(KERN_INFO "ams: Incorrect device version (%d.%d)\n",
- vmaj, vmin);
- return -ENODEV;
- }
-
- ams_i2c_cmd(AMS_CMD_VERSION);
-
- vmaj = ams_i2c_read(AMS_DATA1);
- vmin = ams_i2c_read(AMS_DATA2);
- if (vmaj != 0 || vmin != 1) {
- printk(KERN_INFO "ams: Incorrect firmware version (%d.%d)\n",
- vmaj, vmin);
- return -ENODEV;
- }
-
- /* Disable interrupts */
- ams_i2c_set_irq(AMS_IRQ_ALL, 0);
-
- result = ams_sensor_attach();
- if (result < 0)
- return result;
-
- /* Set default values */
- ams_i2c_write(AMS_SENSLOW, 0x15);
- ams_i2c_write(AMS_SENSHIGH, 0x60);
- ams_i2c_write(AMS_CTRLX, 0x08);
- ams_i2c_write(AMS_CTRLY, 0x0F);
- ams_i2c_write(AMS_CTRLZ, 0x4F);
- ams_i2c_write(AMS_UNKNOWN1, 0x14);
-
- /* Clear interrupts */
- ams_i2c_clear_irq(AMS_IRQ_ALL);
-
- ams_info.has_device = 1;
-
- /* Enable interrupts */
- ams_i2c_set_irq(AMS_IRQ_ALL, 1);
-
- printk(KERN_INFO "ams: Found I2C based motion sensor\n");
-
- return 0;
-}
-
-static int ams_i2c_remove(struct i2c_client *client)
-{
- if (ams_info.has_device) {
- ams_sensor_detach();
-
- /* Disable interrupts */
- ams_i2c_set_irq(AMS_IRQ_ALL, 0);
-
- /* Clear interrupts */
- ams_i2c_clear_irq(AMS_IRQ_ALL);
-
- printk(KERN_INFO "ams: Unloading\n");
-
- ams_info.has_device = 0;
- }
-
- return 0;
-}
-
-static void ams_i2c_exit(void)
-{
- i2c_del_driver(&ams_i2c_driver);
-}
-
-int __init ams_i2c_init(struct device_node *np)
-{
- int result;
-
- /* Set implementation stuff */
- ams_info.of_node = np;
- ams_info.exit = ams_i2c_exit;
- ams_info.get_vendor = ams_i2c_get_vendor;
- ams_info.get_xyz = ams_i2c_get_xyz;
- ams_info.clear_irq = ams_i2c_clear_irq;
- ams_info.bustype = BUS_I2C;
-
- result = i2c_add_driver(&ams_i2c_driver);
-
- return result;
-}
--- linux-2.6.36-rc6.orig/drivers/hwmon/ams/ams-input.c 2010-08-02 00:11:14.000000000 +0200
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,157 +0,0 @@
-/*
- * Apple Motion Sensor driver (joystick emulation)
- *
- * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
- * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include "ams.h"
-
-static unsigned int joystick;
-module_param(joystick, bool, S_IRUGO);
-MODULE_PARM_DESC(joystick, "Enable the input class device on module load");
-
-static unsigned int invert;
-module_param(invert, bool, S_IWUSR | S_IRUGO);
-MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
-
-static DEFINE_MUTEX(ams_input_mutex);
-
-static void ams_idev_poll(struct input_polled_dev *dev)
-{
- struct input_dev *idev = dev->input;
- s8 x, y, z;
-
- mutex_lock(&ams_info.lock);
-
- ams_sensors(&x, &y, &z);
-
- x -= ams_info.xcalib;
- y -= ams_info.ycalib;
- z -= ams_info.zcalib;
-
- input_report_abs(idev, ABS_X, invert ? -x : x);
- input_report_abs(idev, ABS_Y, invert ? -y : y);
- input_report_abs(idev, ABS_Z, z);
-
- input_sync(idev);
-
- mutex_unlock(&ams_info.lock);
-}
-
-/* Call with ams_info.lock held! */
-static int ams_input_enable(void)
-{
- struct input_dev *input;
- s8 x, y, z;
- int error;
-
- ams_sensors(&x, &y, &z);
- ams_info.xcalib = x;
- ams_info.ycalib = y;
- ams_info.zcalib = z;
-
- ams_info.idev = input_allocate_polled_device();
- if (!ams_info.idev)
- return -ENOMEM;
-
- ams_info.idev->poll = ams_idev_poll;
- ams_info.idev->poll_interval = 25;
-
- input = ams_info.idev->input;
- input->name = "Apple Motion Sensor";
- input->id.bustype = ams_info.bustype;
- input->id.vendor = 0;
- input->dev.parent = &ams_info.of_dev->dev;
-
- input_set_abs_params(input, ABS_X, -50, 50, 3, 0);
- input_set_abs_params(input, ABS_Y, -50, 50, 3, 0);
- input_set_abs_params(input, ABS_Z, -50, 50, 3, 0);
-
- set_bit(EV_ABS, input->evbit);
- set_bit(EV_KEY, input->evbit);
- set_bit(BTN_TOUCH, input->keybit);
-
- error = input_register_polled_device(ams_info.idev);
- if (error) {
- input_free_polled_device(ams_info.idev);
- ams_info.idev = NULL;
- return error;
- }
-
- joystick = 1;
-
- return 0;
-}
-
-static void ams_input_disable(void)
-{
- if (ams_info.idev) {
- input_unregister_polled_device(ams_info.idev);
- input_free_polled_device(ams_info.idev);
- ams_info.idev = NULL;
- }
-
- joystick = 0;
-}
-
-static ssize_t ams_input_show_joystick(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", joystick);
-}
-
-static ssize_t ams_input_store_joystick(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- unsigned long enable;
- int error = 0;
-
- if (strict_strtoul(buf, 0, &enable) || enable > 1)
- return -EINVAL;
-
- mutex_lock(&ams_input_mutex);
-
- if (enable != joystick) {
- if (enable)
- error = ams_input_enable();
- else
- ams_input_disable();
- }
-
- mutex_unlock(&ams_input_mutex);
-
- return error ? error : count;
-}
-
-static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR,
- ams_input_show_joystick, ams_input_store_joystick);
-
-int ams_input_init(void)
-{
- if (joystick)
- ams_input_enable();
-
- return device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
-}
-
-void ams_input_exit(void)
-{
- device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick);
-
- mutex_lock(&ams_input_mutex);
- ams_input_disable();
- mutex_unlock(&ams_input_mutex);
-}
--- linux-2.6.36-rc6.orig/drivers/hwmon/ams/ams-pmu.c 2010-08-02 00:11:14.000000000 +0200
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,201 +0,0 @@
-/*
- * Apple Motion Sensor driver (PMU variant)
- *
- * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-
-#include "ams.h"
-
-/* Attitude */
-#define AMS_X 0x00
-#define AMS_Y 0x01
-#define AMS_Z 0x02
-
-/* Not exactly known, maybe chip vendor */
-#define AMS_VENDOR 0x03
-
-/* Freefall registers */
-#define AMS_FF_CLEAR 0x04
-#define AMS_FF_ENABLE 0x05
-#define AMS_FF_LOW_LIMIT 0x06
-#define AMS_FF_DEBOUNCE 0x07
-
-/* Shock registers */
-#define AMS_SHOCK_CLEAR 0x08
-#define AMS_SHOCK_ENABLE 0x09
-#define AMS_SHOCK_HIGH_LIMIT 0x0a
-#define AMS_SHOCK_DEBOUNCE 0x0b
-
-/* Global interrupt and power control register */
-#define AMS_CONTROL 0x0c
-
-static u8 ams_pmu_cmd;
-
-static void ams_pmu_req_complete(struct adb_request *req)
-{
- complete((struct completion *)req->arg);
-}
-
-/* Only call this function from task context */
-static void ams_pmu_set_register(u8 reg, u8 value)
-{
- static struct adb_request req;
- DECLARE_COMPLETION(req_complete);
-
- req.arg = &req_complete;
- if (pmu_request(&req, ams_pmu_req_complete, 4, ams_pmu_cmd, 0x00, reg, value))
- return;
-
- wait_for_completion(&req_complete);
-}
-
-/* Only call this function from task context */
-static u8 ams_pmu_get_register(u8 reg)
-{
- static struct adb_request req;
- DECLARE_COMPLETION(req_complete);
-
- req.arg = &req_complete;
- if (pmu_request(&req, ams_pmu_req_complete, 3, ams_pmu_cmd, 0x01, reg))
- return 0;
-
- wait_for_completion(&req_complete);
-
- if (req.reply_len > 0)
- return req.reply[0];
- else
- return 0;
-}
-
-/* Enables or disables the specified interrupts */
-static void ams_pmu_set_irq(enum ams_irq reg, char enable)
-{
- if (reg & AMS_IRQ_FREEFALL) {
- u8 val = ams_pmu_get_register(AMS_FF_ENABLE);
- if (enable)
- val |= 0x80;
- else
- val &= ~0x80;
- ams_pmu_set_register(AMS_FF_ENABLE, val);
- }
-
- if (reg & AMS_IRQ_SHOCK) {
- u8 val = ams_pmu_get_register(AMS_SHOCK_ENABLE);
- if (enable)
- val |= 0x80;
- else
- val &= ~0x80;
- ams_pmu_set_register(AMS_SHOCK_ENABLE, val);
- }
-
- if (reg & AMS_IRQ_GLOBAL) {
- u8 val = ams_pmu_get_register(AMS_CONTROL);
- if (enable)
- val |= 0x80;
- else
- val &= ~0x80;
- ams_pmu_set_register(AMS_CONTROL, val);
- }
-}
-
-static void ams_pmu_clear_irq(enum ams_irq reg)
-{
- if (reg & AMS_IRQ_FREEFALL)
- ams_pmu_set_register(AMS_FF_CLEAR, 0x00);
-
- if (reg & AMS_IRQ_SHOCK)
- ams_pmu_set_register(AMS_SHOCK_CLEAR, 0x00);
-}
-
-static u8 ams_pmu_get_vendor(void)
-{
- return ams_pmu_get_register(AMS_VENDOR);
-}
-
-static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z)
-{
- *x = ams_pmu_get_register(AMS_X);
- *y = ams_pmu_get_register(AMS_Y);
- *z = ams_pmu_get_register(AMS_Z);
-}
-
-static void ams_pmu_exit(void)
-{
- ams_sensor_detach();
-
- /* Disable interrupts */
- ams_pmu_set_irq(AMS_IRQ_ALL, 0);
-
- /* Clear interrupts */
- ams_pmu_clear_irq(AMS_IRQ_ALL);
-
- ams_info.has_device = 0;
-
- printk(KERN_INFO "ams: Unloading\n");
-}
-
-int __init ams_pmu_init(struct device_node *np)
-{
- const u32 *prop;
- int result;
-
- /* Set implementation stuff */
- ams_info.of_node = np;
- ams_info.exit = ams_pmu_exit;
- ams_info.get_vendor = ams_pmu_get_vendor;
- ams_info.get_xyz = ams_pmu_get_xyz;
- ams_info.clear_irq = ams_pmu_clear_irq;
- ams_info.bustype = BUS_HOST;
-
- /* Get PMU command, should be 0x4e, but we can never know */
- prop = of_get_property(ams_info.of_node, "reg", NULL);
- if (!prop)
- return -ENODEV;
-
- ams_pmu_cmd = ((*prop) >> 8) & 0xff;
-
- /* Disable interrupts */
- ams_pmu_set_irq(AMS_IRQ_ALL, 0);
-
- /* Clear interrupts */
- ams_pmu_clear_irq(AMS_IRQ_ALL);
-
- result = ams_sensor_attach();
- if (result < 0)
- return result;
-
- /* Set default values */
- ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15);
- ams_pmu_set_register(AMS_FF_ENABLE, 0x08);
- ams_pmu_set_register(AMS_FF_DEBOUNCE, 0x14);
-
- ams_pmu_set_register(AMS_SHOCK_HIGH_LIMIT, 0x60);
- ams_pmu_set_register(AMS_SHOCK_ENABLE, 0x0f);
- ams_pmu_set_register(AMS_SHOCK_DEBOUNCE, 0x14);
-
- ams_pmu_set_register(AMS_CONTROL, 0x4f);
-
- /* Clear interrupts */
- ams_pmu_clear_irq(AMS_IRQ_ALL);
-
- ams_info.has_device = 1;
-
- /* Enable interrupts */
- ams_pmu_set_irq(AMS_IRQ_ALL, 1);
-
- printk(KERN_INFO "ams: Found PMU based motion sensor\n");
-
- return 0;
-}
--- linux-2.6.36-rc6.orig/drivers/hwmon/ams/ams.h 2010-09-21 11:07:14.000000000 +0200
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,70 +0,0 @@
-#include <linux/i2c.h>
-#include <linux/input-polldev.h>
-#include <linux/kthread.h>
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/of_device.h>
-
-enum ams_irq {
- AMS_IRQ_FREEFALL = 0x01,
- AMS_IRQ_SHOCK = 0x02,
- AMS_IRQ_GLOBAL = 0x04,
- AMS_IRQ_ALL =
- AMS_IRQ_FREEFALL |
- AMS_IRQ_SHOCK |
- AMS_IRQ_GLOBAL,
-};
-
-struct ams {
- /* Locks */
- spinlock_t irq_lock;
- struct mutex lock;
-
- /* General properties */
- struct device_node *of_node;
- struct platform_device *of_dev;
- char has_device;
- char vflag;
- u32 orient1;
- u32 orient2;
-
- /* Interrupt worker */
- struct work_struct worker;
- u8 worker_irqs;
-
- /* Implementation
- *
- * Only call these functions with the main lock held.
- */
- void (*exit)(void);
-
- void (*get_xyz)(s8 *x, s8 *y, s8 *z);
- u8 (*get_vendor)(void);
-
- void (*clear_irq)(enum ams_irq reg);
-
-#ifdef CONFIG_SENSORS_AMS_I2C
- /* I2C properties */
- struct i2c_client *i2c_client;
-#endif
-
- /* Joystick emulation */
- struct input_polled_dev *idev;
- __u16 bustype;
-
- /* calibrated null values */
- int xcalib, ycalib, zcalib;
-};
-
-extern struct ams ams_info;
-
-extern void ams_sensors(s8 *x, s8 *y, s8 *z);
-extern int ams_sensor_attach(void);
-extern void ams_sensor_detach(void);
-
-extern int ams_pmu_init(struct device_node *np);
-extern int ams_i2c_init(struct device_node *np);
-
-extern int ams_input_init(void);
-extern void ams_input_exit(void);
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.36-rc6/drivers/macintosh/ams/Makefile 2010-08-02 00:11:14.000000000 +0200
@@ -0,0 +1,8 @@
+#
+# Makefile for Apple Motion Sensor driver
+#
+
+ams-y := ams-core.o ams-input.o
+ams-$(CONFIG_SENSORS_AMS_PMU) += ams-pmu.o
+ams-$(CONFIG_SENSORS_AMS_I2C) += ams-i2c.o
+obj-$(CONFIG_SENSORS_AMS) += ams.o
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.36-rc6/drivers/macintosh/ams/ams-core.c 2010-08-02 00:11:14.000000000 +0200
@@ -0,0 +1,250 @@
+/*
+ * Apple Motion Sensor driver
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <asm/pmac_pfunc.h>
+
+#include "ams.h"
+
+/* There is only one motion sensor per machine */
+struct ams ams_info;
+
+static unsigned int verbose;
+module_param(verbose, bool, 0644);
+MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output");
+
+/* Call with ams_info.lock held! */
+void ams_sensors(s8 *x, s8 *y, s8 *z)
+{
+ u32 orient = ams_info.vflag? ams_info.orient1 : ams_info.orient2;
+
+ if (orient & 0x80)
+ /* X and Y swapped */
+ ams_info.get_xyz(y, x, z);
+ else
+ ams_info.get_xyz(x, y, z);
+
+ if (orient & 0x04)
+ *z = ~(*z);
+ if (orient & 0x02)
+ *y = ~(*y);
+ if (orient & 0x01)
+ *x = ~(*x);
+}
+
+static ssize_t ams_show_current(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ s8 x, y, z;
+
+ mutex_lock(&ams_info.lock);
+ ams_sensors(&x, &y, &z);
+ mutex_unlock(&ams_info.lock);
+
+ return snprintf(buf, PAGE_SIZE, "%d %d %d\n", x, y, z);
+}
+
+static DEVICE_ATTR(current, S_IRUGO, ams_show_current, NULL);
+
+static void ams_handle_irq(void *data)
+{
+ enum ams_irq irq = *((enum ams_irq *)data);
+
+ spin_lock(&ams_info.irq_lock);
+
+ ams_info.worker_irqs |= irq;
+ schedule_work(&ams_info.worker);
+
+ spin_unlock(&ams_info.irq_lock);
+}
+
+static enum ams_irq ams_freefall_irq_data = AMS_IRQ_FREEFALL;
+static struct pmf_irq_client ams_freefall_client = {
+ .owner = THIS_MODULE,
+ .handler = ams_handle_irq,
+ .data = &ams_freefall_irq_data,
+};
+
+static enum ams_irq ams_shock_irq_data = AMS_IRQ_SHOCK;
+static struct pmf_irq_client ams_shock_client = {
+ .owner = THIS_MODULE,
+ .handler = ams_handle_irq,
+ .data = &ams_shock_irq_data,
+};
+
+/* Once hard disk parking is implemented in the kernel, this function can
+ * trigger it.
+ */
+static void ams_worker(struct work_struct *work)
+{
+ unsigned long flags;
+ u8 irqs_to_clear;
+
+ mutex_lock(&ams_info.lock);
+
+ spin_lock_irqsave(&ams_info.irq_lock, flags);
+ irqs_to_clear = ams_info.worker_irqs;
+
+ if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) {
+ if (verbose)
+ printk(KERN_INFO "ams: freefall detected!\n");
+
+ ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL;
+ }
+
+ if (ams_info.worker_irqs & AMS_IRQ_SHOCK) {
+ if (verbose)
+ printk(KERN_INFO "ams: shock detected!\n");
+
+ ams_info.worker_irqs &= ~AMS_IRQ_SHOCK;
+ }
+
+ spin_unlock_irqrestore(&ams_info.irq_lock, flags);
+
+ ams_info.clear_irq(irqs_to_clear);
+
+ mutex_unlock(&ams_info.lock);
+}
+
+/* Call with ams_info.lock held! */
+int ams_sensor_attach(void)
+{
+ int result;
+ const u32 *prop;
+
+ /* Get orientation */
+ prop = of_get_property(ams_info.of_node, "orientation", NULL);
+ if (!prop)
+ return -ENODEV;
+ ams_info.orient1 = *prop;
+ ams_info.orient2 = *(prop + 1);
+
+ /* Register freefall interrupt handler */
+ result = pmf_register_irq_client(ams_info.of_node,
+ "accel-int-1",
+ &ams_freefall_client);
+ if (result < 0)
+ return -ENODEV;
+
+ /* Reset saved irqs */
+ ams_info.worker_irqs = 0;
+
+ /* Register shock interrupt handler */
+ result = pmf_register_irq_client(ams_info.of_node,
+ "accel-int-2",
+ &ams_shock_client);
+ if (result < 0)
+ goto release_freefall;
+
+ /* Create device */
+ ams_info.of_dev = of_platform_device_create(ams_info.of_node, "ams", NULL);
+ if (!ams_info.of_dev) {
+ result = -ENODEV;
+ goto release_shock;
+ }
+
+ /* Create attributes */
+ result = device_create_file(&ams_info.of_dev->dev, &dev_attr_current);
+ if (result)
+ goto release_of;
+
+ ams_info.vflag = !!(ams_info.get_vendor() & 0x10);
+
+ /* Init input device */
+ result = ams_input_init();
+ if (result)
+ goto release_device_file;
+
+ return result;
+release_device_file:
+ device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
+release_of:
+ of_device_unregister(ams_info.of_dev);
+release_shock:
+ pmf_unregister_irq_client(&ams_shock_client);
+release_freefall:
+ pmf_unregister_irq_client(&ams_freefall_client);
+ return result;
+}
+
+int __init ams_init(void)
+{
+ struct device_node *np;
+
+ spin_lock_init(&ams_info.irq_lock);
+ mutex_init(&ams_info.lock);
+ INIT_WORK(&ams_info.worker, ams_worker);
+
+#ifdef CONFIG_SENSORS_AMS_I2C
+ np = of_find_node_by_name(NULL, "accelerometer");
+ if (np && of_device_is_compatible(np, "AAPL,accelerometer_1"))
+ /* Found I2C motion sensor */
+ return ams_i2c_init(np);
+#endif
+
+#ifdef CONFIG_SENSORS_AMS_PMU
+ np = of_find_node_by_name(NULL, "sms");
+ if (np && of_device_is_compatible(np, "sms"))
+ /* Found PMU motion sensor */
+ return ams_pmu_init(np);
+#endif
+ return -ENODEV;
+}
+
+void ams_sensor_detach(void)
+{
+ /* Remove input device */
+ ams_input_exit();
+
+ /* Remove attributes */
+ device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
+
+ /* Flush interrupt worker
+ *
+ * We do this after ams_info.exit(), because an interrupt might
+ * have arrived before disabling them.
+ */
+ flush_scheduled_work();
+
+ /* Remove device */
+ of_device_unregister(ams_info.of_dev);
+
+ /* Remove handler */
+ pmf_unregister_irq_client(&ams_shock_client);
+ pmf_unregister_irq_client(&ams_freefall_client);
+}
+
+static void __exit ams_exit(void)
+{
+ /* Shut down implementation */
+ ams_info.exit();
+}
+
+MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
+MODULE_DESCRIPTION("Apple Motion Sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(ams_init);
+module_exit(ams_exit);
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.36-rc6/drivers/macintosh/ams/ams-i2c.c 2010-08-02 00:11:14.000000000 +0200
@@ -0,0 +1,277 @@
+/*
+ * Apple Motion Sensor driver (I2C variant)
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * Clean room implementation based on the reverse engineered Mac OS X driver by
+ * Johannes Berg <johannes@sipsolutions.net>, documentation available at
+ * http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "ams.h"
+
+/* AMS registers */
+#define AMS_COMMAND 0x00 /* command register */
+#define AMS_STATUS 0x01 /* status register */
+#define AMS_CTRL1 0x02 /* read control 1 (number of values) */
+#define AMS_CTRL2 0x03 /* read control 2 (offset?) */
+#define AMS_CTRL3 0x04 /* read control 3 (size of each value?) */
+#define AMS_DATA1 0x05 /* read data 1 */
+#define AMS_DATA2 0x06 /* read data 2 */
+#define AMS_DATA3 0x07 /* read data 3 */
+#define AMS_DATA4 0x08 /* read data 4 */
+#define AMS_DATAX 0x20 /* data X */
+#define AMS_DATAY 0x21 /* data Y */
+#define AMS_DATAZ 0x22 /* data Z */
+#define AMS_FREEFALL 0x24 /* freefall int control */
+#define AMS_SHOCK 0x25 /* shock int control */
+#define AMS_SENSLOW 0x26 /* sensitivity low limit */
+#define AMS_SENSHIGH 0x27 /* sensitivity high limit */
+#define AMS_CTRLX 0x28 /* control X */
+#define AMS_CTRLY 0x29 /* control Y */
+#define AMS_CTRLZ 0x2A /* control Z */
+#define AMS_UNKNOWN1 0x2B /* unknown 1 */
+#define AMS_UNKNOWN2 0x2C /* unknown 2 */
+#define AMS_UNKNOWN3 0x2D /* unknown 3 */
+#define AMS_VENDOR 0x2E /* vendor */
+
+/* AMS commands - use with the AMS_COMMAND register */
+enum ams_i2c_cmd {
+ AMS_CMD_NOOP = 0,
+ AMS_CMD_VERSION,
+ AMS_CMD_READMEM,
+ AMS_CMD_WRITEMEM,
+ AMS_CMD_ERASEMEM,
+ AMS_CMD_READEE,
+ AMS_CMD_WRITEEE,
+ AMS_CMD_RESET,
+ AMS_CMD_START,
+};
+
+static int ams_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+static int ams_i2c_remove(struct i2c_client *client);
+
+static const struct i2c_device_id ams_id[] = {
+ { "ams", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ams_id);
+
+static struct i2c_driver ams_i2c_driver = {
+ .driver = {
+ .name = "ams",
+ .owner = THIS_MODULE,
+ },
+ .probe = ams_i2c_probe,
+ .remove = ams_i2c_remove,
+ .id_table = ams_id,
+};
+
+static s32 ams_i2c_read(u8 reg)
+{
+ return i2c_smbus_read_byte_data(ams_info.i2c_client, reg);
+}
+
+static int ams_i2c_write(u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(ams_info.i2c_client, reg, value);
+}
+
+static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
+{
+ s32 result;
+ int count = 3;
+
+ ams_i2c_write(AMS_COMMAND, cmd);
+ msleep(5);
+
+ while (count--) {
+ result = ams_i2c_read(AMS_COMMAND);
+ if (result == 0 || result & 0x80)
+ return 0;
+
+ schedule_timeout_uninterruptible(HZ / 20);
+ }
+
+ return -1;
+}
+
+static void ams_i2c_set_irq(enum ams_irq reg, char enable)
+{
+ if (reg & AMS_IRQ_FREEFALL) {
+ u8 val = ams_i2c_read(AMS_CTRLX);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_i2c_write(AMS_CTRLX, val);
+ }
+
+ if (reg & AMS_IRQ_SHOCK) {
+ u8 val = ams_i2c_read(AMS_CTRLY);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_i2c_write(AMS_CTRLY, val);
+ }
+
+ if (reg & AMS_IRQ_GLOBAL) {
+ u8 val = ams_i2c_read(AMS_CTRLZ);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_i2c_write(AMS_CTRLZ, val);
+ }
+}
+
+static void ams_i2c_clear_irq(enum ams_irq reg)
+{
+ if (reg & AMS_IRQ_FREEFALL)
+ ams_i2c_write(AMS_FREEFALL, 0);
+
+ if (reg & AMS_IRQ_SHOCK)
+ ams_i2c_write(AMS_SHOCK, 0);
+}
+
+static u8 ams_i2c_get_vendor(void)
+{
+ return ams_i2c_read(AMS_VENDOR);
+}
+
+static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z)
+{
+ *x = ams_i2c_read(AMS_DATAX);
+ *y = ams_i2c_read(AMS_DATAY);
+ *z = ams_i2c_read(AMS_DATAZ);
+}
+
+static int ams_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int vmaj, vmin;
+ int result;
+
+ /* There can be only one */
+ if (unlikely(ams_info.has_device))
+ return -ENODEV;
+
+ ams_info.i2c_client = client;
+
+ if (ams_i2c_cmd(AMS_CMD_RESET)) {
+ printk(KERN_INFO "ams: Failed to reset the device\n");
+ return -ENODEV;
+ }
+
+ if (ams_i2c_cmd(AMS_CMD_START)) {
+ printk(KERN_INFO "ams: Failed to start the device\n");
+ return -ENODEV;
+ }
+
+ /* get version/vendor information */
+ ams_i2c_write(AMS_CTRL1, 0x02);
+ ams_i2c_write(AMS_CTRL2, 0x85);
+ ams_i2c_write(AMS_CTRL3, 0x01);
+
+ ams_i2c_cmd(AMS_CMD_READMEM);
+
+ vmaj = ams_i2c_read(AMS_DATA1);
+ vmin = ams_i2c_read(AMS_DATA2);
+ if (vmaj != 1 || vmin != 52) {
+ printk(KERN_INFO "ams: Incorrect device version (%d.%d)\n",
+ vmaj, vmin);
+ return -ENODEV;
+ }
+
+ ams_i2c_cmd(AMS_CMD_VERSION);
+
+ vmaj = ams_i2c_read(AMS_DATA1);
+ vmin = ams_i2c_read(AMS_DATA2);
+ if (vmaj != 0 || vmin != 1) {
+ printk(KERN_INFO "ams: Incorrect firmware version (%d.%d)\n",
+ vmaj, vmin);
+ return -ENODEV;
+ }
+
+ /* Disable interrupts */
+ ams_i2c_set_irq(AMS_IRQ_ALL, 0);
+
+ result = ams_sensor_attach();
+ if (result < 0)
+ return result;
+
+ /* Set default values */
+ ams_i2c_write(AMS_SENSLOW, 0x15);
+ ams_i2c_write(AMS_SENSHIGH, 0x60);
+ ams_i2c_write(AMS_CTRLX, 0x08);
+ ams_i2c_write(AMS_CTRLY, 0x0F);
+ ams_i2c_write(AMS_CTRLZ, 0x4F);
+ ams_i2c_write(AMS_UNKNOWN1, 0x14);
+
+ /* Clear interrupts */
+ ams_i2c_clear_irq(AMS_IRQ_ALL);
+
+ ams_info.has_device = 1;
+
+ /* Enable interrupts */
+ ams_i2c_set_irq(AMS_IRQ_ALL, 1);
+
+ printk(KERN_INFO "ams: Found I2C based motion sensor\n");
+
+ return 0;
+}
+
+static int ams_i2c_remove(struct i2c_client *client)
+{
+ if (ams_info.has_device) {
+ ams_sensor_detach();
+
+ /* Disable interrupts */
+ ams_i2c_set_irq(AMS_IRQ_ALL, 0);
+
+ /* Clear interrupts */
+ ams_i2c_clear_irq(AMS_IRQ_ALL);
+
+ printk(KERN_INFO "ams: Unloading\n");
+
+ ams_info.has_device = 0;
+ }
+
+ return 0;
+}
+
+static void ams_i2c_exit(void)
+{
+ i2c_del_driver(&ams_i2c_driver);
+}
+
+int __init ams_i2c_init(struct device_node *np)
+{
+ int result;
+
+ /* Set implementation stuff */
+ ams_info.of_node = np;
+ ams_info.exit = ams_i2c_exit;
+ ams_info.get_vendor = ams_i2c_get_vendor;
+ ams_info.get_xyz = ams_i2c_get_xyz;
+ ams_info.clear_irq = ams_i2c_clear_irq;
+ ams_info.bustype = BUS_I2C;
+
+ result = i2c_add_driver(&ams_i2c_driver);
+
+ return result;
+}
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.36-rc6/drivers/macintosh/ams/ams-input.c 2010-08-02 00:11:14.000000000 +0200
@@ -0,0 +1,157 @@
+/*
+ * Apple Motion Sensor driver (joystick emulation)
+ *
+ * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "ams.h"
+
+static unsigned int joystick;
+module_param(joystick, bool, S_IRUGO);
+MODULE_PARM_DESC(joystick, "Enable the input class device on module load");
+
+static unsigned int invert;
+module_param(invert, bool, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
+
+static DEFINE_MUTEX(ams_input_mutex);
+
+static void ams_idev_poll(struct input_polled_dev *dev)
+{
+ struct input_dev *idev = dev->input;
+ s8 x, y, z;
+
+ mutex_lock(&ams_info.lock);
+
+ ams_sensors(&x, &y, &z);
+
+ x -= ams_info.xcalib;
+ y -= ams_info.ycalib;
+ z -= ams_info.zcalib;
+
+ input_report_abs(idev, ABS_X, invert ? -x : x);
+ input_report_abs(idev, ABS_Y, invert ? -y : y);
+ input_report_abs(idev, ABS_Z, z);
+
+ input_sync(idev);
+
+ mutex_unlock(&ams_info.lock);
+}
+
+/* Call with ams_info.lock held! */
+static int ams_input_enable(void)
+{
+ struct input_dev *input;
+ s8 x, y, z;
+ int error;
+
+ ams_sensors(&x, &y, &z);
+ ams_info.xcalib = x;
+ ams_info.ycalib = y;
+ ams_info.zcalib = z;
+
+ ams_info.idev = input_allocate_polled_device();
+ if (!ams_info.idev)
+ return -ENOMEM;
+
+ ams_info.idev->poll = ams_idev_poll;
+ ams_info.idev->poll_interval = 25;
+
+ input = ams_info.idev->input;
+ input->name = "Apple Motion Sensor";
+ input->id.bustype = ams_info.bustype;
+ input->id.vendor = 0;
+ input->dev.parent = &ams_info.of_dev->dev;
+
+ input_set_abs_params(input, ABS_X, -50, 50, 3, 0);
+ input_set_abs_params(input, ABS_Y, -50, 50, 3, 0);
+ input_set_abs_params(input, ABS_Z, -50, 50, 3, 0);
+
+ set_bit(EV_ABS, input->evbit);
+ set_bit(EV_KEY, input->evbit);
+ set_bit(BTN_TOUCH, input->keybit);
+
+ error = input_register_polled_device(ams_info.idev);
+ if (error) {
+ input_free_polled_device(ams_info.idev);
+ ams_info.idev = NULL;
+ return error;
+ }
+
+ joystick = 1;
+
+ return 0;
+}
+
+static void ams_input_disable(void)
+{
+ if (ams_info.idev) {
+ input_unregister_polled_device(ams_info.idev);
+ input_free_polled_device(ams_info.idev);
+ ams_info.idev = NULL;
+ }
+
+ joystick = 0;
+}
+
+static ssize_t ams_input_show_joystick(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", joystick);
+}
+
+static ssize_t ams_input_store_joystick(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long enable;
+ int error = 0;
+
+ if (strict_strtoul(buf, 0, &enable) || enable > 1)
+ return -EINVAL;
+
+ mutex_lock(&ams_input_mutex);
+
+ if (enable != joystick) {
+ if (enable)
+ error = ams_input_enable();
+ else
+ ams_input_disable();
+ }
+
+ mutex_unlock(&ams_input_mutex);
+
+ return error ? error : count;
+}
+
+static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR,
+ ams_input_show_joystick, ams_input_store_joystick);
+
+int ams_input_init(void)
+{
+ if (joystick)
+ ams_input_enable();
+
+ return device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
+}
+
+void ams_input_exit(void)
+{
+ device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick);
+
+ mutex_lock(&ams_input_mutex);
+ ams_input_disable();
+ mutex_unlock(&ams_input_mutex);
+}
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.36-rc6/drivers/macintosh/ams/ams-pmu.c 2010-08-02 00:11:14.000000000 +0200
@@ -0,0 +1,201 @@
+/*
+ * Apple Motion Sensor driver (PMU variant)
+ *
+ * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+#include "ams.h"
+
+/* Attitude */
+#define AMS_X 0x00
+#define AMS_Y 0x01
+#define AMS_Z 0x02
+
+/* Not exactly known, maybe chip vendor */
+#define AMS_VENDOR 0x03
+
+/* Freefall registers */
+#define AMS_FF_CLEAR 0x04
+#define AMS_FF_ENABLE 0x05
+#define AMS_FF_LOW_LIMIT 0x06
+#define AMS_FF_DEBOUNCE 0x07
+
+/* Shock registers */
+#define AMS_SHOCK_CLEAR 0x08
+#define AMS_SHOCK_ENABLE 0x09
+#define AMS_SHOCK_HIGH_LIMIT 0x0a
+#define AMS_SHOCK_DEBOUNCE 0x0b
+
+/* Global interrupt and power control register */
+#define AMS_CONTROL 0x0c
+
+static u8 ams_pmu_cmd;
+
+static void ams_pmu_req_complete(struct adb_request *req)
+{
+ complete((struct completion *)req->arg);
+}
+
+/* Only call this function from task context */
+static void ams_pmu_set_register(u8 reg, u8 value)
+{
+ static struct adb_request req;
+ DECLARE_COMPLETION(req_complete);
+
+ req.arg = &req_complete;
+ if (pmu_request(&req, ams_pmu_req_complete, 4, ams_pmu_cmd, 0x00, reg, value))
+ return;
+
+ wait_for_completion(&req_complete);
+}
+
+/* Only call this function from task context */
+static u8 ams_pmu_get_register(u8 reg)
+{
+ static struct adb_request req;
+ DECLARE_COMPLETION(req_complete);
+
+ req.arg = &req_complete;
+ if (pmu_request(&req, ams_pmu_req_complete, 3, ams_pmu_cmd, 0x01, reg))
+ return 0;
+
+ wait_for_completion(&req_complete);
+
+ if (req.reply_len > 0)
+ return req.reply[0];
+ else
+ return 0;
+}
+
+/* Enables or disables the specified interrupts */
+static void ams_pmu_set_irq(enum ams_irq reg, char enable)
+{
+ if (reg & AMS_IRQ_FREEFALL) {
+ u8 val = ams_pmu_get_register(AMS_FF_ENABLE);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_pmu_set_register(AMS_FF_ENABLE, val);
+ }
+
+ if (reg & AMS_IRQ_SHOCK) {
+ u8 val = ams_pmu_get_register(AMS_SHOCK_ENABLE);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_pmu_set_register(AMS_SHOCK_ENABLE, val);
+ }
+
+ if (reg & AMS_IRQ_GLOBAL) {
+ u8 val = ams_pmu_get_register(AMS_CONTROL);
+ if (enable)
+ val |= 0x80;
+ else
+ val &= ~0x80;
+ ams_pmu_set_register(AMS_CONTROL, val);
+ }
+}
+
+static void ams_pmu_clear_irq(enum ams_irq reg)
+{
+ if (reg & AMS_IRQ_FREEFALL)
+ ams_pmu_set_register(AMS_FF_CLEAR, 0x00);
+
+ if (reg & AMS_IRQ_SHOCK)
+ ams_pmu_set_register(AMS_SHOCK_CLEAR, 0x00);
+}
+
+static u8 ams_pmu_get_vendor(void)
+{
+ return ams_pmu_get_register(AMS_VENDOR);
+}
+
+static void ams_pmu_get_xyz(s8 *x, s8 *y, s8 *z)
+{
+ *x = ams_pmu_get_register(AMS_X);
+ *y = ams_pmu_get_register(AMS_Y);
+ *z = ams_pmu_get_register(AMS_Z);
+}
+
+static void ams_pmu_exit(void)
+{
+ ams_sensor_detach();
+
+ /* Disable interrupts */
+ ams_pmu_set_irq(AMS_IRQ_ALL, 0);
+
+ /* Clear interrupts */
+ ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+ ams_info.has_device = 0;
+
+ printk(KERN_INFO "ams: Unloading\n");
+}
+
+int __init ams_pmu_init(struct device_node *np)
+{
+ const u32 *prop;
+ int result;
+
+ /* Set implementation stuff */
+ ams_info.of_node = np;
+ ams_info.exit = ams_pmu_exit;
+ ams_info.get_vendor = ams_pmu_get_vendor;
+ ams_info.get_xyz = ams_pmu_get_xyz;
+ ams_info.clear_irq = ams_pmu_clear_irq;
+ ams_info.bustype = BUS_HOST;
+
+ /* Get PMU command, should be 0x4e, but we can never know */
+ prop = of_get_property(ams_info.of_node, "reg", NULL);
+ if (!prop)
+ return -ENODEV;
+
+ ams_pmu_cmd = ((*prop) >> 8) & 0xff;
+
+ /* Disable interrupts */
+ ams_pmu_set_irq(AMS_IRQ_ALL, 0);
+
+ /* Clear interrupts */
+ ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+ result = ams_sensor_attach();
+ if (result < 0)
+ return result;
+
+ /* Set default values */
+ ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15);
+ ams_pmu_set_register(AMS_FF_ENABLE, 0x08);
+ ams_pmu_set_register(AMS_FF_DEBOUNCE, 0x14);
+
+ ams_pmu_set_register(AMS_SHOCK_HIGH_LIMIT, 0x60);
+ ams_pmu_set_register(AMS_SHOCK_ENABLE, 0x0f);
+ ams_pmu_set_register(AMS_SHOCK_DEBOUNCE, 0x14);
+
+ ams_pmu_set_register(AMS_CONTROL, 0x4f);
+
+ /* Clear interrupts */
+ ams_pmu_clear_irq(AMS_IRQ_ALL);
+
+ ams_info.has_device = 1;
+
+ /* Enable interrupts */
+ ams_pmu_set_irq(AMS_IRQ_ALL, 1);
+
+ printk(KERN_INFO "ams: Found PMU based motion sensor\n");
+
+ return 0;
+}
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.36-rc6/drivers/macintosh/ams/ams.h 2010-09-21 11:07:14.000000000 +0200
@@ -0,0 +1,70 @@
+#include <linux/i2c.h>
+#include <linux/input-polldev.h>
+#include <linux/kthread.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/of_device.h>
+
+enum ams_irq {
+ AMS_IRQ_FREEFALL = 0x01,
+ AMS_IRQ_SHOCK = 0x02,
+ AMS_IRQ_GLOBAL = 0x04,
+ AMS_IRQ_ALL =
+ AMS_IRQ_FREEFALL |
+ AMS_IRQ_SHOCK |
+ AMS_IRQ_GLOBAL,
+};
+
+struct ams {
+ /* Locks */
+ spinlock_t irq_lock;
+ struct mutex lock;
+
+ /* General properties */
+ struct device_node *of_node;
+ struct platform_device *of_dev;
+ char has_device;
+ char vflag;
+ u32 orient1;
+ u32 orient2;
+
+ /* Interrupt worker */
+ struct work_struct worker;
+ u8 worker_irqs;
+
+ /* Implementation
+ *
+ * Only call these functions with the main lock held.
+ */
+ void (*exit)(void);
+
+ void (*get_xyz)(s8 *x, s8 *y, s8 *z);
+ u8 (*get_vendor)(void);
+
+ void (*clear_irq)(enum ams_irq reg);
+
+#ifdef CONFIG_SENSORS_AMS_I2C
+ /* I2C properties */
+ struct i2c_client *i2c_client;
+#endif
+
+ /* Joystick emulation */
+ struct input_polled_dev *idev;
+ __u16 bustype;
+
+ /* calibrated null values */
+ int xcalib, ycalib, zcalib;
+};
+
+extern struct ams ams_info;
+
+extern void ams_sensors(s8 *x, s8 *y, s8 *z);
+extern int ams_sensor_attach(void);
+extern void ams_sensor_detach(void);
+
+extern int ams_pmu_init(struct device_node *np);
+extern int ams_i2c_init(struct device_node *np);
+
+extern int ams_input_init(void);
+extern void ams_input_exit(void);
--- linux-2.6.36-rc6.orig/MAINTAINERS 2010-10-05 10:45:16.000000000 +0200
+++ linux-2.6.36-rc6/MAINTAINERS 2010-10-05 11:51:21.000000000 +0200
@@ -445,7 +445,7 @@ AMS (Apple Motion Sensor) DRIVER
M: Stelian Pop <stelian@popies.net>
M: Michael Hanselmann <linux-kernel@hansmi.ch>
S: Supported
-F: drivers/hwmon/ams/
+F: drivers/macintosh/ams/
AMSO1100 RNIC DRIVER
M: Tom Tucker <tom@opengridcomputing.com>
--- linux-2.6.36-rc6.orig/drivers/hwmon/Kconfig 2010-10-05 10:45:16.000000000 +0200
+++ linux-2.6.36-rc6/drivers/hwmon/Kconfig 2010-10-05 11:42:38.000000000 +0200
@@ -249,32 +249,6 @@ config SENSORS_K10TEMP
This driver can also be built as a module. If so, the module
will be called k10temp.
-config SENSORS_AMS
- tristate "Apple Motion Sensor driver"
- depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
- select INPUT_POLLDEV
- help
- Support for the motion sensor included in PowerBooks. Includes
- implementations for PMU and I2C.
-
- This driver can also be built as a module. If so, the module
- will be called ams.
-
-config SENSORS_AMS_PMU
- bool "PMU variant"
- depends on SENSORS_AMS && ADB_PMU
- default y
- help
- PMU variant of motion sensor, found in late 2005 PowerBooks.
-
-config SENSORS_AMS_I2C
- bool "I2C variant"
- depends on SENSORS_AMS && I2C
- default y
- help
- I2C variant of motion sensor, found in early 2005 PowerBooks and
- iBooks.
-
config SENSORS_ASB100
tristate "Asus ASB100 Bach"
depends on X86 && I2C && EXPERIMENTAL
--- linux-2.6.36-rc6.orig/drivers/hwmon/Makefile 2010-10-05 10:45:16.000000000 +0200
+++ linux-2.6.36-rc6/drivers/hwmon/Makefile 2010-10-05 11:41:34.000000000 +0200
@@ -36,7 +36,6 @@ obj-$(CONFIG_SENSORS_ADT7462) += adt7462
obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o
obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
-obj-$(CONFIG_SENSORS_AMS) += ams/
obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
--- linux-2.6.36-rc6.orig/drivers/macintosh/Kconfig 2010-08-02 00:11:14.000000000 +0200
+++ linux-2.6.36-rc6/drivers/macintosh/Kconfig 2010-10-05 11:42:49.000000000 +0200
@@ -256,4 +256,30 @@ config PMAC_RACKMETER
This driver provides some support to control the front panel
blue LEDs "vu-meter" of the XServer macs.
+config SENSORS_AMS
+ tristate "Apple Motion Sensor driver"
+ depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
+ select INPUT_POLLDEV
+ help
+ Support for the motion sensor included in PowerBooks. Includes
+ implementations for PMU and I2C.
+
+ This driver can also be built as a module. If so, the module
+ will be called ams.
+
+config SENSORS_AMS_PMU
+ bool "PMU variant"
+ depends on SENSORS_AMS && ADB_PMU
+ default y
+ help
+ PMU variant of motion sensor, found in late 2005 PowerBooks.
+
+config SENSORS_AMS_I2C
+ bool "I2C variant"
+ depends on SENSORS_AMS && I2C
+ default y
+ help
+ I2C variant of motion sensor, found in early 2005 PowerBooks and
+ iBooks.
+
endif # MACINTOSH_DRIVERS
--- linux-2.6.36-rc6.orig/drivers/macintosh/Makefile 2010-08-02 00:11:14.000000000 +0200
+++ linux-2.6.36-rc6/drivers/macintosh/Makefile 2010-10-05 11:42:05.000000000 +0200
@@ -48,3 +48,5 @@ obj-$(CONFIG_WINDFARM_PM121) += windfarm
windfarm_max6690_sensor.o \
windfarm_lm75_sensor.o windfarm_pid.o
obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o
+
+obj-$(CONFIG_SENSORS_AMS) += ams/
--
Jean Delvare
^ permalink raw reply
* Re: Serial RapidIO Maintaintance read causes lock up
From: Bastiaan Nijkamp @ 2010-10-05 8:56 UTC (permalink / raw)
To: Bounine, Alexandre; +Cc: linuxppc-dev
In-Reply-To: <0CE8B6BE3C4AD74AB97D9D29BD24E552013B97E8@CORPEXCH1.na.ads.idt.com>
[-- Attachment #1: Type: text/plain, Size: 3887 bytes --]
Hi Alex,
Thanks for your advice. We are trying to make a board-to-board connection
without any additional hardware (eg. a switch). The boards use a 50-pin,
right-angle MEC8-125-02-L-D-RA1 connector from SAMTEC and are connected
trough a EEDP-016-12.00-RA1-RA2-2 cross cable from SAMTEC. I hope this
information is sufficient since there is not much one can find about it on
Google. In addition, you can see a picture of the board including the
connector in the datasheet located at
http://www.windriver.com/products/product-notes/SBC8548E-product-note.pdf.
It is the connector on the left side of the PCI-EX slot.
We have tried your suggestion but the situation does not change other than
the lane-mode being set to single lane 0, it still locks up when trying to
generate a maintenance transaction. I still think it is memory related since
the lock up occurs when accessing the maintenance window. Although all
memory related settings seems to be alright.
The kernel output is as follows:
Setting up RapidIO peer-to-peer network /soc8548@e0000000/rapidio@c0000
fsl-of-rio e00c0000.rapidio: Of-device full name
/soc8548@e0000000/rapidio@c0000
fsl-of-rio e00c0000.rapidio: Regs: [mem 0xe00c0000-0xe00dffff]
fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, size
0x0000000010000000.
fsl-of-rio e00c0000.rapidio: pwirq: 48, bellirq: 50, txirq: 53, rxirq 54
fsl-of-rio e00c0000.rapidio: DeviceID is 0x0
fsl-of-rio e00c0000.rapidio: Configured as HOST
fsl-of-rio e00c0000.rapidio: Overriding RIO_PORT setting to single lane 0
fsl-of-rio e00c0000.rapidio: RapidIO PHY type: serial
fsl-of-rio e00c0000.rapidio: Hardware port width: 4
fsl-of-rio e00c0000.rapidio: Training connection status: Single-lane 0
fsl-of-rio e00c0000.rapidio: RapidIO Common Transport System size: 256
fsl-of-rio e00c0000.rapidio: LAW start 0x00000000c0000000, RIO Maintainance
Window Size 0x400000,New Main Start: 0xd1080000
RIO: enumerate master port 0, RIO0 mport
fsl_rio_config_read: index 0 destid 255 hopcount 0 offset 00000068 len 4
fsl_rio_config_read: Passed IS_ALIGNED.
fsl_rio_config_read: Passed 'out_be32_1'
fsl_rio_config_read: Passed 'out_be32_2'
fsl_rio_config_read: len is 4
fsl_rio_config_read: triggering '__fsl_read_rio_config'
fsl_rio_config_read: going to request to read data at d108006
Regards,
Bastiaan
2010/10/4 Bounine, Alexandre <Alexandre.Bounine@idt.com>
> Hi Bastiaan,
>
> Are you trying board-to-board connection?
> I am not familiar with WRS SBC8548 board - which type of connector they
> use for SRIO?
>
> Assuming that all configuration is correct,
> I would recommend first to try setting up x1 link mode at the lowest
> link speed.
> The x4 mode may present challenges in some cases.
>
> For quick test you may just add port width override into fsl_rio.c
> like shown below (ugly but sometimes it helps ;) ):
>
> @@ -1461,10 +1461,16 @@ int fsl_rio_setup(struct platform_device *dev)
> rio_register_mport(port);
>
> priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);
> rio_regs_win = priv->regs_win;
>
> +dev_info(&dev->dev, "Overriding RIO_PORT setting to single lane 0\n");
> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) |
> 0x800000);
> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) |
> 0x2000000);
> +out_be32(priv->regs_win + 0x15C, in_be32(priv->regs_win + 0x15C) &
> ~0x800000);
> +msleep(100);
> +
> /* Probe the master port phy type */
> ccsr = in_be32(priv->regs_win + RIO_CCSR);
> port->phy_type = (ccsr & 1) ? RIO_PHY_SERIAL : RIO_PHY_PARALLEL;
> dev_info(&dev->dev, "RapidIO PHY type: %s\n",
> (port->phy_type == RIO_PHY_PARALLEL) ?
> "parallel" :
>
>
> Let me know what happens.
> Please keep me in the CC: list next time when posting RapidIO questions
> to the linuxppc-dev or kernel mailing lists.
>
> Regards,
>
> Alex.
>
>
[-- Attachment #2: Type: text/html, Size: 4562 bytes --]
^ permalink raw reply
* Re: use of BAT before taking over the MMU
From: Benjamin Herrenschmidt @ 2010-10-05 8:11 UTC (permalink / raw)
To: Albert Cahalan; +Cc: linuxppc-dev
In-Reply-To: <AANLkTikt9e5s3UUn1+k=NY7UhqosM5qkgdih=UD+Hd+L@mail.gmail.com>
On Mon, 2010-10-04 at 12:06 -0400, Albert Cahalan wrote:
> On Mon, Oct 4, 2010 at 12:25 AM, Segher Boessenkool
> <segher@kernel.crashing.org> wrote:
>
> > The PowerPC OF binding requires the firmware to save and restore
> > the BATs on entry to / exit from the firmware.
>
> This sucks, because using the BAT is **much** easier for
> the firmware. In my case, it also means I don't need to worry
> about Linux stomping on anything -- I have nothing in RAM.
What FW are we talking about here anyways ? As I said, Linux isn't
supposed to take any fault from the moment it starts setting up BATs to
the moment it takes over exceptions and can handle faults all by itself.
> (this is an emulator, but I don't want to cheat too much
> because adding special cases affects performance)
>
> Page tables would need to go in RAM. If Linux wants to
> use that memory...? It seems that Linux does tend to ask;
> will it panic if I refuse? Are there addresses Linux won't
> ever ask for?
>
> It also looks like I could just start up Linux w/o the MMU on.
> I'm just making 1:1 mappings anyway.
Cheers,
Ben.
^ permalink raw reply
* Re: use of BAT before taking over the MMU
From: Benjamin Herrenschmidt @ 2010-10-05 8:10 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: Albert Cahalan, linuxppc-dev
In-Reply-To: <63799.84.105.60.153.1286166325.squirrel@gate.crashing.org>
On Mon, 2010-10-04 at 06:25 +0200, Segher Boessenkool wrote:
> > On the prom boot path, with the firmware supposed to
> > be managing the MMU, there is a case where:
> >
> > 1. Linux changes some BAT registers.
> > 2. Bits 0x00000070 are/become set in the MSR.
> > 3. Linux takes an MMU fault.
> > 4. The firmware handles it.
> >
> > AFAIK, you can't expect the firmware to leave the BAT alone.
> > If the firmware provides mapping services by using the BAT
> > as a software-filled TLB, Linux's BAT changes may be lost.
> >
> > You also can't expect that your BAT changes will not conflict
> > with mappings that the firmware uses for itself. The firmware
> > might write to your new BAT mapping, relying on those virtual
> > addresses to be something else entirely.
>
> The PowerPC OF binding requires the firmware to save and restore
> the BATs on entry to / exit from the firmware.
I'm not sure he was talking about OF here... In any case, we don't muck
around with BATs until after we're done with OF anyways.
Cheers,
Ben.
^ permalink raw reply
* Re: use of BAT before taking over the MMU
From: Benjamin Herrenschmidt @ 2010-10-05 8:09 UTC (permalink / raw)
To: Albert Cahalan; +Cc: linuxppc-dev
In-Reply-To: <AANLkTikPhpvJetY+NDFggYE6Wp6ppyt2BLmzEbsiwHuZ@mail.gmail.com>
On Sat, 2010-10-02 at 14:32 -0400, Albert Cahalan wrote:
> On the prom boot path, with the firmware supposed to
> be managing the MMU, there is a case where:
>
> 1. Linux changes some BAT registers.
> 2. Bits 0x00000070 are/become set in the MSR.
> 3. Linux takes an MMU fault.
Meeep ! Linux should never take an MMU fault at that point :-) If it
does, then there's a bug somewhere that needs squashing.
> 4. The firmware handles it.
>
> AFAIK, you can't expect the firmware to leave the BAT alone.
> If the firmware provides mapping services by using the BAT
> as a software-filled TLB, Linux's BAT changes may be lost.
>
> You also can't expect that your BAT changes will not conflict
> with mappings that the firmware uses for itself. The firmware
> might write to your new BAT mapping, relying on those virtual
> addresses to be something else entirely.
Right, which is why the moment Linux takes over the BATs, it shouldn't
call into FW anymore nor take faults.
Cheers,
Ben.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox