mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 00:34:20 +08:00
Merge commit 'kumar/kumar-next'
This commit is contained in:
commit
1263965f29
40
Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt
Normal file
40
Documentation/powerpc/dts-bindings/fsl/83xx-512x-pci.txt
Normal file
@ -0,0 +1,40 @@
|
||||
* Freescale 83xx and 512x PCI bridges
|
||||
|
||||
Freescale 83xx and 512x SOCs include the same pci bridge core.
|
||||
|
||||
83xx/512x specific notes:
|
||||
- reg: should contain two address length tuples
|
||||
The first is for the internal pci bridge registers
|
||||
The second is for the pci config space access registers
|
||||
|
||||
Example (MPC8313ERDB)
|
||||
pci0: pci@e0008500 {
|
||||
cell-index = <1>;
|
||||
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
||||
interrupt-map = <
|
||||
/* IDSEL 0x0E -mini PCI */
|
||||
0x7000 0x0 0x0 0x1 &ipic 18 0x8
|
||||
0x7000 0x0 0x0 0x2 &ipic 18 0x8
|
||||
0x7000 0x0 0x0 0x3 &ipic 18 0x8
|
||||
0x7000 0x0 0x0 0x4 &ipic 18 0x8
|
||||
|
||||
/* IDSEL 0x0F - PCI slot */
|
||||
0x7800 0x0 0x0 0x1 &ipic 17 0x8
|
||||
0x7800 0x0 0x0 0x2 &ipic 18 0x8
|
||||
0x7800 0x0 0x0 0x3 &ipic 17 0x8
|
||||
0x7800 0x0 0x0 0x4 &ipic 18 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
interrupts = <66 0x8>;
|
||||
bus-range = <0x0 0x0>;
|
||||
ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
|
||||
0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
|
||||
0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
|
||||
clock-frequency = <66666666>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
@ -20,7 +20,7 @@ Required properties:
|
||||
- compatible : compatible list, contains 2 entries, first is
|
||||
"fsl,CHIP-dma-channel", where CHIP is the processor
|
||||
(mpc8349, mpc8350, etc.) and the second is
|
||||
"fsl,elo-dma-channel"
|
||||
"fsl,elo-dma-channel". However, see note below.
|
||||
- reg : <registers mapping for channel>
|
||||
- cell-index : dma channel index starts at 0.
|
||||
|
||||
@ -82,7 +82,7 @@ Required properties:
|
||||
- compatible : compatible list, contains 2 entries, first is
|
||||
"fsl,CHIP-dma-channel", where CHIP is the processor
|
||||
(mpc8540, mpc8560, etc.) and the second is
|
||||
"fsl,eloplus-dma-channel"
|
||||
"fsl,eloplus-dma-channel". However, see note below.
|
||||
- cell-index : dma channel index starts at 0.
|
||||
- reg : <registers mapping for channel>
|
||||
- interrupts : <interrupt mapping for DMA channel IRQ>
|
||||
@ -125,3 +125,12 @@ Example:
|
||||
interrupts = <17 2>;
|
||||
};
|
||||
};
|
||||
|
||||
Note on DMA channel compatible properties: The compatible property must say
|
||||
"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel" to be used by the Elo DMA
|
||||
driver (fsldma). Any DMA channel used by fsldma cannot be used by another
|
||||
DMA driver, such as the SSI sound drivers for the MPC8610. Therefore, any DMA
|
||||
channel that should be used for another driver should not use
|
||||
"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel". For the SSI drivers, for
|
||||
example, the compatible property should be "fsl,ssi-dma-channel". See ssi.txt
|
||||
for more information.
|
||||
|
@ -24,12 +24,12 @@ Required properties:
|
||||
"rj-master" - r.j., SSI is clock master
|
||||
"ac97-slave" - AC97 mode, SSI is clock slave
|
||||
"ac97-master" - AC97 mode, SSI is clock master
|
||||
- fsl,playback-dma: phandle to a DMA node for the DMA channel to use for
|
||||
playback of audio. This is typically dictated by SOC
|
||||
design. See the notes below.
|
||||
- fsl,capture-dma: phandle to a DMA node for the DMA channel to use for
|
||||
capture (recording) of audio. This is typically dictated
|
||||
by SOC design. See the notes below.
|
||||
- fsl,playback-dma: phandle to a node for the DMA channel to use for
|
||||
playback of audio. This is typically dictated by SOC
|
||||
design. See the notes below.
|
||||
- fsl,capture-dma: phandle to a node for the DMA channel to use for
|
||||
capture (recording) of audio. This is typically dictated
|
||||
by SOC design. See the notes below.
|
||||
|
||||
Optional properties:
|
||||
- codec-handle : phandle to a 'codec' node that defines an audio
|
||||
@ -51,3 +51,11 @@ playback and DMA channel 1 for capture. SSI2 must use DMA channel 2 for
|
||||
playback and DMA channel 3 for capture. The developer can choose which
|
||||
DMA controller to use, but the channels themselves are hard-wired. The
|
||||
purpose of these two properties is to represent this hardware design.
|
||||
|
||||
The device tree nodes for the DMA channels that are referenced by
|
||||
"fsl,playback-dma" and "fsl,capture-dma" must be marked as compatible with
|
||||
"fsl,ssi-dma-channel". The SOC-specific compatible string (e.g.
|
||||
"fsl,mpc8610-dma-channel") can remain. If these nodes are left as
|
||||
"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel", then the generic Elo DMA
|
||||
drivers (fsldma) will attempt to use them, and it will conflict with the
|
||||
sound drivers.
|
||||
|
@ -67,6 +67,39 @@
|
||||
reg = <0x0 0x40000000>; // set by uboot
|
||||
};
|
||||
|
||||
localbus@fef05000 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
compatible = "fsl,mpc8641-localbus", "simple-bus";
|
||||
reg = <0xf8005000 0x1000>;
|
||||
interrupts = <19 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
|
||||
ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
|
||||
1 0 0xe8000000 0x08000000 // Paged Flash 0
|
||||
2 0 0xe0000000 0x08000000 // Paged Flash 1
|
||||
3 0 0xfc100000 0x00020000 // NVRAM
|
||||
4 0 0xfc000000 0x00008000 // FPGA
|
||||
5 0 0xfc008000 0x00008000 // AFIX FPGA
|
||||
6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
|
||||
7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
|
||||
|
||||
fpga@4,0 {
|
||||
compatible = "gef,fpga-regs";
|
||||
reg = <0x4 0x0 0x40>;
|
||||
};
|
||||
gef_pic: pic@4,4000 {
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
compatible = "gef,fpga-pic";
|
||||
reg = <0x4 0x4000 0x20>;
|
||||
interrupts = <0x8
|
||||
0x9>;
|
||||
interrupt-parent = <&mpic>;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
soc@fef00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
@ -150,13 +183,13 @@
|
||||
reg = <0x24520 0x20>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
interrupt-parent = <&mpic>;
|
||||
interrupts = <0x0 0x1>;
|
||||
interrupt-parent = <&gef_pic>;
|
||||
interrupts = <0x9 0x4>;
|
||||
reg = <1>;
|
||||
};
|
||||
phy2: ethernet-phy@2 {
|
||||
interrupt-parent = <&mpic>;
|
||||
interrupts = <0x0 0x1>;
|
||||
interrupt-parent = <&gef_pic>;
|
||||
interrupts = <0x8 0x4>;
|
||||
reg = <3>;
|
||||
};
|
||||
};
|
||||
|
@ -403,7 +403,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0x80008500 0x100>;
|
||||
reg = <0x80008500 0x100 /* internal registers */
|
||||
0x80008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc5121-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -363,7 +363,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -318,7 +318,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -423,7 +423,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -331,7 +331,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -254,7 +254,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
@ -280,7 +281,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008600 0x100>;
|
||||
reg = <0xe0008600 0x100 /* internal registers */
|
||||
0xe0008380 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -228,7 +228,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008600 0x100>;
|
||||
reg = <0xe0008600 0x100 /* internal registers */
|
||||
0xe0008380 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -315,7 +315,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
@ -376,7 +377,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008600 0x100>;
|
||||
reg = <0xe0008600 0x100 /* internal registers */
|
||||
0xe0008380 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -426,7 +426,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -387,6 +387,18 @@
|
||||
device-width = <1>;
|
||||
};
|
||||
|
||||
upm@1,0 {
|
||||
compatible = "fsl,upm-nand";
|
||||
reg = <1 0 1>;
|
||||
fsl,upm-addr-offset = <16>;
|
||||
fsl,upm-cmd-offset = <8>;
|
||||
gpios = <&qe_pio_e 18 0>;
|
||||
|
||||
flash {
|
||||
compatible = "stm,nand512-a";
|
||||
};
|
||||
};
|
||||
|
||||
display@2,0 {
|
||||
device_type = "display";
|
||||
compatible = "fujitsu,MB86277", "fujitsu,mint";
|
||||
@ -409,7 +421,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
device_type = "pci";
|
||||
compatible = "fsl,mpc8360-pci", "fsl,mpc8349-pci";
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000
|
||||
0x42000000 0 0x80000000 0x80000000 0 0x10000000
|
||||
0x01000000 0 0xe0300000 0xe0300000 0 0x00100000>;
|
||||
|
@ -136,6 +136,13 @@
|
||||
interrupts = <14 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
dfsrr;
|
||||
|
||||
rtc@68 {
|
||||
compatible = "dallas,ds1374";
|
||||
reg = <0x68>;
|
||||
interrupts = <19 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c@3100 {
|
||||
@ -378,7 +385,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -319,7 +319,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -136,6 +136,13 @@
|
||||
interrupts = <14 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
dfsrr;
|
||||
|
||||
rtc@68 {
|
||||
compatible = "dallas,ds1374";
|
||||
reg = <0x68>;
|
||||
interrupts = <19 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c@3100 {
|
||||
@ -364,7 +371,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -305,7 +305,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -136,6 +136,13 @@
|
||||
interrupts = <14 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
dfsrr;
|
||||
|
||||
rtc@68 {
|
||||
compatible = "dallas,ds1374";
|
||||
reg = <0x68>;
|
||||
interrupts = <19 0x8>;
|
||||
interrupt-parent = <&ipic>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c@3100 {
|
||||
@ -392,7 +399,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -333,7 +333,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -91,6 +91,8 @@
|
||||
rtc@68 {
|
||||
compatible = "dallas,ds3232";
|
||||
reg = <0x68>;
|
||||
interrupts = <0 0x1>;
|
||||
interrupt-parent = <&mpic>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -237,7 +237,7 @@
|
||||
|
||||
dma00: dma-channel@0 {
|
||||
compatible = "fsl,mpc8610-dma-channel",
|
||||
"fsl,eloplus-dma-channel";
|
||||
"fsl,ssi-dma-channel";
|
||||
cell-index = <0>;
|
||||
reg = <0x0 0x80>;
|
||||
interrupt-parent = <&mpic>;
|
||||
@ -245,7 +245,7 @@
|
||||
};
|
||||
dma01: dma-channel@1 {
|
||||
compatible = "fsl,mpc8610-dma-channel",
|
||||
"fsl,eloplus-dma-channel";
|
||||
"fsl,ssi-dma-channel";
|
||||
cell-index = <1>;
|
||||
reg = <0x80 0x80>;
|
||||
interrupt-parent = <&mpic>;
|
||||
|
@ -272,7 +272,8 @@
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
reg = <0xe0008500 0x100>;
|
||||
reg = <0xe0008500 0x100 /* internal registers */
|
||||
0xe0008300 0x8>; /* config space access registers */
|
||||
compatible = "fsl,mpc8349-pci";
|
||||
device_type = "pci";
|
||||
};
|
||||
|
@ -164,6 +164,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -163,6 +163,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -163,6 +163,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -163,6 +163,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -163,6 +163,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -163,6 +163,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -163,6 +163,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -163,6 +163,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -163,6 +163,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -164,6 +164,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -164,6 +164,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -164,6 +164,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -162,6 +162,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -156,7 +156,10 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
# Platform support
|
||||
#
|
||||
# CONFIG_PPC_MULTIPLATFORM is not set
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_PPC_82xx is not set
|
||||
# CONFIG_PPC_83xx is not set
|
||||
CONFIG_PPC_86xx=y
|
||||
|
@ -165,6 +165,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -167,6 +167,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -166,6 +166,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -150,6 +150,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -151,6 +151,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -166,6 +166,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -152,6 +152,8 @@ CONFIG_CLASSIC_RCU=y
|
||||
#
|
||||
CONFIG_PPC_MULTIPLATFORM=y
|
||||
CONFIG_CLASSIC32=y
|
||||
# CONFIG_PPC_CHRP is not set
|
||||
# CONFIG_PPC_PMAC is not set
|
||||
# CONFIG_MPC5121_ADS is not set
|
||||
# CONFIG_MPC5121_GENERIC is not set
|
||||
# CONFIG_PPC_MPC52xx is not set
|
||||
|
@ -23,9 +23,9 @@
|
||||
#ifndef __ASM_FSL_LBC_H
|
||||
#define __ASM_FSL_LBC_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
struct fsl_lbc_bank {
|
||||
__be32 br; /**< Base Register */
|
||||
@ -227,9 +227,6 @@ struct fsl_lbc_regs {
|
||||
u8 res8[0xF00];
|
||||
};
|
||||
|
||||
extern struct fsl_lbc_regs __iomem *fsl_lbc_regs;
|
||||
extern spinlock_t fsl_lbc_lock;
|
||||
|
||||
/*
|
||||
* FSL UPM routines
|
||||
*/
|
||||
@ -268,44 +265,7 @@ static inline void fsl_upm_end_pattern(struct fsl_upm *upm)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
/**
|
||||
* fsl_upm_run_pattern - actually run an UPM pattern
|
||||
* @upm: pointer to the fsl_upm structure obtained via fsl_upm_find
|
||||
* @io_base: remapped pointer to where memory access should happen
|
||||
* @mar: MAR register content during pattern execution
|
||||
*
|
||||
* This function triggers dummy write to the memory specified by the io_base,
|
||||
* thus UPM pattern actually executed. Note that mar usage depends on the
|
||||
* pre-programmed AMX bits in the UPM RAM.
|
||||
*/
|
||||
static inline int fsl_upm_run_pattern(struct fsl_upm *upm,
|
||||
void __iomem *io_base, u32 mar)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&fsl_lbc_lock, flags);
|
||||
|
||||
out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width));
|
||||
|
||||
switch (upm->width) {
|
||||
case 8:
|
||||
out_8(io_base, 0x0);
|
||||
break;
|
||||
case 16:
|
||||
out_be16(io_base, 0x0);
|
||||
break;
|
||||
case 32:
|
||||
out_be32(io_base, 0x0);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&fsl_lbc_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
extern int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base,
|
||||
u32 mar);
|
||||
|
||||
#endif /* __ASM_FSL_LBC_H */
|
||||
|
@ -656,10 +656,6 @@ interrupt_base:
|
||||
|
||||
bne 2f /* Bail if permission mismach */
|
||||
|
||||
#ifdef CONFIG_PTE_64BIT
|
||||
lwz r13,0(r12)
|
||||
#endif
|
||||
|
||||
/* Jump to common TLB load point */
|
||||
b finish_tlb_load
|
||||
|
||||
|
@ -54,11 +54,12 @@ LIST_HEAD(hose_list);
|
||||
static int pci_bus_count;
|
||||
|
||||
static void
|
||||
fixup_hide_host_resource_fsl(struct pci_dev* dev)
|
||||
fixup_hide_host_resource_fsl(struct pci_dev *dev)
|
||||
{
|
||||
int i, class = dev->class >> 8;
|
||||
|
||||
if ((class == PCI_CLASS_PROCESSOR_POWERPC) &&
|
||||
if ((class == PCI_CLASS_PROCESSOR_POWERPC ||
|
||||
class == PCI_CLASS_BRIDGE_OTHER) &&
|
||||
(dev->hdr_type == PCI_HEADER_TYPE_NORMAL) &&
|
||||
(dev->bus->parent == NULL)) {
|
||||
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
|
@ -3,6 +3,8 @@ config PPC_MPC512x
|
||||
select FSL_SOC
|
||||
select IPIC
|
||||
select PPC_CLOCK
|
||||
select PPC_PCI_CHOICE
|
||||
select FSL_PCI if PCI
|
||||
|
||||
config PPC_MPC5121
|
||||
bool
|
||||
|
@ -22,16 +22,26 @@
|
||||
#include <asm/prom.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <sysdev/fsl_pci.h>
|
||||
|
||||
#include "mpc512x.h"
|
||||
#include "mpc5121_ads.h"
|
||||
|
||||
static void __init mpc5121_ads_setup_arch(void)
|
||||
{
|
||||
#ifdef CONFIG_PCI
|
||||
struct device_node *np;
|
||||
#endif
|
||||
printk(KERN_INFO "MPC5121 ADS board from Freescale Semiconductor\n");
|
||||
/*
|
||||
* cpld regs are needed early
|
||||
*/
|
||||
mpc5121_ads_cpld_map();
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
for_each_compatible_node(np, "pci", "fsl,mpc5121-pci")
|
||||
mpc83xx_add_bridge(np);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __init mpc5121_ads_init_IRQ(void)
|
||||
|
@ -19,7 +19,6 @@ config MPC831x_RDB
|
||||
config MPC832x_MDS
|
||||
bool "Freescale MPC832x MDS"
|
||||
select DEFAULT_UIMAGE
|
||||
select QUICC_ENGINE
|
||||
select PPC_MPC832x
|
||||
help
|
||||
This option enables support for the MPC832x MDS evaluation board.
|
||||
@ -27,7 +26,6 @@ config MPC832x_MDS
|
||||
config MPC832x_RDB
|
||||
bool "Freescale MPC832x RDB"
|
||||
select DEFAULT_UIMAGE
|
||||
select QUICC_ENGINE
|
||||
select PPC_MPC832x
|
||||
help
|
||||
This option enables support for the MPC8323 RDB board.
|
||||
@ -57,15 +55,12 @@ config MPC834x_ITX
|
||||
config MPC836x_MDS
|
||||
bool "Freescale MPC836x MDS"
|
||||
select DEFAULT_UIMAGE
|
||||
select QUICC_ENGINE
|
||||
help
|
||||
This option enables support for the MPC836x MDS Processor Board.
|
||||
|
||||
config MPC836x_RDK
|
||||
bool "Freescale/Logic MPC836x RDK"
|
||||
select DEFAULT_UIMAGE
|
||||
select QUICC_ENGINE
|
||||
select QE_GPIO
|
||||
select FSL_GTM
|
||||
select FSL_LBC
|
||||
help
|
||||
|
@ -85,8 +85,14 @@ static void __init mpc837x_mds_setup_arch(void)
|
||||
ppc_md.progress("mpc837x_mds_setup_arch()", 0);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
|
||||
for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") {
|
||||
if (!of_device_is_available(np)) {
|
||||
pr_warning("%s: disabled by the firmware.\n",
|
||||
np->full_name);
|
||||
continue;
|
||||
}
|
||||
mpc83xx_add_bridge(np);
|
||||
}
|
||||
#endif
|
||||
mpc837xmds_usb_cfg();
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ config MPC85xx_CDS
|
||||
config MPC85xx_MDS
|
||||
bool "Freescale MPC85xx MDS"
|
||||
select DEFAULT_UIMAGE
|
||||
select QUICC_ENGINE
|
||||
select PHYLIB
|
||||
help
|
||||
This option enables support for the MPC85xx MDS board
|
||||
|
@ -7,4 +7,4 @@ obj-$(CONFIG_SMP) += mpc86xx_smp.o
|
||||
obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o
|
||||
obj-$(CONFIG_SBC8641D) += sbc8641d.o
|
||||
obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o
|
||||
obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o
|
||||
obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o
|
||||
|
258
arch/powerpc/platforms/86xx/gef_pic.c
Normal file
258
arch/powerpc/platforms/86xx/gef_pic.c
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Interrupt handling for GE Fanuc's FPGA based PIC
|
||||
*
|
||||
* Author: Martyn Welch <martyn.welch@gefanuc.com>
|
||||
*
|
||||
* 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||
*
|
||||
* 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/stddef.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include "gef_pic.h"
|
||||
|
||||
#define DEBUG
|
||||
#undef DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(fmt...) do { printk(KERN_DEBUG "gef_pic: " fmt); } while (0)
|
||||
#else
|
||||
#define DBG(fmt...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define GEF_PIC_NUM_IRQS 32
|
||||
|
||||
/* Interrupt Controller Interface Registers */
|
||||
#define GEF_PIC_INTR_STATUS 0x0000
|
||||
|
||||
#define GEF_PIC_INTR_MASK(cpu) (0x0010 + (0x4 * cpu))
|
||||
#define GEF_PIC_CPU0_INTR_MASK GEF_PIC_INTR_MASK(0)
|
||||
#define GEF_PIC_CPU1_INTR_MASK GEF_PIC_INTR_MASK(1)
|
||||
|
||||
#define GEF_PIC_MCP_MASK(cpu) (0x0018 + (0x4 * cpu))
|
||||
#define GEF_PIC_CPU0_MCP_MASK GEF_PIC_MCP_MASK(0)
|
||||
#define GEF_PIC_CPU1_MCP_MASK GEF_PIC_MCP_MASK(1)
|
||||
|
||||
#define gef_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
|
||||
|
||||
|
||||
static DEFINE_SPINLOCK(gef_pic_lock);
|
||||
|
||||
static void __iomem *gef_pic_irq_reg_base;
|
||||
static struct irq_host *gef_pic_irq_host;
|
||||
static int gef_pic_cascade_irq;
|
||||
|
||||
/*
|
||||
* Interrupt Controller Handling
|
||||
*
|
||||
* The interrupt controller handles interrupts for most on board interrupts,
|
||||
* apart from PCI interrupts. For example on SBC610:
|
||||
*
|
||||
* 17:31 RO Reserved
|
||||
* 16 RO PCI Express Doorbell 3 Status
|
||||
* 15 RO PCI Express Doorbell 2 Status
|
||||
* 14 RO PCI Express Doorbell 1 Status
|
||||
* 13 RO PCI Express Doorbell 0 Status
|
||||
* 12 RO Real Time Clock Interrupt Status
|
||||
* 11 RO Temperature Interrupt Status
|
||||
* 10 RO Temperature Critical Interrupt Status
|
||||
* 9 RO Ethernet PHY1 Interrupt Status
|
||||
* 8 RO Ethernet PHY3 Interrupt Status
|
||||
* 7 RO PEX8548 Interrupt Status
|
||||
* 6 RO Reserved
|
||||
* 5 RO Watchdog 0 Interrupt Status
|
||||
* 4 RO Watchdog 1 Interrupt Status
|
||||
* 3 RO AXIS Message FIFO A Interrupt Status
|
||||
* 2 RO AXIS Message FIFO B Interrupt Status
|
||||
* 1 RO AXIS Message FIFO C Interrupt Status
|
||||
* 0 RO AXIS Message FIFO D Interrupt Status
|
||||
*
|
||||
* Interrupts can be forwarded to one of two output lines. Nothing
|
||||
* clever is done, so if the masks are incorrectly set, a single input
|
||||
* interrupt could generate interrupts on both output lines!
|
||||
*
|
||||
* The dual lines are there to allow the chained interrupts to be easily
|
||||
* passed into two different cores. We currently do not use this functionality
|
||||
* in this driver.
|
||||
*
|
||||
* Controller can also be configured to generate Machine checks (MCP), again on
|
||||
* two lines, to be attached to two different cores. It is suggested that these
|
||||
* should be masked out.
|
||||
*/
|
||||
|
||||
void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
unsigned int cascade_irq;
|
||||
|
||||
/*
|
||||
* See if we actually have an interrupt, call generic handling code if
|
||||
* we do.
|
||||
*/
|
||||
cascade_irq = gef_pic_get_irq();
|
||||
|
||||
if (cascade_irq != NO_IRQ)
|
||||
generic_handle_irq(cascade_irq);
|
||||
|
||||
desc->chip->eoi(irq);
|
||||
|
||||
}
|
||||
|
||||
static void gef_pic_mask(unsigned int virq)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int hwirq;
|
||||
u32 mask;
|
||||
|
||||
hwirq = gef_irq_to_hw(virq);
|
||||
|
||||
spin_lock_irqsave(&gef_pic_lock, flags);
|
||||
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
|
||||
mask &= ~(1 << hwirq);
|
||||
out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
|
||||
spin_unlock_irqrestore(&gef_pic_lock, flags);
|
||||
}
|
||||
|
||||
static void gef_pic_mask_ack(unsigned int virq)
|
||||
{
|
||||
/* Don't think we actually have to do anything to ack an interrupt,
|
||||
* we just need to clear down the devices interrupt and it will go away
|
||||
*/
|
||||
gef_pic_mask(virq);
|
||||
}
|
||||
|
||||
static void gef_pic_unmask(unsigned int virq)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int hwirq;
|
||||
u32 mask;
|
||||
|
||||
hwirq = gef_irq_to_hw(virq);
|
||||
|
||||
spin_lock_irqsave(&gef_pic_lock, flags);
|
||||
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
|
||||
mask |= (1 << hwirq);
|
||||
out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
|
||||
spin_unlock_irqrestore(&gef_pic_lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip gef_pic_chip = {
|
||||
.typename = "gefp",
|
||||
.mask = gef_pic_mask,
|
||||
.mask_ack = gef_pic_mask_ack,
|
||||
.unmask = gef_pic_unmask,
|
||||
};
|
||||
|
||||
|
||||
/* When an interrupt is being configured, this call allows some flexibilty
|
||||
* in deciding which irq_chip structure is used
|
||||
*/
|
||||
static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
/* All interrupts are LEVEL sensitive */
|
||||
get_irq_desc(virq)->status |= IRQ_LEVEL;
|
||||
set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
|
||||
u32 *intspec, unsigned int intsize,
|
||||
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
|
||||
{
|
||||
|
||||
*out_hwirq = intspec[0];
|
||||
if (intsize > 1)
|
||||
*out_flags = intspec[1];
|
||||
else
|
||||
*out_flags = IRQ_TYPE_LEVEL_HIGH;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_host_ops gef_pic_host_ops = {
|
||||
.map = gef_pic_host_map,
|
||||
.xlate = gef_pic_host_xlate,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initialisation of PIC, this should be called in BSP
|
||||
*/
|
||||
void __init gef_pic_init(struct device_node *np)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* Map the devices registers into memory */
|
||||
gef_pic_irq_reg_base = of_iomap(np, 0);
|
||||
|
||||
spin_lock_irqsave(&gef_pic_lock, flags);
|
||||
|
||||
/* Initialise everything as masked. */
|
||||
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0);
|
||||
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_INTR_MASK, 0);
|
||||
|
||||
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0);
|
||||
out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0);
|
||||
|
||||
spin_unlock_irqrestore(&gef_pic_lock, flags);
|
||||
|
||||
/* Map controller */
|
||||
gef_pic_cascade_irq = irq_of_parse_and_map(np, 0);
|
||||
if (gef_pic_cascade_irq == NO_IRQ) {
|
||||
printk(KERN_ERR "SBC610: failed to map cascade interrupt");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup an irq_host structure */
|
||||
gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
|
||||
GEF_PIC_NUM_IRQS,
|
||||
&gef_pic_host_ops, NO_IRQ);
|
||||
if (gef_pic_irq_host == NULL)
|
||||
return;
|
||||
|
||||
/* Chain with parent controller */
|
||||
set_irq_chained_handler(gef_pic_cascade_irq, gef_pic_cascade);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called when we receive an interrupt with apparently comes from this
|
||||
* chip - check, returning the highest interrupt generated or return NO_IRQ
|
||||
*/
|
||||
unsigned int gef_pic_get_irq(void)
|
||||
{
|
||||
u32 cause, mask, active;
|
||||
unsigned int virq = NO_IRQ;
|
||||
int hwirq;
|
||||
|
||||
cause = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_STATUS);
|
||||
|
||||
mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
|
||||
|
||||
active = cause & mask;
|
||||
|
||||
if (active) {
|
||||
for (hwirq = GEF_PIC_NUM_IRQS - 1; hwirq > -1; hwirq--) {
|
||||
if (active & (0x1 << hwirq))
|
||||
break;
|
||||
}
|
||||
virq = irq_linear_revmap(gef_pic_irq_host,
|
||||
(irq_hw_number_t)hwirq);
|
||||
}
|
||||
|
||||
return virq;
|
||||
}
|
||||
|
11
arch/powerpc/platforms/86xx/gef_pic.h
Normal file
11
arch/powerpc/platforms/86xx/gef_pic.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef __GEF_PIC_H__
|
||||
#define __GEF_PIC_H__
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
void gef_pic_cascade(unsigned int, struct irq_desc *);
|
||||
unsigned int gef_pic_get_irq(void);
|
||||
void gef_pic_init(struct device_node *);
|
||||
|
||||
#endif /* __GEF_PIC_H__ */
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <sysdev/fsl_soc.h>
|
||||
|
||||
#include "mpc86xx.h"
|
||||
#include "gef_pic.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
@ -48,8 +49,31 @@
|
||||
#define DBG (fmt...) do { } while (0)
|
||||
#endif
|
||||
|
||||
void __iomem *sbc610_regs;
|
||||
|
||||
static void __init gef_sbc610_init_irq(void)
|
||||
{
|
||||
struct device_node *cascade_node = NULL;
|
||||
|
||||
mpc86xx_init_irq();
|
||||
|
||||
/*
|
||||
* There is a simple interrupt handler in the main FPGA, this needs
|
||||
* to be cascaded into the MPIC
|
||||
*/
|
||||
cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic");
|
||||
if (!cascade_node) {
|
||||
printk(KERN_WARNING "SBC610: No FPGA PIC\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gef_pic_init(cascade_node);
|
||||
of_node_put(cascade_node);
|
||||
}
|
||||
|
||||
static void __init gef_sbc610_setup_arch(void)
|
||||
{
|
||||
struct device_node *regs;
|
||||
#ifdef CONFIG_PCI
|
||||
struct device_node *np;
|
||||
|
||||
@ -63,8 +87,43 @@ static void __init gef_sbc610_setup_arch(void)
|
||||
#ifdef CONFIG_SMP
|
||||
mpc86xx_smp_init();
|
||||
#endif
|
||||
|
||||
/* Remap basic board registers */
|
||||
regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs");
|
||||
if (regs) {
|
||||
sbc610_regs = of_iomap(regs, 0);
|
||||
if (sbc610_regs == NULL)
|
||||
printk(KERN_WARNING "Unable to map board registers\n");
|
||||
of_node_put(regs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the PCB revision */
|
||||
static unsigned int gef_sbc610_get_pcb_rev(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ioread32(sbc610_regs);
|
||||
return (reg >> 8) & 0xff;
|
||||
}
|
||||
|
||||
/* Return the board (software) revision */
|
||||
static unsigned int gef_sbc610_get_board_rev(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ioread32(sbc610_regs);
|
||||
return (reg >> 16) & 0xff;
|
||||
}
|
||||
|
||||
/* Return the FPGA revision */
|
||||
static unsigned int gef_sbc610_get_fpga_rev(void)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = ioread32(sbc610_regs);
|
||||
return (reg >> 24) & 0xf;
|
||||
}
|
||||
|
||||
static void gef_sbc610_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
@ -73,6 +132,10 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m)
|
||||
|
||||
seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
|
||||
|
||||
seq_printf(m, "Revision\t: %u%c\n", gef_sbc610_get_pcb_rev(),
|
||||
('A' + gef_sbc610_get_board_rev() - 1));
|
||||
seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc610_get_fpga_rev());
|
||||
|
||||
seq_printf(m, "SVR\t\t: 0x%x\n", svid);
|
||||
seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
|
||||
}
|
||||
@ -145,7 +208,7 @@ define_machine(gef_sbc610) {
|
||||
.name = "GE Fanuc SBC610",
|
||||
.probe = gef_sbc610_probe,
|
||||
.setup_arch = gef_sbc610_setup_arch,
|
||||
.init_IRQ = mpc86xx_init_irq,
|
||||
.init_IRQ = gef_sbc610_init_irq,
|
||||
.show_cpuinfo = gef_sbc610_show_cpuinfo,
|
||||
.get_irq = mpic_get_irq,
|
||||
.restart = fsl_rstcr_restart,
|
||||
|
@ -238,7 +238,6 @@ static void __init mpc86xx_hpcd_setup_arch(void)
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||
preallocate_diu_videomemory();
|
||||
diu_ops.get_pixel_format = mpc8610hpcd_get_pixel_format;
|
||||
diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table;
|
||||
diu_ops.set_monitor_port = mpc8610hpcd_set_monitor_port;
|
||||
|
@ -239,7 +239,8 @@ config TAU_AVERAGE
|
||||
If in doubt, say N here.
|
||||
|
||||
config QUICC_ENGINE
|
||||
bool
|
||||
bool "Freescale QUICC Engine (QE) Support"
|
||||
depends on FSL_SOC
|
||||
select PPC_LIB_RHEAP
|
||||
select CRC32
|
||||
help
|
||||
@ -248,6 +249,15 @@ config QUICC_ENGINE
|
||||
Selecting this option means that you wish to build a kernel
|
||||
for a machine with a QE coprocessor.
|
||||
|
||||
config QE_GPIO
|
||||
bool "QE GPIO support"
|
||||
depends on QUICC_ENGINE
|
||||
select GENERIC_GPIO
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Say Y here if you're going to use hardware that connects to the
|
||||
QE GPIOs.
|
||||
|
||||
config CPM2
|
||||
bool "Enable support for the CPM2 (Communications Processor Module)"
|
||||
depends on MPC85xx || 8260
|
||||
|
@ -11,14 +11,19 @@
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/fsl_lbc.h>
|
||||
|
||||
spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock);
|
||||
|
||||
struct fsl_lbc_regs __iomem *fsl_lbc_regs;
|
||||
EXPORT_SYMBOL(fsl_lbc_regs);
|
||||
static spinlock_t fsl_lbc_lock = __SPIN_LOCK_UNLOCKED(fsl_lbc_lock);
|
||||
static struct fsl_lbc_regs __iomem *fsl_lbc_regs;
|
||||
|
||||
static char __initdata *compat_lbc[] = {
|
||||
"fsl,pq2-localbus",
|
||||
@ -127,3 +132,43 @@ int fsl_upm_find(phys_addr_t addr_base, struct fsl_upm *upm)
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(fsl_upm_find);
|
||||
|
||||
/**
|
||||
* fsl_upm_run_pattern - actually run an UPM pattern
|
||||
* @upm: pointer to the fsl_upm structure obtained via fsl_upm_find
|
||||
* @io_base: remapped pointer to where memory access should happen
|
||||
* @mar: MAR register content during pattern execution
|
||||
*
|
||||
* This function triggers dummy write to the memory specified by the io_base,
|
||||
* thus UPM pattern actually executed. Note that mar usage depends on the
|
||||
* pre-programmed AMX bits in the UPM RAM.
|
||||
*/
|
||||
int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&fsl_lbc_lock, flags);
|
||||
|
||||
out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width));
|
||||
|
||||
switch (upm->width) {
|
||||
case 8:
|
||||
out_8(io_base, 0x0);
|
||||
break;
|
||||
case 16:
|
||||
out_be16(io_base, 0x0);
|
||||
break;
|
||||
case 32:
|
||||
out_be32(io_base, 0x0);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&fsl_lbc_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(fsl_upm_run_pattern);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MPC85xx/86xx PCI/PCIE support routing.
|
||||
* MPC83xx/85xx/86xx PCI/PCIE support routing.
|
||||
*
|
||||
* Copyright 2007 Freescale Semiconductor, Inc
|
||||
* Copyright 2007,2008 Freescale Semiconductor, Inc
|
||||
*
|
||||
* Initial author: Xianghua Xiao <x.xiao@freescale.com>
|
||||
* Recode: ZHANG WEI <wei.zhang@freescale.com>
|
||||
@ -251,20 +251,47 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
|
||||
DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
|
||||
#endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
|
||||
|
||||
#if defined(CONFIG_PPC_83xx)
|
||||
#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
|
||||
int __init mpc83xx_add_bridge(struct device_node *dev)
|
||||
{
|
||||
int len;
|
||||
struct pci_controller *hose;
|
||||
struct resource rsrc;
|
||||
struct resource rsrc_reg;
|
||||
struct resource rsrc_cfg;
|
||||
const int *bus_range;
|
||||
int primary = 1, has_address = 0;
|
||||
phys_addr_t immr = get_immrbase();
|
||||
int primary;
|
||||
|
||||
pr_debug("Adding PCI host bridge %s\n", dev->full_name);
|
||||
|
||||
/* Fetch host bridge registers address */
|
||||
has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
|
||||
if (of_address_to_resource(dev, 0, &rsrc_reg)) {
|
||||
printk(KERN_WARNING "Can't get pci register base!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(&rsrc_cfg, 0, sizeof(rsrc_cfg));
|
||||
|
||||
if (of_address_to_resource(dev, 1, &rsrc_cfg)) {
|
||||
printk(KERN_WARNING
|
||||
"No pci config register base in dev tree, "
|
||||
"using default\n");
|
||||
/*
|
||||
* MPC83xx supports up to two host controllers
|
||||
* one at 0x8500 has config space registers at 0x8300
|
||||
* one at 0x8600 has config space registers at 0x8380
|
||||
*/
|
||||
if ((rsrc_reg.start & 0xfffff) == 0x8500)
|
||||
rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8300;
|
||||
else if ((rsrc_reg.start & 0xfffff) == 0x8600)
|
||||
rsrc_cfg.start = (rsrc_reg.start & 0xfff00000) + 0x8380;
|
||||
}
|
||||
/*
|
||||
* Controller at offset 0x8500 is primary
|
||||
*/
|
||||
if ((rsrc_reg.start & 0xfffff) == 0x8500)
|
||||
primary = 1;
|
||||
else
|
||||
primary = 0;
|
||||
|
||||
/* Get bus range if any */
|
||||
bus_range = of_get_property(dev, "bus-range", &len);
|
||||
@ -281,22 +308,11 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
|
||||
hose->first_busno = bus_range ? bus_range[0] : 0;
|
||||
hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||
|
||||
/* MPC83xx supports up to two host controllers one at 0x8500 from immrbar
|
||||
* the other at 0x8600, we consider the 0x8500 the primary controller
|
||||
*/
|
||||
/* PCI 1 */
|
||||
if ((rsrc.start & 0xfffff) == 0x8500) {
|
||||
setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304, 0);
|
||||
}
|
||||
/* PCI 2 */
|
||||
if ((rsrc.start & 0xfffff) == 0x8600) {
|
||||
setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384, 0);
|
||||
primary = 0;
|
||||
}
|
||||
setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 4, 0);
|
||||
|
||||
printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. "
|
||||
printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
|
||||
"Firmware bus number: %d->%d\n",
|
||||
(unsigned long long)rsrc.start, hose->first_busno,
|
||||
(unsigned long long)rsrc_reg.start, hose->first_busno,
|
||||
hose->last_busno);
|
||||
|
||||
pr_debug(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
|
||||
|
@ -720,42 +720,6 @@ void fsl_rstcr_restart(char *cmd)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||
struct platform_diu_data_ops diu_ops = {
|
||||
.diu_size = 1280 * 1024 * 4, /* default one 1280x1024 buffer */
|
||||
};
|
||||
struct platform_diu_data_ops diu_ops;
|
||||
EXPORT_SYMBOL(diu_ops);
|
||||
|
||||
int __init preallocate_diu_videomemory(void)
|
||||
{
|
||||
pr_debug("diu_size=%lu\n", diu_ops.diu_size);
|
||||
|
||||
diu_ops.diu_mem = __alloc_bootmem(diu_ops.diu_size, 8, 0);
|
||||
if (!diu_ops.diu_mem) {
|
||||
printk(KERN_ERR "fsl-diu: cannot allocate %lu bytes\n",
|
||||
diu_ops.diu_size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pr_debug("diu_mem=%p\n", diu_ops.diu_mem);
|
||||
|
||||
rh_init(&diu_ops.diu_rh_info, 4096, ARRAY_SIZE(diu_ops.diu_rh_block),
|
||||
diu_ops.diu_rh_block);
|
||||
return rh_attach_region(&diu_ops.diu_rh_info,
|
||||
(unsigned long) diu_ops.diu_mem,
|
||||
diu_ops.diu_size);
|
||||
}
|
||||
|
||||
static int __init early_parse_diufb(char *p)
|
||||
{
|
||||
if (!p)
|
||||
return 1;
|
||||
|
||||
diu_ops.diu_size = _ALIGN_UP(memparse(p, &p), 8);
|
||||
|
||||
pr_debug("diu_size=%lu\n", diu_ops.diu_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_param("diufb", early_parse_diufb);
|
||||
|
||||
#endif
|
||||
|
@ -20,14 +20,7 @@ extern int fsl_spi_init(struct spi_board_info *board_infos,
|
||||
extern void fsl_rstcr_restart(char *cmd);
|
||||
|
||||
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
|
||||
#include <linux/bootmem.h>
|
||||
#include <asm/rheap.h>
|
||||
struct platform_diu_data_ops {
|
||||
rh_block_t diu_rh_block[16];
|
||||
rh_info_t diu_rh_info;
|
||||
unsigned long diu_size;
|
||||
void *diu_mem;
|
||||
|
||||
unsigned int (*get_pixel_format) (unsigned int bits_per_pixel,
|
||||
int monitor_port);
|
||||
void (*set_gamma_table) (int monitor_port, char *gamma_table_base);
|
||||
@ -38,7 +31,6 @@ struct platform_diu_data_ops {
|
||||
};
|
||||
|
||||
extern struct platform_diu_data_ops diu_ops;
|
||||
int __init preallocate_diu_videomemory(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -24,12 +24,3 @@ config QE_USB
|
||||
bool
|
||||
help
|
||||
QE USB Host Controller support
|
||||
|
||||
config QE_GPIO
|
||||
bool "QE GPIO support"
|
||||
depends on QUICC_ENGINE
|
||||
select GENERIC_GPIO
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Say Y here if you're going to use hardware that connects to the
|
||||
QE GPIOs.
|
||||
|
@ -172,4 +172,15 @@ config MENELAUS
|
||||
and other features that are often used in portable devices like
|
||||
cell phones and PDAs.
|
||||
|
||||
config MCU_MPC8349EMITX
|
||||
tristate "MPC8349E-mITX MCU driver"
|
||||
depends on I2C && PPC_83xx
|
||||
select GENERIC_GPIO
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
help
|
||||
Say Y here to enable soft power-off functionality on the Freescale
|
||||
boards with the MPC8349E-mITX-compatible MCU chips. This driver will
|
||||
also register MCU GPIOs with the generic GPIO API, so you'll able
|
||||
to use MCU pins as GPIOs.
|
||||
|
||||
endmenu
|
||||
|
@ -21,6 +21,7 @@ obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
|
||||
obj-$(CONFIG_TPS65010) += tps65010.o
|
||||
obj-$(CONFIG_MENELAUS) += menelaus.o
|
||||
obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
|
||||
obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o
|
||||
|
||||
ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
|
209
drivers/i2c/chips/mcu_mpc8349emitx.c
Normal file
209
drivers/i2c/chips/mcu_mpc8349emitx.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Power Management and GPIO expander driver for MPC8349E-mITX-compatible MCU
|
||||
*
|
||||
* Copyright (c) 2008 MontaVista Software, Inc.
|
||||
*
|
||||
* Author: Anton Vorontsov <avorontsov@ru.mvista.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.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/machdep.h>
|
||||
|
||||
/*
|
||||
* I don't have specifications for the MCU firmware, I found this register
|
||||
* and bits positions by the trial&error method.
|
||||
*/
|
||||
#define MCU_REG_CTRL 0x20
|
||||
#define MCU_CTRL_POFF 0x40
|
||||
|
||||
#define MCU_NUM_GPIO 2
|
||||
|
||||
struct mcu {
|
||||
struct mutex lock;
|
||||
struct device_node *np;
|
||||
struct i2c_client *client;
|
||||
struct of_gpio_chip of_gc;
|
||||
u8 reg_ctrl;
|
||||
};
|
||||
|
||||
static struct mcu *glob_mcu;
|
||||
|
||||
static void mcu_power_off(void)
|
||||
{
|
||||
struct mcu *mcu = glob_mcu;
|
||||
|
||||
pr_info("Sending power-off request to the MCU...\n");
|
||||
mutex_lock(&mcu->lock);
|
||||
i2c_smbus_write_byte_data(glob_mcu->client, MCU_REG_CTRL,
|
||||
mcu->reg_ctrl | MCU_CTRL_POFF);
|
||||
mutex_unlock(&mcu->lock);
|
||||
}
|
||||
|
||||
static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
struct of_gpio_chip *of_gc = to_of_gpio_chip(gc);
|
||||
struct mcu *mcu = container_of(of_gc, struct mcu, of_gc);
|
||||
u8 bit = 1 << (4 + gpio);
|
||||
|
||||
mutex_lock(&mcu->lock);
|
||||
if (val)
|
||||
mcu->reg_ctrl &= ~bit;
|
||||
else
|
||||
mcu->reg_ctrl |= bit;
|
||||
|
||||
i2c_smbus_write_byte_data(mcu->client, MCU_REG_CTRL, mcu->reg_ctrl);
|
||||
mutex_unlock(&mcu->lock);
|
||||
}
|
||||
|
||||
static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
mcu_gpio_set(gc, gpio, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mcu_gpiochip_add(struct mcu *mcu)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct of_gpio_chip *of_gc = &mcu->of_gc;
|
||||
struct gpio_chip *gc = &of_gc->gc;
|
||||
int ret;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx");
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
gc->owner = THIS_MODULE;
|
||||
gc->label = np->full_name;
|
||||
gc->can_sleep = 1;
|
||||
gc->ngpio = MCU_NUM_GPIO;
|
||||
gc->base = -1;
|
||||
gc->set = mcu_gpio_set;
|
||||
gc->direction_output = mcu_gpio_dir_out;
|
||||
of_gc->gpio_cells = 2;
|
||||
of_gc->xlate = of_gpio_simple_xlate;
|
||||
|
||||
np->data = of_gc;
|
||||
mcu->np = np;
|
||||
|
||||
/*
|
||||
* We don't want to lose the node, its ->data and ->full_name...
|
||||
* So, if succeeded, we don't put the node here.
|
||||
*/
|
||||
ret = gpiochip_add(gc);
|
||||
if (ret)
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcu_gpiochip_remove(struct mcu *mcu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = gpiochip_remove(&mcu->of_gc.gc);
|
||||
if (ret)
|
||||
return ret;
|
||||
of_node_put(mcu->np);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit mcu_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct mcu *mcu;
|
||||
int ret;
|
||||
|
||||
mcu = kzalloc(sizeof(*mcu), GFP_KERNEL);
|
||||
if (!mcu)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&mcu->lock);
|
||||
mcu->client = client;
|
||||
i2c_set_clientdata(client, mcu);
|
||||
|
||||
ret = i2c_smbus_read_byte_data(mcu->client, MCU_REG_CTRL);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
mcu->reg_ctrl = ret;
|
||||
|
||||
ret = mcu_gpiochip_add(mcu);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* XXX: this is potentially racy, but there is no lock for ppc_md */
|
||||
if (!ppc_md.power_off) {
|
||||
glob_mcu = mcu;
|
||||
ppc_md.power_off = mcu_power_off;
|
||||
dev_info(&client->dev, "will provide power-off service\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
kfree(mcu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit mcu_remove(struct i2c_client *client)
|
||||
{
|
||||
struct mcu *mcu = i2c_get_clientdata(client);
|
||||
int ret;
|
||||
|
||||
if (glob_mcu == mcu) {
|
||||
ppc_md.power_off = NULL;
|
||||
glob_mcu = NULL;
|
||||
}
|
||||
|
||||
ret = mcu_gpiochip_remove(mcu);
|
||||
if (ret)
|
||||
return ret;
|
||||
i2c_set_clientdata(client, NULL);
|
||||
kfree(mcu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id mcu_ids[] = {
|
||||
{ "mcu-mpc8349emitx", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mcu_ids);
|
||||
|
||||
static struct i2c_driver mcu_driver = {
|
||||
.driver = {
|
||||
.name = "mcu-mpc8349emitx",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = mcu_probe,
|
||||
.remove = __devexit_p(mcu_remove),
|
||||
.id_table = mcu_ids,
|
||||
};
|
||||
|
||||
static int __init mcu_init(void)
|
||||
{
|
||||
return i2c_add_driver(&mcu_driver);
|
||||
}
|
||||
module_init(mcu_init);
|
||||
|
||||
static void __exit mcu_exit(void)
|
||||
{
|
||||
i2c_del_driver(&mcu_driver);
|
||||
}
|
||||
module_exit(mcu_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Power Management and GPIO expander driver for "
|
||||
"MPC8349E-mITX-compatible MCU");
|
||||
MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
|
||||
MODULE_LICENSE("GPL");
|
Loading…
Reference in New Issue
Block a user