mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-16 01:04:08 +08:00
Merge branch 'master'
This commit is contained in:
commit
f85272a978
56
Documentation/networking/dccp.txt
Normal file
56
Documentation/networking/dccp.txt
Normal file
@ -0,0 +1,56 @@
|
||||
DCCP protocol
|
||||
============
|
||||
|
||||
Last updated: 10 November 2005
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
- Introduction
|
||||
- Missing features
|
||||
- Socket options
|
||||
- Notes
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
|
||||
based protocol designed to solve issues present in UDP and TCP particularly
|
||||
for real time and multimedia traffic.
|
||||
|
||||
It has a base protocol and pluggable congestion control IDs (CCIDs).
|
||||
|
||||
It is at draft RFC status and the homepage for DCCP as a protocol is at:
|
||||
http://www.icir.org/kohler/dcp/
|
||||
|
||||
Missing features
|
||||
================
|
||||
|
||||
The DCCP implementation does not currently have all the features that are in
|
||||
the draft RFC.
|
||||
|
||||
In particular the following are missing:
|
||||
- CCID2 support
|
||||
- feature negotiation
|
||||
|
||||
When testing against other implementations it appears that elapsed time
|
||||
options are not coded compliant to the specification.
|
||||
|
||||
Socket options
|
||||
==============
|
||||
|
||||
DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for
|
||||
calculations.
|
||||
|
||||
DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the
|
||||
specification. If you don't set it you will get EPROTO.
|
||||
|
||||
Notes
|
||||
=====
|
||||
|
||||
SELinux does not yet have support for DCCP. You will need to turn it off or
|
||||
else you will get EACCES.
|
||||
|
||||
DCCP does not travel through NAT successfully at present. This is because
|
||||
the checksum covers the psuedo-header as per TCP and UDP. It should be
|
||||
relatively trivial to add Linux NAT support for DCCP.
|
@ -78,6 +78,11 @@ inet_peer_gc_maxtime - INTEGER
|
||||
|
||||
TCP variables:
|
||||
|
||||
tcp_abc - INTEGER
|
||||
Controls Appropriate Byte Count defined in RFC3465. If set to
|
||||
0 then does congestion avoid once per ack. 1 is conservative
|
||||
value, and 2 is more agressive.
|
||||
|
||||
tcp_syn_retries - INTEGER
|
||||
Number of times initial SYNs for an active TCP connection attempt
|
||||
will be retransmitted. Should not be higher than 255. Default value
|
||||
|
@ -707,7 +707,7 @@ DCCP PROTOCOL
|
||||
P: Arnaldo Carvalho de Melo
|
||||
M: acme@mandriva.com
|
||||
L: dccp@vger.kernel.org
|
||||
W: http://www.wlug.org.nz/DCCP
|
||||
W: http://linux-net.osdl.org/index.php/DCCP
|
||||
S: Maintained
|
||||
|
||||
DECnet NETWORK LAYER
|
||||
|
4
Makefile
4
Makefile
@ -347,7 +347,7 @@ AFLAGS_KERNEL =
|
||||
# Needed to be compatible with the O= option
|
||||
LINUXINCLUDE := -Iinclude \
|
||||
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
|
||||
-imacros include/linux/autoconf.h
|
||||
-include include/linux/autoconf.h
|
||||
|
||||
CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
|
||||
|
||||
@ -407,7 +407,7 @@ outputmakefile:
|
||||
# of make so .config is not included in this case either (for *config).
|
||||
|
||||
no-dot-config-targets := clean mrproper distclean \
|
||||
cscope TAGS tags help %docs check%
|
||||
cscope TAGS tags help %docs check% kernelrelease
|
||||
|
||||
config-targets := 0
|
||||
mixed-targets := 0
|
||||
|
@ -239,6 +239,8 @@ source "arch/arm/plat-omap/Kconfig"
|
||||
|
||||
source "arch/arm/mach-omap1/Kconfig"
|
||||
|
||||
source "arch/arm/mach-omap2/Kconfig"
|
||||
|
||||
source "arch/arm/mach-s3c2410/Kconfig"
|
||||
|
||||
source "arch/arm/mach-lh7a40x/Kconfig"
|
||||
|
@ -93,6 +93,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
|
||||
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
|
||||
machine-$(CONFIG_ARCH_IXP2000) := ixp2000
|
||||
machine-$(CONFIG_ARCH_OMAP1) := omap1
|
||||
machine-$(CONFIG_ARCH_OMAP2) := omap2
|
||||
incdir-$(CONFIG_ARCH_OMAP) := omap
|
||||
machine-$(CONFIG_ARCH_S3C2410) := s3c2410
|
||||
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.13
|
||||
# Mon Sep 5 18:07:12 2005
|
||||
# Linux kernel version: 2.6.14
|
||||
# Wed Nov 9 18:53:40 2005
|
||||
#
|
||||
CONFIG_ARM=y
|
||||
CONFIG_MMU=y
|
||||
@ -22,6 +22,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
|
||||
# General setup
|
||||
#
|
||||
CONFIG_LOCALVERSION=""
|
||||
CONFIG_LOCALVERSION_AUTO=y
|
||||
CONFIG_SWAP=y
|
||||
CONFIG_SYSVIPC=y
|
||||
# CONFIG_POSIX_MQUEUE is not set
|
||||
@ -31,6 +32,7 @@ CONFIG_SYSCTL=y
|
||||
# CONFIG_HOTPLUG is not set
|
||||
CONFIG_KOBJECT_UEVENT=y
|
||||
# CONFIG_IKCONFIG is not set
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
# CONFIG_EMBEDDED is not set
|
||||
CONFIG_KALLSYMS=y
|
||||
# CONFIG_KALLSYMS_EXTRA_PASS is not set
|
||||
@ -59,6 +61,23 @@ CONFIG_OBSOLETE_MODPARM=y
|
||||
# CONFIG_MODULE_SRCVERSION_ALL is not set
|
||||
# CONFIG_KMOD is not set
|
||||
|
||||
#
|
||||
# Block layer
|
||||
#
|
||||
|
||||
#
|
||||
# IO Schedulers
|
||||
#
|
||||
CONFIG_IOSCHED_NOOP=y
|
||||
CONFIG_IOSCHED_AS=y
|
||||
CONFIG_IOSCHED_DEADLINE=y
|
||||
CONFIG_IOSCHED_CFQ=y
|
||||
CONFIG_DEFAULT_AS=y
|
||||
# CONFIG_DEFAULT_DEADLINE is not set
|
||||
# CONFIG_DEFAULT_CFQ is not set
|
||||
# CONFIG_DEFAULT_NOOP is not set
|
||||
CONFIG_DEFAULT_IOSCHED="anticipatory"
|
||||
|
||||
#
|
||||
# System Type
|
||||
#
|
||||
@ -81,6 +100,7 @@ CONFIG_OBSOLETE_MODPARM=y
|
||||
# CONFIG_ARCH_LH7A40X is not set
|
||||
CONFIG_ARCH_OMAP=y
|
||||
# CONFIG_ARCH_VERSATILE is not set
|
||||
# CONFIG_ARCH_REALVIEW is not set
|
||||
# CONFIG_ARCH_IMX is not set
|
||||
# CONFIG_ARCH_H720X is not set
|
||||
# CONFIG_ARCH_AAEC2000 is not set
|
||||
@ -112,7 +132,7 @@ CONFIG_OMAP_SERIAL_WAKE=y
|
||||
# OMAP Core Type
|
||||
#
|
||||
# CONFIG_ARCH_OMAP730 is not set
|
||||
# CONFIG_ARCH_OMAP1510 is not set
|
||||
# CONFIG_ARCH_OMAP15XX is not set
|
||||
CONFIG_ARCH_OMAP16XX=y
|
||||
|
||||
#
|
||||
@ -177,6 +197,8 @@ CONFIG_FLATMEM_MANUAL=y
|
||||
# CONFIG_SPARSEMEM_MANUAL is not set
|
||||
CONFIG_FLATMEM=y
|
||||
CONFIG_FLAT_NODE_MEM_MAP=y
|
||||
# CONFIG_SPARSEMEM_STATIC is not set
|
||||
CONFIG_SPLIT_PTLOCK_CPUS=4096
|
||||
# CONFIG_LEDS is not set
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
|
||||
@ -258,13 +280,18 @@ CONFIG_IP_PNP_BOOTP=y
|
||||
# CONFIG_INET_ESP is not set
|
||||
# CONFIG_INET_IPCOMP is not set
|
||||
# CONFIG_INET_TUNNEL is not set
|
||||
CONFIG_IP_TCPDIAG=y
|
||||
# CONFIG_IP_TCPDIAG_IPV6 is not set
|
||||
CONFIG_INET_DIAG=y
|
||||
CONFIG_INET_TCP_DIAG=y
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_TCP_CONG_BIC=y
|
||||
# CONFIG_IPV6 is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
|
||||
#
|
||||
# DCCP Configuration (EXPERIMENTAL)
|
||||
#
|
||||
# CONFIG_IP_DCCP is not set
|
||||
|
||||
#
|
||||
# SCTP Configuration (EXPERIMENTAL)
|
||||
#
|
||||
@ -281,6 +308,10 @@ CONFIG_TCP_CONG_BIC=y
|
||||
# CONFIG_NET_DIVERT is not set
|
||||
# CONFIG_ECONET is not set
|
||||
# CONFIG_WAN_ROUTER is not set
|
||||
|
||||
#
|
||||
# QoS and/or fair queueing
|
||||
#
|
||||
# CONFIG_NET_SCHED is not set
|
||||
# CONFIG_NET_CLS_ROUTE is not set
|
||||
|
||||
@ -291,6 +322,7 @@ CONFIG_TCP_CONG_BIC=y
|
||||
# CONFIG_HAMRADIO is not set
|
||||
# CONFIG_IRDA is not set
|
||||
# CONFIG_BT is not set
|
||||
# CONFIG_IEEE80211 is not set
|
||||
|
||||
#
|
||||
# Device Drivers
|
||||
@ -328,21 +360,13 @@ CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||
CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
|
||||
#
|
||||
# IO Schedulers
|
||||
#
|
||||
CONFIG_IOSCHED_NOOP=y
|
||||
CONFIG_IOSCHED_AS=y
|
||||
CONFIG_IOSCHED_DEADLINE=y
|
||||
CONFIG_IOSCHED_CFQ=y
|
||||
CONFIG_ATA_OVER_ETH=m
|
||||
|
||||
#
|
||||
# SCSI device support
|
||||
#
|
||||
# CONFIG_RAID_ATTRS is not set
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SCSI_PROC_FS=y
|
||||
|
||||
@ -369,10 +393,12 @@ CONFIG_SCSI_PROC_FS=y
|
||||
# CONFIG_SCSI_SPI_ATTRS is not set
|
||||
# CONFIG_SCSI_FC_ATTRS is not set
|
||||
# CONFIG_SCSI_ISCSI_ATTRS is not set
|
||||
# CONFIG_SCSI_SAS_ATTRS is not set
|
||||
|
||||
#
|
||||
# SCSI low-level drivers
|
||||
#
|
||||
# CONFIG_ISCSI_TCP is not set
|
||||
# CONFIG_SCSI_SATA is not set
|
||||
# CONFIG_SCSI_DEBUG is not set
|
||||
|
||||
@ -403,6 +429,11 @@ CONFIG_NETDEVICES=y
|
||||
# CONFIG_EQUALIZER is not set
|
||||
# CONFIG_TUN is not set
|
||||
|
||||
#
|
||||
# PHY device support
|
||||
#
|
||||
# CONFIG_PHYLIB is not set
|
||||
|
||||
#
|
||||
# Ethernet (10 or 100Mbit)
|
||||
#
|
||||
@ -439,6 +470,7 @@ CONFIG_PPP=y
|
||||
# CONFIG_PPP_SYNC_TTY is not set
|
||||
# CONFIG_PPP_DEFLATE is not set
|
||||
# CONFIG_PPP_BSDCOMP is not set
|
||||
# CONFIG_PPP_MPPE is not set
|
||||
# CONFIG_PPPOE is not set
|
||||
CONFIG_SLIP=y
|
||||
CONFIG_SLIP_COMPRESSED=y
|
||||
@ -541,24 +573,28 @@ CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
#
|
||||
# TPM devices
|
||||
#
|
||||
# CONFIG_TELCLOCK is not set
|
||||
|
||||
#
|
||||
# I2C support
|
||||
#
|
||||
# CONFIG_I2C is not set
|
||||
# CONFIG_I2C_SENSOR is not set
|
||||
CONFIG_ISP1301_OMAP=y
|
||||
|
||||
#
|
||||
# Hardware Monitoring support
|
||||
#
|
||||
CONFIG_HWMON=y
|
||||
# CONFIG_HWMON_VID is not set
|
||||
# CONFIG_HWMON_DEBUG_CHIP is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
|
||||
#
|
||||
# Multimedia Capabilities Port drivers
|
||||
#
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
@ -576,7 +612,6 @@ CONFIG_FB=y
|
||||
# CONFIG_FB_CFB_FILLRECT is not set
|
||||
# CONFIG_FB_CFB_COPYAREA is not set
|
||||
# CONFIG_FB_CFB_IMAGEBLIT is not set
|
||||
# CONFIG_FB_SOFT_CURSOR is not set
|
||||
# CONFIG_FB_MACMODES is not set
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
# CONFIG_FB_TILEBLITTING is not set
|
||||
@ -589,6 +624,7 @@ CONFIG_FB_MODE_HELPERS=y
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
|
||||
CONFIG_FONTS=y
|
||||
CONFIG_FONT_8x8=y
|
||||
CONFIG_FONT_8x16=y
|
||||
@ -600,6 +636,7 @@ CONFIG_FONT_8x16=y
|
||||
# CONFIG_FONT_SUN8x16 is not set
|
||||
# CONFIG_FONT_SUN12x22 is not set
|
||||
# CONFIG_FONT_10x18 is not set
|
||||
# CONFIG_FONT_RL is not set
|
||||
|
||||
#
|
||||
# Logo configuration
|
||||
@ -624,10 +661,10 @@ CONFIG_SOUND=y
|
||||
# Open Sound System
|
||||
#
|
||||
CONFIG_SOUND_PRIME=y
|
||||
# CONFIG_OBSOLETE_OSS_DRIVER is not set
|
||||
# CONFIG_SOUND_MSNDCLAS is not set
|
||||
# CONFIG_SOUND_MSNDPIN is not set
|
||||
# CONFIG_SOUND_OSS is not set
|
||||
# CONFIG_SOUND_AD1980 is not set
|
||||
|
||||
#
|
||||
# USB support
|
||||
@ -636,23 +673,22 @@ CONFIG_USB_ARCH_HAS_HCD=y
|
||||
CONFIG_USB_ARCH_HAS_OHCI=y
|
||||
# CONFIG_USB is not set
|
||||
|
||||
#
|
||||
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
|
||||
#
|
||||
|
||||
#
|
||||
# USB Gadget Support
|
||||
#
|
||||
CONFIG_USB_GADGET=y
|
||||
# CONFIG_USB_GADGET_DEBUG_FILES is not set
|
||||
CONFIG_USB_GADGET_SELECTED=y
|
||||
# CONFIG_USB_GADGET is not set
|
||||
# CONFIG_USB_GADGET_NET2280 is not set
|
||||
# CONFIG_USB_GADGET_PXA2XX is not set
|
||||
# CONFIG_USB_GADGET_GOKU is not set
|
||||
# CONFIG_USB_GADGET_LH7A40X is not set
|
||||
CONFIG_USB_GADGET_OMAP=y
|
||||
CONFIG_USB_OMAP=y
|
||||
# CONFIG_USB_GADGET_OMAP is not set
|
||||
# CONFIG_USB_GADGET_DUMMY_HCD is not set
|
||||
# CONFIG_USB_GADGET_DUALSPEED is not set
|
||||
# CONFIG_USB_ZERO is not set
|
||||
CONFIG_USB_ETH=y
|
||||
CONFIG_USB_ETH_RNDIS=y
|
||||
# CONFIG_USB_ETH is not set
|
||||
# CONFIG_USB_GADGETFS is not set
|
||||
# CONFIG_USB_FILE_STORAGE is not set
|
||||
# CONFIG_USB_G_SERIAL is not set
|
||||
@ -673,10 +709,6 @@ CONFIG_EXT2_FS=y
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_FS_POSIX_ACL is not set
|
||||
|
||||
#
|
||||
# XFS support
|
||||
#
|
||||
# CONFIG_XFS_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
CONFIG_ROMFS_FS=y
|
||||
@ -685,6 +717,7 @@ CONFIG_INOTIFY=y
|
||||
CONFIG_DNOTIFY=y
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
# CONFIG_FUSE_FS is not set
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
@ -706,10 +739,10 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437
|
||||
#
|
||||
CONFIG_PROC_FS=y
|
||||
CONFIG_SYSFS=y
|
||||
# CONFIG_DEVPTS_FS_XATTR is not set
|
||||
# CONFIG_TMPFS is not set
|
||||
# CONFIG_HUGETLB_PAGE is not set
|
||||
CONFIG_RAMFS=y
|
||||
# CONFIG_RELAYFS_FS is not set
|
||||
|
||||
#
|
||||
# Miscellaneous filesystems
|
||||
@ -750,6 +783,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
|
||||
# CONFIG_NCP_FS is not set
|
||||
# CONFIG_CODA_FS is not set
|
||||
# CONFIG_AFS_FS is not set
|
||||
# CONFIG_9P_FS is not set
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
@ -859,6 +893,7 @@ CONFIG_CRYPTO_DES=y
|
||||
# Library routines
|
||||
#
|
||||
# CONFIG_CRC_CCITT is not set
|
||||
# CONFIG_CRC16 is not set
|
||||
CONFIG_CRC32=y
|
||||
# CONFIG_LIBCRC32C is not set
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
|
@ -39,6 +39,7 @@ td3 .req lr
|
||||
|
||||
/* we must have at least one byte. */
|
||||
tst buf, #1 @ odd address?
|
||||
movne sum, sum, ror #8
|
||||
ldrneb td0, [buf], #1
|
||||
subne len, len, #1
|
||||
adcnes sum, sum, td0, put_byte_1
|
||||
@ -103,6 +104,9 @@ ENTRY(csum_partial)
|
||||
cmp len, #8 @ Ensure that we have at least
|
||||
blo .less8 @ 8 bytes to copy.
|
||||
|
||||
tst buf, #1
|
||||
movne sum, sum, ror #8
|
||||
|
||||
adds sum, sum, #0 @ C = 0
|
||||
tst buf, #3 @ Test destination alignment
|
||||
blne .not_aligned @ aligh destination, return here
|
||||
|
@ -8,6 +8,16 @@ menu "Intel IXP4xx Implementation Options"
|
||||
|
||||
comment "IXP4xx Platforms"
|
||||
|
||||
# This entry is placed on top because otherwise it would have
|
||||
# been shown as a submenu.
|
||||
config MACH_NSLU2
|
||||
bool
|
||||
prompt "NSLU2" if !(MACH_IXDP465 || MACH_IXDPG425 || ARCH_IXDP425 || ARCH_ADI_COYOTE || ARCH_AVILA || ARCH_IXCDP1100 || ARCH_PRPMC1100 || MACH_GTWX5715)
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support Linksys's
|
||||
NSLU2 NAS device. For more information on this platform,
|
||||
see http://www.nslu2-linux.org
|
||||
|
||||
config ARCH_AVILA
|
||||
bool "Avila"
|
||||
help
|
||||
|
@ -8,4 +8,5 @@ obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o
|
||||
obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o
|
||||
obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o
|
||||
obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o
|
||||
obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o
|
||||
|
||||
|
77
arch/arm/mach-ixp4xx/nslu2-pci.c
Normal file
77
arch/arm/mach-ixp4xx/nslu2-pci.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* arch/arm/mach-ixp4xx/nslu2-pci.c
|
||||
*
|
||||
* NSLU2 board-level PCI initialization
|
||||
*
|
||||
* based on ixdp425-pci.c:
|
||||
* Copyright (C) 2002 Intel Corporation.
|
||||
* Copyright (C) 2003-2004 MontaVista Software, Inc.
|
||||
*
|
||||
* Maintainer: http://www.nslu2-linux.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
void __init nslu2_pci_preinit(void)
|
||||
{
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTA, IRQT_LOW);
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW);
|
||||
set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW);
|
||||
|
||||
gpio_line_isr_clear(NSLU2_PCI_INTA_PIN);
|
||||
gpio_line_isr_clear(NSLU2_PCI_INTB_PIN);
|
||||
gpio_line_isr_clear(NSLU2_PCI_INTC_PIN);
|
||||
|
||||
/* INTD is not configured as GPIO is used
|
||||
* for the power input button.
|
||||
*/
|
||||
|
||||
ixp4xx_pci_preinit();
|
||||
}
|
||||
|
||||
static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||
{
|
||||
static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = {
|
||||
IRQ_NSLU2_PCI_INTA,
|
||||
IRQ_NSLU2_PCI_INTB,
|
||||
IRQ_NSLU2_PCI_INTC,
|
||||
};
|
||||
|
||||
int irq = -1;
|
||||
|
||||
if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV &&
|
||||
pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) {
|
||||
irq = pci_irq_table[(slot + pin - 2) % NSLU2_PCI_IRQ_LINES];
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
struct hw_pci __initdata nslu2_pci = {
|
||||
.nr_controllers = 1,
|
||||
.preinit = nslu2_pci_preinit,
|
||||
.swizzle = pci_std_swizzle,
|
||||
.setup = ixp4xx_setup,
|
||||
.scan = ixp4xx_scan_bus,
|
||||
.map_irq = nslu2_map_irq,
|
||||
};
|
||||
|
||||
int __init nslu2_pci_init(void) /* monkey see, monkey do */
|
||||
{
|
||||
if (machine_is_nslu2())
|
||||
pci_common_init(&nslu2_pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(nslu2_pci_init);
|
92
arch/arm/mach-ixp4xx/nslu2-power.c
Normal file
92
arch/arm/mach-ixp4xx/nslu2-power.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* arch/arm/mach-ixp4xx/nslu2-power.c
|
||||
*
|
||||
* NSLU2 Power/Reset driver
|
||||
*
|
||||
* Copyright (C) 2005 Tower Technologies
|
||||
*
|
||||
* based on nslu2-io.c
|
||||
* Copyright (C) 2004 Karen Spearel
|
||||
*
|
||||
* Author: Alessandro Zummo <a.zummo@towertech.it>
|
||||
* Maintainers: http://www.nslu2-linux.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
extern void ctrl_alt_del(void);
|
||||
|
||||
static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
/* Signal init to do the ctrlaltdel action, this will bypass init if
|
||||
* it hasn't started and do a kernel_restart.
|
||||
*/
|
||||
ctrl_alt_del();
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t nslu2_reset_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
/* This is the paper-clip reset, it shuts the machine down directly.
|
||||
*/
|
||||
machine_power_off();
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __init nslu2_power_init(void)
|
||||
{
|
||||
if (!(machine_is_nslu2()))
|
||||
return 0;
|
||||
|
||||
*IXP4XX_GPIO_GPISR = 0x20400000; /* read the 2 irqs to clr */
|
||||
|
||||
set_irq_type(NSLU2_RB_IRQ, IRQT_LOW);
|
||||
set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH);
|
||||
|
||||
gpio_line_isr_clear(NSLU2_RB_GPIO);
|
||||
gpio_line_isr_clear(NSLU2_PB_GPIO);
|
||||
|
||||
if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler,
|
||||
SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) {
|
||||
|
||||
printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
|
||||
NSLU2_RB_IRQ);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (request_irq(NSLU2_PB_IRQ, &nslu2_power_handler,
|
||||
SA_INTERRUPT, "NSLU2 power button", NULL) < 0) {
|
||||
|
||||
printk(KERN_DEBUG "Power Button IRQ %d not available\n",
|
||||
NSLU2_PB_IRQ);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit nslu2_power_exit(void)
|
||||
{
|
||||
free_irq(NSLU2_RB_IRQ, NULL);
|
||||
free_irq(NSLU2_PB_IRQ, NULL);
|
||||
}
|
||||
|
||||
module_init(nslu2_power_init);
|
||||
module_exit(nslu2_power_exit);
|
||||
|
||||
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
|
||||
MODULE_DESCRIPTION("NSLU2 Power/Reset driver");
|
||||
MODULE_LICENSE("GPL");
|
134
arch/arm/mach-ixp4xx/nslu2-setup.c
Normal file
134
arch/arm/mach-ixp4xx/nslu2-setup.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* arch/arm/mach-ixp4xx/nslu2-setup.c
|
||||
*
|
||||
* NSLU2 board-setup
|
||||
*
|
||||
* based ixdp425-setup.c:
|
||||
* Copyright (C) 2003-2004 MontaVista Software, Inc.
|
||||
*
|
||||
* Author: Mark Rakes <mrakes at mac.com>
|
||||
* Maintainers: http://www.nslu2-linux.org/
|
||||
*
|
||||
* Fixed missing init_time in MACHINE_START kas11 10/22/04
|
||||
* Changed to conform to new style __init ixdp425 kas11 10/22/04
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_8250.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
static struct flash_platform_data nslu2_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static struct resource nslu2_flash_resource = {
|
||||
.start = NSLU2_FLASH_BASE,
|
||||
.end = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device nslu2_flash = {
|
||||
.name = "IXP4XX-Flash",
|
||||
.id = 0,
|
||||
.dev.platform_data = &nslu2_flash_data,
|
||||
.num_resources = 1,
|
||||
.resource = &nslu2_flash_resource,
|
||||
};
|
||||
|
||||
static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
|
||||
.sda_pin = NSLU2_SDA_PIN,
|
||||
.scl_pin = NSLU2_SCL_PIN,
|
||||
};
|
||||
|
||||
static struct platform_device nslu2_i2c_controller = {
|
||||
.name = "IXP4XX-I2C",
|
||||
.id = 0,
|
||||
.dev.platform_data = &nslu2_i2c_gpio_pins,
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
static struct resource nslu2_uart_resources[] = {
|
||||
{
|
||||
.start = IXP4XX_UART1_BASE_PHYS,
|
||||
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = IXP4XX_UART2_BASE_PHYS,
|
||||
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
}
|
||||
};
|
||||
|
||||
static struct plat_serial8250_port nslu2_uart_data[] = {
|
||||
{
|
||||
.mapbase = IXP4XX_UART1_BASE_PHYS,
|
||||
.membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
|
||||
.irq = IRQ_IXP4XX_UART1,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = IXP4XX_UART_XTAL,
|
||||
},
|
||||
{
|
||||
.mapbase = IXP4XX_UART2_BASE_PHYS,
|
||||
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
|
||||
.irq = IRQ_IXP4XX_UART2,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = IXP4XX_UART_XTAL,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_device nslu2_uart = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev.platform_data = nslu2_uart_data,
|
||||
.num_resources = 2,
|
||||
.resource = nslu2_uart_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *nslu2_devices[] __initdata = {
|
||||
&nslu2_i2c_controller,
|
||||
&nslu2_flash,
|
||||
&nslu2_uart,
|
||||
};
|
||||
|
||||
static void nslu2_power_off(void)
|
||||
{
|
||||
/* This causes the box to drop the power and go dead. */
|
||||
|
||||
/* enable the pwr cntl gpio */
|
||||
gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT);
|
||||
|
||||
/* do the deed */
|
||||
gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
|
||||
}
|
||||
|
||||
static void __init nslu2_init(void)
|
||||
{
|
||||
ixp4xx_sys_init();
|
||||
|
||||
pm_power_off = nslu2_power_off;
|
||||
|
||||
platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
|
||||
}
|
||||
|
||||
MACHINE_START(NSLU2, "Linksys NSLU2")
|
||||
/* Maintainer: www.nslu2-linux.org */
|
||||
.phys_ram = PHYS_OFFSET,
|
||||
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
|
||||
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
|
||||
.boot_params = 0x00000100,
|
||||
.map_io = ixp4xx_map_io,
|
||||
.init_irq = ixp4xx_init_irq,
|
||||
.timer = &ixp4xx_timer,
|
||||
.init_machine = nslu2_init,
|
||||
MACHINE_END
|
@ -6,10 +6,10 @@ config ARCH_OMAP730
|
||||
bool "OMAP730 Based System"
|
||||
select ARCH_OMAP_OTG
|
||||
|
||||
config ARCH_OMAP1510
|
||||
config ARCH_OMAP15XX
|
||||
depends on ARCH_OMAP1
|
||||
default y
|
||||
bool "OMAP1510 Based System"
|
||||
bool "OMAP15xx Based System"
|
||||
|
||||
config ARCH_OMAP16XX
|
||||
depends on ARCH_OMAP1
|
||||
@ -21,7 +21,7 @@ comment "OMAP Board Type"
|
||||
|
||||
config MACH_OMAP_INNOVATOR
|
||||
bool "TI Innovator"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX)
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
|
||||
help
|
||||
TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
|
||||
have such a board.
|
||||
@ -64,20 +64,30 @@ config MACH_OMAP_PERSEUS2
|
||||
|
||||
config MACH_VOICEBLUE
|
||||
bool "Voiceblue"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP1510
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
help
|
||||
Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
|
||||
such a board.
|
||||
|
||||
config MACH_NETSTAR
|
||||
bool "NetStar"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP1510
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
help
|
||||
Support for NetStar PBX. Say Y here if you have such a board.
|
||||
|
||||
config MACH_OMAP_PALMTE
|
||||
bool "Palm Tungsten E"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
help
|
||||
Support for the Palm Tungsten E PDA. Currently only the LCD panel
|
||||
is supported. To boot the kernel, you'll need a PalmOS compatible
|
||||
bootloader; check out http://palmtelinux.sourceforge.net for more
|
||||
informations.
|
||||
Say Y here if you have such a PDA, say NO otherwise.
|
||||
|
||||
config MACH_OMAP_GENERIC
|
||||
bool "Generic OMAP board"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX)
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
|
||||
help
|
||||
Support for generic OMAP-1510, 1610 or 1710 board with
|
||||
no FPGA. Can be used as template for porting Linux to
|
||||
@ -121,32 +131,32 @@ config OMAP_ARM_182MHZ
|
||||
|
||||
config OMAP_ARM_168MHZ
|
||||
bool "OMAP ARM 168 MHz CPU"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
|
||||
help
|
||||
Enable 168MHz clock for OMAP CPU. If unsure, say N.
|
||||
|
||||
config OMAP_ARM_150MHZ
|
||||
bool "OMAP ARM 150 MHz CPU"
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP1510
|
||||
depends on ARCH_OMAP1 && ARCH_OMAP15XX
|
||||
help
|
||||
Enable 150MHz clock for OMAP CPU. If unsure, say N.
|
||||
|
||||
config OMAP_ARM_120MHZ
|
||||
bool "OMAP ARM 120 MHz CPU"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
|
||||
help
|
||||
Enable 120MHz clock for OMAP CPU. If unsure, say N.
|
||||
|
||||
config OMAP_ARM_60MHZ
|
||||
bool "OMAP ARM 60 MHz CPU"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
|
||||
default y
|
||||
help
|
||||
Enable 60MHz clock for OMAP CPU. If unsure, say Y.
|
||||
|
||||
config OMAP_ARM_30MHZ
|
||||
bool "OMAP ARM 30 MHz CPU"
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
|
||||
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
|
||||
help
|
||||
Enable 30MHz clock for OMAP CPU. If unsure, say N.
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
# Common support
|
||||
obj-y := io.o id.o irq.o time.o serial.o devices.o
|
||||
obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o
|
||||
led-y := leds.o
|
||||
|
||||
# Specific board support
|
||||
@ -15,8 +15,9 @@ obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
|
||||
obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
|
||||
obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
|
||||
obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o
|
||||
obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
|
||||
|
||||
ifeq ($(CONFIG_ARCH_OMAP1510),y)
|
||||
ifeq ($(CONFIG_ARCH_OMAP15XX),y)
|
||||
# Innovator-1510 FPGA
|
||||
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o
|
||||
endif
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -28,8 +28,6 @@
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
|
||||
|
||||
static void __init omap_generic_init_irq(void)
|
||||
{
|
||||
omap_init_irq();
|
||||
@ -37,7 +35,7 @@ static void __init omap_generic_init_irq(void)
|
||||
|
||||
/* assume no Mini-AB port */
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
static struct omap_usb_config generic1510_usb_config __initdata = {
|
||||
.register_host = 1,
|
||||
.register_dev = 1,
|
||||
@ -76,21 +74,19 @@ static struct omap_mmc_config generic_mmc_config __initdata = {
|
||||
|
||||
#endif
|
||||
|
||||
static struct omap_uart_config generic_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel generic_config[] = {
|
||||
{ OMAP_TAG_USB, NULL },
|
||||
{ OMAP_TAG_MMC, &generic_mmc_config },
|
||||
{ OMAP_TAG_UART, &generic_uart_config },
|
||||
};
|
||||
|
||||
static void __init omap_generic_init(void)
|
||||
{
|
||||
const struct omap_uart_config *uart_conf;
|
||||
|
||||
/*
|
||||
* Make sure the serial ports are muxed on at this point.
|
||||
* You have to mux them off in device drivers later on
|
||||
* if not needed.
|
||||
*/
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
generic_config[0].data = &generic1510_usb_config;
|
||||
}
|
||||
@ -101,20 +97,9 @@ static void __init omap_generic_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
uart_conf = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
|
||||
if (uart_conf != NULL) {
|
||||
unsigned int enabled_ports, i;
|
||||
|
||||
enabled_ports = uart_conf->enabled_uarts;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!(enabled_ports & (1 << i)))
|
||||
generic_serial_ports[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
omap_board_config = generic_config;
|
||||
omap_board_config_size = ARRAY_SIZE(generic_config);
|
||||
omap_serial_init(generic_serial_ports);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init omap_generic_map_io(void)
|
||||
|
@ -40,8 +40,6 @@
|
||||
|
||||
extern int omap_gpio_init(void);
|
||||
|
||||
static int __initdata h2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
|
||||
|
||||
static struct mtd_partition h2_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -160,9 +158,20 @@ static struct omap_mmc_config h2_mmc_config __initdata = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_uart_config h2_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h2_lcd_config __initdata = {
|
||||
.panel_name = "h2",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel h2_config[] = {
|
||||
{ OMAP_TAG_USB, &h2_usb_config },
|
||||
{ OMAP_TAG_MMC, &h2_mmc_config },
|
||||
{ OMAP_TAG_UART, &h2_uart_config },
|
||||
{ OMAP_TAG_LCD, &h2_lcd_config },
|
||||
};
|
||||
|
||||
static void __init h2_init(void)
|
||||
@ -180,12 +189,12 @@ static void __init h2_init(void)
|
||||
platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
|
||||
omap_board_config = h2_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h2_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init h2_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
omap_serial_init(h2_serial_ports);
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_H2, "TI-H2")
|
||||
|
@ -41,8 +41,6 @@
|
||||
|
||||
extern int omap_gpio_init(void);
|
||||
|
||||
static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
|
||||
|
||||
static struct mtd_partition h3_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -168,9 +166,20 @@ static struct omap_mmc_config h3_mmc_config __initdata = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_uart_config h3_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h3_lcd_config __initdata = {
|
||||
.panel_name = "h3",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel h3_config[] = {
|
||||
{ OMAP_TAG_USB, &h3_usb_config },
|
||||
{ OMAP_TAG_MMC, &h3_mmc_config },
|
||||
{ OMAP_TAG_USB, &h3_usb_config },
|
||||
{ OMAP_TAG_MMC, &h3_mmc_config },
|
||||
{ OMAP_TAG_UART, &h3_uart_config },
|
||||
{ OMAP_TAG_LCD, &h3_lcd_config },
|
||||
};
|
||||
|
||||
static void __init h3_init(void)
|
||||
@ -180,6 +189,7 @@ static void __init h3_init(void)
|
||||
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
omap_board_config = h3_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h3_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init h3_init_smc91x(void)
|
||||
@ -201,7 +211,6 @@ void h3_init_irq(void)
|
||||
static void __init h3_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
omap_serial_init(h3_serial_ports);
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
|
||||
|
@ -36,8 +36,6 @@
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
|
||||
|
||||
static struct mtd_partition innovator_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -99,7 +97,7 @@ static struct platform_device innovator_flash_device = {
|
||||
.resource = &innovator_flash_resource,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
|
||||
/* Only FPGA needs to be mapped here. All others are done with ioremap */
|
||||
static struct map_desc innovator1510_io_desc[] __initdata = {
|
||||
@ -136,7 +134,7 @@ static struct platform_device *innovator1510_devices[] __initdata = {
|
||||
&innovator1510_smc91x_device,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP1510 */
|
||||
#endif /* CONFIG_ARCH_OMAP15XX */
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
|
||||
@ -185,7 +183,7 @@ void innovator_init_irq(void)
|
||||
{
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
omap1510_fpga_init_irq();
|
||||
}
|
||||
@ -193,7 +191,7 @@ void innovator_init_irq(void)
|
||||
innovator_init_smc91x();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
static struct omap_usb_config innovator1510_usb_config __initdata = {
|
||||
/* for bundled non-standard host and peripheral cables */
|
||||
.hmc_mode = 4,
|
||||
@ -205,6 +203,11 @@ static struct omap_usb_config innovator1510_usb_config __initdata = {
|
||||
.register_dev = 1,
|
||||
.pins[0] = 2,
|
||||
};
|
||||
|
||||
static struct omap_lcd_config innovator1510_lcd_config __initdata = {
|
||||
.panel_name = "inn1510",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
@ -222,6 +225,11 @@ static struct omap_usb_config h2_usb_config __initdata = {
|
||||
|
||||
.pins[1] = 3,
|
||||
};
|
||||
|
||||
static struct omap_lcd_config innovator1610_lcd_config __initdata = {
|
||||
.panel_name = "inn1610",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct omap_mmc_config innovator_mmc_config __initdata = {
|
||||
@ -234,14 +242,20 @@ static struct omap_mmc_config innovator_mmc_config __initdata = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_uart_config innovator_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel innovator_config[] = {
|
||||
{ OMAP_TAG_USB, NULL },
|
||||
{ OMAP_TAG_LCD, NULL },
|
||||
{ OMAP_TAG_MMC, &innovator_mmc_config },
|
||||
{ OMAP_TAG_UART, &innovator_uart_config },
|
||||
};
|
||||
|
||||
static void __init innovator_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
|
||||
}
|
||||
@ -252,23 +266,28 @@ static void __init innovator_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
if (cpu_is_omap1510())
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
innovator_config[0].data = &innovator1510_usb_config;
|
||||
innovator_config[1].data = &innovator1510_lcd_config;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
if (cpu_is_omap1610())
|
||||
if (cpu_is_omap1610()) {
|
||||
innovator_config[0].data = &h2_usb_config;
|
||||
innovator_config[1].data = &innovator1610_lcd_config;
|
||||
}
|
||||
#endif
|
||||
omap_board_config = innovator_config;
|
||||
omap_board_config_size = ARRAY_SIZE(innovator_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init innovator_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
|
||||
udelay(10); /* Delay needed for FPGA */
|
||||
@ -280,7 +299,6 @@ static void __init innovator_map_io(void)
|
||||
fpga_read(OMAP1510_FPGA_BOARD_REV));
|
||||
}
|
||||
#endif
|
||||
omap_serial_init(innovator_serial_ports);
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
|
||||
|
@ -55,6 +55,14 @@ static struct platform_device *netstar_devices[] __initdata = {
|
||||
&netstar_smc91x_device,
|
||||
};
|
||||
|
||||
static struct omap_uart_config netstar_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel netstar_config[] = {
|
||||
{ OMAP_TAG_UART, &netstar_uart_config },
|
||||
};
|
||||
|
||||
static void __init netstar_init_irq(void)
|
||||
{
|
||||
omap_init_irq();
|
||||
@ -92,14 +100,15 @@ static void __init netstar_init(void)
|
||||
/* Switch off red LED */
|
||||
omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
|
||||
omap_writeb(0x80, OMAP_LPG1_LCR);
|
||||
}
|
||||
|
||||
static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
|
||||
omap_board_config = netstar_config;
|
||||
omap_board_config_size = ARRAY_SIZE(netstar_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init netstar_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
omap_serial_init(omap_serial_ports);
|
||||
}
|
||||
|
||||
#define MACHINE_PANICED 1
|
||||
|
@ -46,8 +46,6 @@
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
|
||||
|
||||
static struct mtd_partition osk_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -155,7 +153,7 @@ static void __init osk_init_smc91x(void)
|
||||
}
|
||||
|
||||
/* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
|
||||
EMIFS_CCS(1) |= 0x2;
|
||||
EMIFS_CCS(1) |= 0x3;
|
||||
}
|
||||
|
||||
static void __init osk_init_cf(void)
|
||||
@ -193,8 +191,19 @@ static struct omap_usb_config osk_usb_config __initdata = {
|
||||
.pins[0] = 2,
|
||||
};
|
||||
|
||||
static struct omap_uart_config osk_uart_config __initdata = {
|
||||
.enabled_uarts = (1 << 0),
|
||||
};
|
||||
|
||||
static struct omap_lcd_config osk_lcd_config __initdata = {
|
||||
.panel_name = "osk",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel osk_config[] = {
|
||||
{ OMAP_TAG_USB, &osk_usb_config },
|
||||
{ OMAP_TAG_UART, &osk_uart_config },
|
||||
{ OMAP_TAG_LCD, &osk_lcd_config },
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OMAP_OSK_MISTRAL
|
||||
@ -254,13 +263,13 @@ static void __init osk_init(void)
|
||||
omap_board_config_size = ARRAY_SIZE(osk_config);
|
||||
USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
|
||||
|
||||
omap_serial_init();
|
||||
osk_mistral_init();
|
||||
}
|
||||
|
||||
static void __init osk_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
omap_serial_init(osk_serial_ports);
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_OSK, "TI-OSK")
|
||||
|
87
arch/arm/mach-omap1/board-palmte.c
Normal file
87
arch/arm/mach-omap1/board-palmte.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/board-palmte.c
|
||||
*
|
||||
* Modified from board-generic.c
|
||||
*
|
||||
* Support for the Palm Tungsten E PDA.
|
||||
*
|
||||
* Original version : Laurent Gonzalez
|
||||
*
|
||||
* Maintainters : http://palmtelinux.sf.net
|
||||
* palmtelinux-developpers@lists.sf.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/hardware/clock.h>
|
||||
|
||||
static void __init omap_generic_init_irq(void)
|
||||
{
|
||||
omap_init_irq();
|
||||
}
|
||||
|
||||
static struct omap_usb_config palmte_usb_config __initdata = {
|
||||
.register_dev = 1,
|
||||
.hmc_mode = 0,
|
||||
.pins[0] = 3,
|
||||
};
|
||||
|
||||
static struct omap_mmc_config palmte_mmc_config __initdata = {
|
||||
.mmc [0] = {
|
||||
.enabled = 1,
|
||||
.wire4 = 1,
|
||||
.wp_pin = OMAP_MPUIO(3),
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_lcd_config palmte_lcd_config __initdata = {
|
||||
.panel_name = "palmte",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel palmte_config[] = {
|
||||
{ OMAP_TAG_USB, &palmte_usb_config },
|
||||
{ OMAP_TAG_MMC, &palmte_mmc_config },
|
||||
{ OMAP_TAG_LCD, &palmte_lcd_config },
|
||||
};
|
||||
|
||||
static void __init omap_generic_init(void)
|
||||
{
|
||||
omap_board_config = palmte_config;
|
||||
omap_board_config_size = ARRAY_SIZE(palmte_config);
|
||||
}
|
||||
|
||||
static void __init omap_generic_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
|
||||
.phys_ram = 0x10000000,
|
||||
.phys_io = 0xfff00000,
|
||||
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x10000100,
|
||||
.map_io = omap_generic_map_io,
|
||||
.init_irq = omap_generic_init_irq,
|
||||
.init_machine = omap_generic_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
@ -29,6 +29,7 @@
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/fpga.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/board.h>
|
||||
|
||||
static struct resource smc91x_resources[] = {
|
||||
[0] = {
|
||||
@ -43,8 +44,6 @@ static struct resource smc91x_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __initdata p2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 0};
|
||||
|
||||
static struct mtd_partition p2_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
@ -111,9 +110,27 @@ static struct platform_device *devices[] __initdata = {
|
||||
&smc91x_device,
|
||||
};
|
||||
|
||||
static struct omap_uart_config perseus2_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1)),
|
||||
};
|
||||
|
||||
static struct omap_lcd_config perseus2_lcd_config __initdata = {
|
||||
.panel_name = "p2",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel perseus2_config[] = {
|
||||
{ OMAP_TAG_UART, &perseus2_uart_config },
|
||||
{ OMAP_TAG_LCD, &perseus2_lcd_config },
|
||||
};
|
||||
|
||||
static void __init omap_perseus2_init(void)
|
||||
{
|
||||
(void) platform_add_devices(devices, ARRAY_SIZE(devices));
|
||||
|
||||
omap_board_config = perseus2_config;
|
||||
omap_board_config_size = ARRAY_SIZE(perseus2_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init perseus2_init_smc91x(void)
|
||||
@ -131,7 +148,6 @@ void omap_perseus2_init_irq(void)
|
||||
omap_gpio_init();
|
||||
perseus2_init_smc91x();
|
||||
}
|
||||
|
||||
/* Only FPGA needs to be mapped here. All others are done with ioremap */
|
||||
static struct map_desc omap_perseus2_io_desc[] __initdata = {
|
||||
{
|
||||
@ -179,7 +195,6 @@ static void __init omap_perseus2_map_io(void)
|
||||
* It is used as the Ethernet controller interrupt
|
||||
*/
|
||||
omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
|
||||
omap_serial_init(p2_serial_ports);
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
|
||||
|
@ -150,9 +150,14 @@ static struct omap_mmc_config voiceblue_mmc_config __initdata = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_uart_config voiceblue_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel voiceblue_config[] = {
|
||||
{ OMAP_TAG_USB, &voiceblue_usb_config },
|
||||
{ OMAP_TAG_MMC, &voiceblue_mmc_config },
|
||||
{ OMAP_TAG_UART, &voiceblue_uart_config },
|
||||
};
|
||||
|
||||
static void __init voiceblue_init_irq(void)
|
||||
@ -191,6 +196,7 @@ static void __init voiceblue_init(void)
|
||||
platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
|
||||
omap_board_config = voiceblue_config;
|
||||
omap_board_config_size = ARRAY_SIZE(voiceblue_config);
|
||||
omap_serial_init();
|
||||
|
||||
/* There is a good chance board is going up, so enable power LED
|
||||
* (it is connected through invertor) */
|
||||
@ -198,12 +204,9 @@ static void __init voiceblue_init(void)
|
||||
omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
|
||||
}
|
||||
|
||||
static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
|
||||
|
||||
static void __init voiceblue_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
omap_serial_init(omap_serial_ports);
|
||||
}
|
||||
|
||||
#define MACHINE_PANICED 1
|
||||
|
792
arch/arm/mach-omap1/clock.c
Normal file
792
arch/arm/mach-omap1/clock.c
Normal file
@ -0,0 +1,792 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/clock.c
|
||||
*
|
||||
* Copyright (C) 2004 - 2005 Nokia corporation
|
||||
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
*
|
||||
* Modified to use omap shared clock framework by
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/hardware/clock.h>
|
||||
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
__u32 arm_idlect1_mask;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Omap1 specific clock functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
static void omap1_watchdog_recalc(struct clk * clk)
|
||||
{
|
||||
clk->rate = clk->parent->rate / 14;
|
||||
}
|
||||
|
||||
static void omap1_uart_recalc(struct clk * clk)
|
||||
{
|
||||
unsigned int val = omap_readl(clk->enable_reg);
|
||||
if (val & clk->enable_bit)
|
||||
clk->rate = 48000000;
|
||||
else
|
||||
clk->rate = 12000000;
|
||||
}
|
||||
|
||||
static int omap1_clk_enable_dsp_domain(struct clk *clk)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = omap1_clk_use(&api_ck.clk);
|
||||
if (!retval) {
|
||||
retval = omap1_clk_enable(clk);
|
||||
omap1_clk_unuse(&api_ck.clk);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void omap1_clk_disable_dsp_domain(struct clk *clk)
|
||||
{
|
||||
if (omap1_clk_use(&api_ck.clk) == 0) {
|
||||
omap1_clk_disable(clk);
|
||||
omap1_clk_unuse(&api_ck.clk);
|
||||
}
|
||||
}
|
||||
|
||||
static int omap1_clk_enable_uart_functional(struct clk *clk)
|
||||
{
|
||||
int ret;
|
||||
struct uart_clk *uclk;
|
||||
|
||||
ret = omap1_clk_enable(clk);
|
||||
if (ret == 0) {
|
||||
/* Set smart idle acknowledgement mode */
|
||||
uclk = (struct uart_clk *)clk;
|
||||
omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
|
||||
uclk->sysc_addr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void omap1_clk_disable_uart_functional(struct clk *clk)
|
||||
{
|
||||
struct uart_clk *uclk;
|
||||
|
||||
/* Set force idle acknowledgement mode */
|
||||
uclk = (struct uart_clk *)clk;
|
||||
omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
|
||||
|
||||
omap1_clk_disable(clk);
|
||||
}
|
||||
|
||||
static void omap1_clk_allow_idle(struct clk *clk)
|
||||
{
|
||||
struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
|
||||
|
||||
if (!(clk->flags & CLOCK_IDLE_CONTROL))
|
||||
return;
|
||||
|
||||
if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count))
|
||||
arm_idlect1_mask |= 1 << iclk->idlect_shift;
|
||||
}
|
||||
|
||||
static void omap1_clk_deny_idle(struct clk *clk)
|
||||
{
|
||||
struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
|
||||
|
||||
if (!(clk->flags & CLOCK_IDLE_CONTROL))
|
||||
return;
|
||||
|
||||
if (iclk->no_idle_count++ == 0)
|
||||
arm_idlect1_mask &= ~(1 << iclk->idlect_shift);
|
||||
}
|
||||
|
||||
static __u16 verify_ckctl_value(__u16 newval)
|
||||
{
|
||||
/* This function checks for following limitations set
|
||||
* by the hardware (all conditions must be true):
|
||||
* DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
|
||||
* ARM_CK >= TC_CK
|
||||
* DSP_CK >= TC_CK
|
||||
* DSPMMU_CK >= TC_CK
|
||||
*
|
||||
* In addition following rules are enforced:
|
||||
* LCD_CK <= TC_CK
|
||||
* ARMPER_CK <= TC_CK
|
||||
*
|
||||
* However, maximum frequencies are not checked for!
|
||||
*/
|
||||
__u8 per_exp;
|
||||
__u8 lcd_exp;
|
||||
__u8 arm_exp;
|
||||
__u8 dsp_exp;
|
||||
__u8 tc_exp;
|
||||
__u8 dspmmu_exp;
|
||||
|
||||
per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
|
||||
lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
|
||||
arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
|
||||
dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
|
||||
tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
|
||||
dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
|
||||
|
||||
if (dspmmu_exp < dsp_exp)
|
||||
dspmmu_exp = dsp_exp;
|
||||
if (dspmmu_exp > dsp_exp+1)
|
||||
dspmmu_exp = dsp_exp+1;
|
||||
if (tc_exp < arm_exp)
|
||||
tc_exp = arm_exp;
|
||||
if (tc_exp < dspmmu_exp)
|
||||
tc_exp = dspmmu_exp;
|
||||
if (tc_exp > lcd_exp)
|
||||
lcd_exp = tc_exp;
|
||||
if (tc_exp > per_exp)
|
||||
per_exp = tc_exp;
|
||||
|
||||
newval &= 0xf000;
|
||||
newval |= per_exp << CKCTL_PERDIV_OFFSET;
|
||||
newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
|
||||
newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
|
||||
newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
|
||||
newval |= tc_exp << CKCTL_TCDIV_OFFSET;
|
||||
newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
|
||||
|
||||
return newval;
|
||||
}
|
||||
|
||||
static int calc_dsor_exp(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
/* Note: If target frequency is too low, this function will return 4,
|
||||
* which is invalid value. Caller must check for this value and act
|
||||
* accordingly.
|
||||
*
|
||||
* Note: This function does not check for following limitations set
|
||||
* by the hardware (all conditions must be true):
|
||||
* DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
|
||||
* ARM_CK >= TC_CK
|
||||
* DSP_CK >= TC_CK
|
||||
* DSPMMU_CK >= TC_CK
|
||||
*/
|
||||
unsigned long realrate;
|
||||
struct clk * parent;
|
||||
unsigned dsor_exp;
|
||||
|
||||
if (unlikely(!(clk->flags & RATE_CKCTL)))
|
||||
return -EINVAL;
|
||||
|
||||
parent = clk->parent;
|
||||
if (unlikely(parent == 0))
|
||||
return -EIO;
|
||||
|
||||
realrate = parent->rate;
|
||||
for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
|
||||
if (realrate <= rate)
|
||||
break;
|
||||
|
||||
realrate /= 2;
|
||||
}
|
||||
|
||||
return dsor_exp;
|
||||
}
|
||||
|
||||
static void omap1_ckctl_recalc(struct clk * clk)
|
||||
{
|
||||
int dsor;
|
||||
|
||||
/* Calculate divisor encoded as 2-bit exponent */
|
||||
dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
|
||||
|
||||
if (unlikely(clk->rate == clk->parent->rate / dsor))
|
||||
return; /* No change, quick exit */
|
||||
clk->rate = clk->parent->rate / dsor;
|
||||
|
||||
if (unlikely(clk->flags & RATE_PROPAGATES))
|
||||
propagate_rate(clk);
|
||||
}
|
||||
|
||||
static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
|
||||
{
|
||||
int dsor;
|
||||
|
||||
/* Calculate divisor encoded as 2-bit exponent
|
||||
*
|
||||
* The clock control bits are in DSP domain,
|
||||
* so api_ck is needed for access.
|
||||
* Note that DSP_CKCTL virt addr = phys addr, so
|
||||
* we must use __raw_readw() instead of omap_readw().
|
||||
*/
|
||||
omap1_clk_use(&api_ck.clk);
|
||||
dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
|
||||
omap1_clk_unuse(&api_ck.clk);
|
||||
|
||||
if (unlikely(clk->rate == clk->parent->rate / dsor))
|
||||
return; /* No change, quick exit */
|
||||
clk->rate = clk->parent->rate / dsor;
|
||||
|
||||
if (unlikely(clk->flags & RATE_PROPAGATES))
|
||||
propagate_rate(clk);
|
||||
}
|
||||
|
||||
/* MPU virtual clock functions */
|
||||
static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
|
||||
{
|
||||
/* Find the highest supported frequency <= rate and switch to it */
|
||||
struct mpu_rate * ptr;
|
||||
|
||||
if (clk != &virtual_ck_mpu)
|
||||
return -EINVAL;
|
||||
|
||||
for (ptr = rate_table; ptr->rate; ptr++) {
|
||||
if (ptr->xtal != ck_ref.rate)
|
||||
continue;
|
||||
|
||||
/* DPLL1 cannot be reprogrammed without risking system crash */
|
||||
if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
|
||||
continue;
|
||||
|
||||
/* Can check only after xtal frequency check */
|
||||
if (ptr->rate <= rate)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ptr->rate)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* In most cases we should not need to reprogram DPLL.
|
||||
* Reprogramming the DPLL is tricky, it must be done from SRAM.
|
||||
*/
|
||||
omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
|
||||
|
||||
ck_dpll1.rate = ptr->pll_rate;
|
||||
propagate_rate(&ck_dpll1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
int dsor_exp;
|
||||
__u16 regval;
|
||||
|
||||
if (clk->flags & RATE_CKCTL) {
|
||||
dsor_exp = calc_dsor_exp(clk, rate);
|
||||
if (dsor_exp > 3)
|
||||
dsor_exp = -EINVAL;
|
||||
if (dsor_exp < 0)
|
||||
return dsor_exp;
|
||||
|
||||
regval = __raw_readw(DSP_CKCTL);
|
||||
regval &= ~(3 << clk->rate_offset);
|
||||
regval |= dsor_exp << clk->rate_offset;
|
||||
__raw_writew(regval, DSP_CKCTL);
|
||||
clk->rate = clk->parent->rate / (1 << dsor_exp);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
|
||||
propagate_rate(clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
|
||||
{
|
||||
/* Find the highest supported frequency <= rate */
|
||||
struct mpu_rate * ptr;
|
||||
long highest_rate;
|
||||
|
||||
if (clk != &virtual_ck_mpu)
|
||||
return -EINVAL;
|
||||
|
||||
highest_rate = -EINVAL;
|
||||
|
||||
for (ptr = rate_table; ptr->rate; ptr++) {
|
||||
if (ptr->xtal != ck_ref.rate)
|
||||
continue;
|
||||
|
||||
highest_rate = ptr->rate;
|
||||
|
||||
/* Can check only after xtal frequency check */
|
||||
if (ptr->rate <= rate)
|
||||
break;
|
||||
}
|
||||
|
||||
return highest_rate;
|
||||
}
|
||||
|
||||
static unsigned calc_ext_dsor(unsigned long rate)
|
||||
{
|
||||
unsigned dsor;
|
||||
|
||||
/* MCLK and BCLK divisor selection is not linear:
|
||||
* freq = 96MHz / dsor
|
||||
*
|
||||
* RATIO_SEL range: dsor <-> RATIO_SEL
|
||||
* 0..6: (RATIO_SEL+2) <-> (dsor-2)
|
||||
* 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
|
||||
* Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
|
||||
* can not be used.
|
||||
*/
|
||||
for (dsor = 2; dsor < 96; ++dsor) {
|
||||
if ((dsor & 1) && dsor > 8)
|
||||
continue;
|
||||
if (rate >= 96000000 / dsor)
|
||||
break;
|
||||
}
|
||||
return dsor;
|
||||
}
|
||||
|
||||
/* Only needed on 1510 */
|
||||
static int omap1_set_uart_rate(struct clk * clk, unsigned long rate)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = omap_readl(clk->enable_reg);
|
||||
if (rate == 12000000)
|
||||
val &= ~(1 << clk->enable_bit);
|
||||
else if (rate == 48000000)
|
||||
val |= (1 << clk->enable_bit);
|
||||
else
|
||||
return -EINVAL;
|
||||
omap_writel(val, clk->enable_reg);
|
||||
clk->rate = rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* External clock (MCLK & BCLK) functions */
|
||||
static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate)
|
||||
{
|
||||
unsigned dsor;
|
||||
__u16 ratio_bits;
|
||||
|
||||
dsor = calc_ext_dsor(rate);
|
||||
clk->rate = 96000000 / dsor;
|
||||
if (dsor > 8)
|
||||
ratio_bits = ((dsor - 8) / 2 + 6) << 2;
|
||||
else
|
||||
ratio_bits = (dsor - 2) << 2;
|
||||
|
||||
ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
|
||||
omap_writew(ratio_bits, clk->enable_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate)
|
||||
{
|
||||
return 96000000 / calc_ext_dsor(rate);
|
||||
}
|
||||
|
||||
static void omap1_init_ext_clk(struct clk * clk)
|
||||
{
|
||||
unsigned dsor;
|
||||
__u16 ratio_bits;
|
||||
|
||||
/* Determine current rate and ensure clock is based on 96MHz APLL */
|
||||
ratio_bits = omap_readw(clk->enable_reg) & ~1;
|
||||
omap_writew(ratio_bits, clk->enable_reg);
|
||||
|
||||
ratio_bits = (ratio_bits & 0xfc) >> 2;
|
||||
if (ratio_bits > 6)
|
||||
dsor = (ratio_bits - 6) * 2 + 8;
|
||||
else
|
||||
dsor = ratio_bits + 2;
|
||||
|
||||
clk-> rate = 96000000 / dsor;
|
||||
}
|
||||
|
||||
static int omap1_clk_use(struct clk *clk)
|
||||
{
|
||||
int ret = 0;
|
||||
if (clk->usecount++ == 0) {
|
||||
if (likely(clk->parent)) {
|
||||
ret = omap1_clk_use(clk->parent);
|
||||
|
||||
if (unlikely(ret != 0)) {
|
||||
clk->usecount--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (clk->flags & CLOCK_NO_IDLE_PARENT)
|
||||
if (!cpu_is_omap24xx())
|
||||
omap1_clk_deny_idle(clk->parent);
|
||||
}
|
||||
|
||||
ret = clk->enable(clk);
|
||||
|
||||
if (unlikely(ret != 0) && clk->parent) {
|
||||
omap1_clk_unuse(clk->parent);
|
||||
clk->usecount--;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void omap1_clk_unuse(struct clk *clk)
|
||||
{
|
||||
if (clk->usecount > 0 && !(--clk->usecount)) {
|
||||
clk->disable(clk);
|
||||
if (likely(clk->parent)) {
|
||||
omap1_clk_unuse(clk->parent);
|
||||
if (clk->flags & CLOCK_NO_IDLE_PARENT)
|
||||
if (!cpu_is_omap24xx())
|
||||
omap1_clk_allow_idle(clk->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int omap1_clk_enable(struct clk *clk)
|
||||
{
|
||||
__u16 regval16;
|
||||
__u32 regval32;
|
||||
|
||||
if (clk->flags & ALWAYS_ENABLED)
|
||||
return 0;
|
||||
|
||||
if (unlikely(clk->enable_reg == 0)) {
|
||||
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
|
||||
clk->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (clk->flags & ENABLE_REG_32BIT) {
|
||||
if (clk->flags & VIRTUAL_IO_ADDRESS) {
|
||||
regval32 = __raw_readl(clk->enable_reg);
|
||||
regval32 |= (1 << clk->enable_bit);
|
||||
__raw_writel(regval32, clk->enable_reg);
|
||||
} else {
|
||||
regval32 = omap_readl(clk->enable_reg);
|
||||
regval32 |= (1 << clk->enable_bit);
|
||||
omap_writel(regval32, clk->enable_reg);
|
||||
}
|
||||
} else {
|
||||
if (clk->flags & VIRTUAL_IO_ADDRESS) {
|
||||
regval16 = __raw_readw(clk->enable_reg);
|
||||
regval16 |= (1 << clk->enable_bit);
|
||||
__raw_writew(regval16, clk->enable_reg);
|
||||
} else {
|
||||
regval16 = omap_readw(clk->enable_reg);
|
||||
regval16 |= (1 << clk->enable_bit);
|
||||
omap_writew(regval16, clk->enable_reg);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap1_clk_disable(struct clk *clk)
|
||||
{
|
||||
__u16 regval16;
|
||||
__u32 regval32;
|
||||
|
||||
if (clk->enable_reg == 0)
|
||||
return;
|
||||
|
||||
if (clk->flags & ENABLE_REG_32BIT) {
|
||||
if (clk->flags & VIRTUAL_IO_ADDRESS) {
|
||||
regval32 = __raw_readl(clk->enable_reg);
|
||||
regval32 &= ~(1 << clk->enable_bit);
|
||||
__raw_writel(regval32, clk->enable_reg);
|
||||
} else {
|
||||
regval32 = omap_readl(clk->enable_reg);
|
||||
regval32 &= ~(1 << clk->enable_bit);
|
||||
omap_writel(regval32, clk->enable_reg);
|
||||
}
|
||||
} else {
|
||||
if (clk->flags & VIRTUAL_IO_ADDRESS) {
|
||||
regval16 = __raw_readw(clk->enable_reg);
|
||||
regval16 &= ~(1 << clk->enable_bit);
|
||||
__raw_writew(regval16, clk->enable_reg);
|
||||
} else {
|
||||
regval16 = omap_readw(clk->enable_reg);
|
||||
regval16 &= ~(1 << clk->enable_bit);
|
||||
omap_writew(regval16, clk->enable_reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
int dsor_exp;
|
||||
|
||||
if (clk->flags & RATE_FIXED)
|
||||
return clk->rate;
|
||||
|
||||
if (clk->flags & RATE_CKCTL) {
|
||||
dsor_exp = calc_dsor_exp(clk, rate);
|
||||
if (dsor_exp < 0)
|
||||
return dsor_exp;
|
||||
if (dsor_exp > 3)
|
||||
dsor_exp = 3;
|
||||
return clk->parent->rate / (1 << dsor_exp);
|
||||
}
|
||||
|
||||
if(clk->round_rate != 0)
|
||||
return clk->round_rate(clk, rate);
|
||||
|
||||
return clk->rate;
|
||||
}
|
||||
|
||||
static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
int dsor_exp;
|
||||
__u16 regval;
|
||||
|
||||
if (clk->set_rate)
|
||||
ret = clk->set_rate(clk, rate);
|
||||
else if (clk->flags & RATE_CKCTL) {
|
||||
dsor_exp = calc_dsor_exp(clk, rate);
|
||||
if (dsor_exp > 3)
|
||||
dsor_exp = -EINVAL;
|
||||
if (dsor_exp < 0)
|
||||
return dsor_exp;
|
||||
|
||||
regval = omap_readw(ARM_CKCTL);
|
||||
regval &= ~(3 << clk->rate_offset);
|
||||
regval |= dsor_exp << clk->rate_offset;
|
||||
regval = verify_ckctl_value(regval);
|
||||
omap_writew(regval, ARM_CKCTL);
|
||||
clk->rate = clk->parent->rate / (1 << dsor_exp);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
|
||||
propagate_rate(clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Omap1 clock reset and init functions
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef CONFIG_OMAP_RESET_CLOCKS
|
||||
/*
|
||||
* Resets some clocks that may be left on from bootloader,
|
||||
* but leaves serial clocks on. See also omap_late_clk_reset().
|
||||
*/
|
||||
static inline void omap1_early_clk_reset(void)
|
||||
{
|
||||
//omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
|
||||
}
|
||||
|
||||
static int __init omap1_late_clk_reset(void)
|
||||
{
|
||||
/* Turn off all unused clocks */
|
||||
struct clk *p;
|
||||
__u32 regval32;
|
||||
|
||||
/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
|
||||
regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
|
||||
omap_writew(regval32, SOFT_REQ_REG);
|
||||
omap_writew(0, SOFT_REQ_REG2);
|
||||
|
||||
list_for_each_entry(p, &clocks, node) {
|
||||
if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
|
||||
p->enable_reg == 0)
|
||||
continue;
|
||||
|
||||
/* Clocks in the DSP domain need api_ck. Just assume bootloader
|
||||
* has not enabled any DSP clocks */
|
||||
if ((u32)p->enable_reg == DSP_IDLECT2) {
|
||||
printk(KERN_INFO "Skipping reset check for DSP domain "
|
||||
"clock \"%s\"\n", p->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Is the clock already disabled? */
|
||||
if (p->flags & ENABLE_REG_32BIT) {
|
||||
if (p->flags & VIRTUAL_IO_ADDRESS)
|
||||
regval32 = __raw_readl(p->enable_reg);
|
||||
else
|
||||
regval32 = omap_readl(p->enable_reg);
|
||||
} else {
|
||||
if (p->flags & VIRTUAL_IO_ADDRESS)
|
||||
regval32 = __raw_readw(p->enable_reg);
|
||||
else
|
||||
regval32 = omap_readw(p->enable_reg);
|
||||
}
|
||||
|
||||
if ((regval32 & (1 << p->enable_bit)) == 0)
|
||||
continue;
|
||||
|
||||
/* FIXME: This clock seems to be necessary but no-one
|
||||
* has asked for its activation. */
|
||||
if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera
|
||||
|| p == &ck_dpll1out.clk // FIX: SoSSI, SSR
|
||||
|| p == &arm_gpio_ck // FIX: GPIO code for 1510
|
||||
) {
|
||||
printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
|
||||
p->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
|
||||
p->disable(p);
|
||||
printk(" done\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall(omap1_late_clk_reset);
|
||||
|
||||
#else
|
||||
#define omap1_early_clk_reset() {}
|
||||
#endif
|
||||
|
||||
static struct clk_functions omap1_clk_functions = {
|
||||
.clk_use = omap1_clk_use,
|
||||
.clk_unuse = omap1_clk_unuse,
|
||||
.clk_round_rate = omap1_clk_round_rate,
|
||||
.clk_set_rate = omap1_clk_set_rate,
|
||||
};
|
||||
|
||||
int __init omap1_clk_init(void)
|
||||
{
|
||||
struct clk ** clkp;
|
||||
const struct omap_clock_config *info;
|
||||
int crystal_type = 0; /* Default 12 MHz */
|
||||
|
||||
omap1_early_clk_reset();
|
||||
clk_init(&omap1_clk_functions);
|
||||
|
||||
/* By default all idlect1 clocks are allowed to idle */
|
||||
arm_idlect1_mask = ~0;
|
||||
|
||||
for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
|
||||
if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
|
||||
clk_register(*clkp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
|
||||
clk_register(*clkp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
|
||||
clk_register(*clkp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
|
||||
if (info != NULL) {
|
||||
if (!cpu_is_omap1510())
|
||||
crystal_type = info->system_clock_type;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP730)
|
||||
ck_ref.rate = 13000000;
|
||||
#elif defined(CONFIG_ARCH_OMAP16XX)
|
||||
if (crystal_type == 2)
|
||||
ck_ref.rate = 19200000;
|
||||
#endif
|
||||
|
||||
printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
|
||||
omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
|
||||
omap_readw(ARM_CKCTL));
|
||||
|
||||
/* We want to be in syncronous scalable mode */
|
||||
omap_writew(0x1000, ARM_SYSST);
|
||||
|
||||
#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
|
||||
/* Use values set by bootloader. Determine PLL rate and recalculate
|
||||
* dependent clocks as if kernel had changed PLL or divisors.
|
||||
*/
|
||||
{
|
||||
unsigned pll_ctl_val = omap_readw(DPLL_CTL);
|
||||
|
||||
ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
|
||||
if (pll_ctl_val & 0x10) {
|
||||
/* PLL enabled, apply multiplier and divisor */
|
||||
if (pll_ctl_val & 0xf80)
|
||||
ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
|
||||
ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
|
||||
} else {
|
||||
/* PLL disabled, apply bypass divisor */
|
||||
switch (pll_ctl_val & 0xc) {
|
||||
case 0:
|
||||
break;
|
||||
case 0x4:
|
||||
ck_dpll1.rate /= 2;
|
||||
break;
|
||||
default:
|
||||
ck_dpll1.rate /= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
propagate_rate(&ck_dpll1);
|
||||
#else
|
||||
/* Find the highest supported frequency and enable it */
|
||||
if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
|
||||
printk(KERN_ERR "System frequencies not set. Check your config.\n");
|
||||
/* Guess sane values (60MHz) */
|
||||
omap_writew(0x2290, DPLL_CTL);
|
||||
omap_writew(0x1005, ARM_CKCTL);
|
||||
ck_dpll1.rate = 60000000;
|
||||
propagate_rate(&ck_dpll1);
|
||||
}
|
||||
#endif
|
||||
/* Cache rates for clocks connected to ck_ref (not dpll1) */
|
||||
propagate_rate(&ck_ref);
|
||||
printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
|
||||
"%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
|
||||
ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
|
||||
ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
|
||||
arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
|
||||
|
||||
#ifdef CONFIG_MACH_OMAP_PERSEUS2
|
||||
/* Select slicer output as OMAP input clock */
|
||||
omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
|
||||
#endif
|
||||
|
||||
/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
|
||||
omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
|
||||
|
||||
/* Put DSP/MPUI into reset until needed */
|
||||
omap_writew(0, ARM_RSTCT1);
|
||||
omap_writew(1, ARM_RSTCT2);
|
||||
omap_writew(0x400, ARM_IDLECT1);
|
||||
|
||||
/*
|
||||
* According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
|
||||
* of the ARM_IDLECT2 register must be set to zero. The power-on
|
||||
* default value of this bit is one.
|
||||
*/
|
||||
omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
|
||||
|
||||
/*
|
||||
* Only enable those clocks we will need, let the drivers
|
||||
* enable other clocks as necessary
|
||||
*/
|
||||
clk_use(&armper_ck.clk);
|
||||
clk_use(&armxor_ck.clk);
|
||||
clk_use(&armtim_ck.clk); /* This should be done by timer code */
|
||||
|
||||
if (cpu_is_omap1510())
|
||||
clk_enable(&arm_gpio_ck);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
768
arch/arm/mach-omap1/clock.h
Normal file
768
arch/arm/mach-omap1/clock.h
Normal file
@ -0,0 +1,768 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/clock.h
|
||||
*
|
||||
* Copyright (C) 2004 - 2005 Nokia corporation
|
||||
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
* Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
|
||||
#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
|
||||
|
||||
static int omap1_clk_enable(struct clk * clk);
|
||||
static void omap1_clk_disable(struct clk * clk);
|
||||
static void omap1_ckctl_recalc(struct clk * clk);
|
||||
static void omap1_watchdog_recalc(struct clk * clk);
|
||||
static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
|
||||
static int omap1_clk_enable_dsp_domain(struct clk * clk);
|
||||
static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate);
|
||||
static void omap1_clk_disable_dsp_domain(struct clk * clk);
|
||||
static int omap1_set_uart_rate(struct clk * clk, unsigned long rate);
|
||||
static void omap1_uart_recalc(struct clk * clk);
|
||||
static int omap1_clk_enable_uart_functional(struct clk * clk);
|
||||
static void omap1_clk_disable_uart_functional(struct clk * clk);
|
||||
static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate);
|
||||
static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate);
|
||||
static void omap1_init_ext_clk(struct clk * clk);
|
||||
static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
|
||||
static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
|
||||
static int omap1_clk_use(struct clk *clk);
|
||||
static void omap1_clk_unuse(struct clk *clk);
|
||||
|
||||
struct mpu_rate {
|
||||
unsigned long rate;
|
||||
unsigned long xtal;
|
||||
unsigned long pll_rate;
|
||||
__u16 ckctl_val;
|
||||
__u16 dpllctl_val;
|
||||
};
|
||||
|
||||
struct uart_clk {
|
||||
struct clk clk;
|
||||
unsigned long sysc_addr;
|
||||
};
|
||||
|
||||
/* Provide a method for preventing idling some ARM IDLECT clocks */
|
||||
struct arm_idlect1_clk {
|
||||
struct clk clk;
|
||||
unsigned long no_idle_count;
|
||||
__u8 idlect_shift;
|
||||
};
|
||||
|
||||
/* ARM_CKCTL bit shifts */
|
||||
#define CKCTL_PERDIV_OFFSET 0
|
||||
#define CKCTL_LCDDIV_OFFSET 2
|
||||
#define CKCTL_ARMDIV_OFFSET 4
|
||||
#define CKCTL_DSPDIV_OFFSET 6
|
||||
#define CKCTL_TCDIV_OFFSET 8
|
||||
#define CKCTL_DSPMMUDIV_OFFSET 10
|
||||
/*#define ARM_TIMXO 12*/
|
||||
#define EN_DSPCK 13
|
||||
/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
|
||||
/* DSP_CKCTL bit shifts */
|
||||
#define CKCTL_DSPPERDIV_OFFSET 0
|
||||
|
||||
/* ARM_IDLECT2 bit shifts */
|
||||
#define EN_WDTCK 0
|
||||
#define EN_XORPCK 1
|
||||
#define EN_PERCK 2
|
||||
#define EN_LCDCK 3
|
||||
#define EN_LBCK 4 /* Not on 1610/1710 */
|
||||
/*#define EN_HSABCK 5*/
|
||||
#define EN_APICK 6
|
||||
#define EN_TIMCK 7
|
||||
#define DMACK_REQ 8
|
||||
#define EN_GPIOCK 9 /* Not on 1610/1710 */
|
||||
/*#define EN_LBFREECK 10*/
|
||||
#define EN_CKOUT_ARM 11
|
||||
|
||||
/* ARM_IDLECT3 bit shifts */
|
||||
#define EN_OCPI_CK 0
|
||||
#define EN_TC1_CK 2
|
||||
#define EN_TC2_CK 4
|
||||
|
||||
/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
|
||||
#define EN_DSPTIMCK 5
|
||||
|
||||
/* Various register defines for clock controls scattered around OMAP chip */
|
||||
#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
|
||||
#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
|
||||
#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
|
||||
#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
|
||||
#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
|
||||
#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
|
||||
#define SOFT_REQ_REG 0xfffe0834
|
||||
#define SOFT_REQ_REG2 0xfffe0880
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Omap1 MPU rate table
|
||||
*-------------------------------------------------------------------------*/
|
||||
static struct mpu_rate rate_table[] = {
|
||||
/* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
|
||||
* NOTE: Comment order here is different from bits in CKCTL value:
|
||||
* armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
|
||||
*/
|
||||
#if defined(CONFIG_OMAP_ARM_216MHZ)
|
||||
{ 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_195MHZ)
|
||||
{ 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_192MHZ)
|
||||
{ 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
|
||||
{ 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
|
||||
{ 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
|
||||
{ 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */
|
||||
{ 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_182MHZ)
|
||||
{ 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_168MHZ)
|
||||
{ 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_150MHZ)
|
||||
{ 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_120MHZ)
|
||||
{ 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_96MHZ)
|
||||
{ 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_60MHZ)
|
||||
{ 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
|
||||
#endif
|
||||
#if defined(CONFIG_OMAP_ARM_30MHZ)
|
||||
{ 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
|
||||
#endif
|
||||
{ 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Omap1 clocks
|
||||
*-------------------------------------------------------------------------*/
|
||||
|
||||
static struct clk ck_ref = {
|
||||
.name = "ck_ref",
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ALWAYS_ENABLED,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk ck_dpll1 = {
|
||||
.name = "ck_dpll1",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_PROPAGATES | ALWAYS_ENABLED,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk ck_dpll1out = {
|
||||
.clk = {
|
||||
.name = "ck_dpll1out",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_CKOUT_ARM,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 12,
|
||||
};
|
||||
|
||||
static struct clk arm_ck = {
|
||||
.name = "arm_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
|
||||
.rate_offset = CKCTL_ARMDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk armper_ck = {
|
||||
.clk = {
|
||||
.name = "armper_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_PERCK,
|
||||
.rate_offset = CKCTL_PERDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 2,
|
||||
};
|
||||
|
||||
static struct clk arm_gpio_ck = {
|
||||
.name = "arm_gpio_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_GPIOCK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk armxor_ck = {
|
||||
.clk = {
|
||||
.name = "armxor_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_XORPCK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 1,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk armtim_ck = {
|
||||
.clk = {
|
||||
.name = "armtim_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_TIMCK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 9,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk armwdt_ck = {
|
||||
.clk = {
|
||||
.name = "armwdt_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_WDTCK,
|
||||
.recalc = &omap1_watchdog_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 0,
|
||||
};
|
||||
|
||||
static struct clk arminth_ck16xx = {
|
||||
.name = "arminth_ck",
|
||||
.parent = &arm_ck,
|
||||
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
/* Note: On 16xx the frequency can be divided by 2 by programming
|
||||
* ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
|
||||
*
|
||||
* 1510 version is in TC clocks.
|
||||
*/
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk dsp_ck = {
|
||||
.name = "dsp_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL,
|
||||
.enable_reg = (void __iomem *)ARM_CKCTL,
|
||||
.enable_bit = EN_DSPCK,
|
||||
.rate_offset = CKCTL_DSPDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk dspmmu_ck = {
|
||||
.name = "dspmmu_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL | ALWAYS_ENABLED,
|
||||
.rate_offset = CKCTL_DSPMMUDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk dspper_ck = {
|
||||
.name = "dspper_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_CKCTL | VIRTUAL_IO_ADDRESS,
|
||||
.enable_reg = (void __iomem *)DSP_IDLECT2,
|
||||
.enable_bit = EN_PERCK,
|
||||
.rate_offset = CKCTL_PERDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc_dsp_domain,
|
||||
.set_rate = &omap1_clk_set_rate_dsp_domain,
|
||||
.enable = &omap1_clk_enable_dsp_domain,
|
||||
.disable = &omap1_clk_disable_dsp_domain,
|
||||
};
|
||||
|
||||
static struct clk dspxor_ck = {
|
||||
.name = "dspxor_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
VIRTUAL_IO_ADDRESS,
|
||||
.enable_reg = (void __iomem *)DSP_IDLECT2,
|
||||
.enable_bit = EN_XORPCK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable_dsp_domain,
|
||||
.disable = &omap1_clk_disable_dsp_domain,
|
||||
};
|
||||
|
||||
static struct clk dsptim_ck = {
|
||||
.name = "dsptim_ck",
|
||||
.parent = &ck_ref,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
VIRTUAL_IO_ADDRESS,
|
||||
.enable_reg = (void __iomem *)DSP_IDLECT2,
|
||||
.enable_bit = EN_DSPTIMCK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable_dsp_domain,
|
||||
.disable = &omap1_clk_disable_dsp_domain,
|
||||
};
|
||||
|
||||
/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
|
||||
static struct arm_idlect1_clk tc_ck = {
|
||||
.clk = {
|
||||
.name = "tc_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IN_OMAP730 | RATE_CKCTL |
|
||||
RATE_PROPAGATES | ALWAYS_ENABLED |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.rate_offset = CKCTL_TCDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 6,
|
||||
};
|
||||
|
||||
static struct clk arminth_ck1510 = {
|
||||
.name = "arminth_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
/* Note: On 1510 the frequency follows TC_CK
|
||||
*
|
||||
* 16xx version is in MPU clocks.
|
||||
*/
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk tipb_ck = {
|
||||
/* No-idle controlled by "tc_ck" */
|
||||
.name = "tibp_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk l3_ocpi_ck = {
|
||||
/* No-idle controlled by "tc_ck" */
|
||||
.name = "l3_ocpi_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP16XX,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT3,
|
||||
.enable_bit = EN_OCPI_CK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk tc1_ck = {
|
||||
.name = "tc1_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP16XX,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT3,
|
||||
.enable_bit = EN_TC1_CK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk tc2_ck = {
|
||||
.name = "tc2_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP16XX,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT3,
|
||||
.enable_bit = EN_TC2_CK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk dma_ck = {
|
||||
/* No-idle controlled by "tc_ck" */
|
||||
.name = "dma_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk dma_lcdfree_ck = {
|
||||
.name = "dma_lcdfree_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk api_ck = {
|
||||
.clk = {
|
||||
.name = "api_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_APICK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 8,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk lb_ck = {
|
||||
.clk = {
|
||||
.name = "lb_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_LBCK,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 4,
|
||||
};
|
||||
|
||||
static struct clk rhea1_ck = {
|
||||
.name = "rhea1_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk rhea2_ck = {
|
||||
.name = "rhea2_ck",
|
||||
.parent = &tc_ck.clk,
|
||||
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
|
||||
.recalc = &followparent_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk lcd_ck_16xx = {
|
||||
.name = "lcd_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_LCDCK,
|
||||
.rate_offset = CKCTL_LCDDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct arm_idlect1_clk lcd_ck_1510 = {
|
||||
.clk = {
|
||||
.name = "lcd_ck",
|
||||
.parent = &ck_dpll1,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_CKCTL |
|
||||
CLOCK_IDLE_CONTROL,
|
||||
.enable_reg = (void __iomem *)ARM_IDLECT2,
|
||||
.enable_bit = EN_LCDCK,
|
||||
.rate_offset = CKCTL_LCDDIV_OFFSET,
|
||||
.recalc = &omap1_ckctl_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
},
|
||||
.idlect_shift = 3,
|
||||
};
|
||||
|
||||
static struct clk uart1_1510 = {
|
||||
.name = "uart1_ck",
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
|
||||
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 29, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
.recalc = &omap1_uart_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct uart_clk uart1_16xx = {
|
||||
.clk = {
|
||||
.name = "uart1_ck",
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
|
||||
ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 29,
|
||||
.enable = &omap1_clk_enable_uart_functional,
|
||||
.disable = &omap1_clk_disable_uart_functional,
|
||||
},
|
||||
.sysc_addr = 0xfffb0054,
|
||||
};
|
||||
|
||||
static struct clk uart2_ck = {
|
||||
.name = "uart2_ck",
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
ENABLE_REG_32BIT | ALWAYS_ENABLED |
|
||||
CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 30, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
.recalc = &omap1_uart_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk uart3_1510 = {
|
||||
.name = "uart3_ck",
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
|
||||
ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 31, /* Chooses between 12MHz and 48MHz */
|
||||
.set_rate = &omap1_set_uart_rate,
|
||||
.recalc = &omap1_uart_recalc,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct uart_clk uart3_16xx = {
|
||||
.clk = {
|
||||
.name = "uart3_ck",
|
||||
/* Direct from ULPD, no real parent */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
|
||||
ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 31,
|
||||
.enable = &omap1_clk_enable_uart_functional,
|
||||
.disable = &omap1_clk_disable_uart_functional,
|
||||
},
|
||||
.sysc_addr = 0xfffb9854,
|
||||
};
|
||||
|
||||
static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
|
||||
.name = "usb_clko",
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 6000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
|
||||
.enable_bit = USB_MCLK_EN_BIT,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk usb_hhc_ck1510 = {
|
||||
.name = "usb_hhc_ck",
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
|
||||
.flags = CLOCK_IN_OMAP1510 |
|
||||
RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = USB_HOST_HHC_UHOST_EN,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk usb_hhc_ck16xx = {
|
||||
.name = "usb_hhc_ck",
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000,
|
||||
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
|
||||
.flags = CLOCK_IN_OMAP16XX |
|
||||
RATE_FIXED | ENABLE_REG_32BIT,
|
||||
.enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
|
||||
.enable_bit = 8 /* UHOST_EN */,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk usb_dc_ck = {
|
||||
.name = "usb_dc_ck",
|
||||
/* Direct from ULPD, no parent */
|
||||
.rate = 48000000,
|
||||
.flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
|
||||
.enable_reg = (void __iomem *)SOFT_REQ_REG,
|
||||
.enable_bit = 4,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk mclk_1510 = {
|
||||
.name = "mclk",
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk mclk_16xx = {
|
||||
.name = "mclk",
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.flags = CLOCK_IN_OMAP16XX,
|
||||
.enable_reg = (void __iomem *)COM_CLK_DIV_CTRL_SEL,
|
||||
.enable_bit = COM_ULPD_PLL_CLK_REQ,
|
||||
.set_rate = &omap1_set_ext_clk_rate,
|
||||
.round_rate = &omap1_round_ext_clk_rate,
|
||||
.init = &omap1_init_ext_clk,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk bclk_1510 = {
|
||||
.name = "bclk",
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.rate = 12000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk bclk_16xx = {
|
||||
.name = "bclk",
|
||||
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
|
||||
.flags = CLOCK_IN_OMAP16XX,
|
||||
.enable_reg = (void __iomem *)SWD_CLK_DIV_CTRL_SEL,
|
||||
.enable_bit = SWD_ULPD_PLL_CLK_REQ,
|
||||
.set_rate = &omap1_set_ext_clk_rate,
|
||||
.round_rate = &omap1_round_ext_clk_rate,
|
||||
.init = &omap1_init_ext_clk,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk mmc1_ck = {
|
||||
.name = "mmc1_ck",
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 23,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk mmc2_ck = {
|
||||
.name = "mmc2_ck",
|
||||
/* Functional clock is direct from ULPD, interface clock is ARMPER */
|
||||
.parent = &armper_ck.clk,
|
||||
.rate = 48000000,
|
||||
.flags = CLOCK_IN_OMAP16XX |
|
||||
RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
|
||||
.enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
|
||||
.enable_bit = 20,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk virtual_ck_mpu = {
|
||||
.name = "mpu",
|
||||
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
|
||||
VIRTUAL_CLOCK | ALWAYS_ENABLED,
|
||||
.parent = &arm_ck, /* Is smarter alias for */
|
||||
.recalc = &followparent_recalc,
|
||||
.set_rate = &omap1_select_table_rate,
|
||||
.round_rate = &omap1_round_to_table_rate,
|
||||
.enable = &omap1_clk_enable,
|
||||
.disable = &omap1_clk_disable,
|
||||
};
|
||||
|
||||
static struct clk * onchip_clks[] = {
|
||||
/* non-ULPD clocks */
|
||||
&ck_ref,
|
||||
&ck_dpll1,
|
||||
/* CK_GEN1 clocks */
|
||||
&ck_dpll1out.clk,
|
||||
&arm_ck,
|
||||
&armper_ck.clk,
|
||||
&arm_gpio_ck,
|
||||
&armxor_ck.clk,
|
||||
&armtim_ck.clk,
|
||||
&armwdt_ck.clk,
|
||||
&arminth_ck1510, &arminth_ck16xx,
|
||||
/* CK_GEN2 clocks */
|
||||
&dsp_ck,
|
||||
&dspmmu_ck,
|
||||
&dspper_ck,
|
||||
&dspxor_ck,
|
||||
&dsptim_ck,
|
||||
/* CK_GEN3 clocks */
|
||||
&tc_ck.clk,
|
||||
&tipb_ck,
|
||||
&l3_ocpi_ck,
|
||||
&tc1_ck,
|
||||
&tc2_ck,
|
||||
&dma_ck,
|
||||
&dma_lcdfree_ck,
|
||||
&api_ck.clk,
|
||||
&lb_ck.clk,
|
||||
&rhea1_ck,
|
||||
&rhea2_ck,
|
||||
&lcd_ck_16xx,
|
||||
&lcd_ck_1510.clk,
|
||||
/* ULPD clocks */
|
||||
&uart1_1510,
|
||||
&uart1_16xx.clk,
|
||||
&uart2_ck,
|
||||
&uart3_1510,
|
||||
&uart3_16xx.clk,
|
||||
&usb_clko,
|
||||
&usb_hhc_ck1510, &usb_hhc_ck16xx,
|
||||
&usb_dc_ck,
|
||||
&mclk_1510, &mclk_16xx,
|
||||
&bclk_1510, &bclk_16xx,
|
||||
&mmc1_ck,
|
||||
&mmc2_ck,
|
||||
/* Virtual clocks */
|
||||
&virtual_ck_mpu,
|
||||
};
|
||||
|
||||
#endif
|
@ -25,56 +25,7 @@
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
|
||||
static void omap_nop_release(struct device *dev)
|
||||
{
|
||||
/* Nothing */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
|
||||
|
||||
#define OMAP_I2C_BASE 0xfffb3800
|
||||
|
||||
static struct resource i2c_resources[] = {
|
||||
{
|
||||
.start = OMAP_I2C_BASE,
|
||||
.end = OMAP_I2C_BASE + 0x3f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = INT_I2C,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
/* DMA not used; works around erratum writing to non-empty i2c fifo */
|
||||
|
||||
static struct platform_device omap_i2c_device = {
|
||||
.name = "i2c_omap",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(i2c_resources),
|
||||
.resource = i2c_resources,
|
||||
};
|
||||
|
||||
static void omap_init_i2c(void)
|
||||
{
|
||||
/* FIXME define and use a boot tag, in case of boards that
|
||||
* either don't wire up I2C, or chips that mux it differently...
|
||||
* it can include clocking and address info, maybe more.
|
||||
*/
|
||||
omap_cfg_reg(I2C_SCL);
|
||||
omap_cfg_reg(I2C_SDA);
|
||||
|
||||
(void) platform_device_register(&omap_i2c_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_i2c(void) {}
|
||||
#endif
|
||||
extern void omap_nop_release(struct device *dev);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
@ -110,137 +61,6 @@ static inline void omap_init_irda(void) {}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
|
||||
|
||||
#define OMAP_MMC1_BASE 0xfffb7800
|
||||
#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
|
||||
|
||||
static struct omap_mmc_conf mmc1_conf;
|
||||
|
||||
static u64 mmc1_dmamask = 0xffffffff;
|
||||
|
||||
static struct resource mmc1_resources[] = {
|
||||
{
|
||||
.start = IO_ADDRESS(OMAP_MMC1_BASE),
|
||||
.end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = INT_MMC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mmc_omap_device1 = {
|
||||
.name = "mmci-omap",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
.dma_mask = &mmc1_dmamask,
|
||||
.platform_data = &mmc1_conf,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(mmc1_resources),
|
||||
.resource = mmc1_resources,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
|
||||
static struct omap_mmc_conf mmc2_conf;
|
||||
|
||||
static u64 mmc2_dmamask = 0xffffffff;
|
||||
|
||||
static struct resource mmc2_resources[] = {
|
||||
{
|
||||
.start = IO_ADDRESS(OMAP_MMC2_BASE),
|
||||
.end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = INT_1610_MMC2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mmc_omap_device2 = {
|
||||
.name = "mmci-omap",
|
||||
.id = 2,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
.dma_mask = &mmc2_dmamask,
|
||||
.platform_data = &mmc2_conf,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(mmc2_resources),
|
||||
.resource = mmc2_resources,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void __init omap_init_mmc(void)
|
||||
{
|
||||
const struct omap_mmc_config *mmc_conf;
|
||||
const struct omap_mmc_conf *mmc;
|
||||
|
||||
/* NOTE: assumes MMC was never (wrongly) enabled */
|
||||
mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
|
||||
if (!mmc_conf)
|
||||
return;
|
||||
|
||||
/* block 1 is always available and has just one pinout option */
|
||||
mmc = &mmc_conf->mmc[0];
|
||||
if (mmc->enabled) {
|
||||
omap_cfg_reg(MMC_CMD);
|
||||
omap_cfg_reg(MMC_CLK);
|
||||
omap_cfg_reg(MMC_DAT0);
|
||||
if (cpu_is_omap1710()) {
|
||||
omap_cfg_reg(M15_1710_MMC_CLKI);
|
||||
omap_cfg_reg(P19_1710_MMC_CMDDIR);
|
||||
omap_cfg_reg(P20_1710_MMC_DATDIR0);
|
||||
}
|
||||
if (mmc->wire4) {
|
||||
omap_cfg_reg(MMC_DAT1);
|
||||
/* NOTE: DAT2 can be on W10 (here) or M15 */
|
||||
if (!mmc->nomux)
|
||||
omap_cfg_reg(MMC_DAT2);
|
||||
omap_cfg_reg(MMC_DAT3);
|
||||
}
|
||||
mmc1_conf = *mmc;
|
||||
(void) platform_device_register(&mmc_omap_device1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
/* block 2 is on newer chips, and has many pinout options */
|
||||
mmc = &mmc_conf->mmc[1];
|
||||
if (mmc->enabled) {
|
||||
if (!mmc->nomux) {
|
||||
omap_cfg_reg(Y8_1610_MMC2_CMD);
|
||||
omap_cfg_reg(Y10_1610_MMC2_CLK);
|
||||
omap_cfg_reg(R18_1610_MMC2_CLKIN);
|
||||
omap_cfg_reg(W8_1610_MMC2_DAT0);
|
||||
if (mmc->wire4) {
|
||||
omap_cfg_reg(V8_1610_MMC2_DAT1);
|
||||
omap_cfg_reg(W15_1610_MMC2_DAT2);
|
||||
omap_cfg_reg(R10_1610_MMC2_DAT3);
|
||||
}
|
||||
|
||||
/* These are needed for the level shifter */
|
||||
omap_cfg_reg(V9_1610_MMC2_CMDDIR);
|
||||
omap_cfg_reg(V5_1610_MMC2_DATDIR0);
|
||||
omap_cfg_reg(W19_1610_MMC2_DATDIR1);
|
||||
}
|
||||
|
||||
/* Feedback clock must be set on OMAP-1710 MMC2 */
|
||||
if (cpu_is_omap1710())
|
||||
omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
|
||||
MOD_CONF_CTRL_1);
|
||||
mmc2_conf = *mmc;
|
||||
(void) platform_device_register(&mmc_omap_device2);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_mmc(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
|
||||
|
||||
#define OMAP_RTC_BASE 0xfffb4800
|
||||
@ -279,38 +99,6 @@ static void omap_init_rtc(void)
|
||||
static inline void omap_init_rtc(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
|
||||
|
||||
#define OMAP_WDT_BASE 0xfffeb000
|
||||
|
||||
static struct resource wdt_resources[] = {
|
||||
{
|
||||
.start = OMAP_WDT_BASE,
|
||||
.end = OMAP_WDT_BASE + 0x4f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device omap_wdt_device = {
|
||||
.name = "omap1610_wdt",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(wdt_resources),
|
||||
.resource = wdt_resources,
|
||||
};
|
||||
|
||||
static void omap_init_wdt(void)
|
||||
{
|
||||
(void) platform_device_register(&omap_wdt_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_wdt(void) {}
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
@ -334,18 +122,15 @@ static inline void omap_init_wdt(void) {}
|
||||
* may be handled by the boot loader, and drivers should expect it will
|
||||
* normally have been done by the time they're probed.
|
||||
*/
|
||||
static int __init omap_init_devices(void)
|
||||
static int __init omap1_init_devices(void)
|
||||
{
|
||||
/* please keep these calls, and their implementations above,
|
||||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_init_i2c();
|
||||
omap_init_irda();
|
||||
omap_init_mmc();
|
||||
omap_init_rtc();
|
||||
omap_init_wdt();
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(omap_init_devices);
|
||||
arch_initcall(omap1_init_devices);
|
||||
|
||||
|
@ -18,6 +18,13 @@
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#define OMAP_DIE_ID_0 0xfffe1800
|
||||
#define OMAP_DIE_ID_1 0xfffe1804
|
||||
#define OMAP_PRODUCTION_ID_0 0xfffe2000
|
||||
#define OMAP_PRODUCTION_ID_1 0xfffe2004
|
||||
#define OMAP32_ID_0 0xfffed400
|
||||
#define OMAP32_ID_1 0xfffed404
|
||||
|
||||
struct omap_id {
|
||||
u16 jtag_id; /* Used to determine OMAP type */
|
||||
u8 die_rev; /* Processor revision */
|
||||
@ -27,6 +34,7 @@ struct omap_id {
|
||||
|
||||
/* Register values to detect the OMAP version */
|
||||
static struct omap_id omap_ids[] __initdata = {
|
||||
{ .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
|
||||
{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
|
||||
{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
|
||||
{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
|
||||
@ -164,6 +172,7 @@ void __init omap_check_revision(void)
|
||||
case 0x07:
|
||||
system_rev |= 0x07;
|
||||
break;
|
||||
case 0x03:
|
||||
case 0x15:
|
||||
system_rev |= 0x15;
|
||||
break;
|
||||
|
@ -15,9 +15,10 @@
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/tc.h>
|
||||
|
||||
extern int clk_init(void);
|
||||
extern int omap1_clk_init(void);
|
||||
extern void omap_check_revision(void);
|
||||
extern void omap_sram_init(void);
|
||||
|
||||
@ -50,7 +51,7 @@ static struct map_desc omap730_io_desc[] __initdata = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
static struct map_desc omap1510_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = OMAP1510_DSP_BASE,
|
||||
@ -98,7 +99,7 @@ static void __init _omap_map_io(void)
|
||||
iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
|
||||
}
|
||||
@ -119,7 +120,7 @@ static void __init _omap_map_io(void)
|
||||
|
||||
/* Must init clocks early to assure that timer interrupt works
|
||||
*/
|
||||
clk_init();
|
||||
omap1_clk_init();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -127,7 +128,9 @@ static void __init _omap_map_io(void)
|
||||
*/
|
||||
void __init omap_map_common_io(void)
|
||||
{
|
||||
if (!initialized)
|
||||
if (!initialized) {
|
||||
_omap_map_io();
|
||||
omap1_mux_init();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/cpu.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
@ -147,11 +148,15 @@ static struct omap_irq_bank omap730_irq_banks[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
static struct omap_irq_bank omap1510_irq_banks[] = {
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
|
||||
};
|
||||
static struct omap_irq_bank omap310_irq_banks[] = {
|
||||
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
|
||||
{ .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
@ -181,11 +186,15 @@ void __init omap_init_irq(void)
|
||||
irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
irq_banks = omap1510_irq_banks;
|
||||
irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
|
||||
}
|
||||
if (cpu_is_omap310()) {
|
||||
irq_banks = omap310_irq_banks;
|
||||
irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
if (cpu_is_omap16xx()) {
|
||||
@ -226,9 +235,11 @@ void __init omap_init_irq(void)
|
||||
}
|
||||
|
||||
/* Unmask level 2 handler */
|
||||
if (cpu_is_omap730()) {
|
||||
|
||||
if (cpu_is_omap730())
|
||||
omap_unmask_irq(INT_730_IH2_IRQ);
|
||||
} else {
|
||||
omap_unmask_irq(INT_IH2_IRQ);
|
||||
}
|
||||
else if (cpu_is_omap1510())
|
||||
omap_unmask_irq(INT_1510_IH2_IRQ);
|
||||
else if (cpu_is_omap16xx())
|
||||
omap_unmask_irq(INT_1610_IH2_IRQ);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/leds.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <asm/arch/fpga.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
@ -63,14 +64,19 @@ void h2p2_dbg_leds_event(led_event_t evt)
|
||||
case led_stop:
|
||||
case led_halted:
|
||||
/* all leds off during suspend or shutdown */
|
||||
omap_set_gpio_dataout(GPIO_TIMER, 0);
|
||||
omap_set_gpio_dataout(GPIO_IDLE, 0);
|
||||
|
||||
if (! machine_is_omap_perseus2()) {
|
||||
omap_set_gpio_dataout(GPIO_TIMER, 0);
|
||||
omap_set_gpio_dataout(GPIO_IDLE, 0);
|
||||
}
|
||||
|
||||
__raw_writew(~0, &fpga->leds);
|
||||
led_state &= ~LED_STATE_ENABLED;
|
||||
if (evt == led_halted) {
|
||||
iounmap(fpga);
|
||||
fpga = NULL;
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
||||
case led_claim:
|
||||
@ -85,18 +91,37 @@ void h2p2_dbg_leds_event(led_event_t evt)
|
||||
#ifdef CONFIG_LEDS_TIMER
|
||||
case led_timer:
|
||||
led_state ^= LED_TIMER_ON;
|
||||
omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
|
||||
goto done;
|
||||
|
||||
if (machine_is_omap_perseus2())
|
||||
hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
|
||||
else {
|
||||
omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LEDS_CPU
|
||||
case led_idle_start:
|
||||
omap_set_gpio_dataout(GPIO_IDLE, 1);
|
||||
goto done;
|
||||
if (machine_is_omap_perseus2())
|
||||
hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
|
||||
else {
|
||||
omap_set_gpio_dataout(GPIO_IDLE, 1);
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case led_idle_end:
|
||||
omap_set_gpio_dataout(GPIO_IDLE, 0);
|
||||
goto done;
|
||||
if (machine_is_omap_perseus2())
|
||||
hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
|
||||
else {
|
||||
omap_set_gpio_dataout(GPIO_IDLE, 0);
|
||||
goto done;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
case led_green_on:
|
||||
@ -135,7 +160,7 @@ void h2p2_dbg_leds_event(led_event_t evt)
|
||||
/*
|
||||
* Actually burn the LEDs
|
||||
*/
|
||||
if (led_state & LED_STATE_CLAIMED)
|
||||
if (led_state & LED_STATE_ENABLED)
|
||||
__raw_writew(~hw_led_state, &fpga->leds);
|
||||
|
||||
done:
|
||||
|
@ -33,7 +33,6 @@ omap_leds_init(void)
|
||||
|
||||
if (machine_is_omap_h2()
|
||||
|| machine_is_omap_h3()
|
||||
|| machine_is_omap_perseus2()
|
||||
#ifdef CONFIG_OMAP_OSK_MISTRAL
|
||||
|| machine_is_omap_osk()
|
||||
#endif
|
||||
|
289
arch/arm/mach-omap1/mux.c
Normal file
289
arch/arm/mach-omap1/mux.c
Normal file
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/mux.c
|
||||
*
|
||||
* OMAP1 pin multiplexing configurations
|
||||
*
|
||||
* Copyright (C) 2003 - 2005 Nokia Corporation
|
||||
*
|
||||
* Written by Tony Lindgren <tony.lindgren@nokia.com>
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/arch/mux.h>
|
||||
|
||||
#ifdef CONFIG_OMAP_MUX
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP730
|
||||
struct pin_config __initdata_or_module omap730_pins[] = {
|
||||
MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0)
|
||||
MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0)
|
||||
MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0)
|
||||
MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0)
|
||||
MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0)
|
||||
MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0)
|
||||
MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0)
|
||||
MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0)
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
|
||||
struct pin_config __initdata_or_module omap1xxx_pins[] = {
|
||||
/*
|
||||
* description mux mode mux pull pull pull pu_pd pu dbg
|
||||
* reg offset mode reg bit ena reg
|
||||
*/
|
||||
MUX_CFG("UART1_TX", 9, 21, 1, 2, 3, 0, NA, 0, 0)
|
||||
MUX_CFG("UART1_RTS", 9, 12, 1, 2, 0, 0, NA, 0, 0)
|
||||
|
||||
/* UART2 (COM_UART_GATING), conflicts with USB2 */
|
||||
MUX_CFG("UART2_TX", C, 27, 1, 3, 3, 0, NA, 0, 0)
|
||||
MUX_CFG("UART2_RX", C, 18, 0, 3, 1, 1, NA, 0, 0)
|
||||
MUX_CFG("UART2_CTS", C, 21, 0, 3, 1, 1, NA, 0, 0)
|
||||
MUX_CFG("UART2_RTS", C, 24, 1, 3, 2, 0, NA, 0, 0)
|
||||
|
||||
/* UART3 (GIGA_UART_GATING) */
|
||||
MUX_CFG("UART3_TX", 6, 0, 1, 0, 30, 0, NA, 0, 0)
|
||||
MUX_CFG("UART3_RX", 6, 3, 0, 0, 31, 1, NA, 0, 0)
|
||||
MUX_CFG("UART3_CTS", 5, 12, 2, 0, 24, 0, NA, 0, 0)
|
||||
MUX_CFG("UART3_RTS", 5, 15, 2, 0, 25, 0, NA, 0, 0)
|
||||
MUX_CFG("UART3_CLKREQ", 9, 27, 0, 2, 5, 0, NA, 0, 0)
|
||||
MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
|
||||
MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
|
||||
|
||||
/* PWT & PWL, conflicts with UART3 */
|
||||
MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
|
||||
MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
|
||||
|
||||
/* USB internal master generic */
|
||||
MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
|
||||
MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1)
|
||||
/* works around erratum: W4_USB_PUEN and W4_USB_PUDIS are switched! */
|
||||
MUX_CFG("W4_USB_PUEN", D, 3, 3, 3, 5, 1, NA, 0, 1)
|
||||
MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1)
|
||||
MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1)
|
||||
MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1)
|
||||
|
||||
/* USB1 master */
|
||||
MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1)
|
||||
MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1)
|
||||
MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1)
|
||||
MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1)
|
||||
MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1)
|
||||
MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1)
|
||||
MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1)
|
||||
MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1)
|
||||
MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1)
|
||||
MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1)
|
||||
MUX_CFG("R13_1710_USB1_SEO", A, 12, 5, 2, 10, 0, NA, 0, 1)
|
||||
|
||||
/* USB2 master */
|
||||
MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1)
|
||||
MUX_CFG("USB2_VP", B, 6, 1, 2, 18, 0, NA, 0, 1)
|
||||
MUX_CFG("USB2_TXEN", B, 9, 1, 2, 19, 0, NA, 0, 1)
|
||||
MUX_CFG("USB2_VM", C, 18, 1, 3, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("USB2_RCV", C, 21, 1, 3, 1, 0, NA, 0, 1)
|
||||
MUX_CFG("USB2_SE0", C, 24, 2, 3, 2, 0, NA, 0, 1)
|
||||
MUX_CFG("USB2_TXD", C, 27, 2, 3, 3, 0, NA, 0, 1)
|
||||
|
||||
/* OMAP-1510 GPIO */
|
||||
MUX_CFG("R18_1510_GPIO0", 7, 9, 0, 1, 11, 1, 0, 0, 1)
|
||||
MUX_CFG("R19_1510_GPIO1", 7, 6, 0, 1, 10, 1, 0, 0, 1)
|
||||
MUX_CFG("M14_1510_GPIO2", 7, 3, 0, 1, 9, 1, 0, 0, 1)
|
||||
|
||||
/* OMAP1610 GPIO */
|
||||
MUX_CFG("P18_1610_GPIO3", 7, 0, 0, 1, 8, 0, NA, 0, 1)
|
||||
MUX_CFG("Y15_1610_GPIO17", A, 0, 7, 2, 6, 0, NA, 0, 1)
|
||||
|
||||
/* OMAP-1710 GPIO */
|
||||
MUX_CFG("R18_1710_GPIO0", 7, 9, 0, 1, 11, 1, 1, 1, 1)
|
||||
MUX_CFG("V2_1710_GPIO10", F, 27, 1, 4, 3, 1, 4, 1, 1)
|
||||
MUX_CFG("N21_1710_GPIO14", 6, 9, 0, 1, 1, 1, 1, 1, 1)
|
||||
MUX_CFG("W15_1710_GPIO40", 9, 27, 7, 2, 5, 1, 2, 1, 1)
|
||||
|
||||
/* MPUIO */
|
||||
MUX_CFG("MPUIO2", 7, 18, 0, 1, 14, 1, NA, 0, 1)
|
||||
MUX_CFG("N15_1610_MPUIO2", 7, 18, 0, 1, 14, 1, 1, 0, 1)
|
||||
MUX_CFG("MPUIO4", 7, 15, 0, 1, 13, 1, NA, 0, 1)
|
||||
MUX_CFG("MPUIO5", 7, 12, 0, 1, 12, 1, NA, 0, 1)
|
||||
|
||||
MUX_CFG("T20_1610_MPUIO5", 7, 12, 0, 1, 12, 0, 3, 0, 1)
|
||||
MUX_CFG("W11_1610_MPUIO6", 10, 15, 2, 3, 8, 0, 3, 0, 1)
|
||||
MUX_CFG("V10_1610_MPUIO7", A, 24, 2, 2, 14, 0, 2, 0, 1)
|
||||
MUX_CFG("W11_1610_MPUIO9", 10, 15, 1, 3, 8, 0, 3, 0, 1)
|
||||
MUX_CFG("V10_1610_MPUIO10", A, 24, 1, 2, 14, 0, 2, 0, 1)
|
||||
MUX_CFG("W10_1610_MPUIO11", A, 18, 2, 2, 11, 0, 2, 0, 1)
|
||||
MUX_CFG("E20_1610_MPUIO13", 3, 21, 1, 0, 7, 0, 0, 0, 1)
|
||||
MUX_CFG("U20_1610_MPUIO14", 9, 6, 6, 0, 30, 0, 0, 0, 1)
|
||||
MUX_CFG("E19_1610_MPUIO15", 3, 18, 1, 0, 6, 0, 0, 0, 1)
|
||||
|
||||
/* MCBSP2 */
|
||||
MUX_CFG("MCBSP2_CLKR", C, 6, 0, 2, 27, 1, NA, 0, 1)
|
||||
MUX_CFG("MCBSP2_CLKX", C, 9, 0, 2, 29, 1, NA, 0, 1)
|
||||
MUX_CFG("MCBSP2_DR", C, 0, 0, 2, 26, 1, NA, 0, 1)
|
||||
MUX_CFG("MCBSP2_DX", C, 15, 0, 2, 31, 1, NA, 0, 1)
|
||||
MUX_CFG("MCBSP2_FSR", C, 12, 0, 2, 30, 1, NA, 0, 1)
|
||||
MUX_CFG("MCBSP2_FSX", C, 3, 0, 2, 27, 1, NA, 0, 1)
|
||||
|
||||
/* MCBSP3 NOTE: Mode must 1 for clock */
|
||||
MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
|
||||
|
||||
/* Misc ballouts */
|
||||
MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
|
||||
MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
|
||||
|
||||
/* OMAP-1610 MMC2 */
|
||||
MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
|
||||
MUX_CFG("V8_1610_MMC2_DAT1", B, 27, 6, 2, 25, 1, 2, 1, 1)
|
||||
MUX_CFG("W15_1610_MMC2_DAT2", 9, 12, 6, 2, 5, 1, 2, 1, 1)
|
||||
MUX_CFG("R10_1610_MMC2_DAT3", B, 18, 6, 2, 22, 1, 2, 1, 1)
|
||||
MUX_CFG("Y10_1610_MMC2_CLK", B, 3, 6, 2, 17, 0, 2, 0, 1)
|
||||
MUX_CFG("Y8_1610_MMC2_CMD", B, 24, 6, 2, 24, 1, 2, 1, 1)
|
||||
MUX_CFG("V9_1610_MMC2_CMDDIR", B, 12, 6, 2, 20, 0, 2, 1, 1)
|
||||
MUX_CFG("V5_1610_MMC2_DATDIR0", B, 15, 6, 2, 21, 0, 2, 1, 1)
|
||||
MUX_CFG("W19_1610_MMC2_DATDIR1", 8, 15, 6, 1, 23, 0, 1, 1, 1)
|
||||
MUX_CFG("R18_1610_MMC2_CLKIN", 7, 9, 6, 1, 11, 0, 1, 11, 1)
|
||||
|
||||
/* OMAP-1610 External Trace Interface */
|
||||
MUX_CFG("M19_1610_ETM_PSTAT0", 5, 27, 1, 0, 29, 0, 0, 0, 1)
|
||||
MUX_CFG("L15_1610_ETM_PSTAT1", 5, 24, 1, 0, 28, 0, 0, 0, 1)
|
||||
MUX_CFG("L18_1610_ETM_PSTAT2", 5, 21, 1, 0, 27, 0, 0, 0, 1)
|
||||
MUX_CFG("L19_1610_ETM_D0", 5, 18, 1, 0, 26, 0, 0, 0, 1)
|
||||
MUX_CFG("J19_1610_ETM_D6", 5, 0, 1, 0, 20, 0, 0, 0, 1)
|
||||
MUX_CFG("J18_1610_ETM_D7", 5, 27, 1, 0, 19, 0, 0, 0, 1)
|
||||
|
||||
/* OMAP16XX GPIO */
|
||||
MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1)
|
||||
MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1)
|
||||
MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1)
|
||||
MUX_CFG("N20_1610_GPIO11", 6, 18, 0, 1, 4, 0, 1, 1, 1)
|
||||
MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1)
|
||||
MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1)
|
||||
MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1)
|
||||
MUX_CFG("AA20_1610_GPIO_41", 9, 9, 7, 1, 31, 0, 1, 1, 1)
|
||||
MUX_CFG("W19_1610_GPIO48", 8, 15, 7, 1, 23, 1, 1, 0, 1)
|
||||
MUX_CFG("M7_1610_GPIO62", 10, 0, 0, 4, 24, 0, 4, 0, 1)
|
||||
MUX_CFG("V14_16XX_GPIO37", 9, 18, 7, 2, 2, 0, 2, 2, 0)
|
||||
MUX_CFG("R9_16XX_GPIO18", C, 18, 7, 3, 0, 0, 3, 0, 0)
|
||||
MUX_CFG("L14_16XX_GPIO49", 6, 3, 7, 0, 31, 0, 0, 31, 0)
|
||||
|
||||
/* OMAP-1610 uWire */
|
||||
MUX_CFG("V19_1610_UWIRE_SCLK", 8, 6, 0, 1, 20, 0, 1, 1, 1)
|
||||
MUX_CFG("U18_1610_UWIRE_SDI", 8, 0, 0, 1, 18, 0, 1, 1, 1)
|
||||
MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1)
|
||||
MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1)
|
||||
MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
|
||||
MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
|
||||
|
||||
/* OMAP-1610 Flash */
|
||||
MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1)
|
||||
|
||||
/* First MMC interface, same on 1510, 1610 and 1710 */
|
||||
MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1)
|
||||
MUX_CFG("MMC_DAT1", A, 24, 0, 2, 14, 1, 2, 1, 1)
|
||||
MUX_CFG("MMC_DAT2", A, 18, 0, 2, 12, 1, 2, 1, 1)
|
||||
MUX_CFG("MMC_DAT0", B, 0, 0, 2, 16, 1, 2, 1, 1)
|
||||
MUX_CFG("MMC_CLK", A, 21, 0, NA, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("MMC_DAT3", 10, 15, 0, 3, 8, 1, 3, 1, 1)
|
||||
MUX_CFG("M15_1710_MMC_CLKI", 6, 21, 2, 0, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("P19_1710_MMC_CMDDIR", 6, 24, 6, 0, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("P20_1710_MMC_DATDIR0", 6, 27, 5, 0, 0, 0, NA, 0, 1)
|
||||
|
||||
/* OMAP-1610 USB0 alternate configuration */
|
||||
MUX_CFG("W9_USB0_TXEN", B, 9, 5, 2, 19, 0, 2, 0, 1)
|
||||
MUX_CFG("AA9_USB0_VP", B, 6, 5, 2, 18, 0, 2, 0, 1)
|
||||
MUX_CFG("Y5_USB0_RCV", C, 21, 5, 3, 1, 0, 1, 0, 1)
|
||||
MUX_CFG("R9_USB0_VM", C, 18, 5, 3, 0, 0, 3, 0, 1)
|
||||
MUX_CFG("V6_USB0_TXD", C, 27, 5, 3, 3, 0, 3, 0, 1)
|
||||
MUX_CFG("W5_USB0_SE0", C, 24, 5, 3, 2, 0, 3, 0, 1)
|
||||
MUX_CFG("V9_USB0_SPEED", B, 12, 5, 2, 20, 0, 2, 0, 1)
|
||||
MUX_CFG("Y10_USB0_SUSP", B, 3, 5, 2, 17, 0, 2, 0, 1)
|
||||
|
||||
/* USB2 interface */
|
||||
MUX_CFG("W9_USB2_TXEN", B, 9, 1, NA, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("AA9_USB2_VP", B, 6, 1, NA, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("Y5_USB2_RCV", C, 21, 1, NA, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("R9_USB2_VM", C, 18, 1, NA, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("V6_USB2_TXD", C, 27, 2, NA, 0, 0, NA, 0, 1)
|
||||
MUX_CFG("W5_USB2_SE0", C, 24, 2, NA, 0, 0, NA, 0, 1)
|
||||
|
||||
/* 16XX UART */
|
||||
MUX_CFG("R13_1610_UART1_TX", A, 12, 6, 2, 10, 0, 2, 10, 1)
|
||||
MUX_CFG("V14_16XX_UART1_RX", 9, 18, 0, 2, 2, 0, 2, 2, 1)
|
||||
MUX_CFG("R14_1610_UART1_CTS", 9, 15, 0, 2, 1, 0, 2, 1, 1)
|
||||
MUX_CFG("AA15_1610_UART1_RTS", 9, 12, 1, 2, 0, 0, 2, 0, 1)
|
||||
MUX_CFG("R9_16XX_UART2_RX", C, 18, 0, 3, 0, 0, 3, 0, 1)
|
||||
MUX_CFG("L14_16XX_UART3_RX", 6, 3, 0, 0, 31, 0, 0, 31, 1)
|
||||
|
||||
/* I2C interface */
|
||||
MUX_CFG("I2C_SCL", 7, 24, 0, NA, 0, 0, NA, 0, 0)
|
||||
MUX_CFG("I2C_SDA", 7, 27, 0, NA, 0, 0, NA, 0, 0)
|
||||
|
||||
/* Keypad */
|
||||
MUX_CFG("F18_1610_KBC0", 3, 15, 0, 0, 5, 1, 0, 0, 0)
|
||||
MUX_CFG("D20_1610_KBC1", 3, 12, 0, 0, 4, 1, 0, 0, 0)
|
||||
MUX_CFG("D19_1610_KBC2", 3, 9, 0, 0, 3, 1, 0, 0, 0)
|
||||
MUX_CFG("E18_1610_KBC3", 3, 6, 0, 0, 2, 1, 0, 0, 0)
|
||||
MUX_CFG("C21_1610_KBC4", 3, 3, 0, 0, 1, 1, 0, 0, 0)
|
||||
MUX_CFG("G18_1610_KBR0", 4, 0, 0, 0, 10, 1, 0, 1, 0)
|
||||
MUX_CFG("F19_1610_KBR1", 3, 27, 0, 0, 9, 1, 0, 1, 0)
|
||||
MUX_CFG("H14_1610_KBR2", 3, 24, 0, 0, 8, 1, 0, 1, 0)
|
||||
MUX_CFG("E20_1610_KBR3", 3, 21, 0, 0, 7, 1, 0, 1, 0)
|
||||
MUX_CFG("E19_1610_KBR4", 3, 18, 0, 0, 6, 1, 0, 1, 0)
|
||||
MUX_CFG("N19_1610_KBR5", 6, 12, 1, 1, 2, 1, 1, 1, 0)
|
||||
|
||||
/* Power management */
|
||||
MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0)
|
||||
|
||||
/* MCLK Settings */
|
||||
MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0)
|
||||
MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0)
|
||||
MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0)
|
||||
MUX_CFG("R10_1610_MCLK_OFF", B, 18, 6, 2, 22, 1, 2, 1, 1)
|
||||
|
||||
/* CompactFlash controller, conflicts with MMC1 */
|
||||
MUX_CFG("P11_1610_CF_CD2", A, 27, 3, 2, 15, 1, 2, 1, 1)
|
||||
MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1)
|
||||
MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1)
|
||||
MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1)
|
||||
MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1)
|
||||
};
|
||||
#endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
|
||||
|
||||
int __init omap1_mux_init(void)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP730
|
||||
omap_mux_register(omap730_pins, ARRAY_SIZE(omap730_pins));
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
|
||||
omap_mux_register(omap1xxx_pins, ARRAY_SIZE(omap1xxx_pins));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -109,9 +109,10 @@ static struct platform_device serial_device = {
|
||||
* By default UART2 does not work on Innovator-1510 if you have
|
||||
* USB OHCI enabled. To use UART2, you must disable USB2 first.
|
||||
*/
|
||||
void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
|
||||
void __init omap_serial_init(void)
|
||||
{
|
||||
int i;
|
||||
const struct omap_uart_config *info;
|
||||
|
||||
if (cpu_is_omap730()) {
|
||||
serial_platform_data[0].regshift = 0;
|
||||
@ -126,10 +127,14 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
|
||||
serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
|
||||
}
|
||||
|
||||
info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
|
||||
if (info == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
|
||||
unsigned char reg;
|
||||
|
||||
if (ports[i] == 0) {
|
||||
if (!((1 << i) & info->enabled_uarts)) {
|
||||
serial_platform_data[i].membase = NULL;
|
||||
serial_platform_data[i].mapbase = 0;
|
||||
continue;
|
||||
|
@ -226,8 +226,8 @@ unsigned long long sched_clock(void)
|
||||
|
||||
#ifdef CONFIG_OMAP_32K_TIMER
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#error OMAP 32KHz timer does not currently work on 1510!
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
#error OMAP 32KHz timer does not currently work on 15XX!
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
22
arch/arm/mach-omap2/Kconfig
Normal file
22
arch/arm/mach-omap2/Kconfig
Normal file
@ -0,0 +1,22 @@
|
||||
comment "OMAP Core Type"
|
||||
depends on ARCH_OMAP2
|
||||
|
||||
config ARCH_OMAP24XX
|
||||
bool "OMAP24xx Based System"
|
||||
depends on ARCH_OMAP2
|
||||
|
||||
config ARCH_OMAP2420
|
||||
bool "OMAP2420 support"
|
||||
depends on ARCH_OMAP24XX
|
||||
|
||||
comment "OMAP Board Type"
|
||||
depends on ARCH_OMAP2
|
||||
|
||||
config MACH_OMAP_GENERIC
|
||||
bool "Generic OMAP board"
|
||||
depends on ARCH_OMAP2 && ARCH_OMAP24XX
|
||||
|
||||
config MACH_OMAP_H4
|
||||
bool "OMAP 2420 H4 board"
|
||||
depends on ARCH_OMAP2 && ARCH_OMAP24XX
|
||||
|
13
arch/arm/mach-omap2/Makefile
Normal file
13
arch/arm/mach-omap2/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
#
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
# Common support
|
||||
obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o
|
||||
|
||||
obj-$(CONFIG_OMAP_MPU_TIMER) += timer-gp.o
|
||||
|
||||
# Specific board support
|
||||
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
|
||||
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
|
||||
|
3
arch/arm/mach-omap2/Makefile.boot
Normal file
3
arch/arm/mach-omap2/Makefile.boot
Normal file
@ -0,0 +1,3 @@
|
||||
zreladdr-y := 0x80008000
|
||||
params_phys-y := 0x80000100
|
||||
initrd_phys-y := 0x80800000
|
80
arch/arm/mach-omap2/board-generic.c
Normal file
80
arch/arm/mach-omap2/board-generic.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap/omap2/board-generic.c
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Author: Paul Mundt <paul.mundt@nokia.com>
|
||||
*
|
||||
* Modified from mach-omap/omap1/board-generic.c
|
||||
*
|
||||
* Code for generic OMAP2 board. Should work on many OMAP2 systems where
|
||||
* the bootloader passes the board-specific data to the kernel.
|
||||
* Do not put any board specific code to this file; create a new machine
|
||||
* type if you need custom low-level initializations.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
|
||||
static void __init omap_generic_init_irq(void)
|
||||
{
|
||||
omap_init_irq();
|
||||
}
|
||||
|
||||
static struct omap_uart_config generic_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_mmc_config generic_mmc_config __initdata = {
|
||||
.mmc [0] = {
|
||||
.enabled = 0,
|
||||
.wire4 = 0,
|
||||
.wp_pin = -1,
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel generic_config[] = {
|
||||
{ OMAP_TAG_UART, &generic_uart_config },
|
||||
{ OMAP_TAG_MMC, &generic_mmc_config },
|
||||
};
|
||||
|
||||
static void __init omap_generic_init(void)
|
||||
{
|
||||
omap_board_config = generic_config;
|
||||
omap_board_config_size = ARRAY_SIZE(generic_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init omap_generic_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
|
||||
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
|
||||
.phys_ram = 0x80000000,
|
||||
.phys_io = 0x48000000,
|
||||
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x80000100,
|
||||
.map_io = omap_generic_map_io,
|
||||
.init_irq = omap_generic_init_irq,
|
||||
.init_machine = omap_generic_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
197
arch/arm/mach-omap2/board-h4.c
Normal file
197
arch/arm/mach-omap2/board-h4.c
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap/omap2/board-h4.c
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Author: Paul Mundt <paul.mundt@nokia.com>
|
||||
*
|
||||
* Modified from mach-omap/omap1/board-generic.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/usb.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/prcm.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
static struct mtd_partition h4_partitions[] = {
|
||||
/* bootloader (U-Boot, etc) in first sector */
|
||||
{
|
||||
.name = "bootloader",
|
||||
.offset = 0,
|
||||
.size = SZ_128K,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
},
|
||||
/* bootloader params in the next sector */
|
||||
{
|
||||
.name = "params",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_128K,
|
||||
.mask_flags = 0,
|
||||
},
|
||||
/* kernel */
|
||||
{
|
||||
.name = "kernel",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = SZ_2M,
|
||||
.mask_flags = 0
|
||||
},
|
||||
/* file system */
|
||||
{
|
||||
.name = "filesystem",
|
||||
.offset = MTDPART_OFS_APPEND,
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.mask_flags = 0
|
||||
}
|
||||
};
|
||||
|
||||
static struct flash_platform_data h4_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.width = 2,
|
||||
.parts = h4_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h4_partitions),
|
||||
};
|
||||
|
||||
static struct resource h4_flash_resource = {
|
||||
.start = H4_CS0_BASE,
|
||||
.end = H4_CS0_BASE + SZ_64M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
static struct platform_device h4_flash_device = {
|
||||
.name = "omapflash",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &h4_flash_data,
|
||||
},
|
||||
.num_resources = 1,
|
||||
.resource = &h4_flash_resource,
|
||||
};
|
||||
|
||||
static struct resource h4_smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = OMAP24XX_ETHR_START, /* Physical */
|
||||
.end = OMAP24XX_ETHR_START + 0xf,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
|
||||
.end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device h4_smc91x_device = {
|
||||
.name = "smc91x",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(h4_smc91x_resources),
|
||||
.resource = h4_smc91x_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *h4_devices[] __initdata = {
|
||||
&h4_smc91x_device,
|
||||
&h4_flash_device,
|
||||
};
|
||||
|
||||
static inline void __init h4_init_smc91x(void)
|
||||
{
|
||||
/* Make sure CS1 timings are correct */
|
||||
GPMC_CONFIG1_1 = 0x00011200;
|
||||
GPMC_CONFIG2_1 = 0x001f1f01;
|
||||
GPMC_CONFIG3_1 = 0x00080803;
|
||||
GPMC_CONFIG4_1 = 0x1c091c09;
|
||||
GPMC_CONFIG5_1 = 0x041f1f1f;
|
||||
GPMC_CONFIG6_1 = 0x000004c4;
|
||||
GPMC_CONFIG7_1 = 0x00000f40 | (0x08000000 >> 24);
|
||||
udelay(100);
|
||||
|
||||
omap_cfg_reg(M15_24XX_GPIO92);
|
||||
if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) {
|
||||
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
|
||||
OMAP24XX_ETHR_GPIO_IRQ);
|
||||
return;
|
||||
}
|
||||
omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1);
|
||||
}
|
||||
|
||||
static void __init omap_h4_init_irq(void)
|
||||
{
|
||||
omap_init_irq();
|
||||
omap_gpio_init();
|
||||
h4_init_smc91x();
|
||||
}
|
||||
|
||||
static struct omap_uart_config h4_uart_config __initdata = {
|
||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||
};
|
||||
|
||||
static struct omap_mmc_config h4_mmc_config __initdata = {
|
||||
.mmc [0] = {
|
||||
.enabled = 1,
|
||||
.wire4 = 1,
|
||||
.wp_pin = -1,
|
||||
.power_pin = -1,
|
||||
.switch_pin = -1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct omap_lcd_config h4_lcd_config __initdata = {
|
||||
.panel_name = "h4",
|
||||
.ctrl_name = "internal",
|
||||
};
|
||||
|
||||
static struct omap_board_config_kernel h4_config[] = {
|
||||
{ OMAP_TAG_UART, &h4_uart_config },
|
||||
{ OMAP_TAG_MMC, &h4_mmc_config },
|
||||
{ OMAP_TAG_LCD, &h4_lcd_config },
|
||||
};
|
||||
|
||||
static void __init omap_h4_init(void)
|
||||
{
|
||||
/*
|
||||
* Make sure the serial ports are muxed on at this point.
|
||||
* You have to mux them off in device drivers later on
|
||||
* if not needed.
|
||||
*/
|
||||
platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
|
||||
omap_board_config = h4_config;
|
||||
omap_board_config_size = ARRAY_SIZE(h4_config);
|
||||
omap_serial_init();
|
||||
}
|
||||
|
||||
static void __init omap_h4_map_io(void)
|
||||
{
|
||||
omap_map_common_io();
|
||||
}
|
||||
|
||||
MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
|
||||
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
|
||||
.phys_ram = 0x80000000,
|
||||
.phys_io = 0x48000000,
|
||||
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0x80000100,
|
||||
.map_io = omap_h4_map_io,
|
||||
.init_irq = omap_h4_init_irq,
|
||||
.init_machine = omap_h4_init,
|
||||
.timer = &omap_timer,
|
||||
MACHINE_END
|
1129
arch/arm/mach-omap2/clock.c
Normal file
1129
arch/arm/mach-omap2/clock.c
Normal file
File diff suppressed because it is too large
Load Diff
2103
arch/arm/mach-omap2/clock.h
Normal file
2103
arch/arm/mach-omap2/clock.h
Normal file
File diff suppressed because it is too large
Load Diff
89
arch/arm/mach-omap2/devices.c
Normal file
89
arch/arm/mach-omap2/devices.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/devices.c
|
||||
*
|
||||
* OMAP2 platform device setup/initialization
|
||||
*
|
||||
* 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/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
extern void omap_nop_release(struct device *dev);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
|
||||
|
||||
#define OMAP2_I2C_BASE2 0x48072000
|
||||
#define OMAP2_I2C_INT2 57
|
||||
|
||||
static struct resource i2c_resources2[] = {
|
||||
{
|
||||
.start = OMAP2_I2C_BASE2,
|
||||
.end = OMAP2_I2C_BASE2 + 0x3f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = OMAP2_I2C_INT2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device omap_i2c_device2 = {
|
||||
.name = "i2c_omap",
|
||||
.id = 2,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(i2c_resources2),
|
||||
.resource = i2c_resources2,
|
||||
};
|
||||
|
||||
/* See also arch/arm/plat-omap/devices.c for first I2C on 24xx */
|
||||
static void omap_init_i2c(void)
|
||||
{
|
||||
/* REVISIT: Second I2C not in use on H4? */
|
||||
if (machine_is_omap_h4())
|
||||
return;
|
||||
|
||||
omap_cfg_reg(J15_24XX_I2C2_SCL);
|
||||
omap_cfg_reg(H19_24XX_I2C2_SDA);
|
||||
(void) platform_device_register(&omap_i2c_device2);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void omap_init_i2c(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int __init omap2_init_devices(void)
|
||||
{
|
||||
/* please keep these calls, and their implementations above,
|
||||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_init_i2c();
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(omap2_init_devices);
|
||||
|
124
arch/arm/mach-omap2/id.c
Normal file
124
arch/arm/mach-omap2/id.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/id.c
|
||||
*
|
||||
* OMAP2 CPU identification code
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Written by Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#define OMAP24XX_TAP_BASE io_p2v(0x48014000)
|
||||
|
||||
#define OMAP_TAP_IDCODE 0x0204
|
||||
#define OMAP_TAP_PROD_ID 0x0208
|
||||
|
||||
#define OMAP_TAP_DIE_ID_0 0x0218
|
||||
#define OMAP_TAP_DIE_ID_1 0x021C
|
||||
#define OMAP_TAP_DIE_ID_2 0x0220
|
||||
#define OMAP_TAP_DIE_ID_3 0x0224
|
||||
|
||||
/* system_rev fields for OMAP2 processors:
|
||||
* CPU id bits [31:16],
|
||||
* CPU device type [15:12], (unprg,normal,POP)
|
||||
* CPU revision [11:08]
|
||||
* CPU class bits [07:00]
|
||||
*/
|
||||
|
||||
struct omap_id {
|
||||
u16 hawkeye; /* Silicon type (Hawkeye id) */
|
||||
u8 dev; /* Device type from production_id reg */
|
||||
u32 type; /* combined type id copied to system_rev */
|
||||
};
|
||||
|
||||
/* Register values to detect the OMAP version */
|
||||
static struct omap_id omap_ids[] __initdata = {
|
||||
{ .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200000 },
|
||||
{ .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201000 },
|
||||
{ .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202000 },
|
||||
{ .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220000 },
|
||||
{ .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230000 },
|
||||
{ .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 },
|
||||
};
|
||||
|
||||
static u32 __init read_tap_reg(int reg)
|
||||
{
|
||||
return __raw_readl(OMAP24XX_TAP_BASE + reg);
|
||||
}
|
||||
|
||||
void __init omap2_check_revision(void)
|
||||
{
|
||||
int i, j;
|
||||
u32 idcode;
|
||||
u32 prod_id;
|
||||
u16 hawkeye;
|
||||
u8 dev_type;
|
||||
u8 rev;
|
||||
|
||||
idcode = read_tap_reg(OMAP_TAP_IDCODE);
|
||||
prod_id = read_tap_reg(OMAP_TAP_PROD_ID);
|
||||
hawkeye = (idcode >> 12) & 0xffff;
|
||||
rev = (idcode >> 28) & 0x0f;
|
||||
dev_type = (prod_id >> 16) & 0x0f;
|
||||
|
||||
#ifdef DEBUG
|
||||
printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
|
||||
idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
|
||||
printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n",
|
||||
read_tap_reg(OMAP_TAP_DIE_ID_0));
|
||||
printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
|
||||
read_tap_reg(OMAP_TAP_DIE_ID_1),
|
||||
(read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
|
||||
printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n",
|
||||
read_tap_reg(OMAP_TAP_DIE_ID_2));
|
||||
printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n",
|
||||
read_tap_reg(OMAP_TAP_DIE_ID_3));
|
||||
printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
|
||||
prod_id, dev_type);
|
||||
#endif
|
||||
|
||||
/* Check hawkeye ids */
|
||||
for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
|
||||
if (hawkeye == omap_ids[i].hawkeye)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(omap_ids)) {
|
||||
printk(KERN_ERR "Unknown OMAP CPU id\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
|
||||
if (dev_type == omap_ids[j].dev)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == ARRAY_SIZE(omap_ids)) {
|
||||
printk(KERN_ERR "Unknown OMAP device type. "
|
||||
"Handling it as OMAP%04x\n",
|
||||
omap_ids[i].type >> 16);
|
||||
j = i;
|
||||
}
|
||||
system_rev = omap_ids[j].type;
|
||||
|
||||
system_rev |= rev << 8;
|
||||
|
||||
/* Add the cpu class info (24xx) */
|
||||
system_rev |= 0x24;
|
||||
|
||||
pr_info("OMAP%04x", system_rev >> 16);
|
||||
if ((system_rev >> 8) & 0x0f)
|
||||
printk("%x", (system_rev >> 8) & 0x0f);
|
||||
printk("\n");
|
||||
}
|
||||
|
53
arch/arm/mach-omap2/io.c
Normal file
53
arch/arm/mach-omap2/io.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/io.c
|
||||
*
|
||||
* OMAP2 I/O mapping code
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Author: Juha Yrjölä <juha.yrjola@nokia.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/mux.h>
|
||||
|
||||
extern void omap_sram_init(void);
|
||||
extern int omap2_clk_init(void);
|
||||
extern void omap2_check_revision(void);
|
||||
|
||||
/*
|
||||
* The machine specific code may provide the extra mapping besides the
|
||||
* default mapping provided here.
|
||||
*/
|
||||
static struct map_desc omap2_io_desc[] __initdata = {
|
||||
{
|
||||
.virtual = L3_24XX_VIRT,
|
||||
.pfn = __phys_to_pfn(L3_24XX_PHYS),
|
||||
.length = L3_24XX_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
{
|
||||
.virtual = L4_24XX_VIRT,
|
||||
.pfn = __phys_to_pfn(L4_24XX_PHYS),
|
||||
.length = L4_24XX_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
|
||||
void __init omap_map_common_io(void)
|
||||
{
|
||||
iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
|
||||
omap2_check_revision();
|
||||
omap_sram_init();
|
||||
omap2_mux_init();
|
||||
omap2_clk_init();
|
||||
}
|
149
arch/arm/mach-omap2/irq.c
Normal file
149
arch/arm/mach-omap2/irq.c
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap/omap2/irq.c
|
||||
*
|
||||
* Interrupt handler for OMAP2 boards.
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Author: Paul Mundt <paul.mundt@nokia.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define INTC_REVISION 0x0000
|
||||
#define INTC_SYSCONFIG 0x0010
|
||||
#define INTC_SYSSTATUS 0x0014
|
||||
#define INTC_CONTROL 0x0048
|
||||
#define INTC_MIR_CLEAR0 0x0088
|
||||
#define INTC_MIR_SET0 0x008c
|
||||
|
||||
/*
|
||||
* OMAP2 has a number of different interrupt controllers, each interrupt
|
||||
* controller is identified as its own "bank". Register definitions are
|
||||
* fairly consistent for each bank, but not all registers are implemented
|
||||
* for each bank.. when in doubt, consult the TRM.
|
||||
*/
|
||||
static struct omap_irq_bank {
|
||||
unsigned long base_reg;
|
||||
unsigned int nr_irqs;
|
||||
} __attribute__ ((aligned(4))) irq_banks[] = {
|
||||
{
|
||||
/* MPU INTC */
|
||||
.base_reg = OMAP24XX_IC_BASE,
|
||||
.nr_irqs = 96,
|
||||
}, {
|
||||
/* XXX: DSP INTC */
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Commented out for now until we fix the IVA clocking
|
||||
*/
|
||||
#ifdef CONFIG_ARCH_OMAP2420
|
||||
}, {
|
||||
/* IVA INTC (2420 only) */
|
||||
.base_reg = OMAP24XX_IVA_INTC_BASE,
|
||||
.nr_irqs = 16, /* Actually 32, but only 16 are used */
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/* XXX: FIQ and additional INTC support (only MPU at the moment) */
|
||||
static void omap_ack_irq(unsigned int irq)
|
||||
{
|
||||
omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
|
||||
}
|
||||
|
||||
static void omap_mask_irq(unsigned int irq)
|
||||
{
|
||||
int offset = (irq >> 5) << 5;
|
||||
|
||||
if (irq >= 64) {
|
||||
irq %= 64;
|
||||
} else if (irq >= 32) {
|
||||
irq %= 32;
|
||||
}
|
||||
|
||||
omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
|
||||
}
|
||||
|
||||
static void omap_unmask_irq(unsigned int irq)
|
||||
{
|
||||
int offset = (irq >> 5) << 5;
|
||||
|
||||
if (irq >= 64) {
|
||||
irq %= 64;
|
||||
} else if (irq >= 32) {
|
||||
irq %= 32;
|
||||
}
|
||||
|
||||
omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
|
||||
}
|
||||
|
||||
static void omap_mask_ack_irq(unsigned int irq)
|
||||
{
|
||||
omap_mask_irq(irq);
|
||||
omap_ack_irq(irq);
|
||||
}
|
||||
|
||||
static struct irqchip omap_irq_chip = {
|
||||
.ack = omap_mask_ack_irq,
|
||||
.mask = omap_mask_irq,
|
||||
.unmask = omap_unmask_irq,
|
||||
};
|
||||
|
||||
static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff;
|
||||
printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
|
||||
"(revision %ld.%ld) with %d interrupts\n",
|
||||
bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
|
||||
|
||||
tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG);
|
||||
tmp |= 1 << 1; /* soft reset */
|
||||
omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
|
||||
|
||||
while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
|
||||
/* Wait for reset to complete */;
|
||||
}
|
||||
|
||||
void __init omap_init_irq(void)
|
||||
{
|
||||
unsigned long nr_irqs = 0;
|
||||
unsigned int nr_banks = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
|
||||
struct omap_irq_bank *bank = irq_banks + i;
|
||||
|
||||
/* XXX */
|
||||
if (!bank->base_reg)
|
||||
continue;
|
||||
|
||||
omap_irq_bank_init_one(bank);
|
||||
|
||||
nr_irqs += bank->nr_irqs;
|
||||
nr_banks++;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
|
||||
nr_irqs, nr_banks, nr_banks > 1 ? "s" : "");
|
||||
|
||||
for (i = 0; i < nr_irqs; i++) {
|
||||
set_irq_chip(i, &omap_irq_chip);
|
||||
set_irq_handler(i, do_level_IRQ);
|
||||
set_irq_flags(i, IRQF_VALID);
|
||||
}
|
||||
}
|
||||
|
65
arch/arm/mach-omap2/mux.c
Normal file
65
arch/arm/mach-omap2/mux.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/mux.c
|
||||
*
|
||||
* OMAP1 pin multiplexing configurations
|
||||
*
|
||||
* Copyright (C) 2003 - 2005 Nokia Corporation
|
||||
*
|
||||
* Written by Tony Lindgren <tony.lindgren@nokia.com>
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/arch/mux.h>
|
||||
|
||||
#ifdef CONFIG_OMAP_MUX
|
||||
|
||||
/* NOTE: See mux.h for the enumeration */
|
||||
|
||||
struct pin_config __initdata_or_module omap24xx_pins[] = {
|
||||
/*
|
||||
* description mux mux pull pull debug
|
||||
* offset mode ena type
|
||||
*/
|
||||
|
||||
/* 24xx I2C */
|
||||
MUX_CFG_24XX("M19_24XX_I2C1_SCL", 0x111, 0, 0, 0, 1)
|
||||
MUX_CFG_24XX("L15_24XX_I2C1_SDA", 0x112, 0, 0, 0, 1)
|
||||
MUX_CFG_24XX("J15_24XX_I2C2_SCL", 0x113, 0, 0, 0, 1)
|
||||
MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1)
|
||||
|
||||
/* Menelaus interrupt */
|
||||
MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
|
||||
|
||||
/* 24xx GPIO */
|
||||
MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
|
||||
MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
|
||||
|
||||
};
|
||||
|
||||
int __init omap2_mux_init(void)
|
||||
{
|
||||
omap_mux_register(omap24xx_pins, ARRAY_SIZE(omap24xx_pins));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
419
arch/arm/mach-omap2/prcm.h
Normal file
419
arch/arm/mach-omap2/prcm.h
Normal file
@ -0,0 +1,419 @@
|
||||
/*
|
||||
* prcm.h - Access definations for use in OMAP24XX clock and power management
|
||||
*
|
||||
* Copyright (C) 2005 Texas Instruments, Inc.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
|
||||
#define __ASM_ARM_ARCH_DPM_PRCM_H
|
||||
|
||||
/* SET_PERFORMANCE_LEVEL PARAMETERS */
|
||||
#define PRCM_HALF_SPEED 1
|
||||
#define PRCM_FULL_SPEED 2
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#define PRCM_REG32(offset) __REG32(OMAP24XX_PRCM_BASE + (offset))
|
||||
|
||||
#define PRCM_REVISION PRCM_REG32(0x000)
|
||||
#define PRCM_SYSCONFIG PRCM_REG32(0x010)
|
||||
#define PRCM_IRQSTATUS_MPU PRCM_REG32(0x018)
|
||||
#define PRCM_IRQENABLE_MPU PRCM_REG32(0x01C)
|
||||
#define PRCM_VOLTCTRL PRCM_REG32(0x050)
|
||||
#define PRCM_VOLTST PRCM_REG32(0x054)
|
||||
#define PRCM_CLKSRC_CTRL PRCM_REG32(0x060)
|
||||
#define PRCM_CLKOUT_CTRL PRCM_REG32(0x070)
|
||||
#define PRCM_CLKEMUL_CTRL PRCM_REG32(0x078)
|
||||
#define PRCM_CLKCFG_CTRL PRCM_REG32(0x080)
|
||||
#define PRCM_CLKCFG_STATUS PRCM_REG32(0x084)
|
||||
#define PRCM_VOLTSETUP PRCM_REG32(0x090)
|
||||
#define PRCM_CLKSSETUP PRCM_REG32(0x094)
|
||||
#define PRCM_POLCTRL PRCM_REG32(0x098)
|
||||
|
||||
/* GENERAL PURPOSE */
|
||||
#define GENERAL_PURPOSE1 PRCM_REG32(0x0B0)
|
||||
#define GENERAL_PURPOSE2 PRCM_REG32(0x0B4)
|
||||
#define GENERAL_PURPOSE3 PRCM_REG32(0x0B8)
|
||||
#define GENERAL_PURPOSE4 PRCM_REG32(0x0BC)
|
||||
#define GENERAL_PURPOSE5 PRCM_REG32(0x0C0)
|
||||
#define GENERAL_PURPOSE6 PRCM_REG32(0x0C4)
|
||||
#define GENERAL_PURPOSE7 PRCM_REG32(0x0C8)
|
||||
#define GENERAL_PURPOSE8 PRCM_REG32(0x0CC)
|
||||
#define GENERAL_PURPOSE9 PRCM_REG32(0x0D0)
|
||||
#define GENERAL_PURPOSE10 PRCM_REG32(0x0D4)
|
||||
#define GENERAL_PURPOSE11 PRCM_REG32(0x0D8)
|
||||
#define GENERAL_PURPOSE12 PRCM_REG32(0x0DC)
|
||||
#define GENERAL_PURPOSE13 PRCM_REG32(0x0E0)
|
||||
#define GENERAL_PURPOSE14 PRCM_REG32(0x0E4)
|
||||
#define GENERAL_PURPOSE15 PRCM_REG32(0x0E8)
|
||||
#define GENERAL_PURPOSE16 PRCM_REG32(0x0EC)
|
||||
#define GENERAL_PURPOSE17 PRCM_REG32(0x0F0)
|
||||
#define GENERAL_PURPOSE18 PRCM_REG32(0x0F4)
|
||||
#define GENERAL_PURPOSE19 PRCM_REG32(0x0F8)
|
||||
#define GENERAL_PURPOSE20 PRCM_REG32(0x0FC)
|
||||
|
||||
/* MPU */
|
||||
#define CM_CLKSEL_MPU PRCM_REG32(0x140)
|
||||
#define CM_CLKSTCTRL_MPU PRCM_REG32(0x148)
|
||||
#define RM_RSTST_MPU PRCM_REG32(0x158)
|
||||
#define PM_WKDEP_MPU PRCM_REG32(0x1C8)
|
||||
#define PM_EVGENCTRL_MPU PRCM_REG32(0x1D4)
|
||||
#define PM_EVEGENONTIM_MPU PRCM_REG32(0x1D8)
|
||||
#define PM_EVEGENOFFTIM_MPU PRCM_REG32(0x1DC)
|
||||
#define PM_PWSTCTRL_MPU PRCM_REG32(0x1E0)
|
||||
#define PM_PWSTST_MPU PRCM_REG32(0x1E4)
|
||||
|
||||
/* CORE */
|
||||
#define CM_FCLKEN1_CORE PRCM_REG32(0x200)
|
||||
#define CM_FCLKEN2_CORE PRCM_REG32(0x204)
|
||||
#define CM_FCLKEN3_CORE PRCM_REG32(0x208)
|
||||
#define CM_ICLKEN1_CORE PRCM_REG32(0x210)
|
||||
#define CM_ICLKEN2_CORE PRCM_REG32(0x214)
|
||||
#define CM_ICLKEN3_CORE PRCM_REG32(0x218)
|
||||
#define CM_ICLKEN4_CORE PRCM_REG32(0x21C)
|
||||
#define CM_IDLEST1_CORE PRCM_REG32(0x220)
|
||||
#define CM_IDLEST2_CORE PRCM_REG32(0x224)
|
||||
#define CM_IDLEST3_CORE PRCM_REG32(0x228)
|
||||
#define CM_IDLEST4_CORE PRCM_REG32(0x22C)
|
||||
#define CM_AUTOIDLE1_CORE PRCM_REG32(0x230)
|
||||
#define CM_AUTOIDLE2_CORE PRCM_REG32(0x234)
|
||||
#define CM_AUTOIDLE3_CORE PRCM_REG32(0x238)
|
||||
#define CM_AUTOIDLE4_CORE PRCM_REG32(0x23C)
|
||||
#define CM_CLKSEL1_CORE PRCM_REG32(0x240)
|
||||
#define CM_CLKSEL2_CORE PRCM_REG32(0x244)
|
||||
#define CM_CLKSTCTRL_CORE PRCM_REG32(0x248)
|
||||
#define PM_WKEN1_CORE PRCM_REG32(0x2A0)
|
||||
#define PM_WKEN2_CORE PRCM_REG32(0x2A4)
|
||||
#define PM_WKST1_CORE PRCM_REG32(0x2B0)
|
||||
#define PM_WKST2_CORE PRCM_REG32(0x2B4)
|
||||
#define PM_WKDEP_CORE PRCM_REG32(0x2C8)
|
||||
#define PM_PWSTCTRL_CORE PRCM_REG32(0x2E0)
|
||||
#define PM_PWSTST_CORE PRCM_REG32(0x2E4)
|
||||
|
||||
/* GFX */
|
||||
#define CM_FCLKEN_GFX PRCM_REG32(0x300)
|
||||
#define CM_ICLKEN_GFX PRCM_REG32(0x310)
|
||||
#define CM_IDLEST_GFX PRCM_REG32(0x320)
|
||||
#define CM_CLKSEL_GFX PRCM_REG32(0x340)
|
||||
#define CM_CLKSTCTRL_GFX PRCM_REG32(0x348)
|
||||
#define RM_RSTCTRL_GFX PRCM_REG32(0x350)
|
||||
#define RM_RSTST_GFX PRCM_REG32(0x358)
|
||||
#define PM_WKDEP_GFX PRCM_REG32(0x3C8)
|
||||
#define PM_PWSTCTRL_GFX PRCM_REG32(0x3E0)
|
||||
#define PM_PWSTST_GFX PRCM_REG32(0x3E4)
|
||||
|
||||
/* WAKE-UP */
|
||||
#define CM_FCLKEN_WKUP PRCM_REG32(0x400)
|
||||
#define CM_ICLKEN_WKUP PRCM_REG32(0x410)
|
||||
#define CM_IDLEST_WKUP PRCM_REG32(0x420)
|
||||
#define CM_AUTOIDLE_WKUP PRCM_REG32(0x430)
|
||||
#define CM_CLKSEL_WKUP PRCM_REG32(0x440)
|
||||
#define RM_RSTCTRL_WKUP PRCM_REG32(0x450)
|
||||
#define RM_RSTTIME_WKUP PRCM_REG32(0x454)
|
||||
#define RM_RSTST_WKUP PRCM_REG32(0x458)
|
||||
#define PM_WKEN_WKUP PRCM_REG32(0x4A0)
|
||||
#define PM_WKST_WKUP PRCM_REG32(0x4B0)
|
||||
|
||||
/* CLOCKS */
|
||||
#define CM_CLKEN_PLL PRCM_REG32(0x500)
|
||||
#define CM_IDLEST_CKGEN PRCM_REG32(0x520)
|
||||
#define CM_AUTOIDLE_PLL PRCM_REG32(0x530)
|
||||
#define CM_CLKSEL1_PLL PRCM_REG32(0x540)
|
||||
#define CM_CLKSEL2_PLL PRCM_REG32(0x544)
|
||||
|
||||
/* DSP */
|
||||
#define CM_FCLKEN_DSP PRCM_REG32(0x800)
|
||||
#define CM_ICLKEN_DSP PRCM_REG32(0x810)
|
||||
#define CM_IDLEST_DSP PRCM_REG32(0x820)
|
||||
#define CM_AUTOIDLE_DSP PRCM_REG32(0x830)
|
||||
#define CM_CLKSEL_DSP PRCM_REG32(0x840)
|
||||
#define CM_CLKSTCTRL_DSP PRCM_REG32(0x848)
|
||||
#define RM_RSTCTRL_DSP PRCM_REG32(0x850)
|
||||
#define RM_RSTST_DSP PRCM_REG32(0x858)
|
||||
#define PM_WKEN_DSP PRCM_REG32(0x8A0)
|
||||
#define PM_WKDEP_DSP PRCM_REG32(0x8C8)
|
||||
#define PM_PWSTCTRL_DSP PRCM_REG32(0x8E0)
|
||||
#define PM_PWSTST_DSP PRCM_REG32(0x8E4)
|
||||
#define PRCM_IRQSTATUS_DSP PRCM_REG32(0x8F0)
|
||||
#define PRCM_IRQENABLE_DSP PRCM_REG32(0x8F4)
|
||||
|
||||
/* IVA */
|
||||
#define PRCM_IRQSTATUS_IVA PRCM_REG32(0x8F8)
|
||||
#define PRCM_IRQENABLE_IVA PRCM_REG32(0x8FC)
|
||||
|
||||
/* Modem on 2430 */
|
||||
#define CM_FCLKEN_MDM PRCM_REG32(0xC00)
|
||||
#define CM_ICLKEN_MDM PRCM_REG32(0xC10)
|
||||
#define CM_IDLEST_MDM PRCM_REG32(0xC20)
|
||||
#define CM_CLKSEL_MDM PRCM_REG32(0xC40)
|
||||
|
||||
/* FIXME: Move to header for 2430 */
|
||||
#define DISP_BASE (OMAP24XX_L4_IO_BASE+0x50000)
|
||||
#define DISP_REG32(offset) __REG32(DISP_BASE + (offset))
|
||||
|
||||
#define GPMC_BASE (OMAP24XX_GPMC_BASE)
|
||||
#define GPMC_REG32(offset) __REG32(GPMC_BASE + (offset))
|
||||
|
||||
#define GPT1_BASE (OMAP24XX_GPT1)
|
||||
#define GPT1_REG32(offset) __REG32(GPT1_BASE + (offset))
|
||||
|
||||
/* Misc sysconfig */
|
||||
#define DISPC_SYSCONFIG DISP_REG32(0x410)
|
||||
#define SPI_BASE (OMAP24XX_L4_IO_BASE+0x98000)
|
||||
#define MCSPI1_SYSCONFIG __REG32(SPI_BASE + 0x10)
|
||||
#define MCSPI2_SYSCONFIG __REG32(SPI_BASE+0x2000 + 0x10)
|
||||
|
||||
//#define DSP_MMU_SYSCONFIG 0x5A000010
|
||||
#define CAMERA_MMU_SYSCONFIG __REG32(DISP_BASE+0x2C10)
|
||||
//#define IVA_MMU_SYSCONFIG 0x5D000010
|
||||
//#define DSP_DMA_SYSCONFIG 0x00FCC02C
|
||||
#define CAMERA_DMA_SYSCONFIG __REG32(DISP_BASE+0x282C)
|
||||
#define SYSTEM_DMA_SYSCONFIG __REG32(DISP_BASE+0x602C)
|
||||
#define GPMC_SYSCONFIG GPMC_REG32(0x010)
|
||||
#define MAILBOXES_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x94010)
|
||||
#define UART1_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6A054)
|
||||
#define UART2_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6C054)
|
||||
#define UART3_SYSCONFIG __REG32(OMAP24XX_L4_IO_BASE+0x6E054)
|
||||
//#define IVA_SYSCONFIG 0x5C060010
|
||||
#define SDRC_SYSCONFIG __REG32(OMAP24XX_SDRC_BASE+0x10)
|
||||
#define SMS_SYSCONFIG __REG32(OMAP24XX_SMS_BASE+0x10)
|
||||
#define SSI_SYSCONFIG __REG32(DISP_BASE+0x8010)
|
||||
//#define VLYNQ_SYSCONFIG 0x67FFFE10
|
||||
|
||||
/* rkw - good cannidates for PM_ to start what nm was trying */
|
||||
#define OMAP24XX_GPT2 (OMAP24XX_L4_IO_BASE+0x2A000)
|
||||
#define OMAP24XX_GPT3 (OMAP24XX_L4_IO_BASE+0x78000)
|
||||
#define OMAP24XX_GPT4 (OMAP24XX_L4_IO_BASE+0x7A000)
|
||||
#define OMAP24XX_GPT5 (OMAP24XX_L4_IO_BASE+0x7C000)
|
||||
#define OMAP24XX_GPT6 (OMAP24XX_L4_IO_BASE+0x7E000)
|
||||
#define OMAP24XX_GPT7 (OMAP24XX_L4_IO_BASE+0x80000)
|
||||
#define OMAP24XX_GPT8 (OMAP24XX_L4_IO_BASE+0x82000)
|
||||
#define OMAP24XX_GPT9 (OMAP24XX_L4_IO_BASE+0x84000)
|
||||
#define OMAP24XX_GPT10 (OMAP24XX_L4_IO_BASE+0x86000)
|
||||
#define OMAP24XX_GPT11 (OMAP24XX_L4_IO_BASE+0x88000)
|
||||
#define OMAP24XX_GPT12 (OMAP24XX_L4_IO_BASE+0x8A000)
|
||||
|
||||
#define GPTIMER1_SYSCONFIG GPT1_REG32(0x010)
|
||||
#define GPTIMER2_SYSCONFIG __REG32(OMAP24XX_GPT2 + 0x10)
|
||||
#define GPTIMER3_SYSCONFIG __REG32(OMAP24XX_GPT3 + 0x10)
|
||||
#define GPTIMER4_SYSCONFIG __REG32(OMAP24XX_GPT4 + 0x10)
|
||||
#define GPTIMER5_SYSCONFIG __REG32(OMAP24XX_GPT5 + 0x10)
|
||||
#define GPTIMER6_SYSCONFIG __REG32(OMAP24XX_GPT6 + 0x10)
|
||||
#define GPTIMER7_SYSCONFIG __REG32(OMAP24XX_GPT7 + 0x10)
|
||||
#define GPTIMER8_SYSCONFIG __REG32(OMAP24XX_GPT8 + 0x10)
|
||||
#define GPTIMER9_SYSCONFIG __REG32(OMAP24XX_GPT9 + 0x10)
|
||||
#define GPTIMER10_SYSCONFIG __REG32(OMAP24XX_GPT10 + 0x10)
|
||||
#define GPTIMER11_SYSCONFIG __REG32(OMAP24XX_GPT11 + 0x10)
|
||||
#define GPTIMER12_SYSCONFIG __REG32(OMAP24XX_GPT12 + 0x10)
|
||||
|
||||
#define GPIOX_BASE(X) (OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
|
||||
|
||||
#define GPIO1_SYSCONFIG __REG32((GPIOX_BASE(1)+0x10))
|
||||
#define GPIO2_SYSCONFIG __REG32((GPIOX_BASE(2)+0x10))
|
||||
#define GPIO3_SYSCONFIG __REG32((GPIOX_BASE(3)+0x10))
|
||||
#define GPIO4_SYSCONFIG __REG32((GPIOX_BASE(4)+0x10))
|
||||
|
||||
/* GP TIMER 1 */
|
||||
#define GPTIMER1_TISTAT GPT1_REG32(0x014)
|
||||
#define GPTIMER1_TISR GPT1_REG32(0x018)
|
||||
#define GPTIMER1_TIER GPT1_REG32(0x01C)
|
||||
#define GPTIMER1_TWER GPT1_REG32(0x020)
|
||||
#define GPTIMER1_TCLR GPT1_REG32(0x024)
|
||||
#define GPTIMER1_TCRR GPT1_REG32(0x028)
|
||||
#define GPTIMER1_TLDR GPT1_REG32(0x02C)
|
||||
#define GPTIMER1_TTGR GPT1_REG32(0x030)
|
||||
#define GPTIMER1_TWPS GPT1_REG32(0x034)
|
||||
#define GPTIMER1_TMAR GPT1_REG32(0x038)
|
||||
#define GPTIMER1_TCAR1 GPT1_REG32(0x03C)
|
||||
#define GPTIMER1_TSICR GPT1_REG32(0x040)
|
||||
#define GPTIMER1_TCAR2 GPT1_REG32(0x044)
|
||||
|
||||
/* rkw -- base fix up please... */
|
||||
#define GPTIMER3_TISR __REG32(OMAP24XX_L4_IO_BASE+0x78018)
|
||||
|
||||
/* SDRC */
|
||||
#define SDRC_DLLA_CTRL __REG32(OMAP24XX_SDRC_BASE+0x060)
|
||||
#define SDRC_DLLA_STATUS __REG32(OMAP24XX_SDRC_BASE+0x064)
|
||||
#define SDRC_DLLB_CTRL __REG32(OMAP24XX_SDRC_BASE+0x068)
|
||||
#define SDRC_DLLB_STATUS __REG32(OMAP24XX_SDRC_BASE+0x06C)
|
||||
#define SDRC_POWER __REG32(OMAP24XX_SDRC_BASE+0x070)
|
||||
#define SDRC_MR_0 __REG32(OMAP24XX_SDRC_BASE+0x084)
|
||||
|
||||
/* GPIO 1 */
|
||||
#define GPIO1_BASE GPIOX_BASE(1)
|
||||
#define GPIO1_REG32(offset) __REG32(GPIO1_BASE + (offset))
|
||||
#define GPIO1_IRQENABLE1 GPIO1_REG32(0x01C)
|
||||
#define GPIO1_IRQSTATUS1 GPIO1_REG32(0x018)
|
||||
#define GPIO1_IRQENABLE2 GPIO1_REG32(0x02C)
|
||||
#define GPIO1_IRQSTATUS2 GPIO1_REG32(0x028)
|
||||
#define GPIO1_WAKEUPENABLE GPIO1_REG32(0x020)
|
||||
#define GPIO1_RISINGDETECT GPIO1_REG32(0x048)
|
||||
#define GPIO1_DATAIN GPIO1_REG32(0x038)
|
||||
#define GPIO1_OE GPIO1_REG32(0x034)
|
||||
#define GPIO1_DATAOUT GPIO1_REG32(0x03C)
|
||||
|
||||
/* GPIO2 */
|
||||
#define GPIO2_BASE GPIOX_BASE(2)
|
||||
#define GPIO2_REG32(offset) __REG32(GPIO2_BASE + (offset))
|
||||
#define GPIO2_IRQENABLE1 GPIO2_REG32(0x01C)
|
||||
#define GPIO2_IRQSTATUS1 GPIO2_REG32(0x018)
|
||||
#define GPIO2_IRQENABLE2 GPIO2_REG32(0x02C)
|
||||
#define GPIO2_IRQSTATUS2 GPIO2_REG32(0x028)
|
||||
#define GPIO2_WAKEUPENABLE GPIO2_REG32(0x020)
|
||||
#define GPIO2_RISINGDETECT GPIO2_REG32(0x048)
|
||||
#define GPIO2_DATAIN GPIO2_REG32(0x038)
|
||||
#define GPIO2_OE GPIO2_REG32(0x034)
|
||||
#define GPIO2_DATAOUT GPIO2_REG32(0x03C)
|
||||
|
||||
/* GPIO 3 */
|
||||
#define GPIO3_BASE GPIOX_BASE(3)
|
||||
#define GPIO3_REG32(offset) __REG32(GPIO3_BASE + (offset))
|
||||
#define GPIO3_IRQENABLE1 GPIO3_REG32(0x01C)
|
||||
#define GPIO3_IRQSTATUS1 GPIO3_REG32(0x018)
|
||||
#define GPIO3_IRQENABLE2 GPIO3_REG32(0x02C)
|
||||
#define GPIO3_IRQSTATUS2 GPIO3_REG32(0x028)
|
||||
#define GPIO3_WAKEUPENABLE GPIO3_REG32(0x020)
|
||||
#define GPIO3_RISINGDETECT GPIO3_REG32(0x048)
|
||||
#define GPIO3_FALLINGDETECT GPIO3_REG32(0x04C)
|
||||
#define GPIO3_DATAIN GPIO3_REG32(0x038)
|
||||
#define GPIO3_OE GPIO3_REG32(0x034)
|
||||
#define GPIO3_DATAOUT GPIO3_REG32(0x03C)
|
||||
#define GPIO3_DEBOUNCENABLE GPIO3_REG32(0x050)
|
||||
#define GPIO3_DEBOUNCINGTIME GPIO3_REG32(0x054)
|
||||
|
||||
/* GPIO 4 */
|
||||
#define GPIO4_BASE GPIOX_BASE(4)
|
||||
#define GPIO4_REG32(offset) __REG32(GPIO4_BASE + (offset))
|
||||
#define GPIO4_IRQENABLE1 GPIO4_REG32(0x01C)
|
||||
#define GPIO4_IRQSTATUS1 GPIO4_REG32(0x018)
|
||||
#define GPIO4_IRQENABLE2 GPIO4_REG32(0x02C)
|
||||
#define GPIO4_IRQSTATUS2 GPIO4_REG32(0x028)
|
||||
#define GPIO4_WAKEUPENABLE GPIO4_REG32(0x020)
|
||||
#define GPIO4_RISINGDETECT GPIO4_REG32(0x048)
|
||||
#define GPIO4_FALLINGDETECT GPIO4_REG32(0x04C)
|
||||
#define GPIO4_DATAIN GPIO4_REG32(0x038)
|
||||
#define GPIO4_OE GPIO4_REG32(0x034)
|
||||
#define GPIO4_DATAOUT GPIO4_REG32(0x03C)
|
||||
#define GPIO4_DEBOUNCENABLE GPIO4_REG32(0x050)
|
||||
#define GPIO4_DEBOUNCINGTIME GPIO4_REG32(0x054)
|
||||
|
||||
|
||||
/* IO CONFIG */
|
||||
#define CONTROL_BASE (OMAP24XX_CTRL_BASE)
|
||||
#define CONTROL_REG32(offset) __REG32(CONTROL_BASE + (offset))
|
||||
|
||||
#define CONTROL_PADCONF_SPI1_NCS2 CONTROL_REG32(0x104)
|
||||
#define CONTROL_PADCONF_SYS_XTALOUT CONTROL_REG32(0x134)
|
||||
#define CONTROL_PADCONF_UART1_RX CONTROL_REG32(0x0C8)
|
||||
#define CONTROL_PADCONF_MCBSP1_DX CONTROL_REG32(0x10C)
|
||||
#define CONTROL_PADCONF_GPMC_NCS4 CONTROL_REG32(0x090)
|
||||
#define CONTROL_PADCONF_DSS_D5 CONTROL_REG32(0x0B8)
|
||||
#define CONTROL_PADCONF_DSS_D9 CONTROL_REG32(0x0BC)
|
||||
#define CONTROL_PADCONF_DSS_D13 CONTROL_REG32(0x0C0)
|
||||
#define CONTROL_PADCONF_DSS_VSYNC CONTROL_REG32(0x0CC)
|
||||
|
||||
/* CONTROL */
|
||||
#define CONTROL_DEVCONF CONTROL_REG32(0x274)
|
||||
|
||||
/* INTERRUPT CONTROLLER */
|
||||
#define INTC_BASE (OMAP24XX_L4_IO_BASE+0xfe000)
|
||||
#define INTC_REG32(offset) __REG32(INTC_BASE + (offset))
|
||||
|
||||
#define INTC1_U_BASE INTC_REG32(0x000)
|
||||
#define INTC_MIR0 INTC_REG32(0x084)
|
||||
#define INTC_MIR_SET0 INTC_REG32(0x08C)
|
||||
#define INTC_MIR_CLEAR0 INTC_REG32(0x088)
|
||||
#define INTC_ISR_CLEAR0 INTC_REG32(0x094)
|
||||
#define INTC_MIR1 INTC_REG32(0x0A4)
|
||||
#define INTC_MIR_SET1 INTC_REG32(0x0AC)
|
||||
#define INTC_MIR_CLEAR1 INTC_REG32(0x0A8)
|
||||
#define INTC_ISR_CLEAR1 INTC_REG32(0x0B4)
|
||||
#define INTC_MIR2 INTC_REG32(0x0C4)
|
||||
#define INTC_MIR_SET2 INTC_REG32(0x0CC)
|
||||
#define INTC_MIR_CLEAR2 INTC_REG32(0x0C8)
|
||||
#define INTC_ISR_CLEAR2 INTC_REG32(0x0D4)
|
||||
#define INTC_SIR_IRQ INTC_REG32(0x040)
|
||||
#define INTC_CONTROL INTC_REG32(0x048)
|
||||
#define INTC_ILR11 INTC_REG32(0x12C)
|
||||
#define INTC_ILR32 INTC_REG32(0x180)
|
||||
#define INTC_ILR37 INTC_REG32(0x194)
|
||||
#define INTC_SYSCONFIG INTC_REG32(0x010)
|
||||
|
||||
/* RAM FIREWALL */
|
||||
#define RAMFW_BASE (0x68005000)
|
||||
#define RAMFW_REG32(offset) __REG32(RAMFW_BASE + (offset))
|
||||
|
||||
#define RAMFW_REQINFOPERM0 RAMFW_REG32(0x048)
|
||||
#define RAMFW_READPERM0 RAMFW_REG32(0x050)
|
||||
#define RAMFW_WRITEPERM0 RAMFW_REG32(0x058)
|
||||
|
||||
/* GPMC CS1 FPGA ON USER INTERFACE MODULE */
|
||||
//#define DEBUG_BOARD_LED_REGISTER 0x04000014
|
||||
|
||||
/* GPMC CS0 */
|
||||
#define GPMC_CONFIG1_0 GPMC_REG32(0x060)
|
||||
#define GPMC_CONFIG2_0 GPMC_REG32(0x064)
|
||||
#define GPMC_CONFIG3_0 GPMC_REG32(0x068)
|
||||
#define GPMC_CONFIG4_0 GPMC_REG32(0x06C)
|
||||
#define GPMC_CONFIG5_0 GPMC_REG32(0x070)
|
||||
#define GPMC_CONFIG6_0 GPMC_REG32(0x074)
|
||||
#define GPMC_CONFIG7_0 GPMC_REG32(0x078)
|
||||
|
||||
/* DSS */
|
||||
#define DSS_CONTROL DISP_REG32(0x040)
|
||||
#define DISPC_CONTROL DISP_REG32(0x440)
|
||||
#define DISPC_SYSSTATUS DISP_REG32(0x414)
|
||||
#define DISPC_IRQSTATUS DISP_REG32(0x418)
|
||||
#define DISPC_IRQENABLE DISP_REG32(0x41C)
|
||||
#define DISPC_CONFIG DISP_REG32(0x444)
|
||||
#define DISPC_DEFAULT_COLOR0 DISP_REG32(0x44C)
|
||||
#define DISPC_DEFAULT_COLOR1 DISP_REG32(0x450)
|
||||
#define DISPC_TRANS_COLOR0 DISP_REG32(0x454)
|
||||
#define DISPC_TRANS_COLOR1 DISP_REG32(0x458)
|
||||
#define DISPC_LINE_NUMBER DISP_REG32(0x460)
|
||||
#define DISPC_TIMING_H DISP_REG32(0x464)
|
||||
#define DISPC_TIMING_V DISP_REG32(0x468)
|
||||
#define DISPC_POL_FREQ DISP_REG32(0x46C)
|
||||
#define DISPC_DIVISOR DISP_REG32(0x470)
|
||||
#define DISPC_SIZE_DIG DISP_REG32(0x478)
|
||||
#define DISPC_SIZE_LCD DISP_REG32(0x47C)
|
||||
#define DISPC_GFX_BA0 DISP_REG32(0x480)
|
||||
#define DISPC_GFX_BA1 DISP_REG32(0x484)
|
||||
#define DISPC_GFX_POSITION DISP_REG32(0x488)
|
||||
#define DISPC_GFX_SIZE DISP_REG32(0x48C)
|
||||
#define DISPC_GFX_ATTRIBUTES DISP_REG32(0x4A0)
|
||||
#define DISPC_GFX_FIFO_THRESHOLD DISP_REG32(0x4A4)
|
||||
#define DISPC_GFX_ROW_INC DISP_REG32(0x4AC)
|
||||
#define DISPC_GFX_PIXEL_INC DISP_REG32(0x4B0)
|
||||
#define DISPC_GFX_WINDOW_SKIP DISP_REG32(0x4B4)
|
||||
#define DISPC_GFX_TABLE_BA DISP_REG32(0x4B8)
|
||||
#define DISPC_DATA_CYCLE1 DISP_REG32(0x5D4)
|
||||
#define DISPC_DATA_CYCLE2 DISP_REG32(0x5D8)
|
||||
#define DISPC_DATA_CYCLE3 DISP_REG32(0x5DC)
|
||||
|
||||
/* Wake up define for board */
|
||||
#define GPIO97 (1 << 1)
|
||||
#define GPIO88 (1 << 24)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
180
arch/arm/mach-omap2/serial.c
Normal file
180
arch/arm/mach-omap2/serial.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* arch/arm/mach-omap/omap2/serial.c
|
||||
*
|
||||
* OMAP2 serial support.
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Author: Paul Mundt <paul.mundt@nokia.com>
|
||||
*
|
||||
* Based off of arch/arm/mach-omap/omap1/serial.c
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/serial_reg.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/hardware/clock.h>
|
||||
|
||||
#include <asm/arch/common.h>
|
||||
#include <asm/arch/board.h>
|
||||
|
||||
static struct clk * uart1_ick = NULL;
|
||||
static struct clk * uart1_fck = NULL;
|
||||
static struct clk * uart2_ick = NULL;
|
||||
static struct clk * uart2_fck = NULL;
|
||||
static struct clk * uart3_ick = NULL;
|
||||
static struct clk * uart3_fck = NULL;
|
||||
|
||||
static struct plat_serial8250_port serial_platform_data[] = {
|
||||
{
|
||||
.membase = (char *)IO_ADDRESS(OMAP_UART1_BASE),
|
||||
.mapbase = (unsigned long)OMAP_UART1_BASE,
|
||||
.irq = 72,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = OMAP16XX_BASE_BAUD * 16,
|
||||
}, {
|
||||
.membase = (char *)IO_ADDRESS(OMAP_UART2_BASE),
|
||||
.mapbase = (unsigned long)OMAP_UART2_BASE,
|
||||
.irq = 73,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = OMAP16XX_BASE_BAUD * 16,
|
||||
}, {
|
||||
.membase = (char *)IO_ADDRESS(OMAP_UART3_BASE),
|
||||
.mapbase = (unsigned long)OMAP_UART3_BASE,
|
||||
.irq = 74,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 2,
|
||||
.uartclk = OMAP16XX_BASE_BAUD * 16,
|
||||
}, {
|
||||
.flags = 0
|
||||
}
|
||||
};
|
||||
|
||||
static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
|
||||
int offset)
|
||||
{
|
||||
offset <<= up->regshift;
|
||||
return (unsigned int)__raw_readb(up->membase + offset);
|
||||
}
|
||||
|
||||
static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
|
||||
int value)
|
||||
{
|
||||
offset <<= p->regshift;
|
||||
__raw_writeb(value, (unsigned long)(p->membase + offset));
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal UARTs need to be initialized for the 8250 autoconfig to work
|
||||
* properly. Note that the TX watermark initialization may not be needed
|
||||
* once the 8250.c watermark handling code is merged.
|
||||
*/
|
||||
static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
|
||||
{
|
||||
serial_write_reg(p, UART_OMAP_MDR1, 0x07);
|
||||
serial_write_reg(p, UART_OMAP_SCR, 0x08);
|
||||
serial_write_reg(p, UART_OMAP_MDR1, 0x00);
|
||||
serial_write_reg(p, UART_OMAP_SYSC, 0x01);
|
||||
}
|
||||
|
||||
void __init omap_serial_init()
|
||||
{
|
||||
int i;
|
||||
const struct omap_uart_config *info;
|
||||
|
||||
/*
|
||||
* Make sure the serial ports are muxed on at this point.
|
||||
* You have to mux them off in device drivers later on
|
||||
* if not needed.
|
||||
*/
|
||||
|
||||
info = omap_get_config(OMAP_TAG_UART,
|
||||
struct omap_uart_config);
|
||||
|
||||
if (info == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
|
||||
struct plat_serial8250_port *p = serial_platform_data + i;
|
||||
|
||||
if (!(info->enabled_uarts & (1 << i))) {
|
||||
p->membase = 0;
|
||||
p->mapbase = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
uart1_ick = clk_get(NULL, "uart1_ick");
|
||||
if (IS_ERR(uart1_ick))
|
||||
printk("Could not get uart1_ick\n");
|
||||
else {
|
||||
clk_use(uart1_ick);
|
||||
}
|
||||
|
||||
uart1_fck = clk_get(NULL, "uart1_fck");
|
||||
if (IS_ERR(uart1_fck))
|
||||
printk("Could not get uart1_fck\n");
|
||||
else {
|
||||
clk_use(uart1_fck);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
uart2_ick = clk_get(NULL, "uart2_ick");
|
||||
if (IS_ERR(uart2_ick))
|
||||
printk("Could not get uart2_ick\n");
|
||||
else {
|
||||
clk_use(uart2_ick);
|
||||
}
|
||||
|
||||
uart2_fck = clk_get(NULL, "uart2_fck");
|
||||
if (IS_ERR(uart2_fck))
|
||||
printk("Could not get uart2_fck\n");
|
||||
else {
|
||||
clk_use(uart2_fck);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uart3_ick = clk_get(NULL, "uart3_ick");
|
||||
if (IS_ERR(uart3_ick))
|
||||
printk("Could not get uart3_ick\n");
|
||||
else {
|
||||
clk_use(uart3_ick);
|
||||
}
|
||||
|
||||
uart3_fck = clk_get(NULL, "uart3_fck");
|
||||
if (IS_ERR(uart3_fck))
|
||||
printk("Could not get uart3_fck\n");
|
||||
else {
|
||||
clk_use(uart3_fck);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
omap_serial_reset(p);
|
||||
}
|
||||
}
|
||||
|
||||
static struct platform_device serial_device = {
|
||||
.name = "serial8250",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = serial_platform_data,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init omap_init(void)
|
||||
{
|
||||
return platform_device_register(&serial_device);
|
||||
}
|
||||
arch_initcall(omap_init);
|
333
arch/arm/mach-omap2/sram-fn.S
Normal file
333
arch/arm/mach-omap2/sram-fn.S
Normal file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap1/sram.S
|
||||
*
|
||||
* Omap2 specific functions that need to be run in internal SRAM
|
||||
*
|
||||
* (C) Copyright 2004
|
||||
* Texas Instruments, <www.ti.com>
|
||||
* Richard Woodruff <r-woodruff2@ti.com>
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/arch/io.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/arch/prcm.h>
|
||||
|
||||
#define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010)
|
||||
|
||||
#define CM_CLKSEL2_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x544)
|
||||
#define PRCM_VOLTCTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x050)
|
||||
#define PRCM_CLKCFG_CTRL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x080)
|
||||
#define CM_CLKEN_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x500)
|
||||
#define CM_IDLEST_CKGEN_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x520)
|
||||
#define CM_CLKSEL1_PLL_V IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x540)
|
||||
|
||||
#define SDRC_DLLA_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x060)
|
||||
#define SDRC_RFR_CTRL_V IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x0a4)
|
||||
|
||||
.text
|
||||
|
||||
ENTRY(sram_ddr_init)
|
||||
stmfd sp!, {r0 - r12, lr} @ save registers on stack
|
||||
|
||||
mov r12, r2 @ capture CS1 vs CS0
|
||||
mov r8, r3 @ capture force parameter
|
||||
|
||||
/* frequency shift down */
|
||||
ldr r2, cm_clksel2_pll @ get address of dpllout reg
|
||||
mov r3, #0x1 @ value for 1x operation
|
||||
str r3, [r2] @ go to L1-freq operation
|
||||
|
||||
/* voltage shift down */
|
||||
mov r9, #0x1 @ set up for L1 voltage call
|
||||
bl voltage_shift @ go drop voltage
|
||||
|
||||
/* dll lock mode */
|
||||
ldr r11, sdrc_dlla_ctrl @ addr of dlla ctrl
|
||||
ldr r10, [r11] @ get current val
|
||||
cmp r12, #0x1 @ cs1 base (2422 es2.05/1)
|
||||
addeq r11, r11, #0x8 @ if cs1 base, move to DLLB
|
||||
mvn r9, #0x4 @ mask to get clear bit2
|
||||
and r10, r10, r9 @ clear bit2 for lock mode.
|
||||
orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
|
||||
orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz
|
||||
str r10, [r11] @ commit to DLLA_CTRL
|
||||
bl i_dll_wait @ wait for dll to lock
|
||||
|
||||
/* get dll value */
|
||||
add r11, r11, #0x4 @ get addr of status reg
|
||||
ldr r10, [r11] @ get locked value
|
||||
|
||||
/* voltage shift up */
|
||||
mov r9, #0x0 @ shift back to L0-voltage
|
||||
bl voltage_shift @ go raise voltage
|
||||
|
||||
/* frequency shift up */
|
||||
mov r3, #0x2 @ value for 2x operation
|
||||
str r3, [r2] @ go to L0-freq operation
|
||||
|
||||
/* reset entry mode for dllctrl */
|
||||
sub r11, r11, #0x4 @ move from status to ctrl
|
||||
cmp r12, #0x1 @ normalize if cs1 based
|
||||
subeq r11, r11, #0x8 @ possibly back to DLLA
|
||||
cmp r8, #0x1 @ if forced unlock exit
|
||||
orreq r1, r1, #0x4 @ make sure exit with unlocked value
|
||||
str r1, [r11] @ restore DLLA_CTRL high value
|
||||
add r11, r11, #0x8 @ move to DLLB_CTRL addr
|
||||
str r1, [r11] @ set value DLLB_CTRL
|
||||
bl i_dll_wait @ wait for possible lock
|
||||
|
||||
/* set up for return, DDR should be good */
|
||||
str r10, [r0] @ write dll_status and return counter
|
||||
ldmfd sp!, {r0 - r12, pc} @ restore regs and return
|
||||
|
||||
/* ensure the DLL has relocked */
|
||||
i_dll_wait:
|
||||
mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks
|
||||
i_dll_delay:
|
||||
subs r4, r4, #0x1
|
||||
bne i_dll_delay
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* shift up or down voltage, use R9 as input to tell level.
|
||||
* wait for it to finish, use 32k sync counter, 1tick=31uS.
|
||||
*/
|
||||
voltage_shift:
|
||||
ldr r4, prcm_voltctrl @ get addr of volt ctrl.
|
||||
ldr r5, [r4] @ get value.
|
||||
ldr r6, prcm_mask_val @ get value of mask
|
||||
and r5, r5, r6 @ apply mask to clear bits
|
||||
orr r5, r5, r9 @ bulld value for L0/L1-volt operation.
|
||||
str r5, [r4] @ set up for change.
|
||||
mov r3, #0x4000 @ get val for force
|
||||
orr r5, r5, r3 @ build value for force
|
||||
str r5, [r4] @ Force transition to L1
|
||||
|
||||
ldr r3, timer_32ksynct_cr @ get addr of counter
|
||||
ldr r5, [r3] @ get value
|
||||
add r5, r5, #0x3 @ give it at most 93uS
|
||||
volt_delay:
|
||||
ldr r7, [r3] @ get timer value
|
||||
cmp r5, r7 @ time up?
|
||||
bhi volt_delay @ not yet->branch
|
||||
mov pc, lr @ back to caller.
|
||||
|
||||
/* relative load constants */
|
||||
cm_clksel2_pll:
|
||||
.word CM_CLKSEL2_PLL_V
|
||||
sdrc_dlla_ctrl:
|
||||
.word SDRC_DLLA_CTRL_V
|
||||
prcm_voltctrl:
|
||||
.word PRCM_VOLTCTRL_V
|
||||
prcm_mask_val:
|
||||
.word 0xFFFF3FFC
|
||||
timer_32ksynct_cr:
|
||||
.word TIMER_32KSYNCT_CR_V
|
||||
ENTRY(sram_ddr_init_sz)
|
||||
.word . - sram_ddr_init
|
||||
|
||||
/*
|
||||
* Reprograms memory timings.
|
||||
* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
|
||||
* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
|
||||
*/
|
||||
ENTRY(sram_reprogram_sdrc)
|
||||
stmfd sp!, {r0 - r10, lr} @ save registers on stack
|
||||
mov r3, #0x0 @ clear for mrc call
|
||||
mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR
|
||||
nop
|
||||
nop
|
||||
ldr r6, ddr_sdrc_rfr_ctrl @ get addr of refresh reg
|
||||
ldr r5, [r6] @ get value
|
||||
mov r5, r5, lsr #8 @ isolate rfr field and drop burst
|
||||
|
||||
cmp r0, #0x1 @ going to half speed?
|
||||
movne r9, #0x0 @ if up set flag up for pre up, hi volt
|
||||
|
||||
blne voltage_shift_c @ adjust voltage
|
||||
|
||||
cmp r0, #0x1 @ going to half speed (post branch link)
|
||||
moveq r5, r5, lsr #1 @ divide by 2 if to half
|
||||
movne r5, r5, lsl #1 @ mult by 2 if to full
|
||||
mov r5, r5, lsl #8 @ put rfr field back into place
|
||||
add r5, r5, #0x1 @ turn on burst of 1
|
||||
ldr r4, ddr_cm_clksel2_pll @ get address of out reg
|
||||
ldr r3, [r4] @ get curr value
|
||||
orr r3, r3, #0x3
|
||||
bic r3, r3, #0x3 @ clear lower bits
|
||||
orr r3, r3, r0 @ new state value
|
||||
str r3, [r4] @ set new state (pll/x, x=1 or 2)
|
||||
nop
|
||||
nop
|
||||
|
||||
moveq r9, #0x1 @ if speed down, post down, drop volt
|
||||
bleq voltage_shift_c
|
||||
|
||||
mcr p15, 0, r3, c7, c10, 4 @ memory barrier
|
||||
str r5, [r6] @ set new RFR_1 value
|
||||
add r6, r6, #0x30 @ get RFR_2 addr
|
||||
str r5, [r6] @ set RFR_2
|
||||
nop
|
||||
cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL
|
||||
bne freq_out @ leave if SDR, no DLL function
|
||||
|
||||
/* With DDR, we need to take care of the DLL for the frequency change */
|
||||
ldr r2, ddr_sdrc_dlla_ctrl @ addr of dlla ctrl
|
||||
str r1, [r2] @ write out new SDRC_DLLA_CTRL
|
||||
add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL
|
||||
str r1, [r2] @ commit to SDRC_DLLB_CTRL
|
||||
mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks
|
||||
dll_wait:
|
||||
subs r1, r1, #0x1
|
||||
bne dll_wait
|
||||
freq_out:
|
||||
ldmfd sp!, {r0 - r10, pc} @ restore regs and return
|
||||
|
||||
/*
|
||||
* shift up or down voltage, use R9 as input to tell level.
|
||||
* wait for it to finish, use 32k sync counter, 1tick=31uS.
|
||||
*/
|
||||
voltage_shift_c:
|
||||
ldr r10, ddr_prcm_voltctrl @ get addr of volt ctrl
|
||||
ldr r8, [r10] @ get value
|
||||
ldr r7, ddr_prcm_mask_val @ get value of mask
|
||||
and r8, r8, r7 @ apply mask to clear bits
|
||||
orr r8, r8, r9 @ bulld value for L0/L1-volt operation.
|
||||
str r8, [r10] @ set up for change.
|
||||
mov r7, #0x4000 @ get val for force
|
||||
orr r8, r8, r7 @ build value for force
|
||||
str r8, [r10] @ Force transition to L1
|
||||
|
||||
ldr r10, ddr_timer_32ksynct @ get addr of counter
|
||||
ldr r8, [r10] @ get value
|
||||
add r8, r8, #0x2 @ give it at most 62uS (min 31+)
|
||||
volt_delay_c:
|
||||
ldr r7, [r10] @ get timer value
|
||||
cmp r8, r7 @ time up?
|
||||
bhi volt_delay_c @ not yet->branch
|
||||
mov pc, lr @ back to caller
|
||||
|
||||
ddr_cm_clksel2_pll:
|
||||
.word CM_CLKSEL2_PLL_V
|
||||
ddr_sdrc_dlla_ctrl:
|
||||
.word SDRC_DLLA_CTRL_V
|
||||
ddr_sdrc_rfr_ctrl:
|
||||
.word SDRC_RFR_CTRL_V
|
||||
ddr_prcm_voltctrl:
|
||||
.word PRCM_VOLTCTRL_V
|
||||
ddr_prcm_mask_val:
|
||||
.word 0xFFFF3FFC
|
||||
ddr_timer_32ksynct:
|
||||
.word TIMER_32KSYNCT_CR_V
|
||||
|
||||
ENTRY(sram_reprogram_sdrc_sz)
|
||||
.word . - sram_reprogram_sdrc
|
||||
|
||||
/*
|
||||
* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
|
||||
*/
|
||||
ENTRY(sram_set_prcm)
|
||||
stmfd sp!, {r0-r12, lr} @ regs to stack
|
||||
adr r4, pbegin @ addr of preload start
|
||||
adr r8, pend @ addr of preload end
|
||||
mcrr p15, 1, r8, r4, c12 @ preload into icache
|
||||
pbegin:
|
||||
/* move into fast relock bypass */
|
||||
ldr r8, pll_ctl @ get addr
|
||||
ldr r5, [r8] @ get val
|
||||
mvn r6, #0x3 @ clear mask
|
||||
and r5, r5, r6 @ clear field
|
||||
orr r7, r5, #0x2 @ fast relock val
|
||||
str r7, [r8] @ go to fast relock
|
||||
ldr r4, pll_stat @ addr of stat
|
||||
block:
|
||||
/* wait for bypass */
|
||||
ldr r8, [r4] @ stat value
|
||||
and r8, r8, #0x3 @ mask for stat
|
||||
cmp r8, #0x1 @ there yet
|
||||
bne block @ loop if not
|
||||
|
||||
/* set new dpll dividers _after_ in bypass */
|
||||
ldr r4, pll_div @ get addr
|
||||
str r0, [r4] @ set dpll ctrl val
|
||||
|
||||
ldr r4, set_config @ get addr
|
||||
mov r8, #1 @ valid cfg msk
|
||||
str r8, [r4] @ make dividers take
|
||||
|
||||
mov r4, #100 @ dead spin a bit
|
||||
wait_a_bit:
|
||||
subs r4, r4, #1 @ dec loop
|
||||
bne wait_a_bit @ delay done?
|
||||
|
||||
/* check if staying in bypass */
|
||||
cmp r2, #0x1 @ stay in bypass?
|
||||
beq pend @ jump over dpll relock
|
||||
|
||||
/* relock DPLL with new vals */
|
||||
ldr r5, pll_stat @ get addr
|
||||
ldr r4, pll_ctl @ get addr
|
||||
orr r8, r7, #0x3 @ val for lock dpll
|
||||
str r8, [r4] @ set val
|
||||
mov r0, #1000 @ dead spin a bit
|
||||
wait_more:
|
||||
subs r0, r0, #1 @ dec loop
|
||||
bne wait_more @ delay done?
|
||||
wait_lock:
|
||||
ldr r8, [r5] @ get lock val
|
||||
and r8, r8, #3 @ isolate field
|
||||
cmp r8, #2 @ locked?
|
||||
bne wait_lock @ wait if not
|
||||
pend:
|
||||
/* update memory timings & briefly lock dll */
|
||||
ldr r4, sdrc_rfr @ get addr
|
||||
str r1, [r4] @ update refresh timing
|
||||
ldr r11, dlla_ctrl @ get addr of DLLA ctrl
|
||||
ldr r10, [r11] @ get current val
|
||||
mvn r9, #0x4 @ mask to get clear bit2
|
||||
and r10, r10, r9 @ clear bit2 for lock mode
|
||||
orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
|
||||
str r10, [r11] @ commit to DLLA_CTRL
|
||||
add r11, r11, #0x8 @ move to dllb
|
||||
str r10, [r11] @ hit DLLB also
|
||||
|
||||
mov r4, #0x800 @ relock time (min 0x400 L3 clocks)
|
||||
wait_dll_lock:
|
||||
subs r4, r4, #0x1
|
||||
bne wait_dll_lock
|
||||
nop
|
||||
ldmfd sp!, {r0-r12, pc} @ restore regs and return
|
||||
|
||||
set_config:
|
||||
.word PRCM_CLKCFG_CTRL_V
|
||||
pll_ctl:
|
||||
.word CM_CLKEN_PLL_V
|
||||
pll_stat:
|
||||
.word CM_IDLEST_CKGEN_V
|
||||
pll_div:
|
||||
.word CM_CLKSEL1_PLL_V
|
||||
sdrc_rfr:
|
||||
.word SDRC_RFR_CTRL_V
|
||||
dlla_ctrl:
|
||||
.word SDRC_DLLA_CTRL_V
|
||||
|
||||
ENTRY(sram_set_prcm_sz)
|
||||
.word . - sram_set_prcm
|
126
arch/arm/mach-omap2/timer-gp.c
Normal file
126
arch/arm/mach-omap2/timer-gp.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* linux/arch/arm/mach-omap2/timer-gp.c
|
||||
*
|
||||
* OMAP2 GP timer support.
|
||||
*
|
||||
* Copyright (C) 2005 Nokia Corporation
|
||||
* Author: Paul Mundt <paul.mundt@nokia.com>
|
||||
* Juha Yrjölä <juha.yrjola@nokia.com>
|
||||
*
|
||||
* Some parts based off of TI's 24xx code:
|
||||
*
|
||||
* Copyright (C) 2004 Texas Instruments, Inc.
|
||||
*
|
||||
* Roughly modelled after the OMAP1 MPU timer code.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/hardware/clock.h>
|
||||
|
||||
#define OMAP2_GP_TIMER1_BASE 0x48028000
|
||||
#define OMAP2_GP_TIMER2_BASE 0x4802a000
|
||||
#define OMAP2_GP_TIMER3_BASE 0x48078000
|
||||
#define OMAP2_GP_TIMER4_BASE 0x4807a000
|
||||
|
||||
#define GP_TIMER_TIDR 0x00
|
||||
#define GP_TIMER_TISR 0x18
|
||||
#define GP_TIMER_TIER 0x1c
|
||||
#define GP_TIMER_TCLR 0x24
|
||||
#define GP_TIMER_TCRR 0x28
|
||||
#define GP_TIMER_TLDR 0x2c
|
||||
#define GP_TIMER_TSICR 0x40
|
||||
|
||||
#define OS_TIMER_NR 1 /* GP timer 2 */
|
||||
|
||||
static unsigned long timer_base[] = {
|
||||
IO_ADDRESS(OMAP2_GP_TIMER1_BASE),
|
||||
IO_ADDRESS(OMAP2_GP_TIMER2_BASE),
|
||||
IO_ADDRESS(OMAP2_GP_TIMER3_BASE),
|
||||
IO_ADDRESS(OMAP2_GP_TIMER4_BASE),
|
||||
};
|
||||
|
||||
static inline unsigned int timer_read_reg(int nr, unsigned int reg)
|
||||
{
|
||||
return __raw_readl(timer_base[nr] + reg);
|
||||
}
|
||||
|
||||
static inline void timer_write_reg(int nr, unsigned int reg, unsigned int val)
|
||||
{
|
||||
__raw_writel(val, timer_base[nr] + reg);
|
||||
}
|
||||
|
||||
/* Note that we always enable the clock prescale divider bit */
|
||||
static inline void omap2_gp_timer_start(int nr, unsigned long load_val)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
tmp = 0xffffffff - load_val;
|
||||
|
||||
timer_write_reg(nr, GP_TIMER_TLDR, tmp);
|
||||
timer_write_reg(nr, GP_TIMER_TCRR, tmp);
|
||||
timer_write_reg(nr, GP_TIMER_TIER, 1 << 1);
|
||||
timer_write_reg(nr, GP_TIMER_TCLR, (1 << 5) | (1 << 1) | 1);
|
||||
}
|
||||
|
||||
static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
write_seqlock(&xtime_lock);
|
||||
|
||||
timer_write_reg(OS_TIMER_NR, GP_TIMER_TISR, 1 << 1);
|
||||
timer_tick(regs);
|
||||
|
||||
write_sequnlock(&xtime_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction omap2_gp_timer_irq = {
|
||||
.name = "gp timer",
|
||||
.flags = SA_INTERRUPT,
|
||||
.handler = omap2_gp_timer_interrupt,
|
||||
};
|
||||
|
||||
static void __init omap2_gp_timer_init(void)
|
||||
{
|
||||
struct clk * sys_ck;
|
||||
u32 tick_period = 120000;
|
||||
u32 l;
|
||||
|
||||
/* Reset clock and prescale value */
|
||||
timer_write_reg(OS_TIMER_NR, GP_TIMER_TCLR, 0);
|
||||
|
||||
sys_ck = clk_get(NULL, "sys_ck");
|
||||
if (IS_ERR(sys_ck))
|
||||
printk(KERN_ERR "Could not get sys_ck\n");
|
||||
else {
|
||||
clk_use(sys_ck);
|
||||
tick_period = clk_get_rate(sys_ck) / 100;
|
||||
clk_put(sys_ck);
|
||||
}
|
||||
|
||||
tick_period /= 2; /* Minimum prescale divider is 2 */
|
||||
tick_period -= 1;
|
||||
|
||||
l = timer_read_reg(OS_TIMER_NR, GP_TIMER_TIDR);
|
||||
printk(KERN_INFO "OMAP2 GP timer (HW version %d.%d)\n",
|
||||
(l >> 4) & 0x0f, l & 0x0f);
|
||||
|
||||
setup_irq(38, &omap2_gp_timer_irq);
|
||||
|
||||
omap2_gp_timer_start(OS_TIMER_NR, tick_period);
|
||||
}
|
||||
|
||||
struct sys_timer omap_timer = {
|
||||
.init = omap2_gp_timer_init,
|
||||
};
|
||||
|
@ -60,6 +60,7 @@ config MACH_CORGI
|
||||
bool "Enable Sharp SL-C700 (Corgi) Support"
|
||||
depends PXA_SHARPSL_25x
|
||||
select PXA_SHARP_C7xx
|
||||
select PXA_SSP
|
||||
|
||||
config MACH_SHEPHERD
|
||||
bool "Enable Sharp SL-C750 (Shepherd) Support"
|
||||
@ -102,12 +103,18 @@ config IWMMXT
|
||||
|
||||
config PXA_SHARP_C7xx
|
||||
bool
|
||||
select PXA_SSP
|
||||
help
|
||||
Enable support for all Sharp C7xx models
|
||||
|
||||
config PXA_SHARP_Cxx00
|
||||
bool
|
||||
select PXA_SSP
|
||||
help
|
||||
Enable common support for Sharp Cxx00 models
|
||||
|
||||
config PXA_SSP
|
||||
tristate
|
||||
help
|
||||
Enable support for PXA2xx SSP ports
|
||||
endif
|
||||
|
@ -11,8 +11,8 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
|
||||
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
|
||||
obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
|
||||
obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
|
||||
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o
|
||||
obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o
|
||||
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o
|
||||
obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o
|
||||
obj-$(CONFIG_MACH_POODLE) += poodle.o
|
||||
obj-$(CONFIG_MACH_TOSA) += tosa.o
|
||||
|
||||
@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS) += $(led-y)
|
||||
|
||||
# Misc features
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o
|
||||
obj-$(CONFIG_PXA_SSP) += ssp.o
|
||||
|
||||
ifeq ($(CONFIG_PXA27x),y)
|
||||
obj-$(CONFIG_PM) += standby.o
|
||||
|
@ -203,7 +203,7 @@ static int __init corgi_ssp_probe(struct device *dev)
|
||||
GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */
|
||||
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
|
||||
|
||||
ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port);
|
||||
ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
|
||||
|
||||
if (ret)
|
||||
printk(KERN_ERR "Unable to register SSP handler!\n");
|
||||
|
@ -32,3 +32,90 @@ void corgi_put_hsync(void);
|
||||
void spitz_put_hsync(void);
|
||||
void corgi_wait_hsync(void);
|
||||
void spitz_wait_hsync(void);
|
||||
|
||||
/*
|
||||
* SharpSL Battery/PM Driver
|
||||
*/
|
||||
|
||||
struct sharpsl_charger_machinfo {
|
||||
void (*init)(void);
|
||||
int gpio_acin;
|
||||
int gpio_batfull;
|
||||
int gpio_batlock;
|
||||
int gpio_fatal;
|
||||
int (*status_acin)(void);
|
||||
void (*discharge)(int);
|
||||
void (*discharge1)(int);
|
||||
void (*charge)(int);
|
||||
void (*chargeled)(int);
|
||||
void (*measure_temp)(int);
|
||||
void (*presuspend)(void);
|
||||
void (*postsuspend)(void);
|
||||
unsigned long (*charger_wakeup)(void);
|
||||
int (*should_wakeup)(unsigned int resume_on_alarm);
|
||||
int bat_levels;
|
||||
struct battery_thresh *bat_levels_noac;
|
||||
struct battery_thresh *bat_levels_acin;
|
||||
int status_high_acin;
|
||||
int status_low_acin;
|
||||
int status_high_noac;
|
||||
int status_low_noac;
|
||||
};
|
||||
|
||||
struct battery_thresh {
|
||||
int voltage;
|
||||
int percentage;
|
||||
};
|
||||
|
||||
struct battery_stat {
|
||||
int ac_status; /* APM AC Present/Not Present */
|
||||
int mainbat_status; /* APM Main Battery Status */
|
||||
int mainbat_percent; /* Main Battery Percentage Charge */
|
||||
int mainbat_voltage; /* Main Battery Voltage */
|
||||
};
|
||||
|
||||
struct sharpsl_pm_status {
|
||||
struct device *dev;
|
||||
struct timer_list ac_timer;
|
||||
struct timer_list chrg_full_timer;
|
||||
|
||||
int charge_mode;
|
||||
#define CHRG_ERROR (-1)
|
||||
#define CHRG_OFF (0)
|
||||
#define CHRG_ON (1)
|
||||
#define CHRG_DONE (2)
|
||||
|
||||
unsigned int flags;
|
||||
#define SHARPSL_SUSPENDED (1 << 0) /* Device is Suspended */
|
||||
#define SHARPSL_ALARM_ACTIVE (1 << 1) /* Alarm is for charging event (not user) */
|
||||
#define SHARPSL_BL_LIMIT (1 << 2) /* Backlight Intensity Limited */
|
||||
#define SHARPSL_APM_QUEUED (1 << 3) /* APM Event Queued */
|
||||
#define SHARPSL_DO_OFFLINE_CHRG (1 << 4) /* Trigger the offline charger */
|
||||
|
||||
int full_count;
|
||||
unsigned long charge_start_time;
|
||||
struct sharpsl_charger_machinfo *machinfo;
|
||||
struct battery_stat battstat;
|
||||
};
|
||||
|
||||
extern struct sharpsl_pm_status sharpsl_pm;
|
||||
extern struct battery_thresh spitz_battery_levels_acin[];
|
||||
extern struct battery_thresh spitz_battery_levels_noac[];
|
||||
|
||||
#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x))
|
||||
|
||||
#define SHARPSL_LED_ERROR 2
|
||||
#define SHARPSL_LED_ON 1
|
||||
#define SHARPSL_LED_OFF 0
|
||||
|
||||
#define CHARGE_ON() sharpsl_pm.machinfo->charge(1)
|
||||
#define CHARGE_OFF() sharpsl_pm.machinfo->charge(0)
|
||||
#define CHARGE_LED_ON() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ON)
|
||||
#define CHARGE_LED_OFF() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_OFF)
|
||||
#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
|
||||
#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1)
|
||||
#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0)
|
||||
#define STATUS_AC_IN sharpsl_pm.machinfo->status_acin()
|
||||
#define STATUS_BATT_LOCKED READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
|
||||
#define STATUS_CHRG_FULL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
|
||||
#define STATUS_FATAL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
|
||||
|
992
arch/arm/mach-pxa/sharpsl_pm.c
Normal file
992
arch/arm/mach-pxa/sharpsl_pm.c
Normal file
@ -0,0 +1,992 @@
|
||||
/*
|
||||
* Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
|
||||
* series of PDAs
|
||||
*
|
||||
* Copyright (c) 2004-2005 Richard Purdie
|
||||
*
|
||||
* Based on code written by Sharp for 2.4 kernels
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/apm_bios.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/hardware/scoop.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/apm.h>
|
||||
|
||||
#include <asm/arch/pm.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#include <asm/arch/sharpsl.h>
|
||||
#include "sharpsl.h"
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */
|
||||
#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */
|
||||
#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */
|
||||
#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */
|
||||
#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */
|
||||
#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */
|
||||
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */
|
||||
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */
|
||||
#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD 10 /* 10 msec */
|
||||
#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */
|
||||
#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */
|
||||
#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */
|
||||
|
||||
#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */
|
||||
#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */
|
||||
#define SHARPSL_CHARGE_ON_JKVAD_HIGH 0x9b /* 6V */
|
||||
#define SHARPSL_CHARGE_ON_JKVAD_LOW 0x34 /* 2V */
|
||||
#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */
|
||||
#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */
|
||||
|
||||
struct battery_thresh spitz_battery_levels_acin[] = {
|
||||
{ 213, 100},
|
||||
{ 212, 98},
|
||||
{ 211, 95},
|
||||
{ 210, 93},
|
||||
{ 209, 90},
|
||||
{ 208, 88},
|
||||
{ 207, 85},
|
||||
{ 206, 83},
|
||||
{ 205, 80},
|
||||
{ 204, 78},
|
||||
{ 203, 75},
|
||||
{ 202, 73},
|
||||
{ 201, 70},
|
||||
{ 200, 68},
|
||||
{ 199, 65},
|
||||
{ 198, 63},
|
||||
{ 197, 60},
|
||||
{ 196, 58},
|
||||
{ 195, 55},
|
||||
{ 194, 53},
|
||||
{ 193, 50},
|
||||
{ 192, 48},
|
||||
{ 192, 45},
|
||||
{ 191, 43},
|
||||
{ 191, 40},
|
||||
{ 190, 38},
|
||||
{ 190, 35},
|
||||
{ 189, 33},
|
||||
{ 188, 30},
|
||||
{ 187, 28},
|
||||
{ 186, 25},
|
||||
{ 185, 23},
|
||||
{ 184, 20},
|
||||
{ 183, 18},
|
||||
{ 182, 15},
|
||||
{ 181, 13},
|
||||
{ 180, 10},
|
||||
{ 179, 8},
|
||||
{ 178, 5},
|
||||
{ 0, 0},
|
||||
};
|
||||
|
||||
struct battery_thresh spitz_battery_levels_noac[] = {
|
||||
{ 213, 100},
|
||||
{ 212, 98},
|
||||
{ 211, 95},
|
||||
{ 210, 93},
|
||||
{ 209, 90},
|
||||
{ 208, 88},
|
||||
{ 207, 85},
|
||||
{ 206, 83},
|
||||
{ 205, 80},
|
||||
{ 204, 78},
|
||||
{ 203, 75},
|
||||
{ 202, 73},
|
||||
{ 201, 70},
|
||||
{ 200, 68},
|
||||
{ 199, 65},
|
||||
{ 198, 63},
|
||||
{ 197, 60},
|
||||
{ 196, 58},
|
||||
{ 195, 55},
|
||||
{ 194, 53},
|
||||
{ 193, 50},
|
||||
{ 192, 48},
|
||||
{ 191, 45},
|
||||
{ 190, 43},
|
||||
{ 189, 40},
|
||||
{ 188, 38},
|
||||
{ 187, 35},
|
||||
{ 186, 33},
|
||||
{ 185, 30},
|
||||
{ 184, 28},
|
||||
{ 183, 25},
|
||||
{ 182, 23},
|
||||
{ 181, 20},
|
||||
{ 180, 18},
|
||||
{ 179, 15},
|
||||
{ 178, 13},
|
||||
{ 177, 10},
|
||||
{ 176, 8},
|
||||
{ 175, 5},
|
||||
{ 0, 0},
|
||||
};
|
||||
|
||||
/* MAX1111 Commands */
|
||||
#define MAXCTRL_PD0 1u << 0
|
||||
#define MAXCTRL_PD1 1u << 1
|
||||
#define MAXCTRL_SGL 1u << 2
|
||||
#define MAXCTRL_UNI 1u << 3
|
||||
#define MAXCTRL_SEL_SH 4
|
||||
#define MAXCTRL_STR 1u << 7
|
||||
|
||||
/* MAX1111 Channel Definitions */
|
||||
#define BATT_AD 4u
|
||||
#define BATT_THM 2u
|
||||
#define JK_VAD 6u
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
static int sharpsl_read_MainBattery(void);
|
||||
static int sharpsl_off_charge_battery(void);
|
||||
static int sharpsl_check_battery(int mode);
|
||||
static int sharpsl_ac_check(void);
|
||||
static int sharpsl_fatal_check(void);
|
||||
static int sharpsl_average_value(int ad);
|
||||
static void sharpsl_average_clear(void);
|
||||
static void sharpsl_charge_toggle(void *private_);
|
||||
static void sharpsl_battery_thread(void *private_);
|
||||
|
||||
|
||||
/*
|
||||
* Variables
|
||||
*/
|
||||
struct sharpsl_pm_status sharpsl_pm;
|
||||
DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
|
||||
DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
|
||||
|
||||
|
||||
static int get_percentage(int voltage)
|
||||
{
|
||||
int i = sharpsl_pm.machinfo->bat_levels - 1;
|
||||
struct battery_thresh *thresh;
|
||||
|
||||
if (sharpsl_pm.charge_mode == CHRG_ON)
|
||||
thresh=sharpsl_pm.machinfo->bat_levels_acin;
|
||||
else
|
||||
thresh=sharpsl_pm.machinfo->bat_levels_noac;
|
||||
|
||||
while (i > 0 && (voltage > thresh[i].voltage))
|
||||
i--;
|
||||
|
||||
return thresh[i].percentage;
|
||||
}
|
||||
|
||||
static int get_apm_status(int voltage)
|
||||
{
|
||||
int low_thresh, high_thresh;
|
||||
|
||||
if (sharpsl_pm.charge_mode == CHRG_ON) {
|
||||
high_thresh = sharpsl_pm.machinfo->status_high_acin;
|
||||
low_thresh = sharpsl_pm.machinfo->status_low_acin;
|
||||
} else {
|
||||
high_thresh = sharpsl_pm.machinfo->status_high_noac;
|
||||
low_thresh = sharpsl_pm.machinfo->status_low_noac;
|
||||
}
|
||||
|
||||
if (voltage >= high_thresh)
|
||||
return APM_BATTERY_STATUS_HIGH;
|
||||
if (voltage >= low_thresh)
|
||||
return APM_BATTERY_STATUS_LOW;
|
||||
return APM_BATTERY_STATUS_CRITICAL;
|
||||
}
|
||||
|
||||
void sharpsl_battery_kick(void)
|
||||
{
|
||||
schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
|
||||
}
|
||||
EXPORT_SYMBOL(sharpsl_battery_kick);
|
||||
|
||||
|
||||
static void sharpsl_battery_thread(void *private_)
|
||||
{
|
||||
int voltage, percent, apm_status, i = 0;
|
||||
|
||||
if (!sharpsl_pm.machinfo)
|
||||
return;
|
||||
|
||||
sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE);
|
||||
|
||||
/* Corgi cannot confirm when battery fully charged so periodically kick! */
|
||||
if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
|
||||
&& time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL))
|
||||
schedule_work(&toggle_charger);
|
||||
|
||||
while(1) {
|
||||
voltage = sharpsl_read_MainBattery();
|
||||
if (voltage > 0) break;
|
||||
if (i++ > 5) {
|
||||
voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
|
||||
dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
voltage = sharpsl_average_value(voltage);
|
||||
apm_status = get_apm_status(voltage);
|
||||
percent = get_percentage(voltage);
|
||||
|
||||
/* At low battery voltages, the voltage has a tendency to start
|
||||
creeping back up so we try to avoid this here */
|
||||
if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) {
|
||||
sharpsl_pm.battstat.mainbat_voltage = voltage;
|
||||
sharpsl_pm.battstat.mainbat_status = apm_status;
|
||||
sharpsl_pm.battstat.mainbat_percent = percent;
|
||||
}
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage,
|
||||
sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
|
||||
|
||||
/* If battery is low. limit backlight intensity to save power. */
|
||||
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
|
||||
&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
|
||||
(sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
|
||||
if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
|
||||
corgibl_limit_intensity(1);
|
||||
sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
|
||||
}
|
||||
} else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
|
||||
corgibl_limit_intensity(0);
|
||||
sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
|
||||
}
|
||||
|
||||
/* Suspend if critical battery level */
|
||||
if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
|
||||
&& (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
|
||||
&& !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
|
||||
sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
|
||||
dev_err(sharpsl_pm.dev, "Fatal Off\n");
|
||||
apm_queue_event(APM_CRITICAL_SUSPEND);
|
||||
}
|
||||
|
||||
schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
|
||||
}
|
||||
|
||||
static void sharpsl_charge_on(void)
|
||||
{
|
||||
dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
|
||||
|
||||
sharpsl_pm.full_count = 0;
|
||||
sharpsl_pm.charge_mode = CHRG_ON;
|
||||
schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
|
||||
schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
|
||||
}
|
||||
|
||||
static void sharpsl_charge_off(void)
|
||||
{
|
||||
dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
|
||||
|
||||
CHARGE_OFF();
|
||||
CHARGE_LED_OFF();
|
||||
sharpsl_pm.charge_mode = CHRG_OFF;
|
||||
|
||||
schedule_work(&sharpsl_bat);
|
||||
}
|
||||
|
||||
static void sharpsl_charge_error(void)
|
||||
{
|
||||
CHARGE_LED_ERR();
|
||||
CHARGE_OFF();
|
||||
sharpsl_pm.charge_mode = CHRG_ERROR;
|
||||
}
|
||||
|
||||
static void sharpsl_charge_toggle(void *private_)
|
||||
{
|
||||
dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
|
||||
|
||||
if (STATUS_AC_IN == 0) {
|
||||
sharpsl_charge_off();
|
||||
return;
|
||||
} else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) {
|
||||
sharpsl_charge_error();
|
||||
return;
|
||||
}
|
||||
|
||||
CHARGE_LED_ON();
|
||||
CHARGE_OFF();
|
||||
mdelay(SHARPSL_CHARGE_WAIT_TIME);
|
||||
CHARGE_ON();
|
||||
|
||||
sharpsl_pm.charge_start_time = jiffies;
|
||||
}
|
||||
|
||||
static void sharpsl_ac_timer(unsigned long data)
|
||||
{
|
||||
int acin = STATUS_AC_IN;
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
|
||||
|
||||
sharpsl_average_clear();
|
||||
if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
|
||||
sharpsl_charge_on();
|
||||
else if (sharpsl_pm.charge_mode == CHRG_ON)
|
||||
sharpsl_charge_off();
|
||||
|
||||
schedule_work(&sharpsl_bat);
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp)
|
||||
{
|
||||
/* Delay the event slightly to debounce */
|
||||
/* Must be a smaller delay than the chrg_full_isr below */
|
||||
mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void sharpsl_chrg_full_timer(unsigned long data)
|
||||
{
|
||||
dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
|
||||
|
||||
sharpsl_pm.full_count++;
|
||||
|
||||
if (STATUS_AC_IN == 0) {
|
||||
dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
|
||||
if (sharpsl_pm.charge_mode == CHRG_ON)
|
||||
sharpsl_charge_off();
|
||||
} else if (sharpsl_pm.full_count < 2) {
|
||||
dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
|
||||
schedule_work(&toggle_charger);
|
||||
} else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
|
||||
dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
|
||||
schedule_work(&toggle_charger);
|
||||
} else {
|
||||
sharpsl_charge_off();
|
||||
sharpsl_pm.charge_mode = CHRG_DONE;
|
||||
dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Charging Finished Interrupt (Not present on Corgi) */
|
||||
/* Can trigger at the same time as an AC staus change so
|
||||
delay until after that has been processed */
|
||||
static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
|
||||
{
|
||||
if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
/* delay until after any ac interrupt */
|
||||
mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
|
||||
{
|
||||
int is_fatal = 0;
|
||||
|
||||
if (STATUS_BATT_LOCKED == 0) {
|
||||
dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
|
||||
is_fatal = 1;
|
||||
}
|
||||
|
||||
if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) {
|
||||
dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
|
||||
is_fatal = 1;
|
||||
}
|
||||
|
||||
if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
|
||||
sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
|
||||
apm_queue_event(APM_CRITICAL_SUSPEND);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maintain an average of the last 10 readings
|
||||
*/
|
||||
#define SHARPSL_CNV_VALUE_NUM 10
|
||||
static int sharpsl_ad_index;
|
||||
|
||||
static void sharpsl_average_clear(void)
|
||||
{
|
||||
sharpsl_ad_index = 0;
|
||||
}
|
||||
|
||||
static int sharpsl_average_value(int ad)
|
||||
{
|
||||
int i, ad_val = 0;
|
||||
static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
|
||||
|
||||
if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
|
||||
sharpsl_ad_index = 0;
|
||||
return ad;
|
||||
}
|
||||
|
||||
sharpsl_ad[sharpsl_ad_index] = ad;
|
||||
sharpsl_ad_index++;
|
||||
if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
|
||||
for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
|
||||
sharpsl_ad[i] = sharpsl_ad[i+1];
|
||||
sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
|
||||
}
|
||||
for (i=0; i < sharpsl_ad_index; i++)
|
||||
ad_val += sharpsl_ad[i];
|
||||
|
||||
return (ad_val / sharpsl_ad_index);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read MAX1111 ADC
|
||||
*/
|
||||
static int read_max1111(int channel)
|
||||
{
|
||||
return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
|
||||
| MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
|
||||
}
|
||||
|
||||
static int sharpsl_read_MainBattery(void)
|
||||
{
|
||||
return read_max1111(BATT_AD);
|
||||
}
|
||||
|
||||
static int sharpsl_read_Temp(void)
|
||||
{
|
||||
int temp;
|
||||
|
||||
sharpsl_pm.machinfo->measure_temp(1);
|
||||
|
||||
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
|
||||
temp = read_max1111(BATT_THM);
|
||||
|
||||
sharpsl_pm.machinfo->measure_temp(0);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
static int sharpsl_read_jkvad(void)
|
||||
{
|
||||
return read_max1111(JK_VAD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take an array of 5 integers, remove the maximum and minimum values
|
||||
* and return the average.
|
||||
*/
|
||||
static int get_select_val(int *val)
|
||||
{
|
||||
int i, j, k, temp, sum = 0;
|
||||
|
||||
/* Find MAX val */
|
||||
temp = val[0];
|
||||
j=0;
|
||||
for (i=1; i<5; i++) {
|
||||
if (temp < val[i]) {
|
||||
temp = val[i];
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find MIN val */
|
||||
temp = val[4];
|
||||
k=4;
|
||||
for (i=3; i>=0; i--) {
|
||||
if (temp > val[i]) {
|
||||
temp = val[i];
|
||||
k = i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<5; i++)
|
||||
if (i != j && i != k )
|
||||
sum += val[i];
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
|
||||
|
||||
return (sum/3);
|
||||
}
|
||||
|
||||
/* mode 0 - Check temperature and voltage
|
||||
* 1 - Check temperature only */
|
||||
static int sharpsl_check_battery(int mode)
|
||||
{
|
||||
int val, i, buff[5];
|
||||
|
||||
/* Check battery temperature */
|
||||
for (i=0; i<5; i++) {
|
||||
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
|
||||
buff[i] = sharpsl_read_Temp();
|
||||
}
|
||||
|
||||
val = get_select_val(buff);
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
|
||||
if (val > SHARPSL_CHARGE_ON_TEMP)
|
||||
return -1;
|
||||
if (mode == 1)
|
||||
return 0;
|
||||
|
||||
/* disable charge, enable discharge */
|
||||
CHARGE_OFF();
|
||||
DISCHARGE_ON();
|
||||
mdelay(SHARPSL_WAIT_DISCHARGE_ON);
|
||||
|
||||
if (sharpsl_pm.machinfo->discharge1)
|
||||
sharpsl_pm.machinfo->discharge1(1);
|
||||
|
||||
/* Check battery voltage */
|
||||
for (i=0; i<5; i++) {
|
||||
buff[i] = sharpsl_read_MainBattery();
|
||||
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
|
||||
}
|
||||
|
||||
if (sharpsl_pm.machinfo->discharge1)
|
||||
sharpsl_pm.machinfo->discharge1(0);
|
||||
|
||||
DISCHARGE_OFF();
|
||||
|
||||
val = get_select_val(buff);
|
||||
dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
|
||||
|
||||
if (val < SHARPSL_CHARGE_ON_VOLT)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sharpsl_ac_check(void)
|
||||
{
|
||||
int temp, i, buff[5];
|
||||
|
||||
for (i=0; i<5; i++) {
|
||||
buff[i] = sharpsl_read_jkvad();
|
||||
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD);
|
||||
}
|
||||
|
||||
temp = get_select_val(buff);
|
||||
dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
|
||||
|
||||
if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) {
|
||||
dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
sharpsl_pm.flags |= SHARPSL_SUSPENDED;
|
||||
flush_scheduled_work();
|
||||
|
||||
if (sharpsl_pm.charge_mode == CHRG_ON)
|
||||
sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
|
||||
else
|
||||
sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sharpsl_pm_resume(struct device *dev)
|
||||
{
|
||||
/* Clear the reset source indicators as they break the bootloader upon reboot */
|
||||
RCSR = 0x0f;
|
||||
sharpsl_average_clear();
|
||||
sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
|
||||
sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
|
||||
{
|
||||
dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
|
||||
/* not charging and AC-IN! */
|
||||
|
||||
if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) {
|
||||
dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
|
||||
sharpsl_pm.charge_mode = CHRG_OFF;
|
||||
sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
|
||||
sharpsl_off_charge_battery();
|
||||
}
|
||||
|
||||
sharpsl_pm.machinfo->presuspend();
|
||||
|
||||
PEDR = 0xffffffff; /* clear it */
|
||||
|
||||
sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
|
||||
if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
|
||||
RTSR &= RTSR_ALE;
|
||||
RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
|
||||
dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
|
||||
sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
|
||||
} else if (alarm_enable) {
|
||||
RTSR &= RTSR_ALE;
|
||||
RTAR = alarm_time;
|
||||
dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
|
||||
} else {
|
||||
dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
|
||||
}
|
||||
|
||||
pxa_pm_enter(state);
|
||||
|
||||
sharpsl_pm.machinfo->postsuspend();
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
|
||||
}
|
||||
|
||||
static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
|
||||
{
|
||||
if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
|
||||
{
|
||||
if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
|
||||
dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
|
||||
corgi_goto_sleep(alarm_time, alarm_enable, state);
|
||||
return 1;
|
||||
}
|
||||
if(sharpsl_off_charge_battery()) {
|
||||
dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
|
||||
corgi_goto_sleep(alarm_time, alarm_enable, state);
|
||||
return 1;
|
||||
}
|
||||
dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
|
||||
}
|
||||
|
||||
if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) )
|
||||
{
|
||||
dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
|
||||
corgi_goto_sleep(alarm_time, alarm_enable, state);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int corgi_pxa_pm_enter(suspend_state_t state)
|
||||
{
|
||||
unsigned long alarm_time = RTAR;
|
||||
unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
|
||||
|
||||
corgi_goto_sleep(alarm_time, alarm_status, state);
|
||||
|
||||
while (corgi_enter_suspend(alarm_time,alarm_status,state))
|
||||
{}
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Check for fatal battery errors
|
||||
* Fatal returns -1
|
||||
*/
|
||||
static int sharpsl_fatal_check(void)
|
||||
{
|
||||
int buff[5], temp, i, acin;
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
|
||||
|
||||
/* Check AC-Adapter */
|
||||
acin = STATUS_AC_IN;
|
||||
|
||||
if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
|
||||
CHARGE_OFF();
|
||||
udelay(100);
|
||||
DISCHARGE_ON(); /* enable discharge */
|
||||
mdelay(SHARPSL_WAIT_DISCHARGE_ON);
|
||||
}
|
||||
|
||||
if (sharpsl_pm.machinfo->discharge1)
|
||||
sharpsl_pm.machinfo->discharge1(1);
|
||||
|
||||
/* Check battery : check inserting battery ? */
|
||||
for (i=0; i<5; i++) {
|
||||
buff[i] = sharpsl_read_MainBattery();
|
||||
mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
|
||||
}
|
||||
|
||||
if (sharpsl_pm.machinfo->discharge1)
|
||||
sharpsl_pm.machinfo->discharge1(0);
|
||||
|
||||
if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
|
||||
udelay(100);
|
||||
CHARGE_ON();
|
||||
DISCHARGE_OFF();
|
||||
}
|
||||
|
||||
temp = get_select_val(buff);
|
||||
dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery());
|
||||
|
||||
if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
|
||||
(!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sharpsl_off_charge_error(void)
|
||||
{
|
||||
dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n");
|
||||
CHARGE_OFF();
|
||||
CHARGE_LED_ERR();
|
||||
sharpsl_pm.charge_mode = CHRG_ERROR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Charging Control while suspended
|
||||
* Return 1 - go straight to sleep
|
||||
* Return 0 - sleep or wakeup depending on other factors
|
||||
*/
|
||||
static int sharpsl_off_charge_battery(void)
|
||||
{
|
||||
int time;
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
|
||||
|
||||
if (sharpsl_pm.charge_mode == CHRG_OFF) {
|
||||
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
|
||||
|
||||
/* AC Check */
|
||||
if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0))
|
||||
return sharpsl_off_charge_error();
|
||||
|
||||
/* Start Charging */
|
||||
CHARGE_LED_ON();
|
||||
CHARGE_OFF();
|
||||
mdelay(SHARPSL_CHARGE_WAIT_TIME);
|
||||
CHARGE_ON();
|
||||
|
||||
sharpsl_pm.charge_mode = CHRG_ON;
|
||||
sharpsl_pm.full_count = 0;
|
||||
|
||||
return 1;
|
||||
} else if (sharpsl_pm.charge_mode != CHRG_ON) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sharpsl_pm.full_count == 0) {
|
||||
int time;
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
|
||||
|
||||
if (sharpsl_check_battery(0) < 0)
|
||||
return sharpsl_off_charge_error();
|
||||
|
||||
CHARGE_OFF();
|
||||
mdelay(SHARPSL_CHARGE_WAIT_TIME);
|
||||
CHARGE_ON();
|
||||
sharpsl_pm.charge_mode = CHRG_ON;
|
||||
|
||||
mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
|
||||
|
||||
time = RCNR;
|
||||
while(1) {
|
||||
/* Check if any wakeup event had occured */
|
||||
if (sharpsl_pm.machinfo->charger_wakeup() != 0)
|
||||
return 0;
|
||||
/* Check for timeout */
|
||||
if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
|
||||
return 1;
|
||||
if (STATUS_CHRG_FULL) {
|
||||
dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
|
||||
sharpsl_pm.full_count++;
|
||||
CHARGE_OFF();
|
||||
mdelay(SHARPSL_CHARGE_WAIT_TIME);
|
||||
CHARGE_ON();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
|
||||
|
||||
mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
|
||||
|
||||
time = RCNR;
|
||||
while(1) {
|
||||
/* Check if any wakeup event had occured */
|
||||
if (sharpsl_pm.machinfo->charger_wakeup() != 0)
|
||||
return 0;
|
||||
/* Check for timeout */
|
||||
if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
|
||||
if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
|
||||
dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
|
||||
sharpsl_pm.full_count = 0;
|
||||
}
|
||||
sharpsl_pm.full_count++;
|
||||
return 1;
|
||||
}
|
||||
if (STATUS_CHRG_FULL) {
|
||||
dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
|
||||
CHARGE_LED_OFF();
|
||||
CHARGE_OFF();
|
||||
sharpsl_pm.charge_mode = CHRG_DONE;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
|
||||
}
|
||||
|
||||
static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
|
||||
static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
|
||||
|
||||
extern void (*apm_get_power_status)(struct apm_power_info *);
|
||||
|
||||
static void sharpsl_apm_get_power_status(struct apm_power_info *info)
|
||||
{
|
||||
info->ac_line_status = sharpsl_pm.battstat.ac_status;
|
||||
|
||||
if (sharpsl_pm.charge_mode == CHRG_ON)
|
||||
info->battery_status = APM_BATTERY_STATUS_CHARGING;
|
||||
else
|
||||
info->battery_status = sharpsl_pm.battstat.mainbat_status;
|
||||
|
||||
info->battery_flag = (1 << info->battery_status);
|
||||
info->battery_life = sharpsl_pm.battstat.mainbat_percent;
|
||||
}
|
||||
|
||||
static struct pm_ops sharpsl_pm_ops = {
|
||||
.pm_disk_mode = PM_DISK_FIRMWARE,
|
||||
.prepare = pxa_pm_prepare,
|
||||
.enter = corgi_pxa_pm_enter,
|
||||
.finish = pxa_pm_finish,
|
||||
};
|
||||
|
||||
static int __init sharpsl_pm_probe(struct device *dev)
|
||||
{
|
||||
if (!dev->platform_data)
|
||||
return -EINVAL;
|
||||
|
||||
sharpsl_pm.dev = dev;
|
||||
sharpsl_pm.machinfo = dev->platform_data;
|
||||
sharpsl_pm.charge_mode = CHRG_OFF;
|
||||
sharpsl_pm.flags = 0;
|
||||
|
||||
sharpsl_pm.machinfo->init();
|
||||
|
||||
init_timer(&sharpsl_pm.ac_timer);
|
||||
sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
|
||||
|
||||
init_timer(&sharpsl_pm.chrg_full_timer);
|
||||
sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
|
||||
|
||||
pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
|
||||
pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
|
||||
pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
|
||||
|
||||
/* Register interrupt handlers */
|
||||
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) {
|
||||
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
|
||||
}
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE);
|
||||
|
||||
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) {
|
||||
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
|
||||
}
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING);
|
||||
|
||||
if (sharpsl_pm.machinfo->gpio_fatal) {
|
||||
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) {
|
||||
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
|
||||
}
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
|
||||
}
|
||||
|
||||
if (!machine_is_corgi())
|
||||
{
|
||||
/* Register interrupt handler. */
|
||||
if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) {
|
||||
dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
|
||||
}
|
||||
else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
|
||||
}
|
||||
|
||||
device_create_file(dev, &dev_attr_battery_percentage);
|
||||
device_create_file(dev, &dev_attr_battery_voltage);
|
||||
|
||||
apm_get_power_status = sharpsl_apm_get_power_status;
|
||||
|
||||
pm_set_ops(&sharpsl_pm_ops);
|
||||
|
||||
mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sharpsl_pm_remove(struct device *dev)
|
||||
{
|
||||
pm_set_ops(NULL);
|
||||
|
||||
device_remove_file(dev, &dev_attr_battery_percentage);
|
||||
device_remove_file(dev, &dev_attr_battery_voltage);
|
||||
|
||||
free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
|
||||
free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
|
||||
|
||||
if (sharpsl_pm.machinfo->gpio_fatal)
|
||||
free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
|
||||
|
||||
if (!machine_is_corgi())
|
||||
free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
|
||||
|
||||
del_timer_sync(&sharpsl_pm.chrg_full_timer);
|
||||
del_timer_sync(&sharpsl_pm.ac_timer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver sharpsl_pm_driver = {
|
||||
.name = "sharpsl-pm",
|
||||
.bus = &platform_bus_type,
|
||||
.probe = sharpsl_pm_probe,
|
||||
.remove = sharpsl_pm_remove,
|
||||
.suspend = sharpsl_pm_suspend,
|
||||
.resume = sharpsl_pm_resume,
|
||||
};
|
||||
|
||||
static int __devinit sharpsl_pm_init(void)
|
||||
{
|
||||
return driver_register(&sharpsl_pm_driver);
|
||||
}
|
||||
|
||||
static void sharpsl_pm_exit(void)
|
||||
{
|
||||
driver_unregister(&sharpsl_pm_driver);
|
||||
}
|
||||
|
||||
late_initcall(sharpsl_pm_init);
|
||||
module_exit(sharpsl_pm_exit);
|
@ -19,6 +19,8 @@
|
||||
* 22nd Aug 2003 Initial version.
|
||||
* 20th Dec 2004 Added ssp_config for changing port config without
|
||||
* closing the port.
|
||||
* 4th Aug 2005 Added option to disable irq handler registration and
|
||||
* cleaned up irq and clock detection.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@ -37,6 +39,26 @@
|
||||
|
||||
#define PXA_SSP_PORTS 3
|
||||
|
||||
struct ssp_info_ {
|
||||
int irq;
|
||||
u32 clock;
|
||||
};
|
||||
|
||||
/*
|
||||
* SSP port clock and IRQ settings
|
||||
*/
|
||||
static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
|
||||
#if defined (CONFIG_PXA27x)
|
||||
{IRQ_SSP, CKEN23_SSP1},
|
||||
{IRQ_SSP2, CKEN3_SSP2},
|
||||
{IRQ_SSP3, CKEN4_SSP3},
|
||||
#else
|
||||
{IRQ_SSP, CKEN3_SSP},
|
||||
{IRQ_NSSP, CKEN9_NSSP},
|
||||
{IRQ_ASSP, CKEN10_ASSP},
|
||||
#endif
|
||||
};
|
||||
|
||||
static DECLARE_MUTEX(sem);
|
||||
static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
|
||||
|
||||
@ -210,9 +232,9 @@ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 spee
|
||||
* %-EBUSY if the resources are already in use
|
||||
* %0 on success
|
||||
*/
|
||||
int ssp_init(struct ssp_dev *dev, u32 port)
|
||||
int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
|
||||
{
|
||||
int ret, irq;
|
||||
int ret;
|
||||
|
||||
if (port > PXA_SSP_PORTS || port == 0)
|
||||
return -ENODEV;
|
||||
@ -229,61 +251,20 @@ int ssp_init(struct ssp_dev *dev, u32 port)
|
||||
up(&sem);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
switch (port) {
|
||||
case 1:
|
||||
irq = IRQ_SSP;
|
||||
break;
|
||||
#if defined (CONFIG_PXA27x)
|
||||
case 2:
|
||||
irq = IRQ_SSP2;
|
||||
break;
|
||||
case 3:
|
||||
irq = IRQ_SSP3;
|
||||
break;
|
||||
#else
|
||||
case 2:
|
||||
irq = IRQ_NSSP;
|
||||
break;
|
||||
case 3:
|
||||
irq = IRQ_ASSP;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev->port = port;
|
||||
|
||||
ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev);
|
||||
if (ret)
|
||||
goto out_region;
|
||||
/* do we need to get irq */
|
||||
if (!(init_flags & SSP_NO_IRQ)) {
|
||||
ret = request_irq(ssp_info[port-1].irq, ssp_interrupt,
|
||||
0, "SSP", dev);
|
||||
if (ret)
|
||||
goto out_region;
|
||||
dev->irq = ssp_info[port-1].irq;
|
||||
} else
|
||||
dev->irq = 0;
|
||||
|
||||
/* turn on SSP port clock */
|
||||
switch (dev->port) {
|
||||
#if defined (CONFIG_PXA27x)
|
||||
case 1:
|
||||
pxa_set_cken(CKEN23_SSP1, 1);
|
||||
break;
|
||||
case 2:
|
||||
pxa_set_cken(CKEN3_SSP2, 1);
|
||||
break;
|
||||
case 3:
|
||||
pxa_set_cken(CKEN4_SSP3, 1);
|
||||
break;
|
||||
#else
|
||||
case 1:
|
||||
pxa_set_cken(CKEN3_SSP, 1);
|
||||
break;
|
||||
case 2:
|
||||
pxa_set_cken(CKEN9_NSSP, 1);
|
||||
break;
|
||||
case 3:
|
||||
pxa_set_cken(CKEN10_ASSP, 1);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
pxa_set_cken(ssp_info[port-1].clock, 1);
|
||||
up(&sem);
|
||||
return 0;
|
||||
|
||||
@ -301,46 +282,17 @@ out_region:
|
||||
*/
|
||||
void ssp_exit(struct ssp_dev *dev)
|
||||
{
|
||||
int irq;
|
||||
|
||||
down(&sem);
|
||||
SSCR0_P(dev->port) &= ~SSCR0_SSE;
|
||||
|
||||
/* find irq, save power and turn off SSP port clock */
|
||||
switch (dev->port) {
|
||||
#if defined (CONFIG_PXA27x)
|
||||
case 1:
|
||||
irq = IRQ_SSP;
|
||||
pxa_set_cken(CKEN23_SSP1, 0);
|
||||
break;
|
||||
case 2:
|
||||
irq = IRQ_SSP2;
|
||||
pxa_set_cken(CKEN3_SSP2, 0);
|
||||
break;
|
||||
case 3:
|
||||
irq = IRQ_SSP3;
|
||||
pxa_set_cken(CKEN4_SSP3, 0);
|
||||
break;
|
||||
#else
|
||||
case 1:
|
||||
irq = IRQ_SSP;
|
||||
pxa_set_cken(CKEN3_SSP, 0);
|
||||
break;
|
||||
case 2:
|
||||
irq = IRQ_NSSP;
|
||||
pxa_set_cken(CKEN9_NSSP, 0);
|
||||
break;
|
||||
case 3:
|
||||
irq = IRQ_ASSP;
|
||||
pxa_set_cken(CKEN10_ASSP, 0);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printk(KERN_WARNING "SSP: tried to close invalid port\n");
|
||||
return;
|
||||
if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
|
||||
printk(KERN_WARNING "SSP: tried to close invalid port\n");
|
||||
return;
|
||||
}
|
||||
|
||||
free_irq(irq, dev);
|
||||
pxa_set_cken(ssp_info[dev->port-1].clock, 0);
|
||||
if (dev->irq)
|
||||
free_irq(dev->irq, dev);
|
||||
release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
|
||||
use_count[dev->port - 1]--;
|
||||
up(&sem);
|
||||
|
@ -102,8 +102,8 @@ config CPU_ARM922T
|
||||
# ARM925T
|
||||
config CPU_ARM925T
|
||||
bool "Support ARM925T processor" if ARCH_OMAP1
|
||||
depends on ARCH_OMAP1510
|
||||
default y if ARCH_OMAP1510
|
||||
depends on ARCH_OMAP15XX
|
||||
default y if ARCH_OMAP15XX
|
||||
select CPU_32v4
|
||||
select CPU_ABRT_EV4T
|
||||
select CPU_CACHE_V4WT
|
||||
@ -242,7 +242,7 @@ config CPU_XSCALE
|
||||
# ARMv6
|
||||
config CPU_V6
|
||||
bool "Support ARM V6 processor"
|
||||
depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB
|
||||
depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2
|
||||
select CPU_32v6
|
||||
select CPU_ABRT_EV6
|
||||
select CPU_CACHE_V6
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
# Common support
|
||||
obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o
|
||||
obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o
|
||||
obj-m :=
|
||||
obj-n :=
|
||||
obj- :=
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* linux/arch/arm/plat-omap/clock.h
|
||||
*
|
||||
* Copyright (C) 2004 Nokia corporation
|
||||
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
|
||||
* Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_OMAP_CLOCK_H
|
||||
#define __ARCH_ARM_OMAP_CLOCK_H
|
||||
|
||||
struct module;
|
||||
|
||||
struct clk {
|
||||
struct list_head node;
|
||||
struct module *owner;
|
||||
const char *name;
|
||||
struct clk *parent;
|
||||
unsigned long rate;
|
||||
__s8 usecount;
|
||||
__u16 flags;
|
||||
__u32 enable_reg;
|
||||
__u8 enable_bit;
|
||||
__u8 rate_offset;
|
||||
void (*recalc)(struct clk *);
|
||||
int (*set_rate)(struct clk *, unsigned long);
|
||||
long (*round_rate)(struct clk *, unsigned long);
|
||||
void (*init)(struct clk *);
|
||||
};
|
||||
|
||||
|
||||
struct mpu_rate {
|
||||
unsigned long rate;
|
||||
unsigned long xtal;
|
||||
unsigned long pll_rate;
|
||||
__u16 ckctl_val;
|
||||
__u16 dpllctl_val;
|
||||
};
|
||||
|
||||
|
||||
/* Clock flags */
|
||||
#define RATE_CKCTL 1
|
||||
#define RATE_FIXED 2
|
||||
#define RATE_PROPAGATES 4
|
||||
#define VIRTUAL_CLOCK 8
|
||||
#define ALWAYS_ENABLED 16
|
||||
#define ENABLE_REG_32BIT 32
|
||||
#define CLOCK_IN_OMAP16XX 64
|
||||
#define CLOCK_IN_OMAP1510 128
|
||||
#define CLOCK_IN_OMAP730 256
|
||||
#define DSP_DOMAIN_CLOCK 512
|
||||
#define VIRTUAL_IO_ADDRESS 1024
|
||||
|
||||
/* ARM_CKCTL bit shifts */
|
||||
#define CKCTL_PERDIV_OFFSET 0
|
||||
#define CKCTL_LCDDIV_OFFSET 2
|
||||
#define CKCTL_ARMDIV_OFFSET 4
|
||||
#define CKCTL_DSPDIV_OFFSET 6
|
||||
#define CKCTL_TCDIV_OFFSET 8
|
||||
#define CKCTL_DSPMMUDIV_OFFSET 10
|
||||
/*#define ARM_TIMXO 12*/
|
||||
#define EN_DSPCK 13
|
||||
/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
|
||||
/* DSP_CKCTL bit shifts */
|
||||
#define CKCTL_DSPPERDIV_OFFSET 0
|
||||
|
||||
/* ARM_IDLECT1 bit shifts */
|
||||
/*#define IDLWDT_ARM 0*/
|
||||
/*#define IDLXORP_ARM 1*/
|
||||
/*#define IDLPER_ARM 2*/
|
||||
/*#define IDLLCD_ARM 3*/
|
||||
/*#define IDLLB_ARM 4*/
|
||||
/*#define IDLHSAB_ARM 5*/
|
||||
/*#define IDLIF_ARM 6*/
|
||||
/*#define IDLDPLL_ARM 7*/
|
||||
/*#define IDLAPI_ARM 8*/
|
||||
/*#define IDLTIM_ARM 9*/
|
||||
/*#define SETARM_IDLE 11*/
|
||||
|
||||
/* ARM_IDLECT2 bit shifts */
|
||||
#define EN_WDTCK 0
|
||||
#define EN_XORPCK 1
|
||||
#define EN_PERCK 2
|
||||
#define EN_LCDCK 3
|
||||
#define EN_LBCK 4 /* Not on 1610/1710 */
|
||||
/*#define EN_HSABCK 5*/
|
||||
#define EN_APICK 6
|
||||
#define EN_TIMCK 7
|
||||
#define DMACK_REQ 8
|
||||
#define EN_GPIOCK 9 /* Not on 1610/1710 */
|
||||
/*#define EN_LBFREECK 10*/
|
||||
#define EN_CKOUT_ARM 11
|
||||
|
||||
/* ARM_IDLECT3 bit shifts */
|
||||
#define EN_OCPI_CK 0
|
||||
#define EN_TC1_CK 2
|
||||
#define EN_TC2_CK 4
|
||||
|
||||
/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
|
||||
#define EN_DSPTIMCK 5
|
||||
|
||||
/* Various register defines for clock controls scattered around OMAP chip */
|
||||
#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
|
||||
#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
|
||||
#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
|
||||
#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
|
||||
#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
|
||||
#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
|
||||
#define SOFT_REQ_REG 0xfffe0834
|
||||
#define SOFT_REQ_REG2 0xfffe0880
|
||||
|
||||
int clk_register(struct clk *clk);
|
||||
void clk_unregister(struct clk *clk);
|
||||
int clk_init(void);
|
||||
|
||||
#endif
|
@ -31,7 +31,7 @@
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/fpga.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
#define NO_LENGTH_CHECK 0xffffffff
|
||||
|
||||
@ -117,19 +117,43 @@ EXPORT_SYMBOL(omap_get_var_config);
|
||||
|
||||
static int __init omap_add_serial_console(void)
|
||||
{
|
||||
const struct omap_serial_console_config *info;
|
||||
const struct omap_serial_console_config *con_info;
|
||||
const struct omap_uart_config *uart_info;
|
||||
static char speed[11], *opt = NULL;
|
||||
int line, i, uart_idx;
|
||||
|
||||
info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
|
||||
struct omap_serial_console_config);
|
||||
if (info != NULL && info->console_uart) {
|
||||
static char speed[11], *opt = NULL;
|
||||
uart_info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
|
||||
con_info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
|
||||
struct omap_serial_console_config);
|
||||
if (uart_info == NULL || con_info == NULL)
|
||||
return 0;
|
||||
|
||||
if (info->console_speed) {
|
||||
snprintf(speed, sizeof(speed), "%u", info->console_speed);
|
||||
opt = speed;
|
||||
}
|
||||
return add_preferred_console("ttyS", info->console_uart - 1, opt);
|
||||
if (con_info->console_uart == 0)
|
||||
return 0;
|
||||
|
||||
if (con_info->console_speed) {
|
||||
snprintf(speed, sizeof(speed), "%u", con_info->console_speed);
|
||||
opt = speed;
|
||||
}
|
||||
return 0;
|
||||
|
||||
uart_idx = con_info->console_uart - 1;
|
||||
if (uart_idx >= OMAP_MAX_NR_PORTS) {
|
||||
printk(KERN_INFO "Console: external UART#%d. "
|
||||
"Not adding it as console this time.\n",
|
||||
uart_idx + 1);
|
||||
return 0;
|
||||
}
|
||||
if (!(uart_info->enabled_uarts & (1 << uart_idx))) {
|
||||
printk(KERN_ERR "Console: Selected UART#%d is "
|
||||
"not enabled for this platform\n",
|
||||
uart_idx + 1);
|
||||
return -1;
|
||||
}
|
||||
line = 0;
|
||||
for (i = 0; i < uart_idx; i++) {
|
||||
if (uart_info->enabled_uarts & (1 << i))
|
||||
line++;
|
||||
}
|
||||
return add_preferred_console("ttyS", line, opt);
|
||||
}
|
||||
console_initcall(omap_add_serial_console);
|
||||
|
381
arch/arm/plat-omap/devices.c
Normal file
381
arch/arm/plat-omap/devices.c
Normal file
@ -0,0 +1,381 @@
|
||||
/*
|
||||
* linux/arch/arm/plat-omap/devices.c
|
||||
*
|
||||
* Common platform device setup/initialization for OMAP1 and OMAP2
|
||||
*
|
||||
* 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/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <asm/arch/tc.h>
|
||||
#include <asm/arch/board.h>
|
||||
#include <asm/arch/mux.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
||||
|
||||
void omap_nop_release(struct device *dev)
|
||||
{
|
||||
/* Nothing */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
|
||||
|
||||
#define OMAP1_I2C_BASE 0xfffb3800
|
||||
#define OMAP2_I2C_BASE1 0x48070000
|
||||
#define OMAP_I2C_SIZE 0x3f
|
||||
#define OMAP1_I2C_INT INT_I2C
|
||||
#define OMAP2_I2C_INT1 56
|
||||
|
||||
static struct resource i2c_resources1[] = {
|
||||
{
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = 0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
/* DMA not used; works around erratum writing to non-empty i2c fifo */
|
||||
|
||||
static struct platform_device omap_i2c_device1 = {
|
||||
.name = "i2c_omap",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(i2c_resources1),
|
||||
.resource = i2c_resources1,
|
||||
};
|
||||
|
||||
/* See also arch/arm/mach-omap2/devices.c for second I2C on 24xx */
|
||||
static void omap_init_i2c(void)
|
||||
{
|
||||
if (cpu_is_omap24xx()) {
|
||||
i2c_resources1[0].start = OMAP2_I2C_BASE1;
|
||||
i2c_resources1[0].end = OMAP2_I2C_BASE1 + OMAP_I2C_SIZE;
|
||||
i2c_resources1[1].start = OMAP2_I2C_INT1;
|
||||
} else {
|
||||
i2c_resources1[0].start = OMAP1_I2C_BASE;
|
||||
i2c_resources1[0].end = OMAP1_I2C_BASE + OMAP_I2C_SIZE;
|
||||
i2c_resources1[1].start = OMAP1_I2C_INT;
|
||||
}
|
||||
|
||||
/* FIXME define and use a boot tag, in case of boards that
|
||||
* either don't wire up I2C, or chips that mux it differently...
|
||||
* it can include clocking and address info, maybe more.
|
||||
*/
|
||||
if (cpu_is_omap24xx()) {
|
||||
omap_cfg_reg(M19_24XX_I2C1_SCL);
|
||||
omap_cfg_reg(L15_24XX_I2C1_SDA);
|
||||
} else {
|
||||
omap_cfg_reg(I2C_SCL);
|
||||
omap_cfg_reg(I2C_SDA);
|
||||
}
|
||||
|
||||
(void) platform_device_register(&omap_i2c_device1);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void omap_init_i2c(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP24XX
|
||||
#define OMAP_MMC1_BASE 0x4809c000
|
||||
#define OMAP_MMC1_INT 83
|
||||
#else
|
||||
#define OMAP_MMC1_BASE 0xfffb7800
|
||||
#define OMAP_MMC1_INT INT_MMC
|
||||
#endif
|
||||
#define OMAP_MMC2_BASE 0xfffb7c00 /* omap16xx only */
|
||||
|
||||
static struct omap_mmc_conf mmc1_conf;
|
||||
|
||||
static u64 mmc1_dmamask = 0xffffffff;
|
||||
|
||||
static struct resource mmc1_resources[] = {
|
||||
{
|
||||
.start = IO_ADDRESS(OMAP_MMC1_BASE),
|
||||
.end = IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = OMAP_MMC1_INT,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mmc_omap_device1 = {
|
||||
.name = "mmci-omap",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
.dma_mask = &mmc1_dmamask,
|
||||
.platform_data = &mmc1_conf,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(mmc1_resources),
|
||||
.resource = mmc1_resources,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
|
||||
static struct omap_mmc_conf mmc2_conf;
|
||||
|
||||
static u64 mmc2_dmamask = 0xffffffff;
|
||||
|
||||
static struct resource mmc2_resources[] = {
|
||||
{
|
||||
.start = IO_ADDRESS(OMAP_MMC2_BASE),
|
||||
.end = IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = INT_1610_MMC2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mmc_omap_device2 = {
|
||||
.name = "mmci-omap",
|
||||
.id = 2,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
.dma_mask = &mmc2_dmamask,
|
||||
.platform_data = &mmc2_conf,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(mmc2_resources),
|
||||
.resource = mmc2_resources,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void __init omap_init_mmc(void)
|
||||
{
|
||||
const struct omap_mmc_config *mmc_conf;
|
||||
const struct omap_mmc_conf *mmc;
|
||||
|
||||
/* NOTE: assumes MMC was never (wrongly) enabled */
|
||||
mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
|
||||
if (!mmc_conf)
|
||||
return;
|
||||
|
||||
/* block 1 is always available and has just one pinout option */
|
||||
mmc = &mmc_conf->mmc[0];
|
||||
if (mmc->enabled) {
|
||||
if (!cpu_is_omap24xx()) {
|
||||
omap_cfg_reg(MMC_CMD);
|
||||
omap_cfg_reg(MMC_CLK);
|
||||
omap_cfg_reg(MMC_DAT0);
|
||||
if (cpu_is_omap1710()) {
|
||||
omap_cfg_reg(M15_1710_MMC_CLKI);
|
||||
omap_cfg_reg(P19_1710_MMC_CMDDIR);
|
||||
omap_cfg_reg(P20_1710_MMC_DATDIR0);
|
||||
}
|
||||
}
|
||||
if (mmc->wire4) {
|
||||
if (!cpu_is_omap24xx()) {
|
||||
omap_cfg_reg(MMC_DAT1);
|
||||
/* NOTE: DAT2 can be on W10 (here) or M15 */
|
||||
if (!mmc->nomux)
|
||||
omap_cfg_reg(MMC_DAT2);
|
||||
omap_cfg_reg(MMC_DAT3);
|
||||
}
|
||||
}
|
||||
mmc1_conf = *mmc;
|
||||
(void) platform_device_register(&mmc_omap_device1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
/* block 2 is on newer chips, and has many pinout options */
|
||||
mmc = &mmc_conf->mmc[1];
|
||||
if (mmc->enabled) {
|
||||
if (!mmc->nomux) {
|
||||
omap_cfg_reg(Y8_1610_MMC2_CMD);
|
||||
omap_cfg_reg(Y10_1610_MMC2_CLK);
|
||||
omap_cfg_reg(R18_1610_MMC2_CLKIN);
|
||||
omap_cfg_reg(W8_1610_MMC2_DAT0);
|
||||
if (mmc->wire4) {
|
||||
omap_cfg_reg(V8_1610_MMC2_DAT1);
|
||||
omap_cfg_reg(W15_1610_MMC2_DAT2);
|
||||
omap_cfg_reg(R10_1610_MMC2_DAT3);
|
||||
}
|
||||
|
||||
/* These are needed for the level shifter */
|
||||
omap_cfg_reg(V9_1610_MMC2_CMDDIR);
|
||||
omap_cfg_reg(V5_1610_MMC2_DATDIR0);
|
||||
omap_cfg_reg(W19_1610_MMC2_DATDIR1);
|
||||
}
|
||||
|
||||
/* Feedback clock must be set on OMAP-1710 MMC2 */
|
||||
if (cpu_is_omap1710())
|
||||
omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
|
||||
MOD_CONF_CTRL_1);
|
||||
mmc2_conf = *mmc;
|
||||
(void) platform_device_register(&mmc_omap_device2);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_mmc(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP24XX
|
||||
#define OMAP_WDT_BASE 0x48022000
|
||||
#else
|
||||
#define OMAP_WDT_BASE 0xfffeb000
|
||||
#endif
|
||||
|
||||
static struct resource wdt_resources[] = {
|
||||
{
|
||||
.start = OMAP_WDT_BASE,
|
||||
.end = OMAP_WDT_BASE + 0x4f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device omap_wdt_device = {
|
||||
.name = "omap_wdt",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(wdt_resources),
|
||||
.resource = wdt_resources,
|
||||
};
|
||||
|
||||
static void omap_init_wdt(void)
|
||||
{
|
||||
(void) platform_device_register(&omap_wdt_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_wdt(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_OMAP_RNG) || defined(CONFIG_OMAP_RNG_MODULE)
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP24XX
|
||||
#define OMAP_RNG_BASE 0x480A0000
|
||||
#else
|
||||
#define OMAP_RNG_BASE 0xfffe5000
|
||||
#endif
|
||||
|
||||
static struct resource rng_resources[] = {
|
||||
{
|
||||
.start = OMAP_RNG_BASE,
|
||||
.end = OMAP_RNG_BASE + 0x4f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device omap_rng_device = {
|
||||
.name = "omap_rng",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(rng_resources),
|
||||
.resource = rng_resources,
|
||||
};
|
||||
|
||||
static void omap_init_rng(void)
|
||||
{
|
||||
(void) platform_device_register(&omap_rng_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_rng(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
|
||||
|
||||
static struct omap_lcd_config omap_fb_conf;
|
||||
|
||||
static u64 omap_fb_dma_mask = ~(u32)0;
|
||||
|
||||
static struct platform_device omap_fb_device = {
|
||||
.name = "omapfb",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.release = omap_nop_release,
|
||||
.dma_mask = &omap_fb_dma_mask,
|
||||
.coherent_dma_mask = ~(u32)0,
|
||||
.platform_data = &omap_fb_conf,
|
||||
},
|
||||
.num_resources = 0,
|
||||
};
|
||||
|
||||
static inline void omap_init_fb(void)
|
||||
{
|
||||
const struct omap_lcd_config *conf;
|
||||
|
||||
conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
|
||||
if (conf != NULL)
|
||||
omap_fb_conf = *conf;
|
||||
platform_device_register(&omap_fb_device);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void omap_init_fb(void) {}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This gets called after board-specific INIT_MACHINE, and initializes most
|
||||
* on-chip peripherals accessible on this board (except for few like USB):
|
||||
*
|
||||
* (a) Does any "standard config" pin muxing needed. Board-specific
|
||||
* code will have muxed GPIO pins and done "nonstandard" setup;
|
||||
* that code could live in the boot loader.
|
||||
* (b) Populating board-specific platform_data with the data drivers
|
||||
* rely on to handle wiring variations.
|
||||
* (c) Creating platform devices as meaningful on this board and
|
||||
* with this kernel configuration.
|
||||
*
|
||||
* Claiming GPIOs, and setting their direction and initial values, is the
|
||||
* responsibility of the device drivers. So is responding to probe().
|
||||
*
|
||||
* Board-specific knowlege like creating devices or pin setup is to be
|
||||
* kept out of drivers as much as possible. In particular, pin setup
|
||||
* may be handled by the boot loader, and drivers should expect it will
|
||||
* normally have been done by the time they're probed.
|
||||
*/
|
||||
static int __init omap_init_devices(void)
|
||||
{
|
||||
/* please keep these calls, and their implementations above,
|
||||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_init_fb();
|
||||
omap_init_i2c();
|
||||
omap_init_mmc();
|
||||
omap_init_wdt();
|
||||
omap_init_rng();
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(omap_init_devices);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -140,7 +140,7 @@ static struct gpio_bank gpio_bank_1610[5] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
static struct gpio_bank gpio_bank_1510[2] = {
|
||||
{ OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
|
||||
{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 }
|
||||
@ -173,7 +173,7 @@ static int gpio_bank_count;
|
||||
|
||||
static inline struct gpio_bank *get_gpio_bank(int gpio)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
if (OMAP_GPIO_IS_MPUIO(gpio))
|
||||
return &gpio_bank[0];
|
||||
@ -222,7 +222,7 @@ static inline int gpio_valid(int gpio)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510() && gpio < 16)
|
||||
return 0;
|
||||
#endif
|
||||
@ -654,7 +654,7 @@ int omap_request_gpio(int gpio)
|
||||
/* Set trigger to none. You need to enable the trigger after request_irq */
|
||||
_set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (bank->method == METHOD_GPIO_1510) {
|
||||
void __iomem *reg;
|
||||
|
||||
@ -739,7 +739,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
|
||||
bank = (struct gpio_bank *) desc->data;
|
||||
if (bank->method == METHOD_MPUIO)
|
||||
isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (bank->method == METHOD_GPIO_1510)
|
||||
isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
|
||||
#endif
|
||||
@ -774,7 +774,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
|
||||
d = irq_desc + gpio_irq;
|
||||
desc_handle_irq(gpio_irq, d, regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gpio_ack_irq(unsigned int irq)
|
||||
@ -837,8 +837,9 @@ static struct irqchip mpuio_irq_chip = {
|
||||
.unmask = mpuio_unmask_irq
|
||||
};
|
||||
|
||||
static int initialized = 0;
|
||||
static struct clk * gpio_ck = NULL;
|
||||
static int initialized;
|
||||
static struct clk * gpio_ick;
|
||||
static struct clk * gpio_fck;
|
||||
|
||||
static int __init _omap_gpio_init(void)
|
||||
{
|
||||
@ -848,14 +849,26 @@ static int __init _omap_gpio_init(void)
|
||||
initialized = 1;
|
||||
|
||||
if (cpu_is_omap1510()) {
|
||||
gpio_ck = clk_get(NULL, "arm_gpio_ck");
|
||||
if (IS_ERR(gpio_ck))
|
||||
gpio_ick = clk_get(NULL, "arm_gpio_ck");
|
||||
if (IS_ERR(gpio_ick))
|
||||
printk("Could not get arm_gpio_ck\n");
|
||||
else
|
||||
clk_use(gpio_ck);
|
||||
clk_use(gpio_ick);
|
||||
}
|
||||
if (cpu_is_omap24xx()) {
|
||||
gpio_ick = clk_get(NULL, "gpios_ick");
|
||||
if (IS_ERR(gpio_ick))
|
||||
printk("Could not get gpios_ick\n");
|
||||
else
|
||||
clk_use(gpio_ick);
|
||||
gpio_fck = clk_get(NULL, "gpios_fck");
|
||||
if (IS_ERR(gpio_ick))
|
||||
printk("Could not get gpios_fck\n");
|
||||
else
|
||||
clk_use(gpio_fck);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
printk(KERN_INFO "OMAP1510 GPIO hardware\n");
|
||||
gpio_bank_count = 2;
|
||||
@ -901,7 +914,7 @@ static int __init _omap_gpio_init(void)
|
||||
if (bank->method == METHOD_MPUIO) {
|
||||
omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
|
||||
}
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (bank->method == METHOD_GPIO_1510) {
|
||||
__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
|
||||
__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
|
||||
@ -1038,6 +1051,7 @@ static struct sys_device omap_gpio_device = {
|
||||
|
||||
/*
|
||||
* This may get called early from board specific init
|
||||
* for boards that have interrupts routed via FPGA.
|
||||
*/
|
||||
int omap_gpio_init(void)
|
||||
{
|
||||
|
@ -491,17 +491,20 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
|
||||
omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
|
||||
OMAP_DMA_DATA_TYPE_S16,
|
||||
length >> 1, 1,
|
||||
OMAP_DMA_SYNC_ELEMENT);
|
||||
OMAP_DMA_SYNC_ELEMENT,
|
||||
0, 0);
|
||||
|
||||
omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
|
||||
OMAP_DMA_PORT_TIPB,
|
||||
OMAP_DMA_AMODE_CONSTANT,
|
||||
mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
|
||||
mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
|
||||
0, 0);
|
||||
|
||||
omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
|
||||
OMAP_DMA_PORT_EMIFF,
|
||||
OMAP_DMA_AMODE_POST_INC,
|
||||
buffer);
|
||||
buffer,
|
||||
0, 0);
|
||||
|
||||
omap_start_dma(mcbsp[id].dma_tx_lch);
|
||||
wait_for_completion(&(mcbsp[id].tx_dma_completion));
|
||||
@ -531,17 +534,20 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
|
||||
omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
|
||||
OMAP_DMA_DATA_TYPE_S16,
|
||||
length >> 1, 1,
|
||||
OMAP_DMA_SYNC_ELEMENT);
|
||||
OMAP_DMA_SYNC_ELEMENT,
|
||||
0, 0);
|
||||
|
||||
omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
|
||||
OMAP_DMA_PORT_TIPB,
|
||||
OMAP_DMA_AMODE_CONSTANT,
|
||||
mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
|
||||
mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
|
||||
0, 0);
|
||||
|
||||
omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
|
||||
OMAP_DMA_PORT_EMIFF,
|
||||
OMAP_DMA_AMODE_POST_INC,
|
||||
buffer);
|
||||
buffer,
|
||||
0, 0);
|
||||
|
||||
omap_start_dma(mcbsp[id].dma_rx_lch);
|
||||
wait_for_completion(&(mcbsp[id].rx_dma_completion));
|
||||
@ -643,7 +649,7 @@ static const struct omap_mcbsp_info mcbsp_730[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
static const struct omap_mcbsp_info mcbsp_1510[] = {
|
||||
[0] = { .virt_base = OMAP1510_MCBSP1_BASE,
|
||||
.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
|
||||
@ -712,7 +718,7 @@ static int __init omap_mcbsp_init(void)
|
||||
mcbsp_count = ARRAY_SIZE(mcbsp_730);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
if (cpu_is_omap1510()) {
|
||||
mcbsp_info = mcbsp_1510;
|
||||
mcbsp_count = ARRAY_SIZE(mcbsp_1510);
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
|
||||
*
|
||||
* Copyright (C) 2003 Nokia Corporation
|
||||
* Copyright (C) 2003 - 2005 Nokia Corporation
|
||||
*
|
||||
* Written by Tony Lindgren <tony.lindgren@nokia.com>
|
||||
*
|
||||
@ -25,38 +25,74 @@
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define __MUX_C__
|
||||
#include <asm/arch/mux.h>
|
||||
|
||||
#ifdef CONFIG_OMAP_MUX
|
||||
|
||||
#define OMAP24XX_L4_BASE 0x48000000
|
||||
#define OMAP24XX_PULL_ENA (1 << 3)
|
||||
#define OMAP24XX_PULL_UP (1 << 4)
|
||||
|
||||
static struct pin_config * pin_table;
|
||||
static unsigned long pin_table_sz;
|
||||
|
||||
extern struct pin_config * omap730_pins;
|
||||
extern struct pin_config * omap1xxx_pins;
|
||||
extern struct pin_config * omap24xx_pins;
|
||||
|
||||
int __init omap_mux_register(struct pin_config * pins, unsigned long size)
|
||||
{
|
||||
pin_table = pins;
|
||||
pin_table_sz = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the Omap MUX and PULL_DWN registers based on the table
|
||||
*/
|
||||
int __init_or_module
|
||||
omap_cfg_reg(const reg_cfg_t reg_cfg)
|
||||
int __init_or_module omap_cfg_reg(const unsigned long index)
|
||||
{
|
||||
static DEFINE_SPINLOCK(mux_spin_lock);
|
||||
|
||||
unsigned long flags;
|
||||
reg_cfg_set *cfg;
|
||||
struct pin_config *cfg;
|
||||
unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
|
||||
pull_orig = 0, pull = 0;
|
||||
unsigned int mask, warn = 0;
|
||||
|
||||
if (cpu_is_omap7xx())
|
||||
return 0;
|
||||
if (!pin_table)
|
||||
BUG();
|
||||
|
||||
if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
|
||||
printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
|
||||
return -EINVAL;
|
||||
if (index >= pin_table_sz) {
|
||||
printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
|
||||
index, pin_table_sz);
|
||||
dump_stack();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cfg = (reg_cfg_set *)®_cfg_table[reg_cfg];
|
||||
cfg = (struct pin_config *)&pin_table[index];
|
||||
if (cpu_is_omap24xx()) {
|
||||
u8 reg = 0;
|
||||
|
||||
reg |= cfg->mask & 0x7;
|
||||
if (cfg->pull_val)
|
||||
reg |= OMAP24XX_PULL_ENA;
|
||||
if(cfg->pu_pd_val)
|
||||
reg |= OMAP24XX_PULL_UP;
|
||||
#ifdef CONFIG_OMAP_MUX_DEBUG
|
||||
printk("Muxing %s (0x%08x): 0x%02x -> 0x%02x\n",
|
||||
cfg->name, OMAP24XX_L4_BASE + cfg->mux_reg,
|
||||
omap_readb(OMAP24XX_L4_BASE + cfg->mux_reg), reg);
|
||||
#endif
|
||||
omap_writeb(reg, OMAP24XX_L4_BASE + cfg->mux_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the mux register in question */
|
||||
if (cfg->mux_reg) {
|
||||
@ -157,7 +193,8 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(omap_cfg_reg);
|
||||
|
||||
#else
|
||||
#define omap_mux_init() do {} while(0)
|
||||
#define omap_cfg_reg(x) do {} while(0)
|
||||
#endif /* CONFIG_OMAP_MUX */
|
||||
|
@ -54,11 +54,12 @@
|
||||
#include <asm/arch/tps65010.h>
|
||||
#include <asm/arch/dsp_common.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "sram.h"
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sram.h>
|
||||
|
||||
static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
|
||||
static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
|
||||
static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
|
||||
|
||||
@ -120,8 +121,8 @@ void omap_pm_idle(void)
|
||||
*/
|
||||
static void omap_pm_wakeup_setup(void)
|
||||
{
|
||||
u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ);
|
||||
u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD);
|
||||
u32 level1_wake = 0;
|
||||
u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
|
||||
|
||||
/*
|
||||
* Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
|
||||
@ -129,19 +130,29 @@ static void omap_pm_wakeup_setup(void)
|
||||
* drivers must still separately call omap_set_gpio_wakeup() to
|
||||
* wake up to a GPIO interrupt.
|
||||
*/
|
||||
if (cpu_is_omap1510() || cpu_is_omap16xx())
|
||||
level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1);
|
||||
else if (cpu_is_omap730())
|
||||
level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1);
|
||||
if (cpu_is_omap730())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_730_IH2_IRQ);
|
||||
else if (cpu_is_omap1510())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
|
||||
else if (cpu_is_omap16xx())
|
||||
level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
|
||||
OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
|
||||
|
||||
omap_writel(~level1_wake, OMAP_IH1_MIR);
|
||||
|
||||
if (cpu_is_omap1510())
|
||||
omap_writel(~level2_wake, OMAP_IH2_MIR);
|
||||
|
||||
/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
|
||||
if (cpu_is_omap16xx()) {
|
||||
if (cpu_is_omap730()) {
|
||||
omap_writel(~level2_wake, OMAP_IH2_0_MIR);
|
||||
omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR);
|
||||
} else if (cpu_is_omap1510()) {
|
||||
level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
|
||||
omap_writel(~level2_wake, OMAP_IH2_MIR);
|
||||
} else if (cpu_is_omap16xx()) {
|
||||
level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
|
||||
omap_writel(~level2_wake, OMAP_IH2_0_MIR);
|
||||
|
||||
/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
|
||||
omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
|
||||
omap_writel(~0x0, OMAP_IH2_2_MIR);
|
||||
omap_writel(~0x0, OMAP_IH2_3_MIR);
|
||||
@ -185,7 +196,17 @@ void omap_pm_suspend(void)
|
||||
* Save interrupt, MPUI, ARM and UPLD control registers.
|
||||
*/
|
||||
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_SAVE(OMAP_IH1_MIR);
|
||||
MPUI730_SAVE(OMAP_IH2_0_MIR);
|
||||
MPUI730_SAVE(OMAP_IH2_1_MIR);
|
||||
MPUI730_SAVE(MPUI_CTRL);
|
||||
MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI730_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI730_SAVE(EMIFS_CONFIG);
|
||||
MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
|
||||
} else if (cpu_is_omap1510()) {
|
||||
MPUI1510_SAVE(OMAP_IH1_MIR);
|
||||
MPUI1510_SAVE(OMAP_IH2_MIR);
|
||||
MPUI1510_SAVE(MPUI_CTRL);
|
||||
@ -280,7 +301,13 @@ void omap_pm_suspend(void)
|
||||
ULPD_RESTORE(ULPD_CLOCK_CTRL);
|
||||
ULPD_RESTORE(ULPD_STATUS_REQ);
|
||||
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_RESTORE(EMIFS_CONFIG);
|
||||
MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI730_RESTORE(OMAP_IH1_MIR);
|
||||
MPUI730_RESTORE(OMAP_IH2_0_MIR);
|
||||
MPUI730_RESTORE(OMAP_IH2_1_MIR);
|
||||
} else if (cpu_is_omap1510()) {
|
||||
MPUI1510_RESTORE(MPUI_CTRL);
|
||||
MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
|
||||
@ -355,7 +382,14 @@ static int omap_pm_read_proc(
|
||||
ULPD_SAVE(ULPD_DPLL_CTRL);
|
||||
ULPD_SAVE(ULPD_POWER_CTRL);
|
||||
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap730()) {
|
||||
MPUI730_SAVE(MPUI_CTRL);
|
||||
MPUI730_SAVE(MPUI_DSP_STATUS);
|
||||
MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
MPUI730_SAVE(MPUI_DSP_API_CONFIG);
|
||||
MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
|
||||
MPUI730_SAVE(EMIFS_CONFIG);
|
||||
} else if (cpu_is_omap1510()) {
|
||||
MPUI1510_SAVE(MPUI_CTRL);
|
||||
MPUI1510_SAVE(MPUI_DSP_STATUS);
|
||||
MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
|
||||
@ -404,7 +438,21 @@ static int omap_pm_read_proc(
|
||||
ULPD_SHOW(ULPD_STATUS_REQ),
|
||||
ULPD_SHOW(ULPD_POWER_CTRL));
|
||||
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap730()) {
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"MPUI730_CTRL_REG 0x%-8x \n"
|
||||
"MPUI730_DSP_STATUS_REG: 0x%-8x \n"
|
||||
"MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n"
|
||||
"MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n",
|
||||
MPUI730_SHOW(MPUI_CTRL),
|
||||
MPUI730_SHOW(MPUI_DSP_STATUS),
|
||||
MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
|
||||
MPUI730_SHOW(MPUI_DSP_API_CONFIG),
|
||||
MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
|
||||
MPUI730_SHOW(EMIFS_CONFIG));
|
||||
} else if (cpu_is_omap1510()) {
|
||||
my_buffer_offset += sprintf(my_base + my_buffer_offset,
|
||||
"MPUI1510_CTRL_REG 0x%-8x \n"
|
||||
"MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
|
||||
@ -553,7 +601,12 @@ static int __init omap_pm_init(void)
|
||||
* These routines need to be in SRAM as that's the only
|
||||
* memory the MPU can see when it wakes up.
|
||||
*/
|
||||
if (cpu_is_omap1510()) {
|
||||
if (cpu_is_omap730()) {
|
||||
omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
|
||||
omap730_idle_loop_suspend_sz);
|
||||
omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
|
||||
omap730_cpu_suspend_sz);
|
||||
} else if (cpu_is_omap1510()) {
|
||||
omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
|
||||
omap1510_idle_loop_suspend_sz);
|
||||
omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
|
||||
@ -572,7 +625,11 @@ static int __init omap_pm_init(void)
|
||||
|
||||
pm_idle = omap_pm_idle;
|
||||
|
||||
setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
if (cpu_is_omap730())
|
||||
setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
else if (cpu_is_omap16xx())
|
||||
setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
|
||||
|
||||
#if 0
|
||||
/* --- BEGIN BOARD-DEPENDENT CODE --- */
|
||||
/* Sleepx mask direction */
|
||||
@ -591,7 +648,9 @@ static int __init omap_pm_init(void)
|
||||
omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
|
||||
|
||||
/* Configure IDLECT3 */
|
||||
if (cpu_is_omap16xx())
|
||||
if (cpu_is_omap730())
|
||||
omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
|
||||
else if (cpu_is_omap16xx())
|
||||
omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
|
||||
|
||||
pm_set_ops(&omap_pm_ops);
|
||||
@ -600,8 +659,10 @@ static int __init omap_pm_init(void)
|
||||
omap_pm_init_proc();
|
||||
#endif
|
||||
|
||||
/* configure LOW_PWR pin */
|
||||
omap_cfg_reg(T20_1610_LOW_PWR);
|
||||
if (cpu_is_omap16xx()) {
|
||||
/* configure LOW_PWR pin */
|
||||
omap_cfg_reg(T20_1610_LOW_PWR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* linux/arch/arm/plat-omap/sleep.S
|
||||
*
|
||||
* Low-level OMAP1510/1610 sleep/wakeUp support
|
||||
* Low-level OMAP730/1510/1610 sleep/wakeUp support
|
||||
*
|
||||
* Initial SA1110 code:
|
||||
* Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
|
||||
@ -52,7 +52,57 @@
|
||||
* processor specific functions here.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#if defined(CONFIG_ARCH_OMAP730)
|
||||
ENTRY(omap730_idle_loop_suspend)
|
||||
|
||||
stmfd sp!, {r0 - r12, lr} @ save registers on stack
|
||||
|
||||
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
|
||||
mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
|
||||
orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
|
||||
orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
|
||||
|
||||
@ turn off clock domains
|
||||
@ get ARM_IDLECT2 into r2
|
||||
ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
|
||||
orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
|
||||
strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
|
||||
@ request ARM idle
|
||||
@ get ARM_IDLECT1 into r1
|
||||
ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
orr r3, r1, #OMAP730_IDLE_LOOP_REQUEST & 0xffff
|
||||
strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
|
||||
mov r5, #IDLE_WAIT_CYCLES & 0xff
|
||||
orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
|
||||
l_730: subs r5, r5, #1
|
||||
bne l_730
|
||||
/*
|
||||
* Let's wait for the next clock tick to wake us up.
|
||||
*/
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
|
||||
/*
|
||||
* omap730_idle_loop_suspend()'s resume point.
|
||||
*
|
||||
* It will just start executing here, so we'll restore stuff from the
|
||||
* stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
|
||||
*/
|
||||
|
||||
@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
|
||||
@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
|
||||
strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
|
||||
ldmfd sp!, {r0 - r12, pc} @ restore regs and return
|
||||
|
||||
ENTRY(omap730_idle_loop_suspend_sz)
|
||||
.word . - omap730_idle_loop_suspend
|
||||
#endif /* CONFIG_ARCH_OMAP730 */
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
ENTRY(omap1510_idle_loop_suspend)
|
||||
|
||||
stmfd sp!, {r0 - r12, lr} @ save registers on stack
|
||||
@ -100,7 +150,7 @@ l_1510: subs r5, r5, #1
|
||||
|
||||
ENTRY(omap1510_idle_loop_suspend_sz)
|
||||
.word . - omap1510_idle_loop_suspend
|
||||
#endif /* CONFIG_ARCH_OMAP1510 */
|
||||
#endif /* CONFIG_ARCH_OMAP15XX */
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
ENTRY(omap1610_idle_loop_suspend)
|
||||
@ -169,7 +219,86 @@ ENTRY(omap1610_idle_loop_suspend_sz)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#if defined(CONFIG_ARCH_OMAP730)
|
||||
ENTRY(omap730_cpu_suspend)
|
||||
|
||||
@ save registers on stack
|
||||
stmfd sp!, {r0 - r12, lr}
|
||||
|
||||
@ Drain write cache
|
||||
mov r4, #0
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
nop
|
||||
|
||||
@ load base address of Traffic Controller
|
||||
mov r6, #TCMIF_ASM_BASE & 0xff000000
|
||||
orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
|
||||
orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
|
||||
|
||||
@ prepare to put SDRAM into self-refresh manually
|
||||
ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
|
||||
orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
|
||||
str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ prepare to put EMIFS to Sleep
|
||||
ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
|
||||
str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ load base address of ARM_IDLECT1 and ARM_IDLECT2
|
||||
mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
|
||||
orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
|
||||
orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
|
||||
|
||||
@ turn off clock domains
|
||||
@ do not disable PERCK (0x04)
|
||||
mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
|
||||
orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
|
||||
strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
|
||||
@ request ARM idle
|
||||
mov r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff
|
||||
orr r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00
|
||||
strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
|
||||
@ disable instruction cache
|
||||
mrc p15, 0, r9, c1, c0, 0
|
||||
bic r2, r9, #0x1000
|
||||
mcr p15, 0, r2, c1, c0, 0
|
||||
nop
|
||||
|
||||
/*
|
||||
* Let's wait for the next wake up event to wake us up. r0 can't be
|
||||
* used here because r0 holds ARM_IDLECT1
|
||||
*/
|
||||
mov r2, #0
|
||||
mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
|
||||
/*
|
||||
* omap730_cpu_suspend()'s resume point.
|
||||
*
|
||||
* It will just start executing here, so we'll restore stuff from the
|
||||
* stack.
|
||||
*/
|
||||
@ re-enable Icache
|
||||
mcr p15, 0, r9, c1, c0, 0
|
||||
|
||||
@ reset the ARM_IDLECT1 and ARM_IDLECT2.
|
||||
strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
|
||||
strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
|
||||
|
||||
@ Restore EMIFF controls
|
||||
str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
|
||||
str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
|
||||
|
||||
@ restore regs and return
|
||||
ldmfd sp!, {r0 - r12, pc}
|
||||
|
||||
ENTRY(omap730_cpu_suspend_sz)
|
||||
.word . - omap730_cpu_suspend
|
||||
#endif /* CONFIG_ARCH_OMAP730 */
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
ENTRY(omap1510_cpu_suspend)
|
||||
|
||||
@ save registers on stack
|
||||
@ -241,7 +370,7 @@ l_1510_2:
|
||||
|
||||
ENTRY(omap1510_cpu_suspend_sz)
|
||||
.word . - omap1510_cpu_suspend
|
||||
#endif /* CONFIG_ARCH_OMAP1510 */
|
||||
#endif /* CONFIG_ARCH_OMAP15XX */
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
ENTRY(omap1610_cpu_suspend)
|
||||
|
@ -20,10 +20,13 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include "sram.h"
|
||||
#include <asm/arch/sram.h>
|
||||
|
||||
#define OMAP1_SRAM_PA 0x20000000
|
||||
#define OMAP1_SRAM_VA 0xd0000000
|
||||
#define OMAP2_SRAM_PA 0x40200000
|
||||
#define OMAP2_SRAM_VA 0xd0000000
|
||||
|
||||
#define OMAP1_SRAM_BASE 0xd0000000
|
||||
#define OMAP1_SRAM_START 0x20000000
|
||||
#define SRAM_BOOTLOADER_SZ 0x80
|
||||
|
||||
static unsigned long omap_sram_base;
|
||||
@ -31,37 +34,40 @@ static unsigned long omap_sram_size;
|
||||
static unsigned long omap_sram_ceil;
|
||||
|
||||
/*
|
||||
* The amount of SRAM depends on the core type:
|
||||
* 730 = 200K, 1510 = 512K, 5912 = 256K, 1610 = 16K, 1710 = 16K
|
||||
* The amount of SRAM depends on the core type.
|
||||
* Note that we cannot try to test for SRAM here because writes
|
||||
* to secure SRAM will hang the system. Also the SRAM is not
|
||||
* yet mapped at this point.
|
||||
*/
|
||||
void __init omap_detect_sram(void)
|
||||
{
|
||||
omap_sram_base = OMAP1_SRAM_BASE;
|
||||
if (!cpu_is_omap24xx())
|
||||
omap_sram_base = OMAP1_SRAM_VA;
|
||||
else
|
||||
omap_sram_base = OMAP2_SRAM_VA;
|
||||
|
||||
if (cpu_is_omap730())
|
||||
omap_sram_size = 0x32000;
|
||||
else if (cpu_is_omap1510())
|
||||
omap_sram_size = 0x80000;
|
||||
omap_sram_size = 0x32000; /* 200K */
|
||||
else if (cpu_is_omap15xx())
|
||||
omap_sram_size = 0x30000; /* 192K */
|
||||
else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
|
||||
omap_sram_size = 0x4000;
|
||||
omap_sram_size = 0x4000; /* 16K */
|
||||
else if (cpu_is_omap1611())
|
||||
omap_sram_size = 0x3e800;
|
||||
omap_sram_size = 0x3e800; /* 250K */
|
||||
else if (cpu_is_omap2420())
|
||||
omap_sram_size = 0xa0014; /* 640K */
|
||||
else {
|
||||
printk(KERN_ERR "Could not detect SRAM size\n");
|
||||
omap_sram_size = 0x4000;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "SRAM size: 0x%lx\n", omap_sram_size);
|
||||
omap_sram_ceil = omap_sram_base + omap_sram_size;
|
||||
}
|
||||
|
||||
static struct map_desc omap_sram_io_desc[] __initdata = {
|
||||
{ /* .length gets filled in at runtime */
|
||||
.virtual = OMAP1_SRAM_BASE,
|
||||
.pfn = __phys_to_pfn(OMAP1_SRAM_START),
|
||||
.virtual = OMAP1_SRAM_VA,
|
||||
.pfn = __phys_to_pfn(OMAP1_SRAM_PA),
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
@ -76,10 +82,19 @@ void __init omap_map_sram(void)
|
||||
if (omap_sram_size == 0)
|
||||
return;
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
|
||||
omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA);
|
||||
}
|
||||
|
||||
omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
|
||||
omap_sram_io_desc[0].length *= PAGE_SIZE;
|
||||
iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
|
||||
|
||||
printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
|
||||
omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual,
|
||||
omap_sram_io_desc[0].length);
|
||||
|
||||
/*
|
||||
* Looks like we need to preserve some bootloader code at the
|
||||
* beginning of SRAM for jumping to flash for reboot to work...
|
||||
@ -88,16 +103,6 @@ void __init omap_map_sram(void)
|
||||
omap_sram_size - SRAM_BOOTLOADER_SZ);
|
||||
}
|
||||
|
||||
static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL;
|
||||
|
||||
void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
|
||||
{
|
||||
if (_omap_sram_reprogram_clock == NULL)
|
||||
panic("Cannot use SRAM");
|
||||
|
||||
return _omap_sram_reprogram_clock(dpllctl, ckctl);
|
||||
}
|
||||
|
||||
void * omap_sram_push(void * start, unsigned long size)
|
||||
{
|
||||
if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
|
||||
@ -111,10 +116,94 @@ void * omap_sram_push(void * start, unsigned long size)
|
||||
return (void *)omap_sram_ceil;
|
||||
}
|
||||
|
||||
void __init omap_sram_init(void)
|
||||
static void omap_sram_error(void)
|
||||
{
|
||||
panic("Uninitialized SRAM function\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1
|
||||
|
||||
static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
|
||||
|
||||
void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
|
||||
{
|
||||
if (!_omap_sram_reprogram_clock)
|
||||
omap_sram_error();
|
||||
|
||||
return _omap_sram_reprogram_clock(dpllctl, ckctl);
|
||||
}
|
||||
|
||||
int __init omap1_sram_init(void)
|
||||
{
|
||||
_omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
|
||||
sram_reprogram_clock_sz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define omap1_sram_init() do {} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2
|
||||
|
||||
static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
|
||||
u32 base_cs, u32 force_unlock);
|
||||
|
||||
void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
|
||||
u32 base_cs, u32 force_unlock)
|
||||
{
|
||||
if (!_omap2_sram_ddr_init)
|
||||
omap_sram_error();
|
||||
|
||||
return _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
|
||||
base_cs, force_unlock);
|
||||
}
|
||||
|
||||
static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
|
||||
u32 mem_type);
|
||||
|
||||
void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
|
||||
{
|
||||
if (!_omap2_sram_reprogram_sdrc)
|
||||
omap_sram_error();
|
||||
|
||||
return _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
|
||||
}
|
||||
|
||||
static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
|
||||
|
||||
u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
|
||||
{
|
||||
if (!_omap2_set_prcm)
|
||||
omap_sram_error();
|
||||
|
||||
return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
|
||||
}
|
||||
|
||||
int __init omap2_sram_init(void)
|
||||
{
|
||||
_omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz);
|
||||
|
||||
_omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc,
|
||||
sram_reprogram_sdrc_sz);
|
||||
_omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define omap2_sram_init() do {} while (0)
|
||||
#endif
|
||||
|
||||
int __init omap_sram_init(void)
|
||||
{
|
||||
omap_detect_sram();
|
||||
omap_map_sram();
|
||||
_omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
|
||||
sram_reprogram_clock_sz);
|
||||
|
||||
if (!cpu_is_omap24xx())
|
||||
omap1_sram_init();
|
||||
else
|
||||
omap2_sram_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* linux/arch/arm/plat-omap/sram.h
|
||||
*
|
||||
* Interface for functions that need to be run in internal SRAM
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ARM_OMAP_SRAM_H
|
||||
#define __ARCH_ARM_OMAP_SRAM_H
|
||||
|
||||
extern void * omap_sram_push(void * start, unsigned long size);
|
||||
extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
|
||||
|
||||
/* Do not use these */
|
||||
extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
|
||||
extern unsigned long sram_reprogram_clock_sz;
|
||||
|
||||
#endif
|
@ -91,6 +91,8 @@ EXPORT_SYMBOL(otg_set_transceiver);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX)
|
||||
|
||||
static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
|
||||
{
|
||||
u32 syscon1 = 0;
|
||||
@ -271,6 +273,8 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
|
||||
return syscon1 << 24;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_USB_GADGET_OMAP) || \
|
||||
@ -494,7 +498,7 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP1510
|
||||
#ifdef CONFIG_ARCH_OMAP15XX
|
||||
|
||||
#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL)
|
||||
#define DPLL_IOB (1 << 13)
|
||||
@ -507,7 +511,6 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
|
||||
|
||||
static void __init omap_1510_usb_init(struct omap_usb_config *config)
|
||||
{
|
||||
int status;
|
||||
unsigned int val;
|
||||
|
||||
omap_usb0_init(config->pins[0], is_usb0_device(config));
|
||||
@ -539,6 +542,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
|
||||
|
||||
#ifdef CONFIG_USB_GADGET_OMAP
|
||||
if (config->register_dev) {
|
||||
int status;
|
||||
|
||||
udc_device.dev.platform_data = config;
|
||||
status = platform_device_register(&udc_device);
|
||||
if (status)
|
||||
@ -549,6 +554,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
|
||||
|
||||
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
|
||||
if (config->register_host) {
|
||||
int status;
|
||||
|
||||
ohci_device.dev.platform_data = config;
|
||||
status = platform_device_register(&ohci_device);
|
||||
if (status)
|
||||
|
@ -433,9 +433,8 @@ static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev)
|
||||
return; /* only applies to certain Toshibas (so far) */
|
||||
|
||||
/* Restore config space on Toshiba laptops */
|
||||
mdelay(10);
|
||||
pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
|
||||
pci_write_config_word(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, (u8 *)&dev->irq);
|
||||
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
|
||||
pci_resource_start(dev, 0));
|
||||
pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
|
||||
|
@ -987,7 +987,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((res = kcalloc(1, sizeof(struct resource), GFP_KERNEL)) == NULL) {
|
||||
if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
|
||||
printk(KERN_ERR "failed to alocate resource for iomem\n");
|
||||
return;
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
((struct fnptr *)kretprobe_trampoline)->ip;
|
||||
|
||||
spin_lock_irqsave(&kretprobe_lock, flags);
|
||||
head = kretprobe_inst_table_head(current);
|
||||
head = kretprobe_inst_table_head(current);
|
||||
|
||||
/*
|
||||
* It is possible to have multiple instances associated with a given
|
||||
@ -363,9 +363,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
* kretprobe_trampoline
|
||||
*/
|
||||
hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
|
||||
if (ri->task != current)
|
||||
if (ri->task != current)
|
||||
/* another task is sharing our hash bucket */
|
||||
continue;
|
||||
continue;
|
||||
|
||||
if (ri->rp && ri->rp->handler)
|
||||
ri->rp->handler(ri, regs);
|
||||
@ -394,7 +394,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
* kprobe_handler() that we don't want the post_handler
|
||||
* to run (and have re-enabled preemption)
|
||||
*/
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Called with kretprobe_lock held */
|
||||
@ -739,12 +739,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
||||
|
||||
switch(val) {
|
||||
case DIE_BREAK:
|
||||
if (pre_kprobes_handler(args))
|
||||
ret = NOTIFY_STOP;
|
||||
/* err is break number from ia64_bad_break() */
|
||||
if (args->err == 0x80200 || args->err == 0x80300)
|
||||
if (pre_kprobes_handler(args))
|
||||
ret = NOTIFY_STOP;
|
||||
break;
|
||||
case DIE_SS:
|
||||
if (post_kprobes_handler(args->regs))
|
||||
ret = NOTIFY_STOP;
|
||||
case DIE_FAULT:
|
||||
/* err is vector number from ia64_fault() */
|
||||
if (args->err == 36)
|
||||
if (post_kprobes_handler(args->regs))
|
||||
ret = NOTIFY_STOP;
|
||||
break;
|
||||
case DIE_PAGE_FAULT:
|
||||
/* kprobe_running() needs smp_processor_id() */
|
||||
|
@ -51,6 +51,9 @@
|
||||
*
|
||||
* 2005-08-12 Keith Owens <kaos@sgi.com>
|
||||
* Convert MCA/INIT handlers to use per event stacks and SAL/OS state.
|
||||
*
|
||||
* 2005-10-07 Keith Owens <kaos@sgi.com>
|
||||
* Add notify_die() hooks.
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/types.h>
|
||||
@ -58,7 +61,6 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/acpi.h>
|
||||
@ -69,6 +71,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <asm/delay.h>
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/machvec.h>
|
||||
#include <asm/meminit.h>
|
||||
#include <asm/page.h>
|
||||
@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
|
||||
|
||||
static int mca_init;
|
||||
|
||||
|
||||
static void inline
|
||||
ia64_mca_spin(const char *func)
|
||||
{
|
||||
printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func);
|
||||
while (1)
|
||||
cpu_relax();
|
||||
}
|
||||
/*
|
||||
* IA64_MCA log support
|
||||
*/
|
||||
@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void)
|
||||
* Outputs : None
|
||||
*/
|
||||
static irqreturn_t
|
||||
ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
|
||||
ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long flags;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
/* Mask all interrupts */
|
||||
local_irq_save(flags);
|
||||
if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
|
||||
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
|
||||
/* Register with the SAL monarch that the slave has
|
||||
@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
|
||||
*/
|
||||
ia64_sal_mc_rendez();
|
||||
|
||||
if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
|
||||
/* Wait for the monarch cpu to exit. */
|
||||
while (monarch_cpu != -1)
|
||||
cpu_relax(); /* spin until monarch leaves */
|
||||
|
||||
if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
|
||||
/* Enable all interrupts */
|
||||
local_irq_restore(flags);
|
||||
return IRQ_HANDLED;
|
||||
@ -933,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
|
||||
previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
|
||||
monarch_cpu = cpu;
|
||||
if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
ia64_wait_for_slaves(cpu);
|
||||
|
||||
/* Wakeup all the processors which are spinning in the rendezvous loop.
|
||||
@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||
* spinning in SAL does not work.
|
||||
*/
|
||||
ia64_mca_wakeup_all();
|
||||
if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
|
||||
/* Get the MCA error record and log it */
|
||||
ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
|
||||
@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||
ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
|
||||
sos->os_status = IA64_MCA_CORRECTED;
|
||||
}
|
||||
if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
|
||||
set_curr_task(cpu, previous_current);
|
||||
monarch_cpu = -1;
|
||||
@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy)
|
||||
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
static int
|
||||
default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data)
|
||||
{
|
||||
int c;
|
||||
struct task_struct *g, *t;
|
||||
if (val != DIE_INIT_MONARCH_PROCESS)
|
||||
return NOTIFY_DONE;
|
||||
printk(KERN_ERR "Processes interrupted by INIT -");
|
||||
for_each_online_cpu(c) {
|
||||
struct ia64_sal_os_state *s;
|
||||
t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
|
||||
s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
|
||||
g = s->prev_task;
|
||||
if (g) {
|
||||
if (g->pid)
|
||||
printk(" %d", g->pid);
|
||||
else
|
||||
printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
|
||||
}
|
||||
}
|
||||
printk("\n\n");
|
||||
if (read_trylock(&tasklist_lock)) {
|
||||
do_each_thread (g, t) {
|
||||
printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
|
||||
show_stack(t, NULL);
|
||||
} while_each_thread (g, t);
|
||||
read_unlock(&tasklist_lock);
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* C portion of the OS INIT handler
|
||||
*
|
||||
@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||
static atomic_t slaves;
|
||||
static atomic_t monarchs;
|
||||
task_t *previous_current;
|
||||
int cpu = smp_processor_id(), c;
|
||||
struct task_struct *g, *t;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
|
||||
console_loglevel = 15; /* make sure printks make it to console */
|
||||
@ -1253,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
|
||||
while (monarch_cpu == -1)
|
||||
cpu_relax(); /* spin until monarch enters */
|
||||
if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
while (monarch_cpu != -1)
|
||||
cpu_relax(); /* spin until monarch leaves */
|
||||
if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
printk("Slave on cpu %d returning to normal service.\n", cpu);
|
||||
set_curr_task(cpu, previous_current);
|
||||
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
|
||||
@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||
}
|
||||
|
||||
monarch_cpu = cpu;
|
||||
if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
|
||||
/*
|
||||
* Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be
|
||||
@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
|
||||
printk("Delaying for 5 seconds...\n");
|
||||
udelay(5*1000000);
|
||||
ia64_wait_for_slaves(cpu);
|
||||
printk(KERN_ERR "Processes interrupted by INIT -");
|
||||
for_each_online_cpu(c) {
|
||||
struct ia64_sal_os_state *s;
|
||||
t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
|
||||
s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
|
||||
g = s->prev_task;
|
||||
if (g) {
|
||||
if (g->pid)
|
||||
printk(" %d", g->pid);
|
||||
else
|
||||
printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
|
||||
}
|
||||
}
|
||||
printk("\n\n");
|
||||
if (read_trylock(&tasklist_lock)) {
|
||||
do_each_thread (g, t) {
|
||||
printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
|
||||
show_stack(t, NULL);
|
||||
} while_each_thread (g, t);
|
||||
read_unlock(&tasklist_lock);
|
||||
}
|
||||
/* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
|
||||
* to default_monarch_init_process() above and just print all the
|
||||
* tasks.
|
||||
*/
|
||||
if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0)
|
||||
== NOTIFY_STOP)
|
||||
ia64_mca_spin(__FUNCTION__);
|
||||
printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
|
||||
atomic_dec(&monarchs);
|
||||
set_curr_task(cpu, previous_current);
|
||||
@ -1462,6 +1524,10 @@ ia64_mca_init(void)
|
||||
s64 rc;
|
||||
struct ia64_sal_retval isrv;
|
||||
u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */
|
||||
static struct notifier_block default_init_monarch_nb = {
|
||||
.notifier_call = default_monarch_init_process,
|
||||
.priority = 0/* we need to notified last */
|
||||
};
|
||||
|
||||
IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
|
||||
|
||||
@ -1555,6 +1621,10 @@ ia64_mca_init(void)
|
||||
"(status %ld)\n", rc);
|
||||
return;
|
||||
}
|
||||
if (register_die_notifier(&default_init_monarch_nb)) {
|
||||
printk(KERN_ERR "Failed to register default monarch INIT process\n");
|
||||
return;
|
||||
}
|
||||
|
||||
IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
|
||||
|
||||
|
@ -547,9 +547,20 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
|
||||
(pal_processor_state_info_t*)peidx_psp(peidx);
|
||||
|
||||
/*
|
||||
* We cannot recover errors with other than bus_check.
|
||||
* Processor recovery status must key off of the PAL recovery
|
||||
* status in the Processor State Parameter.
|
||||
*/
|
||||
if (psp->cc || psp->rc || psp->uc)
|
||||
|
||||
/*
|
||||
* The machine check is corrected.
|
||||
*/
|
||||
if (psp->cm == 1)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* The error was not contained. Software must be reset.
|
||||
*/
|
||||
if (psp->us || psp->ci == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@ -570,8 +581,6 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
|
||||
return 0;
|
||||
if (pbci->eb && pbci->bsi > 0)
|
||||
return 0;
|
||||
if (psp->ci == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* This is a local MCA and estimated as recoverble external bus error.
|
||||
|
@ -4,6 +4,9 @@
|
||||
* Copyright (C) 1998-2003 Hewlett-Packard Co
|
||||
* David Mosberger-Tang <davidm@hpl.hp.com>
|
||||
* 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
|
||||
*
|
||||
* 2005-10-07 Keith Owens <kaos@sgi.com>
|
||||
* Add notify_die() hooks.
|
||||
*/
|
||||
#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
|
||||
#include <linux/config.h>
|
||||
@ -34,6 +37,7 @@
|
||||
#include <asm/elf.h>
|
||||
#include <asm/ia32.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/sal.h>
|
||||
@ -808,12 +812,14 @@ cpu_halt (void)
|
||||
void
|
||||
machine_restart (char *restart_cmd)
|
||||
{
|
||||
(void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
|
||||
(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
machine_halt (void)
|
||||
{
|
||||
(void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
|
||||
cpu_halt();
|
||||
}
|
||||
|
||||
|
@ -461,6 +461,7 @@ setup_arch (char **cmdline_p)
|
||||
#endif
|
||||
|
||||
cpu_init(); /* initialize the bootstrap CPU */
|
||||
mmu_context_init(); /* initialize context_id bitmap */
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
acpi_boot_init();
|
||||
|
@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
|
||||
struct sigscratch *scr)
|
||||
{
|
||||
extern char __kernel_sigtramp[];
|
||||
unsigned long tramp_addr, new_rbs = 0;
|
||||
unsigned long tramp_addr, new_rbs = 0, new_sp;
|
||||
struct sigframe __user *frame;
|
||||
long err;
|
||||
|
||||
frame = (void __user *) scr->pt.r12;
|
||||
new_sp = scr->pt.r12;
|
||||
tramp_addr = (unsigned long) __kernel_sigtramp;
|
||||
if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) {
|
||||
frame = (void __user *) ((current->sas_ss_sp + current->sas_ss_size)
|
||||
& ~(STACK_ALIGN - 1));
|
||||
if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) {
|
||||
new_sp = current->sas_ss_sp + current->sas_ss_size;
|
||||
/*
|
||||
* We need to check for the register stack being on the signal stack
|
||||
* separately, because it's switched separately (memory stack is switched
|
||||
@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
|
||||
if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
|
||||
new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
|
||||
}
|
||||
frame = (void __user *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1));
|
||||
frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
|
||||
return force_sigsegv_info(sig, frame);
|
||||
|
@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface;
|
||||
EXPORT_SYMBOL(fpswa_interface);
|
||||
|
||||
struct notifier_block *ia64die_chain;
|
||||
static DEFINE_SPINLOCK(die_notifier_lock);
|
||||
|
||||
int register_die_notifier(struct notifier_block *nb)
|
||||
int
|
||||
register_die_notifier(struct notifier_block *nb)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&die_notifier_lock, flags);
|
||||
err = notifier_chain_register(&ia64die_chain, nb);
|
||||
spin_unlock_irqrestore(&die_notifier_lock, flags);
|
||||
return err;
|
||||
return notifier_chain_register(&ia64die_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_die_notifier);
|
||||
|
||||
int
|
||||
unregister_die_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return notifier_chain_unregister(&ia64die_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_die_notifier);
|
||||
|
||||
void __init
|
||||
trap_init (void)
|
||||
@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err)
|
||||
if (++die.lock_owner_depth < 3) {
|
||||
printk("%s[%d]: %s %ld [%d]\n",
|
||||
current->comm, current->pid, str, err, ++die_counter);
|
||||
(void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
|
||||
show_regs(regs);
|
||||
} else
|
||||
printk(KERN_ERR "Recursive die() failure, output suppressed\n");
|
||||
@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
||||
switch (break_num) {
|
||||
case 0: /* unknown error (used by GCC for __builtin_abort()) */
|
||||
if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
||||
== NOTIFY_STOP) {
|
||||
== NOTIFY_STOP)
|
||||
return;
|
||||
}
|
||||
die_if_kernel("bugcheck!", regs, break_num);
|
||||
sig = SIGILL; code = ILL_ILLOPC;
|
||||
break;
|
||||
@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
||||
sig = SIGILL; code = __ILL_BNDMOD;
|
||||
break;
|
||||
|
||||
case 0x80200:
|
||||
case 0x80300:
|
||||
if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
||||
== NOTIFY_STOP) {
|
||||
return;
|
||||
}
|
||||
sig = SIGTRAP; code = TRAP_BRKPT;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (break_num < 0x40000 || break_num > 0x100000)
|
||||
die_if_kernel("Bad break", regs, break_num);
|
||||
@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
|
||||
if (break_num < 0x80000) {
|
||||
sig = SIGILL; code = __ILL_BREAK;
|
||||
} else {
|
||||
if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
|
||||
== NOTIFY_STOP)
|
||||
return;
|
||||
sig = SIGTRAP; code = TRAP_BRKPT;
|
||||
}
|
||||
}
|
||||
@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
|
||||
#endif
|
||||
break;
|
||||
case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
|
||||
case 36:
|
||||
if (notify_die(DIE_SS, "ss", ®s, vector,
|
||||
vector, SIGTRAP) == NOTIFY_STOP)
|
||||
return;
|
||||
siginfo.si_code = TRAP_TRACE; ifa = 0; break;
|
||||
case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
|
||||
}
|
||||
if (notify_die(DIE_FAULT, "ia64_fault", ®s, vector, siginfo.si_code, SIGTRAP)
|
||||
== NOTIFY_STOP)
|
||||
return;
|
||||
siginfo.si_signo = SIGTRAP;
|
||||
siginfo.si_errno = 0;
|
||||
siginfo.si_addr = (void __user *) ifa;
|
||||
|
@ -350,14 +350,12 @@ static void __init initialize_pernode_data(void)
|
||||
* for best.
|
||||
* @nid: node id
|
||||
* @pernodesize: size of this node's pernode data
|
||||
* @align: alignment to use for this node's pernode data
|
||||
*/
|
||||
static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
|
||||
unsigned long align)
|
||||
static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
u8 best = 0xff;
|
||||
int bestnode = -1, node;
|
||||
int bestnode = -1, node, anynode = 0;
|
||||
|
||||
for_each_online_node(node) {
|
||||
if (node_isset(node, memory_less_mask))
|
||||
@ -366,13 +364,15 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
|
||||
best = node_distance(nid, node);
|
||||
bestnode = node;
|
||||
}
|
||||
anynode = node;
|
||||
}
|
||||
|
||||
ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat,
|
||||
pernodesize, align, __pa(MAX_DMA_ADDRESS));
|
||||
if (bestnode == -1)
|
||||
bestnode = anynode;
|
||||
|
||||
ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize,
|
||||
PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
|
||||
|
||||
if (!ptr)
|
||||
panic("NO memory for memory less node\n");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -413,8 +413,7 @@ static void __init memory_less_nodes(void)
|
||||
|
||||
for_each_node_mask(node, memory_less_mask) {
|
||||
pernodesize = compute_pernodesize(node);
|
||||
pernode = memory_less_node_alloc(node, pernodesize,
|
||||
(node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024));
|
||||
pernode = memory_less_node_alloc(node, pernodesize);
|
||||
fill_pernode(node, __pa(pernode), pernodesize);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
* Modified RID allocation for SMP
|
||||
* Goutham Rao <goutham.rao@intel.com>
|
||||
* IPI based ptc implementation and A-step IPI implementation.
|
||||
* Rohit Seth <rohit.seth@intel.com>
|
||||
* Ken Chen <kenneth.w.chen@intel.com>
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
@ -16,78 +18,75 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/bootmem.h>
|
||||
|
||||
#include <asm/delay.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pal.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/dma.h>
|
||||
|
||||
static struct {
|
||||
unsigned long mask; /* mask of supported purge page-sizes */
|
||||
unsigned long max_bits; /* log2() of largest supported purge page-size */
|
||||
unsigned long max_bits; /* log2 of largest supported purge page-size */
|
||||
} purge;
|
||||
|
||||
struct ia64_ctx ia64_ctx = {
|
||||
.lock = SPIN_LOCK_UNLOCKED,
|
||||
.next = 1,
|
||||
.limit = (1 << 15) - 1, /* start out with the safe (architected) limit */
|
||||
.max_ctx = ~0U
|
||||
};
|
||||
|
||||
DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
|
||||
|
||||
/*
|
||||
* Initializes the ia64_ctx.bitmap array based on max_ctx+1.
|
||||
* Called after cpu_init() has setup ia64_ctx.max_ctx based on
|
||||
* maximum RID that is supported by boot CPU.
|
||||
*/
|
||||
void __init
|
||||
mmu_context_init (void)
|
||||
{
|
||||
ia64_ctx.bitmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
|
||||
ia64_ctx.flushmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
|
||||
}
|
||||
|
||||
/*
|
||||
* Acquire the ia64_ctx.lock before calling this function!
|
||||
*/
|
||||
void
|
||||
wrap_mmu_context (struct mm_struct *mm)
|
||||
{
|
||||
unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx;
|
||||
struct task_struct *tsk;
|
||||
int i;
|
||||
int i, cpu;
|
||||
unsigned long flush_bit;
|
||||
|
||||
if (ia64_ctx.next > max_ctx)
|
||||
ia64_ctx.next = 300; /* skip daemons */
|
||||
ia64_ctx.limit = max_ctx + 1;
|
||||
for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) {
|
||||
flush_bit = xchg(&ia64_ctx.flushmap[i], 0);
|
||||
ia64_ctx.bitmap[i] ^= flush_bit;
|
||||
}
|
||||
|
||||
/* use offset at 300 to skip daemons */
|
||||
ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
|
||||
ia64_ctx.max_ctx, 300);
|
||||
ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
|
||||
ia64_ctx.max_ctx, ia64_ctx.next);
|
||||
|
||||
/*
|
||||
* Scan all the task's mm->context and set proper safe range
|
||||
* can't call flush_tlb_all() here because of race condition
|
||||
* with O(1) scheduler [EF]
|
||||
*/
|
||||
|
||||
read_lock(&tasklist_lock);
|
||||
repeat:
|
||||
for_each_process(tsk) {
|
||||
if (!tsk->mm)
|
||||
continue;
|
||||
tsk_context = tsk->mm->context;
|
||||
if (tsk_context == ia64_ctx.next) {
|
||||
if (++ia64_ctx.next >= ia64_ctx.limit) {
|
||||
/* empty range: reset the range limit and start over */
|
||||
if (ia64_ctx.next > max_ctx)
|
||||
ia64_ctx.next = 300;
|
||||
ia64_ctx.limit = max_ctx + 1;
|
||||
goto repeat;
|
||||
}
|
||||
}
|
||||
if ((tsk_context > ia64_ctx.next) && (tsk_context < ia64_ctx.limit))
|
||||
ia64_ctx.limit = tsk_context;
|
||||
}
|
||||
read_unlock(&tasklist_lock);
|
||||
/* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */
|
||||
{
|
||||
int cpu = get_cpu(); /* prevent preemption/migration */
|
||||
for_each_online_cpu(i) {
|
||||
if (i != cpu)
|
||||
per_cpu(ia64_need_tlb_flush, i) = 1;
|
||||
}
|
||||
put_cpu();
|
||||
}
|
||||
cpu = get_cpu(); /* prevent preemption/migration */
|
||||
for_each_online_cpu(i)
|
||||
if (i != cpu)
|
||||
per_cpu(ia64_need_tlb_flush, i) = 1;
|
||||
put_cpu();
|
||||
local_flush_tlb_all();
|
||||
}
|
||||
|
||||
void
|
||||
ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits)
|
||||
ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
|
||||
unsigned long end, unsigned long nbits)
|
||||
{
|
||||
static DEFINE_SPINLOCK(ptcg_lock);
|
||||
|
||||
@ -135,7 +134,8 @@ local_flush_tlb_all (void)
|
||||
}
|
||||
|
||||
void
|
||||
flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end)
|
||||
flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
unsigned long size = end - start;
|
||||
@ -149,7 +149,8 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
|
||||
#endif
|
||||
|
||||
nbits = ia64_fls(size + 0xfff);
|
||||
while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits))
|
||||
while (unlikely (((1UL << nbits) & purge.mask) == 0) &&
|
||||
(nbits < purge.max_bits))
|
||||
++nbits;
|
||||
if (nbits > purge.max_bits)
|
||||
nbits = purge.max_bits;
|
||||
@ -191,5 +192,5 @@ ia64_tlb_init (void)
|
||||
local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
|
||||
local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
|
||||
|
||||
local_flush_tlb_all(); /* nuke left overs from bootstrapping... */
|
||||
local_flush_tlb_all(); /* nuke left overs from bootstrapping... */
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
|
||||
}
|
||||
|
||||
static struct pci_raw_ops pci_sal_ops = {
|
||||
.read = pci_sal_read,
|
||||
.read = pci_sal_read,
|
||||
.write = pci_sal_write
|
||||
};
|
||||
|
||||
@ -137,35 +137,98 @@ alloc_pci_controller (int seg)
|
||||
return controller;
|
||||
}
|
||||
|
||||
static u64 __devinit
|
||||
add_io_space (struct acpi_resource_address64 *addr)
|
||||
struct pci_root_info {
|
||||
struct pci_controller *controller;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
new_space (u64 phys_base, int sparse)
|
||||
{
|
||||
u64 offset;
|
||||
int sparse = 0;
|
||||
u64 mmio_base;
|
||||
int i;
|
||||
|
||||
if (addr->address_translation_offset == 0)
|
||||
return IO_SPACE_BASE(0); /* part of legacy IO space */
|
||||
if (phys_base == 0)
|
||||
return 0; /* legacy I/O port space */
|
||||
|
||||
if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
|
||||
sparse = 1;
|
||||
|
||||
offset = (u64) ioremap(addr->address_translation_offset, 0);
|
||||
mmio_base = (u64) ioremap(phys_base, 0);
|
||||
for (i = 0; i < num_io_spaces; i++)
|
||||
if (io_space[i].mmio_base == offset &&
|
||||
if (io_space[i].mmio_base == mmio_base &&
|
||||
io_space[i].sparse == sparse)
|
||||
return IO_SPACE_BASE(i);
|
||||
return i;
|
||||
|
||||
if (num_io_spaces == MAX_IO_SPACES) {
|
||||
printk("Too many IO port spaces\n");
|
||||
printk(KERN_ERR "PCI: Too many IO port spaces "
|
||||
"(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
i = num_io_spaces++;
|
||||
io_space[i].mmio_base = offset;
|
||||
io_space[i].mmio_base = mmio_base;
|
||||
io_space[i].sparse = sparse;
|
||||
|
||||
return IO_SPACE_BASE(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
static u64 __devinit
|
||||
add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
|
||||
{
|
||||
struct resource *resource;
|
||||
char *name;
|
||||
u64 base, min, max, base_port;
|
||||
unsigned int sparse = 0, space_nr, len;
|
||||
|
||||
resource = kzalloc(sizeof(*resource), GFP_KERNEL);
|
||||
if (!resource) {
|
||||
printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
|
||||
info->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = strlen(info->name) + 32;
|
||||
name = kzalloc(len, GFP_KERNEL);
|
||||
if (!name) {
|
||||
printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
|
||||
info->name);
|
||||
goto free_resource;
|
||||
}
|
||||
|
||||
min = addr->min_address_range;
|
||||
max = min + addr->address_length - 1;
|
||||
if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
|
||||
sparse = 1;
|
||||
|
||||
space_nr = new_space(addr->address_translation_offset, sparse);
|
||||
if (space_nr == ~0)
|
||||
goto free_name;
|
||||
|
||||
base = __pa(io_space[space_nr].mmio_base);
|
||||
base_port = IO_SPACE_BASE(space_nr);
|
||||
snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
|
||||
base_port + min, base_port + max);
|
||||
|
||||
/*
|
||||
* The SDM guarantees the legacy 0-64K space is sparse, but if the
|
||||
* mapping is done by the processor (not the bridge), ACPI may not
|
||||
* mark it as sparse.
|
||||
*/
|
||||
if (space_nr == 0)
|
||||
sparse = 1;
|
||||
|
||||
resource->name = name;
|
||||
resource->flags = IORESOURCE_MEM;
|
||||
resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
|
||||
resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
|
||||
insert_resource(&iomem_resource, resource);
|
||||
|
||||
return base_port;
|
||||
|
||||
free_name:
|
||||
kfree(name);
|
||||
free_resource:
|
||||
kfree(resource);
|
||||
out:
|
||||
return ~0;
|
||||
}
|
||||
|
||||
static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
|
||||
@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data)
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
struct pci_root_info {
|
||||
struct pci_controller *controller;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
||||
{
|
||||
struct pci_root_info *info = data;
|
||||
@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
||||
} else if (addr.resource_type == ACPI_IO_RANGE) {
|
||||
flags = IORESOURCE_IO;
|
||||
root = &ioport_resource;
|
||||
offset = add_io_space(&addr);
|
||||
offset = add_io_space(info, &addr);
|
||||
if (offset == ~0)
|
||||
return AE_OK;
|
||||
} else
|
||||
@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
|
||||
window->resource.name = info->name;
|
||||
window->resource.flags = flags;
|
||||
window->resource.start = addr.min_address_range + offset;
|
||||
window->resource.end = addr.max_address_range + offset;
|
||||
window->resource.end = window->resource.start + addr.address_length - 1;
|
||||
window->resource.child = NULL;
|
||||
window->offset = offset;
|
||||
|
||||
@ -739,7 +797,7 @@ int pci_vector_resources(int last, int nr_released)
|
||||
{
|
||||
int count = nr_released;
|
||||
|
||||
count += (IA64_LAST_DEVICE_VECTOR - last);
|
||||
count += (IA64_LAST_DEVICE_VECTOR - last);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -349,7 +349,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
|
||||
return; /*bus # does not exist */
|
||||
prom_bussoft_ptr = __va(prom_bussoft_ptr);
|
||||
|
||||
controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL);
|
||||
controller = kzalloc(sizeof(struct pci_controller), GFP_KERNEL);
|
||||
controller->segment = segment;
|
||||
if (!controller)
|
||||
BUG();
|
||||
|
@ -163,7 +163,7 @@ struct xpc_vars {
|
||||
u8 version;
|
||||
u64 heartbeat;
|
||||
u64 heartbeating_to_mask;
|
||||
u64 kdb_status; /* 0 = machine running */
|
||||
u64 heartbeat_offline; /* if 0, heartbeat should be changing */
|
||||
int act_nasid;
|
||||
int act_phys_cpuid;
|
||||
u64 vars_part_pa;
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include <linux/reboot.h>
|
||||
#include <asm/sn/intr.h>
|
||||
#include <asm/sn/sn_sal.h>
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include "xpc.h"
|
||||
|
||||
@ -188,6 +189,11 @@ static struct notifier_block xpc_reboot_notifier = {
|
||||
.notifier_call = xpc_system_reboot,
|
||||
};
|
||||
|
||||
static int xpc_system_die(struct notifier_block *, unsigned long, void *);
|
||||
static struct notifier_block xpc_die_notifier = {
|
||||
.notifier_call = xpc_system_die,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Timer function to enforce the timelimit on the partition disengage request.
|
||||
@ -997,6 +1003,9 @@ xpc_do_exit(enum xpc_retval reason)
|
||||
/* take ourselves off of the reboot_notifier_list */
|
||||
(void) unregister_reboot_notifier(&xpc_reboot_notifier);
|
||||
|
||||
/* take ourselves off of the die_notifier list */
|
||||
(void) unregister_die_notifier(&xpc_die_notifier);
|
||||
|
||||
/* close down protections for IPI operations */
|
||||
xpc_restrict_IPI_ops();
|
||||
|
||||
@ -1010,6 +1019,63 @@ xpc_do_exit(enum xpc_retval reason)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called when the system is about to be either restarted or halted.
|
||||
*/
|
||||
static void
|
||||
xpc_die_disengage(void)
|
||||
{
|
||||
struct xpc_partition *part;
|
||||
partid_t partid;
|
||||
unsigned long engaged;
|
||||
long time, print_time, disengage_request_timeout;
|
||||
|
||||
|
||||
/* keep xpc_hb_checker thread from doing anything (just in case) */
|
||||
xpc_exiting = 1;
|
||||
|
||||
xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */
|
||||
|
||||
for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
|
||||
part = &xpc_partitions[partid];
|
||||
|
||||
if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part->
|
||||
remote_vars_version)) {
|
||||
|
||||
/* just in case it was left set by an earlier XPC */
|
||||
xpc_clear_partition_engaged(1UL << partid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xpc_partition_engaged(1UL << partid) ||
|
||||
part->act_state != XPC_P_INACTIVE) {
|
||||
xpc_request_partition_disengage(part);
|
||||
xpc_mark_partition_disengaged(part);
|
||||
xpc_IPI_send_disengage(part);
|
||||
}
|
||||
}
|
||||
|
||||
print_time = rtc_time();
|
||||
disengage_request_timeout = print_time +
|
||||
(xpc_disengage_request_timelimit * sn_rtc_cycles_per_second);
|
||||
|
||||
/* wait for all other partitions to disengage from us */
|
||||
|
||||
while ((engaged = xpc_partition_engaged(-1UL)) &&
|
||||
(time = rtc_time()) < disengage_request_timeout) {
|
||||
|
||||
if (time >= print_time) {
|
||||
dev_info(xpc_part, "waiting for remote partitions to "
|
||||
"disengage, engaged=0x%lx\n", engaged);
|
||||
print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL *
|
||||
sn_rtc_cycles_per_second);
|
||||
}
|
||||
}
|
||||
dev_info(xpc_part, "finished waiting for remote partitions to "
|
||||
"disengage, engaged=0x%lx\n", engaged);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is called when the system is being rebooted.
|
||||
*/
|
||||
@ -1038,6 +1104,33 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is called when the system is being rebooted.
|
||||
*/
|
||||
static int
|
||||
xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
|
||||
{
|
||||
switch (event) {
|
||||
case DIE_MACHINE_RESTART:
|
||||
case DIE_MACHINE_HALT:
|
||||
xpc_die_disengage();
|
||||
break;
|
||||
case DIE_MCA_MONARCH_ENTER:
|
||||
case DIE_INIT_MONARCH_ENTER:
|
||||
xpc_vars->heartbeat++;
|
||||
xpc_vars->heartbeat_offline = 1;
|
||||
break;
|
||||
case DIE_MCA_MONARCH_LEAVE:
|
||||
case DIE_INIT_MONARCH_LEAVE:
|
||||
xpc_vars->heartbeat++;
|
||||
xpc_vars->heartbeat_offline = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
||||
int __init
|
||||
xpc_init(void)
|
||||
{
|
||||
@ -1154,6 +1247,12 @@ xpc_init(void)
|
||||
dev_warn(xpc_part, "can't register reboot notifier\n");
|
||||
}
|
||||
|
||||
/* add ourselves to the die_notifier list (i.e., ia64die_chain) */
|
||||
ret = register_die_notifier(&xpc_die_notifier);
|
||||
if (ret != 0) {
|
||||
dev_warn(xpc_part, "can't register die notifier\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the beating to other partitions into motion. This is
|
||||
@ -1179,6 +1278,9 @@ xpc_init(void)
|
||||
/* take ourselves off of the reboot_notifier_list */
|
||||
(void) unregister_reboot_notifier(&xpc_reboot_notifier);
|
||||
|
||||
/* take ourselves off of the die_notifier list */
|
||||
(void) unregister_die_notifier(&xpc_die_notifier);
|
||||
|
||||
del_timer_sync(&xpc_hb_timer);
|
||||
free_irq(SGI_XPC_ACTIVATE, NULL);
|
||||
xpc_restrict_IPI_ops();
|
||||
|
@ -436,13 +436,13 @@ xpc_check_remote_hb(void)
|
||||
}
|
||||
|
||||
dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat"
|
||||
" = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid,
|
||||
remote_vars->heartbeat, part->last_heartbeat,
|
||||
remote_vars->kdb_status,
|
||||
" = %ld, heartbeat_offline = %ld, HB_mask = 0x%lx\n",
|
||||
partid, remote_vars->heartbeat, part->last_heartbeat,
|
||||
remote_vars->heartbeat_offline,
|
||||
remote_vars->heartbeating_to_mask);
|
||||
|
||||
if (((remote_vars->heartbeat == part->last_heartbeat) &&
|
||||
(remote_vars->kdb_status == 0)) ||
|
||||
(remote_vars->heartbeat_offline == 0)) ||
|
||||
!xpc_hb_allowed(sn_partition_id, remote_vars)) {
|
||||
|
||||
XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
|
||||
|
@ -218,7 +218,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
|
||||
if (i > last)
|
||||
return 0;
|
||||
|
||||
map = kcalloc(1, sizeof(struct tioce_dmamap), GFP_ATOMIC);
|
||||
map = kzalloc(sizeof(struct tioce_dmamap), GFP_ATOMIC);
|
||||
if (!map)
|
||||
return 0;
|
||||
|
||||
@ -555,7 +555,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
|
||||
struct tioce *tioce_mmr;
|
||||
struct tioce_kernel *tioce_kern;
|
||||
|
||||
tioce_kern = kcalloc(1, sizeof(struct tioce_kernel), GFP_KERNEL);
|
||||
tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL);
|
||||
if (!tioce_kern) {
|
||||
return NULL;
|
||||
}
|
||||
@ -727,7 +727,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
|
||||
* Allocate kernel bus soft and copy from prom.
|
||||
*/
|
||||
|
||||
tioce_common = kcalloc(1, sizeof(struct tioce_common), GFP_KERNEL);
|
||||
tioce_common = kzalloc(sizeof(struct tioce_common), GFP_KERNEL);
|
||||
if (!tioce_common)
|
||||
return NULL;
|
||||
|
||||
|
@ -599,6 +599,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
|
||||
def_bool y
|
||||
depends on NEED_MULTIPLE_NODES
|
||||
|
||||
config ARCH_MEMORY_PROBE
|
||||
def_bool y
|
||||
depends on MEMORY_HOTPLUG
|
||||
|
||||
# Some NUMA nodes have memory ranges that span
|
||||
# other nodes. Even though a pfn is valid and
|
||||
# between a node's start and end pfns, it may not
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
ifeq ($(CONFIG_PPC64),y)
|
||||
EXTRA_CFLAGS += -mno-minimal-toc
|
||||
CFLAGS_ioctl32.o += -Ifs/
|
||||
endif
|
||||
ifeq ($(CONFIG_PPC32),y)
|
||||
CFLAGS_prom_init.o += -fPIC
|
||||
@ -11,15 +12,21 @@ CFLAGS_btext.o += -fPIC
|
||||
endif
|
||||
|
||||
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
|
||||
signal_32.o pmc.o
|
||||
irq.o signal_32.o pmc.o
|
||||
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
|
||||
signal_64.o ptrace32.o systbl.o
|
||||
signal_64.o ptrace32.o systbl.o \
|
||||
paca.o ioctl32.o cpu_setup_power4.o \
|
||||
firmware.o sysfs.o
|
||||
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
|
||||
obj-$(CONFIG_POWER4) += idle_power4.o
|
||||
obj-$(CONFIG_PPC_OF) += of_device.o
|
||||
obj-$(CONFIG_PPC_RTAS) += rtas.o
|
||||
procfs-$(CONFIG_PPC64) := proc_ppc64.o
|
||||
obj-$(CONFIG_PROC_FS) += $(procfs-y)
|
||||
rtaspci-$(CONFIG_PPC64) := rtas_pci.o
|
||||
obj-$(CONFIG_PPC_RTAS) += rtas.o $(rtaspci-y)
|
||||
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
|
||||
obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
|
||||
obj-$(CONFIG_LPARCFG) += lparcfg.o
|
||||
obj-$(CONFIG_IBMVIO) += vio.o
|
||||
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
|
||||
|
||||
|
@ -106,7 +106,6 @@ int main(void)
|
||||
DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
|
||||
DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
|
||||
DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
|
||||
DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
|
||||
DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
|
||||
|
||||
/* paca */
|
||||
|
@ -114,11 +114,11 @@ _GLOBAL(__setup_cpu_ppc970)
|
||||
|
||||
.data
|
||||
.balign L1_CACHE_BYTES,0
|
||||
cpu_state_storage:
|
||||
cpu_state_storage:
|
||||
.space CS_SIZE
|
||||
.balign L1_CACHE_BYTES,0
|
||||
.text
|
||||
|
||||
|
||||
/* Called in normal context to backup CPU 0 state. This
|
||||
* does not include cache settings. This function is also
|
||||
* called for machine sleep. This does not include the MMU
|
||||
@ -151,7 +151,7 @@ _GLOBAL(__save_cpu_setup)
|
||||
std r3,CS_HID4(r5)
|
||||
mfspr r3,SPRN_HID5
|
||||
std r3,CS_HID5(r5)
|
||||
|
||||
|
||||
2:
|
||||
mtcr r7
|
||||
blr
|
||||
@ -213,7 +213,7 @@ _GLOBAL(__restore_cpu_setup)
|
||||
mtspr SPRN_HID1,r3
|
||||
sync
|
||||
isync
|
||||
|
||||
|
||||
/* Restore HID4 */
|
||||
ld r3,CS_HID4(r5)
|
||||
sync
|
@ -52,6 +52,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
|
||||
#define COMMON_USER (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
|
||||
PPC_FEATURE_HAS_MMU)
|
||||
#define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64)
|
||||
#define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
|
||||
#define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5)
|
||||
#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS)
|
||||
|
||||
|
||||
/* We only set the spe features if the kernel was compiled with
|
||||
@ -160,7 +163,7 @@ struct cpu_spec cpu_specs[] = {
|
||||
.pvr_value = 0x00350000,
|
||||
.cpu_name = "POWER4 (gp)",
|
||||
.cpu_features = CPU_FTRS_POWER4,
|
||||
.cpu_user_features = COMMON_USER_PPC64,
|
||||
.cpu_user_features = COMMON_USER_POWER4,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 8,
|
||||
@ -175,7 +178,7 @@ struct cpu_spec cpu_specs[] = {
|
||||
.pvr_value = 0x00380000,
|
||||
.cpu_name = "POWER4+ (gq)",
|
||||
.cpu_features = CPU_FTRS_POWER4,
|
||||
.cpu_user_features = COMMON_USER_PPC64,
|
||||
.cpu_user_features = COMMON_USER_POWER4,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 8,
|
||||
@ -190,7 +193,7 @@ struct cpu_spec cpu_specs[] = {
|
||||
.pvr_value = 0x00390000,
|
||||
.cpu_name = "PPC970",
|
||||
.cpu_features = CPU_FTRS_PPC970,
|
||||
.cpu_user_features = COMMON_USER_PPC64 |
|
||||
.cpu_user_features = COMMON_USER_POWER4 |
|
||||
PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
@ -212,7 +215,7 @@ struct cpu_spec cpu_specs[] = {
|
||||
#else
|
||||
.cpu_features = CPU_FTRS_PPC970,
|
||||
#endif
|
||||
.cpu_user_features = COMMON_USER_PPC64 |
|
||||
.cpu_user_features = COMMON_USER_POWER4 |
|
||||
PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
@ -230,7 +233,7 @@ struct cpu_spec cpu_specs[] = {
|
||||
.pvr_value = 0x00440000,
|
||||
.cpu_name = "PPC970MP",
|
||||
.cpu_features = CPU_FTRS_PPC970,
|
||||
.cpu_user_features = COMMON_USER_PPC64 |
|
||||
.cpu_user_features = COMMON_USER_POWER4 |
|
||||
PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
@ -245,7 +248,7 @@ struct cpu_spec cpu_specs[] = {
|
||||
.pvr_value = 0x003a0000,
|
||||
.cpu_name = "POWER5 (gr)",
|
||||
.cpu_features = CPU_FTRS_POWER5,
|
||||
.cpu_user_features = COMMON_USER_PPC64,
|
||||
.cpu_user_features = COMMON_USER_POWER5,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 6,
|
||||
@ -260,7 +263,7 @@ struct cpu_spec cpu_specs[] = {
|
||||
.pvr_value = 0x003b0000,
|
||||
.cpu_name = "POWER5 (gs)",
|
||||
.cpu_features = CPU_FTRS_POWER5,
|
||||
.cpu_user_features = COMMON_USER_PPC64,
|
||||
.cpu_user_features = COMMON_USER_POWER5_PLUS,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 6,
|
||||
@ -276,7 +279,7 @@ struct cpu_spec cpu_specs[] = {
|
||||
.cpu_name = "Cell Broadband Engine",
|
||||
.cpu_features = CPU_FTRS_CELL,
|
||||
.cpu_user_features = COMMON_USER_PPC64 |
|
||||
PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||
PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.cpu_setup = __setup_cpu_be,
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* arch/ppc64/kernel/firmware.c
|
||||
*
|
||||
* Extracted from cputable.c
|
||||
*
|
||||
* Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
|
@ -41,20 +41,20 @@ _GLOBAL(load_up_fpu)
|
||||
#ifndef CONFIG_SMP
|
||||
LOADBASE(r3, last_task_used_math)
|
||||
toreal(r3)
|
||||
LDL r4,OFF(last_task_used_math)(r3)
|
||||
CMPI 0,r4,0
|
||||
PPC_LL r4,OFF(last_task_used_math)(r3)
|
||||
PPC_LCMPI 0,r4,0
|
||||
beq 1f
|
||||
toreal(r4)
|
||||
addi r4,r4,THREAD /* want last_task_used_math->thread */
|
||||
SAVE_32FPRS(0, r4)
|
||||
mffs fr0
|
||||
stfd fr0,THREAD_FPSCR(r4)
|
||||
LDL r5,PT_REGS(r4)
|
||||
PPC_LL r5,PT_REGS(r4)
|
||||
toreal(r5)
|
||||
LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
li r10,MSR_FP|MSR_FE0|MSR_FE1
|
||||
andc r4,r4,r10 /* disable FP for previous task */
|
||||
STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
1:
|
||||
#endif /* CONFIG_SMP */
|
||||
/* enable use of FP after return */
|
||||
@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu)
|
||||
#ifndef CONFIG_SMP
|
||||
subi r4,r5,THREAD
|
||||
fromreal(r4)
|
||||
STL r4,OFF(last_task_used_math)(r3)
|
||||
PPC_STL r4,OFF(last_task_used_math)(r3)
|
||||
#endif /* CONFIG_SMP */
|
||||
/* restore registers and return */
|
||||
/* we haven't used ctr or xer or lr */
|
||||
@ -97,24 +97,24 @@ _GLOBAL(giveup_fpu)
|
||||
MTMSRD(r5) /* enable use of fpu now */
|
||||
SYNC_601
|
||||
isync
|
||||
CMPI 0,r3,0
|
||||
PPC_LCMPI 0,r3,0
|
||||
beqlr- /* if no previous owner, done */
|
||||
addi r3,r3,THREAD /* want THREAD of task */
|
||||
LDL r5,PT_REGS(r3)
|
||||
CMPI 0,r5,0
|
||||
PPC_LL r5,PT_REGS(r3)
|
||||
PPC_LCMPI 0,r5,0
|
||||
SAVE_32FPRS(0, r3)
|
||||
mffs fr0
|
||||
stfd fr0,THREAD_FPSCR(r3)
|
||||
beq 1f
|
||||
LDL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
li r3,MSR_FP|MSR_FE0|MSR_FE1
|
||||
andc r4,r4,r3 /* disable FP for previous task */
|
||||
STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
|
||||
1:
|
||||
#ifndef CONFIG_SMP
|
||||
li r5,0
|
||||
LOADBASE(r4,last_task_used_math)
|
||||
STL r5,OFF(last_task_used_math)(r4)
|
||||
PPC_STL r5,OFF(last_task_used_math)(r4)
|
||||
#endif /* CONFIG_SMP */
|
||||
blr
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include <asm/reg.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/systemcfg.h>
|
||||
#include <asm/ppc_asm.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/bug.h>
|
||||
@ -1697,25 +1696,14 @@ _GLOBAL(pmac_secondary_start)
|
||||
* SPRG3 = paca virtual address
|
||||
*/
|
||||
_GLOBAL(__secondary_start)
|
||||
/* Set thread priority to MEDIUM */
|
||||
HMT_MEDIUM
|
||||
|
||||
HMT_MEDIUM /* Set thread priority to MEDIUM */
|
||||
|
||||
/* Load TOC */
|
||||
ld r2,PACATOC(r13)
|
||||
li r6,0
|
||||
stb r6,PACAPROCENABLED(r13)
|
||||
|
||||
#ifndef CONFIG_PPC_ISERIES
|
||||
/* Initialize the page table pointer register. */
|
||||
LOADADDR(r6,_SDR1)
|
||||
ld r6,0(r6) /* get the value of _SDR1 */
|
||||
mtspr SPRN_SDR1,r6 /* set the htab location */
|
||||
#endif
|
||||
/* Initialize the first segment table (or SLB) entry */
|
||||
ld r3,PACASTABVIRT(r13) /* get addr of segment table */
|
||||
BEGIN_FTR_SECTION
|
||||
bl .stab_initialize
|
||||
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
|
||||
bl .slb_initialize
|
||||
/* Do early setup for that CPU (stab, slb, hash table pointer) */
|
||||
bl .early_setup_secondary
|
||||
|
||||
/* Initialize the kernel stack. Just a repeat for iSeries. */
|
||||
LOADADDR(r3,current_set)
|
||||
@ -1724,37 +1712,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
|
||||
addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
|
||||
std r1,PACAKSAVE(r13)
|
||||
|
||||
ld r3,PACASTABREAL(r13) /* get raddr of segment table */
|
||||
ori r4,r3,1 /* turn on valid bit */
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
li r0,-1 /* hypervisor call */
|
||||
li r3,1
|
||||
sldi r3,r3,63 /* 0x8000000000000000 */
|
||||
ori r3,r3,4 /* 0x8000000000000004 */
|
||||
sc /* HvCall_setASR */
|
||||
#else
|
||||
/* set the ASR */
|
||||
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
|
||||
ld r3,0(r3)
|
||||
lwz r3,PLATFORM(r3) /* r3 = platform flags */
|
||||
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
|
||||
beq 98f /* branch if result is 0 */
|
||||
mfspr r3,SPRN_PVR
|
||||
srwi r3,r3,16
|
||||
cmpwi r3,0x37 /* SStar */
|
||||
beq 97f
|
||||
cmpwi r3,0x36 /* IStar */
|
||||
beq 97f
|
||||
cmpwi r3,0x34 /* Pulsar */
|
||||
bne 98f
|
||||
97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
|
||||
HVSC /* Invoking hcall */
|
||||
b 99f
|
||||
98: /* !(rpa hypervisor) || !(star) */
|
||||
mtasr r4 /* set the stab location */
|
||||
99:
|
||||
#endif
|
||||
/* Clear backchain so we get nice backtraces */
|
||||
li r7,0
|
||||
mtlr r7
|
||||
|
||||
@ -1777,6 +1735,7 @@ _GLOBAL(start_secondary_prolog)
|
||||
li r3,0
|
||||
std r3,0(r1) /* Zero the stack frame pointer */
|
||||
bl .start_secondary
|
||||
b .
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1896,40 +1855,6 @@ _STATIC(start_here_multiplatform)
|
||||
mr r3,r31
|
||||
bl .early_setup
|
||||
|
||||
/* set the ASR */
|
||||
ld r3,PACASTABREAL(r13)
|
||||
ori r4,r3,1 /* turn on valid bit */
|
||||
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
|
||||
ld r3,0(r3)
|
||||
lwz r3,PLATFORM(r3) /* r3 = platform flags */
|
||||
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
|
||||
beq 98f /* branch if result is 0 */
|
||||
mfspr r3,SPRN_PVR
|
||||
srwi r3,r3,16
|
||||
cmpwi r3,0x37 /* SStar */
|
||||
beq 97f
|
||||
cmpwi r3,0x36 /* IStar */
|
||||
beq 97f
|
||||
cmpwi r3,0x34 /* Pulsar */
|
||||
bne 98f
|
||||
97: li r3,H_SET_ASR /* hcall = H_SET_ASR */
|
||||
HVSC /* Invoking hcall */
|
||||
b 99f
|
||||
98: /* !(rpa hypervisor) || !(star) */
|
||||
mtasr r4 /* set the stab location */
|
||||
99:
|
||||
/* Set SDR1 (hash table pointer) */
|
||||
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
|
||||
ld r3,0(r3)
|
||||
lwz r3,PLATFORM(r3) /* r3 = platform flags */
|
||||
/* Test if bit 0 is set (LPAR bit) */
|
||||
andi. r3,r3,PLATFORM_LPAR
|
||||
bne 98f /* branch if result is !0 */
|
||||
LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
|
||||
add r6,r6,r26
|
||||
ld r6,0(r6) /* get the value of _SDR1 */
|
||||
mtspr SPRN_SDR1,r6 /* set the htab location */
|
||||
98:
|
||||
LOADADDR(r3,.start_here_common)
|
||||
SET_REG_TO_CONST(r4, MSR_KERNEL)
|
||||
mtspr SPRN_SRR0,r3
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
/*
|
||||
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
|
||||
*
|
||||
*
|
||||
* Based on sparc64 ioctl32.c by:
|
||||
*
|
||||
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
|
@ -5,12 +5,12 @@
|
||||
* Copyright (C) 1992 Linus Torvalds
|
||||
* Adapted from arch/i386 by Gary Thomas
|
||||
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
||||
* Updated and modified by Cort Dougan (cort@cs.nmt.edu)
|
||||
* Copyright (C) 1996 Cort Dougan
|
||||
* Updated and modified by Cort Dougan <cort@fsmlabs.com>
|
||||
* Copyright (C) 1996-2001 Cort Dougan
|
||||
* Adapted for Power Macintosh by Paul Mackerras
|
||||
* Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
|
||||
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -21,6 +21,14 @@
|
||||
* instead of just grabbing them. Thus setups with different IRQ numbers
|
||||
* shouldn't result in any weird surprises, and installing new handlers
|
||||
* should be easier.
|
||||
*
|
||||
* The MPC8xx has an interrupt mask in the SIU. If a bit is set, the
|
||||
* interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit
|
||||
* mask register (of which only 16 are defined), hence the weird shifting
|
||||
* and complement of the cached_irq_mask. I want to be able to stuff
|
||||
* this right into the SIU SMASK register.
|
||||
* Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
|
||||
* to reduce code space and undefined function references.
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
@ -29,6 +37,7 @@
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/timex.h>
|
||||
@ -40,9 +49,13 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/profile.h>
|
||||
#include <linux/bitops.h>
|
||||
#ifdef CONFIG_PPC64
|
||||
#include <linux/kallsyms.h>
|
||||
#endif
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
@ -52,35 +65,54 @@
|
||||
#include <asm/cache.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/iseries/it_lp_queue.h>
|
||||
#include <asm/machdep.h>
|
||||
#ifdef CONFIG_PPC64
|
||||
#include <asm/iseries/it_lp_queue.h>
|
||||
#include <asm/paca.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern void iSeries_smp_message_recv( struct pt_regs * );
|
||||
#endif
|
||||
|
||||
extern irq_desc_t irq_desc[NR_IRQS];
|
||||
static int ppc_spurious_interrupts;
|
||||
|
||||
#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
|
||||
extern void iSeries_smp_message_recv(struct pt_regs *);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
|
||||
|
||||
unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
|
||||
atomic_t ppc_n_lost_interrupts;
|
||||
|
||||
#ifdef CONFIG_TAU_INT
|
||||
extern int tau_initialized;
|
||||
extern int tau_interrupts(int);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
|
||||
extern atomic_t ipi_recv;
|
||||
extern atomic_t ipi_sent;
|
||||
#endif
|
||||
#endif /* CONFIG_PPC32 */
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
EXPORT_SYMBOL(irq_desc);
|
||||
|
||||
int distribute_irqs = 1;
|
||||
int __irq_offset_value;
|
||||
int ppc_spurious_interrupts;
|
||||
u64 ppc64_interrupt_controller;
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
int show_interrupts(struct seq_file *p, void *v)
|
||||
{
|
||||
int i = *(loff_t *) v, j;
|
||||
struct irqaction * action;
|
||||
int i = *(loff_t *)v, j;
|
||||
struct irqaction *action;
|
||||
irq_desc_t *desc;
|
||||
unsigned long flags;
|
||||
|
||||
if (i == 0) {
|
||||
seq_printf(p, " ");
|
||||
for (j=0; j<NR_CPUS; j++) {
|
||||
if (cpu_online(j))
|
||||
seq_printf(p, "CPU%d ",j);
|
||||
}
|
||||
seq_puts(p, " ");
|
||||
for_each_online_cpu(j)
|
||||
seq_printf(p, "CPU%d ", j);
|
||||
seq_putc(p, '\n');
|
||||
}
|
||||
|
||||
@ -92,26 +124,41 @@ int show_interrupts(struct seq_file *p, void *v)
|
||||
goto skip;
|
||||
seq_printf(p, "%3d: ", i);
|
||||
#ifdef CONFIG_SMP
|
||||
for (j = 0; j < NR_CPUS; j++) {
|
||||
if (cpu_online(j))
|
||||
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
|
||||
}
|
||||
for_each_online_cpu(j)
|
||||
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
|
||||
#else
|
||||
seq_printf(p, "%10u ", kstat_irqs(i));
|
||||
#endif /* CONFIG_SMP */
|
||||
if (desc->handler)
|
||||
seq_printf(p, " %s ", desc->handler->typename );
|
||||
seq_printf(p, " %s ", desc->handler->typename);
|
||||
else
|
||||
seq_printf(p, " None ");
|
||||
seq_puts(p, " None ");
|
||||
seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge ");
|
||||
seq_printf(p, " %s",action->name);
|
||||
for (action=action->next; action; action = action->next)
|
||||
seq_printf(p, " %s", action->name);
|
||||
for (action = action->next; action; action = action->next)
|
||||
seq_printf(p, ", %s", action->name);
|
||||
seq_putc(p, '\n');
|
||||
skip:
|
||||
spin_unlock_irqrestore(&desc->lock, flags);
|
||||
} else if (i == NR_IRQS)
|
||||
} else if (i == NR_IRQS) {
|
||||
#ifdef CONFIG_PPC32
|
||||
#ifdef CONFIG_TAU_INT
|
||||
if (tau_initialized){
|
||||
seq_puts(p, "TAU: ");
|
||||
for (j = 0; j < NR_CPUS; j++)
|
||||
if (cpu_online(j))
|
||||
seq_printf(p, "%10u ", tau_interrupts(j));
|
||||
seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_MERGE)
|
||||
/* should this be per processor send/receive? */
|
||||
seq_printf(p, "IPI (recv/sent): %10u/%u\n",
|
||||
atomic_read(&ipi_recv), atomic_read(&ipi_sent));
|
||||
#endif
|
||||
#endif /* CONFIG_PPC32 */
|
||||
seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -144,126 +191,6 @@ void fixup_irqs(cpumask_t map)
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int noirqdebug;
|
||||
|
||||
/*
|
||||
* Eventually, this should take an array of interrupts and an array size
|
||||
* so it can dispatch multiple interrupts.
|
||||
*/
|
||||
void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
|
||||
{
|
||||
int status;
|
||||
struct irqaction *action;
|
||||
int cpu = smp_processor_id();
|
||||
irq_desc_t *desc = get_irq_desc(irq);
|
||||
irqreturn_t action_ret;
|
||||
#ifdef CONFIG_IRQSTACKS
|
||||
struct thread_info *curtp, *irqtp;
|
||||
#endif
|
||||
|
||||
kstat_cpu(cpu).irqs[irq]++;
|
||||
|
||||
if (desc->status & IRQ_PER_CPU) {
|
||||
/* no locking required for CPU-local interrupts: */
|
||||
ack_irq(irq);
|
||||
action_ret = handle_IRQ_event(irq, regs, desc->action);
|
||||
desc->handler->end(irq);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock(&desc->lock);
|
||||
ack_irq(irq);
|
||||
/*
|
||||
REPLAY is when Linux resends an IRQ that was dropped earlier
|
||||
WAITING is used by probe to mark irqs that are being tested
|
||||
*/
|
||||
status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
|
||||
status |= IRQ_PENDING; /* we _want_ to handle it */
|
||||
|
||||
/*
|
||||
* If the IRQ is disabled for whatever reason, we cannot
|
||||
* use the action we have.
|
||||
*/
|
||||
action = NULL;
|
||||
if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
|
||||
action = desc->action;
|
||||
if (!action || !action->handler) {
|
||||
ppc_spurious_interrupts++;
|
||||
printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq);
|
||||
/* We can't call disable_irq here, it would deadlock */
|
||||
if (!desc->depth)
|
||||
desc->depth = 1;
|
||||
desc->status |= IRQ_DISABLED;
|
||||
/* This is not a real spurrious interrupt, we
|
||||
* have to eoi it, so we jump to out
|
||||
*/
|
||||
mask_irq(irq);
|
||||
goto out;
|
||||
}
|
||||
status &= ~IRQ_PENDING; /* we commit to handling */
|
||||
status |= IRQ_INPROGRESS; /* we are handling it */
|
||||
}
|
||||
desc->status = status;
|
||||
|
||||
/*
|
||||
* If there is no IRQ handler or it was disabled, exit early.
|
||||
Since we set PENDING, if another processor is handling
|
||||
a different instance of this same irq, the other processor
|
||||
will take care of it.
|
||||
*/
|
||||
if (unlikely(!action))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Edge triggered interrupts need to remember
|
||||
* pending events.
|
||||
* This applies to any hw interrupts that allow a second
|
||||
* instance of the same irq to arrive while we are in do_IRQ
|
||||
* or in the handler. But the code here only handles the _second_
|
||||
* instance of the irq, not the third or fourth. So it is mostly
|
||||
* useful for irq hardware that does not mask cleanly in an
|
||||
* SMP environment.
|
||||
*/
|
||||
for (;;) {
|
||||
spin_unlock(&desc->lock);
|
||||
|
||||
#ifdef CONFIG_IRQSTACKS
|
||||
/* Switch to the irq stack to handle this */
|
||||
curtp = current_thread_info();
|
||||
irqtp = hardirq_ctx[smp_processor_id()];
|
||||
if (curtp != irqtp) {
|
||||
irqtp->task = curtp->task;
|
||||
irqtp->flags = 0;
|
||||
action_ret = call_handle_IRQ_event(irq, regs, action, irqtp);
|
||||
irqtp->task = NULL;
|
||||
if (irqtp->flags)
|
||||
set_bits(irqtp->flags, &curtp->flags);
|
||||
} else
|
||||
#endif
|
||||
action_ret = handle_IRQ_event(irq, regs, action);
|
||||
|
||||
spin_lock(&desc->lock);
|
||||
if (!noirqdebug)
|
||||
note_interrupt(irq, desc, action_ret, regs);
|
||||
if (likely(!(desc->status & IRQ_PENDING)))
|
||||
break;
|
||||
desc->status &= ~IRQ_PENDING;
|
||||
}
|
||||
out:
|
||||
desc->status &= ~IRQ_INPROGRESS;
|
||||
/*
|
||||
* The ->end() handler has to deal with interrupts which got
|
||||
* disabled while the handler was running.
|
||||
*/
|
||||
if (desc->handler) {
|
||||
if (desc->handler->end)
|
||||
desc->handler->end(irq);
|
||||
else if (desc->handler->enable)
|
||||
desc->handler->enable(irq);
|
||||
}
|
||||
spin_unlock(&desc->lock);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
void do_IRQ(struct pt_regs *regs)
|
||||
{
|
||||
@ -310,8 +237,11 @@ void do_IRQ(struct pt_regs *regs)
|
||||
void do_IRQ(struct pt_regs *regs)
|
||||
{
|
||||
int irq;
|
||||
#ifdef CONFIG_IRQSTACKS
|
||||
struct thread_info *curtp, *irqtp;
|
||||
#endif
|
||||
|
||||
irq_enter();
|
||||
irq_enter();
|
||||
|
||||
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||
/* Debugging check for stack overflow: is there less than 2KB free? */
|
||||
@ -328,20 +258,44 @@ void do_IRQ(struct pt_regs *regs)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Every platform is required to implement ppc_md.get_irq.
|
||||
* This function will either return an irq number or -1 to
|
||||
* indicate there are no more pending.
|
||||
* The value -2 is for buggy hardware and means that this IRQ
|
||||
* has already been handled. -- Tom
|
||||
*/
|
||||
irq = ppc_md.get_irq(regs);
|
||||
|
||||
if (irq >= 0)
|
||||
ppc_irq_dispatch_handler(regs, irq);
|
||||
else
|
||||
/* That's not SMP safe ... but who cares ? */
|
||||
ppc_spurious_interrupts++;
|
||||
|
||||
irq_exit();
|
||||
if (irq >= 0) {
|
||||
#ifdef CONFIG_IRQSTACKS
|
||||
/* Switch to the irq stack to handle this */
|
||||
curtp = current_thread_info();
|
||||
irqtp = hardirq_ctx[smp_processor_id()];
|
||||
if (curtp != irqtp) {
|
||||
irqtp->task = curtp->task;
|
||||
irqtp->flags = 0;
|
||||
call___do_IRQ(irq, regs, irqtp);
|
||||
irqtp->task = NULL;
|
||||
if (irqtp->flags)
|
||||
set_bits(irqtp->flags, &curtp->flags);
|
||||
} else
|
||||
#endif
|
||||
__do_IRQ(irq, regs);
|
||||
} else
|
||||
#ifdef CONFIG_PPC32
|
||||
if (irq != -2)
|
||||
#endif
|
||||
/* That's not SMP safe ... but who cares ? */
|
||||
ppc_spurious_interrupts++;
|
||||
irq_exit();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
#ifdef CONFIG_PPC64
|
||||
static int once = 0;
|
||||
|
||||
if (once)
|
||||
@ -349,10 +303,14 @@ void __init init_IRQ(void)
|
||||
|
||||
once++;
|
||||
|
||||
#endif
|
||||
ppc_md.init_IRQ();
|
||||
#ifdef CONFIG_PPC64
|
||||
irq_ctx_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#ifndef CONFIG_PPC_ISERIES
|
||||
/*
|
||||
* Virtual IRQ mapping code, used on systems with XICS interrupt controllers.
|
||||
@ -517,3 +475,4 @@ static int __init setup_noirqdistrib(char *str)
|
||||
}
|
||||
|
||||
__setup("noirqdistrib", setup_noirqdistrib);
|
||||
#endif /* CONFIG_PPC64 */
|
@ -35,6 +35,7 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/iseries/it_exp_vpd_panel.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/systemcfg.h>
|
||||
|
||||
#define MODULE_VERS "1.6"
|
||||
#define MODULE_NAME "lparcfg"
|
||||
@ -96,7 +97,7 @@ static unsigned long get_purr(void)
|
||||
|
||||
#define lparcfg_write NULL
|
||||
|
||||
/*
|
||||
/*
|
||||
* Methods used to fetch LPAR data when running on an iSeries platform.
|
||||
*/
|
||||
static int lparcfg_data(struct seq_file *m, void *v)
|
||||
@ -168,7 +169,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
#ifdef CONFIG_PPC_PSERIES
|
||||
/*
|
||||
/*
|
||||
* Methods used to fetch LPAR data when running on a pSeries platform.
|
||||
*/
|
||||
|
||||
@ -177,7 +178,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
|
||||
* entitled_capacity,unallocated_capacity,
|
||||
* aggregation, resource_capability).
|
||||
*
|
||||
* R4 = Entitled Processor Capacity Percentage.
|
||||
* R4 = Entitled Processor Capacity Percentage.
|
||||
* R5 = Unallocated Processor Capacity Percentage.
|
||||
* R6 (AABBCCDDEEFFGGHH).
|
||||
* XXXX - reserved (0)
|
||||
@ -190,7 +191,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
|
||||
* XX - variable processor Capacity Weight
|
||||
* XX - Unallocated Variable Processor Capacity Weight.
|
||||
* XXXX - Active processors in Physical Processor Pool.
|
||||
* XXXX - Processors active on platform.
|
||||
* XXXX - Processors active on platform.
|
||||
*/
|
||||
static unsigned int h_get_ppp(unsigned long *entitled,
|
||||
unsigned long *unallocated,
|
||||
@ -273,7 +274,7 @@ static void parse_system_parameter_string(struct seq_file *m)
|
||||
if (!workbuffer) {
|
||||
printk(KERN_ERR "%s %s kmalloc failure at line %d \n",
|
||||
__FILE__, __FUNCTION__, __LINE__);
|
||||
kfree(local_buffer);
|
||||
kfree(local_buffer);
|
||||
return;
|
||||
}
|
||||
#ifdef LPARCFG_DEBUG
|
||||
@ -371,7 +372,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
|
||||
lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", NULL);
|
||||
|
||||
if (lrdrp == NULL) {
|
||||
partition_potential_processors = systemcfg->processorCount;
|
||||
partition_potential_processors = _systemcfg->processorCount;
|
||||
} else {
|
||||
partition_potential_processors = *(lrdrp + 4);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user