[POWERPC] Linkstation / kurobox support
Support for the Kurobox(HG)/LinkStation-I NAS systems by Buffalo Technology, should be also applicable to the PPC TeraStation family. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
57933f8fbe
commit
04d76b937b
6 changed files with 2089 additions and 3 deletions
148
arch/powerpc/boot/dts/kuroboxHG.dts
Normal file
148
arch/powerpc/boot/dts/kuroboxHG.dts
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* Device Tree Souce for Buffalo KuroboxHG
|
||||||
|
*
|
||||||
|
* Choose CONFIG_LINKSTATION to build a kernel for KuroboxHG, or use
|
||||||
|
* the default configuration linkstation_defconfig.
|
||||||
|
*
|
||||||
|
* Based on sandpoint.dts
|
||||||
|
*
|
||||||
|
* 2006 (c) G. Liakhovetski <g.liakhovetski@gmx.de>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
XXXX add flash parts, rtc, ??
|
||||||
|
|
||||||
|
build with: "dtc -f -I dts -O dtb -o kuroboxHG.dtb -V 16 kuroboxHG.dts"
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/ {
|
||||||
|
linux,phandle = <1000>;
|
||||||
|
model = "KuroboxHG";
|
||||||
|
compatible = "linkstation";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
cpus {
|
||||||
|
linux,phandle = <2000>;
|
||||||
|
#cpus = <1>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
PowerPC,603e { /* Really 8241 */
|
||||||
|
linux,phandle = <2100>;
|
||||||
|
linux,boot-cpu;
|
||||||
|
device_type = "cpu";
|
||||||
|
reg = <0>;
|
||||||
|
clock-frequency = <fdad680>; /* Fixed by bootwrapper */
|
||||||
|
timebase-frequency = <1F04000>; /* Fixed by bootwrapper */
|
||||||
|
bus-frequency = <0>; /* From bootloader */
|
||||||
|
/* Following required by dtc but not used */
|
||||||
|
i-cache-line-size = <0>;
|
||||||
|
d-cache-line-size = <0>;
|
||||||
|
i-cache-size = <4000>;
|
||||||
|
d-cache-size = <4000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
memory {
|
||||||
|
linux,phandle = <3000>;
|
||||||
|
device_type = "memory";
|
||||||
|
reg = <00000000 08000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
soc10x { /* AFAICT need to make soc for 8245's uarts to be defined */
|
||||||
|
linux,phandle = <4000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
device_type = "soc";
|
||||||
|
compatible = "mpc10x";
|
||||||
|
store-gathering = <0>; /* 0 == off, !0 == on */
|
||||||
|
reg = <80000000 00100000>;
|
||||||
|
ranges = <80000000 80000000 70000000 /* pci mem space */
|
||||||
|
fc000000 fc000000 00100000 /* EUMB */
|
||||||
|
fe000000 fe000000 00c00000 /* pci i/o space */
|
||||||
|
fec00000 fec00000 00300000 /* pci cfg regs */
|
||||||
|
fef00000 fef00000 00100000>; /* pci iack */
|
||||||
|
|
||||||
|
i2c@80003000 {
|
||||||
|
linux,phandle = <4300>;
|
||||||
|
device_type = "i2c";
|
||||||
|
compatible = "fsl-i2c";
|
||||||
|
reg = <80003000 1000>;
|
||||||
|
interrupts = <5 2>;
|
||||||
|
interrupt-parent = <4400>;
|
||||||
|
};
|
||||||
|
|
||||||
|
serial@80004500 {
|
||||||
|
linux,phandle = <4511>;
|
||||||
|
device_type = "serial";
|
||||||
|
compatible = "ns16550";
|
||||||
|
reg = <80004500 8>;
|
||||||
|
clock-frequency = <7c044a8>;
|
||||||
|
current-speed = <2580>;
|
||||||
|
interrupts = <9 2>;
|
||||||
|
interrupt-parent = <4400>;
|
||||||
|
};
|
||||||
|
|
||||||
|
serial@80004600 {
|
||||||
|
linux,phandle = <4512>;
|
||||||
|
device_type = "serial";
|
||||||
|
compatible = "ns16550";
|
||||||
|
reg = <80004600 8>;
|
||||||
|
clock-frequency = <7c044a8>;
|
||||||
|
current-speed = <e100>;
|
||||||
|
interrupts = <a 0>;
|
||||||
|
interrupt-parent = <4400>;
|
||||||
|
};
|
||||||
|
|
||||||
|
pic@80040000 {
|
||||||
|
linux,phandle = <4400>;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
#address-cells = <0>;
|
||||||
|
device_type = "open-pic";
|
||||||
|
compatible = "chrp,open-pic";
|
||||||
|
interrupt-controller;
|
||||||
|
reg = <80040000 40000>;
|
||||||
|
built-in;
|
||||||
|
};
|
||||||
|
|
||||||
|
pci@fec00000 {
|
||||||
|
linux,phandle = <4500>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
device_type = "pci";
|
||||||
|
compatible = "mpc10x-pci";
|
||||||
|
reg = <fec00000 400000>;
|
||||||
|
ranges = <01000000 0 0 fe000000 0 00c00000
|
||||||
|
02000000 0 80000000 80000000 0 70000000>;
|
||||||
|
bus-range = <0 ff>;
|
||||||
|
clock-frequency = <7f28155>;
|
||||||
|
interrupt-parent = <4400>;
|
||||||
|
interrupt-map-mask = <f800 0 0 7>;
|
||||||
|
interrupt-map = <
|
||||||
|
/* IDSEL 0x11 - IRQ0 ETH */
|
||||||
|
5800 0 0 1 4400 0 1
|
||||||
|
5800 0 0 2 4400 1 1
|
||||||
|
5800 0 0 3 4400 2 1
|
||||||
|
5800 0 0 4 4400 3 1
|
||||||
|
/* IDSEL 0x12 - IRQ1 IDE0 */
|
||||||
|
6000 0 0 1 4400 1 1
|
||||||
|
6000 0 0 2 4400 2 1
|
||||||
|
6000 0 0 3 4400 3 1
|
||||||
|
6000 0 0 4 4400 0 1
|
||||||
|
/* IDSEL 0x14 - IRQ3 USB2.0 */
|
||||||
|
7000 0 0 1 4400 3 1
|
||||||
|
7000 0 0 2 4400 3 1
|
||||||
|
7000 0 0 3 4400 3 1
|
||||||
|
7000 0 0 4 4400 3 1
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
1583
arch/powerpc/configs/linkstation_defconfig
Normal file
1583
arch/powerpc/configs/linkstation_defconfig
Normal file
File diff suppressed because it is too large
Load diff
|
@ -74,6 +74,18 @@ config SANDPOINT
|
||||||
Select SANDPOINT if configuring for a Motorola Sandpoint X3
|
Select SANDPOINT if configuring for a Motorola Sandpoint X3
|
||||||
(any flavor).
|
(any flavor).
|
||||||
|
|
||||||
|
config LINKSTATION
|
||||||
|
bool "Linkstation / Kurobox(HG) from Buffalo"
|
||||||
|
select MPIC
|
||||||
|
select FSL_SOC
|
||||||
|
select PPC_UDBG_16550 if SERIAL_8250
|
||||||
|
help
|
||||||
|
Select LINKSTATION if configuring for one of PPC- (MPC8241)
|
||||||
|
based NAS systems from Buffalo Technology. So far only
|
||||||
|
KuroboxHG has been tested. In the future classical Kurobox,
|
||||||
|
Linkstation-I HD-HLAN and HD-HGLAN versions, and PPC-based
|
||||||
|
Terastation systems should be supported too.
|
||||||
|
|
||||||
config MPC7448HPC2
|
config MPC7448HPC2
|
||||||
bool "Freescale MPC7448HPC2(Taiga)"
|
bool "Freescale MPC7448HPC2(Taiga)"
|
||||||
select TSI108_BRIDGE
|
select TSI108_BRIDGE
|
||||||
|
@ -196,7 +208,7 @@ config PPC_GEN550
|
||||||
depends on SANDPOINT || SPRUCE || PPLUS || \
|
depends on SANDPOINT || SPRUCE || PPLUS || \
|
||||||
PRPMC750 || PRPMC800 || LOPEC || \
|
PRPMC750 || PRPMC800 || LOPEC || \
|
||||||
(EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \
|
(EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \
|
||||||
83xx
|
83xx || LINKSTATION
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config FORCE
|
config FORCE
|
||||||
|
@ -270,13 +282,13 @@ config EPIC_SERIAL_MODE
|
||||||
|
|
||||||
config MPC10X_BRIDGE
|
config MPC10X_BRIDGE
|
||||||
bool
|
bool
|
||||||
depends on POWERPMC250 || LOPEC || SANDPOINT
|
depends on POWERPMC250 || LOPEC || SANDPOINT || LINKSTATION
|
||||||
select PPC_INDIRECT_PCI
|
select PPC_INDIRECT_PCI
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config MPC10X_OPENPIC
|
config MPC10X_OPENPIC
|
||||||
bool
|
bool
|
||||||
depends on POWERPMC250 || LOPEC || SANDPOINT
|
depends on POWERPMC250 || LOPEC || SANDPOINT || LINKSTATION
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config MPC10X_STORE_GATHERING
|
config MPC10X_STORE_GATHERING
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
# Makefile for the 6xx/7xx/7xxxx linux kernel.
|
# Makefile for the 6xx/7xx/7xxxx linux kernel.
|
||||||
#
|
#
|
||||||
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
|
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
|
||||||
|
obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
|
||||||
|
|
211
arch/powerpc/platforms/embedded6xx/linkstation.c
Normal file
211
arch/powerpc/platforms/embedded6xx/linkstation.c
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
* Board setup routines for the Buffalo Linkstation / Kurobox Platform.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 G. Liakhovetski (g.liakhovetski@gmx.de)
|
||||||
|
*
|
||||||
|
* Based on sandpoint.c by Mark A. Greer
|
||||||
|
*
|
||||||
|
* 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/kernel.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/initrd.h>
|
||||||
|
#include <linux/root_dev.h>
|
||||||
|
#include <linux/mtd/physmap.h>
|
||||||
|
|
||||||
|
#include <asm/time.h>
|
||||||
|
#include <asm/prom.h>
|
||||||
|
#include <asm/mpic.h>
|
||||||
|
#include <asm/mpc10x.h>
|
||||||
|
#include <asm/pci-bridge.h>
|
||||||
|
|
||||||
|
static struct mtd_partition linkstation_physmap_partitions[] = {
|
||||||
|
{
|
||||||
|
.name = "mtd_firmimg",
|
||||||
|
.offset = 0x000000,
|
||||||
|
.size = 0x300000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "mtd_bootcode",
|
||||||
|
.offset = 0x300000,
|
||||||
|
.size = 0x070000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "mtd_status",
|
||||||
|
.offset = 0x370000,
|
||||||
|
.size = 0x010000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "mtd_conf",
|
||||||
|
.offset = 0x380000,
|
||||||
|
.size = 0x080000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "mtd_allflash",
|
||||||
|
.offset = 0x000000,
|
||||||
|
.size = 0x400000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "mtd_data",
|
||||||
|
.offset = 0x310000,
|
||||||
|
.size = 0x0f0000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init add_bridge(struct device_node *dev)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
struct pci_controller *hose;
|
||||||
|
int *bus_range;
|
||||||
|
|
||||||
|
printk("Adding PCI host bridge %s\n", dev->full_name);
|
||||||
|
|
||||||
|
bus_range = (int *) get_property(dev, "bus-range", &len);
|
||||||
|
if (bus_range == NULL || len < 2 * sizeof(int))
|
||||||
|
printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
||||||
|
" bus 0\n", dev->full_name);
|
||||||
|
|
||||||
|
hose = pcibios_alloc_controller();
|
||||||
|
if (hose == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
hose->first_busno = bus_range ? bus_range[0] : 0;
|
||||||
|
hose->last_busno = bus_range ? bus_range[1] : 0xff;
|
||||||
|
hose->arch_data = dev;
|
||||||
|
setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
|
||||||
|
|
||||||
|
/* Interpret the "ranges" property */
|
||||||
|
/* This also maps the I/O region and sets isa_io/mem_base */
|
||||||
|
pci_process_bridge_OF_ranges(hose, dev, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init linkstation_setup_arch(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
#ifdef CONFIG_MTD_PHYSMAP
|
||||||
|
physmap_set_partitions(linkstation_physmap_partitions,
|
||||||
|
ARRAY_SIZE(linkstation_physmap_partitions));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
|
if (initrd_start)
|
||||||
|
ROOT_DEV = Root_RAM0;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_ROOT_NFS
|
||||||
|
ROOT_DEV = Root_NFS;
|
||||||
|
#else
|
||||||
|
ROOT_DEV = Root_HDA1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Lookup PCI host bridges */
|
||||||
|
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
|
||||||
|
add_bridge(np);
|
||||||
|
|
||||||
|
printk(KERN_INFO "BUFFALO Network Attached Storage Series\n");
|
||||||
|
printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt setup and service. Interrrupts on the linkstation come
|
||||||
|
* from the four PCI slots plus onboard 8241 devices: I2C, DUART.
|
||||||
|
*/
|
||||||
|
static void __init linkstation_init_IRQ(void)
|
||||||
|
{
|
||||||
|
struct mpic *mpic;
|
||||||
|
struct device_node *dnp;
|
||||||
|
void *prop;
|
||||||
|
int size;
|
||||||
|
phys_addr_t paddr;
|
||||||
|
|
||||||
|
dnp = of_find_node_by_type(NULL, "open-pic");
|
||||||
|
if (dnp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prop = (struct device_node *)get_property(dnp, "reg", &size);
|
||||||
|
paddr = (phys_addr_t)of_translate_address(dnp, prop);
|
||||||
|
|
||||||
|
mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 4, 32, " EPIC ");
|
||||||
|
BUG_ON(mpic == NULL);
|
||||||
|
|
||||||
|
/* PCI IRQs */
|
||||||
|
mpic_assign_isu(mpic, 0, paddr + 0x10200);
|
||||||
|
|
||||||
|
/* I2C */
|
||||||
|
mpic_assign_isu(mpic, 1, paddr + 0x11000);
|
||||||
|
|
||||||
|
/* ttyS0, ttyS1 */
|
||||||
|
mpic_assign_isu(mpic, 2, paddr + 0x11100);
|
||||||
|
|
||||||
|
mpic_init(mpic);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void avr_uart_configure(void);
|
||||||
|
extern void avr_uart_send(const char);
|
||||||
|
|
||||||
|
static void linkstation_restart(char *cmd)
|
||||||
|
{
|
||||||
|
local_irq_disable();
|
||||||
|
|
||||||
|
/* Reset system via AVR */
|
||||||
|
avr_uart_configure();
|
||||||
|
/* Send reboot command */
|
||||||
|
avr_uart_send('C');
|
||||||
|
|
||||||
|
for(;;) /* Spin until reset happens */
|
||||||
|
avr_uart_send('G'); /* "kick" */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void linkstation_power_off(void)
|
||||||
|
{
|
||||||
|
local_irq_disable();
|
||||||
|
|
||||||
|
/* Power down system via AVR */
|
||||||
|
avr_uart_configure();
|
||||||
|
/* send shutdown command */
|
||||||
|
avr_uart_send('E');
|
||||||
|
|
||||||
|
for(;;) /* Spin until power-off happens */
|
||||||
|
avr_uart_send('G'); /* "kick" */
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void linkstation_halt(void)
|
||||||
|
{
|
||||||
|
linkstation_power_off();
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void linkstation_show_cpuinfo(struct seq_file *m)
|
||||||
|
{
|
||||||
|
seq_printf(m, "vendor\t\t: Buffalo Technology\n");
|
||||||
|
seq_printf(m, "machine\t\t: Linkstation I/Kurobox(HG)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init linkstation_probe(void)
|
||||||
|
{
|
||||||
|
unsigned long root;
|
||||||
|
|
||||||
|
root = of_get_flat_dt_root();
|
||||||
|
|
||||||
|
if (!of_flat_dt_is_compatible(root, "linkstation"))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
define_machine(linkstation){
|
||||||
|
.name = "Buffalo Linkstation",
|
||||||
|
.probe = linkstation_probe,
|
||||||
|
.setup_arch = linkstation_setup_arch,
|
||||||
|
.init_IRQ = linkstation_init_IRQ,
|
||||||
|
.show_cpuinfo = linkstation_show_cpuinfo,
|
||||||
|
.get_irq = mpic_get_irq,
|
||||||
|
.restart = linkstation_restart,
|
||||||
|
.power_off = linkstation_power_off,
|
||||||
|
.halt = linkstation_halt,
|
||||||
|
.calibrate_decr = generic_calibrate_decr,
|
||||||
|
};
|
131
arch/powerpc/platforms/embedded6xx/ls_uart.c
Normal file
131
arch/powerpc/platforms/embedded6xx/ls_uart.c
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/serial_reg.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/mpc10x.h>
|
||||||
|
#include <asm/ppc_sys.h>
|
||||||
|
#include <asm/prom.h>
|
||||||
|
#include <asm/termbits.h>
|
||||||
|
|
||||||
|
static void __iomem *avr_addr;
|
||||||
|
static unsigned long avr_clock;
|
||||||
|
|
||||||
|
static struct work_struct wd_work;
|
||||||
|
|
||||||
|
static void wd_stop(void *unused)
|
||||||
|
{
|
||||||
|
const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";
|
||||||
|
int i = 0, rescue = 8;
|
||||||
|
int len = strlen(string);
|
||||||
|
|
||||||
|
while (rescue--) {
|
||||||
|
int j;
|
||||||
|
char lsr = in_8(avr_addr + UART_LSR);
|
||||||
|
|
||||||
|
if (lsr & (UART_LSR_THRE | UART_LSR_TEMT)) {
|
||||||
|
for (j = 0; j < 16 && i < len; j++, i++)
|
||||||
|
out_8(avr_addr + UART_TX, string[i]);
|
||||||
|
if (i == len) {
|
||||||
|
/* Read "OK" back: 4ms for the last "KKKK"
|
||||||
|
plus a couple bytes back */
|
||||||
|
msleep(7);
|
||||||
|
printk("linkstation: disarming the AVR watchdog: ");
|
||||||
|
while (in_8(avr_addr + UART_LSR) & UART_LSR_DR)
|
||||||
|
printk("%c", in_8(avr_addr + UART_RX));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msleep(17);
|
||||||
|
}
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600)
|
||||||
|
|
||||||
|
void avr_uart_configure(void)
|
||||||
|
{
|
||||||
|
unsigned char cval = UART_LCR_WLEN8;
|
||||||
|
unsigned int quot = AVR_QUOT(avr_clock);
|
||||||
|
|
||||||
|
if (!avr_addr || !avr_clock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
out_8(avr_addr + UART_LCR, cval); /* initialise UART */
|
||||||
|
out_8(avr_addr + UART_MCR, 0);
|
||||||
|
out_8(avr_addr + UART_IER, 0);
|
||||||
|
|
||||||
|
cval |= UART_LCR_STOP | UART_LCR_PARITY | UART_LCR_EPAR;
|
||||||
|
|
||||||
|
out_8(avr_addr + UART_LCR, cval); /* Set character format */
|
||||||
|
|
||||||
|
out_8(avr_addr + UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
|
||||||
|
out_8(avr_addr + UART_DLL, quot & 0xff); /* LS of divisor */
|
||||||
|
out_8(avr_addr + UART_DLM, quot >> 8); /* MS of divisor */
|
||||||
|
out_8(avr_addr + UART_LCR, cval); /* reset DLAB */
|
||||||
|
out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO); /* enable FIFO */
|
||||||
|
}
|
||||||
|
|
||||||
|
void avr_uart_send(const char c)
|
||||||
|
{
|
||||||
|
if (!avr_addr || !avr_clock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
out_8(avr_addr + UART_TX, c);
|
||||||
|
out_8(avr_addr + UART_TX, c);
|
||||||
|
out_8(avr_addr + UART_TX, c);
|
||||||
|
out_8(avr_addr + UART_TX, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init ls_uart_init(void)
|
||||||
|
{
|
||||||
|
local_irq_disable();
|
||||||
|
|
||||||
|
#ifndef CONFIG_SERIAL_8250
|
||||||
|
out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO); /* enable FIFO */
|
||||||
|
out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO |
|
||||||
|
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); /* clear FIFOs */
|
||||||
|
out_8(avr_addr + UART_FCR, 0);
|
||||||
|
out_8(avr_addr + UART_IER, 0);
|
||||||
|
|
||||||
|
/* Clear up interrupts */
|
||||||
|
(void) in_8(avr_addr + UART_LSR);
|
||||||
|
(void) in_8(avr_addr + UART_RX);
|
||||||
|
(void) in_8(avr_addr + UART_IIR);
|
||||||
|
(void) in_8(avr_addr + UART_MSR);
|
||||||
|
#endif
|
||||||
|
avr_uart_configure();
|
||||||
|
|
||||||
|
local_irq_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init ls_uarts_init(void)
|
||||||
|
{
|
||||||
|
struct device_node *avr;
|
||||||
|
phys_addr_t phys_addr;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
avr = of_find_node_by_path("/soc10x/serial@80004500");
|
||||||
|
if (!avr)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
avr_clock = *(u32*)get_property(avr, "clock-frequency", &len);
|
||||||
|
phys_addr = ((u32*)get_property(avr, "reg", &len))[0];
|
||||||
|
|
||||||
|
if (!avr_clock || !phys_addr)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
avr_addr = ioremap(phys_addr, 32);
|
||||||
|
if (!avr_addr)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
ls_uart_init();
|
||||||
|
|
||||||
|
INIT_WORK(&wd_work, wd_stop, NULL);
|
||||||
|
schedule_work(&wd_work);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
late_initcall(ls_uarts_init);
|
Loading…
Reference in a new issue