Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (62 commits)
  powerpc/85xx: Fix signedness bug in cache-sram
  powerpc/fsl: 85xx: document cache sram bindings
  powerpc/fsl: define binding for fsl mpic interrupt controllers
  powerpc/fsl_msi: Handle msi-available-ranges better
  drivers/serial/ucc_uart.c: Add of_node_put to avoid memory leak
  powerpc/85xx: Fix SPE float to integer conversion failure
  powerpc/85xx: Update sata controller compatible for p1022ds board
  ATA: Add FSL sata v2 controller support
  powerpc/mpc8xxx_gpio: simplify searching for 'fsl, qoriq-gpio' compatiable
  powerpc/8xx: remove obsolete mgsuvd board
  powerpc/82xx: rename and update mgcoge board support
  powerpc/83xx: rename and update kmeter1
  powerpc/85xx: Workaroudn e500 CPU erratum A005
  powerpc/fsl_pci: Add support for FSL PCIe controllers v2.x
  powerpc/85xx: Fix writing to spin table 'cpu-release-addr' on ppc64e
  powerpc/pseries: Disable MSI using new interface if possible
  powerpc: Enable GENERIC_HARDIRQS_NO_DEPRECATED.
  powerpc: core irq_data conversion.
  powerpc: sysdev/xilinx_intc irq_data conversion.
  powerpc: sysdev/uic irq_data conversion.
  ...

Fix up conflicts in arch/powerpc/sysdev/fsl_msi.c (due to getting rid of
of_platform_driver in arch/powerpc)
This commit is contained in:
Linus Torvalds 2011-03-18 06:31:43 -07:00
commit 0a95d92c00
101 changed files with 2430 additions and 1387 deletions

View File

@ -0,0 +1,20 @@
* Freescale PQ3 and QorIQ based Cache SRAM
Freescale's mpc85xx and some QorIQ platforms provide an
option of configuring a part of (or full) cache memory
as SRAM. This cache SRAM representation in the device
tree should be done as under:-
Required properties:
- compatible : should be "fsl,p2020-cache-sram"
- fsl,cache-sram-ctlr-handle : points to the L2 controller
- reg : offset and length of the cache-sram.
Example:
cache-sram@fff00000 {
fsl,cache-sram-ctlr-handle = <&L2>;
reg = <0 0xfff00000 0 0x10000>;
compatible = "fsl,p2020-cache-sram";
};

View File

@ -1,42 +1,211 @@
* OpenPIC and its interrupt numbers on Freescale's e500/e600 cores
=====================================================================
Freescale MPIC Interrupt Controller Node
Copyright (C) 2010,2011 Freescale Semiconductor Inc.
=====================================================================
The OpenPIC specification does not specify which interrupt source has to
become which interrupt number. This is up to the software implementation
of the interrupt controller. The only requirement is that every
interrupt source has to have an unique interrupt number / vector number.
To accomplish this the current implementation assigns the number zero to
the first source, the number one to the second source and so on until
all interrupt sources have their unique number.
Usually the assigned vector number equals the interrupt number mentioned
in the documentation for a given core / CPU. This is however not true
for the e500 cores (MPC85XX CPUs) where the documentation distinguishes
between internal and external interrupt sources and starts counting at
zero for both of them.
The Freescale MPIC interrupt controller is found on all PowerQUICC
and QorIQ processors and is compatible with the Open PIC. The
notable difference from Open PIC binding is the addition of 2
additional cells in the interrupt specifier defining interrupt type
information.
So what to write for external interrupt source X or internal interrupt
source Y into the device tree? Here is an example:
PROPERTIES
The memory map for the interrupt controller in the MPC8544[0] shows,
that the first interrupt source starts at 0x5_0000 (PIC Register Address
Map-Interrupt Source Configuration Registers). This source becomes the
number zero therefore:
External interrupt 0 = interrupt number 0
External interrupt 1 = interrupt number 1
External interrupt 2 = interrupt number 2
...
Every interrupt number allocates 0x20 bytes register space. So to get
its number it is sufficient to shift the lower 16bits to right by five.
So for the external interrupt 10 we have:
0x0140 >> 5 = 10
- compatible
Usage: required
Value type: <string>
Definition: Shall include "fsl,mpic". Freescale MPIC
controllers compatible with this binding have Block
Revision Registers BRR1 and BRR2 at offset 0x0 and
0x10 in the MPIC.
After the external sources, the internal sources follow. The in core I2C
controller on the MPC8544 for instance has the internal source number
27. Oo obtain its interrupt number we take the lower 16bits of its memory
address (0x5_0560) and shift it right:
0x0560 >> 5 = 43
- reg
Usage: required
Value type: <prop-encoded-array>
Definition: A standard property. Specifies the physical
offset and length of the device's registers within the
CCSR address space.
Therefore the I2C device node for the MPC8544 CPU has to have the
interrupt number 43 specified in the device tree.
- interrupt-controller
Usage: required
Value type: <empty>
Definition: Specifies that this node is an interrupt
controller
[0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual
MPC8544ERM Rev. 1 10/2007
- #interrupt-cells
Usage: required
Value type: <u32>
Definition: Shall be 2 or 4. A value of 2 means that interrupt
specifiers do not contain the interrupt-type or type-specific
information cells.
- #address-cells
Usage: required
Value type: <u32>
Definition: Shall be 0.
- pic-no-reset
Usage: optional
Value type: <empty>
Definition: The presence of this property specifies that the
MPIC must not be reset by the client program, and that
the boot program has initialized all interrupt source
configuration registers to a sane state-- masked or
directed at other cores. This ensures that the client
program will not receive interrupts for sources not belonging
to the client. The presence of this property also mandates
that any initialization related to interrupt sources shall
be limited to sources explicitly referenced in the device tree.
INTERRUPT SPECIFIER DEFINITION
Interrupt specifiers consists of 4 cells encoded as
follows:
<1st-cell> interrupt-number
Identifies the interrupt source. The meaning
depends on the type of interrupt.
Note: If the interrupt-type cell is undefined
(i.e. #interrupt-cells = 2), this cell
should be interpreted the same as for
interrupt-type 0-- i.e. an external or
normal SoC device interrupt.
<2nd-cell> level-sense information, encoded as follows:
0 = low-to-high edge triggered
1 = active low level-sensitive
2 = active high level-sensitive
3 = high-to-low edge triggered
<3rd-cell> interrupt-type
The following types are supported:
0 = external or normal SoC device interrupt
The interrupt-number cell contains
the SoC device interrupt number. The
type-specific cell is undefined. The
interrupt-number is derived from the
MPIC a block of registers referred to as
the "Interrupt Source Configuration Registers".
Each source has 32-bytes of registers
(vector/priority and destination) in this
region. So interrupt 0 is at offset 0x0,
interrupt 1 is at offset 0x20, and so on.
1 = error interrupt
The interrupt-number cell contains
the SoC device interrupt number for
the error interrupt. The type-specific
cell identifies the specific error
interrupt number.
2 = MPIC inter-processor interrupt (IPI)
The interrupt-number cell identifies
the MPIC IPI number. The type-specific
cell is undefined.
3 = MPIC timer interrupt
The interrupt-number cell identifies
the MPIC timer number. The type-specific
cell is undefined.
<4th-cell> type-specific information
The type-specific cell is encoded as follows:
- For interrupt-type 1 (error interrupt),
the type-specific cell contains the
bit number of the error interrupt in the
Error Interrupt Summary Register.
EXAMPLE 1
/*
* mpic interrupt controller with 4 cells per specifier
*/
mpic: pic@40000 {
compatible = "fsl,mpic";
interrupt-controller;
#interrupt-cells = <4>;
#address-cells = <0>;
reg = <0x40000 0x40000>;
};
EXAMPLE 2
/*
* The MPC8544 I2C controller node has an internal
* interrupt number of 27. As per the reference manual
* this corresponds to interrupt source configuration
* registers at 0x5_0560.
*
* The interrupt source configuration registers begin
* at 0x5_0000.
*
* To compute the interrupt specifier interrupt number
*
* 0x560 >> 5 = 43
*
* The interrupt source configuration registers begin
* at 0x5_0000, and so the i2c vector/priority registers
* are at 0x5_0560.
*/
i2c@3000 {
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl-i2c";
reg = <0x3000 0x100>;
interrupts = <43 2>;
interrupt-parent = <&mpic>;
dfsrr;
};
EXAMPLE 3
/*
* Definition of a node defining the 4
* MPIC IPI interrupts. Note the interrupt
* type of 2.
*/
ipi@410a0 {
compatible = "fsl,mpic-ipi";
reg = <0x40040 0x10>;
interrupts = <0 0 2 0
1 0 2 0
2 0 2 0
3 0 2 0>;
};
EXAMPLE 4
/*
* Definition of a node defining the MPIC
* global timers. Note the interrupt
* type of 3.
*/
timer0: timer@41100 {
compatible = "fsl,mpic-global-timer";
reg = <0x41100 0x100>;
interrupts = <0 0 3 0
1 0 3 0
2 0 3 0
3 0 3 0>;
};
EXAMPLE 5
/*
* Definition of an error interrupt (interupt type 1).
* SoC interrupt number is 16 and the specific error
* interrupt bit in the error interrupt summary register
* is 23.
*/
memory-controller@8000 {
compatible = "fsl,p4080-memory-controller";
reg = <0x8000 0x1000>;
interrupts = <16 2 1 23>;
};

View File

@ -5,14 +5,21 @@ Required properties:
first is "fsl,CHIP-msi", where CHIP is the processor(mpc8610, mpc8572,
etc.) and the second is "fsl,mpic-msi" or "fsl,ipic-msi" depending on
the parent type.
- reg : should contain the address and the length of the shared message
interrupt register set.
- msi-available-ranges: use <start count> style section to define which
msi interrupt can be used in the 256 msi interrupts. This property is
optional, without this, all the 256 MSI interrupts can be used.
Each available range must begin and end on a multiple of 32 (i.e.
no splitting an individual MSI register or the associated PIC interrupt).
- interrupts : each one of the interrupts here is one entry per 32 MSIs,
and routed to the host interrupt controller. the interrupts should
be set as edge sensitive.
be set as edge sensitive. If msi-available-ranges is present, only
the interrupts that correspond to available ranges shall be present.
- interrupt-parent: the phandle for the interrupt controller
that services interrupts for this device. for 83xx cpu, the interrupts
are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed

View File

@ -626,6 +626,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
disable= [IPV6]
See Documentation/networking/ipv6.txt.
disable_ddw [PPC/PSERIES]
Disable Dynamic DMA Window support. Use this if
to workaround buggy firmware.
disable_ipv6= [IPV6]
See Documentation/networking/ipv6.txt.

View File

@ -134,6 +134,7 @@ config PPC
select HAVE_GENERIC_HARDIRQS
select HAVE_SPARSE_IRQ
select IRQ_PER_CPU
select GENERIC_HARDIRQS_NO_DEPRECATED
config EARLY_PRINTK
bool

View File

@ -172,6 +172,19 @@
interrupts = <0x1e 4>;
};
USBOTG0: usbotg@bff80000 {
compatible = "amcc,dwc-otg";
reg = <0x4 0xbff80000 0x10000>;
interrupt-parent = <&USBOTG0>;
#interrupt-cells = <1>;
#address-cells = <0>;
#size-cells = <0>;
interrupts = <0x0 0x1 0x2>;
interrupt-map = </* USB-OTG */ 0x0 &UIC2 0x1c 0x4
/* HIGH-POWER */ 0x1 &UIC1 0x1a 0x8
/* DMA */ 0x2 &UIC0 0xc 0x4>;
};
SATA0: sata@bffd1000 {
compatible = "amcc,sata-460ex";
reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>;
@ -233,6 +246,11 @@
};
};
cpld@2,0 {
compatible = "amcc,ppc460ex-bcsr";
reg = <2 0x0 0x9>;
};
ndfc@3,0 {
compatible = "ibm,ndfc";
reg = <0x00000003 0x00000000 0x00002000>;
@ -307,6 +325,12 @@
interrupts = <0x3 0x4>;
};
GPIO0: gpio@ef600b00 {
compatible = "ibm,ppc4xx-gpio";
reg = <0xef600b00 0x00000048>;
gpio-controller;
};
ZMII0: emac-zmii@ef600d00 {
compatible = "ibm,zmii-460ex", "ibm,zmii";
reg = <0xef600d00 0x0000000c>;

View File

@ -1,7 +1,7 @@
/*
* Keymile KMETER1 Device Tree Source
*
* 2008 DENX Software Engineering GmbH
* 2008-2011 DENX Software Engineering GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -70,11 +70,11 @@
#address-cells = <1>;
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl-i2c";
compatible = "fsl,mpc8313-i2c","fsl-i2c";
reg = <0x3000 0x100>;
interrupts = <14 0x8>;
interrupt-parent = <&ipic>;
dfsrr;
clock-frequency = <400000>;
};
serial0: serial@4500 {
@ -137,6 +137,13 @@
compatible = "fsl,mpc8360-par_io";
num-ports = <7>;
qe_pio_c: gpio-controller@30 {
#gpio-cells = <2>;
compatible = "fsl,mpc8360-qe-pario-bank",
"fsl,mpc8323-qe-pario-bank";
reg = <0x1430 0x18>;
gpio-controller;
};
pio_ucc1: ucc_pin@0 {
reg = <0>;
@ -472,7 +479,17 @@
#address-cells = <0>;
#interrupt-cells = <1>;
reg = <0x80 0x80>;
interrupts = <32 8 33 8>;
big-endian;
interrupts = <
32 0x8
33 0x8
34 0x8
35 0x8
40 0x8
41 0x8
42 0x8
43 0x8
>;
interrupt-parent = <&ipic>;
};
};
@ -484,43 +501,31 @@
compatible = "fsl,mpc8360-localbus", "fsl,pq2pro-localbus",
"simple-bus";
reg = <0xe0005000 0xd8>;
ranges = <0 0 0xf0000000 0x04000000>; /* Filled in by U-Boot */
ranges = <0 0 0xf0000000 0x04000000 /* LB 0 */
1 0 0xe8000000 0x01000000 /* LB 1 */
3 0 0xa0000000 0x10000000>; /* LB 3 */
flash@f0000000,0 {
flash@0,0 {
compatible = "cfi-flash";
/*
* The Intel P30 chip has 2 non-identical chips on
* one die, so we need to define 2 separate regions
* that are scanned by physmap_of independantly.
*/
reg = <0 0x00000000 0x02000000
0 0x02000000 0x02000000>; /* Filled in by U-Boot */
bank-width = <2>;
reg = <0 0 0x04000000>;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
bank-width = <2>;
partition@0 { /* 768KB */
label = "u-boot";
reg = <0 0x40000>;
reg = <0 0xC0000>;
};
partition@40000 {
partition@c0000 { /* 128KB */
label = "env";
reg = <0x40000 0x40000>;
reg = <0xC0000 0x20000>;
};
partition@80000 {
label = "dtb";
reg = <0x80000 0x20000>;
partition@e0000 { /* 128KB */
label = "envred";
reg = <0xE0000 0x20000>;
};
partition@a0000 {
label = "kernel";
reg = <0xa0000 0x300000>;
};
partition@3a0000 {
label = "ramdisk";
reg = <0x3a0000 0x800000>;
};
partition@ba0000 {
label = "user";
reg = <0xba0000 0x3460000>;
partition@100000 { /* 64512KB */
label = "ubi0";
reg = <0x100000 0x3F00000>;
};
};
};

View File

@ -13,7 +13,7 @@
/dts-v1/;
/ {
model = "MGCOGE";
compatible = "keymile,mgcoge";
compatible = "keymile,km82xx";
#address-cells = <1>;
#size-cells = <1>;
@ -48,8 +48,10 @@
reg = <0xf0010100 0x40>;
ranges = <0 0 0xfe000000 0x00400000
5 0 0x50000000 0x20000000
>; /* Filled in by U-Boot */
1 0 0x30000000 0x00010000
2 0 0x40000000 0x00010000
5 0 0x50000000 0x04000000
>;
flash@0,0 {
compatible = "cfi-flash";
@ -60,36 +62,32 @@
device-width = <1>;
partition@0 {
label = "u-boot";
reg = <0 0x40000>;
reg = <0x00000 0xC0000>;
};
partition@40000 {
partition@1 {
label = "env";
reg = <0x40000 0x20000>;
reg = <0xC0000 0x20000>;
};
partition@60000 {
label = "kernel";
reg = <0x60000 0x220000>;
partition@2 {
label = "envred";
reg = <0xE0000 0x20000>;
};
partition@280000 {
label = "dtb";
reg = <0x280000 0x20000>;
partition@3 {
label = "free";
reg = <0x100000 0x300000>;
};
};
flash@5,0 {
compatible = "cfi-flash";
reg = <5 0x0 0x2000000>;
reg = <5 0x00000000 0x02000000
5 0x02000000 0x02000000>;
#address-cells = <1>;
#size-cells = <1>;
bank-width = <2>;
device-width = <2>;
partition@0 {
label = "ramdisk";
reg = <0 0x7a0000>;
};
partition@7a0000 {
label = "user";
reg = <0x7a0000 0x1860000>;
partition@app { /* 64 MBytes */
label = "ubi0";
reg = <0x00000000 0x04000000>;
};
};
};
@ -217,6 +215,13 @@
};
};
cpm2_pio_c: gpio-controller@10d40 {
#gpio-cells = <2>;
compatible = "fsl,cpm2-pario-bank";
reg = <0x10d40 0x14>;
gpio-controller;
};
PIC: interrupt-controller@10c00 {
#interrupt-cells = <2>;
interrupt-controller;

View File

@ -1,163 +0,0 @@
/*
* MGSUVD Device Tree Source
*
* Copyright 2008 DENX Software Engineering GmbH
* Heiko Schocher <hs@denx.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
/dts-v1/;
/ {
model = "MGSUVD";
compatible = "keymile,mgsuvd";
#address-cells = <1>;
#size-cells = <1>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
PowerPC,852@0 {
device_type = "cpu";
reg = <0>;
d-cache-line-size = <16>;
i-cache-line-size = <16>;
d-cache-size = <8192>;
i-cache-size = <8192>;
timebase-frequency = <0>; /* Filled in by u-boot */
bus-frequency = <0>; /* Filled in by u-boot */
clock-frequency = <0>; /* Filled in by u-boot */
interrupts = <15 2>; /* decrementer interrupt */
interrupt-parent = <&PIC>;
};
};
memory {
device_type = "memory";
reg = <00000000 0x4000000>; /* Filled in by u-boot */
};
localbus@fff00100 {
compatible = "fsl,mpc852-localbus", "fsl,pq1-localbus", "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
reg = <0xfff00100 0x40>;
ranges = <0 0 0xf0000000 0x01000000>; /* Filled in by u-boot */
flash@0,0 {
compatible = "cfi-flash";
reg = <0 0 0x1000000>;
#address-cells = <1>;
#size-cells = <1>;
bank-width = <1>;
device-width = <1>;
partition@0 {
label = "u-boot";
reg = <0 0x80000>;
};
partition@80000 {
label = "env";
reg = <0x80000 0x20000>;
};
partition@a0000 {
label = "kernel";
reg = <0xa0000 0x1e0000>;
};
partition@280000 {
label = "dtb";
reg = <0x280000 0x20000>;
};
partition@2a0000 {
label = "root";
reg = <0x2a0000 0x500000>;
};
partition@7a0000 {
label = "user";
reg = <0x7a0000 0x860000>;
};
};
};
soc@fff00000 {
compatible = "fsl,mpc852", "fsl,pq1-soc", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
device_type = "soc";
ranges = <0 0xfff00000 0x00004000>;
PIC: interrupt-controller@0 {
interrupt-controller;
#interrupt-cells = <2>;
reg = <0 24>;
compatible = "fsl,mpc852-pic", "fsl,pq1-pic";
};
cpm@9c0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc852-cpm", "fsl,cpm1", "simple-bus";
interrupts = <0>; /* cpm error interrupt */
interrupt-parent = <&CPM_PIC>;
reg = <0x9c0 10>;
ranges;
muram@2000 {
compatible = "fsl,cpm-muram";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x2000 0x2000>;
data@0 {
compatible = "fsl,cpm-muram-data";
reg = <0x800 0x1800>;
};
};
brg@9f0 {
compatible = "fsl,mpc852-brg",
"fsl,cpm1-brg",
"fsl,cpm-brg";
reg = <0x9f0 0x10>;
clock-frequency = <0>; /* Filled in by u-boot */
};
CPM_PIC: interrupt-controller@930 {
interrupt-controller;
#interrupt-cells = <1>;
interrupts = <5 2 0 2>;
interrupt-parent = <&PIC>;
reg = <0x930 0x20>;
compatible = "fsl,cpm1-pic";
};
/* MON-1 */
serial@a80 {
device_type = "serial";
compatible = "fsl,cpm1-smc-uart";
reg = <0xa80 0x10 0x3fc0 0x40>;
interrupts = <4>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-brg = <1>;
fsl,cpm-command = <0x0090>;
current-speed = <0>; /* Filled in by u-boot */
};
ethernet@a40 {
device_type = "network";
compatible = "fsl,mpc866-scc-enet",
"fsl,cpm1-scc-enet";
reg = <0xa40 0x18 0x3e00 0x100>;
local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by u-boot */
interrupts = <28>;
interrupt-parent = <&CPM_PIC>;
fsl,cpm-command = <0x80>;
fixed-link = <0 0 10 0 0>;
};
};
};
};

View File

@ -475,14 +475,14 @@
};
sata@18000 {
compatible = "fsl,mpc8536-sata", "fsl,pq-sata";
compatible = "fsl,p1022-sata", "fsl,pq-sata-v2";
reg = <0x18000 0x1000>;
cell-index = <1>;
interrupts = <74 0x2>;
};
sata@19000 {
compatible = "fsl,mpc8536-sata", "fsl,pq-sata";
compatible = "fsl,p1022-sata", "fsl,pq-sata-v2";
reg = <0x19000 0x1000>;
cell-index = <2>;
interrupts = <41 0x2>;

View File

@ -2,6 +2,7 @@ CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
CONFIG_SPARSE_IRQ=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_EXPERT=y
# CONFIG_HOTPLUG is not set
@ -18,7 +19,6 @@ CONFIG_KMETER1=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_SPARSE_IRQ=y
# CONFIG_SECCOMP is not set
CONFIG_NET=y
CONFIG_PACKET=y
@ -37,7 +37,6 @@ CONFIG_MTD=y
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
@ -49,13 +48,12 @@ CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_GLUEBI=y
CONFIG_MTD_UBI_DEBUG=y
CONFIG_PROC_DEVICETREE=y
# CONFIG_MISC_DEVICES is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
CONFIG_TUN=y
CONFIG_MII=y
CONFIG_MARVELL_PHY=y
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_UCC_GETH=y
# CONFIG_NETDEV_10000 is not set
CONFIG_WAN=y
@ -77,7 +75,6 @@ CONFIG_I2C_MPC=y
# CONFIG_USB_SUPPORT is not set
CONFIG_UIO=y
# CONFIG_DNOTIFY is not set
CONFIG_INOTIFY=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y

View File

@ -1,4 +1,5 @@
CONFIG_SYSVIPC=y
CONFIG_SPARSE_IRQ=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@ -10,7 +11,6 @@ CONFIG_SLAB=y
CONFIG_PPC_82xx=y
CONFIG_MGCOGE=y
CONFIG_BINFMT_MISC=y
CONFIG_SPARSE_IRQ=y
# CONFIG_SECCOMP is not set
CONFIG_NET=y
CONFIG_PACKET=y
@ -30,7 +30,6 @@ CONFIG_MTD=y
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_CFI=y
@ -43,7 +42,6 @@ CONFIG_MTD_PHYSMAP_OF=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
# CONFIG_MISC_DEVICES is not set
# CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y
CONFIG_FIXED_PHY=y
@ -67,7 +65,6 @@ CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_INOTIFY=y
CONFIG_AUTOFS4_FS=y
CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y
@ -88,13 +85,9 @@ CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_SCHED_DEBUG is not set
CONFIG_DEBUG_INFO=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_BDI_SWITCH=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set

View File

@ -1,81 +0,0 @@
CONFIG_PPC_8xx=y
CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EXPERT=y
# CONFIG_SYSCTL_SYSCALL is not set
# CONFIG_HOTPLUG is not set
# CONFIG_BUG is not set
# CONFIG_BASE_FULL is not set
# CONFIG_EPOLL is not set
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_SLAB=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PPC_MGSUVD=y
CONFIG_8xx_COPYBACK=y
CONFIG_8xx_CPU6=y
CONFIG_I2C_SPI_SMC1_UCODE_PATCH=y
CONFIG_HZ_1000=y
CONFIG_MATH_EMULATION=y
CONFIG_SPARSE_IRQ=y
# CONFIG_SECCOMP is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_SYN_COOKIES=y
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_PHYSMAP_OF=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
# CONFIG_MISC_DEVICES is not set
CONFIG_NETDEVICES=y
CONFIG_FIXED_PHY=y
CONFIG_NET_ETHERNET=y
CONFIG_FS_ENET=y
# CONFIG_FS_ENET_HAS_FEC is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
CONFIG_SERIAL_CPM=y
CONFIG_SERIAL_CPM_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_GEN_RTC=y
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_INOTIFY=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_CRAMFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_CRC_CCITT=y
CONFIG_DEBUG_FS=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_CRYPTO_ANSI_CPRNG is not set

View File

@ -154,6 +154,7 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000)
#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000)
#define CPU_FTR_NO_DPM ASM_CONST(0x0000000000008000)
#define CPU_FTR_476_DD2 ASM_CONST(0x0000000000010000)
#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000)
#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000)
#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000)
@ -465,7 +466,7 @@ enum {
CPU_FTRS_44X | CPU_FTRS_440x6 |
#endif
#ifdef CONFIG_PPC_47x
CPU_FTRS_47X |
CPU_FTRS_47X | CPU_FTR_476_DD2 |
#endif
#ifdef CONFIG_E200
CPU_FTRS_E200 |

View File

@ -141,6 +141,8 @@ static inline bool arch_irqs_disabled(void)
#endif /* CONFIG_PPC64 */
#define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST
/*
* interrupt-retrigger: should we handle this via lost interrupts and IPIs
* or should we not care like we do now ? --BenH.

View File

@ -467,11 +467,11 @@ extern void mpic_request_ipis(void);
void smp_mpic_message_pass(int target, int msg);
/* Unmask a specific virq */
extern void mpic_unmask_irq(unsigned int irq);
extern void mpic_unmask_irq(struct irq_data *d);
/* Mask a specific virq */
extern void mpic_mask_irq(unsigned int irq);
extern void mpic_mask_irq(struct irq_data *d);
/* EOI a specific virq */
extern void mpic_end_irq(unsigned int irq);
extern void mpic_end_irq(struct irq_data *d);
/* Fetch interrupt from a given mpic */
extern unsigned int mpic_get_one_irq(struct mpic *mpic);

View File

@ -51,7 +51,8 @@ static inline int mmio_nvram_init(void)
extern int __init nvram_scan_partitions(void);
extern loff_t nvram_create_partition(const char *name, int sig,
int req_size, int min_size);
extern int nvram_remove_partition(const char *name, int sig);
extern int nvram_remove_partition(const char *name, int sig,
const char *exceptions[]);
extern int nvram_get_partition_size(loff_t data_index);
extern loff_t nvram_find_partition(const char *name, int sig, int *out_size);

View File

@ -170,6 +170,7 @@ extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addre
#define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
_PAGE_COHERENT | _PAGE_WRITETHRU))
#define pgprot_writecombine pgprot_noncached_wc
struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,

View File

@ -81,7 +81,7 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
static inline void qe_ic_cascade_low_ipic(unsigned int irq,
struct irq_desc *desc)
{
struct qe_ic *qe_ic = desc->handler_data;
struct qe_ic *qe_ic = get_irq_desc_data(desc);
unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
if (cascade_irq != NO_IRQ)
@ -91,7 +91,7 @@ static inline void qe_ic_cascade_low_ipic(unsigned int irq,
static inline void qe_ic_cascade_high_ipic(unsigned int irq,
struct irq_desc *desc)
{
struct qe_ic *qe_ic = desc->handler_data;
struct qe_ic *qe_ic = get_irq_desc_data(desc);
unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq != NO_IRQ)
@ -101,32 +101,35 @@ static inline void qe_ic_cascade_high_ipic(unsigned int irq,
static inline void qe_ic_cascade_low_mpic(unsigned int irq,
struct irq_desc *desc)
{
struct qe_ic *qe_ic = desc->handler_data;
struct qe_ic *qe_ic = get_irq_desc_data(desc);
unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
struct irq_chip *chip = get_irq_desc_chip(desc);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static inline void qe_ic_cascade_high_mpic(unsigned int irq,
struct irq_desc *desc)
{
struct qe_ic *qe_ic = desc->handler_data;
struct qe_ic *qe_ic = get_irq_desc_data(desc);
unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
struct irq_chip *chip = get_irq_desc_chip(desc);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
struct irq_desc *desc)
{
struct qe_ic *qe_ic = desc->handler_data;
struct qe_ic *qe_ic = get_irq_desc_data(desc);
unsigned int cascade_irq;
struct irq_chip *chip = get_irq_desc_chip(desc);
cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq == NO_IRQ)
@ -135,7 +138,7 @@ static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
#endif /* _ASM_POWERPC_QE_IC_H */

View File

@ -170,6 +170,16 @@
#define SPEFSCR_FRMC 0x00000003 /* Embedded FP rounding mode control */
/* Special Purpose Registers (SPRNs)*/
#ifdef CONFIG_40x
#define SPRN_PID 0x3B1 /* Process ID */
#else
#define SPRN_PID 0x030 /* Process ID */
#ifdef CONFIG_BOOKE
#define SPRN_PID0 SPRN_PID/* Process ID Register 0 */
#endif
#endif
#define SPRN_CTR 0x009 /* Count Register */
#define SPRN_DSCR 0x11
#define SPRN_CTRLF 0x088
@ -852,6 +862,8 @@
#define PVR_7450 0x80000000
#define PVR_8540 0x80200000
#define PVR_8560 0x80200000
#define PVR_VER_E500V1 0x8020
#define PVR_VER_E500V2 0x8021
/*
* For the 8xx processors, all of them report the same PVR family for
* the PowerPC core. The various versions of these processors must be

View File

@ -150,8 +150,6 @@
* or IBM 40x.
*/
#ifdef CONFIG_BOOKE
#define SPRN_PID 0x030 /* Process ID */
#define SPRN_PID0 SPRN_PID/* Process ID Register 0 */
#define SPRN_CSRR0 0x03A /* Critical Save and Restore Register 0 */
#define SPRN_CSRR1 0x03B /* Critical Save and Restore Register 1 */
#define SPRN_DEAR 0x03D /* Data Error Address Register */
@ -168,7 +166,6 @@
#define SPRN_TCR 0x154 /* Timer Control Register */
#endif /* Book E */
#ifdef CONFIG_40x
#define SPRN_PID 0x3B1 /* Process ID */
#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */
#define SPRN_ESR 0x3D4 /* Exception Syndrome Register */
#define SPRN_DEAR 0x3D5 /* Data Error Address Register */

View File

@ -1811,11 +1811,11 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_440A,
.platform = "ppc440",
},
{ /* 476 core */
.pvr_mask = 0xffff0000,
.pvr_value = 0x11a50000,
{ /* 476 DD2 core */
.pvr_mask = 0xffffffff,
.pvr_value = 0x11a52080,
.cpu_name = "476",
.cpu_features = CPU_FTRS_47X,
.cpu_features = CPU_FTRS_47X | CPU_FTR_476_DD2,
.cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_47x |
@ -1839,6 +1839,20 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_47x,
.platform = "ppc470",
},
{ /* 476 others */
.pvr_mask = 0xffff0000,
.pvr_value = 0x11a50000,
.cpu_name = "476",
.cpu_features = CPU_FTRS_47X,
.cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_47x |
MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
.icache_bsize = 32,
.dcache_bsize = 128,
.machine_check = machine_check_47x,
.platform = "ppc470",
},
{ /* default match */
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,

View File

@ -237,6 +237,7 @@ int show_interrupts(struct seq_file *p, void *v)
int i = *(loff_t *) v, j, prec;
struct irqaction *action;
struct irq_desc *desc;
struct irq_chip *chip;
if (i > nr_irqs)
return 0;
@ -270,8 +271,9 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
if (desc->chip)
seq_printf(p, " %-16s", desc->chip->name);
chip = get_irq_desc_chip(desc);
if (chip)
seq_printf(p, " %-16s", chip->name);
else
seq_printf(p, " %-16s", "None");
seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge");
@ -313,6 +315,8 @@ void fixup_irqs(const struct cpumask *map)
alloc_cpumask_var(&mask, GFP_KERNEL);
for_each_irq(irq) {
struct irq_chip *chip;
desc = irq_to_desc(irq);
if (!desc)
continue;
@ -320,13 +324,15 @@ void fixup_irqs(const struct cpumask *map)
if (desc->status & IRQ_PER_CPU)
continue;
cpumask_and(mask, desc->affinity, map);
chip = get_irq_desc_chip(desc);
cpumask_and(mask, desc->irq_data.affinity, map);
if (cpumask_any(mask) >= nr_cpu_ids) {
printk("Breaking affinity for irq %i\n", irq);
cpumask_copy(mask, map);
}
if (desc->chip->set_affinity)
desc->chip->set_affinity(irq, mask);
if (chip->irq_set_affinity)
chip->irq_set_affinity(&desc->irq_data, mask, true);
else if (desc->action && !(warned++))
printk("Cannot set affinity for irq %i\n", irq);
}
@ -678,16 +684,15 @@ void irq_set_virq_count(unsigned int count)
static int irq_setup_virq(struct irq_host *host, unsigned int virq,
irq_hw_number_t hwirq)
{
struct irq_desc *desc;
int res;
desc = irq_to_desc_alloc_node(virq, 0);
if (!desc) {
res = irq_alloc_desc_at(virq, 0);
if (res != virq) {
pr_debug("irq: -> allocating desc failed\n");
goto error;
}
/* Clear IRQ_NOREQUEST flag */
desc->status &= ~IRQ_NOREQUEST;
irq_clear_status_flags(virq, IRQ_NOREQUEST);
/* map it */
smp_wmb();
@ -696,11 +701,13 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
if (host->ops->map(host, virq, hwirq)) {
pr_debug("irq: -> mapping failed, freeing\n");
goto error;
goto errdesc;
}
return 0;
errdesc:
irq_free_descs(virq, 1);
error:
irq_free_virt(virq, 1);
return -1;
@ -879,9 +886,9 @@ void irq_dispose_mapping(unsigned int virq)
smp_mb();
irq_map[virq].hwirq = host->inval_irq;
/* Set some flags */
irq_to_desc(virq)->status |= IRQ_NOREQUEST;
irq_set_status_flags(virq, IRQ_NOREQUEST);
irq_free_descs(virq, 1);
/* Free it */
irq_free_virt(virq, 1);
}
@ -1074,21 +1081,6 @@ void irq_free_virt(unsigned int virq, unsigned int count)
int arch_early_irq_init(void)
{
struct irq_desc *desc;
int i;
for (i = 0; i < NR_IRQS; i++) {
desc = irq_to_desc(i);
if (desc)
desc->status |= IRQ_NOREQUEST;
}
return 0;
}
int arch_init_chip_data(struct irq_desc *desc, int node)
{
desc->status |= IRQ_NOREQUEST;
return 0;
}
@ -1159,11 +1151,14 @@ static int virq_debug_show(struct seq_file *m, void *private)
raw_spin_lock_irqsave(&desc->lock, flags);
if (desc->action && desc->action->handler) {
struct irq_chip *chip;
seq_printf(m, "%5d ", i);
seq_printf(m, "0x%05lx ", virq_to_hw(i));
if (desc->chip && desc->chip->name)
p = desc->chip->name;
chip = get_irq_desc_chip(desc);
if (chip && chip->name)
p = chip->name;
else
p = none;
seq_printf(m, "%-15s ", p);

View File

@ -26,20 +26,23 @@ void machine_kexec_mask_interrupts(void) {
for_each_irq(i) {
struct irq_desc *desc = irq_to_desc(i);
struct irq_chip *chip;
if (!desc || !desc->chip)
if (!desc)
continue;
if (desc->chip->eoi &&
desc->status & IRQ_INPROGRESS)
desc->chip->eoi(i);
chip = get_irq_desc_chip(desc);
if (!chip)
continue;
if (desc->chip->mask)
desc->chip->mask(i);
if (chip->irq_eoi && desc->status & IRQ_INPROGRESS)
chip->irq_eoi(&desc->irq_data);
if (desc->chip->disable &&
!(desc->status & IRQ_DISABLED))
desc->chip->disable(i);
if (chip->irq_mask)
chip->irq_mask(&desc->irq_data);
if (chip->irq_disable && !(desc->status & IRQ_DISABLED))
chip->irq_disable(&desc->irq_data);
}
}

View File

@ -237,22 +237,45 @@ static unsigned char __init nvram_checksum(struct nvram_header *p)
return c_sum;
}
/*
* Per the criteria passed via nvram_remove_partition(), should this
* partition be removed? 1=remove, 0=keep
*/
static int nvram_can_remove_partition(struct nvram_partition *part,
const char *name, int sig, const char *exceptions[])
{
if (part->header.signature != sig)
return 0;
if (name) {
if (strncmp(name, part->header.name, 12))
return 0;
} else if (exceptions) {
const char **except;
for (except = exceptions; *except; except++) {
if (!strncmp(*except, part->header.name, 12))
return 0;
}
}
return 1;
}
/**
* nvram_remove_partition - Remove one or more partitions in nvram
* @name: name of the partition to remove, or NULL for a
* signature only match
* @sig: signature of the partition(s) to remove
* @exceptions: When removing all partitions with a matching signature,
* leave these alone.
*/
int __init nvram_remove_partition(const char *name, int sig)
int __init nvram_remove_partition(const char *name, int sig,
const char *exceptions[])
{
struct nvram_partition *part, *prev, *tmp;
int rc;
list_for_each_entry(part, &nvram_partitions, partition) {
if (part->header.signature != sig)
continue;
if (name && strncmp(name, part->header.name, 12))
if (!nvram_can_remove_partition(part, name, sig, exceptions))
continue;
/* Make partition a free partition */

View File

@ -97,7 +97,7 @@ static void __init move_device_tree(void)
start = __pa(initial_boot_params);
size = be32_to_cpu(initial_boot_params->totalsize);
if ((memory_limit && (start + size) > memory_limit) ||
if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) ||
overlaps_crashkernel(start, size)) {
p = __va(memblock_alloc(size, PAGE_SIZE));
memcpy(p, initial_boot_params, size);

View File

@ -412,7 +412,8 @@ static void rtas_event_scan(struct work_struct *w)
get_online_cpus();
cpu = cpumask_next(smp_processor_id(), cpu_online_mask);
/* raw_ OK because just using CPU as starting point. */
cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
if (cpu >= nr_cpu_ids) {
cpu = cpumask_first(cpu_online_mask);

View File

@ -1,7 +1,7 @@
/*
* arch/powerpc/math-emu/math_efp.c
*
* Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
* Copyright (C) 2006-2008, 2010 Freescale Semiconductor, Inc.
*
* Author: Ebony Zhu, <ebony.zhu@freescale.com>
* Yu Liu, <yu.liu@freescale.com>
@ -104,6 +104,8 @@
#define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID | FP_EX_DIVZERO | \
FP_EX_UNDERFLOW | FP_EX_OVERFLOW)
static int have_e500_cpu_a005_erratum;
union dw_union {
u64 dp[1];
u32 wp[2];
@ -320,7 +322,8 @@ int do_spe_mathemu(struct pt_regs *regs)
} else {
_FP_ROUND_ZERO(1, SB);
}
FP_TO_INT_S(vc.wp[1], SB, 32, ((func & 0x3) != 0));
FP_TO_INT_S(vc.wp[1], SB, 32,
(((func & 0x3) != 0) || SB_s));
goto update_regs;
default:
@ -458,7 +461,8 @@ cmp_s:
} else {
_FP_ROUND_ZERO(2, DB);
}
FP_TO_INT_D(vc.wp[1], DB, 32, ((func & 0x3) != 0));
FP_TO_INT_D(vc.wp[1], DB, 32,
(((func & 0x3) != 0) || DB_s));
goto update_regs;
default:
@ -589,8 +593,10 @@ cmp_d:
_FP_ROUND_ZERO(1, SB0);
_FP_ROUND_ZERO(1, SB1);
}
FP_TO_INT_S(vc.wp[0], SB0, 32, ((func & 0x3) != 0));
FP_TO_INT_S(vc.wp[1], SB1, 32, ((func & 0x3) != 0));
FP_TO_INT_S(vc.wp[0], SB0, 32,
(((func & 0x3) != 0) || SB0_s));
FP_TO_INT_S(vc.wp[1], SB1, 32,
(((func & 0x3) != 0) || SB1_s));
goto update_regs;
default:
@ -652,6 +658,15 @@ update_regs:
return 0;
illegal:
if (have_e500_cpu_a005_erratum) {
/* according to e500 cpu a005 erratum, reissue efp inst */
regs->nip -= 4;
#ifdef DEBUG
printk(KERN_DEBUG "re-issue efp inst: %08lx\n", speinsn);
#endif
return 0;
}
printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered un-supported instruction.\ninst code: %08lx\n", speinsn);
return -ENOSYS;
}
@ -718,3 +733,43 @@ int speround_handler(struct pt_regs *regs)
return 0;
}
int __init spe_mathemu_init(void)
{
u32 pvr, maj, min;
pvr = mfspr(SPRN_PVR);
if ((PVR_VER(pvr) == PVR_VER_E500V1) ||
(PVR_VER(pvr) == PVR_VER_E500V2)) {
maj = PVR_MAJ(pvr);
min = PVR_MIN(pvr);
/*
* E500 revision below 1.1, 2.3, 3.1, 4.1, 5.1
* need cpu a005 errata workaround
*/
switch (maj) {
case 1:
if (min < 1)
have_e500_cpu_a005_erratum = 1;
break;
case 2:
if (min < 3)
have_e500_cpu_a005_erratum = 1;
break;
case 3:
case 4:
case 5:
if (min < 1)
have_e500_cpu_a005_erratum = 1;
break;
default:
break;
}
}
return 0;
}
module_init(spe_mathemu_init);

View File

@ -148,7 +148,7 @@ void __init MMU_init(void)
lowmem_end_addr = memstart_addr + total_lowmem;
#ifndef CONFIG_HIGHMEM
total_memory = total_lowmem;
memblock_enforce_memory_limit(lowmem_end_addr);
memblock_enforce_memory_limit(total_lowmem);
memblock_analyze();
#endif /* CONFIG_HIGHMEM */
}

View File

@ -189,6 +189,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
blr
#ifdef CONFIG_PPC_47x
/*
* 47x variant of icbt
*/
# define ICBT(CT,RA,RB) \
.long 0x7c00002c | ((CT) << 21) | ((RA) << 16) | ((RB) << 11)
/*
* _tlbivax_bcast is only on 47x. We don't bother doing a runtime
* check though, it will blow up soon enough if we mistakenly try
@ -206,9 +213,37 @@ _GLOBAL(_tlbivax_bcast)
isync
eieio
tlbsync
BEGIN_FTR_SECTION
b 1f
END_FTR_SECTION_IFSET(CPU_FTR_476_DD2)
sync
wrtee r10
blr
/*
* DD2 HW could hang if in instruction fetch happens before msync completes.
* Touch enough instruction cache lines to ensure cache hits
*/
1: mflr r9
bl 2f
2: mflr r6
li r7,32
ICBT(0,r6,r7) /* touch next cache line */
add r6,r6,r7
ICBT(0,r6,r7) /* touch next cache line */
add r6,r6,r7
ICBT(0,r6,r7) /* touch next cache line */
sync
nop
nop
nop
nop
nop
nop
nop
nop
mtlr r9
wrtee r10
blr
#endif /* CONFIG_PPC_47x */
#elif defined(CONFIG_FSL_BOOKE)

View File

@ -4,4 +4,8 @@
extern u8 as1_readb(volatile u8 __iomem *addr);
extern void as1_writeb(u8 data, volatile u8 __iomem *addr);
#define GPIO0_OSRH 0xC
#define GPIO0_TSRH 0x14
#define GPIO0_ISR1H 0x34
#endif /* __POWERPC_PLATFORMS_44X_44X_H */

View File

@ -115,7 +115,6 @@ config CANYONLANDS
bool "Canyonlands"
depends on 44x
default n
select PPC44x_SIMPLE
select 460EX
select PCI
select PPC4xx_PCI_EXPRESS

View File

@ -9,3 +9,4 @@ obj-$(CONFIG_WARP) += warp.o
obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
obj-$(CONFIG_ISS4xx) += iss4xx.o
obj-$(CONFIG_CANYONLANDS)+= canyonlands.o

View File

@ -0,0 +1,134 @@
/*
* This contain platform specific code for APM PPC460EX based Canyonlands
* board.
*
* Copyright (c) 2010, Applied Micro Circuits Corporation
* Author: Rupjyoti Sarmah <rsarmah@apm.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/pci-bridge.h>
#include <asm/ppc4xx.h>
#include <asm/udbg.h>
#include <asm/uic.h>
#include <linux/of_platform.h>
#include <linux/delay.h>
#include "44x.h"
#define BCSR_USB_EN 0x11
static __initdata struct of_device_id ppc460ex_of_bus[] = {
{ .compatible = "ibm,plb4", },
{ .compatible = "ibm,opb", },
{ .compatible = "ibm,ebc", },
{ .compatible = "simple-bus", },
{},
};
static int __init ppc460ex_device_probe(void)
{
of_platform_bus_probe(NULL, ppc460ex_of_bus, NULL);
return 0;
}
machine_device_initcall(canyonlands, ppc460ex_device_probe);
/* Using this code only for the Canyonlands board. */
static int __init ppc460ex_probe(void)
{
unsigned long root = of_get_flat_dt_root();
if (of_flat_dt_is_compatible(root, "amcc,canyonlands")) {
ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
return 1;
}
return 0;
}
/* USB PHY fixup code on Canyonlands kit. */
static int __init ppc460ex_canyonlands_fixup(void)
{
u8 __iomem *bcsr ;
void __iomem *vaddr;
struct device_node *np;
int ret = 0;
np = of_find_compatible_node(NULL, NULL, "amcc,ppc460ex-bcsr");
if (!np) {
printk(KERN_ERR "failed did not find amcc, ppc460ex bcsr node\n");
return -ENODEV;
}
bcsr = of_iomap(np, 0);
of_node_put(np);
if (!bcsr) {
printk(KERN_CRIT "Could not remap bcsr\n");
ret = -ENODEV;
goto err_bcsr;
}
np = of_find_compatible_node(NULL, NULL, "ibm,ppc4xx-gpio");
if (!np) {
printk(KERN_ERR "failed did not find ibm,ppc4xx-gpio node\n");
return -ENODEV;
}
vaddr = of_iomap(np, 0);
of_node_put(np);
if (!vaddr) {
printk(KERN_CRIT "Could not get gpio node address\n");
ret = -ENODEV;
goto err_gpio;
}
/* Disable USB, through the BCSR7 bits */
setbits8(&bcsr[7], BCSR_USB_EN);
/* Wait for a while after reset */
msleep(100);
/* Enable USB here */
clrbits8(&bcsr[7], BCSR_USB_EN);
/*
* Configure multiplexed gpio16 and gpio19 as alternate1 output
* source after USB reset. In this configuration gpio16 will be
* USB2HStop and gpio19 will be USB2DStop. For more details refer to
* table 34-7 of PPC460EX user manual.
*/
setbits32((vaddr + GPIO0_OSRH), 0x42000000);
setbits32((vaddr + GPIO0_TSRH), 0x42000000);
err_gpio:
iounmap(vaddr);
err_bcsr:
iounmap(bcsr);
return ret;
}
machine_device_initcall(canyonlands, ppc460ex_canyonlands_fixup);
define_machine(canyonlands) {
.name = "Canyonlands",
.probe = ppc460ex_probe,
.progress = udbg_progress,
.init_IRQ = uic_init_tree,
.get_irq = uic_get_irq,
.restart = ppc4xx_reset_system,
.calibrate_decr = generic_calibrate_decr,
};

View File

@ -53,7 +53,6 @@ static char *board[] __initdata = {
"amcc,arches",
"amcc,bamboo",
"amcc,bluestone",
"amcc,canyonlands",
"amcc,glacier",
"ibm,ebony",
"amcc,eiger",

View File

@ -59,9 +59,9 @@ irq_to_pic_bit(unsigned int irq)
}
static void
cpld_mask_irq(unsigned int irq)
cpld_mask_irq(struct irq_data *d)
{
unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
unsigned int cpld_irq = (unsigned int)irq_map[d->irq].hwirq;
void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
out_8(pic_mask,
@ -69,9 +69,9 @@ cpld_mask_irq(unsigned int irq)
}
static void
cpld_unmask_irq(unsigned int irq)
cpld_unmask_irq(struct irq_data *d)
{
unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
unsigned int cpld_irq = (unsigned int)irq_map[d->irq].hwirq;
void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
out_8(pic_mask,
@ -80,9 +80,9 @@ cpld_unmask_irq(unsigned int irq)
static struct irq_chip cpld_pic = {
.name = "CPLD PIC",
.mask = cpld_mask_irq,
.ack = cpld_mask_irq,
.unmask = cpld_unmask_irq,
.irq_mask = cpld_mask_irq,
.irq_ack = cpld_mask_irq,
.irq_unmask = cpld_unmask_irq,
};
static int

View File

@ -49,45 +49,46 @@ struct media5200_irq {
};
struct media5200_irq media5200_irq;
static void media5200_irq_unmask(unsigned int virq)
static void media5200_irq_unmask(struct irq_data *d)
{
unsigned long flags;
u32 val;
spin_lock_irqsave(&media5200_irq.lock, flags);
val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq);
val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[d->irq].hwirq);
out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
spin_unlock_irqrestore(&media5200_irq.lock, flags);
}
static void media5200_irq_mask(unsigned int virq)
static void media5200_irq_mask(struct irq_data *d)
{
unsigned long flags;
u32 val;
spin_lock_irqsave(&media5200_irq.lock, flags);
val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq));
val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[d->irq].hwirq));
out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
spin_unlock_irqrestore(&media5200_irq.lock, flags);
}
static struct irq_chip media5200_irq_chip = {
.name = "Media5200 FPGA",
.unmask = media5200_irq_unmask,
.mask = media5200_irq_mask,
.mask_ack = media5200_irq_mask,
.irq_unmask = media5200_irq_unmask,
.irq_mask = media5200_irq_mask,
.irq_mask_ack = media5200_irq_mask,
};
void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
int sub_virq, val;
u32 status, enable;
/* Mask off the cascaded IRQ */
raw_spin_lock(&desc->lock);
desc->chip->mask(virq);
chip->irq_mask(&desc->irq_data);
raw_spin_unlock(&desc->lock);
/* Ask the FPGA for IRQ status. If 'val' is 0, then no irqs
@ -105,9 +106,9 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
/* Processing done; can reenable the cascade now */
raw_spin_lock(&desc->lock);
desc->chip->ack(virq);
chip->irq_ack(&desc->irq_data);
if (!(desc->status & IRQ_DISABLED))
desc->chip->unmask(virq);
chip->irq_unmask(&desc->irq_data);
raw_spin_unlock(&desc->lock);
}

View File

@ -135,9 +135,9 @@ DEFINE_MUTEX(mpc52xx_gpt_list_mutex);
* Cascaded interrupt controller hooks
*/
static void mpc52xx_gpt_irq_unmask(unsigned int virq)
static void mpc52xx_gpt_irq_unmask(struct irq_data *d)
{
struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
unsigned long flags;
spin_lock_irqsave(&gpt->lock, flags);
@ -145,9 +145,9 @@ static void mpc52xx_gpt_irq_unmask(unsigned int virq)
spin_unlock_irqrestore(&gpt->lock, flags);
}
static void mpc52xx_gpt_irq_mask(unsigned int virq)
static void mpc52xx_gpt_irq_mask(struct irq_data *d)
{
struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
unsigned long flags;
spin_lock_irqsave(&gpt->lock, flags);
@ -155,20 +155,20 @@ static void mpc52xx_gpt_irq_mask(unsigned int virq)
spin_unlock_irqrestore(&gpt->lock, flags);
}
static void mpc52xx_gpt_irq_ack(unsigned int virq)
static void mpc52xx_gpt_irq_ack(struct irq_data *d)
{
struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
}
static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
static int mpc52xx_gpt_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
struct mpc52xx_gpt_priv *gpt = irq_data_get_irq_chip_data(d);
unsigned long flags;
u32 reg;
dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, virq, flow_type);
dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, d->irq, flow_type);
spin_lock_irqsave(&gpt->lock, flags);
reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
@ -184,10 +184,10 @@ static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
static struct irq_chip mpc52xx_gpt_irq_chip = {
.name = "MPC52xx GPT",
.unmask = mpc52xx_gpt_irq_unmask,
.mask = mpc52xx_gpt_irq_mask,
.ack = mpc52xx_gpt_irq_ack,
.set_type = mpc52xx_gpt_irq_set_type,
.irq_unmask = mpc52xx_gpt_irq_unmask,
.irq_mask = mpc52xx_gpt_irq_mask,
.irq_ack = mpc52xx_gpt_irq_ack,
.irq_set_type = mpc52xx_gpt_irq_set_type,
};
void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)

View File

@ -155,47 +155,47 @@ static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
/*
* IRQ[0-3] interrupt irq_chip
*/
static void mpc52xx_extirq_mask(unsigned int virq)
static void mpc52xx_extirq_mask(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_clrbit(&intr->ctrl, 11 - l2irq);
}
static void mpc52xx_extirq_unmask(unsigned int virq)
static void mpc52xx_extirq_unmask(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&intr->ctrl, 11 - l2irq);
}
static void mpc52xx_extirq_ack(unsigned int virq)
static void mpc52xx_extirq_ack(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&intr->ctrl, 27-l2irq);
}
static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
static int mpc52xx_extirq_set_type(struct irq_data *d, unsigned int flow_type)
{
u32 ctrl_reg, type;
int irq;
int l2irq;
void *handler = handle_level_irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type);
@ -214,44 +214,44 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
ctrl_reg |= (type << (22 - (l2irq * 2)));
out_be32(&intr->ctrl, ctrl_reg);
__set_irq_handler_unlocked(virq, handler);
__set_irq_handler_unlocked(d->irq, handler);
return 0;
}
static struct irq_chip mpc52xx_extirq_irqchip = {
.name = "MPC52xx External",
.mask = mpc52xx_extirq_mask,
.unmask = mpc52xx_extirq_unmask,
.ack = mpc52xx_extirq_ack,
.set_type = mpc52xx_extirq_set_type,
.irq_mask = mpc52xx_extirq_mask,
.irq_unmask = mpc52xx_extirq_unmask,
.irq_ack = mpc52xx_extirq_ack,
.irq_set_type = mpc52xx_extirq_set_type,
};
/*
* Main interrupt irq_chip
*/
static int mpc52xx_null_set_type(unsigned int virq, unsigned int flow_type)
static int mpc52xx_null_set_type(struct irq_data *d, unsigned int flow_type)
{
return 0; /* Do nothing so that the sense mask will get updated */
}
static void mpc52xx_main_mask(unsigned int virq)
static void mpc52xx_main_mask(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&intr->main_mask, 16 - l2irq);
}
static void mpc52xx_main_unmask(unsigned int virq)
static void mpc52xx_main_unmask(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_clrbit(&intr->main_mask, 16 - l2irq);
@ -259,32 +259,32 @@ static void mpc52xx_main_unmask(unsigned int virq)
static struct irq_chip mpc52xx_main_irqchip = {
.name = "MPC52xx Main",
.mask = mpc52xx_main_mask,
.mask_ack = mpc52xx_main_mask,
.unmask = mpc52xx_main_unmask,
.set_type = mpc52xx_null_set_type,
.irq_mask = mpc52xx_main_mask,
.irq_mask_ack = mpc52xx_main_mask,
.irq_unmask = mpc52xx_main_unmask,
.irq_set_type = mpc52xx_null_set_type,
};
/*
* Peripherals interrupt irq_chip
*/
static void mpc52xx_periph_mask(unsigned int virq)
static void mpc52xx_periph_mask(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&intr->per_mask, 31 - l2irq);
}
static void mpc52xx_periph_unmask(unsigned int virq)
static void mpc52xx_periph_unmask(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_clrbit(&intr->per_mask, 31 - l2irq);
@ -292,43 +292,43 @@ static void mpc52xx_periph_unmask(unsigned int virq)
static struct irq_chip mpc52xx_periph_irqchip = {
.name = "MPC52xx Peripherals",
.mask = mpc52xx_periph_mask,
.mask_ack = mpc52xx_periph_mask,
.unmask = mpc52xx_periph_unmask,
.set_type = mpc52xx_null_set_type,
.irq_mask = mpc52xx_periph_mask,
.irq_mask_ack = mpc52xx_periph_mask,
.irq_unmask = mpc52xx_periph_unmask,
.irq_set_type = mpc52xx_null_set_type,
};
/*
* SDMA interrupt irq_chip
*/
static void mpc52xx_sdma_mask(unsigned int virq)
static void mpc52xx_sdma_mask(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&sdma->IntMask, l2irq);
}
static void mpc52xx_sdma_unmask(unsigned int virq)
static void mpc52xx_sdma_unmask(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_clrbit(&sdma->IntMask, l2irq);
}
static void mpc52xx_sdma_ack(unsigned int virq)
static void mpc52xx_sdma_ack(struct irq_data *d)
{
int irq;
int l2irq;
irq = irq_map[virq].hwirq;
irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
out_be32(&sdma->IntPend, 1 << l2irq);
@ -336,10 +336,10 @@ static void mpc52xx_sdma_ack(unsigned int virq)
static struct irq_chip mpc52xx_sdma_irqchip = {
.name = "MPC52xx SDMA",
.mask = mpc52xx_sdma_mask,
.unmask = mpc52xx_sdma_unmask,
.ack = mpc52xx_sdma_ack,
.set_type = mpc52xx_null_set_type,
.irq_mask = mpc52xx_sdma_mask,
.irq_unmask = mpc52xx_sdma_unmask,
.irq_ack = mpc52xx_sdma_ack,
.irq_set_type = mpc52xx_null_set_type,
};
/**

View File

@ -6,4 +6,4 @@ obj-$(CONFIG_CPM2) += pq2.o
obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o
obj-$(CONFIG_PQ2FADS) += pq2fads.o
obj-$(CONFIG_EP8248E) += ep8248e.o
obj-$(CONFIG_MGCOGE) += mgcoge.o
obj-$(CONFIG_MGCOGE) += km82xx.o

View File

@ -1,6 +1,6 @@
/*
* Keymile mgcoge support
* Copyright 2008 DENX Software Engineering GmbH
* Keymile km82xx support
* Copyright 2008-2011 DENX Software Engineering GmbH
* Author: Heiko Schocher <hs@denx.de>
*
* based on code from:
@ -31,9 +31,10 @@
#include "pq2.h"
static void __init mgcoge_pic_init(void)
static void __init km82xx_pic_init(void)
{
struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,pq2-pic");
struct device_node *np = of_find_compatible_node(NULL, NULL,
"fsl,pq2-pic");
if (!np) {
printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
return;
@ -47,12 +48,18 @@ struct cpm_pin {
int port, pin, flags;
};
static __initdata struct cpm_pin mgcoge_pins[] = {
static __initdata struct cpm_pin km82xx_pins[] = {
/* SMC2 */
{0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{0, 9, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
/* SCC1 */
{2, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{2, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
/* SCC4 */
{2, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{2, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
@ -107,30 +114,49 @@ static __initdata struct cpm_pin mgcoge_pins[] = {
{3, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
{3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
#endif
/* USB */
{0, 10, CPM_PIN_OUTPUT | CPM_PIN_GPIO}, /* FULL_SPEED */
{0, 11, CPM_PIN_OUTPUT | CPM_PIN_GPIO}, /*/SLAVE */
{2, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* RXN */
{2, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* RXP */
{2, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* /OE */
{2, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* RXCLK */
{3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* TXP */
{3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* TXN */
{3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* RXD */
};
static void __init init_ioports(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(mgcoge_pins); i++) {
const struct cpm_pin *pin = &mgcoge_pins[i];
for (i = 0; i < ARRAY_SIZE(km82xx_pins); i++) {
const struct cpm_pin *pin = &km82xx_pins[i];
cpm2_set_pin(pin->port, pin->pin, pin->flags);
}
cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8);
cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_SCC1, CPM_CLK11, CPM_CLK_TX);
cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RTX);
cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK7, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK8, CPM_CLK_TX);
cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK9, CPM_CLK_TX);
cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
/* Force USB FULL SPEED bit to '1' */
setbits32(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 10));
/* clear USB_SLAVE */
clrbits32(&cpm2_immr->im_ioport.iop_pdata, 1 << (31 - 11));
}
static void __init mgcoge_setup_arch(void)
static void __init km82xx_setup_arch(void)
{
if (ppc_md.progress)
ppc_md.progress("mgcoge_setup_arch()", 0);
ppc_md.progress("km82xx_setup_arch()", 0);
cpm2_reset();
@ -142,7 +168,7 @@ static void __init mgcoge_setup_arch(void)
init_ioports();
if (ppc_md.progress)
ppc_md.progress("mgcoge_setup_arch(), finish", 0);
ppc_md.progress("km82xx_setup_arch(), finish", 0);
}
static __initdata struct of_device_id of_bus_ids[] = {
@ -156,23 +182,23 @@ static int __init declare_of_platform_devices(void)
return 0;
}
machine_device_initcall(mgcoge, declare_of_platform_devices);
machine_device_initcall(km82xx, declare_of_platform_devices);
/*
* Called very early, device-tree isn't unflattened
*/
static int __init mgcoge_probe(void)
static int __init km82xx_probe(void)
{
unsigned long root = of_get_flat_dt_root();
return of_flat_dt_is_compatible(root, "keymile,mgcoge");
return of_flat_dt_is_compatible(root, "keymile,km82xx");
}
define_machine(mgcoge)
define_machine(km82xx)
{
.name = "Keymile MGCOGE",
.probe = mgcoge_probe,
.setup_arch = mgcoge_setup_arch,
.init_IRQ = mgcoge_pic_init,
.name = "Keymile km82xx",
.probe = km82xx_probe,
.setup_arch = km82xx_setup_arch,
.init_IRQ = km82xx_pic_init,
.get_irq = cpm2_get_irq,
.calibrate_decr = generic_calibrate_decr,
.restart = pq2_restart,

View File

@ -39,10 +39,10 @@ struct pq2ads_pci_pic {
#define NUM_IRQS 32
static void pq2ads_pci_mask_irq(unsigned int virq)
static void pq2ads_pci_mask_irq(struct irq_data *d)
{
struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
int irq = NUM_IRQS - virq_to_hw(virq) - 1;
struct pq2ads_pci_pic *priv = irq_data_get_irq_chip_data(d);
int irq = NUM_IRQS - virq_to_hw(d->irq) - 1;
if (irq != -1) {
unsigned long flags;
@ -55,10 +55,10 @@ static void pq2ads_pci_mask_irq(unsigned int virq)
}
}
static void pq2ads_pci_unmask_irq(unsigned int virq)
static void pq2ads_pci_unmask_irq(struct irq_data *d)
{
struct pq2ads_pci_pic *priv = get_irq_chip_data(virq);
int irq = NUM_IRQS - virq_to_hw(virq) - 1;
struct pq2ads_pci_pic *priv = irq_data_get_irq_chip_data(d);
int irq = NUM_IRQS - virq_to_hw(d->irq) - 1;
if (irq != -1) {
unsigned long flags;
@ -71,18 +71,17 @@ static void pq2ads_pci_unmask_irq(unsigned int virq)
static struct irq_chip pq2ads_pci_ic = {
.name = "PQ2 ADS PCI",
.end = pq2ads_pci_unmask_irq,
.mask = pq2ads_pci_mask_irq,
.mask_ack = pq2ads_pci_mask_irq,
.ack = pq2ads_pci_mask_irq,
.unmask = pq2ads_pci_unmask_irq,
.enable = pq2ads_pci_unmask_irq,
.disable = pq2ads_pci_mask_irq
.irq_mask = pq2ads_pci_mask_irq,
.irq_mask_ack = pq2ads_pci_mask_irq,
.irq_ack = pq2ads_pci_mask_irq,
.irq_unmask = pq2ads_pci_unmask_irq,
.irq_enable = pq2ads_pci_unmask_irq,
.irq_disable = pq2ads_pci_mask_irq
};
static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
{
struct pq2ads_pci_pic *priv = desc->handler_data;
struct pq2ads_pci_pic *priv = get_irq_desc_data(desc);
u32 stat, mask, pend;
int bit;

View File

@ -16,4 +16,4 @@ obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o
obj-$(CONFIG_SBC834x) += sbc834x.o
obj-$(CONFIG_MPC837x_RDB) += mpc837x_rdb.o
obj-$(CONFIG_ASP834x) += asp834x.o
obj-$(CONFIG_KMETER1) += kmeter1.o
obj-$(CONFIG_KMETER1) += km83xx.o

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 DENX Software Engineering GmbH
* Copyright 2008-2011 DENX Software Engineering GmbH
* Author: Heiko Schocher <hs@denx.de>
*
* Description:
@ -49,12 +49,12 @@
* Setup the architecture
*
*/
static void __init kmeter1_setup_arch(void)
static void __init mpc83xx_km_setup_arch(void)
{
struct device_node *np;
if (ppc_md.progress)
ppc_md.progress("kmeter1_setup_arch()", 0);
ppc_md.progress("kmpbec83xx_setup_arch()", 0);
#ifdef CONFIG_PCI
for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
@ -69,6 +69,9 @@ static void __init kmeter1_setup_arch(void)
par_io_init(np);
of_node_put(np);
for_each_node_by_name(np, "spi")
par_io_of_config(np);
for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
par_io_of_config(np);
}
@ -119,7 +122,7 @@ static void __init kmeter1_setup_arch(void)
#endif /* CONFIG_QUICC_ENGINE */
}
static struct of_device_id kmeter_ids[] = {
static struct of_device_id kmpbec83xx_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
@ -131,13 +134,13 @@ static struct of_device_id kmeter_ids[] = {
static int __init kmeter_declare_of_platform_devices(void)
{
/* Publish the QE devices */
of_platform_bus_probe(NULL, kmeter_ids, NULL);
of_platform_bus_probe(NULL, kmpbec83xx_ids, NULL);
return 0;
}
machine_device_initcall(kmeter1, kmeter_declare_of_platform_devices);
machine_device_initcall(mpc83xx_km, kmeter_declare_of_platform_devices);
static void __init kmeter1_init_IRQ(void)
static void __init mpc83xx_km_init_IRQ(void)
{
struct device_node *np;
@ -168,21 +171,34 @@ static void __init kmeter1_init_IRQ(void)
#endif /* CONFIG_QUICC_ENGINE */
}
/* list of the supported boards */
static char *board[] __initdata = {
"Keymile,KMETER1",
"Keymile,kmpbec8321",
NULL
};
/*
* Called very early, MMU is off, device-tree isn't unflattened
*/
static int __init kmeter1_probe(void)
static int __init mpc83xx_km_probe(void)
{
unsigned long root = of_get_flat_dt_root();
unsigned long node = of_get_flat_dt_root();
int i = 0;
return of_flat_dt_is_compatible(root, "keymile,KMETER1");
while (board[i]) {
if (of_flat_dt_is_compatible(node, board[i]))
break;
i++;
}
return (board[i] != NULL);
}
define_machine(kmeter1) {
.name = "KMETER1",
.probe = kmeter1_probe,
.setup_arch = kmeter1_setup_arch,
.init_IRQ = kmeter1_init_IRQ,
define_machine(mpc83xx_km) {
.name = "mpc83xx-km-platform",
.probe = mpc83xx_km_probe,
.setup_arch = mpc83xx_km_setup_arch,
.init_IRQ = mpc83xx_km_init_IRQ,
.get_irq = ipic_get_irq,
.restart = mpc83xx_restart,
.time_init = mpc83xx_time_init,

View File

@ -56,12 +56,13 @@ static void machine_restart(char *cmd)
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static void __init ksi8560_pic_init(void)

View File

@ -50,12 +50,13 @@ static int mpc85xx_exclude_device(struct pci_controller *hose,
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
#endif /* CONFIG_CPM2 */

View File

@ -47,12 +47,13 @@
#ifdef CONFIG_PPC_I8259
static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ) {
generic_handle_irq(cascade_irq);
}
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
#endif /* CONFIG_PPC_I8259 */

View File

@ -41,12 +41,13 @@
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
#endif /* CONFIG_CPM2 */

View File

@ -91,10 +91,14 @@ smp_85xx_kick_cpu(int nr)
while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
mdelay(1);
#else
smp_generic_kick_cpu(nr);
out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER),
__pa((u64)*((unsigned long long *) generic_secondary_smp_init)));
smp_generic_kick_cpu(nr);
if (!ioremappable)
flush_dcache_range((ulong)bptr_vaddr,
(ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
#endif
local_irq_restore(flags);

View File

@ -93,6 +93,7 @@ static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq)
void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq;
/*
@ -103,17 +104,16 @@ void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static void socrates_fpga_pic_ack(unsigned int virq)
static void socrates_fpga_pic_ack(struct irq_data *d)
{
unsigned long flags;
unsigned int hwirq, irq_line;
uint32_t mask;
hwirq = socrates_fpga_irq_to_hw(virq);
hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
@ -124,14 +124,14 @@ static void socrates_fpga_pic_ack(unsigned int virq)
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static void socrates_fpga_pic_mask(unsigned int virq)
static void socrates_fpga_pic_mask(struct irq_data *d)
{
unsigned long flags;
unsigned int hwirq;
int irq_line;
u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq);
hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
@ -142,14 +142,14 @@ static void socrates_fpga_pic_mask(unsigned int virq)
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static void socrates_fpga_pic_mask_ack(unsigned int virq)
static void socrates_fpga_pic_mask_ack(struct irq_data *d)
{
unsigned long flags;
unsigned int hwirq;
int irq_line;
u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq);
hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
@ -161,14 +161,14 @@ static void socrates_fpga_pic_mask_ack(unsigned int virq)
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static void socrates_fpga_pic_unmask(unsigned int virq)
static void socrates_fpga_pic_unmask(struct irq_data *d)
{
unsigned long flags;
unsigned int hwirq;
int irq_line;
u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq);
hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
@ -179,14 +179,14 @@ static void socrates_fpga_pic_unmask(unsigned int virq)
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static void socrates_fpga_pic_eoi(unsigned int virq)
static void socrates_fpga_pic_eoi(struct irq_data *d)
{
unsigned long flags;
unsigned int hwirq;
int irq_line;
u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq);
hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
@ -197,7 +197,7 @@ static void socrates_fpga_pic_eoi(unsigned int virq)
raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
}
static int socrates_fpga_pic_set_type(unsigned int virq,
static int socrates_fpga_pic_set_type(struct irq_data *d,
unsigned int flow_type)
{
unsigned long flags;
@ -205,7 +205,7 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
int polarity;
u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq);
hwirq = socrates_fpga_irq_to_hw(d->irq);
if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
return -EINVAL;
@ -233,12 +233,12 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
static struct irq_chip socrates_fpga_pic_chip = {
.name = "FPGA-PIC",
.ack = socrates_fpga_pic_ack,
.mask = socrates_fpga_pic_mask,
.mask_ack = socrates_fpga_pic_mask_ack,
.unmask = socrates_fpga_pic_unmask,
.eoi = socrates_fpga_pic_eoi,
.set_type = socrates_fpga_pic_set_type,
.irq_ack = socrates_fpga_pic_ack,
.irq_mask = socrates_fpga_pic_mask,
.irq_mask_ack = socrates_fpga_pic_mask_ack,
.irq_unmask = socrates_fpga_pic_unmask,
.irq_eoi = socrates_fpga_pic_eoi,
.irq_set_type = socrates_fpga_pic_set_type,
};
static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,

View File

@ -46,12 +46,13 @@
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
#endif /* CONFIG_CPM2 */

View File

@ -44,12 +44,13 @@
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
#endif /* CONFIG_CPM2 */

View File

@ -95,6 +95,7 @@ static int gef_pic_cascade_irq;
void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq;
/*
@ -106,17 +107,16 @@ void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static void gef_pic_mask(unsigned int virq)
static void gef_pic_mask(struct irq_data *d)
{
unsigned long flags;
unsigned int hwirq;
u32 mask;
hwirq = gef_irq_to_hw(virq);
hwirq = gef_irq_to_hw(d->irq);
raw_spin_lock_irqsave(&gef_pic_lock, flags);
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
@ -125,21 +125,21 @@ static void gef_pic_mask(unsigned int virq)
raw_spin_unlock_irqrestore(&gef_pic_lock, flags);
}
static void gef_pic_mask_ack(unsigned int virq)
static void gef_pic_mask_ack(struct irq_data *d)
{
/* Don't think we actually have to do anything to ack an interrupt,
* we just need to clear down the devices interrupt and it will go away
*/
gef_pic_mask(virq);
gef_pic_mask(d);
}
static void gef_pic_unmask(unsigned int virq)
static void gef_pic_unmask(struct irq_data *d)
{
unsigned long flags;
unsigned int hwirq;
u32 mask;
hwirq = gef_irq_to_hw(virq);
hwirq = gef_irq_to_hw(d->irq);
raw_spin_lock_irqsave(&gef_pic_lock, flags);
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
@ -150,9 +150,9 @@ static void gef_pic_unmask(unsigned int virq)
static struct irq_chip gef_pic_chip = {
.name = "gefp",
.mask = gef_pic_mask,
.mask_ack = gef_pic_mask_ack,
.unmask = gef_pic_unmask,
.irq_mask = gef_pic_mask,
.irq_mask_ack = gef_pic_mask_ack,
.irq_unmask = gef_pic_unmask,
};

View File

@ -19,10 +19,13 @@
#ifdef CONFIG_PPC_I8259
static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
#endif /* CONFIG_PPC_I8259 */

View File

@ -49,12 +49,6 @@ config PPC_ADDER875
This enables support for the Analogue & Micro Adder 875
board.
config PPC_MGSUVD
bool "MGSUVD"
select CPM1
help
This enables support for the Keymile MGSUVD board.
config TQM8XX
bool "TQM8XX"
select CPM1

View File

@ -6,5 +6,4 @@ obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o
obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o
obj-$(CONFIG_PPC_EP88XC) += ep88xc.o
obj-$(CONFIG_PPC_ADDER875) += adder875.o
obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o
obj-$(CONFIG_TQM8XX) += tqm8xx_setup.o

View File

@ -218,15 +218,20 @@ void mpc8xx_restart(char *cmd)
static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip;
int cascade_irq;
if ((cascade_irq = cpm_get_irq()) >= 0) {
struct irq_desc *cdesc = irq_to_desc(cascade_irq);
generic_handle_irq(cascade_irq);
cdesc->chip->eoi(cascade_irq);
chip = get_irq_desc_chip(cdesc);
chip->irq_eoi(&cdesc->irq_data);
}
desc->chip->eoi(irq);
chip = get_irq_desc_chip(desc);
chip->irq_eoi(&desc->irq_data);
}
/* Initialize the internal interrupt controllers. The number of

View File

@ -1,92 +0,0 @@
/*
*
* Platform setup for the Keymile mgsuvd board
*
* Heiko Schocher <hs@denx.de>
*
* Copyright 2008 DENX Software Engineering GmbH
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/ioport.h>
#include <linux/of_platform.h>
#include <asm/io.h>
#include <asm/machdep.h>
#include <asm/processor.h>
#include <asm/cpm1.h>
#include <asm/prom.h>
#include <asm/fs_pd.h>
#include "mpc8xx.h"
struct cpm_pin {
int port, pin, flags;
};
static __initdata struct cpm_pin mgsuvd_pins[] = {
/* SMC1 */
{CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
{CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
/* SCC3 */
{CPM_PORTA, 10, CPM_PIN_INPUT},
{CPM_PORTA, 11, CPM_PIN_INPUT},
{CPM_PORTA, 3, CPM_PIN_INPUT},
{CPM_PORTA, 2, CPM_PIN_INPUT},
{CPM_PORTC, 13, CPM_PIN_INPUT},
};
static void __init init_ioports(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(mgsuvd_pins); i++) {
struct cpm_pin *pin = &mgsuvd_pins[i];
cpm1_set_pin(pin->port, pin->pin, pin->flags);
}
setbits16(&mpc8xx_immr->im_ioport.iop_pcso, 0x300);
cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RX);
cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_TX);
cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
}
static void __init mgsuvd_setup_arch(void)
{
cpm_reset();
init_ioports();
}
static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus" },
{},
};
static int __init declare_of_platform_devices(void)
{
of_platform_bus_probe(NULL, of_bus_ids, NULL);
return 0;
}
machine_device_initcall(mgsuvd, declare_of_platform_devices);
static int __init mgsuvd_probe(void)
{
unsigned long root = of_get_flat_dt_root();
return of_flat_dt_is_compatible(root, "keymile,mgsuvd");
}
define_machine(mgsuvd) {
.name = "MGSUVD",
.probe = mgsuvd_probe,
.setup_arch = mgsuvd_setup_arch,
.init_IRQ = mpc8xx_pics_init,
.get_irq = mpc8xx_get_irq,
.restart = mpc8xx_restart,
.calibrate_decr = mpc8xx_calibrate_decr,
.set_rtc_time = mpc8xx_set_rtc_time,
.get_rtc_time = mpc8xx_get_rtc_time,
};

View File

@ -93,6 +93,7 @@ static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
struct axon_msic *msic = get_irq_data(irq);
u32 write_offset, msi;
int idx;
@ -145,7 +146,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
msic->read_offset &= MSIC_FIFO_SIZE_MASK;
}
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static struct axon_msic *find_msi_translator(struct pci_dev *dev)

View File

@ -61,59 +61,59 @@ static inline void beatic_update_irq_mask(unsigned int irq_plug)
panic("Failed to set mask IRQ!");
}
static void beatic_mask_irq(unsigned int irq_plug)
static void beatic_mask_irq(struct irq_data *d)
{
unsigned long flags;
raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
beatic_update_irq_mask(irq_plug);
beatic_irq_mask_enable[d->irq/64] &= ~(1UL << (63 - (d->irq%64)));
beatic_update_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}
static void beatic_unmask_irq(unsigned int irq_plug)
static void beatic_unmask_irq(struct irq_data *d)
{
unsigned long flags;
raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
beatic_update_irq_mask(irq_plug);
beatic_irq_mask_enable[d->irq/64] |= 1UL << (63 - (d->irq%64));
beatic_update_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}
static void beatic_ack_irq(unsigned int irq_plug)
static void beatic_ack_irq(struct irq_data *d)
{
unsigned long flags;
raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
beatic_update_irq_mask(irq_plug);
beatic_irq_mask_ack[d->irq/64] &= ~(1UL << (63 - (d->irq%64)));
beatic_update_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}
static void beatic_end_irq(unsigned int irq_plug)
static void beatic_end_irq(struct irq_data *d)
{
s64 err;
unsigned long flags;
err = beat_downcount_of_interrupt(irq_plug);
err = beat_downcount_of_interrupt(d->irq);
if (err != 0) {
if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */
panic("Failed to downcount IRQ! Error = %16llx", err);
printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug);
printk(KERN_ERR "IRQ over-downcounted, plug %d\n", d->irq);
}
raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
beatic_update_irq_mask(irq_plug);
beatic_irq_mask_ack[d->irq/64] |= 1UL << (63 - (d->irq%64));
beatic_update_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
}
static struct irq_chip beatic_pic = {
.name = "CELL-BEAT",
.unmask = beatic_unmask_irq,
.mask = beatic_mask_irq,
.eoi = beatic_end_irq,
.irq_unmask = beatic_unmask_irq,
.irq_mask = beatic_mask_irq,
.irq_eoi = beatic_end_irq,
};
/*
@ -232,7 +232,7 @@ unsigned int beatic_get_irq(void)
ret = beatic_get_irq_plug();
if (ret != NO_IRQ)
beatic_ack_irq(ret);
beatic_ack_irq(irq_get_irq_data(ret));
return ret;
}

View File

@ -72,15 +72,15 @@ static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
}
static void iic_mask(unsigned int irq)
static void iic_mask(struct irq_data *d)
{
}
static void iic_unmask(unsigned int irq)
static void iic_unmask(struct irq_data *d)
{
}
static void iic_eoi(unsigned int irq)
static void iic_eoi(struct irq_data *d)
{
struct iic *iic = &__get_cpu_var(cpu_iic);
out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]);
@ -89,19 +89,21 @@ static void iic_eoi(unsigned int irq)
static struct irq_chip iic_chip = {
.name = "CELL-IIC",
.mask = iic_mask,
.unmask = iic_unmask,
.eoi = iic_eoi,
.irq_mask = iic_mask,
.irq_unmask = iic_unmask,
.irq_eoi = iic_eoi,
};
static void iic_ioexc_eoi(unsigned int irq)
static void iic_ioexc_eoi(struct irq_data *d)
{
}
static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
{
struct cbe_iic_regs __iomem *node_iic = (void __iomem *)desc->handler_data;
struct irq_chip *chip = get_irq_desc_chip(desc);
struct cbe_iic_regs __iomem *node_iic =
(void __iomem *)get_irq_desc_data(desc);
unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
unsigned long bits, ack;
int cascade;
@ -128,15 +130,15 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
if (ack)
out_be64(&node_iic->iic_is, ack);
}
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static struct irq_chip iic_ioexc_chip = {
.name = "CELL-IOEX",
.mask = iic_mask,
.unmask = iic_unmask,
.eoi = iic_ioexc_eoi,
.irq_mask = iic_mask,
.irq_unmask = iic_unmask,
.irq_eoi = iic_ioexc_eoi,
};
/* Get an IRQ number from the pending state register of the IIC */
@ -237,6 +239,8 @@ extern int noirqdebug;
static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
raw_spin_lock(&desc->lock);
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
@ -275,7 +279,7 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
desc->status &= ~IRQ_INPROGRESS;
out_eoi:
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
raw_spin_unlock(&desc->lock);
}

View File

@ -187,13 +187,15 @@ machine_subsys_initcall(cell, cell_publish_devices);
static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
{
struct mpic *mpic = desc->handler_data;
struct irq_chip *chip = get_irq_desc_chip(desc);
struct mpic *mpic = get_irq_desc_data(desc);
unsigned int virq;
virq = mpic_get_one_irq(mpic);
if (virq != NO_IRQ)
generic_handle_irq(virq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static void __init mpic_init_IRQ(void)

View File

@ -79,30 +79,30 @@ static void __iomem *spider_get_irq_config(struct spider_pic *pic,
return pic->regs + TIR_CFGA + 8 * src;
}
static void spider_unmask_irq(unsigned int virq)
static void spider_unmask_irq(struct irq_data *d)
{
struct spider_pic *pic = spider_virq_to_pic(virq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
struct spider_pic *pic = spider_virq_to_pic(d->irq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
out_be32(cfg, in_be32(cfg) | 0x30000000u);
}
static void spider_mask_irq(unsigned int virq)
static void spider_mask_irq(struct irq_data *d)
{
struct spider_pic *pic = spider_virq_to_pic(virq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
struct spider_pic *pic = spider_virq_to_pic(d->irq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
out_be32(cfg, in_be32(cfg) & ~0x30000000u);
}
static void spider_ack_irq(unsigned int virq)
static void spider_ack_irq(struct irq_data *d)
{
struct spider_pic *pic = spider_virq_to_pic(virq);
unsigned int src = irq_map[virq].hwirq;
struct spider_pic *pic = spider_virq_to_pic(d->irq);
unsigned int src = irq_map[d->irq].hwirq;
/* Reset edge detection logic if necessary
*/
if (irq_to_desc(virq)->status & IRQ_LEVEL)
if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
return;
/* Only interrupts 47 to 50 can be set to edge */
@ -113,13 +113,13 @@ static void spider_ack_irq(unsigned int virq)
out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf));
}
static int spider_set_irq_type(unsigned int virq, unsigned int type)
static int spider_set_irq_type(struct irq_data *d, unsigned int type)
{
unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
struct spider_pic *pic = spider_virq_to_pic(virq);
unsigned int hw = irq_map[virq].hwirq;
struct spider_pic *pic = spider_virq_to_pic(d->irq);
unsigned int hw = irq_map[d->irq].hwirq;
void __iomem *cfg = spider_get_irq_config(pic, hw);
struct irq_desc *desc = irq_to_desc(virq);
struct irq_desc *desc = irq_to_desc(d->irq);
u32 old_mask;
u32 ic;
@ -169,10 +169,10 @@ static int spider_set_irq_type(unsigned int virq, unsigned int type)
static struct irq_chip spider_pic = {
.name = "SPIDER",
.unmask = spider_unmask_irq,
.mask = spider_mask_irq,
.ack = spider_ack_irq,
.set_type = spider_set_irq_type,
.irq_unmask = spider_unmask_irq,
.irq_mask = spider_mask_irq,
.irq_ack = spider_ack_irq,
.irq_set_type = spider_set_irq_type,
};
static int spider_host_map(struct irq_host *h, unsigned int virq,
@ -207,7 +207,8 @@ static struct irq_host_ops spider_host_ops = {
static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc)
{
struct spider_pic *pic = desc->handler_data;
struct irq_chip *chip = get_irq_desc_chip(desc);
struct spider_pic *pic = get_irq_desc_data(desc);
unsigned int cs, virq;
cs = in_be32(pic->regs + TIR_CS) >> 24;
@ -215,9 +216,11 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc)
virq = NO_IRQ;
else
virq = irq_linear_revmap(pic->host, cs);
if (virq != NO_IRQ)
generic_handle_irq(virq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
/* For hooking up the cascace we have a problem. Our device-tree is

View File

@ -365,10 +365,13 @@ void __init chrp_setup_arch(void)
static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
/*

View File

@ -46,10 +46,10 @@
*
*/
static void flipper_pic_mask_and_ack(unsigned int virq)
static void flipper_pic_mask_and_ack(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void __iomem *io_base = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
u32 mask = 1 << irq;
clrbits32(io_base + FLIPPER_IMR, mask);
@ -57,27 +57,27 @@ static void flipper_pic_mask_and_ack(unsigned int virq)
out_be32(io_base + FLIPPER_ICR, mask);
}
static void flipper_pic_ack(unsigned int virq)
static void flipper_pic_ack(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void __iomem *io_base = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
/* this is at least needed for RSW */
out_be32(io_base + FLIPPER_ICR, 1 << irq);
}
static void flipper_pic_mask(unsigned int virq)
static void flipper_pic_mask(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void __iomem *io_base = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
clrbits32(io_base + FLIPPER_IMR, 1 << irq);
}
static void flipper_pic_unmask(unsigned int virq)
static void flipper_pic_unmask(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void __iomem *io_base = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
setbits32(io_base + FLIPPER_IMR, 1 << irq);
}
@ -85,10 +85,10 @@ static void flipper_pic_unmask(unsigned int virq)
static struct irq_chip flipper_pic = {
.name = "flipper-pic",
.ack = flipper_pic_ack,
.mask_ack = flipper_pic_mask_and_ack,
.mask = flipper_pic_mask,
.unmask = flipper_pic_unmask,
.irq_ack = flipper_pic_ack,
.irq_mask_ack = flipper_pic_mask_and_ack,
.irq_mask = flipper_pic_mask,
.irq_unmask = flipper_pic_unmask,
};
/*

View File

@ -41,36 +41,36 @@
*
*/
static void hlwd_pic_mask_and_ack(unsigned int virq)
static void hlwd_pic_mask_and_ack(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void __iomem *io_base = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
u32 mask = 1 << irq;
clrbits32(io_base + HW_BROADWAY_IMR, mask);
out_be32(io_base + HW_BROADWAY_ICR, mask);
}
static void hlwd_pic_ack(unsigned int virq)
static void hlwd_pic_ack(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void __iomem *io_base = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
out_be32(io_base + HW_BROADWAY_ICR, 1 << irq);
}
static void hlwd_pic_mask(unsigned int virq)
static void hlwd_pic_mask(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void __iomem *io_base = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
}
static void hlwd_pic_unmask(unsigned int virq)
static void hlwd_pic_unmask(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void __iomem *io_base = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void __iomem *io_base = irq_data_get_irq_chip_data(d);
setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
}
@ -78,10 +78,10 @@ static void hlwd_pic_unmask(unsigned int virq)
static struct irq_chip hlwd_pic = {
.name = "hlwd-pic",
.ack = hlwd_pic_ack,
.mask_ack = hlwd_pic_mask_and_ack,
.mask = hlwd_pic_mask,
.unmask = hlwd_pic_unmask,
.irq_ack = hlwd_pic_ack,
.irq_mask_ack = hlwd_pic_mask_and_ack,
.irq_mask = hlwd_pic_mask,
.irq_unmask = hlwd_pic_unmask,
};
/*
@ -129,11 +129,12 @@ static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
struct irq_host *irq_host = get_irq_data(cascade_virq);
unsigned int virq;
raw_spin_lock(&desc->lock);
desc->chip->mask(cascade_virq); /* IRQ_LEVEL */
chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */
raw_spin_unlock(&desc->lock);
virq = __hlwd_pic_get_irq(irq_host);
@ -143,9 +144,9 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
pr_err("spurious interrupt!\n");
raw_spin_lock(&desc->lock);
desc->chip->ack(cascade_virq); /* IRQ_LEVEL */
if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
desc->chip->unmask(cascade_virq);
chip->irq_ack(&desc->irq_data); /* IRQ_LEVEL */
if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
chip->irq_unmask(&desc->irq_data);
raw_spin_unlock(&desc->lock);
}

View File

@ -167,11 +167,11 @@ static void pci_event_handler(struct HvLpEvent *event)
* This will be called by device drivers (via enable_IRQ)
* to enable INTA in the bridge interrupt status register.
*/
static void iseries_enable_IRQ(unsigned int irq)
static void iseries_enable_IRQ(struct irq_data *d)
{
u32 bus, dev_id, function, mask;
const u32 sub_bus = 0;
unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
/* The IRQ has already been locked by the caller */
bus = REAL_IRQ_TO_BUS(rirq);
@ -184,23 +184,23 @@ static void iseries_enable_IRQ(unsigned int irq)
}
/* This is called by iseries_activate_IRQs */
static unsigned int iseries_startup_IRQ(unsigned int irq)
static unsigned int iseries_startup_IRQ(struct irq_data *d)
{
u32 bus, dev_id, function, mask;
const u32 sub_bus = 0;
unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
bus = REAL_IRQ_TO_BUS(rirq);
function = REAL_IRQ_TO_FUNC(rirq);
dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
/* Link the IRQ number to the bridge */
HvCallXm_connectBusUnit(bus, sub_bus, dev_id, irq);
HvCallXm_connectBusUnit(bus, sub_bus, dev_id, d->irq);
/* Unmask bridge interrupts in the FISR */
mask = 0x01010000 << function;
HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask);
iseries_enable_IRQ(irq);
iseries_enable_IRQ(d);
return 0;
}
@ -215,21 +215,26 @@ void __init iSeries_activate_IRQs()
for_each_irq (irq) {
struct irq_desc *desc = irq_to_desc(irq);
struct irq_chip *chip;
if (desc && desc->chip && desc->chip->startup) {
if (!desc)
continue;
chip = get_irq_desc_chip(desc);
if (chip && chip->irq_startup) {
raw_spin_lock_irqsave(&desc->lock, flags);
desc->chip->startup(irq);
chip->irq_startup(&desc->irq_data);
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
}
}
/* this is not called anywhere currently */
static void iseries_shutdown_IRQ(unsigned int irq)
static void iseries_shutdown_IRQ(struct irq_data *d)
{
u32 bus, dev_id, function, mask;
const u32 sub_bus = 0;
unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
/* irq should be locked by the caller */
bus = REAL_IRQ_TO_BUS(rirq);
@ -248,11 +253,11 @@ static void iseries_shutdown_IRQ(unsigned int irq)
* This will be called by device drivers (via disable_IRQ)
* to disable INTA in the bridge interrupt status register.
*/
static void iseries_disable_IRQ(unsigned int irq)
static void iseries_disable_IRQ(struct irq_data *d)
{
u32 bus, dev_id, function, mask;
const u32 sub_bus = 0;
unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
/* The IRQ has already been locked by the caller */
bus = REAL_IRQ_TO_BUS(rirq);
@ -264,9 +269,9 @@ static void iseries_disable_IRQ(unsigned int irq)
HvCallPci_maskInterrupts(bus, sub_bus, dev_id, mask);
}
static void iseries_end_IRQ(unsigned int irq)
static void iseries_end_IRQ(struct irq_data *d)
{
unsigned int rirq = (unsigned int)irq_map[irq].hwirq;
unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq),
(REAL_IRQ_TO_IDSEL(rirq) << 4) + REAL_IRQ_TO_FUNC(rirq));
@ -274,11 +279,11 @@ static void iseries_end_IRQ(unsigned int irq)
static struct irq_chip iseries_pic = {
.name = "iSeries",
.startup = iseries_startup_IRQ,
.shutdown = iseries_shutdown_IRQ,
.unmask = iseries_enable_IRQ,
.mask = iseries_disable_IRQ,
.eoi = iseries_end_IRQ
.irq_startup = iseries_startup_IRQ,
.irq_shutdown = iseries_shutdown_IRQ,
.irq_unmask = iseries_enable_IRQ,
.irq_mask = iseries_disable_IRQ,
.irq_eoi = iseries_end_IRQ
};
/*

View File

@ -240,7 +240,7 @@ static __init void pas_init_IRQ(void)
nmi_virq = irq_create_mapping(NULL, *nmiprop);
mpic_irq_set_priority(nmi_virq, 15);
set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
mpic_unmask_irq(nmi_virq);
mpic_unmask_irq(irq_get_irq_data(nmi_virq));
}
of_node_put(mpic_node);
@ -266,7 +266,7 @@ static int pas_machine_check_handler(struct pt_regs *regs)
if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
printk(KERN_ERR "NMI delivered\n");
debugger(regs);
mpic_end_irq(nmi_virq);
mpic_end_irq(irq_get_irq_data(nmi_virq));
goto out;
}

View File

@ -82,9 +82,9 @@ static void __pmac_retrigger(unsigned int irq_nr)
}
}
static void pmac_mask_and_ack_irq(unsigned int virq)
static void pmac_mask_and_ack_irq(struct irq_data *d)
{
unsigned int src = irq_map[virq].hwirq;
unsigned int src = irq_map[d->irq].hwirq;
unsigned long bit = 1UL << (src & 0x1f);
int i = src >> 5;
unsigned long flags;
@ -104,9 +104,9 @@ static void pmac_mask_and_ack_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static void pmac_ack_irq(unsigned int virq)
static void pmac_ack_irq(struct irq_data *d)
{
unsigned int src = irq_map[virq].hwirq;
unsigned int src = irq_map[d->irq].hwirq;
unsigned long bit = 1UL << (src & 0x1f);
int i = src >> 5;
unsigned long flags;
@ -149,15 +149,15 @@ static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
/* When an irq gets requested for the first client, if it's an
* edge interrupt, we clear any previous one on the controller
*/
static unsigned int pmac_startup_irq(unsigned int virq)
static unsigned int pmac_startup_irq(struct irq_data *d)
{
unsigned long flags;
unsigned int src = irq_map[virq].hwirq;
unsigned int src = irq_map[d->irq].hwirq;
unsigned long bit = 1UL << (src & 0x1f);
int i = src >> 5;
raw_spin_lock_irqsave(&pmac_pic_lock, flags);
if ((irq_to_desc(virq)->status & IRQ_LEVEL) == 0)
if ((irq_to_desc(d->irq)->status & IRQ_LEVEL) == 0)
out_le32(&pmac_irq_hw[i]->ack, bit);
__set_bit(src, ppc_cached_irq_mask);
__pmac_set_irq_mask(src, 0);
@ -166,10 +166,10 @@ static unsigned int pmac_startup_irq(unsigned int virq)
return 0;
}
static void pmac_mask_irq(unsigned int virq)
static void pmac_mask_irq(struct irq_data *d)
{
unsigned long flags;
unsigned int src = irq_map[virq].hwirq;
unsigned int src = irq_map[d->irq].hwirq;
raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__clear_bit(src, ppc_cached_irq_mask);
@ -177,10 +177,10 @@ static void pmac_mask_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static void pmac_unmask_irq(unsigned int virq)
static void pmac_unmask_irq(struct irq_data *d)
{
unsigned long flags;
unsigned int src = irq_map[virq].hwirq;
unsigned int src = irq_map[d->irq].hwirq;
raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__set_bit(src, ppc_cached_irq_mask);
@ -188,24 +188,24 @@ static void pmac_unmask_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
}
static int pmac_retrigger(unsigned int virq)
static int pmac_retrigger(struct irq_data *d)
{
unsigned long flags;
raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__pmac_retrigger(irq_map[virq].hwirq);
__pmac_retrigger(irq_map[d->irq].hwirq);
raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
return 1;
}
static struct irq_chip pmac_pic = {
.name = "PMAC-PIC",
.startup = pmac_startup_irq,
.mask = pmac_mask_irq,
.ack = pmac_ack_irq,
.mask_ack = pmac_mask_and_ack_irq,
.unmask = pmac_unmask_irq,
.retrigger = pmac_retrigger,
.irq_startup = pmac_startup_irq,
.irq_mask = pmac_mask_irq,
.irq_ack = pmac_ack_irq,
.irq_mask_ack = pmac_mask_and_ack_irq,
.irq_unmask = pmac_unmask_irq,
.irq_retrigger = pmac_retrigger,
};
static irqreturn_t gatwick_action(int cpl, void *dev_id)
@ -472,12 +472,14 @@ int of_irq_map_oldworld(struct device_node *device, int index,
static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
{
struct mpic *mpic = desc->handler_data;
struct irq_chip *chip = get_irq_desc_chip(desc);
struct mpic *mpic = get_irq_desc_data(desc);
unsigned int cascade_irq = mpic_get_one_irq(mpic);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
@ -707,7 +709,7 @@ static int pmacpic_resume(struct sys_device *sysdev)
mb();
for (i = 0; i < max_real_irqs; ++i)
if (test_bit(i, sleep_save_mask))
pmac_unmask_irq(i);
pmac_unmask_irq(irq_get_irq_data(i));
return 0;
}

View File

@ -99,16 +99,16 @@ static DEFINE_PER_CPU(struct ps3_private, ps3_private);
* Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
*/
static void ps3_chip_mask(unsigned int virq)
static void ps3_chip_mask(struct irq_data *d)
{
struct ps3_private *pd = get_irq_chip_data(virq);
struct ps3_private *pd = irq_data_get_irq_chip_data(d);
unsigned long flags;
pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
pd->thread_id, virq);
pd->thread_id, d->irq);
local_irq_save(flags);
clear_bit(63 - virq, &pd->bmp.mask);
clear_bit(63 - d->irq, &pd->bmp.mask);
lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
local_irq_restore(flags);
}
@ -120,16 +120,16 @@ static void ps3_chip_mask(unsigned int virq)
* Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
*/
static void ps3_chip_unmask(unsigned int virq)
static void ps3_chip_unmask(struct irq_data *d)
{
struct ps3_private *pd = get_irq_chip_data(virq);
struct ps3_private *pd = irq_data_get_irq_chip_data(d);
unsigned long flags;
pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__,
pd->thread_id, virq);
pd->thread_id, d->irq);
local_irq_save(flags);
set_bit(63 - virq, &pd->bmp.mask);
set_bit(63 - d->irq, &pd->bmp.mask);
lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
local_irq_restore(flags);
}
@ -141,10 +141,10 @@ static void ps3_chip_unmask(unsigned int virq)
* Calls lv1_end_of_interrupt_ext().
*/
static void ps3_chip_eoi(unsigned int virq)
static void ps3_chip_eoi(struct irq_data *d)
{
const struct ps3_private *pd = get_irq_chip_data(virq);
lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
const struct ps3_private *pd = irq_data_get_irq_chip_data(d);
lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq);
}
/**
@ -153,9 +153,9 @@ static void ps3_chip_eoi(unsigned int virq)
static struct irq_chip ps3_irq_chip = {
.name = "ps3",
.mask = ps3_chip_mask,
.unmask = ps3_chip_unmask,
.eoi = ps3_chip_eoi,
.irq_mask = ps3_chip_mask,
.irq_unmask = ps3_chip_unmask,
.irq_eoi = ps3_chip_eoi,
};
/**
@ -202,7 +202,7 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
goto fail_set;
}
ps3_chip_mask(*virq);
ps3_chip_mask(irq_get_irq_data(*virq));
return result;
@ -296,7 +296,7 @@ int ps3_irq_plug_destroy(unsigned int virq)
pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__,
__LINE__, pd->ppe_id, pd->thread_id, virq);
ps3_chip_mask(virq);
ps3_chip_mask(irq_get_irq_data(virq));
result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
@ -357,7 +357,7 @@ int ps3_event_receive_port_destroy(unsigned int virq)
pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
ps3_chip_mask(virq);
ps3_chip_mask(irq_get_irq_data(virq));
result = lv1_destruct_event_receive_port(virq_to_hw(virq));
@ -492,7 +492,7 @@ int ps3_io_irq_destroy(unsigned int virq)
int result;
unsigned long outlet = virq_to_hw(virq);
ps3_chip_mask(virq);
ps3_chip_mask(irq_get_irq_data(virq));
/*
* lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
@ -553,7 +553,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
{
int result;
ps3_chip_mask(virq);
ps3_chip_mask(irq_get_irq_data(virq));
result = lv1_deconfigure_virtual_uart_irq();
if (result) {
@ -605,7 +605,7 @@ int ps3_spe_irq_destroy(unsigned int virq)
{
int result;
ps3_chip_mask(virq);
ps3_chip_mask(irq_get_irq_data(virq));
result = ps3_irq_plug_destroy(virq);
BUG_ON(result);

View File

@ -508,12 +508,7 @@ static int cmm_memory_isolate_cb(struct notifier_block *self,
if (action == MEM_ISOLATE_COUNT)
ret = cmm_count_pages(arg);
if (ret)
ret = notifier_from_errno(ret);
else
ret = NOTIFY_OK;
return ret;
return notifier_from_errno(ret);
}
static struct notifier_block cmm_mem_isolate_nb = {
@ -635,12 +630,7 @@ static int cmm_memory_cb(struct notifier_block *self,
break;
}
if (ret)
ret = notifier_from_errno(ret);
else
ret = NOTIFY_OK;
return ret;
return notifier_from_errno(ret);
}
static struct notifier_block cmm_mem_nb = {

View File

@ -876,7 +876,7 @@ void eeh_restore_bars(struct pci_dn *pdn)
*
* Save the values of the device bars. Unlike the restore
* routine, this routine is *not* recursive. This is because
* PCI devices are added individuallly; but, for the restore,
* PCI devices are added individually; but, for the restore,
* an entire slot is reset at a time.
*/
static void eeh_save_bars(struct pci_dn *pdn)

View File

@ -33,6 +33,7 @@
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/crash_dump.h>
#include <linux/memory.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/rtas.h>
@ -45,6 +46,7 @@
#include <asm/tce.h>
#include <asm/ppc-pci.h>
#include <asm/udbg.h>
#include <asm/mmzone.h>
#include "plpar_wrappers.h"
@ -270,6 +272,152 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum)
return tce_ret;
}
/* this is compatable with cells for the device tree property */
struct dynamic_dma_window_prop {
__be32 liobn; /* tce table number */
__be64 dma_base; /* address hi,lo */
__be32 tce_shift; /* ilog2(tce_page_size) */
__be32 window_shift; /* ilog2(tce_window_size) */
};
struct direct_window {
struct device_node *device;
const struct dynamic_dma_window_prop *prop;
struct list_head list;
};
/* Dynamic DMA Window support */
struct ddw_query_response {
u32 windows_available;
u32 largest_available_block;
u32 page_size;
u32 migration_capable;
};
struct ddw_create_response {
u32 liobn;
u32 addr_hi;
u32 addr_lo;
};
static LIST_HEAD(direct_window_list);
/* prevents races between memory on/offline and window creation */
static DEFINE_SPINLOCK(direct_window_list_lock);
/* protects initializing window twice for same device */
static DEFINE_MUTEX(direct_window_init_mutex);
#define DIRECT64_PROPNAME "linux,direct64-ddr-window-info"
static int tce_clearrange_multi_pSeriesLP(unsigned long start_pfn,
unsigned long num_pfn, const void *arg)
{
const struct dynamic_dma_window_prop *maprange = arg;
int rc;
u64 tce_size, num_tce, dma_offset, next;
u32 tce_shift;
long limit;
tce_shift = be32_to_cpu(maprange->tce_shift);
tce_size = 1ULL << tce_shift;
next = start_pfn << PAGE_SHIFT;
num_tce = num_pfn << PAGE_SHIFT;
/* round back to the beginning of the tce page size */
num_tce += next & (tce_size - 1);
next &= ~(tce_size - 1);
/* covert to number of tces */
num_tce |= tce_size - 1;
num_tce >>= tce_shift;
do {
/*
* Set up the page with TCE data, looping through and setting
* the values.
*/
limit = min_t(long, num_tce, 512);
dma_offset = next + be64_to_cpu(maprange->dma_base);
rc = plpar_tce_stuff((u64)be32_to_cpu(maprange->liobn),
dma_offset,
0, limit);
num_tce -= limit;
} while (num_tce > 0 && !rc);
return rc;
}
static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
unsigned long num_pfn, const void *arg)
{
const struct dynamic_dma_window_prop *maprange = arg;
u64 *tcep, tce_size, num_tce, dma_offset, next, proto_tce, liobn;
u32 tce_shift;
u64 rc = 0;
long l, limit;
local_irq_disable(); /* to protect tcep and the page behind it */
tcep = __get_cpu_var(tce_page);
if (!tcep) {
tcep = (u64 *)__get_free_page(GFP_ATOMIC);
if (!tcep) {
local_irq_enable();
return -ENOMEM;
}
__get_cpu_var(tce_page) = tcep;
}
proto_tce = TCE_PCI_READ | TCE_PCI_WRITE;
liobn = (u64)be32_to_cpu(maprange->liobn);
tce_shift = be32_to_cpu(maprange->tce_shift);
tce_size = 1ULL << tce_shift;
next = start_pfn << PAGE_SHIFT;
num_tce = num_pfn << PAGE_SHIFT;
/* round back to the beginning of the tce page size */
num_tce += next & (tce_size - 1);
next &= ~(tce_size - 1);
/* covert to number of tces */
num_tce |= tce_size - 1;
num_tce >>= tce_shift;
/* We can map max one pageful of TCEs at a time */
do {
/*
* Set up the page with TCE data, looping through and setting
* the values.
*/
limit = min_t(long, num_tce, 4096/TCE_ENTRY_SIZE);
dma_offset = next + be64_to_cpu(maprange->dma_base);
for (l = 0; l < limit; l++) {
tcep[l] = proto_tce | next;
next += tce_size;
}
rc = plpar_tce_put_indirect(liobn,
dma_offset,
(u64)virt_to_abs(tcep),
limit);
num_tce -= limit;
} while (num_tce > 0 && !rc);
/* error cleanup: caller will clear whole range */
local_irq_enable();
return rc;
}
static int tce_setrange_multi_pSeriesLP_walk(unsigned long start_pfn,
unsigned long num_pfn, void *arg)
{
return tce_setrange_multi_pSeriesLP(start_pfn, num_pfn, arg);
}
#ifdef CONFIG_PCI
static void iommu_table_setparms(struct pci_controller *phb,
struct device_node *dn,
@ -495,6 +643,329 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
pci_name(dev));
}
static int __read_mostly disable_ddw;
static int __init disable_ddw_setup(char *str)
{
disable_ddw = 1;
printk(KERN_INFO "ppc iommu: disabling ddw.\n");
return 0;
}
early_param("disable_ddw", disable_ddw_setup);
static void remove_ddw(struct device_node *np)
{
struct dynamic_dma_window_prop *dwp;
struct property *win64;
const u32 *ddr_avail;
u64 liobn;
int len, ret;
ddr_avail = of_get_property(np, "ibm,ddw-applicable", &len);
win64 = of_find_property(np, DIRECT64_PROPNAME, NULL);
if (!win64 || !ddr_avail || len < 3 * sizeof(u32))
return;
dwp = win64->value;
liobn = (u64)be32_to_cpu(dwp->liobn);
/* clear the whole window, note the arg is in kernel pages */
ret = tce_clearrange_multi_pSeriesLP(0,
1ULL << (be32_to_cpu(dwp->window_shift) - PAGE_SHIFT), dwp);
if (ret)
pr_warning("%s failed to clear tces in window.\n",
np->full_name);
else
pr_debug("%s successfully cleared tces in window.\n",
np->full_name);
ret = rtas_call(ddr_avail[2], 1, 1, NULL, liobn);
if (ret)
pr_warning("%s: failed to remove direct window: rtas returned "
"%d to ibm,remove-pe-dma-window(%x) %llx\n",
np->full_name, ret, ddr_avail[2], liobn);
else
pr_debug("%s: successfully removed direct window: rtas returned "
"%d to ibm,remove-pe-dma-window(%x) %llx\n",
np->full_name, ret, ddr_avail[2], liobn);
}
static int dupe_ddw_if_already_created(struct pci_dev *dev, struct device_node *pdn)
{
struct device_node *dn;
struct pci_dn *pcidn;
struct direct_window *window;
const struct dynamic_dma_window_prop *direct64;
u64 dma_addr = 0;
dn = pci_device_to_OF_node(dev);
pcidn = PCI_DN(dn);
spin_lock(&direct_window_list_lock);
/* check if we already created a window and dupe that config if so */
list_for_each_entry(window, &direct_window_list, list) {
if (window->device == pdn) {
direct64 = window->prop;
dma_addr = direct64->dma_base;
break;
}
}
spin_unlock(&direct_window_list_lock);
return dma_addr;
}
static u64 dupe_ddw_if_kexec(struct pci_dev *dev, struct device_node *pdn)
{
struct device_node *dn;
struct pci_dn *pcidn;
int len;
struct direct_window *window;
const struct dynamic_dma_window_prop *direct64;
u64 dma_addr = 0;
dn = pci_device_to_OF_node(dev);
pcidn = PCI_DN(dn);
direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len);
if (direct64) {
window = kzalloc(sizeof(*window), GFP_KERNEL);
if (!window) {
remove_ddw(pdn);
} else {
window->device = pdn;
window->prop = direct64;
spin_lock(&direct_window_list_lock);
list_add(&window->list, &direct_window_list);
spin_unlock(&direct_window_list_lock);
dma_addr = direct64->dma_base;
}
}
return dma_addr;
}
static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail,
struct ddw_query_response *query)
{
struct device_node *dn;
struct pci_dn *pcidn;
u32 cfg_addr;
u64 buid;
int ret;
/*
* Get the config address and phb buid of the PE window.
* Rely on eeh to retrieve this for us.
* Retrieve them from the pci device, not the node with the
* dma-window property
*/
dn = pci_device_to_OF_node(dev);
pcidn = PCI_DN(dn);
cfg_addr = pcidn->eeh_config_addr;
if (pcidn->eeh_pe_config_addr)
cfg_addr = pcidn->eeh_pe_config_addr;
buid = pcidn->phb->buid;
ret = rtas_call(ddr_avail[0], 3, 5, (u32 *)query,
cfg_addr, BUID_HI(buid), BUID_LO(buid));
dev_info(&dev->dev, "ibm,query-pe-dma-windows(%x) %x %x %x"
" returned %d\n", ddr_avail[0], cfg_addr, BUID_HI(buid),
BUID_LO(buid), ret);
return ret;
}
static int create_ddw(struct pci_dev *dev, const u32 *ddr_avail,
struct ddw_create_response *create, int page_shift,
int window_shift)
{
struct device_node *dn;
struct pci_dn *pcidn;
u32 cfg_addr;
u64 buid;
int ret;
/*
* Get the config address and phb buid of the PE window.
* Rely on eeh to retrieve this for us.
* Retrieve them from the pci device, not the node with the
* dma-window property
*/
dn = pci_device_to_OF_node(dev);
pcidn = PCI_DN(dn);
cfg_addr = pcidn->eeh_config_addr;
if (pcidn->eeh_pe_config_addr)
cfg_addr = pcidn->eeh_pe_config_addr;
buid = pcidn->phb->buid;
do {
/* extra outputs are LIOBN and dma-addr (hi, lo) */
ret = rtas_call(ddr_avail[1], 5, 4, (u32 *)create, cfg_addr,
BUID_HI(buid), BUID_LO(buid), page_shift, window_shift);
} while (rtas_busy_delay(ret));
dev_info(&dev->dev,
"ibm,create-pe-dma-window(%x) %x %x %x %x %x returned %d "
"(liobn = 0x%x starting addr = %x %x)\n", ddr_avail[1],
cfg_addr, BUID_HI(buid), BUID_LO(buid), page_shift,
window_shift, ret, create->liobn, create->addr_hi, create->addr_lo);
return ret;
}
/*
* If the PE supports dynamic dma windows, and there is space for a table
* that can map all pages in a linear offset, then setup such a table,
* and record the dma-offset in the struct device.
*
* dev: the pci device we are checking
* pdn: the parent pe node with the ibm,dma_window property
* Future: also check if we can remap the base window for our base page size
*
* returns the dma offset for use by dma_set_mask
*/
static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
{
int len, ret;
struct ddw_query_response query;
struct ddw_create_response create;
int page_shift;
u64 dma_addr, max_addr;
struct device_node *dn;
const u32 *uninitialized_var(ddr_avail);
struct direct_window *window;
struct property *uninitialized_var(win64);
struct dynamic_dma_window_prop *ddwprop;
mutex_lock(&direct_window_init_mutex);
dma_addr = dupe_ddw_if_already_created(dev, pdn);
if (dma_addr != 0)
goto out_unlock;
dma_addr = dupe_ddw_if_kexec(dev, pdn);
if (dma_addr != 0)
goto out_unlock;
/*
* the ibm,ddw-applicable property holds the tokens for:
* ibm,query-pe-dma-window
* ibm,create-pe-dma-window
* ibm,remove-pe-dma-window
* for the given node in that order.
* the property is actually in the parent, not the PE
*/
ddr_avail = of_get_property(pdn, "ibm,ddw-applicable", &len);
if (!ddr_avail || len < 3 * sizeof(u32))
goto out_unlock;
/*
* Query if there is a second window of size to map the
* whole partition. Query returns number of windows, largest
* block assigned to PE (partition endpoint), and two bitmasks
* of page sizes: supported and supported for migrate-dma.
*/
dn = pci_device_to_OF_node(dev);
ret = query_ddw(dev, ddr_avail, &query);
if (ret != 0)
goto out_unlock;
if (query.windows_available == 0) {
/*
* no additional windows are available for this device.
* We might be able to reallocate the existing window,
* trading in for a larger page size.
*/
dev_dbg(&dev->dev, "no free dynamic windows");
goto out_unlock;
}
if (query.page_size & 4) {
page_shift = 24; /* 16MB */
} else if (query.page_size & 2) {
page_shift = 16; /* 64kB */
} else if (query.page_size & 1) {
page_shift = 12; /* 4kB */
} else {
dev_dbg(&dev->dev, "no supported direct page size in mask %x",
query.page_size);
goto out_unlock;
}
/* verify the window * number of ptes will map the partition */
/* check largest block * page size > max memory hotplug addr */
max_addr = memory_hotplug_max();
if (query.largest_available_block < (max_addr >> page_shift)) {
dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u "
"%llu-sized pages\n", max_addr, query.largest_available_block,
1ULL << page_shift);
goto out_unlock;
}
len = order_base_2(max_addr);
win64 = kzalloc(sizeof(struct property), GFP_KERNEL);
if (!win64) {
dev_info(&dev->dev,
"couldn't allocate property for 64bit dma window\n");
goto out_unlock;
}
win64->name = kstrdup(DIRECT64_PROPNAME, GFP_KERNEL);
win64->value = ddwprop = kmalloc(sizeof(*ddwprop), GFP_KERNEL);
if (!win64->name || !win64->value) {
dev_info(&dev->dev,
"couldn't allocate property name and value\n");
goto out_free_prop;
}
ret = create_ddw(dev, ddr_avail, &create, page_shift, len);
if (ret != 0)
goto out_free_prop;
ddwprop->liobn = cpu_to_be32(create.liobn);
ddwprop->dma_base = cpu_to_be64(of_read_number(&create.addr_hi, 2));
ddwprop->tce_shift = cpu_to_be32(page_shift);
ddwprop->window_shift = cpu_to_be32(len);
dev_dbg(&dev->dev, "created tce table LIOBN 0x%x for %s\n",
create.liobn, dn->full_name);
window = kzalloc(sizeof(*window), GFP_KERNEL);
if (!window)
goto out_clear_window;
ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT,
win64->value, tce_setrange_multi_pSeriesLP_walk);
if (ret) {
dev_info(&dev->dev, "failed to map direct window for %s: %d\n",
dn->full_name, ret);
goto out_clear_window;
}
ret = prom_add_property(pdn, win64);
if (ret) {
dev_err(&dev->dev, "unable to add dma window property for %s: %d",
pdn->full_name, ret);
goto out_clear_window;
}
window->device = pdn;
window->prop = ddwprop;
spin_lock(&direct_window_list_lock);
list_add(&window->list, &direct_window_list);
spin_unlock(&direct_window_list_lock);
dma_addr = of_read_number(&create.addr_hi, 2);
goto out_unlock;
out_clear_window:
remove_ddw(pdn);
out_free_prop:
kfree(win64->name);
kfree(win64->value);
kfree(win64);
out_unlock:
mutex_unlock(&direct_window_init_mutex);
return dma_addr;
}
static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
{
struct device_node *pdn, *dn;
@ -541,23 +1012,137 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
set_iommu_table_base(&dev->dev, pci->iommu_table);
}
static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)
{
bool ddw_enabled = false;
struct device_node *pdn, *dn;
struct pci_dev *pdev;
const void *dma_window = NULL;
u64 dma_offset;
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;
/* only attempt to use a new window if 64-bit DMA is requested */
if (!disable_ddw && dma_mask == DMA_BIT_MASK(64)) {
pdev = to_pci_dev(dev);
dn = pci_device_to_OF_node(pdev);
dev_dbg(dev, "node is %s\n", dn->full_name);
/*
* the device tree might contain the dma-window properties
* per-device and not neccesarily for the bus. So we need to
* search upwards in the tree until we either hit a dma-window
* property, OR find a parent with a table already allocated.
*/
for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
pdn = pdn->parent) {
dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
if (dma_window)
break;
}
if (pdn && PCI_DN(pdn)) {
dma_offset = enable_ddw(pdev, pdn);
if (dma_offset != 0) {
dev_info(dev, "Using 64-bit direct DMA at offset %llx\n", dma_offset);
set_dma_offset(dev, dma_offset);
set_dma_ops(dev, &dma_direct_ops);
ddw_enabled = true;
}
}
}
/* fall-through to iommu ops */
if (!ddw_enabled) {
dev_info(dev, "Using 32-bit DMA via iommu\n");
set_dma_ops(dev, &dma_iommu_ops);
}
*dev->dma_mask = dma_mask;
return 0;
}
#else /* CONFIG_PCI */
#define pci_dma_bus_setup_pSeries NULL
#define pci_dma_dev_setup_pSeries NULL
#define pci_dma_bus_setup_pSeriesLP NULL
#define pci_dma_dev_setup_pSeriesLP NULL
#define dma_set_mask_pSeriesLP NULL
#endif /* !CONFIG_PCI */
static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
void *data)
{
struct direct_window *window;
struct memory_notify *arg = data;
int ret = 0;
switch (action) {
case MEM_GOING_ONLINE:
spin_lock(&direct_window_list_lock);
list_for_each_entry(window, &direct_window_list, list) {
ret |= tce_setrange_multi_pSeriesLP(arg->start_pfn,
arg->nr_pages, window->prop);
/* XXX log error */
}
spin_unlock(&direct_window_list_lock);
break;
case MEM_CANCEL_ONLINE:
case MEM_OFFLINE:
spin_lock(&direct_window_list_lock);
list_for_each_entry(window, &direct_window_list, list) {
ret |= tce_clearrange_multi_pSeriesLP(arg->start_pfn,
arg->nr_pages, window->prop);
/* XXX log error */
}
spin_unlock(&direct_window_list_lock);
break;
default:
break;
}
if (ret && action != MEM_CANCEL_ONLINE)
return NOTIFY_BAD;
return NOTIFY_OK;
}
static struct notifier_block iommu_mem_nb = {
.notifier_call = iommu_mem_notifier,
};
static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
{
int err = NOTIFY_OK;
struct device_node *np = node;
struct pci_dn *pci = PCI_DN(np);
struct direct_window *window;
switch (action) {
case PSERIES_RECONFIG_REMOVE:
if (pci && pci->iommu_table)
iommu_free_table(pci->iommu_table, np->full_name);
spin_lock(&direct_window_list_lock);
list_for_each_entry(window, &direct_window_list, list) {
if (window->device == np) {
list_del(&window->list);
kfree(window);
break;
}
}
spin_unlock(&direct_window_list_lock);
/*
* Because the notifier runs after isolation of the
* slot, we are guaranteed any DMA window has already
* been revoked and the TCEs have been marked invalid,
* so we don't need a call to remove_ddw(np). However,
* if an additional notifier action is added before the
* isolate call, we should update this code for
* completeness with such a call.
*/
break;
default:
err = NOTIFY_DONE;
@ -587,6 +1172,7 @@ void iommu_init_early_pSeries(void)
ppc_md.tce_get = tce_get_pSeriesLP;
ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
ppc_md.dma_set_mask = dma_set_mask_pSeriesLP;
} else {
ppc_md.tce_build = tce_build_pSeries;
ppc_md.tce_free = tce_free_pSeries;
@ -597,6 +1183,7 @@ void iommu_init_early_pSeries(void)
pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
register_memory_notifier(&iommu_mem_nb);
set_pci_dma_ops(&dma_iommu_ops);
}

View File

@ -93,8 +93,18 @@ static void rtas_disable_msi(struct pci_dev *pdev)
if (!pdn)
return;
if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0)
pr_debug("rtas_msi: Setting MSIs to 0 failed!\n");
/*
* disabling MSI with the explicit interface also disables MSI-X
*/
if (rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, 0) != 0) {
/*
* may have failed because explicit interface is not
* present
*/
if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0) {
pr_debug("rtas_msi: Setting MSIs to 0 failed!\n");
}
}
}
static int rtas_query_irq_number(struct pci_dn *pdn, int offset)

View File

@ -16,6 +16,8 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/kmsg_dump.h>
#include <asm/uaccess.h>
#include <asm/nvram.h>
#include <asm/rtas.h>
@ -30,17 +32,54 @@ static int nvram_fetch, nvram_store;
static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */
static DEFINE_SPINLOCK(nvram_lock);
static long nvram_error_log_index = -1;
static long nvram_error_log_size = 0;
struct err_log_info {
int error_type;
unsigned int seq_num;
};
#define NVRAM_MAX_REQ 2079
#define NVRAM_MIN_REQ 1055
#define NVRAM_LOG_PART_NAME "ibm,rtas-log"
struct nvram_os_partition {
const char *name;
int req_size; /* desired size, in bytes */
int min_size; /* minimum acceptable size (0 means req_size) */
long size; /* size of data portion (excluding err_log_info) */
long index; /* offset of data portion of partition */
};
static struct nvram_os_partition rtas_log_partition = {
.name = "ibm,rtas-log",
.req_size = 2079,
.min_size = 1055,
.index = -1
};
static struct nvram_os_partition oops_log_partition = {
.name = "lnx,oops-log",
.req_size = 4000,
.min_size = 2000,
.index = -1
};
static const char *pseries_nvram_os_partitions[] = {
"ibm,rtas-log",
"lnx,oops-log",
NULL
};
static void oops_to_nvram(struct kmsg_dumper *dumper,
enum kmsg_dump_reason reason,
const char *old_msgs, unsigned long old_len,
const char *new_msgs, unsigned long new_len);
static struct kmsg_dumper nvram_kmsg_dumper = {
.dump = oops_to_nvram
};
/* See clobbering_unread_rtas_event() */
#define NVRAM_RTAS_READ_TIMEOUT 5 /* seconds */
static unsigned long last_unread_rtas_event; /* timestamp */
/* We preallocate oops_buf during init to avoid kmalloc during oops/panic. */
static char *oops_buf;
static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
{
@ -134,7 +173,7 @@ static ssize_t pSeries_nvram_get_size(void)
}
/* nvram_write_error_log
/* nvram_write_os_partition, nvram_write_error_log
*
* We need to buffer the error logs into nvram to ensure that we have
* the failure information to decode. If we have a severe error there
@ -156,48 +195,58 @@ static ssize_t pSeries_nvram_get_size(void)
* The 'data' section would look like (in bytes):
* +--------------+------------+-----------------------------------+
* | event_logged | sequence # | error log |
* |0 3|4 7|8 nvram_error_log_size-1|
* |0 3|4 7|8 error_log_size-1|
* +--------------+------------+-----------------------------------+
*
* event_logged: 0 if event has not been logged to syslog, 1 if it has
* sequence #: The unique sequence # for each event. (until it wraps)
* error log: The error log from event_scan
*/
int nvram_write_error_log(char * buff, int length,
unsigned int err_type, unsigned int error_log_cnt)
int nvram_write_os_partition(struct nvram_os_partition *part, char * buff,
int length, unsigned int err_type, unsigned int error_log_cnt)
{
int rc;
loff_t tmp_index;
struct err_log_info info;
if (nvram_error_log_index == -1) {
if (part->index == -1) {
return -ESPIPE;
}
if (length > nvram_error_log_size) {
length = nvram_error_log_size;
if (length > part->size) {
length = part->size;
}
info.error_type = err_type;
info.seq_num = error_log_cnt;
tmp_index = nvram_error_log_index;
tmp_index = part->index;
rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index);
if (rc <= 0) {
printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc);
pr_err("%s: Failed nvram_write (%d)\n", __FUNCTION__, rc);
return rc;
}
rc = ppc_md.nvram_write(buff, length, &tmp_index);
if (rc <= 0) {
printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc);
pr_err("%s: Failed nvram_write (%d)\n", __FUNCTION__, rc);
return rc;
}
return 0;
}
int nvram_write_error_log(char * buff, int length,
unsigned int err_type, unsigned int error_log_cnt)
{
int rc = nvram_write_os_partition(&rtas_log_partition, buff, length,
err_type, error_log_cnt);
if (!rc)
last_unread_rtas_event = get_seconds();
return rc;
}
/* nvram_read_error_log
*
* Reads nvram for error log for at most 'length'
@ -209,13 +258,13 @@ int nvram_read_error_log(char * buff, int length,
loff_t tmp_index;
struct err_log_info info;
if (nvram_error_log_index == -1)
if (rtas_log_partition.index == -1)
return -1;
if (length > nvram_error_log_size)
length = nvram_error_log_size;
if (length > rtas_log_partition.size)
length = rtas_log_partition.size;
tmp_index = nvram_error_log_index;
tmp_index = rtas_log_partition.index;
rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index);
if (rc <= 0) {
@ -244,37 +293,40 @@ int nvram_clear_error_log(void)
int clear_word = ERR_FLAG_ALREADY_LOGGED;
int rc;
if (nvram_error_log_index == -1)
if (rtas_log_partition.index == -1)
return -1;
tmp_index = nvram_error_log_index;
tmp_index = rtas_log_partition.index;
rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index);
if (rc <= 0) {
printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc);
return rc;
}
last_unread_rtas_event = 0;
return 0;
}
/* pseries_nvram_init_log_partition
/* pseries_nvram_init_os_partition
*
* This will setup the partition we need for buffering the
* error logs and cleanup partitions if needed.
* This sets up a partition with an "OS" signature.
*
* The general strategy is the following:
* 1.) If there is log partition large enough then use it.
* 2.) If there is none large enough, search
* for a free partition that is large enough.
* 3.) If there is not a free partition large enough remove
* _all_ OS partitions and consolidate the space.
* 4.) Will first try getting a chunk that will satisfy the maximum
* error log size (NVRAM_MAX_REQ).
* 5.) If the max chunk cannot be allocated then try finding a chunk
* that will satisfy the minum needed (NVRAM_MIN_REQ).
* 1.) If a partition with the indicated name already exists...
* - If it's large enough, use it.
* - Otherwise, recycle it and keep going.
* 2.) Search for a free partition that is large enough.
* 3.) If there's not a free partition large enough, recycle any obsolete
* OS partitions and try again.
* 4.) Will first try getting a chunk that will satisfy the requested size.
* 5.) If a chunk of the requested size cannot be allocated, then try finding
* a chunk that will satisfy the minum needed.
*
* Returns 0 on success, else -1.
*/
static int __init pseries_nvram_init_log_partition(void)
static int __init pseries_nvram_init_os_partition(struct nvram_os_partition
*part)
{
loff_t p;
int size;
@ -282,47 +334,76 @@ static int __init pseries_nvram_init_log_partition(void)
/* Scan nvram for partitions */
nvram_scan_partitions();
/* Lookg for ours */
p = nvram_find_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS, &size);
/* Look for ours */
p = nvram_find_partition(part->name, NVRAM_SIG_OS, &size);
/* Found one but too small, remove it */
if (p && size < NVRAM_MIN_REQ) {
pr_info("nvram: Found too small "NVRAM_LOG_PART_NAME" partition"
",removing it...");
nvram_remove_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS);
if (p && size < part->min_size) {
pr_info("nvram: Found too small %s partition,"
" removing it...\n", part->name);
nvram_remove_partition(part->name, NVRAM_SIG_OS, NULL);
p = 0;
}
/* Create one if we didn't find */
if (!p) {
p = nvram_create_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS,
NVRAM_MAX_REQ, NVRAM_MIN_REQ);
/* No room for it, try to get rid of any OS partition
* and try again
*/
p = nvram_create_partition(part->name, NVRAM_SIG_OS,
part->req_size, part->min_size);
if (p == -ENOSPC) {
pr_info("nvram: No room to create "NVRAM_LOG_PART_NAME
" partition, deleting all OS partitions...");
nvram_remove_partition(NULL, NVRAM_SIG_OS);
p = nvram_create_partition(NVRAM_LOG_PART_NAME,
NVRAM_SIG_OS, NVRAM_MAX_REQ,
NVRAM_MIN_REQ);
pr_info("nvram: No room to create %s partition, "
"deleting any obsolete OS partitions...\n",
part->name);
nvram_remove_partition(NULL, NVRAM_SIG_OS,
pseries_nvram_os_partitions);
p = nvram_create_partition(part->name, NVRAM_SIG_OS,
part->req_size, part->min_size);
}
}
if (p <= 0) {
pr_err("nvram: Failed to find or create "NVRAM_LOG_PART_NAME
" partition, err %d\n", (int)p);
return 0;
pr_err("nvram: Failed to find or create %s"
" partition, err %d\n", part->name, (int)p);
return -1;
}
nvram_error_log_index = p;
nvram_error_log_size = nvram_get_partition_size(p) -
sizeof(struct err_log_info);
part->index = p;
part->size = nvram_get_partition_size(p) - sizeof(struct err_log_info);
return 0;
}
machine_arch_initcall(pseries, pseries_nvram_init_log_partition);
static void __init nvram_init_oops_partition(int rtas_partition_exists)
{
int rc;
rc = pseries_nvram_init_os_partition(&oops_log_partition);
if (rc != 0) {
if (!rtas_partition_exists)
return;
pr_notice("nvram: Using %s partition to log both"
" RTAS errors and oops/panic reports\n",
rtas_log_partition.name);
memcpy(&oops_log_partition, &rtas_log_partition,
sizeof(rtas_log_partition));
}
oops_buf = kmalloc(oops_log_partition.size, GFP_KERNEL);
rc = kmsg_dump_register(&nvram_kmsg_dumper);
if (rc != 0) {
pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc);
kfree(oops_buf);
return;
}
}
static int __init pseries_nvram_init_log_partitions(void)
{
int rc;
rc = pseries_nvram_init_os_partition(&rtas_log_partition);
nvram_init_oops_partition(rc == 0);
return 0;
}
machine_arch_initcall(pseries, pseries_nvram_init_log_partitions);
int __init pSeries_nvram_init(void)
{
@ -353,3 +434,59 @@ int __init pSeries_nvram_init(void)
return 0;
}
/*
* Try to capture the last capture_len bytes of the printk buffer. Return
* the amount actually captured.
*/
static size_t capture_last_msgs(const char *old_msgs, size_t old_len,
const char *new_msgs, size_t new_len,
char *captured, size_t capture_len)
{
if (new_len >= capture_len) {
memcpy(captured, new_msgs + (new_len - capture_len),
capture_len);
return capture_len;
} else {
/* Grab the end of old_msgs. */
size_t old_tail_len = min(old_len, capture_len - new_len);
memcpy(captured, old_msgs + (old_len - old_tail_len),
old_tail_len);
memcpy(captured + old_tail_len, new_msgs, new_len);
return old_tail_len + new_len;
}
}
/*
* Are we using the ibm,rtas-log for oops/panic reports? And if so,
* would logging this oops/panic overwrite an RTAS event that rtas_errd
* hasn't had a chance to read and process? Return 1 if so, else 0.
*
* We assume that if rtas_errd hasn't read the RTAS event in
* NVRAM_RTAS_READ_TIMEOUT seconds, it's probably not going to.
*/
static int clobbering_unread_rtas_event(void)
{
return (oops_log_partition.index == rtas_log_partition.index
&& last_unread_rtas_event
&& get_seconds() - last_unread_rtas_event <=
NVRAM_RTAS_READ_TIMEOUT);
}
/* our kmsg_dump callback */
static void oops_to_nvram(struct kmsg_dumper *dumper,
enum kmsg_dump_reason reason,
const char *old_msgs, unsigned long old_len,
const char *new_msgs, unsigned long new_len)
{
static unsigned int oops_count = 0;
size_t text_len;
if (clobbering_unread_rtas_event())
return;
text_len = capture_last_msgs(old_msgs, old_len, new_msgs, new_len,
oops_buf, oops_log_partition.size);
(void) nvram_write_os_partition(&oops_log_partition, oops_buf,
(int) text_len, ERR_TYPE_KERNEL_PANIC, ++oops_count);
}

View File

@ -114,10 +114,13 @@ static void __init fwnmi_init(void)
static void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}
static void __init pseries_setup_i8259_cascade(void)

View File

@ -202,20 +202,20 @@ static int get_irq_server(unsigned int virq, const struct cpumask *cpumask,
#define get_irq_server(virq, cpumask, strict_check) (default_server)
#endif
static void xics_unmask_irq(unsigned int virq)
static void xics_unmask_irq(struct irq_data *d)
{
unsigned int irq;
int call_status;
int server;
pr_devel("xics: unmask virq %d\n", virq);
pr_devel("xics: unmask virq %d\n", d->irq);
irq = (unsigned int)irq_map[virq].hwirq;
irq = (unsigned int)irq_map[d->irq].hwirq;
pr_devel(" -> map to hwirq 0x%x\n", irq);
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return;
server = get_irq_server(virq, irq_to_desc(virq)->affinity, 0);
server = get_irq_server(d->irq, d->affinity, 0);
call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
DEFAULT_PRIORITY);
@ -235,61 +235,61 @@ static void xics_unmask_irq(unsigned int virq)
}
}
static unsigned int xics_startup(unsigned int virq)
static unsigned int xics_startup(struct irq_data *d)
{
/*
* The generic MSI code returns with the interrupt disabled on the
* card, using the MSI mask bits. Firmware doesn't appear to unmask
* at that level, so we do it here by hand.
*/
if (irq_to_desc(virq)->msi_desc)
unmask_msi_irq(irq_get_irq_data(virq));
if (d->msi_desc)
unmask_msi_irq(d);
/* unmask it */
xics_unmask_irq(virq);
xics_unmask_irq(d);
return 0;
}
static void xics_mask_real_irq(unsigned int irq)
static void xics_mask_real_irq(struct irq_data *d)
{
int call_status;
if (irq == XICS_IPI)
if (d->irq == XICS_IPI)
return;
call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
call_status = rtas_call(ibm_int_off, 1, 1, NULL, d->irq);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
__func__, irq, call_status);
__func__, d->irq, call_status);
return;
}
/* Have to set XIVE to 0xff to be able to remove a slot */
call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq,
call_status = rtas_call(ibm_set_xive, 3, 1, NULL, d->irq,
default_server, 0xff);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
__func__, irq, call_status);
__func__, d->irq, call_status);
return;
}
}
static void xics_mask_irq(unsigned int virq)
static void xics_mask_irq(struct irq_data *d)
{
unsigned int irq;
pr_devel("xics: mask virq %d\n", virq);
pr_devel("xics: mask virq %d\n", d->irq);
irq = (unsigned int)irq_map[virq].hwirq;
irq = (unsigned int)irq_map[d->irq].hwirq;
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return;
xics_mask_real_irq(irq);
xics_mask_real_irq(d);
}
static void xics_mask_unknown_vec(unsigned int vec)
{
printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
xics_mask_real_irq(vec);
xics_mask_real_irq(irq_get_irq_data(vec));
}
static inline unsigned int xics_xirr_vector(unsigned int xirr)
@ -371,30 +371,31 @@ static unsigned char pop_cppr(void)
return os_cppr->stack[--os_cppr->index];
}
static void xics_eoi_direct(unsigned int virq)
static void xics_eoi_direct(struct irq_data *d)
{
unsigned int irq = (unsigned int)irq_map[virq].hwirq;
unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
iosync();
direct_xirr_info_set((pop_cppr() << 24) | irq);
}
static void xics_eoi_lpar(unsigned int virq)
static void xics_eoi_lpar(struct irq_data *d)
{
unsigned int irq = (unsigned int)irq_map[virq].hwirq;
unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
iosync();
lpar_xirr_info_set((pop_cppr() << 24) | irq);
}
static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
static int
xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
{
unsigned int irq;
int status;
int xics_status[2];
int irq_server;
irq = (unsigned int)irq_map[virq].hwirq;
irq = (unsigned int)irq_map[d->irq].hwirq;
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return -1;
@ -406,13 +407,13 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
return -1;
}
irq_server = get_irq_server(virq, cpumask, 1);
irq_server = get_irq_server(d->irq, cpumask, 1);
if (irq_server == -1) {
char cpulist[128];
cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
printk(KERN_WARNING
"%s: No online cpus in the mask %s for irq %d\n",
__func__, cpulist, virq);
__func__, cpulist, d->irq);
return -1;
}
@ -430,20 +431,20 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
static struct irq_chip xics_pic_direct = {
.name = "XICS",
.startup = xics_startup,
.mask = xics_mask_irq,
.unmask = xics_unmask_irq,
.eoi = xics_eoi_direct,
.set_affinity = xics_set_affinity
.irq_startup = xics_startup,
.irq_mask = xics_mask_irq,
.irq_unmask = xics_unmask_irq,
.irq_eoi = xics_eoi_direct,
.irq_set_affinity = xics_set_affinity
};
static struct irq_chip xics_pic_lpar = {
.name = "XICS",
.startup = xics_startup,
.mask = xics_mask_irq,
.unmask = xics_unmask_irq,
.eoi = xics_eoi_lpar,
.set_affinity = xics_set_affinity
.irq_startup = xics_startup,
.irq_mask = xics_mask_irq,
.irq_unmask = xics_unmask_irq,
.irq_eoi = xics_eoi_lpar,
.irq_set_affinity = xics_set_affinity
};
@ -890,6 +891,7 @@ void xics_migrate_irqs_away(void)
for_each_irq(virq) {
struct irq_desc *desc;
struct irq_chip *chip;
int xics_status[2];
int status;
unsigned long flags;
@ -903,12 +905,15 @@ void xics_migrate_irqs_away(void)
/* We need to get IPIs still. */
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
continue;
desc = irq_to_desc(virq);
/* We only need to migrate enabled IRQS */
if (desc == NULL || desc->chip == NULL
|| desc->action == NULL
|| desc->chip->set_affinity == NULL)
if (desc == NULL || desc->action == NULL)
continue;
chip = get_irq_desc_chip(desc);
if (chip == NULL || chip->irq_set_affinity == NULL)
continue;
raw_spin_lock_irqsave(&desc->lock, flags);
@ -934,8 +939,8 @@ void xics_migrate_irqs_away(void)
virq, cpu);
/* Reset affinity to all cpus */
cpumask_setall(irq_to_desc(virq)->affinity);
desc->chip->set_affinity(virq, cpu_all_mask);
cpumask_setall(desc->irq_data.affinity);
chip->irq_set_affinity(&desc->irq_data, cpu_all_mask, true);
unlock:
raw_spin_unlock_irqrestore(&desc->lock, flags);
}

View File

@ -56,32 +56,32 @@ static cpic8xx_t __iomem *cpic_reg;
static struct irq_host *cpm_pic_host;
static void cpm_mask_irq(unsigned int irq)
static void cpm_mask_irq(struct irq_data *d)
{
unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
}
static void cpm_unmask_irq(unsigned int irq)
static void cpm_unmask_irq(struct irq_data *d)
{
unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
}
static void cpm_end_irq(unsigned int irq)
static void cpm_end_irq(struct irq_data *d)
{
unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
}
static struct irq_chip cpm_pic = {
.name = "CPM PIC",
.mask = cpm_mask_irq,
.unmask = cpm_unmask_irq,
.eoi = cpm_end_irq,
.irq_mask = cpm_mask_irq,
.irq_unmask = cpm_unmask_irq,
.irq_eoi = cpm_end_irq,
};
int cpm_get_irq(void)

View File

@ -78,10 +78,10 @@ static const u_char irq_to_siubit[] = {
24, 25, 26, 27, 28, 29, 30, 31,
};
static void cpm2_mask_irq(unsigned int virq)
static void cpm2_mask_irq(struct irq_data *d)
{
int bit, word;
unsigned int irq_nr = virq_to_hw(virq);
unsigned int irq_nr = virq_to_hw(d->irq);
bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[irq_nr];
@ -90,10 +90,10 @@ static void cpm2_mask_irq(unsigned int virq)
out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
}
static void cpm2_unmask_irq(unsigned int virq)
static void cpm2_unmask_irq(struct irq_data *d)
{
int bit, word;
unsigned int irq_nr = virq_to_hw(virq);
unsigned int irq_nr = virq_to_hw(d->irq);
bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[irq_nr];
@ -102,10 +102,10 @@ static void cpm2_unmask_irq(unsigned int virq)
out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
}
static void cpm2_ack(unsigned int virq)
static void cpm2_ack(struct irq_data *d)
{
int bit, word;
unsigned int irq_nr = virq_to_hw(virq);
unsigned int irq_nr = virq_to_hw(d->irq);
bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[irq_nr];
@ -113,11 +113,11 @@ static void cpm2_ack(unsigned int virq)
out_be32(&cpm2_intctl->ic_sipnrh + word, 1 << bit);
}
static void cpm2_end_irq(unsigned int virq)
static void cpm2_end_irq(struct irq_data *d)
{
struct irq_desc *desc;
int bit, word;
unsigned int irq_nr = virq_to_hw(virq);
unsigned int irq_nr = virq_to_hw(d->irq);
desc = irq_to_desc(irq_nr);
if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))
@ -137,10 +137,10 @@ static void cpm2_end_irq(unsigned int virq)
}
}
static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type)
static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
unsigned int src = virq_to_hw(virq);
struct irq_desc *desc = irq_to_desc(virq);
unsigned int src = virq_to_hw(d->irq);
struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vold, vnew, edibit;
/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
@ -199,11 +199,11 @@ err_sense:
static struct irq_chip cpm2_pic = {
.name = "CPM2 SIU",
.mask = cpm2_mask_irq,
.unmask = cpm2_unmask_irq,
.ack = cpm2_ack,
.eoi = cpm2_end_irq,
.set_type = cpm2_set_irq_type,
.irq_mask = cpm2_mask_irq,
.irq_unmask = cpm2_unmask_irq,
.irq_ack = cpm2_ack,
.irq_eoi = cpm2_end_irq,
.irq_set_type = cpm2_set_irq_type,
};
unsigned int cpm2_get_irq(void)

View File

@ -93,14 +93,14 @@ static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev)
l2cache_size = *prop;
sram_params.sram_size = get_cache_sram_size();
if (sram_params.sram_size <= 0) {
if ((int)sram_params.sram_size <= 0) {
dev_err(&dev->dev,
"Entire L2 as cache, Aborting Cache-SRAM stuff\n");
return -EINVAL;
}
sram_params.sram_offset = get_cache_sram_offset();
if (sram_params.sram_offset <= 0) {
if ((int64_t)sram_params.sram_offset <= 0) {
dev_err(&dev->dev,
"Entire L2 as cache, provide a valid sram offset\n");
return -EINVAL;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2010 Freescale Semiconductor, Inc.
* Copyright (C) 2007-2011 Freescale Semiconductor, Inc.
*
* Author: Tony Li <tony.li@freescale.com>
* Jason Jin <Jason.jin@freescale.com>
@ -47,14 +47,14 @@ static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg)
* We do not need this actually. The MSIR register has been read once
* in the cascade interrupt. So, this MSI interrupt has been acked
*/
static void fsl_msi_end_irq(unsigned int virq)
static void fsl_msi_end_irq(struct irq_data *d)
{
}
static struct irq_chip fsl_msi_chip = {
.irq_mask = mask_msi_irq,
.irq_unmask = unmask_msi_irq,
.ack = fsl_msi_end_irq,
.irq_ack = fsl_msi_end_irq,
.name = "FSL-MSI",
};
@ -183,6 +183,7 @@ out_free:
static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq;
struct fsl_msi *msi_data;
int msir_index = -1;
@ -196,11 +197,11 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
raw_spin_lock(&desc->lock);
if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
if (desc->chip->mask_ack)
desc->chip->mask_ack(irq);
if (chip->irq_mask_ack)
chip->irq_mask_ack(&desc->irq_data);
else {
desc->chip->mask(irq);
desc->chip->ack(irq);
chip->irq_mask(&desc->irq_data);
chip->irq_ack(&desc->irq_data);
}
}
@ -238,11 +239,11 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
switch (msi_data->feature & FSL_PIC_IP_MASK) {
case FSL_PIC_IP_MPIC:
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
break;
case FSL_PIC_IP_IPIC:
if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
desc->chip->unmask(irq);
if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
chip->irq_unmask(&desc->irq_data);
break;
}
unlock:
@ -273,18 +274,46 @@ static int fsl_of_msi_remove(struct platform_device *ofdev)
return 0;
}
static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi,
struct platform_device *dev,
int offset, int irq_index)
{
struct fsl_msi_cascade_data *cascade_data = NULL;
int virt_msir;
virt_msir = irq_of_parse_and_map(dev->dev.of_node, irq_index);
if (virt_msir == NO_IRQ) {
dev_err(&dev->dev, "%s: Cannot translate IRQ index %d\n",
__func__, irq_index);
return 0;
}
cascade_data = kzalloc(sizeof(struct fsl_msi_cascade_data), GFP_KERNEL);
if (!cascade_data) {
dev_err(&dev->dev, "No memory for MSI cascade data\n");
return -ENOMEM;
}
msi->msi_virqs[irq_index] = virt_msir;
cascade_data->index = offset + irq_index;
cascade_data->msi_data = msi;
set_irq_data(virt_msir, cascade_data);
set_irq_chained_handler(virt_msir, fsl_msi_cascade);
return 0;
}
static int __devinit fsl_of_msi_probe(struct platform_device *dev)
{
struct fsl_msi *msi;
struct resource res;
int err, i, count;
int err, i, j, irq_index, count;
int rc;
int virt_msir;
const u32 *p;
struct fsl_msi_feature *features;
struct fsl_msi_cascade_data *cascade_data = NULL;
int len;
u32 offset;
static const u32 all_avail[] = { 0, NR_MSI_IRQS };
if (!dev->dev.of_match)
return -EINVAL;
@ -335,42 +364,34 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
goto error_out;
}
p = of_get_property(dev->dev.of_node, "interrupts", &count);
if (!p) {
dev_err(&dev->dev, "no interrupts property found on %s\n",
dev->dev.of_node->full_name);
err = -ENODEV;
goto error_out;
}
if (count % 8 != 0) {
dev_err(&dev->dev, "Malformed interrupts property on %s\n",
dev->dev.of_node->full_name);
p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
if (p && len % (2 * sizeof(u32)) != 0) {
dev_err(&dev->dev, "%s: Malformed msi-available-ranges property\n",
__func__);
err = -EINVAL;
goto error_out;
}
offset = 0;
p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
if (p)
offset = *p / IRQS_PER_MSI_REG;
count /= sizeof(u32);
for (i = 0; i < min(count / 2, NR_MSI_REG); i++) {
virt_msir = irq_of_parse_and_map(dev->dev.of_node, i);
if (virt_msir != NO_IRQ) {
cascade_data = kzalloc(
sizeof(struct fsl_msi_cascade_data),
GFP_KERNEL);
if (!cascade_data) {
dev_err(&dev->dev,
"No memory for MSI cascade data\n");
err = -ENOMEM;
if (!p)
p = all_avail;
for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) {
if (p[i * 2] % IRQS_PER_MSI_REG ||
p[i * 2 + 1] % IRQS_PER_MSI_REG) {
printk(KERN_WARNING "%s: %s: msi available range of %u at %u is not IRQ-aligned\n",
__func__, dev->dev.of_node->full_name,
p[i * 2 + 1], p[i * 2]);
err = -EINVAL;
goto error_out;
}
offset = p[i * 2] / IRQS_PER_MSI_REG;
count = p[i * 2 + 1] / IRQS_PER_MSI_REG;
for (j = 0; j < count; j++, irq_index++) {
err = fsl_msi_setup_hwirq(msi, dev, offset, irq_index);
if (err)
goto error_out;
}
msi->msi_virqs[i] = virt_msir;
cascade_data->index = i + offset;
cascade_data->msi_data = msi;
set_irq_data(virt_msir, (void *)cascade_data);
set_irq_chained_handler(virt_msir, fsl_msi_cascade);
}
}

View File

@ -1,7 +1,7 @@
/*
* MPC83xx/85xx/86xx PCI/PCIE support routing.
*
* Copyright 2007-2010 Freescale Semiconductor, Inc.
* Copyright 2007-2011 Freescale Semiconductor, Inc.
* Copyright 2008-2009 MontaVista Software, Inc.
*
* Initial author: Xianghua Xiao <x.xiao@freescale.com>
@ -99,7 +99,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
struct resource *rsrc)
{
struct ccsr_pci __iomem *pci;
int i, j, n, mem_log, win_idx = 2;
int i, j, n, mem_log, win_idx = 3, start_idx = 1, end_idx = 4;
u64 mem, sz, paddr_hi = 0;
u64 paddr_lo = ULLONG_MAX;
u32 pcicsrbar = 0, pcicsrbar_sz;
@ -109,6 +109,13 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
(u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1);
if (of_device_is_compatible(hose->dn, "fsl,qoriq-pcie-v2.2")) {
win_idx = 2;
start_idx = 0;
end_idx = 3;
}
pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);
if (!pci) {
dev_err(hose->parent, "Unable to map ATMU registers\n");
@ -118,7 +125,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
/* Disable all windows (except powar0 since it's ignored) */
for(i = 1; i < 5; i++)
out_be32(&pci->pow[i].powar, 0);
for(i = 0; i < 3; i++)
for (i = start_idx; i < end_idx; i++)
out_be32(&pci->piw[i].piwar, 0);
/* Setup outbound MEM window */
@ -204,7 +211,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
mem_log++;
}
piwar |= (mem_log - 1);
piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
/* Setup inbound memory window */
out_be32(&pci->piw[win_idx].pitar, 0x00000000);

View File

@ -1,7 +1,7 @@
/*
* MPC85xx/86xx PCI Express structure define
*
* Copyright 2007 Freescale Semiconductor, Inc
* Copyright 2007,2011 Freescale Semiconductor, Inc
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -21,6 +21,7 @@
#define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */
#define PIWAR_READ_SNOOP 0x00050000
#define PIWAR_WRITE_SNOOP 0x00005000
#define PIWAR_SZ_MASK 0x0000003f
/* PCI/PCI Express outbound window reg */
struct pci_outbound_window_regs {
@ -49,7 +50,9 @@ struct ccsr_pci {
__be32 int_ack; /* 0x.008 - PCI Interrupt Acknowledge Register */
__be32 pex_otb_cpl_tor; /* 0x.00c - PCIE Outbound completion timeout register */
__be32 pex_conf_tor; /* 0x.010 - PCIE configuration timeout register */
u8 res2[12];
__be32 pex_config; /* 0x.014 - PCIE CONFIG Register */
__be32 pex_int_status; /* 0x.018 - PCIE interrupt status */
u8 res2[4];
__be32 pex_pme_mes_dr; /* 0x.020 - PCIE PME and message detect register */
__be32 pex_pme_mes_disr; /* 0x.024 - PCIE PME and message disable register */
__be32 pex_pme_mes_ier; /* 0x.028 - PCIE PME and message interrupt enable register */
@ -62,14 +65,14 @@ struct ccsr_pci {
* in all of the other outbound windows.
*/
struct pci_outbound_window_regs pow[5];
u8 res14[256];
/* PCI/PCI Express inbound window 3-1
u8 res14[96];
struct pci_inbound_window_regs pmit; /* 0xd00 - 0xd9c Inbound MSI */
u8 res6[96];
/* PCI/PCI Express inbound window 3-0
* inbound window 1 supports only a 32-bit base address and does not
* define an inbound window base extended address register.
*/
struct pci_inbound_window_regs piw[3];
struct pci_inbound_window_regs piw[4];
__be32 pex_err_dr; /* 0x.e00 - PCI/PCIE error detect register */
u8 res21[4];

View File

@ -78,19 +78,19 @@ unsigned int i8259_irq(void)
return irq;
}
static void i8259_mask_and_ack_irq(unsigned int irq_nr)
static void i8259_mask_and_ack_irq(struct irq_data *d)
{
unsigned long flags;
raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr > 7) {
cached_A1 |= 1 << (irq_nr-8);
if (d->irq > 7) {
cached_A1 |= 1 << (d->irq-8);
inb(0xA1); /* DUMMY */
outb(cached_A1, 0xA1);
outb(0x20, 0xA0); /* Non-specific EOI */
outb(0x20, 0x20); /* Non-specific EOI to cascade */
} else {
cached_21 |= 1 << irq_nr;
cached_21 |= 1 << d->irq;
inb(0x21); /* DUMMY */
outb(cached_21, 0x21);
outb(0x20, 0x20); /* Non-specific EOI */
@ -104,42 +104,42 @@ static void i8259_set_irq_mask(int irq_nr)
outb(cached_21,0x21);
}
static void i8259_mask_irq(unsigned int irq_nr)
static void i8259_mask_irq(struct irq_data *d)
{
unsigned long flags;
pr_debug("i8259_mask_irq(%d)\n", irq_nr);
pr_debug("i8259_mask_irq(%d)\n", d->irq);
raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr < 8)
cached_21 |= 1 << irq_nr;
if (d->irq < 8)
cached_21 |= 1 << d->irq;
else
cached_A1 |= 1 << (irq_nr-8);
i8259_set_irq_mask(irq_nr);
cached_A1 |= 1 << (d->irq-8);
i8259_set_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&i8259_lock, flags);
}
static void i8259_unmask_irq(unsigned int irq_nr)
static void i8259_unmask_irq(struct irq_data *d)
{
unsigned long flags;
pr_debug("i8259_unmask_irq(%d)\n", irq_nr);
pr_debug("i8259_unmask_irq(%d)\n", d->irq);
raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr < 8)
cached_21 &= ~(1 << irq_nr);
if (d->irq < 8)
cached_21 &= ~(1 << d->irq);
else
cached_A1 &= ~(1 << (irq_nr-8));
i8259_set_irq_mask(irq_nr);
cached_A1 &= ~(1 << (d->irq-8));
i8259_set_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&i8259_lock, flags);
}
static struct irq_chip i8259_pic = {
.name = "i8259",
.mask = i8259_mask_irq,
.disable = i8259_mask_irq,
.unmask = i8259_unmask_irq,
.mask_ack = i8259_mask_and_ack_irq,
.irq_mask = i8259_mask_irq,
.irq_disable = i8259_mask_irq,
.irq_unmask = i8259_unmask_irq,
.irq_mask_ack = i8259_mask_and_ack_irq,
};
static struct resource pic1_iores = {
@ -188,7 +188,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
{
/* Make sure irq is masked in hardware */
i8259_mask_irq(virq);
i8259_mask_irq(irq_get_irq_data(virq));
/* remove chip and handler */
set_irq_chip_and_handler(virq, NULL, NULL);

View File

@ -523,10 +523,10 @@ static inline struct ipic * ipic_from_irq(unsigned int virq)
#define ipic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
static void ipic_unmask_irq(unsigned int virq)
static void ipic_unmask_irq(struct irq_data *d)
{
struct ipic *ipic = ipic_from_irq(virq);
unsigned int src = ipic_irq_to_hw(virq);
struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(d->irq);
unsigned long flags;
u32 temp;
@ -539,10 +539,10 @@ static void ipic_unmask_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&ipic_lock, flags);
}
static void ipic_mask_irq(unsigned int virq)
static void ipic_mask_irq(struct irq_data *d)
{
struct ipic *ipic = ipic_from_irq(virq);
unsigned int src = ipic_irq_to_hw(virq);
struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(d->irq);
unsigned long flags;
u32 temp;
@ -559,10 +559,10 @@ static void ipic_mask_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&ipic_lock, flags);
}
static void ipic_ack_irq(unsigned int virq)
static void ipic_ack_irq(struct irq_data *d)
{
struct ipic *ipic = ipic_from_irq(virq);
unsigned int src = ipic_irq_to_hw(virq);
struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(d->irq);
unsigned long flags;
u32 temp;
@ -578,10 +578,10 @@ static void ipic_ack_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&ipic_lock, flags);
}
static void ipic_mask_irq_and_ack(unsigned int virq)
static void ipic_mask_irq_and_ack(struct irq_data *d)
{
struct ipic *ipic = ipic_from_irq(virq);
unsigned int src = ipic_irq_to_hw(virq);
struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(d->irq);
unsigned long flags;
u32 temp;
@ -601,11 +601,11 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
raw_spin_unlock_irqrestore(&ipic_lock, flags);
}
static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
struct ipic *ipic = ipic_from_irq(virq);
unsigned int src = ipic_irq_to_hw(virq);
struct irq_desc *desc = irq_to_desc(virq);
struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(d->irq);
struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vold, vnew, edibit;
if (flow_type == IRQ_TYPE_NONE)
@ -630,10 +630,10 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
if (flow_type & IRQ_TYPE_LEVEL_LOW) {
desc->status |= IRQ_LEVEL;
desc->handle_irq = handle_level_irq;
desc->chip = &ipic_level_irq_chip;
desc->irq_data.chip = &ipic_level_irq_chip;
} else {
desc->handle_irq = handle_edge_irq;
desc->chip = &ipic_edge_irq_chip;
desc->irq_data.chip = &ipic_edge_irq_chip;
}
/* only EXT IRQ senses are programmable on ipic
@ -661,19 +661,19 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
/* level interrupts and edge interrupts have different ack operations */
static struct irq_chip ipic_level_irq_chip = {
.name = "IPIC",
.unmask = ipic_unmask_irq,
.mask = ipic_mask_irq,
.mask_ack = ipic_mask_irq,
.set_type = ipic_set_irq_type,
.irq_unmask = ipic_unmask_irq,
.irq_mask = ipic_mask_irq,
.irq_mask_ack = ipic_mask_irq,
.irq_set_type = ipic_set_irq_type,
};
static struct irq_chip ipic_edge_irq_chip = {
.name = "IPIC",
.unmask = ipic_unmask_irq,
.mask = ipic_mask_irq,
.mask_ack = ipic_mask_irq_and_ack,
.ack = ipic_ack_irq,
.set_type = ipic_set_irq_type,
.irq_unmask = ipic_unmask_irq,
.irq_mask = ipic_mask_irq,
.irq_mask_ack = ipic_mask_irq_and_ack,
.irq_ack = ipic_ack_irq,
.irq_set_type = ipic_set_irq_type,
};
static int ipic_host_match(struct irq_host *h, struct device_node *node)

View File

@ -25,10 +25,10 @@ static sysconf8xx_t __iomem *siu_reg;
int cpm_get_irq(struct pt_regs *regs);
static void mpc8xx_unmask_irq(unsigned int virq)
static void mpc8xx_unmask_irq(struct irq_data *d)
{
int bit, word;
unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
bit = irq_nr & 0x1f;
word = irq_nr >> 5;
@ -37,10 +37,10 @@ static void mpc8xx_unmask_irq(unsigned int virq)
out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
}
static void mpc8xx_mask_irq(unsigned int virq)
static void mpc8xx_mask_irq(struct irq_data *d)
{
int bit, word;
unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
bit = irq_nr & 0x1f;
word = irq_nr >> 5;
@ -49,19 +49,19 @@ static void mpc8xx_mask_irq(unsigned int virq)
out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
}
static void mpc8xx_ack(unsigned int virq)
static void mpc8xx_ack(struct irq_data *d)
{
int bit;
unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
bit = irq_nr & 0x1f;
out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
}
static void mpc8xx_end_irq(unsigned int virq)
static void mpc8xx_end_irq(struct irq_data *d)
{
int bit, word;
unsigned int irq_nr = (unsigned int)irq_map[virq].hwirq;
unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
bit = irq_nr & 0x1f;
word = irq_nr >> 5;
@ -70,9 +70,9 @@ static void mpc8xx_end_irq(unsigned int virq)
out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
}
static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
struct irq_desc *desc = irq_to_desc(virq);
struct irq_desc *desc = irq_to_desc(d->irq);
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
@ -80,7 +80,7 @@ static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
desc->status |= IRQ_LEVEL;
if (flow_type & IRQ_TYPE_EDGE_FALLING) {
irq_hw_number_t hw = (unsigned int)irq_map[virq].hwirq;
irq_hw_number_t hw = (unsigned int)irq_map[d->irq].hwirq;
unsigned int siel = in_be32(&siu_reg->sc_siel);
/* only external IRQ senses are programmable */
@ -95,11 +95,11 @@ static int mpc8xx_set_irq_type(unsigned int virq, unsigned int flow_type)
static struct irq_chip mpc8xx_pic = {
.name = "MPC8XX SIU",
.unmask = mpc8xx_unmask_irq,
.mask = mpc8xx_mask_irq,
.ack = mpc8xx_ack,
.eoi = mpc8xx_end_irq,
.set_type = mpc8xx_set_irq_type,
.irq_unmask = mpc8xx_unmask_irq,
.irq_mask = mpc8xx_mask_irq,
.irq_ack = mpc8xx_ack,
.irq_eoi = mpc8xx_end_irq,
.irq_set_type = mpc8xx_set_irq_type,
};
unsigned int mpc8xx_get_irq(void)

View File

@ -155,43 +155,43 @@ static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
32 - ffs(mask)));
}
static void mpc8xxx_irq_unmask(unsigned int virq)
static void mpc8xxx_irq_unmask(struct irq_data *d)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
unsigned long flags;
spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq)));
setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
}
static void mpc8xxx_irq_mask(unsigned int virq)
static void mpc8xxx_irq_mask(struct irq_data *d)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
unsigned long flags;
spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq)));
clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
}
static void mpc8xxx_irq_ack(unsigned int virq)
static void mpc8xxx_irq_ack(struct irq_data *d)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(virq)));
out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
}
static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
unsigned long flags;
@ -199,14 +199,14 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
case IRQ_TYPE_EDGE_FALLING:
spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
setbits32(mm->regs + GPIO_ICR,
mpc8xxx_gpio2mask(virq_to_hw(virq)));
mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
break;
case IRQ_TYPE_EDGE_BOTH:
spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
clrbits32(mm->regs + GPIO_ICR,
mpc8xxx_gpio2mask(virq_to_hw(virq)));
mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
break;
@ -217,11 +217,11 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
return 0;
}
static int mpc512x_irq_set_type(unsigned int virq, unsigned int flow_type)
static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
unsigned long gpio = virq_to_hw(virq);
unsigned long gpio = virq_to_hw(d->irq);
void __iomem *reg;
unsigned int shift;
unsigned long flags;
@ -264,10 +264,10 @@ static int mpc512x_irq_set_type(unsigned int virq, unsigned int flow_type)
static struct irq_chip mpc8xxx_irq_chip = {
.name = "mpc8xxx-gpio",
.unmask = mpc8xxx_irq_unmask,
.mask = mpc8xxx_irq_mask,
.ack = mpc8xxx_irq_ack,
.set_type = mpc8xxx_irq_set_type,
.irq_unmask = mpc8xxx_irq_unmask,
.irq_mask = mpc8xxx_irq_mask,
.irq_ack = mpc8xxx_irq_ack,
.irq_set_type = mpc8xxx_irq_set_type,
};
static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
@ -276,7 +276,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
if (mpc8xxx_gc->of_dev_id_data)
mpc8xxx_irq_chip.set_type = mpc8xxx_gc->of_dev_id_data;
mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
set_irq_chip_data(virq, h->host_data);
set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
@ -310,6 +310,7 @@ static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
{ .compatible = "fsl,mpc8572-gpio", },
{ .compatible = "fsl,mpc8610-gpio", },
{ .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
{ .compatible = "fsl,qoriq-gpio", },
{}
};
@ -389,9 +390,6 @@ static int __init mpc8xxx_add_gpiochips(void)
for_each_matching_node(np, mpc8xxx_gpio_ids)
mpc8xxx_add_controller(np);
for_each_compatible_node(np, NULL, "fsl,qoriq-gpio")
mpc8xxx_add_controller(np);
return 0;
}
arch_initcall(mpc8xxx_add_gpiochips);

View File

@ -611,7 +611,7 @@ static struct mpic *mpic_find(unsigned int irq)
if (irq < NUM_ISA_INTERRUPTS)
return NULL;
return irq_to_desc(irq)->chip_data;
return get_irq_chip_data(irq);
}
/* Determine if the linux irq is an IPI */
@ -636,16 +636,22 @@ static inline u32 mpic_physmask(u32 cpumask)
#ifdef CONFIG_SMP
/* Get the mpic structure from the IPI number */
static inline struct mpic * mpic_from_ipi(unsigned int ipi)
static inline struct mpic * mpic_from_ipi(struct irq_data *d)
{
return irq_to_desc(ipi)->chip_data;
return irq_data_get_irq_chip_data(d);
}
#endif
/* Get the mpic structure from the irq number */
static inline struct mpic * mpic_from_irq(unsigned int irq)
{
return irq_to_desc(irq)->chip_data;
return get_irq_chip_data(irq);
}
/* Get the mpic structure from the irq data */
static inline struct mpic * mpic_from_irq_data(struct irq_data *d)
{
return irq_data_get_irq_chip_data(d);
}
/* Send an EOI */
@ -660,13 +666,13 @@ static inline void mpic_eoi(struct mpic *mpic)
*/
void mpic_unmask_irq(unsigned int irq)
void mpic_unmask_irq(struct irq_data *d)
{
unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
@ -681,13 +687,13 @@ void mpic_unmask_irq(unsigned int irq)
} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
}
void mpic_mask_irq(unsigned int irq)
void mpic_mask_irq(struct irq_data *d)
{
unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
@ -703,12 +709,12 @@ void mpic_mask_irq(unsigned int irq)
} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
}
void mpic_end_irq(unsigned int irq)
void mpic_end_irq(struct irq_data *d)
{
struct mpic *mpic = mpic_from_irq(irq);
struct mpic *mpic = mpic_from_irq_data(d);
#ifdef DEBUG_IRQ
DBG("%s: end_irq: %d\n", mpic->name, irq);
DBG("%s: end_irq: %d\n", mpic->name, d->irq);
#endif
/* We always EOI on end_irq() even for edge interrupts since that
* should only lower the priority, the MPIC should have properly
@ -720,51 +726,51 @@ void mpic_end_irq(unsigned int irq)
#ifdef CONFIG_MPIC_U3_HT_IRQS
static void mpic_unmask_ht_irq(unsigned int irq)
static void mpic_unmask_ht_irq(struct irq_data *d)
{
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
mpic_unmask_irq(irq);
mpic_unmask_irq(d);
if (irq_to_desc(irq)->status & IRQ_LEVEL)
if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
mpic_ht_end_irq(mpic, src);
}
static unsigned int mpic_startup_ht_irq(unsigned int irq)
static unsigned int mpic_startup_ht_irq(struct irq_data *d)
{
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
mpic_unmask_irq(irq);
mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
mpic_unmask_irq(d);
mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
return 0;
}
static void mpic_shutdown_ht_irq(unsigned int irq)
static void mpic_shutdown_ht_irq(struct irq_data *d)
{
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
mpic_mask_irq(irq);
mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
mpic_mask_irq(d);
}
static void mpic_end_ht_irq(unsigned int irq)
static void mpic_end_ht_irq(struct irq_data *d)
{
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
#ifdef DEBUG_IRQ
DBG("%s: end_irq: %d\n", mpic->name, irq);
DBG("%s: end_irq: %d\n", mpic->name, d->irq);
#endif
/* We always EOI on end_irq() even for edge interrupts since that
* should only lower the priority, the MPIC should have properly
* latched another edge interrupt coming in anyway
*/
if (irq_to_desc(irq)->status & IRQ_LEVEL)
if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
mpic_ht_end_irq(mpic, src);
mpic_eoi(mpic);
}
@ -772,23 +778,23 @@ static void mpic_end_ht_irq(unsigned int irq)
#ifdef CONFIG_SMP
static void mpic_unmask_ipi(unsigned int irq)
static void mpic_unmask_ipi(struct irq_data *d)
{
struct mpic *mpic = mpic_from_ipi(irq);
unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
struct mpic *mpic = mpic_from_ipi(d);
unsigned int src = mpic_irq_to_hw(d->irq) - mpic->ipi_vecs[0];
DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, d->irq, src);
mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
}
static void mpic_mask_ipi(unsigned int irq)
static void mpic_mask_ipi(struct irq_data *d)
{
/* NEVER disable an IPI... that's just plain wrong! */
}
static void mpic_end_ipi(unsigned int irq)
static void mpic_end_ipi(struct irq_data *d)
{
struct mpic *mpic = mpic_from_ipi(irq);
struct mpic *mpic = mpic_from_ipi(d);
/*
* IPIs are marked IRQ_PER_CPU. This has the side effect of
@ -802,10 +808,11 @@ static void mpic_end_ipi(unsigned int irq)
#endif /* CONFIG_SMP */
int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
bool force)
{
struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq);
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
int cpuid = irq_choose_cpu(cpumask);
@ -848,15 +855,15 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
}
}
int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
struct mpic *mpic = mpic_from_irq(virq);
unsigned int src = mpic_irq_to_hw(virq);
struct irq_desc *desc = irq_to_desc(virq);
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vecpri, vold, vnew;
DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
mpic, virq, src, flow_type);
mpic, d->irq, src, flow_type);
if (src >= mpic->irq_count)
return -EINVAL;
@ -907,28 +914,28 @@ void mpic_set_vector(unsigned int virq, unsigned int vector)
}
static struct irq_chip mpic_irq_chip = {
.mask = mpic_mask_irq,
.unmask = mpic_unmask_irq,
.eoi = mpic_end_irq,
.set_type = mpic_set_irq_type,
.irq_mask = mpic_mask_irq,
.irq_unmask = mpic_unmask_irq,
.irq_eoi = mpic_end_irq,
.irq_set_type = mpic_set_irq_type,
};
#ifdef CONFIG_SMP
static struct irq_chip mpic_ipi_chip = {
.mask = mpic_mask_ipi,
.unmask = mpic_unmask_ipi,
.eoi = mpic_end_ipi,
.irq_mask = mpic_mask_ipi,
.irq_unmask = mpic_unmask_ipi,
.irq_eoi = mpic_end_ipi,
};
#endif /* CONFIG_SMP */
#ifdef CONFIG_MPIC_U3_HT_IRQS
static struct irq_chip mpic_irq_ht_chip = {
.startup = mpic_startup_ht_irq,
.shutdown = mpic_shutdown_ht_irq,
.mask = mpic_mask_irq,
.unmask = mpic_unmask_ht_irq,
.eoi = mpic_end_ht_irq,
.set_type = mpic_set_irq_type,
.irq_startup = mpic_startup_ht_irq,
.irq_shutdown = mpic_shutdown_ht_irq,
.irq_mask = mpic_mask_irq,
.irq_unmask = mpic_unmask_ht_irq,
.irq_eoi = mpic_end_ht_irq,
.irq_set_type = mpic_set_irq_type,
};
#endif /* CONFIG_MPIC_U3_HT_IRQS */
@ -1060,12 +1067,12 @@ struct mpic * __init mpic_alloc(struct device_node *node,
mpic->hc_irq = mpic_irq_chip;
mpic->hc_irq.name = name;
if (flags & MPIC_PRIMARY)
mpic->hc_irq.set_affinity = mpic_set_affinity;
mpic->hc_irq.irq_set_affinity = mpic_set_affinity;
#ifdef CONFIG_MPIC_U3_HT_IRQS
mpic->hc_ht_irq = mpic_irq_ht_chip;
mpic->hc_ht_irq.name = name;
if (flags & MPIC_PRIMARY)
mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
mpic->hc_ht_irq.irq_set_affinity = mpic_set_affinity;
#endif /* CONFIG_MPIC_U3_HT_IRQS */
#ifdef CONFIG_SMP

View File

@ -34,9 +34,10 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
}
#endif
extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
extern int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type);
extern void mpic_set_vector(unsigned int virq, unsigned int vector);
extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
extern int mpic_set_affinity(struct irq_data *d,
const struct cpumask *cpumask, bool force);
extern void mpic_reset_core(int cpu);
#endif /* _POWERPC_SYSDEV_MPIC_H */

View File

@ -43,24 +43,24 @@ static void mpic_pasemi_msi_mask_irq(struct irq_data *data)
{
pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
mask_msi_irq(data);
mpic_mask_irq(data->irq);
mpic_mask_irq(data);
}
static void mpic_pasemi_msi_unmask_irq(struct irq_data *data)
{
pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
mpic_unmask_irq(data->irq);
mpic_unmask_irq(data);
unmask_msi_irq(data);
}
static struct irq_chip mpic_pasemi_msi_chip = {
.irq_shutdown = mpic_pasemi_msi_mask_irq,
.irq_mask = mpic_pasemi_msi_mask_irq,
.irq_unmask = mpic_pasemi_msi_unmask_irq,
.eoi = mpic_end_irq,
.set_type = mpic_set_irq_type,
.set_affinity = mpic_set_affinity,
.name = "PASEMI-MSI",
.irq_shutdown = mpic_pasemi_msi_mask_irq,
.irq_mask = mpic_pasemi_msi_mask_irq,
.irq_unmask = mpic_pasemi_msi_unmask_irq,
.irq_eoi = mpic_end_irq,
.irq_set_type = mpic_set_irq_type,
.irq_set_affinity = mpic_set_affinity,
.name = "PASEMI-MSI",
};
static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)

View File

@ -26,23 +26,23 @@ static struct mpic *msi_mpic;
static void mpic_u3msi_mask_irq(struct irq_data *data)
{
mask_msi_irq(data);
mpic_mask_irq(data->irq);
mpic_mask_irq(data);
}
static void mpic_u3msi_unmask_irq(struct irq_data *data)
{
mpic_unmask_irq(data->irq);
mpic_unmask_irq(data);
unmask_msi_irq(data);
}
static struct irq_chip mpic_u3msi_chip = {
.irq_shutdown = mpic_u3msi_mask_irq,
.irq_mask = mpic_u3msi_mask_irq,
.irq_unmask = mpic_u3msi_unmask_irq,
.eoi = mpic_end_irq,
.set_type = mpic_set_irq_type,
.set_affinity = mpic_set_affinity,
.name = "MPIC-U3MSI",
.irq_shutdown = mpic_u3msi_mask_irq,
.irq_mask = mpic_u3msi_mask_irq,
.irq_unmask = mpic_u3msi_unmask_irq,
.irq_eoi = mpic_end_irq,
.irq_set_type = mpic_set_irq_type,
.irq_set_affinity = mpic_set_affinity,
.name = "MPIC-U3MSI",
};
static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)

View File

@ -346,7 +346,7 @@ static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
if (prop)
pdata.freq_m = *prop;
pdata.freq_m = 3; /* default */
pdata.freq_n = 3; /* default */
prop = of_get_property(np, "freq_n", NULL);
if (prop)
pdata.freq_n = *prop;

View File

@ -76,9 +76,9 @@ static struct irq_host *mv64x60_irq_host;
* mv64x60_chip_low functions
*/
static void mv64x60_mask_low(unsigned int virq)
static void mv64x60_mask_low(struct irq_data *d)
{
int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, flags);
@ -89,9 +89,9 @@ static void mv64x60_mask_low(unsigned int virq)
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
}
static void mv64x60_unmask_low(unsigned int virq)
static void mv64x60_unmask_low(struct irq_data *d)
{
int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, flags);
@ -104,18 +104,18 @@ static void mv64x60_unmask_low(unsigned int virq)
static struct irq_chip mv64x60_chip_low = {
.name = "mv64x60_low",
.mask = mv64x60_mask_low,
.mask_ack = mv64x60_mask_low,
.unmask = mv64x60_unmask_low,
.irq_mask = mv64x60_mask_low,
.irq_mask_ack = mv64x60_mask_low,
.irq_unmask = mv64x60_unmask_low,
};
/*
* mv64x60_chip_high functions
*/
static void mv64x60_mask_high(unsigned int virq)
static void mv64x60_mask_high(struct irq_data *d)
{
int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, flags);
@ -126,9 +126,9 @@ static void mv64x60_mask_high(unsigned int virq)
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
}
static void mv64x60_unmask_high(unsigned int virq)
static void mv64x60_unmask_high(struct irq_data *d)
{
int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, flags);
@ -141,18 +141,18 @@ static void mv64x60_unmask_high(unsigned int virq)
static struct irq_chip mv64x60_chip_high = {
.name = "mv64x60_high",
.mask = mv64x60_mask_high,
.mask_ack = mv64x60_mask_high,
.unmask = mv64x60_unmask_high,
.irq_mask = mv64x60_mask_high,
.irq_mask_ack = mv64x60_mask_high,
.irq_unmask = mv64x60_unmask_high,
};
/*
* mv64x60_chip_gpp functions
*/
static void mv64x60_mask_gpp(unsigned int virq)
static void mv64x60_mask_gpp(struct irq_data *d)
{
int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, flags);
@ -163,9 +163,9 @@ static void mv64x60_mask_gpp(unsigned int virq)
(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
}
static void mv64x60_mask_ack_gpp(unsigned int virq)
static void mv64x60_mask_ack_gpp(struct irq_data *d)
{
int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, flags);
@ -178,9 +178,9 @@ static void mv64x60_mask_ack_gpp(unsigned int virq)
(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE);
}
static void mv64x60_unmask_gpp(unsigned int virq)
static void mv64x60_unmask_gpp(struct irq_data *d)
{
int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, flags);
@ -193,9 +193,9 @@ static void mv64x60_unmask_gpp(unsigned int virq)
static struct irq_chip mv64x60_chip_gpp = {
.name = "mv64x60_gpp",
.mask = mv64x60_mask_gpp,
.mask_ack = mv64x60_mask_ack_gpp,
.unmask = mv64x60_unmask_gpp,
.irq_mask = mv64x60_mask_gpp,
.irq_mask_ack = mv64x60_mask_ack_gpp,
.irq_unmask = mv64x60_unmask_gpp,
};
/*

View File

@ -189,15 +189,20 @@ static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg
static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
{
return irq_to_desc(virq)->chip_data;
return get_irq_chip_data(virq);
}
static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
{
return irq_data_get_irq_chip_data(d);
}
#define virq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
static void qe_ic_unmask_irq(unsigned int virq)
static void qe_ic_unmask_irq(struct irq_data *d)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
unsigned int src = virq_to_hw(d->irq);
unsigned long flags;
u32 temp;
@ -210,10 +215,10 @@ static void qe_ic_unmask_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
}
static void qe_ic_mask_irq(unsigned int virq)
static void qe_ic_mask_irq(struct irq_data *d)
{
struct qe_ic *qe_ic = qe_ic_from_irq(virq);
unsigned int src = virq_to_hw(virq);
struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
unsigned int src = virq_to_hw(d->irq);
unsigned long flags;
u32 temp;
@ -238,9 +243,9 @@ static void qe_ic_mask_irq(unsigned int virq)
static struct irq_chip qe_ic_irq_chip = {
.name = "QEIC",
.unmask = qe_ic_unmask_irq,
.mask = qe_ic_mask_irq,
.mask_ack = qe_ic_mask_irq,
.irq_unmask = qe_ic_unmask_irq,
.irq_mask = qe_ic_mask_irq,
.irq_mask_ack = qe_ic_mask_irq,
};
static int qe_ic_host_match(struct irq_host *h, struct device_node *node)

View File

@ -343,24 +343,9 @@ static inline unsigned int get_pci_source(void)
* Linux descriptor level callbacks
*/
static void tsi108_pci_irq_enable(u_int irq)
static void tsi108_pci_irq_unmask(struct irq_data *d)
{
tsi108_pci_int_unmask(irq);
}
static void tsi108_pci_irq_disable(u_int irq)
{
tsi108_pci_int_mask(irq);
}
static void tsi108_pci_irq_ack(u_int irq)
{
tsi108_pci_int_mask(irq);
}
static void tsi108_pci_irq_end(u_int irq)
{
tsi108_pci_int_unmask(irq);
tsi108_pci_int_unmask(d->irq);
/* Enable interrupts from PCI block */
tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
@ -370,16 +355,25 @@ static void tsi108_pci_irq_end(u_int irq)
mb();
}
static void tsi108_pci_irq_mask(struct irq_data *d)
{
tsi108_pci_int_mask(d->irq);
}
static void tsi108_pci_irq_ack(struct irq_data *d)
{
tsi108_pci_int_mask(d->irq);
}
/*
* Interrupt controller descriptor for cascaded PCI interrupt controller.
*/
static struct irq_chip tsi108_pci_irq = {
.name = "tsi108_PCI_int",
.mask = tsi108_pci_irq_disable,
.ack = tsi108_pci_irq_ack,
.end = tsi108_pci_irq_end,
.unmask = tsi108_pci_irq_enable,
.irq_mask = tsi108_pci_irq_mask,
.irq_ack = tsi108_pci_irq_ack,
.irq_unmask = tsi108_pci_irq_unmask,
};
static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
@ -437,8 +431,11 @@ void __init tsi108_pci_int_init(struct device_node *node)
void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq = get_pci_source();
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
}

View File

@ -55,11 +55,11 @@ struct uic {
struct irq_host *irqhost;
};
static void uic_unmask_irq(unsigned int virq)
static void uic_unmask_irq(struct irq_data *d)
{
struct irq_desc *desc = irq_to_desc(virq);
struct uic *uic = get_irq_chip_data(virq);
unsigned int src = uic_irq_to_hw(virq);
struct irq_desc *desc = irq_to_desc(d->irq);
struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags;
u32 er, sr;
@ -74,10 +74,10 @@ static void uic_unmask_irq(unsigned int virq)
spin_unlock_irqrestore(&uic->lock, flags);
}
static void uic_mask_irq(unsigned int virq)
static void uic_mask_irq(struct irq_data *d)
{
struct uic *uic = get_irq_chip_data(virq);
unsigned int src = uic_irq_to_hw(virq);
struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags;
u32 er;
@ -88,10 +88,10 @@ static void uic_mask_irq(unsigned int virq)
spin_unlock_irqrestore(&uic->lock, flags);
}
static void uic_ack_irq(unsigned int virq)
static void uic_ack_irq(struct irq_data *d)
{
struct uic *uic = get_irq_chip_data(virq);
unsigned int src = uic_irq_to_hw(virq);
struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags;
spin_lock_irqsave(&uic->lock, flags);
@ -99,11 +99,11 @@ static void uic_ack_irq(unsigned int virq)
spin_unlock_irqrestore(&uic->lock, flags);
}
static void uic_mask_ack_irq(unsigned int virq)
static void uic_mask_ack_irq(struct irq_data *d)
{
struct irq_desc *desc = irq_to_desc(virq);
struct uic *uic = get_irq_chip_data(virq);
unsigned int src = uic_irq_to_hw(virq);
struct irq_desc *desc = irq_to_desc(d->irq);
struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags;
u32 er, sr;
@ -125,18 +125,18 @@ static void uic_mask_ack_irq(unsigned int virq)
spin_unlock_irqrestore(&uic->lock, flags);
}
static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
struct uic *uic = get_irq_chip_data(virq);
unsigned int src = uic_irq_to_hw(virq);
struct irq_desc *desc = irq_to_desc(virq);
struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(d->irq);
struct irq_desc *desc = irq_to_desc(d->irq);
unsigned long flags;
int trigger, polarity;
u32 tr, pr, mask;
switch (flow_type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_NONE:
uic_mask_irq(virq);
uic_mask_irq(d);
return 0;
case IRQ_TYPE_EDGE_RISING:
@ -178,11 +178,11 @@ static int uic_set_irq_type(unsigned int virq, unsigned int flow_type)
static struct irq_chip uic_irq_chip = {
.name = "UIC",
.unmask = uic_unmask_irq,
.mask = uic_mask_irq,
.mask_ack = uic_mask_ack_irq,
.ack = uic_ack_irq,
.set_type = uic_set_irq_type,
.irq_unmask = uic_unmask_irq,
.irq_mask = uic_mask_irq,
.irq_mask_ack = uic_mask_ack_irq,
.irq_ack = uic_ack_irq,
.irq_set_type = uic_set_irq_type,
};
static int uic_host_map(struct irq_host *h, unsigned int virq,
@ -220,6 +220,7 @@ static struct irq_host_ops uic_host_ops = {
void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
struct uic *uic = get_irq_data(virq);
u32 msr;
int src;
@ -227,9 +228,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
raw_spin_lock(&desc->lock);
if (desc->status & IRQ_LEVEL)
desc->chip->mask(virq);
chip->irq_mask(&desc->irq_data);
else
desc->chip->mask_ack(virq);
chip->irq_mask_ack(&desc->irq_data);
raw_spin_unlock(&desc->lock);
msr = mfdcr(uic->dcrbase + UIC_MSR);
@ -244,9 +245,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
uic_irq_ret:
raw_spin_lock(&desc->lock);
if (desc->status & IRQ_LEVEL)
desc->chip->ack(virq);
if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
desc->chip->unmask(virq);
chip->irq_ack(&desc->irq_data);
if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
chip->irq_unmask(&desc->irq_data);
raw_spin_unlock(&desc->lock);
}

View File

@ -69,17 +69,17 @@ static unsigned char xilinx_intc_map_senses[] = {
*
* IRQ Chip common (across level and edge) operations
*/
static void xilinx_intc_mask(unsigned int virq)
static void xilinx_intc_mask(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void * regs = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void * regs = irq_data_get_irq_chip_data(d);
pr_debug("mask: %d\n", irq);
out_be32(regs + XINTC_CIE, 1 << irq);
}
static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
static int xilinx_intc_set_type(struct irq_data *d, unsigned int flow_type)
{
struct irq_desc *desc = irq_to_desc(virq);
struct irq_desc *desc = irq_to_desc(d->irq);
desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
@ -91,10 +91,10 @@ static int xilinx_intc_set_type(unsigned int virq, unsigned int flow_type)
/*
* IRQ Chip level operations
*/
static void xilinx_intc_level_unmask(unsigned int virq)
static void xilinx_intc_level_unmask(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void * regs = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void * regs = irq_data_get_irq_chip_data(d);
pr_debug("unmask: %d\n", irq);
out_be32(regs + XINTC_SIE, 1 << irq);
@ -107,37 +107,37 @@ static void xilinx_intc_level_unmask(unsigned int virq)
static struct irq_chip xilinx_intc_level_irqchip = {
.name = "Xilinx Level INTC",
.mask = xilinx_intc_mask,
.mask_ack = xilinx_intc_mask,
.unmask = xilinx_intc_level_unmask,
.set_type = xilinx_intc_set_type,
.irq_mask = xilinx_intc_mask,
.irq_mask_ack = xilinx_intc_mask,
.irq_unmask = xilinx_intc_level_unmask,
.irq_set_type = xilinx_intc_set_type,
};
/*
* IRQ Chip edge operations
*/
static void xilinx_intc_edge_unmask(unsigned int virq)
static void xilinx_intc_edge_unmask(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void *regs = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void *regs = irq_data_get_irq_chip_data(d);
pr_debug("unmask: %d\n", irq);
out_be32(regs + XINTC_SIE, 1 << irq);
}
static void xilinx_intc_edge_ack(unsigned int virq)
static void xilinx_intc_edge_ack(struct irq_data *d)
{
int irq = virq_to_hw(virq);
void * regs = get_irq_chip_data(virq);
int irq = virq_to_hw(d->irq);
void * regs = irq_data_get_irq_chip_data(d);
pr_debug("ack: %d\n", irq);
out_be32(regs + XINTC_IAR, 1 << irq);
}
static struct irq_chip xilinx_intc_edge_irqchip = {
.name = "Xilinx Edge INTC",
.mask = xilinx_intc_mask,
.unmask = xilinx_intc_edge_unmask,
.ack = xilinx_intc_edge_ack,
.set_type = xilinx_intc_set_type,
.irq_mask = xilinx_intc_mask,
.irq_unmask = xilinx_intc_edge_unmask,
.irq_ack = xilinx_intc_edge_ack,
.irq_set_type = xilinx_intc_set_type,
};
/*
@ -229,12 +229,14 @@ int xilinx_intc_get_irq(void)
*/
static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq)
generic_handle_irq(cascade_irq);
/* Let xilinx_intc end the interrupt */
desc->chip->unmask(irq);
chip->irq_unmask(&desc->irq_data);
}
static void __init xilinx_i8259_setup_cascade(void)

View File

@ -6,7 +6,7 @@
* Author: Ashish Kalra <ashish.kalra@freescale.com>
* Li Yang <leoli@freescale.com>
*
* Copyright (c) 2006-2007 Freescale Semiconductor, Inc.
* Copyright (c) 2006-2007, 2011 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -157,7 +157,8 @@ enum {
IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,
EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31),
DATA_SNOOP_ENABLE = (1 << 22),
DATA_SNOOP_ENABLE_V1 = (1 << 22),
DATA_SNOOP_ENABLE_V2 = (1 << 28),
};
/*
@ -260,6 +261,7 @@ struct sata_fsl_host_priv {
void __iomem *ssr_base;
void __iomem *csr_base;
int irq;
int data_snoop;
};
static inline unsigned int sata_fsl_tag(unsigned int tag,
@ -312,7 +314,8 @@ static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp,
}
static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
u32 *ttl, dma_addr_t cmd_desc_paddr)
u32 *ttl, dma_addr_t cmd_desc_paddr,
int data_snoop)
{
struct scatterlist *sg;
unsigned int num_prde = 0;
@ -362,8 +365,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
ttl_dwords += sg_len;
prd->dba = cpu_to_le32(sg_addr);
prd->ddc_and_ext =
cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03));
prd->ddc_and_ext = cpu_to_le32(data_snoop | (sg_len & ~0x03));
VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n",
ttl_dwords, prd->dba, prd->ddc_and_ext);
@ -378,7 +380,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc,
/* set indirect extension flag along with indirect ext. size */
prd_ptr_to_indirect_ext->ddc_and_ext =
cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG |
DATA_SNOOP_ENABLE |
data_snoop |
(indirect_ext_segment_sz & ~0x03)));
}
@ -421,7 +423,8 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)
if (qc->flags & ATA_QCFLAG_DMAMAP)
num_prde = sata_fsl_fill_sg(qc, (void *)cd,
&ttl_dwords, cd_paddr);
&ttl_dwords, cd_paddr,
host_priv->data_snoop);
if (qc->tf.protocol == ATA_PROT_NCQ)
desc_info |= FPDMA_QUEUED_CMD;
@ -1349,6 +1352,11 @@ static int sata_fsl_probe(struct platform_device *ofdev)
}
host_priv->irq = irq;
if (of_device_is_compatible(ofdev->dev.of_node, "fsl,pq-sata-v2"))
host_priv->data_snoop = DATA_SNOOP_ENABLE_V2;
else
host_priv->data_snoop = DATA_SNOOP_ENABLE_V1;
/* allocate host structure */
host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS);
@ -1431,6 +1439,9 @@ static struct of_device_id fsl_sata_match[] = {
{
.compatible = "fsl,pq-sata",
},
{
.compatible = "fsl,pq-sata-v2",
},
{},
};

View File

@ -283,7 +283,7 @@ static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm)
}
}
static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm)
static void rackmeter_stop_cpu_sniffer(struct rackmeter *rm)
{
cancel_delayed_work_sync(&rm->cpu[0].sniffer);
cancel_delayed_work_sync(&rm->cpu[1].sniffer);

View File

@ -309,6 +309,7 @@ struct hvcs_struct {
static LIST_HEAD(hvcs_structs);
static DEFINE_SPINLOCK(hvcs_structs_lock);
static DEFINE_MUTEX(hvcs_init_mutex);
static void hvcs_unthrottle(struct tty_struct *tty);
static void hvcs_throttle(struct tty_struct *tty);
@ -340,6 +341,7 @@ static int __devinit hvcs_probe(struct vio_dev *dev,
static int __devexit hvcs_remove(struct vio_dev *dev);
static int __init hvcs_module_init(void);
static void __exit hvcs_module_exit(void);
static int __devinit hvcs_initialize(void);
#define HVCS_SCHED_READ 0x00000001
#define HVCS_QUICK_READ 0x00000002
@ -762,7 +764,7 @@ static int __devinit hvcs_probe(
const struct vio_device_id *id)
{
struct hvcs_struct *hvcsd;
int index;
int index, rc;
int retval;
if (!dev || !id) {
@ -770,6 +772,13 @@ static int __devinit hvcs_probe(
return -EPERM;
}
/* Make sure we are properly initialized */
rc = hvcs_initialize();
if (rc) {
pr_err("HVCS: Failed to initialize core driver.\n");
return rc;
}
/* early to avoid cleanup on failure */
index = hvcs_get_index();
if (index < 0) {
@ -1464,12 +1473,15 @@ static void hvcs_free_index_list(void)
hvcs_index_count = 0;
}
static int __init hvcs_module_init(void)
static int __devinit hvcs_initialize(void)
{
int rc;
int num_ttys_to_alloc;
int rc, num_ttys_to_alloc;
printk(KERN_INFO "Initializing %s\n", hvcs_driver_string);
mutex_lock(&hvcs_init_mutex);
if (hvcs_task) {
mutex_unlock(&hvcs_init_mutex);
return 0;
}
/* Has the user specified an overload with an insmod param? */
if (hvcs_parm_num_devs <= 0 ||
@ -1528,35 +1540,13 @@ static int __init hvcs_module_init(void)
hvcs_task = kthread_run(khvcsd, NULL, "khvcsd");
if (IS_ERR(hvcs_task)) {
printk(KERN_ERR "HVCS: khvcsd creation failed. Driver not loaded.\n");
printk(KERN_ERR "HVCS: khvcsd creation failed.\n");
rc = -EIO;
goto kthread_fail;
}
rc = vio_register_driver(&hvcs_vio_driver);
if (rc) {
printk(KERN_ERR "HVCS: can't register vio driver\n");
goto vio_fail;
}
/*
* This needs to be done AFTER the vio_register_driver() call or else
* the kobjects won't be initialized properly.
*/
rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan);
if (rc) {
printk(KERN_ERR "HVCS: sysfs attr create failed\n");
goto attr_fail;
}
printk(KERN_INFO "HVCS: driver module inserted.\n");
mutex_unlock(&hvcs_init_mutex);
return 0;
attr_fail:
vio_unregister_driver(&hvcs_vio_driver);
vio_fail:
kthread_stop(hvcs_task);
kthread_fail:
kfree(hvcs_pi_buff);
buff_alloc_fail:
@ -1566,15 +1556,39 @@ register_fail:
index_fail:
put_tty_driver(hvcs_tty_driver);
hvcs_tty_driver = NULL;
mutex_unlock(&hvcs_init_mutex);
return rc;
}
static int __init hvcs_module_init(void)
{
int rc = vio_register_driver(&hvcs_vio_driver);
if (rc) {
printk(KERN_ERR "HVCS: can't register vio driver\n");
return rc;
}
pr_info("HVCS: Driver registered.\n");
/* This needs to be done AFTER the vio_register_driver() call or else
* the kobjects won't be initialized properly.
*/
rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan);
if (rc)
pr_warning(KERN_ERR "HVCS: Failed to create rescan file (err %d)\n", rc);
return 0;
}
static void __exit hvcs_module_exit(void)
{
/*
* This driver receives hvcs_remove callbacks for each device upon
* module removal.
*/
vio_unregister_driver(&hvcs_vio_driver);
if (!hvcs_task)
return;
/*
* This synchronous operation will wake the khvcsd kthread if it is
@ -1589,8 +1603,6 @@ static void __exit hvcs_module_exit(void)
driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan);
vio_unregister_driver(&hvcs_vio_driver);
tty_unregister_driver(hvcs_tty_driver);
hvcs_free_index_list();

Some files were not shown because too many files have changed in this diff Show More