forked from Minki/linux
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (29 commits) powerpc/rtas: Fix watchdog driver temperature read functionality powerpc/mm: Fix potential access to freed pages when using hugetlbfs powerpc/440: Fix warning early debug code powerpc/of: Fix usage of dev_set_name() in of_device_alloc() powerpc/pasemi: Use raw spinlock in SMP TB sync powerpc: Use one common impl. of RTAS timebase sync and use raw spinlock powerpc/rtas: Turn rtas lock into a raw spinlock powerpc: Add irqtrace support for 32-bit powerpc powerpc/BSR: Fix BSR to allow mmap of small BSR on 64k kernel powerpc/BSR: add 4096 byte BSR size powerpc: Map more memory early on 601 processors powerpc/pmac: Fix DMA ops for MacIO devices powerpc/mm: Make k(un)map_atomic out of line powerpc: Fix mpic alloc warning powerpc: Fix output from show_regs powerpc/pmac: Fix issues with PowerMac "PowerSurge" SMP powerpc/amigaone: Limit ISA I/O range to 4k in the device tree powerpc/warp: Platform fix for i2c change powerpc: Have git ignore generated files from dtc compile powerpc/mpic: Fix mapping of "DCR" based MPIC variants ...
This commit is contained in:
commit
919a6d10fd
File diff suppressed because it is too large
Load Diff
148
Documentation/powerpc/dts-bindings/4xx/emac.txt
Normal file
148
Documentation/powerpc/dts-bindings/4xx/emac.txt
Normal file
@ -0,0 +1,148 @@
|
||||
4xx/Axon EMAC ethernet nodes
|
||||
|
||||
The EMAC ethernet controller in IBM and AMCC 4xx chips, and also
|
||||
the Axon bridge. To operate this needs to interact with a ths
|
||||
special McMAL DMA controller, and sometimes an RGMII or ZMII
|
||||
interface. In addition to the nodes and properties described
|
||||
below, the node for the OPB bus on which the EMAC sits must have a
|
||||
correct clock-frequency property.
|
||||
|
||||
i) The EMAC node itself
|
||||
|
||||
Required properties:
|
||||
- device_type : "network"
|
||||
|
||||
- compatible : compatible list, contains 2 entries, first is
|
||||
"ibm,emac-CHIP" where CHIP is the host ASIC (440gx,
|
||||
405gp, Axon) and second is either "ibm,emac" or
|
||||
"ibm,emac4". For Axon, thus, we have: "ibm,emac-axon",
|
||||
"ibm,emac4"
|
||||
- interrupts : <interrupt mapping for EMAC IRQ and WOL IRQ>
|
||||
- interrupt-parent : optional, if needed for interrupt mapping
|
||||
- reg : <registers mapping>
|
||||
- local-mac-address : 6 bytes, MAC address
|
||||
- mal-device : phandle of the associated McMAL node
|
||||
- mal-tx-channel : 1 cell, index of the tx channel on McMAL associated
|
||||
with this EMAC
|
||||
- mal-rx-channel : 1 cell, index of the rx channel on McMAL associated
|
||||
with this EMAC
|
||||
- cell-index : 1 cell, hardware index of the EMAC cell on a given
|
||||
ASIC (typically 0x0 and 0x1 for EMAC0 and EMAC1 on
|
||||
each Axon chip)
|
||||
- max-frame-size : 1 cell, maximum frame size supported in bytes
|
||||
- rx-fifo-size : 1 cell, Rx fifo size in bytes for 10 and 100 Mb/sec
|
||||
operations.
|
||||
For Axon, 2048
|
||||
- tx-fifo-size : 1 cell, Tx fifo size in bytes for 10 and 100 Mb/sec
|
||||
operations.
|
||||
For Axon, 2048.
|
||||
- fifo-entry-size : 1 cell, size of a fifo entry (used to calculate
|
||||
thresholds).
|
||||
For Axon, 0x00000010
|
||||
- mal-burst-size : 1 cell, MAL burst size (used to calculate thresholds)
|
||||
in bytes.
|
||||
For Axon, 0x00000100 (I think ...)
|
||||
- phy-mode : string, mode of operations of the PHY interface.
|
||||
Supported values are: "mii", "rmii", "smii", "rgmii",
|
||||
"tbi", "gmii", rtbi", "sgmii".
|
||||
For Axon on CAB, it is "rgmii"
|
||||
- mdio-device : 1 cell, required iff using shared MDIO registers
|
||||
(440EP). phandle of the EMAC to use to drive the
|
||||
MDIO lines for the PHY used by this EMAC.
|
||||
- zmii-device : 1 cell, required iff connected to a ZMII. phandle of
|
||||
the ZMII device node
|
||||
- zmii-channel : 1 cell, required iff connected to a ZMII. Which ZMII
|
||||
channel or 0xffffffff if ZMII is only used for MDIO.
|
||||
- rgmii-device : 1 cell, required iff connected to an RGMII. phandle
|
||||
of the RGMII device node.
|
||||
For Axon: phandle of plb5/plb4/opb/rgmii
|
||||
- rgmii-channel : 1 cell, required iff connected to an RGMII. Which
|
||||
RGMII channel is used by this EMAC.
|
||||
Fox Axon: present, whatever value is appropriate for each
|
||||
EMAC, that is the content of the current (bogus) "phy-port"
|
||||
property.
|
||||
|
||||
Optional properties:
|
||||
- phy-address : 1 cell, optional, MDIO address of the PHY. If absent,
|
||||
a search is performed.
|
||||
- phy-map : 1 cell, optional, bitmap of addresses to probe the PHY
|
||||
for, used if phy-address is absent. bit 0x00000001 is
|
||||
MDIO address 0.
|
||||
For Axon it can be absent, though my current driver
|
||||
doesn't handle phy-address yet so for now, keep
|
||||
0x00ffffff in it.
|
||||
- rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec
|
||||
operations (if absent the value is the same as
|
||||
rx-fifo-size). For Axon, either absent or 2048.
|
||||
- tx-fifo-size-gige : 1 cell, Tx fifo size in bytes for 1000 Mb/sec
|
||||
operations (if absent the value is the same as
|
||||
tx-fifo-size). For Axon, either absent or 2048.
|
||||
- tah-device : 1 cell, optional. If connected to a TAH engine for
|
||||
offload, phandle of the TAH device node.
|
||||
- tah-channel : 1 cell, optional. If appropriate, channel used on the
|
||||
TAH engine.
|
||||
|
||||
Example:
|
||||
|
||||
EMAC0: ethernet@40000800 {
|
||||
device_type = "network";
|
||||
compatible = "ibm,emac-440gp", "ibm,emac";
|
||||
interrupt-parent = <&UIC1>;
|
||||
interrupts = <1c 4 1d 4>;
|
||||
reg = <40000800 70>;
|
||||
local-mac-address = [00 04 AC E3 1B 1E];
|
||||
mal-device = <&MAL0>;
|
||||
mal-tx-channel = <0 1>;
|
||||
mal-rx-channel = <0>;
|
||||
cell-index = <0>;
|
||||
max-frame-size = <5dc>;
|
||||
rx-fifo-size = <1000>;
|
||||
tx-fifo-size = <800>;
|
||||
phy-mode = "rmii";
|
||||
phy-map = <00000001>;
|
||||
zmii-device = <&ZMII0>;
|
||||
zmii-channel = <0>;
|
||||
};
|
||||
|
||||
ii) McMAL node
|
||||
|
||||
Required properties:
|
||||
- device_type : "dma-controller"
|
||||
- compatible : compatible list, containing 2 entries, first is
|
||||
"ibm,mcmal-CHIP" where CHIP is the host ASIC (like
|
||||
emac) and the second is either "ibm,mcmal" or
|
||||
"ibm,mcmal2".
|
||||
For Axon, "ibm,mcmal-axon","ibm,mcmal2"
|
||||
- interrupts : <interrupt mapping for the MAL interrupts sources:
|
||||
5 sources: tx_eob, rx_eob, serr, txde, rxde>.
|
||||
For Axon: This is _different_ from the current
|
||||
firmware. We use the "delayed" interrupts for txeob
|
||||
and rxeob. Thus we end up with mapping those 5 MPIC
|
||||
interrupts, all level positive sensitive: 10, 11, 32,
|
||||
33, 34 (in decimal)
|
||||
- dcr-reg : < DCR registers range >
|
||||
- dcr-parent : if needed for dcr-reg
|
||||
- num-tx-chans : 1 cell, number of Tx channels
|
||||
- num-rx-chans : 1 cell, number of Rx channels
|
||||
|
||||
iii) ZMII node
|
||||
|
||||
Required properties:
|
||||
- compatible : compatible list, containing 2 entries, first is
|
||||
"ibm,zmii-CHIP" where CHIP is the host ASIC (like
|
||||
EMAC) and the second is "ibm,zmii".
|
||||
For Axon, there is no ZMII node.
|
||||
- reg : <registers mapping>
|
||||
|
||||
iv) RGMII node
|
||||
|
||||
Required properties:
|
||||
- compatible : compatible list, containing 2 entries, first is
|
||||
"ibm,rgmii-CHIP" where CHIP is the host ASIC (like
|
||||
EMAC) and the second is "ibm,rgmii".
|
||||
For Axon, "ibm,rgmii-axon","ibm,rgmii"
|
||||
- reg : <registers mapping>
|
||||
- revision : as provided by the RGMII new version register if
|
||||
available.
|
||||
For Axon: 0x0000012a
|
||||
|
50
Documentation/powerpc/dts-bindings/gpio/gpio.txt
Normal file
50
Documentation/powerpc/dts-bindings/gpio/gpio.txt
Normal file
@ -0,0 +1,50 @@
|
||||
Specifying GPIO information for devices
|
||||
============================================
|
||||
|
||||
1) gpios property
|
||||
-----------------
|
||||
|
||||
Nodes that makes use of GPIOs should define them using `gpios' property,
|
||||
format of which is: <&gpio-controller1-phandle gpio1-specifier
|
||||
&gpio-controller2-phandle gpio2-specifier
|
||||
0 /* holes are permitted, means no GPIO 3 */
|
||||
&gpio-controller4-phandle gpio4-specifier
|
||||
...>;
|
||||
|
||||
Note that gpio-specifier length is controller dependent.
|
||||
|
||||
gpio-specifier may encode: bank, pin position inside the bank,
|
||||
whether pin is open-drain and whether pin is logically inverted.
|
||||
|
||||
Example of the node using GPIOs:
|
||||
|
||||
node {
|
||||
gpios = <&qe_pio_e 18 0>;
|
||||
};
|
||||
|
||||
In this example gpio-specifier is "18 0" and encodes GPIO pin number,
|
||||
and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller.
|
||||
|
||||
2) gpio-controller nodes
|
||||
------------------------
|
||||
|
||||
Every GPIO controller node must have #gpio-cells property defined,
|
||||
this information will be used to translate gpio-specifiers.
|
||||
|
||||
Example of two SOC GPIO banks defined as gpio-controller nodes:
|
||||
|
||||
qe_pio_a: gpio-controller@1400 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank";
|
||||
reg = <0x1400 0x18>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
qe_pio_e: gpio-controller@1460 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
|
||||
reg = <0x1460 0x18>;
|
||||
gpio-controller;
|
||||
};
|
||||
|
||||
|
19
Documentation/powerpc/dts-bindings/gpio/mdio.txt
Normal file
19
Documentation/powerpc/dts-bindings/gpio/mdio.txt
Normal file
@ -0,0 +1,19 @@
|
||||
MDIO on GPIOs
|
||||
|
||||
Currently defined compatibles:
|
||||
- virtual,gpio-mdio
|
||||
|
||||
MDC and MDIO lines connected to GPIO controllers are listed in the
|
||||
gpios property as described in section VIII.1 in the following order:
|
||||
|
||||
MDC, MDIO.
|
||||
|
||||
Example:
|
||||
|
||||
mdio {
|
||||
compatible = "virtual,mdio-gpio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
gpios = <&qe_pio_a 11
|
||||
&qe_pio_c 6>;
|
||||
};
|
521
Documentation/powerpc/dts-bindings/marvell.txt
Normal file
521
Documentation/powerpc/dts-bindings/marvell.txt
Normal file
@ -0,0 +1,521 @@
|
||||
Marvell Discovery mv64[345]6x System Controller chips
|
||||
===========================================================
|
||||
|
||||
The Marvell mv64[345]60 series of system controller chips contain
|
||||
many of the peripherals needed to implement a complete computer
|
||||
system. In this section, we define device tree nodes to describe
|
||||
the system controller chip itself and each of the peripherals
|
||||
which it contains. Compatible string values for each node are
|
||||
prefixed with the string "marvell,", for Marvell Technology Group Ltd.
|
||||
|
||||
1) The /system-controller node
|
||||
|
||||
This node is used to represent the system-controller and must be
|
||||
present when the system uses a system controller chip. The top-level
|
||||
system-controller node contains information that is global to all
|
||||
devices within the system controller chip. The node name begins
|
||||
with "system-controller" followed by the unit address, which is
|
||||
the base address of the memory-mapped register set for the system
|
||||
controller chip.
|
||||
|
||||
Required properties:
|
||||
|
||||
- ranges : Describes the translation of system controller addresses
|
||||
for memory mapped registers.
|
||||
- clock-frequency: Contains the main clock frequency for the system
|
||||
controller chip.
|
||||
- reg : This property defines the address and size of the
|
||||
memory-mapped registers contained within the system controller
|
||||
chip. The address specified in the "reg" property should match
|
||||
the unit address of the system-controller node.
|
||||
- #address-cells : Address representation for system controller
|
||||
devices. This field represents the number of cells needed to
|
||||
represent the address of the memory-mapped registers of devices
|
||||
within the system controller chip.
|
||||
- #size-cells : Size representation for for the memory-mapped
|
||||
registers within the system controller chip.
|
||||
- #interrupt-cells : Defines the width of cells used to represent
|
||||
interrupts.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- model : The specific model of the system controller chip. Such
|
||||
as, "mv64360", "mv64460", or "mv64560".
|
||||
- compatible : A string identifying the compatibility identifiers
|
||||
of the system controller chip.
|
||||
|
||||
The system-controller node contains child nodes for each system
|
||||
controller device that the platform uses. Nodes should not be created
|
||||
for devices which exist on the system controller chip but are not used
|
||||
|
||||
Example Marvell Discovery mv64360 system-controller node:
|
||||
|
||||
system-controller@f1000000 { /* Marvell Discovery mv64360 */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
model = "mv64360"; /* Default */
|
||||
compatible = "marvell,mv64360";
|
||||
clock-frequency = <133333333>;
|
||||
reg = <0xf1000000 0x10000>;
|
||||
virtual-reg = <0xf1000000>;
|
||||
ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */
|
||||
0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */
|
||||
0xa0000000 0xa0000000 0x4000000 /* User FLASH */
|
||||
0x00000000 0xf1000000 0x0010000 /* Bridge's regs */
|
||||
0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */
|
||||
|
||||
[ child node definitions... ]
|
||||
}
|
||||
|
||||
2) Child nodes of /system-controller
|
||||
|
||||
a) Marvell Discovery MDIO bus
|
||||
|
||||
The MDIO is a bus to which the PHY devices are connected. For each
|
||||
device that exists on this bus, a child node should be created. See
|
||||
the definition of the PHY node below for an example of how to define
|
||||
a PHY.
|
||||
|
||||
Required properties:
|
||||
- #address-cells : Should be <1>
|
||||
- #size-cells : Should be <0>
|
||||
- device_type : Should be "mdio"
|
||||
- compatible : Should be "marvell,mv64360-mdio"
|
||||
|
||||
Example:
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
device_type = "mdio";
|
||||
compatible = "marvell,mv64360-mdio";
|
||||
|
||||
ethernet-phy@0 {
|
||||
......
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
b) Marvell Discovery ethernet controller
|
||||
|
||||
The Discover ethernet controller is described with two levels
|
||||
of nodes. The first level describes an ethernet silicon block
|
||||
and the second level describes up to 3 ethernet nodes within
|
||||
that block. The reason for the multiple levels is that the
|
||||
registers for the node are interleaved within a single set
|
||||
of registers. The "ethernet-block" level describes the
|
||||
shared register set, and the "ethernet" nodes describe ethernet
|
||||
port-specific properties.
|
||||
|
||||
Ethernet block node
|
||||
|
||||
Required properties:
|
||||
- #address-cells : <1>
|
||||
- #size-cells : <0>
|
||||
- compatible : "marvell,mv64360-eth-block"
|
||||
- reg : Offset and length of the register set for this block
|
||||
|
||||
Example Discovery Ethernet block node:
|
||||
ethernet-block@2000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,mv64360-eth-block";
|
||||
reg = <0x2000 0x2000>;
|
||||
ethernet@0 {
|
||||
.......
|
||||
};
|
||||
};
|
||||
|
||||
Ethernet port node
|
||||
|
||||
Required properties:
|
||||
- device_type : Should be "network".
|
||||
- compatible : Should be "marvell,mv64360-eth".
|
||||
- reg : Should be <0>, <1>, or <2>, according to which registers
|
||||
within the silicon block the device uses.
|
||||
- interrupts : <a> where a is the interrupt number for the port.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
- phy : the phandle for the PHY connected to this ethernet
|
||||
controller.
|
||||
- local-mac-address : 6 bytes, MAC address
|
||||
|
||||
Example Discovery Ethernet port node:
|
||||
ethernet@0 {
|
||||
device_type = "network";
|
||||
compatible = "marvell,mv64360-eth";
|
||||
reg = <0>;
|
||||
interrupts = <32>;
|
||||
interrupt-parent = <&PIC>;
|
||||
phy = <&PHY0>;
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
|
||||
|
||||
|
||||
c) Marvell Discovery PHY nodes
|
||||
|
||||
Required properties:
|
||||
- device_type : Should be "ethernet-phy"
|
||||
- interrupts : <a> where a is the interrupt number for this phy.
|
||||
- interrupt-parent : the phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
- reg : The ID number for the phy, usually a small integer
|
||||
|
||||
Example Discovery PHY node:
|
||||
ethernet-phy@1 {
|
||||
device_type = "ethernet-phy";
|
||||
compatible = "broadcom,bcm5421";
|
||||
interrupts = <76>; /* GPP 12 */
|
||||
interrupt-parent = <&PIC>;
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
|
||||
d) Marvell Discovery SDMA nodes
|
||||
|
||||
Represent DMA hardware associated with the MPSC (multiprotocol
|
||||
serial controllers).
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-sdma"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : <a> where a is the interrupt number for the DMA
|
||||
device.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery SDMA node:
|
||||
sdma@4000 {
|
||||
compatible = "marvell,mv64360-sdma";
|
||||
reg = <0x4000 0xc18>;
|
||||
virtual-reg = <0xf1004000>;
|
||||
interrupts = <36>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
e) Marvell Discovery BRG nodes
|
||||
|
||||
Represent baud rate generator hardware associated with the MPSC
|
||||
(multiprotocol serial controllers).
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-brg"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- clock-src : A value from 0 to 15 which selects the clock
|
||||
source for the baud rate generator. This value corresponds
|
||||
to the CLKS value in the BRGx configuration register. See
|
||||
the mv64x60 User's Manual.
|
||||
- clock-frequence : The frequency (in Hz) of the baud rate
|
||||
generator's input clock.
|
||||
- current-speed : The current speed setting (presumably by
|
||||
firmware) of the baud rate generator.
|
||||
|
||||
Example Discovery BRG node:
|
||||
brg@b200 {
|
||||
compatible = "marvell,mv64360-brg";
|
||||
reg = <0xb200 0x8>;
|
||||
clock-src = <8>;
|
||||
clock-frequency = <133333333>;
|
||||
current-speed = <9600>;
|
||||
};
|
||||
|
||||
|
||||
f) Marvell Discovery CUNIT nodes
|
||||
|
||||
Represent the Serial Communications Unit device hardware.
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery CUNIT node:
|
||||
cunit@f200 {
|
||||
reg = <0xf200 0x200>;
|
||||
};
|
||||
|
||||
|
||||
g) Marvell Discovery MPSCROUTING nodes
|
||||
|
||||
Represent the Discovery's MPSC routing hardware
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery CUNIT node:
|
||||
mpscrouting@b500 {
|
||||
reg = <0xb400 0xc>;
|
||||
};
|
||||
|
||||
|
||||
h) Marvell Discovery MPSCINTR nodes
|
||||
|
||||
Represent the Discovery's MPSC DMA interrupt hardware registers
|
||||
(SDMA cause and mask registers).
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery MPSCINTR node:
|
||||
mpsintr@b800 {
|
||||
reg = <0xb800 0x100>;
|
||||
};
|
||||
|
||||
|
||||
i) Marvell Discovery MPSC nodes
|
||||
|
||||
Represent the Discovery's MPSC (Multiprotocol Serial Controller)
|
||||
serial port.
|
||||
|
||||
Required properties:
|
||||
- device_type : "serial"
|
||||
- compatible : "marvell,mv64360-mpsc"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- sdma : the phandle for the SDMA node used by this port
|
||||
- brg : the phandle for the BRG node used by this port
|
||||
- cunit : the phandle for the CUNIT node used by this port
|
||||
- mpscrouting : the phandle for the MPSCROUTING node used by this port
|
||||
- mpscintr : the phandle for the MPSCINTR node used by this port
|
||||
- cell-index : the hardware index of this cell in the MPSC core
|
||||
- max_idle : value needed for MPSC CHR3 (Maximum Frame Length)
|
||||
register
|
||||
- interrupts : <a> where a is the interrupt number for the MPSC.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery MPSCINTR node:
|
||||
mpsc@8000 {
|
||||
device_type = "serial";
|
||||
compatible = "marvell,mv64360-mpsc";
|
||||
reg = <0x8000 0x38>;
|
||||
virtual-reg = <0xf1008000>;
|
||||
sdma = <&SDMA0>;
|
||||
brg = <&BRG0>;
|
||||
cunit = <&CUNIT>;
|
||||
mpscrouting = <&MPSCROUTING>;
|
||||
mpscintr = <&MPSCINTR>;
|
||||
cell-index = <0>;
|
||||
max_idle = <40>;
|
||||
interrupts = <40>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
j) Marvell Discovery Watch Dog Timer nodes
|
||||
|
||||
Represent the Discovery's watchdog timer hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-wdt"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery Watch Dog Timer node:
|
||||
wdt@b410 {
|
||||
compatible = "marvell,mv64360-wdt";
|
||||
reg = <0xb410 0x8>;
|
||||
};
|
||||
|
||||
|
||||
k) Marvell Discovery I2C nodes
|
||||
|
||||
Represent the Discovery's I2C hardware
|
||||
|
||||
Required properties:
|
||||
- device_type : "i2c"
|
||||
- compatible : "marvell,mv64360-i2c"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : <a> where a is the interrupt number for the I2C.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery I2C node:
|
||||
compatible = "marvell,mv64360-i2c";
|
||||
reg = <0xc000 0x20>;
|
||||
virtual-reg = <0xf100c000>;
|
||||
interrupts = <37>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes
|
||||
|
||||
Represent the Discovery's PIC hardware
|
||||
|
||||
Required properties:
|
||||
- #interrupt-cells : <1>
|
||||
- #address-cells : <0>
|
||||
- compatible : "marvell,mv64360-pic"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupt-controller
|
||||
|
||||
Example Discovery PIC node:
|
||||
pic {
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
compatible = "marvell,mv64360-pic";
|
||||
reg = <0x0 0x88>;
|
||||
interrupt-controller;
|
||||
};
|
||||
|
||||
|
||||
m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes
|
||||
|
||||
Represent the Discovery's MPP hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-mpp"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery MPP node:
|
||||
mpp@f000 {
|
||||
compatible = "marvell,mv64360-mpp";
|
||||
reg = <0xf000 0x10>;
|
||||
};
|
||||
|
||||
|
||||
n) Marvell Discovery GPP (General Purpose Pins) nodes
|
||||
|
||||
Represent the Discovery's GPP hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-gpp"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery GPP node:
|
||||
gpp@f000 {
|
||||
compatible = "marvell,mv64360-gpp";
|
||||
reg = <0xf100 0x20>;
|
||||
};
|
||||
|
||||
|
||||
o) Marvell Discovery PCI host bridge node
|
||||
|
||||
Represents the Discovery's PCI host bridge device. The properties
|
||||
for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE
|
||||
1275-1994. A typical value for the compatible property is
|
||||
"marvell,mv64360-pci".
|
||||
|
||||
Example Discovery PCI host bridge node
|
||||
pci@80000000 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
device_type = "pci";
|
||||
compatible = "marvell,mv64360-pci";
|
||||
reg = <0xcf8 0x8>;
|
||||
ranges = <0x01000000 0x0 0x0
|
||||
0x88000000 0x0 0x01000000
|
||||
0x02000000 0x0 0x80000000
|
||||
0x80000000 0x0 0x08000000>;
|
||||
bus-range = <0 255>;
|
||||
clock-frequency = <66000000>;
|
||||
interrupt-parent = <&PIC>;
|
||||
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
||||
interrupt-map = <
|
||||
/* IDSEL 0x0a */
|
||||
0x5000 0 0 1 &PIC 80
|
||||
0x5000 0 0 2 &PIC 81
|
||||
0x5000 0 0 3 &PIC 91
|
||||
0x5000 0 0 4 &PIC 93
|
||||
|
||||
/* IDSEL 0x0b */
|
||||
0x5800 0 0 1 &PIC 91
|
||||
0x5800 0 0 2 &PIC 93
|
||||
0x5800 0 0 3 &PIC 80
|
||||
0x5800 0 0 4 &PIC 81
|
||||
|
||||
/* IDSEL 0x0c */
|
||||
0x6000 0 0 1 &PIC 91
|
||||
0x6000 0 0 2 &PIC 93
|
||||
0x6000 0 0 3 &PIC 80
|
||||
0x6000 0 0 4 &PIC 81
|
||||
|
||||
/* IDSEL 0x0d */
|
||||
0x6800 0 0 1 &PIC 93
|
||||
0x6800 0 0 2 &PIC 80
|
||||
0x6800 0 0 3 &PIC 81
|
||||
0x6800 0 0 4 &PIC 91
|
||||
>;
|
||||
};
|
||||
|
||||
|
||||
p) Marvell Discovery CPU Error nodes
|
||||
|
||||
Represent the Discovery's CPU error handler device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-cpu-error"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery CPU Error node:
|
||||
cpu-error@0070 {
|
||||
compatible = "marvell,mv64360-cpu-error";
|
||||
reg = <0x70 0x10 0x128 0x28>;
|
||||
interrupts = <3>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
q) Marvell Discovery SRAM Controller nodes
|
||||
|
||||
Represent the Discovery's SRAM controller device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-sram-ctrl"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery SRAM Controller node:
|
||||
sram-ctrl@0380 {
|
||||
compatible = "marvell,mv64360-sram-ctrl";
|
||||
reg = <0x380 0x80>;
|
||||
interrupts = <13>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
r) Marvell Discovery PCI Error Handler nodes
|
||||
|
||||
Represent the Discovery's PCI error handler device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-pci-error"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery PCI Error Handler node:
|
||||
pci-error@1d40 {
|
||||
compatible = "marvell,mv64360-pci-error";
|
||||
reg = <0x1d40 0x40 0xc28 0x4>;
|
||||
interrupts = <12>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
s) Marvell Discovery Memory Controller nodes
|
||||
|
||||
Represent the Discovery's memory controller device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-mem-ctrl"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery Memory Controller node:
|
||||
mem-ctrl@1400 {
|
||||
compatible = "marvell,mv64360-mem-ctrl";
|
||||
reg = <0x1400 0x60>;
|
||||
interrupts = <17>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
25
Documentation/powerpc/dts-bindings/phy.txt
Normal file
25
Documentation/powerpc/dts-bindings/phy.txt
Normal file
@ -0,0 +1,25 @@
|
||||
PHY nodes
|
||||
|
||||
Required properties:
|
||||
|
||||
- device_type : Should be "ethernet-phy"
|
||||
- interrupts : <a b> where a is the interrupt number and b is a
|
||||
field that represents an encoding of the sense and level
|
||||
information for the interrupt. This should be encoded based on
|
||||
the information in section 2) depending on the type of interrupt
|
||||
controller you have.
|
||||
- interrupt-parent : the phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
- reg : The ID number for the phy, usually a small integer
|
||||
- linux,phandle : phandle for this node; likely referenced by an
|
||||
ethernet controller node.
|
||||
|
||||
Example:
|
||||
|
||||
ethernet-phy@0 {
|
||||
linux,phandle = <2452000>
|
||||
interrupt-parent = <40000>;
|
||||
interrupts = <35 1>;
|
||||
reg = <0>;
|
||||
device_type = "ethernet-phy";
|
||||
};
|
57
Documentation/powerpc/dts-bindings/spi-bus.txt
Normal file
57
Documentation/powerpc/dts-bindings/spi-bus.txt
Normal file
@ -0,0 +1,57 @@
|
||||
SPI (Serial Peripheral Interface) busses
|
||||
|
||||
SPI busses can be described with a node for the SPI master device
|
||||
and a set of child nodes for each SPI slave on the bus. For this
|
||||
discussion, it is assumed that the system's SPI controller is in
|
||||
SPI master mode. This binding does not describe SPI controllers
|
||||
in slave mode.
|
||||
|
||||
The SPI master node requires the following properties:
|
||||
- #address-cells - number of cells required to define a chip select
|
||||
address on the SPI bus.
|
||||
- #size-cells - should be zero.
|
||||
- compatible - name of SPI bus controller following generic names
|
||||
recommended practice.
|
||||
No other properties are required in the SPI bus node. It is assumed
|
||||
that a driver for an SPI bus device will understand that it is an SPI bus.
|
||||
However, the binding does not attempt to define the specific method for
|
||||
assigning chip select numbers. Since SPI chip select configuration is
|
||||
flexible and non-standardized, it is left out of this binding with the
|
||||
assumption that board specific platform code will be used to manage
|
||||
chip selects. Individual drivers can define additional properties to
|
||||
support describing the chip select layout.
|
||||
|
||||
SPI slave nodes must be children of the SPI master node and can
|
||||
contain the following properties.
|
||||
- reg - (required) chip select address of device.
|
||||
- compatible - (required) name of SPI device following generic names
|
||||
recommended practice
|
||||
- spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz
|
||||
- spi-cpol - (optional) Empty property indicating device requires
|
||||
inverse clock polarity (CPOL) mode
|
||||
- spi-cpha - (optional) Empty property indicating device requires
|
||||
shifted clock phase (CPHA) mode
|
||||
- spi-cs-high - (optional) Empty property indicating device requires
|
||||
chip select active high
|
||||
|
||||
SPI example for an MPC5200 SPI bus:
|
||||
spi@f00 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
|
||||
reg = <0xf00 0x20>;
|
||||
interrupts = <2 13 0 2 14 0>;
|
||||
interrupt-parent = <&mpc5200_pic>;
|
||||
|
||||
ethernet-switch@0 {
|
||||
compatible = "micrel,ks8995m";
|
||||
spi-max-frequency = <1000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
codec@1 {
|
||||
compatible = "ti,tlv320aic26";
|
||||
spi-max-frequency = <100000>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
25
Documentation/powerpc/dts-bindings/usb-ehci.txt
Normal file
25
Documentation/powerpc/dts-bindings/usb-ehci.txt
Normal file
@ -0,0 +1,25 @@
|
||||
USB EHCI controllers
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "usb-ehci".
|
||||
- reg : should contain at least address and length of the standard EHCI
|
||||
register set for the device. Optional platform-dependent registers
|
||||
(debug-port or other) can be also specified here, but only after
|
||||
definition of standard EHCI registers.
|
||||
- interrupts : one EHCI interrupt should be described here.
|
||||
If device registers are implemented in big endian mode, the device
|
||||
node should have "big-endian-regs" property.
|
||||
If controller implementation operates with big endian descriptors,
|
||||
"big-endian-desc" property should be specified.
|
||||
If both big endian registers and descriptors are used by the controller
|
||||
implementation, "big-endian" property can be specified instead of having
|
||||
both "big-endian-regs" and "big-endian-desc".
|
||||
|
||||
Example (Sequoia 440EPx):
|
||||
ehci@e0000300 {
|
||||
compatible = "ibm,usb-ehci-440epx", "usb-ehci";
|
||||
interrupt-parent = <&UIC0>;
|
||||
interrupts = <1a 4>;
|
||||
reg = <0 e0000300 90 0 e0000390 70>;
|
||||
big-endian;
|
||||
};
|
295
Documentation/powerpc/dts-bindings/xilinx.txt
Normal file
295
Documentation/powerpc/dts-bindings/xilinx.txt
Normal file
@ -0,0 +1,295 @@
|
||||
d) Xilinx IP cores
|
||||
|
||||
The Xilinx EDK toolchain ships with a set of IP cores (devices) for use
|
||||
in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range
|
||||
of standard device types (network, serial, etc.) and miscellaneous
|
||||
devices (gpio, LCD, spi, etc). Also, since these devices are
|
||||
implemented within the fpga fabric every instance of the device can be
|
||||
synthesised with different options that change the behaviour.
|
||||
|
||||
Each IP-core has a set of parameters which the FPGA designer can use to
|
||||
control how the core is synthesized. Historically, the EDK tool would
|
||||
extract the device parameters relevant to device drivers and copy them
|
||||
into an 'xparameters.h' in the form of #define symbols. This tells the
|
||||
device drivers how the IP cores are configured, but it requres the kernel
|
||||
to be recompiled every time the FPGA bitstream is resynthesized.
|
||||
|
||||
The new approach is to export the parameters into the device tree and
|
||||
generate a new device tree each time the FPGA bitstream changes. The
|
||||
parameters which used to be exported as #defines will now become
|
||||
properties of the device node. In general, device nodes for IP-cores
|
||||
will take the following form:
|
||||
|
||||
(name): (generic-name)@(base-address) {
|
||||
compatible = "xlnx,(ip-core-name)-(HW_VER)"
|
||||
[, (list of compatible devices), ...];
|
||||
reg = <(baseaddr) (size)>;
|
||||
interrupt-parent = <&interrupt-controller-phandle>;
|
||||
interrupts = < ... >;
|
||||
xlnx,(parameter1) = "(string-value)";
|
||||
xlnx,(parameter2) = <(int-value)>;
|
||||
};
|
||||
|
||||
(generic-name): an open firmware-style name that describes the
|
||||
generic class of device. Preferably, this is one word, such
|
||||
as 'serial' or 'ethernet'.
|
||||
(ip-core-name): the name of the ip block (given after the BEGIN
|
||||
directive in system.mhs). Should be in lowercase
|
||||
and all underscores '_' converted to dashes '-'.
|
||||
(name): is derived from the "PARAMETER INSTANCE" value.
|
||||
(parameter#): C_* parameters from system.mhs. The C_ prefix is
|
||||
dropped from the parameter name, the name is converted
|
||||
to lowercase and all underscore '_' characters are
|
||||
converted to dashes '-'.
|
||||
(baseaddr): the baseaddr parameter value (often named C_BASEADDR).
|
||||
(HW_VER): from the HW_VER parameter.
|
||||
(size): the address range size (often C_HIGHADDR - C_BASEADDR + 1).
|
||||
|
||||
Typically, the compatible list will include the exact IP core version
|
||||
followed by an older IP core version which implements the same
|
||||
interface or any other device with the same interface.
|
||||
|
||||
'reg', 'interrupt-parent' and 'interrupts' are all optional properties.
|
||||
|
||||
For example, the following block from system.mhs:
|
||||
|
||||
BEGIN opb_uartlite
|
||||
PARAMETER INSTANCE = opb_uartlite_0
|
||||
PARAMETER HW_VER = 1.00.b
|
||||
PARAMETER C_BAUDRATE = 115200
|
||||
PARAMETER C_DATA_BITS = 8
|
||||
PARAMETER C_ODD_PARITY = 0
|
||||
PARAMETER C_USE_PARITY = 0
|
||||
PARAMETER C_CLK_FREQ = 50000000
|
||||
PARAMETER C_BASEADDR = 0xEC100000
|
||||
PARAMETER C_HIGHADDR = 0xEC10FFFF
|
||||
BUS_INTERFACE SOPB = opb_7
|
||||
PORT OPB_Clk = CLK_50MHz
|
||||
PORT Interrupt = opb_uartlite_0_Interrupt
|
||||
PORT RX = opb_uartlite_0_RX
|
||||
PORT TX = opb_uartlite_0_TX
|
||||
PORT OPB_Rst = sys_bus_reset_0
|
||||
END
|
||||
|
||||
becomes the following device tree node:
|
||||
|
||||
opb_uartlite_0: serial@ec100000 {
|
||||
device_type = "serial";
|
||||
compatible = "xlnx,opb-uartlite-1.00.b";
|
||||
reg = <ec100000 10000>;
|
||||
interrupt-parent = <&opb_intc_0>;
|
||||
interrupts = <1 0>; // got this from the opb_intc parameters
|
||||
current-speed = <d#115200>; // standard serial device prop
|
||||
clock-frequency = <d#50000000>; // standard serial device prop
|
||||
xlnx,data-bits = <8>;
|
||||
xlnx,odd-parity = <0>;
|
||||
xlnx,use-parity = <0>;
|
||||
};
|
||||
|
||||
Some IP cores actually implement 2 or more logical devices. In
|
||||
this case, the device should still describe the whole IP core with
|
||||
a single node and add a child node for each logical device. The
|
||||
ranges property can be used to translate from parent IP-core to the
|
||||
registers of each device. In addition, the parent node should be
|
||||
compatible with the bus type 'xlnx,compound', and should contain
|
||||
#address-cells and #size-cells, as with any other bus. (Note: this
|
||||
makes the assumption that both logical devices have the same bus
|
||||
binding. If this is not true, then separate nodes should be used
|
||||
for each logical device). The 'cell-index' property can be used to
|
||||
enumerate logical devices within an IP core. For example, the
|
||||
following is the system.mhs entry for the dual ps2 controller found
|
||||
on the ml403 reference design.
|
||||
|
||||
BEGIN opb_ps2_dual_ref
|
||||
PARAMETER INSTANCE = opb_ps2_dual_ref_0
|
||||
PARAMETER HW_VER = 1.00.a
|
||||
PARAMETER C_BASEADDR = 0xA9000000
|
||||
PARAMETER C_HIGHADDR = 0xA9001FFF
|
||||
BUS_INTERFACE SOPB = opb_v20_0
|
||||
PORT Sys_Intr1 = ps2_1_intr
|
||||
PORT Sys_Intr2 = ps2_2_intr
|
||||
PORT Clkin1 = ps2_clk_rx_1
|
||||
PORT Clkin2 = ps2_clk_rx_2
|
||||
PORT Clkpd1 = ps2_clk_tx_1
|
||||
PORT Clkpd2 = ps2_clk_tx_2
|
||||
PORT Rx1 = ps2_d_rx_1
|
||||
PORT Rx2 = ps2_d_rx_2
|
||||
PORT Txpd1 = ps2_d_tx_1
|
||||
PORT Txpd2 = ps2_d_tx_2
|
||||
END
|
||||
|
||||
It would result in the following device tree nodes:
|
||||
|
||||
opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "xlnx,compound";
|
||||
ranges = <0 a9000000 2000>;
|
||||
// If this device had extra parameters, then they would
|
||||
// go here.
|
||||
ps2@0 {
|
||||
compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
|
||||
reg = <0 40>;
|
||||
interrupt-parent = <&opb_intc_0>;
|
||||
interrupts = <3 0>;
|
||||
cell-index = <0>;
|
||||
};
|
||||
ps2@1000 {
|
||||
compatible = "xlnx,opb-ps2-dual-ref-1.00.a";
|
||||
reg = <1000 40>;
|
||||
interrupt-parent = <&opb_intc_0>;
|
||||
interrupts = <3 0>;
|
||||
cell-index = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
Also, the system.mhs file defines bus attachments from the processor
|
||||
to the devices. The device tree structure should reflect the bus
|
||||
attachments. Again an example; this system.mhs fragment:
|
||||
|
||||
BEGIN ppc405_virtex4
|
||||
PARAMETER INSTANCE = ppc405_0
|
||||
PARAMETER HW_VER = 1.01.a
|
||||
BUS_INTERFACE DPLB = plb_v34_0
|
||||
BUS_INTERFACE IPLB = plb_v34_0
|
||||
END
|
||||
|
||||
BEGIN opb_intc
|
||||
PARAMETER INSTANCE = opb_intc_0
|
||||
PARAMETER HW_VER = 1.00.c
|
||||
PARAMETER C_BASEADDR = 0xD1000FC0
|
||||
PARAMETER C_HIGHADDR = 0xD1000FDF
|
||||
BUS_INTERFACE SOPB = opb_v20_0
|
||||
END
|
||||
|
||||
BEGIN opb_uart16550
|
||||
PARAMETER INSTANCE = opb_uart16550_0
|
||||
PARAMETER HW_VER = 1.00.d
|
||||
PARAMETER C_BASEADDR = 0xa0000000
|
||||
PARAMETER C_HIGHADDR = 0xa0001FFF
|
||||
BUS_INTERFACE SOPB = opb_v20_0
|
||||
END
|
||||
|
||||
BEGIN plb_v34
|
||||
PARAMETER INSTANCE = plb_v34_0
|
||||
PARAMETER HW_VER = 1.02.a
|
||||
END
|
||||
|
||||
BEGIN plb_bram_if_cntlr
|
||||
PARAMETER INSTANCE = plb_bram_if_cntlr_0
|
||||
PARAMETER HW_VER = 1.00.b
|
||||
PARAMETER C_BASEADDR = 0xFFFF0000
|
||||
PARAMETER C_HIGHADDR = 0xFFFFFFFF
|
||||
BUS_INTERFACE SPLB = plb_v34_0
|
||||
END
|
||||
|
||||
BEGIN plb2opb_bridge
|
||||
PARAMETER INSTANCE = plb2opb_bridge_0
|
||||
PARAMETER HW_VER = 1.01.a
|
||||
PARAMETER C_RNG0_BASEADDR = 0x20000000
|
||||
PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF
|
||||
PARAMETER C_RNG1_BASEADDR = 0x60000000
|
||||
PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF
|
||||
PARAMETER C_RNG2_BASEADDR = 0x80000000
|
||||
PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF
|
||||
PARAMETER C_RNG3_BASEADDR = 0xC0000000
|
||||
PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF
|
||||
BUS_INTERFACE SPLB = plb_v34_0
|
||||
BUS_INTERFACE MOPB = opb_v20_0
|
||||
END
|
||||
|
||||
Gives this device tree (some properties removed for clarity):
|
||||
|
||||
plb@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "xlnx,plb-v34-1.02.a";
|
||||
device_type = "ibm,plb";
|
||||
ranges; // 1:1 translation
|
||||
|
||||
plb_bram_if_cntrl_0: bram@ffff0000 {
|
||||
reg = <ffff0000 10000>;
|
||||
}
|
||||
|
||||
opb@20000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <20000000 20000000 20000000
|
||||
60000000 60000000 20000000
|
||||
80000000 80000000 40000000
|
||||
c0000000 c0000000 20000000>;
|
||||
|
||||
opb_uart16550_0: serial@a0000000 {
|
||||
reg = <a00000000 2000>;
|
||||
};
|
||||
|
||||
opb_intc_0: interrupt-controller@d1000fc0 {
|
||||
reg = <d1000fc0 20>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
That covers the general approach to binding xilinx IP cores into the
|
||||
device tree. The following are bindings for specific devices:
|
||||
|
||||
i) Xilinx ML300 Framebuffer
|
||||
|
||||
Simple framebuffer device from the ML300 reference design (also on the
|
||||
ML403 reference design as well as others).
|
||||
|
||||
Optional properties:
|
||||
- resolution = <xres yres> : pixel resolution of framebuffer. Some
|
||||
implementations use a different resolution.
|
||||
Default is <d#640 d#480>
|
||||
- virt-resolution = <xvirt yvirt> : Size of framebuffer in memory.
|
||||
Default is <d#1024 d#480>.
|
||||
- rotate-display (empty) : rotate display 180 degrees.
|
||||
|
||||
ii) Xilinx SystemACE
|
||||
|
||||
The Xilinx SystemACE device is used to program FPGAs from an FPGA
|
||||
bitstream stored on a CF card. It can also be used as a generic CF
|
||||
interface device.
|
||||
|
||||
Optional properties:
|
||||
- 8-bit (empty) : Set this property for SystemACE in 8 bit mode
|
||||
|
||||
iii) Xilinx EMAC and Xilinx TEMAC
|
||||
|
||||
Xilinx Ethernet devices. In addition to general xilinx properties
|
||||
listed above, nodes for these devices should include a phy-handle
|
||||
property, and may include other common network device properties
|
||||
like local-mac-address.
|
||||
|
||||
iv) Xilinx Uartlite
|
||||
|
||||
Xilinx uartlite devices are simple fixed speed serial ports.
|
||||
|
||||
Required properties:
|
||||
- current-speed : Baud rate of uartlite
|
||||
|
||||
v) Xilinx hwicap
|
||||
|
||||
Xilinx hwicap devices provide access to the configuration logic
|
||||
of the FPGA through the Internal Configuration Access Port
|
||||
(ICAP). The ICAP enables partial reconfiguration of the FPGA,
|
||||
readback of the configuration information, and some control over
|
||||
'warm boots' of the FPGA fabric.
|
||||
|
||||
Required properties:
|
||||
- xlnx,family : The family of the FPGA, necessary since the
|
||||
capabilities of the underlying ICAP hardware
|
||||
differ between different families. May be
|
||||
'virtex2p', 'virtex4', or 'virtex5'.
|
||||
|
||||
vi) Xilinx Uart 16550
|
||||
|
||||
Xilinx UART 16550 devices are very similar to the NS16550 but with
|
||||
different register spacing and an offset from the base address.
|
||||
|
||||
Required properties:
|
||||
- clock-frequency : Frequency of the clock input
|
||||
- reg-offset : A value of 3 is required
|
||||
- reg-shift : A value of 2 is required
|
||||
|
||||
|
@ -62,7 +62,6 @@ config HAVE_LATENCYTOP_SUPPORT
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
bool
|
||||
depends on PPC64
|
||||
default y
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
|
10
arch/powerpc/boot/.gitignore
vendored
10
arch/powerpc/boot/.gitignore
vendored
@ -36,3 +36,13 @@ zImage.pseries
|
||||
zconf.h
|
||||
zlib.h
|
||||
zutil.h
|
||||
fdt.c
|
||||
fdt.h
|
||||
fdt_ro.c
|
||||
fdt_rw.c
|
||||
fdt_strerror.c
|
||||
fdt_sw.c
|
||||
fdt_wip.c
|
||||
libfdt.h
|
||||
libfdt_internal.h
|
||||
|
||||
|
@ -70,8 +70,8 @@
|
||||
devsel-speed = <0x00000001>;
|
||||
min-grant = <0>;
|
||||
max-latency = <0>;
|
||||
/* First 64k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */
|
||||
ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00010000>;
|
||||
/* First 4k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */
|
||||
ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00001000>;
|
||||
interrupt-parent = <&i8259>;
|
||||
#interrupt-cells = <2>;
|
||||
#address-cells = <2>;
|
||||
|
@ -253,6 +253,7 @@
|
||||
/* Filled in by U-Boot */
|
||||
clock-frequency = <0>;
|
||||
status = "disabled";
|
||||
sdhci,1-bit-only;
|
||||
};
|
||||
|
||||
crypto@30000 {
|
||||
|
@ -598,8 +598,6 @@ typedef struct risc_timer_pram {
|
||||
#define CICR_IEN ((uint)0x00000080) /* Int. enable */
|
||||
#define CICR_SPS ((uint)0x00000001) /* SCC Spread */
|
||||
|
||||
#define IMAP_ADDR (get_immrbase())
|
||||
|
||||
#define CPM_PIN_INPUT 0
|
||||
#define CPM_PIN_OUTPUT 1
|
||||
#define CPM_PIN_PRIMARY 0
|
||||
|
@ -309,7 +309,9 @@ static inline void dma_sync_single_for_cpu(struct device *dev,
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0,
|
||||
|
||||
if (dma_ops->sync_single_range_for_cpu)
|
||||
dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0,
|
||||
size, direction);
|
||||
}
|
||||
|
||||
@ -320,7 +322,9 @@ static inline void dma_sync_single_for_device(struct device *dev,
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
dma_ops->sync_single_range_for_device(dev, dma_handle,
|
||||
|
||||
if (dma_ops->sync_single_range_for_device)
|
||||
dma_ops->sync_single_range_for_device(dev, dma_handle,
|
||||
0, size, direction);
|
||||
}
|
||||
|
||||
@ -331,7 +335,9 @@ static inline void dma_sync_sg_for_cpu(struct device *dev,
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction);
|
||||
|
||||
if (dma_ops->sync_sg_for_cpu)
|
||||
dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction);
|
||||
}
|
||||
|
||||
static inline void dma_sync_sg_for_device(struct device *dev,
|
||||
@ -341,7 +347,9 @@ static inline void dma_sync_sg_for_device(struct device *dev,
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
dma_ops->sync_sg_for_device(dev, sgl, nents, direction);
|
||||
|
||||
if (dma_ops->sync_sg_for_device)
|
||||
dma_ops->sync_sg_for_device(dev, sgl, nents, direction);
|
||||
}
|
||||
|
||||
static inline void dma_sync_single_range_for_cpu(struct device *dev,
|
||||
@ -351,7 +359,9 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
dma_ops->sync_single_range_for_cpu(dev, dma_handle,
|
||||
|
||||
if (dma_ops->sync_single_range_for_cpu)
|
||||
dma_ops->sync_single_range_for_cpu(dev, dma_handle,
|
||||
offset, size, direction);
|
||||
}
|
||||
|
||||
@ -362,7 +372,9 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
|
||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||
|
||||
BUG_ON(!dma_ops);
|
||||
dma_ops->sync_single_range_for_device(dev, dma_handle, offset,
|
||||
|
||||
if (dma_ops->sync_single_range_for_device)
|
||||
dma_ops->sync_single_range_for_device(dev, dma_handle, offset,
|
||||
size, direction);
|
||||
}
|
||||
#else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */
|
||||
|
@ -22,9 +22,7 @@
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <asm/kmap_types.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/page.h>
|
||||
@ -62,6 +60,9 @@ extern pte_t *pkmap_page_table;
|
||||
|
||||
extern void *kmap_high(struct page *page);
|
||||
extern void kunmap_high(struct page *page);
|
||||
extern void *kmap_atomic_prot(struct page *page, enum km_type type,
|
||||
pgprot_t prot);
|
||||
extern void kunmap_atomic(void *kvaddr, enum km_type type);
|
||||
|
||||
static inline void *kmap(struct page *page)
|
||||
{
|
||||
@ -79,62 +80,11 @@ static inline void kunmap(struct page *page)
|
||||
kunmap_high(page);
|
||||
}
|
||||
|
||||
/*
|
||||
* The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
|
||||
* gives a more generic (and caching) interface. But kmap_atomic can
|
||||
* be used in IRQ contexts, so in some (very limited) cases we need
|
||||
* it.
|
||||
*/
|
||||
static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
|
||||
{
|
||||
unsigned int idx;
|
||||
unsigned long vaddr;
|
||||
|
||||
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
|
||||
pagefault_disable();
|
||||
if (!PageHighMem(page))
|
||||
return page_address(page);
|
||||
|
||||
debug_kmap_atomic(type);
|
||||
idx = type + KM_TYPE_NR*smp_processor_id();
|
||||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||
BUG_ON(!pte_none(*(kmap_pte-idx)));
|
||||
#endif
|
||||
__set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1);
|
||||
local_flush_tlb_page(NULL, vaddr);
|
||||
|
||||
return (void*) vaddr;
|
||||
}
|
||||
|
||||
static inline void *kmap_atomic(struct page *page, enum km_type type)
|
||||
{
|
||||
return kmap_atomic_prot(page, type, kmap_prot);
|
||||
}
|
||||
|
||||
static inline void kunmap_atomic(void *kvaddr, enum km_type type)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
|
||||
enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
|
||||
|
||||
if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
|
||||
pagefault_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
|
||||
|
||||
/*
|
||||
* force other mappings to Oops if they'll try to access
|
||||
* this pte without first remap it
|
||||
*/
|
||||
pte_clear(&init_mm, vaddr, kmap_pte-idx);
|
||||
local_flush_tlb_page(NULL, vaddr);
|
||||
#endif
|
||||
pagefault_enable();
|
||||
}
|
||||
|
||||
static inline struct page *kmap_atomic_to_page(void *ptr)
|
||||
{
|
||||
unsigned long idx, vaddr = (unsigned long) ptr;
|
||||
@ -148,6 +98,7 @@ static inline struct page *kmap_atomic_to_page(void *ptr)
|
||||
return pte_page(*pte);
|
||||
}
|
||||
|
||||
|
||||
#define flush_cache_kmaps() flush_cache_all()
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -68,13 +68,13 @@ static inline int irqs_disabled_flags(unsigned long flags)
|
||||
|
||||
#if defined(CONFIG_BOOKE)
|
||||
#define SET_MSR_EE(x) mtmsr(x)
|
||||
#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
|
||||
#define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
|
||||
#else
|
||||
#define SET_MSR_EE(x) mtmsr(x)
|
||||
#define local_irq_restore(flags) mtmsr(flags)
|
||||
#define raw_local_irq_restore(flags) mtmsr(flags)
|
||||
#endif
|
||||
|
||||
static inline void local_irq_disable(void)
|
||||
static inline void raw_local_irq_disable(void)
|
||||
{
|
||||
#ifdef CONFIG_BOOKE
|
||||
__asm__ __volatile__("wrteei 0": : :"memory");
|
||||
@ -86,7 +86,7 @@ static inline void local_irq_disable(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void local_irq_enable(void)
|
||||
static inline void raw_local_irq_enable(void)
|
||||
{
|
||||
#ifdef CONFIG_BOOKE
|
||||
__asm__ __volatile__("wrteei 1": : :"memory");
|
||||
@ -98,7 +98,7 @@ static inline void local_irq_enable(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void local_irq_save_ptr(unsigned long *flags)
|
||||
static inline void raw_local_irq_save_ptr(unsigned long *flags)
|
||||
{
|
||||
unsigned long msr;
|
||||
msr = mfmsr();
|
||||
@ -110,12 +110,12 @@ static inline void local_irq_save_ptr(unsigned long *flags)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define local_save_flags(flags) ((flags) = mfmsr())
|
||||
#define local_irq_save(flags) local_irq_save_ptr(&flags)
|
||||
#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
|
||||
#define raw_local_save_flags(flags) ((flags) = mfmsr())
|
||||
#define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags)
|
||||
#define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0)
|
||||
#define raw_irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0)
|
||||
|
||||
#define hard_irq_enable() local_irq_enable()
|
||||
#define hard_irq_disable() local_irq_disable()
|
||||
#define hard_irq_disable() raw_local_irq_disable()
|
||||
|
||||
static inline int irqs_disabled_flags(unsigned long flags)
|
||||
{
|
||||
|
@ -47,7 +47,8 @@
|
||||
* generic accessors and iterators here
|
||||
*/
|
||||
#define __real_pte(e,p) ((real_pte_t) { \
|
||||
(e), pte_val(*((p) + PTRS_PER_PTE)) })
|
||||
(e), ((e) & _PAGE_COMBO) ? \
|
||||
(pte_val(*((p) + PTRS_PER_PTE))) : 0 })
|
||||
#define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \
|
||||
(((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf))
|
||||
#define __rpte_to_pte(r) ((r).pte)
|
||||
|
@ -58,7 +58,7 @@ struct rtas_t {
|
||||
unsigned long entry; /* physical address pointer */
|
||||
unsigned long base; /* physical address pointer */
|
||||
unsigned long size;
|
||||
spinlock_t lock;
|
||||
raw_spinlock_t lock;
|
||||
struct rtas_args args;
|
||||
struct device_node *dev; /* virtual address pointer */
|
||||
};
|
||||
@ -245,5 +245,8 @@ static inline u32 rtas_config_addr(int busno, int devfn, int reg)
|
||||
(devfn << 8) | (reg & 0xff);
|
||||
}
|
||||
|
||||
extern void __cpuinit rtas_give_timebase(void);
|
||||
extern void __cpuinit rtas_take_timebase(void);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _POWERPC_RTAS_H */
|
||||
|
@ -191,11 +191,49 @@ transfer_to_handler_cont:
|
||||
mflr r9
|
||||
lwz r11,0(r9) /* virtual address of handler */
|
||||
lwz r9,4(r9) /* where to go when done */
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
lis r12,reenable_mmu@h
|
||||
ori r12,r12,reenable_mmu@l
|
||||
mtspr SPRN_SRR0,r12
|
||||
mtspr SPRN_SRR1,r10
|
||||
SYNC
|
||||
RFI
|
||||
reenable_mmu: /* re-enable mmu so we can */
|
||||
mfmsr r10
|
||||
lwz r12,_MSR(r1)
|
||||
xor r10,r10,r12
|
||||
andi. r10,r10,MSR_EE /* Did EE change? */
|
||||
beq 1f
|
||||
|
||||
/* Save handler and return address into the 2 unused words
|
||||
* of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything
|
||||
* else can be recovered from the pt_regs except r3 which for
|
||||
* normal interrupts has been set to pt_regs and for syscalls
|
||||
* is an argument, so we temporarily use ORIG_GPR3 to save it
|
||||
*/
|
||||
stw r9,8(r1)
|
||||
stw r11,12(r1)
|
||||
stw r3,ORIG_GPR3(r1)
|
||||
bl trace_hardirqs_off
|
||||
lwz r0,GPR0(r1)
|
||||
lwz r3,ORIG_GPR3(r1)
|
||||
lwz r4,GPR4(r1)
|
||||
lwz r5,GPR5(r1)
|
||||
lwz r6,GPR6(r1)
|
||||
lwz r7,GPR7(r1)
|
||||
lwz r8,GPR8(r1)
|
||||
lwz r9,8(r1)
|
||||
lwz r11,12(r1)
|
||||
1: mtctr r11
|
||||
mtlr r9
|
||||
bctr /* jump to handler */
|
||||
#else /* CONFIG_TRACE_IRQFLAGS */
|
||||
mtspr SPRN_SRR0,r11
|
||||
mtspr SPRN_SRR1,r10
|
||||
mtlr r9
|
||||
SYNC
|
||||
RFI /* jump to handler, enable MMU */
|
||||
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||
|
||||
#if defined (CONFIG_6xx) || defined(CONFIG_E500)
|
||||
4: rlwinm r12,r12,0,~_TLF_NAPPING
|
||||
@ -251,6 +289,31 @@ _GLOBAL(DoSyscall)
|
||||
#ifdef SHOW_SYSCALLS
|
||||
bl do_show_syscall
|
||||
#endif /* SHOW_SYSCALLS */
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/* Return from syscalls can (and generally will) hard enable
|
||||
* interrupts. You aren't supposed to call a syscall with
|
||||
* interrupts disabled in the first place. However, to ensure
|
||||
* that we get it right vs. lockdep if it happens, we force
|
||||
* that hard enable here with appropriate tracing if we see
|
||||
* that we have been called with interrupts off
|
||||
*/
|
||||
mfmsr r11
|
||||
andi. r12,r11,MSR_EE
|
||||
bne+ 1f
|
||||
/* We came in with interrupts disabled, we enable them now */
|
||||
bl trace_hardirqs_on
|
||||
mfmsr r11
|
||||
lwz r0,GPR0(r1)
|
||||
lwz r3,GPR3(r1)
|
||||
lwz r4,GPR4(r1)
|
||||
ori r11,r11,MSR_EE
|
||||
lwz r5,GPR5(r1)
|
||||
lwz r6,GPR6(r1)
|
||||
lwz r7,GPR7(r1)
|
||||
lwz r8,GPR8(r1)
|
||||
mtmsr r11
|
||||
1:
|
||||
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||
rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
|
||||
lwz r11,TI_FLAGS(r10)
|
||||
andi. r11,r11,_TIF_SYSCALL_T_OR_A
|
||||
@ -275,6 +338,7 @@ ret_from_syscall:
|
||||
rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
|
||||
/* disable interrupts so current_thread_info()->flags can't change */
|
||||
LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
|
||||
/* Note: We don't bother telling lockdep about it */
|
||||
SYNC
|
||||
MTMSRD(r10)
|
||||
lwz r9,TI_FLAGS(r12)
|
||||
@ -288,6 +352,19 @@ ret_from_syscall:
|
||||
oris r11,r11,0x1000 /* Set SO bit in CR */
|
||||
stw r11,_CCR(r1)
|
||||
syscall_exit_cont:
|
||||
lwz r8,_MSR(r1)
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/* If we are going to return from the syscall with interrupts
|
||||
* off, we trace that here. It shouldn't happen though but we
|
||||
* want to catch the bugger if it does right ?
|
||||
*/
|
||||
andi. r10,r8,MSR_EE
|
||||
bne+ 1f
|
||||
stw r3,GPR3(r1)
|
||||
bl trace_hardirqs_off
|
||||
lwz r3,GPR3(r1)
|
||||
1:
|
||||
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
|
||||
/* If the process has its own DBCR0 value, load it up. The internal
|
||||
debug mode bit tells us that dbcr0 should be loaded. */
|
||||
@ -311,7 +388,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
||||
mtlr r4
|
||||
mtcr r5
|
||||
lwz r7,_NIP(r1)
|
||||
lwz r8,_MSR(r1)
|
||||
FIX_SRR1(r8, r0)
|
||||
lwz r2,GPR2(r1)
|
||||
lwz r1,GPR1(r1)
|
||||
@ -394,7 +470,9 @@ syscall_exit_work:
|
||||
andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
|
||||
beq ret_from_except
|
||||
|
||||
/* Re-enable interrupts */
|
||||
/* Re-enable interrupts. There is no need to trace that with
|
||||
* lockdep as we are supposed to have IRQs on at this point
|
||||
*/
|
||||
ori r10,r10,MSR_EE
|
||||
SYNC
|
||||
MTMSRD(r10)
|
||||
@ -705,6 +783,7 @@ ret_from_except:
|
||||
/* Hard-disable interrupts so that current_thread_info()->flags
|
||||
* can't change between when we test it and when we return
|
||||
* from the interrupt. */
|
||||
/* Note: We don't bother telling lockdep about it */
|
||||
LOAD_MSR_KERNEL(r10,MSR_KERNEL)
|
||||
SYNC /* Some chip revs have problems here... */
|
||||
MTMSRD(r10) /* disable interrupts */
|
||||
@ -744,11 +823,24 @@ resume_kernel:
|
||||
beq+ restore
|
||||
andi. r0,r3,MSR_EE /* interrupts off? */
|
||||
beq restore /* don't schedule if so */
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/* Lockdep thinks irqs are enabled, we need to call
|
||||
* preempt_schedule_irq with IRQs off, so we inform lockdep
|
||||
* now that we -did- turn them off already
|
||||
*/
|
||||
bl trace_hardirqs_off
|
||||
#endif
|
||||
1: bl preempt_schedule_irq
|
||||
rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
|
||||
lwz r3,TI_FLAGS(r9)
|
||||
andi. r0,r3,_TIF_NEED_RESCHED
|
||||
bne- 1b
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/* And now, to properly rebalance the above, we tell lockdep they
|
||||
* are being turned back on, which will happen when we return
|
||||
*/
|
||||
bl trace_hardirqs_on
|
||||
#endif
|
||||
#else
|
||||
resume_kernel:
|
||||
#endif /* CONFIG_PREEMPT */
|
||||
@ -765,6 +857,28 @@ restore:
|
||||
stw r6,icache_44x_need_flush@l(r4)
|
||||
1:
|
||||
#endif /* CONFIG_44x */
|
||||
|
||||
lwz r9,_MSR(r1)
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/* Lockdep doesn't know about the fact that IRQs are temporarily turned
|
||||
* off in this assembly code while peeking at TI_FLAGS() and such. However
|
||||
* we need to inform it if the exception turned interrupts off, and we
|
||||
* are about to trun them back on.
|
||||
*
|
||||
* The problem here sadly is that we don't know whether the exceptions was
|
||||
* one that turned interrupts off or not. So we always tell lockdep about
|
||||
* turning them on here when we go back to wherever we came from with EE
|
||||
* on, even if that may meen some redudant calls being tracked. Maybe later
|
||||
* we could encode what the exception did somewhere or test the exception
|
||||
* type in the pt_regs but that sounds overkill
|
||||
*/
|
||||
andi. r10,r9,MSR_EE
|
||||
beq 1f
|
||||
bl trace_hardirqs_on
|
||||
lwz r9,_MSR(r1)
|
||||
1:
|
||||
#endif /* CONFIG_TRACE_IRQFLAGS */
|
||||
|
||||
lwz r0,GPR0(r1)
|
||||
lwz r2,GPR2(r1)
|
||||
REST_4GPRS(3, r1)
|
||||
@ -782,7 +896,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
||||
stwcx. r0,0,r1 /* to clear the reservation */
|
||||
|
||||
#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
|
||||
lwz r9,_MSR(r1)
|
||||
andi. r10,r9,MSR_RI /* check if this exception occurred */
|
||||
beql nonrecoverable /* at a bad place (MSR:RI = 0) */
|
||||
|
||||
@ -805,7 +918,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
||||
MTMSRD(r10) /* clear the RI bit */
|
||||
.globl exc_exit_restart
|
||||
exc_exit_restart:
|
||||
lwz r9,_MSR(r1)
|
||||
lwz r12,_NIP(r1)
|
||||
FIX_SRR1(r9,r10)
|
||||
mtspr SPRN_SRR0,r12
|
||||
@ -1035,11 +1147,18 @@ do_work: /* r10 contains MSR_KERNEL here */
|
||||
beq do_user_signal
|
||||
|
||||
do_resched: /* r10 contains MSR_KERNEL here */
|
||||
/* Note: We don't need to inform lockdep that we are enabling
|
||||
* interrupts here. As far as it knows, they are already enabled
|
||||
*/
|
||||
ori r10,r10,MSR_EE
|
||||
SYNC
|
||||
MTMSRD(r10) /* hard-enable interrupts */
|
||||
bl schedule
|
||||
recheck:
|
||||
/* Note: And we don't tell it we are disabling them again
|
||||
* neither. Those disable/enable cycles used to peek at
|
||||
* TI_FLAGS aren't advertised.
|
||||
*/
|
||||
LOAD_MSR_KERNEL(r10,MSR_KERNEL)
|
||||
SYNC
|
||||
MTMSRD(r10) /* disable interrupts */
|
||||
|
@ -1124,9 +1124,8 @@ mmu_off:
|
||||
RFI
|
||||
|
||||
/*
|
||||
* Use the first pair of BAT registers to map the 1st 16MB
|
||||
* of RAM to PAGE_OFFSET. From this point on we can't safely
|
||||
* call OF any more.
|
||||
* On 601, we use 3 BATs to map up to 24M of RAM at _PAGE_OFFSET
|
||||
* (we keep one for debugging) and on others, we use one 256M BAT.
|
||||
*/
|
||||
initial_bats:
|
||||
lis r11,PAGE_OFFSET@h
|
||||
@ -1136,12 +1135,16 @@ initial_bats:
|
||||
bne 4f
|
||||
ori r11,r11,4 /* set up BAT registers for 601 */
|
||||
li r8,0x7f /* valid, block length = 8MB */
|
||||
oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */
|
||||
oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */
|
||||
mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */
|
||||
mtspr SPRN_IBAT0L,r8 /* lower BAT register */
|
||||
mtspr SPRN_IBAT1U,r9
|
||||
mtspr SPRN_IBAT1L,r10
|
||||
addis r11,r11,0x800000@h
|
||||
addis r8,r8,0x800000@h
|
||||
mtspr SPRN_IBAT1U,r11
|
||||
mtspr SPRN_IBAT1L,r8
|
||||
addis r11,r11,0x800000@h
|
||||
addis r8,r8,0x800000@h
|
||||
mtspr SPRN_IBAT2U,r11
|
||||
mtspr SPRN_IBAT2L,r8
|
||||
isync
|
||||
blr
|
||||
|
||||
|
@ -76,7 +76,7 @@ struct of_device *of_device_alloc(struct device_node *np,
|
||||
dev->dev.archdata.of_node = np;
|
||||
|
||||
if (bus_id)
|
||||
dev_set_name(&dev->dev, bus_id);
|
||||
dev_set_name(&dev->dev, "%s", bus_id);
|
||||
else
|
||||
of_device_make_bus_id(dev);
|
||||
|
||||
|
@ -528,7 +528,7 @@ void show_regs(struct pt_regs * regs)
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((i % REGS_PER_LINE) == 0)
|
||||
printk("\n" KERN_INFO "GPR%02d: ", i);
|
||||
printk("\nGPR%02d: ", i);
|
||||
printk(REG " ", regs->gpr[i]);
|
||||
if (i == LAST_VOLATILE && !FULL_REGS(regs))
|
||||
break;
|
||||
|
@ -38,9 +38,10 @@
|
||||
#include <asm/syscalls.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
struct rtas_t rtas = {
|
||||
.lock = SPIN_LOCK_UNLOCKED
|
||||
.lock = __RAW_SPIN_LOCK_UNLOCKED
|
||||
};
|
||||
EXPORT_SYMBOL(rtas);
|
||||
|
||||
@ -67,6 +68,28 @@ unsigned long rtas_rmo_buf;
|
||||
void (*rtas_flash_term_hook)(int);
|
||||
EXPORT_SYMBOL(rtas_flash_term_hook);
|
||||
|
||||
/* RTAS use home made raw locking instead of spin_lock_irqsave
|
||||
* because those can be called from within really nasty contexts
|
||||
* such as having the timebase stopped which would lockup with
|
||||
* normal locks and spinlock debugging enabled
|
||||
*/
|
||||
static unsigned long lock_rtas(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
preempt_disable();
|
||||
__raw_spin_lock_flags(&rtas.lock, flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void unlock_rtas(unsigned long flags)
|
||||
{
|
||||
__raw_spin_unlock(&rtas.lock);
|
||||
local_irq_restore(flags);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* call_rtas_display_status and call_rtas_display_status_delay
|
||||
* are designed only for very early low-level debugging, which
|
||||
@ -79,7 +102,7 @@ static void call_rtas_display_status(char c)
|
||||
|
||||
if (!rtas.base)
|
||||
return;
|
||||
spin_lock_irqsave(&rtas.lock, s);
|
||||
s = lock_rtas();
|
||||
|
||||
args->token = 10;
|
||||
args->nargs = 1;
|
||||
@ -89,7 +112,7 @@ static void call_rtas_display_status(char c)
|
||||
|
||||
enter_rtas(__pa(args));
|
||||
|
||||
spin_unlock_irqrestore(&rtas.lock, s);
|
||||
unlock_rtas(s);
|
||||
}
|
||||
|
||||
static void call_rtas_display_status_delay(char c)
|
||||
@ -411,8 +434,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
|
||||
if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE)
|
||||
return -1;
|
||||
|
||||
/* Gotta do something different here, use global lock for now... */
|
||||
spin_lock_irqsave(&rtas.lock, s);
|
||||
s = lock_rtas();
|
||||
rtas_args = &rtas.args;
|
||||
|
||||
rtas_args->token = token;
|
||||
@ -439,8 +461,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
|
||||
outputs[i] = rtas_args->rets[i+1];
|
||||
ret = (nret > 0)? rtas_args->rets[0]: 0;
|
||||
|
||||
/* Gotta do something different here, use global lock for now... */
|
||||
spin_unlock_irqrestore(&rtas.lock, s);
|
||||
unlock_rtas(s);
|
||||
|
||||
if (buff_copy) {
|
||||
log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0);
|
||||
@ -837,7 +858,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
|
||||
|
||||
buff_copy = get_errorlog_buffer();
|
||||
|
||||
spin_lock_irqsave(&rtas.lock, flags);
|
||||
flags = lock_rtas();
|
||||
|
||||
rtas.args = args;
|
||||
enter_rtas(__pa(&rtas.args));
|
||||
@ -848,7 +869,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
|
||||
if (args.rets[0] == -1)
|
||||
errbuf = __fetch_rtas_last_error(buff_copy);
|
||||
|
||||
spin_unlock_irqrestore(&rtas.lock, flags);
|
||||
unlock_rtas(flags);
|
||||
|
||||
if (buff_copy) {
|
||||
if (errbuf)
|
||||
@ -951,3 +972,33 @@ int __init early_init_dt_scan_rtas(unsigned long node,
|
||||
/* break now */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static raw_spinlock_t timebase_lock;
|
||||
static u64 timebase = 0;
|
||||
|
||||
void __cpuinit rtas_give_timebase(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
hard_irq_disable();
|
||||
__raw_spin_lock(&timebase_lock);
|
||||
rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
|
||||
timebase = get_tb();
|
||||
__raw_spin_unlock(&timebase_lock);
|
||||
|
||||
while (timebase)
|
||||
barrier();
|
||||
rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
void __cpuinit rtas_take_timebase(void)
|
||||
{
|
||||
while (!timebase)
|
||||
barrier();
|
||||
__raw_spin_lock(&timebase_lock);
|
||||
set_tb(timebase >> 32, timebase & 0xffffffff);
|
||||
timebase = 0;
|
||||
__raw_spin_unlock(&timebase_lock);
|
||||
}
|
||||
|
@ -119,6 +119,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
|
||||
*/
|
||||
notrace void __init machine_init(unsigned long dt_ptr)
|
||||
{
|
||||
lockdep_init();
|
||||
|
||||
/* Enable early debugging if any specified (see udbg.h) */
|
||||
udbg_early_init();
|
||||
|
||||
|
@ -68,7 +68,8 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map);
|
||||
/* SMP operations for this machine */
|
||||
struct smp_ops_t *smp_ops;
|
||||
|
||||
static volatile unsigned int cpu_callin_map[NR_CPUS];
|
||||
/* Can't be static due to PowerMac hackery */
|
||||
volatile unsigned int cpu_callin_map[NR_CPUS];
|
||||
|
||||
int smt_enabled_at_boot = 1;
|
||||
|
||||
|
@ -219,7 +219,7 @@ void udbg_init_pas_realmode(void)
|
||||
#ifdef CONFIG_PPC_EARLY_DEBUG_44x
|
||||
#include <platforms/44x/44x.h>
|
||||
|
||||
static int udbg_44x_as1_flush(void)
|
||||
static void udbg_44x_as1_flush(void)
|
||||
{
|
||||
if (udbg_comport) {
|
||||
while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
|
||||
|
@ -30,3 +30,4 @@ obj-$(CONFIG_PPC_MM_SLICES) += slice.o
|
||||
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
|
||||
obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o
|
||||
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
|
||||
obj-$(CONFIG_HIGHMEM) += highmem.o
|
||||
|
77
arch/powerpc/mm/highmem.c
Normal file
77
arch/powerpc/mm/highmem.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* highmem.c: virtual kernel memory mappings for high memory
|
||||
*
|
||||
* PowerPC version, stolen from the i386 version.
|
||||
*
|
||||
* Used in CONFIG_HIGHMEM systems for memory pages which
|
||||
* are not addressable by direct kernel virtual addresses.
|
||||
*
|
||||
* Copyright (C) 1999 Gerhard Wichert, Siemens AG
|
||||
* Gerhard.Wichert@pdb.siemens.de
|
||||
*
|
||||
*
|
||||
* Redesigned the x86 32-bit VM architecture to deal with
|
||||
* up to 16 Terrabyte physical memory. With current x86 CPUs
|
||||
* we now support up to 64 Gigabytes physical RAM.
|
||||
*
|
||||
* Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
|
||||
*
|
||||
* Reworked for PowerPC by various contributors. Moved from
|
||||
* highmem.h by Benjamin Herrenschmidt (c) 2009 IBM Corp.
|
||||
*/
|
||||
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
/*
|
||||
* The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
|
||||
* gives a more generic (and caching) interface. But kmap_atomic can
|
||||
* be used in IRQ contexts, so in some (very limited) cases we need
|
||||
* it.
|
||||
*/
|
||||
void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
|
||||
{
|
||||
unsigned int idx;
|
||||
unsigned long vaddr;
|
||||
|
||||
/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
|
||||
pagefault_disable();
|
||||
if (!PageHighMem(page))
|
||||
return page_address(page);
|
||||
|
||||
debug_kmap_atomic(type);
|
||||
idx = type + KM_TYPE_NR*smp_processor_id();
|
||||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||
BUG_ON(!pte_none(*(kmap_pte-idx)));
|
||||
#endif
|
||||
__set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1);
|
||||
local_flush_tlb_page(NULL, vaddr);
|
||||
|
||||
return (void*) vaddr;
|
||||
}
|
||||
EXPORT_SYMBOL(kmap_atomic_prot);
|
||||
|
||||
void kunmap_atomic(void *kvaddr, enum km_type type)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||
unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
|
||||
enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
|
||||
|
||||
if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
|
||||
pagefault_enable();
|
||||
return;
|
||||
}
|
||||
|
||||
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
|
||||
|
||||
/*
|
||||
* force other mappings to Oops if they'll try to access
|
||||
* this pte without first remap it
|
||||
*/
|
||||
pte_clear(&init_mm, vaddr, kmap_pte-idx);
|
||||
local_flush_tlb_page(NULL, vaddr);
|
||||
#endif
|
||||
pagefault_enable();
|
||||
}
|
||||
EXPORT_SYMBOL(kunmap_atomic);
|
@ -16,6 +16,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_i2c.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/prom.h>
|
||||
@ -65,7 +66,6 @@ define_machine(warp) {
|
||||
|
||||
static u32 post_info;
|
||||
|
||||
/* I am not sure this is the best place for this... */
|
||||
static int __init warp_post_info(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
@ -194,9 +194,9 @@ static int pika_setup_leds(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pika_setup_critical_temp(struct i2c_client *client)
|
||||
static void pika_setup_critical_temp(struct device_node *np,
|
||||
struct i2c_client *client)
|
||||
{
|
||||
struct device_node *np;
|
||||
int irq, rc;
|
||||
|
||||
/* Do this before enabling critical temp interrupt since we
|
||||
@ -208,14 +208,7 @@ static void pika_setup_critical_temp(struct i2c_client *client)
|
||||
i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
|
||||
i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
|
||||
if (np == NULL) {
|
||||
printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
|
||||
return;
|
||||
}
|
||||
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
of_node_put(np);
|
||||
if (irq == NO_IRQ) {
|
||||
printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
|
||||
return;
|
||||
@ -244,32 +237,24 @@ static inline void pika_dtm_check_fan(void __iomem *fpga)
|
||||
|
||||
static int pika_dtm_thread(void __iomem *fpga)
|
||||
{
|
||||
struct i2c_adapter *adap;
|
||||
struct device_node *np;
|
||||
struct i2c_client *client;
|
||||
|
||||
/* We loop in case either driver was compiled as a module and
|
||||
* has not been insmoded yet.
|
||||
*/
|
||||
while (!(adap = i2c_get_adapter(0))) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule_timeout(HZ);
|
||||
np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
|
||||
if (np == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
client = of_find_i2c_device_by_node(np);
|
||||
if (client == NULL) {
|
||||
of_node_put(np);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
list_for_each_entry(client, &adap->clients, list)
|
||||
if (client->addr == 0x4a)
|
||||
goto found_it;
|
||||
pika_setup_critical_temp(np, client);
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule_timeout(HZ);
|
||||
}
|
||||
of_node_put(np);
|
||||
|
||||
found_it:
|
||||
pika_setup_critical_temp(client);
|
||||
|
||||
i2c_put_adapter(adap);
|
||||
|
||||
printk(KERN_INFO "PIKA DTM thread running.\n");
|
||||
printk(KERN_INFO "Warp DTM thread running.\n");
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
int val;
|
||||
@ -291,7 +276,6 @@ found_it:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int __init pika_dtm_start(void)
|
||||
{
|
||||
struct task_struct *dtm_thread;
|
||||
|
@ -285,6 +285,7 @@ static struct of_device_id mpc85xx_ids[] = {
|
||||
{ .type = "qe", },
|
||||
{ .compatible = "fsl,qe", },
|
||||
{ .compatible = "gianfar", },
|
||||
{ .compatible = "fsl,rapidio-delta", },
|
||||
{},
|
||||
};
|
||||
|
||||
|
@ -52,20 +52,19 @@ smp_85xx_kick_cpu(int nr)
|
||||
|
||||
pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
np = of_get_cpu_node(nr, NULL);
|
||||
cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
|
||||
|
||||
if (cpu_rel_addr == NULL) {
|
||||
printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
|
||||
local_irq_restore(flags);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Map the spin table */
|
||||
bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
|
||||
out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
|
||||
|
||||
@ -73,10 +72,10 @@ smp_85xx_kick_cpu(int nr)
|
||||
while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
|
||||
mdelay(1);
|
||||
|
||||
iounmap(bptr_vaddr);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
iounmap(bptr_vaddr);
|
||||
|
||||
pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
|
||||
}
|
||||
|
||||
|
@ -102,10 +102,11 @@ static struct of_device_id __initdata socrates_of_bus_ids[] = {
|
||||
{},
|
||||
};
|
||||
|
||||
static void __init socrates_init(void)
|
||||
static int __init socrates_publish_devices(void)
|
||||
{
|
||||
of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL);
|
||||
return of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL);
|
||||
}
|
||||
machine_device_initcall(socrates, socrates_publish_devices);
|
||||
|
||||
/*
|
||||
* Called very early, device-tree isn't unflattened
|
||||
@ -124,7 +125,6 @@ define_machine(socrates) {
|
||||
.name = "Socrates",
|
||||
.probe = socrates_probe,
|
||||
.setup_arch = socrates_setup_arch,
|
||||
.init = socrates_init,
|
||||
.init_IRQ = socrates_pic_init,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
#include <sysdev/fsl_soc.h>
|
||||
#include <sysdev/fsl_pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
/* A few bit definitions needed for fixups on some boards */
|
||||
#define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include <asm/prom.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/paca.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/firmware.h>
|
||||
@ -140,31 +139,6 @@ static void __devinit smp_cell_setup_cpu(int cpu)
|
||||
mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(timebase_lock);
|
||||
static unsigned long timebase = 0;
|
||||
|
||||
static void __devinit cell_give_timebase(void)
|
||||
{
|
||||
spin_lock(&timebase_lock);
|
||||
rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
|
||||
timebase = get_tb();
|
||||
spin_unlock(&timebase_lock);
|
||||
|
||||
while (timebase)
|
||||
barrier();
|
||||
rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
|
||||
}
|
||||
|
||||
static void __devinit cell_take_timebase(void)
|
||||
{
|
||||
while (!timebase)
|
||||
barrier();
|
||||
spin_lock(&timebase_lock);
|
||||
set_tb(timebase >> 32, timebase & 0xffffffff);
|
||||
timebase = 0;
|
||||
spin_unlock(&timebase_lock);
|
||||
}
|
||||
|
||||
static void __devinit smp_cell_kick_cpu(int nr)
|
||||
{
|
||||
BUG_ON(nr < 0 || nr >= NR_CPUS);
|
||||
@ -224,8 +198,8 @@ void __init smp_init_cell(void)
|
||||
|
||||
/* Non-lpar has additional take/give timebase */
|
||||
if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
|
||||
smp_ops->give_timebase = cell_give_timebase;
|
||||
smp_ops->take_timebase = cell_take_timebase;
|
||||
smp_ops->give_timebase = rtas_give_timebase;
|
||||
smp_ops->take_timebase = rtas_take_timebase;
|
||||
}
|
||||
|
||||
DBG(" <- smp_init_cell()\n");
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/rtas.h>
|
||||
@ -42,40 +41,12 @@ static void __devinit smp_chrp_setup_cpu(int cpu_nr)
|
||||
mpic_setup_this_cpu();
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(timebase_lock);
|
||||
static unsigned int timebase_upper = 0, timebase_lower = 0;
|
||||
|
||||
void __devinit smp_chrp_give_timebase(void)
|
||||
{
|
||||
spin_lock(&timebase_lock);
|
||||
rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
|
||||
timebase_upper = get_tbu();
|
||||
timebase_lower = get_tbl();
|
||||
spin_unlock(&timebase_lock);
|
||||
|
||||
while (timebase_upper || timebase_lower)
|
||||
barrier();
|
||||
rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
|
||||
}
|
||||
|
||||
void __devinit smp_chrp_take_timebase(void)
|
||||
{
|
||||
while (!(timebase_upper || timebase_lower))
|
||||
barrier();
|
||||
spin_lock(&timebase_lock);
|
||||
set_tb(timebase_upper, timebase_lower);
|
||||
timebase_upper = 0;
|
||||
timebase_lower = 0;
|
||||
spin_unlock(&timebase_lock);
|
||||
printk("CPU %i taken timebase\n", smp_processor_id());
|
||||
}
|
||||
|
||||
/* CHRP with openpic */
|
||||
struct smp_ops_t chrp_smp_ops = {
|
||||
.message_pass = smp_mpic_message_pass,
|
||||
.probe = smp_mpic_probe,
|
||||
.kick_cpu = smp_chrp_kick_cpu,
|
||||
.setup_cpu = smp_chrp_setup_cpu,
|
||||
.give_timebase = smp_chrp_give_timebase,
|
||||
.take_timebase = smp_chrp_take_timebase,
|
||||
.give_timebase = rtas_give_timebase,
|
||||
.take_timebase = rtas_take_timebase,
|
||||
};
|
||||
|
@ -71,20 +71,25 @@ static void pas_restart(char *cmd)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static DEFINE_SPINLOCK(timebase_lock);
|
||||
static raw_spinlock_t timebase_lock;
|
||||
static unsigned long timebase;
|
||||
|
||||
static void __devinit pas_give_timebase(void)
|
||||
{
|
||||
spin_lock(&timebase_lock);
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
hard_irq_disable();
|
||||
__raw_spin_lock(&timebase_lock);
|
||||
mtspr(SPRN_TBCTL, TBCTL_FREEZE);
|
||||
isync();
|
||||
timebase = get_tb();
|
||||
spin_unlock(&timebase_lock);
|
||||
__raw_spin_unlock(&timebase_lock);
|
||||
|
||||
while (timebase)
|
||||
barrier();
|
||||
mtspr(SPRN_TBCTL, TBCTL_RESTART);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static void __devinit pas_take_timebase(void)
|
||||
@ -92,10 +97,10 @@ static void __devinit pas_take_timebase(void)
|
||||
while (!timebase)
|
||||
smp_rmb();
|
||||
|
||||
spin_lock(&timebase_lock);
|
||||
__raw_spin_lock(&timebase_lock);
|
||||
set_tb(timebase >> 32, timebase & 0xffffffff);
|
||||
timebase = 0;
|
||||
spin_unlock(&timebase_lock);
|
||||
__raw_spin_unlock(&timebase_lock);
|
||||
}
|
||||
|
||||
struct smp_ops_t pas_smp_ops = {
|
||||
|
@ -103,11 +103,6 @@ unsigned long smu_cmdbuf_abs;
|
||||
EXPORT_SYMBOL(smu_cmdbuf_abs);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern struct smp_ops_t psurge_smp_ops;
|
||||
extern struct smp_ops_t core99_smp_ops;
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
static void pmac_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
struct device_node *np;
|
||||
@ -341,34 +336,6 @@ static void __init pmac_setup_arch(void)
|
||||
ROOT_DEV = DEFAULT_ROOT_DEVICE;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Check for Core99 */
|
||||
ic = of_find_node_by_name(NULL, "uni-n");
|
||||
if (!ic)
|
||||
ic = of_find_node_by_name(NULL, "u3");
|
||||
if (!ic)
|
||||
ic = of_find_node_by_name(NULL, "u4");
|
||||
if (ic) {
|
||||
of_node_put(ic);
|
||||
smp_ops = &core99_smp_ops;
|
||||
}
|
||||
#ifdef CONFIG_PPC32
|
||||
else {
|
||||
/*
|
||||
* We have to set bits in cpu_possible_map here since the
|
||||
* secondary CPU(s) aren't in the device tree, and
|
||||
* setup_per_cpu_areas only allocates per-cpu data for
|
||||
* CPUs in the cpu_possible_map.
|
||||
*/
|
||||
int cpu;
|
||||
|
||||
for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
|
||||
cpu_set(cpu, cpu_possible_map);
|
||||
smp_ops = &psurge_smp_ops;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_ADB
|
||||
if (strstr(cmd_line, "adb_sync")) {
|
||||
extern int __adb_probe_sync;
|
||||
@ -512,6 +479,14 @@ static void __init pmac_init_early(void)
|
||||
#ifdef CONFIG_PPC64
|
||||
iommu_init_early_dart();
|
||||
#endif
|
||||
|
||||
/* SMP Init has to be done early as we need to patch up
|
||||
* cpu_possible_map before interrupt stacks are allocated
|
||||
* or kaboom...
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
pmac_setup_smp();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __init pmac_declare_of_platform_devices(void)
|
||||
|
@ -64,10 +64,11 @@
|
||||
extern void __secondary_start_pmac_0(void);
|
||||
extern int pmac_pfunc_base_install(void);
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
static void (*pmac_tb_freeze)(int freeze);
|
||||
static u64 timebase;
|
||||
static int tb_req;
|
||||
|
||||
/* Sync flag for HW tb sync */
|
||||
static volatile int sec_tb_reset = 0;
|
||||
#ifdef CONFIG_PPC32
|
||||
|
||||
/*
|
||||
* Powersurge (old powermac SMP) support.
|
||||
@ -294,6 +295,9 @@ static int __init smp_psurge_probe(void)
|
||||
psurge_quad_init();
|
||||
/* All released cards using this HW design have 4 CPUs */
|
||||
ncpus = 4;
|
||||
/* No sure how timebase sync works on those, let's use SW */
|
||||
smp_ops->give_timebase = smp_generic_give_timebase;
|
||||
smp_ops->take_timebase = smp_generic_take_timebase;
|
||||
} else {
|
||||
iounmap(quad_base);
|
||||
if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
|
||||
@ -308,18 +312,15 @@ static int __init smp_psurge_probe(void)
|
||||
psurge_start = ioremap(PSURGE_START, 4);
|
||||
psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
|
||||
|
||||
/*
|
||||
* This is necessary because OF doesn't know about the
|
||||
/* This is necessary because OF doesn't know about the
|
||||
* secondary cpu(s), and thus there aren't nodes in the
|
||||
* device tree for them, and smp_setup_cpu_maps hasn't
|
||||
* set their bits in cpu_possible_map and cpu_present_map.
|
||||
* set their bits in cpu_present_map.
|
||||
*/
|
||||
if (ncpus > NR_CPUS)
|
||||
ncpus = NR_CPUS;
|
||||
for (i = 1; i < ncpus ; ++i) {
|
||||
for (i = 1; i < ncpus ; ++i)
|
||||
cpu_set(i, cpu_present_map);
|
||||
set_hard_smp_processor_id(i, i);
|
||||
}
|
||||
|
||||
if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
|
||||
|
||||
@ -329,8 +330,14 @@ static int __init smp_psurge_probe(void)
|
||||
static void __init smp_psurge_kick_cpu(int nr)
|
||||
{
|
||||
unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
|
||||
unsigned long a;
|
||||
int i;
|
||||
unsigned long a, flags;
|
||||
int i, j;
|
||||
|
||||
/* Defining this here is evil ... but I prefer hiding that
|
||||
* crap to avoid giving people ideas that they can do the
|
||||
* same.
|
||||
*/
|
||||
extern volatile unsigned int cpu_callin_map[NR_CPUS];
|
||||
|
||||
/* may need to flush here if secondary bats aren't setup */
|
||||
for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
|
||||
@ -339,47 +346,52 @@ static void __init smp_psurge_kick_cpu(int nr)
|
||||
|
||||
if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
|
||||
|
||||
/* This is going to freeze the timeebase, we disable interrupts */
|
||||
local_irq_save(flags);
|
||||
|
||||
out_be32(psurge_start, start);
|
||||
mb();
|
||||
|
||||
psurge_set_ipi(nr);
|
||||
|
||||
/*
|
||||
* We can't use udelay here because the timebase is now frozen.
|
||||
*/
|
||||
for (i = 0; i < 2000; ++i)
|
||||
barrier();
|
||||
asm volatile("nop" : : : "memory");
|
||||
psurge_clr_ipi(nr);
|
||||
|
||||
if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
|
||||
}
|
||||
|
||||
/*
|
||||
* With the dual-cpu powersurge board, the decrementers and timebases
|
||||
* of both cpus are frozen after the secondary cpu is started up,
|
||||
* until we give the secondary cpu another interrupt. This routine
|
||||
* uses this to get the timebases synchronized.
|
||||
* -- paulus.
|
||||
*/
|
||||
static void __init psurge_dual_sync_tb(int cpu_nr)
|
||||
{
|
||||
int t;
|
||||
|
||||
set_dec(tb_ticks_per_jiffy);
|
||||
/* XXX fixme */
|
||||
set_tb(0, 0);
|
||||
|
||||
if (cpu_nr > 0) {
|
||||
mb();
|
||||
sec_tb_reset = 1;
|
||||
return;
|
||||
/*
|
||||
* Also, because the timebase is frozen, we must not return to the
|
||||
* caller which will try to do udelay's etc... Instead, we wait -here-
|
||||
* for the CPU to callin.
|
||||
*/
|
||||
for (i = 0; i < 100000 && !cpu_callin_map[nr]; ++i) {
|
||||
for (j = 1; j < 10000; j++)
|
||||
asm volatile("nop" : : : "memory");
|
||||
asm volatile("sync" : : : "memory");
|
||||
}
|
||||
if (!cpu_callin_map[nr])
|
||||
goto stuck;
|
||||
|
||||
/* wait for the secondary to have reset its TB before proceeding */
|
||||
for (t = 10000000; t > 0 && !sec_tb_reset; --t)
|
||||
;
|
||||
/* And we do the TB sync here too for standard dual CPU cards */
|
||||
if (psurge_type == PSURGE_DUAL) {
|
||||
while(!tb_req)
|
||||
barrier();
|
||||
tb_req = 0;
|
||||
mb();
|
||||
timebase = get_tb();
|
||||
mb();
|
||||
while (timebase)
|
||||
barrier();
|
||||
mb();
|
||||
}
|
||||
stuck:
|
||||
/* now interrupt the secondary, restarting both TBs */
|
||||
if (psurge_type == PSURGE_DUAL)
|
||||
psurge_set_ipi(1);
|
||||
|
||||
/* now interrupt the secondary, starting both TBs */
|
||||
psurge_set_ipi(1);
|
||||
if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
|
||||
}
|
||||
|
||||
static struct irqaction psurge_irqaction = {
|
||||
@ -390,36 +402,35 @@ static struct irqaction psurge_irqaction = {
|
||||
|
||||
static void __init smp_psurge_setup_cpu(int cpu_nr)
|
||||
{
|
||||
if (cpu_nr != 0)
|
||||
return;
|
||||
|
||||
if (cpu_nr == 0) {
|
||||
/* If we failed to start the second CPU, we should still
|
||||
* send it an IPI to start the timebase & DEC or we might
|
||||
* have them stuck.
|
||||
*/
|
||||
if (num_online_cpus() < 2) {
|
||||
if (psurge_type == PSURGE_DUAL)
|
||||
psurge_set_ipi(1);
|
||||
return;
|
||||
}
|
||||
/* reset the entry point so if we get another intr we won't
|
||||
* try to startup again */
|
||||
out_be32(psurge_start, 0x100);
|
||||
if (setup_irq(30, &psurge_irqaction))
|
||||
printk(KERN_ERR "Couldn't get primary IPI interrupt");
|
||||
}
|
||||
|
||||
if (psurge_type == PSURGE_DUAL)
|
||||
psurge_dual_sync_tb(cpu_nr);
|
||||
/* reset the entry point so if we get another intr we won't
|
||||
* try to startup again */
|
||||
out_be32(psurge_start, 0x100);
|
||||
if (setup_irq(30, &psurge_irqaction))
|
||||
printk(KERN_ERR "Couldn't get primary IPI interrupt");
|
||||
}
|
||||
|
||||
void __init smp_psurge_take_timebase(void)
|
||||
{
|
||||
/* Dummy implementation */
|
||||
if (psurge_type != PSURGE_DUAL)
|
||||
return;
|
||||
|
||||
tb_req = 1;
|
||||
mb();
|
||||
while (!timebase)
|
||||
barrier();
|
||||
mb();
|
||||
set_tb(timebase >> 32, timebase & 0xffffffff);
|
||||
timebase = 0;
|
||||
mb();
|
||||
set_dec(tb_ticks_per_jiffy/2);
|
||||
}
|
||||
|
||||
void __init smp_psurge_give_timebase(void)
|
||||
{
|
||||
/* Dummy implementation */
|
||||
/* Nothing to do here */
|
||||
}
|
||||
|
||||
/* PowerSurge-style Macs */
|
||||
@ -437,9 +448,6 @@ struct smp_ops_t psurge_smp_ops = {
|
||||
* Core 99 and later support
|
||||
*/
|
||||
|
||||
static void (*pmac_tb_freeze)(int freeze);
|
||||
static u64 timebase;
|
||||
static int tb_req;
|
||||
|
||||
static void smp_core99_give_timebase(void)
|
||||
{
|
||||
@ -478,7 +486,6 @@ static void __devinit smp_core99_take_timebase(void)
|
||||
set_tb(timebase >> 32, timebase & 0xffffffff);
|
||||
timebase = 0;
|
||||
mb();
|
||||
set_dec(tb_ticks_per_jiffy/2);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
@ -920,3 +927,34 @@ struct smp_ops_t core99_smp_ops = {
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
void __init pmac_setup_smp(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
/* Check for Core99 */
|
||||
np = of_find_node_by_name(NULL, "uni-n");
|
||||
if (!np)
|
||||
np = of_find_node_by_name(NULL, "u3");
|
||||
if (!np)
|
||||
np = of_find_node_by_name(NULL, "u4");
|
||||
if (np) {
|
||||
of_node_put(np);
|
||||
smp_ops = &core99_smp_ops;
|
||||
}
|
||||
#ifdef CONFIG_PPC32
|
||||
else {
|
||||
/* We have to set bits in cpu_possible_map here since the
|
||||
* secondary CPU(s) aren't in the device tree. Various
|
||||
* things won't be initialized for CPUs not in the possible
|
||||
* map, so we really need to fix it up here.
|
||||
*/
|
||||
int cpu;
|
||||
|
||||
for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
|
||||
cpu_set(cpu, cpu_possible_map);
|
||||
smp_ops = &psurge_smp_ops;
|
||||
}
|
||||
#endif /* CONFIG_PPC32 */
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <asm/prom.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/paca.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/firmware.h>
|
||||
@ -118,31 +117,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
|
||||
}
|
||||
#endif /* CONFIG_XICS */
|
||||
|
||||
static DEFINE_SPINLOCK(timebase_lock);
|
||||
static unsigned long timebase = 0;
|
||||
|
||||
static void __devinit pSeries_give_timebase(void)
|
||||
{
|
||||
spin_lock(&timebase_lock);
|
||||
rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
|
||||
timebase = get_tb();
|
||||
spin_unlock(&timebase_lock);
|
||||
|
||||
while (timebase)
|
||||
barrier();
|
||||
rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
|
||||
}
|
||||
|
||||
static void __devinit pSeries_take_timebase(void)
|
||||
{
|
||||
while (!timebase)
|
||||
barrier();
|
||||
spin_lock(&timebase_lock);
|
||||
set_tb(timebase >> 32, timebase & 0xffffffff);
|
||||
timebase = 0;
|
||||
spin_unlock(&timebase_lock);
|
||||
}
|
||||
|
||||
static void __devinit smp_pSeries_kick_cpu(int nr)
|
||||
{
|
||||
BUG_ON(nr < 0 || nr >= NR_CPUS);
|
||||
@ -209,8 +183,8 @@ static void __init smp_init_pseries(void)
|
||||
|
||||
/* Non-lpar has additional take/give timebase */
|
||||
if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
|
||||
smp_ops->give_timebase = pSeries_give_timebase;
|
||||
smp_ops->take_timebase = pSeries_take_timebase;
|
||||
smp_ops->give_timebase = rtas_give_timebase;
|
||||
smp_ops->take_timebase = rtas_take_timebase;
|
||||
}
|
||||
|
||||
pr_debug(" <- smp_init_pSeries()\n");
|
||||
|
@ -279,28 +279,29 @@ static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_DCR
|
||||
static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
|
||||
static void _mpic_map_dcr(struct mpic *mpic, struct device_node *node,
|
||||
struct mpic_reg_bank *rb,
|
||||
unsigned int offset, unsigned int size)
|
||||
{
|
||||
const u32 *dbasep;
|
||||
|
||||
dbasep = of_get_property(mpic->irqhost->of_node, "dcr-reg", NULL);
|
||||
dbasep = of_get_property(node, "dcr-reg", NULL);
|
||||
|
||||
rb->dhost = dcr_map(mpic->irqhost->of_node, *dbasep + offset, size);
|
||||
rb->dhost = dcr_map(node, *dbasep + offset, size);
|
||||
BUG_ON(!DCR_MAP_OK(rb->dhost));
|
||||
}
|
||||
|
||||
static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr,
|
||||
struct mpic_reg_bank *rb, unsigned int offset,
|
||||
unsigned int size)
|
||||
static inline void mpic_map(struct mpic *mpic, struct device_node *node,
|
||||
phys_addr_t phys_addr, struct mpic_reg_bank *rb,
|
||||
unsigned int offset, unsigned int size)
|
||||
{
|
||||
if (mpic->flags & MPIC_USES_DCR)
|
||||
_mpic_map_dcr(mpic, rb, offset, size);
|
||||
_mpic_map_dcr(mpic, node, rb, offset, size);
|
||||
else
|
||||
_mpic_map_mmio(mpic, phys_addr, rb, offset, size);
|
||||
}
|
||||
#else /* CONFIG_PPC_DCR */
|
||||
#define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s)
|
||||
#define mpic_map(m,n,p,b,o,s) _mpic_map_mmio(m,p,b,o,s)
|
||||
#endif /* !CONFIG_PPC_DCR */
|
||||
|
||||
|
||||
@ -1052,11 +1053,10 @@ struct mpic * __init mpic_alloc(struct device_node *node,
|
||||
int intvec_top;
|
||||
u64 paddr = phys_addr;
|
||||
|
||||
mpic = alloc_bootmem(sizeof(struct mpic));
|
||||
mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
|
||||
if (mpic == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(mpic, 0, sizeof(struct mpic));
|
||||
|
||||
mpic->name = name;
|
||||
|
||||
mpic->hc_irq = mpic_irq_chip;
|
||||
@ -1152,8 +1152,8 @@ struct mpic * __init mpic_alloc(struct device_node *node,
|
||||
}
|
||||
|
||||
/* Map the global registers */
|
||||
mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
|
||||
mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
|
||||
mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
|
||||
mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
|
||||
|
||||
/* Reset */
|
||||
if (flags & MPIC_WANTS_RESET) {
|
||||
@ -1194,7 +1194,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
|
||||
|
||||
/* Map the per-CPU registers */
|
||||
for (i = 0; i < mpic->num_cpus; i++) {
|
||||
mpic_map(mpic, paddr, &mpic->cpuregs[i],
|
||||
mpic_map(mpic, node, paddr, &mpic->cpuregs[i],
|
||||
MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
|
||||
0x1000);
|
||||
}
|
||||
@ -1202,7 +1202,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
|
||||
/* Initialize main ISU if none provided */
|
||||
if (mpic->isu_size == 0) {
|
||||
mpic->isu_size = mpic->num_sources;
|
||||
mpic_map(mpic, paddr, &mpic->isus[0],
|
||||
mpic_map(mpic, node, paddr, &mpic->isus[0],
|
||||
MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
|
||||
}
|
||||
mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
|
||||
@ -1256,8 +1256,10 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
|
||||
|
||||
BUG_ON(isu_num >= MPIC_MAX_ISU);
|
||||
|
||||
mpic_map(mpic, paddr, &mpic->isus[isu_num], 0,
|
||||
mpic_map(mpic, mpic->irqhost->of_node,
|
||||
paddr, &mpic->isus[isu_num], 0,
|
||||
MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
|
||||
|
||||
if ((isu_first + mpic->isu_size) > mpic->num_sources)
|
||||
mpic->num_sources = isu_first + mpic->isu_size;
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
|
||||
{
|
||||
unsigned long flags;
|
||||
u8 mcn_shift = 0, dev_shift = 0;
|
||||
u32 ret;
|
||||
|
||||
spin_lock_irqsave(&qe_lock, flags);
|
||||
if (cmd == QE_RESET) {
|
||||
@ -139,11 +140,13 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
|
||||
}
|
||||
|
||||
/* wait for the QE_CR_FLG to clear */
|
||||
while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG)
|
||||
cpu_relax();
|
||||
ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0,
|
||||
100, 0);
|
||||
/* On timeout (e.g. failure), the expression will be false (ret == 0),
|
||||
otherwise it will be true (ret == 1). */
|
||||
spin_unlock_irqrestore(&qe_lock, flags);
|
||||
|
||||
return 0;
|
||||
return ret == 1;
|
||||
}
|
||||
EXPORT_SYMBOL(qe_issue_cmd);
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/*
|
||||
@ -75,12 +76,13 @@ static struct class *bsr_class;
|
||||
static int bsr_major;
|
||||
|
||||
enum {
|
||||
BSR_8 = 0,
|
||||
BSR_16 = 1,
|
||||
BSR_64 = 2,
|
||||
BSR_128 = 3,
|
||||
BSR_UNKNOWN = 4,
|
||||
BSR_MAX = 5,
|
||||
BSR_8 = 0,
|
||||
BSR_16 = 1,
|
||||
BSR_64 = 2,
|
||||
BSR_128 = 3,
|
||||
BSR_4096 = 4,
|
||||
BSR_UNKNOWN = 5,
|
||||
BSR_MAX = 6,
|
||||
};
|
||||
|
||||
static unsigned bsr_types[BSR_MAX];
|
||||
@ -117,15 +119,22 @@ static int bsr_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
struct bsr_dev *dev = filp->private_data;
|
||||
int ret;
|
||||
|
||||
if (size > dev->bsr_len || (size & (PAGE_SIZE-1)))
|
||||
return -EINVAL;
|
||||
|
||||
vma->vm_flags |= (VM_IO | VM_DONTEXPAND);
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
|
||||
if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT,
|
||||
size, vma->vm_page_prot))
|
||||
/* check for the case of a small BSR device and map one 4k page for it*/
|
||||
if (dev->bsr_len < PAGE_SIZE && size == PAGE_SIZE)
|
||||
ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12,
|
||||
vma->vm_page_prot);
|
||||
else if (size <= dev->bsr_len)
|
||||
ret = io_remap_pfn_range(vma, vma->vm_start,
|
||||
dev->bsr_addr >> PAGE_SHIFT,
|
||||
size, vma->vm_page_prot);
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
if (ret)
|
||||
return -EAGAIN;
|
||||
|
||||
return 0;
|
||||
@ -205,6 +214,11 @@ static int bsr_add_node(struct device_node *bn)
|
||||
cur->bsr_stride = bsr_stride[i];
|
||||
cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs);
|
||||
|
||||
/* if we have a bsr_len of > 4k and less then PAGE_SIZE (64k pages) */
|
||||
/* we can only map 4k of it, so only advertise the 4k in sysfs */
|
||||
if (cur->bsr_len > 4096 && cur->bsr_len < PAGE_SIZE)
|
||||
cur->bsr_len = 4096;
|
||||
|
||||
switch(cur->bsr_bytes) {
|
||||
case 8:
|
||||
cur->bsr_type = BSR_8;
|
||||
@ -218,9 +232,11 @@ static int bsr_add_node(struct device_node *bn)
|
||||
case 128:
|
||||
cur->bsr_type = BSR_128;
|
||||
break;
|
||||
case 4096:
|
||||
cur->bsr_type = BSR_4096;
|
||||
break;
|
||||
default:
|
||||
cur->bsr_type = BSR_UNKNOWN;
|
||||
printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes);
|
||||
}
|
||||
|
||||
cur->bsr_num = bsr_types[cur->bsr_type];
|
||||
|
@ -378,6 +378,17 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
|
||||
dev->ofdev.dev.bus = &macio_bus_type;
|
||||
dev->ofdev.dev.release = macio_release_dev;
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/* Set the DMA ops to the ones from the PCI device, this could be
|
||||
* fishy if we didn't know that on PowerMac it's always direct ops
|
||||
* or iommu ops that will work fine
|
||||
*/
|
||||
dev->ofdev.dev.archdata.dma_ops =
|
||||
chip->lbus.pdev->dev.archdata.dma_ops;
|
||||
dev->ofdev.dev.archdata.dma_data =
|
||||
chip->lbus.pdev->dev.archdata.dma_data;
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n",
|
||||
dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj);
|
||||
|
@ -218,16 +218,14 @@ static void wdrtas_timer_keepalive(void)
|
||||
*/
|
||||
static int wdrtas_get_temperature(void)
|
||||
{
|
||||
long result;
|
||||
int result;
|
||||
int temperature = 0;
|
||||
|
||||
result = rtas_call(wdrtas_token_get_sensor_state, 2, 2,
|
||||
(void *)__pa(&temperature),
|
||||
WDRTAS_THERMAL_SENSOR, 0);
|
||||
result = rtas_get_sensor(WDRTAS_THERMAL_SENSOR, 0, &temperature);
|
||||
|
||||
if (result < 0)
|
||||
printk(KERN_WARNING "wdrtas: reading the thermal sensor "
|
||||
"faild: %li\n", result);
|
||||
"failed: %i\n", result);
|
||||
else
|
||||
temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */
|
||||
|
||||
|
5
scripts/dtc/.gitignore
vendored
Normal file
5
scripts/dtc/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
dtc
|
||||
dtc-lexer.lex.c
|
||||
dtc-parser.tab.c
|
||||
dtc-parser.tab.h
|
||||
|
Loading…
Reference in New Issue
Block a user