提交 0526484a 编写于 作者: B Benjamin Herrenschmidt

Merge commit 'origin/master' into next

What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
Date: August 2008
KernelVersion: 2.6.27
Contact: mark.langsdorf@amd.com
Description: These files exist in every cpu's cache index directories.
There are currently 2 cache_disable_# files in each
directory. Reading from these files on a supported
processor will return that cache disable index value
for that processor and node. Writing to one of these
files will cause the specificed cache index to be disabled.
Currently, only AMD Family 10h Processors support cache index
disable, and only for their L3 caches. See the BIOS and
Kernel Developer's Guide at
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
for formatting information and other details on the
cache index disable.
Users: joachim.deguara@amd.com
What: /sys/devices/system/cpu/
Date: pre-git history
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description:
A collection of both global and individual CPU attributes
Individual CPU attributes are contained in subdirectories
named by the kernel's logical CPU number, e.g.:
/sys/devices/system/cpu/cpu#/
What: /sys/devices/system/cpu/sched_mc_power_savings
/sys/devices/system/cpu/sched_smt_power_savings
Date: June 2006
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: Discover and adjust the kernel's multi-core scheduler support.
Possible values are:
0 - No power saving load balance (default value)
1 - Fill one thread/core/package first for long running threads
2 - Also bias task wakeups to semi-idle cpu package for power
savings
sched_mc_power_savings is dependent upon SCHED_MC, which is
itself architecture dependent.
sched_smt_power_savings is dependent upon SCHED_SMT, which
is itself architecture dependent.
The two files are independent of each other. It is possible
that one file may be present without the other.
Introduced by git commit 5c45bf27.
What: /sys/devices/system/cpu/kernel_max
/sys/devices/system/cpu/offline
/sys/devices/system/cpu/online
/sys/devices/system/cpu/possible
/sys/devices/system/cpu/present
Date: December 2008
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: CPU topology files that describe kernel limits related to
hotplug. Briefly:
kernel_max: the maximum cpu index allowed by the kernel
configuration.
offline: cpus that are not online because they have been
HOTPLUGGED off or exceed the limit of cpus allowed by the
kernel configuration (kernel_max above).
online: cpus that are online and being scheduled.
possible: cpus that have been allocated resources and can be
brought online if they are present.
present: cpus that have been identified as being present in
the system.
See Documentation/cputopology.txt for more information.
What: /sys/devices/system/cpu/cpu#/node
Date: October 2009
Contact: Linux memory management mailing list <linux-mm@kvack.org>
Description: Discover NUMA node a CPU belongs to
When CONFIG_NUMA is enabled, a symbolic link that points
to the corresponding NUMA node directory.
For example, the following symlink is created for cpu42
in NUMA node 2:
/sys/devices/system/cpu/cpu42/node2 -> ../../node/node2
What: /sys/devices/system/cpu/cpu#/topology/core_id
/sys/devices/system/cpu/cpu#/topology/core_siblings
/sys/devices/system/cpu/cpu#/topology/core_siblings_list
/sys/devices/system/cpu/cpu#/topology/physical_package_id
/sys/devices/system/cpu/cpu#/topology/thread_siblings
/sys/devices/system/cpu/cpu#/topology/thread_siblings_list
Date: December 2008
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: CPU topology files that describe a logical CPU's relationship
to other cores and threads in the same physical package.
One cpu# directory is created per logical CPU in the system,
e.g. /sys/devices/system/cpu/cpu42/.
Briefly, the files above are:
core_id: the CPU core ID of cpu#. Typically it is the
hardware platform's identifier (rather than the kernel's).
The actual value is architecture and platform dependent.
core_siblings: internal kernel map of cpu#'s hardware threads
within the same physical_package_id.
core_siblings_list: human-readable list of the logical CPU
numbers within the same physical_package_id as cpu#.
physical_package_id: physical package id of cpu#. Typically
corresponds to a physical socket number, but the actual value
is architecture and platform dependent.
thread_siblings: internel kernel map of cpu#'s hardware
threads within the same core as cpu#
thread_siblings_list: human-readable list of cpu#'s hardware
threads within the same core as cpu#
See Documentation/cputopology.txt for more information.
What: /sys/devices/system/cpu/cpuidle/current_driver
/sys/devices/system/cpu/cpuidle/current_governer_ro
Date: September 2007
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description: Discover cpuidle policy and mechanism
Various CPUs today support multiple idle levels that are
differentiated by varying exit latencies and power
consumption during idle.
Idle policy (governor) is differentiated from idle mechanism
(driver)
current_driver: displays current idle mechanism
current_governor_ro: displays current idle policy
See files in Documentation/cpuidle/ for more information.
What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
Date: August 2008
KernelVersion: 2.6.27
Contact: mark.langsdorf@amd.com
Description: These files exist in every cpu's cache index directories.
There are currently 2 cache_disable_# files in each
directory. Reading from these files on a supported
processor will return that cache disable index value
for that processor and node. Writing to one of these
files will cause the specificed cache index to be disabled.
Currently, only AMD Family 10h Processors support cache index
disable, and only for their L3 caches. See the BIOS and
Kernel Developer's Guide at
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/31116-Public-GH-BKDG_3.20_2-4-09.pdf
for formatting information and other details on the
cache index disable.
Users: joachim.deguara@amd.com
Export cpu topology info via sysfs. Items (attributes) are similar Export CPU topology info via sysfs. Items (attributes) are similar
to /proc/cpuinfo. to /proc/cpuinfo.
1) /sys/devices/system/cpu/cpuX/topology/physical_package_id: 1) /sys/devices/system/cpu/cpuX/topology/physical_package_id:
represent the physical package id of cpu X;
physical package id of cpuX. Typically corresponds to a physical
socket number, but the actual value is architecture and platform
dependent.
2) /sys/devices/system/cpu/cpuX/topology/core_id: 2) /sys/devices/system/cpu/cpuX/topology/core_id:
represent the cpu core id to cpu X;
the CPU core ID of cpuX. Typically it is the hardware platform's
identifier (rather than the kernel's). The actual value is
architecture and platform dependent.
3) /sys/devices/system/cpu/cpuX/topology/thread_siblings: 3) /sys/devices/system/cpu/cpuX/topology/thread_siblings:
represent the thread siblings to cpu X in the same core;
internel kernel map of cpuX's hardware threads within the same
core as cpuX
4) /sys/devices/system/cpu/cpuX/topology/core_siblings: 4) /sys/devices/system/cpu/cpuX/topology/core_siblings:
represent the thread siblings to cpu X in the same physical package;
internal kernel map of cpuX's hardware threads within the same
physical_package_id.
To implement it in an architecture-neutral way, a new source file, To implement it in an architecture-neutral way, a new source file,
drivers/base/topology.c, is to export the 4 attributes. drivers/base/topology.c, is to export the 4 attributes.
...@@ -32,32 +45,32 @@ not defined by include/asm-XXX/topology.h: ...@@ -32,32 +45,32 @@ not defined by include/asm-XXX/topology.h:
3) thread_siblings: just the given CPU 3) thread_siblings: just the given CPU
4) core_siblings: just the given CPU 4) core_siblings: just the given CPU
Additionally, cpu topology information is provided under Additionally, CPU topology information is provided under
/sys/devices/system/cpu and includes these files. The internal /sys/devices/system/cpu and includes these files. The internal
source for the output is in brackets ("[]"). source for the output is in brackets ("[]").
kernel_max: the maximum cpu index allowed by the kernel configuration. kernel_max: the maximum CPU index allowed by the kernel configuration.
[NR_CPUS-1] [NR_CPUS-1]
offline: cpus that are not online because they have been offline: CPUs that are not online because they have been
HOTPLUGGED off (see cpu-hotplug.txt) or exceed the limit HOTPLUGGED off (see cpu-hotplug.txt) or exceed the limit
of cpus allowed by the kernel configuration (kernel_max of CPUs allowed by the kernel configuration (kernel_max
above). [~cpu_online_mask + cpus >= NR_CPUS] above). [~cpu_online_mask + cpus >= NR_CPUS]
online: cpus that are online and being scheduled [cpu_online_mask] online: CPUs that are online and being scheduled [cpu_online_mask]
possible: cpus that have been allocated resources and can be possible: CPUs that have been allocated resources and can be
brought online if they are present. [cpu_possible_mask] brought online if they are present. [cpu_possible_mask]
present: cpus that have been identified as being present in the present: CPUs that have been identified as being present in the
system. [cpu_present_mask] system. [cpu_present_mask]
The format for the above output is compatible with cpulist_parse() The format for the above output is compatible with cpulist_parse()
[see <linux/cpumask.h>]. Some examples follow. [see <linux/cpumask.h>]. Some examples follow.
In this example, there are 64 cpus in the system but cpus 32-63 exceed In this example, there are 64 CPUs in the system but cpus 32-63 exceed
the kernel max which is limited to 0..31 by the NR_CPUS config option the kernel max which is limited to 0..31 by the NR_CPUS config option
being 32. Note also that cpus 2 and 4-31 are not online but could be being 32. Note also that CPUs 2 and 4-31 are not online but could be
brought online as they are both present and possible. brought online as they are both present and possible.
kernel_max: 31 kernel_max: 31
...@@ -67,8 +80,8 @@ brought online as they are both present and possible. ...@@ -67,8 +80,8 @@ brought online as they are both present and possible.
present: 0-31 present: 0-31
In this example, the NR_CPUS config option is 128, but the kernel was In this example, the NR_CPUS config option is 128, but the kernel was
started with possible_cpus=144. There are 4 cpus in the system and cpu2 started with possible_cpus=144. There are 4 CPUs in the system and cpu2
was manually taken offline (and is the only cpu that can be brought was manually taken offline (and is the only CPU that can be brought
online.) online.)
kernel_max: 127 kernel_max: 127
...@@ -78,4 +91,4 @@ online.) ...@@ -78,4 +91,4 @@ online.)
present: 0-3 present: 0-3
See cpu-hotplug.txt for the possible_cpus=NUM kernel start parameter See cpu-hotplug.txt for the possible_cpus=NUM kernel start parameter
as well as more information on the various cpumask's. as well as more information on the various cpumasks.
...@@ -134,9 +134,15 @@ ro Mount filesystem read only. Note that ext4 will ...@@ -134,9 +134,15 @@ ro Mount filesystem read only. Note that ext4 will
mount options "ro,noload" can be used to prevent mount options "ro,noload" can be used to prevent
writes to the filesystem. writes to the filesystem.
journal_checksum Enable checksumming of the journal transactions.
This will allow the recovery code in e2fsck and the
kernel to detect corruption in the kernel. It is a
compatible change and will be ignored by older kernels.
journal_async_commit Commit block can be written to disk without waiting journal_async_commit Commit block can be written to disk without waiting
for descriptor blocks. If enabled older kernels cannot for descriptor blocks. If enabled older kernels cannot
mount the device. mount the device. This will enable 'journal_checksum'
internally.
journal=update Update the ext4 file system's journal to the current journal=update Update the ext4 file system's journal to the current
format. format.
......
...@@ -8,7 +8,7 @@ Supported adapters: ...@@ -8,7 +8,7 @@ Supported adapters:
Datasheet: Only available via NDA from ServerWorks Datasheet: Only available via NDA from ServerWorks
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges * ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
Datasheet: Not publicly available Datasheet: Not publicly available
* AMD SB900 * AMD Hudson-2
Datasheet: Not publicly available Datasheet: Not publicly available
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
Datasheet: Publicly available at the SMSC website http://www.smsc.com Datasheet: Publicly available at the SMSC website http://www.smsc.com
......
...@@ -522,7 +522,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ...@@ -522,7 +522,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
pcm_devs - Number of PCM devices assigned to each card pcm_devs - Number of PCM devices assigned to each card
(default = 1, up to 4) (default = 1, up to 4)
pcm_substreams - Number of PCM substreams assigned to each PCM pcm_substreams - Number of PCM substreams assigned to each PCM
(default = 8, up to 16) (default = 8, up to 128)
hrtimer - Use hrtimer (=1, default) or system timer (=0) hrtimer - Use hrtimer (=1, default) or system timer (=0)
fake_buffer - Fake buffer allocations (default = 1) fake_buffer - Fake buffer allocations (default = 1)
......
Generic Thermal Sysfs driver How To Generic Thermal Sysfs driver How To
========================= ===================================
Written by Sujith Thomas <sujith.thomas@intel.com>, Zhang Rui <rui.zhang@intel.com> Written by Sujith Thomas <sujith.thomas@intel.com>, Zhang Rui <rui.zhang@intel.com>
...@@ -10,20 +10,20 @@ Copyright (c) 2008 Intel Corporation ...@@ -10,20 +10,20 @@ Copyright (c) 2008 Intel Corporation
0. Introduction 0. Introduction
The generic thermal sysfs provides a set of interfaces for thermal zone devices (sensors) The generic thermal sysfs provides a set of interfaces for thermal zone
and thermal cooling devices (fan, processor...) to register with the thermal management devices (sensors) and thermal cooling devices (fan, processor...) to register
solution and to be a part of it. with the thermal management solution and to be a part of it.
This how-to focuses on enabling new thermal zone and cooling devices to participate This how-to focuses on enabling new thermal zone and cooling devices to
in thermal management. participate in thermal management.
This solution is platform independent and any type of thermal zone devices and This solution is platform independent and any type of thermal zone devices
cooling devices should be able to make use of the infrastructure. and cooling devices should be able to make use of the infrastructure.
The main task of the thermal sysfs driver is to expose thermal zone attributes as well The main task of the thermal sysfs driver is to expose thermal zone attributes
as cooling device attributes to the user space. as well as cooling device attributes to the user space.
An intelligent thermal management application can make decisions based on inputs An intelligent thermal management application can make decisions based on
from thermal zone attributes (the current temperature and trip point temperature) inputs from thermal zone attributes (the current temperature and trip point
and throttle appropriate devices. temperature) and throttle appropriate devices.
[0-*] denotes any positive number starting from 0 [0-*] denotes any positive number starting from 0
[1-*] denotes any positive number starting from 1 [1-*] denotes any positive number starting from 1
...@@ -31,77 +31,77 @@ and throttle appropriate devices. ...@@ -31,77 +31,77 @@ and throttle appropriate devices.
1. thermal sysfs driver interface functions 1. thermal sysfs driver interface functions
1.1 thermal zone device interface 1.1 thermal zone device interface
1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name, int trips, 1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name,
void *devdata, struct thermal_zone_device_ops *ops) int trips, void *devdata, struct thermal_zone_device_ops *ops)
This interface function adds a new thermal zone device (sensor) to This interface function adds a new thermal zone device (sensor) to
/sys/class/thermal folder as thermal_zone[0-*]. /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
It tries to bind all the thermal cooling devices registered at the same time. thermal cooling devices registered at the same time.
name: the thermal zone name. name: the thermal zone name.
trips: the total number of trip points this thermal zone supports. trips: the total number of trip points this thermal zone supports.
devdata: device private data devdata: device private data
ops: thermal zone device call-backs. ops: thermal zone device call-backs.
.bind: bind the thermal zone device with a thermal cooling device. .bind: bind the thermal zone device with a thermal cooling device.
.unbind: unbind the thermal zone device with a thermal cooling device. .unbind: unbind the thermal zone device with a thermal cooling device.
.get_temp: get the current temperature of the thermal zone. .get_temp: get the current temperature of the thermal zone.
.get_mode: get the current mode (user/kernel) of the thermal zone. .get_mode: get the current mode (user/kernel) of the thermal zone.
"kernel" means thermal management is done in kernel. - "kernel" means thermal management is done in kernel.
"user" will prevent kernel thermal driver actions upon trip points - "user" will prevent kernel thermal driver actions upon trip points
so that user applications can take charge of thermal management. so that user applications can take charge of thermal management.
.set_mode: set the mode (user/kernel) of the thermal zone. .set_mode: set the mode (user/kernel) of the thermal zone.
.get_trip_type: get the type of certain trip point. .get_trip_type: get the type of certain trip point.
.get_trip_temp: get the temperature above which the certain trip point .get_trip_temp: get the temperature above which the certain trip point
will be fired. will be fired.
1.1.2 void thermal_zone_device_unregister(struct thermal_zone_device *tz) 1.1.2 void thermal_zone_device_unregister(struct thermal_zone_device *tz)
This interface function removes the thermal zone device. This interface function removes the thermal zone device.
It deletes the corresponding entry form /sys/class/thermal folder and unbind all It deletes the corresponding entry form /sys/class/thermal folder and
the thermal cooling devices it uses. unbind all the thermal cooling devices it uses.
1.2 thermal cooling device interface 1.2 thermal cooling device interface
1.2.1 struct thermal_cooling_device *thermal_cooling_device_register(char *name, 1.2.1 struct thermal_cooling_device *thermal_cooling_device_register(char *name,
void *devdata, struct thermal_cooling_device_ops *) void *devdata, struct thermal_cooling_device_ops *)
This interface function adds a new thermal cooling device (fan/processor/...) to This interface function adds a new thermal cooling device (fan/processor/...)
/sys/class/thermal/ folder as cooling_device[0-*]. to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
It tries to bind itself to all the thermal zone devices register at the same time. to all the thermal zone devices register at the same time.
name: the cooling device name. name: the cooling device name.
devdata: device private data. devdata: device private data.
ops: thermal cooling devices call-backs. ops: thermal cooling devices call-backs.
.get_max_state: get the Maximum throttle state of the cooling device. .get_max_state: get the Maximum throttle state of the cooling device.
.get_cur_state: get the Current throttle state of the cooling device. .get_cur_state: get the Current throttle state of the cooling device.
.set_cur_state: set the Current throttle state of the cooling device. .set_cur_state: set the Current throttle state of the cooling device.
1.2.2 void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) 1.2.2 void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
This interface function remove the thermal cooling device. This interface function remove the thermal cooling device.
It deletes the corresponding entry form /sys/class/thermal folder and unbind It deletes the corresponding entry form /sys/class/thermal folder and
itself from all the thermal zone devices using it. unbind itself from all the thermal zone devices using it.
1.3 interface for binding a thermal zone device with a thermal cooling device 1.3 interface for binding a thermal zone device with a thermal cooling device
1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, 1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
int trip, struct thermal_cooling_device *cdev); int trip, struct thermal_cooling_device *cdev);
This interface function bind a thermal cooling device to the certain trip point This interface function bind a thermal cooling device to the certain trip
of a thermal zone device. point of a thermal zone device.
This function is usually called in the thermal zone device .bind callback. This function is usually called in the thermal zone device .bind callback.
tz: the thermal zone device tz: the thermal zone device
cdev: thermal cooling device cdev: thermal cooling device
trip: indicates which trip point the cooling devices is associated with trip: indicates which trip point the cooling devices is associated with
in this thermal zone. in this thermal zone.
1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, 1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
int trip, struct thermal_cooling_device *cdev); int trip, struct thermal_cooling_device *cdev);
This interface function unbind a thermal cooling device from the certain trip point This interface function unbind a thermal cooling device from the certain
of a thermal zone device. trip point of a thermal zone device. This function is usually called in
This function is usually called in the thermal zone device .unbind callback. the thermal zone device .unbind callback.
tz: the thermal zone device tz: the thermal zone device
cdev: thermal cooling device cdev: thermal cooling device
trip: indicates which trip point the cooling devices is associated with trip: indicates which trip point the cooling devices is associated with
in this thermal zone. in this thermal zone.
2. sysfs attributes structure 2. sysfs attributes structure
...@@ -114,153 +114,166 @@ if hwmon is compiled in or built as a module. ...@@ -114,153 +114,166 @@ if hwmon is compiled in or built as a module.
Thermal zone device sys I/F, created once it's registered: Thermal zone device sys I/F, created once it's registered:
/sys/class/thermal/thermal_zone[0-*]: /sys/class/thermal/thermal_zone[0-*]:
|-----type: Type of the thermal zone |---type: Type of the thermal zone
|-----temp: Current temperature |---temp: Current temperature
|-----mode: Working mode of the thermal zone |---mode: Working mode of the thermal zone
|-----trip_point_[0-*]_temp: Trip point temperature |---trip_point_[0-*]_temp: Trip point temperature
|-----trip_point_[0-*]_type: Trip point type |---trip_point_[0-*]_type: Trip point type
Thermal cooling device sys I/F, created once it's registered: Thermal cooling device sys I/F, created once it's registered:
/sys/class/thermal/cooling_device[0-*]: /sys/class/thermal/cooling_device[0-*]:
|-----type : Type of the cooling device(processor/fan/...) |---type: Type of the cooling device(processor/fan/...)
|-----max_state: Maximum cooling state of the cooling device |---max_state: Maximum cooling state of the cooling device
|-----cur_state: Current cooling state of the cooling device |---cur_state: Current cooling state of the cooling device
These two dynamic attributes are created/removed in pairs. Then next two dynamic attributes are created/removed in pairs. They represent
They represent the relationship between a thermal zone and its associated cooling device. the relationship between a thermal zone and its associated cooling device.
They are created/removed for each They are created/removed for each successful execution of
thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device successful execution. thermal_zone_bind_cooling_device/thermal_zone_unbind_cooling_device.
/sys/class/thermal/thermal_zone[0-*] /sys/class/thermal/thermal_zone[0-*]:
|-----cdev[0-*]: The [0-*]th cooling device in the current thermal zone |---cdev[0-*]: [0-*]th cooling device in current thermal zone
|-----cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with |---cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with
Besides the thermal zone device sysfs I/F and cooling device sysfs I/F, Besides the thermal zone device sysfs I/F and cooling device sysfs I/F,
the generic thermal driver also creates a hwmon sysfs I/F for each _type_ of the generic thermal driver also creates a hwmon sysfs I/F for each _type_
thermal zone device. E.g. the generic thermal driver registers one hwmon class device of thermal zone device. E.g. the generic thermal driver registers one hwmon
and build the associated hwmon sysfs I/F for all the registered ACPI thermal zones. class device and build the associated hwmon sysfs I/F for all the registered
ACPI thermal zones.
/sys/class/hwmon/hwmon[0-*]: /sys/class/hwmon/hwmon[0-*]:
|-----name: The type of the thermal zone devices. |---name: The type of the thermal zone devices
|-----temp[1-*]_input: The current temperature of thermal zone [1-*]. |---temp[1-*]_input: The current temperature of thermal zone [1-*]
|-----temp[1-*]_critical: The critical trip point of thermal zone [1-*]. |---temp[1-*]_critical: The critical trip point of thermal zone [1-*]
Please read Documentation/hwmon/sysfs-interface for additional information. Please read Documentation/hwmon/sysfs-interface for additional information.
*************************** ***************************
* Thermal zone attributes * * Thermal zone attributes *
*************************** ***************************
type Strings which represent the thermal zone type. type
This is given by thermal zone driver as part of registration. Strings which represent the thermal zone type.
Eg: "acpitz" indicates it's an ACPI thermal device. This is given by thermal zone driver as part of registration.
In order to keep it consistent with hwmon sys attribute, E.g: "acpitz" indicates it's an ACPI thermal device.
this should be a short, lowercase string, In order to keep it consistent with hwmon sys attribute; this should
not containing spaces nor dashes. be a short, lowercase string, not containing spaces nor dashes.
RO RO, Required
Required
temp
temp Current temperature as reported by thermal zone (sensor) Current temperature as reported by thermal zone (sensor).
Unit: millidegree Celsius Unit: millidegree Celsius
RO RO, Required
Required
mode
mode One of the predefined values in [kernel, user] One of the predefined values in [kernel, user].
This file gives information about the algorithm This file gives information about the algorithm that is currently
that is currently managing the thermal zone. managing the thermal zone. It can be either default kernel based
It can be either default kernel based algorithm algorithm or user space application.
or user space application. kernel = Thermal management in kernel thermal zone driver.
RW user = Preventing kernel thermal zone driver actions upon
Optional trip points so that user application can take full
kernel = Thermal management in kernel thermal zone driver. charge of the thermal management.
user = Preventing kernel thermal zone driver actions upon RW, Optional
trip points so that user application can take full
charge of the thermal management. trip_point_[0-*]_temp
The temperature above which trip point will be fired.
trip_point_[0-*]_temp The temperature above which trip point will be fired Unit: millidegree Celsius
Unit: millidegree Celsius RO, Optional
RO
Optional trip_point_[0-*]_type
Strings which indicate the type of the trip point.
trip_point_[0-*]_type Strings which indicate the type of the trip point E.g. it can be one of critical, hot, passive, active[0-*] for ACPI
E.g. it can be one of critical, hot, passive, thermal zone.
active[0-*] for ACPI thermal zone. RO, Optional
RO
Optional cdev[0-*]
Sysfs link to the thermal cooling device node where the sys I/F
cdev[0-*] Sysfs link to the thermal cooling device node where the sys I/F for cooling device throttling control represents.
for cooling device throttling control represents. RO, Optional
RO
Optional cdev[0-*]_trip_point
The trip point with which cdev[0-*] is associated in this thermal
cdev[0-*]_trip_point The trip point with which cdev[0-*] is associated in this thermal zone zone; -1 means the cooling device is not associated with any trip
-1 means the cooling device is not associated with any trip point. point.
RO RO, Optional
Optional
passive
****************************** Attribute is only present for zones in which the passive cooling
* Cooling device attributes * policy is not supported by native thermal driver. Default is zero
****************************** and can be set to a temperature (in millidegrees) to enable a
passive trip point for the zone. Activation is done by polling with
type String which represents the type of device an interval of 1 second.
eg: For generic ACPI: this should be "Fan", Unit: millidegrees Celsius
"Processor" or "LCD" RW, Optional
eg. For memory controller device on intel_menlow platform:
this should be "Memory controller" *****************************
RO * Cooling device attributes *
Required *****************************
max_state The maximum permissible cooling state of this cooling device. type
RO String which represents the type of device, e.g:
Required - for generic ACPI: should be "Fan", "Processor" or "LCD"
- for memory controller device on intel_menlow platform:
cur_state The current cooling state of this cooling device. should be "Memory controller".
the value can any integer numbers between 0 and max_state, RO, Required
cur_state == 0 means no cooling
cur_state == max_state means the maximum cooling. max_state
RW The maximum permissible cooling state of this cooling device.
Required RO, Required
cur_state
The current cooling state of this cooling device.
The value can any integer numbers between 0 and max_state:
- cur_state == 0 means no cooling
- cur_state == max_state means the maximum cooling.
RW, Required
3. A simple implementation 3. A simple implementation
ACPI thermal zone may support multiple trip points like critical/hot/passive/active. ACPI thermal zone may support multiple trip points like critical, hot,
If an ACPI thermal zone supports critical, passive, active[0] and active[1] at the same time, passive, active. If an ACPI thermal zone supports critical, passive,
it may register itself as a thermal_zone_device (thermal_zone1) with 4 trip points in all. active[0] and active[1] at the same time, it may register itself as a
It has one processor and one fan, which are both registered as thermal_cooling_device. thermal_zone_device (thermal_zone1) with 4 trip points in all.
If the processor is listed in _PSL method, and the fan is listed in _AL0 method, It has one processor and one fan, which are both registered as
the sys I/F structure will be built like this: thermal_cooling_device.
If the processor is listed in _PSL method, and the fan is listed in _AL0
method, the sys I/F structure will be built like this:
/sys/class/thermal: /sys/class/thermal:
|thermal_zone1: |thermal_zone1:
|-----type: acpitz |---type: acpitz
|-----temp: 37000 |---temp: 37000
|-----mode: kernel |---mode: kernel
|-----trip_point_0_temp: 100000 |---trip_point_0_temp: 100000
|-----trip_point_0_type: critical |---trip_point_0_type: critical
|-----trip_point_1_temp: 80000 |---trip_point_1_temp: 80000
|-----trip_point_1_type: passive |---trip_point_1_type: passive
|-----trip_point_2_temp: 70000 |---trip_point_2_temp: 70000
|-----trip_point_2_type: active0 |---trip_point_2_type: active0
|-----trip_point_3_temp: 60000 |---trip_point_3_temp: 60000
|-----trip_point_3_type: active1 |---trip_point_3_type: active1
|-----cdev0: --->/sys/class/thermal/cooling_device0 |---cdev0: --->/sys/class/thermal/cooling_device0
|-----cdev0_trip_point: 1 /* cdev0 can be used for passive */ |---cdev0_trip_point: 1 /* cdev0 can be used for passive */
|-----cdev1: --->/sys/class/thermal/cooling_device3 |---cdev1: --->/sys/class/thermal/cooling_device3
|-----cdev1_trip_point: 2 /* cdev1 can be used for active[0]*/ |---cdev1_trip_point: 2 /* cdev1 can be used for active[0]*/
|cooling_device0: |cooling_device0:
|-----type: Processor |---type: Processor
|-----max_state: 8 |---max_state: 8
|-----cur_state: 0 |---cur_state: 0
|cooling_device3: |cooling_device3:
|-----type: Fan |---type: Fan
|-----max_state: 2 |---max_state: 2
|-----cur_state: 0 |---cur_state: 0
/sys/class/hwmon: /sys/class/hwmon:
|hwmon0: |hwmon0:
|-----name: acpitz |---name: acpitz
|-----temp1_input: 37000 |---temp1_input: 37000
|-----temp1_crit: 100000 |---temp1_crit: 100000
...@@ -1231,6 +1231,7 @@ something like this simple program: ...@@ -1231,6 +1231,7 @@ something like this simple program:
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#define _STR(x) #x #define _STR(x) #x
#define STR(x) _STR(x) #define STR(x) _STR(x)
...@@ -1265,6 +1266,7 @@ const char *find_debugfs(void) ...@@ -1265,6 +1266,7 @@ const char *find_debugfs(void)
return NULL; return NULL;
} }
strcat(debugfs, "/tracing/");
debugfs_found = 1; debugfs_found = 1;
return debugfs; return debugfs;
......
...@@ -3665,6 +3665,7 @@ L: netdev@vger.kernel.org ...@@ -3665,6 +3665,7 @@ L: netdev@vger.kernel.org
W: http://www.linuxfoundation.org/en/Net W: http://www.linuxfoundation.org/en/Net
W: http://patchwork.ozlabs.org/project/netdev/list/ W: http://patchwork.ozlabs.org/project/netdev/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git
S: Maintained S: Maintained
F: net/ F: net/
F: include/net/ F: include/net/
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 32 SUBLEVEL = 32
EXTRAVERSION = -rc5 EXTRAVERSION = -rc6
NAME = Man-Eating Seals of Antiquity NAME = Man-Eating Seals of Antiquity
# *DOCUMENTATION* # *DOCUMENTATION*
......
此差异已折叠。
此差异已折叠。
...@@ -414,9 +414,14 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page ...@@ -414,9 +414,14 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
static inline void __flush_icache_all(void) static inline void __flush_icache_all(void)
{ {
#ifdef CONFIG_ARM_ERRATA_411920
extern void v6_icache_inval_all(void);
v6_icache_inval_all();
#else
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
: :
: "r" (0)); : "r" (0));
#endif
} }
#define ARCH_HAS_FLUSH_ANON_PAGE #define ARCH_HAS_FLUSH_ANON_PAGE
......
...@@ -402,6 +402,15 @@ ...@@ -402,6 +402,15 @@
#define __ARM_NR_usr32 (__ARM_NR_BASE+4) #define __ARM_NR_usr32 (__ARM_NR_BASE+4)
#define __ARM_NR_set_tls (__ARM_NR_BASE+5) #define __ARM_NR_set_tls (__ARM_NR_BASE+5)
/*
* *NOTE*: This is a ghost syscall private to the kernel. Only the
* __kuser_cmpxchg code in entry-armv.S should be aware of its
* existence. Don't ever use this from user code.
*/
#ifdef __KERNEL__
#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
#endif
/* /*
* The following syscalls are obsolete and no longer available for EABI. * The following syscalls are obsolete and no longer available for EABI.
*/ */
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <mach/entry-macro.S> #include <mach/entry-macro.S>
#include <asm/thread_notify.h> #include <asm/thread_notify.h>
#include <asm/unwind.h> #include <asm/unwind.h>
#include <asm/unistd.h>
#include "entry-header.S" #include "entry-header.S"
...@@ -908,10 +909,10 @@ __kuser_cmpxchg: @ 0xffff0fc0 ...@@ -908,10 +909,10 @@ __kuser_cmpxchg: @ 0xffff0fc0
* A special ghost syscall is used for that (see traps.c). * A special ghost syscall is used for that (see traps.c).
*/ */
stmfd sp!, {r7, lr} stmfd sp!, {r7, lr}
mov r7, #0xff00 @ 0xfff0 into r7 for EABI ldr r7, =1f @ it's 20 bits
orr r7, r7, #0xf0 swi __ARM_NR_cmpxchg
swi #0x9ffff0
ldmfd sp!, {r7, pc} ldmfd sp!, {r7, pc}
1: .word __ARM_NR_cmpxchg
#elif __LINUX_ARM_ARCH__ < 6 #elif __LINUX_ARM_ARCH__ < 6
......
...@@ -97,7 +97,7 @@ __error_a: ...@@ -97,7 +97,7 @@ __error_a:
bl printhex8 bl printhex8
adr r0, str_a2 adr r0, str_a2
bl printascii bl printascii
adr r3, 3f adr r3, 4f
ldmia r3, {r4, r5, r6} @ get machine desc list ldmia r3, {r4, r5, r6} @ get machine desc list
sub r4, r3, r4 @ get offset between virt&phys sub r4, r3, r4 @ get offset between virt&phys
add r5, r5, r4 @ convert virt addresses to add r5, r5, r4 @ convert virt addresses to
......
/* /*
* linux/arch/arm/kernel/signal.c * linux/arch/arm/kernel/signal.c
* *
* Copyright (C) 1995-2002 Russell King * Copyright (C) 1995-2009 Russell King
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
*/ */
#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) #define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
/* /*
* With EABI, the syscall number has to be loaded into r7. * With EABI, the syscall number has to be loaded into r7.
...@@ -48,6 +49,18 @@ const unsigned long sigreturn_codes[7] = { ...@@ -48,6 +49,18 @@ const unsigned long sigreturn_codes[7] = {
MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
}; };
/*
* Either we support OABI only, or we have EABI with the OABI
* compat layer enabled. In the later case we don't know if
* user space is EABI or not, and if not we must not clobber r7.
* Always using the OABI syscall solves that issue and works for
* all those cases.
*/
const unsigned long syscall_restart_code[2] = {
SWI_SYS_RESTART, /* swi __NR_restart_syscall */
0xe49df004, /* ldr pc, [sp], #4 */
};
/* /*
* atomically swap in the new signal mask, and wait for a signal. * atomically swap in the new signal mask, and wait for a signal.
*/ */
...@@ -645,32 +658,12 @@ static void do_signal(struct pt_regs *regs, int syscall) ...@@ -645,32 +658,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
regs->ARM_pc -= 4; regs->ARM_pc -= 4;
#else #else
u32 __user *usp; u32 __user *usp;
u32 swival = __NR_restart_syscall;
regs->ARM_sp -= 12; regs->ARM_sp -= 4;
usp = (u32 __user *)regs->ARM_sp; usp = (u32 __user *)regs->ARM_sp;
/* put_user(regs->ARM_pc, usp);
* Either we supports OABI only, or we have regs->ARM_pc = KERN_RESTART_CODE;
* EABI with the OABI compat layer enabled.
* In the later case we don't know if user
* space is EABI or not, and if not we must
* not clobber r7. Always using the OABI
* syscall solves that issue and works for
* all those cases.
*/
swival = swival - __NR_SYSCALL_BASE + __NR_OABI_SYSCALL_BASE;
put_user(regs->ARM_pc, &usp[0]);
/* swi __NR_restart_syscall */
put_user(0xef000000 | swival, &usp[1]);
/* ldr pc, [sp], #12 */
put_user(0xe49df00c, &usp[2]);
flush_icache_range((unsigned long)usp,
(unsigned long)(usp + 3));
regs->ARM_pc = regs->ARM_sp + 4;
#endif #endif
} }
} }
......
/* /*
* linux/arch/arm/kernel/signal.h * linux/arch/arm/kernel/signal.h
* *
* Copyright (C) 2005 Russell King. * Copyright (C) 2005-2009 Russell King.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) #define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
extern const unsigned long sigreturn_codes[7]; extern const unsigned long sigreturn_codes[7];
extern const unsigned long syscall_restart_code[2];
...@@ -37,6 +37,10 @@ void __init scu_enable(void __iomem *scu_base) ...@@ -37,6 +37,10 @@ void __init scu_enable(void __iomem *scu_base)
u32 scu_ctrl; u32 scu_ctrl;
scu_ctrl = __raw_readl(scu_base + SCU_CTRL); scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
/* already enabled? */
if (scu_ctrl & 1)
return;
scu_ctrl |= 1; scu_ctrl |= 1;
__raw_writel(scu_ctrl, scu_base + SCU_CTRL); __raw_writel(scu_ctrl, scu_base + SCU_CTRL);
......
/* /*
* linux/arch/arm/kernel/traps.c * linux/arch/arm/kernel/traps.c
* *
* Copyright (C) 1995-2002 Russell King * Copyright (C) 1995-2009 Russell King
* Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -528,7 +528,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) ...@@ -528,7 +528,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
* __kuser_cmpxchg code in entry-armv.S should be aware of its * __kuser_cmpxchg code in entry-armv.S should be aware of its
* existence. Don't ever use this from user code. * existence. Don't ever use this from user code.
*/ */
case 0xfff0: case NR(cmpxchg):
for (;;) { for (;;) {
extern void do_DataAbort(unsigned long addr, unsigned int fsr, extern void do_DataAbort(unsigned long addr, unsigned int fsr,
struct pt_regs *regs); struct pt_regs *regs);
...@@ -573,7 +573,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) ...@@ -573,7 +573,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
if not implemented, rather than raising SIGILL. This if not implemented, rather than raising SIGILL. This
way the calling program can gracefully determine whether way the calling program can gracefully determine whether
a feature is supported. */ a feature is supported. */
if (no <= 0x7ff) if ((no & 0xffff) <= 0x7ff)
return -ENOSYS; return -ENOSYS;
break; break;
} }
...@@ -751,6 +751,8 @@ void __init early_trap_init(void) ...@@ -751,6 +751,8 @@ void __init early_trap_init(void)
*/ */
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
sizeof(sigreturn_codes)); sizeof(sigreturn_codes));
memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
sizeof(syscall_restart_code));
flush_icache_range(vectors, vectors + PAGE_SIZE); flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT); modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
......
...@@ -26,6 +26,15 @@ ...@@ -26,6 +26,15 @@
* http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html * http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
*/ */
#if !defined (__ARM_EABI__)
#warning Your compiler does not have EABI support.
#warning ARM unwind is known to compile only with EABI compilers.
#warning Change compiler or disable ARM_UNWIND option.
#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
#warning Your compiler is too buggy; it is known to not compile ARM unwind support.
#warning Change compiler or disable ARM_UNWIND option.
#endif
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#define ARCH_ID_AT91SAM9G20 0x019905a0 #define ARCH_ID_AT91SAM9G20 0x019905a0
#define ARCH_ID_AT91SAM9RL64 0x019b03a0 #define ARCH_ID_AT91SAM9RL64 0x019b03a0
#define ARCH_ID_AT91SAM9G45 0x819b05a0 #define ARCH_ID_AT91SAM9G45 0x819b05a0
#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */
#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */
#define ARCH_ID_AT91CAP9 0x039A03A0 #define ARCH_ID_AT91CAP9 0x039A03A0
#define ARCH_ID_AT91SAM9XE128 0x329973a0 #define ARCH_ID_AT91SAM9XE128 0x329973a0
...@@ -41,6 +43,11 @@ static inline unsigned long at91_cpu_identify(void) ...@@ -41,6 +43,11 @@ static inline unsigned long at91_cpu_identify(void)
return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION); return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
} }
static inline unsigned long at91_cpu_fully_identify(void)
{
return at91_sys_read(AT91_DBGU_CIDR);
}
#define ARCH_EXID_AT91SAM9M11 0x00000001 #define ARCH_EXID_AT91SAM9M11 0x00000001
#define ARCH_EXID_AT91SAM9M10 0x00000002 #define ARCH_EXID_AT91SAM9M10 0x00000002
#define ARCH_EXID_AT91SAM9G45 0x00000004 #define ARCH_EXID_AT91SAM9G45 0x00000004
...@@ -118,8 +125,10 @@ static inline unsigned long at91cap9_rev_identify(void) ...@@ -118,8 +125,10 @@ static inline unsigned long at91cap9_rev_identify(void)
#ifdef CONFIG_ARCH_AT91SAM9G45 #ifdef CONFIG_ARCH_AT91SAM9G45
#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45) #define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES)
#else #else
#define cpu_is_at91sam9g45() (0) #define cpu_is_at91sam9g45() (0)
#define cpu_is_at91sam9g45es() (0)
#endif #endif
#ifdef CONFIG_ARCH_AT91CAP9 #ifdef CONFIG_ARCH_AT91CAP9
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/io.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
...@@ -28,5 +28,6 @@ ...@@ -28,5 +28,6 @@
#define BUS_OFFSET UL(0x80000000) #define BUS_OFFSET UL(0x80000000)
#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET) #define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
#define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET) #define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET)
#define __pfn_to_bus(x) (((x) << PAGE_SHIFT) + BUS_OFFSET)
#endif #endif
...@@ -105,7 +105,7 @@ void __init kirkwood_setup_cpu_mbus(void) ...@@ -105,7 +105,7 @@ void __init kirkwood_setup_cpu_mbus(void)
setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE); TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE);
setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
TARGET_PCIE, ATTR_PCIE_MEM, -1); TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
/* /*
* Setup window for NAND controller. * Setup window for NAND controller.
......
...@@ -845,7 +845,7 @@ int __init kirkwood_find_tclk(void) ...@@ -845,7 +845,7 @@ int __init kirkwood_find_tclk(void)
return 166666667; return 166666667;
} }
static void kirkwood_timer_init(void) static void __init kirkwood_timer_init(void)
{ {
kirkwood_tclk = kirkwood_find_tclk(); kirkwood_tclk = kirkwood_find_tclk();
orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
static inline void __iomem *__io(unsigned long addr) static inline void __iomem *__io(unsigned long addr)
{ {
return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_PHYS_BASE) return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_BUS_BASE)
+ KIRKWOOD_PCIE_IO_VIRT_BASE); + KIRKWOOD_PCIE_IO_VIRT_BASE);
} }
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#define KIRKWOOD_REGS_SIZE SZ_1M #define KIRKWOOD_REGS_SIZE SZ_1M
#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000 #define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000
#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M #define KIRKWOOD_PCIE_MEM_SIZE SZ_128M
/* /*
......
...@@ -70,8 +70,20 @@ static void __init openrd_base_init(void) ...@@ -70,8 +70,20 @@ static void __init openrd_base_init(void)
kirkwood_ge00_init(&openrd_base_ge00_data); kirkwood_ge00_init(&openrd_base_ge00_data);
kirkwood_sata_init(&openrd_base_sata_data); kirkwood_sata_init(&openrd_base_sata_data);
kirkwood_sdio_init(&openrd_base_mvsdio_data); kirkwood_sdio_init(&openrd_base_mvsdio_data);
kirkwood_i2c_init();
} }
static int __init openrd_base_pci_init(void)
{
if (machine_is_openrd_base())
kirkwood_pcie_init();
return 0;
}
subsys_initcall(openrd_base_pci_init);
MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board") MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */ /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
.phys_io = KIRKWOOD_REGS_PHYS_BASE, .phys_io = KIRKWOOD_REGS_PHYS_BASE,
......
...@@ -93,7 +93,7 @@ static struct pci_ops pcie_ops = { ...@@ -93,7 +93,7 @@ static struct pci_ops pcie_ops = {
}; };
static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
{ {
struct resource *res; struct resource *res;
extern unsigned int kirkwood_clk_ctrl; extern unsigned int kirkwood_clk_ctrl;
...@@ -115,7 +115,7 @@ static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) ...@@ -115,7 +115,7 @@ static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
*/ */
res[0].name = "PCIe I/O Space"; res[0].name = "PCIe I/O Space";
res[0].flags = IORESOURCE_IO; res[0].flags = IORESOURCE_IO;
res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE; res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
if (request_resource(&ioport_resource, &res[0])) if (request_resource(&ioport_resource, &res[0]))
panic("Request PCIe IO resource failed\n"); panic("Request PCIe IO resource failed\n");
...@@ -126,7 +126,7 @@ static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) ...@@ -126,7 +126,7 @@ static int kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
*/ */
res[1].name = "PCIe Memory Space"; res[1].name = "PCIe Memory Space";
res[1].flags = IORESOURCE_MEM; res[1].flags = IORESOURCE_MEM;
res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE; res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1; res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
if (request_resource(&iomem_resource, &res[1])) if (request_resource(&iomem_resource, &res[1]))
panic("Request PCIe Memory resource failed\n"); panic("Request PCIe Memory resource failed\n");
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#define KS8695_SEC1 (0x04) /* Switch Engine Control 1 */ #define KS8695_SEC1 (0x04) /* Switch Engine Control 1 */
#define KS8695_SEC2 (0x08) /* Switch Engine Control 2 */ #define KS8695_SEC2 (0x08) /* Switch Engine Control 2 */
#define KS8695_P(x)_C(z) (0xc0 + (((x)-1)*3 + ((z)-1))*4) /* Port Configuration Registers */ #define KS8695_SEPXCZ(x,z) (0x0c + (((x)-1)*3 + ((z)-1))*4) /* Port Configuration Registers */
#define KS8695_SEP12AN (0x48) /* Port 1 & 2 Auto-Negotiation */ #define KS8695_SEP12AN (0x48) /* Port 1 & 2 Auto-Negotiation */
#define KS8695_SEP34AN (0x4c) /* Port 3 & 4 Auto-Negotiation */ #define KS8695_SEP34AN (0x4c) /* Port 3 & 4 Auto-Negotiation */
......
...@@ -845,6 +845,8 @@ static char * __init mv78xx0_id(void) ...@@ -845,6 +845,8 @@ static char * __init mv78xx0_id(void)
} else if (dev == MV78100_DEV_ID) { } else if (dev == MV78100_DEV_ID) {
if (rev == MV78100_REV_A0) if (rev == MV78100_REV_A0)
return "MV78100-A0"; return "MV78100-A0";
else if (rev == MV78100_REV_A1)
return "MV78100-A1";
else else
return "MV78100-Rev-Unsupported"; return "MV78100-Rev-Unsupported";
} else if (dev == MV78200_DEV_ID) { } else if (dev == MV78200_DEV_ID) {
......
...@@ -112,6 +112,7 @@ ...@@ -112,6 +112,7 @@
#define MV78100_DEV_ID 0x7810 #define MV78100_DEV_ID 0x7810
#define MV78100_REV_A0 1 #define MV78100_REV_A0 1
#define MV78100_REV_A1 2
#define MV78200_DEV_ID 0x7820 #define MV78200_DEV_ID 0x7820
#define MV78200_REV_A0 1 #define MV78200_REV_A0 1
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include "generic.h" #include "generic.h"
#define MAX_INTERNAL_IRQS 128
#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f) #define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
#define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR)) #define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
#define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR)) #define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
...@@ -122,6 +124,8 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn) ...@@ -122,6 +124,8 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
{ {
int irq, i; int irq, i;
BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
pxa_internal_irq_nr = irq_nr; pxa_internal_irq_nr = irq_nr;
for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) { for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) {
...@@ -149,7 +153,8 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn) ...@@ -149,7 +153,8 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
static unsigned long saved_icmr[2]; static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32];
static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
{ {
...@@ -159,6 +164,8 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state) ...@@ -159,6 +164,8 @@ static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
saved_icmr[i] = _ICMR(irq); saved_icmr[i] = _ICMR(irq);
_ICMR(irq) = 0; _ICMR(irq) = 0;
} }
for (i = 0; i < pxa_internal_irq_nr; i++)
saved_ipr[i] = IPR(i);
return 0; return 0;
} }
...@@ -171,6 +178,8 @@ static int pxa_irq_resume(struct sys_device *dev) ...@@ -171,6 +178,8 @@ static int pxa_irq_resume(struct sys_device *dev)
_ICMR(irq) = saved_icmr[i]; _ICMR(irq) = saved_icmr[i];
_ICLR(irq) = 0; _ICLR(irq) = 0;
} }
for (i = 0; i < pxa_internal_irq_nr; i++)
IPR(i) = saved_ipr[i];
ICCR = 1; ICCR = 1;
return 0; return 0;
......
...@@ -292,10 +292,10 @@ const static unsigned int palmtc_keypad_col_gpios[] = { ...@@ -292,10 +292,10 @@ const static unsigned int palmtc_keypad_col_gpios[] = {
static struct matrix_keypad_platform_data palmtc_keypad_platform_data = { static struct matrix_keypad_platform_data palmtc_keypad_platform_data = {
.keymap_data = &palmtc_keymap_data, .keymap_data = &palmtc_keymap_data,
.col_gpios = palmtc_keypad_row_gpios, .row_gpios = palmtc_keypad_row_gpios,
.num_col_gpios = 12, .num_row_gpios = ARRAY_SIZE(palmtc_keypad_row_gpios),
.row_gpios = palmtc_keypad_col_gpios, .col_gpios = palmtc_keypad_col_gpios,
.num_row_gpios = 4, .num_col_gpios = ARRAY_SIZE(palmtc_keypad_col_gpios),
.active_low = 1, .active_low = 1,
.debounce_ms = 20, .debounce_ms = 20,
......
...@@ -779,11 +779,34 @@ static void __init common_init(void) ...@@ -779,11 +779,34 @@ static void __init common_init(void)
pxa_set_i2c_info(NULL); pxa_set_i2c_info(NULL);
} }
#if defined(CONFIG_MACH_AKITA) || defined(CONFIG_MACH_BORZOI)
static struct nand_bbt_descr sharpsl_akita_bbt = {
.options = 0,
.offs = 4,
.len = 1,
.pattern = scan_ff_pattern
};
static struct nand_ecclayout akita_oobinfo = {
.eccbytes = 24,
.eccpos = {
0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
.oobfree = {{0x08, 0x09}}
};
#endif
#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI) #if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
static void __init spitz_init(void) static void __init spitz_init(void)
{ {
spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON; spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON;
if (machine_is_borzoi()) {
sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt;
sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo;
}
platform_scoop_config = &spitz_pcmcia_config; platform_scoop_config = &spitz_pcmcia_config;
common_init(); common_init();
...@@ -808,22 +831,6 @@ static struct i2c_board_info akita_i2c_board_info[] = { ...@@ -808,22 +831,6 @@ static struct i2c_board_info akita_i2c_board_info[] = {
}, },
}; };
static struct nand_bbt_descr sharpsl_akita_bbt = {
.options = 0,
.offs = 4,
.len = 1,
.pattern = scan_ff_pattern
};
static struct nand_ecclayout akita_oobinfo = {
.eccbytes = 24,
.eccpos = {
0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
.oobfree = {{0x08, 0x09}}
};
static void __init akita_init(void) static void __init akita_init(void)
{ {
spitz_ficp_platform_data.gpio_pwdown = AKITA_GPIO_IR_ON; spitz_ficp_platform_data.gpio_pwdown = AKITA_GPIO_IR_ON;
......
...@@ -70,6 +70,8 @@ config MACH_REALVIEW_PBX ...@@ -70,6 +70,8 @@ config MACH_REALVIEW_PBX
bool "Support RealView/PBX platform" bool "Support RealView/PBX platform"
select ARM_GIC select ARM_GIC
select HAVE_PATA_PLATFORM select HAVE_PATA_PLATFORM
select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !HIGH_PHYS_OFFSET
select ZONE_DMA if SPARSEMEM
help help
Include support for the ARM(R) RealView PBX platform. Include support for the ARM(R) RealView PBX platform.
...@@ -82,6 +84,7 @@ config REALVIEW_HIGH_PHYS_OFFSET ...@@ -82,6 +84,7 @@ config REALVIEW_HIGH_PHYS_OFFSET
0x70000000, 256MB of which being mirrored at 0x00000000. If 0x70000000, 256MB of which being mirrored at 0x00000000. If
the board supports 512MB of RAM, this option allows the the board supports 512MB of RAM, this option allows the
memory to be accessed contiguously at the high physical memory to be accessed contiguously at the high physical
offset. offset. On the PBX board, disabling this option allows 1GB of
RAM to be used with SPARSEMEM.
endmenu endmenu
...@@ -59,6 +59,25 @@ ...@@ -59,6 +59,25 @@
/* used by entry-macro.S and platsmp.c */ /* used by entry-macro.S and platsmp.c */
void __iomem *gic_cpu_base_addr; void __iomem *gic_cpu_base_addr;
#ifdef CONFIG_ZONE_DMA
/*
* Adjust the zones if there are restrictions for DMA access.
*/
void __init realview_adjust_zones(int node, unsigned long *size,
unsigned long *hole)
{
unsigned long dma_size = SZ_256M >> PAGE_SHIFT;
if (!machine_is_realview_pbx() || node || (size[0] <= dma_size))
return;
size[ZONE_NORMAL] = size[0] - dma_size;
size[ZONE_DMA] = dma_size;
hole[ZONE_NORMAL] = hole[0];
hole[ZONE_DMA] = 0;
}
#endif
/* /*
* This is the RealView sched_clock implementation. This has * This is the RealView sched_clock implementation. This has
* a resolution of 41.7ns, and a maximum value of about 179s. * a resolution of 41.7ns, and a maximum value of about 179s.
...@@ -543,7 +562,7 @@ static int realview_clcd_setup(struct clcd_fb *fb) ...@@ -543,7 +562,7 @@ static int realview_clcd_setup(struct clcd_fb *fb)
fb->panel = realview_clcd_panel(); fb->panel = realview_clcd_panel();
fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
&dma, GFP_KERNEL); &dma, GFP_KERNEL | GFP_DMA);
if (!fb->fb.screen_base) { if (!fb->fb.screen_base) {
printk(KERN_ERR "CLCD: unable to map framebuffer\n"); printk(KERN_ERR "CLCD: unable to map framebuffer\n");
return -ENOMEM; return -ENOMEM;
...@@ -788,3 +807,24 @@ void __init realview_timer_init(unsigned int timer_irq) ...@@ -788,3 +807,24 @@ void __init realview_timer_init(unsigned int timer_irq)
realview_clocksource_init(); realview_clocksource_init();
realview_clockevents_init(timer_irq); realview_clockevents_init(timer_irq);
} }
/*
* Setup the memory banks.
*/
void realview_fixup(struct machine_desc *mdesc, struct tag *tags, char **from,
struct meminfo *meminfo)
{
/*
* Most RealView platforms have 512MB contiguous RAM at 0x70000000.
* Half of this is mirrored at 0.
*/
#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
meminfo->bank[0].start = 0x70000000;
meminfo->bank[0].size = SZ_512M;
meminfo->nr_banks = 1;
#else
meminfo->bank[0].start = 0;
meminfo->bank[0].size = SZ_256M;
meminfo->nr_banks = 1;
#endif
}
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/setup.h>
#include <asm/leds.h> #include <asm/leds.h>
#define AMBA_DEVICE(name,busid,base,plat) \ #define AMBA_DEVICE(name,busid,base,plat) \
...@@ -44,6 +45,8 @@ static struct amba_device name##_device = { \ ...@@ -44,6 +45,8 @@ static struct amba_device name##_device = { \
/* .dma = base##_DMA,*/ \ /* .dma = base##_DMA,*/ \
} }
struct machine_desc;
extern struct platform_device realview_flash_device; extern struct platform_device realview_flash_device;
extern struct platform_device realview_cf_device; extern struct platform_device realview_cf_device;
extern struct platform_device realview_i2c_device; extern struct platform_device realview_i2c_device;
...@@ -61,5 +64,8 @@ extern void realview_timer_init(unsigned int timer_irq); ...@@ -61,5 +64,8 @@ extern void realview_timer_init(unsigned int timer_irq);
extern int realview_flash_register(struct resource *res, u32 num); extern int realview_flash_register(struct resource *res, u32 num);
extern int realview_eth_register(const char *name, struct resource *res); extern int realview_eth_register(const char *name, struct resource *res);
extern int realview_usb_register(struct resource *res); extern int realview_usb_register(struct resource *res);
extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags,
char **from, struct meminfo *meminfo);
extern void (*realview_reset)(char);
#endif #endif
...@@ -73,4 +73,9 @@ ...@@ -73,4 +73,9 @@
#define REALVIEW_PB1176_GIC_DIST_BASE 0x10041000 /* GIC distributor, on FPGA */ #define REALVIEW_PB1176_GIC_DIST_BASE 0x10041000 /* GIC distributor, on FPGA */
#define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */ #define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */
/*
* Control register SYS_RESETCTL is set to 1 to force a soft reset
*/
#define REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL 0x0100
#endif /* __ASM_ARCH_BOARD_PB1176_H */ #endif /* __ASM_ARCH_BOARD_PB1176_H */
...@@ -81,4 +81,16 @@ ...@@ -81,4 +81,16 @@
#define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */ #define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */
#define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */ #define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */
/*
* Values for REALVIEW_SYS_RESET_CTRL
*/
#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR 0x01
#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGINIT 0x02
#define REALVIEW_PB11MP_SYS_CTRL_RESET_DLLRESET 0x03
#define REALVIEW_PB11MP_SYS_CTRL_RESET_PLLRESET 0x04
#define REALVIEW_PB11MP_SYS_CTRL_RESET_POR 0x05
#define REALVIEW_PB11MP_SYS_CTRL_RESET_DoC 0x06
#define REALVIEW_PB11MP_SYS_CTRL_LED (1 << 0)
#endif /* __ASM_ARCH_BOARD_PB11MP_H */ #endif /* __ASM_ARCH_BOARD_PB11MP_H */
...@@ -29,4 +29,53 @@ ...@@ -29,4 +29,53 @@
#define PHYS_OFFSET UL(0x00000000) #define PHYS_OFFSET UL(0x00000000)
#endif #endif
#if !defined(__ASSEMBLY__) && defined(CONFIG_ZONE_DMA)
extern void realview_adjust_zones(int node, unsigned long *size,
unsigned long *hole);
#define arch_adjust_zones(node, size, hole) \
realview_adjust_zones(node, size, hole)
#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_256M - 1)
#define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_256M)
#endif
#ifdef CONFIG_SPARSEMEM
/*
* Sparsemem definitions for RealView PBX.
*
* The RealView PBX board has another block of 512MB of RAM at 0x20000000,
* however only the block at 0x70000000 (or the 256MB mirror at 0x00000000)
* may be used for DMA.
*
* The macros below define a section size of 256MB and a non-linear virtual to
* physical mapping:
*
* 256MB @ 0x00000000 -> PAGE_OFFSET
* 512MB @ 0x20000000 -> PAGE_OFFSET + 0x10000000
* 256MB @ 0x80000000 -> PAGE_OFFSET + 0x30000000
*/
#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
#error "SPARSEMEM not available with REALVIEW_HIGH_PHYS_OFFSET"
#endif
#define MAX_PHYSMEM_BITS 32
#define SECTION_SIZE_BITS 28
/* bank page offsets */
#define PAGE_OFFSET1 (PAGE_OFFSET + 0x10000000)
#define PAGE_OFFSET2 (PAGE_OFFSET + 0x30000000)
#define __phys_to_virt(phys) \
((phys) >= 0x80000000 ? (phys) - 0x80000000 + PAGE_OFFSET2 : \
(phys) >= 0x20000000 ? (phys) - 0x20000000 + PAGE_OFFSET1 : \
(phys) + PAGE_OFFSET)
#define __virt_to_phys(virt) \
((virt) >= PAGE_OFFSET2 ? (virt) - PAGE_OFFSET2 + 0x80000000 : \
(virt) >= PAGE_OFFSET1 ? (virt) - PAGE_OFFSET1 + 0x20000000 : \
(virt) - PAGE_OFFSET)
#endif /* CONFIG_SPARSEMEM */
#endif #endif
...@@ -119,19 +119,6 @@ ...@@ -119,19 +119,6 @@
#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET) #define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET) #define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
/*
* Values for REALVIEW_SYS_RESET_CTRL
*/
#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01
#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02
#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03
#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04
#define REALVIEW_SYS_CTRL_RESET_POR 0x05
#define REALVIEW_SYS_CTRL_RESET_DoC 0x06
#define REALVIEW_SYS_CTRL_LED (1 << 0)
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
* RealView control registers * RealView control registers
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
...@@ -153,7 +140,7 @@ ...@@ -153,7 +140,7 @@
* SYS_CLD, SYS_BOOTCS * SYS_CLD, SYS_BOOTCS
*/ */
#define REALVIEW_SYS_LOCK_LOCKED (1 << 16) #define REALVIEW_SYS_LOCK_LOCKED (1 << 16)
#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */ #define REALVIEW_SYS_LOCKVAL_MASK 0xA05F /* Enable write access */
/* /*
* REALVIEW_SYS_FLASH * REALVIEW_SYS_FLASH
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/platform.h> #include <mach/platform.h>
void (*realview_reset)(char mode);
static inline void arch_idle(void) static inline void arch_idle(void)
{ {
/* /*
...@@ -36,16 +38,12 @@ static inline void arch_idle(void) ...@@ -36,16 +38,12 @@ static inline void arch_idle(void)
static inline void arch_reset(char mode, const char *cmd) static inline void arch_reset(char mode, const char *cmd)
{ {
void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET;
unsigned int val;
/* /*
* To reset, we hit the on-board reset register * To reset, we hit the on-board reset register
* in the system FPGA * in the system FPGA
*/ */
val = __raw_readl(hdr_ctrl); if (realview_reset)
val |= REALVIEW_SYS_CTRL_RESET_CONFIGCLR; realview_reset(mode);
__raw_writel(val, hdr_ctrl);
} }
#endif #endif
...@@ -146,11 +146,8 @@ static void __init poke_milo(void) ...@@ -146,11 +146,8 @@ static void __init poke_milo(void)
* register. The BootMonitor waits for this register to become * register. The BootMonitor waits for this register to become
* non-zero. * non-zero.
*/ */
#define REALVIEW_SYS_FLAGSS_OFFSET 0x30
#define REALVIEW_SYS_FLAGSC_OFFSET 0x34
__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)), __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
__io_address(REALVIEW_SYS_BASE) + __io_address(REALVIEW_SYS_FLAGSSET));
REALVIEW_SYS_FLAGSS_OFFSET);
mb(); mb();
} }
......
...@@ -415,6 +415,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB") ...@@ -415,6 +415,7 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
.phys_io = REALVIEW_EB_UART0_BASE, .phys_io = REALVIEW_EB_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_EB_UART0_BASE) >> 18) & 0xfffc, .io_pg_offst = (IO_ADDRESS(REALVIEW_EB_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100, .boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_eb_map_io, .map_io = realview_eb_map_io,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_eb_timer, .timer = &realview_eb_timer,
......
...@@ -290,6 +290,28 @@ static struct sys_timer realview_pb1176_timer = { ...@@ -290,6 +290,28 @@ static struct sys_timer realview_pb1176_timer = {
.init = realview_pb1176_timer_init, .init = realview_pb1176_timer_init,
}; };
static void realview_pb1176_reset(char mode)
{
void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
REALVIEW_SYS_RESETCTL_OFFSET;
void __iomem *rst_hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
REALVIEW_SYS_LOCK_OFFSET;
__raw_writel(REALVIEW_SYS_LOCKVAL_MASK, rst_hdr_ctrl);
__raw_writel(REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL, hdr_ctrl);
}
static void realview_pb1176_fixup(struct machine_desc *mdesc,
struct tag *tags, char **from,
struct meminfo *meminfo)
{
/*
* RealView PB1176 only has 128MB of RAM mapped at 0.
*/
meminfo->bank[0].start = 0;
meminfo->bank[0].size = SZ_128M;
meminfo->nr_banks = 1;
}
static void __init realview_pb1176_init(void) static void __init realview_pb1176_init(void)
{ {
int i; int i;
...@@ -313,6 +335,7 @@ static void __init realview_pb1176_init(void) ...@@ -313,6 +335,7 @@ static void __init realview_pb1176_init(void)
#ifdef CONFIG_LEDS #ifdef CONFIG_LEDS
leds_event = realview_leds_event; leds_event = realview_leds_event;
#endif #endif
realview_reset = realview_pb1176_reset;
} }
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176") MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
...@@ -320,6 +343,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176") ...@@ -320,6 +343,7 @@ MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
.phys_io = REALVIEW_PB1176_UART0_BASE, .phys_io = REALVIEW_PB1176_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PB1176_UART0_BASE) >> 18) & 0xfffc, .io_pg_offst = (IO_ADDRESS(REALVIEW_PB1176_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100, .boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_pb1176_fixup,
.map_io = realview_pb1176_map_io, .map_io = realview_pb1176_map_io,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_pb1176_timer, .timer = &realview_pb1176_timer,
......
...@@ -299,6 +299,21 @@ static struct sys_timer realview_pb11mp_timer = { ...@@ -299,6 +299,21 @@ static struct sys_timer realview_pb11mp_timer = {
.init = realview_pb11mp_timer_init, .init = realview_pb11mp_timer_init,
}; };
static void realview_pb11mp_reset(char mode)
{
void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
REALVIEW_SYS_RESETCTL_OFFSET;
unsigned int val;
/*
* To reset, we hit the on-board reset register
* in the system FPGA
*/
val = __raw_readl(hdr_ctrl);
val |= REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR;
__raw_writel(val, hdr_ctrl);
}
static void __init realview_pb11mp_init(void) static void __init realview_pb11mp_init(void)
{ {
int i; int i;
...@@ -324,6 +339,7 @@ static void __init realview_pb11mp_init(void) ...@@ -324,6 +339,7 @@ static void __init realview_pb11mp_init(void)
#ifdef CONFIG_LEDS #ifdef CONFIG_LEDS
leds_event = realview_leds_event; leds_event = realview_leds_event;
#endif #endif
realview_reset = realview_pb11mp_reset;
} }
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
...@@ -331,6 +347,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") ...@@ -331,6 +347,7 @@ MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
.phys_io = REALVIEW_PB11MP_UART0_BASE, .phys_io = REALVIEW_PB11MP_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE) >> 18) & 0xfffc, .io_pg_offst = (IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100, .boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_pb11mp_map_io, .map_io = realview_pb11mp_map_io,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_pb11mp_timer, .timer = &realview_pb11mp_timer,
......
...@@ -298,6 +298,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8") ...@@ -298,6 +298,7 @@ MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
.phys_io = REALVIEW_PBA8_UART0_BASE, .phys_io = REALVIEW_PBA8_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PBA8_UART0_BASE) >> 18) & 0xfffc, .io_pg_offst = (IO_ADDRESS(REALVIEW_PBA8_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100, .boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_pba8_map_io, .map_io = realview_pba8_map_io,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_pba8_timer, .timer = &realview_pba8_timer,
......
...@@ -304,6 +304,26 @@ static struct sys_timer realview_pbx_timer = { ...@@ -304,6 +304,26 @@ static struct sys_timer realview_pbx_timer = {
.init = realview_pbx_timer_init, .init = realview_pbx_timer_init,
}; };
static void realview_pbx_fixup(struct machine_desc *mdesc, struct tag *tags,
char **from, struct meminfo *meminfo)
{
#ifdef CONFIG_SPARSEMEM
/*
* Memory configuration with SPARSEMEM enabled on RealView PBX (see
* asm/mach/memory.h for more information).
*/
meminfo->bank[0].start = 0;
meminfo->bank[0].size = SZ_256M;
meminfo->bank[1].start = 0x20000000;
meminfo->bank[1].size = SZ_512M;
meminfo->bank[2].start = 0x80000000;
meminfo->bank[2].size = SZ_256M;
meminfo->nr_banks = 3;
#else
realview_fixup(mdesc, tags, from, meminfo);
#endif
}
static void __init realview_pbx_init(void) static void __init realview_pbx_init(void)
{ {
int i; int i;
...@@ -345,6 +365,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") ...@@ -345,6 +365,7 @@ MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
.phys_io = REALVIEW_PBX_UART0_BASE, .phys_io = REALVIEW_PBX_UART0_BASE,
.io_pg_offst = (IO_ADDRESS(REALVIEW_PBX_UART0_BASE) >> 18) & 0xfffc, .io_pg_offst = (IO_ADDRESS(REALVIEW_PBX_UART0_BASE) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x00000100, .boot_params = PHYS_OFFSET + 0x00000100,
.fixup = realview_pbx_fixup,
.map_io = realview_pbx_map_io, .map_io = realview_pbx_map_io,
.init_irq = gic_init_irq, .init_irq = gic_init_irq,
.timer = &realview_pbx_timer, .timer = &realview_pbx_timer,
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-fns.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
......
...@@ -110,6 +110,8 @@ enum s3c2410_dma_loadst { ...@@ -110,6 +110,8 @@ enum s3c2410_dma_loadst {
* waiting for reloads */ * waiting for reloads */
#define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */ #define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */
#define S3C2410_DMAF_CIRCULAR (1 << 2) /* no circular dma support */
/* dma buffer */ /* dma buffer */
struct s3c2410_dma_buf; struct s3c2410_dma_buf;
...@@ -194,4 +196,9 @@ struct s3c2410_dma_chan { ...@@ -194,4 +196,9 @@ struct s3c2410_dma_chan {
typedef unsigned long dma_device_t; typedef unsigned long dma_device_t;
static inline bool s3c_dma_has_circular(void)
{
return false;
}
#endif /* __ASM_ARCH_DMA_H */ #endif /* __ASM_ARCH_DMA_H */
...@@ -103,6 +103,7 @@ config MACH_MINI2440 ...@@ -103,6 +103,7 @@ config MACH_MINI2440
select LEDS_TRIGGER_BACKLIGHT select LEDS_TRIGGER_BACKLIGHT
select SND_S3C24XX_SOC_S3C24XX_UDA134X select SND_S3C24XX_SOC_S3C24XX_UDA134X
select S3C_DEV_NAND select S3C_DEV_NAND
select S3C_DEV_USB_HOST
help help
Say Y here to select support for the MINI2440. Is a 10cm x 10cm board Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
available via various sources. It can come with a 3.5" or 7" touch LCD. available via various sources. It can come with a 3.5" or 7" touch LCD.
......
...@@ -144,7 +144,7 @@ static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = { ...@@ -144,7 +144,7 @@ static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = {
.type = (S3C2410_LCDCON1_TFT16BPP |\ .type = (S3C2410_LCDCON1_TFT16BPP |\
S3C2410_LCDCON1_TFT) S3C2410_LCDCON1_TFT)
struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = { static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
[0] = { /* mini2440 + 3.5" TFT + touchscreen */ [0] = { /* mini2440 + 3.5" TFT + touchscreen */
_LCD_DECLARE( _LCD_DECLARE(
7, /* The 3.5 is quite fast */ 7, /* The 3.5 is quite fast */
...@@ -191,7 +191,7 @@ struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = { ...@@ -191,7 +191,7 @@ struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2)) #define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2)) #define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
struct s3c2410fb_mach_info mini2440_fb_info __initdata = { static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
.displays = &mini2440_lcd_cfg[0], /* not constant! see init */ .displays = &mini2440_lcd_cfg[0], /* not constant! see init */
.num_displays = 1, .num_displays = 1,
.default_display = 0, .default_display = 0,
......
...@@ -58,12 +58,9 @@ enum dma_ch { ...@@ -58,12 +58,9 @@ enum dma_ch {
DMACH_MAX /* the end */ DMACH_MAX /* the end */
}; };
static __inline__ int s3c_dma_has_circular(void) static __inline__ bool s3c_dma_has_circular(void)
{ {
/* we will be supporting ciruclar buffers as soon as we have DMA return true;
* engine support.
*/
return 1;
} }
#define S3C2410_DMAF_CIRCULAR (1 << 0) #define S3C2410_DMAF_CIRCULAR (1 << 0)
......
...@@ -77,6 +77,7 @@ config SMDK6410_WM1190_EV1 ...@@ -77,6 +77,7 @@ config SMDK6410_WM1190_EV1
depends on MACH_SMDK6410 depends on MACH_SMDK6410
select REGULATOR select REGULATOR
select REGULATOR_WM8350 select REGULATOR_WM8350
select S3C24XX_GPIO_EXTRA64
select MFD_WM8350_I2C select MFD_WM8350_I2C
select MFD_WM8350_CONFIG_MODE_0 select MFD_WM8350_CONFIG_MODE_0
select MFD_WM8350_CONFIG_MODE_3 select MFD_WM8350_CONFIG_MODE_3
......
...@@ -320,6 +320,9 @@ static int __init smdk6410_wm8350_init(struct wm8350 *wm8350) ...@@ -320,6 +320,9 @@ static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
{ {
int i; int i;
/* Configure the IRQ line */
s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
/* Instantiate the regulators */ /* Instantiate the regulators */
for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++) for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
wm8350_register_regulator(wm8350, wm8350_register_regulator(wm8350,
......
...@@ -50,10 +50,7 @@ void __new_context(struct mm_struct *mm) ...@@ -50,10 +50,7 @@ void __new_context(struct mm_struct *mm)
isb(); isb();
flush_tlb_all(); flush_tlb_all();
if (icache_is_vivt_asid_tagged()) { if (icache_is_vivt_asid_tagged()) {
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" __flush_icache_all();
"mcr p15, 0, %0, c7, c5, 6 @ flush BTAC/BTB\n"
:
: "r" (0));
dsb(); dsb();
} }
} }
......
...@@ -205,7 +205,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, ...@@ -205,7 +205,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
order = get_order(size); order = get_order(size);
if (mask != 0xffffffff) if (mask < 0xffffffffULL)
gfp |= GFP_DMA; gfp |= GFP_DMA;
page = alloc_pages(gfp, order); page = alloc_pages(gfp, order);
...@@ -289,7 +289,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, ...@@ -289,7 +289,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
if (!mask) if (!mask)
goto error; goto error;
if (mask != 0xffffffff) if (mask < 0xffffffffULL)
gfp |= GFP_DMA; gfp |= GFP_DMA;
virt = kmalloc(size, gfp); virt = kmalloc(size, gfp);
if (!virt) if (!virt)
......
...@@ -18,10 +18,6 @@ ...@@ -18,10 +18,6 @@
#include "mm.h" #include "mm.h"
#ifdef CONFIG_ARM_ERRATA_411920
extern void v6_icache_inval_all(void);
#endif
#ifdef CONFIG_CPU_CACHE_VIPT #ifdef CONFIG_CPU_CACHE_VIPT
#define ALIAS_FLUSH_START 0xffff4000 #define ALIAS_FLUSH_START 0xffff4000
...@@ -35,16 +31,11 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) ...@@ -35,16 +31,11 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
flush_tlb_kernel_page(to); flush_tlb_kernel_page(to);
asm( "mcrr p15, 0, %1, %0, c14\n" asm( "mcrr p15, 0, %1, %0, c14\n"
" mcr p15, 0, %2, c7, c10, 4\n" " mcr p15, 0, %2, c7, c10, 4"
#ifndef CONFIG_ARM_ERRATA_411920
" mcr p15, 0, %2, c7, c5, 0\n"
#endif
: :
: "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero) : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
: "cc"); : "cc");
#ifdef CONFIG_ARM_ERRATA_411920 __flush_icache_all();
v6_icache_inval_all();
#endif
} }
void flush_cache_mm(struct mm_struct *mm) void flush_cache_mm(struct mm_struct *mm)
...@@ -57,16 +48,11 @@ void flush_cache_mm(struct mm_struct *mm) ...@@ -57,16 +48,11 @@ void flush_cache_mm(struct mm_struct *mm)
if (cache_is_vipt_aliasing()) { if (cache_is_vipt_aliasing()) {
asm( "mcr p15, 0, %0, c7, c14, 0\n" asm( "mcr p15, 0, %0, c7, c14, 0\n"
" mcr p15, 0, %0, c7, c10, 4\n" " mcr p15, 0, %0, c7, c10, 4"
#ifndef CONFIG_ARM_ERRATA_411920
" mcr p15, 0, %0, c7, c5, 0\n"
#endif
: :
: "r" (0) : "r" (0)
: "cc"); : "cc");
#ifdef CONFIG_ARM_ERRATA_411920 __flush_icache_all();
v6_icache_inval_all();
#endif
} }
} }
...@@ -81,16 +67,11 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned ...@@ -81,16 +67,11 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
if (cache_is_vipt_aliasing()) { if (cache_is_vipt_aliasing()) {
asm( "mcr p15, 0, %0, c7, c14, 0\n" asm( "mcr p15, 0, %0, c7, c14, 0\n"
" mcr p15, 0, %0, c7, c10, 4\n" " mcr p15, 0, %0, c7, c10, 4"
#ifndef CONFIG_ARM_ERRATA_411920
" mcr p15, 0, %0, c7, c5, 0\n"
#endif
: :
: "r" (0) : "r" (0)
: "cc"); : "cc");
#ifdef CONFIG_ARM_ERRATA_411920 __flush_icache_all();
v6_icache_inval_all();
#endif
} }
} }
......
...@@ -273,7 +273,6 @@ static void __init bootmem_init_node(int node, struct meminfo *mi, ...@@ -273,7 +273,6 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
struct membank *bank = &mi->bank[i]; struct membank *bank = &mi->bank[i];
if (!bank->highmem) if (!bank->highmem)
free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank)); free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
} }
/* /*
...@@ -370,6 +369,19 @@ int pfn_valid(unsigned long pfn) ...@@ -370,6 +369,19 @@ int pfn_valid(unsigned long pfn)
return 0; return 0;
} }
EXPORT_SYMBOL(pfn_valid); EXPORT_SYMBOL(pfn_valid);
static void arm_memory_present(struct meminfo *mi, int node)
{
}
#else
static void arm_memory_present(struct meminfo *mi, int node)
{
int i;
for_each_nodebank(i, mi, node) {
struct membank *bank = &mi->bank[i];
memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
}
}
#endif #endif
static int __init meminfo_cmp(const void *_a, const void *_b) static int __init meminfo_cmp(const void *_a, const void *_b)
...@@ -427,6 +439,12 @@ void __init bootmem_init(void) ...@@ -427,6 +439,12 @@ void __init bootmem_init(void)
*/ */
if (node == initrd_node) if (node == initrd_node)
bootmem_reserve_initrd(node); bootmem_reserve_initrd(node);
/*
* Sparsemem tries to allocate bootmem in memory_present(),
* so must be done after the fixed reservations
*/
arm_memory_present(mi, node);
} }
/* /*
......
...@@ -117,6 +117,13 @@ static void __init early_cachepolicy(char **p) ...@@ -117,6 +117,13 @@ static void __init early_cachepolicy(char **p)
} }
if (i == ARRAY_SIZE(cache_policies)) if (i == ARRAY_SIZE(cache_policies))
printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
/*
* This restriction is partly to do with the way we boot; it is
* unpredictable to have memory mapped using two different sets of
* memory attributes (shared, type, and cache attribs). We can not
* change these attributes once the initial assembly has setup the
* page tables.
*/
if (cpu_architecture() >= CPU_ARCH_ARMv6) { if (cpu_architecture() >= CPU_ARCH_ARMv6) {
printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n"); printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
cachepolicy = CPOLICY_WRITEBACK; cachepolicy = CPOLICY_WRITEBACK;
......
...@@ -32,8 +32,10 @@ ...@@ -32,8 +32,10 @@
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
#define TTB_FLAGS TTB_RGN_WBWA #define TTB_FLAGS TTB_RGN_WBWA
#define PMD_FLAGS PMD_SECT_WB
#else #else
#define TTB_FLAGS TTB_RGN_WBWA|TTB_S #define TTB_FLAGS TTB_RGN_WBWA|TTB_S
#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
#endif #endif
ENTRY(cpu_v6_proc_init) ENTRY(cpu_v6_proc_init)
...@@ -222,10 +224,9 @@ __v6_proc_info: ...@@ -222,10 +224,9 @@ __v6_proc_info:
.long 0x0007b000 .long 0x0007b000
.long 0x0007f000 .long 0x0007f000
.long PMD_TYPE_SECT | \ .long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \ PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ PMD_SECT_AP_READ | \
PMD_FLAGS
.long PMD_TYPE_SECT | \ .long PMD_TYPE_SECT | \
PMD_SECT_XN | \ PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \ PMD_SECT_AP_WRITE | \
......
...@@ -33,9 +33,11 @@ ...@@ -33,9 +33,11 @@
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
/* PTWs cacheable, inner WB not shareable, outer WB not shareable */ /* PTWs cacheable, inner WB not shareable, outer WB not shareable */
#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB #define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB
#define PMD_FLAGS PMD_SECT_WB
#else #else
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */ /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA #define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
#endif #endif
ENTRY(cpu_v7_proc_init) ENTRY(cpu_v7_proc_init)
...@@ -184,9 +186,10 @@ cpu_v7_name: ...@@ -184,9 +186,10 @@ cpu_v7_name:
*/ */
__v7_setup: __v7_setup:
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode and mrc p15, 0, r0, c1, c0, 1
orr r0, r0, #(1 << 6) | (1 << 0) @ TLB ops broadcasting tst r0, #(1 << 6) @ SMP/nAMP mode enabled?
mcr p15, 0, r0, c1, c0, 1 orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and
mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting
#endif #endif
adr r12, __v7_setup_stack @ the local stack adr r12, __v7_setup_stack @ the local stack
stmia r12, {r0-r5, r7, r9, r11, lr} stmia r12, {r0-r5, r7, r9, r11, lr}
...@@ -326,10 +329,9 @@ __v7_proc_info: ...@@ -326,10 +329,9 @@ __v7_proc_info:
.long 0x000f0000 @ Required ID value .long 0x000f0000 @ Required ID value
.long 0x000f0000 @ Mask for ID .long 0x000f0000 @ Mask for ID
.long PMD_TYPE_SECT | \ .long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \ PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ PMD_SECT_AP_READ | \
PMD_FLAGS
.long PMD_TYPE_SECT | \ .long PMD_TYPE_SECT | \
PMD_SECT_XN | \ PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \ PMD_SECT_AP_WRITE | \
......
...@@ -189,7 +189,7 @@ int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch) ...@@ -189,7 +189,7 @@ int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
err: err:
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(s3c_adc_convert); EXPORT_SYMBOL_GPL(s3c_adc_read);
static void s3c_adc_default_select(struct s3c_adc_client *client, static void s3c_adc_default_select(struct s3c_adc_client *client,
unsigned select) unsigned select)
......
...@@ -61,6 +61,7 @@ static const char name_s3c2410[] = "S3C2410"; ...@@ -61,6 +61,7 @@ static const char name_s3c2410[] = "S3C2410";
static const char name_s3c2412[] = "S3C2412"; static const char name_s3c2412[] = "S3C2412";
static const char name_s3c2440[] = "S3C2440"; static const char name_s3c2440[] = "S3C2440";
static const char name_s3c2442[] = "S3C2442"; static const char name_s3c2442[] = "S3C2442";
static const char name_s3c2442b[] = "S3C2442B";
static const char name_s3c2443[] = "S3C2443"; static const char name_s3c2443[] = "S3C2443";
static const char name_s3c2410a[] = "S3C2410A"; static const char name_s3c2410a[] = "S3C2410A";
static const char name_s3c2440a[] = "S3C2440A"; static const char name_s3c2440a[] = "S3C2440A";
...@@ -111,6 +112,15 @@ static struct cpu_table cpu_ids[] __initdata = { ...@@ -111,6 +112,15 @@ static struct cpu_table cpu_ids[] __initdata = {
.init = s3c2442_init, .init = s3c2442_init,
.name = name_s3c2442 .name = name_s3c2442
}, },
{
.idcode = 0x32440aab,
.idmask = 0xffffffff,
.map_io = s3c244x_map_io,
.init_clocks = s3c244x_init_clocks,
.init_uarts = s3c244x_init_uarts,
.init = s3c2442_init,
.name = name_s3c2442b
},
{ {
.idcode = 0x32412001, .idcode = 0x32412001,
.idmask = 0xffffffff, .idmask = 0xffffffff,
......
...@@ -208,14 +208,14 @@ s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan, ...@@ -208,14 +208,14 @@ s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
{ {
unsigned long reload; unsigned long reload;
pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
buf, (unsigned long)buf->data, buf->size);
if (buf == NULL) { if (buf == NULL) {
dmawarn("buffer is NULL\n"); dmawarn("buffer is NULL\n");
return -EINVAL; return -EINVAL;
} }
pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
buf, (unsigned long)buf->data, buf->size);
/* check the state of the channel before we do anything */ /* check the state of the channel before we do anything */
if (chan->load_state == S3C2410_DMALOAD_1LOADED) { if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/gpio-fns.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
......
...@@ -222,7 +222,9 @@ extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *); ...@@ -222,7 +222,9 @@ extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
/* S3C2410 and compatible exported functions */ /* S3C2410 and compatible exported functions */
extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg); extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
#ifdef CONFIG_S3C2410_IOTIMING
extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg, extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
struct s3c_iotimings *iot); struct s3c_iotimings *iot);
...@@ -231,8 +233,11 @@ extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg, ...@@ -231,8 +233,11 @@ extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg, extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
struct s3c_iotimings *iot); struct s3c_iotimings *iot);
#else
extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg); #define s3c2410_iotiming_calc NULL
#define s3c2410_iotiming_get NULL
#define s3c2410_iotiming_set NULL
#endif /* CONFIG_S3C2410_IOTIMING */
/* S3C2412 compatible routines */ /* S3C2412 compatible routines */
......
...@@ -27,6 +27,7 @@ extern void s3c2410_init_clocks(int xtal); ...@@ -27,6 +27,7 @@ extern void s3c2410_init_clocks(int xtal);
#define s3c2410_init_uarts NULL #define s3c2410_init_uarts NULL
#define s3c2410_map_io NULL #define s3c2410_map_io NULL
#define s3c2410_init NULL #define s3c2410_init NULL
#define s3c2410a_init NULL
#endif #endif
extern int s3c2410_baseclk_add(void); extern int s3c2410_baseclk_add(void);
...@@ -151,8 +151,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan, ...@@ -151,8 +151,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
src = chan->dev_addr; src = chan->dev_addr;
dst = data; dst = data;
control0 = PL080_CONTROL_SRC_AHB2; control0 = PL080_CONTROL_SRC_AHB2;
control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
control0 |= 2 << PL080_CONTROL_DWIDTH_SHIFT;
control0 |= PL080_CONTROL_DST_INCR; control0 |= PL080_CONTROL_DST_INCR;
break; break;
...@@ -160,8 +158,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan, ...@@ -160,8 +158,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
src = data; src = data;
dst = chan->dev_addr; dst = chan->dev_addr;
control0 = PL080_CONTROL_DST_AHB2; control0 = PL080_CONTROL_DST_AHB2;
control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
control0 |= 2 << PL080_CONTROL_SWIDTH_SHIFT;
control0 |= PL080_CONTROL_SRC_INCR; control0 |= PL080_CONTROL_SRC_INCR;
break; break;
default: default:
...@@ -173,6 +169,8 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan, ...@@ -173,6 +169,8 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
control1 = size >> chan->hw_width; /* size in no of xfers */ control1 = size >> chan->hw_width; /* size in no of xfers */
control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */ control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */
control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */ control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */
control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
lli->src_addr = src; lli->src_addr = src;
lli->dst_addr = dst; lli->dst_addr = dst;
...@@ -339,6 +337,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, ...@@ -339,6 +337,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
struct s3c64xx_dma_buff *next; struct s3c64xx_dma_buff *next;
struct s3c64xx_dma_buff *buff; struct s3c64xx_dma_buff *buff;
struct pl080s_lli *lli; struct pl080s_lli *lli;
unsigned long flags;
int ret; int ret;
WARN_ON(!chan); WARN_ON(!chan);
...@@ -366,6 +365,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, ...@@ -366,6 +365,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
s3c64xx_dma_fill_lli(chan, lli, data, size); s3c64xx_dma_fill_lli(chan, lli, data, size);
local_irq_save(flags);
if ((next = chan->next) != NULL) { if ((next = chan->next) != NULL) {
struct s3c64xx_dma_buff *end = chan->end; struct s3c64xx_dma_buff *end = chan->end;
struct pl080s_lli *endlli = end->lli; struct pl080s_lli *endlli = end->lli;
...@@ -397,6 +398,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, ...@@ -397,6 +398,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
s3c64xx_lli_to_regs(chan, lli); s3c64xx_lli_to_regs(chan, lli);
} }
local_irq_restore(flags);
show_lli(lli); show_lli(lli);
dbg_showchan(chan); dbg_showchan(chan);
...@@ -560,26 +563,11 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) ...@@ -560,26 +563,11 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
EXPORT_SYMBOL(s3c2410_dma_free); EXPORT_SYMBOL(s3c2410_dma_free);
static void s3c64xx_dma_tcirq(struct s3c64xx_dmac *dmac, int offs)
{
struct s3c2410_dma_chan *chan = dmac->channels + offs;
/* note, we currently do not bother to work out which buffer
* or buffers have been completed since the last tc-irq. */
if (chan->callback_fn)
(chan->callback_fn)(chan, chan->curr->pw, 0, S3C2410_RES_OK);
}
static void s3c64xx_dma_errirq(struct s3c64xx_dmac *dmac, int offs)
{
printk(KERN_DEBUG "%s: offs %d\n", __func__, offs);
}
static irqreturn_t s3c64xx_dma_irq(int irq, void *pw) static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
{ {
struct s3c64xx_dmac *dmac = pw; struct s3c64xx_dmac *dmac = pw;
struct s3c2410_dma_chan *chan;
enum s3c2410_dma_buffresult res;
u32 tcstat, errstat; u32 tcstat, errstat;
u32 bit; u32 bit;
int offs; int offs;
...@@ -588,14 +576,54 @@ static irqreturn_t s3c64xx_dma_irq(int irq, void *pw) ...@@ -588,14 +576,54 @@ static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
errstat = readl(dmac->regs + PL080_ERR_STATUS); errstat = readl(dmac->regs + PL080_ERR_STATUS);
for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) { for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
struct s3c64xx_dma_buff *buff;
if (!(errstat & bit) && !(tcstat & bit))
continue;
chan = dmac->channels + offs;
res = S3C2410_RES_ERR;
if (tcstat & bit) { if (tcstat & bit) {
writel(bit, dmac->regs + PL080_TC_CLEAR); writel(bit, dmac->regs + PL080_TC_CLEAR);
s3c64xx_dma_tcirq(dmac, offs); res = S3C2410_RES_OK;
} }
if (errstat & bit) { if (errstat & bit)
s3c64xx_dma_errirq(dmac, offs);
writel(bit, dmac->regs + PL080_ERR_CLEAR); writel(bit, dmac->regs + PL080_ERR_CLEAR);
/* 'next' points to the buffer that is next to the
* currently active buffer.
* For CIRCULAR queues, 'next' will be same as 'curr'
* when 'end' is the active buffer.
*/
buff = chan->curr;
while (buff && buff != chan->next
&& buff->next != chan->next)
buff = buff->next;
if (!buff)
BUG();
if (buff == chan->next)
buff = chan->end;
s3c64xx_dma_bufffdone(chan, buff, res);
/* Free the node and update curr, if non-circular queue */
if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
chan->curr = buff->next;
s3c64xx_dma_freebuff(buff);
}
/* Update 'next' */
buff = chan->next;
if (chan->next == chan->end) {
chan->next = chan->curr;
if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
chan->end = NULL;
} else {
chan->next = buff->next;
} }
} }
......
...@@ -51,8 +51,8 @@ ...@@ -51,8 +51,8 @@
#define S3C6400_CLKDIV0_HCLK_SHIFT (8) #define S3C6400_CLKDIV0_HCLK_SHIFT (8)
#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4) #define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4)
#define S3C6400_CLKDIV0_MPLL_SHIFT (4) #define S3C6400_CLKDIV0_MPLL_SHIFT (4)
#define S3C6400_CLKDIV0_ARM_MASK (0x3 << 0) #define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0)
#define S3C6410_CLKDIV0_ARM_MASK (0x7 << 0) #define S3C6410_CLKDIV0_ARM_MASK (0xf << 0)
#define S3C6400_CLKDIV0_ARM_SHIFT (0) #define S3C6400_CLKDIV0_ARM_SHIFT (0)
/* CLKDIV1 */ /* CLKDIV1 */
......
...@@ -677,6 +677,9 @@ void __init_or_cpufreq s3c6400_setup_clocks(void) ...@@ -677,6 +677,9 @@ void __init_or_cpufreq s3c6400_setup_clocks(void)
printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
/* For now assume the mux always selects the crystal */
clk_ext_xtal_mux.parent = xtal_clk;
epll = s3c6400_get_epll(xtal); epll = s3c6400_get_epll(xtal);
mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON)); mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON)); apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
......
...@@ -31,5 +31,8 @@ ...@@ -31,5 +31,8 @@
#define cpu_is_at91sam9263() (0) #define cpu_is_at91sam9263() (0)
#define cpu_is_at91sam9rl() (0) #define cpu_is_at91sam9rl() (0)
#define cpu_is_at91cap9() (0) #define cpu_is_at91cap9() (0)
#define cpu_is_at91sam9g10() (0)
#define cpu_is_at91sam9g45() (0)
#define cpu_is_at91sam9g45es() (0)
#endif /* __ASM_ARCH_CPU_H */ #endif /* __ASM_ARCH_CPU_H */
...@@ -25,61 +25,82 @@ ...@@ -25,61 +25,82 @@
* by atomically noting the tail and incrementing it by one (thus adding * by atomically noting the tail and incrementing it by one (thus adding
* ourself to the queue and noting our position), then waiting until the head * ourself to the queue and noting our position), then waiting until the head
* becomes equal to the the initial value of the tail. * becomes equal to the the initial value of the tail.
* The pad bits in the middle are used to prevent the next_ticket number
* overflowing into the now_serving number.
* *
* 63 32 31 0 * 31 17 16 15 14 0
* +----------------------------------------------------+ * +----------------------------------------------------+
* | next_ticket_number | now_serving | * | now_serving | padding | next_ticket |
* +----------------------------------------------------+ * +----------------------------------------------------+
*/ */
#define TICKET_SHIFT 32 #define TICKET_SHIFT 17
#define TICKET_BITS 15
#define TICKET_MASK ((1 << TICKET_BITS) - 1)
static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
{ {
int *p = (int *)&lock->lock, turn, now_serving; int *p = (int *)&lock->lock, ticket, serve;
now_serving = *p; ticket = ia64_fetchadd(1, p, acq);
turn = ia64_fetchadd(1, p+1, acq);
if (turn == now_serving) if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK))
return; return;
do { ia64_invala();
for (;;) {
asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(p) : "memory");
if (!(((serve >> TICKET_SHIFT) ^ ticket) & TICKET_MASK))
return;
cpu_relax(); cpu_relax();
} while (ACCESS_ONCE(*p) != turn); }
} }
static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
{ {
long tmp = ACCESS_ONCE(lock->lock), try; int tmp = ACCESS_ONCE(lock->lock);
if (!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1L << TICKET_SHIFT) - 1))) {
try = tmp + (1L << TICKET_SHIFT);
return ia64_cmpxchg(acq, &lock->lock, tmp, try, sizeof (tmp)) == tmp; if (!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK))
} return ia64_cmpxchg(acq, &lock->lock, tmp, tmp + 1, sizeof (tmp)) == tmp;
return 0; return 0;
} }
static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock)
{ {
int *p = (int *)&lock->lock; unsigned short *p = (unsigned short *)&lock->lock + 1, tmp;
(void)ia64_fetchadd(1, p, rel); asm volatile ("ld2.bias %0=[%1]" : "=r"(tmp) : "r"(p));
ACCESS_ONCE(*p) = (tmp + 2) & ~1;
}
static __always_inline void __ticket_spin_unlock_wait(raw_spinlock_t *lock)
{
int *p = (int *)&lock->lock, ticket;
ia64_invala();
for (;;) {
asm volatile ("ld4.c.nc %0=[%1]" : "=r"(ticket) : "r"(p) : "memory");
if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK))
return;
cpu_relax();
}
} }
static inline int __ticket_spin_is_locked(raw_spinlock_t *lock) static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
{ {
long tmp = ACCESS_ONCE(lock->lock); long tmp = ACCESS_ONCE(lock->lock);
return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1L << TICKET_SHIFT) - 1)); return !!(((tmp >> TICKET_SHIFT) ^ tmp) & TICKET_MASK);
} }
static inline int __ticket_spin_is_contended(raw_spinlock_t *lock) static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
{ {
long tmp = ACCESS_ONCE(lock->lock); long tmp = ACCESS_ONCE(lock->lock);
return (((tmp >> TICKET_SHIFT) - tmp) & ((1L << TICKET_SHIFT) - 1)) > 1; return ((tmp - (tmp >> TICKET_SHIFT)) & TICKET_MASK) > 1;
} }
static inline int __raw_spin_is_locked(raw_spinlock_t *lock) static inline int __raw_spin_is_locked(raw_spinlock_t *lock)
...@@ -116,8 +137,7 @@ static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock, ...@@ -116,8 +137,7 @@ static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock,
static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
{ {
while (__raw_spin_is_locked(lock)) __ticket_spin_unlock_wait(lock);
cpu_relax();
} }
#define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0) #define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#endif #endif
typedef struct { typedef struct {
volatile unsigned long lock; volatile unsigned int lock;
} raw_spinlock_t; } raw_spinlock_t;
#define __RAW_SPIN_LOCK_UNLOCKED { 0 } #define __RAW_SPIN_LOCK_UNLOCKED { 0 }
......
...@@ -887,6 +887,60 @@ ia64_mca_modify_comm(const struct task_struct *previous_current) ...@@ -887,6 +887,60 @@ ia64_mca_modify_comm(const struct task_struct *previous_current)
memcpy(current->comm, comm, sizeof(current->comm)); memcpy(current->comm, comm, sizeof(current->comm));
} }
static void
finish_pt_regs(struct pt_regs *regs, const pal_min_state_area_t *ms,
unsigned long *nat)
{
const u64 *bank;
/* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use
* pmsa_{xip,xpsr,xfs}
*/
if (ia64_psr(regs)->ic) {
regs->cr_iip = ms->pmsa_iip;
regs->cr_ipsr = ms->pmsa_ipsr;
regs->cr_ifs = ms->pmsa_ifs;
} else {
regs->cr_iip = ms->pmsa_xip;
regs->cr_ipsr = ms->pmsa_xpsr;
regs->cr_ifs = ms->pmsa_xfs;
}
regs->pr = ms->pmsa_pr;
regs->b0 = ms->pmsa_br0;
regs->ar_rsc = ms->pmsa_rsc;
copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, &regs->r1, nat);
copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, &regs->r2, nat);
copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, &regs->r3, nat);
copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, &regs->r8, nat);
copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, &regs->r9, nat);
copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, &regs->r10, nat);
copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, &regs->r11, nat);
copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, &regs->r12, nat);
copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, &regs->r13, nat);
copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, &regs->r14, nat);
copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, &regs->r15, nat);
if (ia64_psr(regs)->bn)
bank = ms->pmsa_bank1_gr;
else
bank = ms->pmsa_bank0_gr;
copy_reg(&bank[16-16], ms->pmsa_nat_bits, &regs->r16, nat);
copy_reg(&bank[17-16], ms->pmsa_nat_bits, &regs->r17, nat);
copy_reg(&bank[18-16], ms->pmsa_nat_bits, &regs->r18, nat);
copy_reg(&bank[19-16], ms->pmsa_nat_bits, &regs->r19, nat);
copy_reg(&bank[20-16], ms->pmsa_nat_bits, &regs->r20, nat);
copy_reg(&bank[21-16], ms->pmsa_nat_bits, &regs->r21, nat);
copy_reg(&bank[22-16], ms->pmsa_nat_bits, &regs->r22, nat);
copy_reg(&bank[23-16], ms->pmsa_nat_bits, &regs->r23, nat);
copy_reg(&bank[24-16], ms->pmsa_nat_bits, &regs->r24, nat);
copy_reg(&bank[25-16], ms->pmsa_nat_bits, &regs->r25, nat);
copy_reg(&bank[26-16], ms->pmsa_nat_bits, &regs->r26, nat);
copy_reg(&bank[27-16], ms->pmsa_nat_bits, &regs->r27, nat);
copy_reg(&bank[28-16], ms->pmsa_nat_bits, &regs->r28, nat);
copy_reg(&bank[29-16], ms->pmsa_nat_bits, &regs->r29, nat);
copy_reg(&bank[30-16], ms->pmsa_nat_bits, &regs->r30, nat);
copy_reg(&bank[31-16], ms->pmsa_nat_bits, &regs->r31, nat);
}
/* On entry to this routine, we are running on the per cpu stack, see /* On entry to this routine, we are running on the per cpu stack, see
* mca_asm.h. The original stack has not been touched by this event. Some of * mca_asm.h. The original stack has not been touched by this event. Some of
* the original stack's registers will be in the RBS on this stack. This stack * the original stack's registers will be in the RBS on this stack. This stack
...@@ -921,7 +975,6 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, ...@@ -921,7 +975,6 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
u64 r12 = ms->pmsa_gr[12-1], r13 = ms->pmsa_gr[13-1]; u64 r12 = ms->pmsa_gr[12-1], r13 = ms->pmsa_gr[13-1];
u64 ar_bspstore = regs->ar_bspstore; u64 ar_bspstore = regs->ar_bspstore;
u64 ar_bsp = regs->ar_bspstore + (loadrs >> 16); u64 ar_bsp = regs->ar_bspstore + (loadrs >> 16);
const u64 *bank;
const char *msg; const char *msg;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
...@@ -1024,54 +1077,9 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, ...@@ -1024,54 +1077,9 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
p = (char *)r12 - sizeof(*regs); p = (char *)r12 - sizeof(*regs);
old_regs = (struct pt_regs *)p; old_regs = (struct pt_regs *)p;
memcpy(old_regs, regs, sizeof(*regs)); memcpy(old_regs, regs, sizeof(*regs));
/* If ipsr.ic then use pmsa_{iip,ipsr,ifs}, else use
* pmsa_{xip,xpsr,xfs}
*/
if (ia64_psr(regs)->ic) {
old_regs->cr_iip = ms->pmsa_iip;
old_regs->cr_ipsr = ms->pmsa_ipsr;
old_regs->cr_ifs = ms->pmsa_ifs;
} else {
old_regs->cr_iip = ms->pmsa_xip;
old_regs->cr_ipsr = ms->pmsa_xpsr;
old_regs->cr_ifs = ms->pmsa_xfs;
}
old_regs->pr = ms->pmsa_pr;
old_regs->b0 = ms->pmsa_br0;
old_regs->loadrs = loadrs; old_regs->loadrs = loadrs;
old_regs->ar_rsc = ms->pmsa_rsc;
old_unat = old_regs->ar_unat; old_unat = old_regs->ar_unat;
copy_reg(&ms->pmsa_gr[1-1], ms->pmsa_nat_bits, &old_regs->r1, &old_unat); finish_pt_regs(old_regs, ms, &old_unat);
copy_reg(&ms->pmsa_gr[2-1], ms->pmsa_nat_bits, &old_regs->r2, &old_unat);
copy_reg(&ms->pmsa_gr[3-1], ms->pmsa_nat_bits, &old_regs->r3, &old_unat);
copy_reg(&ms->pmsa_gr[8-1], ms->pmsa_nat_bits, &old_regs->r8, &old_unat);
copy_reg(&ms->pmsa_gr[9-1], ms->pmsa_nat_bits, &old_regs->r9, &old_unat);
copy_reg(&ms->pmsa_gr[10-1], ms->pmsa_nat_bits, &old_regs->r10, &old_unat);
copy_reg(&ms->pmsa_gr[11-1], ms->pmsa_nat_bits, &old_regs->r11, &old_unat);
copy_reg(&ms->pmsa_gr[12-1], ms->pmsa_nat_bits, &old_regs->r12, &old_unat);
copy_reg(&ms->pmsa_gr[13-1], ms->pmsa_nat_bits, &old_regs->r13, &old_unat);
copy_reg(&ms->pmsa_gr[14-1], ms->pmsa_nat_bits, &old_regs->r14, &old_unat);
copy_reg(&ms->pmsa_gr[15-1], ms->pmsa_nat_bits, &old_regs->r15, &old_unat);
if (ia64_psr(old_regs)->bn)
bank = ms->pmsa_bank1_gr;
else
bank = ms->pmsa_bank0_gr;
copy_reg(&bank[16-16], ms->pmsa_nat_bits, &old_regs->r16, &old_unat);
copy_reg(&bank[17-16], ms->pmsa_nat_bits, &old_regs->r17, &old_unat);
copy_reg(&bank[18-16], ms->pmsa_nat_bits, &old_regs->r18, &old_unat);
copy_reg(&bank[19-16], ms->pmsa_nat_bits, &old_regs->r19, &old_unat);
copy_reg(&bank[20-16], ms->pmsa_nat_bits, &old_regs->r20, &old_unat);
copy_reg(&bank[21-16], ms->pmsa_nat_bits, &old_regs->r21, &old_unat);
copy_reg(&bank[22-16], ms->pmsa_nat_bits, &old_regs->r22, &old_unat);
copy_reg(&bank[23-16], ms->pmsa_nat_bits, &old_regs->r23, &old_unat);
copy_reg(&bank[24-16], ms->pmsa_nat_bits, &old_regs->r24, &old_unat);
copy_reg(&bank[25-16], ms->pmsa_nat_bits, &old_regs->r25, &old_unat);
copy_reg(&bank[26-16], ms->pmsa_nat_bits, &old_regs->r26, &old_unat);
copy_reg(&bank[27-16], ms->pmsa_nat_bits, &old_regs->r27, &old_unat);
copy_reg(&bank[28-16], ms->pmsa_nat_bits, &old_regs->r28, &old_unat);
copy_reg(&bank[29-16], ms->pmsa_nat_bits, &old_regs->r29, &old_unat);
copy_reg(&bank[30-16], ms->pmsa_nat_bits, &old_regs->r30, &old_unat);
copy_reg(&bank[31-16], ms->pmsa_nat_bits, &old_regs->r31, &old_unat);
/* Next stack a struct switch_stack. mca_asm.S built a partial /* Next stack a struct switch_stack. mca_asm.S built a partial
* switch_stack, copy it and fill in the blanks using pt_regs and * switch_stack, copy it and fill in the blanks using pt_regs and
...@@ -1141,6 +1149,8 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, ...@@ -1141,6 +1149,8 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
no_mod: no_mod:
mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n",
smp_processor_id(), type, msg); smp_processor_id(), type, msg);
old_unat = regs->ar_unat;
finish_pt_regs(regs, ms, &old_unat);
return previous_current; return previous_current;
} }
......
...@@ -60,7 +60,6 @@ dump (const char *str, void *vp, size_t len) ...@@ -60,7 +60,6 @@ dump (const char *str, void *vp, size_t len)
*/ */
int no_unaligned_warning; int no_unaligned_warning;
int unaligned_dump_stack; int unaligned_dump_stack;
static int noprint_warning;
/* /*
* For M-unit: * For M-unit:
...@@ -1357,9 +1356,8 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) ...@@ -1357,9 +1356,8 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
/* watch for command names containing %s */ /* watch for command names containing %s */
printk(KERN_WARNING "%s", buf); printk(KERN_WARNING "%s", buf);
} else { } else {
if (no_unaligned_warning && !noprint_warning) { if (no_unaligned_warning) {
noprint_warning = 1; printk_once(KERN_WARNING "%s(%d) encountered an "
printk(KERN_WARNING "%s(%d) encountered an "
"unaligned exception which required\n" "unaligned exception which required\n"
"kernel assistance, which degrades " "kernel assistance, which degrades "
"the performance of the application.\n" "the performance of the application.\n"
......
...@@ -100,24 +100,36 @@ wrap_mmu_context (struct mm_struct *mm) ...@@ -100,24 +100,36 @@ wrap_mmu_context (struct mm_struct *mm)
* this primitive it can be moved up to a spinaphore.h header. * this primitive it can be moved up to a spinaphore.h header.
*/ */
struct spinaphore { struct spinaphore {
atomic_t cur; unsigned long ticket;
unsigned long serve;
}; };
static inline void spinaphore_init(struct spinaphore *ss, int val) static inline void spinaphore_init(struct spinaphore *ss, int val)
{ {
atomic_set(&ss->cur, val); ss->ticket = 0;
ss->serve = val;
} }
static inline void down_spin(struct spinaphore *ss) static inline void down_spin(struct spinaphore *ss)
{ {
while (unlikely(!atomic_add_unless(&ss->cur, -1, 0))) unsigned long t = ia64_fetchadd(1, &ss->ticket, acq), serve;
while (atomic_read(&ss->cur) == 0)
cpu_relax(); if (time_before(t, ss->serve))
return;
ia64_invala();
for (;;) {
asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
if (time_before(t, serve))
return;
cpu_relax();
}
} }
static inline void up_spin(struct spinaphore *ss) static inline void up_spin(struct spinaphore *ss)
{ {
atomic_add(1, &ss->cur); ia64_fetchadd(1, &ss->serve, rel);
} }
static struct spinaphore ptcg_sem; static struct spinaphore ptcg_sem;
......
...@@ -56,10 +56,13 @@ int raw_pci_read(unsigned int seg, unsigned int bus, unsigned int devfn, ...@@ -56,10 +56,13 @@ int raw_pci_read(unsigned int seg, unsigned int bus, unsigned int devfn,
if ((seg | reg) <= 255) { if ((seg | reg) <= 255) {
addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg); addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg);
mode = 0; mode = 0;
} else { } else if (sal_revision >= SAL_VERSION_CODE(3,2)) {
addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg); addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg);
mode = 1; mode = 1;
} else {
return -EINVAL;
} }
result = ia64_sal_pci_config_read(addr, mode, len, &data); result = ia64_sal_pci_config_read(addr, mode, len, &data);
if (result != 0) if (result != 0)
return -EINVAL; return -EINVAL;
...@@ -80,9 +83,11 @@ int raw_pci_write(unsigned int seg, unsigned int bus, unsigned int devfn, ...@@ -80,9 +83,11 @@ int raw_pci_write(unsigned int seg, unsigned int bus, unsigned int devfn,
if ((seg | reg) <= 255) { if ((seg | reg) <= 255) {
addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg); addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg);
mode = 0; mode = 0;
} else { } else if (sal_revision >= SAL_VERSION_CODE(3,2)) {
addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg); addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg);
mode = 1; mode = 1;
} else {
return -EINVAL;
} }
result = ia64_sal_pci_config_write(addr, mode, len, value); result = ia64_sal_pci_config_write(addr, mode, len, value);
if (result != 0) if (result != 0)
......
...@@ -119,7 +119,6 @@ sn_pcidev_info_get(struct pci_dev *dev) ...@@ -119,7 +119,6 @@ sn_pcidev_info_get(struct pci_dev *dev)
* Additionally note that the struct sn_flush_device_war also has to be * Additionally note that the struct sn_flush_device_war also has to be
* removed from arch/ia64/sn/include/xtalk/hubdev.h * removed from arch/ia64/sn/include/xtalk/hubdev.h
*/ */
static u8 war_implemented = 0;
static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
struct sn_flush_device_common *common) struct sn_flush_device_common *common)
...@@ -128,11 +127,8 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, ...@@ -128,11 +127,8 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
struct sn_flush_device_war *dev_entry; struct sn_flush_device_war *dev_entry;
struct ia64_sal_retval isrv = {0,0,0,0}; struct ia64_sal_retval isrv = {0,0,0,0};
if (!war_implemented) { printk_once(KERN_WARNING
printk(KERN_WARNING "PROM version < 4.50 -- implementing old " "PROM version < 4.50 -- implementing old PROM flush WAR\n");
"PROM flush WAR\n");
war_implemented = 1;
}
war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
BUG_ON(!war_list); BUG_ON(!war_list);
......
...@@ -786,17 +786,18 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg) ...@@ -786,17 +786,18 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, unsigned long arg)
break; break;
case SN_HWPERF_GET_OBJ_NODE: case SN_HWPERF_GET_OBJ_NODE:
if (a.sz != sizeof(u64) || a.arg < 0) { i = a.arg;
if (a.sz != sizeof(u64) || i < 0) {
r = -EINVAL; r = -EINVAL;
goto error; goto error;
} }
if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) { if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
if (a.arg >= nobj) { if (i >= nobj) {
r = -EINVAL; r = -EINVAL;
vfree(objs); vfree(objs);
goto error; goto error;
} }
if (objs[(i = a.arg)].id != a.arg) { if (objs[i].id != a.arg) {
for (i = 0; i < nobj; i++) { for (i = 0; i < nobj; i++) {
if (objs[i].id == a.arg) if (objs[i].id == a.arg)
break; break;
......
...@@ -11,6 +11,9 @@ config M32R ...@@ -11,6 +11,9 @@ config M32R
select HAVE_IDE select HAVE_IDE
select HAVE_OPROFILE select HAVE_OPROFILE
select INIT_ALL_POSSIBLE select INIT_ALL_POSSIBLE
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
config SBUS config SBUS
bool bool
......
# #
# linux/arch/sh/boot/compressed/Makefile # linux/arch/m32r/boot/compressed/Makefile
# #
# create a compressed vmlinux image from the original vmlinux # create a compressed vmlinux image from the original vmlinux
# #
targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o \ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
piggy.o vmlinux.lds vmlinux.bin.lzma head.o misc.o piggy.o vmlinux.lds
OBJECTS = $(obj)/head.o $(obj)/misc.o OBJECTS = $(obj)/head.o $(obj)/misc.o
...@@ -27,6 +27,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE ...@@ -27,6 +27,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip) $(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
$(call if_changed,bzip2)
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
$(call if_changed,lzma)
CFLAGS_misc.o += -fpic CFLAGS_misc.o += -fpic
ifdef CONFIG_MMU ifdef CONFIG_MMU
...@@ -37,5 +43,9 @@ endif ...@@ -37,5 +43,9 @@ endif
OBJCOPYFLAGS += -R .empty_zero_page OBJCOPYFLAGS += -R .empty_zero_page
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE suffix_$(CONFIG_KERNEL_GZIP) = gz
suffix_$(CONFIG_KERNEL_BZIP2) = bz2
suffix_$(CONFIG_KERNEL_LZMA) = lzma
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
$(call if_changed,ld) $(call if_changed,ld)
...@@ -9,140 +9,49 @@ ...@@ -9,140 +9,49 @@
* Adapted for SH by Stuart Menefy, Aug 1999 * Adapted for SH by Stuart Menefy, Aug 1999
* *
* 2003-02-12: Support M32R by Takeo Takahashi * 2003-02-12: Support M32R by Takeo Takahashi
* This is based on arch/sh/boot/compressed/misc.c.
*/ */
#include <linux/string.h>
/* /*
* gzip declarations * gzip declarations
*/ */
#define OF(args) args
#define STATIC static #define STATIC static
#undef memset #undef memset
#undef memcpy #undef memcpy
#define memzero(s, n) memset ((s), 0, (n)) #define memzero(s, n) memset ((s), 0, (n))
typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;
#define WSIZE 0x8000 /* Window size must be at least 32k, */
/* and a power of two */
static uch *inbuf; /* input buffer */
static uch window[WSIZE]; /* Sliding window buffer */
static unsigned insize = 0; /* valid bytes in inbuf */
static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
static unsigned outcnt = 0; /* bytes in output buffer */
/* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
#define COMMENT 0x10 /* bit 4 set: file comment present */
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
#define RESERVED 0xC0 /* bit 6,7: reserved */
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
/* Diagnostic functions */
#ifdef DEBUG
# define Assert(cond,msg) {if(!(cond)) error(msg);}
# define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x ;}
# define Tracevv(x) {if (verbose>1) fprintf x ;}
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
#else
# define Assert(cond,msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
# define Tracec(c,x)
# define Tracecv(c,x)
#endif
static int fill_inbuf(void);
static void flush_window(void);
static void error(char *m); static void error(char *m);
static unsigned char *input_data;
static int input_len;
static long bytes_out = 0;
static uch *output_data;
static unsigned long output_ptr = 0;
#include "m32r_sio.c" #include "m32r_sio.c"
static unsigned long free_mem_ptr; static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr; static unsigned long free_mem_end_ptr;
#define HEAP_SIZE 0x10000 #ifdef CONFIG_KERNEL_BZIP2
static void *memset(void *s, int c, size_t n)
#include "../../../../lib/inflate.c"
void* memset(void* s, int c, size_t n)
{ {
int i; char *ss = s;
char *ss = (char*)s;
for (i=0;i<n;i++) ss[i] = c; while (n--)
*ss++ = c;
return s; return s;
} }
#endif
void* memcpy(void* __dest, __const void* __src, #ifdef CONFIG_KERNEL_GZIP
size_t __n) #define BOOT_HEAP_SIZE 0x10000
{ #include "../../../../lib/decompress_inflate.c"
int i; #endif
char *d = (char *)__dest, *s = (char *)__src;
for (i=0;i<__n;i++) d[i] = s[i];
return __dest;
}
/* ===========================================================================
* Fill the input buffer. This is called only when the buffer is empty
* and at least one byte is really needed.
*/
static int fill_inbuf(void)
{
if (insize != 0) {
error("ran out of input data");
}
inbuf = input_data;
insize = input_len;
inptr = 1;
return inbuf[0];
}
/* =========================================================================== #ifdef CONFIG_KERNEL_BZIP2
* Write the output window window[0..outcnt-1] and update crc and bytes_out. #define BOOT_HEAP_SIZE 0x400000
* (Used for the decompressed data only.) #include "../../../../lib/decompress_bunzip2.c"
*/ #endif
static void flush_window(void)
{
ulg c = crc; /* temporary variable */
unsigned n;
uch *in, *out, ch;
in = window; #ifdef CONFIG_KERNEL_LZMA
out = &output_data[output_ptr]; #define BOOT_HEAP_SIZE 0x10000
for (n = 0; n < outcnt; n++) { #include "../../../../lib/decompress_unlzma.c"
ch = *out++ = *in++; #endif
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
}
crc = c;
bytes_out += (ulg)outcnt;
output_ptr += (ulg)outcnt;
outcnt = 0;
}
static void error(char *x) static void error(char *x)
{ {
...@@ -153,20 +62,20 @@ static void error(char *x) ...@@ -153,20 +62,20 @@ static void error(char *x)
while(1); /* Halt */ while(1); /* Halt */
} }
/* return decompressed size */
void void
decompress_kernel(int mmu_on, unsigned char *zimage_data, decompress_kernel(int mmu_on, unsigned char *zimage_data,
unsigned int zimage_len, unsigned long heap) unsigned int zimage_len, unsigned long heap)
{ {
unsigned char *input_data = zimage_data;
int input_len = zimage_len;
unsigned char *output_data;
output_data = (unsigned char *)CONFIG_MEMORY_START + 0x2000 output_data = (unsigned char *)CONFIG_MEMORY_START + 0x2000
+ (mmu_on ? 0x80000000 : 0); + (mmu_on ? 0x80000000 : 0);
free_mem_ptr = heap; free_mem_ptr = heap;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; free_mem_end_ptr = free_mem_ptr + BOOT_HEAP_SIZE;
input_data = zimage_data;
input_len = zimage_len;
makecrc(); puts("\nDecompressing Linux... ");
puts("Uncompressing Linux... "); decompress(input_data, input_len, NULL, NULL, output_data, NULL, error);
gunzip(); puts("done.\nBooting the kernel.\n");
puts("Ok, booting the kernel.\n");
} }
...@@ -806,7 +806,7 @@ unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num, ...@@ -806,7 +806,7 @@ unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num,
if (mask & ~physids_coerce(phys_cpu_present_map)) if (mask & ~physids_coerce(phys_cpu_present_map))
BUG(); BUG();
if (ipi_num >= NR_IPIS) if (ipi_num >= NR_IPIS || ipi_num < 0)
BUG(); BUG();
mask <<= IPI_SHIFT; mask <<= IPI_SHIFT;
......
...@@ -75,7 +75,7 @@ u32 arch_gettimeoffset(void) ...@@ -75,7 +75,7 @@ u32 arch_gettimeoffset(void)
count = 0; count = 0;
count = (latch - count) * TICK_SIZE; count = (latch - count) * TICK_SIZE;
elapsed_time = (count + latch / 2) / latch; elapsed_time = DIV_ROUND_CLOSEST(count, latch);
/* NOTE: LATCH is equal to the "interval" value (= reload count). */ /* NOTE: LATCH is equal to the "interval" value (= reload count). */
#else /* CONFIG_SMP */ #else /* CONFIG_SMP */
...@@ -93,7 +93,7 @@ u32 arch_gettimeoffset(void) ...@@ -93,7 +93,7 @@ u32 arch_gettimeoffset(void)
p_count = count; p_count = count;
count = (latch - count) * TICK_SIZE; count = (latch - count) * TICK_SIZE;
elapsed_time = (count + latch / 2) / latch; elapsed_time = DIV_ROUND_CLOSEST(count, latch);
/* NOTE: LATCH is equal to the "interval" value (= reload count). */ /* NOTE: LATCH is equal to the "interval" value (= reload count). */
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
#elif defined(CONFIG_CHIP_M32310) #elif defined(CONFIG_CHIP_M32310)
...@@ -211,7 +211,7 @@ void __init time_init(void) ...@@ -211,7 +211,7 @@ void __init time_init(void)
bus_clock = boot_cpu_data.bus_clock; bus_clock = boot_cpu_data.bus_clock;
divide = boot_cpu_data.timer_divide; divide = boot_cpu_data.timer_divide;
latch = (bus_clock/divide + HZ / 2) / HZ; latch = DIV_ROUND_CLOSEST(bus_clock/divide, HZ);
printk("Timer start : latch = %ld\n", latch); printk("Timer start : latch = %ld\n", latch);
......
...@@ -42,6 +42,8 @@ SECTIONS ...@@ -42,6 +42,8 @@ SECTIONS
_etext = .; /* End of text section */ _etext = .; /* End of text section */
EXCEPTION_TABLE(16) EXCEPTION_TABLE(16)
NOTES
RODATA RODATA
RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE) RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
_edata = .; /* End of data section */ _edata = .; /* End of data section */
......
...@@ -561,7 +561,7 @@ config HPAPCI ...@@ -561,7 +561,7 @@ config HPAPCI
config MVME147_SCC config MVME147_SCC
bool "SCC support for MVME147 serial ports" bool "SCC support for MVME147 serial ports"
depends on MVME147 depends on MVME147 && BROKEN
help help
This is the driver for the serial ports on the Motorola MVME147 This is the driver for the serial ports on the Motorola MVME147
boards. Everyone using one of these boards should say Y here. boards. Everyone using one of these boards should say Y here.
...@@ -576,14 +576,14 @@ config SERIAL167 ...@@ -576,14 +576,14 @@ config SERIAL167
config MVME162_SCC config MVME162_SCC
bool "SCC support for MVME162 serial ports" bool "SCC support for MVME162 serial ports"
depends on MVME16x depends on MVME16x && BROKEN
help help
This is the driver for the serial ports on the Motorola MVME162 and This is the driver for the serial ports on the Motorola MVME162 and
172 boards. Everyone using one of these boards should say Y here. 172 boards. Everyone using one of these boards should say Y here.
config BVME6000_SCC config BVME6000_SCC
bool "SCC support for BVME6000 serial ports" bool "SCC support for BVME6000 serial ports"
depends on BVME6000 depends on BVME6000 && BROKEN
help help
This is the driver for the serial ports on the BVME4000 and BVME6000 This is the driver for the serial ports on the BVME4000 and BVME6000
boards from BVM Ltd. Everyone using one of these boards should say boards from BVM Ltd. Everyone using one of these boards should say
......
...@@ -1012,9 +1012,9 @@ config BOOT_ELF32 ...@@ -1012,9 +1012,9 @@ config BOOT_ELF32
config MIPS_L1_CACHE_SHIFT config MIPS_L1_CACHE_SHIFT
int int
default "4" if MACH_DECSTATION || MIKROTIK_RB532 default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL
default "6" if MIPS_CPU_SCACHE
default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
default "4" if PMC_MSP4200_EVAL
default "5" default "5"
config HAVE_STD_PC_SERIAL_PORT config HAVE_STD_PC_SERIAL_PORT
......
...@@ -354,6 +354,28 @@ static void au1x_ic1_ack(unsigned int irq_nr) ...@@ -354,6 +354,28 @@ static void au1x_ic1_ack(unsigned int irq_nr)
au_sync(); au_sync();
} }
static void au1x_ic0_maskack(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
au_writel(1 << bit, IC0_WAKECLR);
au_writel(1 << bit, IC0_MASKCLR);
au_writel(1 << bit, IC0_RISINGCLR);
au_writel(1 << bit, IC0_FALLINGCLR);
au_sync();
}
static void au1x_ic1_maskack(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_WAKECLR);
au_writel(1 << bit, IC1_MASKCLR);
au_writel(1 << bit, IC1_RISINGCLR);
au_writel(1 << bit, IC1_FALLINGCLR);
au_sync();
}
static int au1x_ic1_setwake(unsigned int irq, unsigned int on) static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
{ {
unsigned int bit = irq - AU1000_INTC1_INT_BASE; unsigned int bit = irq - AU1000_INTC1_INT_BASE;
...@@ -379,25 +401,21 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on) ...@@ -379,25 +401,21 @@ static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
/* /*
* irq_chips for both ICs; this way the mask handlers can be * irq_chips for both ICs; this way the mask handlers can be
* as short as possible. * as short as possible.
*
* NOTE: the ->ack() callback is used by the handle_edge_irq
* flowhandler only, the ->mask_ack() one by handle_level_irq,
* so no need for an irq_chip for each type of irq (level/edge).
*/ */
static struct irq_chip au1x_ic0_chip = { static struct irq_chip au1x_ic0_chip = {
.name = "Alchemy-IC0", .name = "Alchemy-IC0",
.ack = au1x_ic0_ack, /* edge */ .ack = au1x_ic0_ack,
.mask = au1x_ic0_mask, .mask = au1x_ic0_mask,
.mask_ack = au1x_ic0_mask, /* level */ .mask_ack = au1x_ic0_maskack,
.unmask = au1x_ic0_unmask, .unmask = au1x_ic0_unmask,
.set_type = au1x_ic_settype, .set_type = au1x_ic_settype,
}; };
static struct irq_chip au1x_ic1_chip = { static struct irq_chip au1x_ic1_chip = {
.name = "Alchemy-IC1", .name = "Alchemy-IC1",
.ack = au1x_ic1_ack, /* edge */ .ack = au1x_ic1_ack,
.mask = au1x_ic1_mask, .mask = au1x_ic1_mask,
.mask_ack = au1x_ic1_mask, /* level */ .mask_ack = au1x_ic1_maskack,
.unmask = au1x_ic1_unmask, .unmask = au1x_ic1_unmask,
.set_type = au1x_ic_settype, .set_type = au1x_ic_settype,
.set_wake = au1x_ic1_setwake, .set_wake = au1x_ic1_setwake,
......
...@@ -69,6 +69,7 @@ void __init board_setup(void) ...@@ -69,6 +69,7 @@ void __init board_setup(void)
#else #else
au_writel(0xf, Au1500_PCI_CFG); au_writel(0xf, Au1500_PCI_CFG);
#endif #endif
board_pci_idsel = mtx1_pci_idsel;
#endif #endif
/* Initialize sys_pinfunc */ /* Initialize sys_pinfunc */
...@@ -85,8 +86,6 @@ void __init board_setup(void) ...@@ -85,8 +86,6 @@ void __init board_setup(void)
alchemy_gpio_direction_output(211, 1); /* green on */ alchemy_gpio_direction_output(211, 1); /* green on */
alchemy_gpio_direction_output(212, 0); /* red off */ alchemy_gpio_direction_output(212, 0); /* red off */
board_pci_idsel = mtx1_pci_idsel;
printk(KERN_INFO "4G Systems MTX-1 Board\n"); printk(KERN_INFO "4G Systems MTX-1 Board\n");
} }
......
...@@ -503,6 +503,7 @@ static int __init ar7_register_devices(void) ...@@ -503,6 +503,7 @@ static int __init ar7_register_devices(void)
{ {
u16 chip_id; u16 chip_id;
int res; int res;
u32 *bootcr, val;
#ifdef CONFIG_SERIAL_8250 #ifdef CONFIG_SERIAL_8250
static struct uart_port uart_port[2]; static struct uart_port uart_port[2];
...@@ -595,7 +596,13 @@ static int __init ar7_register_devices(void) ...@@ -595,7 +596,13 @@ static int __init ar7_register_devices(void)
ar7_wdt_res.end = ar7_wdt_res.start + 0x20; ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
res = platform_device_register(&ar7_wdt); bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
val = *bootcr;
iounmap(bootcr);
/* Register watchdog only if enabled in hardware */
if (val & AR7_WDT_HW_ENA)
res = platform_device_register(&ar7_wdt);
return res; return res;
} }
......
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/ obj-y += boards/
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <bcm63xx_dev_enet.h> #include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h> #include <bcm63xx_dev_dsp.h>
#include <bcm63xx_dev_pcmcia.h> #include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_uart.h>
#include <board_bcm963xx.h> #include <board_bcm963xx.h>
#define PFX "board_bcm963xx: " #define PFX "board_bcm963xx: "
...@@ -794,8 +793,6 @@ int __init board_register_devices(void) ...@@ -794,8 +793,6 @@ int __init board_register_devices(void)
{ {
u32 val; u32 val;
bcm63xx_uart_register();
if (board.has_pccard) if (board.has_pccard)
bcm63xx_pcmcia_register(); bcm63xx_pcmcia_register();
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <asm/cpu-info.h>
#include <bcm63xx_cpu.h> #include <bcm63xx_cpu.h>
#include <bcm63xx_regs.h> #include <bcm63xx_regs.h>
#include <bcm63xx_io.h> #include <bcm63xx_io.h>
...@@ -284,6 +285,7 @@ void __init bcm63xx_cpu_init(void) ...@@ -284,6 +285,7 @@ void __init bcm63xx_cpu_init(void)
{ {
unsigned int tmp, expected_cpu_id; unsigned int tmp, expected_cpu_id;
struct cpuinfo_mips *c = &current_cpu_data; struct cpuinfo_mips *c = &current_cpu_data;
unsigned int cpu = smp_processor_id();
/* soc registers location depends on cpu type */ /* soc registers location depends on cpu type */
expected_cpu_id = 0; expected_cpu_id = 0;
...@@ -293,6 +295,7 @@ void __init bcm63xx_cpu_init(void) ...@@ -293,6 +295,7 @@ void __init bcm63xx_cpu_init(void)
* BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
*/ */
case CPU_BCM3302: case CPU_BCM3302:
__cpu_name[cpu] = "Broadcom BCM6338";
expected_cpu_id = BCM6338_CPU_ID; expected_cpu_id = BCM6338_CPU_ID;
bcm63xx_regs_base = bcm96338_regs_base; bcm63xx_regs_base = bcm96338_regs_base;
bcm63xx_irqs = bcm96338_irqs; bcm63xx_irqs = bcm96338_irqs;
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <bcm63xx_cpu.h> #include <bcm63xx_cpu.h>
#include <bcm63xx_dev_uart.h>
static struct resource uart_resources[] = { static struct resource uart_resources[] = {
{ {
...@@ -39,3 +38,4 @@ int __init bcm63xx_uart_register(void) ...@@ -39,3 +38,4 @@ int __init bcm63xx_uart_register(void)
uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0); uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
return platform_device_register(&bcm63xx_uart_device); return platform_device_register(&bcm63xx_uart_device);
} }
arch_initcall(bcm63xx_uart_register);
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <bcm63xx_cpu.h>
static struct resource wdt_resources[] = {
{
.start = -1, /* filled at runtime */
.end = -1, /* filled at runtime */
.flags = IORESOURCE_MEM,
},
};
static struct platform_device bcm63xx_wdt_device = {
.name = "bcm63xx-wdt",
.id = 0,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};
int __init bcm63xx_wdt_register(void)
{
wdt_resources[0].start = bcm63xx_regset_address(RSET_WDT);
wdt_resources[0].end = wdt_resources[0].start;
wdt_resources[0].end += RSET_WDT_SIZE - 1;
return platform_device_register(&bcm63xx_wdt_device);
}
arch_initcall(bcm63xx_wdt_register);
...@@ -75,7 +75,9 @@ void bcm63xx_machine_reboot(void) ...@@ -75,7 +75,9 @@ void bcm63xx_machine_reboot(void)
bcm6348_a1_reboot(); bcm6348_a1_reboot();
printk(KERN_INFO "triggering watchdog soft-reset...\n"); printk(KERN_INFO "triggering watchdog soft-reset...\n");
bcm_perf_writel(SYS_PLL_SOFT_RESET, PERF_SYS_PLL_CTL_REG); reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
reg |= SYS_PLL_SOFT_RESET;
bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
while (1) while (1)
; ;
} }
......
...@@ -17,6 +17,15 @@ DEFINE_RWLOCK(octeon_irq_ciu0_rwlock); ...@@ -17,6 +17,15 @@ DEFINE_RWLOCK(octeon_irq_ciu0_rwlock);
DEFINE_RWLOCK(octeon_irq_ciu1_rwlock); DEFINE_RWLOCK(octeon_irq_ciu1_rwlock);
DEFINE_SPINLOCK(octeon_irq_msi_lock); DEFINE_SPINLOCK(octeon_irq_msi_lock);
static int octeon_coreid_for_cpu(int cpu)
{
#ifdef CONFIG_SMP
return cpu_logical_map(cpu);
#else
return cvmx_get_core_num();
#endif
}
static void octeon_irq_core_ack(unsigned int irq) static void octeon_irq_core_ack(unsigned int irq)
{ {
unsigned int bit = irq - OCTEON_IRQ_SW0; unsigned int bit = irq - OCTEON_IRQ_SW0;
...@@ -152,11 +161,10 @@ static void octeon_irq_ciu0_disable(unsigned int irq) ...@@ -152,11 +161,10 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
unsigned long flags; unsigned long flags;
uint64_t en0; uint64_t en0;
#ifdef CONFIG_SMP
int cpu; int cpu;
write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags); write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu); int coreid = octeon_coreid_for_cpu(cpu);
en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
en0 &= ~(1ull << bit); en0 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
...@@ -167,26 +175,57 @@ static void octeon_irq_ciu0_disable(unsigned int irq) ...@@ -167,26 +175,57 @@ static void octeon_irq_ciu0_disable(unsigned int irq)
*/ */
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags); write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
#else }
int coreid = cvmx_get_core_num();
local_irq_save(flags); /*
en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); * Enable the irq on the current core for chips that have the EN*_W1{S,C}
en0 &= ~(1ull << bit); * registers.
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0); */
cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); static void octeon_irq_ciu0_enable_v2(unsigned int irq)
local_irq_restore(flags); {
#endif int index = cvmx_get_core_num() * 2;
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
}
/*
* Disable the irq on the current core for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu0_disable_v2(unsigned int irq)
{
int index = cvmx_get_core_num() * 2;
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
}
/*
* Disable the irq on the all cores for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu0_disable_all_v2(unsigned int irq)
{
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
int index;
int cpu;
for_each_online_cpu(cpu) {
index = octeon_coreid_for_cpu(cpu) * 2;
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
}
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest) static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
{ {
int cpu; int cpu;
unsigned long flags;
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */ int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
write_lock(&octeon_irq_ciu0_rwlock); write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu); int coreid = octeon_coreid_for_cpu(cpu);
uint64_t en0 = uint64_t en0 =
cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)); cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
if (cpumask_test_cpu(cpu, dest)) if (cpumask_test_cpu(cpu, dest))
...@@ -200,11 +239,45 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask * ...@@ -200,11 +239,45 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
* of them are done. * of them are done.
*/ */
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2)); cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
write_unlock(&octeon_irq_ciu0_rwlock); write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
return 0; return 0;
} }
/*
* Set affinity for the irq for chips that have the EN*_W1{S,C}
* registers.
*/
static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq,
const struct cpumask *dest)
{
int cpu;
int index;
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
for_each_online_cpu(cpu) {
index = octeon_coreid_for_cpu(cpu) * 2;
if (cpumask_test_cpu(cpu, dest))
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
else
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
}
return 0;
}
#endif
/*
* Newer octeon chips have support for lockless CIU operation.
*/
static struct irq_chip octeon_irq_chip_ciu0_v2 = {
.name = "CIU0",
.enable = octeon_irq_ciu0_enable_v2,
.disable = octeon_irq_ciu0_disable_all_v2,
.ack = octeon_irq_ciu0_disable_v2,
.eoi = octeon_irq_ciu0_enable_v2,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu0_set_affinity_v2,
#endif #endif
};
static struct irq_chip octeon_irq_chip_ciu0 = { static struct irq_chip octeon_irq_chip_ciu0 = {
.name = "CIU0", .name = "CIU0",
...@@ -269,11 +342,10 @@ static void octeon_irq_ciu1_disable(unsigned int irq) ...@@ -269,11 +342,10 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
unsigned long flags; unsigned long flags;
uint64_t en1; uint64_t en1;
#ifdef CONFIG_SMP
int cpu; int cpu;
write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags); write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu); int coreid = octeon_coreid_for_cpu(cpu);
en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
en1 &= ~(1ull << bit); en1 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
...@@ -284,26 +356,58 @@ static void octeon_irq_ciu1_disable(unsigned int irq) ...@@ -284,26 +356,58 @@ static void octeon_irq_ciu1_disable(unsigned int irq)
*/ */
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags); write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
#else }
int coreid = cvmx_get_core_num();
local_irq_save(flags); /*
en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); * Enable the irq on the current core for chips that have the EN*_W1{S,C}
en1 &= ~(1ull << bit); * registers.
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1); */
cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1)); static void octeon_irq_ciu1_enable_v2(unsigned int irq)
local_irq_restore(flags); {
#endif int index = cvmx_get_core_num() * 2 + 1;
u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
}
/*
* Disable the irq on the current core for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu1_disable_v2(unsigned int irq)
{
int index = cvmx_get_core_num() * 2 + 1;
u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
}
/*
* Disable the irq on the all cores for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu1_disable_all_v2(unsigned int irq)
{
u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
int index;
int cpu;
for_each_online_cpu(cpu) {
index = octeon_coreid_for_cpu(cpu) * 2 + 1;
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
}
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest) static int octeon_irq_ciu1_set_affinity(unsigned int irq,
const struct cpumask *dest)
{ {
int cpu; int cpu;
unsigned long flags;
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */ int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
write_lock(&octeon_irq_ciu1_rwlock); write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu); int coreid = octeon_coreid_for_cpu(cpu);
uint64_t en1 = uint64_t en1 =
cvmx_read_csr(CVMX_CIU_INTX_EN1 cvmx_read_csr(CVMX_CIU_INTX_EN1
(coreid * 2 + 1)); (coreid * 2 + 1));
...@@ -318,12 +422,46 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask * ...@@ -318,12 +422,46 @@ static int octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *
* of them are done. * of them are done.
*/ */
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1)); cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
write_unlock(&octeon_irq_ciu1_rwlock); write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
return 0;
}
/*
* Set affinity for the irq for chips that have the EN*_W1{S,C}
* registers.
*/
static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq,
const struct cpumask *dest)
{
int cpu;
int index;
u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
for_each_online_cpu(cpu) {
index = octeon_coreid_for_cpu(cpu) * 2 + 1;
if (cpumask_test_cpu(cpu, dest))
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
else
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
}
return 0; return 0;
} }
#endif #endif
/*
* Newer octeon chips have support for lockless CIU operation.
*/
static struct irq_chip octeon_irq_chip_ciu1_v2 = {
.name = "CIU0",
.enable = octeon_irq_ciu1_enable_v2,
.disable = octeon_irq_ciu1_disable_all_v2,
.ack = octeon_irq_ciu1_disable_v2,
.eoi = octeon_irq_ciu1_enable_v2,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu1_set_affinity_v2,
#endif
};
static struct irq_chip octeon_irq_chip_ciu1 = { static struct irq_chip octeon_irq_chip_ciu1 = {
.name = "CIU1", .name = "CIU1",
.enable = octeon_irq_ciu1_enable, .enable = octeon_irq_ciu1_enable,
...@@ -420,6 +558,8 @@ static struct irq_chip octeon_irq_chip_msi = { ...@@ -420,6 +558,8 @@ static struct irq_chip octeon_irq_chip_msi = {
void __init arch_init_irq(void) void __init arch_init_irq(void)
{ {
int irq; int irq;
struct irq_chip *chip0;
struct irq_chip *chip1;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Set the default affinity to the boot cpu. */ /* Set the default affinity to the boot cpu. */
...@@ -430,6 +570,16 @@ void __init arch_init_irq(void) ...@@ -430,6 +570,16 @@ void __init arch_init_irq(void)
if (NR_IRQS < OCTEON_IRQ_LAST) if (NR_IRQS < OCTEON_IRQ_LAST)
pr_err("octeon_irq_init: NR_IRQS is set too low\n"); pr_err("octeon_irq_init: NR_IRQS is set too low\n");
if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) {
chip0 = &octeon_irq_chip_ciu0_v2;
chip1 = &octeon_irq_chip_ciu1_v2;
} else {
chip0 = &octeon_irq_chip_ciu0;
chip1 = &octeon_irq_chip_ciu1;
}
/* 0 - 15 reserved for i8259 master and slave controller. */ /* 0 - 15 reserved for i8259 master and slave controller. */
/* 17 - 23 Mips internal */ /* 17 - 23 Mips internal */
...@@ -440,14 +590,12 @@ void __init arch_init_irq(void) ...@@ -440,14 +590,12 @@ void __init arch_init_irq(void)
/* 24 - 87 CIU_INT_SUM0 */ /* 24 - 87 CIU_INT_SUM0 */
for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) { for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu0, set_irq_chip_and_handler(irq, chip0, handle_percpu_irq);
handle_percpu_irq);
} }
/* 88 - 151 CIU_INT_SUM1 */ /* 88 - 151 CIU_INT_SUM1 */
for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) { for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu1, set_irq_chip_and_handler(irq, chip1, handle_percpu_irq);
handle_percpu_irq);
} }
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
...@@ -505,14 +653,10 @@ asmlinkage void plat_irq_dispatch(void) ...@@ -505,14 +653,10 @@ asmlinkage void plat_irq_dispatch(void)
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu) static int is_irq_enabled_on_cpu(unsigned int irq, unsigned int cpu)
{ {
unsigned int isset; unsigned int isset;
#ifdef CONFIG_SMP int coreid = octeon_coreid_for_cpu(cpu);
int coreid = cpu_logical_map(cpu);
#else
int coreid = cvmx_get_core_num();
#endif
int bit = (irq < OCTEON_IRQ_WDOG0) ? int bit = (irq < OCTEON_IRQ_WDOG0) ?
irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0; irq - OCTEON_IRQ_WORKQ0 : irq - OCTEON_IRQ_WDOG0;
if (irq < 64) { if (irq < 64) {
isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) & isset = (cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)) &
(1ull << bit)) >> bit; (1ull << bit)) >> bit;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册