Commit dad99cb4 authored by Len Brown's avatar Len Brown

Merge

parents 272dacf7 f199195e
......@@ -100,8 +100,8 @@
<para>
I'd like to thank Jeff Garzik
<email>jgarzik@pobox.com</email> and Alexander Viro
<email>viro@math.psu.edu</email> for their input, Tim Waugh
<email>twaugh@redhat.com</email> for his <ulink
<email>viro@parcelfarce.linux.theplanet.co.uk</email> for their input,
Tim Waugh <email>twaugh@redhat.com</email> for his <ulink
url="http://people.redhat.com/twaugh/docbook/selfdocbook/">Selfdocbook</ulink>,
and Marc Joosen <email>marcj@historia.et.tudelft.nl</email> for
proofreading.
......
......@@ -82,7 +82,7 @@ lock might be used as follows for deletion and insertion:
list_for_each_entry(e, list, list) {
if (!audit_compare_rule(rule, &e->rule)) {
list_del(&e->list);
call_rcu(&e->rcu, audit_free_rule, e);
write_unlock(&auditsc_lock);
return 0;
}
}
......
......@@ -33,7 +33,8 @@ Resuming
code to resume Linux operation.
GSTATUS4 is currently left alone by the sleep code, and is free to
use for any other purposes.
use for any other purposes (for example, the EB2410ITX uses this to
save memory configuration in).
Machine Support
......@@ -41,9 +42,9 @@ Machine Support
The machine specific functions must call the s3c2410_pm_init() function
to say that it's bootloader is capable of resuming. This can be as
simple as adding the following to the file:
simple as adding the following to the machine's definition:
late_initcall(s3c2410_pm_init);
INITMACHINE(s3c2410_pm_init)
A board can do its own setup before calling s3c2410_pm_init, if it
needs to setup anything else for power management support.
......@@ -52,6 +53,23 @@ Machine Support
saving the resume address, if your board requires it, then contact
the maintainer and discuss what is required.
Note, the origianal method of adding an late_initcall() is wrong,
and will end up initialising all compiled machine's pm init!
Debugging
---------
There are several important things to rember when using PM suspend:
1) The uart drivers will disable the clocks to the UART blocks when
suspending, which means that use of printascii() or similar direct
access to the UARTs will cause the debug to stop.
2) Whilst the pm code itself will attempt to re-enabled the UART clocks,
care should be taken that any external clock sources that the UARTs
rely on are still enabled at that point
Configuration
-------------
......
......@@ -1632,7 +1632,7 @@ Changes for patch v177
- Fixed bugs in handling symlinks: could leak or cause Oops
- Cleaned up directory handling by separating fops
Thanks to Alexander Viro <viro@math.psu.edu>
Thanks to Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk>
===============================================================================
Changes for patch v178
......
......@@ -701,7 +701,7 @@ running once the system is up.
[KNL,ACPI] Mark specific memory as reserved.
Region of memory to be used, from ss to ss+nn.
meye= [HW] Set MotionEye Camera parameters
meye.*= [HW] Set MotionEye Camera parameters
See Documentation/video4linux/meye.txt.
mga= [HW,DRM]
......@@ -866,6 +866,16 @@ running once the system is up.
order they are specified on the command
line, starting with parport0.
parport_init_mode=
[HW,PPT] Configure VIA parallel port to
operate in specific mode. This is
necessary on Pegasos computer where
firmware has no options for setting up
parallel port mode and sets it to
spp. Currently this function knows
686a and 8231 chips.
Format: [spp|ps2|epp|ecp|ecpepp]
pas2= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16>
......@@ -1020,10 +1030,6 @@ running once the system is up.
New name for the ramdisk parameter.
See Documentation/ramdisk.txt.
ramdisk_start= [RAM] Starting block of RAM disk image (so you can
place it after the kernel image on a boot floppy).
See Documentation/ramdisk.txt.
reboot= [BUGS=IA-32,BUGS=ARM,BUGS=IA-64] Rebooting mode
Format: <reboot_mode>[,<reboot_mode2>[,...]]
See arch/*/kernel/reboot.c.
......
The prio_tree.c code indexes vmas using 3 different indexes:
* heap_index = vm_pgoff + vm_size_in_pages : end_vm_pgoff
* radix_index = vm_pgoff : start_vm_pgoff
* size_index = vm_size_in_pages
A regular radix-priority-search-tree indexes vmas using only heap_index and
radix_index. The conditions for indexing are:
* ->heap_index >= ->left->heap_index &&
->heap_index >= ->right->heap_index
* if (->heap_index == ->left->heap_index)
then ->radix_index < ->left->radix_index;
* if (->heap_index == ->right->heap_index)
then ->radix_index < ->right->radix_index;
* nodes are hashed to left or right subtree using radix_index
similar to a pure binary radix tree.
A regular radix-priority-search-tree helps to store and query
intervals (vmas). However, a regular radix-priority-search-tree is only
suitable for storing vmas with different radix indices (vm_pgoff).
Therefore, the prio_tree.c extends the regular radix-priority-search-tree
to handle many vmas with the same vm_pgoff. Such vmas are handled in
2 different ways: 1) All vmas with the same radix _and_ heap indices are
linked using vm_set.list, 2) if there are many vmas with the same radix
index, but different heap indices and if the regular radix-priority-search
tree cannot index them all, we build an overflow-sub-tree that indexes such
vmas using heap and size indices instead of heap and radix indices. For
example, in the figure below some vmas with vm_pgoff = 0 (zero) are
indexed by regular radix-priority-search-tree whereas others are pushed
into an overflow-subtree. Note that all vmas in an overflow-sub-tree have
the same vm_pgoff (radix_index) and if necessary we build different
overflow-sub-trees to handle each possible radix_index. For example,
in figure we have 3 overflow-sub-trees corresponding to radix indices
0, 2, and 4.
In the final tree the first few (prio_tree_root->index_bits) levels
are indexed using heap and radix indices whereas the overflow-sub-trees below
those levels (i.e. levels prio_tree_root->index_bits + 1 and higher) are
indexed using heap and size indices. In overflow-sub-trees the size_index
is used for hashing the nodes to appropriate places.
Now, an example prio_tree:
vmas are represented [radix_index, size_index, heap_index]
i.e., [start_vm_pgoff, vm_size_in_pages, end_vm_pgoff]
level prio_tree_root->index_bits = 3
-----
_
0 [0,7,7] |
/ \ |
------------------ ------------ | Regular
/ \ | radix priority
1 [1,6,7] [4,3,7] | search tree
/ \ / \ |
------- ----- ------ ----- | heap-and-radix
/ \ / \ | indexed
2 [0,6,6] [2,5,7] [5,2,7] [6,1,7] |
/ \ / \ / \ / \ |
3 [0,5,5] [1,5,6] [2,4,6] [3,4,7] [4,2,6] [5,1,6] [6,0,6] [7,0,7] |
/ / / _
/ / / _
4 [0,4,4] [2,3,5] [4,1,5] |
/ / / |
5 [0,3,3] [2,2,4] [4,0,4] | Overflow-sub-trees
/ / |
6 [0,2,2] [2,1,3] | heap-and-size
/ / | indexed
7 [0,1,1] [2,0,2] |
/ |
8 [0,0,0] |
_
Note that we use prio_tree_root->index_bits to optimize the height
of the heap-and-radix indexed tree. Since prio_tree_root->index_bits is
set according to the maximum end_vm_pgoff mapped, we are sure that all
bits (in vm_pgoff) above prio_tree_root->index_bits are 0 (zero). Therefore,
we only use the first prio_tree_root->index_bits as radix_index.
Whenever index_bits is increased in prio_tree_expand, we shuffle the tree
to make sure that the first prio_tree_root->index_bits levels of the tree
is indexed properly using heap and radix indices.
We do not optimize the height of overflow-sub-trees using index_bits.
The reason is: there can be many such overflow-sub-trees and all of
them have to be suffled whenever the index_bits increases. This may involve
walking the whole prio_tree in prio_tree_insert->prio_tree_expand code
path which is not desirable. Hence, we do not optimize the height of the
heap-and-size indexed overflow-sub-trees using prio_tree->index_bits.
Instead the overflow sub-trees are indexed using full BITS_PER_LONG bits
of size_index. This may lead to skewed sub-trees because most of the
higher significant bits of the size_index are likely to be be 0 (zero). In
the example above, all 3 overflow-sub-trees are skewed. This may marginally
affect the performance. However, processes rarely map many vmas with the
same start_vm_pgoff but different end_vm_pgoffs. Therefore, we normally
do not require overflow-sub-trees to index all vmas.
From the above discussion it is clear that the maximum height of
a prio_tree can be prio_tree_root->index_bits + BITS_PER_LONG.
However, in most of the common cases we do not need overflow-sub-trees,
so the tree height in the common cases will be prio_tree_root->index_bits.
It is fair to mention here that the prio_tree_root->index_bits
is increased on demand, however, the index_bits is not decreased when
vmas are removed from the prio_tree. That's tricky to do. Hence, it's
left as a home work problem.
Sony Programmable I/O Control Device Driver Readme
--------------------------------------------------
Copyright (C) 2001-2003 Stelian Pop <stelian@popies.net>
Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
Copyright (C) 2001-2002 Alcôve <www.alcove.com>
Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
......@@ -23,16 +23,18 @@ generate, like:
Those events (see linux/sonypi.h) can be polled using the character device node
/dev/sonypi (major 10, minor auto allocated or specified as a option).
A simple daemon which translates the jogdial movements into mouse wheel events
can be downloaded at: <http://popies.net/sonypi/>
Another option to intercept the events is to get them directly through the
input layer.
This driver supports also some ioctl commands for setting the LCD screen
brightness and querying the batteries charge information (some more
brightness and querying the batteries charge information (some more
commands may be added in the future).
This driver can also be used to set the camera controls on Picturebook series
(brightness, contrast etc), and is used by the video4linux driver for the
(brightness, contrast etc), and is used by the video4linux driver for the
Motion Eye camera.
Please note that this driver was created by reverse engineering the Windows
......@@ -47,7 +49,7 @@ module argument syntax (<param>=<value> when passing the option to the
module or sonypi.<param>=<value> on the kernel boot line when sonypi is
statically linked into the kernel). Those options are:
minor: minor number of the misc device /dev/sonypi,
minor: minor number of the misc device /dev/sonypi,
default is -1 (automatic allocation, see /proc/misc
or kernel logs)
......@@ -59,14 +61,14 @@ statically linked into the kernel). Those options are:
get enabled unless you set this parameter to 1.
Do not use this option unless it's actually necessary,
some Vaio models don't deal well with this option.
This option is available only if the kernel is
This option is available only if the kernel is
compiled without ACPI support (since it conflicts
with it and it shouldn't be required anyway if
with it and it shouldn't be required anyway if
ACPI is already enabled).
verbose: set to 1 to print unknown events received from the
verbose: set to 1 to print unknown events received from the
sonypi device.
set to 2 to print all events received from the
set to 2 to print all events received from the
sonypi device.
compat: uses some compatibility code for enabling the sonypi
......@@ -75,14 +77,15 @@ statically linked into the kernel). Those options are:
add this option and report to the author.
mask: event mask telling the driver what events will be
reported to the user. This parameter is required for some
Vaio models where the hardware reuses values used in
other Vaio models (like the FX series who does not
have a jogdial but reuses the jogdial events for
reported to the user. This parameter is required for
some Vaio models where the hardware reuses values
used in other Vaio models (like the FX series who does
not have a jogdial but reuses the jogdial events for
programmable keys events). The default event mask is
set to 0xffffffff, meaning that all possible events will be
tried. You can use the following bits to construct
your own event mask (from drivers/char/sonypi.h):
set to 0xffffffff, meaning that all possible events
will be tried. You can use the following bits to
construct your own event mask (from
drivers/char/sonypi.h):
SONYPI_JOGGER_MASK 0x0001
SONYPI_CAPTURE_MASK 0x0002
SONYPI_FNKEY_MASK 0x0004
......@@ -97,10 +100,10 @@ statically linked into the kernel). Those options are:
SONYPI_MEMORYSTICK_MASK 0x0800
SONYPI_BATTERY_MASK 0x1000
useinput: if set (which is the default) jogdial events are
forwarded to the input subsystem as mouse wheel
events.
useinput: if set (which is the default) two input devices are
created, one which interprets the jogdial events as
mouse events, the other one which acts like a
keyboard reporting the pressing of the special keys.
Module use:
-----------
......@@ -123,17 +126,17 @@ Bugs:
external monitor on/off. There is no workaround yet, since this
driver disables all APM management for those keys, by enabling the
ACPI management (and the ACPI core stuff is not complete yet). If
you have one of those laptops with working Fn keys and want to
you have one of those laptops with working Fn keys and want to
continue to use them, don't use this driver.
- some users reported that the laptop speed is lower (dhrystone
tested) when using the driver with the fnkeyinit parameter. I cannot
reproduce it on my laptop and not all users have this problem.
This happens because the fnkeyinit parameter enables the ACPI
mode (but without additional ACPI control, like processor
This happens because the fnkeyinit parameter enables the ACPI
mode (but without additional ACPI control, like processor
speed handling etc). Use ACPI instead of APM if it works on your
laptop.
- since all development was done by reverse engineering, there is
_absolutely no guarantee_ that this driver will not crash your
laptop. Permanently.
......@@ -4,7 +4,7 @@
Author: Romain Lievin
Homepage: http://lpg.ticalc.org/prj_dev
Homepage: http://lpg.ticalc.org/prj_tidev/index.html
INTRODUCTION:
......@@ -12,31 +12,30 @@ INTRODUCTION:
This is a driver for the very common home-made parallel link cable, a cable
designed for connecting TI8x/9x graphing calculators (handhelds) to a computer
or workstation (Alpha, Sparc). Given that driver is built on parport, the
parallel port abstraction layer, this driver is independent of the platform.
parallel port abstraction layer, this driver is architecture-independent.
It can also be used with another device plugged on the same port (such as a
ZIP drive). I have a 100MB ZIP and both of them work fine !
ZIP drive). I have a 100MB ZIP and both of them work fine!
If you need more information, please visit the 'TI drivers' homepage at the URL
above.
WHAT YOU NEED:
A TI calculator of course and a program capable to communicate with your
calculator.
TiLP will work for sure (since I am his developer !). yal92 may be able to use
A TI calculator and a program capable of communicating with your calculator.
TiLP will work for sure (since I am its developer!). yal92 may be able to use
it by changing tidev for tipar (may require some hacking...).
HOW TO USE IT:
You must have first compiled parport support (CONFIG_PARPORT_DEV): either
compiled in your kernel, either as a module.
This driver supports the new device hierarchy (devfs).
Next, (as root) from your appropriate modules directory (lib/modules/2.5.XX):
Next, (as root):
modprobe parport
insmod tipar.o
modprobe tipar
If it is not already there (it usually is), create the device:
......@@ -47,14 +46,14 @@ If it is not already there (it usually is), create the device:
You will have to set permissions on this device to allow you to read/write
from it:
chmod 666 /dev/tipar?
chmod 666 /dev/tipar[0..2]
Now you are ready to run a linking program such as TiLP. Be sure to configure
it properly (RTFM).
MODULE PARAMETERS:
You can set these with: insmod tipar NAME=VALUE
You can set these with: modprobe tipar NAME=VALUE
There is currently no way to set these on a per-cable basis.
NAME: timeout
......@@ -66,11 +65,12 @@ MODULE PARAMETERS:
NAME: delay
TYPE: integer
DEFAULT: 10
DESC: Inter-bit delay in micro-seconds. An lower value gives an higher data
DESC: Inter-bit delay in micro-seconds. A lower value gives an higher data
rate but makes transmission less reliable.
These parameters can be changed at run time by any program via ioctl(2) calls
as listed in ./include/linux/ticable.h
as listed in ./include/linux/ticable.h.
Rather than write 50 pages describing the ioctl() and so on, it is
perhaps more useful you look at ticables library (dev_link.c) that demonstrates
how to use them, and demonstrates the features of the driver. This is
......
Vaio Picturebook Motion Eye Camera Driver Readme
------------------------------------------------
Copyright (C) 2001-2003 Stelian Pop <stelian@popies.net>
Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
Copyright (C) 2001-2002 Alcôve <www.alcove.com>
Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
This driver enable the use of video4linux compatible applications with the
Motion Eye camera. This driver requires the "Sony Vaio Programmable I/O
Control Device" driver (which can be found in the "Character drivers"
Motion Eye camera. This driver requires the "Sony Vaio Programmable I/O
Control Device" driver (which can be found in the "Character drivers"
section of the kernel configuration utility) to be compiled and installed
(using its "camera=1" parameter).
......@@ -24,7 +24,7 @@ This driver supports the 'second' version of the MotionEye camera :)
The first version was connected directly on the video bus of the Neomagic
video card and is unsupported.
The second one, made by Kawasaki Steel is fully supported by this
The second one, made by Kawasaki Steel is fully supported by this
driver (PCI vendor/device is 0x136b/0xff01)
The third one, present in recent (more or less last year) Picturebooks
......@@ -41,13 +41,12 @@ little information if any is available for this camera
Driver options:
---------------
Several options can be passed to the meye driver, either by adding them
to /etc/modprobe.conf file, when the driver is compiled as a module, or
by adding the following to the kernel command line (in your bootloader):
Several options can be passed to the meye driver using the standard
module argument syntax (<param>=<value> when passing the option to the
module or meye.<param>=<value> on the kernel boot line when meye is
statically linked into the kernel). Those options are:
meye=gbuffers[,gbufsize[,video_nr]]
where:
forcev4l1: force use of V4L1 API instead of V4L2
gbuffers: number of capture buffers, default is 2 (32 max)
......@@ -81,8 +80,9 @@ Usage:
Private API:
------------
The driver supports frame grabbing with the video4linux API, so
all video4linux tools (like xawtv) should work with this driver.
The driver supports frame grabbing with the video4linux API
(either v4l1 or v4l2), so all video4linux tools (like xawtv)
should work with this driver.
Besides the video4linux interface, the driver has a private interface
for accessing the Motion Eye extended parameters (camera sharpness,
......@@ -116,7 +116,7 @@ Private API:
MEYEIOC_STILLJCAPT
Takes a snapshot in an uncompressed or compressed jpeg format.
This ioctl blocks until the snapshot is done and returns (for
jpeg snapshot) the size of the image. The image data is
jpeg snapshot) the size of the image. The image data is
available from the first mmap'ed buffer.
Look at the 'motioneye' application code for an actual example.
......@@ -124,13 +124,7 @@ Private API:
Bugs / Todo:
------------
- overlay output is not supported (although the camera is capable of).
(it should not be too hard to to it, provided we found how...)
- mjpeg hardware playback doesn't work (depends on overlay...)
- the driver could be much cleaned up by removing the v4l1 support.
However, this means all v4l1-only applications will stop working.
- rewrite the driver to use some common video4linux API for snapshot
and mjpeg capture. Unfortunately, video4linux1 does not permit it,
the BUZ API seems to be targeted to TV cards only. The video4linux 2
API may be an option, if it goes into the kernel (maybe 2.5
material ?).
- 'motioneye' still uses the meye private v4l1 API extensions.
......@@ -831,7 +831,7 @@ S: Maintained
FILESYSTEMS (VFS and infrastructure)
P: Alexander Viro
M: viro@math.psu.edu
M: viro@parcelfarce.linux.theplanet.co.uk
S: Maintained
FIRMWARE LOADER (request_firmware)
......
......@@ -162,10 +162,10 @@ config ARCH_LH7A40X
config ARCH_OMAP
bool "TI OMAP"
config ARCH_VERSATILE_PB
bool "Versatile PB"
config ARCH_VERSATILE
bool "Versatile"
help
This enables support for ARM Ltd Versatile PB board.
This enables support for ARM Ltd Versatile board.
config ARCH_IMX
bool "IMX"
......@@ -205,6 +205,8 @@ source "arch/arm/mach-imx/Kconfig"
source "arch/arm/mach-h720x/Kconfig"
source "arch/arm/mach-versatile/Kconfig"
# Definitions to make life easier
config ARCH_ACORN
bool
......@@ -287,9 +289,14 @@ config ICST525
depends on ARCH_INTEGRATOR
default y
config ICST307
bool
depends on ARCH_VERSATILE
default y
config ARM_AMBA
bool
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB
depends on ARCH_INTEGRATOR || ARCH_VERSATILE
default y
config ISA
......@@ -547,7 +554,7 @@ config CMDLINE
config LEDS
bool "Timer and CPU usage LEDs"
depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB || ARCH_IMX
depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE || ARCH_IMX
help
If you say Y here, the LEDs on your machine will be used
to provide useful information about your current system status.
......@@ -560,8 +567,8 @@ config LEDS
system, but the driver will do nothing.
config LEDS_TIMER
bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB || ARCH_IMX)
depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB || ARCH_IMX
bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE || ARCH_IMX)
depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE || ARCH_IMX
default y if ARCH_EBSA110
help
If you say Y here, one of the system LEDs (the green one on the
......@@ -576,7 +583,7 @@ config LEDS_TIMER
config LEDS_CPU
bool "CPU usage LED"
depends on LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB || ARCH_IMX)
depends on LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE || ARCH_IMX)
help
If you say Y here, the red LED will be used to give a good real
time indication of CPU usage, by lighting whenever the idle task
......
......@@ -93,7 +93,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
machine-$(CONFIG_ARCH_OMAP) := omap
machine-$(CONFIG_ARCH_S3C2410) := s3c2410
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
machine-$(CONFIG_ARCH_VERSATILE_PB) := versatile
machine-$(CONFIG_ARCH_VERSATILE) := versatile
machine-$(CONFIG_ARCH_IMX) := imx
machine-$(CONFIG_ARCH_H720X) := h720x
......
......@@ -5,6 +5,7 @@
obj-y += rtctime.o
obj-$(CONFIG_ARM_AMBA) += amba.o
obj-$(CONFIG_ICST525) += icst525.o
obj-$(CONFIG_ICST307) += icst307.o
obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
obj-$(CONFIG_DMABOUNCE) += dmabounce.o
......
/*
* linux/arch/arm/common/icst307.c
*
* Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
*
* 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.
*
* Support functions for calculating clocks/divisors for the ICST307
* clock generators. See http://www.icst.com/ for more information
* on these devices.
*
* This is an almost identical implementation to the ICST525 clock generator.
* The s2div and idx2s files are different
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/hardware/icst307.h>
/*
* Divisors for each OD setting.
*/
static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 };
unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco)
{
return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]);
}
EXPORT_SYMBOL(icst307_khz);
/*
* Ascending divisor S values.
*/
static unsigned char idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 };
struct icst307_vco
icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq)
{
struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
unsigned long f;
unsigned int i = 0, rd, best = (unsigned int)-1;
/*
* First, find the PLL output divisor such
* that the PLL output is within spec.
*/
do {
f = freq * s2div[idx2s[i]];
/*
* f must be between 6MHz and 200MHz (3.3 or 5V)
*/
if (f > 6000 && f <= p->vco_max)
break;
} while (i < ARRAY_SIZE(idx2s));
if (i > ARRAY_SIZE(idx2s))
return vco;
vco.s = idx2s[i];
/*
* Now find the closest divisor combination
* which gives a PLL output of 'f'.
*/
for (rd = p->rd_min; rd <= p->rd_max; rd++) {
unsigned long fref_div, f_pll;
unsigned int vd;
int f_diff;
fref_div = (2 * p->ref) / rd;
vd = (f + fref_div / 2) / fref_div;
if (vd < p->vd_min || vd > p->vd_max)
continue;
f_pll = fref_div * vd;
f_diff = f_pll - f;
if (f_diff < 0)
f_diff = -f_diff;
if ((unsigned)f_diff < best) {
vco.v = vd - 8;
vco.r = rd - 2;
if (f_diff == 0)
break;
best = f_diff;
}
}
return vco;
}
EXPORT_SYMBOL(icst307_khz_to_vco);
struct icst307_vco
icst307_ps_to_vco(const struct icst307_params *p, unsigned long period)
{
struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
unsigned long f, ps;
unsigned int i = 0, rd, best = (unsigned int)-1;
ps = 1000000000UL / p->vco_max;
/*
* First, find the PLL output divisor such
* that the PLL output is within spec.
*/
do {
f = period / s2div[idx2s[i]];
/*
* f must be between 6MHz and 200MHz (3.3 or 5V)
*/
if (f >= ps && f < 1000000000UL / 6000 + 1)
break;
} while (i < ARRAY_SIZE(idx2s));
if (i > ARRAY_SIZE(idx2s))
return vco;
vco.s = idx2s[i];
ps = 500000000UL / p->ref;
/*
* Now find the closest divisor combination
* which gives a PLL output of 'f'.
*/
for (rd = p->rd_min; rd <= p->rd_max; rd++) {
unsigned long f_in_div, f_pll;
unsigned int vd;
int f_diff;
f_in_div = ps * rd;
vd = (f_in_div + f / 2) / f;
if (vd < p->vd_min || vd > p->vd_max)
continue;
f_pll = (f_in_div + vd / 2) / vd;
f_diff = f_pll - f;
if (f_diff < 0)
f_diff = -f_diff;
if ((unsigned)f_diff < best) {
vco.v = vd - 8;
vco.r = rd - 2;
if (f_diff == 0)
break;
best = f_diff;
}
}
return vco;
}
EXPORT_SYMBOL(icst307_ps_to_vco);
......@@ -609,17 +609,15 @@ static void __locomo_remove(struct locomo *lchip)
static int locomo_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct resource *mem = NULL, *irq = NULL;
int i;
for (i = 0; i < pdev->num_resources; i++) {
if (pdev->resource[i].flags & IORESOURCE_MEM)
mem = &pdev->resource[i];
if (pdev->resource[i].flags & IORESOURCE_IRQ)
irq = &pdev->resource[i];
}
struct resource *mem;
int irq;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem)
return -EINVAL;
irq = platform_get_irq(pdev, 0);
return __locomo_probe(dev, mem, irq ? irq->start : NO_IRQ);
return __locomo_probe(dev, mem, irq);
}
static int locomo_remove(struct device *dev)
......@@ -756,7 +754,7 @@ module_exit(locomo_exit);
MODULE_DESCRIPTION("Sharp LoCoMo core driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("John Lenz <jelenz@students.wisc.edu>");
MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
EXPORT_SYMBOL(locomo_driver_register);
EXPORT_SYMBOL(locomo_driver_unregister);
......@@ -647,7 +647,7 @@
.endm
#elif defined(CONFIG_ARCH_VERSATILE_PB)
#elif defined(CONFIG_ARCH_VERSATILE)
#include <asm/hardware/amba_serial.h>
......
......@@ -464,7 +464,7 @@ ENTRY(soft_irq_mask)
.macro irq_prio_table
.endm
#elif defined(CONFIG_ARCH_VERSATILE_PB)
#elif defined(CONFIG_ARCH_VERSATILE)
.macro disable_fiq
.endm
......
......@@ -73,8 +73,7 @@ td3 .req lr
.done: adc r0, sum, #0 @ collect up the last carry
ldr td0, [sp], #4
tst td0, #1 @ check buffer alignment
movne td0, r0, lsl #8 @ rotate checksum by 8 bits
orrne r0, td0, r0, lsr #24
movne r0, r0, ror #8 @ rotate checksum by 8 bits
ldr pc, [sp], #4 @ return
.not_aligned: tst buf, #1 @ odd address
......
......@@ -160,8 +160,7 @@ FN_ENTRY
.done: adc r0, sum, #0
ldr sum, [sp, #0] @ dst
tst sum, #1
movne sum, r0, lsl #8
orrne r0, sum, r0, lsr #24
movne r0, r0, ror #8
load_regs ea
.src_not_aligned:
......
......@@ -27,11 +27,10 @@ ENTRY(__raw_readsl)
stmia r1!, {r3, r4, ip, lr}
bpl 1b
ldmfd sp!, {r4, lr}
2: tst r2, #2
ldrne r3, [r0, #0]
ldrne ip, [r0, #0]
stmneia r1!, {r3, ip}
tst r2, #1
2: movs r2, r2, lsl #31
ldrcs r3, [r0, #0]
ldrcs ip, [r0, #0]
stmcsia r1!, {r3, ip}
ldrne r3, [r0, #0]
strne r3, [r1, #0]
mov pc, lr
......
......@@ -27,12 +27,11 @@ ENTRY(__raw_writesl)
str lr, [r0, #0]
bpl 1b
ldmfd sp!, {r4, lr}
2: tst r2, #2
ldmneia r1!, {r3, ip}
strne r3, [r0, #0]
strne ip, [r0, #0]
tst r2, #1
2: movs r2, r2, lsl #31
ldmcsia r1!, {r3, ip}
strcs r3, [r0, #0]
ldrne r3, [r1, #0]
strcs ip, [r0, #0]
strne r3, [r0, #0]
mov pc, lr
......
......@@ -12,6 +12,7 @@
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
......@@ -313,6 +314,55 @@ static struct clps7500_timer = {
.offset = ioc_timer_gettimeoffset,
};
static struct plat_serial8250_port serial_platform_data[] = {
{
.mapbase = 0x03010fe0,
.irq = 10,
.uartclk = 1843200,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST,
},
{
.mapbase = 0x03010be0,
.irq = 0,
.uartclk = 1843200,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST,
},
{
.iobase = ISASLOT_IO + 0x2e8,
.irq = 41,
.uartclk = 1843200,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.iobase = ISASLOT_IO + 0x3e8,
.irq = 40,
.uartclk = 1843200,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
static int __init clps7500_init(void)
{
return platform_register_device(&serial_device);
}
MACHINE_START(CLPS7500, "CL-PS7500")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
......
......@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/serial_8250.h>
#include <linux/init.h>
#include <asm/hardware.h>
......@@ -196,6 +197,41 @@ static struct sys_timer ebsa110_timer = {
.offset = ebsa110_gettimeoffset,
};
static struct plat_serial8250_port serial_platform_data[] = {
{
.iobase = 0x3f8,
.irq = 1,
.uartclk = 1843200,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.iobase = 0x2f8,
.irq = 2,
.uartclk = 1843200,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
static int __init ebsa110_init(void)
{
return platform_device_register(&serial_device);
}
arch_initcall(ebsa110_init);
MACHINE_START(EBSA110, "EBSA110")
MAINTAINER("Russell King")
BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000)
......
......@@ -20,6 +20,7 @@
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/serial_8250.h>
#include <asm/hardware.h>
#include <asm/setup.h>
......@@ -27,6 +28,36 @@
#include <asm/mach/arch.h>
static struct plat_serial8250_port serial_platform_data[] = {
{
.iobase = 0x3f8,
.irq = IRQ_UARTINT0,
#error FIXME
.uartclk = 0,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.iobase = 0x2f8,
.irq = IRQ_UARTINT1,
#error FIXME
.uartclk = 0,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
extern void epxa10db_map_io(void);
extern void epxa10db_init_irq(void);
extern struct sys_timer epxa10db_timer;
......
......@@ -26,3 +26,5 @@ obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o
obj-$(CONFIG_PCI) +=$(pci-y)
obj-$(CONFIG_LEDS) +=$(leds-y)
obj-$(CONFIG_ISA) += isa.o
/*
* linux/arch/arm/mach-footbridge/isa.c
*
* Copyright (C) 2004 Russell King.
*
* 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/init.h>
#include <linux/serial_8250.h>
#include <asm/irq.h>
static struct plat_serial8250_port serial_platform_data[] = {
{
.iobase = 0x3f8,
.irq = IRQ_ISA_UART,
.uartclk = 1843200,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.iobase = 0x2f8,
.irq = IRQ_ISA_UART2,
.uartclk = 1843200,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
static int __init footbridge_isa_init(void)
{
return platform_device_register(&serial_device);
}
arch_initcall(footbridge_isa_init);
/*
* linux/arch/arm/mach-h720x/common.h
*
* Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
* 2003 Robert Schwebel <r.schwebel@pengutronix.de>
* 2004 Sascha Hauer <s.hauer@pengutronix.de>
*
* Architecture specific stuff for Hynix GMS30C7201 development board
*
* 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.
*
*/
extern unsigned long h720x_gettimeoffset(void);
extern void __init h720x_init_irq (void);
extern void __init h720x_map_io(void);
#ifdef CONFIG_ARCH_H7202
extern struct sys_timer h7202_timer;
extern void __init init_hw_h7202(void);
extern void __init h7202_init_irq (void);
extern void __init h7202_init_time(void);
#endif
#ifdef CONFIG_ARCH_H7201
extern struct sys_timer h7201_timer;
#endif
......@@ -22,10 +22,7 @@
#include <asm/arch/irqs.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
extern unsigned long h720x_gettimeoffset(void);
extern void __init h720x_init_irq (void);
#include "common.h"
/*
* Timer interrupt handler
*/
......@@ -53,8 +50,6 @@ static struct irqaction h7201_timer_irq = {
*/
void __init h7201_init_time(void)
{
gettimeoffset = h720x_gettimeoffset;
CPU_REG (TIMER_VIRT, TM0_PERIOD) = LATCH;
CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_RESET;
CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_REPEAT | TM_START;
......@@ -62,3 +57,8 @@ void __init h7201_init_time(void)
setup_irq(IRQ_TIMER0, &h7201_timer_irq);
}
struct sys_timer h7201_timer = {
.init = h7201_init_time,
.offset = h720x_gettimeoffset,
};
......@@ -23,6 +23,8 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <linux/device.h>
#include <linux/serial_8250.h>
#include "common.h"
static struct resource h7202ps2_resources[] = {
[0] = {
......@@ -44,13 +46,55 @@ static struct platform_device h7202ps2_device = {
.resource = h7202ps2_resources,
};
static struct plat_serial8250_port serial_platform_data[] = {
{
.membase = SERIAL0_BASE,
.irq = IRQ_UART0,
.uartclk = 2*1843200,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.membase = SERIAL1_BASE,
.irq = IRQ_UART1,
.uartclk = 2*1843200,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.membase = SERIAL2_BASE,
.irq = IRQ_UART2,
.uartclk = 2*1843200,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.membase = SERIAL3_BASE,
.irq = IRQ_UART3,
.uartclk = 2*1843200,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
static struct platform_device *devices[] __initdata = {
&h7202ps2_device,
&serial_device,
};
extern unsigned long h720x_gettimeoffset(void);
extern void __init h720x_init_irq (void);
/* Although we have two interrupt lines for the timers, we only have one
* status register which clears all pending timer interrupts on reading. So
* we have to handle all timer interrupts in one place.
......@@ -130,8 +174,6 @@ static struct irqaction h7202_timer_irq = {
*/
void __init h7202_init_time(void)
{
gettimeoffset = h720x_gettimeoffset;
CPU_REG (TIMER_VIRT, TM0_PERIOD) = LATCH;
CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_RESET;
CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_REPEAT | TM_START;
......@@ -140,6 +182,11 @@ void __init h7202_init_time(void)
setup_irq(IRQ_TIMER0, &h7202_timer_irq);
}
struct sys_timer h7202_timer = {
.init = h7202_init_time,
.offset = h720x_gettimeoffset,
};
void __init h7202_init_irq (void)
{
int irq;
......
......@@ -27,10 +27,7 @@
#include <asm/pgtable.h>
#include <asm/mach/arch.h>
#include <asm/hardware.h>
extern void h720x_init_irq (void);
extern void h7201_init_time(void);
extern void __init h720x_map_io(void);
#include "common.h"
MACHINE_START(H7201, "Hynix GMS30C7201")
MAINTAINER("Robert Schwebel, Pengutronix")
......@@ -38,5 +35,5 @@ MACHINE_START(H7201, "Hynix GMS30C7201")
BOOT_PARAMS(0xc0001000)
MAPIO(h720x_map_io)
INITIRQ(h720x_init_irq)
INITTIME(h7201_init_time)
.timer = &h7201_timer,
MACHINE_END
......@@ -27,11 +27,7 @@
#include <asm/pgtable.h>
#include <asm/mach/arch.h>
#include <asm/hardware.h>
extern void __init init_hw_h7202(void);
extern void __init h7202_init_irq (void);
extern void __init h7202_init_time(void);
extern void __init h720x_map_io(void);
#include "common.h"
static struct resource cirrus_resources[] = {
[0] = {
......@@ -80,6 +76,6 @@ MACHINE_START(H7202, "Hynix HMS30C7202")
BOOT_PARAMS(0x40000100)
MAPIO(h720x_map_io)
INITIRQ(h7202_init_irq)
INITTIME(h7202_init_time)
.timer = &h7202_timer,
INIT_MACHINE(init_eval_h7202)
MACHINE_END
......@@ -261,7 +261,7 @@ static void __init ixp4xx_timer_init(void)
setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
}
struct ixp4xx_timer = {
struct sys_timer ixp4xx_timer = {
.init = ixp4xx_timer_init,
.offset = ixp4xx_gettimeoffset,
};
if ARCH_OMAP
menu "TI OMAP Implementations"
......@@ -171,3 +172,5 @@ config OMAP_ARM_30MHZ
Enable 30MHz clock for OMAP CPU. If unsure, say N.
endmenu
endif
This diff is collapsed.
......@@ -48,8 +48,8 @@ struct mpu_rate {
#define VIRTUAL_CLOCK 8
#define ALWAYS_ENABLED 16
#define ENABLE_REG_32BIT 32
#define DOES_NOT_EXIST_ON_1510 64
#define DOES_NOT_EXIST_ON_1610 128 /* Including 1710 */
#define CLOCK_IN_OMAP16XX 64
#define CLOCK_IN_OMAP1510 128
/* ARM_CKCTL bit shifts */
#define CKCTL_PERDIV_OFFSET 0
......
......@@ -16,7 +16,8 @@
#include <linux/console.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <asm/hardware.h>
#include <asm/system.h>
......@@ -306,41 +307,72 @@ void omap_map_io(void)
_omap_map_io();
}
static struct uart_port omap_serial_ports[] = {
static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
int offset)
{
offset <<= up->regshift;
return (unsigned int)__raw_readb(up->membase + offset);
}
static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset,
int value)
{
offset <<= p->regshift;
__raw_writeb(value, p->membase + offset);
}
/*
* Internal UARTs need to be initialized for the 8250 autoconfig to work
* properly.
*/
static void __init omap_serial_reset(struct plat_serial8250_port *p)
{
omap_serial_outp(p, UART_OMAP_MDR1, 0x07); /* disable UART */
omap_serial_outp(p, UART_OMAP_MDR1, 0x00); /* enable UART */
if (!cpu_is_omap1510()) {
omap_serial_outp(p, UART_OMAP_SYSC, 0x01);
while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01));
}
}
static struct plat_serial8250_port serial_platform_data[] = {
{
.membase = (char*)IO_ADDRESS(OMAP_UART1_BASE),
.mapbase = (unsigned long)OMAP_UART1_BASE,
.irq = INT_UART1,
.flags = UPF_SKIP_TEST,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = OMAP16XX_BASE_BAUD * 16,
.line = 0,
.type = PORT_OMAP,
.fifosize = 64
} , {
},
{
.membase = (char*)IO_ADDRESS(OMAP_UART2_BASE),
.mapbase = (unsigned long)OMAP_UART2_BASE,
.irq = INT_UART2,
.flags = UPF_SKIP_TEST,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = OMAP16XX_BASE_BAUD * 16,
.line = 1,
.type = PORT_OMAP,
.fifosize = 64
} , {
},
{
.membase = (char*)IO_ADDRESS(OMAP_UART3_BASE),
.mapbase = (unsigned long)OMAP_UART3_BASE,
.irq = INT_UART3,
.flags = UPF_SKIP_TEST,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = OMAP16XX_BASE_BAUD * 16,
.line = 2,
.type = PORT_OMAP,
.fifosize = 64
}
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
/*
......@@ -353,25 +385,26 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
int i;
if (cpu_is_omap730()) {
omap_serial_ports[0].regshift = 0;
omap_serial_ports[1].regshift = 0;
omap_serial_ports[0].irq = INT_730_UART_MODEM_1;
omap_serial_ports[1].irq = INT_730_UART_MODEM_IRDA_2;
serial_platform_data[0].regshift = 0;
serial_platform_data[1].regshift = 0;
serial_platform_data[0].irq = INT_730_UART_MODEM_1;
serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
}
if (cpu_is_omap1510()) {
omap_serial_ports[0].uartclk = OMAP1510_BASE_BAUD * 16;
omap_serial_ports[1].uartclk = OMAP1510_BASE_BAUD * 16;
omap_serial_ports[2].uartclk = OMAP1510_BASE_BAUD * 16;
serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
}
for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
unsigned long port;
unsigned char regshift;
unsigned char reg;
if (ports[i] != 1)
if (ports[i] == 0) {
serial_platform_data[i].membase = 0;
serial_platform_data[i].mapbase = 0;
continue;
}
switch (i) {
case 0:
......@@ -382,7 +415,7 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
reg = fpga_read(OMAP1510_FPGA_POWER);
reg |= OMAP1510_FPGA_PCR_COM1_EN;
fpga_write(reg, OMAP1510_FPGA_POWER);
udelay(1);
udelay(10);
}
}
break;
......@@ -394,7 +427,7 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
reg = fpga_read(OMAP1510_FPGA_POWER);
reg |= OMAP1510_FPGA_PCR_COM2_EN;
fpga_write(reg, OMAP1510_FPGA_POWER);
udelay(1);
udelay(10);
}
}
break;
......@@ -405,19 +438,16 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
}
break;
}
/* Reset port */
if (!cpu_is_omap1510()) {
port = (unsigned long)omap_serial_ports[i].membase;
regshift = omap_serial_ports[i].regshift;
writeb(0x01, port + (UART_SYSC << regshift));
while (!(readb(port + (UART_SYSC << regshift)) & 0x01));
}
//early_serial_setup(&omap_serial_ports[i]);
omap_serial_reset(&serial_platform_data[i]);
}
}
static int __init omap_init(void)
{
return platform_device_register(&serial_device);
}
arch_initcall(omap_init);
#define NO_LENGTH_CHECK 0xffffffff
extern int omap_bootloader_tag_len;
......
......@@ -185,7 +185,7 @@ int ssp_init(struct ssp_dev *dev, u32 port, u32 mode, u32 flags, u32 psp_flags,
{
int ret, irq;
if (!request_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c, "SSP")) {
if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) {
return -EBUSY;
}
......
......@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/serial_8250.h>
#include <asm/elf.h>
#include <asm/io.h>
......@@ -130,9 +131,30 @@ static struct platform_device kbd_device = {
},
};
static struct plat_serial8250_port serial_platform_data[] = {
{
.mapbase = 0x03010fe0,
.irq = 10,
.uartclk = 1843200,
.regshift = 2,
.iotype = UPIO_MEM,
.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
static struct platform_device *devs[] __initdata = {
&iomd_device,
&kbd_device,
&serial_device,
&acornfb_device,
};
......
......@@ -66,7 +66,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.name = name_s3c2410
},
{
.idcode = 0x3241002,
.idcode = 0x32410002,
.idmask = 0xffffffff,
.map_io = s3c2410_map_io,
.init = s3c2410_init,
......
......@@ -28,6 +28,7 @@
* 01-Oct-2004 BJD Fixed mask bug in pullup() call
* 01-Oct-2004 BJD Added getirq() to turn pin into irqno
* 04-Oct-2004 BJD Added irq filter controls for GPIO
* 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code
*/
......@@ -66,6 +67,8 @@ void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
local_irq_restore(flags);
}
EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
unsigned int s3c2410_gpio_getcfg(unsigned int pin)
{
unsigned long base = S3C2410_GPIO_BASE(pin);
......@@ -80,6 +83,8 @@ unsigned int s3c2410_gpio_getcfg(unsigned int pin)
return __raw_readl(base) & mask;
}
EXPORT_SYMBOL(s3c2410_gpio_getcfg);
void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
{
unsigned long base = S3C2410_GPIO_BASE(pin);
......@@ -100,6 +105,8 @@ void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
local_irq_restore(flags);
}
EXPORT_SYMBOL(s3c2410_gpio_pullup);
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
unsigned long base = S3C2410_GPIO_BASE(pin);
......@@ -117,6 +124,8 @@ void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
local_irq_restore(flags);
}
EXPORT_SYMBOL(s3c2410_gpio_setpin);
unsigned int s3c2410_gpio_getpin(unsigned int pin)
{
unsigned long base = S3C2410_GPIO_BASE(pin);
......@@ -125,6 +134,8 @@ unsigned int s3c2410_gpio_getpin(unsigned int pin)
return __raw_readl(base + 0x04) & (1<< offs);
}
EXPORT_SYMBOL(s3c2410_gpio_getpin);
unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
{
unsigned long flags;
......@@ -140,6 +151,8 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
return misccr;
}
EXPORT_SYMBOL(s3c2410_modify_misccr);
int s3c2410_gpio_getirq(unsigned int pin)
{
if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23)
......@@ -157,6 +170,8 @@ int s3c2410_gpio_getirq(unsigned int pin)
return (pin - S3C2410_GPG0) + IRQ_EINT8;
}
EXPORT_SYMBOL(s3c2410_gpio_getirq);
int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
unsigned int config)
{
......@@ -192,3 +207,5 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
return 0;
}
EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
......@@ -36,6 +36,9 @@
*
* 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
* Add support for power management controls
*
* 04-Nov-2004 Ben Dooks
* Fix standard IRQ wake for EINT0..4 and RTC
*/
#include <linux/init.h>
......@@ -91,7 +94,7 @@ s3c_irq_wake(unsigned int irqno, unsigned int state)
if (!state)
s3c_irqwake_intmask |= irqbit;
else
s3c_irqwake_intmask &= irqbit;
s3c_irqwake_intmask &= ~irqbit;
return 0;
}
......
......@@ -23,6 +23,7 @@
*
* Parts based on arch/arm/mach-pxa/pm.c
*
* Thanks to Dimitry Andric for debugging
*/
#include <linux/config.h>
......@@ -33,10 +34,12 @@
#include <linux/interrupt.h>
#include <linux/crc32.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-mem.h>
......@@ -68,7 +71,21 @@ struct sleep_save {
static struct sleep_save core_save[] = {
SAVE_ITEM(S3C2410_LOCKTIME),
SAVE_ITEM(S3C2410_CLKCON)
SAVE_ITEM(S3C2410_CLKCON),
/* we restore the timings here, with the proviso that the board
* brings the system up in an slower, or equal frequency setting
* to the original system.
*
* if we cannot guarantee this, then things are going to go very
* wrong here, as we modify the refresh and both pll settings.
*/
SAVE_ITEM(S3C2410_REFRESH),
SAVE_ITEM(S3C2410_MPLLCON),
SAVE_ITEM(S3C2410_UPLLCON),
SAVE_ITEM(S3C2410_CLKDIVN),
SAVE_ITEM(S3C2410_CLKSLOW),
};
/* this lot should be really saved by the IRQ code */
......@@ -115,6 +132,20 @@ static struct sleep_save gpio_save[] = {
};
#ifdef CONFIG_S3C2410_PM_DEBUG
#define SAVE_UART(va) \
SAVE_ITEM((va) + S3C2410_ULCON), \
SAVE_ITEM((va) + S3C2410_UCON), \
SAVE_ITEM((va) + S3C2410_UFCON), \
SAVE_ITEM((va) + S3C2410_UMCON), \
SAVE_ITEM((va) + S3C2410_UBRDIV)
static struct sleep_save uart_save[] = {
SAVE_UART(S3C2410_VA_UART0),
SAVE_UART(S3C2410_VA_UART1),
SAVE_UART(S3C2410_VA_UART2),
};
/* debug
*
* we send the debug to printascii() to allow it to be seen if the
......@@ -135,10 +166,24 @@ static void pm_dbg(const char *fmt, ...)
printascii(buff);
}
static void s3c2410_pm_debug_init(void)
{
unsigned long tmp = __raw_readl(S3C2410_CLKCON);
/* re-start uart clocks */
tmp |= S3C2410_CLKCON_UART0;
tmp |= S3C2410_CLKCON_UART1;
tmp |= S3C2410_CLKCON_UART2;
__raw_writel(tmp, S3C2410_CLKCON);
udelay(10);
}
#define DBG(fmt...) pm_dbg(fmt)
#else
#define DBG(fmt...) printk(KERN_DEBUG fmt)
#define s3c2410_pm_debug_init() do { } while(0)
#endif
#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
......@@ -329,6 +374,9 @@ static void s3c2410_pm_check_restore(void)
}
#else
static struct sleep_save uart_save[] = {};
#define s3c2410_pm_check_prepare() do { } while(0)
#define s3c2410_pm_check_restore() do { } while(0)
#define s3c2410_pm_check_store() do { } while(0)
......@@ -344,12 +392,20 @@ static void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
}
}
/* s3c2410_pm_do_restore
*
* restore the system from the given list of saved registers
*
* Note, we do not use DBG() in here, as the system may not have
* restore the UARTs state yet
*/
static void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
{
for (; count > 0; count--, ptr++) {
DBG("restore %08lx (restore %08lx, current %08x)\n",
ptr->reg, ptr->val, __raw_readl(ptr->reg));
printk(KERN_DEBUG "restore %08lx (restore %08lx, was %08x)\n",
ptr->reg, ptr->val, __raw_readl(ptr->reg));
__raw_writel(ptr->val, ptr->reg);
}
}
......@@ -434,11 +490,15 @@ static void s3c2410_pm_configure_extint(void)
* central control for sleep/resume process
*/
static int s3c2410_pm_enter(u32 state)
static int s3c2410_pm_enter(suspend_state_t state)
{
unsigned long regs_save[16];
unsigned long tmp;
/* ensure the debug is initialised (if enabled) */
s3c2410_pm_debug_init();
DBG("s3c2410_pm_enter(%d)\n", state);
if (state != PM_SUSPEND_MEM) {
......@@ -480,6 +540,7 @@ static int s3c2410_pm_enter(u32 state)
s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
/* set the irq configuration for wake */
......@@ -493,7 +554,7 @@ static int s3c2410_pm_enter(u32 state)
/* ack any outstanding external interrupts before we go to sleep */
__raw_writel(S3C2410_EINTPEND, __raw_readl(S3C2410_EINTPEND));
__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
/* flush cache back to ram */
......@@ -512,9 +573,18 @@ static int s3c2410_pm_enter(u32 state)
/* unset the return-from-sleep flag, to ensure reset */
tmp = __raw_readl(S3C2410_GSTATUS2);
tmp &= S3C2410_GSTATUs2_OFFRESET;
tmp &= S3C2410_GSTATUS2_OFFRESET;
__raw_writel(tmp, S3C2410_GSTATUS2);
/* restore the system state */
s3c2410_pm_do_restore(core_save, ARRAY_SIZE(core_save));
s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
s3c2410_pm_debug_init();
/* check what irq (if any) restored the system */
DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
......@@ -527,12 +597,6 @@ static int s3c2410_pm_enter(u32 state)
s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
s3c_irqwake_eintmask);
DBG("post sleep, restoring state...\n");
s3c2410_pm_do_restore(core_save, ARRAY_SIZE(core_save));
s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
DBG("post sleep, preparing to return\n");
s3c2410_pm_check_restore();
......@@ -546,7 +610,7 @@ static int s3c2410_pm_enter(u32 state)
/*
* Called after processes are frozen, but before we shut down devices.
*/
static int s3c2410_pm_prepare(u32 state)
static int s3c2410_pm_prepare(suspend_state_t state)
{
return 0;
}
......@@ -554,7 +618,7 @@ static int s3c2410_pm_prepare(u32 state)
/*
* Called after devices are re-setup, but before processes are thawed.
*/
static int s3c2410_pm_finish(u32 state)
static int s3c2410_pm_finish(suspend_state_t state)
{
return 0;
}
......
......@@ -35,7 +35,10 @@
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-serial.h>
#define CONFIG_DEBUG_RESUME
/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
* reset the UART configuration, only enable if you really need this!
*/
//#define CONFIG_DEBUG_RESUME
.text
......@@ -133,6 +136,15 @@ ENTRY(s3c2410_cpu_resume)
mov r2, #S3C2410_PA_UART & 0xff000000
orr r2, r2, #S3C2410_PA_UART & 0xff000
#if 0
/* SMDK2440 LED set */
mov r14, #S3C2410_PA_GPIO
ldr r12, [ r14, #0x54 ]
bic r12, r12, #3<<4
orr r12, r12, #1<<7
str r12, [ r14, #0x54 ]
#endif
#ifdef CONFIG_DEBUG_RESUME
mov r3, #'L'
strb r3, [ r2, #S3C2410_UTXH ]
......
......@@ -161,7 +161,7 @@ static u64 sa11x0udc_dma_mask = 0xffffffffUL;
static struct platform_device sa11x0udc_device = {
.name = "sa11x0-udc",
.id = 0,
.id = -1,
.dev = {
.dma_mask = &sa11x0udc_dma_mask,
.coherent_dma_mask = 0xffffffff,
......@@ -212,7 +212,7 @@ static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
static struct platform_device sa11x0mcp_device = {
.name = "sa11x0-mcp",
.id = 0,
.id = -1,
.dev = {
.dma_mask = &sa11x0mcp_dma_mask,
.coherent_dma_mask = 0xffffffff,
......@@ -233,7 +233,7 @@ static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
static struct platform_device sa11x0ssp_device = {
.name = "sa11x0-ssp",
.id = 0,
.id = -1,
.dev = {
.dma_mask = &sa11x0ssp_dma_mask,
.coherent_dma_mask = 0xffffffff,
......@@ -257,7 +257,7 @@ static struct resource sa11x0fb_resources[] = {
static struct platform_device sa11x0fb_device = {
.name = "sa11x0-fb",
.id = 0,
.id = -1,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
......@@ -267,7 +267,7 @@ static struct platform_device sa11x0fb_device = {
static struct platform_device sa11x0pcmcia_device = {
.name = "sa11x0-pcmcia",
.id = 0,
.id = -1,
};
static struct platform_device *sa11x0_devices[] __initdata = {
......
......@@ -20,6 +20,7 @@
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/serial_8250.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
......@@ -32,9 +33,6 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/serial_sa1100.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <asm/arch/serial.h>
#include <asm/io.h>
#include <asm/irq.h>
......@@ -178,6 +176,34 @@ static void trizeps_power_off(void)
PMCR = PMCR_SF;
}
static struct plat_serial8250_port serial_platform_data[] = {
{
.mapbase = TRIZEPS_UART5,
.irq = IRQ_GPIO16,
.uartclk = 24000000,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.mapbase = TRIZEPS_UART6,
.irq = IRQ_GPIO17,
.uartclk = 24000000,
.regshift = 0,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
static int __init trizeps_init(void)
{
if (!machine_is_trizeps())
......@@ -201,6 +227,8 @@ static int __init trizeps_init(void)
set_irq_type(IRQ_GPIO16, IRQT_RISING);
set_irq_type(IRQ_GPIO17, IRQT_RISING);
platform_device_register(&serial_device);
return 0;
}
......
......@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/serial_8250.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
......@@ -18,6 +19,46 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
static struct plat_serial8250_port serial_platform_data[] = {
{
.iobase = 0x3f8,
.irq = 4,
.uartclk = 1843200,
.regshift = 2,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{
.iobase = 0x2f8,
.irq = 3,
.uartclk = 1843200,
.regshift = 2,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
},
{ },
};
static struct platform_device serial_device = {
.name = "serial8250",
.id = 0,
.dev = {
.platform_data = serial_platform_data,
},
};
static int __init shark_init(void)
{
int ret;
if (machine_is_shark())
ret = platform_device_register(&serial_device);
return ret;
}
arch_initcall(shark_init);
extern void shark_init_irq(void);
static struct map_desc shark_io_desc[] __initdata = {
......
menu "Versatile platform type"
depends on ARCH_VERSATILE
config ARCH_VERSATILE_PB
bool "Support Versatile/PB platform"
default y
help
Include support for the ARM(R) Versatile/PB platform.
config ARCH_VERSATILE_AB
bool "Support Versatile/AB platform"
default n
help
Include support for the ARM(R) Versatile/AP platform.
endmenu
......@@ -3,3 +3,5 @@
#
obj-y := core.o clock.o
obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o
obj-$(CONFIG_ARCH_VERSATILE_AB) += versatile_ab.o
......@@ -16,7 +16,7 @@
#include <asm/semaphore.h>
#include <asm/hardware/clock.h>
#include <asm/hardware/icst525.h>
#include <asm/hardware/icst307.h>
#include "clock.h"
......@@ -83,12 +83,12 @@ EXPORT_SYMBOL(clk_round_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
int ret = -EIO;
#if 0 // Not yet
if (clk->setvco) {
struct icst525_vco vco;
struct icst307_vco vco;
vco = icst525_khz_to_vco(clk->params, rate / 1000);
clk->rate = icst525_khz(clk->params, vco) * 1000;
vco = icst307_khz_to_vco(clk->params, rate / 1000);
clk->rate = icst307_khz(clk->params, vco) * 1000;
printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
clk->name, vco.s, vco.r, vco.v);
......@@ -96,7 +96,6 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
clk->setvco(clk, vco);
ret = 0;
}
#endif
return ret;
}
EXPORT_SYMBOL(clk_set_rate);
......
......@@ -9,16 +9,16 @@
* published by the Free Software Foundation.
*/
struct module;
struct icst525_params;
struct icst307_params;
struct clk {
struct list_head node;
unsigned long rate;
struct module *owner;
const char *name;
const struct icst525_params *params;
const struct icst307_params *params;
void *data;
void (*setvco)(struct clk *, struct icst525_vco vco);
void (*setvco)(struct clk *, struct icst307_vco vco);
};
int clk_register(struct clk *clk);
......
This diff is collapsed.
/*
* linux/include/asm-arm/arch-integrator/serial.h
* linux/arch/arm/mach-versatile/core.h
*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2004 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
*
* 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
......@@ -17,31 +18,33 @@
* 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_ARCH_SERIAL_H
#define __ASM_ARCH_SERIAL_H
#include <asm/arch/platform.h>
#include <asm/irq.h>
#ifndef __ASM_ARCH_VERSATILE_H
#define __ASM_ARCH_VERSATILE_H
/*
* This assumes you have a 1.8432 MHz clock for your UART.
*
* It'd be nice if someone built a serial card with a 24.576 MHz
* clock, since the 16550A is capable of handling a top speed of 1.5
* megabits/second; but this requires the faster clock.
*/
#define BASE_BAUD (1843200 / 16)
#define _SER_IRQ0 IRQ_UARTINT0
#define _SER_IRQ1 IRQ_UARTINT1
#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
#include <asm/hardware/amba.h>
/* UART CLK PORT IRQ FLAGS */
#define STD_SERIAL_PORT_DEFNS \
{ 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0x2F8, _SER_IRQ1, STD_COM_FLAGS }, /* ttyS1 */
extern void __init versatile_init(void);
extern void __init versatile_init_irq(void);
extern void __init versatile_map_io(void);
extern struct sys_timer versatile_timer;
extern unsigned int mmc_status(struct device *dev);
#define EXTRA_SERIAL_PORT_DEFNS
#define AMBA_DEVICE(name,busid,base,plat) \
static struct amba_device name##_device = { \
.dev = { \
.coherent_dma_mask = ~0, \
.bus_id = busid, \
.platform_data = plat, \
}, \
.res = { \
.start = VERSATILE_##base##_BASE, \
.end = (VERSATILE_##base##_BASE) + SZ_4K - 1,\
.flags = IORESOURCE_MEM, \
}, \
.dma_mask = ~0, \
.irq = base##_IRQ, \
/* .dma = base##_DMA,*/ \
}
#endif
/*
* linux/include/asm-arm/arch-versatile/serial.h
* linux/arch/arm/mach-versatile/versatile_ab.c
*
* Copyright (C) 2003 ARM Limited
* Copyright (C) 2004 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
*
* 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
......@@ -17,21 +18,28 @@
* 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_ARCH_SERIAL_H
#define __ASM_ARCH_SERIAL_H
/*
* This assumes you have a 14.7456 MHz clock UART.
*/
#define BASE_BAUD 115200
#include <linux/config.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware/amba.h>
/* UART CLK PORT IRQ FLAGS */
#define STD_SERIAL_PORT_DEFNS \
{ 0, BASE_BAUD, 0, 0, ASYNC_SKIP_TEST }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0, 0, ASYNC_SKIP_TEST }, /* ttyS1 */ \
{ 0, BASE_BAUD, 0, 0, ASYNC_SKIP_TEST }, /* ttyS2 */ \
{ 0, BASE_BAUD, 0, 0, ASYNC_SKIP_TEST }, /* ttyS3 */
#include <asm/mach/arch.h>
#define EXTRA_SERIAL_PORT_DEFNS
#include "core.h"
#endif
MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
BOOT_PARAMS(0x00000100)
MAPIO(versatile_map_io)
INITIRQ(versatile_init_irq)
.timer = &versatile_timer,
INIT_MACHINE(versatile_init)
MACHINE_END
/*
* linux/arch/arm/mach-versatile/versatile_pb.c
*
* Copyright (C) 2004 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
*
* 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/init.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/hardware/amba.h>
#include <asm/mach/arch.h>
#include <asm/mach/mmc.h>
#include "core.h"
#if 1
#define IRQ_MMCI1A IRQ_VICSOURCE23
#else
#define IRQ_MMCI1A IRQ_SIC_MMCI1A
#endif
static struct mmc_platform_data mmc1_plat_data = {
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
.status = mmc_status,
};
#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ }
#define UART3_DMA { 0x86, 0x87 }
#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ }
#define SCI1_DMA { 0x88, 0x89 }
#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
#define MMCI1_DMA { 0x85, 0 }
/*
* These devices are connected via the core APB bridge
*/
#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
#define GPIO2_DMA { 0, 0 }
#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
#define GPIO3_DMA { 0, 0 }
/*
* These devices are connected via the DMA APB bridge
*/
/* FPGA Primecells */
AMBA_DEVICE(uart3, "fpga:09", UART3, NULL);
AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL);
AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data);
/* DevChip Primecells */
AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL);
AMBA_DEVICE(gpio3, "dev:e7", GPIO3, NULL);
static struct amba_device *amba_devs[] __initdata = {
&uart3_device,
&gpio2_device,
&gpio3_device,
&sci1_device,
&mmc1_device,
};
static int __init versatile_pb_init(void)
{
int i;
if (machine_is_versatile_pb()) {
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
amba_device_register(d, &iomem_resource);
}
}
return 0;
}
arch_initcall(versatile_pb_init);
MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
BOOT_PARAMS(0x00000100)
MAPIO(versatile_map_io)
INITIRQ(versatile_init_irq)
.timer = &versatile_timer,
INIT_MACHINE(versatile_init)
MACHINE_END
......@@ -14,6 +14,7 @@ config CPU_ARM610
depends on ARCH_RPC
select CPU_32v3
select CPU_CACHE_V3
select CPU_CACHE_VIVT
select CPU_COPY_V3
select CPU_TLB_V3
help
......@@ -29,6 +30,7 @@ config CPU_ARM710
default y if ARCH_CLPS7500
select CPU_32v3
select CPU_CACHE_V3
select CPU_CACHE_VIVT
select CPU_COPY_V3
select CPU_TLB_V3
help
......@@ -47,6 +49,7 @@ config CPU_ARM720T
select CPU_32v4
select CPU_ABRT_LV4T
select CPU_CACHE_V4
select CPU_CACHE_VIVT
select CPU_COPY_V4WT
select CPU_TLB_V4WT
help
......@@ -64,6 +67,7 @@ config CPU_ARM920T
select CPU_32v4
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_COPY_V4WB
select CPU_TLB_V4WBI
help
......@@ -84,6 +88,7 @@ config CPU_ARM922T
select CPU_32v4
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_COPY_V4WB
select CPU_TLB_V4WBI
help
......@@ -102,6 +107,7 @@ config CPU_ARM925T
select CPU_32v4
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_COPY_V4WB
select CPU_TLB_V4WBI
help
......@@ -115,10 +121,11 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor" if ARCH_INTEGRATOR
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || ARCH_OMAP730 || ARCH_OMAP1610 || ARCH_OMAP5912
default y if ARCH_VERSATILE_PB
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || ARCH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP1610 || ARCH_OMAP5912
default y if ARCH_VERSATILE_PB || ARCH_VERSATILE_AB
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT
select CPU_COPY_V4WB
select CPU_TLB_V4WBI
help
......@@ -136,6 +143,7 @@ config CPU_ARM1020
select CPU_32v5
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_COPY_V4WB
select CPU_TLB_V4WBI
help
......@@ -152,6 +160,7 @@ config CPU_ARM1020E
select CPU_32v5
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select CPU_COPY_V4WB
select CPU_TLB_V4WBI
depends on n
......@@ -162,6 +171,7 @@ config CPU_ARM1022
depends on ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV4T
select CPU_CACHE_VIVT
select CPU_COPY_V4WB # can probably do better
select CPU_TLB_V4WBI
help
......@@ -178,6 +188,7 @@ config CPU_ARM1026
depends on ARCH_INTEGRATOR
select CPU_32v5
select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
select CPU_CACHE_VIVT
select CPU_COPY_V4WB # can probably do better
select CPU_TLB_V4WBI
help
......@@ -195,6 +206,7 @@ config CPU_SA110
select CPU_32v4 if !ARCH_RPC
select CPU_ABRT_EV4
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_COPY_V4WB
select CPU_TLB_V4WB
help
......@@ -214,6 +226,7 @@ config CPU_SA1100
select CPU_32v4
select CPU_ABRT_EV4
select CPU_CACHE_V4WB
select CPU_CACHE_VIVT
select CPU_TLB_V4WB
select CPU_MINICACHE
......@@ -224,6 +237,7 @@ config CPU_XSCALE
default y
select CPU_32v5
select CPU_ABRT_EV5T
select CPU_CACHE_VIVT
select CPU_TLB_V4WBI
select CPU_MINICACHE
......@@ -234,6 +248,7 @@ config CPU_V6
select CPU_32v6
select CPU_ABRT_EV6
select CPU_CACHE_V6
select CPU_CACHE_VIPT
select CPU_COPY_V6
select CPU_TLB_V6
......@@ -286,6 +301,12 @@ config CPU_CACHE_V4WB
config CPU_CACHE_V6
bool
config CPU_CACHE_VIVT
bool
config CPU_CACHE_VIPT
bool
# The copy-page model
config CPU_COPY_V3
bool
......
......@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
# Last update: Thu Sep 30 15:23:21 2004
# Last update: Sun Nov 7 13:20:41 2004
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
......@@ -595,8 +595,8 @@ pxa_dnp2110 MACH_PXA_DNP2110 PXA_DNP2110 584
xaeniax MACH_XAENIAX XAENIAX 585
somn4250 MACH_SOMN4250 SOMN4250 586
pleb2 MACH_PLEB2 PLEB2 587
cwl MACH_CWL CWL 588
gd MACH_GD GD 589
cornwallis MACH_CORNWALLIS CORNWALLIS 588
gurney_drv MACH_GURNEY_DRV GURNEY_DRV 589
chaffee MACH_CHAFFEE CHAFFEE 590
rms101 MACH_RMS101 RMS101 591
rx3715 MACH_RX3715 RX3715 592
......@@ -615,3 +615,22 @@ ixdpg425 MACH_IXDPG425 IXDPG425 604
tomtomgo MACH_TOMTOMGO TOMTOMGO 605
versatile_ab MACH_VERSATILE_AB VERSATILE_AB 606
edb9307 MACH_EDB9307 EDB9307 607
sg565 MACH_SG565 SG565 608
lpd79524 MACH_LPD79524 LPD79524 609
lpd79525 MACH_LPD79525 LPD79525 610
rms100 MACH_RMS100 RMS100 611
kb9200 MACH_KB9200 KB9200 612
sx1 MACH_SX1 SX1 613
hms39c7092 MACH_HMS39C7092 HMS39C7092 614
armadillo MACH_ARMADILLO ARMADILLO 615
ipcu MACH_IPCU IPCU 616
loox720 MACH_LOOX720 LOOX720 617
ixdp465 MACH_IXDP465 IXDP465 618
ixdp2351 MACH_IXDP2351 IXDP2351 619
adsvix MACH_ADSVIX ADSVIX 620
dm270 MACH_DM270 DM270 621
socltplus MACH_SOCLTPLUS SOCLTPLUS 622
ecia MACH_ECIA ECIA 623
cm4008 MACH_CM4008 CM4008 624
p2001 MACH_P2001 P2001 625
twister MACH_TWISTER TWISTER 626
......@@ -249,6 +249,12 @@ struct vfp_double {
u64 significand;
};
/*
* VFP_REG_ZERO is a special register number for vfp_get_double
* which returns (double)0.0. This is useful for the compare with
* zero instructions.
*/
#define VFP_REG_ZERO 16
extern u64 vfp_get_double(unsigned int reg);
extern void vfp_put_double(unsigned int reg, u64 val);
......
......@@ -427,12 +427,12 @@ static u32 vfp_double_fcmpe(int dd, int unused, int dm, u32 fpscr)
static u32 vfp_double_fcmpz(int dd, int unused, int dm, u32 fpscr)
{
return vfp_compare(dd, 0, -1, fpscr);
return vfp_compare(dd, 0, VFP_REG_ZERO, fpscr);
}
static u32 vfp_double_fcmpez(int dd, int unused, int dm, u32 fpscr)
{
return vfp_compare(dd, 1, -1, fpscr);
return vfp_compare(dd, 1, VFP_REG_ZERO, fpscr);
}
static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr)
......
......@@ -199,6 +199,11 @@ vfp_get_double:
mov pc, lr
.endr
@ virtual register 16 for compare with zero
mov r0, #0
mov r1, #0
mov pc, lr
.globl vfp_put_double
vfp_put_double:
mov r0, r0, lsr #1
......
......@@ -689,7 +689,7 @@ static int __init detect_init_APIC (void)
u32 h, l, features;
extern void get_cpu_vendor(struct cpuinfo_x86*);
/* Disabled by DMI scan or kernel option? */
/* Disabled by kernel option? */
if (enable_local_apic < 0)
return -1;
......@@ -703,8 +703,7 @@ static int __init detect_init_APIC (void)
break;
goto no_apic;
case X86_VENDOR_INTEL:
if (boot_cpu_data.x86 == 6 ||
(boot_cpu_data.x86 == 15 && (cpu_has_apic || enable_local_apic > 0)) ||
if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
(boot_cpu_data.x86 == 5 && cpu_has_apic))
break;
goto no_apic;
......@@ -714,15 +713,20 @@ static int __init detect_init_APIC (void)
if (!cpu_has_apic) {
/*
* Over-ride BIOS and try to enable LAPIC
* only if "lapic" specified
* Over-ride BIOS and try to enable the local
* APIC only if "lapic" specified.
*/
if (enable_local_apic != 1)
goto no_apic;
if (enable_local_apic <= 0) {
apic_printk(APIC_VERBOSE,
"Local APIC disabled by BIOS -- "
"you can enable it with \"lapic\"\n");
return -1;
}
/*
* Some BIOSes disable the local APIC in the
* APIC_BASE MSR. This can only be done in
* software for Intel P6 and AMD K7 (Model > 1).
* software for Intel P6 or later and AMD K7
* (Model > 1) or later.
*/
rdmsr(MSR_IA32_APICBASE, l, h);
if (!(l & MSR_IA32_APICBASE_ENABLE)) {
......
......@@ -42,6 +42,7 @@ static struct pt_regs jprobe_saved_regs;
static long *jprobe_saved_esp;
/* copy of the kernel stack at the probe fire time */
static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
void jprobe_return_end(void);
/*
* returns non-zero if opcode modifies the interrupt flag.
......@@ -58,9 +59,14 @@ static inline int is_IF_modifier(kprobe_opcode_t opcode)
return 0;
}
void arch_prepare_kprobe(struct kprobe *p)
int arch_prepare_kprobe(struct kprobe *p)
{
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
return 0;
}
void arch_remove_kprobe(struct kprobe *p)
{
memcpy(p->insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
}
static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
......@@ -73,7 +79,7 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
regs->eflags |= TF_MASK;
regs->eflags &= ~IF_MASK;
regs->eip = (unsigned long)&p->insn;
regs->eip = (unsigned long)&p->ainsn.insn;
}
/*
......@@ -153,7 +159,7 @@ static inline int kprobe_handler(struct pt_regs *regs)
* instruction. To avoid the SMP problems that can occur when we
* temporarily put back the original opcode to single-step, we
* single-stepped a copy of the instruction. The address of this
* copy is p->insn.
* copy is p->ainsn.insn.
*
* This function prepares to return from the post-single-step
* interrupt. We have to fix up the stack as follows:
......@@ -173,10 +179,10 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
{
unsigned long *tos = (unsigned long *)&regs->esp;
unsigned long next_eip = 0;
unsigned long copy_eip = (unsigned long)&p->insn;
unsigned long copy_eip = (unsigned long)&p->ainsn.insn;
unsigned long orig_eip = (unsigned long)p->addr;
switch (p->insn[0]) {
switch (p->ainsn.insn[0]) {
case 0x9c: /* pushfl */
*tos &= ~(TF_MASK | IF_MASK);
*tos |= kprobe_old_eflags;
......@@ -185,13 +191,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
*tos = orig_eip + (*tos - copy_eip);
break;
case 0xff:
if ((p->insn[1] & 0x30) == 0x10) {
if ((p->ainsn.insn[1] & 0x30) == 0x10) {
/* call absolute, indirect */
/* Fix return addr; eip is correct. */
next_eip = regs->eip;
*tos = orig_eip + (*tos - copy_eip);
} else if (((p->insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */
((p->insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */
} else if (((p->ainsn.insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */
((p->ainsn.insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */
/* eip is correct. */
next_eip = regs->eip;
}
......@@ -315,12 +321,12 @@ void jprobe_return(void)
{
preempt_enable_no_resched();
asm volatile (" xchgl %%ebx,%%esp \n"
" int3 \n"::"b"
" int3 \n"
" .globl jprobe_return_end \n"
" jprobe_return_end: \n"
" nop \n"::"b"
(jprobe_saved_esp):"memory");
}
void jprobe_return_end(void)
{
};
int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
......
......@@ -344,6 +344,36 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if(addr < (long) &dummy->u_debugreg[4] &&
((unsigned long) data) >= TASK_SIZE-3) break;
/* Sanity-check data. Take one half-byte at once with
* check = (val >> (16 + 4*i)) & 0xf. It contains the
* R/Wi and LENi bits; bits 0 and 1 are R/Wi, and bits
* 2 and 3 are LENi. Given a list of invalid values,
* we do mask |= 1 << invalid_value, so that
* (mask >> check) & 1 is a correct test for invalid
* values.
*
* R/Wi contains the type of the breakpoint /
* watchpoint, LENi contains the length of the watched
* data in the watchpoint case.
*
* The invalid values are:
* - LENi == 0x10 (undefined), so mask |= 0x0f00.
* - R/Wi == 0x10 (break on I/O reads or writes), so
* mask |= 0x4444.
* - R/Wi == 0x00 && LENi != 0x00, so we have mask |=
* 0x1110.
*
* Finally, mask = 0x0f00 | 0x4444 | 0x1110 == 0x5f54.
*
* See the Intel Manual "System Programming Guide",
* 15.2.4
*
* Note that LENi == 0x10 is defined on x86_64 in long
* mode (i.e. even for 32-bit userspace software, but
* 64-bit kernel), so the x86_64 mask value is 0x5454.
* See the AMD manual no. 24593 (AMD64 System
* Programming)*/
if(addr == (long) &dummy->u_debugreg[7]) {
data &= ~DR_CONTROL_RESERVED;
for(i=0; i<4; i++)
......
......@@ -583,7 +583,11 @@ void die_nmi (struct pt_regs *regs, const char *msg)
static void default_do_nmi(struct pt_regs * regs)
{
unsigned char reason = get_nmi_reason();
unsigned char reason = 0;
/* Only the BSP gets external NMIs from the system. */
if (!smp_processor_id())
reason = get_nmi_reason();
if (!(reason & 0xc0)) {
if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
......
......@@ -208,7 +208,6 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
*/
__flush_tlb_all();
}
EXPORT_SYMBOL(kernel_map_pages);
#endif
EXPORT_SYMBOL(change_page_attr);
......
......@@ -15,7 +15,7 @@
#include <asm/io.h>
#include <asm/byteorder.h>
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
#include <linux/types.h>
#define M32R_PCC_IOMAP_SIZE 0x1000
......@@ -27,7 +27,7 @@
extern void pcc_ioread(int, unsigned long, void *, size_t, size_t, int);
extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int);
#endif /* CONFIG_PCMCIA && CONFIG_M32RPCC */
#endif /* CONFIG_PCMCIA && CONFIG_M32R_PCC */
#define PORT2ADDR(port) _port2addr(port)
......@@ -80,7 +80,7 @@ unsigned char _inb(unsigned long port)
if (port >= 0x300 && port < 0x320)
return _ne_inb(PORT2ADDR_NE(port));
else
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
unsigned char b;
pcc_ioread(0, port, &b, sizeof(b), 1, 0);
......@@ -100,7 +100,7 @@ unsigned short _inw(unsigned long port)
if (port >= 0x300 && port < 0x320)
return _ne_inw(PORT2ADDR_NE(port));
else
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
unsigned short w;
pcc_ioread(0, port, &w, sizeof(w), 1, 0);
......@@ -116,7 +116,7 @@ unsigned short _inw(unsigned long port)
unsigned long _inl(unsigned long port)
{
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
unsigned long l;
pcc_ioread(0, port, &l, sizeof(l), 1, 0);
......@@ -137,7 +137,7 @@ unsigned char _inb_p(unsigned long port)
if (port >= 0x300 && port < 0x320)
v = _ne_inb(PORT2ADDR_NE(port));
else
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
unsigned char b;
pcc_ioread(0, port, &b, sizeof(b), 1, 0);
......@@ -161,7 +161,7 @@ unsigned short _inw_p(unsigned long port)
if (port >= 0x300 && port < 0x320)
v = _ne_inw(PORT2ADDR_NE(port));
else
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
unsigned short w;
pcc_ioread(0, port, &w, sizeof(w), 1, 0);
......@@ -192,7 +192,7 @@ void _outb(unsigned char b, unsigned long port)
if (port >= 0x300 && port < 0x320)
_ne_outb(b, PORT2ADDR_NE(port));
else
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_iowrite(0, port, &b, sizeof(b), 1, 0);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......@@ -207,7 +207,7 @@ void _outw(unsigned short w, unsigned long port)
if (port >= 0x300 && port < 0x320)
_ne_outw(w, PORT2ADDR_NE(port));
else
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_iowrite(0, port, &w, sizeof(w), 1, 0);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......@@ -219,7 +219,7 @@ void _outw(unsigned short w, unsigned long port)
void _outl(unsigned long l, unsigned long port)
{
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_iowrite(0, port, &l, sizeof(l), 1, 0);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......@@ -234,7 +234,7 @@ void _outb_p(unsigned char b, unsigned long port)
if (port >= 0x300 && port < 0x320)
_ne_outb(b, PORT2ADDR_NE(port));
else
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_iowrite(0, port, &b, sizeof(b), 1, 0);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......@@ -251,7 +251,7 @@ void _outw_p(unsigned short w, unsigned long port)
if (port >= 0x300 && port < 0x320)
_ne_outw(w, PORT2ADDR_NE(port));
else
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_iowrite(0, port, &w, sizeof(w), 1, 0);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......@@ -277,7 +277,7 @@ void _insb(unsigned int port, void * addr, unsigned long count)
if (port >= 0x300 && port < 0x320){
portp = PORT2ADDR_NE(port);
while(count--) *buf++ = *(volatile unsigned char *)portp;
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_ioread(0, port, (void *)addr, sizeof(unsigned char), count, 1);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......@@ -297,7 +297,7 @@ void _insw(unsigned int port, void * addr, unsigned long count)
if (port >= 0x300 && port < 0x320) {
portp = PORT2ADDR_NE(port);
while (count--) *buf++ = _ne_inw(portp);
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_ioread(0, port, (void *)addr, sizeof(unsigned short), count, 1);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......@@ -326,7 +326,7 @@ void _outsb(unsigned int port, const void * addr, unsigned long count)
if (port >= 0x300 && port < 0x320) {
portp = PORT2ADDR_NE(port);
while (count--) _ne_outb(*buf++, portp);
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_iowrite(0, port, (void *)addr, sizeof(unsigned char), count, 1);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......@@ -346,7 +346,7 @@ void _outsw(unsigned int port, const void * addr, unsigned long count)
if (port >= 0x300 && port < 0x320) {
portp = PORT2ADDR_NE(port);
while (count--) _ne_outw(*buf++, portp);
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC)
#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
pcc_iowrite(0, port, (void *)addr, sizeof(unsigned short), count, 1);
} else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
......
......@@ -140,7 +140,7 @@ void __init init_IRQ(void)
disable_mappi_irq(M32R_IRQ_SIO1_S);
#endif /* CONFIG_SERIAL_M32R_SIO */
#if defined(CONFIG_M32RPCC)
#if defined(CONFIG_M32R_PCC)
/* INT1 : pccard0 interrupt */
irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED;
irq_desc[M32R_IRQ_INT1].handler = &mappi_irq_type;
......
......@@ -70,16 +70,18 @@ qword_set_loop:
st r1, @+r4
bnc qword_set_loop || cmpz r2
jc r14
word_set_wrap:
set_remainder:
cmpui r2, #4
bc byte_set
bc byte_set_wrap1
addi r2, #-4
bra word_set_loop
byte_set_wrap:
addi r2, #4
addi r4, #4 || cmpz r2
cmpz r2
jc r14
byte_set_wrap1:
addi r4, #4
#if defined(CONFIG_ISA_M32R2)
byte_set:
addi r2, #-1 || stb r1, @r4+
......@@ -153,18 +155,19 @@ qword_set_loop:
st r1, @+r4
st r1, @+r4
bnc qword_set_loop
bnez r2, word_set_wrap
bnez r2, set_remainder
jmp r14
word_set_wrap:
set_remainder:
cmpui r2, #4
bc byte_set
bc byte_set_wrap1
addi r2, #-4
bra word_set_loop
byte_set_wrap:
addi r2, #4
addi r4, #4
beqz r2, end_memset
byte_set_wrap1:
addi r4, #4
byte_set:
addi r2, #-1
stb r1, @r4
......
......@@ -17,6 +17,7 @@
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
#include <asm/serial.h>
#include <asm/io.h>
#include <asm/time.h>
#if MPC52xx_PF_CONSOLE_PORT == 0
......
......@@ -145,13 +145,13 @@ static void __init ocotea_set_emacdata(void)
}
#define PCIX_READW(offset) \
(readw((u32)pcix_reg_base+offset))
(readw(pcix_reg_base+offset))
#define PCIX_WRITEW(value, offset) \
(writew(value, (u32)pcix_reg_base+offset))
(writew(value, pcix_reg_base+offset))
#define PCIX_WRITEL(value, offset) \
(writel(value, (u32)pcix_reg_base+offset))
(writel(value, pcix_reg_base+offset))
/*
* FIXME: This is only here to "make it work". This will move
......@@ -321,6 +321,11 @@ ocotea_setup_arch(void)
printk("IBM Ocotea port (MontaVista Software, Inc. <source@mvista.com>)\n");
}
static void __init ocotea_init(void)
{
ibm440gx_l2c_setup(&clocks);
}
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
......@@ -342,12 +347,11 @@ void __init platform_init(unsigned long r3, unsigned long r4,
ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
ocp_sys_info.opb_bus_freq = clocks.opb;
/*
* Always disable L2 cache. All revs/speeds of silicon
* have parity error problems despite errata claims to
* the contrary.
/* XXX Fix L2C IRQ triggerring setting (edge-sensitive).
* Firmware (at least PIBS v1.72 OCT/28/2003) sets it incorrectly
* --ebs
*/
ibm440gx_l2c_disable();
mtdcr(DCRN_UIC_TR(UIC2), mfdcr(DCRN_UIC_TR(UIC2)) | 0x00000100);
ibm44x_platform_init();
......@@ -365,4 +369,5 @@ void __init platform_init(unsigned long r3, unsigned long r4,
#ifdef CONFIG_KGDB
ppc_md.early_serial_map = ocotea_early_serial_map;
#endif
ppc_md.init = ocotea_init;
}
......@@ -60,11 +60,6 @@
* of the amount of memory in the system. Once a method of determining
* what version of DINK initializes the system for us, if applicable, is
* found, we can hopefully stop hardcoding 32MB of RAM.
*
* It is important to note that this code only supports the Sandpoint X3
* (all flavors) platform, and it does not support the X2 anymore. Code
* that at one time worked on the X2 can be found at:
* ftp://source.mvista.com/pub/linuxppc/obsolete/sandpoint/
*/
#include <linux/config.h>
......@@ -107,9 +102,13 @@
#include "sandpoint.h"
/* Set non-zero if an X2 Sandpoint detected. */
static int sandpoint_is_x2;
unsigned char __res[sizeof(bd_t)];
static void sandpoint_halt(void);
static void sandpoint_probe_type(void);
/*
* Define all of the IRQ senses and polarities. Taken from the
......@@ -129,7 +128,7 @@ static u_char sandpoint_openpic_initsenses[] __initdata = {
* Motorola SPS Sandpoint interrupt routing.
*/
static inline int
sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
x3_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
{
static char pci_irq_table[][4] =
/*
......@@ -149,6 +148,27 @@ sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
return PCI_IRQ_TABLE_LOOKUP;
}
static inline int
x2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
{
static char pci_irq_table[][4] =
/*
* PCI IDSEL/INTPIN->INTLINE
* A B C D
*/
{
{ 18, 0, 0, 0 }, /* IDSEL 11 - i8259 on Windbond */
{ 0, 0, 0, 0 }, /* IDSEL 12 - unused */
{ 16, 17, 18, 19 }, /* IDSEL 13 - PCI slot 1 */
{ 17, 18, 19, 16 }, /* IDSEL 14 - PCI slot 2 */
{ 18, 19, 16, 17 }, /* IDSEL 15 - PCI slot 3 */
{ 19, 16, 17, 18 }, /* IDSEL 16 - PCI slot 4 */
};
const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4;
return PCI_IRQ_TABLE_LOOKUP;
}
static void __init
sandpoint_setup_winbond_83553(struct pci_controller *hose)
{
......@@ -216,6 +236,18 @@ sandpoint_setup_winbond_83553(struct pci_controller *hose)
return;
}
/* On the sandpoint X2, we must avoid sending configuration cycles to
* device #12 (IDSEL addr = AD12).
*/
static int
x2_exclude_device(u_char bus, u_char devfn)
{
if ((bus == 0) && (PCI_SLOT(devfn) == SANDPOINT_HOST_BRIDGE_IDSEL))
return PCIBIOS_DEVICE_NOT_FOUND;
else
return PCIBIOS_SUCCESSFUL;
}
static void __init
sandpoint_find_bridges(void)
{
......@@ -241,7 +273,11 @@ sandpoint_find_bridges(void)
ppc_md.pcibios_fixup = NULL;
ppc_md.pcibios_fixup_bus = NULL;
ppc_md.pci_swizzle = common_swizzle;
ppc_md.pci_map_irq = sandpoint_map_irq;
if (sandpoint_is_x2) {
ppc_md.pci_map_irq = x2_map_irq;
ppc_md.pci_exclude_device = x2_exclude_device;
} else
ppc_md.pci_map_irq = x3_map_irq;
}
else {
if (ppc_md.progress)
......@@ -255,6 +291,11 @@ sandpoint_find_bridges(void)
static void __init
sandpoint_setup_arch(void)
{
/* Probe for Sandpoint model */
sandpoint_probe_type();
if (sandpoint_is_x2)
epic_serial_mode = 0;
loops_per_jiffy = 100000000 / HZ;
#ifdef CONFIG_BLK_DEV_INITRD
......@@ -318,14 +359,49 @@ sandpoint_setup_arch(void)
SANDPOINT_87308_CFG_OUTB(0x30, 0x01); \
}
/*
* To probe the Sandpoint type, we need to check for a connection between GPIO
* pins 6 and 7 on the NS87308 SuperIO.
*/
static void __init sandpoint_probe_type(void)
{
u8 x;
/* First, ensure that the GPIO pins are enabled. */
SANDPOINT_87308_SELECT_DEV(0x07); /* Select GPIO logical device */
SANDPOINT_87308_CFG_OUTB(0x60, 0x07); /* Base address 0x700 */
SANDPOINT_87308_CFG_OUTB(0x61, 0x00);
SANDPOINT_87308_CFG_OUTB(0x30, 0x01); /* Enable */
/* Now, set pin 7 to output and pin 6 to input. */
outb((inb(0x701) | 0x80) & 0xbf, 0x701);
/* Set push-pull output */
outb(inb(0x702) | 0x80, 0x702);
/* Set pull-up on input */
outb(inb(0x703) | 0x40, 0x703);
/* Set output high and check */
x = inb(0x700);
outb(x | 0x80, 0x700);
x = inb(0x700);
sandpoint_is_x2 = ! (x & 0x40);
if (ppc_md.progress && sandpoint_is_x2)
ppc_md.progress("High output says X2", 0);
/* Set output low and check */
outb(x & 0x7f, 0x700);
sandpoint_is_x2 |= inb(0x700) & 0x40;
if (ppc_md.progress && sandpoint_is_x2)
ppc_md.progress("Low output says X2", 0);
if (ppc_md.progress && ! sandpoint_is_x2)
ppc_md.progress("Sandpoint is X3", 0);
}
/*
* Fix IDE interrupts.
*/
static int __init
sandpoint_fix_winbond_83553(void)
{
/* Make all 8259 interrupt level sensitive */
outb(0xf8, 0x4d0);
/* Make some 8259 interrupt level sensitive */
outb(0xe0, 0x4d0);
outb(0xde, 0x4d1);
return 0;
......@@ -398,7 +474,7 @@ sandpoint_init_IRQ(void)
OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses);
mpc10x_set_openpic();
openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
openpic_hookup_cascade(sandpoint_is_x2 ? 17 : NUM_8259_INTERRUPTS, "82c59 cascade",
i8259_irq);
/*
......
......@@ -4,7 +4,7 @@
* PPC440GX system library
*
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
* Copyright (c) 2003 Zultys Technologies
* Copyright (c) 2003, 2004 Zultys Technologies
*
* 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
......@@ -14,6 +14,7 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <asm/ibm44x.h>
#include <asm/mmu.h>
#include <asm/processor.h>
......@@ -97,10 +98,51 @@ void __init ibm440gx_get_clocks(struct ibm44x_clocks* p, unsigned int sys_clk,
p->uart1 = p->plb / __fix_zero(uart1 & 0xff, 256);
}
/* Enable L2 cache (call with IRQs disabled) */
/* Issue L2C diagnostic command */
static inline u32 l2c_diag(u32 addr)
{
mtdcr(DCRN_L2C0_ADDR, addr);
mtdcr(DCRN_L2C0_CMD, L2C_CMD_DIAG);
while (!(mfdcr(DCRN_L2C0_SR) & L2C_SR_CC)) ;
return mfdcr(DCRN_L2C0_DATA);
}
static irqreturn_t l2c_error_handler(int irq, void* dev, struct pt_regs* regs)
{
u32 sr = mfdcr(DCRN_L2C0_SR);
if (sr & L2C_SR_CPE){
/* Read cache trapped address */
u32 addr = l2c_diag(0x42000000);
printk(KERN_EMERG "L2C: Cache Parity Error, addr[16:26] = 0x%08x\n", addr);
}
if (sr & L2C_SR_TPE){
/* Read tag trapped address */
u32 addr = l2c_diag(0x82000000) >> 16;
printk(KERN_EMERG "L2C: Tag Parity Error, addr[16:26] = 0x%08x\n", addr);
}
/* Clear parity errors */
if (sr & (L2C_SR_CPE | L2C_SR_TPE)){
mtdcr(DCRN_L2C0_ADDR, 0);
mtdcr(DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE);
} else
printk(KERN_EMERG "L2C: LRU error\n");
return IRQ_HANDLED;
}
/* Enable L2 cache */
void __init ibm440gx_l2c_enable(void){
u32 r;
unsigned long flags;
/* Install error handler */
if (request_irq(87, l2c_error_handler, SA_INTERRUPT, "L2C", 0) < 0){
printk(KERN_ERR "Cannot install L2C error handler, cache is not enabled\n");
return;
}
local_irq_save(flags);
asm volatile ("sync" ::: "memory");
/* Disable SRAM */
......@@ -137,20 +179,22 @@ void __init ibm440gx_l2c_enable(void){
/* Enable ICU/DCU ports */
r = mfdcr(DCRN_L2C0_CFG);
r &= ~(L2C_CFG_DCW_MASK | L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM
| L2C_CFG_PMUX_MASK | L2C_CFG_PMIM | L2C_CFG_TPEI | L2C_CFG_CPEI
| L2C_CFG_NAM | L2C_CFG_NBRM);
r &= ~(L2C_CFG_DCW_MASK | L2C_CFG_PMUX_MASK | L2C_CFG_PMIM | L2C_CFG_TPEI
| L2C_CFG_CPEI | L2C_CFG_NAM | L2C_CFG_NBRM);
r |= L2C_CFG_ICU | L2C_CFG_DCU | L2C_CFG_TPC | L2C_CFG_CPC | L2C_CFG_FRAN
| L2C_CFG_SMCM;
| L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM | L2C_CFG_SMCM;
mtdcr(DCRN_L2C0_CFG, r);
asm volatile ("sync; isync" ::: "memory");
local_irq_restore(flags);
}
/* Disable L2 cache (call with IRQs disabled) */
/* Disable L2 cache */
void __init ibm440gx_l2c_disable(void){
u32 r;
unsigned long flags;
local_irq_save(flags);
asm volatile ("sync" ::: "memory");
/* Disable L2C mode */
......@@ -169,6 +213,7 @@ void __init ibm440gx_l2c_disable(void){
SRAM_SBCR_BAS3 | SRAM_SBCR_BS_64KB | SRAM_SBCR_BU_RW);
asm volatile ("sync; isync" ::: "memory");
local_irq_restore(flags);
}
void __init ibm440gx_l2c_setup(struct ibm44x_clocks* p)
......
......@@ -43,7 +43,7 @@
#ifdef CONFIG_MPC10X_OPENPIC
#ifdef CONFIG_EPIC_SERIAL_MODE
#define EPIC_IRQ_BASE 16
#define EPIC_IRQ_BASE (epic_serial_mode ? 16 : 5)
#else
#define EPIC_IRQ_BASE 5
#endif
......@@ -69,20 +69,16 @@ static struct ocp_def mpc10x_i2c_ocp = {
.vendor = OCP_VENDOR_MOTOROLA,
.function = OCP_FUNC_IIC,
.index = 0,
.irq = MPC10X_I2C_IRQ,
.additions = &mpc10x_i2c_data
};
static struct ocp_def mpc10x_dma_ocp[2] = {
{ .vendor = OCP_VENDOR_MOTOROLA,
.function = OCP_FUNC_DMA,
.index = 0,
.irq = MPC10X_DMA0_IRQ
},
.index = 0 },
{ .vendor = OCP_VENDOR_MOTOROLA,
.function = OCP_FUNC_DMA,
.index = 1,
.irq = MPC10X_DMA1_IRQ }
.index = 1 }
};
/* Set resources to match bridge memory map */
......@@ -292,12 +288,15 @@ mpc10x_bridge_init(struct pci_controller *hose,
MPC10X_EUMB_EPIC_SIZE);
#endif
mpc10x_i2c_ocp.paddr = phys_eumb_base + MPC10X_EUMB_I2C_OFFSET;
mpc10x_i2c_ocp.irq = MPC10X_I2C_IRQ;
ocp_add_one_device(&mpc10x_i2c_ocp);
mpc10x_dma_ocp[0].paddr = phys_eumb_base +
MPC10X_EUMB_DMA_OFFSET + 0x100;
mpc10x_dma_ocp[0].irq = MPC10X_DMA0_IRQ;
ocp_add_one_device(&mpc10x_dma_ocp[0]);
mpc10x_dma_ocp[1].paddr = phys_eumb_base +
MPC10X_EUMB_DMA_OFFSET + 0x200;
mpc10x_dma_ocp[1].irq = MPC10X_DMA1_IRQ;
ocp_add_one_device(&mpc10x_dma_ocp[1]);
}
......
......@@ -19,6 +19,7 @@
#include <linux/config.h>
#include <asm/io.h>
#include <asm/time.h>
#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>
......
......@@ -261,6 +261,9 @@ static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int
#endif /* CONFIG_SMP */
#ifdef CONFIG_EPIC_SERIAL_MODE
/* On platforms that may use EPIC serial mode, the default is enabled. */
int epic_serial_mode = 1;
static void __init openpic_eicr_set_clk(u_int clkval)
{
openpic_writefield(&OpenPIC->Global.Global_Configuration1,
......@@ -415,8 +418,10 @@ void __init openpic_init(int offset)
openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
openpic_disable_8259_pass_through();
#ifdef CONFIG_EPIC_SERIAL_MODE
openpic_eicr_set_clk(7); /* Slowest value until we know better */
openpic_enable_sie();
if (epic_serial_mode) {
openpic_eicr_set_clk(7); /* Slowest value until we know better */
openpic_enable_sie();
}
#endif
openpic_set_priority(0);
......
......@@ -18,6 +18,7 @@
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/bcd.h>
#include <linux/mc146818rtc.h>
#include <asm/machdep.h>
#include <asm/io.h>
......@@ -48,8 +49,6 @@
* --MAG
*/
extern spinlock_t rtc_lock;
/*
* 'todc_info' should be initialized in your *_setup.c file to
* point to a fully initialized 'todc_info_t' structure.
......
......@@ -25,30 +25,14 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/ppcdebug.h>
#include <linux/list.h>
#include <asm/iSeries/HvCallXm.h>
#include <asm/iSeries/LparData.h>
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/iSeries/iSeries_pci.h>
#include <asm/machdep.h>
#include "pci.h"
#include <asm/iSeries/HvCallXm.h>
#include <asm/iSeries/iSeries_pci.h>
extern struct list_head iSeries_Global_Device_List;
......@@ -76,12 +60,11 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
tce.te_bits.tb_pciwr = 1;
}
rc = HvCallXm_setTce((u64)tbl->it_index,
(u64)index,
tce.te_word);
rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index,
tce.te_word);
if (rc)
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc);
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
rc);
index++;
uaddr += PAGE_SIZE;
}
......@@ -90,20 +73,14 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
{
u64 rc;
union tce_entry tce;
while (npages--) {
tce.te_word = 0;
rc = HvCallXm_setTce((u64)tbl->it_index,
(u64)index,
tce.te_word);
rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);
if (rc)
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc);
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
rc);
index++;
}
}
......@@ -115,17 +92,14 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
{
struct iSeries_Device_Node *dp;
for (dp = (struct iSeries_Device_Node *)iSeries_Global_Device_List.next;
dp != (struct iSeries_Device_Node *)&iSeries_Global_Device_List;
dp = (struct iSeries_Device_Node *)dp->Device_List.next)
if (dp->iommu_table != NULL &&
dp->iommu_table->it_type == TCE_PCI &&
dp->iommu_table->it_offset == tbl->it_offset &&
dp->iommu_table->it_index == tbl->it_index &&
dp->iommu_table->it_size == tbl->it_size)
list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) {
if ((dp->iommu_table != NULL) &&
(dp->iommu_table->it_type == TCE_PCI) &&
(dp->iommu_table->it_offset == tbl->it_offset) &&
(dp->iommu_table->it_index == tbl->it_index) &&
(dp->iommu_table->it_size == tbl->it_size))
return dp->iommu_table;
}
return NULL;
}
......@@ -143,15 +117,14 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
{
struct iommu_table_cb *parms;
parms = (struct iommu_table_cb*)kmalloc(sizeof(*parms), GFP_KERNEL);
parms = kmalloc(sizeof(*parms), GFP_KERNEL);
if (parms == NULL)
panic("PCI_DMA: TCE Table Allocation failed.");
memset(parms, 0, sizeof(*parms));
parms->itc_busno = ISERIES_BUS(dn);
parms->itc_slotno = dn->LogicalSlot;
parms->itc_busno = ISERIES_BUS(dn);
parms->itc_slotno = dn->LogicalSlot;
parms->itc_virtbus = 0;
HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms));
......@@ -159,34 +132,32 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
if (parms->itc_size == 0)
panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
tbl->it_size = parms->itc_size;
tbl->it_busno = parms->itc_busno;
tbl->it_offset = parms->itc_offset;
tbl->it_index = parms->itc_index;
tbl->it_entrysize = sizeof(union tce_entry);
tbl->it_blocksize = 1;
tbl->it_type = TCE_PCI;
tbl->it_size = parms->itc_size;
tbl->it_busno = parms->itc_busno;
tbl->it_offset = parms->itc_offset;
tbl->it_index = parms->itc_index;
tbl->it_entrysize = sizeof(union tce_entry);
tbl->it_blocksize = 1;
tbl->it_type = TCE_PCI;
kfree(parms);
}
void iommu_devnode_init(struct iSeries_Device_Node *dn) {
void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn)
{
struct iommu_table *tbl;
tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
iommu_table_getparms(dn, tbl);
/* Look for existing tce table */
dn->iommu_table = iommu_table_find(tbl);
if (dn->iommu_table == NULL)
dn->iommu_table = iommu_init_table(tbl);
else
kfree(tbl);
return;
}
......
......@@ -312,8 +312,7 @@ void __init iSeries_pci_final_fixup(void)
mf_displaySrc(0xC9000100);
printk("pcibios_final_fixup\n");
while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))
!= NULL) {
for_each_pci_dev(pdev) {
node = find_Device_Node(pdev->bus->number, pdev->devfn);
printk("pci dev %p (%x.%x), node %p\n", pdev,
pdev->bus->number, pdev->devfn, node);
......@@ -329,7 +328,7 @@ void __init iSeries_pci_final_fixup(void)
iSeries_Device_Information(pdev, Buffer,
sizeof(Buffer));
printk("%d. %s\n", DeviceCount, Buffer);
iommu_devnode_init(node);
iommu_devnode_init_iSeries(node);
} else
printk("PCI: Device Tree not found for 0x%016lX\n",
(unsigned long)pdev);
......
......@@ -425,6 +425,39 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)
return tbl;
}
void iommu_free_table(struct device_node *dn)
{
struct iommu_table *tbl = dn->iommu_table;
unsigned long bitmap_sz, i;
unsigned int order;
if (!tbl || !tbl->it_map) {
printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
dn->full_name);
return;
}
/* verify that table contains no entries */
/* it_mapsize is in entries, and we're examining 64 at a time */
for (i = 0; i < (tbl->it_mapsize/64); i++) {
if (tbl->it_map[i] != 0) {
printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
__FUNCTION__, dn->full_name);
break;
}
}
/* calculate bitmap size in bytes */
bitmap_sz = (tbl->it_mapsize + 7) / 8;
/* free bitmap */
order = get_order(bitmap_sz);
free_pages((unsigned long) tbl->it_map, order);
/* free table */
kfree(tbl);
}
/* Creates TCEs for a user provided buffer. The user buffer must be
* contiguous real kernel storage (not vmalloc). The address of the buffer
* passed here is the kernel (virtual) address of the buffer. The buffer
......
......@@ -276,7 +276,7 @@ static void iommu_buses_init(void)
first_phb = 0;
for (dn = first_dn; dn != NULL; dn = dn->sibling)
iommu_devnode_init(dn);
iommu_devnode_init_pSeries(dn);
}
}
......@@ -298,7 +298,7 @@ static void iommu_buses_init_lpar(struct list_head *bus_list)
* Do it now because iommu_table_setparms_lpar needs it.
*/
busdn->bussubno = bus->number;
iommu_devnode_init(busdn);
iommu_devnode_init_pSeries(busdn);
}
/* look for a window on a bridge even if the PHB had one */
......@@ -397,7 +397,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
}
void iommu_devnode_init(struct device_node *dn)
void iommu_devnode_init_pSeries(struct device_node *dn)
{
struct iommu_table *tbl;
......@@ -412,39 +412,6 @@ void iommu_devnode_init(struct device_node *dn)
dn->iommu_table = iommu_init_table(tbl);
}
void iommu_free_table(struct device_node *dn)
{
struct iommu_table *tbl = dn->iommu_table;
unsigned long bitmap_sz, i;
unsigned int order;
if (!tbl || !tbl->it_map) {
printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
dn->full_name);
return;
}
/* verify that table contains no entries */
/* it_mapsize is in entries, and we're examining 64 at a time */
for (i = 0; i < (tbl->it_mapsize/64); i++) {
if (tbl->it_map[i] != 0) {
printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
__FUNCTION__, dn->full_name);
break;
}
}
/* calculate bitmap size in bytes */
bitmap_sz = (tbl->it_mapsize + 7) / 8;
/* free bitmap */
order = get_order(bitmap_sz);
free_pages((unsigned long) tbl->it_map, order);
/* free table */
kfree(tbl);
}
void iommu_setup_pSeries(void)
{
struct pci_dev *dev = NULL;
......@@ -459,7 +426,7 @@ void iommu_setup_pSeries(void)
* pci device_node. This means get_iommu_table() won't need to search
* up the device tree to find it.
*/
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
for_each_pci_dev(dev) {
mydn = dn = PCI_GET_DN(dev);
while (dn && dn->iommu_table == NULL)
......@@ -469,7 +436,6 @@ void iommu_setup_pSeries(void)
}
}
/* These are called very early. */
void tce_init_pSeries(void)
{
......
......@@ -548,7 +548,7 @@ void __init pSeries_final_fixup(void)
check_s7a();
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
for_each_pci_dev(dev) {
pci_read_irq_line(dev);
if (s7a_workaround) {
if (dev->irq > 16) {
......
......@@ -663,7 +663,7 @@ void __init pmac_pcibios_fixup(void)
{
struct pci_dev *dev = NULL;
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
for_each_pci_dev(dev)
pci_read_irq_line(dev);
pci_fix_bus_sysdata();
......
......@@ -1740,7 +1740,7 @@ static int of_finish_dynamic_node(struct device_node *node)
if (strcmp(node->name, "pci") == 0 &&
get_property(node, "ibm,dma-window", NULL)) {
node->bussubno = node->busno;
iommu_devnode_init(node);
iommu_devnode_init_pSeries(node);
} else
node->iommu_table = parent->iommu_table;
#endif /* CONFIG_PPC_PSERIES */
......@@ -1801,6 +1801,15 @@ int of_add_node(const char *path, struct property *proplist)
return 0;
}
/*
* Prepare an OF node for removal from system
*/
static void of_cleanup_node(struct device_node *np)
{
if (np->iommu_table && get_property(np, "ibm,dma-window", NULL))
iommu_free_table(np);
}
/*
* Remove an OF device node from the system.
* Caller should have already "gotten" np.
......@@ -1818,13 +1827,7 @@ int of_remove_node(struct device_node *np)
return -EBUSY;
}
/* XXX This is a layering violation, should be moved to the caller
* --BenH.
*/
#ifdef CONFIG_PPC_PSERIES
if (np->iommu_table)
iommu_free_table(np);
#endif /* CONFIG_PPC_PSERIES */
of_cleanup_node(np);
write_lock(&devtree_lock);
OF_MARK_STALE(np);
......
......@@ -291,7 +291,7 @@ void iommu_setup_u3(void)
/* We only have one iommu table on the mac for now, which makes
* things simple. Setup all PCI devices to point to this table
*/
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
for_each_pci_dev(dev) {
/* We must use pci_device_to_OF_node() to make sure that
* we get the real "final" pointer to the device in the
* pci_dev sysdata and not the temporary PHB one
......
......@@ -521,24 +521,7 @@ static struct iommu_table * vio_build_iommu_table(struct vio_dev *dev)
newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
/* RPA docs say that #address-cells is always 1 for virtual
devices, but some older boxes' OF returns 2. This should
be removed by GA, unless there is legacy OFs that still
have 2 for #address-cells */
size = ((dma_window[1+vio_num_address_cells] >> PAGE_SHIFT) << 3)
>> PAGE_SHIFT;
/* This is just an ugly kludge. Remove as soon as the OF for all
machines actually follow the spec and encodes the offset field
as phys-encode (that is, #address-cells wide)*/
if (dma_window_property_size == 12) {
size = ((dma_window[1] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
} else if (dma_window_property_size == 20) {
size = ((dma_window[4] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
} else {
printk(KERN_WARNING "vio_build_iommu_table: Invalid size of ibm,my-dma-window=%i, using 0x80 for size\n", dma_window_property_size);
size = 0x80;
}
size = ((dma_window[4] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
/* There should be some code to extract the phys-encoded offset
using prom_n_addr_cells(). However, according to a comment
......
......@@ -112,11 +112,16 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root)
oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
&sys.backtrace_spinlocks);
/* Default to tracing both kernel and user */
sys.enable_kernel = 1;
sys.enable_user = 1;
/* Turn on backtracing through spinlocks by default */
sys.backtrace_spinlocks = 1;
return 0;
}
......
......@@ -71,6 +71,7 @@ struct op_system_config {
unsigned long mmcra;
unsigned long enable_kernel;
unsigned long enable_user;
unsigned long backtrace_spinlocks;
};
/* Per-arch configuration */
......
......@@ -32,6 +32,13 @@ static u32 mmcr0_val;
static u64 mmcr1_val;
static u32 mmcra_val;
/*
* Since we do not have an NMI, backtracing through spinlocks is
* only a best guess. In light of this, allow it to be disabled at
* runtime.
*/
static int backtrace_spinlocks;
static void power4_reg_setup(struct op_counter_config *ctr,
struct op_system_config *sys,
int num_ctrs)
......@@ -59,6 +66,8 @@ static void power4_reg_setup(struct op_counter_config *ctr,
mmcr1_val = sys->mmcr1;
mmcra_val = sys->mmcra;
backtrace_spinlocks = sys->backtrace_spinlocks;
for (i = 0; i < num_counters; ++i)
reset_value[i] = 0x80000000UL - ctr[i].count;
......@@ -170,19 +179,38 @@ static void __attribute_used__ kernel_unknown_bucket(void)
{
}
static unsigned long check_spinlock_pc(struct pt_regs *regs,
unsigned long profile_pc)
{
unsigned long pc = instruction_pointer(regs);
/*
* If both the SIAR (sampled instruction) and the perfmon exception
* occurred in a spinlock region then we account the sample to the
* calling function. This isnt 100% correct, we really need soft
* IRQ disable so we always get the perfmon exception at the
* point at which the SIAR is set.
*/
if (backtrace_spinlocks && in_lock_functions(pc) &&
in_lock_functions(profile_pc))
return regs->link;
else
return profile_pc;
}
/*
* On GQ and newer the MMCRA stores the HV and PR bits at the time
* the SIAR was sampled. We use that to work out if the SIAR was sampled in
* the hypervisor, our exception vectors or RTAS.
*/
static unsigned long get_pc(void)
static unsigned long get_pc(struct pt_regs *regs)
{
unsigned long pc = mfspr(SPRN_SIAR);
unsigned long mmcra;
/* Cant do much about it */
if (!mmcra_has_sihv)
return pc;
return check_spinlock_pc(regs, pc);
mmcra = mfspr(SPRN_MMCRA);
......@@ -196,10 +224,6 @@ static unsigned long get_pc(void)
if (mmcra & MMCRA_SIPR)
return pc;
/* Were we in our exception vectors? */
if (pc < 0x4000UL)
return (unsigned long)__va(pc);
#ifdef CONFIG_PPC_PSERIES
/* Were we in RTAS? */
if (pc >= rtas.base && pc < (rtas.base + rtas.size))
......@@ -207,12 +231,16 @@ static unsigned long get_pc(void)
return *((unsigned long *)rtas_bucket);
#endif
/* Were we in our exception vectors or SLB real mode miss handler? */
if (pc < 0x1000000UL)
return (unsigned long)__va(pc);
/* Not sure where we were */
if (pc < KERNELBASE)
/* function descriptor madness */
return *((unsigned long *)kernel_unknown_bucket);
return pc;
return check_spinlock_pc(regs, pc);
}
static int get_kernel(unsigned long pc)
......@@ -239,7 +267,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,
unsigned int cpu = smp_processor_id();
unsigned int mmcr0;
pc = get_pc();
pc = get_pc(regs);
is_kernel = get_kernel(pc);
/* set the PMM bit (see comment below) */
......
......@@ -75,7 +75,7 @@ sys_call_table:
/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
/*280*/ .long sys_setaltroot, sys_add_key, sys_request_key, sys_keyctl
/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl
#ifdef CONFIG_SUNOS_EMUL
/* Now the SunOS syscall table. */
......
......@@ -5,7 +5,8 @@
ARCH_DIR = arch/um
OS := $(shell uname -s)
#We require it or things break.
# We require bash because the vmlinux link and loader script cpp use bash
# features.
SHELL := /bin/bash
filechk_gen_header = $<
......@@ -62,16 +63,18 @@ ifeq ($(CONFIG_MODE_SKAS), y)
$(SYS_HEADERS) : $(ARCH_DIR)/include/skas_ptregs.h
endif
.PHONY: linux
all: linux
linux: vmlinux
$(RM) $@
ln $< $@
ln -f $< $@
define archhelp
echo '* linux - Binary kernel image (./linux) - for backward'
echo ' compatibility only: now you can simply run'
echo ' the vmlinux binary you find in the kernel root.'
echo ' compatibility only, this creates a hard link to the'
echo ' real kernel binary, the the "vmlinux" binary you'
echo ' find in the kernel root.'
endef
prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \
......@@ -117,7 +120,8 @@ define cmd_vmlinux__
-Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
-Wl,--start-group $(vmlinux-main) -Wl,--end-group \
-L/usr/lib -lutil \
$(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
$(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \
FORCE ,$^) ; rm -f linux
endef
USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
......
......@@ -27,14 +27,26 @@ int generic_console_write(int fd, const char *buf, int n, void *unused)
int err;
if(isatty(fd)){
tcgetattr(fd, &save);
CATCH_EINTR(err = tcgetattr(fd, &save));
if (err)
goto error;
new = save;
/* The terminal becomes a bit less raw, to handle \n also as
* "Carriage Return", not only as "New Line". Otherwise, the new
* line won't start at the first column.*/
new.c_oflag |= OPOST;
tcsetattr(fd, TCSAFLUSH, &new);
CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &new));
if (err)
goto error;
}
err = generic_write(fd, buf, n, NULL);
if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save);
/* Restore raw mode, in any case; we *must* ignore any error apart
* EINTR, except for debug.*/
if(isatty(fd))
CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save));
return(err);
error:
return(-errno);
}
static void winch_handler(int sig)
......
......@@ -119,12 +119,98 @@ void mconsole_log(struct mc_request *req)
mconsole_reply(req, "", 0, 0);
}
/* This is a more convoluted version of mconsole_proc, which has some stability
* problems; however, we need it fixed, because it is expected that UML users
* mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
* show the real procfs content, not the ones from hppfs.*/
#if 0
void mconsole_proc(struct mc_request *req)
{
struct nameidata nd;
struct file_system_type *proc;
struct super_block *super;
struct file *file;
int n, err;
char *ptr = req->request.data, *buf;
ptr += strlen("proc");
while(isspace(*ptr)) ptr++;
proc = get_fs_type("proc");
if(proc == NULL){
mconsole_reply(req, "procfs not registered", 1, 0);
goto out;
}
super = (*proc->get_sb)(proc, 0, NULL, NULL);
put_filesystem(proc);
if(super == NULL){
mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
goto out;
}
up_write(&super->s_umount);
nd.dentry = super->s_root;
nd.mnt = NULL;
nd.flags = O_RDONLY + 1;
nd.last_type = LAST_ROOT;
/* START: it was experienced that the stability problems are closed
* if commenting out these two calls + the below read cycle. To
* make UML crash again, it was enough to readd either one.*/
err = link_path_walk(ptr, &nd);
if(err){
mconsole_reply(req, "Failed to look up file", 1, 0);
goto out_kill;
}
file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
if(IS_ERR(file)){
mconsole_reply(req, "Failed to open file", 1, 0);
goto out_kill;
}
/*END*/
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
if(buf == NULL){
mconsole_reply(req, "Failed to allocate buffer", 1, 0);
goto out_fput;
}
if((file->f_op != NULL) && (file->f_op->read != NULL)){
do {
n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
&file->f_pos);
if(n >= 0){
buf[n] = '\0';
mconsole_reply(req, buf, 0, (n > 0));
}
else {
mconsole_reply(req, "Read of file failed",
1, 0);
goto out_free;
}
} while(n > 0);
}
else mconsole_reply(req, "", 0, 0);
out_free:
kfree(buf);
out_fput:
fput(file);
out_kill:
deactivate_super(super);
out: ;
}
#endif
void mconsole_proc(struct mc_request *req)
{
char path[64];
char *buf;
int len;
int fd;
int first_chunk = 1;
char *ptr = req->request.data;
ptr += strlen("proc");
......@@ -149,7 +235,13 @@ void mconsole_proc(struct mc_request *req)
if (len < 0) {
mconsole_reply(req, "Read of file failed", 1, 0);
goto out_free;
} else if (len == PAGE_SIZE-1) {
}
/*Begin the file content on his own line.*/
if (first_chunk) {
mconsole_reply(req, "\n", 0, 1);
first_chunk = 0;
}
if (len == PAGE_SIZE-1) {
buf[len] = '\0';
mconsole_reply(req, buf, 0, 1);
} else {
......
......@@ -123,12 +123,18 @@ struct chan_ops port_ops = {
int port_listen_fd(int port)
{
struct sockaddr_in addr;
int fd, err;
int fd, err, arg;
fd = socket(PF_INET, SOCK_STREAM, 0);
if(fd == -1)
return(-errno);
arg = 1;
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){
err = -errno;
goto out;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
......
......@@ -67,6 +67,7 @@ extern void map_memory(unsigned long virt, unsigned long phys,
extern int protect_memory(unsigned long addr, unsigned long len,
int r, int w, int x, int must_succeed);
extern unsigned long get_kmem_end(void);
extern void check_tmpexec(void);
#endif
......
......@@ -9,11 +9,11 @@
#include "uml-config.h"
#ifdef UML_CONFIG_MODE_TT
#include "../kernel/tt/include/mode.h"
#include "mode-tt.h"
#endif
#ifdef UML_CONFIG_MODE_SKAS
#include "../kernel/skas/include/mode.h"
#include "mode-skas.h"
#endif
#endif
......
......@@ -9,11 +9,11 @@
#include "linux/config.h"
#ifdef CONFIG_MODE_TT
#include "../kernel/tt/include/mode_kern.h"
#include "mode_kern-tt.h"
#endif
#ifdef CONFIG_MODE_SKAS
#include "../kernel/skas/include/mode_kern.h"
#include "mode_kern-skas.h"
#endif
#endif
......
......@@ -157,6 +157,7 @@ extern unsigned long os_process_pc(int pid);
extern int os_process_parent(int pid);
extern void os_stop_process(int pid);
extern void os_kill_process(int pid, int reap_child);
extern void os_kill_ptraced_process(int pid, int reap_child);
extern void os_usr1_process(int pid);
extern int os_getpid(void);
......
......@@ -15,4 +15,15 @@ extern void arch_enter_kernel(void *task, int pid);
extern void arch_leave_kernel(void *task, int pid);
extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
/* syscall emulation path in ptrace */
#ifndef PTRACE_SYSEMU
#define PTRACE_SYSEMU 31
#endif
void set_using_sysemu(int value);
int get_using_sysemu(void);
extern int sysemu_supported;
#endif
......@@ -10,11 +10,11 @@
#include "choose-mode.h"
#ifdef CONFIG_MODE_TT
#include "../kernel/tt/include/mmu.h"
#include "mmu-tt.h"
#endif
#ifdef CONFIG_MODE_SKAS
#include "../kernel/skas/include/mmu.h"
#include "mmu-skas.h"
#endif
typedef union {
......
......@@ -10,11 +10,11 @@
#include "choose-mode.h"
#ifdef CONFIG_MODE_TT
#include "../kernel/tt/include/uaccess.h"
#include "uaccess-tt.h"
#endif
#ifdef CONFIG_MODE_SKAS
#include "../kernel/skas/include/uaccess.h"
#include "uaccess-skas.h"
#endif
#define access_ok(type, addr, size) \
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment