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 The Freescale MPIC interrupt controller is found on all PowerQUICC
become which interrupt number. This is up to the software implementation and QorIQ processors and is compatible with the Open PIC. The
of the interrupt controller. The only requirement is that every notable difference from Open PIC binding is the addition of 2
interrupt source has to have an unique interrupt number / vector number. additional cells in the interrupt specifier defining interrupt type
To accomplish this the current implementation assigns the number zero to information.
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.
So what to write for external interrupt source X or internal interrupt PROPERTIES
source Y into the device tree? Here is an example:
The memory map for the interrupt controller in the MPC8544[0] shows, - compatible
that the first interrupt source starts at 0x5_0000 (PIC Register Address Usage: required
Map-Interrupt Source Configuration Registers). This source becomes the Value type: <string>
number zero therefore: Definition: Shall include "fsl,mpic". Freescale MPIC
External interrupt 0 = interrupt number 0 controllers compatible with this binding have Block
External interrupt 1 = interrupt number 1 Revision Registers BRR1 and BRR2 at offset 0x0 and
External interrupt 2 = interrupt number 2 0x10 in the MPIC.
...
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
After the external sources, the internal sources follow. The in core I2C - reg
controller on the MPC8544 for instance has the internal source number Usage: required
27. Oo obtain its interrupt number we take the lower 16bits of its memory Value type: <prop-encoded-array>
address (0x5_0560) and shift it right: Definition: A standard property. Specifies the physical
0x0560 >> 5 = 43 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-controller
interrupt number 43 specified in the device tree. Usage: required
Value type: <empty>
Definition: Specifies that this node is an interrupt
controller
[0] MPC8544E PowerQUICCTM III, Integrated Host Processor Family Reference Manual - #interrupt-cells
MPC8544ERM Rev. 1 10/2007 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, 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 etc.) and the second is "fsl,mpic-msi" or "fsl,ipic-msi" depending on
the parent type. the parent type.
- reg : should contain the address and the length of the shared message - reg : should contain the address and the length of the shared message
interrupt register set. interrupt register set.
- msi-available-ranges: use <start count> style section to define which - msi-available-ranges: use <start count> style section to define which
msi interrupt can be used in the 256 msi interrupts. This property is msi interrupt can be used in the 256 msi interrupts. This property is
optional, without this, all the 256 MSI interrupts can be used. 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, - interrupts : each one of the interrupts here is one entry per 32 MSIs,
and routed to the host interrupt controller. the interrupts should 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 - interrupt-parent: the phandle for the interrupt controller
that services interrupts for this device. for 83xx cpu, the interrupts that services interrupts for this device. for 83xx cpu, the interrupts
are routed to IPIC, and for 85xx/86xx cpu the interrupts are routed 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] disable= [IPV6]
See Documentation/networking/ipv6.txt. See Documentation/networking/ipv6.txt.
disable_ddw [PPC/PSERIES]
Disable Dynamic DMA Window support. Use this if
to workaround buggy firmware.
disable_ipv6= [IPV6] disable_ipv6= [IPV6]
See Documentation/networking/ipv6.txt. See Documentation/networking/ipv6.txt.

View file

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

View file

@ -172,6 +172,19 @@
interrupts = <0x1e 4>; 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 { SATA0: sata@bffd1000 {
compatible = "amcc,sata-460ex"; compatible = "amcc,sata-460ex";
reg = <4 0xbffd1000 0x800 4 0xbffd0800 0x400>; 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 { ndfc@3,0 {
compatible = "ibm,ndfc"; compatible = "ibm,ndfc";
reg = <0x00000003 0x00000000 0x00002000>; reg = <0x00000003 0x00000000 0x00002000>;
@ -307,6 +325,12 @@
interrupts = <0x3 0x4>; interrupts = <0x3 0x4>;
}; };
GPIO0: gpio@ef600b00 {
compatible = "ibm,ppc4xx-gpio";
reg = <0xef600b00 0x00000048>;
gpio-controller;
};
ZMII0: emac-zmii@ef600d00 { ZMII0: emac-zmii@ef600d00 {
compatible = "ibm,zmii-460ex", "ibm,zmii"; compatible = "ibm,zmii-460ex", "ibm,zmii";
reg = <0xef600d00 0x0000000c>; reg = <0xef600d00 0x0000000c>;

View file

@ -1,7 +1,7 @@
/* /*
* Keymile KMETER1 Device Tree Source * 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 * 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 * under the terms of the GNU General Public License as published by the
@ -70,11 +70,11 @@
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
cell-index = <0>; cell-index = <0>;
compatible = "fsl-i2c"; compatible = "fsl,mpc8313-i2c","fsl-i2c";
reg = <0x3000 0x100>; reg = <0x3000 0x100>;
interrupts = <14 0x8>; interrupts = <14 0x8>;
interrupt-parent = <&ipic>; interrupt-parent = <&ipic>;
dfsrr; clock-frequency = <400000>;
}; };
serial0: serial@4500 { serial0: serial@4500 {
@ -137,6 +137,13 @@
compatible = "fsl,mpc8360-par_io"; compatible = "fsl,mpc8360-par_io";
num-ports = <7>; 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 { pio_ucc1: ucc_pin@0 {
reg = <0>; reg = <0>;
@ -472,7 +479,17 @@
#address-cells = <0>; #address-cells = <0>;
#interrupt-cells = <1>; #interrupt-cells = <1>;
reg = <0x80 0x80>; 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>; interrupt-parent = <&ipic>;
}; };
}; };
@ -484,43 +501,31 @@
compatible = "fsl,mpc8360-localbus", "fsl,pq2pro-localbus", compatible = "fsl,mpc8360-localbus", "fsl,pq2pro-localbus",
"simple-bus"; "simple-bus";
reg = <0xe0005000 0xd8>; 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"; compatible = "cfi-flash";
/* reg = <0 0 0x04000000>;
* 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>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
partition@0 { bank-width = <2>;
partition@0 { /* 768KB */
label = "u-boot"; label = "u-boot";
reg = <0 0x40000>; reg = <0 0xC0000>;
}; };
partition@40000 { partition@c0000 { /* 128KB */
label = "env"; label = "env";
reg = <0x40000 0x40000>; reg = <0xC0000 0x20000>;
}; };
partition@80000 { partition@e0000 { /* 128KB */
label = "dtb"; label = "envred";
reg = <0x80000 0x20000>; reg = <0xE0000 0x20000>;
}; };
partition@a0000 { partition@100000 { /* 64512KB */
label = "kernel"; label = "ubi0";
reg = <0xa0000 0x300000>; reg = <0x100000 0x3F00000>;
};
partition@3a0000 {
label = "ramdisk";
reg = <0x3a0000 0x800000>;
};
partition@ba0000 {
label = "user";
reg = <0xba0000 0x3460000>;
}; };
}; };
}; };

View file

@ -13,7 +13,7 @@
/dts-v1/; /dts-v1/;
/ { / {
model = "MGCOGE"; model = "MGCOGE";
compatible = "keymile,mgcoge"; compatible = "keymile,km82xx";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
@ -48,8 +48,10 @@
reg = <0xf0010100 0x40>; reg = <0xf0010100 0x40>;
ranges = <0 0 0xfe000000 0x00400000 ranges = <0 0 0xfe000000 0x00400000
5 0 0x50000000 0x20000000 1 0 0x30000000 0x00010000
>; /* Filled in by U-Boot */ 2 0 0x40000000 0x00010000
5 0 0x50000000 0x04000000
>;
flash@0,0 { flash@0,0 {
compatible = "cfi-flash"; compatible = "cfi-flash";
@ -60,36 +62,32 @@
device-width = <1>; device-width = <1>;
partition@0 { partition@0 {
label = "u-boot"; label = "u-boot";
reg = <0 0x40000>; reg = <0x00000 0xC0000>;
}; };
partition@40000 { partition@1 {
label = "env"; label = "env";
reg = <0x40000 0x20000>; reg = <0xC0000 0x20000>;
}; };
partition@60000 { partition@2 {
label = "kernel"; label = "envred";
reg = <0x60000 0x220000>; reg = <0xE0000 0x20000>;
}; };
partition@280000 { partition@3 {
label = "dtb"; label = "free";
reg = <0x280000 0x20000>; reg = <0x100000 0x300000>;
}; };
}; };
flash@5,0 { flash@5,0 {
compatible = "cfi-flash"; compatible = "cfi-flash";
reg = <5 0x0 0x2000000>; reg = <5 0x00000000 0x02000000
5 0x02000000 0x02000000>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
bank-width = <2>; bank-width = <2>;
device-width = <2>; partition@app { /* 64 MBytes */
partition@0 { label = "ubi0";
label = "ramdisk"; reg = <0x00000000 0x04000000>;
reg = <0 0x7a0000>;
};
partition@7a0000 {
label = "user";
reg = <0x7a0000 0x1860000>;
}; };
}; };
}; };
@ -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 { PIC: interrupt-controller@10c00 {
#interrupt-cells = <2>; #interrupt-cells = <2>;
interrupt-controller; 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 { sata@18000 {
compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; compatible = "fsl,p1022-sata", "fsl,pq-sata-v2";
reg = <0x18000 0x1000>; reg = <0x18000 0x1000>;
cell-index = <1>; cell-index = <1>;
interrupts = <74 0x2>; interrupts = <74 0x2>;
}; };
sata@19000 { sata@19000 {
compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; compatible = "fsl,p1022-sata", "fsl,pq-sata-v2";
reg = <0x19000 0x1000>; reg = <0x19000 0x1000>;
cell-index = <2>; cell-index = <2>;
interrupts = <41 0x2>; interrupts = <41 0x2>;

View file

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

View file

@ -1,4 +1,5 @@
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_SPARSE_IRQ=y
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_BUF_SHIFT=14
@ -10,7 +11,6 @@ CONFIG_SLAB=y
CONFIG_PPC_82xx=y CONFIG_PPC_82xx=y
CONFIG_MGCOGE=y CONFIG_MGCOGE=y
CONFIG_BINFMT_MISC=y CONFIG_BINFMT_MISC=y
CONFIG_SPARSE_IRQ=y
# CONFIG_SECCOMP is not set # CONFIG_SECCOMP is not set
CONFIG_NET=y CONFIG_NET=y
CONFIG_PACKET=y CONFIG_PACKET=y
@ -30,7 +30,6 @@ CONFIG_MTD=y
CONFIG_MTD_CONCAT=y CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_CFI=y CONFIG_MTD_CFI=y
@ -43,7 +42,6 @@ CONFIG_MTD_PHYSMAP_OF=y
CONFIG_PROC_DEVICETREE=y CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM=y
# CONFIG_MISC_DEVICES is not set
# CONFIG_MACINTOSH_DRIVERS is not set # CONFIG_MACINTOSH_DRIVERS is not set
CONFIG_NETDEVICES=y CONFIG_NETDEVICES=y
CONFIG_FIXED_PHY=y CONFIG_FIXED_PHY=y
@ -67,7 +65,6 @@ CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set # CONFIG_EXT3_FS_XATTR is not set
CONFIG_INOTIFY=y
CONFIG_AUTOFS4_FS=y CONFIG_AUTOFS4_FS=y
CONFIG_PROC_KCORE=y CONFIG_PROC_KCORE=y
CONFIG_TMPFS=y CONFIG_TMPFS=y
@ -88,13 +85,9 @@ CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_KERNEL=y
# CONFIG_SCHED_DEBUG is not set # CONFIG_SCHED_DEBUG is not set
CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_BDI_SWITCH=y CONFIG_BDI_SWITCH=y
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW 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_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000)
#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000) #define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000)
#define CPU_FTR_NO_DPM ASM_CONST(0x0000000000008000) #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_NEED_COHERENT ASM_CONST(0x0000000000020000)
#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000) #define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000)
#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000) #define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000)
@ -465,7 +466,7 @@ enum {
CPU_FTRS_44X | CPU_FTRS_440x6 | CPU_FTRS_44X | CPU_FTRS_440x6 |
#endif #endif
#ifdef CONFIG_PPC_47x #ifdef CONFIG_PPC_47x
CPU_FTRS_47X | CPU_FTRS_47X | CPU_FTR_476_DD2 |
#endif #endif
#ifdef CONFIG_E200 #ifdef CONFIG_E200
CPU_FTRS_E200 | CPU_FTRS_E200 |

View file

@ -141,6 +141,8 @@ static inline bool arch_irqs_disabled(void)
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
#define ARCH_IRQ_INIT_FLAGS IRQ_NOREQUEST
/* /*
* interrupt-retrigger: should we handle this via lost interrupts and IPIs * interrupt-retrigger: should we handle this via lost interrupts and IPIs
* or should we not care like we do now ? --BenH. * 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); void smp_mpic_message_pass(int target, int msg);
/* Unmask a specific virq */ /* 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 */ /* 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 */ /* 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 */ /* Fetch interrupt from a given mpic */
extern unsigned int mpic_get_one_irq(struct mpic *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 int __init nvram_scan_partitions(void);
extern loff_t nvram_create_partition(const char *name, int sig, extern loff_t nvram_create_partition(const char *name, int sig,
int req_size, int min_size); 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 int nvram_get_partition_size(loff_t data_index);
extern loff_t nvram_find_partition(const char *name, int sig, int *out_size); 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) | \ #define pgprot_cached_wthru(prot) (__pgprot((pgprot_val(prot) & ~_PAGE_CACHE_CTL) | \
_PAGE_COHERENT | _PAGE_WRITETHRU)) _PAGE_COHERENT | _PAGE_WRITETHRU))
#define pgprot_writecombine pgprot_noncached_wc
struct file; struct file;
extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, 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, static inline void qe_ic_cascade_low_ipic(unsigned int irq,
struct irq_desc *desc) 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); unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
if (cascade_irq != NO_IRQ) 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, static inline void qe_ic_cascade_high_ipic(unsigned int irq,
struct irq_desc *desc) 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); unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq != NO_IRQ) 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, static inline void qe_ic_cascade_low_mpic(unsigned int irq,
struct irq_desc *desc) 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); 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) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_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, static inline void qe_ic_cascade_high_mpic(unsigned int irq,
struct irq_desc *desc) 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); 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) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_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, static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
struct irq_desc *desc) 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; unsigned int cascade_irq;
struct irq_chip *chip = get_irq_desc_chip(desc);
cascade_irq = qe_ic_get_high_irq(qe_ic); cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq == NO_IRQ) 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) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq); generic_handle_irq(cascade_irq);
desc->chip->eoi(irq); chip->irq_eoi(&desc->irq_data);
} }
#endif /* _ASM_POWERPC_QE_IC_H */ #endif /* _ASM_POWERPC_QE_IC_H */

View file

@ -170,6 +170,16 @@
#define SPEFSCR_FRMC 0x00000003 /* Embedded FP rounding mode control */ #define SPEFSCR_FRMC 0x00000003 /* Embedded FP rounding mode control */
/* Special Purpose Registers (SPRNs)*/ /* 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_CTR 0x009 /* Count Register */
#define SPRN_DSCR 0x11 #define SPRN_DSCR 0x11
#define SPRN_CTRLF 0x088 #define SPRN_CTRLF 0x088
@ -852,6 +862,8 @@
#define PVR_7450 0x80000000 #define PVR_7450 0x80000000
#define PVR_8540 0x80200000 #define PVR_8540 0x80200000
#define PVR_8560 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 * For the 8xx processors, all of them report the same PVR family for
* the PowerPC core. The various versions of these processors must be * the PowerPC core. The various versions of these processors must be

View file

@ -150,8 +150,6 @@
* or IBM 40x. * or IBM 40x.
*/ */
#ifdef CONFIG_BOOKE #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_CSRR0 0x03A /* Critical Save and Restore Register 0 */
#define SPRN_CSRR1 0x03B /* Critical Save and Restore Register 1 */ #define SPRN_CSRR1 0x03B /* Critical Save and Restore Register 1 */
#define SPRN_DEAR 0x03D /* Data Error Address Register */ #define SPRN_DEAR 0x03D /* Data Error Address Register */
@ -168,7 +166,6 @@
#define SPRN_TCR 0x154 /* Timer Control Register */ #define SPRN_TCR 0x154 /* Timer Control Register */
#endif /* Book E */ #endif /* Book E */
#ifdef CONFIG_40x #ifdef CONFIG_40x
#define SPRN_PID 0x3B1 /* Process ID */
#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ #define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */
#define SPRN_ESR 0x3D4 /* Exception Syndrome Register */ #define SPRN_ESR 0x3D4 /* Exception Syndrome Register */
#define SPRN_DEAR 0x3D5 /* Data Error Address 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, .machine_check = machine_check_440A,
.platform = "ppc440", .platform = "ppc440",
}, },
{ /* 476 core */ { /* 476 DD2 core */
.pvr_mask = 0xffff0000, .pvr_mask = 0xffffffff,
.pvr_value = 0x11a50000, .pvr_value = 0x11a52080,
.cpu_name = "476", .cpu_name = "476",
.cpu_features = CPU_FTRS_47X, .cpu_features = CPU_FTRS_47X | CPU_FTR_476_DD2,
.cpu_user_features = COMMON_USER_BOOKE | .cpu_user_features = COMMON_USER_BOOKE |
PPC_FEATURE_HAS_FPU, PPC_FEATURE_HAS_FPU,
.mmu_features = MMU_FTR_TYPE_47x | .mmu_features = MMU_FTR_TYPE_47x |
@ -1839,6 +1839,20 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_47x, .machine_check = machine_check_47x,
.platform = "ppc470", .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 */ { /* default match */
.pvr_mask = 0x00000000, .pvr_mask = 0x00000000,
.pvr_value = 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; int i = *(loff_t *) v, j, prec;
struct irqaction *action; struct irqaction *action;
struct irq_desc *desc; struct irq_desc *desc;
struct irq_chip *chip;
if (i > nr_irqs) if (i > nr_irqs)
return 0; return 0;
@ -270,8 +271,9 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j) for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
if (desc->chip) chip = get_irq_desc_chip(desc);
seq_printf(p, " %-16s", desc->chip->name); if (chip)
seq_printf(p, " %-16s", chip->name);
else else
seq_printf(p, " %-16s", "None"); seq_printf(p, " %-16s", "None");
seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge"); 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); alloc_cpumask_var(&mask, GFP_KERNEL);
for_each_irq(irq) { for_each_irq(irq) {
struct irq_chip *chip;
desc = irq_to_desc(irq); desc = irq_to_desc(irq);
if (!desc) if (!desc)
continue; continue;
@ -320,13 +324,15 @@ void fixup_irqs(const struct cpumask *map)
if (desc->status & IRQ_PER_CPU) if (desc->status & IRQ_PER_CPU)
continue; 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) { if (cpumask_any(mask) >= nr_cpu_ids) {
printk("Breaking affinity for irq %i\n", irq); printk("Breaking affinity for irq %i\n", irq);
cpumask_copy(mask, map); cpumask_copy(mask, map);
} }
if (desc->chip->set_affinity) if (chip->irq_set_affinity)
desc->chip->set_affinity(irq, mask); chip->irq_set_affinity(&desc->irq_data, mask, true);
else if (desc->action && !(warned++)) else if (desc->action && !(warned++))
printk("Cannot set affinity for irq %i\n", irq); 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, static int irq_setup_virq(struct irq_host *host, unsigned int virq,
irq_hw_number_t hwirq) irq_hw_number_t hwirq)
{ {
struct irq_desc *desc; int res;
desc = irq_to_desc_alloc_node(virq, 0); res = irq_alloc_desc_at(virq, 0);
if (!desc) { if (res != virq) {
pr_debug("irq: -> allocating desc failed\n"); pr_debug("irq: -> allocating desc failed\n");
goto error; goto error;
} }
/* Clear IRQ_NOREQUEST flag */ irq_clear_status_flags(virq, IRQ_NOREQUEST);
desc->status &= ~IRQ_NOREQUEST;
/* map it */ /* map it */
smp_wmb(); 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)) { if (host->ops->map(host, virq, hwirq)) {
pr_debug("irq: -> mapping failed, freeing\n"); pr_debug("irq: -> mapping failed, freeing\n");
goto error; goto errdesc;
} }
return 0; return 0;
errdesc:
irq_free_descs(virq, 1);
error: error:
irq_free_virt(virq, 1); irq_free_virt(virq, 1);
return -1; return -1;
@ -879,9 +886,9 @@ void irq_dispose_mapping(unsigned int virq)
smp_mb(); smp_mb();
irq_map[virq].hwirq = host->inval_irq; irq_map[virq].hwirq = host->inval_irq;
/* Set some flags */ irq_set_status_flags(virq, IRQ_NOREQUEST);
irq_to_desc(virq)->status |= IRQ_NOREQUEST;
irq_free_descs(virq, 1);
/* Free it */ /* Free it */
irq_free_virt(virq, 1); 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) 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; return 0;
} }
@ -1159,11 +1151,14 @@ static int virq_debug_show(struct seq_file *m, void *private)
raw_spin_lock_irqsave(&desc->lock, flags); raw_spin_lock_irqsave(&desc->lock, flags);
if (desc->action && desc->action->handler) { if (desc->action && desc->action->handler) {
struct irq_chip *chip;
seq_printf(m, "%5d ", i); seq_printf(m, "%5d ", i);
seq_printf(m, "0x%05lx ", virq_to_hw(i)); seq_printf(m, "0x%05lx ", virq_to_hw(i));
if (desc->chip && desc->chip->name) chip = get_irq_desc_chip(desc);
p = desc->chip->name; if (chip && chip->name)
p = chip->name;
else else
p = none; p = none;
seq_printf(m, "%-15s ", p); seq_printf(m, "%-15s ", p);

View file

@ -26,20 +26,23 @@ void machine_kexec_mask_interrupts(void) {
for_each_irq(i) { for_each_irq(i) {
struct irq_desc *desc = irq_to_desc(i); struct irq_desc *desc = irq_to_desc(i);
struct irq_chip *chip;
if (!desc || !desc->chip) if (!desc)
continue; continue;
if (desc->chip->eoi && chip = get_irq_desc_chip(desc);
desc->status & IRQ_INPROGRESS) if (!chip)
desc->chip->eoi(i); continue;
if (desc->chip->mask) if (chip->irq_eoi && desc->status & IRQ_INPROGRESS)
desc->chip->mask(i); chip->irq_eoi(&desc->irq_data);
if (desc->chip->disable && if (chip->irq_mask)
!(desc->status & IRQ_DISABLED)) chip->irq_mask(&desc->irq_data);
desc->chip->disable(i);
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; 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 * nvram_remove_partition - Remove one or more partitions in nvram
* @name: name of the partition to remove, or NULL for a * @name: name of the partition to remove, or NULL for a
* signature only match * signature only match
* @sig: signature of the partition(s) to remove * @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; struct nvram_partition *part, *prev, *tmp;
int rc; int rc;
list_for_each_entry(part, &nvram_partitions, partition) { list_for_each_entry(part, &nvram_partitions, partition) {
if (part->header.signature != sig) if (!nvram_can_remove_partition(part, name, sig, exceptions))
continue;
if (name && strncmp(name, part->header.name, 12))
continue; continue;
/* Make partition a free partition */ /* Make partition a free partition */

View file

@ -97,7 +97,7 @@ static void __init move_device_tree(void)
start = __pa(initial_boot_params); start = __pa(initial_boot_params);
size = be32_to_cpu(initial_boot_params->totalsize); 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)) { overlaps_crashkernel(start, size)) {
p = __va(memblock_alloc(size, PAGE_SIZE)); p = __va(memblock_alloc(size, PAGE_SIZE));
memcpy(p, initial_boot_params, 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(); 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) { if (cpu >= nr_cpu_ids) {
cpu = cpumask_first(cpu_online_mask); cpu = cpumask_first(cpu_online_mask);

View file

@ -1,7 +1,7 @@
/* /*
* arch/powerpc/math-emu/math_efp.c * 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> * Author: Ebony Zhu, <ebony.zhu@freescale.com>
* Yu Liu, <yu.liu@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 | \ #define FP_EX_MASK (FP_EX_INEXACT | FP_EX_INVALID | FP_EX_DIVZERO | \
FP_EX_UNDERFLOW | FP_EX_OVERFLOW) FP_EX_UNDERFLOW | FP_EX_OVERFLOW)
static int have_e500_cpu_a005_erratum;
union dw_union { union dw_union {
u64 dp[1]; u64 dp[1];
u32 wp[2]; u32 wp[2];
@ -320,7 +322,8 @@ int do_spe_mathemu(struct pt_regs *regs)
} else { } else {
_FP_ROUND_ZERO(1, SB); _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; goto update_regs;
default: default:
@ -458,7 +461,8 @@ cmp_s:
} else { } else {
_FP_ROUND_ZERO(2, DB); _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; goto update_regs;
default: default:
@ -589,8 +593,10 @@ cmp_d:
_FP_ROUND_ZERO(1, SB0); _FP_ROUND_ZERO(1, SB0);
_FP_ROUND_ZERO(1, SB1); _FP_ROUND_ZERO(1, SB1);
} }
FP_TO_INT_S(vc.wp[0], SB0, 32, ((func & 0x3) != 0)); FP_TO_INT_S(vc.wp[0], SB0, 32,
FP_TO_INT_S(vc.wp[1], SB1, 32, ((func & 0x3) != 0)); (((func & 0x3) != 0) || SB0_s));
FP_TO_INT_S(vc.wp[1], SB1, 32,
(((func & 0x3) != 0) || SB1_s));
goto update_regs; goto update_regs;
default: default:
@ -652,6 +658,15 @@ update_regs:
return 0; return 0;
illegal: 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); printk(KERN_ERR "\nOoops! IEEE-754 compliance handler encountered un-supported instruction.\ninst code: %08lx\n", speinsn);
return -ENOSYS; return -ENOSYS;
} }
@ -718,3 +733,43 @@ int speround_handler(struct pt_regs *regs)
return 0; 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; lowmem_end_addr = memstart_addr + total_lowmem;
#ifndef CONFIG_HIGHMEM #ifndef CONFIG_HIGHMEM
total_memory = total_lowmem; total_memory = total_lowmem;
memblock_enforce_memory_limit(lowmem_end_addr); memblock_enforce_memory_limit(total_lowmem);
memblock_analyze(); memblock_analyze();
#endif /* CONFIG_HIGHMEM */ #endif /* CONFIG_HIGHMEM */
} }

View file

@ -189,6 +189,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
blr blr
#ifdef CONFIG_PPC_47x #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 * _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 * check though, it will blow up soon enough if we mistakenly try
@ -206,9 +213,37 @@ _GLOBAL(_tlbivax_bcast)
isync isync
eieio eieio
tlbsync tlbsync
BEGIN_FTR_SECTION
b 1f
END_FTR_SECTION_IFSET(CPU_FTR_476_DD2)
sync sync
wrtee r10 wrtee r10
blr 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 */ #endif /* CONFIG_PPC_47x */
#elif defined(CONFIG_FSL_BOOKE) #elif defined(CONFIG_FSL_BOOKE)

View file

@ -4,4 +4,8 @@
extern u8 as1_readb(volatile u8 __iomem *addr); extern u8 as1_readb(volatile u8 __iomem *addr);
extern void as1_writeb(u8 data, 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 */ #endif /* __POWERPC_PLATFORMS_44X_44X_H */

View file

@ -115,7 +115,6 @@ config CANYONLANDS
bool "Canyonlands" bool "Canyonlands"
depends on 44x depends on 44x
default n default n
select PPC44x_SIMPLE
select 460EX select 460EX
select PCI select PCI
select PPC4xx_PCI_EXPRESS 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_VIRTEX_5_FXT) += virtex.o
obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
obj-$(CONFIG_ISS4xx) += iss4xx.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,arches",
"amcc,bamboo", "amcc,bamboo",
"amcc,bluestone", "amcc,bluestone",
"amcc,canyonlands",
"amcc,glacier", "amcc,glacier",
"ibm,ebony", "ibm,ebony",
"amcc,eiger", "amcc,eiger",

View file

@ -59,9 +59,9 @@ irq_to_pic_bit(unsigned int irq)
} }
static void 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); void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
out_8(pic_mask, out_8(pic_mask,
@ -69,9 +69,9 @@ cpld_mask_irq(unsigned int irq)
} }
static void 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); void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
out_8(pic_mask, out_8(pic_mask,
@ -80,9 +80,9 @@ cpld_unmask_irq(unsigned int irq)
static struct irq_chip cpld_pic = { static struct irq_chip cpld_pic = {
.name = "CPLD PIC", .name = "CPLD PIC",
.mask = cpld_mask_irq, .irq_mask = cpld_mask_irq,
.ack = cpld_mask_irq, .irq_ack = cpld_mask_irq,
.unmask = cpld_unmask_irq, .irq_unmask = cpld_unmask_irq,
}; };
static int static int

View file

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

View file

@ -135,9 +135,9 @@ DEFINE_MUTEX(mpc52xx_gpt_list_mutex);
* Cascaded interrupt controller hooks * 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; unsigned long flags;
spin_lock_irqsave(&gpt->lock, 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); 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; unsigned long flags;
spin_lock_irqsave(&gpt->lock, 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); 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); 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; unsigned long flags;
u32 reg; 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); spin_lock_irqsave(&gpt->lock, flags);
reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK; 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 = { static struct irq_chip mpc52xx_gpt_irq_chip = {
.name = "MPC52xx GPT", .name = "MPC52xx GPT",
.unmask = mpc52xx_gpt_irq_unmask, .irq_unmask = mpc52xx_gpt_irq_unmask,
.mask = mpc52xx_gpt_irq_mask, .irq_mask = mpc52xx_gpt_irq_mask,
.ack = mpc52xx_gpt_irq_ack, .irq_ack = mpc52xx_gpt_irq_ack,
.set_type = mpc52xx_gpt_irq_set_type, .irq_set_type = mpc52xx_gpt_irq_set_type,
}; };
void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc) 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 * 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 irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_clrbit(&intr->ctrl, 11 - l2irq); 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 irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&intr->ctrl, 11 - l2irq); 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 irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&intr->ctrl, 27-l2irq); 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; u32 ctrl_reg, type;
int irq; int irq;
int l2irq; int l2irq;
void *handler = handle_level_irq; void *handler = handle_level_irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type); 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))); ctrl_reg |= (type << (22 - (l2irq * 2)));
out_be32(&intr->ctrl, ctrl_reg); out_be32(&intr->ctrl, ctrl_reg);
__set_irq_handler_unlocked(virq, handler); __set_irq_handler_unlocked(d->irq, handler);
return 0; return 0;
} }
static struct irq_chip mpc52xx_extirq_irqchip = { static struct irq_chip mpc52xx_extirq_irqchip = {
.name = "MPC52xx External", .name = "MPC52xx External",
.mask = mpc52xx_extirq_mask, .irq_mask = mpc52xx_extirq_mask,
.unmask = mpc52xx_extirq_unmask, .irq_unmask = mpc52xx_extirq_unmask,
.ack = mpc52xx_extirq_ack, .irq_ack = mpc52xx_extirq_ack,
.set_type = mpc52xx_extirq_set_type, .irq_set_type = mpc52xx_extirq_set_type,
}; };
/* /*
* Main interrupt irq_chip * 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 */ 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 irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&intr->main_mask, 16 - l2irq); 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 irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_clrbit(&intr->main_mask, 16 - l2irq); 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 = { static struct irq_chip mpc52xx_main_irqchip = {
.name = "MPC52xx Main", .name = "MPC52xx Main",
.mask = mpc52xx_main_mask, .irq_mask = mpc52xx_main_mask,
.mask_ack = mpc52xx_main_mask, .irq_mask_ack = mpc52xx_main_mask,
.unmask = mpc52xx_main_unmask, .irq_unmask = mpc52xx_main_unmask,
.set_type = mpc52xx_null_set_type, .irq_set_type = mpc52xx_null_set_type,
}; };
/* /*
* Peripherals interrupt irq_chip * Peripherals interrupt irq_chip
*/ */
static void mpc52xx_periph_mask(unsigned int virq) static void mpc52xx_periph_mask(struct irq_data *d)
{ {
int irq; int irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&intr->per_mask, 31 - l2irq); 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 irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_clrbit(&intr->per_mask, 31 - l2irq); 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 = { static struct irq_chip mpc52xx_periph_irqchip = {
.name = "MPC52xx Peripherals", .name = "MPC52xx Peripherals",
.mask = mpc52xx_periph_mask, .irq_mask = mpc52xx_periph_mask,
.mask_ack = mpc52xx_periph_mask, .irq_mask_ack = mpc52xx_periph_mask,
.unmask = mpc52xx_periph_unmask, .irq_unmask = mpc52xx_periph_unmask,
.set_type = mpc52xx_null_set_type, .irq_set_type = mpc52xx_null_set_type,
}; };
/* /*
* SDMA interrupt irq_chip * SDMA interrupt irq_chip
*/ */
static void mpc52xx_sdma_mask(unsigned int virq) static void mpc52xx_sdma_mask(struct irq_data *d)
{ {
int irq; int irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_setbit(&sdma->IntMask, l2irq); 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 irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
io_be_clrbit(&sdma->IntMask, l2irq); 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 irq;
int l2irq; int l2irq;
irq = irq_map[virq].hwirq; irq = irq_map[d->irq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK; l2irq = irq & MPC52xx_IRQ_L2_MASK;
out_be32(&sdma->IntPend, 1 << l2irq); 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 = { static struct irq_chip mpc52xx_sdma_irqchip = {
.name = "MPC52xx SDMA", .name = "MPC52xx SDMA",
.mask = mpc52xx_sdma_mask, .irq_mask = mpc52xx_sdma_mask,
.unmask = mpc52xx_sdma_unmask, .irq_unmask = mpc52xx_sdma_unmask,
.ack = mpc52xx_sdma_ack, .irq_ack = mpc52xx_sdma_ack,
.set_type = mpc52xx_null_set_type, .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_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o
obj-$(CONFIG_PQ2FADS) += pq2fads.o obj-$(CONFIG_PQ2FADS) += pq2fads.o
obj-$(CONFIG_EP8248E) += ep8248e.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 * Keymile km82xx support
* Copyright 2008 DENX Software Engineering GmbH * Copyright 2008-2011 DENX Software Engineering GmbH
* Author: Heiko Schocher <hs@denx.de> * Author: Heiko Schocher <hs@denx.de>
* *
* based on code from: * based on code from:
@ -31,9 +31,10 @@
#include "pq2.h" #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) { if (!np) {
printk(KERN_ERR "PIC init: can not find cpm-pic node\n"); printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
return; return;
@ -47,12 +48,18 @@ struct cpm_pin {
int port, pin, flags; int port, pin, flags;
}; };
static __initdata struct cpm_pin mgcoge_pins[] = { static __initdata struct cpm_pin km82xx_pins[] = {
/* SMC2 */ /* SMC2 */
{0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, {0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{0, 9, CPM_PIN_OUTPUT | 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 */ /* SCC4 */
{2, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, {2, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
{2, 24, 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, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
{3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN}, {3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
#endif #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) static void __init init_ioports(void)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(mgcoge_pins); i++) { for (i = 0; i < ARRAY_SIZE(km82xx_pins); i++) {
const struct cpm_pin *pin = &mgcoge_pins[i]; const struct cpm_pin *pin = &km82xx_pins[i];
cpm2_set_pin(pin->port, pin->pin, pin->flags); cpm2_set_pin(pin->port, pin->pin, pin->flags);
} }
cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8); 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_CLK7, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK8, CPM_CLK_TX); 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_CLK10, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK9, CPM_CLK_TX); 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_CLK13, CPM_CLK_RX);
cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX); 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) if (ppc_md.progress)
ppc_md.progress("mgcoge_setup_arch()", 0); ppc_md.progress("km82xx_setup_arch()", 0);
cpm2_reset(); cpm2_reset();
@ -142,7 +168,7 @@ static void __init mgcoge_setup_arch(void)
init_ioports(); init_ioports();
if (ppc_md.progress) 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[] = { static __initdata struct of_device_id of_bus_ids[] = {
@ -156,23 +182,23 @@ static int __init declare_of_platform_devices(void)
return 0; 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 * 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(); 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", .name = "Keymile km82xx",
.probe = mgcoge_probe, .probe = km82xx_probe,
.setup_arch = mgcoge_setup_arch, .setup_arch = km82xx_setup_arch,
.init_IRQ = mgcoge_pic_init, .init_IRQ = km82xx_pic_init,
.get_irq = cpm2_get_irq, .get_irq = cpm2_get_irq,
.calibrate_decr = generic_calibrate_decr, .calibrate_decr = generic_calibrate_decr,
.restart = pq2_restart, .restart = pq2_restart,

View file

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

View file

@ -16,4 +16,4 @@ obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o
obj-$(CONFIG_SBC834x) += sbc834x.o obj-$(CONFIG_SBC834x) += sbc834x.o
obj-$(CONFIG_MPC837x_RDB) += mpc837x_rdb.o obj-$(CONFIG_MPC837x_RDB) += mpc837x_rdb.o
obj-$(CONFIG_ASP834x) += asp834x.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> * Author: Heiko Schocher <hs@denx.de>
* *
* Description: * Description:
@ -49,12 +49,12 @@
* Setup the architecture * Setup the architecture
* *
*/ */
static void __init kmeter1_setup_arch(void) static void __init mpc83xx_km_setup_arch(void)
{ {
struct device_node *np; struct device_node *np;
if (ppc_md.progress) if (ppc_md.progress)
ppc_md.progress("kmeter1_setup_arch()", 0); ppc_md.progress("kmpbec83xx_setup_arch()", 0);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
for_each_compatible_node(np, "pci", "fsl,mpc8349-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); par_io_init(np);
of_node_put(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;) for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
par_io_of_config(np); par_io_of_config(np);
} }
@ -119,7 +122,7 @@ static void __init kmeter1_setup_arch(void)
#endif /* CONFIG_QUICC_ENGINE */ #endif /* CONFIG_QUICC_ENGINE */
} }
static struct of_device_id kmeter_ids[] = { static struct of_device_id kmpbec83xx_ids[] = {
{ .type = "soc", }, { .type = "soc", },
{ .compatible = "soc", }, { .compatible = "soc", },
{ .compatible = "simple-bus", }, { .compatible = "simple-bus", },
@ -131,13 +134,13 @@ static struct of_device_id kmeter_ids[] = {
static int __init kmeter_declare_of_platform_devices(void) static int __init kmeter_declare_of_platform_devices(void)
{ {
/* Publish the QE devices */ /* Publish the QE devices */
of_platform_bus_probe(NULL, kmeter_ids, NULL); of_platform_bus_probe(NULL, kmpbec83xx_ids, NULL);
return 0; 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; struct device_node *np;
@ -168,21 +171,34 @@ static void __init kmeter1_init_IRQ(void)
#endif /* CONFIG_QUICC_ENGINE */ #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 * 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) { define_machine(mpc83xx_km) {
.name = "KMETER1", .name = "mpc83xx-km-platform",
.probe = kmeter1_probe, .probe = mpc83xx_km_probe,
.setup_arch = kmeter1_setup_arch, .setup_arch = mpc83xx_km_setup_arch,
.init_IRQ = kmeter1_init_IRQ, .init_IRQ = mpc83xx_km_init_IRQ,
.get_irq = ipic_get_irq, .get_irq = ipic_get_irq,
.restart = mpc83xx_restart, .restart = mpc83xx_restart,
.time_init = mpc83xx_time_init, .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) static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{ {
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq; int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0) while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq); generic_handle_irq(cascade_irq);
desc->chip->eoi(irq); chip->irq_eoi(&desc->irq_data);
} }
static void __init ksi8560_pic_init(void) 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) static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{ {
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq; int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0) while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq); generic_handle_irq(cascade_irq);
desc->chip->eoi(irq); chip->irq_eoi(&desc->irq_data);
} }
#endif /* CONFIG_CPM2 */ #endif /* CONFIG_CPM2 */

View file

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

View file

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

View file

@ -91,10 +91,14 @@ smp_85xx_kick_cpu(int nr)
while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
mdelay(1); mdelay(1);
#else #else
smp_generic_kick_cpu(nr);
out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER), out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER),
__pa((u64)*((unsigned long long *) generic_secondary_smp_init))); __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 #endif
local_irq_restore(flags); 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) 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; 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) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_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 long flags;
unsigned int hwirq, irq_line; unsigned int hwirq, irq_line;
uint32_t mask; 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; irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); 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); 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 long flags;
unsigned int hwirq; unsigned int hwirq;
int irq_line; int irq_line;
u32 mask; u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq); hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line; irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); 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); 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 long flags;
unsigned int hwirq; unsigned int hwirq;
int irq_line; int irq_line;
u32 mask; u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq); hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line; irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); 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); 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 long flags;
unsigned int hwirq; unsigned int hwirq;
int irq_line; int irq_line;
u32 mask; u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq); hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line; irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); 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); 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 long flags;
unsigned int hwirq; unsigned int hwirq;
int irq_line; int irq_line;
u32 mask; u32 mask;
hwirq = socrates_fpga_irq_to_hw(virq); hwirq = socrates_fpga_irq_to_hw(d->irq);
irq_line = fpga_irqs[hwirq].irq_line; irq_line = fpga_irqs[hwirq].irq_line;
raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); 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); 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 int flow_type)
{ {
unsigned long flags; unsigned long flags;
@ -205,7 +205,7 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
int polarity; int polarity;
u32 mask; 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) if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
return -EINVAL; return -EINVAL;
@ -233,12 +233,12 @@ static int socrates_fpga_pic_set_type(unsigned int virq,
static struct irq_chip socrates_fpga_pic_chip = { static struct irq_chip socrates_fpga_pic_chip = {
.name = "FPGA-PIC", .name = "FPGA-PIC",
.ack = socrates_fpga_pic_ack, .irq_ack = socrates_fpga_pic_ack,
.mask = socrates_fpga_pic_mask, .irq_mask = socrates_fpga_pic_mask,
.mask_ack = socrates_fpga_pic_mask_ack, .irq_mask_ack = socrates_fpga_pic_mask_ack,
.unmask = socrates_fpga_pic_unmask, .irq_unmask = socrates_fpga_pic_unmask,
.eoi = socrates_fpga_pic_eoi, .irq_eoi = socrates_fpga_pic_eoi,
.set_type = socrates_fpga_pic_set_type, .irq_set_type = socrates_fpga_pic_set_type,
}; };
static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq, 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) static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{ {
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq; int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0) while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq); generic_handle_irq(cascade_irq);
desc->chip->eoi(irq); chip->irq_eoi(&desc->irq_data);
} }
#endif /* CONFIG_CPM2 */ #endif /* CONFIG_CPM2 */

View file

@ -44,12 +44,13 @@
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{ {
struct irq_chip *chip = get_irq_desc_chip(desc);
int cascade_irq; int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0) while ((cascade_irq = cpm2_get_irq()) >= 0)
generic_handle_irq(cascade_irq); generic_handle_irq(cascade_irq);
desc->chip->eoi(irq); chip->irq_eoi(&desc->irq_data);
} }
#endif /* CONFIG_CPM2 */ #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) void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
{ {
struct irq_chip *chip = get_irq_desc_chip(desc);
unsigned int cascade_irq; unsigned int cascade_irq;
/* /*
@ -106,17 +107,16 @@ void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
if (cascade_irq != NO_IRQ) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_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 long flags;
unsigned int hwirq; unsigned int hwirq;
u32 mask; u32 mask;
hwirq = gef_irq_to_hw(virq); hwirq = gef_irq_to_hw(d->irq);
raw_spin_lock_irqsave(&gef_pic_lock, flags); raw_spin_lock_irqsave(&gef_pic_lock, flags);
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); 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); 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, /* 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 * 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 long flags;
unsigned int hwirq; unsigned int hwirq;
u32 mask; u32 mask;
hwirq = gef_irq_to_hw(virq); hwirq = gef_irq_to_hw(d->irq);
raw_spin_lock_irqsave(&gef_pic_lock, flags); raw_spin_lock_irqsave(&gef_pic_lock, flags);
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); 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 = { static struct irq_chip gef_pic_chip = {
.name = "gefp", .name = "gefp",
.mask = gef_pic_mask, .irq_mask = gef_pic_mask,
.mask_ack = gef_pic_mask_ack, .irq_mask_ack = gef_pic_mask_ack,
.unmask = gef_pic_unmask, .irq_unmask = gef_pic_unmask,
}; };

View file

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

View file

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

View file

@ -6,5 +6,4 @@ obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o
obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o
obj-$(CONFIG_PPC_EP88XC) += ep88xc.o obj-$(CONFIG_PPC_EP88XC) += ep88xc.o
obj-$(CONFIG_PPC_ADDER875) += adder875.o obj-$(CONFIG_PPC_ADDER875) += adder875.o
obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o
obj-$(CONFIG_TQM8XX) += tqm8xx_setup.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) static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
{ {
struct irq_chip *chip;
int cascade_irq; int cascade_irq;
if ((cascade_irq = cpm_get_irq()) >= 0) { if ((cascade_irq = cpm_get_irq()) >= 0) {
struct irq_desc *cdesc = irq_to_desc(cascade_irq); struct irq_desc *cdesc = irq_to_desc(cascade_irq);
generic_handle_irq(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 /* 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) 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); struct axon_msic *msic = get_irq_data(irq);
u32 write_offset, msi; u32 write_offset, msi;
int idx; 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; 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) 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!"); 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; unsigned long flags;
raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags); raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64))); beatic_irq_mask_enable[d->irq/64] &= ~(1UL << (63 - (d->irq%64)));
beatic_update_irq_mask(irq_plug); beatic_update_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); 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; unsigned long flags;
raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags); raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); beatic_irq_mask_enable[d->irq/64] |= 1UL << (63 - (d->irq%64));
beatic_update_irq_mask(irq_plug); beatic_update_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); 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; unsigned long flags;
raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags); raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64))); beatic_irq_mask_ack[d->irq/64] &= ~(1UL << (63 - (d->irq%64)));
beatic_update_irq_mask(irq_plug); beatic_update_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); 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; s64 err;
unsigned long flags; unsigned long flags;
err = beat_downcount_of_interrupt(irq_plug); err = beat_downcount_of_interrupt(d->irq);
if (err != 0) { if (err != 0) {
if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */ if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */
panic("Failed to downcount IRQ! Error = %16llx", err); 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); raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags);
beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); beatic_irq_mask_ack[d->irq/64] |= 1UL << (63 - (d->irq%64));
beatic_update_irq_mask(irq_plug); beatic_update_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
} }
static struct irq_chip beatic_pic = { static struct irq_chip beatic_pic = {
.name = "CELL-BEAT", .name = "CELL-BEAT",
.unmask = beatic_unmask_irq, .irq_unmask = beatic_unmask_irq,
.mask = beatic_mask_irq, .irq_mask = beatic_mask_irq,
.eoi = beatic_end_irq, .irq_eoi = beatic_end_irq,
}; };
/* /*
@ -232,7 +232,7 @@ unsigned int beatic_get_irq(void)
ret = beatic_get_irq_plug(); ret = beatic_get_irq_plug();
if (ret != NO_IRQ) if (ret != NO_IRQ)
beatic_ack_irq(ret); beatic_ack_irq(irq_get_irq_data(ret));
return 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; 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); struct iic *iic = &__get_cpu_var(cpu_iic);
out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]); 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 = { static struct irq_chip iic_chip = {
.name = "CELL-IIC", .name = "CELL-IIC",
.mask = iic_mask, .irq_mask = iic_mask,
.unmask = iic_unmask, .irq_unmask = iic_unmask,
.eoi = iic_eoi, .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) 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 int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
unsigned long bits, ack; unsigned long bits, ack;
int cascade; int cascade;
@ -128,15 +130,15 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
if (ack) if (ack)
out_be64(&node_iic->iic_is, 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 = { static struct irq_chip iic_ioexc_chip = {
.name = "CELL-IOEX", .name = "CELL-IOEX",
.mask = iic_mask, .irq_mask = iic_mask,
.unmask = iic_unmask, .irq_unmask = iic_unmask,
.eoi = iic_ioexc_eoi, .irq_eoi = iic_ioexc_eoi,
}; };
/* Get an IRQ number from the pending state register of the IIC */ /* 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) 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); raw_spin_lock(&desc->lock);
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 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; desc->status &= ~IRQ_INPROGRESS;
out_eoi: out_eoi:
desc->chip->eoi(irq); chip->irq_eoi(&desc->irq_data);
raw_spin_unlock(&desc->lock); 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) 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; unsigned int virq;
virq = mpic_get_one_irq(mpic); virq = mpic_get_one_irq(mpic);
if (virq != NO_IRQ) if (virq != NO_IRQ)
generic_handle_irq(virq); generic_handle_irq(virq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
} }
static void __init mpic_init_IRQ(void) 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; 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); struct spider_pic *pic = spider_virq_to_pic(d->irq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
out_be32(cfg, in_be32(cfg) | 0x30000000u); 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); struct spider_pic *pic = spider_virq_to_pic(d->irq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
out_be32(cfg, in_be32(cfg) & ~0x30000000u); 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); struct spider_pic *pic = spider_virq_to_pic(d->irq);
unsigned int src = irq_map[virq].hwirq; unsigned int src = irq_map[d->irq].hwirq;
/* Reset edge detection logic if necessary /* Reset edge detection logic if necessary
*/ */
if (irq_to_desc(virq)->status & IRQ_LEVEL) if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
return; return;
/* Only interrupts 47 to 50 can be set to edge */ /* 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)); 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; unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
struct spider_pic *pic = spider_virq_to_pic(virq); struct spider_pic *pic = spider_virq_to_pic(d->irq);
unsigned int hw = irq_map[virq].hwirq; unsigned int hw = irq_map[d->irq].hwirq;
void __iomem *cfg = spider_get_irq_config(pic, hw); 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 old_mask;
u32 ic; u32 ic;
@ -169,10 +169,10 @@ static int spider_set_irq_type(unsigned int virq, unsigned int type)
static struct irq_chip spider_pic = { static struct irq_chip spider_pic = {
.name = "SPIDER", .name = "SPIDER",
.unmask = spider_unmask_irq, .irq_unmask = spider_unmask_irq,
.mask = spider_mask_irq, .irq_mask = spider_mask_irq,
.ack = spider_ack_irq, .irq_ack = spider_ack_irq,
.set_type = spider_set_irq_type, .irq_set_type = spider_set_irq_type,
}; };
static int spider_host_map(struct irq_host *h, unsigned int virq, 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) 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; unsigned int cs, virq;
cs = in_be32(pic->regs + TIR_CS) >> 24; 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; virq = NO_IRQ;
else else
virq = irq_linear_revmap(pic->host, cs); virq = irq_linear_revmap(pic->host, cs);
if (virq != NO_IRQ) if (virq != NO_IRQ)
generic_handle_irq(virq); 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 /* 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) 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(); unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_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); int irq = virq_to_hw(d->irq);
void __iomem *io_base = get_irq_chip_data(virq); void __iomem *io_base = irq_data_get_irq_chip_data(d);
u32 mask = 1 << irq; u32 mask = 1 << irq;
clrbits32(io_base + FLIPPER_IMR, mask); 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); 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); int irq = virq_to_hw(d->irq);
void __iomem *io_base = get_irq_chip_data(virq); void __iomem *io_base = irq_data_get_irq_chip_data(d);
/* this is at least needed for RSW */ /* this is at least needed for RSW */
out_be32(io_base + FLIPPER_ICR, 1 << irq); 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); int irq = virq_to_hw(d->irq);
void __iomem *io_base = get_irq_chip_data(virq); void __iomem *io_base = irq_data_get_irq_chip_data(d);
clrbits32(io_base + FLIPPER_IMR, 1 << irq); 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); int irq = virq_to_hw(d->irq);
void __iomem *io_base = get_irq_chip_data(virq); void __iomem *io_base = irq_data_get_irq_chip_data(d);
setbits32(io_base + FLIPPER_IMR, 1 << irq); 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 = { static struct irq_chip flipper_pic = {
.name = "flipper-pic", .name = "flipper-pic",
.ack = flipper_pic_ack, .irq_ack = flipper_pic_ack,
.mask_ack = flipper_pic_mask_and_ack, .irq_mask_ack = flipper_pic_mask_and_ack,
.mask = flipper_pic_mask, .irq_mask = flipper_pic_mask,
.unmask = flipper_pic_unmask, .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); int irq = virq_to_hw(d->irq);
void __iomem *io_base = get_irq_chip_data(virq); void __iomem *io_base = irq_data_get_irq_chip_data(d);
u32 mask = 1 << irq; u32 mask = 1 << irq;
clrbits32(io_base + HW_BROADWAY_IMR, mask); clrbits32(io_base + HW_BROADWAY_IMR, mask);
out_be32(io_base + HW_BROADWAY_ICR, 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); int irq = virq_to_hw(d->irq);
void __iomem *io_base = get_irq_chip_data(virq); void __iomem *io_base = irq_data_get_irq_chip_data(d);
out_be32(io_base + HW_BROADWAY_ICR, 1 << irq); 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); int irq = virq_to_hw(d->irq);
void __iomem *io_base = get_irq_chip_data(virq); void __iomem *io_base = irq_data_get_irq_chip_data(d);
clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq); 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); int irq = virq_to_hw(d->irq);
void __iomem *io_base = get_irq_chip_data(virq); void __iomem *io_base = irq_data_get_irq_chip_data(d);
setbits32(io_base + HW_BROADWAY_IMR, 1 << irq); 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 = { static struct irq_chip hlwd_pic = {
.name = "hlwd-pic", .name = "hlwd-pic",
.ack = hlwd_pic_ack, .irq_ack = hlwd_pic_ack,
.mask_ack = hlwd_pic_mask_and_ack, .irq_mask_ack = hlwd_pic_mask_and_ack,
.mask = hlwd_pic_mask, .irq_mask = hlwd_pic_mask,
.unmask = hlwd_pic_unmask, .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, static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
struct irq_desc *desc) struct irq_desc *desc)
{ {
struct irq_chip *chip = get_irq_desc_chip(desc);
struct irq_host *irq_host = get_irq_data(cascade_virq); struct irq_host *irq_host = get_irq_data(cascade_virq);
unsigned int virq; unsigned int virq;
raw_spin_lock(&desc->lock); 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); raw_spin_unlock(&desc->lock);
virq = __hlwd_pic_get_irq(irq_host); 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"); pr_err("spurious interrupt!\n");
raw_spin_lock(&desc->lock); raw_spin_lock(&desc->lock);
desc->chip->ack(cascade_virq); /* IRQ_LEVEL */ chip->irq_ack(&desc->irq_data); /* IRQ_LEVEL */
if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
desc->chip->unmask(cascade_virq); chip->irq_unmask(&desc->irq_data);
raw_spin_unlock(&desc->lock); 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) * This will be called by device drivers (via enable_IRQ)
* to enable INTA in the bridge interrupt status register. * 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; u32 bus, dev_id, function, mask;
const u32 sub_bus = 0; 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 */ /* The IRQ has already been locked by the caller */
bus = REAL_IRQ_TO_BUS(rirq); 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 */ /* 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; u32 bus, dev_id, function, mask;
const u32 sub_bus = 0; 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); bus = REAL_IRQ_TO_BUS(rirq);
function = REAL_IRQ_TO_FUNC(rirq); function = REAL_IRQ_TO_FUNC(rirq);
dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
/* Link the IRQ number to the bridge */ /* 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 */ /* Unmask bridge interrupts in the FISR */
mask = 0x01010000 << function; mask = 0x01010000 << function;
HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask); HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask);
iseries_enable_IRQ(irq); iseries_enable_IRQ(d);
return 0; return 0;
} }
@ -215,21 +215,26 @@ void __init iSeries_activate_IRQs()
for_each_irq (irq) { for_each_irq (irq) {
struct irq_desc *desc = irq_to_desc(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); raw_spin_lock_irqsave(&desc->lock, flags);
desc->chip->startup(irq); chip->irq_startup(&desc->irq_data);
raw_spin_unlock_irqrestore(&desc->lock, flags); raw_spin_unlock_irqrestore(&desc->lock, flags);
} }
} }
} }
/* this is not called anywhere currently */ /* 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; u32 bus, dev_id, function, mask;
const u32 sub_bus = 0; 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 */ /* irq should be locked by the caller */
bus = REAL_IRQ_TO_BUS(rirq); 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) * This will be called by device drivers (via disable_IRQ)
* to disable INTA in the bridge interrupt status register. * 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; u32 bus, dev_id, function, mask;
const u32 sub_bus = 0; 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 */ /* The IRQ has already been locked by the caller */
bus = REAL_IRQ_TO_BUS(rirq); 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); 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), HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq),
(REAL_IRQ_TO_IDSEL(rirq) << 4) + REAL_IRQ_TO_FUNC(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 = { static struct irq_chip iseries_pic = {
.name = "iSeries", .name = "iSeries",
.startup = iseries_startup_IRQ, .irq_startup = iseries_startup_IRQ,
.shutdown = iseries_shutdown_IRQ, .irq_shutdown = iseries_shutdown_IRQ,
.unmask = iseries_enable_IRQ, .irq_unmask = iseries_enable_IRQ,
.mask = iseries_disable_IRQ, .irq_mask = iseries_disable_IRQ,
.eoi = iseries_end_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); nmi_virq = irq_create_mapping(NULL, *nmiprop);
mpic_irq_set_priority(nmi_virq, 15); mpic_irq_set_priority(nmi_virq, 15);
set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING); 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); 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) { if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
printk(KERN_ERR "NMI delivered\n"); printk(KERN_ERR "NMI delivered\n");
debugger(regs); debugger(regs);
mpic_end_irq(nmi_virq); mpic_end_irq(irq_get_irq_data(nmi_virq));
goto out; 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); unsigned long bit = 1UL << (src & 0x1f);
int i = src >> 5; int i = src >> 5;
unsigned long flags; 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); 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); unsigned long bit = 1UL << (src & 0x1f);
int i = src >> 5; int i = src >> 5;
unsigned long flags; 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 /* When an irq gets requested for the first client, if it's an
* edge interrupt, we clear any previous one on the controller * 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 long flags;
unsigned int src = irq_map[virq].hwirq; unsigned int src = irq_map[d->irq].hwirq;
unsigned long bit = 1UL << (src & 0x1f); unsigned long bit = 1UL << (src & 0x1f);
int i = src >> 5; int i = src >> 5;
raw_spin_lock_irqsave(&pmac_pic_lock, flags); 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); out_le32(&pmac_irq_hw[i]->ack, bit);
__set_bit(src, ppc_cached_irq_mask); __set_bit(src, ppc_cached_irq_mask);
__pmac_set_irq_mask(src, 0); __pmac_set_irq_mask(src, 0);
@ -166,10 +166,10 @@ static unsigned int pmac_startup_irq(unsigned int virq)
return 0; return 0;
} }
static void pmac_mask_irq(unsigned int virq) static void pmac_mask_irq(struct irq_data *d)
{ {
unsigned long flags; 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); raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__clear_bit(src, ppc_cached_irq_mask); __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); 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 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); raw_spin_lock_irqsave(&pmac_pic_lock, flags);
__set_bit(src, ppc_cached_irq_mask); __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); 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; unsigned long flags;
raw_spin_lock_irqsave(&pmac_pic_lock, 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); raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
return 1; return 1;
} }
static struct irq_chip pmac_pic = { static struct irq_chip pmac_pic = {
.name = "PMAC-PIC", .name = "PMAC-PIC",
.startup = pmac_startup_irq, .irq_startup = pmac_startup_irq,
.mask = pmac_mask_irq, .irq_mask = pmac_mask_irq,
.ack = pmac_ack_irq, .irq_ack = pmac_ack_irq,
.mask_ack = pmac_mask_and_ack_irq, .irq_mask_ack = pmac_mask_and_ack_irq,
.unmask = pmac_unmask_irq, .irq_unmask = pmac_unmask_irq,
.retrigger = pmac_retrigger, .irq_retrigger = pmac_retrigger,
}; };
static irqreturn_t gatwick_action(int cpl, void *dev_id) 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) 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); unsigned int cascade_irq = mpic_get_one_irq(mpic);
if (cascade_irq != NO_IRQ) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_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) static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
@ -707,7 +709,7 @@ static int pmacpic_resume(struct sys_device *sysdev)
mb(); mb();
for (i = 0; i < max_real_irqs; ++i) for (i = 0; i < max_real_irqs; ++i)
if (test_bit(i, sleep_save_mask)) if (test_bit(i, sleep_save_mask))
pmac_unmask_irq(i); pmac_unmask_irq(irq_get_irq_data(i));
return 0; 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(). * 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; unsigned long flags;
pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, 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); 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); lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
local_irq_restore(flags); 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(). * 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; unsigned long flags;
pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, 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); 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); lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
local_irq_restore(flags); local_irq_restore(flags);
} }
@ -141,10 +141,10 @@ static void ps3_chip_unmask(unsigned int virq)
* Calls lv1_end_of_interrupt_ext(). * 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); const struct ps3_private *pd = irq_data_get_irq_chip_data(d);
lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq); 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 = { static struct irq_chip ps3_irq_chip = {
.name = "ps3", .name = "ps3",
.mask = ps3_chip_mask, .irq_mask = ps3_chip_mask,
.unmask = ps3_chip_unmask, .irq_unmask = ps3_chip_unmask,
.eoi = ps3_chip_eoi, .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; goto fail_set;
} }
ps3_chip_mask(*virq); ps3_chip_mask(irq_get_irq_data(*virq));
return result; 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__, pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__,
__LINE__, pd->ppe_id, pd->thread_id, virq); __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); 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); 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)); result = lv1_destruct_event_receive_port(virq_to_hw(virq));
@ -492,7 +492,7 @@ int ps3_io_irq_destroy(unsigned int virq)
int result; int result;
unsigned long outlet = virq_to_hw(virq); 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, * lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
@ -553,7 +553,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
{ {
int result; int result;
ps3_chip_mask(virq); ps3_chip_mask(irq_get_irq_data(virq));
result = lv1_deconfigure_virtual_uart_irq(); result = lv1_deconfigure_virtual_uart_irq();
if (result) { if (result) {
@ -605,7 +605,7 @@ int ps3_spe_irq_destroy(unsigned int virq)
{ {
int result; int result;
ps3_chip_mask(virq); ps3_chip_mask(irq_get_irq_data(virq));
result = ps3_irq_plug_destroy(virq); result = ps3_irq_plug_destroy(virq);
BUG_ON(result); BUG_ON(result);

View file

@ -508,12 +508,7 @@ static int cmm_memory_isolate_cb(struct notifier_block *self,
if (action == MEM_ISOLATE_COUNT) if (action == MEM_ISOLATE_COUNT)
ret = cmm_count_pages(arg); ret = cmm_count_pages(arg);
if (ret) return notifier_from_errno(ret);
ret = notifier_from_errno(ret);
else
ret = NOTIFY_OK;
return ret;
} }
static struct notifier_block cmm_mem_isolate_nb = { static struct notifier_block cmm_mem_isolate_nb = {
@ -635,12 +630,7 @@ static int cmm_memory_cb(struct notifier_block *self,
break; break;
} }
if (ret) return notifier_from_errno(ret);
ret = notifier_from_errno(ret);
else
ret = NOTIFY_OK;
return ret;
} }
static struct notifier_block cmm_mem_nb = { 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 * Save the values of the device bars. Unlike the restore
* routine, this routine is *not* recursive. This is because * 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. * an entire slot is reset at a time.
*/ */
static void eeh_save_bars(struct pci_dn *pdn) static void eeh_save_bars(struct pci_dn *pdn)

View file

@ -33,6 +33,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/crash_dump.h> #include <linux/crash_dump.h>
#include <linux/memory.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/rtas.h> #include <asm/rtas.h>
@ -45,6 +46,7 @@
#include <asm/tce.h> #include <asm/tce.h>
#include <asm/ppc-pci.h> #include <asm/ppc-pci.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/mmzone.h>
#include "plpar_wrappers.h" #include "plpar_wrappers.h"
@ -270,6 +272,152 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum)
return tce_ret; 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 #ifdef CONFIG_PCI
static void iommu_table_setparms(struct pci_controller *phb, static void iommu_table_setparms(struct pci_controller *phb,
struct device_node *dn, struct device_node *dn,
@ -495,6 +643,329 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
pci_name(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) static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
{ {
struct device_node *pdn, *dn; 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); 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 */ #else /* CONFIG_PCI */
#define pci_dma_bus_setup_pSeries NULL #define pci_dma_bus_setup_pSeries NULL
#define pci_dma_dev_setup_pSeries NULL #define pci_dma_dev_setup_pSeries NULL
#define pci_dma_bus_setup_pSeriesLP NULL #define pci_dma_bus_setup_pSeriesLP NULL
#define pci_dma_dev_setup_pSeriesLP NULL #define pci_dma_dev_setup_pSeriesLP NULL
#define dma_set_mask_pSeriesLP NULL
#endif /* !CONFIG_PCI */ #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) static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
{ {
int err = NOTIFY_OK; int err = NOTIFY_OK;
struct device_node *np = node; struct device_node *np = node;
struct pci_dn *pci = PCI_DN(np); struct pci_dn *pci = PCI_DN(np);
struct direct_window *window;
switch (action) { switch (action) {
case PSERIES_RECONFIG_REMOVE: case PSERIES_RECONFIG_REMOVE:
if (pci && pci->iommu_table) if (pci && pci->iommu_table)
iommu_free_table(pci->iommu_table, np->full_name); 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; break;
default: default:
err = NOTIFY_DONE; err = NOTIFY_DONE;
@ -587,6 +1172,7 @@ void iommu_init_early_pSeries(void)
ppc_md.tce_get = tce_get_pSeriesLP; ppc_md.tce_get = tce_get_pSeriesLP;
ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_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.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
ppc_md.dma_set_mask = dma_set_mask_pSeriesLP;
} else { } else {
ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_build = tce_build_pSeries;
ppc_md.tce_free = tce_free_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); pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
register_memory_notifier(&iommu_mem_nb);
set_pci_dma_ops(&dma_iommu_ops); set_pci_dma_ops(&dma_iommu_ops);
} }

View file

@ -93,8 +93,18 @@ static void rtas_disable_msi(struct pci_dev *pdev)
if (!pdn) if (!pdn)
return; 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) static int rtas_query_irq_number(struct pci_dn *pdn, int offset)

View file

@ -16,6 +16,8 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/kmsg_dump.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/nvram.h> #include <asm/nvram.h>
#include <asm/rtas.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 char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */
static DEFINE_SPINLOCK(nvram_lock); static DEFINE_SPINLOCK(nvram_lock);
static long nvram_error_log_index = -1;
static long nvram_error_log_size = 0;
struct err_log_info { struct err_log_info {
int error_type; int error_type;
unsigned int seq_num; 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) 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 * 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 * 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): * The 'data' section would look like (in bytes):
* +--------------+------------+-----------------------------------+ * +--------------+------------+-----------------------------------+
* | event_logged | sequence # | error log | * | 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 * 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) * sequence #: The unique sequence # for each event. (until it wraps)
* error log: The error log from event_scan * error log: The error log from event_scan
*/ */
int nvram_write_error_log(char * buff, int length, int nvram_write_os_partition(struct nvram_os_partition *part, char * buff,
unsigned int err_type, unsigned int error_log_cnt) int length, unsigned int err_type, unsigned int error_log_cnt)
{ {
int rc; int rc;
loff_t tmp_index; loff_t tmp_index;
struct err_log_info info; struct err_log_info info;
if (nvram_error_log_index == -1) { if (part->index == -1) {
return -ESPIPE; return -ESPIPE;
} }
if (length > nvram_error_log_size) { if (length > part->size) {
length = nvram_error_log_size; length = part->size;
} }
info.error_type = err_type; info.error_type = err_type;
info.seq_num = error_log_cnt; 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); rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index);
if (rc <= 0) { 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 rc;
} }
rc = ppc_md.nvram_write(buff, length, &tmp_index); rc = ppc_md.nvram_write(buff, length, &tmp_index);
if (rc <= 0) { 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 rc;
} }
return 0; 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 /* nvram_read_error_log
* *
* Reads nvram for error log for at most 'length' * 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; loff_t tmp_index;
struct err_log_info info; struct err_log_info info;
if (nvram_error_log_index == -1) if (rtas_log_partition.index == -1)
return -1; return -1;
if (length > nvram_error_log_size) if (length > rtas_log_partition.size)
length = nvram_error_log_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); rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index);
if (rc <= 0) { if (rc <= 0) {
@ -244,37 +293,40 @@ int nvram_clear_error_log(void)
int clear_word = ERR_FLAG_ALREADY_LOGGED; int clear_word = ERR_FLAG_ALREADY_LOGGED;
int rc; int rc;
if (nvram_error_log_index == -1) if (rtas_log_partition.index == -1)
return -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); rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index);
if (rc <= 0) { if (rc <= 0) {
printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc); printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc);
return rc; return rc;
} }
last_unread_rtas_event = 0;
return 0; return 0;
} }
/* pseries_nvram_init_log_partition /* pseries_nvram_init_os_partition
* *
* This will setup the partition we need for buffering the * This sets up a partition with an "OS" signature.
* error logs and cleanup partitions if needed.
* *
* The general strategy is the following: * The general strategy is the following:
* 1.) If there is log partition large enough then use it. * 1.) If a partition with the indicated name already exists...
* 2.) If there is none large enough, search * - If it's large enough, use it.
* for a free partition that is large enough. * - Otherwise, recycle it and keep going.
* 3.) If there is not a free partition large enough remove * 2.) Search for a free partition that is large enough.
* _all_ OS partitions and consolidate the space. * 3.) If there's not a free partition large enough, recycle any obsolete
* 4.) Will first try getting a chunk that will satisfy the maximum * OS partitions and try again.
* error log size (NVRAM_MAX_REQ). * 4.) Will first try getting a chunk that will satisfy the requested size.
* 5.) If the max chunk cannot be allocated then try finding a chunk * 5.) If a chunk of the requested size cannot be allocated, then try finding
* that will satisfy the minum needed (NVRAM_MIN_REQ). * 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; loff_t p;
int size; int size;
@ -282,47 +334,76 @@ static int __init pseries_nvram_init_log_partition(void)
/* Scan nvram for partitions */ /* Scan nvram for partitions */
nvram_scan_partitions(); nvram_scan_partitions();
/* Lookg for ours */ /* Look for ours */
p = nvram_find_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS, &size); p = nvram_find_partition(part->name, NVRAM_SIG_OS, &size);
/* Found one but too small, remove it */ /* Found one but too small, remove it */
if (p && size < NVRAM_MIN_REQ) { if (p && size < part->min_size) {
pr_info("nvram: Found too small "NVRAM_LOG_PART_NAME" partition" pr_info("nvram: Found too small %s partition,"
",removing it..."); " removing it...\n", part->name);
nvram_remove_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS); nvram_remove_partition(part->name, NVRAM_SIG_OS, NULL);
p = 0; p = 0;
} }
/* Create one if we didn't find */ /* Create one if we didn't find */
if (!p) { if (!p) {
p = nvram_create_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS, p = nvram_create_partition(part->name, NVRAM_SIG_OS,
NVRAM_MAX_REQ, NVRAM_MIN_REQ); part->req_size, part->min_size);
/* No room for it, try to get rid of any OS partition
* and try again
*/
if (p == -ENOSPC) { if (p == -ENOSPC) {
pr_info("nvram: No room to create "NVRAM_LOG_PART_NAME pr_info("nvram: No room to create %s partition, "
" partition, deleting all OS partitions..."); "deleting any obsolete OS partitions...\n",
nvram_remove_partition(NULL, NVRAM_SIG_OS); part->name);
p = nvram_create_partition(NVRAM_LOG_PART_NAME, nvram_remove_partition(NULL, NVRAM_SIG_OS,
NVRAM_SIG_OS, NVRAM_MAX_REQ, pseries_nvram_os_partitions);
NVRAM_MIN_REQ); p = nvram_create_partition(part->name, NVRAM_SIG_OS,
part->req_size, part->min_size);
} }
} }
if (p <= 0) { if (p <= 0) {
pr_err("nvram: Failed to find or create "NVRAM_LOG_PART_NAME pr_err("nvram: Failed to find or create %s"
" partition, err %d\n", (int)p); " partition, err %d\n", part->name, (int)p);
return 0; return -1;
} }
nvram_error_log_index = p; part->index = p;
nvram_error_log_size = nvram_get_partition_size(p) - part->size = nvram_get_partition_size(p) - sizeof(struct err_log_info);
sizeof(struct err_log_info);
return 0; 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) int __init pSeries_nvram_init(void)
{ {
@ -353,3 +434,59 @@ int __init pSeries_nvram_init(void)
return 0; 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) 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(); unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq); generic_handle_irq(cascade_irq);
desc->chip->eoi(irq);
chip->irq_eoi(&desc->irq_data);
} }
static void __init pseries_setup_i8259_cascade(void) 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) #define get_irq_server(virq, cpumask, strict_check) (default_server)
#endif #endif
static void xics_unmask_irq(unsigned int virq) static void xics_unmask_irq(struct irq_data *d)
{ {
unsigned int irq; unsigned int irq;
int call_status; int call_status;
int server; 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); pr_devel(" -> map to hwirq 0x%x\n", irq);
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return; 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, call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
DEFAULT_PRIORITY); 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 * The generic MSI code returns with the interrupt disabled on the
* card, using the MSI mask bits. Firmware doesn't appear to unmask * card, using the MSI mask bits. Firmware doesn't appear to unmask
* at that level, so we do it here by hand. * at that level, so we do it here by hand.
*/ */
if (irq_to_desc(virq)->msi_desc) if (d->msi_desc)
unmask_msi_irq(irq_get_irq_data(virq)); unmask_msi_irq(d);
/* unmask it */ /* unmask it */
xics_unmask_irq(virq); xics_unmask_irq(d);
return 0; return 0;
} }
static void xics_mask_real_irq(unsigned int irq) static void xics_mask_real_irq(struct irq_data *d)
{ {
int call_status; int call_status;
if (irq == XICS_IPI) if (d->irq == XICS_IPI)
return; 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) { if (call_status != 0) {
printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n", printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
__func__, irq, call_status); __func__, d->irq, call_status);
return; return;
} }
/* Have to set XIVE to 0xff to be able to remove a slot */ /* 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); default_server, 0xff);
if (call_status != 0) { if (call_status != 0) {
printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n", printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
__func__, irq, call_status); __func__, d->irq, call_status);
return; return;
} }
} }
static void xics_mask_irq(unsigned int virq) static void xics_mask_irq(struct irq_data *d)
{ {
unsigned int irq; 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) if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return; return;
xics_mask_real_irq(irq); xics_mask_real_irq(d);
} }
static void xics_mask_unknown_vec(unsigned int vec) static void xics_mask_unknown_vec(unsigned int vec)
{ {
printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", 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) 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]; 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(); iosync();
direct_xirr_info_set((pop_cppr() << 24) | irq); 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(); iosync();
lpar_xirr_info_set((pop_cppr() << 24) | irq); 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; unsigned int irq;
int status; int status;
int xics_status[2]; int xics_status[2];
int irq_server; 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) if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return -1; return -1;
@ -406,13 +407,13 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
return -1; return -1;
} }
irq_server = get_irq_server(virq, cpumask, 1); irq_server = get_irq_server(d->irq, cpumask, 1);
if (irq_server == -1) { if (irq_server == -1) {
char cpulist[128]; char cpulist[128];
cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
printk(KERN_WARNING printk(KERN_WARNING
"%s: No online cpus in the mask %s for irq %d\n", "%s: No online cpus in the mask %s for irq %d\n",
__func__, cpulist, virq); __func__, cpulist, d->irq);
return -1; 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 = { static struct irq_chip xics_pic_direct = {
.name = "XICS", .name = "XICS",
.startup = xics_startup, .irq_startup = xics_startup,
.mask = xics_mask_irq, .irq_mask = xics_mask_irq,
.unmask = xics_unmask_irq, .irq_unmask = xics_unmask_irq,
.eoi = xics_eoi_direct, .irq_eoi = xics_eoi_direct,
.set_affinity = xics_set_affinity .irq_set_affinity = xics_set_affinity
}; };
static struct irq_chip xics_pic_lpar = { static struct irq_chip xics_pic_lpar = {
.name = "XICS", .name = "XICS",
.startup = xics_startup, .irq_startup = xics_startup,
.mask = xics_mask_irq, .irq_mask = xics_mask_irq,
.unmask = xics_unmask_irq, .irq_unmask = xics_unmask_irq,
.eoi = xics_eoi_lpar, .irq_eoi = xics_eoi_lpar,
.set_affinity = xics_set_affinity .irq_set_affinity = xics_set_affinity
}; };
@ -890,6 +891,7 @@ void xics_migrate_irqs_away(void)
for_each_irq(virq) { for_each_irq(virq) {
struct irq_desc *desc; struct irq_desc *desc;
struct irq_chip *chip;
int xics_status[2]; int xics_status[2];
int status; int status;
unsigned long flags; unsigned long flags;
@ -903,12 +905,15 @@ void xics_migrate_irqs_away(void)
/* We need to get IPIs still. */ /* We need to get IPIs still. */
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
continue; continue;
desc = irq_to_desc(virq); desc = irq_to_desc(virq);
/* We only need to migrate enabled IRQS */ /* We only need to migrate enabled IRQS */
if (desc == NULL || desc->chip == NULL if (desc == NULL || desc->action == NULL)
|| desc->action == NULL continue;
|| desc->chip->set_affinity == NULL)
chip = get_irq_desc_chip(desc);
if (chip == NULL || chip->irq_set_affinity == NULL)
continue; continue;
raw_spin_lock_irqsave(&desc->lock, flags); raw_spin_lock_irqsave(&desc->lock, flags);
@ -934,8 +939,8 @@ void xics_migrate_irqs_away(void)
virq, cpu); virq, cpu);
/* Reset affinity to all cpus */ /* Reset affinity to all cpus */
cpumask_setall(irq_to_desc(virq)->affinity); cpumask_setall(desc->irq_data.affinity);
desc->chip->set_affinity(virq, cpu_all_mask); chip->irq_set_affinity(&desc->irq_data, cpu_all_mask, true);
unlock: unlock:
raw_spin_unlock_irqrestore(&desc->lock, flags); 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 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)); 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)); 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)); out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
} }
static struct irq_chip cpm_pic = { static struct irq_chip cpm_pic = {
.name = "CPM PIC", .name = "CPM PIC",
.mask = cpm_mask_irq, .irq_mask = cpm_mask_irq,
.unmask = cpm_unmask_irq, .irq_unmask = cpm_unmask_irq,
.eoi = cpm_end_irq, .irq_eoi = cpm_end_irq,
}; };
int cpm_get_irq(void) 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, 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; 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]; bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[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]); 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; 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]; bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[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]); 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; 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]; bit = irq_to_siubit[irq_nr];
word = irq_to_siureg[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); 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; struct irq_desc *desc;
int bit, word; 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); desc = irq_to_desc(irq_nr);
if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)) 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); unsigned int src = virq_to_hw(d->irq);
struct irq_desc *desc = irq_to_desc(virq); struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vold, vnew, edibit; unsigned int vold, vnew, edibit;
/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
@ -199,11 +199,11 @@ err_sense:
static struct irq_chip cpm2_pic = { static struct irq_chip cpm2_pic = {
.name = "CPM2 SIU", .name = "CPM2 SIU",
.mask = cpm2_mask_irq, .irq_mask = cpm2_mask_irq,
.unmask = cpm2_unmask_irq, .irq_unmask = cpm2_unmask_irq,
.ack = cpm2_ack, .irq_ack = cpm2_ack,
.eoi = cpm2_end_irq, .irq_eoi = cpm2_end_irq,
.set_type = cpm2_set_irq_type, .irq_set_type = cpm2_set_irq_type,
}; };
unsigned int cpm2_get_irq(void) 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; l2cache_size = *prop;
sram_params.sram_size = get_cache_sram_size(); 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, dev_err(&dev->dev,
"Entire L2 as cache, Aborting Cache-SRAM stuff\n"); "Entire L2 as cache, Aborting Cache-SRAM stuff\n");
return -EINVAL; return -EINVAL;
} }
sram_params.sram_offset = get_cache_sram_offset(); 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, dev_err(&dev->dev,
"Entire L2 as cache, provide a valid sram offset\n"); "Entire L2 as cache, provide a valid sram offset\n");
return -EINVAL; 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> * Author: Tony Li <tony.li@freescale.com>
* Jason Jin <Jason.jin@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 * We do not need this actually. The MSIR register has been read once
* in the cascade interrupt. So, this MSI interrupt has been acked * 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 = { static struct irq_chip fsl_msi_chip = {
.irq_mask = mask_msi_irq, .irq_mask = mask_msi_irq,
.irq_unmask = unmask_msi_irq, .irq_unmask = unmask_msi_irq,
.ack = fsl_msi_end_irq, .irq_ack = fsl_msi_end_irq,
.name = "FSL-MSI", .name = "FSL-MSI",
}; };
@ -183,6 +183,7 @@ out_free:
static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) 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; unsigned int cascade_irq;
struct fsl_msi *msi_data; struct fsl_msi *msi_data;
int msir_index = -1; 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); raw_spin_lock(&desc->lock);
if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
if (desc->chip->mask_ack) if (chip->irq_mask_ack)
desc->chip->mask_ack(irq); chip->irq_mask_ack(&desc->irq_data);
else { else {
desc->chip->mask(irq); chip->irq_mask(&desc->irq_data);
desc->chip->ack(irq); 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) { switch (msi_data->feature & FSL_PIC_IP_MASK) {
case FSL_PIC_IP_MPIC: case FSL_PIC_IP_MPIC:
desc->chip->eoi(irq); chip->irq_eoi(&desc->irq_data);
break; break;
case FSL_PIC_IP_IPIC: case FSL_PIC_IP_IPIC:
if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
desc->chip->unmask(irq); chip->irq_unmask(&desc->irq_data);
break; break;
} }
unlock: unlock:
@ -273,18 +274,46 @@ static int fsl_of_msi_remove(struct platform_device *ofdev)
return 0; 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) static int __devinit fsl_of_msi_probe(struct platform_device *dev)
{ {
struct fsl_msi *msi; struct fsl_msi *msi;
struct resource res; struct resource res;
int err, i, count; int err, i, j, irq_index, count;
int rc; int rc;
int virt_msir;
const u32 *p; const u32 *p;
struct fsl_msi_feature *features; struct fsl_msi_feature *features;
struct fsl_msi_cascade_data *cascade_data = NULL;
int len; int len;
u32 offset; u32 offset;
static const u32 all_avail[] = { 0, NR_MSI_IRQS };
if (!dev->dev.of_match) if (!dev->dev.of_match)
return -EINVAL; return -EINVAL;
@ -335,42 +364,34 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
goto error_out; goto error_out;
} }
p = of_get_property(dev->dev.of_node, "interrupts", &count); p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
if (!p) { if (p && len % (2 * sizeof(u32)) != 0) {
dev_err(&dev->dev, "no interrupts property found on %s\n", dev_err(&dev->dev, "%s: Malformed msi-available-ranges property\n",
dev->dev.of_node->full_name); __func__);
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);
err = -EINVAL; err = -EINVAL;
goto error_out; 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); if (!p)
for (i = 0; i < min(count / 2, NR_MSI_REG); i++) { p = all_avail;
virt_msir = irq_of_parse_and_map(dev->dev.of_node, i);
if (virt_msir != NO_IRQ) { for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) {
cascade_data = kzalloc( if (p[i * 2] % IRQS_PER_MSI_REG ||
sizeof(struct fsl_msi_cascade_data), p[i * 2 + 1] % IRQS_PER_MSI_REG) {
GFP_KERNEL); printk(KERN_WARNING "%s: %s: msi available range of %u at %u is not IRQ-aligned\n",
if (!cascade_data) { __func__, dev->dev.of_node->full_name,
dev_err(&dev->dev, p[i * 2 + 1], p[i * 2]);
"No memory for MSI cascade data\n"); err = -EINVAL;
err = -ENOMEM; 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; 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. * 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. * Copyright 2008-2009 MontaVista Software, Inc.
* *
* Initial author: Xianghua Xiao <x.xiao@freescale.com> * 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 resource *rsrc)
{ {
struct ccsr_pci __iomem *pci; 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 mem, sz, paddr_hi = 0;
u64 paddr_lo = ULLONG_MAX; u64 paddr_lo = ULLONG_MAX;
u32 pcicsrbar = 0, pcicsrbar_sz; 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", pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
(u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1); (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); pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);
if (!pci) { if (!pci) {
dev_err(hose->parent, "Unable to map ATMU registers\n"); 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) */ /* Disable all windows (except powar0 since it's ignored) */
for(i = 1; i < 5; i++) for(i = 1; i < 5; i++)
out_be32(&pci->pow[i].powar, 0); 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); out_be32(&pci->piw[i].piwar, 0);
/* Setup outbound MEM window */ /* Setup outbound MEM window */
@ -204,7 +211,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
mem_log++; mem_log++;
} }
piwar |= (mem_log - 1); piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
/* Setup inbound memory window */ /* Setup inbound memory window */
out_be32(&pci->piw[win_idx].pitar, 0x00000000); out_be32(&pci->piw[win_idx].pitar, 0x00000000);

View file

@ -1,7 +1,7 @@
/* /*
* MPC85xx/86xx PCI Express structure define * 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 * 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 * 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_TGI_LOCAL 0x00f00000 /* target - local memory */
#define PIWAR_READ_SNOOP 0x00050000 #define PIWAR_READ_SNOOP 0x00050000
#define PIWAR_WRITE_SNOOP 0x00005000 #define PIWAR_WRITE_SNOOP 0x00005000
#define PIWAR_SZ_MASK 0x0000003f
/* PCI/PCI Express outbound window reg */ /* PCI/PCI Express outbound window reg */
struct pci_outbound_window_regs { struct pci_outbound_window_regs {
@ -49,7 +50,9 @@ struct ccsr_pci {
__be32 int_ack; /* 0x.008 - PCI Interrupt Acknowledge Register */ __be32 int_ack; /* 0x.008 - PCI Interrupt Acknowledge Register */
__be32 pex_otb_cpl_tor; /* 0x.00c - PCIE Outbound completion timeout register */ __be32 pex_otb_cpl_tor; /* 0x.00c - PCIE Outbound completion timeout register */
__be32 pex_conf_tor; /* 0x.010 - PCIE configuration 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_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_disr; /* 0x.024 - PCIE PME and message disable register */
__be32 pex_pme_mes_ier; /* 0x.028 - PCIE PME and message interrupt enable 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. * in all of the other outbound windows.
*/ */
struct pci_outbound_window_regs pow[5]; struct pci_outbound_window_regs pow[5];
u8 res14[96];
u8 res14[256]; struct pci_inbound_window_regs pmit; /* 0xd00 - 0xd9c Inbound MSI */
u8 res6[96];
/* PCI/PCI Express inbound window 3-1 /* PCI/PCI Express inbound window 3-0
* inbound window 1 supports only a 32-bit base address and does not * inbound window 1 supports only a 32-bit base address and does not
* define an inbound window base extended address register. * 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 */ __be32 pex_err_dr; /* 0x.e00 - PCI/PCIE error detect register */
u8 res21[4]; u8 res21[4];

View file

@ -78,19 +78,19 @@ unsigned int i8259_irq(void)
return irq; 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; unsigned long flags;
raw_spin_lock_irqsave(&i8259_lock, flags); raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr > 7) { if (d->irq > 7) {
cached_A1 |= 1 << (irq_nr-8); cached_A1 |= 1 << (d->irq-8);
inb(0xA1); /* DUMMY */ inb(0xA1); /* DUMMY */
outb(cached_A1, 0xA1); outb(cached_A1, 0xA1);
outb(0x20, 0xA0); /* Non-specific EOI */ outb(0x20, 0xA0); /* Non-specific EOI */
outb(0x20, 0x20); /* Non-specific EOI to cascade */ outb(0x20, 0x20); /* Non-specific EOI to cascade */
} else { } else {
cached_21 |= 1 << irq_nr; cached_21 |= 1 << d->irq;
inb(0x21); /* DUMMY */ inb(0x21); /* DUMMY */
outb(cached_21, 0x21); outb(cached_21, 0x21);
outb(0x20, 0x20); /* Non-specific EOI */ outb(0x20, 0x20); /* Non-specific EOI */
@ -104,42 +104,42 @@ static void i8259_set_irq_mask(int irq_nr)
outb(cached_21,0x21); 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; 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); raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr < 8) if (d->irq < 8)
cached_21 |= 1 << irq_nr; cached_21 |= 1 << d->irq;
else else
cached_A1 |= 1 << (irq_nr-8); cached_A1 |= 1 << (d->irq-8);
i8259_set_irq_mask(irq_nr); i8259_set_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&i8259_lock, flags); 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; 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); raw_spin_lock_irqsave(&i8259_lock, flags);
if (irq_nr < 8) if (d->irq < 8)
cached_21 &= ~(1 << irq_nr); cached_21 &= ~(1 << d->irq);
else else
cached_A1 &= ~(1 << (irq_nr-8)); cached_A1 &= ~(1 << (d->irq-8));
i8259_set_irq_mask(irq_nr); i8259_set_irq_mask(d->irq);
raw_spin_unlock_irqrestore(&i8259_lock, flags); raw_spin_unlock_irqrestore(&i8259_lock, flags);
} }
static struct irq_chip i8259_pic = { static struct irq_chip i8259_pic = {
.name = "i8259", .name = "i8259",
.mask = i8259_mask_irq, .irq_mask = i8259_mask_irq,
.disable = i8259_mask_irq, .irq_disable = i8259_mask_irq,
.unmask = i8259_unmask_irq, .irq_unmask = i8259_unmask_irq,
.mask_ack = i8259_mask_and_ack_irq, .irq_mask_ack = i8259_mask_and_ack_irq,
}; };
static struct resource pic1_iores = { 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) static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
{ {
/* Make sure irq is masked in hardware */ /* Make sure irq is masked in hardware */
i8259_mask_irq(virq); i8259_mask_irq(irq_get_irq_data(virq));
/* remove chip and handler */ /* remove chip and handler */
set_irq_chip_and_handler(virq, NULL, NULL); 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) #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); struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(virq); unsigned int src = ipic_irq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 temp; u32 temp;
@ -539,10 +539,10 @@ static void ipic_unmask_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&ipic_lock, flags); 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); struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(virq); unsigned int src = ipic_irq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 temp; u32 temp;
@ -559,10 +559,10 @@ static void ipic_mask_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&ipic_lock, flags); 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); struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(virq); unsigned int src = ipic_irq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 temp; u32 temp;
@ -578,10 +578,10 @@ static void ipic_ack_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&ipic_lock, flags); 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); struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(virq); unsigned int src = ipic_irq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 temp; u32 temp;
@ -601,11 +601,11 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
raw_spin_unlock_irqrestore(&ipic_lock, flags); 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); struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(virq); unsigned int src = ipic_irq_to_hw(d->irq);
struct irq_desc *desc = irq_to_desc(virq); struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vold, vnew, edibit; unsigned int vold, vnew, edibit;
if (flow_type == IRQ_TYPE_NONE) 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) { if (flow_type & IRQ_TYPE_LEVEL_LOW) {
desc->status |= IRQ_LEVEL; desc->status |= IRQ_LEVEL;
desc->handle_irq = handle_level_irq; desc->handle_irq = handle_level_irq;
desc->chip = &ipic_level_irq_chip; desc->irq_data.chip = &ipic_level_irq_chip;
} else { } else {
desc->handle_irq = handle_edge_irq; 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 /* 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 */ /* level interrupts and edge interrupts have different ack operations */
static struct irq_chip ipic_level_irq_chip = { static struct irq_chip ipic_level_irq_chip = {
.name = "IPIC", .name = "IPIC",
.unmask = ipic_unmask_irq, .irq_unmask = ipic_unmask_irq,
.mask = ipic_mask_irq, .irq_mask = ipic_mask_irq,
.mask_ack = ipic_mask_irq, .irq_mask_ack = ipic_mask_irq,
.set_type = ipic_set_irq_type, .irq_set_type = ipic_set_irq_type,
}; };
static struct irq_chip ipic_edge_irq_chip = { static struct irq_chip ipic_edge_irq_chip = {
.name = "IPIC", .name = "IPIC",
.unmask = ipic_unmask_irq, .irq_unmask = ipic_unmask_irq,
.mask = ipic_mask_irq, .irq_mask = ipic_mask_irq,
.mask_ack = ipic_mask_irq_and_ack, .irq_mask_ack = ipic_mask_irq_and_ack,
.ack = ipic_ack_irq, .irq_ack = ipic_ack_irq,
.set_type = ipic_set_irq_type, .irq_set_type = ipic_set_irq_type,
}; };
static int ipic_host_match(struct irq_host *h, struct device_node *node) 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); 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; 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; bit = irq_nr & 0x1f;
word = irq_nr >> 5; 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]); 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; 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; bit = irq_nr & 0x1f;
word = irq_nr >> 5; 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]); 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; 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; bit = irq_nr & 0x1f;
out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); 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; 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; bit = irq_nr & 0x1f;
word = irq_nr >> 5; 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]); 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 &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; 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; desc->status |= IRQ_LEVEL;
if (flow_type & IRQ_TYPE_EDGE_FALLING) { 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); unsigned int siel = in_be32(&siu_reg->sc_siel);
/* only external IRQ senses are programmable */ /* 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 = { static struct irq_chip mpc8xx_pic = {
.name = "MPC8XX SIU", .name = "MPC8XX SIU",
.unmask = mpc8xx_unmask_irq, .irq_unmask = mpc8xx_unmask_irq,
.mask = mpc8xx_mask_irq, .irq_mask = mpc8xx_mask_irq,
.ack = mpc8xx_ack, .irq_ack = mpc8xx_ack,
.eoi = mpc8xx_end_irq, .irq_eoi = mpc8xx_end_irq,
.set_type = mpc8xx_set_irq_type, .irq_set_type = mpc8xx_set_irq_type,
}; };
unsigned int mpc8xx_get_irq(void) 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))); 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; struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&mpc8xxx_gc->lock, 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); 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; struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&mpc8xxx_gc->lock, 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); 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; 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; struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
unsigned long flags; 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: case IRQ_TYPE_EDGE_FALLING:
spin_lock_irqsave(&mpc8xxx_gc->lock, flags); spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
setbits32(mm->regs + GPIO_ICR, 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); spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
break; break;
case IRQ_TYPE_EDGE_BOTH: case IRQ_TYPE_EDGE_BOTH:
spin_lock_irqsave(&mpc8xxx_gc->lock, flags); spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
clrbits32(mm->regs + GPIO_ICR, 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); spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
break; break;
@ -217,11 +217,11 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
return 0; 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; 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; void __iomem *reg;
unsigned int shift; unsigned int shift;
unsigned long flags; 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 = { static struct irq_chip mpc8xxx_irq_chip = {
.name = "mpc8xxx-gpio", .name = "mpc8xxx-gpio",
.unmask = mpc8xxx_irq_unmask, .irq_unmask = mpc8xxx_irq_unmask,
.mask = mpc8xxx_irq_mask, .irq_mask = mpc8xxx_irq_mask,
.ack = mpc8xxx_irq_ack, .irq_ack = mpc8xxx_irq_ack,
.set_type = mpc8xxx_irq_set_type, .irq_set_type = mpc8xxx_irq_set_type,
}; };
static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, 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; struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
if (mpc8xxx_gc->of_dev_id_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_data(virq, h->host_data);
set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); 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,mpc8572-gpio", },
{ .compatible = "fsl,mpc8610-gpio", }, { .compatible = "fsl,mpc8610-gpio", },
{ .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, }, { .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) for_each_matching_node(np, mpc8xxx_gpio_ids)
mpc8xxx_add_controller(np); mpc8xxx_add_controller(np);
for_each_compatible_node(np, NULL, "fsl,qoriq-gpio")
mpc8xxx_add_controller(np);
return 0; return 0;
} }
arch_initcall(mpc8xxx_add_gpiochips); arch_initcall(mpc8xxx_add_gpiochips);

View file

@ -611,7 +611,7 @@ static struct mpic *mpic_find(unsigned int irq)
if (irq < NUM_ISA_INTERRUPTS) if (irq < NUM_ISA_INTERRUPTS)
return NULL; return NULL;
return irq_to_desc(irq)->chip_data; return get_irq_chip_data(irq);
} }
/* Determine if the linux irq is an IPI */ /* Determine if the linux irq is an IPI */
@ -636,16 +636,22 @@ static inline u32 mpic_physmask(u32 cpumask)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Get the mpic structure from the IPI number */ /* 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 #endif
/* Get the mpic structure from the irq number */ /* Get the mpic structure from the irq number */
static inline struct mpic * mpic_from_irq(unsigned int irq) 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 */ /* 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; unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq); struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(irq); 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_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
mpic_irq_read(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); } 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; unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq); struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(irq); 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_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
mpic_irq_read(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)); } 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 #ifdef DEBUG_IRQ
DBG("%s: end_irq: %d\n", mpic->name, irq); DBG("%s: end_irq: %d\n", mpic->name, d->irq);
#endif #endif
/* We always EOI on end_irq() even for edge interrupts since that /* We always EOI on end_irq() even for edge interrupts since that
* should only lower the priority, the MPIC should have properly * 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 #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); struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(irq); 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); 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); struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(irq); unsigned int src = mpic_irq_to_hw(d->irq);
mpic_unmask_irq(irq); mpic_unmask_irq(d);
mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status); mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
return 0; 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); struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(irq); unsigned int src = mpic_irq_to_hw(d->irq);
mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status); mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
mpic_mask_irq(irq); 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); struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(irq); unsigned int src = mpic_irq_to_hw(d->irq);
#ifdef DEBUG_IRQ #ifdef DEBUG_IRQ
DBG("%s: end_irq: %d\n", mpic->name, irq); DBG("%s: end_irq: %d\n", mpic->name, d->irq);
#endif #endif
/* We always EOI on end_irq() even for edge interrupts since that /* We always EOI on end_irq() even for edge interrupts since that
* should only lower the priority, the MPIC should have properly * should only lower the priority, the MPIC should have properly
* latched another edge interrupt coming in anyway * 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_ht_end_irq(mpic, src);
mpic_eoi(mpic); mpic_eoi(mpic);
} }
@ -772,23 +778,23 @@ static void mpic_end_ht_irq(unsigned int irq)
#ifdef CONFIG_SMP #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); struct mpic *mpic = mpic_from_ipi(d);
unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]; 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); 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! */ /* 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 * 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 */ #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); struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(irq); unsigned int src = mpic_irq_to_hw(d->irq);
if (mpic->flags & MPIC_SINGLE_DEST_CPU) { if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
int cpuid = irq_choose_cpu(cpumask); 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); struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(virq); unsigned int src = mpic_irq_to_hw(d->irq);
struct irq_desc *desc = irq_to_desc(virq); struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vecpri, vold, vnew; unsigned int vecpri, vold, vnew;
DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n", 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) if (src >= mpic->irq_count)
return -EINVAL; return -EINVAL;
@ -907,28 +914,28 @@ void mpic_set_vector(unsigned int virq, unsigned int vector)
} }
static struct irq_chip mpic_irq_chip = { static struct irq_chip mpic_irq_chip = {
.mask = mpic_mask_irq, .irq_mask = mpic_mask_irq,
.unmask = mpic_unmask_irq, .irq_unmask = mpic_unmask_irq,
.eoi = mpic_end_irq, .irq_eoi = mpic_end_irq,
.set_type = mpic_set_irq_type, .irq_set_type = mpic_set_irq_type,
}; };
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static struct irq_chip mpic_ipi_chip = { static struct irq_chip mpic_ipi_chip = {
.mask = mpic_mask_ipi, .irq_mask = mpic_mask_ipi,
.unmask = mpic_unmask_ipi, .irq_unmask = mpic_unmask_ipi,
.eoi = mpic_end_ipi, .irq_eoi = mpic_end_ipi,
}; };
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
#ifdef CONFIG_MPIC_U3_HT_IRQS #ifdef CONFIG_MPIC_U3_HT_IRQS
static struct irq_chip mpic_irq_ht_chip = { static struct irq_chip mpic_irq_ht_chip = {
.startup = mpic_startup_ht_irq, .irq_startup = mpic_startup_ht_irq,
.shutdown = mpic_shutdown_ht_irq, .irq_shutdown = mpic_shutdown_ht_irq,
.mask = mpic_mask_irq, .irq_mask = mpic_mask_irq,
.unmask = mpic_unmask_ht_irq, .irq_unmask = mpic_unmask_ht_irq,
.eoi = mpic_end_ht_irq, .irq_eoi = mpic_end_ht_irq,
.set_type = mpic_set_irq_type, .irq_set_type = mpic_set_irq_type,
}; };
#endif /* CONFIG_MPIC_U3_HT_IRQS */ #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 = mpic_irq_chip;
mpic->hc_irq.name = name; mpic->hc_irq.name = name;
if (flags & MPIC_PRIMARY) 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 #ifdef CONFIG_MPIC_U3_HT_IRQS
mpic->hc_ht_irq = mpic_irq_ht_chip; mpic->hc_ht_irq = mpic_irq_ht_chip;
mpic->hc_ht_irq.name = name; mpic->hc_ht_irq.name = name;
if (flags & MPIC_PRIMARY) 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 */ #endif /* CONFIG_MPIC_U3_HT_IRQS */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP

View file

@ -34,9 +34,10 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
} }
#endif #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 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); extern void mpic_reset_core(int cpu);
#endif /* _POWERPC_SYSDEV_MPIC_H */ #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); pr_debug("mpic_pasemi_msi_mask_irq %d\n", data->irq);
mask_msi_irq(data); mask_msi_irq(data);
mpic_mask_irq(data->irq); mpic_mask_irq(data);
} }
static void mpic_pasemi_msi_unmask_irq(struct irq_data *data) static void mpic_pasemi_msi_unmask_irq(struct irq_data *data)
{ {
pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq); pr_debug("mpic_pasemi_msi_unmask_irq %d\n", data->irq);
mpic_unmask_irq(data->irq); mpic_unmask_irq(data);
unmask_msi_irq(data); unmask_msi_irq(data);
} }
static struct irq_chip mpic_pasemi_msi_chip = { static struct irq_chip mpic_pasemi_msi_chip = {
.irq_shutdown = mpic_pasemi_msi_mask_irq, .irq_shutdown = mpic_pasemi_msi_mask_irq,
.irq_mask = mpic_pasemi_msi_mask_irq, .irq_mask = mpic_pasemi_msi_mask_irq,
.irq_unmask = mpic_pasemi_msi_unmask_irq, .irq_unmask = mpic_pasemi_msi_unmask_irq,
.eoi = mpic_end_irq, .irq_eoi = mpic_end_irq,
.set_type = mpic_set_irq_type, .irq_set_type = mpic_set_irq_type,
.set_affinity = mpic_set_affinity, .irq_set_affinity = mpic_set_affinity,
.name = "PASEMI-MSI", .name = "PASEMI-MSI",
}; };
static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type) 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) static void mpic_u3msi_mask_irq(struct irq_data *data)
{ {
mask_msi_irq(data); mask_msi_irq(data);
mpic_mask_irq(data->irq); mpic_mask_irq(data);
} }
static void mpic_u3msi_unmask_irq(struct irq_data *data) static void mpic_u3msi_unmask_irq(struct irq_data *data)
{ {
mpic_unmask_irq(data->irq); mpic_unmask_irq(data);
unmask_msi_irq(data); unmask_msi_irq(data);
} }
static struct irq_chip mpic_u3msi_chip = { static struct irq_chip mpic_u3msi_chip = {
.irq_shutdown = mpic_u3msi_mask_irq, .irq_shutdown = mpic_u3msi_mask_irq,
.irq_mask = mpic_u3msi_mask_irq, .irq_mask = mpic_u3msi_mask_irq,
.irq_unmask = mpic_u3msi_unmask_irq, .irq_unmask = mpic_u3msi_unmask_irq,
.eoi = mpic_end_irq, .irq_eoi = mpic_end_irq,
.set_type = mpic_set_irq_type, .irq_set_type = mpic_set_irq_type,
.set_affinity = mpic_set_affinity, .irq_set_affinity = mpic_set_affinity,
.name = "MPIC-U3MSI", .name = "MPIC-U3MSI",
}; };
static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos) 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) if (prop)
pdata.freq_m = *prop; pdata.freq_m = *prop;
pdata.freq_m = 3; /* default */ pdata.freq_n = 3; /* default */
prop = of_get_property(np, "freq_n", NULL); prop = of_get_property(np, "freq_n", NULL);
if (prop) if (prop)
pdata.freq_n = *prop; pdata.freq_n = *prop;

View file

@ -76,9 +76,9 @@ static struct irq_host *mv64x60_irq_host;
* mv64x60_chip_low functions * 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; unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, 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); (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; unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, 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 = { static struct irq_chip mv64x60_chip_low = {
.name = "mv64x60_low", .name = "mv64x60_low",
.mask = mv64x60_mask_low, .irq_mask = mv64x60_mask_low,
.mask_ack = mv64x60_mask_low, .irq_mask_ack = mv64x60_mask_low,
.unmask = mv64x60_unmask_low, .irq_unmask = mv64x60_unmask_low,
}; };
/* /*
* mv64x60_chip_high functions * 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; unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, 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); (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; unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, 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 = { static struct irq_chip mv64x60_chip_high = {
.name = "mv64x60_high", .name = "mv64x60_high",
.mask = mv64x60_mask_high, .irq_mask = mv64x60_mask_high,
.mask_ack = mv64x60_mask_high, .irq_mask_ack = mv64x60_mask_high,
.unmask = mv64x60_unmask_high, .irq_unmask = mv64x60_unmask_high,
}; };
/* /*
* mv64x60_chip_gpp functions * 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; unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, 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); (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; unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, 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); (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; unsigned long flags;
spin_lock_irqsave(&mv64x60_lock, 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 = { static struct irq_chip mv64x60_chip_gpp = {
.name = "mv64x60_gpp", .name = "mv64x60_gpp",
.mask = mv64x60_mask_gpp, .irq_mask = mv64x60_mask_gpp,
.mask_ack = mv64x60_mask_ack_gpp, .irq_mask_ack = mv64x60_mask_ack_gpp,
.unmask = mv64x60_unmask_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) 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) #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); struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
unsigned int src = virq_to_hw(virq); unsigned int src = virq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 temp; u32 temp;
@ -210,10 +215,10 @@ static void qe_ic_unmask_irq(unsigned int virq)
raw_spin_unlock_irqrestore(&qe_ic_lock, flags); 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); struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
unsigned int src = virq_to_hw(virq); unsigned int src = virq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 temp; u32 temp;
@ -238,9 +243,9 @@ static void qe_ic_mask_irq(unsigned int virq)
static struct irq_chip qe_ic_irq_chip = { static struct irq_chip qe_ic_irq_chip = {
.name = "QEIC", .name = "QEIC",
.unmask = qe_ic_unmask_irq, .irq_unmask = qe_ic_unmask_irq,
.mask = qe_ic_mask_irq, .irq_mask = qe_ic_mask_irq,
.mask_ack = 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) 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 * 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); tsi108_pci_int_unmask(d->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);
/* Enable interrupts from PCI block */ /* Enable interrupts from PCI block */
tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
@ -370,16 +355,25 @@ static void tsi108_pci_irq_end(u_int irq)
mb(); 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. * Interrupt controller descriptor for cascaded PCI interrupt controller.
*/ */
static struct irq_chip tsi108_pci_irq = { static struct irq_chip tsi108_pci_irq = {
.name = "tsi108_PCI_int", .name = "tsi108_PCI_int",
.mask = tsi108_pci_irq_disable, .irq_mask = tsi108_pci_irq_mask,
.ack = tsi108_pci_irq_ack, .irq_ack = tsi108_pci_irq_ack,
.end = tsi108_pci_irq_end, .irq_unmask = tsi108_pci_irq_unmask,
.unmask = tsi108_pci_irq_enable,
}; };
static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct, 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) 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(); unsigned int cascade_irq = get_pci_source();
if (cascade_irq != NO_IRQ) if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_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; 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 irq_desc *desc = irq_to_desc(d->irq);
struct uic *uic = get_irq_chip_data(virq); struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(virq); unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 er, sr; u32 er, sr;
@ -74,10 +74,10 @@ static void uic_unmask_irq(unsigned int virq)
spin_unlock_irqrestore(&uic->lock, flags); 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); struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(virq); unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 er; u32 er;
@ -88,10 +88,10 @@ static void uic_mask_irq(unsigned int virq)
spin_unlock_irqrestore(&uic->lock, flags); 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); struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(virq); unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&uic->lock, 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); 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 irq_desc *desc = irq_to_desc(d->irq);
struct uic *uic = get_irq_chip_data(virq); struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(virq); unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags; unsigned long flags;
u32 er, sr; u32 er, sr;
@ -125,18 +125,18 @@ static void uic_mask_ack_irq(unsigned int virq)
spin_unlock_irqrestore(&uic->lock, flags); 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); struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(virq); unsigned int src = uic_irq_to_hw(d->irq);
struct irq_desc *desc = irq_to_desc(virq); struct irq_desc *desc = irq_to_desc(d->irq);
unsigned long flags; unsigned long flags;
int trigger, polarity; int trigger, polarity;
u32 tr, pr, mask; u32 tr, pr, mask;
switch (flow_type & IRQ_TYPE_SENSE_MASK) { switch (flow_type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_NONE: case IRQ_TYPE_NONE:
uic_mask_irq(virq); uic_mask_irq(d);
return 0; return 0;
case IRQ_TYPE_EDGE_RISING: 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 = { static struct irq_chip uic_irq_chip = {
.name = "UIC", .name = "UIC",
.unmask = uic_unmask_irq, .irq_unmask = uic_unmask_irq,
.mask = uic_mask_irq, .irq_mask = uic_mask_irq,
.mask_ack = uic_mask_ack_irq, .irq_mask_ack = uic_mask_ack_irq,
.ack = uic_ack_irq, .irq_ack = uic_ack_irq,
.set_type = uic_set_irq_type, .irq_set_type = uic_set_irq_type,
}; };
static int uic_host_map(struct irq_host *h, unsigned int virq, 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) 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); struct uic *uic = get_irq_data(virq);
u32 msr; u32 msr;
int src; int src;
@ -227,9 +228,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
raw_spin_lock(&desc->lock); raw_spin_lock(&desc->lock);
if (desc->status & IRQ_LEVEL) if (desc->status & IRQ_LEVEL)
desc->chip->mask(virq); chip->irq_mask(&desc->irq_data);
else else
desc->chip->mask_ack(virq); chip->irq_mask_ack(&desc->irq_data);
raw_spin_unlock(&desc->lock); raw_spin_unlock(&desc->lock);
msr = mfdcr(uic->dcrbase + UIC_MSR); msr = mfdcr(uic->dcrbase + UIC_MSR);
@ -244,9 +245,9 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
uic_irq_ret: uic_irq_ret:
raw_spin_lock(&desc->lock); raw_spin_lock(&desc->lock);
if (desc->status & IRQ_LEVEL) if (desc->status & IRQ_LEVEL)
desc->chip->ack(virq); chip->irq_ack(&desc->irq_data);
if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
desc->chip->unmask(virq); chip->irq_unmask(&desc->irq_data);
raw_spin_unlock(&desc->lock); 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 * 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); int irq = virq_to_hw(d->irq);
void * regs = get_irq_chip_data(virq); void * regs = irq_data_get_irq_chip_data(d);
pr_debug("mask: %d\n", irq); pr_debug("mask: %d\n", irq);
out_be32(regs + XINTC_CIE, 1 << 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 &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; 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 * 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); int irq = virq_to_hw(d->irq);
void * regs = get_irq_chip_data(virq); void * regs = irq_data_get_irq_chip_data(d);
pr_debug("unmask: %d\n", irq); pr_debug("unmask: %d\n", irq);
out_be32(regs + XINTC_SIE, 1 << 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 = { static struct irq_chip xilinx_intc_level_irqchip = {
.name = "Xilinx Level INTC", .name = "Xilinx Level INTC",
.mask = xilinx_intc_mask, .irq_mask = xilinx_intc_mask,
.mask_ack = xilinx_intc_mask, .irq_mask_ack = xilinx_intc_mask,
.unmask = xilinx_intc_level_unmask, .irq_unmask = xilinx_intc_level_unmask,
.set_type = xilinx_intc_set_type, .irq_set_type = xilinx_intc_set_type,
}; };
/* /*
* IRQ Chip edge operations * 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); int irq = virq_to_hw(d->irq);
void *regs = get_irq_chip_data(virq); void *regs = irq_data_get_irq_chip_data(d);
pr_debug("unmask: %d\n", irq); pr_debug("unmask: %d\n", irq);
out_be32(regs + XINTC_SIE, 1 << 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); int irq = virq_to_hw(d->irq);
void * regs = get_irq_chip_data(virq); void * regs = irq_data_get_irq_chip_data(d);
pr_debug("ack: %d\n", irq); pr_debug("ack: %d\n", irq);
out_be32(regs + XINTC_IAR, 1 << irq); out_be32(regs + XINTC_IAR, 1 << irq);
} }
static struct irq_chip xilinx_intc_edge_irqchip = { static struct irq_chip xilinx_intc_edge_irqchip = {
.name = "Xilinx Edge INTC", .name = "Xilinx Edge INTC",
.mask = xilinx_intc_mask, .irq_mask = xilinx_intc_mask,
.unmask = xilinx_intc_edge_unmask, .irq_unmask = xilinx_intc_edge_unmask,
.ack = xilinx_intc_edge_ack, .irq_ack = xilinx_intc_edge_ack,
.set_type = xilinx_intc_set_type, .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) 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(); unsigned int cascade_irq = i8259_irq();
if (cascade_irq) if (cascade_irq)
generic_handle_irq(cascade_irq); generic_handle_irq(cascade_irq);
/* Let xilinx_intc end the interrupt */ /* Let xilinx_intc end the interrupt */
desc->chip->unmask(irq); chip->irq_unmask(&desc->irq_data);
} }
static void __init xilinx_i8259_setup_cascade(void) static void __init xilinx_i8259_setup_cascade(void)

View file

@ -6,7 +6,7 @@
* Author: Ashish Kalra <ashish.kalra@freescale.com> * Author: Ashish Kalra <ashish.kalra@freescale.com>
* Li Yang <leoli@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 * 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 * 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, IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE,
EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31), 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 *ssr_base;
void __iomem *csr_base; void __iomem *csr_base;
int irq; int irq;
int data_snoop;
}; };
static inline unsigned int sata_fsl_tag(unsigned int tag, 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, 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; struct scatterlist *sg;
unsigned int num_prde = 0; 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; ttl_dwords += sg_len;
prd->dba = cpu_to_le32(sg_addr); prd->dba = cpu_to_le32(sg_addr);
prd->ddc_and_ext = prd->ddc_and_ext = cpu_to_le32(data_snoop | (sg_len & ~0x03));
cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03));
VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n", VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n",
ttl_dwords, prd->dba, prd->ddc_and_ext); 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 */ /* set indirect extension flag along with indirect ext. size */
prd_ptr_to_indirect_ext->ddc_and_ext = prd_ptr_to_indirect_ext->ddc_and_ext =
cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG | cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG |
DATA_SNOOP_ENABLE | data_snoop |
(indirect_ext_segment_sz & ~0x03))); (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) if (qc->flags & ATA_QCFLAG_DMAMAP)
num_prde = sata_fsl_fill_sg(qc, (void *)cd, 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) if (qc->tf.protocol == ATA_PROT_NCQ)
desc_info |= FPDMA_QUEUED_CMD; desc_info |= FPDMA_QUEUED_CMD;
@ -1349,6 +1352,11 @@ static int sata_fsl_probe(struct platform_device *ofdev)
} }
host_priv->irq = irq; 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 */ /* allocate host structure */
host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS); 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",
}, },
{
.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[0].sniffer);
cancel_delayed_work_sync(&rm->cpu[1].sniffer); cancel_delayed_work_sync(&rm->cpu[1].sniffer);

View file

@ -309,6 +309,7 @@ struct hvcs_struct {
static LIST_HEAD(hvcs_structs); static LIST_HEAD(hvcs_structs);
static DEFINE_SPINLOCK(hvcs_structs_lock); static DEFINE_SPINLOCK(hvcs_structs_lock);
static DEFINE_MUTEX(hvcs_init_mutex);
static void hvcs_unthrottle(struct tty_struct *tty); static void hvcs_unthrottle(struct tty_struct *tty);
static void hvcs_throttle(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 __devexit hvcs_remove(struct vio_dev *dev);
static int __init hvcs_module_init(void); static int __init hvcs_module_init(void);
static void __exit hvcs_module_exit(void); static void __exit hvcs_module_exit(void);
static int __devinit hvcs_initialize(void);
#define HVCS_SCHED_READ 0x00000001 #define HVCS_SCHED_READ 0x00000001
#define HVCS_QUICK_READ 0x00000002 #define HVCS_QUICK_READ 0x00000002
@ -762,7 +764,7 @@ static int __devinit hvcs_probe(
const struct vio_device_id *id) const struct vio_device_id *id)
{ {
struct hvcs_struct *hvcsd; struct hvcs_struct *hvcsd;
int index; int index, rc;
int retval; int retval;
if (!dev || !id) { if (!dev || !id) {
@ -770,6 +772,13 @@ static int __devinit hvcs_probe(
return -EPERM; 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 */ /* early to avoid cleanup on failure */
index = hvcs_get_index(); index = hvcs_get_index();
if (index < 0) { if (index < 0) {
@ -1464,12 +1473,15 @@ static void hvcs_free_index_list(void)
hvcs_index_count = 0; hvcs_index_count = 0;
} }
static int __init hvcs_module_init(void) static int __devinit hvcs_initialize(void)
{ {
int rc; int rc, num_ttys_to_alloc;
int 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? */ /* Has the user specified an overload with an insmod param? */
if (hvcs_parm_num_devs <= 0 || if (hvcs_parm_num_devs <= 0 ||
@ -1528,35 +1540,13 @@ static int __init hvcs_module_init(void)
hvcs_task = kthread_run(khvcsd, NULL, "khvcsd"); hvcs_task = kthread_run(khvcsd, NULL, "khvcsd");
if (IS_ERR(hvcs_task)) { 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; rc = -EIO;
goto kthread_fail; goto kthread_fail;
} }
mutex_unlock(&hvcs_init_mutex);
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");
return 0; return 0;
attr_fail:
vio_unregister_driver(&hvcs_vio_driver);
vio_fail:
kthread_stop(hvcs_task);
kthread_fail: kthread_fail:
kfree(hvcs_pi_buff); kfree(hvcs_pi_buff);
buff_alloc_fail: buff_alloc_fail:
@ -1566,15 +1556,39 @@ register_fail:
index_fail: index_fail:
put_tty_driver(hvcs_tty_driver); put_tty_driver(hvcs_tty_driver);
hvcs_tty_driver = NULL; hvcs_tty_driver = NULL;
mutex_unlock(&hvcs_init_mutex);
return rc; 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) static void __exit hvcs_module_exit(void)
{ {
/* /*
* This driver receives hvcs_remove callbacks for each device upon * This driver receives hvcs_remove callbacks for each device upon
* module removal. * module removal.
*/ */
vio_unregister_driver(&hvcs_vio_driver);
if (!hvcs_task)
return;
/* /*
* This synchronous operation will wake the khvcsd kthread if it is * 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); driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan);
vio_unregister_driver(&hvcs_vio_driver);
tty_unregister_driver(hvcs_tty_driver); tty_unregister_driver(hvcs_tty_driver);
hvcs_free_index_list(); hvcs_free_index_list();

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