Merge branch 'ux500/dt' into next/dt2
* ux500/dt: ARM: ux500: Provide local timer support for Device Tree ARM: ux500: Enable PL022 SSP Controller in Device Tree ARM: ux500: Enable PL310 Level 2 Cache Controller in Device Tree ARM: ux500: Enable PL011 AMBA UART Controller for Device Tree ARM: ux500: Enable Cortex-A9 GIC (Generic Interrupt Controller) in Device Tree ARM: ux500: db8500: list most devices in the snowball device tree ARM: ux500: split dts file for snowball into generic part ARM: ux500: combine the board init functions for DT boot ARM: ux500: Initial Device Tree support for Snowball ARM: ux500: CONFIG: Enable Device Tree support for future endeavours ARM: ux500: fix compilation after local timer rework (adds dependency on localtimer branch, irqdomain branch and ux500/soc branch) Conflicts: arch/arm/mach-ux500/devices-common.c This adds patches from Lee Jones, Niklas Hernaeus and myself to provide initial device tree support on the ux500 platform. The pull request from Lee contained some other changes, so I rebased the patches on top of the branches that are actually dependencies for this. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Коммит
d4ef467aea
|
@ -0,0 +1,58 @@
|
|||
What: /sys/devices/socX
|
||||
Date: January 2012
|
||||
contact: Lee Jones <lee.jones@linaro.org>
|
||||
Description:
|
||||
The /sys/devices/ directory contains a sub-directory for each
|
||||
System-on-Chip (SoC) device on a running platform. Information
|
||||
regarding each SoC can be obtained by reading sysfs files. This
|
||||
functionality is only available if implemented by the platform.
|
||||
|
||||
The directory created for each SoC will also house information
|
||||
about devices which are commonly contained in /sys/devices/platform.
|
||||
It has been agreed that if an SoC device exists, its supported
|
||||
devices would be better suited to appear as children of that SoC.
|
||||
|
||||
What: /sys/devices/socX/machine
|
||||
Date: January 2012
|
||||
contact: Lee Jones <lee.jones@linaro.org>
|
||||
Description:
|
||||
Read-only attribute common to all SoCs. Contains the SoC machine
|
||||
name (e.g. Ux500).
|
||||
|
||||
What: /sys/devices/socX/family
|
||||
Date: January 2012
|
||||
contact: Lee Jones <lee.jones@linaro.org>
|
||||
Description:
|
||||
Read-only attribute common to all SoCs. Contains SoC family name
|
||||
(e.g. DB8500).
|
||||
|
||||
What: /sys/devices/socX/soc_id
|
||||
Date: January 2012
|
||||
contact: Lee Jones <lee.jones@linaro.org>
|
||||
Description:
|
||||
Read-only attribute supported by most SoCs. In the case of
|
||||
ST-Ericsson's chips this contains the SoC serial number.
|
||||
|
||||
What: /sys/devices/socX/revision
|
||||
Date: January 2012
|
||||
contact: Lee Jones <lee.jones@linaro.org>
|
||||
Description:
|
||||
Read-only attribute supported by most SoCs. Contains the SoC's
|
||||
manufacturing revision number.
|
||||
|
||||
What: /sys/devices/socX/process
|
||||
Date: January 2012
|
||||
contact: Lee Jones <lee.jones@linaro.org>
|
||||
Description:
|
||||
Read-only attribute supported ST-Ericsson's silicon. Contains the
|
||||
the process by which the silicon chip was manufactured.
|
||||
|
||||
What: /sys/bus/soc
|
||||
Date: January 2012
|
||||
contact: Lee Jones <lee.jones@linaro.org>
|
||||
Description:
|
||||
The /sys/bus/soc/ directory contains the usual sub-folders
|
||||
expected under most buses. /sys/bus/soc/devices is of particular
|
||||
interest, as it contains a symlink for each SoC device found on
|
||||
the system. Each symlink points back into the aforementioned
|
||||
/sys/devices/socX devices.
|
|
@ -0,0 +1,48 @@
|
|||
* ARM Timer Watchdog
|
||||
|
||||
ARM 11MP, Cortex-A5 and Cortex-A9 are often associated with a per-core
|
||||
Timer-Watchdog (aka TWD), which provides both a per-cpu local timer
|
||||
and watchdog.
|
||||
|
||||
The TWD is usually attached to a GIC to deliver its two per-processor
|
||||
interrupts.
|
||||
|
||||
** Timer node required properties:
|
||||
|
||||
- compatible : Should be one of:
|
||||
"arm,cortex-a9-twd-timer"
|
||||
"arm,cortex-a5-twd-timer"
|
||||
"arm,arm11mp-twd-timer"
|
||||
|
||||
- interrupts : One interrupt to each core
|
||||
|
||||
- reg : Specify the base address and the size of the TWD timer
|
||||
register window.
|
||||
|
||||
Example:
|
||||
|
||||
twd-timer@2c000600 {
|
||||
compatible = "arm,arm11mp-twd-timer"";
|
||||
reg = <0x2c000600 0x20>;
|
||||
interrupts = <1 13 0xf01>;
|
||||
};
|
||||
|
||||
** Watchdog node properties:
|
||||
|
||||
- compatible : Should be one of:
|
||||
"arm,cortex-a9-twd-wdt"
|
||||
"arm,cortex-a5-twd-wdt"
|
||||
"arm,arm11mp-twd-wdt"
|
||||
|
||||
- interrupts : One interrupt to each core
|
||||
|
||||
- reg : Specify the base address and the size of the TWD watchdog
|
||||
register window.
|
||||
|
||||
Example:
|
||||
|
||||
twd-watchdog@2c000620 {
|
||||
compatible = "arm,arm11mp-twd-wdt";
|
||||
reg = <0x2c000620 0x20>;
|
||||
interrupts = <1 14 0xf01>;
|
||||
};
|
|
@ -12,7 +12,7 @@ dynamically enabled per-callsite.
|
|||
Dynamic debug has even more useful features:
|
||||
|
||||
* Simple query language allows turning on and off debugging statements by
|
||||
matching any combination of:
|
||||
matching any combination of 0 or 1 of:
|
||||
|
||||
- source filename
|
||||
- function name
|
||||
|
@ -79,31 +79,24 @@ Command Language Reference
|
|||
==========================
|
||||
|
||||
At the lexical level, a command comprises a sequence of words separated
|
||||
by whitespace characters. Note that newlines are treated as word
|
||||
separators and do *not* end a command or allow multiple commands to
|
||||
be done together. So these are all equivalent:
|
||||
by spaces or tabs. So these are all equivalent:
|
||||
|
||||
nullarbor:~ # echo -c 'file svcsock.c line 1603 +p' >
|
||||
<debugfs>/dynamic_debug/control
|
||||
nullarbor:~ # echo -c ' file svcsock.c line 1603 +p ' >
|
||||
<debugfs>/dynamic_debug/control
|
||||
nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' >
|
||||
<debugfs>/dynamic_debug/control
|
||||
nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
|
||||
<debugfs>/dynamic_debug/control
|
||||
|
||||
Commands are bounded by a write() system call. If you want to do
|
||||
multiple commands you need to do a separate "echo" for each, like:
|
||||
Command submissions are bounded by a write() system call.
|
||||
Multiple commands can be written together, separated by ';' or '\n'.
|
||||
|
||||
nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
|
||||
> echo 'file svcsock.c line 1563 +p' > /proc/dprintk
|
||||
~# echo "func pnpacpi_get_resources +p; func pnp_assign_mem +p" \
|
||||
> <debugfs>/dynamic_debug/control
|
||||
|
||||
or even like:
|
||||
If your query set is big, you can batch them too:
|
||||
|
||||
nullarbor:~ # (
|
||||
> echo 'file svcsock.c line 1603 +p' ;\
|
||||
> echo 'file svcsock.c line 1563 +p' ;\
|
||||
> ) > /proc/dprintk
|
||||
~# cat query-batch-file > <debugfs>/dynamic_debug/control
|
||||
|
||||
At the syntactical level, a command comprises a sequence of match
|
||||
specifications, followed by a flags change specification.
|
||||
|
@ -144,11 +137,12 @@ func
|
|||
func svc_tcp_accept
|
||||
|
||||
file
|
||||
The given string is compared against either the full
|
||||
pathname or the basename of the source file of each
|
||||
callsite. Examples:
|
||||
The given string is compared against either the full pathname, the
|
||||
src-root relative pathname, or the basename of the source file of
|
||||
each callsite. Examples:
|
||||
|
||||
file svcsock.c
|
||||
file kernel/freezer.c
|
||||
file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c
|
||||
|
||||
module
|
||||
|
|
|
@ -15,6 +15,9 @@ Debugfs is typically mounted with a command like:
|
|||
mount -t debugfs none /sys/kernel/debug
|
||||
|
||||
(Or an equivalent /etc/fstab line).
|
||||
The debugfs root directory is accessible by anyone by default. To
|
||||
restrict access to the tree the "uid", "gid" and "mode" mount
|
||||
options can be used.
|
||||
|
||||
Note that the debugfs API is exported GPL-only to modules.
|
||||
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Copyright 2012 Linaro Ltd
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/include/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
soc-u9500 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "stericsson,db8500";
|
||||
interrupt-parent = <&intc>;
|
||||
ranges;
|
||||
|
||||
intc: interrupt-controller@a0411000 {
|
||||
compatible = "arm,cortex-a9-gic";
|
||||
#interrupt-cells = <3>;
|
||||
#address-cells = <1>;
|
||||
interrupt-controller;
|
||||
interrupt-parent;
|
||||
reg = <0xa0411000 0x1000>,
|
||||
<0xa0410100 0x100>;
|
||||
};
|
||||
|
||||
L2: l2-cache {
|
||||
compatible = "arm,pl310-cache";
|
||||
reg = <0xa0412000 0x1000>;
|
||||
interrupts = <0 13 4>;
|
||||
cache-unified;
|
||||
cache-level = <2>;
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,cortex-a9-pmu";
|
||||
interrupts = <0 7 0x4>;
|
||||
};
|
||||
|
||||
timer@a0410600 {
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0xa0410600 0x20>;
|
||||
interrupts = <1 13 0x304>;
|
||||
};
|
||||
|
||||
rtc@80154000 {
|
||||
compatible = "stericsson,db8500-rtc";
|
||||
reg = <0x80154000 0x1000>;
|
||||
interrupts = <0 18 0x4>;
|
||||
};
|
||||
|
||||
gpio0: gpio@8012e000 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0x8012e000 0x80>;
|
||||
interrupts = <0 119 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio1: gpio@8012e080 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0x8012e080 0x80>;
|
||||
interrupts = <0 120 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio2: gpio@8000e000 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0x8000e000 0x80>;
|
||||
interrupts = <0 121 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio3: gpio@8000e080 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0x8000e080 0x80>;
|
||||
interrupts = <0 122 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio4: gpio@8000e100 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0x8000e100 0x80>;
|
||||
interrupts = <0 123 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio5: gpio@8000e180 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0x8000e180 0x80>;
|
||||
interrupts = <0 124 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio6: gpio@8011e000 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0x8011e000 0x80>;
|
||||
interrupts = <0 125 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio7: gpio@8011e080 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0x8011e080 0x80>;
|
||||
interrupts = <0 126 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
gpio8: gpio@a03fe000 {
|
||||
compatible = "stericsson,db8500-gpio",
|
||||
"stmicroelectronics,nomadik-gpio";
|
||||
reg = <0xa03fe000 0x80>;
|
||||
interrupts = <0 127 0x4>;
|
||||
supports-sleepmode;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
usb@a03e0000 {
|
||||
compatible = "stericsson,db8500-musb",
|
||||
"mentor,musb";
|
||||
reg = <0xa03e0000 0x10000>;
|
||||
interrupts = <0 23 0x4>;
|
||||
};
|
||||
|
||||
dma-controller@801C0000 {
|
||||
compatible = "stericsson,db8500-dma40",
|
||||
"stericsson,dma40";
|
||||
reg = <0x801C0000 0x1000 0x40010000 0x800>;
|
||||
interrupts = <0 25 0x4>;
|
||||
};
|
||||
|
||||
prcmu@80157000 {
|
||||
compatible = "stericsson,db8500-prcmu";
|
||||
reg = <0x80157000 0x1000>;
|
||||
interrupts = <46 47>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ab8500@5 {
|
||||
compatible = "stericsson,ab8500";
|
||||
reg = <5>; /* mailbox 5 is i2c */
|
||||
interrupts = <0 40 0x4>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c@80004000 {
|
||||
compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
|
||||
reg = <0x80004000 0x1000>;
|
||||
interrupts = <0 21 0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
i2c@80122000 {
|
||||
compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
|
||||
reg = <0x80122000 0x1000>;
|
||||
interrupts = <0 22 0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
i2c@80128000 {
|
||||
compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
|
||||
reg = <0x80128000 0x1000>;
|
||||
interrupts = <0 55 0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
i2c@80110000 {
|
||||
compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
|
||||
reg = <0x80110000 0x1000>;
|
||||
interrupts = <0 12 0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
i2c@8012a000 {
|
||||
compatible = "stericsson,db8500-i2c", "stmicroelectronics,nomadik-i2c";
|
||||
reg = <0x8012a000 0x1000>;
|
||||
interrupts = <0 51 0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
ssp@80002000 {
|
||||
compatible = "arm,pl022", "arm,primecell";
|
||||
reg = <80002000 0x1000>;
|
||||
interrupts = <0 14 0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
// Add one of these for each child device
|
||||
cs-gpios = <&gpio0 31 &gpio4 14 &gpio4 16 &gpio6 22 &gpio7 0>;
|
||||
|
||||
};
|
||||
|
||||
uart@80120000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x80120000 0x1000>;
|
||||
interrupts = <0 11 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
uart@80121000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x80121000 0x1000>;
|
||||
interrupts = <0 19 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
uart@80007000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x80007000 0x1000>;
|
||||
interrupts = <0 26 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sdi@80126000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
reg = <0x80126000 0x1000>;
|
||||
interrupts = <0 60 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
sdi@80118000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
reg = <0x80118000 0x1000>;
|
||||
interrupts = <0 50 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
sdi@80005000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
reg = <0x80005000 0x1000>;
|
||||
interrupts = <0 41 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
sdi@80119000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
reg = <0x80119000 0x1000>;
|
||||
interrupts = <0 59 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
sdi@80114000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
reg = <0x80114000 0x1000>;
|
||||
interrupts = <0 99 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
sdi@80008000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
reg = <0x80114000 0x1000>;
|
||||
interrupts = <0 100 0x4>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -72,15 +72,15 @@
|
|||
ranges;
|
||||
|
||||
timer@fff10600 {
|
||||
compatible = "arm,smp-twd";
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0xfff10600 0x20>;
|
||||
interrupts = <1 13 0xf04>;
|
||||
interrupts = <1 13 0xf01>;
|
||||
};
|
||||
|
||||
watchdog@fff10620 {
|
||||
compatible = "arm,cortex-a9-wdt";
|
||||
compatible = "arm,cortex-a9-twd-wdt";
|
||||
reg = <0xfff10620 0x20>;
|
||||
interrupts = <1 14 0xf04>;
|
||||
interrupts = <1 14 0xf01>;
|
||||
};
|
||||
|
||||
intc: interrupt-controller@fff11000 {
|
||||
|
|
|
@ -88,9 +88,9 @@
|
|||
ranges;
|
||||
|
||||
timer@00a00600 {
|
||||
compatible = "arm,smp-twd";
|
||||
reg = <0x00a00600 0x100>;
|
||||
interrupts = <1 13 0xf4>;
|
||||
compatible = "arm,cortex-a9-twd-timer";
|
||||
reg = <0x00a00600 0x20>;
|
||||
interrupts = <1 13 0xf01>;
|
||||
};
|
||||
|
||||
L2: l2-cache@00a02000 {
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright 2011 ST-Ericsson AB
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/include/ "db8500.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Calao Systems Snowball platform with device tree";
|
||||
compatible = "calaosystems,snowball-a9500";
|
||||
|
||||
memory {
|
||||
reg = <0x00000000 0x20000000>;
|
||||
};
|
||||
|
||||
gpio_keys {
|
||||
compatible = "gpio-keys";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
button@1 {
|
||||
debounce_interval = <50>;
|
||||
wakeup = <1>;
|
||||
linux,code = <2>;
|
||||
label = "userpb";
|
||||
gpios = <&gpio1 0>;
|
||||
};
|
||||
button@2 {
|
||||
debounce_interval = <50>;
|
||||
wakeup = <1>;
|
||||
linux,code = <3>;
|
||||
label = "userpb";
|
||||
gpios = <&gpio4 23>;
|
||||
};
|
||||
button@3 {
|
||||
debounce_interval = <50>;
|
||||
wakeup = <1>;
|
||||
linux,code = <4>;
|
||||
label = "userpb";
|
||||
gpios = <&gpio4 23>;
|
||||
};
|
||||
button@4 {
|
||||
debounce_interval = <50>;
|
||||
wakeup = <1>;
|
||||
linux,code = <5>;
|
||||
label = "userpb";
|
||||
gpios = <&gpio5 1>;
|
||||
};
|
||||
button@5 {
|
||||
debounce_interval = <50>;
|
||||
wakeup = <1>;
|
||||
linux,code = <6>;
|
||||
label = "userpb";
|
||||
gpios = <&gpio5 2>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
used-led {
|
||||
label = "user_led";
|
||||
gpios = <&gpio4 14>;
|
||||
};
|
||||
};
|
||||
|
||||
soc-u9500 {
|
||||
|
||||
external-bus@50000000 {
|
||||
compatible = "simple-bus";
|
||||
reg = <0x50000000 0x10000000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
ethernet@50000000 {
|
||||
compatible = "smsc,9111";
|
||||
reg = <0x50000000 0x10000>;
|
||||
interrupts = <12>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
};
|
||||
};
|
||||
|
||||
sdi@80126000 {
|
||||
status = "enabled";
|
||||
cd-gpios = <&gpio6 26>;
|
||||
};
|
||||
|
||||
sdi@80114000 {
|
||||
status = "enabled";
|
||||
};
|
||||
|
||||
uart@80120000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uart@80121000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uart@80007000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
i2c@80004000 {
|
||||
tc3589x@42 {
|
||||
//compatible = "tc3589x";
|
||||
reg = <0x42>;
|
||||
interrupts = <25>;
|
||||
interrupt-parent = <&gpio6>;
|
||||
};
|
||||
tps61052@33 {
|
||||
//compatible = "tps61052";
|
||||
reg = <0x33>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c@80128000 {
|
||||
lp5521@0x33 {
|
||||
// compatible = "lp5521";
|
||||
reg = <0x33>;
|
||||
};
|
||||
lp5521@0x34 {
|
||||
// compatible = "lp5521";
|
||||
reg = <0x34>;
|
||||
};
|
||||
bh1780@0x29 {
|
||||
// compatible = "rohm,bh1780gli";
|
||||
reg = <0x33>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -13,6 +13,7 @@ CONFIG_UX500_SOC_DB8500=y
|
|||
CONFIG_MACH_HREFV60=y
|
||||
CONFIG_MACH_SNOWBALL=y
|
||||
CONFIG_MACH_U5500=y
|
||||
CONFIG_MACH_UX500_DT=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_SMP=y
|
||||
|
|
|
@ -11,47 +11,24 @@
|
|||
#define __ASM_ARM_LOCALTIMER_H
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
struct clock_event_device;
|
||||
|
||||
/*
|
||||
* Setup a per-cpu timer, whether it be a local timer or dummy broadcast
|
||||
*/
|
||||
void percpu_timer_setup(void);
|
||||
struct local_timer_ops {
|
||||
int (*setup)(struct clock_event_device *);
|
||||
void (*stop)(struct clock_event_device *);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
|
||||
#include "smp_twd.h"
|
||||
|
||||
#define local_timer_stop(c) twd_timer_stop((c))
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Stop the local timer
|
||||
* Register a local timer driver
|
||||
*/
|
||||
void local_timer_stop(struct clock_event_device *);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup a local timer interrupt for a CPU.
|
||||
*/
|
||||
int local_timer_setup(struct clock_event_device *);
|
||||
|
||||
int local_timer_register(struct local_timer_ops *);
|
||||
#else
|
||||
|
||||
static inline int local_timer_setup(struct clock_event_device *evt)
|
||||
static inline int local_timer_register(struct local_timer_ops *ops)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static inline void local_timer_stop(struct clock_event_device *evt)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,11 +18,28 @@
|
|||
#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
|
||||
#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
|
||||
|
||||
struct clock_event_device;
|
||||
#include <linux/ioport.h>
|
||||
|
||||
extern void __iomem *twd_base;
|
||||
struct twd_local_timer {
|
||||
struct resource res[2];
|
||||
};
|
||||
|
||||
void twd_timer_setup(struct clock_event_device *);
|
||||
void twd_timer_stop(struct clock_event_device *);
|
||||
#define DEFINE_TWD_LOCAL_TIMER(name,base,irq) \
|
||||
struct twd_local_timer name __initdata = { \
|
||||
.res = { \
|
||||
DEFINE_RES_MEM(base, 0x10), \
|
||||
DEFINE_RES_IRQ(irq), \
|
||||
}, \
|
||||
};
|
||||
|
||||
int twd_local_timer_register(struct twd_local_timer *);
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
void twd_local_timer_of_register(void);
|
||||
#else
|
||||
static inline void twd_local_timer_of_register(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -246,6 +246,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
|
|||
store_cpu_topology(cpuid);
|
||||
}
|
||||
|
||||
static void percpu_timer_setup(void);
|
||||
|
||||
/*
|
||||
* This is the secondary CPU boot entry. We're using this CPUs
|
||||
* idle thread stack, but a set of temporary page tables.
|
||||
|
@ -459,7 +461,20 @@ static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
|
|||
clockevents_register_device(evt);
|
||||
}
|
||||
|
||||
void __cpuinit percpu_timer_setup(void)
|
||||
static struct local_timer_ops *lt_ops;
|
||||
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
int local_timer_register(struct local_timer_ops *ops)
|
||||
{
|
||||
if (lt_ops)
|
||||
return -EBUSY;
|
||||
|
||||
lt_ops = ops;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __cpuinit percpu_timer_setup(void)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
|
||||
|
@ -467,7 +482,7 @@ void __cpuinit percpu_timer_setup(void)
|
|||
evt->cpumask = cpumask_of(cpu);
|
||||
evt->broadcast = smp_timer_broadcast;
|
||||
|
||||
if (local_timer_setup(evt))
|
||||
if (!lt_ops || lt_ops->setup(evt))
|
||||
broadcast_timer_setup(evt);
|
||||
}
|
||||
|
||||
|
@ -482,7 +497,8 @@ static void percpu_timer_stop(void)
|
|||
unsigned int cpu = smp_processor_id();
|
||||
struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
|
||||
|
||||
local_timer_stop(evt);
|
||||
if (lt_ops)
|
||||
lt_ops->stop(evt);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,20 +18,23 @@
|
|||
#include <linux/smp.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
|
||||
/* set up by the platform code */
|
||||
void __iomem *twd_base;
|
||||
static void __iomem *twd_base;
|
||||
|
||||
static struct clk *twd_clk;
|
||||
static unsigned long twd_timer_rate;
|
||||
|
||||
static struct clock_event_device __percpu **twd_evt;
|
||||
static int twd_ppi;
|
||||
|
||||
static void twd_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk)
|
||||
|
@ -77,7 +80,7 @@ static int twd_set_next_event(unsigned long evt,
|
|||
* If a local timer interrupt has occurred, acknowledge and return 1.
|
||||
* Otherwise, return 0.
|
||||
*/
|
||||
int twd_timer_ack(void)
|
||||
static int twd_timer_ack(void)
|
||||
{
|
||||
if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
|
||||
__raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
|
||||
|
@ -87,7 +90,7 @@ int twd_timer_ack(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void twd_timer_stop(struct clock_event_device *clk)
|
||||
static void twd_timer_stop(struct clock_event_device *clk)
|
||||
{
|
||||
twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
|
||||
disable_percpu_irq(clk->irq);
|
||||
|
@ -222,28 +225,10 @@ static struct clk *twd_get_clock(void)
|
|||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
void __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
||||
static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
||||
{
|
||||
struct clock_event_device **this_cpu_clk;
|
||||
|
||||
if (!twd_evt) {
|
||||
int err;
|
||||
|
||||
twd_evt = alloc_percpu(struct clock_event_device *);
|
||||
if (!twd_evt) {
|
||||
pr_err("twd: can't allocate memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = request_percpu_irq(clk->irq, twd_handler,
|
||||
"twd", twd_evt);
|
||||
if (err) {
|
||||
pr_err("twd: can't register interrupt %d (%d)\n",
|
||||
clk->irq, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!twd_clk)
|
||||
twd_clk = twd_get_clock();
|
||||
|
||||
|
@ -260,6 +245,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
|||
clk->rating = 350;
|
||||
clk->set_mode = twd_set_mode;
|
||||
clk->set_next_event = twd_set_next_event;
|
||||
clk->irq = twd_ppi;
|
||||
|
||||
this_cpu_clk = __this_cpu_ptr(twd_evt);
|
||||
*this_cpu_clk = clk;
|
||||
|
@ -267,4 +253,95 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
|||
clockevents_config_and_register(clk, twd_timer_rate,
|
||||
0xf, 0xffffffff);
|
||||
enable_percpu_irq(clk->irq, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct local_timer_ops twd_lt_ops __cpuinitdata = {
|
||||
.setup = twd_timer_setup,
|
||||
.stop = twd_timer_stop,
|
||||
};
|
||||
|
||||
static int __init twd_local_timer_common_register(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
twd_evt = alloc_percpu(struct clock_event_device *);
|
||||
if (!twd_evt) {
|
||||
err = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_evt);
|
||||
if (err) {
|
||||
pr_err("twd: can't register interrupt %d (%d)\n", twd_ppi, err);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
err = local_timer_register(&twd_lt_ops);
|
||||
if (err)
|
||||
goto out_irq;
|
||||
|
||||
return 0;
|
||||
|
||||
out_irq:
|
||||
free_percpu_irq(twd_ppi, twd_evt);
|
||||
out_free:
|
||||
iounmap(twd_base);
|
||||
twd_base = NULL;
|
||||
free_percpu(twd_evt);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int __init twd_local_timer_register(struct twd_local_timer *tlt)
|
||||
{
|
||||
if (twd_base || twd_evt)
|
||||
return -EBUSY;
|
||||
|
||||
twd_ppi = tlt->res[1].start;
|
||||
|
||||
twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0]));
|
||||
if (!twd_base)
|
||||
return -ENOMEM;
|
||||
|
||||
return twd_local_timer_common_register();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
const static struct of_device_id twd_of_match[] __initconst = {
|
||||
{ .compatible = "arm,cortex-a9-twd-timer", },
|
||||
{ .compatible = "arm,cortex-a5-twd-timer", },
|
||||
{ .compatible = "arm,arm11mp-twd-timer", },
|
||||
{ },
|
||||
};
|
||||
|
||||
void __init twd_local_timer_of_register(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
int err;
|
||||
|
||||
np = of_find_matching_node(NULL, twd_of_match);
|
||||
if (!np) {
|
||||
err = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
twd_ppi = irq_of_parse_and_map(np, 0);
|
||||
if (!twd_ppi) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
twd_base = of_iomap(np, 0);
|
||||
if (!twd_base) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = twd_local_timer_common_register();
|
||||
|
||||
out:
|
||||
WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/percpu.h>
|
||||
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/localtimer.h>
|
||||
|
||||
#include <plat/cpu.h>
|
||||
|
||||
|
@ -375,7 +376,7 @@ static struct irqaction mct_tick1_event_irq = {
|
|||
.handler = exynos4_mct_tick_isr,
|
||||
};
|
||||
|
||||
static void exynos4_mct_tick_init(struct clock_event_device *evt)
|
||||
static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
struct mct_clock_event_device *mevt;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
@ -417,17 +418,11 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
|
|||
} else {
|
||||
enable_percpu_irq(IRQ_MCT_LOCALTIMER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the local clock events for a CPU */
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
exynos4_mct_tick_init(evt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void local_timer_stop(struct clock_event_device *evt)
|
||||
static void exynos4_local_timer_stop(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
|
||||
|
@ -439,6 +434,11 @@ void local_timer_stop(struct clock_event_device *evt)
|
|||
else
|
||||
disable_percpu_irq(IRQ_MCT_LOCALTIMER);
|
||||
}
|
||||
|
||||
static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
|
||||
.setup = exynos4_local_timer_setup,
|
||||
.stop = exynos4_local_timer_stop,
|
||||
};
|
||||
#endif /* CONFIG_LOCAL_TIMERS */
|
||||
|
||||
static void __init exynos4_timer_resources(void)
|
||||
|
@ -458,6 +458,8 @@ static void __init exynos4_timer_resources(void)
|
|||
WARN(err, "MCT: can't request IRQ %d (%d)\n",
|
||||
IRQ_MCT_LOCALTIMER, err);
|
||||
}
|
||||
|
||||
local_timer_register(&exynos4_mct_tick_ops);
|
||||
#endif /* CONFIG_LOCAL_TIMERS */
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
obj-y := clock.o highbank.o system.o
|
||||
obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o
|
||||
obj-$(CONFIG_SMP) += platsmp.o
|
||||
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
obj-$(CONFIG_PM_SLEEP) += pm.o
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/smp_scu.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/hardware/arm_timer.h>
|
||||
#include <asm/hardware/timer-sp.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
|
@ -111,6 +112,8 @@ static void __init highbank_timer_init(void)
|
|||
|
||||
sp804_clocksource_init(timer_base + 0x20, "timer1");
|
||||
sp804_clockevents_init(timer_base, irq, "timer0");
|
||||
|
||||
twd_local_timer_of_register();
|
||||
}
|
||||
|
||||
static struct sys_timer highbank_timer = {
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010-2011 Calxeda, Inc.
|
||||
* Based on localtimer.c, Copyright (C) 2002 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
|
||||
if (!twd_base) {
|
||||
twd_base = of_iomap(np, 0);
|
||||
WARN_ON(!twd_base);
|
||||
}
|
||||
evt->irq = irq_of_parse_and_map(np, 0);
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
|
@ -72,7 +72,6 @@ obj-$(CONFIG_CPU_V7) += head-v7.o
|
|||
AFLAGS_head-v7.o :=-Wa,-march=armv7-a
|
||||
obj-$(CONFIG_SMP) += platsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
|
||||
obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
|
||||
|
||||
ifeq ($(CONFIG_PM),y)
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc.
|
||||
* Copyright 2011 Linaro Ltd.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
|
||||
if (!twd_base) {
|
||||
twd_base = of_iomap(np, 0);
|
||||
WARN_ON(!twd_base);
|
||||
}
|
||||
evt->irq = irq_of_parse_and_map(np, 0);
|
||||
twd_timer_setup(evt);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/of_platform.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/micrel_phy.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -120,6 +121,7 @@ static void __init imx6q_init_irq(void)
|
|||
static void __init imx6q_timer_init(void)
|
||||
{
|
||||
mx6q_clocks_init();
|
||||
twd_local_timer_of_register();
|
||||
}
|
||||
|
||||
static struct sys_timer imx6q_timer = {
|
||||
|
|
|
@ -127,6 +127,45 @@ static struct clocksource msm_clocksource = {
|
|||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
/* Use existing clock_event for cpu 0 */
|
||||
if (!smp_processor_id())
|
||||
return 0;
|
||||
|
||||
writel_relaxed(0, event_base + TIMER_ENABLE);
|
||||
writel_relaxed(0, event_base + TIMER_CLEAR);
|
||||
writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
|
||||
evt->irq = msm_clockevent.irq;
|
||||
evt->name = "local_timer";
|
||||
evt->features = msm_clockevent.features;
|
||||
evt->rating = msm_clockevent.rating;
|
||||
evt->set_mode = msm_timer_set_mode;
|
||||
evt->set_next_event = msm_timer_set_next_event;
|
||||
evt->shift = msm_clockevent.shift;
|
||||
evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
|
||||
evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
|
||||
evt->min_delta_ns = clockevent_delta2ns(4, evt);
|
||||
|
||||
*__this_cpu_ptr(msm_evt.percpu_evt) = evt;
|
||||
clockevents_register_device(evt);
|
||||
enable_percpu_irq(evt->irq, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msm_local_timer_stop(struct clock_event_device *evt)
|
||||
{
|
||||
evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
|
||||
disable_percpu_irq(evt->irq);
|
||||
}
|
||||
|
||||
static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
|
||||
.setup = msm_local_timer_setup,
|
||||
.stop = msm_local_timer_stop,
|
||||
};
|
||||
#endif /* CONFIG_LOCAL_TIMERS */
|
||||
|
||||
static void __init msm_timer_init(void)
|
||||
{
|
||||
struct clock_event_device *ce = &msm_clockevent;
|
||||
|
@ -173,8 +212,12 @@ static void __init msm_timer_init(void)
|
|||
*__this_cpu_ptr(msm_evt.percpu_evt) = ce;
|
||||
res = request_percpu_irq(ce->irq, msm_timer_interrupt,
|
||||
ce->name, msm_evt.percpu_evt);
|
||||
if (!res)
|
||||
if (!res) {
|
||||
enable_percpu_irq(ce->irq, 0);
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
local_timer_register(&msm_local_timer_ops);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
msm_evt.evt = ce;
|
||||
res = request_irq(ce->irq, msm_timer_interrupt,
|
||||
|
@ -191,40 +234,6 @@ err:
|
|||
pr_err("clocksource_register failed\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
/* Use existing clock_event for cpu 0 */
|
||||
if (!smp_processor_id())
|
||||
return 0;
|
||||
|
||||
writel_relaxed(0, event_base + TIMER_ENABLE);
|
||||
writel_relaxed(0, event_base + TIMER_CLEAR);
|
||||
writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
|
||||
evt->irq = msm_clockevent.irq;
|
||||
evt->name = "local_timer";
|
||||
evt->features = msm_clockevent.features;
|
||||
evt->rating = msm_clockevent.rating;
|
||||
evt->set_mode = msm_timer_set_mode;
|
||||
evt->set_next_event = msm_timer_set_next_event;
|
||||
evt->shift = msm_clockevent.shift;
|
||||
evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
|
||||
evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
|
||||
evt->min_delta_ns = clockevent_delta2ns(4, evt);
|
||||
|
||||
*__this_cpu_ptr(msm_evt.percpu_evt) = evt;
|
||||
clockevents_register_device(evt);
|
||||
enable_percpu_irq(evt->irq, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void local_timer_stop(struct clock_event_device *evt)
|
||||
{
|
||||
evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
|
||||
disable_percpu_irq(evt->irq);
|
||||
}
|
||||
#endif /* CONFIG_LOCAL_TIMERS */
|
||||
|
||||
struct sys_timer msm_timer = {
|
||||
.init = msm_timer_init
|
||||
};
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include <plat/gpio-nomadik.h>
|
||||
#include <plat/mtu.h>
|
||||
|
||||
#include <mach/setup.h>
|
||||
#include <mach/nand.h>
|
||||
#include <mach/fsmc.h>
|
||||
|
||||
|
@ -246,10 +246,7 @@ static void __init nomadik_timer_init(void)
|
|||
src_cr |= SRC_CR_INIT_VAL;
|
||||
writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
|
||||
|
||||
/* Save global pointer to mtu, used by platform timer code */
|
||||
mtu_base = io_p2v(NOMADIK_MTU0_BASE);
|
||||
|
||||
nmdk_timer_init();
|
||||
nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE));
|
||||
}
|
||||
|
||||
static struct sys_timer nomadik_timer = {
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
|
||||
/*
|
||||
* These symbols are needed for board-specific files to call their
|
||||
* own cpu-specific files
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_SETUP_H
|
||||
#define __ASM_ARCH_SETUP_H
|
||||
|
||||
#include <asm/mach/time.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#ifdef CONFIG_NOMADIK_8815
|
||||
|
||||
extern void nmdk_timer_init(void);
|
||||
|
||||
#endif /* NOMADIK_8815 */
|
||||
|
||||
#endif /* __ASM_ARCH_SETUP_H */
|
|
@ -23,7 +23,6 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
|
|||
|
||||
# SMP support ONLY available for OMAP4
|
||||
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
|
||||
obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \
|
||||
sleep44xx.o
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* The MPU local timer source file. In OMAP4, both cortex-a9 cores have
|
||||
* own timer in it's MPU domain. These timers will be driving the
|
||||
* linux kernel SMP tick framework when active. These timers are not
|
||||
* part of the wake up domain.
|
||||
*
|
||||
* Copyright (C) 2009 Texas Instruments, Inc.
|
||||
*
|
||||
* Author:
|
||||
* Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||
*
|
||||
* This file is based on arm realview smp platform file.
|
||||
* Copyright (C) 2002 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/localtimer.h>
|
||||
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
/* Local timers are not supprted on OMAP4430 ES1.0 */
|
||||
if (omap_rev() == OMAP4430_REV_ES1_0)
|
||||
return -ENXIO;
|
||||
|
||||
evt->irq = OMAP44XX_IRQ_LOCALTIMER;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#include <asm/mach/time.h>
|
||||
#include <plat/dmtimer.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/sched_clock.h>
|
||||
#include "common.h"
|
||||
#include <plat/omap_hwmod.h>
|
||||
|
@ -324,14 +324,26 @@ OMAP_SYS_TIMER(3_secure)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP4
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
|
||||
OMAP44XX_LOCAL_TWD_BASE,
|
||||
OMAP44XX_IRQ_LOCALTIMER);
|
||||
#endif
|
||||
|
||||
static void __init omap4_timer_init(void)
|
||||
{
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
|
||||
BUG_ON(!twd_base);
|
||||
#endif
|
||||
omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
|
||||
omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE);
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
/* Local timers are not supprted on OMAP4430 ES1.0 */
|
||||
if (omap_rev() != OMAP4430_REV_ES1_0) {
|
||||
int err;
|
||||
|
||||
err = twd_local_timer_register(&twd_local_timer);
|
||||
if (err)
|
||||
pr_err("twd_local_timer_register failed %d\n", err);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
OMAP_SYS_TIMER(4)
|
||||
#endif
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <asm/pgtable.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
@ -383,6 +383,23 @@ static void realview_eb11mp_fixup(void)
|
|||
realview_eb_isp1761_resources[1].end = IRQ_EB11MP_USB;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
|
||||
REALVIEW_EB11MP_TWD_BASE,
|
||||
IRQ_LOCALTIMER);
|
||||
|
||||
static void __init realview_eb_twd_init(void)
|
||||
{
|
||||
if (core_tile_eb11mp() || core_tile_a9mp()) {
|
||||
int err = twd_local_timer_register(&twd_local_timer);
|
||||
if (err)
|
||||
pr_err("twd_local_timer_register failed %d\n", err);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define realview_eb_twd_init() do { } while(0)
|
||||
#endif
|
||||
|
||||
static void __init realview_eb_timer_init(void)
|
||||
{
|
||||
unsigned int timer_irq;
|
||||
|
@ -392,15 +409,13 @@ static void __init realview_eb_timer_init(void)
|
|||
timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE);
|
||||
timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20;
|
||||
|
||||
if (core_tile_eb11mp() || core_tile_a9mp()) {
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE);
|
||||
#endif
|
||||
if (core_tile_eb11mp() || core_tile_a9mp())
|
||||
timer_irq = IRQ_EB11MP_TIMER0_1;
|
||||
} else
|
||||
else
|
||||
timer_irq = IRQ_EB_TIMER0_1;
|
||||
|
||||
realview_timer_init(timer_irq);
|
||||
realview_eb_twd_init();
|
||||
}
|
||||
|
||||
static struct sys_timer realview_eb_timer = {
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <asm/pgtable.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
@ -290,6 +290,21 @@ static void __init gic_init_irq(void)
|
|||
gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
|
||||
REALVIEW_TC11MP_TWD_BASE,
|
||||
IRQ_LOCALTIMER);
|
||||
|
||||
static void __init realview_pb11mp_twd_init(void)
|
||||
{
|
||||
int err = twd_local_timer_register(&twd_local_timer);
|
||||
if (err)
|
||||
pr_err("twd_local_timer_register failed %d\n", err);
|
||||
}
|
||||
#else
|
||||
#define realview_pb11mp_twd_init() do {} while(0)
|
||||
#endif
|
||||
|
||||
static void __init realview_pb11mp_timer_init(void)
|
||||
{
|
||||
timer0_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE);
|
||||
|
@ -297,10 +312,8 @@ static void __init realview_pb11mp_timer_init(void)
|
|||
timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
|
||||
timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
|
||||
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE);
|
||||
#endif
|
||||
realview_timer_init(IRQ_TC11MP_TIMER0_1);
|
||||
realview_pb11mp_twd_init();
|
||||
}
|
||||
|
||||
static struct sys_timer realview_pb11mp_timer = {
|
||||
|
|
|
@ -298,6 +298,21 @@ static void __init gic_init_irq(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
|
||||
REALVIEW_PBX_TILE_TWD_BASE,
|
||||
IRQ_LOCALTIMER);
|
||||
|
||||
static void __init realview_pbx_twd_init(void)
|
||||
{
|
||||
int err = twd_local_timer_register(&twd_local_timer);
|
||||
if (err)
|
||||
pr_err("twd_local_timer_register failed %d\n", err);
|
||||
}
|
||||
#else
|
||||
#define realview_pbx_twd_init() do { } while(0)
|
||||
#endif
|
||||
|
||||
static void __init realview_pbx_timer_init(void)
|
||||
{
|
||||
timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE);
|
||||
|
@ -305,11 +320,8 @@ static void __init realview_pbx_timer_init(void)
|
|||
timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
|
||||
timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
|
||||
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
if (core_tile_pbx11mp() || core_tile_pbxa9mp())
|
||||
twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE);
|
||||
#endif
|
||||
realview_timer_init(IRQ_PBX_TIMER0_1);
|
||||
realview_pbx_twd_init();
|
||||
}
|
||||
|
||||
static struct sys_timer realview_pbx_timer = {
|
||||
|
|
|
@ -16,7 +16,6 @@ obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o
|
|||
# SMP objects
|
||||
smp-y := platsmp.o headsmp.o
|
||||
smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o
|
||||
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
|
||||
smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define __ARCH_MACH_COMMON_H
|
||||
|
||||
extern struct sys_timer shmobile_timer;
|
||||
struct twd_local_timer;
|
||||
void shmobile_twd_init(struct twd_local_timer *twd_local_timer);
|
||||
extern void shmobile_setup_console(void);
|
||||
extern void shmobile_secondary_vector(void);
|
||||
extern int shmobile_platform_cpu_kill(unsigned int cpu);
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* SMP support for R-Mobile / SH-Mobile - local timer portion
|
||||
*
|
||||
* Copyright (C) 2010 Magnus Damm
|
||||
*
|
||||
* Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/localtimer.h>
|
||||
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
evt->irq = 29;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
|
@ -17,7 +17,6 @@
|
|||
#include <linux/smp.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ static void __iomem *scu_base_addr(void)
|
|||
static DEFINE_SPINLOCK(scu_lock);
|
||||
static unsigned long tmp;
|
||||
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
|
||||
|
||||
static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
|
||||
{
|
||||
void __iomem *scu_base = scu_base_addr();
|
||||
|
@ -82,11 +84,7 @@ unsigned int __init r8a7779_get_core_count(void)
|
|||
{
|
||||
void __iomem *scu_base = scu_base_addr();
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
/* twd_base needs to be initialized before percpu_timer_setup() */
|
||||
twd_base = (void __iomem *)0xf0000600;
|
||||
#endif
|
||||
|
||||
shmobile_twd_init(&twd_local_timer);
|
||||
return scu_get_core_count(scu_base);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ static void __iomem *scu_base_addr(void)
|
|||
static DEFINE_SPINLOCK(scu_lock);
|
||||
static unsigned long tmp;
|
||||
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
|
||||
|
||||
static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
|
||||
{
|
||||
void __iomem *scu_base = scu_base_addr();
|
||||
|
@ -60,11 +62,7 @@ unsigned int __init sh73a0_get_core_count(void)
|
|||
{
|
||||
void __iomem *scu_base = scu_base_addr();
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
/* twd_base needs to be initialized before percpu_timer_setup() */
|
||||
twd_base = (void __iomem *)0xf0000600;
|
||||
#endif
|
||||
|
||||
shmobile_twd_init(&twd_local_timer);
|
||||
return scu_get_core_count(scu_base);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
static void __init shmobile_late_time_init(void)
|
||||
{
|
||||
|
@ -41,6 +42,15 @@ static void __init shmobile_timer_init(void)
|
|||
late_time_init = shmobile_late_time_init;
|
||||
}
|
||||
|
||||
void __init shmobile_twd_init(struct twd_local_timer *twd_local_timer)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
int err = twd_local_timer_register(twd_local_timer);
|
||||
if (err)
|
||||
pr_err("twd_local_timer_register failed %d\n", err);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct sys_timer shmobile_timer = {
|
||||
.init = shmobile_timer_init,
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
|
|||
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-tegra20-tables.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o
|
||||
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
|
||||
obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
|
||||
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* arch/arm/mach-tegra/localtimer.c
|
||||
*
|
||||
* Copyright (C) 2002 ARM Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/localtimer.h>
|
||||
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
evt->irq = IRQ_LOCALTIMER;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
|
@ -28,7 +28,7 @@
|
|||
#include <linux/io.h>
|
||||
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/sched_clock.h>
|
||||
|
||||
#include <mach/iomap.h>
|
||||
|
@ -162,6 +162,21 @@ static struct irqaction tegra_timer_irq = {
|
|||
.irq = INT_TMR3,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
|
||||
TEGRA_ARM_PERIF_BASE + 0x600,
|
||||
IRQ_LOCALTIMER);
|
||||
|
||||
static void __init tegra_twd_init(void)
|
||||
{
|
||||
int err = twd_local_timer_register(&twd_local_timer);
|
||||
if (err)
|
||||
pr_err("twd_local_timer_register failed %d\n", err);
|
||||
}
|
||||
#else
|
||||
#define tegra_twd_init() do {} while(0)
|
||||
#endif
|
||||
|
||||
static void __init tegra_init_timer(void)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
@ -188,10 +203,6 @@ static void __init tegra_init_timer(void)
|
|||
else
|
||||
clk_enable(clk);
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
|
||||
#endif
|
||||
|
||||
switch (rate) {
|
||||
case 12000000:
|
||||
timer_writel(0x000b, TIMERUS_USEC_CFG);
|
||||
|
@ -231,6 +242,7 @@ static void __init tegra_init_timer(void)
|
|||
tegra_clockevent.cpumask = cpu_all_mask;
|
||||
tegra_clockevent.irq = tegra_timer_irq.irq;
|
||||
clockevents_register_device(&tegra_clockevent);
|
||||
tegra_twd_init();
|
||||
}
|
||||
|
||||
struct sys_timer tegra_timer = {
|
||||
|
|
|
@ -28,6 +28,7 @@ config MACH_U8500
|
|||
bool "U8500 Development platform"
|
||||
depends on UX500_SOC_DB8500
|
||||
select TPS6105X
|
||||
select SOC_BUS
|
||||
help
|
||||
Include support for the mop500 development platform.
|
||||
|
||||
|
@ -49,6 +50,12 @@ config MACH_U5500
|
|||
depends on UX500_SOC_DB5500
|
||||
help
|
||||
Include support for the U5500 development platform.
|
||||
|
||||
config MACH_UX500_DT
|
||||
bool "Generic U8500 support using device tree"
|
||||
depends on MACH_U8500
|
||||
select USE_OF
|
||||
|
||||
endmenu
|
||||
|
||||
config UX500_DEBUG_UART
|
||||
|
|
|
@ -15,7 +15,6 @@ obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \
|
|||
obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o
|
||||
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
|
||||
obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o
|
||||
obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
params_phys-y := 0x00000100
|
||||
initrd_phys-y := 0x00800000
|
||||
|
||||
dtb-$(CONFIG_MACH_SNOWBALL) += snowball.dtb
|
||||
|
|
|
@ -104,7 +104,7 @@ static struct mmci_platform_data mop500_sdi0_data = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static void sdi0_configure(void)
|
||||
static void sdi0_configure(struct device *parent)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -123,15 +123,15 @@ static void sdi0_configure(void)
|
|||
gpio_direction_output(sdi0_en, 1);
|
||||
|
||||
/* Add the device, force v2 to subrevision 1 */
|
||||
db8500_add_sdi0(&mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
|
||||
db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
|
||||
}
|
||||
|
||||
void mop500_sdi_tc35892_init(void)
|
||||
void mop500_sdi_tc35892_init(struct device *parent)
|
||||
{
|
||||
mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
|
||||
sdi0_en = GPIO_SDMMC_EN;
|
||||
sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
|
||||
sdi0_configure();
|
||||
sdi0_configure(parent);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -246,12 +246,13 @@ static struct mmci_platform_data mop500_sdi4_data = {
|
|||
#endif
|
||||
};
|
||||
|
||||
void __init mop500_sdi_init(void)
|
||||
void __init mop500_sdi_init(struct device *parent)
|
||||
{
|
||||
/* PoP:ed eMMC */
|
||||
db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
|
||||
db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
|
||||
/* On-board eMMC */
|
||||
db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
|
||||
db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
|
||||
|
||||
/*
|
||||
* On boards with the TC35892 GPIO expander, sdi0 will finally
|
||||
* be added when the TC35892 initializes and calls
|
||||
|
@ -259,31 +260,31 @@ void __init mop500_sdi_init(void)
|
|||
*/
|
||||
}
|
||||
|
||||
void __init snowball_sdi_init(void)
|
||||
void __init snowball_sdi_init(struct device *parent)
|
||||
{
|
||||
/* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */
|
||||
mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED;
|
||||
/* On-board eMMC */
|
||||
db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
|
||||
db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
|
||||
/* External Micro SD slot */
|
||||
mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO;
|
||||
mop500_sdi0_data.cd_invert = true;
|
||||
sdi0_en = SNOWBALL_SDMMC_EN_GPIO;
|
||||
sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO;
|
||||
sdi0_configure();
|
||||
sdi0_configure(parent);
|
||||
}
|
||||
|
||||
void __init hrefv60_sdi_init(void)
|
||||
void __init hrefv60_sdi_init(struct device *parent)
|
||||
{
|
||||
/* PoP:ed eMMC */
|
||||
db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
|
||||
db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
|
||||
/* On-board eMMC */
|
||||
db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
|
||||
db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
|
||||
/* External Micro SD slot */
|
||||
mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
|
||||
sdi0_en = HREFV60_SDMMC_EN_GPIO;
|
||||
sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO;
|
||||
sdi0_configure();
|
||||
sdi0_configure(parent);
|
||||
/* WLAN SDIO channel */
|
||||
db8500_add_sdi1(&mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
|
||||
db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#include <linux/gpio_keys.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <linux/leds.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -226,7 +229,12 @@ static struct tps6105x_platform_data mop500_tps61052_data = {
|
|||
|
||||
static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base)
|
||||
{
|
||||
mop500_sdi_tc35892_init();
|
||||
struct device *parent = NULL;
|
||||
#if 0
|
||||
/* FIXME: Is the sdi actually part of tc3589x? */
|
||||
parent = tc3589x->dev;
|
||||
#endif
|
||||
mop500_sdi_tc35892_init(parent);
|
||||
}
|
||||
|
||||
static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = {
|
||||
|
@ -353,12 +361,12 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
|
|||
U8500_I2C_CONTROLLER(2, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
|
||||
U8500_I2C_CONTROLLER(3, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
|
||||
|
||||
static void __init mop500_i2c_init(void)
|
||||
static void __init mop500_i2c_init(struct device *parent)
|
||||
{
|
||||
db8500_add_i2c0(&u8500_i2c0_data);
|
||||
db8500_add_i2c1(&u8500_i2c1_data);
|
||||
db8500_add_i2c2(&u8500_i2c2_data);
|
||||
db8500_add_i2c3(&u8500_i2c3_data);
|
||||
db8500_add_i2c0(parent, &u8500_i2c0_data);
|
||||
db8500_add_i2c1(parent, &u8500_i2c1_data);
|
||||
db8500_add_i2c2(parent, &u8500_i2c2_data);
|
||||
db8500_add_i2c3(parent, &u8500_i2c3_data);
|
||||
}
|
||||
|
||||
static struct gpio_keys_button mop500_gpio_keys[] = {
|
||||
|
@ -435,7 +443,7 @@ static struct stedma40_chan_cfg ssp0_dma_cfg_tx = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static struct pl022_ssp_controller ssp0_platform_data = {
|
||||
static struct pl022_ssp_controller ssp0_plat = {
|
||||
.bus_id = 0,
|
||||
#ifdef CONFIG_STE_DMA40
|
||||
.enable_dma = 1,
|
||||
|
@ -451,9 +459,9 @@ static struct pl022_ssp_controller ssp0_platform_data = {
|
|||
.num_chipselect = 5,
|
||||
};
|
||||
|
||||
static void __init mop500_spi_init(void)
|
||||
static void __init mop500_spi_init(struct device *parent)
|
||||
{
|
||||
db8500_add_ssp0(&ssp0_platform_data);
|
||||
db8500_add_ssp0(parent, &ssp0_plat);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STE_DMA40
|
||||
|
@ -587,11 +595,11 @@ static struct amba_pl011_data uart2_plat = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static void __init mop500_uart_init(void)
|
||||
static void __init mop500_uart_init(struct device *parent)
|
||||
{
|
||||
db8500_add_uart0(&uart0_plat);
|
||||
db8500_add_uart1(&uart1_plat);
|
||||
db8500_add_uart2(&uart2_plat);
|
||||
db8500_add_uart0(parent, &uart0_plat);
|
||||
db8500_add_uart1(parent, &uart1_plat);
|
||||
db8500_add_uart2(parent, &uart2_plat);
|
||||
}
|
||||
|
||||
static struct platform_device *snowball_platform_devs[] __initdata = {
|
||||
|
@ -603,21 +611,27 @@ static struct platform_device *snowball_platform_devs[] __initdata = {
|
|||
|
||||
static void __init mop500_init_machine(void)
|
||||
{
|
||||
struct device *parent = NULL;
|
||||
int i2c0_devs;
|
||||
int i;
|
||||
|
||||
mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
|
||||
|
||||
u8500_init_devices();
|
||||
parent = u8500_init_devices();
|
||||
|
||||
mop500_pins_init();
|
||||
|
||||
/* FIXME: parent of ab8500 should be prcmu */
|
||||
for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
|
||||
mop500_platform_devs[i]->dev.parent = parent;
|
||||
|
||||
platform_add_devices(mop500_platform_devs,
|
||||
ARRAY_SIZE(mop500_platform_devs));
|
||||
|
||||
mop500_i2c_init();
|
||||
mop500_sdi_init();
|
||||
mop500_spi_init();
|
||||
mop500_uart_init();
|
||||
mop500_i2c_init(parent);
|
||||
mop500_sdi_init(parent);
|
||||
mop500_spi_init(parent);
|
||||
mop500_uart_init(parent);
|
||||
|
||||
i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
|
||||
|
||||
|
@ -631,19 +645,24 @@ static void __init mop500_init_machine(void)
|
|||
|
||||
static void __init snowball_init_machine(void)
|
||||
{
|
||||
struct device *parent = NULL;
|
||||
int i2c0_devs;
|
||||
int i;
|
||||
|
||||
u8500_init_devices();
|
||||
parent = u8500_init_devices();
|
||||
|
||||
snowball_pins_init();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
|
||||
snowball_platform_devs[i]->dev.parent = parent;
|
||||
|
||||
platform_add_devices(snowball_platform_devs,
|
||||
ARRAY_SIZE(snowball_platform_devs));
|
||||
|
||||
mop500_i2c_init();
|
||||
snowball_sdi_init();
|
||||
mop500_spi_init();
|
||||
mop500_uart_init();
|
||||
mop500_i2c_init(parent);
|
||||
snowball_sdi_init(parent);
|
||||
mop500_spi_init(parent);
|
||||
mop500_uart_init(parent);
|
||||
|
||||
i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
|
||||
i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
|
||||
|
@ -656,7 +675,9 @@ static void __init snowball_init_machine(void)
|
|||
|
||||
static void __init hrefv60_init_machine(void)
|
||||
{
|
||||
struct device *parent = NULL;
|
||||
int i2c0_devs;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* The HREFv60 board removed a GPIO expander and routed
|
||||
|
@ -665,17 +686,20 @@ static void __init hrefv60_init_machine(void)
|
|||
*/
|
||||
mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
|
||||
|
||||
u8500_init_devices();
|
||||
parent = u8500_init_devices();
|
||||
|
||||
hrefv60_pins_init();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
|
||||
mop500_platform_devs[i]->dev.parent = parent;
|
||||
|
||||
platform_add_devices(mop500_platform_devs,
|
||||
ARRAY_SIZE(mop500_platform_devs));
|
||||
|
||||
mop500_i2c_init();
|
||||
hrefv60_sdi_init();
|
||||
mop500_spi_init();
|
||||
mop500_uart_init();
|
||||
mop500_i2c_init(parent);
|
||||
hrefv60_sdi_init(parent);
|
||||
mop500_spi_init(parent);
|
||||
mop500_uart_init(parent);
|
||||
|
||||
i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
|
||||
|
||||
|
@ -718,3 +742,94 @@ MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
|
|||
.handle_irq = gic_handle_irq,
|
||||
.init_machine = snowball_init_machine,
|
||||
MACHINE_END
|
||||
|
||||
#ifdef CONFIG_MACH_UX500_DT
|
||||
|
||||
struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
|
||||
OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
|
||||
OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
|
||||
OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
|
||||
OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0", &ssp0_plat),
|
||||
{},
|
||||
};
|
||||
|
||||
static const struct of_device_id u8500_soc_node[] = {
|
||||
/* only create devices below soc node */
|
||||
{ .compatible = "stericsson,db8500", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static void __init u8500_init_machine(void)
|
||||
{
|
||||
struct device *parent = NULL;
|
||||
int i2c0_devs;
|
||||
int i;
|
||||
|
||||
parent = u8500_init_devices();
|
||||
i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
|
||||
mop500_platform_devs[i]->dev.parent = parent;
|
||||
for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
|
||||
snowball_platform_devs[i]->dev.parent = parent;
|
||||
|
||||
/* automatically probe child nodes of db8500 device */
|
||||
of_platform_populate(NULL, u8500_soc_node, u8500_auxdata_lookup, parent);
|
||||
|
||||
if (of_machine_is_compatible("st-ericsson,mop500")) {
|
||||
mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
|
||||
mop500_pins_init();
|
||||
|
||||
platform_add_devices(mop500_platform_devs,
|
||||
ARRAY_SIZE(mop500_platform_devs));
|
||||
|
||||
mop500_sdi_init(parent);
|
||||
} else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
|
||||
snowball_pins_init();
|
||||
platform_add_devices(snowball_platform_devs,
|
||||
ARRAY_SIZE(snowball_platform_devs));
|
||||
|
||||
snowball_sdi_init(parent);
|
||||
} else if (of_machine_is_compatible("st-ericsson,hrefv60+")) {
|
||||
/*
|
||||
* The HREFv60 board removed a GPIO expander and routed
|
||||
* all these GPIO pins to the internal GPIO controller
|
||||
* instead.
|
||||
*/
|
||||
mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
|
||||
i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES;
|
||||
hrefv60_pins_init();
|
||||
platform_add_devices(mop500_platform_devs,
|
||||
ARRAY_SIZE(mop500_platform_devs));
|
||||
|
||||
hrefv60_sdi_init(parent);
|
||||
}
|
||||
mop500_i2c_init(parent);
|
||||
|
||||
i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
|
||||
i2c_register_board_info(2, mop500_i2c2_devices,
|
||||
ARRAY_SIZE(mop500_i2c2_devices));
|
||||
|
||||
/* This board has full regulator constraints */
|
||||
regulator_has_full_constraints();
|
||||
}
|
||||
|
||||
static const char * u8500_dt_board_compat[] = {
|
||||
"calaosystems,snowball-a9500",
|
||||
"st-ericsson,hrefv60+",
|
||||
"st-ericsson,u8500",
|
||||
"st-ericsson,mop500",
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)")
|
||||
.map_io = u8500_map_io,
|
||||
.init_irq = ux500_init_irq,
|
||||
/* we re-use nomadik timer here */
|
||||
.timer = &ux500_timer,
|
||||
.handle_irq = gic_handle_irq,
|
||||
.init_machine = u8500_init_machine,
|
||||
.dt_compat = u8500_dt_board_compat,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
|
|
@ -75,10 +75,10 @@
|
|||
|
||||
struct i2c_board_info;
|
||||
|
||||
extern void mop500_sdi_init(void);
|
||||
extern void snowball_sdi_init(void);
|
||||
extern void hrefv60_sdi_init(void);
|
||||
extern void mop500_sdi_tc35892_init(void);
|
||||
extern void mop500_sdi_init(struct device *parent);
|
||||
extern void snowball_sdi_init(struct device *parent);
|
||||
extern void hrefv60_sdi_init(struct device *parent);
|
||||
extern void mop500_sdi_tc35892_init(struct device *parent);
|
||||
void __init mop500_u8500uib_init(void);
|
||||
void __init mop500_stuib_init(void);
|
||||
void __init mop500_pins_init(void);
|
||||
|
|
|
@ -66,9 +66,9 @@ static struct mmci_platform_data u5500_sdi0_data = {
|
|||
#endif
|
||||
};
|
||||
|
||||
void __init u5500_sdi_init(void)
|
||||
void __init u5500_sdi_init(struct device *parent)
|
||||
{
|
||||
nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins));
|
||||
|
||||
db5500_add_sdi0(&u5500_sdi0_data);
|
||||
db5500_add_sdi0(parent, &u5500_sdi0_data);
|
||||
}
|
||||
|
|
|
@ -97,9 +97,9 @@ static struct i2c_board_info __initdata u5500_i2c2_devices[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static void __init u5500_i2c_init(void)
|
||||
static void __init u5500_i2c_init(struct device *parent)
|
||||
{
|
||||
db5500_add_i2c2(&u5500_i2c2_data);
|
||||
db5500_add_i2c2(parent, &u5500_i2c2_data);
|
||||
i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices));
|
||||
}
|
||||
|
||||
|
@ -126,20 +126,27 @@ static struct platform_device *u5500_platform_devices[] __initdata = {
|
|||
&ab5500_device,
|
||||
};
|
||||
|
||||
static void __init u5500_uart_init(void)
|
||||
static void __init u5500_uart_init(struct device *parent)
|
||||
{
|
||||
db5500_add_uart0(NULL);
|
||||
db5500_add_uart1(NULL);
|
||||
db5500_add_uart2(NULL);
|
||||
db5500_add_uart0(parent, NULL);
|
||||
db5500_add_uart1(parent, NULL);
|
||||
db5500_add_uart2(parent, NULL);
|
||||
}
|
||||
|
||||
static void __init u5500_init_machine(void)
|
||||
{
|
||||
u5500_init_devices();
|
||||
struct device *parent = NULL;
|
||||
int i;
|
||||
|
||||
parent = u5500_init_devices();
|
||||
nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins));
|
||||
u5500_i2c_init();
|
||||
u5500_sdi_init();
|
||||
u5500_uart_init();
|
||||
|
||||
u5500_i2c_init(parent);
|
||||
u5500_sdi_init(parent);
|
||||
u5500_uart_init(parent);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(u5500_platform_devices); i++)
|
||||
u5500_platform_devices[i]->dev.parent = parent;
|
||||
|
||||
platform_add_devices(u5500_platform_devices,
|
||||
ARRAY_SIZE(u5500_platform_devices));
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <mach/hardware.h>
|
||||
|
@ -45,7 +47,10 @@ static int __init ux500_l2x0_init(void)
|
|||
ux500_l2x0_unlock();
|
||||
|
||||
/* 64KB way size, 8 way associativity, force WA */
|
||||
l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
|
||||
if (of_have_populated_dt())
|
||||
l2x0_of_init(0x3e060000, 0xc0000fff);
|
||||
else
|
||||
l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
|
||||
|
||||
/*
|
||||
* We can't disable l2 as we are in non secure mode, currently
|
||||
|
|
|
@ -147,13 +147,13 @@ static resource_size_t __initdata db5500_gpio_base[] = {
|
|||
U5500_GPIOBANK7_BASE,
|
||||
};
|
||||
|
||||
static void __init db5500_add_gpios(void)
|
||||
static void __init db5500_add_gpios(struct device *parent)
|
||||
{
|
||||
struct nmk_gpio_platform_data pdata = {
|
||||
/* No custom data yet */
|
||||
};
|
||||
|
||||
dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base),
|
||||
dbx500_add_gpios(parent, ARRAY_AND_SIZE(db5500_gpio_base),
|
||||
IRQ_DB5500_GPIO0, &pdata);
|
||||
}
|
||||
|
||||
|
@ -212,14 +212,36 @@ static int usb_db5500_tx_dma_cfg[] = {
|
|||
DB5500_DMA_DEV38_USB_OTG_OEP_8
|
||||
};
|
||||
|
||||
void __init u5500_init_devices(void)
|
||||
static const char *db5500_read_soc_id(void)
|
||||
{
|
||||
db5500_add_gpios();
|
||||
return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n");
|
||||
}
|
||||
|
||||
static struct device * __init db5500_soc_device_init(void)
|
||||
{
|
||||
const char *soc_id = db5500_read_soc_id();
|
||||
|
||||
return ux500_soc_device_init(soc_id);
|
||||
}
|
||||
|
||||
struct device * __init u5500_init_devices(void)
|
||||
{
|
||||
struct device *parent;
|
||||
int i;
|
||||
|
||||
parent = db5500_soc_device_init();
|
||||
|
||||
db5500_add_gpios(parent);
|
||||
db5500_pmu_init();
|
||||
db5500_dma_init();
|
||||
db5500_add_rtc();
|
||||
db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg);
|
||||
db5500_dma_init(parent);
|
||||
db5500_add_rtc(parent);
|
||||
db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(db5500_platform_devs); i++)
|
||||
db5500_platform_devs[i]->dev.parent = parent;
|
||||
|
||||
platform_add_devices(db5500_platform_devs,
|
||||
ARRAY_SIZE(db5500_platform_devs));
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <mach/setup.h>
|
||||
#include <mach/devices.h>
|
||||
#include <mach/usb.h>
|
||||
#include <mach/db8500-regs.h>
|
||||
|
||||
#include "devices-db8500.h"
|
||||
#include "ste-dma40-db8500.h"
|
||||
|
@ -132,13 +133,13 @@ static resource_size_t __initdata db8500_gpio_base[] = {
|
|||
U8500_GPIOBANK8_BASE,
|
||||
};
|
||||
|
||||
static void __init db8500_add_gpios(void)
|
||||
static void __init db8500_add_gpios(struct device *parent)
|
||||
{
|
||||
struct nmk_gpio_platform_data pdata = {
|
||||
.supports_sleepmode = true,
|
||||
};
|
||||
|
||||
dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base),
|
||||
dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base),
|
||||
IRQ_DB8500_GPIO0, &pdata);
|
||||
}
|
||||
|
||||
|
@ -164,17 +165,44 @@ static int usb_db8500_tx_dma_cfg[] = {
|
|||
DB8500_DMA_DEV39_USB_OTG_OEP_8
|
||||
};
|
||||
|
||||
static const char *db8500_read_soc_id(void)
|
||||
{
|
||||
void __iomem *uid = __io_address(U8500_BB_UID_BASE);
|
||||
|
||||
return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
|
||||
readl((u32 *)uid+1),
|
||||
readl((u32 *)uid+1), readl((u32 *)uid+2),
|
||||
readl((u32 *)uid+3), readl((u32 *)uid+4));
|
||||
}
|
||||
|
||||
static struct device * __init db8500_soc_device_init(void)
|
||||
{
|
||||
const char *soc_id = db8500_read_soc_id();
|
||||
|
||||
return ux500_soc_device_init(soc_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called from the board init
|
||||
*/
|
||||
void __init u8500_init_devices(void)
|
||||
struct device * __init u8500_init_devices(void)
|
||||
{
|
||||
db8500_add_rtc();
|
||||
db8500_add_gpios();
|
||||
db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
|
||||
struct device *parent;
|
||||
int i;
|
||||
|
||||
parent = db8500_soc_device_init();
|
||||
|
||||
db8500_add_rtc(parent);
|
||||
db8500_add_gpios(parent);
|
||||
db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
|
||||
|
||||
platform_device_register_data(parent,
|
||||
"cpufreq-u8500", -1, NULL, 0);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
|
||||
platform_devs[i]->dev.parent = parent;
|
||||
|
||||
platform_device_register_simple("cpufreq-u8500", -1, NULL, 0);
|
||||
platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
|
||||
|
||||
return ;
|
||||
return parent;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
|
||||
* Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson
|
||||
* License terms: GNU General Public License (GPL) version 2
|
||||
*/
|
||||
|
||||
|
@ -11,10 +12,15 @@
|
|||
#include <linux/mfd/db8500-prcmu.h>
|
||||
#include <linux/mfd/db5500-prcmu.h>
|
||||
#include <linux/clksrc-dbx500-prcmu.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/localtimer.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/setup.h>
|
||||
|
@ -24,6 +30,11 @@
|
|||
|
||||
void __iomem *_PRCMU_BASE;
|
||||
|
||||
static const struct of_device_id ux500_dt_irq_match[] = {
|
||||
{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
|
||||
{},
|
||||
};
|
||||
|
||||
void __init ux500_init_irq(void)
|
||||
{
|
||||
void __iomem *dist_base;
|
||||
|
@ -38,7 +49,12 @@ void __init ux500_init_irq(void)
|
|||
} else
|
||||
ux500_unknown_soc();
|
||||
|
||||
gic_init(0, 29, dist_base, cpu_base);
|
||||
#ifdef CONFIG_OF
|
||||
if (of_have_populated_dt())
|
||||
of_irq_init(ux500_dt_irq_match);
|
||||
else
|
||||
#endif
|
||||
gic_init(0, 29, dist_base, cpu_base);
|
||||
|
||||
/*
|
||||
* Init clocks here so that they are available for system timer
|
||||
|
@ -50,3 +66,73 @@ void __init ux500_init_irq(void)
|
|||
db8500_prcmu_early_init();
|
||||
clk_init();
|
||||
}
|
||||
|
||||
static const char * __init ux500_get_machine(void)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber());
|
||||
}
|
||||
|
||||
static const char * __init ux500_get_family(void)
|
||||
{
|
||||
return kasprintf(GFP_KERNEL, "ux500");
|
||||
}
|
||||
|
||||
static const char * __init ux500_get_revision(void)
|
||||
{
|
||||
unsigned int rev = dbx500_revision();
|
||||
|
||||
if (rev == 0x01)
|
||||
return kasprintf(GFP_KERNEL, "%s", "ED");
|
||||
else if (rev >= 0xA0)
|
||||
return kasprintf(GFP_KERNEL, "%d.%d",
|
||||
(rev >> 4) - 0xA + 1, rev & 0xf);
|
||||
|
||||
return kasprintf(GFP_KERNEL, "%s", "Unknown");
|
||||
}
|
||||
|
||||
static ssize_t ux500_get_process(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (dbx500_id.process == 0x00)
|
||||
return sprintf(buf, "Standard\n");
|
||||
|
||||
return sprintf(buf, "%02xnm\n", dbx500_id.process);
|
||||
}
|
||||
|
||||
static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr,
|
||||
const char *soc_id)
|
||||
{
|
||||
soc_dev_attr->soc_id = soc_id;
|
||||
soc_dev_attr->machine = ux500_get_machine();
|
||||
soc_dev_attr->family = ux500_get_family();
|
||||
soc_dev_attr->revision = ux500_get_revision();
|
||||
}
|
||||
|
||||
struct device_attribute ux500_soc_attr =
|
||||
__ATTR(process, S_IRUGO, ux500_get_process, NULL);
|
||||
|
||||
struct device * __init ux500_soc_device_init(const char *soc_id)
|
||||
{
|
||||
struct device *parent;
|
||||
struct soc_device *soc_dev;
|
||||
struct soc_device_attribute *soc_dev_attr;
|
||||
|
||||
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
||||
if (!soc_dev_attr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
soc_info_populate(soc_dev_attr, soc_id);
|
||||
|
||||
soc_dev = soc_device_register(soc_dev_attr);
|
||||
if (IS_ERR_OR_NULL(soc_dev)) {
|
||||
kfree(soc_dev_attr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parent = soc_device_to_device(soc_dev);
|
||||
if (!IS_ERR_OR_NULL(parent))
|
||||
device_create_file(parent, &ux500_soc_attr);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
#include "devices-common.h"
|
||||
|
||||
struct amba_device *
|
||||
dbx500_add_amba_device(const char *name, resource_size_t base,
|
||||
int irq, void *pdata, unsigned int periphid)
|
||||
dbx500_add_amba_device(struct device *parent, const char *name,
|
||||
resource_size_t base, int irq, void *pdata,
|
||||
unsigned int periphid)
|
||||
{
|
||||
struct amba_device *dev;
|
||||
int ret;
|
||||
|
@ -39,6 +40,8 @@ dbx500_add_amba_device(const char *name, resource_size_t base,
|
|||
|
||||
dev->dev.platform_data = pdata;
|
||||
|
||||
dev->dev.parent = parent;
|
||||
|
||||
ret = amba_device_add(dev, &iomem_resource);
|
||||
if (ret) {
|
||||
amba_device_put(dev);
|
||||
|
@ -49,60 +52,7 @@ dbx500_add_amba_device(const char *name, resource_size_t base,
|
|||
}
|
||||
|
||||
static struct platform_device *
|
||||
dbx500_add_platform_device(const char *name, int id, void *pdata,
|
||||
struct resource *res, int resnum)
|
||||
{
|
||||
struct platform_device *dev;
|
||||
int ret;
|
||||
|
||||
dev = platform_device_alloc(name, id);
|
||||
if (!dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
|
||||
|
||||
ret = platform_device_add_resources(dev, res, resnum);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
dev->dev.platform_data = pdata;
|
||||
|
||||
ret = platform_device_add(dev);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
return dev;
|
||||
|
||||
out_free:
|
||||
platform_device_put(dev);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
struct platform_device *
|
||||
dbx500_add_platform_device_4k1irq(const char *name, int id,
|
||||
resource_size_t base,
|
||||
int irq, void *pdata)
|
||||
{
|
||||
struct resource resources[] = {
|
||||
[0] = {
|
||||
.start = base,
|
||||
.end = base + SZ_4K - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = irq,
|
||||
.end = irq,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
return dbx500_add_platform_device(name, id, pdata, resources,
|
||||
ARRAY_SIZE(resources));
|
||||
}
|
||||
|
||||
static struct platform_device *
|
||||
dbx500_add_gpio(int id, resource_size_t addr, int irq,
|
||||
dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq,
|
||||
struct nmk_gpio_platform_data *pdata)
|
||||
{
|
||||
struct resource resources[] = {
|
||||
|
@ -118,13 +68,18 @@ dbx500_add_gpio(int id, resource_size_t addr, int irq,
|
|||
}
|
||||
};
|
||||
|
||||
return platform_device_register_resndata(NULL, "gpio", id,
|
||||
resources, ARRAY_SIZE(resources),
|
||||
pdata, sizeof(*pdata));
|
||||
return platform_device_register_resndata(
|
||||
parent,
|
||||
"gpio",
|
||||
id,
|
||||
resources,
|
||||
ARRAY_SIZE(resources),
|
||||
pdata,
|
||||
sizeof(*pdata));
|
||||
}
|
||||
|
||||
void dbx500_add_gpios(resource_size_t *base, int num, int irq,
|
||||
struct nmk_gpio_platform_data *pdata)
|
||||
void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
|
||||
int irq, struct nmk_gpio_platform_data *pdata)
|
||||
{
|
||||
int first = 0;
|
||||
int i;
|
||||
|
@ -134,6 +89,6 @@ void dbx500_add_gpios(resource_size_t *base, int num, int irq,
|
|||
pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first);
|
||||
pdata->num_gpio = 32;
|
||||
|
||||
dbx500_add_gpio(i, base[i], irq, pdata);
|
||||
dbx500_add_gpio(parent, i, base[i], irq, pdata);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,80 +8,89 @@
|
|||
#ifndef __DEVICES_COMMON_H
|
||||
#define __DEVICES_COMMON_H
|
||||
|
||||
extern struct amba_device *
|
||||
dbx500_add_amba_device(const char *name, resource_size_t base,
|
||||
int irq, void *pdata, unsigned int periphid);
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <plat/i2c.h>
|
||||
|
||||
extern struct platform_device *
|
||||
dbx500_add_platform_device_4k1irq(const char *name, int id,
|
||||
resource_size_t base,
|
||||
int irq, void *pdata);
|
||||
extern struct amba_device *
|
||||
dbx500_add_amba_device(struct device *parent, const char *name,
|
||||
resource_size_t base, int irq, void *pdata,
|
||||
unsigned int periphid);
|
||||
|
||||
struct spi_master_cntlr;
|
||||
|
||||
static inline struct amba_device *
|
||||
dbx500_add_msp_spi(const char *name, resource_size_t base, int irq,
|
||||
dbx500_add_msp_spi(struct device *parent, const char *name,
|
||||
resource_size_t base, int irq,
|
||||
struct spi_master_cntlr *pdata)
|
||||
{
|
||||
return dbx500_add_amba_device(name, base, irq, pdata, 0);
|
||||
return dbx500_add_amba_device(parent, name, base, irq,
|
||||
pdata, 0);
|
||||
}
|
||||
|
||||
static inline struct amba_device *
|
||||
dbx500_add_spi(const char *name, resource_size_t base, int irq,
|
||||
struct spi_master_cntlr *pdata,
|
||||
dbx500_add_spi(struct device *parent, const char *name, resource_size_t base,
|
||||
int irq, struct spi_master_cntlr *pdata,
|
||||
u32 periphid)
|
||||
{
|
||||
return dbx500_add_amba_device(name, base, irq, pdata, periphid);
|
||||
return dbx500_add_amba_device(parent, name, base, irq,
|
||||
pdata, periphid);
|
||||
}
|
||||
|
||||
struct mmci_platform_data;
|
||||
|
||||
static inline struct amba_device *
|
||||
dbx500_add_sdi(const char *name, resource_size_t base, int irq,
|
||||
struct mmci_platform_data *pdata,
|
||||
u32 periphid)
|
||||
dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base,
|
||||
int irq, struct mmci_platform_data *pdata, u32 periphid)
|
||||
{
|
||||
return dbx500_add_amba_device(name, base, irq, pdata, periphid);
|
||||
return dbx500_add_amba_device(parent, name, base, irq,
|
||||
pdata, periphid);
|
||||
}
|
||||
|
||||
struct amba_pl011_data;
|
||||
|
||||
static inline struct amba_device *
|
||||
dbx500_add_uart(const char *name, resource_size_t base, int irq,
|
||||
struct amba_pl011_data *pdata)
|
||||
dbx500_add_uart(struct device *parent, const char *name, resource_size_t base,
|
||||
int irq, struct amba_pl011_data *pdata)
|
||||
{
|
||||
return dbx500_add_amba_device(name, base, irq, pdata, 0);
|
||||
return dbx500_add_amba_device(parent, name, base, irq, pdata, 0);
|
||||
}
|
||||
|
||||
struct nmk_i2c_controller;
|
||||
|
||||
static inline struct platform_device *
|
||||
dbx500_add_i2c(int id, resource_size_t base, int irq,
|
||||
struct nmk_i2c_controller *pdata)
|
||||
dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq,
|
||||
struct nmk_i2c_controller *data)
|
||||
{
|
||||
return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq,
|
||||
pdata);
|
||||
}
|
||||
struct resource res[] = {
|
||||
DEFINE_RES_MEM(base, SZ_4K),
|
||||
DEFINE_RES_IRQ(irq),
|
||||
};
|
||||
|
||||
struct msp_i2s_platform_data;
|
||||
struct platform_device_info pdevinfo = {
|
||||
.parent = parent,
|
||||
.name = "nmk-i2c",
|
||||
.id = id,
|
||||
.res = res,
|
||||
.num_res = ARRAY_SIZE(res),
|
||||
.data = data,
|
||||
.size_data = sizeof(*data),
|
||||
.dma_mask = DMA_BIT_MASK(32),
|
||||
};
|
||||
|
||||
static inline struct platform_device *
|
||||
dbx500_add_msp_i2s(int id, resource_size_t base, int irq,
|
||||
struct msp_i2s_platform_data *pdata)
|
||||
{
|
||||
return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq,
|
||||
pdata);
|
||||
return platform_device_register_full(&pdevinfo);
|
||||
}
|
||||
|
||||
static inline struct amba_device *
|
||||
dbx500_add_rtc(resource_size_t base, int irq)
|
||||
dbx500_add_rtc(struct device *parent, resource_size_t base, int irq)
|
||||
{
|
||||
return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0);
|
||||
return dbx500_add_amba_device(parent, "rtc-pl031", base, irq, NULL, 0);
|
||||
}
|
||||
|
||||
struct nmk_gpio_platform_data;
|
||||
|
||||
void dbx500_add_gpios(resource_size_t *base, int num, int irq,
|
||||
struct nmk_gpio_platform_data *pdata);
|
||||
void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
|
||||
int irq, struct nmk_gpio_platform_data *pdata);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,70 +10,90 @@
|
|||
|
||||
#include "devices-common.h"
|
||||
|
||||
#define db5500_add_i2c1(pdata) \
|
||||
dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata)
|
||||
#define db5500_add_i2c2(pdata) \
|
||||
dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata)
|
||||
#define db5500_add_i2c3(pdata) \
|
||||
dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata)
|
||||
#define db5500_add_i2c1(parent, pdata) \
|
||||
dbx500_add_i2c(parent, 1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata)
|
||||
#define db5500_add_i2c2(parent, pdata) \
|
||||
dbx500_add_i2c(parent, 2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata)
|
||||
#define db5500_add_i2c3(parent, pdata) \
|
||||
dbx500_add_i2c(parent, 3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata)
|
||||
|
||||
#define db5500_add_msp0_i2s(pdata) \
|
||||
dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
|
||||
#define db5500_add_msp1_i2s(pdata) \
|
||||
dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
|
||||
#define db5500_add_msp2_i2s(pdata) \
|
||||
dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
|
||||
#define db5500_add_msp0_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \
|
||||
IRQ_DB5500_MSP0, pdata)
|
||||
#define db5500_add_msp1_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \
|
||||
IRQ_DB5500_MSP1, pdata)
|
||||
#define db5500_add_msp2_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \
|
||||
IRQ_DB5500_MSP2, pdata)
|
||||
|
||||
#define db5500_add_msp0_spi(pdata) \
|
||||
dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
|
||||
#define db5500_add_msp1_spi(pdata) \
|
||||
dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
|
||||
#define db5500_add_msp2_spi(pdata) \
|
||||
dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
|
||||
#define db5500_add_msp0_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \
|
||||
IRQ_DB5500_MSP0, pdata)
|
||||
#define db5500_add_msp1_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \
|
||||
IRQ_DB5500_MSP1, pdata)
|
||||
#define db5500_add_msp2_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \
|
||||
IRQ_DB5500_MSP2, pdata)
|
||||
|
||||
#define db5500_add_rtc() \
|
||||
dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC);
|
||||
#define db5500_add_rtc(parent) \
|
||||
dbx500_add_rtc(parent, U5500_RTC_BASE, IRQ_DB5500_RTC);
|
||||
|
||||
#define db5500_add_usb(rx_cfg, tx_cfg) \
|
||||
ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg)
|
||||
#define db5500_add_usb(parent, rx_cfg, tx_cfg) \
|
||||
ux500_add_usb(parent, U5500_USBOTG_BASE, \
|
||||
IRQ_DB5500_USBOTG, rx_cfg, tx_cfg)
|
||||
|
||||
#define db5500_add_sdi0(pdata) \
|
||||
dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \
|
||||
#define db5500_add_sdi0(parent, pdata) \
|
||||
dbx500_add_sdi(parent, "sdi0", U5500_SDI0_BASE, \
|
||||
IRQ_DB5500_SDMMC0, pdata, \
|
||||
0x10480180)
|
||||
#define db5500_add_sdi1(pdata) \
|
||||
dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \
|
||||
#define db5500_add_sdi1(parent, pdata) \
|
||||
dbx500_add_sdi(parent, "sdi1", U5500_SDI1_BASE, \
|
||||
IRQ_DB5500_SDMMC1, pdata, \
|
||||
0x10480180)
|
||||
#define db5500_add_sdi2(pdata) \
|
||||
dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \
|
||||
#define db5500_add_sdi2(parent, pdata) \
|
||||
dbx500_add_sdi(parent, "sdi2", U5500_SDI2_BASE, \
|
||||
IRQ_DB5500_SDMMC2, pdata \
|
||||
0x10480180)
|
||||
#define db5500_add_sdi3(pdata) \
|
||||
dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \
|
||||
#define db5500_add_sdi3(parent, pdata) \
|
||||
dbx500_add_sdi(parent, "sdi3", U5500_SDI3_BASE, \
|
||||
IRQ_DB5500_SDMMC3, pdata \
|
||||
0x10480180)
|
||||
#define db5500_add_sdi4(pdata) \
|
||||
dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \
|
||||
#define db5500_add_sdi4(parent, pdata) \
|
||||
dbx500_add_sdi(parent, "sdi4", U5500_SDI4_BASE, \
|
||||
IRQ_DB5500_SDMMC4, pdata \
|
||||
0x10480180)
|
||||
|
||||
/* This one has a bad peripheral ID in the U5500 silicon */
|
||||
#define db5500_add_spi0(pdata) \
|
||||
dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \
|
||||
#define db5500_add_spi0(parent, pdata) \
|
||||
dbx500_add_spi(parent, "spi0", U5500_SPI0_BASE, \
|
||||
IRQ_DB5500_SPI0, pdata, \
|
||||
0x10080023)
|
||||
#define db5500_add_spi1(pdata) \
|
||||
dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \
|
||||
#define db5500_add_spi1(parent, pdata) \
|
||||
dbx500_add_spi(parent, "spi1", U5500_SPI1_BASE, \
|
||||
IRQ_DB5500_SPI1, pdata, \
|
||||
0x10080023)
|
||||
#define db5500_add_spi2(pdata) \
|
||||
dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \
|
||||
#define db5500_add_spi2(parent, pdata) \
|
||||
dbx500_add_spi(parent, "spi2", U5500_SPI2_BASE, \
|
||||
IRQ_DB5500_SPI2, pdata \
|
||||
0x10080023)
|
||||
#define db5500_add_spi3(pdata) \
|
||||
dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \
|
||||
#define db5500_add_spi3(parent, pdata) \
|
||||
dbx500_add_spi(parent, "spi3", U5500_SPI3_BASE, \
|
||||
IRQ_DB5500_SPI3, pdata \
|
||||
0x10080023)
|
||||
|
||||
#define db5500_add_uart0(plat) \
|
||||
dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat)
|
||||
#define db5500_add_uart1(plat) \
|
||||
dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1, plat)
|
||||
#define db5500_add_uart2(plat) \
|
||||
dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2, plat)
|
||||
#define db5500_add_uart3(plat) \
|
||||
dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat)
|
||||
#define db5500_add_uart0(parent, plat) \
|
||||
dbx500_add_uart(parent, "uart0", U5500_UART0_BASE, \
|
||||
IRQ_DB5500_UART0, plat)
|
||||
#define db5500_add_uart1(parent, plat) \
|
||||
dbx500_add_uart(parent, "uart1", U5500_UART1_BASE, \
|
||||
IRQ_DB5500_UART1, plat)
|
||||
#define db5500_add_uart2(parent, plat) \
|
||||
dbx500_add_uart(parent, "uart2", U5500_UART2_BASE, \
|
||||
IRQ_DB5500_UART2, plat)
|
||||
#define db5500_add_uart3(parent, plat) \
|
||||
dbx500_add_uart(parent, "uart3", U5500_UART3_BASE, \
|
||||
IRQ_DB5500_UART3, plat)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,88 +14,114 @@ struct ske_keypad_platform_data;
|
|||
struct pl022_ssp_controller;
|
||||
|
||||
static inline struct platform_device *
|
||||
db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata)
|
||||
db8500_add_ske_keypad(struct device *parent,
|
||||
struct ske_keypad_platform_data *pdata,
|
||||
size_t size)
|
||||
{
|
||||
return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1,
|
||||
U8500_SKE_BASE,
|
||||
IRQ_DB8500_KB, pdata);
|
||||
struct resource resources[] = {
|
||||
DEFINE_RES_MEM(U8500_SKE_BASE, SZ_4K),
|
||||
DEFINE_RES_IRQ(IRQ_DB8500_KB),
|
||||
};
|
||||
|
||||
return platform_device_register_resndata(parent, "nmk-ske-keypad", -1,
|
||||
resources, 2, pdata, size);
|
||||
}
|
||||
|
||||
static inline struct amba_device *
|
||||
db8500_add_ssp(const char *name, resource_size_t base, int irq,
|
||||
struct pl022_ssp_controller *pdata)
|
||||
db8500_add_ssp(struct device *parent, const char *name, resource_size_t base,
|
||||
int irq, struct pl022_ssp_controller *pdata)
|
||||
{
|
||||
return dbx500_add_amba_device(name, base, irq, pdata, 0);
|
||||
return dbx500_add_amba_device(parent, name, base, irq, pdata, 0);
|
||||
}
|
||||
|
||||
|
||||
#define db8500_add_i2c0(pdata) \
|
||||
dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
|
||||
#define db8500_add_i2c1(pdata) \
|
||||
dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
|
||||
#define db8500_add_i2c2(pdata) \
|
||||
dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
|
||||
#define db8500_add_i2c3(pdata) \
|
||||
dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
|
||||
#define db8500_add_i2c4(pdata) \
|
||||
dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
|
||||
#define db8500_add_i2c0(parent, pdata) \
|
||||
dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
|
||||
#define db8500_add_i2c1(parent, pdata) \
|
||||
dbx500_add_i2c(parent, 1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
|
||||
#define db8500_add_i2c2(parent, pdata) \
|
||||
dbx500_add_i2c(parent, 2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
|
||||
#define db8500_add_i2c3(parent, pdata) \
|
||||
dbx500_add_i2c(parent, 3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
|
||||
#define db8500_add_i2c4(parent, pdata) \
|
||||
dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
|
||||
|
||||
#define db8500_add_msp0_i2s(pdata) \
|
||||
dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
|
||||
#define db8500_add_msp1_i2s(pdata) \
|
||||
dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
|
||||
#define db8500_add_msp2_i2s(pdata) \
|
||||
dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
|
||||
#define db8500_add_msp3_i2s(pdata) \
|
||||
dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
|
||||
#define db8500_add_msp0_i2s(parent, pdata) \
|
||||
dbx500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
|
||||
#define db8500_add_msp1_i2s(parent, pdata) \
|
||||
dbx500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
|
||||
#define db8500_add_msp2_i2s(parent, pdata) \
|
||||
dbx500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
|
||||
#define db8500_add_msp3_i2s(parent, pdata) \
|
||||
dbx500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
|
||||
|
||||
#define db8500_add_msp0_spi(pdata) \
|
||||
dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
|
||||
#define db8500_add_msp1_spi(pdata) \
|
||||
dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
|
||||
#define db8500_add_msp2_spi(pdata) \
|
||||
dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
|
||||
#define db8500_add_msp3_spi(pdata) \
|
||||
dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
|
||||
#define db8500_add_msp0_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \
|
||||
IRQ_DB8500_MSP0, pdata)
|
||||
#define db8500_add_msp1_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp1", U8500_MSP1_BASE, \
|
||||
IRQ_DB8500_MSP1, pdata)
|
||||
#define db8500_add_msp2_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp2", U8500_MSP2_BASE, \
|
||||
IRQ_DB8500_MSP2, pdata)
|
||||
#define db8500_add_msp3_spi(parent, pdata) \
|
||||
dbx500_add_msp_spi(parent, "msp3", U8500_MSP3_BASE, \
|
||||
IRQ_DB8500_MSP1, pdata)
|
||||
|
||||
#define db8500_add_rtc() \
|
||||
dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC);
|
||||
#define db8500_add_rtc(parent) \
|
||||
dbx500_add_rtc(parent, U8500_RTC_BASE, IRQ_DB8500_RTC);
|
||||
|
||||
#define db8500_add_usb(rx_cfg, tx_cfg) \
|
||||
ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
|
||||
#define db8500_add_usb(parent, rx_cfg, tx_cfg) \
|
||||
ux500_add_usb(parent, U8500_USBOTG_BASE, \
|
||||
IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
|
||||
|
||||
#define db8500_add_sdi0(pdata, pid) \
|
||||
dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid)
|
||||
#define db8500_add_sdi1(pdata, pid) \
|
||||
dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid)
|
||||
#define db8500_add_sdi2(pdata, pid) \
|
||||
dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid)
|
||||
#define db8500_add_sdi3(pdata, pid) \
|
||||
dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid)
|
||||
#define db8500_add_sdi4(pdata, pid) \
|
||||
dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid)
|
||||
#define db8500_add_sdi5(pdata, pid) \
|
||||
dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid)
|
||||
#define db8500_add_sdi0(parent, pdata, pid) \
|
||||
dbx500_add_sdi(parent, "sdi0", U8500_SDI0_BASE, \
|
||||
IRQ_DB8500_SDMMC0, pdata, pid)
|
||||
#define db8500_add_sdi1(parent, pdata, pid) \
|
||||
dbx500_add_sdi(parent, "sdi1", U8500_SDI1_BASE, \
|
||||
IRQ_DB8500_SDMMC1, pdata, pid)
|
||||
#define db8500_add_sdi2(parent, pdata, pid) \
|
||||
dbx500_add_sdi(parent, "sdi2", U8500_SDI2_BASE, \
|
||||
IRQ_DB8500_SDMMC2, pdata, pid)
|
||||
#define db8500_add_sdi3(parent, pdata, pid) \
|
||||
dbx500_add_sdi(parent, "sdi3", U8500_SDI3_BASE, \
|
||||
IRQ_DB8500_SDMMC3, pdata, pid)
|
||||
#define db8500_add_sdi4(parent, pdata, pid) \
|
||||
dbx500_add_sdi(parent, "sdi4", U8500_SDI4_BASE, \
|
||||
IRQ_DB8500_SDMMC4, pdata, pid)
|
||||
#define db8500_add_sdi5(parent, pdata, pid) \
|
||||
dbx500_add_sdi(parent, "sdi5", U8500_SDI5_BASE, \
|
||||
IRQ_DB8500_SDMMC5, pdata, pid)
|
||||
|
||||
#define db8500_add_ssp0(pdata) \
|
||||
db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata)
|
||||
#define db8500_add_ssp1(pdata) \
|
||||
db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata)
|
||||
#define db8500_add_ssp0(parent, pdata) \
|
||||
db8500_add_ssp(parent, "ssp0", U8500_SSP0_BASE, \
|
||||
IRQ_DB8500_SSP0, pdata)
|
||||
#define db8500_add_ssp1(parent, pdata) \
|
||||
db8500_add_ssp(parent, "ssp1", U8500_SSP1_BASE, \
|
||||
IRQ_DB8500_SSP1, pdata)
|
||||
|
||||
#define db8500_add_spi0(pdata) \
|
||||
dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0)
|
||||
#define db8500_add_spi1(pdata) \
|
||||
dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0)
|
||||
#define db8500_add_spi2(pdata) \
|
||||
dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0)
|
||||
#define db8500_add_spi3(pdata) \
|
||||
dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0)
|
||||
#define db8500_add_spi0(parent, pdata) \
|
||||
dbx500_add_spi(parent, "spi0", U8500_SPI0_BASE, \
|
||||
IRQ_DB8500_SPI0, pdata, 0)
|
||||
#define db8500_add_spi1(parent, pdata) \
|
||||
dbx500_add_spi(parent, "spi1", U8500_SPI1_BASE, \
|
||||
IRQ_DB8500_SPI1, pdata, 0)
|
||||
#define db8500_add_spi2(parent, pdata) \
|
||||
dbx500_add_spi(parent, "spi2", U8500_SPI2_BASE, \
|
||||
IRQ_DB8500_SPI2, pdata, 0)
|
||||
#define db8500_add_spi3(parent, pdata) \
|
||||
dbx500_add_spi(parent, "spi3", U8500_SPI3_BASE, \
|
||||
IRQ_DB8500_SPI3, pdata, 0)
|
||||
|
||||
#define db8500_add_uart0(pdata) \
|
||||
dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata)
|
||||
#define db8500_add_uart1(pdata) \
|
||||
dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1, pdata)
|
||||
#define db8500_add_uart2(pdata) \
|
||||
dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata)
|
||||
#define db8500_add_uart0(parent, pdata) \
|
||||
dbx500_add_uart(parent, "uart0", U8500_UART0_BASE, \
|
||||
IRQ_DB8500_UART0, pdata)
|
||||
#define db8500_add_uart1(parent, pdata) \
|
||||
dbx500_add_uart(parent, "uart1", U8500_UART1_BASE, \
|
||||
IRQ_DB8500_UART1, pdata)
|
||||
#define db8500_add_uart2(parent, pdata) \
|
||||
dbx500_add_uart(parent, "uart2", U8500_UART2_BASE, \
|
||||
IRQ_DB8500_UART2, pdata)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -125,10 +125,11 @@ static struct platform_device dma40_device = {
|
|||
.resource = dma40_resources
|
||||
};
|
||||
|
||||
void __init db5500_dma_init(void)
|
||||
void __init db5500_dma_init(struct device *parent)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dma40_device.dev.parent = parent;
|
||||
ret = platform_device_register(&dma40_device);
|
||||
if (ret)
|
||||
dev_err(&dma40_device.dev, "unable to register device: %d\n", ret);
|
||||
|
|
|
@ -161,4 +161,7 @@
|
|||
#define U8500_MODEM_BASE 0xe000000
|
||||
#define U8500_APE_BASE 0x6000000
|
||||
|
||||
/* SoC identification number information */
|
||||
#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,17 +18,16 @@ void __init ux500_map_io(void);
|
|||
extern void __init u5500_map_io(void);
|
||||
extern void __init u8500_map_io(void);
|
||||
|
||||
extern void __init u5500_init_devices(void);
|
||||
extern void __init u8500_init_devices(void);
|
||||
extern struct device * __init u5500_init_devices(void);
|
||||
extern struct device * __init u8500_init_devices(void);
|
||||
|
||||
extern void __init ux500_init_irq(void);
|
||||
|
||||
extern void __init u5500_sdi_init(void);
|
||||
extern void __init u5500_sdi_init(struct device *parent);
|
||||
|
||||
extern void __init db5500_dma_init(void);
|
||||
extern void __init db5500_dma_init(struct device *parent);
|
||||
|
||||
/* We re-use nomadik_timer for this platform */
|
||||
extern void nmdk_timer_init(void);
|
||||
extern struct device *ux500_soc_device_init(const char *soc_id);
|
||||
|
||||
struct amba_device;
|
||||
extern void __init amba_add_devices(struct amba_device *devs[], int num);
|
||||
|
|
|
@ -20,6 +20,6 @@ struct ux500_musb_board_data {
|
|||
bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
|
||||
};
|
||||
|
||||
void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
|
||||
int *dma_tx_cfg);
|
||||
void ux500_add_usb(struct device *parent, resource_size_t base,
|
||||
int irq, int *dma_rx_cfg, int *dma_tx_cfg);
|
||||
#endif
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 ST-Ericsson
|
||||
* Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
|
||||
*
|
||||
* This file is heavily based on relaview platform, almost a copy.
|
||||
*
|
||||
* Copyright (C) 2002 ARM Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/clockchips.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/localtimer.h>
|
||||
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
evt->irq = IRQ_LOCALTIMER;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
|
@ -7,29 +7,52 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clksrc-dbx500-prcmu.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/smp_twd.h>
|
||||
|
||||
#include <plat/mtu.h>
|
||||
|
||||
#include <mach/setup.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
static DEFINE_TWD_LOCAL_TIMER(u5500_twd_local_timer,
|
||||
U5500_TWD_BASE, IRQ_LOCALTIMER);
|
||||
static DEFINE_TWD_LOCAL_TIMER(u8500_twd_local_timer,
|
||||
U8500_TWD_BASE, IRQ_LOCALTIMER);
|
||||
|
||||
static void __init ux500_twd_init(void)
|
||||
{
|
||||
struct twd_local_timer *twd_local_timer;
|
||||
int err;
|
||||
|
||||
twd_local_timer = cpu_is_u5500() ? &u5500_twd_local_timer :
|
||||
&u8500_twd_local_timer;
|
||||
|
||||
if (of_have_populated_dt())
|
||||
twd_local_timer_of_register();
|
||||
else {
|
||||
err = twd_local_timer_register(twd_local_timer);
|
||||
if (err)
|
||||
pr_err("twd_local_timer_register failed %d\n", err);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ux500_twd_init() do { } while(0)
|
||||
#endif
|
||||
|
||||
static void __init ux500_timer_init(void)
|
||||
{
|
||||
void __iomem *mtu_timer_base;
|
||||
void __iomem *prcmu_timer_base;
|
||||
|
||||
if (cpu_is_u5500()) {
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
twd_base = __io_address(U5500_TWD_BASE);
|
||||
#endif
|
||||
mtu_base = __io_address(U5500_MTU0_BASE);
|
||||
mtu_timer_base = __io_address(U5500_MTU0_BASE);
|
||||
prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
|
||||
} else if (cpu_is_u8500()) {
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
twd_base = __io_address(U8500_TWD_BASE);
|
||||
#endif
|
||||
mtu_base = __io_address(U8500_MTU0_BASE);
|
||||
mtu_timer_base = __io_address(U8500_MTU0_BASE);
|
||||
prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
|
||||
} else {
|
||||
ux500_unknown_soc();
|
||||
|
@ -52,8 +75,9 @@ static void __init ux500_timer_init(void)
|
|||
*
|
||||
*/
|
||||
|
||||
nmdk_timer_init();
|
||||
nmdk_timer_init(mtu_timer_base);
|
||||
clksrc_dbx500_prcmu_init(prcmu_timer_base);
|
||||
ux500_twd_init();
|
||||
}
|
||||
|
||||
static void ux500_timer_reset(void)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/usb/musb.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <plat/ste_dma40.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/usb.h>
|
||||
|
@ -140,8 +141,8 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type)
|
|||
musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx];
|
||||
}
|
||||
|
||||
void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
|
||||
int *dma_tx_cfg)
|
||||
void ux500_add_usb(struct device *parent, resource_size_t base, int irq,
|
||||
int *dma_rx_cfg, int *dma_tx_cfg)
|
||||
{
|
||||
ux500_musb_device.resource[0].start = base;
|
||||
ux500_musb_device.resource[0].end = base + SZ_64K - 1;
|
||||
|
@ -151,5 +152,7 @@ void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
|
|||
ux500_usb_dma_update_rx_ch_config(dma_rx_cfg);
|
||||
ux500_usb_dma_update_tx_ch_config(dma_tx_cfg);
|
||||
|
||||
ux500_musb_device.dev.parent = parent;
|
||||
|
||||
platform_device_register(&ux500_musb_device);
|
||||
}
|
||||
|
|
|
@ -42,15 +42,26 @@ static struct map_desc ct_ca9x4_io_desc[] __initdata = {
|
|||
static void __init ct_ca9x4_map_io(void)
|
||||
{
|
||||
iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
|
||||
#ifdef CONFIG_LOCAL_TIMERS
|
||||
twd_base = ioremap(A9_MPCORE_TWD, SZ_32);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
|
||||
|
||||
static void __init ca9x4_twd_init(void)
|
||||
{
|
||||
int err = twd_local_timer_register(&twd_local_timer);
|
||||
if (err)
|
||||
pr_err("twd_local_timer_register failed %d\n", err);
|
||||
}
|
||||
#else
|
||||
#define ca9x4_twd_init() do {} while(0)
|
||||
#endif
|
||||
|
||||
static void __init ct_ca9x4_init_irq(void)
|
||||
{
|
||||
gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
|
||||
ioremap(A9_MPCORE_GIC_CPU, SZ_256));
|
||||
ca9x4_twd_init();
|
||||
}
|
||||
|
||||
static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
#ifndef __PLAT_MTU_H
|
||||
#define __PLAT_MTU_H
|
||||
|
||||
/* should be set by the platform code */
|
||||
extern void __iomem *mtu_base;
|
||||
|
||||
void nmdk_timer_init(void __iomem *base);
|
||||
void nmdk_clkevt_reset(void);
|
||||
void nmdk_clksrc_reset(void);
|
||||
|
||||
|
|
|
@ -20,12 +20,6 @@
|
|||
#include <asm/mach/time.h>
|
||||
#include <asm/sched_clock.h>
|
||||
|
||||
/*
|
||||
* Guaranteed runtime conversion range in seconds for
|
||||
* the clocksource and clockevent.
|
||||
*/
|
||||
#define MTU_MIN_RANGE 4
|
||||
|
||||
/*
|
||||
* The MTU device hosts four different counters, with 4 set of
|
||||
* registers. These are register names.
|
||||
|
@ -66,12 +60,11 @@
|
|||
#define MTU_PCELL2 0xff8
|
||||
#define MTU_PCELL3 0xffC
|
||||
|
||||
static void __iomem *mtu_base;
|
||||
static bool clkevt_periodic;
|
||||
static u32 clk_prescale;
|
||||
static u32 nmdk_cycle; /* write-once */
|
||||
|
||||
void __iomem *mtu_base; /* Assigned by machine code */
|
||||
|
||||
#ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK
|
||||
/*
|
||||
* Override the global weak sched_clock symbol with this
|
||||
|
@ -103,7 +96,6 @@ static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
|
|||
void nmdk_clkevt_reset(void)
|
||||
{
|
||||
if (clkevt_periodic) {
|
||||
|
||||
/* Timer: configure load and background-load, and fire it up */
|
||||
writel(nmdk_cycle, mtu_base + MTU_LR(1));
|
||||
writel(nmdk_cycle, mtu_base + MTU_BGLR(1));
|
||||
|
@ -121,7 +113,6 @@ void nmdk_clkevt_reset(void)
|
|||
static void nmdk_clkevt_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *dev)
|
||||
{
|
||||
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_PERIODIC:
|
||||
clkevt_periodic = true;
|
||||
|
@ -183,15 +174,16 @@ void nmdk_clksrc_reset(void)
|
|||
mtu_base + MTU_CR(0));
|
||||
}
|
||||
|
||||
void __init nmdk_timer_init(void)
|
||||
void __init nmdk_timer_init(void __iomem *base)
|
||||
{
|
||||
unsigned long rate;
|
||||
struct clk *clk0;
|
||||
|
||||
mtu_base = base;
|
||||
clk0 = clk_get_sys("mtu0", NULL);
|
||||
BUG_ON(IS_ERR(clk0));
|
||||
|
||||
clk_enable(clk0);
|
||||
BUG_ON(clk_prepare(clk0) < 0);
|
||||
BUG_ON(clk_enable(clk0) < 0);
|
||||
|
||||
/*
|
||||
* Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
|
||||
|
@ -224,17 +216,8 @@ void __init nmdk_timer_init(void)
|
|||
setup_sched_clock(nomadik_read_sched_clock, 32, rate);
|
||||
#endif
|
||||
|
||||
/* Timer 1 is used for events */
|
||||
|
||||
clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
|
||||
|
||||
nmdk_clkevt.max_delta_ns =
|
||||
clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
|
||||
nmdk_clkevt.min_delta_ns =
|
||||
clockevent_delta2ns(0x00000002, &nmdk_clkevt);
|
||||
nmdk_clkevt.cpumask = cpumask_of(0);
|
||||
|
||||
/* Register irq and clockevents */
|
||||
/* Timer 1 is used for events, register irq and clockevents */
|
||||
setup_irq(IRQ_MTU0, &nmdk_timer_irq);
|
||||
clockevents_register_device(&nmdk_clkevt);
|
||||
nmdk_clkevt.cpumask = cpumask_of(0);
|
||||
clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
obj-y := clock.o
|
||||
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
|
||||
obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
|
||||
obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
|
||||
obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* linux/arch/arm/plat-versatile/localtimer.c
|
||||
*
|
||||
* Copyright (C) 2002 ARM Ltd.
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
const static struct of_device_id twd_of_match[] __initconst = {
|
||||
{ .compatible = "arm,cortex-a9-twd-timer", },
|
||||
{ .compatible = "arm,cortex-a5-twd-timer", },
|
||||
{ .compatible = "arm,arm11mp-twd-timer", },
|
||||
{ },
|
||||
};
|
||||
|
||||
/*
|
||||
* Setup the local clock events for a CPU.
|
||||
*/
|
||||
int __cpuinit local_timer_setup(struct clock_event_device *evt)
|
||||
{
|
||||
#if defined(CONFIG_OF)
|
||||
static int dt_node_probed;
|
||||
|
||||
/* Look for TWD node only once */
|
||||
if (!dt_node_probed) {
|
||||
struct device_node *node = of_find_matching_node(NULL,
|
||||
twd_of_match);
|
||||
|
||||
if (node)
|
||||
twd_base = of_iomap(node, 0);
|
||||
|
||||
dt_node_probed = 1;
|
||||
}
|
||||
#endif
|
||||
if (!twd_base)
|
||||
return -ENXIO;
|
||||
|
||||
evt->irq = IRQ_LOCALTIMER;
|
||||
twd_timer_setup(evt);
|
||||
return 0;
|
||||
}
|
|
@ -179,6 +179,9 @@ config ARCH_HAS_DEFAULT_IDLE
|
|||
config ARCH_HAS_CACHE_LINE_SIZE
|
||||
def_bool y
|
||||
|
||||
config ARCH_HAS_CPU_AUTOPROBE
|
||||
def_bool y
|
||||
|
||||
config HAVE_SETUP_PER_CPU_AREA
|
||||
def_bool y
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <crypto/aes.h>
|
||||
#include <crypto/cryptd.h>
|
||||
#include <crypto/ctr.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/aes.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
|
@ -1253,14 +1254,19 @@ static struct crypto_alg __rfc4106_alg = {
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
static const struct x86_cpu_id aesni_cpu_id[] = {
|
||||
X86_FEATURE_MATCH(X86_FEATURE_AES),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id);
|
||||
|
||||
static int __init aesni_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!cpu_has_aes) {
|
||||
printk(KERN_INFO "Intel AES-NI instructions are not detected.\n");
|
||||
if (!x86_match_cpu(aesni_cpu_id))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if ((err = crypto_fpu_init()))
|
||||
goto fpu_err;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <crypto/internal/hash.h>
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#define CHKSUM_BLOCK_SIZE 1
|
||||
#define CHKSUM_DIGEST_SIZE 4
|
||||
|
@ -173,13 +174,17 @@ static struct shash_alg alg = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id crc32c_cpu_id[] = {
|
||||
X86_FEATURE_MATCH(X86_FEATURE_XMM4_2),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id);
|
||||
|
||||
static int __init crc32c_intel_mod_init(void)
|
||||
{
|
||||
if (cpu_has_xmm4_2)
|
||||
return crypto_register_shash(&alg);
|
||||
else
|
||||
if (!x86_match_cpu(crc32c_cpu_id))
|
||||
return -ENODEV;
|
||||
return crypto_register_shash(&alg);
|
||||
}
|
||||
|
||||
static void __exit crc32c_intel_mod_fini(void)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <crypto/gf128mul.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#define GHASH_BLOCK_SIZE 16
|
||||
#define GHASH_DIGEST_SIZE 16
|
||||
|
@ -294,15 +295,18 @@ static struct ahash_alg ghash_async_alg = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id pcmul_cpu_id[] = {
|
||||
X86_FEATURE_MATCH(X86_FEATURE_PCLMULQDQ), /* Pickle-Mickle-Duck */
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, pcmul_cpu_id);
|
||||
|
||||
static int __init ghash_pclmulqdqni_mod_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!cpu_has_pclmulqdq) {
|
||||
printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not"
|
||||
" detected.\n");
|
||||
if (!x86_match_cpu(pcmul_cpu_id))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = crypto_register_shash(&ghash_alg);
|
||||
if (err)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef _CPU_DEVICE_ID
|
||||
#define _CPU_DEVICE_ID 1
|
||||
|
||||
/*
|
||||
* Declare drivers belonging to specific x86 CPUs
|
||||
* Similar in spirit to pci_device_id and related PCI functions
|
||||
*/
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
|
||||
extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match);
|
||||
|
||||
#endif
|
|
@ -177,6 +177,7 @@
|
|||
#define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */
|
||||
#define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */
|
||||
#define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */
|
||||
#define X86_FEATURE_HW_PSTATE (7*32+ 8) /* AMD HW-PState */
|
||||
|
||||
/* Virtualization flags: Linux defined, word 8 */
|
||||
#define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
|
||||
|
|
|
@ -16,6 +16,7 @@ obj-y := intel_cacheinfo.o scattered.o topology.o
|
|||
obj-y += proc.o capflags.o powerflags.o common.o
|
||||
obj-y += vmware.o hypervisor.o sched.o mshyperv.o
|
||||
obj-y += rdrand.o
|
||||
obj-y += match.o
|
||||
|
||||
obj-$(CONFIG_X86_32) += bugs.o
|
||||
obj-$(CONFIG_X86_64) += bugs_64.o
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/processor.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/**
|
||||
* x86_match_cpu - match current CPU again an array of x86_cpu_ids
|
||||
* @match: Pointer to array of x86_cpu_ids. Last entry terminated with
|
||||
* {}.
|
||||
*
|
||||
* Return the entry if the current CPU matches the entries in the
|
||||
* passed x86_cpu_id match table. Otherwise NULL. The match table
|
||||
* contains vendor (X86_VENDOR_*), family, model and feature bits or
|
||||
* respective wildcard entries.
|
||||
*
|
||||
* A typical table entry would be to match a specific CPU
|
||||
* { X86_VENDOR_INTEL, 6, 0x12 }
|
||||
* or to match a specific CPU feature
|
||||
* { X86_FEATURE_MATCH(X86_FEATURE_FOOBAR) }
|
||||
*
|
||||
* Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY,
|
||||
* %X86_MODEL_ANY, %X86_FEATURE_ANY or 0 (except for vendor)
|
||||
*
|
||||
* Arrays used to match for this should also be declared using
|
||||
* MODULE_DEVICE_TABLE(x86_cpu, ...)
|
||||
*
|
||||
* This always matches against the boot cpu, assuming models and features are
|
||||
* consistent over all CPUs.
|
||||
*/
|
||||
const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
|
||||
{
|
||||
const struct x86_cpu_id *m;
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
|
||||
for (m = match; m->vendor | m->family | m->model | m->feature; m++) {
|
||||
if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
|
||||
continue;
|
||||
if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
|
||||
continue;
|
||||
if (m->model != X86_MODEL_ANY && c->x86_model != m->model)
|
||||
continue;
|
||||
if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
|
||||
continue;
|
||||
return m;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(x86_match_cpu);
|
||||
|
||||
ssize_t arch_print_cpu_modalias(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *bufptr)
|
||||
{
|
||||
int size = PAGE_SIZE;
|
||||
int i, n;
|
||||
char *buf = bufptr;
|
||||
|
||||
n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:"
|
||||
"model:%04X:feature:",
|
||||
boot_cpu_data.x86_vendor,
|
||||
boot_cpu_data.x86,
|
||||
boot_cpu_data.x86_model);
|
||||
size -= n;
|
||||
buf += n;
|
||||
size -= 2;
|
||||
for (i = 0; i < NCAPINTS*32; i++) {
|
||||
if (boot_cpu_has(i)) {
|
||||
n = snprintf(buf, size, ",%04X", i);
|
||||
if (n < 0) {
|
||||
WARN(1, "x86 features overflow page\n");
|
||||
break;
|
||||
}
|
||||
size -= n;
|
||||
buf += n;
|
||||
}
|
||||
}
|
||||
*buf++ = ',';
|
||||
*buf++ = '\n';
|
||||
return buf - bufptr;
|
||||
}
|
||||
|
||||
int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (buf) {
|
||||
arch_print_cpu_modalias(NULL, NULL, buf);
|
||||
add_uevent_var(env, "MODALIAS=%s", buf);
|
||||
kfree(buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -40,6 +40,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
|
|||
{ X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 },
|
||||
{ X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 },
|
||||
{ X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 },
|
||||
{ X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 },
|
||||
{ X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 },
|
||||
{ X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 },
|
||||
{ X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 },
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
|
||||
#include <asm/microcode.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
MODULE_DESCRIPTION("Microcode Update Driver");
|
||||
MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
|
||||
|
@ -504,6 +505,20 @@ static struct notifier_block __refdata mc_cpu_notifier = {
|
|||
.notifier_call = mc_cpu_callback,
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
/* Autoload on Intel and AMD systems */
|
||||
static const struct x86_cpu_id microcode_id[] = {
|
||||
#ifdef CONFIG_MICROCODE_INTEL
|
||||
{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, },
|
||||
#endif
|
||||
#ifdef CONFIG_MICROCODE_AMD
|
||||
{ X86_VENDOR_AMD, X86_FAMILY_ANY, X86_MODEL_ANY, },
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, microcode_id);
|
||||
#endif
|
||||
|
||||
static int __init microcode_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
|
|
@ -474,6 +474,7 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
|
|||
|
||||
#ifdef CONFIG_CPU_FREQ
|
||||
acpi_processor_ppc_has_changed(pr, 0);
|
||||
acpi_processor_load_module(pr);
|
||||
#endif
|
||||
acpi_processor_get_throttling_info(pr);
|
||||
acpi_processor_get_limit_info(pr);
|
||||
|
|
|
@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void)
|
|||
acpi_processor_ppc_status &= ~PPC_REGISTERED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a quick check if the systems looks like it should use ACPI
|
||||
* cpufreq. We look at a _PCT method being available, but don't
|
||||
* do a whole lot of sanity checks.
|
||||
*/
|
||||
void acpi_processor_load_module(struct acpi_processor *pr)
|
||||
{
|
||||
static int requested;
|
||||
acpi_status status = 0;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
||||
if (!arch_has_acpi_pdc() || requested)
|
||||
return;
|
||||
status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
|
||||
if (!ACPI_FAILURE(status)) {
|
||||
printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n");
|
||||
request_module_nowait("acpi_cpufreq");
|
||||
requested = 1;
|
||||
}
|
||||
kfree(buffer.pointer);
|
||||
}
|
||||
|
||||
static int acpi_processor_get_performance_control(struct acpi_processor *pr)
|
||||
{
|
||||
int result = 0;
|
||||
|
|
|
@ -176,6 +176,9 @@ config GENERIC_CPU_DEVICES
|
|||
bool
|
||||
default n
|
||||
|
||||
config SOC_BUS
|
||||
bool
|
||||
|
||||
source "drivers/base/regmap/Kconfig"
|
||||
|
||||
config DMA_SHARED_BUFFER
|
||||
|
|
|
@ -19,6 +19,7 @@ obj-$(CONFIG_MODULES) += module.o
|
|||
endif
|
||||
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
|
||||
obj-$(CONFIG_REGMAP) += regmap/
|
||||
obj-$(CONFIG_SOC_BUS) += soc.o
|
||||
|
||||
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
|
||||
|
||||
|
|
|
@ -1194,13 +1194,15 @@ EXPORT_SYMBOL_GPL(subsys_interface_register);
|
|||
|
||||
void subsys_interface_unregister(struct subsys_interface *sif)
|
||||
{
|
||||
struct bus_type *subsys = sif->subsys;
|
||||
struct bus_type *subsys;
|
||||
struct subsys_dev_iter iter;
|
||||
struct device *dev;
|
||||
|
||||
if (!sif)
|
||||
if (!sif || !sif->subsys)
|
||||
return;
|
||||
|
||||
subsys = sif->subsys;
|
||||
|
||||
mutex_lock(&subsys->p->mutex);
|
||||
list_del_init(&sif->node);
|
||||
if (sif->remove_dev) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/node.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#include "base.h"
|
||||
|
@ -244,6 +245,9 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
|
|||
cpu->dev.id = num;
|
||||
cpu->dev.bus = &cpu_subsys;
|
||||
cpu->dev.release = cpu_device_release;
|
||||
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
cpu->dev.bus->uevent = arch_cpu_uevent;
|
||||
#endif
|
||||
error = device_register(&cpu->dev);
|
||||
if (!error && cpu->hotpluggable)
|
||||
register_cpu_control(cpu);
|
||||
|
@ -268,6 +272,10 @@ struct device *get_cpu_device(unsigned cpu)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(get_cpu_device);
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
|
||||
#endif
|
||||
|
||||
static struct attribute *cpu_root_attrs[] = {
|
||||
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
|
||||
&dev_attr_probe.attr,
|
||||
|
@ -278,6 +286,9 @@ static struct attribute *cpu_root_attrs[] = {
|
|||
&cpu_attrs[2].attr.attr,
|
||||
&dev_attr_kernel_max.attr,
|
||||
&dev_attr_offline.attr,
|
||||
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
|
||||
&dev_attr_modalias.attr,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -153,34 +153,6 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(driver_add_kobj);
|
||||
|
||||
/**
|
||||
* get_driver - increment driver reference count.
|
||||
* @drv: driver.
|
||||
*/
|
||||
struct device_driver *get_driver(struct device_driver *drv)
|
||||
{
|
||||
if (drv) {
|
||||
struct driver_private *priv;
|
||||
struct kobject *kobj;
|
||||
|
||||
kobj = kobject_get(&drv->p->kobj);
|
||||
priv = to_driver(kobj);
|
||||
return priv->driver;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_driver);
|
||||
|
||||
/**
|
||||
* put_driver - decrement driver's refcount.
|
||||
* @drv: driver.
|
||||
*/
|
||||
void put_driver(struct device_driver *drv)
|
||||
{
|
||||
kobject_put(&drv->p->kobj);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(put_driver);
|
||||
|
||||
static int driver_add_groups(struct device_driver *drv,
|
||||
const struct attribute_group **groups)
|
||||
{
|
||||
|
@ -234,7 +206,6 @@ int driver_register(struct device_driver *drv)
|
|||
|
||||
other = driver_find(drv->name, drv->bus);
|
||||
if (other) {
|
||||
put_driver(other);
|
||||
printk(KERN_ERR "Error: Driver '%s' is already registered, "
|
||||
"aborting...\n", drv->name);
|
||||
return -EBUSY;
|
||||
|
@ -275,7 +246,9 @@ EXPORT_SYMBOL_GPL(driver_unregister);
|
|||
* Call kset_find_obj() to iterate over list of drivers on
|
||||
* a bus to find driver by name. Return driver if found.
|
||||
*
|
||||
* Note that kset_find_obj increments driver's reference count.
|
||||
* This routine provides no locking to prevent the driver it returns
|
||||
* from being unregistered or unloaded while the caller is using it.
|
||||
* The caller is responsible for preventing this.
|
||||
*/
|
||||
struct device_driver *driver_find(const char *name, struct bus_type *bus)
|
||||
{
|
||||
|
@ -283,6 +256,8 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus)
|
|||
struct driver_private *priv;
|
||||
|
||||
if (k) {
|
||||
/* Drop reference added by kset_find_obj() */
|
||||
kobject_put(k);
|
||||
priv = to_driver(k);
|
||||
return priv->driver;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2011
|
||||
*
|
||||
* Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson.
|
||||
* License terms: GNU General Public License (GPL), version 2
|
||||
*/
|
||||
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
static DEFINE_IDR(soc_ida);
|
||||
static DEFINE_SPINLOCK(soc_lock);
|
||||
|
||||
static ssize_t soc_info_get(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf);
|
||||
|
||||
struct soc_device {
|
||||
struct device dev;
|
||||
struct soc_device_attribute *attr;
|
||||
int soc_dev_num;
|
||||
};
|
||||
|
||||
static struct bus_type soc_bus_type = {
|
||||
.name = "soc",
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(machine, S_IRUGO, soc_info_get, NULL);
|
||||
static DEVICE_ATTR(family, S_IRUGO, soc_info_get, NULL);
|
||||
static DEVICE_ATTR(soc_id, S_IRUGO, soc_info_get, NULL);
|
||||
static DEVICE_ATTR(revision, S_IRUGO, soc_info_get, NULL);
|
||||
|
||||
struct device *soc_device_to_device(struct soc_device *soc_dev)
|
||||
{
|
||||
return &soc_dev->dev;
|
||||
}
|
||||
|
||||
static mode_t soc_attribute_mode(struct kobject *kobj,
|
||||
struct attribute *attr,
|
||||
int index)
|
||||
{
|
||||
struct device *dev = container_of(kobj, struct device, kobj);
|
||||
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
|
||||
|
||||
if ((attr == &dev_attr_machine.attr)
|
||||
&& (soc_dev->attr->machine != NULL))
|
||||
return attr->mode;
|
||||
if ((attr == &dev_attr_family.attr)
|
||||
&& (soc_dev->attr->family != NULL))
|
||||
return attr->mode;
|
||||
if ((attr == &dev_attr_revision.attr)
|
||||
&& (soc_dev->attr->revision != NULL))
|
||||
return attr->mode;
|
||||
if ((attr == &dev_attr_soc_id.attr)
|
||||
&& (soc_dev->attr->soc_id != NULL))
|
||||
return attr->mode;
|
||||
|
||||
/* Unknown or unfilled attribute. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t soc_info_get(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
|
||||
|
||||
if (attr == &dev_attr_machine)
|
||||
return sprintf(buf, "%s\n", soc_dev->attr->machine);
|
||||
if (attr == &dev_attr_family)
|
||||
return sprintf(buf, "%s\n", soc_dev->attr->family);
|
||||
if (attr == &dev_attr_revision)
|
||||
return sprintf(buf, "%s\n", soc_dev->attr->revision);
|
||||
if (attr == &dev_attr_soc_id)
|
||||
return sprintf(buf, "%s\n", soc_dev->attr->soc_id);
|
||||
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
|
||||
static struct attribute *soc_attr[] = {
|
||||
&dev_attr_machine.attr,
|
||||
&dev_attr_family.attr,
|
||||
&dev_attr_soc_id.attr,
|
||||
&dev_attr_revision.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group soc_attr_group = {
|
||||
.attrs = soc_attr,
|
||||
.is_visible = soc_attribute_mode,
|
||||
};
|
||||
|
||||
static const struct attribute_group *soc_attr_groups[] = {
|
||||
&soc_attr_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void soc_release(struct device *dev)
|
||||
{
|
||||
struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
|
||||
|
||||
kfree(soc_dev);
|
||||
}
|
||||
|
||||
struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr)
|
||||
{
|
||||
struct soc_device *soc_dev;
|
||||
int ret;
|
||||
|
||||
soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL);
|
||||
if (!soc_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
/* Fetch a unique (reclaimable) SOC ID. */
|
||||
do {
|
||||
if (!ida_pre_get(&soc_ida, GFP_KERNEL)) {
|
||||
ret = -ENOMEM;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
spin_lock(&soc_lock);
|
||||
ret = ida_get_new(&soc_ida, &soc_dev->soc_dev_num);
|
||||
spin_unlock(&soc_lock);
|
||||
|
||||
} while (ret == -EAGAIN);
|
||||
|
||||
if (ret)
|
||||
goto out2;
|
||||
|
||||
soc_dev->attr = soc_dev_attr;
|
||||
soc_dev->dev.bus = &soc_bus_type;
|
||||
soc_dev->dev.groups = soc_attr_groups;
|
||||
soc_dev->dev.release = soc_release;
|
||||
|
||||
dev_set_name(&soc_dev->dev, "soc%d", soc_dev->soc_dev_num);
|
||||
|
||||
ret = device_register(&soc_dev->dev);
|
||||
if (ret)
|
||||
goto out3;
|
||||
|
||||
return soc_dev;
|
||||
|
||||
out3:
|
||||
ida_remove(&soc_ida, soc_dev->soc_dev_num);
|
||||
out2:
|
||||
kfree(soc_dev);
|
||||
out1:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */
|
||||
void soc_device_unregister(struct soc_device *soc_dev)
|
||||
{
|
||||
ida_remove(&soc_ida, soc_dev->soc_dev_num);
|
||||
|
||||
device_unregister(&soc_dev->dev);
|
||||
}
|
||||
|
||||
static int __init soc_bus_register(void)
|
||||
{
|
||||
spin_lock_init(&soc_lock);
|
||||
|
||||
return bus_register(&soc_bus_type);
|
||||
}
|
||||
core_initcall(soc_bus_register);
|
||||
|
||||
static void __exit soc_bus_unregister(void)
|
||||
{
|
||||
ida_destroy(&soc_ida);
|
||||
|
||||
bus_unregister(&soc_bus_type);
|
||||
}
|
||||
module_exit(soc_bus_unregister);
|
|
@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = {
|
||||
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, nforce2_ids);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
|
||||
*
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/tsc.h>
|
||||
|
||||
|
@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = {
|
|||
.attr = eps_attr,
|
||||
};
|
||||
|
||||
|
||||
/* This driver will work only on Centaur C7 processors with
|
||||
* Enhanced SpeedStep/PowerSaver registers */
|
||||
static const struct x86_cpu_id eps_cpu_id[] = {
|
||||
{ X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
|
||||
|
||||
static int __init eps_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
/* This driver will work only on Centaur C7 processors with
|
||||
* Enhanced SpeedStep/PowerSaver registers */
|
||||
if (c->x86_vendor != X86_VENDOR_CENTAUR
|
||||
|| c->x86 != 6 || c->x86_model < 10)
|
||||
if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
|
||||
return -ENODEV;
|
||||
if (!cpu_has(c, X86_FEATURE_EST))
|
||||
return -ENODEV;
|
||||
|
||||
if (cpufreq_register_driver(&eps_driver))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/cpufreq.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = {
|
|||
.attr = elanfreq_attr,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id elan_id[] = {
|
||||
{ X86_VENDOR_AMD, 4, 10, },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, elan_id);
|
||||
|
||||
static int __init elanfreq_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
/* Test if we have the right hardware */
|
||||
if ((c->x86_vendor != X86_VENDOR_AMD) ||
|
||||
(c->x86 != 4) || (c->x86_model != 10)) {
|
||||
printk(KERN_INFO "elanfreq: error: no Elan processor found!\n");
|
||||
if (!x86_match_cpu(elan_id))
|
||||
return -ENODEV;
|
||||
}
|
||||
return cpufreq_register_driver(&elanfreq_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/processor-cyrix.h>
|
||||
|
||||
/* PCI config registers, all at F0 */
|
||||
|
@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = {
|
|||
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
|
||||
{ 0, },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, gx_chipset_tbl);
|
||||
|
||||
static void gx_write_byte(int reg, int value)
|
||||
{
|
||||
|
@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void)
|
|||
{
|
||||
struct pci_dev *gx_pci = NULL;
|
||||
|
||||
/* check if CPU is a MediaGX or a Geode. */
|
||||
if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
|
||||
(boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
|
||||
pr_debug("error: no MediaGX/Geode processor found!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* detect which companion chip is used */
|
||||
for_each_pci_dev(gx_pci) {
|
||||
if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL)
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <linux/acpi.h>
|
||||
|
||||
#include <asm/msr.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <acpi/processor.h>
|
||||
|
||||
#include "longhaul.h"
|
||||
|
@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = {
|
|||
.attr = longhaul_attr,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id longhaul_id[] = {
|
||||
{ X86_VENDOR_CENTAUR, 6 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, longhaul_id);
|
||||
|
||||
static int __init longhaul_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
|
||||
if (!x86_match_cpu(longhaul_id))
|
||||
return -ENODEV;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
static struct cpufreq_driver longrun_driver;
|
||||
|
||||
|
@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id longrun_ids[] = {
|
||||
{ X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY,
|
||||
X86_FEATURE_LONGRUN },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, longrun_ids);
|
||||
|
||||
/**
|
||||
* longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
|
||||
|
@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = {
|
|||
*/
|
||||
static int __init longrun_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
|
||||
!cpu_has(c, X86_FEATURE_LONGRUN))
|
||||
if (!x86_match_cpu(longrun_ids))
|
||||
return -ENODEV;
|
||||
|
||||
return cpufreq_register_driver(&longrun_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <asm/processor.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/timer.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#include "speedstep-lib.h"
|
||||
|
||||
|
@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = {
|
|||
.attr = p4clockmod_attr,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id cpufreq_p4_id[] = {
|
||||
{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC },
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Intentionally no MODULE_DEVICE_TABLE here: this driver should not
|
||||
* be auto loaded. Please don't add one.
|
||||
*/
|
||||
|
||||
static int __init cpufreq_p4_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* THERM_CONTROL is architectural for IA32 now, so
|
||||
* we can rely on the capability checks
|
||||
*/
|
||||
if (c->x86_vendor != X86_VENDOR_INTEL)
|
||||
return -ENODEV;
|
||||
|
||||
if (!test_cpu_cap(c, X86_FEATURE_ACPI) ||
|
||||
!test_cpu_cap(c, X86_FEATURE_ACC))
|
||||
if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI))
|
||||
return -ENODEV;
|
||||
|
||||
ret = cpufreq_register_driver(&p4clockmod_driver);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/timex.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
#define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long
|
||||
|
@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = {
|
|||
.attr = powernow_k6_attr,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id powernow_k6_ids[] = {
|
||||
{ X86_VENDOR_AMD, 5, 12 },
|
||||
{ X86_VENDOR_AMD, 5, 13 },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
|
||||
|
@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = {
|
|||
*/
|
||||
static int __init powernow_k6_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
||||
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
|
||||
((c->x86_model != 12) && (c->x86_model != 13)))
|
||||
if (!x86_match_cpu(powernow_k6_ids))
|
||||
return -ENODEV;
|
||||
|
||||
if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */
|
||||
#include <asm/msr.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
|
||||
#include <linux/acpi.h>
|
||||
|
@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed)
|
|||
return delta < 5;
|
||||
}
|
||||
|
||||
static const struct x86_cpu_id powernow_k7_cpuids[] = {
|
||||
{ X86_VENDOR_AMD, 7, },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
|
||||
|
||||
static int check_powernow(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
unsigned int maxei, eax, ebx, ecx, edx;
|
||||
|
||||
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) {
|
||||
#ifdef MODULE
|
||||
printk(KERN_INFO PFX "This module only works with "
|
||||
"AMD K7 CPUs\n");
|
||||
#endif
|
||||
if (!x86_match_cpu(powernow_k7_cpuids))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get maximum capabilities */
|
||||
maxei = cpuid_eax(0x80000000);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/msr.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/mutex.h>
|
||||
|
@ -520,6 +521,15 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct x86_cpu_id powernow_k8_ids[] = {
|
||||
/* IO based frequency switching */
|
||||
{ X86_VENDOR_AMD, 0xf },
|
||||
/* MSR based frequency switching supported */
|
||||
X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids);
|
||||
|
||||
static void check_supported_cpu(void *_rc)
|
||||
{
|
||||
u32 eax, ebx, ecx, edx;
|
||||
|
@ -527,13 +537,7 @@ static void check_supported_cpu(void *_rc)
|
|||
|
||||
*rc = -ENODEV;
|
||||
|
||||
if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD)
|
||||
return;
|
||||
|
||||
eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
|
||||
if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) &&
|
||||
((eax & CPUID_XFAM) < CPUID_XFAM_10H))
|
||||
return;
|
||||
|
||||
if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
|
||||
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
|
||||
|
@ -1553,6 +1557,9 @@ static int __cpuinit powernowk8_init(void)
|
|||
unsigned int i, supported_cpus = 0, cpu;
|
||||
int rv;
|
||||
|
||||
if (!x86_match_cpu(powernow_k8_ids))
|
||||
return -ENODEV;
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
int rc;
|
||||
smp_call_function_single(i, check_supported_cpu, &rc, 1);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/timex.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/msr.h>
|
||||
|
||||
#define MMCR_BASE 0xfffef000 /* The default base address */
|
||||
|
@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = {
|
|||
.attr = sc520_freq_attr,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id sc520_ids[] = {
|
||||
{ X86_VENDOR_AMD, 4, 9 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, sc520_ids);
|
||||
|
||||
static int __init sc520_freq_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
int err;
|
||||
|
||||
/* Test if we have the right hardware */
|
||||
if (c->x86_vendor != X86_VENDOR_AMD ||
|
||||
c->x86 != 4 || c->x86_model != 9) {
|
||||
pr_debug("no Elan SC520 processor found!\n");
|
||||
if (!x86_match_cpu(sc520_ids))
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
|
||||
if (!cpuctl) {
|
||||
printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <asm/msr.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#define PFX "speedstep-centrino: "
|
||||
#define MAINTAINER "cpufreq@vger.kernel.org"
|
||||
|
@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
/*
|
||||
* This doesn't replace the detailed checks above because
|
||||
* the generic CPU IDs don't have a way to match for steppings
|
||||
* or ASCII model IDs.
|
||||
*/
|
||||
static const struct x86_cpu_id centrino_ids[] = {
|
||||
{ X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST },
|
||||
{ X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
|
||||
{ X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
|
||||
{ X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
|
||||
{ X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST },
|
||||
{ X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST },
|
||||
{}
|
||||
};
|
||||
#if 0
|
||||
/* Autoload or not? Do not for now. */
|
||||
MODULE_DEVICE_TABLE(x86cpu, centrino_ids);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
|
||||
|
@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = {
|
|||
*/
|
||||
static int __init centrino_init(void)
|
||||
{
|
||||
struct cpuinfo_x86 *cpu = &cpu_data(0);
|
||||
|
||||
if (!cpu_has(cpu, X86_FEATURE_EST))
|
||||
if (!x86_match_cpu(centrino_ids))
|
||||
return -ENODEV;
|
||||
|
||||
return cpufreq_register_driver(¢rino_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#include "speedstep-lib.h"
|
||||
|
||||
|
||||
|
@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = {
|
|||
.attr = speedstep_attr,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id ss_smi_ids[] = {
|
||||
{ X86_VENDOR_INTEL, 6, 0xb, },
|
||||
{ X86_VENDOR_INTEL, 6, 0x8, },
|
||||
{ X86_VENDOR_INTEL, 15, 2 },
|
||||
{}
|
||||
};
|
||||
#if 0
|
||||
/* Autoload or not? Do not for now. */
|
||||
MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* speedstep_init - initializes the SpeedStep CPUFreq driver
|
||||
|
@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = {
|
|||
*/
|
||||
static int __init speedstep_init(void)
|
||||
{
|
||||
if (!x86_match_cpu(ss_smi_ids))
|
||||
return -ENODEV;
|
||||
|
||||
/* detect processor */
|
||||
speedstep_processor = speedstep_detect_processor();
|
||||
if (!speedstep_processor) {
|
||||
|
|
|
@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);
|
|||
* DETECT SPEEDSTEP-CAPABLE PROCESSOR *
|
||||
*********************************************************************/
|
||||
|
||||
/* Keep in sync with the x86_cpu_id tables in the different modules */
|
||||
unsigned int speedstep_detect_processor(void)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(0);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/ist.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
|
||||
#include "speedstep-lib.h"
|
||||
|
||||
|
@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = {
|
|||
.attr = speedstep_attr,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id ss_smi_ids[] = {
|
||||
{ X86_VENDOR_INTEL, 6, 0xb, },
|
||||
{ X86_VENDOR_INTEL, 6, 0x8, },
|
||||
{ X86_VENDOR_INTEL, 15, 2 },
|
||||
{}
|
||||
};
|
||||
#if 0
|
||||
/* Not auto loaded currently */
|
||||
MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* speedstep_init - initializes the SpeedStep CPUFreq driver
|
||||
*
|
||||
|
@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = {
|
|||
*/
|
||||
static int __init speedstep_init(void)
|
||||
{
|
||||
if (!x86_match_cpu(ss_smi_ids))
|
||||
return -ENODEV;
|
||||
|
||||
speedstep_processor = speedstep_detect_processor();
|
||||
|
||||
switch (speedstep_processor) {
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче