mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-16 01:04:08 +08:00
powerpc: Remove core support for Marvell mv64x60 hostbridges
There are no longer any platforms that use Marvell's mv64x60 hostbridges so remove the supporting kernel code. CC: Dale Farnsworth <dale@farnsworth.org> Signed-off-by: Mark Greer <mgreer@animalcreek.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
297f831401
commit
04debf21fa
@ -1,516 +0,0 @@
|
||||
Marvell Discovery mv64[345]6x System Controller chips
|
||||
===========================================================
|
||||
|
||||
The Marvell mv64[345]60 series of system controller chips contain
|
||||
many of the peripherals needed to implement a complete computer
|
||||
system. In this section, we define device tree nodes to describe
|
||||
the system controller chip itself and each of the peripherals
|
||||
which it contains. Compatible string values for each node are
|
||||
prefixed with the string "marvell,", for Marvell Technology Group Ltd.
|
||||
|
||||
1) The /system-controller node
|
||||
|
||||
This node is used to represent the system-controller and must be
|
||||
present when the system uses a system controller chip. The top-level
|
||||
system-controller node contains information that is global to all
|
||||
devices within the system controller chip. The node name begins
|
||||
with "system-controller" followed by the unit address, which is
|
||||
the base address of the memory-mapped register set for the system
|
||||
controller chip.
|
||||
|
||||
Required properties:
|
||||
|
||||
- ranges : Describes the translation of system controller addresses
|
||||
for memory mapped registers.
|
||||
- clock-frequency: Contains the main clock frequency for the system
|
||||
controller chip.
|
||||
- reg : This property defines the address and size of the
|
||||
memory-mapped registers contained within the system controller
|
||||
chip. The address specified in the "reg" property should match
|
||||
the unit address of the system-controller node.
|
||||
- #address-cells : Address representation for system controller
|
||||
devices. This field represents the number of cells needed to
|
||||
represent the address of the memory-mapped registers of devices
|
||||
within the system controller chip.
|
||||
- #size-cells : Size representation for the memory-mapped
|
||||
registers within the system controller chip.
|
||||
- #interrupt-cells : Defines the width of cells used to represent
|
||||
interrupts.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- model : The specific model of the system controller chip. Such
|
||||
as, "mv64360", "mv64460", or "mv64560".
|
||||
- compatible : A string identifying the compatibility identifiers
|
||||
of the system controller chip.
|
||||
|
||||
The system-controller node contains child nodes for each system
|
||||
controller device that the platform uses. Nodes should not be created
|
||||
for devices which exist on the system controller chip but are not used
|
||||
|
||||
Example Marvell Discovery mv64360 system-controller node:
|
||||
|
||||
system-controller@f1000000 { /* Marvell Discovery mv64360 */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
model = "mv64360"; /* Default */
|
||||
compatible = "marvell,mv64360";
|
||||
clock-frequency = <133333333>;
|
||||
reg = <0xf1000000 0x10000>;
|
||||
virtual-reg = <0xf1000000>;
|
||||
ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */
|
||||
0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */
|
||||
0xa0000000 0xa0000000 0x4000000 /* User FLASH */
|
||||
0x00000000 0xf1000000 0x0010000 /* Bridge's regs */
|
||||
0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */
|
||||
|
||||
[ child node definitions... ]
|
||||
}
|
||||
|
||||
2) Child nodes of /system-controller
|
||||
|
||||
a) Marvell Discovery MDIO bus
|
||||
|
||||
The MDIO is a bus to which the PHY devices are connected. For each
|
||||
device that exists on this bus, a child node should be created. See
|
||||
the definition of the PHY node below for an example of how to define
|
||||
a PHY.
|
||||
|
||||
Required properties:
|
||||
- #address-cells : Should be <1>
|
||||
- #size-cells : Should be <0>
|
||||
- compatible : Should be "marvell,mv64360-mdio"
|
||||
|
||||
Example:
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,mv64360-mdio";
|
||||
|
||||
ethernet-phy@0 {
|
||||
......
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
b) Marvell Discovery ethernet controller
|
||||
|
||||
The Discover ethernet controller is described with two levels
|
||||
of nodes. The first level describes an ethernet silicon block
|
||||
and the second level describes up to 3 ethernet nodes within
|
||||
that block. The reason for the multiple levels is that the
|
||||
registers for the node are interleaved within a single set
|
||||
of registers. The "ethernet-block" level describes the
|
||||
shared register set, and the "ethernet" nodes describe ethernet
|
||||
port-specific properties.
|
||||
|
||||
Ethernet block node
|
||||
|
||||
Required properties:
|
||||
- #address-cells : <1>
|
||||
- #size-cells : <0>
|
||||
- compatible : "marvell,mv64360-eth-block"
|
||||
- reg : Offset and length of the register set for this block
|
||||
|
||||
Optional properties:
|
||||
- clocks : Phandle to the clock control device and gate bit
|
||||
|
||||
Example Discovery Ethernet block node:
|
||||
ethernet-block@2000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,mv64360-eth-block";
|
||||
reg = <0x2000 0x2000>;
|
||||
ethernet@0 {
|
||||
.......
|
||||
};
|
||||
};
|
||||
|
||||
Ethernet port node
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "marvell,mv64360-eth".
|
||||
- reg : Should be <0>, <1>, or <2>, according to which registers
|
||||
within the silicon block the device uses.
|
||||
- interrupts : <a> where a is the interrupt number for the port.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
- phy : the phandle for the PHY connected to this ethernet
|
||||
controller.
|
||||
- local-mac-address : 6 bytes, MAC address
|
||||
|
||||
Example Discovery Ethernet port node:
|
||||
ethernet@0 {
|
||||
compatible = "marvell,mv64360-eth";
|
||||
reg = <0>;
|
||||
interrupts = <32>;
|
||||
interrupt-parent = <&PIC>;
|
||||
phy = <&PHY0>;
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
|
||||
|
||||
|
||||
c) Marvell Discovery PHY nodes
|
||||
|
||||
Required properties:
|
||||
- interrupts : <a> where a is the interrupt number for this phy.
|
||||
- interrupt-parent : the phandle for the interrupt controller that
|
||||
services interrupts for this device.
|
||||
- reg : The ID number for the phy, usually a small integer
|
||||
|
||||
Example Discovery PHY node:
|
||||
ethernet-phy@1 {
|
||||
compatible = "broadcom,bcm5421";
|
||||
interrupts = <76>; /* GPP 12 */
|
||||
interrupt-parent = <&PIC>;
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
|
||||
d) Marvell Discovery SDMA nodes
|
||||
|
||||
Represent DMA hardware associated with the MPSC (multiprotocol
|
||||
serial controllers).
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-sdma"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : <a> where a is the interrupt number for the DMA
|
||||
device.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery SDMA node:
|
||||
sdma@4000 {
|
||||
compatible = "marvell,mv64360-sdma";
|
||||
reg = <0x4000 0xc18>;
|
||||
virtual-reg = <0xf1004000>;
|
||||
interrupts = <36>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
e) Marvell Discovery BRG nodes
|
||||
|
||||
Represent baud rate generator hardware associated with the MPSC
|
||||
(multiprotocol serial controllers).
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-brg"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- clock-src : A value from 0 to 15 which selects the clock
|
||||
source for the baud rate generator. This value corresponds
|
||||
to the CLKS value in the BRGx configuration register. See
|
||||
the mv64x60 User's Manual.
|
||||
- clock-frequence : The frequency (in Hz) of the baud rate
|
||||
generator's input clock.
|
||||
- current-speed : The current speed setting (presumably by
|
||||
firmware) of the baud rate generator.
|
||||
|
||||
Example Discovery BRG node:
|
||||
brg@b200 {
|
||||
compatible = "marvell,mv64360-brg";
|
||||
reg = <0xb200 0x8>;
|
||||
clock-src = <8>;
|
||||
clock-frequency = <133333333>;
|
||||
current-speed = <9600>;
|
||||
};
|
||||
|
||||
|
||||
f) Marvell Discovery CUNIT nodes
|
||||
|
||||
Represent the Serial Communications Unit device hardware.
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery CUNIT node:
|
||||
cunit@f200 {
|
||||
reg = <0xf200 0x200>;
|
||||
};
|
||||
|
||||
|
||||
g) Marvell Discovery MPSCROUTING nodes
|
||||
|
||||
Represent the Discovery's MPSC routing hardware
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery CUNIT node:
|
||||
mpscrouting@b500 {
|
||||
reg = <0xb400 0xc>;
|
||||
};
|
||||
|
||||
|
||||
h) Marvell Discovery MPSCINTR nodes
|
||||
|
||||
Represent the Discovery's MPSC DMA interrupt hardware registers
|
||||
(SDMA cause and mask registers).
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery MPSCINTR node:
|
||||
mpsintr@b800 {
|
||||
reg = <0xb800 0x100>;
|
||||
};
|
||||
|
||||
|
||||
i) Marvell Discovery MPSC nodes
|
||||
|
||||
Represent the Discovery's MPSC (Multiprotocol Serial Controller)
|
||||
serial port.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-mpsc"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- sdma : the phandle for the SDMA node used by this port
|
||||
- brg : the phandle for the BRG node used by this port
|
||||
- cunit : the phandle for the CUNIT node used by this port
|
||||
- mpscrouting : the phandle for the MPSCROUTING node used by this port
|
||||
- mpscintr : the phandle for the MPSCINTR node used by this port
|
||||
- cell-index : the hardware index of this cell in the MPSC core
|
||||
- max_idle : value needed for MPSC CHR3 (Maximum Frame Length)
|
||||
register
|
||||
- interrupts : <a> where a is the interrupt number for the MPSC.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery MPSCINTR node:
|
||||
mpsc@8000 {
|
||||
compatible = "marvell,mv64360-mpsc";
|
||||
reg = <0x8000 0x38>;
|
||||
virtual-reg = <0xf1008000>;
|
||||
sdma = <&SDMA0>;
|
||||
brg = <&BRG0>;
|
||||
cunit = <&CUNIT>;
|
||||
mpscrouting = <&MPSCROUTING>;
|
||||
mpscintr = <&MPSCINTR>;
|
||||
cell-index = <0>;
|
||||
max_idle = <40>;
|
||||
interrupts = <40>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
j) Marvell Discovery Watch Dog Timer nodes
|
||||
|
||||
Represent the Discovery's watchdog timer hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-wdt"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery Watch Dog Timer node:
|
||||
wdt@b410 {
|
||||
compatible = "marvell,mv64360-wdt";
|
||||
reg = <0xb410 0x8>;
|
||||
};
|
||||
|
||||
|
||||
k) Marvell Discovery I2C nodes
|
||||
|
||||
Represent the Discovery's I2C hardware
|
||||
|
||||
Required properties:
|
||||
- device_type : "i2c"
|
||||
- compatible : "marvell,mv64360-i2c"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : <a> where a is the interrupt number for the I2C.
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery I2C node:
|
||||
compatible = "marvell,mv64360-i2c";
|
||||
reg = <0xc000 0x20>;
|
||||
virtual-reg = <0xf100c000>;
|
||||
interrupts = <37>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes
|
||||
|
||||
Represent the Discovery's PIC hardware
|
||||
|
||||
Required properties:
|
||||
- #interrupt-cells : <1>
|
||||
- #address-cells : <0>
|
||||
- compatible : "marvell,mv64360-pic"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupt-controller
|
||||
|
||||
Example Discovery PIC node:
|
||||
pic {
|
||||
#interrupt-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
compatible = "marvell,mv64360-pic";
|
||||
reg = <0x0 0x88>;
|
||||
interrupt-controller;
|
||||
};
|
||||
|
||||
|
||||
m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes
|
||||
|
||||
Represent the Discovery's MPP hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-mpp"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery MPP node:
|
||||
mpp@f000 {
|
||||
compatible = "marvell,mv64360-mpp";
|
||||
reg = <0xf000 0x10>;
|
||||
};
|
||||
|
||||
|
||||
n) Marvell Discovery GPP (General Purpose Pins) nodes
|
||||
|
||||
Represent the Discovery's GPP hardware
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-gpp"
|
||||
- reg : Offset and length of the register set for this device
|
||||
|
||||
Example Discovery GPP node:
|
||||
gpp@f000 {
|
||||
compatible = "marvell,mv64360-gpp";
|
||||
reg = <0xf100 0x20>;
|
||||
};
|
||||
|
||||
|
||||
o) Marvell Discovery PCI host bridge node
|
||||
|
||||
Represents the Discovery's PCI host bridge device. The properties
|
||||
for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE
|
||||
1275-1994. A typical value for the compatible property is
|
||||
"marvell,mv64360-pci".
|
||||
|
||||
Example Discovery PCI host bridge node
|
||||
pci@80000000 {
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
#interrupt-cells = <1>;
|
||||
device_type = "pci";
|
||||
compatible = "marvell,mv64360-pci";
|
||||
reg = <0xcf8 0x8>;
|
||||
ranges = <0x01000000 0x0 0x0
|
||||
0x88000000 0x0 0x01000000
|
||||
0x02000000 0x0 0x80000000
|
||||
0x80000000 0x0 0x08000000>;
|
||||
bus-range = <0 255>;
|
||||
clock-frequency = <66000000>;
|
||||
interrupt-parent = <&PIC>;
|
||||
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
|
||||
interrupt-map = <
|
||||
/* IDSEL 0x0a */
|
||||
0x5000 0 0 1 &PIC 80
|
||||
0x5000 0 0 2 &PIC 81
|
||||
0x5000 0 0 3 &PIC 91
|
||||
0x5000 0 0 4 &PIC 93
|
||||
|
||||
/* IDSEL 0x0b */
|
||||
0x5800 0 0 1 &PIC 91
|
||||
0x5800 0 0 2 &PIC 93
|
||||
0x5800 0 0 3 &PIC 80
|
||||
0x5800 0 0 4 &PIC 81
|
||||
|
||||
/* IDSEL 0x0c */
|
||||
0x6000 0 0 1 &PIC 91
|
||||
0x6000 0 0 2 &PIC 93
|
||||
0x6000 0 0 3 &PIC 80
|
||||
0x6000 0 0 4 &PIC 81
|
||||
|
||||
/* IDSEL 0x0d */
|
||||
0x6800 0 0 1 &PIC 93
|
||||
0x6800 0 0 2 &PIC 80
|
||||
0x6800 0 0 3 &PIC 81
|
||||
0x6800 0 0 4 &PIC 91
|
||||
>;
|
||||
};
|
||||
|
||||
|
||||
p) Marvell Discovery CPU Error nodes
|
||||
|
||||
Represent the Discovery's CPU error handler device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-cpu-error"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery CPU Error node:
|
||||
cpu-error@70 {
|
||||
compatible = "marvell,mv64360-cpu-error";
|
||||
reg = <0x70 0x10 0x128 0x28>;
|
||||
interrupts = <3>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
q) Marvell Discovery SRAM Controller nodes
|
||||
|
||||
Represent the Discovery's SRAM controller device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-sram-ctrl"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery SRAM Controller node:
|
||||
sram-ctrl@380 {
|
||||
compatible = "marvell,mv64360-sram-ctrl";
|
||||
reg = <0x380 0x80>;
|
||||
interrupts = <13>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
r) Marvell Discovery PCI Error Handler nodes
|
||||
|
||||
Represent the Discovery's PCI error handler device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-pci-error"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery PCI Error Handler node:
|
||||
pci-error@1d40 {
|
||||
compatible = "marvell,mv64360-pci-error";
|
||||
reg = <0x1d40 0x40 0xc28 0x4>;
|
||||
interrupts = <12>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
||||
s) Marvell Discovery Memory Controller nodes
|
||||
|
||||
Represent the Discovery's memory controller device.
|
||||
|
||||
Required properties:
|
||||
- compatible : "marvell,mv64360-mem-ctrl"
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : the interrupt number for this device
|
||||
- interrupt-parent : the phandle for the interrupt controller
|
||||
that services interrupts for this device.
|
||||
|
||||
Example Discovery Memory Controller node:
|
||||
mem-ctrl@1400 {
|
||||
compatible = "marvell,mv64360-mem-ctrl";
|
||||
reg = <0x1400 0x60>;
|
||||
interrupts = <17>;
|
||||
interrupt-parent = <&PIC>;
|
||||
};
|
||||
|
||||
|
@ -28,9 +28,6 @@ obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
|
||||
obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
|
||||
obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o
|
||||
obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
|
||||
mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
|
||||
obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \
|
||||
mv64x60_udbg.o
|
||||
obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
|
||||
|
||||
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
|
||||
|
@ -1,13 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __MV64X60_H__
|
||||
#define __MV64X60_H__
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
extern void __init mv64x60_init_irq(void);
|
||||
extern unsigned int mv64x60_get_irq(void);
|
||||
|
||||
extern void __init mv64x60_pci_init(void);
|
||||
extern void __init mv64x60_init_early(void);
|
||||
|
||||
#endif /* __MV64X60_H__ */
|
@ -1,535 +0,0 @@
|
||||
/*
|
||||
* Platform device setup for Marvell mv64360/mv64460 host bridges (Discovery)
|
||||
*
|
||||
* Author: Dale Farnsworth <dale@farnsworth.org>
|
||||
*
|
||||
* 2007 (c) MontaVista, Software, 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/console.h>
|
||||
#include <linux/mv643xx.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
|
||||
/* These functions provide the necessary setup for the mv64x60 drivers. */
|
||||
|
||||
static const struct of_device_id of_mv64x60_devices[] __initconst = {
|
||||
{ .compatible = "marvell,mv64306-devctrl", },
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Create MPSC platform devices
|
||||
*/
|
||||
static int __init mv64x60_mpsc_register_shared_pdev(struct device_node *np)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct resource r[2];
|
||||
struct mpsc_shared_pdata pdata;
|
||||
const phandle *ph;
|
||||
struct device_node *mpscrouting, *mpscintr;
|
||||
int err;
|
||||
|
||||
ph = of_get_property(np, "mpscrouting", NULL);
|
||||
mpscrouting = of_find_node_by_phandle(*ph);
|
||||
if (!mpscrouting)
|
||||
return -ENODEV;
|
||||
|
||||
err = of_address_to_resource(mpscrouting, 0, &r[0]);
|
||||
of_node_put(mpscrouting);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ph = of_get_property(np, "mpscintr", NULL);
|
||||
mpscintr = of_find_node_by_phandle(*ph);
|
||||
if (!mpscintr)
|
||||
return -ENODEV;
|
||||
|
||||
err = of_address_to_resource(mpscintr, 0, &r[1]);
|
||||
of_node_put(mpscintr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
|
||||
pdev = platform_device_alloc(MPSC_SHARED_NAME, 0);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
err = platform_device_add_resources(pdev, r, 2);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add(pdev);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
platform_device_put(pdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
|
||||
{
|
||||
struct resource r[5];
|
||||
struct mpsc_pdata pdata;
|
||||
struct platform_device *pdev;
|
||||
const unsigned int *prop;
|
||||
const phandle *ph;
|
||||
struct device_node *sdma, *brg;
|
||||
int err;
|
||||
int port_number;
|
||||
|
||||
/* only register the shared platform device the first time through */
|
||||
if (id == 0 && (err = mv64x60_mpsc_register_shared_pdev(np)))
|
||||
return err;
|
||||
|
||||
memset(r, 0, sizeof(r));
|
||||
|
||||
err = of_address_to_resource(np, 0, &r[0]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
of_irq_to_resource(np, 0, &r[4]);
|
||||
|
||||
ph = of_get_property(np, "sdma", NULL);
|
||||
sdma = of_find_node_by_phandle(*ph);
|
||||
if (!sdma)
|
||||
return -ENODEV;
|
||||
|
||||
of_irq_to_resource(sdma, 0, &r[3]);
|
||||
err = of_address_to_resource(sdma, 0, &r[1]);
|
||||
of_node_put(sdma);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ph = of_get_property(np, "brg", NULL);
|
||||
brg = of_find_node_by_phandle(*ph);
|
||||
if (!brg)
|
||||
return -ENODEV;
|
||||
|
||||
err = of_address_to_resource(brg, 0, &r[2]);
|
||||
of_node_put(brg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
prop = of_get_property(np, "cell-index", NULL);
|
||||
if (!prop)
|
||||
return -ENODEV;
|
||||
port_number = *(int *)prop;
|
||||
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
|
||||
pdata.cache_mgmt = 1; /* All current revs need this set */
|
||||
|
||||
pdata.max_idle = 40; /* default */
|
||||
prop = of_get_property(np, "max_idle", NULL);
|
||||
if (prop)
|
||||
pdata.max_idle = *prop;
|
||||
|
||||
prop = of_get_property(brg, "current-speed", NULL);
|
||||
if (prop)
|
||||
pdata.default_baud = *prop;
|
||||
|
||||
/* Default is 8 bits, no parity, no flow control */
|
||||
pdata.default_bits = 8;
|
||||
pdata.default_parity = 'n';
|
||||
pdata.default_flow = 'n';
|
||||
|
||||
prop = of_get_property(np, "chr_1", NULL);
|
||||
if (prop)
|
||||
pdata.chr_1_val = *prop;
|
||||
|
||||
prop = of_get_property(np, "chr_2", NULL);
|
||||
if (prop)
|
||||
pdata.chr_2_val = *prop;
|
||||
|
||||
prop = of_get_property(np, "chr_10", NULL);
|
||||
if (prop)
|
||||
pdata.chr_10_val = *prop;
|
||||
|
||||
prop = of_get_property(np, "mpcr", NULL);
|
||||
if (prop)
|
||||
pdata.mpcr_val = *prop;
|
||||
|
||||
prop = of_get_property(brg, "bcr", NULL);
|
||||
if (prop)
|
||||
pdata.bcr_val = *prop;
|
||||
|
||||
pdata.brg_can_tune = 1; /* All current revs need this set */
|
||||
|
||||
prop = of_get_property(brg, "clock-src", NULL);
|
||||
if (prop)
|
||||
pdata.brg_clk_src = *prop;
|
||||
|
||||
prop = of_get_property(brg, "clock-frequency", NULL);
|
||||
if (prop)
|
||||
pdata.brg_clk_freq = *prop;
|
||||
|
||||
pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
err = platform_device_add_resources(pdev, r, 5);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add(pdev);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
platform_device_put(pdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create mv64x60_eth platform devices
|
||||
*/
|
||||
static struct platform_device * __init mv64x60_eth_register_shared_pdev(
|
||||
struct device_node *np, int id)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct resource r[2];
|
||||
int err;
|
||||
|
||||
err = of_address_to_resource(np, 0, &r[0]);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
/* register an orion mdio bus driver */
|
||||
r[1].start = r[0].start + 0x4;
|
||||
r[1].end = r[0].start + 0x84 - 1;
|
||||
r[1].flags = IORESOURCE_MEM;
|
||||
|
||||
if (id == 0) {
|
||||
pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1);
|
||||
if (IS_ERR(pdev))
|
||||
return pdev;
|
||||
}
|
||||
|
||||
pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id,
|
||||
&r[0], 1);
|
||||
|
||||
return pdev;
|
||||
}
|
||||
|
||||
static int __init mv64x60_eth_device_setup(struct device_node *np, int id,
|
||||
struct platform_device *shared_pdev)
|
||||
{
|
||||
struct resource r[1];
|
||||
struct mv643xx_eth_platform_data pdata;
|
||||
struct platform_device *pdev;
|
||||
struct device_node *phy;
|
||||
const u8 *mac_addr;
|
||||
const int *prop;
|
||||
const phandle *ph;
|
||||
int err;
|
||||
|
||||
memset(r, 0, sizeof(r));
|
||||
of_irq_to_resource(np, 0, &r[0]);
|
||||
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
|
||||
pdata.shared = shared_pdev;
|
||||
|
||||
prop = of_get_property(np, "reg", NULL);
|
||||
if (!prop)
|
||||
return -ENODEV;
|
||||
pdata.port_number = *prop;
|
||||
|
||||
mac_addr = of_get_mac_address(np);
|
||||
if (mac_addr)
|
||||
memcpy(pdata.mac_addr, mac_addr, 6);
|
||||
|
||||
prop = of_get_property(np, "speed", NULL);
|
||||
if (prop)
|
||||
pdata.speed = *prop;
|
||||
|
||||
prop = of_get_property(np, "tx_queue_size", NULL);
|
||||
if (prop)
|
||||
pdata.tx_queue_size = *prop;
|
||||
|
||||
prop = of_get_property(np, "rx_queue_size", NULL);
|
||||
if (prop)
|
||||
pdata.rx_queue_size = *prop;
|
||||
|
||||
prop = of_get_property(np, "tx_sram_addr", NULL);
|
||||
if (prop)
|
||||
pdata.tx_sram_addr = *prop;
|
||||
|
||||
prop = of_get_property(np, "tx_sram_size", NULL);
|
||||
if (prop)
|
||||
pdata.tx_sram_size = *prop;
|
||||
|
||||
prop = of_get_property(np, "rx_sram_addr", NULL);
|
||||
if (prop)
|
||||
pdata.rx_sram_addr = *prop;
|
||||
|
||||
prop = of_get_property(np, "rx_sram_size", NULL);
|
||||
if (prop)
|
||||
pdata.rx_sram_size = *prop;
|
||||
|
||||
ph = of_get_property(np, "phy", NULL);
|
||||
if (!ph)
|
||||
return -ENODEV;
|
||||
|
||||
phy = of_find_node_by_phandle(*ph);
|
||||
if (phy == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
prop = of_get_property(phy, "reg", NULL);
|
||||
if (prop)
|
||||
pdata.phy_addr = MV643XX_ETH_PHY_ADDR(*prop);
|
||||
|
||||
of_node_put(phy);
|
||||
|
||||
pdev = platform_device_alloc(MV643XX_ETH_NAME, id);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
err = platform_device_add_resources(pdev, r, 1);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add(pdev);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
platform_device_put(pdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create mv64x60_i2c platform devices
|
||||
*/
|
||||
static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
|
||||
{
|
||||
struct resource r[2];
|
||||
struct platform_device *pdev;
|
||||
struct mv64xxx_i2c_pdata pdata;
|
||||
const unsigned int *prop;
|
||||
int err;
|
||||
|
||||
memset(r, 0, sizeof(r));
|
||||
|
||||
err = of_address_to_resource(np, 0, &r[0]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
of_irq_to_resource(np, 0, &r[1]);
|
||||
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
|
||||
pdata.freq_m = 8; /* default */
|
||||
prop = of_get_property(np, "freq_m", NULL);
|
||||
if (prop)
|
||||
pdata.freq_m = *prop;
|
||||
|
||||
pdata.freq_n = 3; /* default */
|
||||
prop = of_get_property(np, "freq_n", NULL);
|
||||
if (prop)
|
||||
pdata.freq_n = *prop;
|
||||
|
||||
pdata.timeout = 1000; /* default: 1 second */
|
||||
|
||||
pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, id);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
err = platform_device_add_resources(pdev, r, 2);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add(pdev);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
platform_device_put(pdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create mv64x60_wdt platform devices
|
||||
*/
|
||||
static int __init mv64x60_wdt_device_setup(struct device_node *np, int id)
|
||||
{
|
||||
struct resource r;
|
||||
struct platform_device *pdev;
|
||||
struct mv64x60_wdt_pdata pdata;
|
||||
const unsigned int *prop;
|
||||
int err;
|
||||
|
||||
err = of_address_to_resource(np, 0, &r);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
|
||||
pdata.timeout = 10; /* Default: 10 seconds */
|
||||
|
||||
np = of_get_parent(np);
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
prop = of_get_property(np, "clock-frequency", NULL);
|
||||
of_node_put(np);
|
||||
if (!prop)
|
||||
return -ENODEV;
|
||||
pdata.bus_clk = *prop / 1000000; /* wdt driver wants freq in MHz */
|
||||
|
||||
pdev = platform_device_alloc(MV64x60_WDT_NAME, id);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
err = platform_device_add_resources(pdev, &r, 1);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
err = platform_device_add(pdev);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
platform_device_put(pdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __init mv64x60_device_setup(void)
|
||||
{
|
||||
struct device_node *np, *np2;
|
||||
struct platform_device *pdev;
|
||||
int id, id2;
|
||||
int err;
|
||||
|
||||
id = 0;
|
||||
for_each_compatible_node(np, NULL, "marvell,mv64360-mpsc") {
|
||||
err = mv64x60_mpsc_device_setup(np, id++);
|
||||
if (err)
|
||||
printk(KERN_ERR "Failed to initialize MV64x60 "
|
||||
"serial device %pOF: error %d.\n",
|
||||
np, err);
|
||||
}
|
||||
|
||||
id = 0;
|
||||
id2 = 0;
|
||||
for_each_compatible_node(np, NULL, "marvell,mv64360-eth-group") {
|
||||
pdev = mv64x60_eth_register_shared_pdev(np, id++);
|
||||
if (IS_ERR(pdev)) {
|
||||
err = PTR_ERR(pdev);
|
||||
printk(KERN_ERR "Failed to initialize MV64x60 "
|
||||
"network block %pOF: error %d.\n",
|
||||
np, err);
|
||||
continue;
|
||||
}
|
||||
for_each_child_of_node(np, np2) {
|
||||
if (!of_device_is_compatible(np2,
|
||||
"marvell,mv64360-eth"))
|
||||
continue;
|
||||
err = mv64x60_eth_device_setup(np2, id2++, pdev);
|
||||
if (err)
|
||||
printk(KERN_ERR "Failed to initialize "
|
||||
"MV64x60 network device %pOF: "
|
||||
"error %d.\n",
|
||||
np2, err);
|
||||
}
|
||||
}
|
||||
|
||||
id = 0;
|
||||
for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c") {
|
||||
err = mv64x60_i2c_device_setup(np, id++);
|
||||
if (err)
|
||||
printk(KERN_ERR "Failed to initialize MV64x60 I2C "
|
||||
"bus %pOF: error %d.\n",
|
||||
np, err);
|
||||
}
|
||||
|
||||
/* support up to one watchdog timer */
|
||||
np = of_find_compatible_node(np, NULL, "marvell,mv64360-wdt");
|
||||
if (np) {
|
||||
if ((err = mv64x60_wdt_device_setup(np, id)))
|
||||
printk(KERN_ERR "Failed to initialize MV64x60 "
|
||||
"Watchdog %pOF: error %d.\n",
|
||||
np, err);
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
/* Now add every node that is on the device bus */
|
||||
for_each_compatible_node(np, NULL, "marvell,mv64360")
|
||||
of_platform_bus_probe(np, of_mv64x60_devices, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(mv64x60_device_setup);
|
||||
|
||||
static int __init mv64x60_add_mpsc_console(void)
|
||||
{
|
||||
struct device_node *np = NULL;
|
||||
const char *prop;
|
||||
|
||||
prop = of_get_property(of_chosen, "linux,stdout-path", NULL);
|
||||
if (prop == NULL)
|
||||
goto not_mpsc;
|
||||
|
||||
np = of_find_node_by_path(prop);
|
||||
if (!np)
|
||||
goto not_mpsc;
|
||||
|
||||
if (!of_device_is_compatible(np, "marvell,mv64360-mpsc"))
|
||||
goto not_mpsc;
|
||||
|
||||
prop = of_get_property(np, "cell-index", NULL);
|
||||
if (!prop)
|
||||
goto not_mpsc;
|
||||
|
||||
add_preferred_console("ttyMM", *(int *)prop, NULL);
|
||||
|
||||
not_mpsc:
|
||||
return 0;
|
||||
}
|
||||
console_initcall(mv64x60_add_mpsc_console);
|
@ -1,171 +0,0 @@
|
||||
/*
|
||||
* PCI bus setup for Marvell mv64360/mv64460 host bridges (Discovery)
|
||||
*
|
||||
* Author: Dale Farnsworth <dale@farnsworth.org>
|
||||
*
|
||||
* 2007 (c) MontaVista, Software, 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/stat.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
|
||||
#define PCI_HEADER_TYPE_INVALID 0x7f /* Invalid PCI header type */
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
/* 32-bit hex or dec stringified number + '\n' */
|
||||
#define MV64X60_VAL_LEN_MAX 11
|
||||
#define MV64X60_PCICFG_CPCI_HOTSWAP 0x68
|
||||
|
||||
static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
struct pci_dev *phb;
|
||||
u32 v;
|
||||
|
||||
if (off > 0)
|
||||
return 0;
|
||||
if (count < MV64X60_VAL_LEN_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
|
||||
if (!phb)
|
||||
return -ENODEV;
|
||||
pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v);
|
||||
pci_dev_put(phb);
|
||||
|
||||
return sprintf(buf, "0x%08x\n", v);
|
||||
}
|
||||
|
||||
static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
struct pci_dev *phb;
|
||||
u32 v;
|
||||
|
||||
if (off > 0)
|
||||
return 0;
|
||||
if (count <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (sscanf(buf, "%i", &v) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
|
||||
if (!phb)
|
||||
return -ENODEV;
|
||||
pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v);
|
||||
pci_dev_put(phb);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
|
||||
.attr = {
|
||||
.name = "hs_reg",
|
||||
.mode = 0644,
|
||||
},
|
||||
.size = MV64X60_VAL_LEN_MAX,
|
||||
.read = mv64x60_hs_reg_read,
|
||||
.write = mv64x60_hs_reg_write,
|
||||
};
|
||||
|
||||
static int __init mv64x60_sysfs_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct platform_device *pdev;
|
||||
const unsigned int *prop;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360");
|
||||
if (!np)
|
||||
return 0;
|
||||
|
||||
prop = of_get_property(np, "hs_reg_valid", NULL);
|
||||
of_node_put(np);
|
||||
|
||||
pdev = platform_device_register_simple("marvell,mv64360", 0, NULL, 0);
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
return sysfs_create_bin_file(&pdev->dev.kobj, &mv64x60_hs_reg_attr);
|
||||
}
|
||||
|
||||
subsys_initcall(mv64x60_sysfs_init);
|
||||
|
||||
#endif /* CONFIG_SYSFS */
|
||||
|
||||
static void mv64x60_pci_fixup_early(struct pci_dev *dev)
|
||||
{
|
||||
/*
|
||||
* Set the host bridge hdr_type to an invalid value so that
|
||||
* pci_setup_device() will ignore the host bridge.
|
||||
*/
|
||||
dev->hdr_type = PCI_HEADER_TYPE_INVALID;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360,
|
||||
mv64x60_pci_fixup_early);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64460,
|
||||
mv64x60_pci_fixup_early);
|
||||
|
||||
static int __init mv64x60_add_bridge(struct device_node *dev)
|
||||
{
|
||||
int len;
|
||||
struct pci_controller *hose;
|
||||
struct resource rsrc;
|
||||
const int *bus_range;
|
||||
int primary;
|
||||
|
||||
memset(&rsrc, 0, sizeof(rsrc));
|
||||
|
||||
/* Fetch host bridge registers address */
|
||||
if (of_address_to_resource(dev, 0, &rsrc)) {
|
||||
printk(KERN_ERR "No PCI reg property in device tree\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Get bus range if any */
|
||||
bus_range = of_get_property(dev, "bus-range", &len);
|
||||
if (bus_range == NULL || len < 2 * sizeof(int))
|
||||
printk(KERN_WARNING "Can't get bus-range for %pOF, assume"
|
||||
" bus 0\n", dev);
|
||||
|
||||
hose = pcibios_alloc_controller(dev);
|
||||
if (!hose)
|
||||
return -ENOMEM;
|
||||
|
||||
hose->first_busno = bus_range ? bus_range[0] : 0;
|
||||
hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||
|
||||
setup_indirect_pci(hose, rsrc.start, rsrc.start + 4, 0);
|
||||
hose->self_busno = hose->first_busno;
|
||||
|
||||
printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. "
|
||||
"Firmware bus number: %d->%d\n",
|
||||
(unsigned long long)rsrc.start, hose->first_busno,
|
||||
hose->last_busno);
|
||||
|
||||
/* Interpret the "ranges" property */
|
||||
/* This also maps the I/O region and sets isa_io/mem_base */
|
||||
primary = (hose->first_busno == 0);
|
||||
pci_process_bridge_OF_ranges(hose, dev, primary);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init mv64x60_pci_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
for_each_compatible_node(np, "pci", "marvell,mv64360-pci")
|
||||
mv64x60_add_bridge(np);
|
||||
}
|
@ -1,297 +0,0 @@
|
||||
/*
|
||||
* Interrupt handling for Marvell mv64360/mv64460 host bridges (Discovery)
|
||||
*
|
||||
* Author: Dale Farnsworth <dale@farnsworth.org>
|
||||
*
|
||||
* 2007 (c) MontaVista, Software, 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 "mv64x60.h"
|
||||
|
||||
/* Interrupt Controller Interface Registers */
|
||||
#define MV64X60_IC_MAIN_CAUSE_LO 0x0004
|
||||
#define MV64X60_IC_MAIN_CAUSE_HI 0x000c
|
||||
#define MV64X60_IC_CPU0_INTR_MASK_LO 0x0014
|
||||
#define MV64X60_IC_CPU0_INTR_MASK_HI 0x001c
|
||||
#define MV64X60_IC_CPU0_SELECT_CAUSE 0x0024
|
||||
|
||||
#define MV64X60_HIGH_GPP_GROUPS 0x0f000000
|
||||
#define MV64X60_SELECT_CAUSE_HIGH 0x40000000
|
||||
|
||||
/* General Purpose Pins Controller Interface Registers */
|
||||
#define MV64x60_GPP_INTR_CAUSE 0x0008
|
||||
#define MV64x60_GPP_INTR_MASK 0x000c
|
||||
|
||||
#define MV64x60_LEVEL1_LOW 0
|
||||
#define MV64x60_LEVEL1_HIGH 1
|
||||
#define MV64x60_LEVEL1_GPP 2
|
||||
|
||||
#define MV64x60_LEVEL1_MASK 0x00000060
|
||||
#define MV64x60_LEVEL1_OFFSET 5
|
||||
|
||||
#define MV64x60_LEVEL2_MASK 0x0000001f
|
||||
|
||||
#define MV64x60_NUM_IRQS 96
|
||||
|
||||
static DEFINE_SPINLOCK(mv64x60_lock);
|
||||
|
||||
static void __iomem *mv64x60_irq_reg_base;
|
||||
static void __iomem *mv64x60_gpp_reg_base;
|
||||
|
||||
/*
|
||||
* Interrupt Controller Handling
|
||||
*
|
||||
* The interrupt controller handles three groups of interrupts:
|
||||
* main low: IRQ0-IRQ31
|
||||
* main high: IRQ32-IRQ63
|
||||
* gpp: IRQ64-IRQ95
|
||||
*
|
||||
* This code handles interrupts in two levels. Level 1 selects the
|
||||
* interrupt group, and level 2 selects an IRQ within that group.
|
||||
* Each group has its own irq_chip structure.
|
||||
*/
|
||||
|
||||
static u32 mv64x60_cached_low_mask;
|
||||
static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
|
||||
static u32 mv64x60_cached_gpp_mask;
|
||||
|
||||
static struct irq_domain *mv64x60_irq_host;
|
||||
|
||||
/*
|
||||
* mv64x60_chip_low functions
|
||||
*/
|
||||
|
||||
static void mv64x60_mask_low(struct irq_data *d)
|
||||
{
|
||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
||||
mv64x60_cached_low_mask &= ~(1 << level2);
|
||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
|
||||
mv64x60_cached_low_mask);
|
||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
||||
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
|
||||
}
|
||||
|
||||
static void mv64x60_unmask_low(struct irq_data *d)
|
||||
{
|
||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
||||
mv64x60_cached_low_mask |= 1 << level2;
|
||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
|
||||
mv64x60_cached_low_mask);
|
||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
||||
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
|
||||
}
|
||||
|
||||
static struct irq_chip mv64x60_chip_low = {
|
||||
.name = "mv64x60_low",
|
||||
.irq_mask = mv64x60_mask_low,
|
||||
.irq_mask_ack = mv64x60_mask_low,
|
||||
.irq_unmask = mv64x60_unmask_low,
|
||||
};
|
||||
|
||||
/*
|
||||
* mv64x60_chip_high functions
|
||||
*/
|
||||
|
||||
static void mv64x60_mask_high(struct irq_data *d)
|
||||
{
|
||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
||||
mv64x60_cached_high_mask &= ~(1 << level2);
|
||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
|
||||
mv64x60_cached_high_mask);
|
||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
||||
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
|
||||
}
|
||||
|
||||
static void mv64x60_unmask_high(struct irq_data *d)
|
||||
{
|
||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
||||
mv64x60_cached_high_mask |= 1 << level2;
|
||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
|
||||
mv64x60_cached_high_mask);
|
||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
||||
(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
|
||||
}
|
||||
|
||||
static struct irq_chip mv64x60_chip_high = {
|
||||
.name = "mv64x60_high",
|
||||
.irq_mask = mv64x60_mask_high,
|
||||
.irq_mask_ack = mv64x60_mask_high,
|
||||
.irq_unmask = mv64x60_unmask_high,
|
||||
};
|
||||
|
||||
/*
|
||||
* mv64x60_chip_gpp functions
|
||||
*/
|
||||
|
||||
static void mv64x60_mask_gpp(struct irq_data *d)
|
||||
{
|
||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
||||
mv64x60_cached_gpp_mask &= ~(1 << level2);
|
||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
|
||||
mv64x60_cached_gpp_mask);
|
||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
||||
(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
|
||||
}
|
||||
|
||||
static void mv64x60_mask_ack_gpp(struct irq_data *d)
|
||||
{
|
||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
||||
mv64x60_cached_gpp_mask &= ~(1 << level2);
|
||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
|
||||
mv64x60_cached_gpp_mask);
|
||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE,
|
||||
~(1 << level2));
|
||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
||||
(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE);
|
||||
}
|
||||
|
||||
static void mv64x60_unmask_gpp(struct irq_data *d)
|
||||
{
|
||||
int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
||||
mv64x60_cached_gpp_mask |= 1 << level2;
|
||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
|
||||
mv64x60_cached_gpp_mask);
|
||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
||||
(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
|
||||
}
|
||||
|
||||
static struct irq_chip mv64x60_chip_gpp = {
|
||||
.name = "mv64x60_gpp",
|
||||
.irq_mask = mv64x60_mask_gpp,
|
||||
.irq_mask_ack = mv64x60_mask_ack_gpp,
|
||||
.irq_unmask = mv64x60_unmask_gpp,
|
||||
};
|
||||
|
||||
/*
|
||||
* mv64x60_host_ops functions
|
||||
*/
|
||||
|
||||
static struct irq_chip *mv64x60_chips[] = {
|
||||
[MV64x60_LEVEL1_LOW] = &mv64x60_chip_low,
|
||||
[MV64x60_LEVEL1_HIGH] = &mv64x60_chip_high,
|
||||
[MV64x60_LEVEL1_GPP] = &mv64x60_chip_gpp,
|
||||
};
|
||||
|
||||
static int mv64x60_host_map(struct irq_domain *h, unsigned int virq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
int level1;
|
||||
|
||||
irq_set_status_flags(virq, IRQ_LEVEL);
|
||||
|
||||
level1 = (hwirq & MV64x60_LEVEL1_MASK) >> MV64x60_LEVEL1_OFFSET;
|
||||
BUG_ON(level1 > MV64x60_LEVEL1_GPP);
|
||||
irq_set_chip_and_handler(virq, mv64x60_chips[level1],
|
||||
handle_level_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops mv64x60_host_ops = {
|
||||
.map = mv64x60_host_map,
|
||||
};
|
||||
|
||||
/*
|
||||
* Global functions
|
||||
*/
|
||||
|
||||
void __init mv64x60_init_irq(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
phys_addr_t paddr;
|
||||
unsigned int size;
|
||||
const unsigned int *reg;
|
||||
unsigned long flags;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
|
||||
reg = of_get_property(np, "reg", &size);
|
||||
paddr = of_translate_address(np, reg);
|
||||
mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
|
||||
of_node_put(np);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-pic");
|
||||
reg = of_get_property(np, "reg", &size);
|
||||
paddr = of_translate_address(np, reg);
|
||||
mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
|
||||
|
||||
mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS,
|
||||
&mv64x60_host_ops, NULL);
|
||||
|
||||
spin_lock_irqsave(&mv64x60_lock, flags);
|
||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
|
||||
mv64x60_cached_gpp_mask);
|
||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
|
||||
mv64x60_cached_low_mask);
|
||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
|
||||
mv64x60_cached_high_mask);
|
||||
|
||||
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE, 0);
|
||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_MAIN_CAUSE_LO, 0);
|
||||
out_le32(mv64x60_irq_reg_base + MV64X60_IC_MAIN_CAUSE_HI, 0);
|
||||
spin_unlock_irqrestore(&mv64x60_lock, flags);
|
||||
}
|
||||
|
||||
unsigned int mv64x60_get_irq(void)
|
||||
{
|
||||
u32 cause;
|
||||
int level1;
|
||||
irq_hw_number_t hwirq;
|
||||
int virq = 0;
|
||||
|
||||
cause = in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_SELECT_CAUSE);
|
||||
if (cause & MV64X60_SELECT_CAUSE_HIGH) {
|
||||
cause &= mv64x60_cached_high_mask;
|
||||
level1 = MV64x60_LEVEL1_HIGH;
|
||||
if (cause & MV64X60_HIGH_GPP_GROUPS) {
|
||||
cause = in_le32(mv64x60_gpp_reg_base +
|
||||
MV64x60_GPP_INTR_CAUSE);
|
||||
cause &= mv64x60_cached_gpp_mask;
|
||||
level1 = MV64x60_LEVEL1_GPP;
|
||||
}
|
||||
} else {
|
||||
cause &= mv64x60_cached_low_mask;
|
||||
level1 = MV64x60_LEVEL1_LOW;
|
||||
}
|
||||
if (cause) {
|
||||
hwirq = (level1 << MV64x60_LEVEL1_OFFSET) | __ilog2(cause);
|
||||
virq = irq_linear_revmap(mv64x60_irq_host, hwirq);
|
||||
}
|
||||
|
||||
return virq;
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* udbg serial input/output routines for the Marvell MV64x60 (Discovery).
|
||||
*
|
||||
* Author: Dale Farnsworth <dale@farnsworth.org>
|
||||
*
|
||||
* 2007 (c) MontaVista Software, 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 <asm/io.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/udbg.h>
|
||||
|
||||
#include <sysdev/mv64x60.h>
|
||||
|
||||
#define MPSC_0_CR1_OFFSET 0x000c
|
||||
|
||||
#define MPSC_0_CR2_OFFSET 0x0010
|
||||
#define MPSC_CHR_2_TCS (1 << 9)
|
||||
|
||||
#define MPSC_0_CHR_10_OFFSET 0x0030
|
||||
|
||||
#define MPSC_INTR_CAUSE_OFF_0 0x0004
|
||||
#define MPSC_INTR_CAUSE_OFF_1 0x000c
|
||||
#define MPSC_INTR_CAUSE_RCC (1<<6)
|
||||
|
||||
static void __iomem *mpsc_base;
|
||||
static void __iomem *mpsc_intr_cause;
|
||||
|
||||
static void mv64x60_udbg_putc(char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
mv64x60_udbg_putc('\r');
|
||||
|
||||
while(in_le32(mpsc_base + MPSC_0_CR2_OFFSET) & MPSC_CHR_2_TCS)
|
||||
;
|
||||
out_le32(mpsc_base + MPSC_0_CR1_OFFSET, c);
|
||||
out_le32(mpsc_base + MPSC_0_CR2_OFFSET, MPSC_CHR_2_TCS);
|
||||
}
|
||||
|
||||
static int mv64x60_udbg_testc(void)
|
||||
{
|
||||
return (in_le32(mpsc_intr_cause) & MPSC_INTR_CAUSE_RCC) != 0;
|
||||
}
|
||||
|
||||
static int mv64x60_udbg_getc(void)
|
||||
{
|
||||
int cause = 0;
|
||||
int c;
|
||||
|
||||
while (!mv64x60_udbg_testc())
|
||||
;
|
||||
|
||||
c = in_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2);
|
||||
out_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2, c);
|
||||
out_le32(mpsc_intr_cause, cause & ~MPSC_INTR_CAUSE_RCC);
|
||||
return c;
|
||||
}
|
||||
|
||||
static int mv64x60_udbg_getc_poll(void)
|
||||
{
|
||||
if (!mv64x60_udbg_testc())
|
||||
return -1;
|
||||
|
||||
return mv64x60_udbg_getc();
|
||||
}
|
||||
|
||||
static void mv64x60_udbg_init(void)
|
||||
{
|
||||
struct device_node *np, *mpscintr, *stdout = NULL;
|
||||
const char *path;
|
||||
const phandle *ph;
|
||||
struct resource r[2];
|
||||
const int *block_index;
|
||||
int intr_cause_offset;
|
||||
int err;
|
||||
|
||||
path = of_get_property(of_chosen, "linux,stdout-path", NULL);
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
stdout = of_find_node_by_path(path);
|
||||
if (!stdout)
|
||||
return;
|
||||
|
||||
for_each_compatible_node(np, NULL, "marvell,mv64360-mpsc") {
|
||||
if (np == stdout)
|
||||
break;
|
||||
}
|
||||
|
||||
of_node_put(stdout);
|
||||
if (!np)
|
||||
return;
|
||||
|
||||
block_index = of_get_property(np, "cell-index", NULL);
|
||||
if (!block_index)
|
||||
goto error;
|
||||
|
||||
switch (*block_index) {
|
||||
case 0:
|
||||
intr_cause_offset = MPSC_INTR_CAUSE_OFF_0;
|
||||
break;
|
||||
case 1:
|
||||
intr_cause_offset = MPSC_INTR_CAUSE_OFF_1;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = of_address_to_resource(np, 0, &r[0]);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
ph = of_get_property(np, "mpscintr", NULL);
|
||||
mpscintr = of_find_node_by_phandle(*ph);
|
||||
if (!mpscintr)
|
||||
goto error;
|
||||
|
||||
err = of_address_to_resource(mpscintr, 0, &r[1]);
|
||||
of_node_put(mpscintr);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
mpsc_base = ioremap(r[0].start, resource_size(&r[0]));
|
||||
if (!mpsc_base)
|
||||
return;
|
||||
|
||||
mpsc_intr_cause = ioremap(r[1].start, resource_size(&r[1]));
|
||||
if (!mpsc_intr_cause) {
|
||||
iounmap(mpsc_base);
|
||||
return;
|
||||
}
|
||||
mpsc_intr_cause += intr_cause_offset;
|
||||
|
||||
udbg_putc = mv64x60_udbg_putc;
|
||||
udbg_getc = mv64x60_udbg_getc;
|
||||
udbg_getc_poll = mv64x60_udbg_getc_poll;
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
void mv64x60_init_early(void)
|
||||
{
|
||||
mv64x60_udbg_init();
|
||||
}
|
Loading…
Reference in New Issue
Block a user