summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-10-09 03:58:49 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2011-10-09 03:58:49 +0200
commit597da1b76ebd0083f929e59801f72a6dd6aef5cd (patch)
tree533372bf174baae1b81bccae1b6ba300a518d642
parent0e7c77a3fdfa0504c31594dd800e460820a5fff1 (diff)
parent502ecda2d17ed4b50b6c4d5afb04832013996173 (diff)
downloadbarebox-597da1b76ebd0083f929e59801f72a6dd6aef5cd.tar.gz
barebox-597da1b76ebd0083f929e59801f72a6dd6aef5cd.tar.xz
Merge branch 'next'
-rw-r--r--.gitignore1
-rw-r--r--Makefile3
-rw-r--r--arch/arm/Makefile3
-rw-r--r--arch/arm/boards/a9m2410/a9m2410.c2
-rw-r--r--arch/arm/boards/a9m2440/a9m2410dev.c2
-rw-r--r--arch/arm/boards/a9m2440/a9m2440.c2
-rw-r--r--arch/arm/boards/at91rm9200ek/init.c2
-rw-r--r--arch/arm/boards/at91sam9260ek/init.c4
-rw-r--r--arch/arm/boards/at91sam9261ek/init.c3
-rw-r--r--arch/arm/boards/at91sam9263ek/init.c4
-rw-r--r--arch/arm/boards/at91sam9m10g45ek/init.c2
-rw-r--r--arch/arm/boards/chumby_falconwing/falconwing.c2
-rw-r--r--arch/arm/boards/edb93xx/edb93xx.c2
-rw-r--r--arch/arm/boards/edb93xx/flash_cfg.c2
-rw-r--r--arch/arm/boards/edb93xx/pll_cfg.c2
-rw-r--r--arch/arm/boards/edb93xx/sdram_cfg.c2
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c2
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/lowlevel.c2
-rw-r--r--arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c2
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c2
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/lowlevel.c2
-rw-r--r--arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c2
-rw-r--r--arch/arm/boards/freescale-mx25-3-stack/3stack.c2
-rw-r--r--arch/arm/boards/freescale-mx35-3-stack/3stack.c2
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/board.c2
-rw-r--r--arch/arm/boards/freescale-mx53-loco/board.c2
-rw-r--r--arch/arm/boards/guf-cupid/board.c2
-rw-r--r--arch/arm/boards/guf-cupid/lowlevel.c2
-rw-r--r--arch/arm/boards/guf-neso/board.c2
-rw-r--r--arch/arm/boards/guf-neso/lowlevel.c2
-rw-r--r--arch/arm/boards/imx21ads/imx21ads.c2
-rw-r--r--arch/arm/boards/imx27ads/imx27ads.c2
-rw-r--r--arch/arm/boards/karo-tx25/board.c2
-rw-r--r--arch/arm/boards/karo-tx25/lowlevel.c2
-rw-r--r--arch/arm/boards/karo-tx28/tx28-stk5.c3
-rw-r--r--arch/arm/boards/karo-tx28/tx28.c2
-rw-r--r--arch/arm/boards/mini2440/mini2440.c2
-rw-r--r--arch/arm/boards/mmccpu/init.c2
-rw-r--r--arch/arm/boards/nhk8815/setup.c2
-rw-r--r--arch/arm/boards/omap/board-beagle.c2
-rw-r--r--arch/arm/boards/omap/board-omap3evm.c2
-rw-r--r--arch/arm/boards/omap/board-sdp343x.c2
-rw-r--r--arch/arm/boards/panda/board.c2
-rw-r--r--arch/arm/boards/panda/lowlevel.c2
-rw-r--r--arch/arm/boards/panda/mux.c2
-rw-r--r--arch/arm/boards/pcm037/pcm037.c2
-rw-r--r--arch/arm/boards/pcm038/lowlevel.c2
-rw-r--r--arch/arm/boards/pcm038/pcm038.c2
-rw-r--r--arch/arm/boards/pcm043/lowlevel.c2
-rw-r--r--arch/arm/boards/pcm043/pcm043.c2
-rw-r--r--arch/arm/boards/pcm049/board.c2
-rw-r--r--arch/arm/boards/pcm049/lowlevel.c2
-rw-r--r--arch/arm/boards/pcm049/mux.c2
-rw-r--r--arch/arm/boards/phycard-i.MX27/pca100.c2
-rw-r--r--arch/arm/boards/pm9261/init.c2
-rw-r--r--arch/arm/boards/pm9263/init.c4
-rw-r--r--arch/arm/boards/pm9g45/init.c2
-rw-r--r--arch/arm/boards/scb9328/scb9328.c2
-rw-r--r--arch/arm/boards/usb-a926x/Makefile1
-rw-r--r--arch/arm/boards/usb-a926x/config.h6
-rw-r--r--arch/arm/boards/usb-a926x/env/config41
-rw-r--r--arch/arm/boards/usb-a926x/init.c202
-rw-r--r--arch/arm/configs/at91sam9260ek_defconfig1
-rw-r--r--arch/arm/configs/usb_a9260_defconfig58
-rw-r--r--arch/arm/configs/usb_a9263_128mib_defconfig59
-rw-r--r--arch/arm/configs/usb_a9263_defconfig58
-rw-r--r--arch/arm/configs/usb_a9g20_128mib_defconfig59
-rw-r--r--arch/arm/configs/usb_a9g20_defconfig58
-rw-r--r--arch/arm/cpu/cache-l2x0.c2
-rw-r--r--arch/arm/cpu/cpu.c13
-rw-r--r--arch/arm/cpu/mmu.c62
-rw-r--r--arch/arm/include/asm/armlinux.h3
-rw-r--r--arch/arm/include/asm/io.h49
-rw-r--r--arch/arm/include/asm/memory.h18
-rw-r--r--arch/arm/lib/arm.c2
-rw-r--r--arch/arm/lib/armlinux.c17
-rw-r--r--arch/arm/lib/bootz.c13
-rw-r--r--arch/arm/mach-at91/Kconfig27
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c18
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c2
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c30
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c17
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c42
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c86
-rw-r--r--arch/arm/mach-at91/clock.c9
-rw-r--r--arch/arm/mach-at91/gpio.c2
-rw-r--r--arch/arm/mach-at91/include/mach/board.h17
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h2
-rw-r--r--arch/arm/mach-at91/include/mach/io.h2
-rw-r--r--arch/arm/mach-at91/sam9_smc.c2
-rw-r--r--arch/arm/mach-ep93xx/clocksource.c2
-rw-r--r--arch/arm/mach-ep93xx/gpio.c2
-rw-r--r--arch/arm/mach-ep93xx/led.c2
-rw-r--r--arch/arm/mach-imx/Kconfig10
-rw-r--r--arch/arm/mach-imx/boot.c2
-rw-r--r--arch/arm/mach-imx/clocksource.c2
-rw-r--r--arch/arm/mach-imx/gpio.c2
-rw-r--r--arch/arm/mach-imx/iim.c22
-rw-r--r--arch/arm/mach-imx/imx25.c2
-rw-r--r--arch/arm/mach-imx/imx35.c2
-rw-r--r--arch/arm/mach-imx/imx51.c2
-rw-r--r--arch/arm/mach-imx/imx53.c2
-rw-r--r--arch/arm/mach-imx/include/mach/clock-imx51_53.h4
-rw-r--r--arch/arm/mach-imx/include/mach/clock.h1
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx25.h5
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx51.h25
-rw-r--r--arch/arm/mach-imx/include/mach/imx25-regs.h1
-rw-r--r--arch/arm/mach-imx/include/mach/imx51-regs.h11
-rw-r--r--arch/arm/mach-imx/internal-nand-boot.c2
-rw-r--r--arch/arm/mach-imx/iomux-v2.c2
-rw-r--r--arch/arm/mach-imx/iomux-v3.c2
-rw-r--r--arch/arm/mach-imx/nand.c2
-rw-r--r--arch/arm/mach-imx/speed-imx25.c7
-rw-r--r--arch/arm/mach-imx/speed-imx31.c2
-rw-r--r--arch/arm/mach-imx/speed-imx35.c2
-rw-r--r--arch/arm/mach-imx/speed-imx51.c7
-rw-r--r--arch/arm/mach-imx/speed-imx53.c2
-rw-r--r--arch/arm/mach-mxs/clocksource-imx23.c2
-rw-r--r--arch/arm/mach-mxs/clocksource-imx28.c2
-rw-r--r--arch/arm/mach-mxs/imx_lcd_clk.c2
-rw-r--r--arch/arm/mach-mxs/iomux-imx.c2
-rw-r--r--arch/arm/mach-mxs/reset-imx.c2
-rw-r--r--arch/arm/mach-mxs/speed-imx23.c2
-rw-r--r--arch/arm/mach-mxs/speed-imx28.c2
-rw-r--r--arch/arm/mach-mxs/usb.c2
-rw-r--r--arch/arm/mach-nomadik/reset.c2
-rw-r--r--arch/arm/mach-nomadik/timer.c2
-rw-r--r--arch/arm/mach-omap/devices-gpmc-nand.c2
-rw-r--r--arch/arm/mach-omap/gpio.c2
-rw-r--r--arch/arm/mach-omap/gpmc.c2
-rw-r--r--arch/arm/mach-omap/include/mach/omap3-silicon.h3
-rw-r--r--arch/arm/mach-omap/include/mach/omap_hsmmc.h28
-rw-r--r--arch/arm/mach-omap/include/mach/sys_info.h1
-rw-r--r--arch/arm/mach-omap/include/mach/syslib.h2
-rw-r--r--arch/arm/mach-omap/omap3_clock.c2
-rw-r--r--arch/arm/mach-omap/omap3_generic.c26
-rw-r--r--arch/arm/mach-omap/omap4_clock.c2
-rw-r--r--arch/arm/mach-omap/omap4_generic.c2
-rw-r--r--arch/arm/mach-omap/s32k_clksource.c2
-rw-r--r--arch/arm/mach-omap/syslib.c2
-rw-r--r--arch/arm/mach-s3c24xx/generic.c2
-rw-r--r--arch/arm/mach-s3c24xx/gpio-s3c24x0.c2
-rw-r--r--arch/arm/mach-versatile/core.c2
-rw-r--r--arch/arm/mach-versatile/include/mach/debug_ll.h2
-rw-r--r--arch/blackfin/lib/board.c2
-rw-r--r--arch/mips/boards/dlink-dir-320/serial.c2
-rw-r--r--arch/mips/boards/qemu-malta/serial.c2
-rw-r--r--arch/mips/lib/barebox.lds.S4
-rw-r--r--arch/mips/lib/csrc-r4k.c2
-rw-r--r--arch/mips/lib/memory.c2
-rw-r--r--arch/mips/mach-bcm47xx/include/mach/debug_ll.h2
-rw-r--r--arch/mips/mach-bcm47xx/reset.c2
-rw-r--r--arch/mips/mach-malta/include/mach/debug_ll.h2
-rw-r--r--arch/mips/mach-malta/reset.c2
-rw-r--r--arch/nios2/cpu/interrupts.c2
-rw-r--r--arch/nios2/lib/board.c2
-rw-r--r--arch/nios2/lib/clock.c2
-rw-r--r--arch/nios2/lib/early_printf.c2
-rw-r--r--arch/ppc/Kconfig9
-rw-r--r--arch/ppc/boards/pcm030/barebox.lds.S4
-rw-r--r--arch/ppc/boards/pcm030/config.h68
-rw-r--r--arch/ppc/boards/pcm030/pcm030.c83
-rw-r--r--arch/ppc/include/asm/common.h23
-rw-r--r--arch/ppc/include/asm/mc146818rtc.h2
-rw-r--r--arch/ppc/lib/board.c5
-rw-r--r--arch/ppc/lib/board_data.c2
-rw-r--r--arch/ppc/mach-mpc5xxx/Kconfig3
-rw-r--r--arch/ppc/mach-mpc5xxx/cpu.c132
-rw-r--r--arch/ppc/mach-mpc5xxx/cpu_init.c141
-rw-r--r--arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h12
-rw-r--r--arch/ppc/mach-mpc5xxx/interrupts.c2
-rw-r--r--arch/ppc/mach-mpc5xxx/pci_mpc5200.c2
-rw-r--r--arch/ppc/mach-mpc5xxx/start.S100
-rw-r--r--arch/x86/boot/a20.c2
-rw-r--r--arch/x86/boot/prepare_uboot.c2
-rw-r--r--arch/x86/include/asm/io.h2
-rw-r--r--arch/x86/lib/memory.c2
-rw-r--r--arch/x86/mach-i386/generic.c2
-rw-r--r--arch/x86/mach-i386/pit_timer.c2
-rw-r--r--commands/bootm.c116
-rw-r--r--common/Kconfig26
-rw-r--r--common/console.c36
-rw-r--r--common/dlmalloc.c2
-rw-r--r--common/image.c152
-rw-r--r--common/memory.c18
-rw-r--r--common/startup.c30
-rw-r--r--common/version.c5
-rw-r--r--defaultenv/bin/_update_help2
-rw-r--r--defaultenv/bin/boot17
-rw-r--r--defaultenv/bin/update11
-rw-r--r--defaultenv/config69
-rw-r--r--drivers/base/resource.c82
-rw-r--r--drivers/i2c/busses/i2c-imx.c54
-rw-r--r--drivers/i2c/busses/i2c-omap.c2
-rw-r--r--drivers/mci/atmel_mci.c7
-rw-r--r--drivers/mci/imx-esdhc.c2
-rw-r--r--drivers/mci/imx.c2
-rw-r--r--drivers/mci/mxs.c2
-rw-r--r--drivers/mci/omap_hsmmc.c12
-rw-r--r--drivers/mci/s3c.c2
-rw-r--r--drivers/mtd/nand/atmel_nand.c10
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/nand_base.c2
-rw-r--r--drivers/mtd/nand/nand_hwecc.c2
-rw-r--r--drivers/mtd/nand/nand_hwecc_syndrome.c2
-rw-r--r--drivers/mtd/nand/nand_imx.c23
-rw-r--r--drivers/mtd/nand/nand_omap_gpmc.c2
-rw-r--r--drivers/mtd/nand/nand_s3c2410.c2
-rw-r--r--drivers/mtd/nand/nand_swecc.c2
-rw-r--r--drivers/mtd/nand/nand_write.c2
-rw-r--r--drivers/mtd/nand/nomadik_nand.c2
-rw-r--r--drivers/net/altera_tse.c2
-rw-r--r--drivers/net/cs8900.c2
-rw-r--r--drivers/net/dm9000.c2
-rw-r--r--drivers/net/ep93xx.c2
-rw-r--r--drivers/net/fec_imx.c2
-rw-r--r--drivers/net/fec_mpc5200.c8
-rw-r--r--drivers/net/macb.c20
-rw-r--r--drivers/net/netx_eth.c2
-rw-r--r--drivers/net/smc91111.c2
-rw-r--r--drivers/net/smc911x.c2
-rw-r--r--drivers/nor/cfi_flash.c26
-rw-r--r--drivers/nor/cfi_flash.h14
-rw-r--r--drivers/serial/amba-pl011.c2
-rw-r--r--drivers/serial/atmel.c2
-rw-r--r--drivers/serial/serial_altera.c2
-rw-r--r--drivers/serial/serial_altera_jtag.c2
-rw-r--r--drivers/serial/serial_at91rm9200.c2
-rw-r--r--drivers/serial/serial_blackfin.c2
-rw-r--r--drivers/serial/serial_imx.c2
-rw-r--r--drivers/serial/serial_mpc5xxx.c25
-rw-r--r--drivers/serial/serial_netx.c2
-rw-r--r--drivers/serial/serial_ns16550.c2
-rw-r--r--drivers/serial/serial_pl010.c2
-rw-r--r--drivers/serial/serial_s3c24x0.c2
-rw-r--r--drivers/serial/stm-serial.c2
-rw-r--r--drivers/spi/Kconfig10
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/altera_spi.c2
-rw-r--r--drivers/spi/atmel_spi.c321
-rw-r--r--drivers/spi/atmel_spi.h167
-rw-r--r--drivers/spi/imx_spi.c168
-rw-r--r--drivers/spi/spi.c7
-rw-r--r--drivers/usb/Kconfig2
-rw-r--r--drivers/usb/Makefile1
-rw-r--r--drivers/usb/core/usb.c63
-rw-r--r--drivers/usb/gadget/fsl_udc.c2
-rw-r--r--drivers/usb/host/Kconfig3
-rw-r--r--drivers/usb/host/Makefile2
-rw-r--r--drivers/usb/host/ehci-hcd.c16
-rw-r--r--drivers/usb/host/ehci-omap.c2
-rw-r--r--drivers/usb/host/ohci-at91.c98
-rw-r--r--drivers/usb/host/ohci-hcd.c1856
-rw-r--r--drivers/usb/host/ohci.h428
-rw-r--r--drivers/usb/otg/ulpi.c2
-rw-r--r--drivers/usb/storage/Kconfig2
-rw-r--r--drivers/usb/storage/Makefile4
-rw-r--r--drivers/usb/storage/transport.c251
-rw-r--r--drivers/usb/storage/transport.h95
-rw-r--r--drivers/usb/storage/usb.c619
-rw-r--r--drivers/usb/storage/usb.h96
-rw-r--r--drivers/video/imx-ipu-fb.c2
-rw-r--r--drivers/video/imx.c2
-rw-r--r--drivers/video/s3c.c2
-rw-r--r--drivers/video/stm.c2
-rw-r--r--include/asm-generic/io.h222
-rw-r--r--include/common.h2
-rw-r--r--include/driver.h7
-rw-r--r--include/i2c/i2c.h1
-rw-r--r--include/image.h16
-rw-r--r--include/io.h23
-rw-r--r--include/linux/ctype.h3
-rw-r--r--include/mem_malloc.h10
-rw-r--r--include/memory.h25
-rw-r--r--include/reloc.h62
-rw-r--r--include/scsi.h208
-rw-r--r--include/spi/spi.h3
-rw-r--r--include/usb/usb.h26
-rw-r--r--lib/vsprintf.c1
-rw-r--r--net/net.c9
-rw-r--r--scripts/mkimage.c5
282 files changed, 6494 insertions, 1154 deletions
diff --git a/.gitignore b/.gitignore
index 84d9f73580..cc1f2e2446 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ cross_compile
barebox
barebox.S
barebox.bin
+barebox.srec
barebox.netx
barebox.map
System.map
diff --git a/Makefile b/Makefile
index 972478d95b..5414e63136 100644
--- a/Makefile
+++ b/Makefile
@@ -689,6 +689,9 @@ barebox: $(barebox-lds) $(barebox-head) $(barebox-common) $(kallsyms.o) FORCE
$(call if_changed_rule,barebox__)
$(Q)rm -f .old_version
+barebox.srec: barebox
+ $(OBJCOPY) -O srec $< $@
+
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
$(sort $(barebox-head) $(barebox-common) ) $(barebox-lds): $(barebox-dirs) ;
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index f1c045e04f..d25412d11f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -105,6 +105,9 @@ board-$(CONFIG_MACH_FREESCALE_MX51_PDK) := freescale-mx51-pdk
board-$(CONFIG_MACH_FREESCALE_MX53_LOCO) := freescale-mx53-loco
board-$(CONFIG_MACH_GUF_CUPID) := guf-cupid
board-$(CONFIG_MACH_MINI2440) := mini2440
+board-$(CONFIG_MACH_USB_A9260) := usb-a926x
+board-$(CONFIG_MACH_USB_A9263) := usb-a926x
+board-$(CONFIG_MACH_USB_A9G20) := usb-a926x
board-$(CONFIG_MACH_VERSATILEPB) := versatile
board-$(CONFIG_MACH_TX25) := karo-tx25
diff --git a/arch/arm/boards/a9m2410/a9m2410.c b/arch/arm/boards/a9m2410/a9m2410.c
index 44ac44bcbc..bbe16044ef 100644
--- a/arch/arm/boards/a9m2410/a9m2410.c
+++ b/arch/arm/boards/a9m2410/a9m2410.c
@@ -31,7 +31,7 @@
#include <generated/mach-types.h>
#include <partition.h>
#include <nand.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/s3c24x0-iomap.h>
#include <mach/s3c24x0-nand.h>
diff --git a/arch/arm/boards/a9m2440/a9m2410dev.c b/arch/arm/boards/a9m2440/a9m2410dev.c
index 1220bd9777..5f7c53b9f6 100644
--- a/arch/arm/boards/a9m2440/a9m2410dev.c
+++ b/arch/arm/boards/a9m2440/a9m2410dev.c
@@ -27,7 +27,7 @@
#include <common.h>
#include <driver.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/s3c24x0-iomap.h>
/**
diff --git a/arch/arm/boards/a9m2440/a9m2440.c b/arch/arm/boards/a9m2440/a9m2440.c
index 89c9cdf57e..964d376412 100644
--- a/arch/arm/boards/a9m2440/a9m2440.c
+++ b/arch/arm/boards/a9m2440/a9m2440.c
@@ -31,7 +31,7 @@
#include <generated/mach-types.h>
#include <partition.h>
#include <nand.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/s3c24x0-iomap.h>
#include <mach/s3c24x0-nand.h>
#include <mach/s3c24xx-generic.h>
diff --git a/arch/arm/boards/at91rm9200ek/init.c b/arch/arm/boards/at91rm9200ek/init.c
index cff7ede4d3..b2008a4394 100644
--- a/arch/arm/boards/at91rm9200ek/init.c
+++ b/arch/arm/boards/at91rm9200ek/init.c
@@ -27,7 +27,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <mach/at91_pmc.h>
#include <mach/board.h>
diff --git a/arch/arm/boards/at91sam9260ek/init.c b/arch/arm/boards/at91sam9260ek/init.c
index 861e8980a5..ea80a1b039 100644
--- a/arch/arm/boards/at91sam9260ek/init.c
+++ b/arch/arm/boards/at91sam9260ek/init.c
@@ -28,7 +28,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <nand.h>
#include <linux/mtd/nand.h>
@@ -63,8 +63,6 @@ static struct atmel_nand_data nand_pdata = {
.ale = 21,
.cle = 22,
/* .det_pin = ... not connected */
- .ecc_base = (void __iomem *)(AT91_BASE_SYS + AT91_ECC),
- .ecc_mode = NAND_ECC_HW,
.rdy_pin = AT91_PIN_PC13,
.enable_pin = AT91_PIN_PC14,
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
diff --git a/arch/arm/boards/at91sam9261ek/init.c b/arch/arm/boards/at91sam9261ek/init.c
index 73b411add0..0bef84d132 100644
--- a/arch/arm/boards/at91sam9261ek/init.c
+++ b/arch/arm/boards/at91sam9261ek/init.c
@@ -27,7 +27,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <nand.h>
#include <linux/mtd/nand.h>
@@ -43,7 +43,6 @@ static struct atmel_nand_data nand_pdata = {
.ale = 22,
.cle = 21,
/* .det_pin = ... not connected */
- .ecc_mode = NAND_ECC_SOFT,
.rdy_pin = AT91_PIN_PC15,
.enable_pin = AT91_PIN_PC14,
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
diff --git a/arch/arm/boards/at91sam9263ek/init.c b/arch/arm/boards/at91sam9263ek/init.c
index 46f3a7ede2..40c0b7b6f2 100644
--- a/arch/arm/boards/at91sam9263ek/init.c
+++ b/arch/arm/boards/at91sam9263ek/init.c
@@ -29,7 +29,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <nand.h>
#include <linux/mtd/nand.h>
@@ -44,8 +44,6 @@ static struct atmel_nand_data nand_pdata = {
.ale = 21,
.cle = 22,
/* .det_pin = ... not connected */
- .ecc_base = (void __iomem *)(AT91_BASE_SYS + AT91_ECC0),
- .ecc_mode = NAND_ECC_HW,
.rdy_pin = AT91_PIN_PA22,
.enable_pin = AT91_PIN_PD15,
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
diff --git a/arch/arm/boards/at91sam9m10g45ek/init.c b/arch/arm/boards/at91sam9m10g45ek/init.c
index ba7c2fff48..073ff42374 100644
--- a/arch/arm/boards/at91sam9m10g45ek/init.c
+++ b/arch/arm/boards/at91sam9m10g45ek/init.c
@@ -30,7 +30,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <nand.h>
#include <linux/mtd/nand.h>
diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index 1c66eb231a..38f28be9c5 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -25,7 +25,7 @@
#include <sizes.h>
#include <usb/ehci.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
#include <generated/mach-types.h>
#include <mach/imx-regs.h>
diff --git a/arch/arm/boards/edb93xx/edb93xx.c b/arch/arm/boards/edb93xx/edb93xx.c
index 3e4e0b04a0..70fd12c1bf 100644
--- a/arch/arm/boards/edb93xx/edb93xx.c
+++ b/arch/arm/boards/edb93xx/edb93xx.c
@@ -27,7 +27,7 @@
#include <init.h>
#include <partition.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <generated/mach-types.h>
#include <mach/ep93xx-regs.h>
#include "edb93xx.h"
diff --git a/arch/arm/boards/edb93xx/flash_cfg.c b/arch/arm/boards/edb93xx/flash_cfg.c
index 91a6a4ea96..56bf0b57c2 100644
--- a/arch/arm/boards/edb93xx/flash_cfg.c
+++ b/arch/arm/boards/edb93xx/flash_cfg.c
@@ -24,7 +24,7 @@
#include <common.h>
#include <mach/ep93xx-regs.h>
-#include <asm/io.h>
+#include <io.h>
#define SMC_BCR6_VALUE (2 << SMC_BCR_IDCY_SHIFT | 5 << SMC_BCR_WST1_SHIFT | \
SMC_BCR_BLE | 2 << SMC_BCR_WST2_SHIFT | \
diff --git a/arch/arm/boards/edb93xx/pll_cfg.c b/arch/arm/boards/edb93xx/pll_cfg.c
index a687af0a01..a53efa69c1 100644
--- a/arch/arm/boards/edb93xx/pll_cfg.c
+++ b/arch/arm/boards/edb93xx/pll_cfg.c
@@ -25,7 +25,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include "pll_cfg.h"
#include "early_udelay.h"
diff --git a/arch/arm/boards/edb93xx/sdram_cfg.c b/arch/arm/boards/edb93xx/sdram_cfg.c
index 3d4fe08e19..8342d446b3 100644
--- a/arch/arm/boards/edb93xx/sdram_cfg.c
+++ b/arch/arm/boards/edb93xx/sdram_cfg.c
@@ -23,7 +23,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include "sdram_cfg.h"
#include "early_udelay.h"
diff --git a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
index 1c54202dfa..6355e3c205 100644
--- a/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
+++ b/arch/arm/boards/eukrea_cpuimx25/eukrea_cpuimx25.c
@@ -29,7 +29,7 @@
#include <mach/imx-regs.h>
#include <asm/armlinux.h>
#include <mach/gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
#include <led.h>
diff --git a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
index 4ebf247776..12219737c0 100644
--- a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
+++ b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
@@ -26,7 +26,7 @@
#include <mach/imx-regs.h>
#include <mach/imx-pll.h>
#include <mach/esdctl.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <asm/barebox-arm.h>
#include <asm-generic/memory_layout.h>
diff --git a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
index a5aadac0d9..994f45629b 100644
--- a/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
+++ b/arch/arm/boards/eukrea_cpuimx27/eukrea_cpuimx27.c
@@ -37,7 +37,7 @@
#include <fcntl.h>
#include <nand.h>
#include <command.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <mach/imx-pll.h>
#include <mach/imxfb.h>
diff --git a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
index 426445f59d..5f654d47c1 100644
--- a/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
+++ b/arch/arm/boards/eukrea_cpuimx35/eukrea_cpuimx35.c
@@ -39,7 +39,7 @@
#include <partition.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <generated/mach-types.h>
#include <asm/mmu.h>
diff --git a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
index 6c0e106f67..a909a8784e 100644
--- a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
+++ b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
@@ -26,7 +26,7 @@
#include <mach/imx-pll.h>
#include <mach/esdctl.h>
#include <asm/cache-l2x0.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <asm/barebox-arm.h>
#include <asm-generic/memory_layout.h>
diff --git a/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c b/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c
index 727db29241..a128d500ad 100644
--- a/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c
+++ b/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c
@@ -34,7 +34,7 @@
#include <nand.h>
#include <spi/spi.h>
#include <mfd/mc13892.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
#include <mach/imx-nand.h>
#include <mach/spi.h>
diff --git a/arch/arm/boards/freescale-mx25-3-stack/3stack.c b/arch/arm/boards/freescale-mx25-3-stack/3stack.c
index 979115d927..5aa54e43ff 100644
--- a/arch/arm/boards/freescale-mx25-3-stack/3stack.c
+++ b/arch/arm/boards/freescale-mx25-3-stack/3stack.c
@@ -28,7 +28,7 @@
#include <mach/imx-regs.h>
#include <asm/armlinux.h>
#include <mach/gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <partition.h>
#include <generated/mach-types.h>
#include <mach/imx-nand.h>
diff --git a/arch/arm/boards/freescale-mx35-3-stack/3stack.c b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
index ab702650ab..030a1a7acf 100644
--- a/arch/arm/boards/freescale-mx35-3-stack/3stack.c
+++ b/arch/arm/boards/freescale-mx35-3-stack/3stack.c
@@ -37,7 +37,7 @@
#include <partition.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <generated/mach-types.h>
#include <mach/gpio.h>
diff --git a/arch/arm/boards/freescale-mx51-pdk/board.c b/arch/arm/boards/freescale-mx51-pdk/board.c
index 646f807c7a..d56effaaf9 100644
--- a/arch/arm/boards/freescale-mx51-pdk/board.c
+++ b/arch/arm/boards/freescale-mx51-pdk/board.c
@@ -32,7 +32,7 @@
#include <nand.h>
#include <spi/spi.h>
#include <mfd/mc13892.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
#include <mach/imx-nand.h>
#include <mach/spi.h>
diff --git a/arch/arm/boards/freescale-mx53-loco/board.c b/arch/arm/boards/freescale-mx53-loco/board.c
index b5240f4f3a..24df9ae0b0 100644
--- a/arch/arm/boards/freescale-mx53-loco/board.c
+++ b/arch/arm/boards/freescale-mx53-loco/board.c
@@ -36,7 +36,7 @@
#include <mach/iim.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
static struct fec_platform_data fec_info = {
diff --git a/arch/arm/boards/guf-cupid/board.c b/arch/arm/boards/guf-cupid/board.c
index 706707d0bb..158adfcda4 100644
--- a/arch/arm/boards/guf-cupid/board.c
+++ b/arch/arm/boards/guf-cupid/board.c
@@ -32,7 +32,7 @@
#include <mach/imx-regs.h>
#include <asm/armlinux.h>
#include <mach/gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <partition.h>
#include <nand.h>
#include <generated/mach-types.h>
diff --git a/arch/arm/boards/guf-cupid/lowlevel.c b/arch/arm/boards/guf-cupid/lowlevel.c
index 8d403ee821..396604d59f 100644
--- a/arch/arm/boards/guf-cupid/lowlevel.c
+++ b/arch/arm/boards/guf-cupid/lowlevel.c
@@ -26,7 +26,7 @@
#include <mach/imx-pll.h>
#include <mach/esdctl.h>
#include <asm/cache-l2x0.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <asm/barebox-arm.h>
#include <asm-generic/memory_layout.h>
diff --git a/arch/arm/boards/guf-neso/board.c b/arch/arm/boards/guf-neso/board.c
index 446b333f1f..e524b70aac 100644
--- a/arch/arm/boards/guf-neso/board.c
+++ b/arch/arm/boards/guf-neso/board.c
@@ -32,7 +32,7 @@
#include <spi/spi.h>
#include <usb/isp1504.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
diff --git a/arch/arm/boards/guf-neso/lowlevel.c b/arch/arm/boards/guf-neso/lowlevel.c
index d366d440af..b1ad621e06 100644
--- a/arch/arm/boards/guf-neso/lowlevel.c
+++ b/arch/arm/boards/guf-neso/lowlevel.c
@@ -26,7 +26,7 @@
#include <mach/imx-pll.h>
#include <mach/esdctl.h>
#include <asm/cache-l2x0.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <asm/barebox-arm.h>
#include <asm/system.h>
diff --git a/arch/arm/boards/imx21ads/imx21ads.c b/arch/arm/boards/imx21ads/imx21ads.c
index d58831e748..fc34709630 100644
--- a/arch/arm/boards/imx21ads/imx21ads.c
+++ b/arch/arm/boards/imx21ads/imx21ads.c
@@ -27,7 +27,7 @@
#include <environment.h>
#include <mach/imx-regs.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/gpio.h>
#include <partition.h>
#include <fs.h>
diff --git a/arch/arm/boards/imx27ads/imx27ads.c b/arch/arm/boards/imx27ads/imx27ads.c
index da4260fa58..e93f07a078 100644
--- a/arch/arm/boards/imx27ads/imx27ads.c
+++ b/arch/arm/boards/imx27ads/imx27ads.c
@@ -24,7 +24,7 @@
#include <environment.h>
#include <mach/imx-regs.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <fec.h>
#include <mach/gpio.h>
#include <partition.h>
diff --git a/arch/arm/boards/karo-tx25/board.c b/arch/arm/boards/karo-tx25/board.c
index 22bc27a291..1eece1dfed 100644
--- a/arch/arm/boards/karo-tx25/board.c
+++ b/arch/arm/boards/karo-tx25/board.c
@@ -28,7 +28,7 @@
#include <mach/imx-regs.h>
#include <asm/armlinux.h>
#include <mach/gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <partition.h>
#include <generated/mach-types.h>
#include <mach/imx-nand.h>
diff --git a/arch/arm/boards/karo-tx25/lowlevel.c b/arch/arm/boards/karo-tx25/lowlevel.c
index 868ba08dd7..09c0339659 100644
--- a/arch/arm/boards/karo-tx25/lowlevel.c
+++ b/arch/arm/boards/karo-tx25/lowlevel.c
@@ -24,7 +24,7 @@
#include <init.h>
#include <mach/imx-regs.h>
#include <mach/esdctl.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <asm/barebox-arm.h>
#include <asm/system.h>
diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c
index 8427dc2391..b36d8226e5 100644
--- a/arch/arm/boards/karo-tx28/tx28-stk5.c
+++ b/arch/arm/boards/karo-tx28/tx28-stk5.c
@@ -20,8 +20,7 @@
#include <mci.h>
#include <fec.h>
#include <sizes.h>
-#include <reloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/sections.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
index def388a8d9..a62cb8257f 100644
--- a/arch/arm/boards/karo-tx28/tx28.c
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -18,7 +18,7 @@
#include <environment.h>
#include <errno.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <generated/mach-types.h>
#include <mach/imx-regs.h>
#include <asm/mmu.h>
diff --git a/arch/arm/boards/mini2440/mini2440.c b/arch/arm/boards/mini2440/mini2440.c
index fd1f2f27c3..43510238e0 100644
--- a/arch/arm/boards/mini2440/mini2440.c
+++ b/arch/arm/boards/mini2440/mini2440.c
@@ -36,7 +36,7 @@
#include <mci.h>
#include <fb.h>
#include <asm/armlinux.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/gpio.h>
#include <mach/s3c24x0-iomap.h>
#include <mach/s3c24x0-nand.h>
diff --git a/arch/arm/boards/mmccpu/init.c b/arch/arm/boards/mmccpu/init.c
index 36bc193bfc..51dbf24621 100644
--- a/arch/arm/boards/mmccpu/init.c
+++ b/arch/arm/boards/mmccpu/init.c
@@ -28,7 +28,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <nand.h>
#include <linux/mtd/nand.h>
diff --git a/arch/arm/boards/nhk8815/setup.c b/arch/arm/boards/nhk8815/setup.c
index dcf716620d..42d981cbfd 100644
--- a/arch/arm/boards/nhk8815/setup.c
+++ b/arch/arm/boards/nhk8815/setup.c
@@ -26,7 +26,7 @@
#include <nand.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
#include <mach/board.h>
diff --git a/arch/arm/boards/omap/board-beagle.c b/arch/arm/boards/omap/board-beagle.c
index 4e7f179a6f..bfb08f7042 100644
--- a/arch/arm/boards/omap/board-beagle.c
+++ b/arch/arm/boards/omap/board-beagle.c
@@ -57,7 +57,7 @@
#include <init.h>
#include <driver.h>
#include <sizes.h>
-#include <asm/io.h>
+#include <io.h>
#include <ns16550.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
diff --git a/arch/arm/boards/omap/board-omap3evm.c b/arch/arm/boards/omap/board-omap3evm.c
index 71d6ca9e40..d2f041ad71 100644
--- a/arch/arm/boards/omap/board-omap3evm.c
+++ b/arch/arm/boards/omap/board-omap3evm.c
@@ -48,7 +48,7 @@
#include <console.h>
#include <init.h>
#include <driver.h>
-#include <asm/io.h>
+#include <io.h>
#include <ns16550.h>
#include <asm/armlinux.h>
#include <mach/silicon.h>
diff --git a/arch/arm/boards/omap/board-sdp343x.c b/arch/arm/boards/omap/board-sdp343x.c
index 83efe62233..d486c20d74 100644
--- a/arch/arm/boards/omap/board-sdp343x.c
+++ b/arch/arm/boards/omap/board-sdp343x.c
@@ -51,7 +51,7 @@
#include <console.h>
#include <init.h>
#include <driver.h>
-#include <asm/io.h>
+#include <io.h>
#include <ns16550.h>
#include <asm/armlinux.h>
#include <mach/silicon.h>
diff --git a/arch/arm/boards/panda/board.c b/arch/arm/boards/panda/board.c
index 33ec144db4..6a149aaeaa 100644
--- a/arch/arm/boards/panda/board.c
+++ b/arch/arm/boards/panda/board.c
@@ -3,7 +3,7 @@
#include <init.h>
#include <fs.h>
#include <driver.h>
-#include <asm/io.h>
+#include <io.h>
#include <ns16550.h>
#include <asm/armlinux.h>
#include <linux/stat.h>
diff --git a/arch/arm/boards/panda/lowlevel.c b/arch/arm/boards/panda/lowlevel.c
index cc0c374a03..45ea221d87 100644
--- a/arch/arm/boards/panda/lowlevel.c
+++ b/arch/arm/boards/panda/lowlevel.c
@@ -21,7 +21,7 @@
* MA 02111-1307 USA
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/omap4-mux.h>
#include <mach/omap4-silicon.h>
#include <mach/omap4-clock.h>
diff --git a/arch/arm/boards/panda/mux.c b/arch/arm/boards/panda/mux.c
index a03104011d..7586e86745 100644
--- a/arch/arm/boards/panda/mux.c
+++ b/arch/arm/boards/panda/mux.c
@@ -1,6 +1,6 @@
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/omap4-silicon.h>
#include <mach/omap4-mux.h>
diff --git a/arch/arm/boards/pcm037/pcm037.c b/arch/arm/boards/pcm037/pcm037.c
index 85f004fe48..42a543d2cc 100644
--- a/arch/arm/boards/pcm037/pcm037.c
+++ b/arch/arm/boards/pcm037/pcm037.c
@@ -32,7 +32,7 @@
#include <mach/iomux-mx31.h>
#include <asm/armlinux.h>
#include <mach/gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
#include <partition.h>
#include <generated/mach-types.h>
diff --git a/arch/arm/boards/pcm038/lowlevel.c b/arch/arm/boards/pcm038/lowlevel.c
index b50e1c8386..32392636e7 100644
--- a/arch/arm/boards/pcm038/lowlevel.c
+++ b/arch/arm/boards/pcm038/lowlevel.c
@@ -25,7 +25,7 @@
#include <mach/imx-regs.h>
#include <mach/imx-pll.h>
#include <mach/esdctl.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <asm/barebox-arm.h>
#include <asm/system.h>
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index 6fee5c2d61..0b07a6378a 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -35,7 +35,7 @@
#include <nand.h>
#include <command.h>
#include <spi/spi.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <mach/imx-pll.h>
#include <mach/imxfb.h>
diff --git a/arch/arm/boards/pcm043/lowlevel.c b/arch/arm/boards/pcm043/lowlevel.c
index e488681c13..40e3204425 100644
--- a/arch/arm/boards/pcm043/lowlevel.c
+++ b/arch/arm/boards/pcm043/lowlevel.c
@@ -26,7 +26,7 @@
#include <mach/imx-pll.h>
#include <mach/esdctl.h>
#include <asm/cache-l2x0.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <asm/barebox-arm.h>
#include <asm-generic/memory_layout.h>
diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
index fbe8cea12f..23580c9f6f 100644
--- a/arch/arm/boards/pcm043/pcm043.c
+++ b/arch/arm/boards/pcm043/pcm043.c
@@ -32,7 +32,7 @@
#include <mach/imx-regs.h>
#include <asm/armlinux.h>
#include <mach/gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <partition.h>
#include <nand.h>
#include <generated/mach-types.h>
diff --git a/arch/arm/boards/pcm049/board.c b/arch/arm/boards/pcm049/board.c
index 3d0277988e..8de333f0d9 100644
--- a/arch/arm/boards/pcm049/board.c
+++ b/arch/arm/boards/pcm049/board.c
@@ -22,7 +22,7 @@
#include <console.h>
#include <init.h>
#include <driver.h>
-#include <asm/io.h>
+#include <io.h>
#include <ns16550.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
diff --git a/arch/arm/boards/pcm049/lowlevel.c b/arch/arm/boards/pcm049/lowlevel.c
index e036ba742d..bea895e31f 100644
--- a/arch/arm/boards/pcm049/lowlevel.c
+++ b/arch/arm/boards/pcm049/lowlevel.c
@@ -21,7 +21,7 @@
* MA 02111-1307 USA
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/omap4-mux.h>
#include <mach/omap4-silicon.h>
#include <mach/omap4-clock.h>
diff --git a/arch/arm/boards/pcm049/mux.c b/arch/arm/boards/pcm049/mux.c
index d93d4589eb..9911b62e5a 100644
--- a/arch/arm/boards/pcm049/mux.c
+++ b/arch/arm/boards/pcm049/mux.c
@@ -1,6 +1,6 @@
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/omap4-silicon.h>
#include <mach/omap4-mux.h>
diff --git a/arch/arm/boards/phycard-i.MX27/pca100.c b/arch/arm/boards/phycard-i.MX27/pca100.c
index f285466641..41567673a7 100644
--- a/arch/arm/boards/phycard-i.MX27/pca100.c
+++ b/arch/arm/boards/phycard-i.MX27/pca100.c
@@ -32,7 +32,7 @@
#include <fcntl.h>
#include <nand.h>
#include <spi/spi.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-nand.h>
#include <mach/imx-pll.h>
#include <gpio.h>
diff --git a/arch/arm/boards/pm9261/init.c b/arch/arm/boards/pm9261/init.c
index efc5dcc1fb..2766f473d8 100644
--- a/arch/arm/boards/pm9261/init.c
+++ b/arch/arm/boards/pm9261/init.c
@@ -27,7 +27,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <nand.h>
#include <linux/mtd/nand.h>
diff --git a/arch/arm/boards/pm9263/init.c b/arch/arm/boards/pm9263/init.c
index aeca4e7d79..92d7e9f166 100644
--- a/arch/arm/boards/pm9263/init.c
+++ b/arch/arm/boards/pm9263/init.c
@@ -28,7 +28,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <nand.h>
#include <linux/mtd/nand.h>
@@ -43,8 +43,6 @@ static struct atmel_nand_data nand_pdata = {
.ale = 21,
.cle = 22,
/* .det_pin = ... not connected */
- .ecc_base = (void __iomem *)(AT91_BASE_SYS + AT91_ECC0),
- .ecc_mode = NAND_ECC_HW,
.rdy_pin = AT91_PIN_PB30,
.enable_pin = AT91_PIN_PD15,
#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
diff --git a/arch/arm/boards/pm9g45/init.c b/arch/arm/boards/pm9g45/init.c
index 35c9ce9f83..480c7513e3 100644
--- a/arch/arm/boards/pm9g45/init.c
+++ b/arch/arm/boards/pm9g45/init.c
@@ -29,7 +29,7 @@
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware.h>
#include <nand.h>
#include <linux/mtd/nand.h>
diff --git a/arch/arm/boards/scb9328/scb9328.c b/arch/arm/boards/scb9328/scb9328.c
index e90417f01e..906a17e07e 100644
--- a/arch/arm/boards/scb9328/scb9328.c
+++ b/arch/arm/boards/scb9328/scb9328.c
@@ -26,7 +26,7 @@
#include <mach/imx-regs.h>
#include <asm/armlinux.h>
#include <mach/gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <partition.h>
#include <fs.h>
#include <fcntl.h>
diff --git a/arch/arm/boards/usb-a926x/Makefile b/arch/arm/boards/usb-a926x/Makefile
new file mode 100644
index 0000000000..eb072c0161
--- /dev/null
+++ b/arch/arm/boards/usb-a926x/Makefile
@@ -0,0 +1 @@
+obj-y += init.o
diff --git a/arch/arm/boards/usb-a926x/config.h b/arch/arm/boards/usb-a926x/config.h
new file mode 100644
index 0000000000..d97181032f
--- /dev/null
+++ b/arch/arm/boards/usb-a926x/config.h
@@ -0,0 +1,6 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define AT91_MAIN_CLOCK 12000000 /* 12 MHz crystal */
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/usb-a926x/env/config b/arch/arm/boards/usb-a926x/env/config
new file mode 100644
index 0000000000..d77f6785f5
--- /dev/null
+++ b/arch/arm/boards/usb-a926x/env/config
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.netmask=a.b.c.d
+#eth0.gateway=a.b.c.d
+#eth0.serverip=a.b.c.d
+
+# can be either 'nfs', 'tftp', 'nor' or 'nand'
+kernel_loc=tftp
+# can be either 'net', 'nor', 'nand' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+#kernelimage_type=zimage
+#kernelimage=zImage
+kernelimage_type=uimage
+kernelimage=uImage
+#kernelimage_type=raw
+#kernelimage=Image
+#kernelimage_type=raw_lzo
+#kernelimage=Image.lzo
+
+nand_device=atmel_nand
+nand_parts="128k(at91bootstrap),256k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),4M(kernel),120M(rootfs),-(data)"
+rootfs_mtdblock_nand=5
+
+autoboot_timeout=3
+
+bootargs="console=ttyS0,115200"
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m\n# "
diff --git a/arch/arm/boards/usb-a926x/init.c b/arch/arm/boards/usb-a926x/init.c
new file mode 100644
index 0000000000..535458226c
--- /dev/null
+++ b/arch/arm/boards/usb-a926x/init.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <net.h>
+#include <init.h>
+#include <environment.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <partition.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <io.h>
+#include <asm/hardware.h>
+#include <nand.h>
+#include <sizes.h>
+#include <linux/mtd/nand.h>
+#include <linux/clk.h>
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/sam9_smc.h>
+#include <gpio.h>
+#include <mach/io.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+
+static void usb_a9260_set_board_type(void)
+{
+ if (machine_is_usb_a9g20())
+ armlinux_set_architecture(MACH_TYPE_USB_A9G20);
+ else if (machine_is_usb_a9263())
+ armlinux_set_architecture(MACH_TYPE_USB_A9263);
+ else
+ armlinux_set_architecture(MACH_TYPE_USB_A9260);
+}
+
+static struct atmel_nand_data nand_pdata = {
+ .ale = 21,
+ .cle = 22,
+/* .det_pin = ... not connected */
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+};
+
+static struct sam9_smc_config usb_a9260_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+
+static struct sam9_smc_config usb_a9g20_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 2,
+ .ncs_write_setup = 0,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 4,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 4,
+ .nwe_pulse = 2,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 3,
+};
+
+static void usb_a9260_add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ if (machine_is_usb_a9g20())
+ sam9_smc_configure(3, &usb_a9g20_nand_smc_config);
+ else
+ sam9_smc_configure(3, &usb_a9260_nand_smc_config);
+
+ if (machine_is_usb_a9263()) {
+ nand_pdata.rdy_pin = AT91_PIN_PA22;
+ nand_pdata.enable_pin = AT91_PIN_PD15;
+ }
+
+ at91_add_device_nand(&nand_pdata);
+}
+
+static struct at91_ether_platform_data macb_pdata = {
+ .flags = AT91SAM_ETHER_RMII,
+ .phy_addr = 0,
+};
+
+static void usb_a9260_phy_reset(void)
+{
+ unsigned long rstc;
+ struct clk *clk = clk_get(NULL, "macb_clk");
+
+ clk_enable(clk);
+
+ at91_set_gpio_input(AT91_PIN_PA14, 0);
+ at91_set_gpio_input(AT91_PIN_PA15, 0);
+ at91_set_gpio_input(AT91_PIN_PA17, 0);
+ at91_set_gpio_input(AT91_PIN_PA25, 0);
+ at91_set_gpio_input(AT91_PIN_PA26, 0);
+ at91_set_gpio_input(AT91_PIN_PA28, 0);
+
+ rstc = at91_sys_read(AT91_RSTC_MR) & AT91_RSTC_ERSTL;
+
+ /* Need to reset PHY -> 500ms reset */
+ at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
+ (AT91_RSTC_ERSTL & (0x0d << 8)) |
+ AT91_RSTC_URSTEN);
+
+ at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST);
+
+ /* Wait for end hardware reset */
+ while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL));
+
+ /* Restore NRST value */
+ at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
+ (rstc) |
+ AT91_RSTC_URSTEN);
+}
+
+#if defined(CONFIG_MCI_ATMEL)
+static struct atmel_mci_platform_data __initdata usb_a9260_mci_data = {
+ .bus_width = 4,
+};
+
+static void usb_a9260_add_device_mci(void)
+{
+ at91_add_device_mci(0, &usb_a9260_mci_data);
+}
+#else
+static void usb_a9260_add_device_mci(void) {}
+#endif
+
+static struct at91_usbh_data ek_usbh_data = {
+ .ports = 2,
+};
+
+static int usb_a9260_devices_init(void)
+{
+ usb_a9260_add_device_nand();
+ usb_a9260_phy_reset();
+ at91_add_device_eth(&macb_pdata);
+ usb_a9260_add_device_mci();
+ at91_add_device_usbh_ohci(&ek_usbh_data);
+
+#ifdef CONFIG_AT91_HAVE_SRAM_128M
+ at91_add_device_sdram(128 * 1024 * 1024);
+#else
+ at91_add_device_sdram(64 * 1024 * 1024);
+#endif
+ armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100));
+ usb_a9260_set_board_type();
+
+ devfs_add_partition("nand0", 0x00000, SZ_128K, PARTITION_FIXED, "at91bootstrap_raw");
+ dev_add_bb_dev("at91bootstrap_raw", "at91bootstrap");
+ devfs_add_partition("nand0", SZ_128K, SZ_256K, PARTITION_FIXED, "self_raw");
+ dev_add_bb_dev("self_raw", "self0");
+ devfs_add_partition("nand0", SZ_256K + SZ_128K, SZ_128K, PARTITION_FIXED, "env_raw");
+ dev_add_bb_dev("env_raw", "env0");
+ devfs_add_partition("nand0", SZ_512K, SZ_128K, PARTITION_FIXED, "env_raw1");
+ dev_add_bb_dev("env_raw1", "env1");
+
+ return 0;
+}
+device_initcall(usb_a9260_devices_init);
+
+static int usb_a9260_console_init(void)
+{
+ at91_register_uart(0, 0);
+ return 0;
+}
+console_initcall(usb_a9260_console_init);
diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig
index 6038aec3fe..2d04206cfa 100644
--- a/arch/arm/configs/at91sam9260ek_defconfig
+++ b/arch/arm/configs/at91sam9260ek_defconfig
@@ -1,3 +1,4 @@
+CONFIG_ARCH_AT91SAM9260=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_LONGHELP=y
CONFIG_GLOB=y
diff --git a/arch/arm/configs/usb_a9260_defconfig b/arch/arm/configs/usb_a9260_defconfig
new file mode 100644
index 0000000000..adcb6036f5
--- /dev/null
+++ b/arch/arm/configs/usb_a9260_defconfig
@@ -0,0 +1,58 @@
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_USB_A9260=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_KALLSYMS=y
+CONFIG_PROMPT="USB-9G20:"
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/usb-a926x/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_MACB=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_ATMEL=y
+CONFIG_UBI=y
diff --git a/arch/arm/configs/usb_a9263_128mib_defconfig b/arch/arm/configs/usb_a9263_128mib_defconfig
new file mode 100644
index 0000000000..8d5342e38c
--- /dev/null
+++ b/arch/arm/configs/usb_a9263_128mib_defconfig
@@ -0,0 +1,59 @@
+CONFIG_ARCH_AT91SAM9263=y
+CONFIG_MACH_USB_A9263=y
+CONFIG_AEABI=y
+CONFIG_AT91_HAVE_SRAM_128M=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_KALLSYMS=y
+CONFIG_PROMPT="USB-9G20:"
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/usb-a926x/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_MACB=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_ATMEL=y
+CONFIG_UBI=y
diff --git a/arch/arm/configs/usb_a9263_defconfig b/arch/arm/configs/usb_a9263_defconfig
new file mode 100644
index 0000000000..9f53431b93
--- /dev/null
+++ b/arch/arm/configs/usb_a9263_defconfig
@@ -0,0 +1,58 @@
+CONFIG_ARCH_AT91SAM9263=y
+CONFIG_MACH_USB_A9263=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_KALLSYMS=y
+CONFIG_PROMPT="USB-9G20:"
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/usb-a926x/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_MACB=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_ATMEL=y
+CONFIG_UBI=y
diff --git a/arch/arm/configs/usb_a9g20_128mib_defconfig b/arch/arm/configs/usb_a9g20_128mib_defconfig
new file mode 100644
index 0000000000..3c0e6f72a3
--- /dev/null
+++ b/arch/arm/configs/usb_a9g20_128mib_defconfig
@@ -0,0 +1,59 @@
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_USB_A9G20=y
+CONFIG_AEABI=y
+CONFIG_AT91_HAVE_SRAM_128M=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_KALLSYMS=y
+CONFIG_PROMPT="USB-9G20:"
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/usb-a926x/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_MACB=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_ATMEL=y
+CONFIG_UBI=y
diff --git a/arch/arm/configs/usb_a9g20_defconfig b/arch/arm/configs/usb_a9g20_defconfig
new file mode 100644
index 0000000000..2bcb8eb797
--- /dev/null
+++ b/arch/arm/configs/usb_a9g20_defconfig
@@ -0,0 +1,58 @@
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_USB_A9G20=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_KALLSYMS=y
+CONFIG_PROMPT="USB-9G20:"
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/usb-a926x/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_MACB=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_ATMEL=y
+CONFIG_UBI=y
diff --git a/arch/arm/cpu/cache-l2x0.c b/arch/arm/cpu/cache-l2x0.c
index 1ea7bab362..b300e6ffb0 100644
--- a/arch/arm/cpu/cache-l2x0.c
+++ b/arch/arm/cpu/cache-l2x0.c
@@ -1,6 +1,6 @@
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
#define CACHE_LINE_SIZE 32
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 3df0c0f647..d4a3b14819 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -90,19 +90,6 @@ void arch_shutdown(void)
#endif
}
-LIST_HEAD(memory_list);
-
-void armlinux_add_dram(struct device_d *dev)
-{
- struct arm_memory *mem = xzalloc(sizeof(*mem));
-
- mem->dev = dev;
- mem->start = dev->resource[0].start;
- mem->size = dev->resource[0].size;
-
- list_add_tail(&mem->list, &memory_list);
-}
-
/**
* @page arm_boot_preparation Linux Preparation on ARM
*
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index b6693495b6..4446813d0a 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -5,6 +5,7 @@
#include <sizes.h>
#include <asm/memory.h>
#include <asm/system.h>
+#include <memory.h>
static unsigned long *ttb;
@@ -76,28 +77,28 @@ static u32 *arm_create_pte(unsigned long virt)
return table;
}
+static u32 *find_pte(unsigned long adr)
+{
+ u32 *table;
+
+ if ((ttb[adr >> 20] & PMD_TYPE_MASK) != PMD_TYPE_TABLE)
+ BUG();
+
+ /* find the coarse page table base address */
+ table = (u32 *)(ttb[adr >> 20] & ~0x3ff);
+
+ /* find second level descriptor */
+ return &table[(adr >> PAGE_SHIFT) & 0xff];
+}
+
static void remap_range(void *_start, size_t size, uint32_t flags)
{
- u32 pteentry;
- struct arm_memory *mem;
unsigned long start = (unsigned long)_start;
u32 *p;
int numentries, i;
- for_each_sdram_bank(mem) {
- if (start >= mem->start && start < mem->start + mem->size)
- goto found;
- }
-
- BUG();
- return;
-
-found:
- pteentry = (start - mem->start) >> PAGE_SHIFT;
-
numentries = size >> PAGE_SHIFT;
-
- p = mem->ptes + pteentry;
+ p = find_pte(start);
for (i = 0; i < numentries; i++) {
p[i] &= ~PTE_MASK;
@@ -114,38 +115,39 @@ found:
* remap the memory bank described by mem cachable and
* bufferable
*/
-static int arm_mmu_remap_sdram(struct arm_memory *mem)
+static int arm_mmu_remap_sdram(struct memory_bank *bank)
{
- unsigned long phys = (unsigned long)mem->start;
+ unsigned long phys = (unsigned long)bank->start;
unsigned long ttb_start = phys >> 20;
- unsigned long ttb_end = (phys + mem->size) >> 20;
- unsigned long num_ptes = mem->size >> 10;
+ unsigned long ttb_end = (phys + bank->size) >> 20;
+ unsigned long num_ptes = bank->size >> 10;
int i, pte;
+ u32 *ptes;
debug("remapping SDRAM from 0x%08lx (size 0x%08lx)\n",
- phys, mem->size);
+ phys, bank->size);
/*
* We replace each 1MiB section in this range with second level page
* tables, therefore we must have 1Mib aligment here.
*/
- if ((phys & (SZ_1M - 1)) || (mem->size & (SZ_1M - 1)))
+ if ((phys & (SZ_1M - 1)) || (bank->size & (SZ_1M - 1)))
return -EINVAL;
- mem->ptes = memalign(0x400, num_ptes * sizeof(u32));
+ ptes = memalign(0x400, num_ptes * sizeof(u32));
debug("ptes: 0x%p ttb_start: 0x%08lx ttb_end: 0x%08lx\n",
- mem->ptes, ttb_start, ttb_end);
+ ptes, ttb_start, ttb_end);
for (i = 0; i < num_ptes; i++) {
- mem->ptes[i] = (phys + i * 4096) | PTE_TYPE_SMALL |
+ ptes[i] = (phys + i * 4096) | PTE_TYPE_SMALL |
PTE_FLAGS_CACHED;
}
pte = 0;
for (i = ttb_start; i < ttb_end; i++) {
- ttb[i] = (unsigned long)(&mem->ptes[pte]) | PMD_TYPE_TABLE |
+ ttb[i] = (unsigned long)(&ptes[pte]) | PMD_TYPE_TABLE |
(0 << 4);
pte += 256;
}
@@ -209,7 +211,7 @@ static void vectors_init(void)
*/
static int mmu_init(void)
{
- struct arm_memory *mem;
+ struct memory_bank *bank;
int i;
ttb = memalign(0x10000, 0x4000);
@@ -234,8 +236,8 @@ static int mmu_init(void)
* This is to speed up the generation of 2nd level page tables
* below
*/
- for_each_sdram_bank(mem)
- create_section(mem->start, mem->start, mem->size >> 20,
+ for_each_memory_bank(bank)
+ create_section(bank->start, bank->start, bank->size >> 20,
PMD_SECT_DEF_CACHED);
asm volatile (
@@ -249,8 +251,8 @@ static int mmu_init(void)
* Now that we have the MMU and caches on remap sdram again using
* page tables
*/
- for_each_sdram_bank(mem)
- arm_mmu_remap_sdram(mem);
+ for_each_memory_bank(bank)
+ arm_mmu_remap_sdram(bank);
return 0;
}
diff --git a/arch/arm/include/asm/armlinux.h b/arch/arm/include/asm/armlinux.h
index bb25f9a87d..ba3a424e26 100644
--- a/arch/arm/include/asm/armlinux.h
+++ b/arch/arm/include/asm/armlinux.h
@@ -31,7 +31,4 @@ struct image_data;
void start_linux(void *adr, int swap, struct image_data *data);
-struct device_d *arm_add_mem_device(const char* name, resource_size_t start,
- resource_size_t size);
-
#endif /* __ARCH_ARMLINUX_H */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index e8e82f6f8b..ab78be3848 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -1,53 +1,6 @@
-/*
- * linux/include/asm-arm/io.h
- *
- * Copyright (C) 1996-2000 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Modifications:
- * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both
- * constant addresses and variable addresses.
- * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture
- * specific IO header files.
- * 27-Mar-1999 PJB Second parameter of memcpy_toio is const..
- * 04-Apr-1999 PJB Added check_signature.
- * 12-Dec-1999 RMK More cleanups
- * 18-Jun-2000 RMK Removed virt_to_* and friends definitions
- */
-
-/**
- * @file
- * @brief ARM IO access functions
- */
-
#ifndef __ASM_ARM_IO_H
#define __ASM_ARM_IO_H
-#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
-#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
-#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
-
-#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
-#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
-#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
-
-#define writeb(v,a) __raw_writeb(v,a)
-#define writew(v,a) __raw_writew(v,a)
-#define writel(v,a) __raw_writel(v,a)
-
-#define readb(a) __raw_readb(a)
-#define readw(a) __raw_readw(a)
-#define readl(a) __raw_readl(a)
-
-/* for the ARM architecture the string functions are library based */
-extern void writesb(void __iomem*, const void*, int);
-extern void writesw(void __iomem*, const void*, int);
-extern void writesl(void __iomem*, const void*, int);
-extern void readsb(const void __iomem*, void*, int);
-extern void readsw(const void __iomem*, void*, int);
-extern void readsl(const void __iomem*, void*, int);
+#include <asm-generic/io.h>
#endif /* __ASM_ARM_IO_H */
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 93c2fe6007..28afaa39e4 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -1,18 +1,12 @@
#ifndef __ASM_ARM_MEMORY_H
#define __ASM_ARM_MEMORY_H
-struct arm_memory {
- struct list_head list;
- struct device_d *dev;
- u32 *ptes;
- unsigned long start;
- unsigned long size;
-};
+#include <memory.h>
-extern struct list_head memory_list;
-
-void armlinux_add_dram(struct device_d *dev);
-
-#define for_each_sdram_bank(mem) list_for_each_entry(mem, &memory_list, list)
+static inline void arm_add_mem_device(const char* name, resource_size_t start,
+ resource_size_t size)
+{
+ barebox_add_memory_bank(name, start, size);
+}
#endif /* __ASM_ARM_MEMORY_H */
diff --git a/arch/arm/lib/arm.c b/arch/arm/lib/arm.c
index 6549118b83..c85aae14a0 100644
--- a/arch/arm/lib/arm.c
+++ b/arch/arm/lib/arm.c
@@ -1,6 +1,6 @@
#include <common.h>
#include <init.h>
-#include <mem_malloc.h>
+#include <memory.h>
#include <asm/barebox-arm.h>
#include <asm-generic/memory_layout.h>
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index 5bdbb92bff..e3a74f4ffb 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -35,13 +35,13 @@
#include <malloc.h>
#include <fcntl.h>
#include <errno.h>
+#include <memory.h>
#include <asm/byteorder.h>
#include <asm/setup.h>
#include <asm/barebox-arm.h>
#include <asm/armlinux.h>
#include <asm/system.h>
-#include <asm/memory.h>
static struct tag *params;
static int armlinux_architecture = 0;
@@ -66,14 +66,14 @@ static void setup_start_tag(void)
static void setup_memory_tags(void)
{
- struct arm_memory *mem;
+ struct memory_bank *bank;
- for_each_sdram_bank(mem) {
+ for_each_memory_bank(bank) {
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size(tag_mem32);
- params->u.mem.start = mem->dev->resource[0].start;
- params->u.mem.size = mem->dev->resource[0].size;
+ params->u.mem.start = bank->start;
+ params->u.mem.size = bank->size;
params = tag_next(params);
}
@@ -186,7 +186,14 @@ void armlinux_set_bootparams(void *params)
void armlinux_set_architecture(int architecture)
{
+ char *arch_number = asprintf("%d", architecture);
+
armlinux_architecture = architecture;
+
+ setenv("arch_number", arch_number);
+ export("arch_number");
+
+ kfree(arch_number);
}
void armlinux_set_revision(unsigned int rev)
diff --git a/arch/arm/lib/bootz.c b/arch/arm/lib/bootz.c
index 13bed25aeb..fc14487bfa 100644
--- a/arch/arm/lib/bootz.c
+++ b/arch/arm/lib/bootz.c
@@ -9,6 +9,7 @@
#include <asm/armlinux.h>
#include <asm/system.h>
#include <asm-generic/memory_layout.h>
+#include <memory.h>
struct zimage_header {
u32 unused[9];
@@ -26,7 +27,7 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[])
void *zimage;
u32 end;
int usemap = 0;
- struct arm_memory *mem = list_first_entry(&memory_list, struct arm_memory, list);
+ struct memory_bank *bank = list_first_entry(&memory_banks, struct memory_bank, list);
if (argc != 2) {
barebox_cmd_usage(cmdtp);
@@ -44,8 +45,8 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[])
* the first 128MB of SDRAM.
*/
zimage = memmap(fd, PROT_READ);
- if (zimage && (unsigned long)zimage >= mem->start &&
- (unsigned long)zimage < mem->start + SZ_128M) {
+ if (zimage && (unsigned long)zimage >= bank->start &&
+ (unsigned long)zimage < bank->start + SZ_128M) {
usemap = 1;
header = zimage;
}
@@ -78,11 +79,11 @@ static int do_bootz(struct command *cmdtp, int argc, char *argv[])
end = swab32(end);
if (!usemap) {
- if (mem->size <= SZ_128M) {
+ if (bank->size <= SZ_128M) {
zimage = xmalloc(end);
} else {
- zimage = (void *)mem->start + SZ_8M;
- if (mem->start + SZ_8M + end >= MALLOC_BASE) {
+ zimage = (void *)bank->start + SZ_8M;
+ if (bank->start + SZ_8M + end >= MALLOC_BASE) {
printf("won't overwrite malloc space with image\n");
goto err_out1;
}
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index ee46002819..2ac23b5f19 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -14,6 +14,9 @@ config BOARDINFO
default "Atmel at91sam9g20-ek" if MACH_AT91SAM9G20EK
default "Atmel at91sam9m10g45-ek" if MACH_AT91SAM9M10G45EK
default "Bucyrus MMC-CPU" if MACH_MMCCPU
+ default "Calao USB-A9260" if MACH_USB_A9260
+ default "Calao USB-A9263" if MACH_USB_A9263
+ default "Calao USB-A9G20" if MACH_USB_A9G20
default "Ronetix PM9261" if MACH_PM9261
default "Ronetix PM9263" if MACH_PM9263
default "Ronetix PM9G45" if MACH_PM9G45
@@ -96,6 +99,12 @@ config MACH_AT91SAM9260EK
help
Say y here if you are using Atmel's AT91SAM9260-EK Evaluation board
+config MACH_USB_A9260
+ bool "CALAO USB-A9260"
+ help
+ Select this if you are using a Calao Systems USB-A9260.
+ <http://www.calao-systems.com>
+
endchoice
endif
@@ -160,6 +169,12 @@ config MACH_AT91SAM9G20EK
Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit
that embeds only one SD/MMC slot.
+config MACH_USB_A9G20
+ bool "CALAO USB-A9G20"
+ help
+ Select this if you are using a Calao Systems USB-A9G20.
+ <http://www.calao-systems.com>
+
endchoice
endif
@@ -189,6 +204,12 @@ config MACH_PM9263
help
Say y here if you are using the Ronetix PM9263 Board
+config MACH_USB_A9263
+ bool "CALAO USB-A9263"
+ help
+ Select this if you are using a Calao Systems USB-A9263.
+ <http://www.calao-systems.com>
+
endchoice
endif
@@ -234,6 +255,12 @@ config AT91_HAVE_2MMC
with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and
onwards.
+config AT91_HAVE_SRAM_128M
+ bool "Have 128 of ram"
+ depends on MACH_USB_A9G20 || MACH_USB_A9263
+ help
+ Select this if you board have 128 MiB of Ram (as USB_A9G20 C11)
+
choice
prompt "LCD type"
depends on MACH_AT91SAM9M10G45EK
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 453c10a5de..bd7d3f05e4 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -26,6 +26,24 @@ void at91_add_device_sdram(u32 size)
}
/* --------------------------------------------------------------------
+ * USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI)
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
+{
+ if (!data)
+ return;
+
+ add_generic_device("at91_ohci", -1, NULL, AT91RM9200_UHP_BASE, 1024 * 1024,
+ IORESOURCE_MEM, data);
+}
+#else
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
* Ethernet
* -------------------------------------------------------------------- */
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index 92b9e663a4..b6e7f552e1 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -37,7 +37,7 @@
#include <mach/at91_st.h>
#include <mach/at91_pmc.h>
#include <mach/io.h>
-#include <asm/io.h>
+#include <io.h>
/*
* The ST_CRTR is updated asynchronously to the master clock ... but
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 44d3f1e989..9d1acda7fe 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -26,6 +26,19 @@ void at91_add_device_sdram(u32 size)
arm_add_mem_device("ram0", AT91_CHIPSELECT_1, size);
}
+#if defined(CONFIG_USB_OHCI)
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
+{
+ if (!data)
+ return;
+
+ add_generic_device("at91_ohci", -1, NULL, AT91SAM9260_UHP_BASE, 1024 * 1024,
+ IORESOURCE_MEM, data);
+}
+#else
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
+#endif
+
#if defined(CONFIG_DRIVER_NET_MACB)
void at91_add_device_eth(struct at91_ether_platform_data *data)
{
@@ -63,6 +76,19 @@ void at91_add_device_eth(struct at91_ether_platform_data *data) {}
#endif
#if defined(CONFIG_NAND_ATMEL)
+static struct resource nand_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_3,
+ .size = SZ_256M,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .size = 512,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
void at91_add_device_nand(struct atmel_nand_data *data)
{
unsigned long csa;
@@ -85,8 +111,8 @@ void at91_add_device_nand(struct atmel_nand_data *data)
if (data->det_pin)
at91_set_gpio_input(data->det_pin, 1);
- add_generic_device("atmel_nand", 0, NULL, AT91_CHIPSELECT_3, 0x10,
- IORESOURCE_MEM, data);
+ add_generic_device_res("atmel_nand", 0, nand_resources,
+ ARRAY_SIZE(nand_resources), data);
}
#else
void at91_add_device_nand(struct atmel_nand_data *data) {}
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index c6a3dba901..3f69b1886c 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -26,6 +26,23 @@ void at91_add_device_sdram(u32 size)
arm_add_mem_device("ram0", AT91_CHIPSELECT_1, size);
}
+/* --------------------------------------------------------------------
+ * USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI)
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
+{
+ if (!data)
+ return;
+
+ add_generic_device("at91_ohci", -1, NULL, AT91SAM9261_UHP_BASE, 1024 * 1024,
+ IORESOURCE_MEM, data);
+}
+#else
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
+#endif
+
#if defined(CONFIG_NAND_ATMEL)
void at91_add_device_nand(struct atmel_nand_data *data)
{
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index c7ae45ad30..994a975cf9 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -26,6 +26,31 @@ void at91_add_device_sdram(u32 size)
arm_add_mem_device("ram0", AT91_CHIPSELECT_1, size);
}
+/* --------------------------------------------------------------------
+ * USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI)
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
+{
+ int i;
+
+ if (!data)
+ return;
+
+ /* Enable VBus control for UHP ports */
+ for (i = 0; i < data->ports; i++) {
+ if (data->vbus_pin[i])
+ at91_set_gpio_output(data->vbus_pin[i], 0);
+ }
+
+ add_generic_device("at91_ohci", -1, NULL, AT91SAM9263_UHP_BASE, 1024 * 1024,
+ IORESOURCE_MEM, data);
+}
+#else
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
+#endif
+
#if defined(CONFIG_DRIVER_NET_MACB)
void at91_add_device_eth(struct at91_ether_platform_data *data)
{
@@ -62,6 +87,19 @@ void at91_add_device_eth(struct at91_ether_platform_data *data) {}
#endif
#if defined(CONFIG_NAND_ATMEL)
+static struct resource nand_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_3,
+ .size = SZ_256M,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC0,
+ .size = 512,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
void at91_add_device_nand(struct atmel_nand_data *data)
{
unsigned long csa;
@@ -84,8 +122,8 @@ void at91_add_device_nand(struct atmel_nand_data *data)
if (data->det_pin)
at91_set_gpio_input(data->det_pin, 1);
- add_generic_device("atmel_nand", -1, NULL, AT91_CHIPSELECT_3, 0x10,
- IORESOURCE_MEM, data);
+ add_generic_device_res("atmel_nand", -1, nand_resources,
+ ARRAY_SIZE(nand_resources), data);
}
#else
void at91_add_device_nand(struct atmel_nand_data *data) {}
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 7a1d6dd2f4..7ca2ef4f48 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -37,7 +37,7 @@
#include <mach/at91_pmc.h>
#include <mach/at91_rstc.h>
#include <mach/io.h>
-#include <asm/io.h>
+#include <io.h>
uint64_t at91sam9_clocksource_read(void)
{
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 022f3e1875..1d47dcfa10 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -26,6 +26,31 @@ void at91_add_device_sdram(u32 size)
arm_add_mem_device("ram0", AT91_CHIPSELECT_6, size);
}
+/* --------------------------------------------------------------------
+ * USB Host (OHCI)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI)
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
+{
+ int i;
+
+ if (!data)
+ return;
+
+ /* Enable VBus control for UHP ports */
+ for (i = 0; i < data->ports; i++) {
+ if (data->vbus_pin[i])
+ at91_set_gpio_output(data->vbus_pin[i], 0);
+ }
+
+ add_generic_device("at91_ohci", -1, NULL, AT91SAM9G45_OHCI_BASE, 1024 * 1024,
+ IORESOURCE_MEM, data);
+}
+#else
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
+#endif
+
#if defined(CONFIG_DRIVER_NET_MACB)
void at91_add_device_eth(struct at91_ether_platform_data *data)
{
@@ -63,6 +88,19 @@ void at91_add_device_eth(struct at91_ether_platform_data *data) {}
#endif
#if defined(CONFIG_NAND_ATMEL)
+static struct resource nand_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_3,
+ .size = SZ_256M,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .size = 512,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
void at91_add_device_nand(struct atmel_nand_data *data)
{
unsigned long csa;
@@ -70,9 +108,6 @@ void at91_add_device_nand(struct atmel_nand_data *data)
if (!data)
return;
- data->ecc_base = (void __iomem *)(AT91_BASE_SYS + AT91_ECC);
- data->ecc_mode = NAND_ECC_HW;
-
csa = at91_sys_read(AT91_MATRIX_EBICSA);
at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
@@ -88,8 +123,8 @@ void at91_add_device_nand(struct atmel_nand_data *data)
if (data->det_pin)
at91_set_gpio_input(data->det_pin, 1);
- add_generic_device("atmel_nand", -1, NULL, AT91_CHIPSELECT_3, 0x10,
- IORESOURCE_MEM, data);
+ add_generic_device_res("atmel_nand", -1, nand_resources,
+ ARRAY_SIZE(nand_resources), data);
}
#else
void at91_add_device_nand(struct atmel_nand_data *data) {}
@@ -256,3 +291,44 @@ void at91_add_device_mci(short mmc_id, struct atmel_mci_platform_data *data)
void at91_add_device_mci(short mmc_id, struct atmel_mci_platform_data *data) {}
#endif
+#if defined(CONFIG_DRIVER_SPI_ATMEL)
+/* SPI */
+void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata)
+{
+ int i;
+ int cs_pin;
+ resource_size_t start;
+
+ for (i = 0; i < pdata->num_chipselect; i++) {
+ cs_pin = pdata->chipselect[i];
+
+ /* enable chip-select pin */
+ if (cs_pin > 0)
+ at91_set_gpio_output(cs_pin, 1);
+ }
+
+ /* Configure SPI bus(es) */
+ if (spi_id == 0) {
+ start = AT91SAM9G45_BASE_SPI0;
+ at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */
+ at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */
+ at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */
+
+ add_generic_device("atmel_spi", spi_id, NULL, start, SZ_16K,
+ IORESOURCE_MEM, pdata);
+ }
+
+ else if (spi_id == 1) {
+ start = AT91SAM9G45_BASE_SPI1;
+ at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */
+ at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */
+ at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */
+
+ add_generic_device("atmel_spi", spi_id, NULL, start, SZ_16K,
+ IORESOURCE_MEM, pdata);
+ }
+}
+
+#else
+void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata) {}
+#endif
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 528994f630..0406382daf 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -530,11 +530,12 @@ static void at91_upll_usbfs_clock_init(unsigned long main_clock)
/* Now set uhpck values */
uhpck.parent = &utmi_clk;
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
- uhpck.rate_hz = utmi_clk.parent->rate_hz;
+ uhpck.rate_hz = utmi_clk.rate_hz;
uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
}
static int pll_overclock = 0;
+static u32 cpu_freq = 0;
int at91_clock_init(unsigned long main_clock)
{
@@ -622,6 +623,8 @@ int at91_clock_init(unsigned long main_clock)
mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
}
+ cpu_freq = freq;
+
/* Register the PMC's standard clocks */
for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
at91_clk_add(standard_pmc_clocks[i]);
@@ -649,8 +652,8 @@ static int at91_clock_display(void)
if (pll_overclock)
pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
- printf("Clocks: CPU %lu MHz, master %u MHz, main %u.%03u MHz\n",
- mck.parent->rate_hz / 1000000, (unsigned) mck.rate_hz / 1000000,
+ printf("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n",
+ cpu_freq / 1000000, (unsigned) mck.rate_hz / 1000000,
(unsigned) main_clk.rate_hz / 1000000,
((unsigned) main_clk.rate_hz % 1000000) / 1000);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index b257128da6..c34df0520e 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -24,7 +24,7 @@
#include <common.h>
#include <linux/clk.h>
#include <errno.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/gpio.h>
#include <gpio.h>
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index 89caebb9c2..546fe90e82 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -22,13 +22,20 @@
#define __ASM_ARCH_BOARD_H
#include <net.h>
+#include <spi/spi.h>
#include <linux/mtd/mtd.h>
+ /* USB Host */
+struct at91_usbh_data {
+ u8 ports; /* number of ports on root hub */
+ u8 vbus_pin[2]; /* port power-control pin */
+};
+extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
+
void atmel_nand_load_image(void *dest, int size, int pagesize, int blocksize);
/* NAND / SmartMedia */
struct atmel_nand_data {
- void __iomem *ecc_base;
u8 enable_pin; /* chip enable */
u8 det_pin; /* card detect */
u8 rdy_pin; /* ready/busy */
@@ -75,4 +82,12 @@ struct atmel_mci_platform_data {
};
void at91_add_device_mci(short mmc_id, struct atmel_mci_platform_data *data);
+
+/* SPI Master platform data */
+struct at91_spi_platform_data {
+ int *chipselect; /* array of gpio_pins */
+ int num_chipselect; /* chipselect array entry count */
+};
+
+void at91_add_device_spi(int spi_id, struct at91_spi_platform_data *pdata);
#endif
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index 7e1a9a8acd..f3239f5f42 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_AT91_GPIO_H
#define __ASM_ARCH_AT91_GPIO_H
-#include <asm/io.h>
+#include <io.h>
#include <asm-generic/errno.h>
#include <mach/at91_pio.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-at91/include/mach/io.h b/arch/arm/mach-at91/include/mach/io.h
index f09b2df0e3..7b0cd9dcbb 100644
--- a/arch/arm/mach-at91/include/mach/io.h
+++ b/arch/arm/mach-at91/include/mach/io.h
@@ -21,7 +21,7 @@
#ifndef __ASM_ARCH_IO_H
#define __ASM_ARCH_IO_H
-#include <asm/io.h>
+#include <io.h>
static inline unsigned int at91_sys_read(unsigned int reg_offset)
{
diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c
index 3e7de2fc58..c397fe46b5 100644
--- a/arch/arm/mach-at91/sam9_smc.c
+++ b/arch/arm/mach-at91/sam9_smc.c
@@ -9,7 +9,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
#include <mach/io.h>
diff --git a/arch/arm/mach-ep93xx/clocksource.c b/arch/arm/mach-ep93xx/clocksource.c
index b500948968..ce8a29fee7 100644
--- a/arch/arm/mach-ep93xx/clocksource.c
+++ b/arch/arm/mach-ep93xx/clocksource.c
@@ -23,7 +23,7 @@
#include <common.h>
#include <init.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/ep93xx-regs.h>
#define TIMER_CLKSEL (1 << 3)
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index 5d57434031..f4def289e4 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -20,7 +20,7 @@
#include <common.h>
#include <errno.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/ep93xx-regs.h>
#define EP93XX_GPIO_NUM_PORTS 8
diff --git a/arch/arm/mach-ep93xx/led.c b/arch/arm/mach-ep93xx/led.c
index 6d6b90235f..91f33d1aea 100644
--- a/arch/arm/mach-ep93xx/led.c
+++ b/arch/arm/mach-ep93xx/led.c
@@ -21,7 +21,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/ep93xx-regs.h>
#define GREEN_LED_POS 0x01
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 8dc6a24fb5..8d5bd744e8 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -497,6 +497,12 @@ config IMX_IIM
Device driver for the IC Identification Module (IIM) fusebox. Use the
regular md/mw commands to program and read the fusebox.
+ Fuses are grouped in "rows", 8 bits per row. When using md/mw commands,
+ employ the -b switch and consider the region to be specifying the "Fuse
+ Row Index" rather than "Fuse Row Offset" (which is FRI * 4). You should
+ consult the documentation for your chip for more elaborate description,
+ including the eFuse map, e.g. see AN3682 for i.MX25.
+
config IMX_IIM_FUSE_BLOW
bool "IIM fuses blow support"
depends on IMX_IIM
@@ -507,6 +513,10 @@ config IMX_IIM_FUSE_BLOW
Warning: blown fuses can not be unblown. Using this option may damage
your CPU, or make it unbootalbe. Use with care.
+ Before being actually able to blow the fuses, you need to explicitely
+ enable it:
+ imx_iim0.permanent_write_enable=1
+
endmenu
endif
diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c
index 8482b60f40..f13d956bf1 100644
--- a/arch/arm/mach-imx/boot.c
+++ b/arch/arm/mach-imx/boot.c
@@ -19,7 +19,7 @@
#include <environment.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#if defined(CONFIG_ARCH_IMX25) || defined(CONFIG_ARCH_IMX35)
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index 5397da03d7..4f5895c2a5 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -35,7 +35,7 @@
#include <notifier.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
-#include <asm/io.h>
+#include <io.h>
#define GPT(x) __REG(IMX_TIM1_BASE + (x))
#define timer_base (IMX_TIM1_BASE)
diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c
index 0a3e0461eb..fdee20b865 100644
--- a/arch/arm/mach-imx/gpio.c
+++ b/arch/arm/mach-imx/gpio.c
@@ -25,7 +25,7 @@
#include <common.h>
#include <errno.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <mach/gpio.h>
diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c
index ca89710329..f2ace8aa0f 100644
--- a/arch/arm/mach-imx/iim.c
+++ b/arch/arm/mach-imx/iim.c
@@ -25,7 +25,7 @@
#include <fcntl.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/iim.h>
@@ -51,8 +51,8 @@ static int do_fuse_sense(void __iomem *reg_base, unsigned int bank,
return -EINVAL;
}
- if (row > 0x3ff) {
- printf("%s: invalid row offset\n", __func__);
+ if (row > 255) {
+ printf("%s: invalid row index\n", __func__);
return -EINVAL;
}
@@ -61,8 +61,8 @@ static int do_fuse_sense(void __iomem *reg_base, unsigned int bank,
writeb(0xfe, reg_base + IIM_ERR);
/* upper and lower address halves */
- writeb((bank << 3) | (row >> 7), reg_base + IIM_UA);
- writeb((row << 1) & 0xf8, reg_base + IIM_LA);
+ writeb((bank << 3) | (row >> 5), reg_base + IIM_UA);
+ writeb((row << 3) & 0xf8, reg_base + IIM_LA);
/* start fuse sensing */
writeb(0x08, reg_base + IIM_FCTL);
@@ -100,7 +100,7 @@ static ssize_t imx_iim_cdev_read(struct cdev *cdev, void *buf, size_t count,
int row_val;
row_val = do_fuse_sense(priv->base,
- priv->bank, (offset + i) * 4);
+ priv->bank, offset + i);
if (row_val < 0)
return row_val;
((u8 *)buf)[i] = (u8)row_val;
@@ -125,8 +125,8 @@ static int do_fuse_blow(void __iomem *reg_base, unsigned int bank,
return -EINVAL;
}
- if (row > 0x3ff) {
- printf("%s: invalid row offset\n", __func__);
+ if (row > 255) {
+ printf("%s: invalid row index\n", __func__);
return -EINVAL;
}
@@ -138,14 +138,14 @@ static int do_fuse_blow(void __iomem *reg_base, unsigned int bank,
writeb(0xaa, reg_base + IIM_PREG_P);
/* upper half address register */
- writeb((bank << 3) | (row >> 7), reg_base + IIM_UA);
+ writeb((bank << 3) | (row >> 5), reg_base + IIM_UA);
for (bit = 0; bit < 8; bit++) {
if (((value >> bit) & 1) == 0)
continue;
/* lower half address register */
- writeb(((row << 1) | bit), reg_base + IIM_LA);
+ writeb(((row << 3) | bit), reg_base + IIM_LA);
/* start fuse programing */
writeb(0x71, reg_base + IIM_FCTL);
@@ -193,7 +193,7 @@ static ssize_t imx_iim_cdev_write(struct cdev *cdev, const void *buf, size_t cou
int ret;
ret = do_fuse_blow(priv->base, priv->bank,
- (offset + i) * 4, ((u8 *)buf)[i]);
+ offset + i, ((u8 *)buf)[i]);
if (ret < 0)
return ret;
}
diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c
index 75ec8c7f45..19a2909e18 100644
--- a/arch/arm/mach-imx/imx25.c
+++ b/arch/arm/mach-imx/imx25.c
@@ -19,7 +19,7 @@
#include <init.h>
#include <mach/imx-regs.h>
#include <mach/iim.h>
-#include <asm/io.h>
+#include <io.h>
#include <sizes.h>
#include "gpio.h"
diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c
index c846260682..381a564580 100644
--- a/arch/arm/mach-imx/imx35.c
+++ b/arch/arm/mach-imx/imx35.c
@@ -18,7 +18,7 @@
#include <common.h>
#include <sizes.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <mach/iim.h>
#include <mach/generic.h>
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index a42ff41400..2c1efed150 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -19,7 +19,7 @@
#include <common.h>
#include <sizes.h>
#include <environment.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx51-regs.h>
#include "gpio.h"
diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index 7a822c2c85..8fb64bb96a 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -17,7 +17,7 @@
#include <init.h>
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <sizes.h>
#include <mach/imx53-regs.h>
diff --git a/arch/arm/mach-imx/include/mach/clock-imx51_53.h b/arch/arm/mach-imx/include/mach/clock-imx51_53.h
index 34ca1bb94f..1e90d21d4a 100644
--- a/arch/arm/mach-imx/include/mach/clock-imx51_53.h
+++ b/arch/arm/mach-imx/include/mach/clock-imx51_53.h
@@ -606,6 +606,10 @@
#define MX5_PLL_DP_MFD_665 (96 - 1)
#define MX5_PLL_DP_MFN_665 89
+#define MX5_PLL_DP_OP_600 ((6 << 4) + ((1 - 1) << 0))
+#define MX5_PLL_DP_MFD_600 (4 - 1)
+#define MX5_PLL_DP_MFN_600 1
+
#define MX5_PLL_DP_OP_532 ((5 << 4) + ((1 - 1) << 0))
#define MX5_PLL_DP_MFD_532 (24 - 1)
#define MX5_PLL_DP_MFN_532 13
diff --git a/arch/arm/mach-imx/include/mach/clock.h b/arch/arm/mach-imx/include/mach/clock.h
index 5b590a251e..10821782fe 100644
--- a/arch/arm/mach-imx/include/mach/clock.h
+++ b/arch/arm/mach-imx/include/mach/clock.h
@@ -29,6 +29,7 @@ ulong imx_get_uartclk(void);
ulong imx_get_lcdclk(void);
ulong imx_get_i2cclk(void);
ulong imx_get_mmcclk(void);
+ulong imx_get_cspiclk(void);
int imx_clko_set_div(int div);
void imx_clko_set_src(int src);
diff --git a/arch/arm/mach-imx/include/mach/devices-imx25.h b/arch/arm/mach-imx/include/mach/devices-imx25.h
index 87f5ba0e5e..eff59773f7 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx25.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx25.h
@@ -6,6 +6,11 @@ static inline struct device_d *imx25_add_i2c0(struct i2c_platform_data *pdata)
return imx_add_i2c((void *)IMX_I2C1_BASE, 0, pdata);
}
+static inline struct device_d *imx25_add_spi0(struct spi_imx_master *pdata)
+{
+ return imx_add_spi((void *)IMX_CSPI1_BASE, 0, pdata);
+}
+
static inline struct device_d *imx25_add_uart0(void)
{
return imx_add_uart((void *)IMX_UART1_BASE, 0);
diff --git a/arch/arm/mach-imx/include/mach/devices-imx51.h b/arch/arm/mach-imx/include/mach/devices-imx51.h
index a5deb5c863..54ea647461 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx51.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx51.h
@@ -1,5 +1,6 @@
#include <mach/devices.h>
+#include <sizes.h>
static inline struct device_d *imx51_add_spi0(struct spi_imx_master *pdata)
{
@@ -53,6 +54,28 @@ static inline struct device_d *imx51_add_mmc1(void *pdata)
static inline struct device_d *imx51_add_nand(struct imx_nand_platform_data *pdata)
{
- return imx_add_nand((void *)MX51_NFC_AXI_BASE_ADDR, pdata);
+ struct resource res[] = {
+ {
+ .start = MX51_NFC_BASE_ADDR,
+ .size = SZ_4K,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX51_NFC_AXI_BASE_ADDR,
+ .size = SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+ struct device_d *dev = xzalloc(sizeof(*dev));
+
+ dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res));
+ memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res));
+ dev->num_resources = ARRAY_SIZE(res);
+ strcpy(dev->name, "imx_nand");
+ dev->id = -1;
+ dev->platform_data = pdata;
+
+ register_device(dev);
+
+ return dev;
}
diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h
index 78ec0cdbf1..73307c452e 100644
--- a/arch/arm/mach-imx/include/mach/imx25-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx25-regs.h
@@ -47,6 +47,7 @@
#define IMX_NFC_BASE 0xBB000000
#define IMX_FEC_BASE 0x50038000
#define IMX_I2C1_BASE 0x43F80000
+#define IMX_CSPI1_BASE 0x43FA4000
/*
* Clock Controller Module (CCM)
diff --git a/arch/arm/mach-imx/include/mach/imx51-regs.h b/arch/arm/mach-imx/include/mach/imx51-regs.h
index 2e6cacb5bf..c6d14cdc6b 100644
--- a/arch/arm/mach-imx/include/mach/imx51-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx51-regs.h
@@ -12,6 +12,16 @@
#define GPT_TCN 0x24
#define GPT_TSTAT 0x08
+/* WEIM registers */
+#define WEIM_CSxGCR1(n) (((n) * 0x18) + 0x00)
+#define WEIM_CSxGCR2(n) (((n) * 0x18) + 0x04)
+#define WEIM_CSxRCR1(n) (((n) * 0x18) + 0x08)
+#define WEIM_CSxRCR2(n) (((n) * 0x18) + 0x0c)
+#define WEIM_CSxWCR1(n) (((n) * 0x18) + 0x10)
+#define WEIM_WCR 0x90
+#define WEIM_WIAR 0x94
+#define WEIM_EAR 0x98
+
/* Part 2: Bitfields */
#define TCTL_SWR (1<<15) /* Software reset */
#define TCTL_FRR (1<<9) /* Freerun / restart */
@@ -134,4 +144,3 @@
#define MX51_CHIP_REV_3_2 0x32
#endif /* __MACH_IMX51_REGS_H */
-
diff --git a/arch/arm/mach-imx/internal-nand-boot.c b/arch/arm/mach-imx/internal-nand-boot.c
index 0d71b99f92..c55a0e7682 100644
--- a/arch/arm/mach-imx/internal-nand-boot.c
+++ b/arch/arm/mach-imx/internal-nand-boot.c
@@ -17,7 +17,7 @@
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <linux/mtd/nand.h>
#include <mach/imx-nand.h>
#include <mach/generic.h>
diff --git a/arch/arm/mach-imx/iomux-v2.c b/arch/arm/mach-imx/iomux-v2.c
index abb2ebe195..1b49ccb328 100644
--- a/arch/arm/mach-imx/iomux-v2.c
+++ b/arch/arm/mach-imx/iomux-v2.c
@@ -18,7 +18,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <mach/iomux-mx31.h>
diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c
index a74f942509..bb2307a370 100644
--- a/arch/arm/mach-imx/iomux-v3.c
+++ b/arch/arm/mach-imx/iomux-v3.c
@@ -19,7 +19,7 @@
* MA 02110-1301, USA.
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/iomux-v3.h>
#include <mach/imx-regs.h>
diff --git a/arch/arm/mach-imx/nand.c b/arch/arm/mach-imx/nand.c
index c52b8b06c2..fcbb85ef68 100644
--- a/arch/arm/mach-imx/nand.c
+++ b/arch/arm/mach-imx/nand.c
@@ -17,7 +17,7 @@
#include <common.h>
#include <mach/imx-regs.h>
-#include <asm/io.h>
+#include <io.h>
#if defined(CONFIG_ARCH_IMX35) || defined (CONFIG_ARCH_IMX25)
diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c
index 68b50e943b..f6dcacb71b 100644
--- a/arch/arm/mach-imx/speed-imx25.c
+++ b/arch/arm/mach-imx/speed-imx25.c
@@ -1,6 +1,6 @@
#include <common.h>
#include <mach/imx-regs.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/clock.h>
#include <init.h>
@@ -87,6 +87,11 @@ unsigned long imx_get_mmcclk(void)
return imx_get_perclk(3);
}
+unsigned long imx_get_cspiclk(void)
+{
+ return imx_get_ipgclk();
+}
+
void imx_dump_clocks(void)
{
printf("mpll: %10ld Hz\n", imx_get_mpllclk());
diff --git a/arch/arm/mach-imx/speed-imx31.c b/arch/arm/mach-imx/speed-imx31.c
index 32a517d724..d3f168c4ae 100644
--- a/arch/arm/mach-imx/speed-imx31.c
+++ b/arch/arm/mach-imx/speed-imx31.c
@@ -16,7 +16,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
#include <init.h>
diff --git a/arch/arm/mach-imx/speed-imx35.c b/arch/arm/mach-imx/speed-imx35.c
index b2a339c6c2..1e1c39ff82 100644
--- a/arch/arm/mach-imx/speed-imx35.c
+++ b/arch/arm/mach-imx/speed-imx35.c
@@ -17,7 +17,7 @@
#include <common.h>
#include <mach/imx-regs.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/clock.h>
#include <mach/generic.h>
#include <init.h>
diff --git a/arch/arm/mach-imx/speed-imx51.c b/arch/arm/mach-imx/speed-imx51.c
index f1fb74c474..643ad8f39b 100644
--- a/arch/arm/mach-imx/speed-imx51.c
+++ b/arch/arm/mach-imx/speed-imx51.c
@@ -1,5 +1,5 @@
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm-generic/div64.h>
#include <mach/imx51-regs.h>
#include <mach/clock-imx51_53.h>
@@ -156,6 +156,11 @@ unsigned long imx_get_fecclk(void)
return imx_get_ipgclk();
}
+unsigned long imx_get_i2cclk(void)
+{
+ return imx_get_ipgclk();
+}
+
unsigned long imx_get_mmcclk(void)
{
u32 reg, prediv, podf, rate;
diff --git a/arch/arm/mach-imx/speed-imx53.c b/arch/arm/mach-imx/speed-imx53.c
index 7b099f5fa6..0d6ac24944 100644
--- a/arch/arm/mach-imx/speed-imx53.c
+++ b/arch/arm/mach-imx/speed-imx53.c
@@ -1,5 +1,5 @@
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm-generic/div64.h>
#include <mach/imx-regs.h>
#include "mach/clock-imx51_53.h"
diff --git a/arch/arm/mach-mxs/clocksource-imx23.c b/arch/arm/mach-mxs/clocksource-imx23.c
index f7c94c1d75..66e534bda3 100644
--- a/arch/arm/mach-mxs/clocksource-imx23.c
+++ b/arch/arm/mach-mxs/clocksource-imx23.c
@@ -23,7 +23,7 @@
#include <notifier.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
-#include <asm/io.h>
+#include <io.h>
#define TIMROTCTRL 0x00
#define TIMCTRL1 0x40
diff --git a/arch/arm/mach-mxs/clocksource-imx28.c b/arch/arm/mach-mxs/clocksource-imx28.c
index 15ae951004..328ca5d023 100644
--- a/arch/arm/mach-mxs/clocksource-imx28.c
+++ b/arch/arm/mach-mxs/clocksource-imx28.c
@@ -18,7 +18,7 @@
#include <notifier.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
-#include <asm/io.h>
+#include <io.h>
#define TIMROTCTRL 0x00
# define TIMROTCTRL_SFTRST
diff --git a/arch/arm/mach-mxs/imx_lcd_clk.c b/arch/arm/mach-mxs/imx_lcd_clk.c
index 65bfc6ee3d..455dfcb9c7 100644
--- a/arch/arm/mach-mxs/imx_lcd_clk.c
+++ b/arch/arm/mach-mxs/imx_lcd_clk.c
@@ -16,7 +16,7 @@
#include <init.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
-#include <asm/io.h>
+#include <io.h>
#ifdef CONFIG_ARCH_IMX23
diff --git a/arch/arm/mach-mxs/iomux-imx.c b/arch/arm/mach-mxs/iomux-imx.c
index bf6165f8d2..3161a5d3cc 100644
--- a/arch/arm/mach-mxs/iomux-imx.c
+++ b/arch/arm/mach-mxs/iomux-imx.c
@@ -21,7 +21,7 @@
#include <init.h>
#include <gpio.h>
#include <errno.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#define HW_PINCTRL_CTRL 0x000
diff --git a/arch/arm/mach-mxs/reset-imx.c b/arch/arm/mach-mxs/reset-imx.c
index b35f796b40..cfb3548f2a 100644
--- a/arch/arm/mach-mxs/reset-imx.c
+++ b/arch/arm/mach-mxs/reset-imx.c
@@ -21,7 +21,7 @@
#include <init.h>
#include <notifier.h>
#include <mach/imx-regs.h>
-#include <asm/io.h>
+#include <io.h>
#define HW_RTC_CTRL 0x000
# define BM_RTC_CTRL_WATCHDOGEN (1 << 4)
diff --git a/arch/arm/mach-mxs/speed-imx23.c b/arch/arm/mach-mxs/speed-imx23.c
index a31139d7a7..b10c78643c 100644
--- a/arch/arm/mach-mxs/speed-imx23.c
+++ b/arch/arm/mach-mxs/speed-imx23.c
@@ -24,7 +24,7 @@
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <mach/generic.h>
#include <mach/clock.h>
diff --git a/arch/arm/mach-mxs/speed-imx28.c b/arch/arm/mach-mxs/speed-imx28.c
index 63c6b0754b..67cdbdf81d 100644
--- a/arch/arm/mach-mxs/speed-imx28.c
+++ b/arch/arm/mach-mxs/speed-imx28.c
@@ -18,7 +18,7 @@
*/
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <mach/generic.h>
#include <mach/clock.h>
diff --git a/arch/arm/mach-mxs/usb.c b/arch/arm/mach-mxs/usb.c
index d232bb6075..b7a93769b7 100644
--- a/arch/arm/mach-mxs/usb.c
+++ b/arch/arm/mach-mxs/usb.c
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#define POWER_CTRL (IMX_POWER_BASE + 0x0)
diff --git a/arch/arm/mach-nomadik/reset.c b/arch/arm/mach-nomadik/reset.c
index d55f278293..6ea74dd6c0 100644
--- a/arch/arm/mach-nomadik/reset.c
+++ b/arch/arm/mach-nomadik/reset.c
@@ -18,7 +18,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
void __noreturn reset_cpu(unsigned long addr)
diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c
index 7de1f391a6..becd36357a 100644
--- a/arch/arm/mach-nomadik/timer.c
+++ b/arch/arm/mach-nomadik/timer.c
@@ -11,7 +11,7 @@
#include <common.h>
#include <init.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
#include <mach/mtu.h>
#include <mach/timex.h>
diff --git a/arch/arm/mach-omap/devices-gpmc-nand.c b/arch/arm/mach-omap/devices-gpmc-nand.c
index 76ceb20024..197d4be418 100644
--- a/arch/arm/mach-omap/devices-gpmc-nand.c
+++ b/arch/arm/mach-omap/devices-gpmc-nand.c
@@ -31,7 +31,7 @@
#include <init.h>
#include <driver.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/silicon.h>
#include <mach/gpmc.h>
diff --git a/arch/arm/mach-omap/gpio.c b/arch/arm/mach-omap/gpio.c
index b0bd805628..142cf524eb 100644
--- a/arch/arm/mach-omap/gpio.c
+++ b/arch/arm/mach-omap/gpio.c
@@ -37,7 +37,7 @@
*/
#include <common.h>
#include <mach/gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <errno.h>
#ifdef CONFIG_ARCH_OMAP3
diff --git a/arch/arm/mach-omap/gpmc.c b/arch/arm/mach-omap/gpmc.c
index 2b9964950d..e8946d7c56 100644
--- a/arch/arm/mach-omap/gpmc.c
+++ b/arch/arm/mach-omap/gpmc.c
@@ -29,7 +29,7 @@
*/
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/silicon.h>
#include <mach/gpmc.h>
#include <mach/sys_info.h>
diff --git a/arch/arm/mach-omap/include/mach/omap3-silicon.h b/arch/arm/mach-omap/include/mach/omap3-silicon.h
index 0e6a45f8fd..67f77476a9 100644
--- a/arch/arm/mach-omap/include/mach/omap3-silicon.h
+++ b/arch/arm/mach-omap/include/mach/omap3-silicon.h
@@ -132,5 +132,8 @@
#define OMAP_SDRC_CS0 0x80000000
#define OMAP_SDRC_CS1 0xA0000000
+/* PRM */
+#define PRM_RSTCTRL_RESET 0x04
+
#endif /* __ASM_ARCH_OMAP3_H */
diff --git a/arch/arm/mach-omap/include/mach/omap_hsmmc.h b/arch/arm/mach-omap/include/mach/omap_hsmmc.h
new file mode 100644
index 0000000000..a15f8e62a2
--- /dev/null
+++ b/arch/arm/mach-omap/include/mach/omap_hsmmc.h
@@ -0,0 +1,28 @@
+/**
+ * @file
+ * @brief This file contains exported structure for OMAP hsmmc
+ *
+ * FileName: include/asm-arm/arch-omap/omap_hsmmc.h
+ *
+ * OMAP3 and OMAP4 has a MMC/SD controller embedded.
+ * This file provides the platform data structure required to
+ * addapt to platform specialities.
+ */
+/*
+ * (C) Copyright 2011
+ * Phytec Messtechnik GmbH, <www.phytec.de>
+ * Juergen Kilb <j.kilb@phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_OMAP_HSMMC_H
+#define __ASM_OMAP_HSMMC_H
+
+/** omapmmc platform data structure */
+struct omap_hsmmc_platform_data {
+ unsigned f_max; /* host interface upper limit */
+};
+#endif /* __ASM_OMAP_HSMMC_H */
diff --git a/arch/arm/mach-omap/include/mach/sys_info.h b/arch/arm/mach-omap/include/mach/sys_info.h
index f557068345..f0594bf2b7 100644
--- a/arch/arm/mach-omap/include/mach/sys_info.h
+++ b/arch/arm/mach-omap/include/mach/sys_info.h
@@ -91,6 +91,7 @@
u32 get_cpu_type(void);
u32 get_cpu_rev(void);
u32 get_sdr_cs_size(u32 offset);
+u32 get_sdr_cs1_base(void);
inline u32 get_sysboot_value(void);
u32 get_gpmc0_base(void);
u32 get_base(void);
diff --git a/arch/arm/mach-omap/include/mach/syslib.h b/arch/arm/mach-omap/include/mach/syslib.h
index 65aca0297f..1909f172a6 100644
--- a/arch/arm/mach-omap/include/mach/syslib.h
+++ b/arch/arm/mach-omap/include/mach/syslib.h
@@ -30,7 +30,7 @@
*/
#ifndef __ASM_ARCH_OMAP_SYSLIB_H_
#define __ASM_ARCH_OMAP_SYSLIB_H_
-#include <asm/io.h>
+#include <io.h>
/** System Independent functions */
diff --git a/arch/arm/mach-omap/omap3_clock.c b/arch/arm/mach-omap/omap3_clock.c
index 3a0ab24e58..412d7b714c 100644
--- a/arch/arm/mach-omap/omap3_clock.c
+++ b/arch/arm/mach-omap/omap3_clock.c
@@ -39,7 +39,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/silicon.h>
#include <mach/clocks.h>
#include <mach/timers.h>
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index 661a971fc0..fc83d23713 100644
--- a/arch/arm/mach-omap/omap3_generic.c
+++ b/arch/arm/mach-omap/omap3_generic.c
@@ -36,7 +36,7 @@
*/
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/silicon.h>
#include <mach/gpmc.h>
#include <mach/sdrc.h>
@@ -59,8 +59,9 @@
*/
void __noreturn reset_cpu(unsigned long addr)
{
- /* FIXME: Enable WDT and cause reset */
- hang();
+ writel(PRM_RSTCTRL_RESET, PRM_REG(RSTCTRL));
+
+ while (1);
}
EXPORT_SYMBOL(reset_cpu);
@@ -177,7 +178,26 @@ u32 get_sdr_cs_size(u32 offset)
size *= 2 * (1024 * 1024); /* find size in MB */
return size;
}
+EXPORT_SYMBOL(get_sdr_cs_size);
+/**
+ * @brief base address of chip select 1 (cs0 is defined at 0x80000000)
+ *
+ * @return return the CS1 base address.
+ */
+u32 get_sdr_cs1_base(void)
+{
+ u32 base;
+ u32 cs_cfg;
+ cs_cfg = readl(SDRC_REG(CS_CFG));
+ /* get ram size field */
+ base = (cs_cfg & 0x0000000F) << 2; /* get CS1STARTHIGH */
+ base = base | ((cs_cfg & 0x00000300) >> 8); /* get CS1STARTLOW */
+ base = base << 25;
+ base += 0x80000000;
+ return base;
+}
+EXPORT_SYMBOL(get_sdr_cs1_base);
/**
* @brief Get the initial SYSBOOT value
*
diff --git a/arch/arm/mach-omap/omap4_clock.c b/arch/arm/mach-omap/omap4_clock.c
index 23a77d06f1..f8bab5f93a 100644
--- a/arch/arm/mach-omap/omap4_clock.c
+++ b/arch/arm/mach-omap/omap4_clock.c
@@ -1,6 +1,6 @@
#include <common.h>
#include <mach/syslib.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/omap4-clock.h>
#define LDELAY 12000000
diff --git a/arch/arm/mach-omap/omap4_generic.c b/arch/arm/mach-omap/omap4_generic.c
index 313e5e997b..5223c7e757 100644
--- a/arch/arm/mach-omap/omap4_generic.c
+++ b/arch/arm/mach-omap/omap4_generic.c
@@ -1,7 +1,7 @@
#include <common.h>
#include <init.h>
#include <mach/silicon.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/omap4-silicon.h>
#include <mach/omap4-clock.h>
#include <mach/syslib.h>
diff --git a/arch/arm/mach-omap/s32k_clksource.c b/arch/arm/mach-omap/s32k_clksource.c
index 094b76d6b7..3ed9448949 100644
--- a/arch/arm/mach-omap/s32k_clksource.c
+++ b/arch/arm/mach-omap/s32k_clksource.c
@@ -33,7 +33,7 @@
#include <common.h>
#include <clock.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/silicon.h>
#include <mach/clocks.h>
#include <mach/timers.h>
diff --git a/arch/arm/mach-omap/syslib.c b/arch/arm/mach-omap/syslib.c
index 677de6a27d..765a816147 100644
--- a/arch/arm/mach-omap/syslib.c
+++ b/arch/arm/mach-omap/syslib.c
@@ -32,7 +32,7 @@
#include <config.h>
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/syslib.h>
/**
diff --git a/arch/arm/mach-s3c24xx/generic.c b/arch/arm/mach-s3c24xx/generic.c
index 4c7e799850..d2f2ac7ac0 100644
--- a/arch/arm/mach-s3c24xx/generic.c
+++ b/arch/arm/mach-s3c24xx/generic.c
@@ -26,7 +26,7 @@
#include <common.h>
#include <init.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/s3c24x0-iomap.h>
/**
diff --git a/arch/arm/mach-s3c24xx/gpio-s3c24x0.c b/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
index 3d5e5e5c96..946ec3396e 100644
--- a/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
+++ b/arch/arm/mach-s3c24xx/gpio-s3c24x0.c
@@ -17,7 +17,7 @@
#include <common.h>
#include <errno.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/s3c24x0-iomap.h>
#include <mach/gpio.h>
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 1231a7db63..bdf48f97a2 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -35,7 +35,7 @@
#include <linux/clk.h>
#include <linux/err.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/hardware/arm_timer.h>
#include <asm/armlinux.h>
diff --git a/arch/arm/mach-versatile/include/mach/debug_ll.h b/arch/arm/mach-versatile/include/mach/debug_ll.h
index 1f6162b9db..30762c93fb 100644
--- a/arch/arm/mach-versatile/include/mach/debug_ll.h
+++ b/arch/arm/mach-versatile/include/mach/debug_ll.h
@@ -20,7 +20,7 @@
#define __MACH_DEBUG_LL_H__
#include <linux/amba/serial.h>
-#include <asm/io.h>
+#include <io.h>
static inline void putc(char c)
{
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index 581947be26..d1b39fa347 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -31,7 +31,7 @@
#include <net.h>
#include <init.h>
#include <environment.h>
-#include <mem_malloc.h>
+#include <memory.h>
#include <asm/cpu.h>
#include <asm-generic/memory_layout.h>
diff --git a/arch/mips/boards/dlink-dir-320/serial.c b/arch/mips/boards/dlink-dir-320/serial.c
index ebe8c06c7a..3eaab2a129 100644
--- a/arch/mips/boards/dlink-dir-320/serial.c
+++ b/arch/mips/boards/dlink-dir-320/serial.c
@@ -24,7 +24,7 @@
#include <init.h>
#include <ns16550.h>
#include <mach/hardware.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/common.h>
static struct NS16550_plat serial_plat = {
diff --git a/arch/mips/boards/qemu-malta/serial.c b/arch/mips/boards/qemu-malta/serial.c
index ef6be17f1f..502b3468bb 100644
--- a/arch/mips/boards/qemu-malta/serial.c
+++ b/arch/mips/boards/qemu-malta/serial.c
@@ -24,7 +24,7 @@
#include <init.h>
#include <ns16550.h>
#include <mach/hardware.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/common.h>
static struct NS16550_plat serial_plat = {
diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S
index dd9eab7970..ba4c0afc11 100644
--- a/arch/mips/lib/barebox.lds.S
+++ b/arch/mips/lib/barebox.lds.S
@@ -64,10 +64,6 @@ SECTIONS
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
- __early_init_data_begin = .;
- .early_init_data : { *(.early_init_data) }
- __early_init_data_end = .;
-
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss*) }
diff --git a/arch/mips/lib/csrc-r4k.c b/arch/mips/lib/csrc-r4k.c
index 8e93e6f6c4..1dd0928949 100644
--- a/arch/mips/lib/csrc-r4k.c
+++ b/arch/mips/lib/csrc-r4k.c
@@ -25,7 +25,7 @@
#include <init.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mipsregs.h>
static uint64_t c0_hpt_read(void)
diff --git a/arch/mips/lib/memory.c b/arch/mips/lib/memory.c
index 23a995c45d..ad9f6a6a40 100644
--- a/arch/mips/lib/memory.c
+++ b/arch/mips/lib/memory.c
@@ -20,7 +20,7 @@
#include <common.h>
#include <init.h>
-#include <mem_malloc.h>
+#include <memory.h>
#include <asm-generic/memory_layout.h>
static int mips_mem_malloc_init(void)
diff --git a/arch/mips/mach-bcm47xx/include/mach/debug_ll.h b/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
index 32d13c1a87..ccc9d9bfc7 100644
--- a/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
+++ b/arch/mips/mach-bcm47xx/include/mach/debug_ll.h
@@ -24,7 +24,7 @@
#ifndef __INCLUDE_ARCH_DEBUG_LL_H__
#define __INCLUDE_ARCH_DEBUG_LL_H__
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
#define rbr 0
diff --git a/arch/mips/mach-bcm47xx/reset.c b/arch/mips/mach-bcm47xx/reset.c
index 2818e7cfa3..d6fcd8dec2 100644
--- a/arch/mips/mach-bcm47xx/reset.c
+++ b/arch/mips/mach-bcm47xx/reset.c
@@ -24,7 +24,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
void __noreturn reset_cpu(ulong addr)
diff --git a/arch/mips/mach-malta/include/mach/debug_ll.h b/arch/mips/mach-malta/include/mach/debug_ll.h
index 32d13c1a87..ccc9d9bfc7 100644
--- a/arch/mips/mach-malta/include/mach/debug_ll.h
+++ b/arch/mips/mach-malta/include/mach/debug_ll.h
@@ -24,7 +24,7 @@
#ifndef __INCLUDE_ARCH_DEBUG_LL_H__
#define __INCLUDE_ARCH_DEBUG_LL_H__
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
#define rbr 0
diff --git a/arch/mips/mach-malta/reset.c b/arch/mips/mach-malta/reset.c
index 2818e7cfa3..d6fcd8dec2 100644
--- a/arch/mips/mach-malta/reset.c
+++ b/arch/mips/mach-malta/reset.c
@@ -24,7 +24,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
void __noreturn reset_cpu(ulong addr)
diff --git a/arch/nios2/cpu/interrupts.c b/arch/nios2/cpu/interrupts.c
index 5efbd5e354..f443bfdec5 100644
--- a/arch/nios2/cpu/interrupts.c
+++ b/arch/nios2/cpu/interrupts.c
@@ -27,7 +27,7 @@
#include <nios2.h>
#include <asm/nios2-io.h>
#include <asm/types.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/ptrace.h>
#include <common.h>
#include <command.h>
diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c
index 7cbff4032b..07f045b3aa 100644
--- a/arch/nios2/lib/board.c
+++ b/arch/nios2/lib/board.c
@@ -23,7 +23,7 @@
#include <common.h>
#include <malloc.h>
#include <init.h>
-#include <mem_malloc.h>
+#include <memory.h>
#include <asm-generic/memory_layout.h>
#include <cache.h>
diff --git a/arch/nios2/lib/clock.c b/arch/nios2/lib/clock.c
index 05008be793..52f52fd145 100644
--- a/arch/nios2/lib/clock.c
+++ b/arch/nios2/lib/clock.c
@@ -24,7 +24,7 @@
#include <clock.h>
#include <init.h>
#include <asm/nios2-io.h>
-#include <asm/io.h>
+#include <io.h>
static struct nios_timer *timer = (struct nios_timer *)NIOS_SOPC_TIMER_BASE;
diff --git a/arch/nios2/lib/early_printf.c b/arch/nios2/lib/early_printf.c
index 637bb73b0d..50b071ba5e 100644
--- a/arch/nios2/lib/early_printf.c
+++ b/arch/nios2/lib/early_printf.c
@@ -23,7 +23,7 @@
#include <stdio.h>
#include <common.h>
#include <asm/nios2-io.h>
-#include <asm/io.h>
+#include <io.h>
void early_putc(char ch)
{
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index cda14de25d..50ccaac5f3 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -7,15 +7,6 @@ config ARCH_TEXT_BASE
default 0x00000000 if RELOCATABLE
default 0x01000000 if MACH_PHYCORE_MPC5200B_TINY
-config MPC5XXX_EARLY_CONSOLE
- bool
- depends on ARCH_MPC5200
- default y
-
-config HAS_EARLY_INIT
- bool
- default y
-
config PPC
bool
select HAVE_CONFIGURABLE_TEXT_BASE
diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/boards/pcm030/barebox.lds.S
index 21bf4a75c7..4aacfc5f12 100644
--- a/arch/ppc/boards/pcm030/barebox.lds.S
+++ b/arch/ppc/boards/pcm030/barebox.lds.S
@@ -111,10 +111,6 @@ SECTIONS
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
- __early_init_data_begin = .;
- .early_init_data : { *(.early_init_data) }
- __early_init_data_end = .;
-
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
diff --git a/arch/ppc/boards/pcm030/config.h b/arch/ppc/boards/pcm030/config.h
index a772ee6d96..508e017161 100644
--- a/arch/ppc/boards/pcm030/config.h
+++ b/arch/ppc/boards/pcm030/config.h
@@ -29,79 +29,15 @@
#include <mach/mpc5xxx.h>
-/* #define DEBUG */
-
-/*------------------------------------------------------------------------------------------------------------------------------------------------------
-High Level Configuration Options
-(easy to change)
- ------------------------------------------------------------------------------------------------------------------------------------------------------*/
-#define CONFIG_MPC5200_DDR 1 /* (with DDR-SDRAM) */
#define CFG_MPC5XXX_CLKIN 33333333 /* ... running at 33.333333MHz */
-#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
-#define BOOTFLAG_WARM 0x02 /* Software reboot */
-
-/*------------------------------------------------------------------------------------------------------------------------------------------------------
-Serial console configuration
- ------------------------------------------------------------------------------------------------------------------------------------------------------*/
-
-#if (TEXT_BASE == 0xFF000000) /* Boot low */
-#define CFG_LOWBOOT 1
-#endif
-/* RAMBOOT will be defined automatically in memory section */
-
-/*------------------------------------------------------------------------------------------------------------------------------------------------------
-IPB Bus clocking configuration.
- ------------------------------------------------------------------------------------------------------------------------------------------------------*/
-#define CFG_IPBSPEED_133 /* define for 133MHz speed */
-#if defined(CFG_IPBSPEED_133)
-/*
- * PCI Bus clocking configuration
- *
- * Actually a PCI Clock of 66 MHz is only set (in cpu_init.c) if
- * CFG_IPBSPEED_133 is defined. This is because a PCI Clock of 66 MHz yet hasn't
- * been tested with a IPB Bus Clock of 66 MHz.
- */
-#define CFG_PCISPEED_66 /* define for 66MHz speed */
-#else
-#undef CFG_PCISPEED_66 /* for 33MHz speed */
-#endif
-/* we only use CS-Boot */
-#define CFG_BOOTCS_START 0xFF000000
-#define CFG_BOOTCS_SIZE 0x01000000
-
-#if CONFIG_MACH_PHYCORE_MPC5200B_TINY_REV == 1
-#define CFG_BOOTCS_CFG 0x0008FD00
-#else
-#define CFG_BOOTCS_CFG 0x00083800
-#endif
-
-/*------------------------------------------------------------------------------------------------------------------------------------------------------
- Memory map
- ------------------------------------------------------------------------------------------------------------------------------------------------------*/
-#define CFG_MBAR 0xF0000000 /* MBAR hast to be switched by other bootloader or debugger config */
-#define CFG_SDRAM_BASE 0x00000000
-
-/* Use SRAM until RAM will be available */
-#define CFG_INIT_RAM_ADDR MPC5XXX_SRAM
-#define CFG_INIT_RAM_SIZE MPC5XXX_SRAM_SIZE /* End of used area in DPRAM */
-#define CONFIG_EARLY_INITDATA_SIZE 0x100
-
-#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
-
-/*------------------------------------------------------------------------------------------------------------------------------------------------------
- GPIO configuration
- ------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CFG_GPS_PORT_CONFIG 0x00558c10 /* PSC6=UART, PSC3=UART ; Ether=100MBit with MD */
-/*------------------------------------------------------------------------------------------------------------------------------------------------------
- Various low-level settings
- ------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CFG_HID0_INIT HID0_ICE | HID0_ICFI
#define CFG_HID0_FINAL HID0_ICE
-#define CFG_CS_BURST 0x00000000
-#define CFG_CS_DEADCYCLE 0x33333333
+
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
#define OF_CPU "PowerPC,5200@0"
#define OF_TBCLK CFG_MPC5XXX_CLKIN
diff --git a/arch/ppc/boards/pcm030/pcm030.c b/arch/ppc/boards/pcm030/pcm030.c
index ba59bfe101..61fb11620f 100644
--- a/arch/ppc/boards/pcm030/pcm030.c
+++ b/arch/ppc/boards/pcm030/pcm030.c
@@ -34,8 +34,10 @@
#include <mach/fec.h>
#include <types.h>
#include <partition.h>
-#include <mem_malloc.h>
-#include <reloc.h>
+#include <memory.h>
+#include <sizes.h>
+#include <linux/stat.h>
+#include <fs.h>
static struct mpc5xxx_fec_platform_data fec_info = {
.xcv_type = MII100,
@@ -43,14 +45,29 @@ static struct mpc5xxx_fec_platform_data fec_info = {
static int devices_init (void)
{
- add_cfi_flash_device(-1, 0xff000000, 16 * 1024 * 1024, 0);
- add_mem_device("ram0", 0x0, 64 * 1024 * 1024,
- IORESOURCE_MEM_WRITEABLE);
+ unsigned long sdramsize;
+ struct stat s;
+ int ret;
+
+ /*
+ * Flash can be 16MB or 32MB, setup for the last 32MB no matter
+ * what we find later.
+ */
+ mpc5200_setup_cs(MPC5200_BOOTCS, 0xfe000000, SZ_32M, 0x0008fd00);
+ add_cfi_flash_device(-1, 0xfe000000, 32 * 1024 * 1024, 0);
+
+ sdramsize = mpc5200_get_sdram_size(0) + mpc5200_get_sdram_size(1);
+ barebox_add_memory_bank("ram0", 0x0, sdramsize);
+
add_generic_device("fec_mpc5xxx", -1, NULL, MPC5XXX_FEC, 0,
IORESOURCE_MEM, &fec_info);
- devfs_add_partition("nor0", 0x00f00000, 0x40000, PARTITION_FIXED, "self0");
- devfs_add_partition("nor0", 0x00f60000, 0x20000, PARTITION_FIXED, "env0");
+ ret = stat("/dev/nor0", &s);
+ if (ret)
+ return 0;
+
+ devfs_add_partition("nor0", s.st_size - SZ_1M, SZ_512K, PARTITION_FIXED, "self0");
+ devfs_add_partition("nor0", s.st_size - SZ_512K, SZ_512K, PARTITION_FIXED, "env0");
return 0;
}
@@ -68,15 +85,6 @@ static int console_init(void)
console_initcall(console_init);
-void *get_early_console_base(const char *name)
-{
- if (!strcmp(name, RELOC("psc3")))
- return (void *)MPC5XXX_PSC3;
- if (!strcmp(name, RELOC("psc6")))
- return (void *)MPC5XXX_PSC6;
- return NULL;
-}
-
#include "mt46v32m16-75.h"
static void sdram_start (int hi_addr)
@@ -118,20 +126,22 @@ static void sdram_start (int hi_addr)
__asm__ volatile ("sync");
}
-/*
- * ATTENTION: Although partially referenced initdram does NOT make real use
- * use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
- * is something else than 0x00000000.
- */
-
-long int initdram (int board_type)
+void initdram (int board_type)
{
ulong dramsize = 0;
- ulong dramsize2 = 0;
ulong test1, test2;
- if ((ulong)RELOC(initdram) > (2 << 30)) {
+ /* Setup pin multiplexing */
+
+ /* PSC6=UART, PSC3=UART ; Ether=100MBit with MD */
+ *(vu_long *)MPC5XXX_GPS_PORT_CONFIG = 0x00558c10;
+ *(vu_long *)MPC5XXX_CS_BURST = 0x00000000;
+ *(vu_long *)MPC5XXX_CS_DEADCYCLE = 0x33333333;
+
+ mpc5200_setup_bus_clocks(1, 4);
+
+ if (get_pc() > SZ_128M) {
/* setup SDRAM chip selects */
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001b;/* 256MB at 0x0 */
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x10000000;/* disabled */
@@ -150,9 +160,9 @@ long int initdram (int board_type)
/* find RAM size using SDRAM CS0 only */
sdram_start(0);
- test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x10000000);
+ test1 = get_ram_size((ulong *)0, 0x10000000);
sdram_start(1);
- test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x10000000);
+ test2 = get_ram_size((ulong *)0, 0x10000000);
if (test1 > test2) {
sdram_start(0);
dramsize = test1;
@@ -171,26 +181,7 @@ long int initdram (int board_type)
} else {
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
}
- } else
- puts(RELOC("skipping sdram initialization\n"));
-
- /* retrieve size of memory connected to SDRAM CS0 */
- dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
- if (dramsize >= 0x13) {
- dramsize = (1 << (dramsize - 0x13)) << 20;
- } else {
- dramsize = 0;
- }
-
- /* retrieve size of memory connected to SDRAM CS1 */
- dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
- if (dramsize2 >= 0x13) {
- dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
- } else {
- dramsize2 = 0;
}
-
- return dramsize + dramsize2;
}
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
diff --git a/arch/ppc/include/asm/common.h b/arch/ppc/include/asm/common.h
index 96de5c6568..b7c524a646 100644
--- a/arch/ppc/include/asm/common.h
+++ b/arch/ppc/include/asm/common.h
@@ -3,14 +3,10 @@
#include <asm/barebox.h>
-void upmconfig (unsigned int, unsigned int *, unsigned int);
-ulong get_tbclk (void);
+extern unsigned long _text_base;
unsigned long long get_ticks(void);
-int get_clocks (void);
-ulong get_bus_freq (ulong);
-
int cpu_init (void);
uint get_pvr (void);
@@ -21,4 +17,21 @@ void trap_init (ulong);
int cpu_init_board_data(bd_t *bd);
int init_board_data(bd_t *bd);
+static inline unsigned long get_pc(void)
+{
+ unsigned long pc;
+
+ __asm__ __volatile__(
+ " mflr 0\n"
+ " bl 1f\n"
+ "1:\n"
+ " mflr %0\n"
+ " mtlr 0\n"
+ : "=r" (pc)
+ :
+ : "0", "memory");
+
+ return pc;
+}
+
#endif /* __ASM_COMMON_H */
diff --git a/arch/ppc/include/asm/mc146818rtc.h b/arch/ppc/include/asm/mc146818rtc.h
index 5f806c4ec2..adc4e24db7 100644
--- a/arch/ppc/include/asm/mc146818rtc.h
+++ b/arch/ppc/include/asm/mc146818rtc.h
@@ -4,7 +4,7 @@
#ifndef __ASM_PPC_MC146818RTC_H
#define __ASM_PPC_MC146818RTC_H
-#include <asm/io.h>
+#include <io.h>
#ifndef RTC_PORT
#define RTC_PORT(x) (0x70 + (x))
diff --git a/arch/ppc/lib/board.c b/arch/ppc/lib/board.c
index 7f8118e16f..82ba458fcc 100644
--- a/arch/ppc/lib/board.c
+++ b/arch/ppc/lib/board.c
@@ -26,10 +26,9 @@
#include <watchdog.h>
#include <command.h>
#include <malloc.h>
-#include <mem_malloc.h>
+#include <memory.h>
#include <init.h>
#include <net.h>
-#include <reloc.h>
#include <asm-generic/memory_layout.h>
/************************************************************************
@@ -48,8 +47,6 @@ void board_init_r (ulong end_of_ram)
asm ("sync ; isync");
- _text_base += reloc_offset();
-
/*
* FIXME: 128k stack size. Is this enough? should
* it be configurable?
diff --git a/arch/ppc/lib/board_data.c b/arch/ppc/lib/board_data.c
index b28830f792..ff9f0d0f0c 100644
--- a/arch/ppc/lib/board_data.c
+++ b/arch/ppc/lib/board_data.c
@@ -4,7 +4,7 @@ int init_board_data(bd_t *bd)
{
cpu_init_board_data(bd);
- bd->bi_memstart = CFG_SDRAM_BASE; /* start of DRAM memory */
+ bd->bi_memstart = 0; /* start of DRAM memory */
// bd->bi_memsize = gd->ram_size; /* size of DRAM memory in bytes */ /* FIXME */
#ifdef CONFIG_IP860
diff --git a/arch/ppc/mach-mpc5xxx/Kconfig b/arch/ppc/mach-mpc5xxx/Kconfig
index 5da6a5b5b2..632fb857f1 100644
--- a/arch/ppc/mach-mpc5xxx/Kconfig
+++ b/arch/ppc/mach-mpc5xxx/Kconfig
@@ -10,6 +10,3 @@ config MACH_PHYCORE_MPC5200B_TINY_REV
old board you should set this option to 1
endmenu
-
-config EARLY_CONSOLE_PORT
- default "psc3" if MACH_PHYCORE_MPC5200B_TINY \ No newline at end of file
diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu.c
index be7c19d136..d695b9b545 100644
--- a/arch/ppc/mach-mpc5xxx/cpu.c
+++ b/arch/ppc/mach-mpc5xxx/cpu.c
@@ -30,8 +30,10 @@
#include <mach/mpc5xxx.h>
#include <asm/processor.h>
#include <asm/byteorder.h>
+#include <asm/io.h>
#include <init.h>
#include <types.h>
+#include <errno.h>
#include <mach/clocks.h>
#if defined(CONFIG_OF_FLAT_TREE)
@@ -41,16 +43,10 @@
int checkcpu (void)
{
ulong clock = get_cpu_clock();
-#ifndef CONFIG_MGT5100
uint svr, pvr;
-#endif
puts ("CPU: ");
-#ifdef CONFIG_MGT5100
- puts (CPU_ID_STR);
- printf (" (JTAG ID %08lx)", *(vu_long *)MPC5XXX_CDM_JTAGID);
-#else
svr = get_svr();
pvr = get_pvr();
switch (SVR_VER (svr)) {
@@ -64,7 +60,6 @@ int checkcpu (void)
printf (" v%d.%d, Core v%d.%d", SVR_MJREV (svr), SVR_MNREV (svr),
PVR_MAJ(pvr), PVR_MIN(pvr));
-#endif
printf (" at %ld Hz\n", clock);
return 0;
}
@@ -120,3 +115,126 @@ int cpu_init_board_data(bd_t *bd)
bd->bi_pcifreq = get_pci_clock();
return 0;
}
+
+unsigned long mpc5200_get_sdram_size(unsigned int cs)
+{
+ unsigned long size;
+
+ if (cs > 1)
+ return 0;
+
+ /* retrieve size of memory connected to SDRAM CS0 */
+ size = *(vu_long *)(MPC5XXX_SDRAM_CS0CFG + (cs * 4)) & 0xFF;
+ if (size >= 0x13)
+ size = (1 << (size - 0x13)) << 20;
+ else
+ size = 0;
+
+ return size;
+}
+
+int mpc5200_setup_bus_clocks(unsigned int ipbdiv, unsigned long pcidiv)
+{
+ u32 cdmcfg = *(vu_long *)MPC5XXX_CDM_CFG;
+
+ cdmcfg &= ~0x103;
+
+ switch (ipbdiv) {
+ case 1:
+ break;
+ case 2:
+ cdmcfg |= 0x100;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (pcidiv) {
+ case 1:
+ if (ipbdiv == 2)
+ return -EINVAL;
+ break;
+ case 2:
+ if (ipbdiv == 1)
+ cdmcfg |= 0x1; /* ipb / 2 */
+ break;
+ case 4:
+ cdmcfg |= 0x2; /* xlb / 4 */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *(vu_long *)MPC5XXX_CDM_CFG = cdmcfg;
+
+ return 0;
+}
+
+struct mpc5200_cs {
+ void *start;
+ void *stop;
+ void *cfg;
+ unsigned int addecr;
+};
+
+static struct mpc5200_cs chipselects[] = {
+ {
+ .start = (void *)MPC5XXX_CS0_START,
+ .stop = (void *)MPC5XXX_CS0_STOP,
+ .cfg = (void *)MPC5XXX_CS0_CFG,
+ .addecr = 1 << 16,
+ }, {
+ .start = (void *)MPC5XXX_CS1_START,
+ .stop = (void *)MPC5XXX_CS1_STOP,
+ .cfg = (void *)MPC5XXX_CS1_CFG,
+ .addecr = 1 << 17,
+ }, {
+ .start = (void *)MPC5XXX_CS2_START,
+ .stop = (void *)MPC5XXX_CS2_STOP,
+ .cfg = (void *)MPC5XXX_CS2_CFG,
+ .addecr = 1 << 18,
+ }, {
+ .start = (void *)MPC5XXX_CS3_START,
+ .stop = (void *)MPC5XXX_CS3_STOP,
+ .cfg = (void *)MPC5XXX_CS3_CFG,
+ .addecr = 1 << 19,
+ }, {
+ .start = (void *)MPC5XXX_CS4_START,
+ .stop = (void *)MPC5XXX_CS4_STOP,
+ .cfg = (void *)MPC5XXX_CS4_CFG,
+ .addecr = 1 << 20,
+ }, {
+ .start = (void *)MPC5XXX_CS5_START,
+ .stop = (void *)MPC5XXX_CS5_STOP,
+ .cfg = (void *)MPC5XXX_CS5_CFG,
+ .addecr = 1 << 21,
+ }, {
+ .start = (void *)MPC5XXX_CS6_START,
+ .stop = (void *)MPC5XXX_CS6_STOP,
+ .cfg = (void *)MPC5XXX_CS6_CFG,
+ .addecr = 1 << 26,
+ }, {
+ .start = (void *)MPC5XXX_CS7_START,
+ .stop = (void *)MPC5XXX_CS7_STOP,
+ .cfg = (void *)MPC5XXX_CS7_CFG,
+ .addecr = 1 << 27,
+ }, {
+ .start = (void *)MPC5XXX_BOOTCS_START,
+ .stop = (void *)MPC5XXX_BOOTCS_STOP,
+ .cfg = (void *)MPC5XXX_CS0_CFG,
+ .addecr = 1 << 25,
+ },
+};
+
+void mpc5200_setup_cs(int cs, unsigned long start, unsigned long size, u32 cfg)
+{
+ u32 addecr;
+
+ out_be32(chipselects[cs].start, START_REG(start));
+ out_be32(chipselects[cs].stop, STOP_REG(start, size));
+ out_be32(chipselects[cs].cfg, cfg);
+
+ addecr = in_be32((void *)MPC5XXX_ADDECR);
+ addecr |= chipselects[cs].addecr | 1;
+ out_be32((void *)MPC5XXX_ADDECR, addecr);
+}
diff --git a/arch/ppc/mach-mpc5xxx/cpu_init.c b/arch/ppc/mach-mpc5xxx/cpu_init.c
index fc5db0ec3e..a6c270b3ef 100644
--- a/arch/ppc/mach-mpc5xxx/cpu_init.c
+++ b/arch/ppc/mach-mpc5xxx/cpu_init.c
@@ -24,172 +24,35 @@
#include <common.h>
#include <mach/mpc5xxx.h>
#include <types.h>
-#include <reloc.h>
/*
* Breath some life into the CPU...
*
- * Set up the memory map,
* initialize a bunch of registers.
*/
int cpu_init(void)
{
unsigned long addecr = (1 << 25); /* Boot_CS */
-#if defined(CFG_RAMBOOT) && defined(CONFIG_MGT5100)
- addecr |= (1 << 22); /* SDRAM enable */
-#endif
-
- /*
- * Memory Controller: configure chip selects and enable them
- */
-#if defined(CFG_BOOTCS_START) && defined(CFG_BOOTCS_SIZE)
- *(vu_long *)MPC5XXX_BOOTCS_START = START_REG(CFG_BOOTCS_START);
- *(vu_long *)MPC5XXX_BOOTCS_STOP = STOP_REG(CFG_BOOTCS_START,
- CFG_BOOTCS_SIZE);
-#endif
-#if defined(CFG_BOOTCS_CFG)
- *(vu_long *)MPC5XXX_BOOTCS_CFG = CFG_BOOTCS_CFG;
-#endif
-
-#if defined(CFG_CS0_START) && defined(CFG_CS0_SIZE)
- *(vu_long *)MPC5XXX_CS0_START = START_REG(CFG_CS0_START);
- *(vu_long *)MPC5XXX_CS0_STOP = STOP_REG(CFG_CS0_START, CFG_CS0_SIZE);
- /* CS0 and BOOT_CS cannot be enabled at once. */
- /* addecr |= (1 << 16); */
-#endif
-#if defined(CFG_CS0_CFG)
- *(vu_long *)MPC5XXX_CS0_CFG = CFG_CS0_CFG;
-#endif
-
-#if defined(CFG_CS1_START) && defined(CFG_CS1_SIZE)
- *(vu_long *)MPC5XXX_CS1_START = START_REG(CFG_CS1_START);
- *(vu_long *)MPC5XXX_CS1_STOP = STOP_REG(CFG_CS1_START, CFG_CS1_SIZE);
- addecr |= (1 << 17);
-#endif
-#if defined(CFG_CS1_CFG)
- *(vu_long *)MPC5XXX_CS1_CFG = CFG_CS1_CFG;
-#endif
-
-#if defined(CFG_CS2_START) && defined(CFG_CS2_SIZE)
- *(vu_long *)MPC5XXX_CS2_START = START_REG(CFG_CS2_START);
- *(vu_long *)MPC5XXX_CS2_STOP = STOP_REG(CFG_CS2_START, CFG_CS2_SIZE);
- addecr |= (1 << 18);
-#endif
-#if defined(CFG_CS2_CFG)
- *(vu_long *)MPC5XXX_CS2_CFG = CFG_CS2_CFG;
-#endif
-
-#if defined(CFG_CS3_START) && defined(CFG_CS3_SIZE)
- *(vu_long *)MPC5XXX_CS3_START = START_REG(CFG_CS3_START);
- *(vu_long *)MPC5XXX_CS3_STOP = STOP_REG(CFG_CS3_START, CFG_CS3_SIZE);
- addecr |= (1 << 19);
-#endif
-#if defined(CFG_CS3_CFG)
- *(vu_long *)MPC5XXX_CS3_CFG = CFG_CS3_CFG;
-#endif
-
-#if defined(CFG_CS4_START) && defined(CFG_CS4_SIZE)
- *(vu_long *)MPC5XXX_CS4_START = START_REG(CFG_CS4_START);
- *(vu_long *)MPC5XXX_CS4_STOP = STOP_REG(CFG_CS4_START, CFG_CS4_SIZE);
- addecr |= (1 << 20);
-#endif
-#if defined(CFG_CS4_CFG)
- *(vu_long *)MPC5XXX_CS4_CFG = CFG_CS4_CFG;
-#endif
-
-#if defined(CFG_CS5_START) && defined(CFG_CS5_SIZE)
- *(vu_long *)MPC5XXX_CS5_START = START_REG(CFG_CS5_START);
- *(vu_long *)MPC5XXX_CS5_STOP = STOP_REG(CFG_CS5_START, CFG_CS5_SIZE);
- addecr |= (1 << 21);
-#endif
-#if defined(CFG_CS5_CFG)
- *(vu_long *)MPC5XXX_CS5_CFG = CFG_CS5_CFG;
-#endif
-
-#if defined(CONFIG_MPC5200)
- addecr |= 1;
-#if defined(CFG_CS6_START) && defined(CFG_CS6_SIZE)
- *(vu_long *)MPC5XXX_CS6_START = START_REG(CFG_CS6_START);
- *(vu_long *)MPC5XXX_CS6_STOP = STOP_REG(CFG_CS6_START, CFG_CS6_SIZE);
- addecr |= (1 << 26);
-#endif
-#if defined(CFG_CS6_CFG)
- *(vu_long *)MPC5XXX_CS6_CFG = CFG_CS6_CFG;
-#endif
-
-#if defined(CFG_CS7_START) && defined(CFG_CS7_SIZE)
- *(vu_long *)MPC5XXX_CS7_START = START_REG(CFG_CS5_START);
- *(vu_long *)MPC5XXX_CS7_STOP = STOP_REG(CFG_CS7_START, CFG_CS7_SIZE);
- addecr |= (1 << 27);
-#endif
-#if defined(CFG_CS7_CFG)
- *(vu_long *)MPC5XXX_CS7_CFG = CFG_CS7_CFG;
-#endif
-
-#if defined(CFG_CS_BURST)
- *(vu_long *)MPC5XXX_CS_BURST = CFG_CS_BURST;
-#endif
-#if defined(CFG_CS_DEADCYCLE)
- *(vu_long *)MPC5XXX_CS_DEADCYCLE = CFG_CS_DEADCYCLE;
-#endif
-#endif /* CONFIG_MPC5200 */
-
- /* Enable chip selects */
- *(vu_long *)MPC5XXX_ADDECR = addecr;
- *(vu_long *)MPC5XXX_CS_CTRL = (1 << 24);
-
- /* Setup pin multiplexing */
-#if defined(CFG_GPS_PORT_CONFIG)
- *(vu_long *)MPC5XXX_GPS_PORT_CONFIG = CFG_GPS_PORT_CONFIG;
-#endif
-
-#if defined(CONFIG_MPC5200)
/* enable timebase */
*(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 13);
/* Enable snooping for RAM */
*(vu_long *)(MPC5XXX_XLBARB + 0x40) |= (1 << 15);
- *(vu_long *)(MPC5XXX_XLBARB + 0x70) = CFG_SDRAM_BASE | 0x1d;
+ *(vu_long *)(MPC5XXX_XLBARB + 0x70) = 0 | 0x1d;
-# if defined(CFG_IPBSPEED_133)
- /* Motorola reports IPB should better run at 133 MHz. */
- *(vu_long *)MPC5XXX_ADDECR |= 1;
- /* pci_clk_sel = 0x02, ipb_clk_sel = 0x00; */
- addecr = *(vu_long *)MPC5XXX_CDM_CFG;
- addecr &= ~0x103;
-# if defined(CFG_PCISPEED_66)
- /* pci_clk_sel = 0x01 -> IPB_CLK/2 */
- addecr |= 0x01;
-# else
- /* pci_clk_sel = 0x02 -> XLB_CLK/4 = IPB_CLK/4 */
- addecr |= 0x02;
-# endif /* CFG_PCISPEED_66 */
- *(vu_long *)MPC5XXX_CDM_CFG = addecr;
-# endif /* CFG_IPBSPEED_133 */
/* Configure the XLB Arbiter */
*(vu_long *)MPC5XXX_XLBARB_MPRIEN = 0xff;
*(vu_long *)MPC5XXX_XLBARB_MPRIVAL = 0x11111111;
-# if defined(CFG_XLB_PIPELINING)
- /* Enable piplining */
- *(vu_long *)(MPC5XXX_XLBARB + 0x40) &= ~(1 << 31);
-# endif
-#endif /* CONFIG_MPC5200 */
-
/* mask all interrupts */
-#if defined(CONFIG_MGT5100)
- *(vu_long *)MPC5XXX_ICTL_PER_MASK = 0xfffffc00;
-#elif defined(CONFIG_MPC5200)
*(vu_long *)MPC5XXX_ICTL_PER_MASK = 0xffffff00;
-#endif
+
*(vu_long *)MPC5XXX_ICTL_CRIT |= 0x0001ffff;
*(vu_long *)MPC5XXX_ICTL_EXT &= ~0x00000f00;
/* route critical ints to normal ints */
*(vu_long *)MPC5XXX_ICTL_EXT |= 0x00000001;
- early_init();
-
return 0;
}
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
index d7d081137b..cef02d8b18 100644
--- a/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
+++ b/arch/ppc/mach-mpc5xxx/include/mach/mpc5xxx.h
@@ -40,6 +40,8 @@
/* Exception offsets (PowerPC standard) */
#define EXC_OFF_SYS_RESET 0x0100
+#define CFG_MBAR 0xf0000000
+
/* useful macros for manipulating CSx_START/STOP */
#if defined(CONFIG_MGT5100)
#define START_REG(start) ((start) >> 15)
@@ -779,6 +781,16 @@ struct mpc5xxx_mscan {
/* function prototypes */
void loadtask(int basetask, int tasks);
+/* retrieve configured sdram size connected to a chipselect */
+unsigned long mpc5200_get_sdram_size(unsigned int cs);
+
+/* configure a local plus bus chip select */
+#define MPC5200_BOOTCS 8
+void mpc5200_setup_cs(int cs, unsigned long start, unsigned long size, u32 cfg);
+
+/* configure bus speeds. Both dividers are relative to xlb clock */
+int mpc5200_setup_bus_clocks(unsigned int ipbdiv, unsigned long pcidiv);
+
#endif /* __ASSEMBLY__ */
#endif /* __ASMPPC_MPC5XXX_H */
diff --git a/arch/ppc/mach-mpc5xxx/interrupts.c b/arch/ppc/mach-mpc5xxx/interrupts.c
index e484b6ecde..4838bc5f70 100644
--- a/arch/ppc/mach-mpc5xxx/interrupts.c
+++ b/arch/ppc/mach-mpc5xxx/interrupts.c
@@ -39,7 +39,7 @@
#include <common.h>
#include <asm/processor.h>
-#include <asm/io.h>
+#include <io.h>
#include <command.h>
#include <mach/sdma.h>
#include <asm/bitops.h>
diff --git a/arch/ppc/mach-mpc5xxx/pci_mpc5200.c b/arch/ppc/mach-mpc5xxx/pci_mpc5200.c
index a7de4a2268..d8f3b00759 100644
--- a/arch/ppc/mach-mpc5xxx/pci_mpc5200.c
+++ b/arch/ppc/mach-mpc5xxx/pci_mpc5200.c
@@ -26,7 +26,7 @@
#if defined(CONFIG_PCI) && defined(CONFIG_MPC5200)
#include <asm/processor.h>
-#include <asm/io.h>
+#include <io.h>
#include <pci.h>
#include <mpc5xxx.h>
diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S
index 8fca31b7a6..dc53c8a226 100644
--- a/arch/ppc/mach-mpc5xxx/start.S
+++ b/arch/ppc/mach-mpc5xxx/start.S
@@ -66,76 +66,32 @@
* Exception vectors
*/
.text
+ /*
+ * Second stage loader entry. When entered here we assume that spr 311
+ * is set to the current MBAR address.
+ */
+ mfspr r4, MBAR
+ b setup_mbar
. = EXC_OFF_SYS_RESET
.globl _start
_start:
- li r21, BOOTFLAG_COLD /* Normal Power-On */
- nop
- b boot_cold
-
- . = EXC_OFF_SYS_RESET + 0x10
-
- .globl _start_warm
-_start_warm:
- li r21, BOOTFLAG_WARM /* Software reboot */
- b boot_warm
+ /*
+ * Reset entry. When entered here we assume that MBAR is at reset default
+ * 0x80000000.
+ */
+ lis r4, 0x80000000@h
+ ori r4, r4, 0x80000000@l
-boot_cold:
-boot_warm:
+setup_mbar:
+ /* r4 == current MBAR */
mfmsr r5 /* save msr contents */
- /* Move CSBoot and adjust instruction pointer */
- /*--------------------------------------------------------------*/
-
-#if defined(CFG_LOWBOOT)
-# if defined(CFG_RAMBOOT)
-# error CFG_LOWBOOT is incompatible with CFG_RAMBOOT
-# endif /* CFG_RAMBOOT */
-# if defined(CONFIG_MGT5100)
-# error CFG_LOWBOOT is incompatible with MGT5100
-# endif /* CONFIG_MGT5100 */
- lis r4, CFG_DEFAULT_MBAR@h
- lis r3, START_REG(CFG_BOOTCS_START)@h
- ori r3, r3, START_REG(CFG_BOOTCS_START)@l
- stw r3, 0x4(r4) /* CS0 start */
- lis r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@h
- ori r3, r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@l
- stw r3, 0x8(r4) /* CS0 stop */
- lis r3, 0x02010000@h
- ori r3, r3, 0x02010000@l
- stw r3, 0x54(r4) /* CS0 and Boot enable */
-
- lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */
- ori r3, r3, lowboot_reentry@l /* to the address space the linker used */
- mtlr r3
- blr
-
-lowboot_reentry:
- lis r3, START_REG(CFG_BOOTCS_START)@h
- ori r3, r3, START_REG(CFG_BOOTCS_START)@l
- stw r3, 0x4c(r4) /* Boot start */
- lis r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@h
- ori r3, r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@l
- stw r3, 0x50(r4) /* Boot stop */
- lis r3, 0x02000001@h
- ori r3, r3, 0x02000001@l
- stw r3, 0x54(r4) /* Boot enable, CS0 disable */
-#endif /* CFG_LOWBOOT */
-
-#if defined(CFG_DEFAULT_MBAR) && !defined(CFG_RAMBOOT)
- lis r3, CFG_MBAR@h
- ori r3, r3, CFG_MBAR@l
-#if defined(CONFIG_MPC5200)
- /* MBAR is mirrored into the MBAR SPR */
- mtspr MBAR,r3
+ /* Switch MBAR to 0xf0000000 */
+ lis r3, 0xf0000000@h
+ ori r3, r3, 0xf0000000@l
+ mtspr MBAR, r3
rlwinm r3, r3, 16, 16, 31
-#endif
-#if defined(CONFIG_MGT5100)
- rlwinm r3, r3, 17, 15, 31
-#endif
- lis r4, CFG_DEFAULT_MBAR@h
stw r3, 0(r4)
-#endif /* CFG_DEFAULT_MBAR */
/* Initialise the MPC5xxx processor core */
/*--------------------------------------------------------------*/
@@ -146,9 +102,8 @@ lowboot_reentry:
/*--------------------------------------------------------------*/
/* set up stack in on-chip SRAM */
- lis r3, (CFG_INIT_RAM_ADDR + CFG_INIT_RAM_SIZE)@h
- ori r3, r3, (CFG_INIT_RAM_ADDR + CFG_INIT_RAM_SIZE)@l
- subi r1, r3, CONFIG_EARLY_INITDATA_SIZE
+ lis r1, (MPC5XXX_SRAM + MPC5XXX_SRAM_SIZE)@h
+ ori r1, r1, (MPC5XXX_SRAM + MPC5XXX_SRAM_SIZE)@l
li r0, 0 /* Make room for stack frame header and */
stwu r0, -4(r1) /* clear final stack frame so that */
stwu r0, -4(r1) /* stack backtraces terminate cleanly */
@@ -809,21 +764,6 @@ trap_reloc:
blr
- .globl reloc_offset
-reloc_offset:
- mfspr r4, LR
- bl pc
-pc:
- mfspr r3, LR
- mtspr LR, r4
- addi r4, r3, (_text_base - pc)
- subi r3, r3, (pc - _start)
- lwz r4, 0(r4)
-
- sub r3, r3, r4
- subi r3, r3, 0x100
- blr
-
.globl _text_base
_text_base:
.long TEXT_BASE
diff --git a/arch/x86/boot/a20.c b/arch/x86/boot/a20.c
index 4b61d91930..ddb40ee5c2 100644
--- a/arch/x86/boot/a20.c
+++ b/arch/x86/boot/a20.c
@@ -14,7 +14,7 @@
*/
#include <asm/segment.h>
-#include <asm/io.h>
+#include <io.h>
#include "boot.h"
#define MAX_8042_LOOPS 100000
diff --git a/arch/x86/boot/prepare_uboot.c b/arch/x86/boot/prepare_uboot.c
index a68aceddb6..79e6fb0cbe 100644
--- a/arch/x86/boot/prepare_uboot.c
+++ b/arch/x86/boot/prepare_uboot.c
@@ -13,7 +13,7 @@
*/
#include <asm/segment.h>
#include <asm/modes.h>
-#include <asm/io.h>
+#include <io.h>
#include "boot.h"
/* be aware of: */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 27ea642527..9cb78e41ec 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -10,6 +10,8 @@
#ifndef __ASM_X86_IO_H
#define __ASM_X86_IO_H
+#include <asm/byteorder.h>
+
static inline void outb(unsigned char value, int port)
{
asm volatile("outb %b0, %w1" : : "a"(value), "Nd"(port));
diff --git a/arch/x86/lib/memory.c b/arch/x86/lib/memory.c
index 9496d2277f..fa7bc03962 100644
--- a/arch/x86/lib/memory.c
+++ b/arch/x86/lib/memory.c
@@ -27,7 +27,7 @@
#include <init.h>
#include <stdio.h>
-#include <mem_malloc.h>
+#include <memory.h>
#include <asm/syslib.h>
#include <asm-generic/memory_layout.h>
diff --git a/arch/x86/mach-i386/generic.c b/arch/x86/mach-i386/generic.c
index edeacc4275..376de58964 100644
--- a/arch/x86/mach-i386/generic.c
+++ b/arch/x86/mach-i386/generic.c
@@ -23,7 +23,7 @@
* @brief x86 Architecture Initialization routines
*/
-#include <asm/io.h>
+#include <io.h>
/** to work with the 8250 UART driver implementation we need this function */
unsigned int x86_uart_read(unsigned long base, unsigned char reg_idx)
diff --git a/arch/x86/mach-i386/pit_timer.c b/arch/x86/mach-i386/pit_timer.c
index ec97cee49b..36019b0ede 100644
--- a/arch/x86/mach-i386/pit_timer.c
+++ b/arch/x86/mach-i386/pit_timer.c
@@ -32,7 +32,7 @@
#include <init.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
/** base address of the PIT in a standard PC */
#define PIT 0x40
diff --git a/commands/bootm.c b/commands/bootm.c
index e5ffacb022..755932b505 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -95,16 +95,28 @@ fixup_silent_linux ()
}
#endif /* CONFIG_SILENT_CONSOLE */
+struct image_handle_data* image_handle_data_get_by_num(struct image_handle* handle, int num)
+{
+ if (!handle || num < 0 || num >= handle->nb_data_entries)
+ return NULL;
+
+ return &handle->data_entries[num];
+}
+
int relocate_image(struct image_handle *handle, void *load_address)
{
image_header_t *hdr = &handle->header;
unsigned long len = image_get_size(hdr);
- unsigned long data = (unsigned long)(handle->data);
+ struct image_handle_data *iha;
+ unsigned long data;
#if defined CONFIG_CMD_BOOTM_ZLIB || defined CONFIG_CMD_BOOTM_BZLIB
uint unc_len = CFG_BOOTM_LEN;
#endif
+ iha = image_handle_data_get_by_num(handle, 0);
+ data = (unsigned long)(iha->data);
+
switch (image_get_comp(hdr)) {
case IH_COMP_NONE:
if(image_get_load(hdr) == data) {
@@ -146,91 +158,32 @@ int relocate_image(struct image_handle *handle, void *load_address)
}
EXPORT_SYMBOL(relocate_image);
-struct image_handle *map_image(const char *filename, int verify)
+static LIST_HEAD(handler_list);
+
+int register_image_handler(struct image_handler *handler)
+{
+ list_add_tail(&handler->list, &handler_list);
+ return 0;
+}
+
+/*
+ * generate a image_handle from a multi_image
+ * this image_handle can be free by unmap_image
+ */
+static struct image_handle *get_fake_image_handle(struct image_data *data, int num)
{
- int fd;
- uint32_t checksum, len;
struct image_handle *handle;
+ struct image_handle_data* iha;
image_header_t *header;
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- printf("could not open: %s\n", errno_str());
- return NULL;
- }
+ iha = image_handle_data_get_by_num(data->os, num);
handle = xzalloc(sizeof(struct image_handle));
header = &handle->header;
-
- if (read(fd, header, image_get_header_size()) < 0) {
- printf("could not read: %s\n", errno_str());
- goto err_out;
- }
-
- if (image_get_magic(header) != IH_MAGIC) {
- puts ("Bad Magic Number\n");
- goto err_out;
- }
-
- checksum = image_get_hcrc(header);
- header->ih_hcrc = 0;
-
- if (crc32 (0, (uchar *)header, image_get_header_size()) != checksum) {
- puts ("Bad Header Checksum\n");
- goto err_out;
- }
- len = image_get_size(header);
-
- handle->data = memmap(fd, PROT_READ);
- if (handle->data == (void *)-1) {
- handle->data = xmalloc(len);
- handle->flags = IH_MALLOC;
- if (read(fd, handle->data, len) < 0) {
- printf("could not read: %s\n", errno_str());
- goto err_out;
- }
- } else {
- handle->data = (void *)((unsigned long)handle->data +
- image_get_header_size());
- }
-
- if (verify) {
- puts (" Verifying Checksum ... ");
- if (crc32 (0, handle->data, len) != image_get_dcrc(header)) {
- printf ("Bad Data CRC\n");
- goto err_out;
- }
- puts ("OK\n");
- }
-
- image_print_contents(header);
-
- close(fd);
+ handle->data_entries = gen_image_handle_data(iha->data, iha->len);
+ handle->data = handle->data_entries[0].data;
return handle;
-err_out:
- close(fd);
- if (handle->flags & IH_MALLOC)
- free(handle->data);
- free(handle);
- return NULL;
-}
-EXPORT_SYMBOL(map_image);
-
-void unmap_image(struct image_handle *handle)
-{
- if (handle->flags & IH_MALLOC)
- free(handle->data);
- free(handle);
-}
-EXPORT_SYMBOL(unmap_image);
-
-static LIST_HEAD(handler_list);
-
-int register_image_handler(struct image_handler *handler)
-{
- list_add_tail(&handler->list, &handler_list);
- return 0;
}
static int initrd_handler_parse_options(struct image_data *data, int opt,
@@ -239,7 +192,14 @@ static int initrd_handler_parse_options(struct image_data *data, int opt,
switch(opt) {
case 'r':
printf("use initrd %s\n", optarg);
- data->initrd = map_image(optarg, data->verify);
+ /* check for multi image @<num> */
+ if (optarg[0] == '@') {
+ int num = simple_strtol(optarg + 1, NULL, 0);
+
+ data->initrd = get_fake_image_handle(data, num);
+ } else {
+ data->initrd = map_image(optarg, data->verify);
+ }
if (!data->initrd)
return -1;
return 0;
diff --git a/common/Kconfig b/common/Kconfig
index 422d1856b1..8e96920e48 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -42,6 +42,15 @@ config HAVE_NOSHELL
menu "General Settings "
+config LOCALVERSION
+ string "Local version - append to the version string"
+ help
+ Append an extra string to the end of your version string.
+ The string you set here will be appended after the contents of
+ any files with a filename matching localversion* in your
+ object and source tree, in that order. Your total string can
+ be a maximum of 64 characters.
+
config LOCALVERSION_AUTO
bool "Automatically append version information to the version string"
default y
@@ -389,23 +398,6 @@ config CONSOLE_ACTIVATE_ALL
Enabling this options activates all consoles on startup, so
you will get output and a prompt on all consoles simultaneously.
-config EARLY_CONSOLE_PORT
- string
- depends on HAS_EARLY_INIT
- prompt "Console device for early output"
- help
- Choose the device on which you want to have early output printed
- to. This is only used during startup when no device information
- is available.
-
-config EARLY_CONSOLE_BAUDRATE
- int
- default 115200
- depends on HAS_EARLY_INIT
- prompt "Early console baudrate"
- help
- Choose the baudrate for your early console.
-
config OF_FLAT_TREE
bool
prompt "Open Firmware flat device tree support"
diff --git a/common/console.c b/common/console.c
index 1f6ee93b4b..06e9c29e8c 100644
--- a/common/console.c
+++ b/common/console.c
@@ -29,7 +29,6 @@
#include <console.h>
#include <driver.h>
#include <fs.h>
-#include <reloc.h>
#include <init.h>
#include <clock.h>
#include <kfifo.h>
@@ -42,10 +41,9 @@ LIST_HEAD(console_list);
EXPORT_SYMBOL(console_list);
#define CONSOLE_UNINITIALIZED 0
-#define CONSOLE_INIT_EARLY 1
-#define CONSOLE_INIT_FULL 2
+#define CONSOLE_INIT_FULL 1
-static int __early_initdata initialized = 0;
+static int initialized = 0;
static int console_std_set(struct device_d *dev, struct param_d *param,
const char *val)
@@ -163,10 +161,8 @@ int console_register(struct console_device *newcdev)
console_output_buffer = NULL;
}
-#ifndef CONFIG_HAS_EARLY_INIT
if (first)
barebox_banner();
-#endif
return 0;
}
@@ -250,26 +246,16 @@ int tstc(void)
}
EXPORT_SYMBOL(tstc);
-#ifdef CONFIG_HAS_EARLY_INIT
-static void __early_initdata *early_console_base;
-#endif
-
void console_putc(unsigned int ch, char c)
{
struct console_device *cdev;
- int init = INITDATA(initialized);
+ int init = initialized;
switch (init) {
case CONSOLE_UNINITIALIZED:
kfifo_putc(console_output_buffer, c);
return;
-#ifdef CONFIG_HAS_EARLY_INIT
- case CONSOLE_INIT_EARLY:
- early_console_putc(INITDATA(early_console_base), c);
- return;
-#endif
-
case CONSOLE_INIT_FULL:
for_each_console(cdev) {
if (cdev->f_active & ch) {
@@ -410,19 +396,3 @@ int ctrlc (void)
}
EXPORT_SYMBOL(ctrlc);
#endif /* ARCH_HAS_CTRC */
-
-#ifdef CONFIG_HAS_EARLY_INIT
-
-void early_console_start(const char *name, int baudrate)
-{
- void *base = get_early_console_base(name);
-
- if (base) {
- early_console_init(base, baudrate);
- INITDATA(initialized) = CONSOLE_INIT_EARLY;
- INITDATA(early_console_base) = base;
- barebox_banner();
- }
-}
-
-#endif
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index f9e1828cbf..7ad368ee53 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -2,7 +2,7 @@
#include <config.h>
#include <malloc.h>
#include <string.h>
-#include <mem_malloc.h>
+#include <memory.h>
#include <stdio.h>
#include <module.h>
diff --git a/common/image.c b/common/image.c
index a4c8b95210..4a6402d8b9 100644
--- a/common/image.c
+++ b/common/image.c
@@ -27,6 +27,10 @@
#include <common.h>
#include <image.h>
#include <rtc.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <fs.h>
#else
#include <time.h>
#endif
@@ -154,14 +158,14 @@ const char *image_get_comp_name(uint8_t comp)
* returns:
* number of components
*/
-ulong image_multi_count(const image_header_t *hdr)
+ulong image_multi_count(void *data)
{
ulong i, count = 0;
uint32_t *size;
/* get start of the image payload, which in case of multi
* component images that points to a table of component sizes */
- size = (uint32_t *)image_get_data (hdr);
+ size = (uint32_t *)data;
/* count non empty slots */
for (i = 0; size[i]; ++i)
@@ -187,23 +191,23 @@ ulong image_multi_count(const image_header_t *hdr)
* data address and size of the component, if idx is valid
* 0 in data and len, if idx is out of range
*/
-void image_multi_getimg(const image_header_t *hdr, ulong idx,
- ulong *data, ulong *len)
+void image_multi_getimg(void *data, ulong idx,
+ ulong *img_data, ulong *len)
{
int i;
uint32_t *size;
- ulong offset, count, img_data;
+ ulong offset, count, tmp_img_data;
/* get number of component */
- count = image_multi_count(hdr);
+ count = image_multi_count(data);
/* get start of the image payload, which in case of multi
* component images that points to a table of component sizes */
- size = (uint32_t *)image_get_data(hdr);
+ size = (uint32_t *)data;
/* get address of the proper component data start, which means
* skipping sizes table (add 1 for last, null entry) */
- img_data = image_get_data(hdr) + (count + 1) * sizeof (uint32_t);
+ tmp_img_data = (ulong)data + (count + 1) * sizeof (uint32_t);
if (idx < count) {
*len = uimage_to_cpu(size[idx]);
@@ -216,10 +220,10 @@ void image_multi_getimg(const image_header_t *hdr, ulong idx,
}
/* calculate idx-th component data address */
- *data = img_data + offset;
+ *img_data = tmp_img_data + offset;
} else {
*len = 0;
- *data = 0;
+ *img_data = 0;
}
}
@@ -262,9 +266,8 @@ void image_print_size(uint32_t size)
#endif
}
-void image_print_contents(const void *ptr)
+void image_print_contents(const image_header_t *hdr, void *data)
{
- const image_header_t *hdr = (const image_header_t *)ptr;
const char *p;
int type;
@@ -289,12 +292,12 @@ void image_print_contents(const void *ptr)
type = image_get_type(hdr);
if (type == IH_TYPE_MULTI || type == IH_TYPE_SCRIPT) {
int i;
- ulong data, len;
- ulong count = image_multi_count(hdr);
+ ulong img_data, len;
+ ulong count = image_multi_count(data);
printf ("%sContents:\n", p);
for (i = 0; i < count; i++) {
- image_multi_getimg(hdr, i, &data, &len);
+ image_multi_getimg(data, i, &img_data, &len);
printf("%s Image %d: ", p, i);
image_print_size(len);
@@ -305,8 +308,125 @@ void image_print_contents(const void *ptr)
* if planning to do something with
* multiple files
*/
- printf("%s Offset = 0x%08lx\n", p, data);
+ printf("%s Offset = 0x%08lx\n", p, img_data);
}
}
}
}
+
+#ifdef __BAREBOX__
+struct image_handle *map_image(const char *filename, int verify)
+{
+ int fd;
+ uint32_t checksum, len;
+ struct image_handle *handle;
+ image_header_t *header;
+ int type;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ printf("could not open: %s\n", errno_str());
+ return NULL;
+ }
+
+ handle = xzalloc(sizeof(struct image_handle));
+ header = &handle->header;
+
+ if (read(fd, header, image_get_header_size()) < 0) {
+ printf("could not read: %s\n", errno_str());
+ goto err_out;
+ }
+
+ if (image_get_magic(header) != IH_MAGIC) {
+ puts ("Bad Magic Number\n");
+ goto err_out;
+ }
+
+ checksum = image_get_hcrc(header);
+ header->ih_hcrc = 0;
+
+ if (crc32 (0, (uchar *)header, image_get_header_size()) != checksum) {
+ puts ("Bad Header Checksum\n");
+ goto err_out;
+ }
+ len = image_get_size(header);
+
+ handle->data = memmap(fd, PROT_READ);
+ if (handle->data == (void *)-1) {
+ handle->data = xmalloc(len);
+ handle->flags = IH_MALLOC;
+ if (read(fd, handle->data, len) < 0) {
+ printf("could not read: %s\n", errno_str());
+ goto err_out;
+ }
+ } else {
+ handle->data = (void *)((unsigned long)handle->data +
+ image_get_header_size());
+ }
+
+ type = image_get_type(header);
+ if (type == IH_TYPE_MULTI) {
+ struct image_handle_data *data_entries;
+ int i;
+ ulong img_data;
+ ulong count = image_multi_count(handle->data);
+
+ data_entries = xzalloc(sizeof(struct image_handle_data) * count);
+
+ for (i = 0; i < count; i++) {
+ image_multi_getimg(handle->data, i, &img_data,
+ &data_entries[i].len);
+
+ data_entries[i].data = (void*)img_data;
+ }
+ handle->data_entries = data_entries;
+ handle->nb_data_entries = count;
+ } else {
+ handle->data_entries = gen_image_handle_data(handle->data, len);
+ handle->nb_data_entries = 1;
+ }
+
+ if (verify) {
+ puts (" Verifying Checksum ... ");
+ if (crc32 (0, handle->data, len) != image_get_dcrc(header)) {
+ printf ("Bad Data CRC\n");
+ goto err_out;
+ }
+ puts ("OK\n");
+ }
+
+ image_print_contents(header, handle->data);
+
+ close(fd);
+
+ return handle;
+err_out:
+ close(fd);
+ if (handle->flags & IH_MALLOC)
+ free(handle->data);
+ free(handle);
+ return NULL;
+}
+EXPORT_SYMBOL(map_image);
+
+void unmap_image(struct image_handle *handle)
+{
+ if (handle->flags & IH_MALLOC)
+ free(handle->data);
+ free(handle->data_entries);
+ free(handle);
+}
+EXPORT_SYMBOL(unmap_image);
+
+struct image_handle_data * gen_image_handle_data(void* data, ulong len)
+{
+ struct image_handle_data *iha;
+
+ iha = xzalloc(sizeof(struct image_handle_data));
+ iha->data = data;
+ iha->len = len;
+
+ return iha;
+}
+EXPORT_SYMBOL(gen_image_handle_data);
+#endif
diff --git a/common/memory.c b/common/memory.c
index 8f4a7681b0..4d59f15fec 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -21,6 +21,7 @@
*/
#include <common.h>
+#include <memory.h>
/*
* Begin and End of memory area for malloc(), and current "brk"
@@ -69,3 +70,20 @@ void *sbrk(ptrdiff_t increment)
return old;
}
+
+LIST_HEAD(memory_banks);
+
+void barebox_add_memory_bank(const char *name, resource_size_t start,
+ resource_size_t size)
+{
+ struct memory_bank *bank = xzalloc(sizeof(*bank));
+ struct device_d *dev;
+
+ dev = add_mem_device(name, start, size, IORESOURCE_MEM_WRITEABLE);
+
+ bank->dev = dev;
+ bank->start = start;
+ bank->size = size;
+
+ list_add_tail(&bank->list, &memory_banks);
+}
diff --git a/common/startup.c b/common/startup.c
index bf67aef152..13783fb27a 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -33,12 +33,11 @@
#include <init.h>
#include <command.h>
#include <malloc.h>
-#include <mem_malloc.h>
+#include <memory.h>
#include <debug_ll.h>
#include <fs.h>
#include <linux/stat.h>
#include <environment.h>
-#include <reloc.h>
#include <asm-generic/memory_layout.h>
#include <asm/sections.h>
@@ -62,23 +61,6 @@ static void display_meminfo(void)
#endif
}
-#ifdef CONFIG_HAS_EARLY_INIT
-
-#define EARLY_INITDATA (CFG_INIT_RAM_ADDR + CFG_INIT_RAM_SIZE \
- - CONFIG_EARLY_INITDATA_SIZE)
-
-void *init_data_ptr = (void *)EARLY_INITDATA;
-
-void early_init (void)
-{
- /* copy the early initdata segment to early init RAM */
- memcpy((void *)EARLY_INITDATA, RELOC(&__early_init_data_begin),
- (ulong)&__early_init_data_end -
- (ulong)&__early_init_data_begin);
-}
-
-#endif /* CONFIG_HAS_EARLY_INIT */
-
#ifdef CONFIG_DEFAULT_ENVIRONMENT
#include <generated/barebox_default_env.h>
@@ -112,16 +94,6 @@ void start_barebox (void)
struct stat s;
#endif
-#ifdef CONFIG_HAS_EARLY_INIT
- /* We are running from RAM now, copy early initdata from
- * early RAM to RAM
- */
- memcpy(&__early_init_data_begin, init_data_ptr,
- (ulong)&__early_init_data_end -
- (ulong)&__early_init_data_begin);
- init_data_ptr = &__early_init_data_begin;
-#endif /* CONFIG_HAS_EARLY_INIT */
-
for (initcall = __barebox_initcalls_start;
initcall < __barebox_initcalls_end; initcall++) {
PUTS_LL("<<");
diff --git a/common/version.c b/common/version.c
index 945475fc3d..0af8ec160a 100644
--- a/common/version.c
+++ b/common/version.c
@@ -1,5 +1,4 @@
#include <common.h>
-#include <reloc.h>
#include <generated/utsrelease.h>
const char version_string[] =
@@ -7,7 +6,7 @@ const char version_string[] =
void barebox_banner (void)
{
- printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string));
- printf(RELOC("Board: " CONFIG_BOARDINFO "\n"));
+ printf("\n\n%s\n\n", version_string);
+ printf("Board: " CONFIG_BOARDINFO "\n");
}
diff --git a/defaultenv/bin/_update_help b/defaultenv/bin/_update_help
index 98096daecc..92d677234a 100644
--- a/defaultenv/bin/_update_help
+++ b/defaultenv/bin/_update_help
@@ -7,7 +7,7 @@ echo "options"
echo " -c to check the crc32 for the image and flashed one"
echo ""
echo "default mode is tftp"
-echo "type update -t kernel -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update kernel into flash"
+echo "type update -t kernel -d <nor|nand|disk> [-m tftp|xmodem] [-f imagename] to update kernel into flash"
echo "type update -t rootfs -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update rootfs into flash"
echo "type update -t barebox -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update barebox into flash"
echo "type update -t bareboxenv -d <nor|nand> [-m tftp|xmodem] [-f imagename] to update bareboxenv into flash"
diff --git a/defaultenv/bin/boot b/defaultenv/bin/boot
index de4fa24f27..652ae0c2ba 100644
--- a/defaultenv/bin/boot
+++ b/defaultenv/bin/boot
@@ -2,6 +2,10 @@
. /env/config
+if [ x$kernel_loc = xnet ]; then
+ kernel_loc=tftp
+fi
+
if [ x$1 = xnand ]; then
rootfs_loc=nand
kernel_loc=nand
@@ -14,6 +18,9 @@ elif [ x$1 = xnfs ]; then
elif [ x$1 = xtftp ]; then
rootfs_loc=net
kernel_loc=tftp
+elif [ x$1 = xdisk ]; then
+ rootfs_loc=disk
+ kernel_loc=disk
fi
if [ x$ip = xdhcp ]; then
@@ -21,12 +28,14 @@ if [ x$ip = xdhcp ]; then
elif [ x$ip = xnone ]; then
bootargs="$bootargs ip=none"
else
- bootargs="$bootargs ip=$eth0.ipaddr::$eth0.gateway:$eth0.netmask:::"
+ bootargs="$bootargs ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask::eth0:"
fi
if [ x$rootfs_loc = xnet ]; then
bootargs="$bootargs root=/dev/nfs nfsroot=$nfsroot,v3,tcp noinitrd"
+elif [ x$rootfs_loc = xdisk ]; then
+ bootargs="$bootargs root=/dev/$rootfs_part_linux_dev rootfstype=$rootfs_type noinitrd rootwait"
elif [ x$rootfs_loc = xinitrd ]; then
bootargs="$bootargs root=/dev/ram0 rdinit=/sbin/init"
else
@@ -74,7 +83,7 @@ if [ ! -e /dev/ram0.kernel ]; then
addpart /dev/ram0 8M@8M(kernel)
fi
-if [ x$kernel_loc = xnfs ] || [ x$kernel_loc = xtftp ]; then
+if [ x$kernel_loc = xnfs -o x$kernel_loc = xtftp ]; then
if [ x$ip = xdhcp ]; then
dhcp
fi
@@ -96,8 +105,10 @@ elif [ x$kernel_loc = xnor ]; then
kdev="/dev/nor0.kernel"
elif [ x$kernel_loc = xnand ]; then
kdev="/dev/nand0.kernel.bb"
+elif [ x$kernel_loc = xdisk ]; then
+ kdev="/dev/$kernel_part"
else
- echo "error: set kernel_loc to one of 'nfs', 'tftp', 'nand' or 'nor'"
+ echo "error: set kernel_loc to one of 'tftp', 'nfs', 'nand', 'nor' or 'disk'"
exit 1
fi
diff --git a/defaultenv/bin/update b/defaultenv/bin/update
index 55ac10b95d..39e759145f 100644
--- a/defaultenv/bin/update
+++ b/defaultenv/bin/update
@@ -27,17 +27,18 @@ done
if [ x${type} = xkernel ]; then
image=$kernelimage
+ disk_part=$kernel_part
elif [ x${type} = xrootfs ]; then
image=$rootfsimage
type=root
elif [ x${type} = xbarebox ]; then
image=$bareboximage
- if [ x${image} = x ]; then
+ if [ -z ${image} ]; then
image=barebox.bin
fi
elif [ x${type} = xbareboxenv ]; then
image=$bareboxenvimage
- if [ x${image} = x ]; then
+ if [ -z ${image} ]; then
image=bareboxenv.bin
fi
elif [ x${type} = xxload ]; then
@@ -47,7 +48,7 @@ else
exit 1
fi
-if [ x${imagename} != x ]; then
+if [ -n ${imagename} ]; then
image=${imagename}
fi
@@ -55,12 +56,14 @@ if [ x${device_type} = xnand ]; then
part=/dev/nand0.${type}.bb
elif [ x${device_type} = xnor ]; then
part=/dev/nor0.${type}
+elif [ x${device_type} = xdisk ]; then
+ part=/dev/${disk_part}
else
. /env/bin/_update_help
exit 1
fi
-if [ x${mode} != xtftp ] && [ x${mode} != xxmodem ] ; then
+if [ x${mode} != xtftp -a x${mode} != xxmodem ] ; then
echo "unsupported mode ${mode}."
. /env/bin/_update_help
exit 1
diff --git a/defaultenv/config b/defaultenv/config
new file mode 100644
index 0000000000..0aaead5ccb
--- /dev/null
+++ b/defaultenv/config
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+machine=FIXME
+#user=
+
+# Enter MAC address here if not retrieved automatically
+#eth0.ethaddr=de:ad:be:ef:00:00
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.netmask=a.b.c.d
+#eth0.serverip=a.b.c.d
+#eth0.gateway=a.b.c.d
+
+# can be either 'tftp', 'nfs', 'nand', 'nor' or 'disk'
+kernel_loc=tftp
+# can be either 'net', 'nand', 'nor', 'disk' or 'initrd'
+rootfs_loc=net
+
+# for flash based rootfs: 'jffs2' or 'ubifs'
+# in case of disk any regular filesystem like 'ext2', 'ext3', 'reiserfs'
+rootfs_type=ubifs
+# where is the rootfs in case of 'rootfs_loc=disk' (linux name)
+rootfs_part_linux_dev=mmcblk0p4
+rootfsimage=rootfs-${machine}.$rootfs_type
+
+# where is the kernel image in case of 'kernel_loc=disk'
+kernel_part=disk0.2
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+kernelimage_type=zimage
+kernelimage=zImage-$machine
+#kernelimage_type=uimage
+#kernelimage=uImage-$machine
+#kernelimage_type=raw
+#kernelimage=Image-$machine
+#kernelimage_type=raw_lzo
+#kernelimage=Image-$machine.lzo
+
+bareboximage=barebox-${machine}.bin
+bareboxenvimage=barebox-${machine}.bin
+
+if [ -n $user ]; then
+ bareboximage="$user"-"$bareboximage"
+ bareboxenvimage="$user"-"$bareboxenvimage"
+ kernelimage="$user"-"$kernelimage"
+ rootfsimage="$user"-"$rootfsimage"
+ nfsroot="/home/$user/nfsroot/$machine"
+else
+ nfsroot="/path/to/nfs/root"
+fi
+
+autoboot_timeout=3
+
+bootargs="console=ttyFIXME,115200"
+
+nor_parts="256k(barebox)ro,128k(bareboxenv),3M(kernel),-(root)"
+rootfs_mtdblock_nor=3
+
+nand_parts="256k(barebox)ro,128k(bareboxenv),3M(kernel),-(root)"
+nand_device="FIXME"
+rootfs_mtdblock_nand=7
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m "
diff --git a/drivers/base/resource.c b/drivers/base/resource.c
index 175beb9c2d..5c9c16c591 100644
--- a/drivers/base/resource.c
+++ b/drivers/base/resource.c
@@ -41,33 +41,42 @@ struct device_d *add_generic_device(const char* devname, int id, const char *res
resource_size_t start, resource_size_t size, unsigned int flags,
void *pdata)
{
+ struct resource *res;
+
+ res = xzalloc(sizeof(struct resource));
+ if (resname)
+ res[0].name = xstrdup(resname);
+ res[0].start = start;
+ res[0].size = size;
+ res[0].flags = flags;
+
+ return add_generic_device_res(devname, id, res, 1, pdata);
+}
+EXPORT_SYMBOL(add_generic_device);
+
+struct device_d *add_generic_device_res(const char* devname, int id,
+ struct resource *res, int nb, void *pdata)
+{
struct device_d *dev;
dev = alloc_device(devname, id, pdata);
- dev->resource = xzalloc(sizeof(struct resource));
- dev->num_resources = 1;
- if (resname)
- dev->resource[0].name = xstrdup(resname);
- dev->resource[0].start = start;
- dev->resource[0].size = size;
- dev->resource[0].flags = flags;
+ dev->resource = res;
+ dev->num_resources = nb;
register_device(dev);
return dev;
}
-EXPORT_SYMBOL(add_generic_device);
+EXPORT_SYMBOL(add_generic_device_res);
#ifdef CONFIG_DRIVER_NET_DM9000
struct device_d *add_dm9000_device(int id, resource_size_t base,
resource_size_t data, int flags, void *pdata)
{
- struct device_d *dev;
+ struct resource *res;
resource_size_t size;
- dev = alloc_device("dm9000", id, pdata);
- dev->resource = xzalloc(sizeof(struct resource) * 2);
- dev->num_resources = 2;
+ res = xzalloc(sizeof(struct resource) * 2);
switch (flags) {
case IORESOURCE_MEM_32BIT:
@@ -84,16 +93,14 @@ struct device_d *add_dm9000_device(int id, resource_size_t base,
return NULL;
}
- dev->resource[0].start = base;
- dev->resource[0].size = size;
- dev->resource[0].flags = IORESOURCE_MEM | flags;
- dev->resource[1].start = data;
- dev->resource[1].size = size;
- dev->resource[1].flags = IORESOURCE_MEM | flags;
+ res[0].start = base;
+ res[0].size = size;
+ res[0].flags = IORESOURCE_MEM | flags;
+ res[1].start = data;
+ res[1].size = size;
+ res[1].flags = IORESOURCE_MEM | flags;
- register_device(dev);
-
- return dev;
+ return add_generic_device_res("dm9000", id, res, 2, pdata);
}
EXPORT_SYMBOL(add_dm9000_device);
#endif
@@ -102,34 +109,15 @@ EXPORT_SYMBOL(add_dm9000_device);
struct device_d *add_usb_ehci_device(int id, resource_size_t hccr,
resource_size_t hcor, void *pdata)
{
- struct device_d *dev;
-
- dev = alloc_device("ehci", id, pdata);
- dev->resource = xzalloc(sizeof(struct resource) * 2);
- dev->num_resources = 2;
- dev->resource[0].start = hccr;
- dev->resource[0].flags = IORESOURCE_MEM;
- dev->resource[1].start = hcor;
- dev->resource[1].flags = IORESOURCE_MEM;
+ struct resource *res;
- register_device(dev);
+ res = xzalloc(sizeof(struct resource) * 2);
+ res[0].start = hccr;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = hcor;
+ res[1].flags = IORESOURCE_MEM;
- return dev;
+ return add_generic_device_res("ehci", id, res, 2, pdata);
}
EXPORT_SYMBOL(add_usb_ehci_device);
#endif
-
-#ifdef CONFIG_ARM
-#include <asm/armlinux.h>
-
-struct device_d *arm_add_mem_device(const char* name, resource_size_t start,
- resource_size_t size)
-{
- struct device_d *dev;
-
- dev = add_mem_device(name, start, size, IORESOURCE_MEM_WRITEABLE);
- armlinux_add_dram(dev);
-
- return dev;
-}
-#endif
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 2d075f72ca..da6218f43c 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -44,7 +44,7 @@
#include <linux/err.h>
-#include <asm/io.h>
+#include <io.h>
#include <i2c/i2c.h>
#include <mach/generic.h>
#include <mach/clock.h>
@@ -314,19 +314,21 @@ static int i2c_imx_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
void __iomem *base = i2c_imx->base;
int i, result;
- dev_dbg(adapter->dev,
- "<%s> write slave address: addr=0x%02x\n",
- __func__, msgs->addr << 1);
+ if ( !(msgs->flags & I2C_M_DATA_ONLY) ) {
+ dev_dbg(adapter->dev,
+ "<%s> write slave address: addr=0x%02x\n",
+ __func__, msgs->addr << 1);
- /* write slave address */
- writeb(msgs->addr << 1, base + IMX_I2C_I2DR);
+ /* write slave address */
+ writeb(msgs->addr << 1, base + IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(adapter);
- if (result)
- return result;
- result = i2c_imx_acked(adapter);
- if (result)
- return result;
+ result = i2c_imx_trx_complete(adapter);
+ if (result)
+ return result;
+ result = i2c_imx_acked(adapter);
+ if (result)
+ return result;
+ }
/* write data */
for (i = 0; i < msgs->len; i++) {
@@ -352,22 +354,24 @@ static int i2c_imx_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
int i, result;
unsigned int temp;
- dev_dbg(adapter->dev,
- "<%s> write slave address: addr=0x%02x\n",
- __func__, (msgs->addr << 1) | 0x01);
-
/* clear IIF */
writeb(0x0, base + IMX_I2C_I2SR);
- /* write slave address */
- writeb((msgs->addr << 1) | 0x01, base + IMX_I2C_I2DR);
+ if ( !(msgs->flags & I2C_M_DATA_ONLY) ) {
+ dev_dbg(adapter->dev,
+ "<%s> write slave address: addr=0x%02x\n",
+ __func__, (msgs->addr << 1) | 0x01);
- result = i2c_imx_trx_complete(adapter);
- if (result)
- return result;
- result = i2c_imx_acked(adapter);
- if (result)
- return result;
+ /* write slave address */
+ writeb((msgs->addr << 1) | 0x01, base + IMX_I2C_I2DR);
+
+ result = i2c_imx_trx_complete(adapter);
+ if (result)
+ return result;
+ result = i2c_imx_acked(adapter);
+ if (result)
+ return result;
+ }
/* setup bus to read data */
temp = readb(base + IMX_I2C_I2CR);
@@ -428,7 +432,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
/* read/write data */
for (i = 0; i < num; i++) {
- if (i) {
+ if (i && !(msgs[i].flags & I2C_M_DATA_ONLY)) {
temp = readb(base + IMX_I2C_I2CR);
temp |= I2CR_RSTA;
writeb(temp, base + IMX_I2C_I2CR);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 95c4fdf782..2a1ae7af75 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,7 +43,7 @@
#include <linux/err.h>
-#include <asm/io.h>
+#include <io.h>
#include <i2c/i2c.h>
#include <mach/generic.h>
#include <mach/omap3-clock.h>
diff --git a/drivers/mci/atmel_mci.c b/drivers/mci/atmel_mci.c
index 71aec16fa2..4a29cad18f 100644
--- a/drivers/mci/atmel_mci.c
+++ b/drivers/mci/atmel_mci.c
@@ -20,9 +20,10 @@
#include <errno.h>
#include <clock.h>
#include <gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/board.h>
#include <linux/clk.h>
+#include <linux/err.h>
#include "at91_mci.h"
@@ -461,9 +462,9 @@ static int mci_probe(struct device_d *hw_dev)
host->hw_dev = hw_dev;
hw_dev->priv = host;
host->clk = clk_get(hw_dev, "mci_clk");
- if (host->clk == NULL) {
+ if (IS_ERR(host->clk)) {
dev_err(hw_dev, "no mci_clk\n");
- return -EINVAL;
+ return PTR_ERR(host->clk);
}
clk_rate = clk_get_rate(host->clk);
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 358f0dc25c..a0e61f0d01 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -32,7 +32,7 @@
#include <malloc.h>
#include <mci.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/mmu.h>
#include <mach/clock.h>
#include <mach/generic.h>
diff --git a/drivers/mci/imx.c b/drivers/mci/imx.c
index 905c251db3..50c98e1cef 100644
--- a/drivers/mci/imx.c
+++ b/drivers/mci/imx.c
@@ -26,7 +26,7 @@
#include <init.h>
#include <driver.h>
#include <mach/clock.h>
-#include <asm/io.h>
+#include <io.h>
#define DRIVER_NAME "imx-mmc"
diff --git a/drivers/mci/mxs.c b/drivers/mci/mxs.c
index eda9250885..4b8bd75b34 100644
--- a/drivers/mci/mxs.c
+++ b/drivers/mci/mxs.c
@@ -39,7 +39,7 @@
#include <mci.h>
#include <errno.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/bitops.h>
#include <mach/imx-regs.h>
#include <mach/mci.h>
diff --git a/drivers/mci/omap_hsmmc.c b/drivers/mci/omap_hsmmc.c
index 5fdf445c70..3f70e22629 100644
--- a/drivers/mci/omap_hsmmc.c
+++ b/drivers/mci/omap_hsmmc.c
@@ -29,7 +29,9 @@
#include <mci.h>
#include <clock.h>
#include <errno.h>
-#include <asm/io.h>
+#include <io.h>
+
+#include <mach/omap_hsmmc.h>
struct hsmmc {
unsigned char res1[0x10];
@@ -549,6 +551,7 @@ static void mmc_set_ios(struct mci_host *mci, struct device_d *dev,
static int omap_mmc_probe(struct device_d *dev)
{
struct omap_hsmmc *hsmmc;
+ struct omap_hsmmc_platform_data *pdata;
hsmmc = xzalloc(sizeof(*hsmmc));
@@ -564,7 +567,12 @@ static int omap_mmc_probe(struct device_d *dev)
hsmmc->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
hsmmc->mci.f_min = 400000;
- hsmmc->mci.f_max = 52000000;
+
+ pdata = (struct omap_hsmmc_platform_data *)dev->platform_data;
+ if (pdata->f_max)
+ hsmmc->mci.f_max = pdata->f_max;
+ else
+ hsmmc->mci.f_max = 52000000;
mci_register(&hsmmc->mci);
diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
index c621445e5c..f97e13a6dd 100644
--- a/drivers/mci/s3c.c
+++ b/drivers/mci/s3c.c
@@ -39,7 +39,7 @@
#include <mci.h>
#include <errno.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/mci.h>
#include <mach/s3c24xx-generic.h>
#include <mach/s3c24x0-iomap.h>
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index f79be9a3c6..8cc1b51f7f 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -31,7 +31,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/board.h>
#include <errno.h>
@@ -399,13 +399,13 @@ static int __init atmel_nand_probe(struct device_d *dev)
if (host->board->rdy_pin)
nand_chip->dev_ready = atmel_nand_device_ready;
- nand_chip->ecc.mode = pdata->ecc_mode;
+ nand_chip->ecc.mode = NAND_ECC_SOFT;
if (pdata->ecc_mode == NAND_ECC_HW) {
- if (!pdata->ecc_base)
- return -ENODEV;
+ host->ecc = dev_request_mem_region(dev, 1);
- host->ecc = pdata->ecc_base;
+ if (!host->ecc)
+ return -ENODEV;
nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.calculate = atmel_nand_calculate;
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e762524540..2433945571 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -29,7 +29,7 @@
#include <linux/delay.h>
#include <linux/rslib.h>
#include <linux/moduleparam.h>
-#include <asm/io.h>
+#include <io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5e122a10a5..2710f6a309 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -39,7 +39,7 @@
#include <linux/err.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/byteorder.h>
-#include <asm/io.h>
+#include <io.h>
#include <malloc.h>
#include <module.h>
diff --git a/drivers/mtd/nand/nand_hwecc.c b/drivers/mtd/nand/nand_hwecc.c
index 95b08d3a79..5ead49c60c 100644
--- a/drivers/mtd/nand/nand_hwecc.c
+++ b/drivers/mtd/nand/nand_hwecc.c
@@ -6,7 +6,7 @@
#include <linux/err.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/byteorder.h>
-#include <asm/io.h>
+#include <io.h>
#include <malloc.h>
#include "nand.h"
diff --git a/drivers/mtd/nand/nand_hwecc_syndrome.c b/drivers/mtd/nand/nand_hwecc_syndrome.c
index 9a66180952..dd067c9970 100644
--- a/drivers/mtd/nand/nand_hwecc_syndrome.c
+++ b/drivers/mtd/nand/nand_hwecc_syndrome.c
@@ -6,7 +6,7 @@
#include <linux/err.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/byteorder.h>
-#include <asm/io.h>
+#include <io.h>
#include <malloc.h>
#include <module.h>
diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index e471c8a719..581136aed4 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -27,7 +27,7 @@
#include <mach/generic.h>
#include <mach/imx-nand.h>
#include <mach/imx-regs.h>
-#include <asm/io.h>
+#include <io.h>
#include <errno.h>
#define NFC_V3_FLASH_CMD (host->regs_axi + 0x00)
@@ -1034,9 +1034,6 @@ static int __init imxnd_probe(struct device_d *dev)
return -ENOMEM;
host->data_buf = (uint8_t *)(host + 1);
- host->base = dev_request_mem_region(dev, 0);
-
- host->main_area0 = host->base;
if (nfc_is_v1() || nfc_is_v21()) {
host->preset = preset_v1_v2;
@@ -1049,21 +1046,32 @@ static int __init imxnd_probe(struct device_d *dev)
}
if (nfc_is_v21()) {
+ host->base = dev_request_mem_region(dev, 0);
+ host->main_area0 = host->base;
host->regs = host->base + 0x1e00;
host->spare0 = host->base + 0x1000;
host->spare_len = 64;
oob_smallpage = &nandv2_hw_eccoob_smallpage;
oob_largepage = &nandv2_hw_eccoob_largepage;
} else if (nfc_is_v1()) {
+ host->base = dev_request_mem_region(dev, 0);
+ host->main_area0 = host->base;
host->regs = host->base + 0xe00;
host->spare0 = host->base + 0x800;
host->spare_len = 16;
oob_smallpage = &nandv1_hw_eccoob_smallpage;
oob_largepage = &nandv1_hw_eccoob_largepage;
} else if (nfc_is_v3_2()) {
-#ifdef CONFIG_ARCH_IMX51
- host->regs_ip = (void *)MX51_NFC_BASE_ADDR;
-#endif
+ host->regs_ip = dev_request_mem_region(dev, 0);
+ host->base = dev_request_mem_region(dev, 1);
+ host->main_area0 = host->base;
+
+ if (!host->regs_ip) {
+ dev_err(dev, "no second mem region\n");
+ err = -ENODEV;
+ goto escan;
+ }
+
host->regs_axi = host->base + 0x1e00;
host->spare0 = host->base + 0x1000;
host->spare_len = 64;
@@ -1083,6 +1091,7 @@ static int __init imxnd_probe(struct device_d *dev)
this = &host->nand;
mtd = &host->mtd;
mtd->priv = this;
+ mtd->dev = dev;
/* 50 us command delay time */
this->chip_delay = 5;
diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index 083aa57520..a012c03dec 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -71,7 +71,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/silicon.h>
#include <mach/gpmc.h>
#include <mach/gpmc_nand.h>
diff --git a/drivers/mtd/nand/nand_s3c2410.c b/drivers/mtd/nand/nand_s3c2410.c
index 0ce20d42c3..c5f5d97db3 100644
--- a/drivers/mtd/nand/nand_s3c2410.c
+++ b/drivers/mtd/nand/nand_s3c2410.c
@@ -33,7 +33,7 @@
#include <mach/s3c24xx-generic.h>
#include <mach/s3c24x0-iomap.h>
#include <mach/s3c24x0-nand.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm-generic/errno.h>
#ifdef CONFIG_S3C24XX_NAND_BOOT
diff --git a/drivers/mtd/nand/nand_swecc.c b/drivers/mtd/nand/nand_swecc.c
index 93511cbe3d..a5edffaece 100644
--- a/drivers/mtd/nand/nand_swecc.c
+++ b/drivers/mtd/nand/nand_swecc.c
@@ -6,7 +6,7 @@
#include <linux/err.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/byteorder.h>
-#include <asm/io.h>
+#include <io.h>
#include <malloc.h>
#include "nand.h"
diff --git a/drivers/mtd/nand/nand_write.c b/drivers/mtd/nand/nand_write.c
index 3ede8d02f0..13b6c8984f 100644
--- a/drivers/mtd/nand/nand_write.c
+++ b/drivers/mtd/nand/nand_write.c
@@ -6,7 +6,7 @@
#include <linux/err.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/byteorder.h>
-#include <asm/io.h>
+#include <io.h>
#include <malloc.h>
#include <module.h>
diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c
index 3073011614..c1e93ad076 100644
--- a/drivers/mtd/nand/nomadik_nand.c
+++ b/drivers/mtd/nand/nomadik_nand.c
@@ -30,7 +30,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/nand.h>
#include <mach/fsmc.h>
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index 7e456c762e..5163488183 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -31,7 +31,7 @@
#include <clock.h>
#include <linux/mii.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/dma-mapping.h>
#include "altera_tse.h"
diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c
index 33afc5e0f3..da23755a5e 100644
--- a/drivers/net/cs8900.c
+++ b/drivers/net/cs8900.c
@@ -27,7 +27,7 @@
#include <net.h>
#include <malloc.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#include <errno.h>
/* I/O ports for I/O Space operation */
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index e9ec61b37d..f32778135d 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -50,7 +50,7 @@
#include <malloc.h>
#include <net.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <xfuncs.h>
#include <dm9000.h>
#include <errno.h>
diff --git a/drivers/net/ep93xx.c b/drivers/net/ep93xx.c
index 954ec789f3..227e317492 100644
--- a/drivers/net/ep93xx.c
+++ b/drivers/net/ep93xx.c
@@ -35,7 +35,7 @@
#include <init.h>
#include <malloc.h>
#include <miidev.h>
-#include <asm/io.h>
+#include <io.h>
#include <linux/types.h>
#include <mach/ep93xx-regs.h>
#include "ep93xx.h"
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 3b0f266a2b..ae63fdc3b5 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -28,7 +28,7 @@
#include <fec.h>
#include <asm/mmu.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/generic.h>
#include <mach/imx-regs.h>
#include <clock.h>
diff --git a/drivers/net/fec_mpc5200.c b/drivers/net/fec_mpc5200.c
index 403aad5235..001a3a0355 100644
--- a/drivers/net/fec_mpc5200.c
+++ b/drivers/net/fec_mpc5200.c
@@ -697,9 +697,17 @@ int mpc5xxx_fec_probe(struct device_d *dev)
return 0;
}
+static void mpc5xxx_fec_remove(struct device_d *dev)
+{
+ struct eth_device *edev = dev->type_data;
+
+ mpc5xxx_fec_halt(edev);
+}
+
static struct driver_d mpc5xxx_driver = {
.name = "fec_mpc5xxx",
.probe = mpc5xxx_fec_probe,
+ .remove = mpc5xxx_fec_remove,
};
static int mpc5xxx_fec_register(void)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 898cf3d1ab..c1f7f68484 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -46,9 +46,10 @@
#include <init.h>
#include <miidev.h>
#include <errno.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/board.h>
#include <linux/clk.h>
+#include <linux/err.h>
#include "macb.h"
@@ -392,7 +393,7 @@ static int macb_get_ethaddr(struct eth_device *edev, unsigned char *adr)
static int macb_set_ethaddr(struct eth_device *edev, unsigned char *adr)
{
- struct macb_device *macb = edev->priv;
+ struct macb_device *macb = edev->priv;
debug("%s\n", __func__);
@@ -444,7 +445,7 @@ static int macb_probe(struct device_d *dev)
macb->miidev.parent = dev;
macb->flags = pdata->flags;
- macb->rx_buffer = xmalloc(CFG_MACB_RX_BUFFER_SIZE);
+ macb->rx_buffer = xmalloc(CFG_MACB_RX_BUFFER_SIZE);
macb->rx_ring = xmalloc(CFG_MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc));
macb->tx_ring = xmalloc(sizeof(struct macb_dma_desc));
@@ -456,6 +457,11 @@ static int macb_probe(struct device_d *dev)
*/
#if defined(CONFIG_ARCH_AT91)
pclk = clk_get(dev, "macb_clk");
+ if (IS_ERR(pclk)) {
+ dev_err(dev, "no macb_clk\n");
+ return PTR_ERR(pclk);
+ }
+
clk_enable(pclk);
macb_hz = clk_get_rate(pclk);
#else
@@ -479,15 +485,15 @@ static int macb_probe(struct device_d *dev)
}
static struct driver_d macb_driver = {
- .name = "macb",
- .probe = macb_probe,
+ .name = "macb",
+ .probe = macb_probe,
};
static int macb_driver_init(void)
{
debug("%s\n", __func__);
- register_driver(&macb_driver);
- return 0;
+ register_driver(&macb_driver);
+ return 0;
}
device_initcall(macb_driver_init);
diff --git a/drivers/net/netx_eth.c b/drivers/net/netx_eth.c
index 5503bc94dd..81a7ff4fcd 100644
--- a/drivers/net/netx_eth.c
+++ b/drivers/net/netx_eth.c
@@ -1,7 +1,7 @@
#include <common.h>
#include <command.h>
#include <net.h>
-#include <asm/io.h>
+#include <io.h>
#include <miidev.h>
#include <mach/netx-xc.h>
#include <mach/netx-eth.h>
diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c
index 2313aaeb63..c51f8c7291 100644
--- a/drivers/net/smc91111.c
+++ b/drivers/net/smc91111.c
@@ -73,7 +73,7 @@
#include <xfuncs.h>
#include <errno.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
/*---------------------------------------------------------------
.
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index fba61c460f..e34c0df90d 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -36,7 +36,7 @@
#include <xfuncs.h>
#include <errno.h>
#include <clock.h>
-#include <asm/io.h>
+#include <io.h>
#define AS CONFIG_DRIVER_NET_SMC911X_ADDRESS_SHIFT
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 7b25adb3ac..654e6470c1 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -40,7 +40,7 @@
#include <clock.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <errno.h>
#include <progress.h>
#include "cfi_flash.h"
@@ -822,26 +822,12 @@ int flash_generic_status_check (struct flash_info *info, flash_sect_t sector,
*/
void flash_make_cmd(struct flash_info *info, u32 cmd, cfiword_t *cmdbuf)
{
- int i;
- int cp_offset;
- int cword_offset;
- uchar val;
- uchar *cp;
-
- *cmdbuf = 0;
- cp = (uchar *)cmdbuf;
+ cfiword_t result = 0;
+ int i = info->portwidth / info->chipwidth;
- for (i = info->portwidth; i > 0; i--) {
- cword_offset = (info->portwidth-i) % info->chipwidth;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- cp_offset = info->portwidth - i;
- val = *((uchar *)&cmd + cword_offset);
-#else
- cp_offset = i - 1;
- val = *((uchar *)&cmd + sizeof(u32) - cword_offset - 1);
-#endif
- cp[cp_offset] = (cword_offset >= sizeof(u32)) ? 0x00 : val;
- }
+ while (i--)
+ result = (result << (8 * info->chipwidth)) | cmd;
+ *cmdbuf = result;
}
/*
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index 32dcc8c5e0..df482b6c56 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -26,7 +26,7 @@
#include <driver.h>
#include <asm/byteorder.h>
-#include <asm/io.h>
+#include <io.h>
#include <linux/mtd/mtd.h>
typedef unsigned long flash_sect_t;
@@ -247,17 +247,17 @@ void flash_make_cmd(struct flash_info *info, u32 cmd, cfiword_t *cmdbuf);
static inline void flash_write8(u8 value, void *addr)
{
- writeb(value, addr);
+ cpu_writeb(value, addr);
}
static inline void flash_write16(u16 value, void *addr)
{
- writew(value, addr);
+ cpu_writew(value, addr);
}
static inline void flash_write32(u32 value, void *addr)
{
- writel(value, addr);
+ cpu_writel(value, addr);
}
static inline void flash_write64(u64 value, void *addr)
@@ -267,17 +267,17 @@ static inline void flash_write64(u64 value, void *addr)
static inline u8 flash_read8(void *addr)
{
- return readb(addr);
+ return cpu_readb(addr);
}
static inline u16 flash_read16(void *addr)
{
- return readw(addr);
+ return cpu_readw(addr);
}
static inline u32 flash_read32(void *addr)
{
- return readl(addr);
+ return cpu_readl(addr);
}
static inline u64 flash_read64(void *addr)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 2b6d5d384c..148bdbf576 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -31,7 +31,7 @@
#include <driver.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <linux/amba/serial.h>
#include <linux/clk.h>
#include <linux/err.h>
diff --git a/drivers/serial/atmel.c b/drivers/serial/atmel.c
index 2d4b842420..9ba4ca9dab 100644
--- a/drivers/serial/atmel.c
+++ b/drivers/serial/atmel.c
@@ -21,7 +21,7 @@
#include <driver.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <linux/clk.h>
/* USART3 register offsets */
diff --git a/drivers/serial/serial_altera.c b/drivers/serial/serial_altera.c
index 1148564b9e..8fd5d8a1a0 100644
--- a/drivers/serial/serial_altera.c
+++ b/drivers/serial/serial_altera.c
@@ -24,7 +24,7 @@
#include <driver.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/nios2-io.h>
struct altera_serial_priv {
diff --git a/drivers/serial/serial_altera_jtag.c b/drivers/serial/serial_altera_jtag.c
index 2e34c894a4..3e1b0cf6e1 100644
--- a/drivers/serial/serial_altera_jtag.c
+++ b/drivers/serial/serial_altera_jtag.c
@@ -27,7 +27,7 @@
#include <driver.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/nios2-io.h>
struct altera_serial_jtag_priv {
diff --git a/drivers/serial/serial_at91rm9200.c b/drivers/serial/serial_at91rm9200.c
index f5546aa758..9bdc626e4d 100644
--- a/drivers/serial/serial_at91rm9200.c
+++ b/drivers/serial/serial_at91rm9200.c
@@ -30,7 +30,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/hardware.h>
#if !defined(CONFIG_DBGU) && !defined(CONFIG_USART0) && !defined(CONFIG_USART1)
diff --git a/drivers/serial/serial_blackfin.c b/drivers/serial/serial_blackfin.c
index 59b2fbb1ec..9ad55792ac 100644
--- a/drivers/serial/serial_blackfin.c
+++ b/drivers/serial/serial_blackfin.c
@@ -25,7 +25,7 @@
#include <driver.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/blackfin.h>
#define UART_IER_ERBFI 0x01
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index e3edac951f..4923dcbd94 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -24,7 +24,7 @@
#include <init.h>
#include <malloc.h>
#include <notifier.h>
-#include <asm/io.h>
+#include <io.h>
#define URXD0 0x0 /* Receiver Register */
#define URTX0 0x40 /* Transmitter Register */
diff --git a/drivers/serial/serial_mpc5xxx.c b/drivers/serial/serial_mpc5xxx.c
index fb580cf1fd..b00b442bce 100644
--- a/drivers/serial/serial_mpc5xxx.c
+++ b/drivers/serial/serial_mpc5xxx.c
@@ -39,7 +39,6 @@
#include <init.h>
#include <console.h>
#include <xfuncs.h>
-#include <reloc.h>
#include <mach/clocks.h>
static int __mpc5xxx_serial_setbaudrate(struct mpc5xxx_psc *psc, int baudrate)
@@ -180,27 +179,3 @@ static int mpc5xxx_serial_register(void)
}
console_initcall(mpc5xxx_serial_register);
-
-#ifdef CONFIG_MPC5XXX_EARLY_CONSOLE
-
-void early_console_putc(void *base, char c)
-{
- struct mpc5xxx_psc *psc =
- (struct mpc5xxx_psc *)base;
-
- /* Wait for last character to go. */
- while (!(psc->psc_status & PSC_SR_TXEMP))
- ;
-
- psc->psc_buffer_8 = c;
-}
-
-void early_console_init(void *base, int baudrate)
-{
- struct mpc5xxx_psc *psc =
- (struct mpc5xxx_psc *)base;
- __mpc5xxx_serial_init(psc);
- __mpc5xxx_serial_setbaudrate(psc, baudrate);
-}
-
-#endif
diff --git a/drivers/serial/serial_netx.c b/drivers/serial/serial_netx.c
index fbbc4efdac..a3273e9602 100644
--- a/drivers/serial/serial_netx.c
+++ b/drivers/serial/serial_netx.c
@@ -26,7 +26,7 @@
#include <driver.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
enum uart_regs {
UART_DR = 0x00,
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 36d39cd125..1217a5f249 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -41,7 +41,7 @@
#include <init.h>
#include <errno.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include "serial_ns16550.h"
#include <ns16550.h>
diff --git a/drivers/serial/serial_pl010.c b/drivers/serial/serial_pl010.c
index 9f7b7d3b02..cb875410ea 100644
--- a/drivers/serial/serial_pl010.c
+++ b/drivers/serial/serial_pl010.c
@@ -32,7 +32,7 @@
#include <common.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include "serial_pl010.h"
static int pl010_setbaudrate(struct console_device *cdev, int baudrate)
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index 21bca12f39..3a703b6fe8 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -24,7 +24,7 @@
#include <driver.h>
#include <init.h>
#include <malloc.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/s3c24xx-generic.h>
#include <mach/s3c24x0-iomap.h>
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
index 4264345182..1563d2a93b 100644
--- a/drivers/serial/stm-serial.c
+++ b/drivers/serial/stm-serial.c
@@ -30,7 +30,7 @@
#include <init.h>
#include <notifier.h>
#include <gpio.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index c72493c016..609bafd07f 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -14,6 +14,11 @@ config DRIVER_SPI_IMX_0_0
depends on ARCH_IMX27
default y
+config DRIVER_SPI_IMX_0_7
+ bool
+ depends on ARCH_IMX25
+ default y
+
config DRIVER_SPI_IMX_2_3
bool
depends on ARCH_IMX51 || ARCH_IMX53
@@ -24,4 +29,9 @@ config DRIVER_SPI_ALTERA
depends on NIOS2
depends on SPI
+config DRIVER_SPI_ATMEL
+ bool "Atmel (AT91) SPI Master driver"
+ depends on ARCH_AT91
+ depends on SPI
+
endmenu
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 90e141dae6..101652ff85 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_SPI) += spi.o
obj-$(CONFIG_DRIVER_SPI_IMX) += imx_spi.o
obj-$(CONFIG_DRIVER_SPI_ALTERA) += altera_spi.o
+obj-$(CONFIG_DRIVER_SPI_ATMEL) += atmel_spi.o
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 2c02d7af63..4fd82fb905 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -22,7 +22,7 @@
#include <init.h>
#include <driver.h>
#include <spi/spi.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/spi.h>
#include <asm/nios2-io.h>
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
new file mode 100644
index 0000000000..faa03b1c9e
--- /dev/null
+++ b/drivers/spi/atmel_spi.c
@@ -0,0 +1,321 @@
+/*
+ * Driver for Atmel AT32 and AT91 SPI Controllers
+ *
+ * Copyright (C) 2011 Hubert Feurstein <h.feurstein@gmail.com>
+ *
+ * based on imx_spi.c by:
+ * Copyright (C) 2008 Sascha Hauer, Pengutronix
+ *
+ * based on atmel_spi.c from the linux kernel by:
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <errno.h>
+#include <clock.h>
+#include <xfuncs.h>
+#include <gpio.h>
+#include <io.h>
+#include <spi/spi.h>
+#include <mach/io.h>
+#include <mach/board.h>
+#include <mach/cpu.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include "atmel_spi.h"
+
+struct atmel_spi {
+ struct spi_master master;
+ void __iomem *regs;
+ struct clk *clk;
+ int *cs_pins;
+};
+
+#define to_atmel_spi(p) container_of(p, struct atmel_spi, master)
+#define SPI_XCHG_TIMEOUT (100 * MSECOND)
+
+/*
+ * Version 2 of the SPI controller has
+ * - CR.LASTXFER
+ * - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero)
+ * - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs)
+ * - SPI_CSRx.CSAAT
+ * - SPI_CSRx.SBCR allows faster clocking
+ *
+ * We can determine the controller version by reading the VERSION
+ * register, but I haven't checked that it exists on all chips, and
+ * this is cheaper anyway.
+ */
+static inline bool atmel_spi_is_v2(void)
+{
+ return !cpu_is_at91rm9200();
+}
+
+static int atmel_spi_setup(struct spi_device *spi)
+{
+ struct spi_master *master = spi->master;
+ struct atmel_spi *as = to_atmel_spi(master);
+
+ u32 scbr, csr;
+ unsigned int bits = spi->bits_per_word;
+ unsigned long bus_hz;
+
+ if (spi->controller_data) {
+ csr = (u32)spi->controller_data;
+ spi_writel(as, CSR0, csr);
+ return 0;
+ }
+
+ dev_dbg(master->dev, "%s mode 0x%08x bits_per_word: %d speed: %d\n",
+ __func__, spi->mode, spi->bits_per_word,
+ spi->max_speed_hz);
+
+ bus_hz = clk_get_rate(as->clk);
+ if (!atmel_spi_is_v2())
+ bus_hz /= 2;
+
+ if (spi->max_speed_hz) {
+ /*
+ * Calculate the lowest divider that satisfies the
+ * constraint, assuming div32/fdiv/mbz == 0.
+ */
+ scbr = DIV_ROUND_UP(bus_hz, spi->max_speed_hz);
+
+ /*
+ * If the resulting divider doesn't fit into the
+ * register bitfield, we can't satisfy the constraint.
+ */
+ if (scbr >= (1 << SPI_SCBR_SIZE)) {
+ dev_dbg(master->dev,
+ "setup: %d Hz too slow, scbr %u; min %ld Hz\n",
+ spi->max_speed_hz, scbr, bus_hz/255);
+ return -EINVAL;
+ }
+ } else {
+ /* speed zero means "as slow as possible" */
+ scbr = 0xff;
+ }
+
+ csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8);
+ if (spi->mode & SPI_CPOL)
+ csr |= SPI_BIT(CPOL);
+ if (!(spi->mode & SPI_CPHA))
+ csr |= SPI_BIT(NCPHA);
+
+ /* DLYBS is mostly irrelevant since we manage chipselect using GPIOs.
+ *
+ * DLYBCT would add delays between words, slowing down transfers.
+ * It could potentially be useful to cope with DMA bottlenecks, but
+ * in those cases it's probably best to just use a lower bitrate.
+ */
+ csr |= SPI_BF(DLYBS, 0);
+ csr |= SPI_BF(DLYBCT, 0);
+
+ /* gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); */
+ dev_dbg(master->dev,
+ "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n",
+ bus_hz / scbr, bits, spi->mode, spi->chip_select, csr);
+
+ spi_writel(as, CSR0, csr);
+
+ /*
+ * store the csr-setting when bits are defined. This happens usually
+ * after the specific spi_device driver has been probed.
+ */
+ if (bits > 0)
+ spi->controller_data = (void *)csr;
+
+ return 0;
+}
+
+static void atmel_spi_chipselect(struct spi_device *spi, struct atmel_spi *as, int on)
+{
+ struct spi_master *master = &as->master;
+ int cs_pin;
+ int val = ((spi->mode & SPI_CS_HIGH) != 0) == on;
+
+ BUG_ON(spi->chip_select >= master->num_chipselect);
+ cs_pin = as->cs_pins[spi->chip_select];
+
+ gpio_direction_output(cs_pin, val);
+}
+
+static int atmel_spi_xchg(struct atmel_spi *as, u32 tx_val)
+{
+ uint64_t start;
+
+ start = get_time_ns();
+ while (!(spi_readl(as, SR) & SPI_BIT(TDRE))) {
+ if (is_timeout(start, SPI_XCHG_TIMEOUT)) {
+ dev_err(as->master.dev, "tx timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+ spi_writel(as, TDR, tx_val);
+
+ start = get_time_ns();
+ while (!(spi_readl(as, SR) & SPI_BIT(RDRF))) {
+ if (is_timeout(start, SPI_XCHG_TIMEOUT)) {
+ dev_err(as->master.dev, "rx timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+ return spi_readl(as, RDR) & 0xffff;
+}
+
+static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
+{
+ int ret;
+ struct spi_master *master = spi->master;
+ struct atmel_spi *as = to_atmel_spi(master);
+ struct spi_transfer *t = NULL;
+ unsigned int bits = spi->bits_per_word;
+
+ ret = master->setup(spi);
+ if (ret < 0) {
+ dev_dbg(master->dev, "transfer: master setup failed\n");
+ return ret;
+ }
+
+ dev_dbg(master->dev, " csr0: %08x\n", spi_readl(as, CSR0));
+
+#ifdef VERBOSE
+ list_for_each_entry(t, &mesg->transfers, transfer_list) {
+ dev_dbg(master->dev,
+ " xfer %p: len %u tx %p rx %p\n",
+ t, t->len, t->tx_buf, t->rx_buf);
+ }
+#endif
+ atmel_spi_chipselect(spi, as, 1);
+ list_for_each_entry(t, &mesg->transfers, transfer_list) {
+ u32 tx_val;
+ int i = 0, rx_val;
+
+ if (bits <= 8) {
+ const u8 *txbuf = t->tx_buf;
+ u8 *rxbuf = t->rx_buf;
+
+ while (i < t->len) {
+ tx_val = txbuf ? txbuf[i] : 0;
+
+ rx_val = atmel_spi_xchg(as, tx_val);
+ if (rx_val < 0) {
+ ret = rx_val;
+ goto out;
+ }
+
+ if (rxbuf)
+ rxbuf[i] = rx_val;
+ i++;
+ }
+ } else if (bits <= 16) {
+ const u16 *txbuf = t->tx_buf;
+ u16 *rxbuf = t->rx_buf;
+
+ while (i < t->len >> 1) {
+ tx_val = txbuf ? txbuf[i] : 0;
+
+ rx_val = atmel_spi_xchg(as, tx_val);
+ if (rx_val < 0) {
+ ret = rx_val;
+ goto out;
+ }
+
+ if (rxbuf)
+ rxbuf[i] = rx_val;
+ i++;
+ }
+ }
+ }
+out:
+ atmel_spi_chipselect(spi, as, 0);
+ return ret;
+}
+
+static int atmel_spi_probe(struct device_d *dev)
+{
+ int ret = 0;
+ struct spi_master *master;
+ struct atmel_spi *as;
+ struct at91_spi_platform_data *pdata = dev->platform_data;
+
+ if (!pdata) {
+ dev_err(dev, "missing platform data\n");
+ return -EINVAL;
+ }
+
+ as = xzalloc(sizeof(*as));
+
+ master = &as->master;
+ master->dev = dev;
+
+ as->clk = clk_get(dev, "spi_clk");
+ if (IS_ERR(as->clk)) {
+ dev_err(dev, "no spi_clk\n");
+ ret = PTR_ERR(as->clk);
+ goto out_free;
+ }
+
+ master->setup = atmel_spi_setup;
+ master->transfer = atmel_spi_transfer;
+ master->num_chipselect = pdata->num_chipselect;
+ as->cs_pins = pdata->chipselect;
+ as->regs = dev_request_mem_region(dev, 0);
+
+ /* Initialize the hardware */
+ clk_enable(as->clk);
+ spi_writel(as, CR, SPI_BIT(SWRST));
+ spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
+ spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS));
+ spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
+ spi_writel(as, CR, SPI_BIT(SPIEN));
+
+ dev_dbg(dev, "Atmel SPI Controller at initialized\n");
+
+ ret = spi_register_master(master);
+ if (ret)
+ goto out_reset_hw;
+
+ return 0;
+
+out_reset_hw:
+ spi_writel(as, CR, SPI_BIT(SWRST));
+ spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
+ clk_disable(as->clk);
+ clk_put(as->clk);
+out_free:
+ free(as);
+ return ret;
+}
+
+static struct driver_d atmel_spi_driver = {
+ .name = "atmel_spi",
+ .probe = atmel_spi_probe,
+};
+
+static int atmel_spi_init(void)
+{
+ register_driver(&atmel_spi_driver);
+ return 0;
+}
+
+device_initcall(atmel_spi_init);
diff --git a/drivers/spi/atmel_spi.h b/drivers/spi/atmel_spi.h
new file mode 100644
index 0000000000..38ce11998a
--- /dev/null
+++ b/drivers/spi/atmel_spi.h
@@ -0,0 +1,167 @@
+/*
+ * Register definitions for Atmel Serial Peripheral Interface (SPI)
+ *
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ATMEL_SPI_H__
+#define __ATMEL_SPI_H__
+
+/* SPI register offsets */
+#define SPI_CR 0x0000
+#define SPI_MR 0x0004
+#define SPI_RDR 0x0008
+#define SPI_TDR 0x000c
+#define SPI_SR 0x0010
+#define SPI_IER 0x0014
+#define SPI_IDR 0x0018
+#define SPI_IMR 0x001c
+#define SPI_CSR0 0x0030
+#define SPI_CSR1 0x0034
+#define SPI_CSR2 0x0038
+#define SPI_CSR3 0x003c
+#define SPI_RPR 0x0100
+#define SPI_RCR 0x0104
+#define SPI_TPR 0x0108
+#define SPI_TCR 0x010c
+#define SPI_RNPR 0x0110
+#define SPI_RNCR 0x0114
+#define SPI_TNPR 0x0118
+#define SPI_TNCR 0x011c
+#define SPI_PTCR 0x0120
+#define SPI_PTSR 0x0124
+
+/* Bitfields in CR */
+#define SPI_SPIEN_OFFSET 0
+#define SPI_SPIEN_SIZE 1
+#define SPI_SPIDIS_OFFSET 1
+#define SPI_SPIDIS_SIZE 1
+#define SPI_SWRST_OFFSET 7
+#define SPI_SWRST_SIZE 1
+#define SPI_LASTXFER_OFFSET 24
+#define SPI_LASTXFER_SIZE 1
+
+/* Bitfields in MR */
+#define SPI_MSTR_OFFSET 0
+#define SPI_MSTR_SIZE 1
+#define SPI_PS_OFFSET 1
+#define SPI_PS_SIZE 1
+#define SPI_PCSDEC_OFFSET 2
+#define SPI_PCSDEC_SIZE 1
+#define SPI_FDIV_OFFSET 3
+#define SPI_FDIV_SIZE 1
+#define SPI_MODFDIS_OFFSET 4
+#define SPI_MODFDIS_SIZE 1
+#define SPI_LLB_OFFSET 7
+#define SPI_LLB_SIZE 1
+#define SPI_PCS_OFFSET 16
+#define SPI_PCS_SIZE 4
+#define SPI_DLYBCS_OFFSET 24
+#define SPI_DLYBCS_SIZE 8
+
+/* Bitfields in RDR */
+#define SPI_RD_OFFSET 0
+#define SPI_RD_SIZE 16
+
+/* Bitfields in TDR */
+#define SPI_TD_OFFSET 0
+#define SPI_TD_SIZE 16
+
+/* Bitfields in SR */
+#define SPI_RDRF_OFFSET 0
+#define SPI_RDRF_SIZE 1
+#define SPI_TDRE_OFFSET 1
+#define SPI_TDRE_SIZE 1
+#define SPI_MODF_OFFSET 2
+#define SPI_MODF_SIZE 1
+#define SPI_OVRES_OFFSET 3
+#define SPI_OVRES_SIZE 1
+#define SPI_ENDRX_OFFSET 4
+#define SPI_ENDRX_SIZE 1
+#define SPI_ENDTX_OFFSET 5
+#define SPI_ENDTX_SIZE 1
+#define SPI_RXBUFF_OFFSET 6
+#define SPI_RXBUFF_SIZE 1
+#define SPI_TXBUFE_OFFSET 7
+#define SPI_TXBUFE_SIZE 1
+#define SPI_NSSR_OFFSET 8
+#define SPI_NSSR_SIZE 1
+#define SPI_TXEMPTY_OFFSET 9
+#define SPI_TXEMPTY_SIZE 1
+#define SPI_SPIENS_OFFSET 16
+#define SPI_SPIENS_SIZE 1
+
+/* Bitfields in CSR0 */
+#define SPI_CPOL_OFFSET 0
+#define SPI_CPOL_SIZE 1
+#define SPI_NCPHA_OFFSET 1
+#define SPI_NCPHA_SIZE 1
+#define SPI_CSAAT_OFFSET 3
+#define SPI_CSAAT_SIZE 1
+#define SPI_BITS_OFFSET 4
+#define SPI_BITS_SIZE 4
+#define SPI_SCBR_OFFSET 8
+#define SPI_SCBR_SIZE 8
+#define SPI_DLYBS_OFFSET 16
+#define SPI_DLYBS_SIZE 8
+#define SPI_DLYBCT_OFFSET 24
+#define SPI_DLYBCT_SIZE 8
+
+/* Bitfields in RCR */
+#define SPI_RXCTR_OFFSET 0
+#define SPI_RXCTR_SIZE 16
+
+/* Bitfields in TCR */
+#define SPI_TXCTR_OFFSET 0
+#define SPI_TXCTR_SIZE 16
+
+/* Bitfields in RNCR */
+#define SPI_RXNCR_OFFSET 0
+#define SPI_RXNCR_SIZE 16
+
+/* Bitfields in TNCR */
+#define SPI_TXNCR_OFFSET 0
+#define SPI_TXNCR_SIZE 16
+
+/* Bitfields in PTCR */
+#define SPI_RXTEN_OFFSET 0
+#define SPI_RXTEN_SIZE 1
+#define SPI_RXTDIS_OFFSET 1
+#define SPI_RXTDIS_SIZE 1
+#define SPI_TXTEN_OFFSET 8
+#define SPI_TXTEN_SIZE 1
+#define SPI_TXTDIS_OFFSET 9
+#define SPI_TXTDIS_SIZE 1
+
+/* Constants for BITS */
+#define SPI_BITS_8_BPT 0
+#define SPI_BITS_9_BPT 1
+#define SPI_BITS_10_BPT 2
+#define SPI_BITS_11_BPT 3
+#define SPI_BITS_12_BPT 4
+#define SPI_BITS_13_BPT 5
+#define SPI_BITS_14_BPT 6
+#define SPI_BITS_15_BPT 7
+#define SPI_BITS_16_BPT 8
+
+/* Bit manipulation macros */
+#define SPI_BIT(name) \
+ (1 << SPI_##name##_OFFSET)
+#define SPI_BF(name, value) \
+ (((value) & ((1 << SPI_##name##_SIZE) - 1)) << SPI_##name##_OFFSET)
+#define SPI_BFEXT(name, value) \
+ (((value) >> SPI_##name##_OFFSET) & ((1 << SPI_##name##_SIZE) - 1))
+#define SPI_BFINS(name, value, old) \
+ (((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \
+ | SPI_BF(name, value))
+
+/* Register access macros */
+#define spi_readl(port, reg) \
+ __raw_readl((port)->regs + SPI_##reg)
+#define spi_writel(port, reg, value) \
+ __raw_writel((value), (port)->regs + SPI_##reg)
+
+#endif /* __ATMEL_SPI_H__ */
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 6dc41b92f5..3b33b669fb 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -23,10 +23,11 @@
#include <driver.h>
#include <spi/spi.h>
#include <xfuncs.h>
-#include <asm/io.h>
+#include <io.h>
#include <gpio.h>
#include <mach/spi.h>
#include <mach/generic.h>
+#include <mach/clock.h>
#define CSPI_0_0_RXDATA 0x00
#define CSPI_0_0_TXDATA 0x04
@@ -65,6 +66,22 @@
#define CSPI_0_0_TEST_LBC (1 << 14)
+#define CSPI_0_7_RXDATA 0x00
+#define CSPI_0_7_TXDATA 0x04
+#define CSPI_0_7_CTRL 0x08
+#define CSPI_0_7_CTRL_ENABLE (1 << 0)
+#define CSPI_0_7_CTRL_MASTER (1 << 1)
+#define CSPI_0_7_CTRL_XCH (1 << 2)
+#define CSPI_0_7_CTRL_POL (1 << 4)
+#define CSPI_0_7_CTRL_PHA (1 << 5)
+#define CSPI_0_7_CTRL_SSCTL (1 << 6)
+#define CSPI_0_7_CTRL_SSPOL (1 << 7)
+#define CSPI_0_7_CTRL_CS_SHIFT 12
+#define CSPI_0_7_CTRL_DR_SHIFT 16
+#define CSPI_0_7_CTRL_BL_SHIFT 20
+#define CSPI_0_7_STAT 0x14
+#define CSPI_0_7_STAT_RR (1 << 3)
+
#define CSPI_2_3_RXDATA 0x00
#define CSPI_2_3_TXDATA 0x04
#define CSPI_2_3_CTRL 0x08
@@ -206,6 +223,89 @@ static void cspi_0_0_init(struct imx_spi *imx)
}
#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_0_7
+static unsigned int cspi_0_7_xchg_single(struct imx_spi *imx, unsigned int data)
+{
+ void __iomem *base = imx->regs;
+
+ unsigned int cfg_reg = readl(base + CSPI_0_7_CTRL);
+
+ writel(data, base + CSPI_0_7_TXDATA);
+
+ cfg_reg |= CSPI_0_7_CTRL_XCH;
+
+ writel(cfg_reg, base + CSPI_0_7_CTRL);
+
+ while (!(readl(base + CSPI_0_7_STAT) & CSPI_0_7_STAT_RR))
+ ;
+
+ return readl(base + CSPI_0_7_RXDATA);
+}
+
+/* MX1, MX31, MX35, MX51 CSPI */
+static unsigned int spi_imx_clkdiv_2(unsigned int fin,
+ unsigned int fspi)
+{
+ int i, div = 4;
+
+ for (i = 0; i < 7; i++) {
+ if (fspi * div >= fin)
+ return i;
+ div <<= 1;
+ }
+
+ return 7;
+}
+
+static void cspi_0_7_chipselect(struct spi_device *spi, int is_active)
+{
+ struct spi_master *master = spi->master;
+ struct imx_spi *imx = container_of(master, struct imx_spi, master);
+ void __iomem *base = imx->regs;
+ unsigned int cs = 0;
+ int gpio = imx->cs_array[spi->chip_select];
+ unsigned int reg = CSPI_0_7_CTRL_ENABLE | CSPI_0_7_CTRL_MASTER;
+
+ if (spi->mode & SPI_CS_HIGH)
+ cs = 1;
+
+ if (!is_active) {
+ if (gpio >= 0)
+ gpio_set_value(gpio, !cs);
+ return;
+ }
+
+ reg |= spi_imx_clkdiv_2(imx_get_cspiclk(), spi->max_speed_hz) <<
+ CSPI_0_7_CTRL_DR_SHIFT;
+
+ reg |= (spi->bits_per_word - 1) << CSPI_0_7_CTRL_BL_SHIFT;
+ reg |= CSPI_0_7_CTRL_SSCTL;
+
+ if (spi->mode & SPI_CPHA)
+ reg |= CSPI_0_7_CTRL_PHA;
+ if (spi->mode & SPI_CPOL)
+ reg |= CSPI_0_7_CTRL_POL;
+ if (spi->mode & SPI_CS_HIGH)
+ reg |= CSPI_0_7_CTRL_SSPOL;
+ if (gpio < 0)
+ reg |= (gpio + 32) << CSPI_0_7_CTRL_CS_SHIFT;
+
+ writel(reg, base + CSPI_0_7_CTRL);
+
+ if (gpio >= 0)
+ gpio_set_value(gpio, cs);
+}
+
+static void cspi_0_7_init(struct imx_spi *imx)
+{
+ void __iomem *base = imx->regs;
+
+ /* drain receive buffer */
+ while (readl(base + CSPI_0_7_STAT) & CSPI_0_7_STAT_RR)
+ readl(base + CSPI_0_7_RXDATA);
+}
+#endif
+
#ifdef CONFIG_DRIVER_SPI_IMX_2_3
static unsigned int cspi_2_3_xchg_single(struct imx_spi *imx, unsigned int data)
{
@@ -310,23 +410,56 @@ static void cspi_2_3_init(struct imx_spi *imx)
}
#endif
+static void imx_spi_do_transfer(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct imx_spi *imx = container_of(spi->master, struct imx_spi, master);
+ unsigned i;
+
+ if (spi->bits_per_word <= 8) {
+ const u8 *tx_buf = t->tx_buf;
+ u8 *rx_buf = t->rx_buf;
+ u8 rx_val;
+
+ for (i = 0; i < t->len; i++) {
+ rx_val = imx->xchg_single(imx, tx_buf ? tx_buf[i] : 0);
+ if (rx_buf)
+ rx_buf[i] = rx_val;
+ }
+ } else if (spi->bits_per_word <= 16) {
+ const u16 *tx_buf = t->tx_buf;
+ u16 *rx_buf = t->rx_buf;
+ u16 rx_val;
+
+ for (i = 0; i < t->len >> 1; i++) {
+ rx_val = imx->xchg_single(imx, tx_buf ? tx_buf[i] : 0);
+ if (rx_buf)
+ rx_buf[i] = rx_val;
+ }
+ } else if (spi->bits_per_word <= 32) {
+ const u32 *tx_buf = t->tx_buf;
+ u32 *rx_buf = t->rx_buf;
+ u32 rx_val;
+
+ for (i = 0; i < t->len >> 2; i++) {
+ rx_val = imx->xchg_single(imx, tx_buf ? tx_buf[i] : 0);
+ if (rx_buf)
+ rx_buf[i] = rx_val;
+ }
+ }
+}
+
static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
{
- struct spi_master *master = spi->master;
- struct imx_spi *imx = container_of(master, struct imx_spi, master);
- struct spi_transfer *t = NULL;
+ struct imx_spi *imx = container_of(spi->master, struct imx_spi, master);
+ struct spi_transfer *t = NULL;
imx->chipselect(spi, 1);
- list_for_each_entry (t, &mesg->transfers, transfer_list) {
- const u32 *txbuf = t->tx_buf;
- u32 *rxbuf = t->rx_buf;
- int i = 0;
+ mesg->actual_length = 0;
- while(i < t->len >> 2) {
- rxbuf[i] = imx->xchg_single(imx, txbuf[i]);
- i++;
- }
+ list_for_each_entry(t, &mesg->transfers, transfer_list) {
+ imx_spi_do_transfer(spi, t);
+ mesg->actual_length += t->len;
}
imx->chipselect(spi, 0);
@@ -342,6 +475,13 @@ static struct spi_imx_devtype_data spi_imx_devtype_data[] = {
.init = cspi_0_0_init,
},
#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_0_7
+ [SPI_IMX_VER_0_7] = {
+ .chipselect = cspi_0_7_chipselect,
+ .xchg_single = cspi_0_7_xchg_single,
+ .init = cspi_0_7_init,
+ },
+#endif
#ifdef CONFIG_DRIVER_SPI_IMX_2_3
[SPI_IMX_VER_2_3] = {
.chipselect = cspi_2_3_chipselect,
@@ -372,6 +512,10 @@ static int imx_spi_probe(struct device_d *dev)
if (cpu_is_mx27())
version = SPI_IMX_VER_0_0;
#endif
+#ifdef CONFIG_DRIVER_SPI_IMX_0_7
+ if (cpu_is_mx25())
+ version = SPI_IMX_VER_0_7;
+#endif
#ifdef CONFIG_DRIVER_SPI_IMX_2_3
if (cpu_is_mx51() || cpu_is_mx53())
version = SPI_IMX_VER_2_3;
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index b561f9da2d..7a8aed42e2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -75,12 +75,11 @@ struct spi_device *spi_new_device(struct spi_master *master,
proxy->chip_select = chip->chip_select;
proxy->max_speed_hz = chip->max_speed_hz;
proxy->mode = chip->mode;
- proxy->bits_per_word = chip->bits_per_word;
+ proxy->bits_per_word = chip->bits_per_word ? chip->bits_per_word : 8;
proxy->dev.platform_data = chip->platform_data;
strcpy(proxy->dev.name, chip->name);
proxy->dev.type_data = proxy;
dev_add_child(master->dev, &proxy->dev);
- status = register_device(&proxy->dev);
/* drivers may modify this initial i/o setup */
status = master->setup(proxy);
@@ -90,10 +89,10 @@ struct spi_device *spi_new_device(struct spi_master *master,
goto fail;
}
- return proxy;
+ register_device(&proxy->dev);
+ return proxy;
fail:
- unregister_device(&proxy->dev);
free(proxy);
return NULL;
}
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index c7b2c52660..254b196415 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -7,6 +7,8 @@ source drivers/usb/host/Kconfig
source drivers/usb/otg/Kconfig
+source drivers/usb/storage/Kconfig
+
endif
source drivers/usb/gadget/Kconfig
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index e6f683bb29..be4b371413 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_USB) += core/
obj-$(CONFIG_USB_GADGET) += gadget/
+obj-$(CONFIG_USB_STORAGE) += storage/
obj-y += host/
obj-y += otg/
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 5dc8afee00..7039a2cb75 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -78,13 +78,14 @@ static LIST_HEAD(usb_device_list);
static void print_usb_device(struct usb_device *dev)
{
- printf("%s: %04x:%04x %s\n", dev->dev.name,
- dev->descriptor.idVendor,
- dev->descriptor.idProduct,
- dev->prod);
+ printf("Bus %03d Device %03d: ID %04x:%04x %s\n",
+ dev->host->busnum, dev->devnum,
+ dev->descriptor.idVendor,
+ dev->descriptor.idProduct,
+ dev->prod);
}
-static int host_busnum;
+static int host_busnum = 1;
int usb_register_host(struct usb_host *host)
{
@@ -530,6 +531,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
void *data, unsigned short size, int timeout)
{
struct usb_host *host = dev->host;
+ int ret;
if ((timeout == 0) && (!asynch_allowed)) {
/* request for a asynch control pipe is not allowed */
@@ -547,18 +549,9 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
request, requesttype, value, index, size);
dev->status = USB_ST_NOT_PROC; /*not yet processed */
- host->submit_control_msg(dev, pipe, data, size, &setup_packet);
- if (timeout == 0)
- return (int)size;
-
- if (dev->status != 0) {
- /*
- * Let's wait a while for the timeout to elapse.
- * It has no real use, but it keeps the interface happy.
- */
- wait_ms(timeout);
- return -1;
- }
+ ret = host->submit_control_msg(dev, pipe, data, size, &setup_packet, timeout);
+ if (ret)
+ return ret;
return dev->act_len;
}
@@ -578,7 +571,7 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
return -1;
dev->status = USB_ST_NOT_PROC; /* not yet processed */
- ret = host->submit_bulk_msg(dev, pipe, data, len);
+ ret = host->submit_bulk_msg(dev, pipe, data, len, timeout);
if (ret)
return ret;
@@ -1300,10 +1293,13 @@ static int usb_match_device(struct usb_device *dev, const struct usb_device_id *
return 1;
}
+
/* returns 0 if no match, 1 if match */
static int usb_match_one_id(struct usb_device *usbdev,
const struct usb_device_id *id)
{
+ int ifno;
+
/* proc_connectinfo in devio.c may call us with id == NULL. */
if (id == NULL)
return 0;
@@ -1311,6 +1307,37 @@ static int usb_match_one_id(struct usb_device *usbdev,
if (!usb_match_device(usbdev, id))
return 0;
+ /* The interface class, subclass, and protocol should never be
+ * checked for a match if the device class is Vendor Specific,
+ * unless the match record specifies the Vendor ID. */
+ if (usbdev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+ !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+ (id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO))
+ return 0;
+
+ if ( (id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) ) {
+ /* match any interface */
+ for (ifno=0; ifno<usbdev->config.no_of_if; ifno++) {
+ struct usb_interface_descriptor *intf;
+ intf = &usbdev->config.if_desc[ifno];
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+ (id->bInterfaceClass != intf->bInterfaceClass))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+ (id->bInterfaceSubClass != intf->bInterfaceSubClass))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+ (id->bInterfaceProtocol != intf->bInterfaceProtocol))
+ continue;
+ break;
+ }
+ if (ifno >= usbdev->config.no_of_if)
+ return 0;
+ }
+
return 1;
}
EXPORT_SYMBOL(usb_match_one_id);
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 1e4d4b08f3..fbc6e4ecc7 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -5,7 +5,7 @@
#include <usb/ch9.h>
#include <usb/gadget.h>
#include <usb/fsl_usb2.h>
-#include <asm/io.h>
+#include <io.h>
#include <asm/byteorder.h>
#include <asm/mmu.h>
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 145f7d1c69..929eb89a3a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -4,3 +4,6 @@ config USB_EHCI
config USB_EHCI_OMAP
depends on ARCH_OMAP3
bool "OMAP EHCI driver"
+
+config USB_OHCI
+ bool "OHCI driver"
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index a334b08115..1c7e18f75f 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -1,2 +1,4 @@
obj-$(CONFIG_USB_EHCI) += ehci-hcd.o
obj-$(CONFIG_USB_EHCI_OMAP) += ehci-omap.o
+obj-$(CONFIG_USB_OHCI) += ohci-hcd.o
+obj-$(CONFIG_ARCH_AT91) += ohci-at91.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 60fc1819eb..72f1c14359 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -24,7 +24,7 @@
#include <common.h>
#include <asm/byteorder.h>
#include <usb/usb.h>
-#include <asm/io.h>
+#include <io.h>
#include <malloc.h>
#include <driver.h>
#include <init.h>
@@ -298,7 +298,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
uint32_t c, toggle;
uint32_t cmd;
int ret = 0;
- uint64_t start;
+ uint64_t start, timeout_val;
static struct QH __qh __attribute__((aligned(32)));
static struct qTD __td[3] __attribute__((aligned(32)));
@@ -415,13 +415,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
}
/* Wait for TDs to be processed. */
+ timeout_val = usb_pipebulk(pipe) ? (SECOND << 2) : (SECOND >> 2);
start = get_time_ns();
vtd = td;
do {
/* Invalidate dcache */
ehci_invalidate_dcache(ehci->qh_list);
token = hc32_to_cpu(vtd->qt_token);
- if (is_timeout(start, SECOND >> 2)) {
+ if (is_timeout(start, timeout_val)) {
/* Disable async schedule. */
cmd = ehci_readl(&ehci->hcor->or_usbcmd);
cmd &= ~CMD_ASE;
@@ -850,7 +851,7 @@ static int ehci_init(struct usb_host *host)
static int
submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int length)
+ int length, int timeout)
{
if (usb_pipetype(pipe) != PIPE_BULK) {
@@ -862,7 +863,7 @@ submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
static int
submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int length, struct devrequest *setup)
+ int length, struct devrequest *setup, int timeout)
{
struct usb_host *host = dev->host;
struct ehci_priv *ehci = to_ehci(host);
@@ -922,10 +923,7 @@ static int ehci_probe(struct device_d *dev)
host->submit_bulk_msg = submit_bulk_msg;
if (ehci->flags & EHCI_HAS_TT) {
- /* Set to host mode */
- reg = ehci_readl(ehci->hcor + USBMODE);
- reg |= USBMODE_CM_HC;
- writel(reg, ehci->hcor + USBMODE);
+ ehci_reset(ehci);
}
usb_register_host(host);
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 94aa356dd3..e2ce65f864 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -15,7 +15,7 @@
#include <usb/twl4030.h>
#include <mach/ehci.h>
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <clock.h>
#include <gpio.h>
#include <mach/omap3-silicon.h>
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
new file mode 100644
index 0000000000..7465182a7b
--- /dev/null
+++ b/drivers/usb/host/ohci-at91.c
@@ -0,0 +1,98 @@
+/*
+ * (C) Copyright 2010 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/clk.h>
+#include <driver.h>
+#include <init.h>
+#include <usb/usb.h>
+#include <usb/usb_defs.h>
+#include <errno.h>
+#include <io.h>
+
+#include "ohci.h"
+
+/* interface and function clocks; sometimes also an AHB clock */
+static struct clk *iclk, *fclk;
+
+static void at91_start_clock(void)
+{
+ clk_enable(iclk);
+ clk_enable(fclk);
+}
+
+static void at91_stop_clock(void)
+{
+ clk_disable(fclk);
+ clk_disable(iclk);
+}
+
+static int at91_ohci_probe(struct device_d *dev)
+{
+ struct ohci_regs __iomem *regs = (struct ohci_regs __iomem *)dev->resource[0].start;
+
+ iclk = clk_get(NULL, "ohci_clk");
+ fclk = clk_get(NULL, "uhpck");
+
+ /*
+ * Start the USB clocks.
+ */
+ at91_start_clock();
+
+ /*
+ * The USB host controller must remain in reset.
+ */
+ writel(0, &regs->control);
+
+ add_generic_device("ohci", -1, NULL, dev->resource[0].start,
+ dev->resource[0].size, IORESOURCE_MEM, NULL);
+
+ return 0;
+}
+
+static void at91_ohci_remove(struct device_d *dev)
+{
+ struct ohci_regs __iomem *regs = (struct ohci_regs __iomem *)dev->resource[0].start;
+
+ /*
+ * Put the USB host controller into reset.
+ */
+ writel(0, &regs->control);
+
+ /*
+ * Stop the USB clocks.
+ */
+ at91_stop_clock();
+}
+
+static struct driver_d at91_ohci_driver = {
+ .name = "at91_ohci",
+ .probe = at91_ohci_probe,
+ .remove = at91_ohci_remove,
+};
+
+static int at91_ohci_init(void)
+{
+ register_driver(&at91_ohci_driver);
+ return 0;
+}
+device_initcall(at91_ohci_init);
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
new file mode 100644
index 0000000000..f103101464
--- /dev/null
+++ b/drivers/usb/host/ohci-hcd.c
@@ -0,0 +1,1856 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB on the AT91RM9200 and PCI bus.
+ *
+ * Interrupt support is added. Now, it has been tested
+ * on ULI1575 chip and works well with USB keyboard.
+ *
+ * (C) Copyright 2007
+ * Zhang Wei, Freescale Semiconductor, Inc. <wei.zhang@freescale.com>
+ *
+ * (C) Copyright 2003
+ * Gary Jennejohn, DENX Software Engineering <garyj@denx.de>
+ *
+ * Note: Much of this code has been derived from Linux 2.4
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell
+ *
+ * Modified for the MP2USB by (C) Copyright 2005 Eric Benard
+ * ebenard@eukrea.com - based on s3c24x0's driver
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+/*
+ * IMPORTANT NOTES
+ * 1 - Read doc/README.generic_usb_ohci
+ * 2 - this driver is intended for use with USB Mass Storage Devices
+ * (BBB) and USB keyboard. There is NO support for Isochronous pipes!
+ * 2 - when running on a PQFP208 AT91RM9200, define CONFIG_AT91C_PQFP_UHPBUG
+ * to activate workaround for bug #41 or this driver will NOT work!
+ */
+#include <common.h>
+#include <clock.h>
+#include <malloc.h>
+#include <usb/usb.h>
+#include <usb/usb_defs.h>
+#include <init.h>
+#include <errno.h>
+
+#include <asm/byteorder.h>
+#include <io.h>
+#include <asm/mmu.h>
+
+#include "ohci.h"
+
+#undef OHCI_VERBOSE_DEBUG /* not always helpful */
+#undef SHOW_INFO
+#undef OHCI_FILL_TRACE
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+ ((OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE)
+
+#define err(format, arg...) printf("ERROR: " format, ## arg)
+#ifdef SHOW_INFO
+#define info(format, arg...) printf("INFO: " format, ## arg)
+#else
+#define info(format, arg...) do {} while (0)
+#endif
+
+#define to_ohci(ptr) container_of(ptr, struct ohci, host)
+
+static inline u32 roothub_a(struct ohci *hc)
+{
+ return readl(&hc->regs->roothub.a);
+}
+
+static inline u32 roothub_b(struct ohci *hc)
+{
+ return readl(&hc->regs->roothub.b);
+}
+
+static inline u32 roothub_status(struct ohci *hc)
+{
+ return readl(&hc->regs->roothub.status);
+}
+
+static inline u32 roothub_portstatus(struct ohci *hc, int i)
+{
+ return readl(&hc->regs->roothub.portstatus[i]);
+}
+
+/* forward declaration */
+static int hc_interrupt(struct ohci *ohci);
+static void td_submit_job(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len,
+ struct devrequest *setup, struct urb_priv *urb,
+ int interval);
+
+static int ep_link(struct ohci *ohci, struct ed *ed);
+static int ep_unlink(struct ohci *ohci, struct ed *ed);
+static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe,
+ int interval, int load);
+
+#ifdef CONFIG_SYS_OHCI_BE_CONTROLLER
+# define m16_swap(x) cpu_to_be16(x)
+# define m32_swap(x) cpu_to_be32(x)
+#else
+# define m16_swap(x) cpu_to_le16(x)
+# define m32_swap(x) cpu_to_le32(x)
+#endif /* CONFIG_SYS_OHCI_BE_CONTROLLER */
+
+/*-------------------------------------------------------------------------*
+ * URB support functions
+ *-------------------------------------------------------------------------*/
+
+/* TDs ... */
+static inline struct td *td_alloc(struct usb_device *usb_dev)
+{
+ int i;
+ struct usb_host *host = usb_dev->host;
+ struct ohci *ohci = to_ohci(host);
+ struct td *ptd = ohci->ptd;
+ struct td *td = NULL;
+
+ for (i = 0; i < NUM_TD; i++) {
+ if (!ptd[i].usb_dev) {
+ td = &ptd[i];
+ td->usb_dev = usb_dev;
+ break;
+ }
+ }
+
+ return td;
+}
+
+static inline void ed_free(struct ed *ed)
+{
+ ed->usb_dev = NULL;
+}
+
+/* free HCD-private data associated with this URB */
+
+static void urb_free_priv(struct urb_priv *urb)
+{
+ int i;
+ int last;
+ struct td *td;
+
+ last = urb->length - 1;
+ if (last >= 0) {
+ for (i = 0; i <= last; i++) {
+ td = urb->td[i];
+ if (td) {
+ td->usb_dev = NULL;
+ urb->td[i] = NULL;
+ }
+ }
+ }
+ free(urb);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+static int sohci_get_current_frame_number(struct usb_device *dev);
+
+/* debug| print the main components of an URB
+ * small: 0) header + data packets 1) just header */
+
+static void pkt_print(struct urb_priv *purb, struct usb_device *dev,
+ unsigned long pipe, void *buffer, int transfer_len,
+ struct devrequest *setup, char *str, int small)
+{
+ debug("%s URB:[%4x] dev:%2lu,ep:%2lu-%c,type:%s,len:%d/%d stat:%#lx\n",
+ str,
+ sohci_get_current_frame_number(dev),
+ usb_pipedevice(pipe),
+ usb_pipeendpoint(pipe),
+ usb_pipeout(pipe) ? 'O' : 'I',
+ usb_pipetype(pipe) < 2 ? \
+ (usb_pipeint(pipe) ? "INTR" : "ISOC") : \
+ (usb_pipecontrol(pipe) ? "CTRL" : "BULK"),
+ (purb ? purb->actual_length : 0),
+ transfer_len, dev->status);
+#ifdef OHCI_VERBOSE_DEBUG
+ if (!small) {
+ int i, len;
+
+ if (usb_pipecontrol(pipe)) {
+ printf(__FILE__ ": cmd(8):");
+ for (i = 0; i < 8 ; i++)
+ printf(" %02x", ((__u8 *) setup)[i]);
+ printf("\n");
+ }
+ if (transfer_len > 0 && buffer) {
+ printf(__FILE__ ": data(%d/%d):",
+ (purb ? purb->actual_length : 0),
+ transfer_len);
+ len = usb_pipeout(pipe) ? transfer_len :
+ (purb ? purb->actual_length : 0);
+ for (i = 0; i < 16 && i < len; i++)
+ printf(" %02x", ((__u8 *) buffer)[i]);
+ printf("%s\n", i < leni ? "..." : "");
+ }
+ }
+#endif
+}
+
+/* just for debugging; prints non-empty branches of the int ed tree
+ * inclusive iso eds */
+void ep_print_int_eds(struct ohci *ohci, char *str)
+{
+ int i, j;
+ __u32 *ed_p;
+
+ for (i = 0; i < 32; i++) {
+ j = 5;
+ ed_p = &(ohci->hcca->int_table[i]);
+ if (*ed_p == 0)
+ continue;
+ printf(__FILE__ ": %s branch int %2d(%2x):", str, i, i);
+ while (*ed_p != 0 && j--) {
+ struct ed *ed = (struct ed *)m32_swap(ed_p);
+ printf(" ed: %4x;", ed->hwINFO);
+ ed_p = &ed->hwNextED;
+ }
+ printf("\n");
+ }
+}
+
+static void ohci_dump_intr_mask(char *label, __u32 mask)
+{
+ debug("%s: 0x%08x%s%s%s%s%s%s%s%s%s\n",
+ label,
+ mask,
+ (mask & OHCI_INTR_MIE) ? " MIE" : "",
+ (mask & OHCI_INTR_OC) ? " OC" : "",
+ (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
+ (mask & OHCI_INTR_FNO) ? " FNO" : "",
+ (mask & OHCI_INTR_UE) ? " UE" : "",
+ (mask & OHCI_INTR_RD) ? " RD" : "",
+ (mask & OHCI_INTR_SF) ? " SF" : "",
+ (mask & OHCI_INTR_WDH) ? " WDH" : "",
+ (mask & OHCI_INTR_SO) ? " SO" : ""
+ );
+}
+
+static void maybe_print_eds(char *label, __u32 value)
+{
+ struct ed *edp = (struct ed *)value;
+
+ if (value) {
+ debug("%s %08x\n", label, value);
+ debug("%08x\n", edp->hwINFO);
+ debug("%08x\n", edp->hwTailP);
+ debug("%08x\n", edp->hwHeadP);
+ debug("%08x\n", edp->hwNextED);
+ }
+}
+
+static char *hcfs2string(int state)
+{
+ switch (state) {
+ case OHCI_USB_RESET: return "reset";
+ case OHCI_USB_RESUME: return "resume";
+ case OHCI_USB_OPER: return "operational";
+ case OHCI_USB_SUSPEND: return "suspend";
+ }
+
+ return "?";
+}
+
+/* dump control and status registers */
+static void ohci_dump_status(struct ohci *controller)
+{
+ struct ohci_regs *regs = controller->regs;
+ __u32 temp;
+
+ temp = readl(&regs->revision) & 0xff;
+ if (temp != 0x10)
+ debug("spec %d.%d\n", (temp >> 4), (temp & 0x0f));
+
+ temp = readl(&regs->control);
+ debug("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n", temp,
+ (temp & OHCI_CTRL_RWE) ? " RWE" : "",
+ (temp & OHCI_CTRL_RWC) ? " RWC" : "",
+ (temp & OHCI_CTRL_IR) ? " IR" : "",
+ hcfs2string(temp & OHCI_CTRL_HCFS),
+ (temp & OHCI_CTRL_BLE) ? " BLE" : "",
+ (temp & OHCI_CTRL_CLE) ? " CLE" : "",
+ (temp & OHCI_CTRL_IE) ? " IE" : "",
+ (temp & OHCI_CTRL_PLE) ? " PLE" : "",
+ temp & OHCI_CTRL_CBSR
+ );
+
+ temp = readl(&regs->cmdstatus);
+ debug("cmdstatus: 0x%08x SOC=%d%s%s%s%s\n", temp,
+ (temp & OHCI_SOC) >> 16,
+ (temp & OHCI_OCR) ? " OCR" : "",
+ (temp & OHCI_BLF) ? " BLF" : "",
+ (temp & OHCI_CLF) ? " CLF" : "",
+ (temp & OHCI_HCR) ? " HCR" : ""
+ );
+
+ ohci_dump_intr_mask("intrstatus", readl(&regs->intrstatus));
+ ohci_dump_intr_mask("intrenable", readl(&regs->intrenable));
+
+ maybe_print_eds("ed_periodcurrent", readl(&regs->ed_periodcurrent));
+
+ maybe_print_eds("ed_controlhead", readl(&regs->ed_controlhead));
+ maybe_print_eds("ed_controlcurrent", readl(&regs->ed_controlcurrent));
+
+ maybe_print_eds("ed_bulkhead", readl(&regs->ed_bulkhead));
+ maybe_print_eds("ed_bulkcurrent", readl(&regs->ed_bulkcurrent));
+
+ maybe_print_eds("donehead", readl(&regs->donehead));
+}
+
+static void ohci_dump_roothub(struct ohci *controller, int verbose)
+{
+ __u32 temp, ndp, i;
+
+ temp = roothub_a(controller);
+ ndp = (temp & RH_A_NDP);
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+ ndp = (ndp == 2) ? 1 : 0;
+#endif
+ if (verbose) {
+ debug("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d\n", temp,
+ ((temp & RH_A_POTPGT) >> 24) & 0xff,
+ (temp & RH_A_NOCP) ? " NOCP" : "",
+ (temp & RH_A_OCPM) ? " OCPM" : "",
+ (temp & RH_A_DT) ? " DT" : "",
+ (temp & RH_A_NPS) ? " NPS" : "",
+ (temp & RH_A_PSM) ? " PSM" : "",
+ ndp
+ );
+ temp = roothub_b(controller);
+ debug("roothub.b: %08x PPCM=%04x DR=%04x\n",
+ temp,
+ (temp & RH_B_PPCM) >> 16,
+ (temp & RH_B_DR)
+ );
+ temp = roothub_status(controller);
+ debug("roothub.status: %08x%s%s%s%s%s%s\n",
+ temp,
+ (temp & RH_HS_CRWE) ? " CRWE" : "",
+ (temp & RH_HS_OCIC) ? " OCIC" : "",
+ (temp & RH_HS_LPSC) ? " LPSC" : "",
+ (temp & RH_HS_DRWE) ? " DRWE" : "",
+ (temp & RH_HS_OCI) ? " OCI" : "",
+ (temp & RH_HS_LPS) ? " LPS" : ""
+ );
+ }
+
+ for (i = 0; i < ndp; i++) {
+ temp = roothub_portstatus(controller, i);
+ debug("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n",
+ i,
+ temp,
+ (temp & RH_PS_PRSC) ? " PRSC" : "",
+ (temp & RH_PS_OCIC) ? " OCIC" : "",
+ (temp & RH_PS_PSSC) ? " PSSC" : "",
+ (temp & RH_PS_PESC) ? " PESC" : "",
+ (temp & RH_PS_CSC) ? " CSC" : "",
+
+ (temp & RH_PS_LSDA) ? " LSDA" : "",
+ (temp & RH_PS_PPS) ? " PPS" : "",
+ (temp & RH_PS_PRS) ? " PRS" : "",
+ (temp & RH_PS_POCI) ? " POCI" : "",
+ (temp & RH_PS_PSS) ? " PSS" : "",
+
+ (temp & RH_PS_PES) ? " PES" : "",
+ (temp & RH_PS_CCS) ? " CCS" : ""
+ );
+ }
+}
+
+static void ohci_dump(struct ohci *controller, int verbose)
+{
+ debug("OHCI controller usb-%s state\n", controller->slot_name);
+
+ /* dumps some of the state we know about */
+ ohci_dump_status(controller);
+ if (verbose)
+ ep_print_int_eds(controller, "hcca");
+ debug("hcca frame #%04x\n", controller->hcca->frame_no);
+ ohci_dump_roothub(controller, 1);
+}
+#else /* DEBUG */
+static void pkt_print(struct urb_priv *purb, struct usb_device *dev,
+ unsigned long pipe, void *buffer, int transfer_len,
+ struct devrequest *setup, char *str, int small)
+{
+}
+
+static void ohci_dump_roothub(struct ohci *controller, int verbose)
+{
+}
+
+static void ohci_dump(struct ohci *controller, int verbose)
+{
+}
+#endif
+
+/*-------------------------------------------------------------------------*
+ * Interface functions (URB)
+ *-------------------------------------------------------------------------*/
+
+/* get a transfer request */
+
+int sohci_submit_job(struct urb_priv *urb, struct devrequest *setup)
+{
+ struct ed *ed;
+ int i, size = 0;
+ struct usb_device *dev = urb->dev;
+ struct usb_host *host = dev->host;
+ struct ohci *ohci = to_ohci(host);
+ unsigned long pipe = urb->pipe;
+ void *buffer = urb->transfer_buffer;
+ int transfer_len = urb->transfer_buffer_length;
+ int interval = urb->interval;
+
+ /* when controller's hung, permit only roothub cleanup attempts
+ * such as powering down ports */
+ if (ohci->disabled)
+ return -EPIPE;
+
+ /* we're about to begin a new transaction here so mark the
+ * URB unfinished */
+ urb->finished = 0;
+
+ /* every endpoint has a ed, locate and fill it */
+ ed = ep_add_ed(dev, pipe, interval, 1);
+ if (!ed)
+ return -ENOMEM;
+
+ /* for the private part of the URB we need the number of TDs (size) */
+ switch (usb_pipetype(pipe)) {
+ case PIPE_BULK: /* one TD for every 4096 Byte */
+ size = (transfer_len - 1) / 4096 + 1;
+ break;
+ case PIPE_CONTROL:/* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
+ size = (transfer_len == 0) ? 2 :
+ (transfer_len - 1) / 4096 + 3;
+ break;
+ case PIPE_INTERRUPT: /* 1 TD */
+ size = 1;
+ break;
+ }
+
+ ed->purb = urb;
+
+ if (size >= (N_URB_TD - 1)) {
+ err("need %d TDs, only have %d\n", size, N_URB_TD);
+ return -EINVAL;
+ }
+ urb->pipe = pipe;
+
+ /* fill the private part of the URB */
+ urb->length = size;
+ urb->ed = ed;
+ urb->actual_length = 0;
+
+ /* allocate the TDs */
+ /* note that td[0] was allocated in ep_add_ed */
+ for (i = 0; i < size; i++) {
+ urb->td[i] = td_alloc(dev);
+ if (!urb->td[i]) {
+ urb->length = i;
+ urb_free_priv(urb);
+ return -ENOMEM;
+ }
+ }
+
+ if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
+ urb_free_priv(urb);
+ return -EINVAL;
+ }
+
+ /* link the ed into a chain if is not already */
+ if (ed->state != ED_OPER)
+ ep_link(ohci, ed);
+
+ /* fill the TDs and link it to the ed */
+ td_submit_job(dev, pipe, buffer, transfer_len,
+ setup, urb, interval);
+
+ return 0;
+}
+
+static inline int sohci_return_job(struct ohci *hc, struct urb_priv *urb)
+{
+#ifdef ENBALE_PIPE_INTERRUPT
+ struct ohci_regs *regs = hc->regs;
+#endif
+
+ switch (usb_pipetype(urb->pipe)) {
+ case PIPE_INTERRUPT:
+#ifdef ENBALE_PIPE_INTERRUPT
+ /* implicitly requeued */
+ if (urb->dev->irq_handle &&
+ (urb->dev->irq_act_len == urb->actual_length)) {
+ writel(OHCI_INTR_WDH, &regs->intrenable);
+ readl(&regs->intrenable); /* PCI posting flush */
+ urb->dev->irq_handle(urb->dev);
+ writel(OHCI_INTR_WDH, &regs->intrdisable);
+ readl(&regs->intrdisable); /* PCI posting flush */
+ }
+ urb->actual_length = 0;
+ td_submit_job(
+ urb->dev,
+ urb->pipe,
+ urb->transfer_buffer,
+ urb->transfer_buffer_length,
+ NULL,
+ urb,
+ urb->interval);
+#endif
+ break;
+ case PIPE_CONTROL:
+ case PIPE_BULK:
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+#ifdef DEBUG
+/* tell us the current USB frame number */
+
+static int sohci_get_current_frame_number(struct usb_device *usb_dev)
+{
+ struct usb_host *host = usb_dev->host;
+ struct ohci *ohci = to_ohci(host);
+
+ return m16_swap(ohci->hcca->frame_no);
+}
+#endif
+
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* search for the right branch to insert an interrupt ed into the int tree
+ * do some load ballancing;
+ * returns the branch and
+ * sets the interval to interval = 2^integer (ld (interval)) */
+
+static int ep_int_ballance(struct ohci *ohci, int interval, int load)
+{
+ int i, branch = 0;
+
+ /* search for the least loaded interrupt endpoint
+ * branch of all 32 branches
+ */
+ for (i = 0; i < 32; i++)
+ if (ohci->ohci_int_load[branch] > ohci->ohci_int_load[i])
+ branch = i;
+
+ branch = branch % interval;
+ for (i = branch; i < 32; i += interval)
+ ohci->ohci_int_load[i] += load;
+
+ return branch;
+}
+
+/* 2^int( ld (inter)) */
+
+static int ep_2_n_interval(int inter)
+{
+ int i;
+
+ for (i = 0; ((inter >> i) > 1) && (i < 5); i++)
+ ;
+
+ return 1 << i;
+}
+
+/* the int tree is a binary tree
+ * in order to process it sequentially the indexes of the branches have to
+ * be mapped the mapping reverses the bits of a word of num_bits length */
+static int ep_rev(int num_bits, int word)
+{
+ int i, wout = 0;
+
+ for (i = 0; i < num_bits; i++)
+ wout |= (((word >> i) & 1) << (num_bits - i - 1));
+ return wout;
+}
+
+/*-------------------------------------------------------------------------*
+ * ED handling functions
+ *-------------------------------------------------------------------------*/
+
+/* link an ed into one of the HC chains */
+
+static int ep_link(struct ohci *ohci, struct ed *edi)
+{
+ volatile struct ed *ed = edi;
+ int int_branch;
+ int i;
+ int inter;
+ int interval;
+ int load;
+ __u32 *ed_p;
+
+ ed->state = ED_OPER;
+ ed->int_interval = 0;
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ ed->hwNextED = 0;
+ if (ohci->ed_controltail == NULL)
+ writel(virt_to_phys((void *)ed), &ohci->regs->ed_controlhead);
+ else
+ ohci->ed_controltail->hwNextED =
+ virt_to_phys((void *)m32_swap((unsigned long)ed));
+
+ ed->ed_prev = ohci->ed_controltail;
+ if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1]) {
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ writel(ohci->hc_control, &ohci->regs->control);
+ }
+ ohci->ed_controltail = edi;
+ break;
+
+ case PIPE_BULK:
+ ed->hwNextED = 0;
+ if (ohci->ed_bulktail == NULL)
+ writel(virt_to_phys((void *)ed), &ohci->regs->ed_bulkhead);
+ else
+ ohci->ed_bulktail->hwNextED =
+ virt_to_phys((void *)m32_swap((unsigned long)ed));
+
+ ed->ed_prev = ohci->ed_bulktail;
+ if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1]) {
+ ohci->hc_control |= OHCI_CTRL_BLE;
+ writel(ohci->hc_control, &ohci->regs->control);
+ }
+ ohci->ed_bulktail = edi;
+ break;
+
+ case PIPE_INTERRUPT:
+ load = ed->int_load;
+ interval = ep_2_n_interval(ed->int_period);
+ ed->int_interval = interval;
+ int_branch = ep_int_ballance(ohci, interval, load);
+ ed->int_branch = int_branch;
+
+ for (i = 0; i < ep_rev(6, interval); i += inter) {
+ inter = 1;
+ for (ed_p = &(ohci->hcca->int_table[ep_rev(5, i) + int_branch]);
+ (*ed_p != 0) &&
+ (((struct ed *)ed_p)->int_interval >= interval);
+ ed_p = &(((struct ed *)ed_p)->hwNextED))
+ inter = ep_rev(6,
+ ((struct ed *)ed_p)->int_interval);
+ ed->hwNextED = *ed_p;
+ *ed_p = m32_swap((unsigned long)ed);
+ }
+ break;
+ }
+ return 0;
+}
+
+/* scan the periodic table to find and unlink this ED */
+static void periodic_unlink(struct ohci *ohci, volatile struct ed *ed,
+ unsigned index, unsigned period)
+{
+ for (; index < NUM_INTS; index += period) {
+ __u32 *ed_p = &ohci->hcca->int_table[index];
+
+ /* ED might have been unlinked through another path */
+ while (*ed_p != 0) {
+ if (((struct ed *)
+ m32_swap((unsigned long)ed_p)) == ed) {
+ *ed_p = ed->hwNextED;
+ break;
+ }
+ ed_p = &(((struct ed *)
+ m32_swap((unsigned long)ed_p))->hwNextED);
+ }
+ }
+}
+
+/*
+ * Unlink an ed from one of the HC chains.
+ * just the link to the ed is unlinked.
+ * the link from the ed still points to another operational ed or 0
+ * so the HC can eventually finish the processing of the unlinked ed
+ */
+static int ep_unlink(struct ohci *ohci, struct ed *edi)
+{
+ volatile struct ed *ed = edi;
+ int i;
+
+ ed->hwINFO |= m32_swap(OHCI_ED_SKIP);
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_CLE;
+ writel(ohci->hc_control, &ohci->regs->control);
+ }
+ writel(m32_swap(*((__u32 *)&ed->hwNextED)),
+ &ohci->regs->ed_controlhead);
+ } else {
+ ed->ed_prev->hwNextED = ed->hwNextED;
+ }
+ if (ohci->ed_controltail == ed) {
+ ohci->ed_controltail = ed->ed_prev;
+ } else {
+ ((struct ed *)m32_swap(
+ *((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+ }
+ break;
+
+ case PIPE_BULK:
+ if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_BLE;
+ writel(ohci->hc_control, &ohci->regs->control);
+ }
+ writel(m32_swap(*((__u32 *)&ed->hwNextED)),
+ &ohci->regs->ed_bulkhead);
+ } else {
+ ed->ed_prev->hwNextED = ed->hwNextED;
+ }
+ if (ohci->ed_bulktail == ed) {
+ ohci->ed_bulktail = ed->ed_prev;
+ } else {
+ ((struct ed *)m32_swap(
+ *((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
+ }
+ break;
+
+ case PIPE_INTERRUPT:
+ periodic_unlink(ohci, ed, 0, 1);
+ for (i = ed->int_branch; i < 32; i += ed->int_interval)
+ ohci->ohci_int_load[i] -= ed->int_load;
+ break;
+ }
+ ed->state = ED_UNLINK;
+ return 0;
+}
+
+/*
+ * Add/reinit an endpoint; this should be done once at the
+ * usb_set_configuration command, but the USB stack is a little bit
+ * stateless so we do it at every transaction if the state of the ed
+ * is ED_NEW then a dummy td is added and the state is changed to
+ * ED_UNLINK in all other cases the state is left unchanged the ed
+ * info fields are setted anyway even though most of them should not
+ * change
+ */
+static struct ed *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe,
+ int interval, int load)
+{
+ struct usb_host *host = usb_dev->host;
+ struct ohci *ohci = to_ohci(host);
+ struct ohci_device *ohci_dev = ohci->ohci_dev;
+ struct td *td;
+ struct ed *ed_ret;
+ volatile struct ed *ed;
+
+ ed = ed_ret = &ohci_dev->ed[(usb_pipeendpoint(pipe) << 1) |
+ (usb_pipecontrol(pipe) ? 0 : usb_pipeout(pipe))];
+
+ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
+ err("ep_add_ed: pending delete\n");
+ /* pending delete request */
+ return NULL;
+ }
+
+ if (ed->state == ED_NEW) {
+ /* dummy td; end of td list for ed */
+ td = td_alloc(usb_dev);
+ ed->hwTailP = virt_to_phys((void *)m32_swap((unsigned long)td));
+ ed->hwHeadP = ed->hwTailP;
+ ed->state = ED_UNLINK;
+ ed->type = usb_pipetype(pipe);
+ ohci_dev->ed_cnt++;
+ }
+
+ ed->hwINFO = m32_swap(usb_pipedevice(pipe)
+ | usb_pipeendpoint(pipe) << 7
+ | (usb_pipeisoc(pipe) ? 0x8000 : 0)
+ | (usb_pipecontrol(pipe) ? 0 : \
+ (usb_pipeout(pipe) ? 0x800 : 0x1000))
+ | usb_pipeslow(pipe) << 13
+ | usb_maxpacket(usb_dev, pipe) << 16);
+
+ if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
+ ed->int_period = interval;
+ ed->int_load = load;
+ }
+
+ return ed_ret;
+}
+
+/*-------------------------------------------------------------------------*
+ * TD handling functions
+ *-------------------------------------------------------------------------*/
+
+/*
+ * enqueue next TD for this URB (OHCI spec 5.2.8.2)
+ */
+static void td_fill(struct ohci *ohci, unsigned int info,
+ void *data, int len,
+ struct usb_device *dev, int index, struct urb_priv *urb_priv)
+{
+ volatile struct td *td, *td_pt;
+#ifdef OHCI_FILL_TRACE
+ int i;
+#endif
+ if (index > urb_priv->length) {
+ err("index > length\n");
+ return;
+ }
+ /* use this td as the next dummy */
+ td_pt = urb_priv->td[index];
+ td_pt->hwNextTD = 0;
+
+ /* fill the old dummy TD */
+ td = urb_priv->td[index] =
+ (struct td *)(m32_swap(urb_priv->ed->hwTailP) & ~0xf);
+
+ td->ed = urb_priv->ed;
+ td->next_dl_td = NULL;
+ td->index = index;
+ td->data = (__u32)data;
+#ifdef OHCI_FILL_TRACE
+ if (usb_pipebulk(urb_priv->pipe) && usb_pipeout(urb_priv->pipe)) {
+ for (i = 0; i < len; i++)
+ printf("td->data[%d] %#2x ", i, ((unsigned char *)td->data)[i]);
+ printf("\n");
+ }
+#endif
+ if (!len)
+ data = 0;
+
+ td->hwINFO = m32_swap(info);
+ td->hwCBP = virt_to_phys((void *)m32_swap((unsigned long)data));
+ if (data)
+ td->hwBE = virt_to_phys((void *)m32_swap((unsigned long)(data + len - 1)));
+ else
+ td->hwBE = 0;
+
+ td->hwNextTD = virt_to_phys((void *)m32_swap((unsigned long)td_pt));
+
+ /* append to queue */
+ td->ed->hwTailP = td->hwNextTD;
+}
+
+/*
+ * Prepare all TDs of a transfer
+ */
+static void td_submit_job(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len,
+ struct devrequest *setup, struct urb_priv *urb,
+ int interval)
+{
+ struct usb_host *host = dev->host;
+ struct ohci *ohci = to_ohci(host);
+ int data_len = transfer_len;
+ void *data;
+ int cnt = 0;
+ __u32 info = 0;
+ unsigned int toggle = 0;
+
+ /* OHCI handles the DATA-toggles itself, we just use the USB-toggle
+ * bits for reseting */
+ if (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
+ toggle = TD_T_TOGGLE;
+ } else {
+ toggle = TD_T_DATA0;
+ usb_settoggle(dev, usb_pipeendpoint(pipe),
+ usb_pipeout(pipe), 1);
+ }
+ urb->td_cnt = 0;
+ if (data_len)
+ data = buffer;
+ else
+ data = 0;
+
+ switch (usb_pipetype(pipe)) {
+ case PIPE_BULK:
+ info = usb_pipeout(pipe) ?
+ TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
+ while (data_len > 4096) {
+ td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle),
+ data, 4096, dev, cnt, urb);
+ data += 4096; data_len -= 4096; cnt++;
+ }
+ info = usb_pipeout(pipe) ?
+ TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
+ td_fill(ohci, info | (cnt ? TD_T_TOGGLE : toggle), data,
+ data_len, dev, cnt, urb);
+ cnt++;
+
+ /* start bulk list */
+ writel(OHCI_BLF, &ohci->regs->cmdstatus);
+
+ break;
+
+ case PIPE_CONTROL:
+ /* Setup phase */
+ info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
+ td_fill(ohci, info, setup, 8, dev, cnt++, urb);
+
+ /* Optional Data phase */
+ if (data_len > 0) {
+ info = usb_pipeout(pipe) ?
+ TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 :
+ TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
+ /* NOTE: mishandles transfers >8K, some >4K */
+ td_fill(ohci, info, data, data_len, dev, cnt++, urb);
+ }
+
+ /* Status phase */
+ info = usb_pipeout(pipe) ?
+ TD_CC | TD_DP_IN | TD_T_DATA1 :
+ TD_CC | TD_DP_OUT | TD_T_DATA1;
+ td_fill(ohci, info, data, 0, dev, cnt++, urb);
+
+ /* start Control list */
+ writel(OHCI_CLF, &ohci->regs->cmdstatus);
+
+ break;
+
+ case PIPE_INTERRUPT:
+ info = usb_pipeout(urb->pipe) ?
+ TD_CC | TD_DP_OUT | toggle :
+ TD_CC | TD_R | TD_DP_IN | toggle;
+ td_fill(ohci, info, data, data_len, dev, cnt++, urb);
+ break;
+ }
+ if (urb->length != cnt)
+ debug("TD LENGTH %d != CNT %d\n", urb->length, cnt);
+}
+
+/*-------------------------------------------------------------------------*
+ * Done List handling functions
+ *-------------------------------------------------------------------------*/
+
+/* calculate the transfer length and update the urb */
+
+static void dl_transfer_length(struct td *td)
+{
+ __u32 tdINFO, tdBE, tdCBP;
+ struct urb_priv *lurb_priv = td->ed->purb;
+
+ tdINFO = m32_swap(td->hwINFO);
+ tdBE = m32_swap(td->hwBE);
+ tdCBP = m32_swap(td->hwCBP);
+
+ if (!(usb_pipecontrol(lurb_priv->pipe) &&
+ ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
+ if (tdBE != 0) {
+ __u32 data = virt_to_phys((void *)td->data);
+ if (td->hwCBP == 0)
+ lurb_priv->actual_length += tdBE - data + 1;
+ else
+ lurb_priv->actual_length += tdCBP - data;
+ }
+ }
+}
+
+static void check_status(struct td *td_list)
+{
+ struct urb_priv *lurb_priv = td_list->ed->purb;
+ int urb_len = lurb_priv->length;
+ __u32 *phwHeadP = &td_list->ed->hwHeadP;
+ int cc;
+
+ cc = TD_CC_GET(m32_swap(td_list->hwINFO));
+ if (cc) {
+ err(" USB-error: %s (%x)\n", cc_to_string[cc], cc);
+
+ if (*phwHeadP & m32_swap(0x1)) {
+ if (lurb_priv &&
+ ((td_list->index + 1) < urb_len)) {
+ *phwHeadP =
+ (lurb_priv->td[urb_len - 1]->hwNextTD &\
+ m32_swap(0xfffffff0)) |
+ (*phwHeadP & m32_swap(0x2));
+
+ lurb_priv->td_cnt += urb_len -
+ td_list->index - 1;
+ } else
+ *phwHeadP &= m32_swap(0xfffffff2);
+ }
+#ifdef CONFIG_MPC5200
+ td_list->hwNextTD = 0;
+#endif
+ }
+}
+
+/* replies to the request have to be on a FIFO basis so
+ * we reverse the reversed done-list */
+static struct td *dl_reverse_done_list(struct ohci *ohci)
+{
+ __u32 td_list_hc;
+ struct td *td_rev = NULL;
+ struct td *td_list = NULL;
+
+ td_list_hc = m32_swap(ohci->hcca->done_head) & 0xfffffff0;
+
+ ohci->hcca->done_head = 0;
+
+ while (td_list_hc) {
+ td_list = (struct td *)td_list_hc;
+ check_status(td_list);
+ td_list->next_dl_td = td_rev;
+ td_rev = td_list;
+ td_list_hc = m32_swap(td_list->hwNextTD) & 0xfffffff0;
+ }
+ return td_list;
+}
+
+static void finish_urb(struct ohci *ohci, struct urb_priv *urb, int status)
+{
+ if ((status & (ED_OPER | ED_UNLINK)) && (urb->state != URB_DEL))
+ urb->finished = sohci_return_job(ohci, urb);
+ else
+ debug("finish_urb: strange.., ED state %x, \n", status);
+}
+
+/*
+ * Used to take back a TD from the host controller. This would normally be
+ * called from within dl_done_list, however it may be called directly if the
+ * HC no longer sees the TD and it has not appeared on the donelist (after
+ * two frames). This bug has been observed on ZF Micro systems.
+ */
+static int takeback_td(struct ohci *ohci, struct td *td_list)
+{
+ struct ed *ed;
+ int cc;
+ int stat = 0;
+ struct urb_priv *lurb_priv;
+ __u32 tdINFO, edHeadP, edTailP;
+
+ tdINFO = m32_swap(td_list->hwINFO);
+
+ ed = td_list->ed;
+ lurb_priv = ed->purb;
+
+ dl_transfer_length(td_list);
+
+ lurb_priv->td_cnt++;
+
+ /* error code of transfer */
+ cc = TD_CC_GET(tdINFO);
+ if (cc) {
+ err("USB-error: %s (%x)\n", cc_to_string[cc], cc);
+ stat = cc_to_error[cc];
+ }
+
+ /* see if this done list makes for all TD's of current URB,
+ * and mark the URB finished if so */
+ if (lurb_priv->td_cnt == lurb_priv->length)
+ finish_urb(ohci, lurb_priv, ed->state);
+
+ debug("dl_done_list: processing TD %x, len %x\n",
+ lurb_priv->td_cnt, lurb_priv->length);
+
+ if (ed->state != ED_NEW && (!usb_pipeint(lurb_priv->pipe))) {
+ edHeadP = m32_swap(ed->hwHeadP) & 0xfffffff0;
+ edTailP = m32_swap(ed->hwTailP);
+
+ /* unlink eds if they are not busy */
+ if ((edHeadP == edTailP) && (ed->state == ED_OPER))
+ ep_unlink(ohci, ed);
+ }
+ return stat;
+}
+
+static int dl_done_list(struct ohci *ohci)
+{
+ struct td *ptd = ohci->ptd;
+ int stat = 0;
+ unsigned long ptdphys = virt_to_phys(ptd);
+ struct td *td_list;
+
+ dma_clean_range(ptdphys, ptdphys + (sizeof(struct td) * NUM_TD));
+
+ td_list = dl_reverse_done_list(ohci);
+
+ while (td_list) {
+ struct td *td_next = td_list->next_dl_td;
+ stat = takeback_td(ohci, td_list);
+ td_list = td_next;
+ }
+
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*
+ * Virtual Root Hub
+ *-------------------------------------------------------------------------*/
+
+/* Device descriptor */
+static __u8 root_hub_dev_des[] = {
+ 0x12, /* __u8 bLength; */
+ 0x01, /* __u8 bDescriptorType; Device */
+ 0x10, /* __u16 bcdUSB; v1.1 */
+ 0x01,
+ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 bDeviceSubClass; */
+ 0x00, /* __u8 bDeviceProtocol; */
+ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
+ 0x00, /* __u16 idVendor; */
+ 0x00,
+ 0x00, /* __u16 idProduct; */
+ 0x00,
+ 0x00, /* __u16 bcdDevice; */
+ 0x00,
+ 0x00, /* __u8 iManufacturer; */
+ 0x01, /* __u8 iProduct; */
+ 0x00, /* __u8 iSerialNumber; */
+ 0x01 /* __u8 bNumConfigurations; */
+};
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] = {
+ 0x09, /* __u8 bLength; */
+ 0x02, /* __u8 bDescriptorType; Configuration */
+ 0x19, /* __u16 wTotalLength; */
+ 0x00,
+ 0x01, /* __u8 bNumInterfaces; */
+ 0x01, /* __u8 bConfigurationValue; */
+ 0x00, /* __u8 iConfiguration; */
+ 0x40, /* __u8 bmAttributes;
+ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+ 0x00, /* __u8 MaxPower; */
+
+ /* interface */
+ 0x09, /* __u8 if_bLength; */
+ 0x04, /* __u8 if_bDescriptorType; Interface */
+ 0x00, /* __u8 if_bInterfaceNumber; */
+ 0x00, /* __u8 if_bAlternateSetting; */
+ 0x01, /* __u8 if_bNumEndpoints; */
+ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 if_bInterfaceSubClass; */
+ 0x00, /* __u8 if_bInterfaceProtocol; */
+ 0x00, /* __u8 if_iInterface; */
+
+ /* endpoint */
+ 0x07, /* __u8 ep_bLength; */
+ 0x05, /* __u8 ep_bDescriptorType; Endpoint */
+ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
+ 0x03, /* __u8 ep_bmAttributes; Interrupt */
+ 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
+ 0x00,
+ 0xff /* __u8 ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_str_index0[] = {
+ 0x04, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 0x09, /* __u8 lang ID */
+ 0x04, /* __u8 lang ID */
+};
+
+static unsigned char root_hub_str_index1[] = {
+ 28, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 'O', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'C', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'I', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'R', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 't', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'u', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'b', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+};
+
+/* Hub class-specific descriptor is constructed dynamically */
+
+static inline void wr_rh_portstat(struct ohci *ohci, int wIndex, __u32 value)
+{
+ info("WR:portstatus[%d] %#8x\n", wIndex - 1, value);
+ writel(value, &ohci->regs->roothub.portstatus[wIndex-1]);
+}
+
+/* request to virtual root hub */
+
+int rh_check_port_status(struct ohci *controller)
+{
+ __u32 temp, ndp, i;
+ int res;
+
+ res = -1;
+ temp = roothub_a(controller);
+ ndp = (temp & RH_A_NDP);
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+ ndp = (ndp == 2) ? 1 : 0;
+#endif
+ for (i = 0; i < ndp; i++) {
+ temp = roothub_portstatus(controller, i);
+ /* check for a device disconnect */
+ if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+ (RH_PS_PESC | RH_PS_CSC)) &&
+ ((temp & RH_PS_CCS) == 0)) {
+ res = i;
+ break;
+ }
+ }
+ return res;
+}
+
+static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len, struct devrequest *cmd)
+{
+ struct usb_host *host = dev->host;
+ struct ohci *ohci = to_ohci(host);
+ void *data = buffer;
+ int leni = transfer_len;
+ int len = 0;
+ int stat = 0;
+ __u32 datab[4];
+ __u8 *data_buf = (__u8 *)datab;
+ __u16 bmRType_bReq;
+ __u16 wValue;
+ __u16 wIndex;
+ __u16 wLength;
+
+ pkt_print(NULL, dev, pipe, buffer, transfer_len,
+ cmd, "SUB(rh)", usb_pipein(pipe));
+
+ if (usb_pipeint(pipe)) {
+ info("Root-Hub submit IRQ: NOT implemented\n");
+ return 0;
+ }
+
+ bmRType_bReq = cmd->requesttype | (cmd->request << 8);
+ wValue = le16_to_cpu(cmd->value);
+ wIndex = le16_to_cpu(cmd->index);
+ wLength = le16_to_cpu(cmd->length);
+
+ info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x\n",
+ dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
+
+ switch (bmRType_bReq) {
+ /* Request Destination:
+ * without flags: Device,
+ * RH_INTERFACE: interface,
+ * RH_ENDPOINT: endpoint,
+ * RH_CLASS means HUB here,
+ * RH_OTHER | RH_CLASS almost ever means HUB_PORT here
+ */
+
+ case RH_GET_STATUS:
+ *(__u16 *) data_buf = cpu_to_le16(1);
+ len = 2;
+ break;
+ case RH_GET_STATUS | RH_INTERFACE:
+ *(__u16 *) data_buf = cpu_to_le16(0);
+ len = 2;
+ break;
+ case RH_GET_STATUS | RH_ENDPOINT:
+ *(__u16 *) data_buf = cpu_to_le16(0);
+ len = 2;
+ break;
+ case RH_GET_STATUS | RH_CLASS:
+ *(__u32 *) data_buf = cpu_to_le32(
+ roothub_status(ohci) & ~(RH_HS_CRWE | RH_HS_DRWE));
+ len = 4;
+ break;
+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+ *(__u32 *) data_buf = cpu_to_le32(roothub_portstatus(ohci, wIndex - 1));
+ len = 4;
+ break;
+
+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
+ switch (wValue) {
+ case RH_ENDPOINT_STALL:
+ len = 0;
+ break;
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_CLASS:
+ switch (wValue) {
+ case RH_C_HUB_LOCAL_POWER:
+ len = 0;
+ break;
+ case RH_C_HUB_OVER_CURRENT:
+ writel(RH_HS_OCIC, &ohci->regs->roothub.status);
+ len = 0;
+ break;
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+ switch (wValue) {
+ case RH_PORT_ENABLE:
+ wr_rh_portstat(ohci, wIndex, RH_PS_CCS);
+ len = 0;
+ break;
+ case RH_PORT_SUSPEND:
+ wr_rh_portstat(ohci, wIndex, RH_PS_POCI);
+ len = 0;
+ break;
+ case RH_PORT_POWER:
+ wr_rh_portstat(ohci, wIndex, RH_PS_LSDA);
+ len = 0;
+ break;
+ case RH_C_PORT_CONNECTION:
+ wr_rh_portstat(ohci, wIndex, RH_PS_CSC);
+ len = 0;
+ break;
+ case RH_C_PORT_ENABLE:
+ wr_rh_portstat(ohci, wIndex, RH_PS_PESC);
+ len = 0;
+ break;
+ case RH_C_PORT_SUSPEND:
+ wr_rh_portstat(ohci, wIndex, RH_PS_PSSC);
+ len = 0;
+ break;
+ case RH_C_PORT_OVER_CURRENT:
+ wr_rh_portstat(ohci, wIndex, RH_PS_OCIC);
+ len = 0;
+ break;
+ case RH_C_PORT_RESET:
+ wr_rh_portstat(ohci, wIndex, RH_PS_PRSC);
+ len = 0;
+ break;
+ }
+ break;
+
+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+ switch (wValue) {
+ case RH_PORT_SUSPEND:
+ wr_rh_portstat(ohci, wIndex, RH_PS_PSS);
+ len = 0;
+ break;
+ case RH_PORT_RESET: /* BUG IN HUP CODE *********/
+ if (roothub_portstatus(ohci, wIndex - 1) & RH_PS_CCS)
+ wr_rh_portstat(ohci, wIndex, RH_PS_PRS);
+ len = 0;
+ break;
+ case RH_PORT_POWER:
+ wr_rh_portstat(ohci, wIndex, RH_PS_PPS);
+ mdelay(100);
+ len = 0;
+ break;
+ case RH_PORT_ENABLE: /* BUG IN HUP CODE *********/
+ if (roothub_portstatus(ohci, wIndex - 1) & RH_PS_CCS)
+ wr_rh_portstat(ohci, wIndex, RH_PS_PES);
+ len = 0;
+ break;
+ }
+ break;
+
+ case RH_SET_ADDRESS:
+ ohci->rh.devnum = wValue;
+ len = 0;
+ break;
+
+ case RH_GET_DESCRIPTOR:
+ switch ((wValue & 0xff00) >> 8) {
+ case 0x01: /* device descriptor */
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof(root_hub_dev_des),
+ wLength));
+ data_buf = root_hub_dev_des;
+ break;
+ case 0x02: /* configuration descriptor */
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof(root_hub_config_des),
+ wLength));
+ data_buf = root_hub_config_des;
+ break;
+ case 0x03: /* string descriptors */
+ if (wValue == 0x0300) {
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof(root_hub_str_index0),
+ wLength));
+ data_buf = root_hub_str_index0;
+ break;
+ }
+ if (wValue == 0x0301) {
+ len = min_t(unsigned int,
+ leni,
+ min_t(unsigned int,
+ sizeof(root_hub_str_index1),
+ wLength));
+ data_buf = root_hub_str_index1;
+ break;
+ }
+ default:
+ stat = USB_ST_STALLED;
+ }
+ break;
+
+ case RH_GET_DESCRIPTOR | RH_CLASS:
+ {
+ __u32 temp = roothub_a(ohci);
+
+ data_buf[0] = 9; /* min length; */
+ data_buf[1] = 0x29;
+ data_buf[2] = temp & RH_A_NDP;
+#ifdef CONFIG_AT91C_PQFP_UHPBUG
+ data_buf[2] = (data_buf[2] == 2) ? 1 : 0;
+#endif
+ data_buf[3] = 0;
+ if (temp & RH_A_PSM) /* per-port power switching? */
+ data_buf[3] |= 0x1;
+ if (temp & RH_A_NOCP) /* no overcurrent reporting? */
+ data_buf[3] |= 0x10;
+ else if (temp & RH_A_OCPM)/* per-port overcurrent reporting? */
+ data_buf[3] |= 0x8;
+
+ /* corresponds to data_buf[4-7] */
+ datab[1] = 0;
+ data_buf[5] = (temp & RH_A_POTPGT) >> 24;
+ temp = roothub_b(ohci);
+ data_buf[7] = temp & RH_B_DR;
+ if (data_buf[2] < 7) {
+ data_buf[8] = 0xff;
+ } else {
+ data_buf[0] += 2;
+ data_buf[8] = (temp & RH_B_DR) >> 8;
+ data_buf[10] = data_buf[9] = 0xff;
+ }
+
+ len = min_t(unsigned int, leni,
+ min_t(unsigned int, data_buf[0], wLength));
+ break;
+ }
+
+ case RH_GET_CONFIGURATION:
+ *(__u8 *) data_buf = 0x01;
+ len = 1;
+ break;
+
+ case RH_SET_CONFIGURATION:
+ writel(0x10000, &ohci->regs->roothub.status);
+ len = 0;
+ break;
+
+ default:
+ debug("unsupported root hub command\n");
+ stat = USB_ST_STALLED;
+ }
+
+ ohci_dump_roothub(ohci, 1);
+
+ len = min_t(int, len, leni);
+
+ if (data != data_buf)
+ memcpy(data, data_buf, len);
+
+ dev->act_len = len;
+ dev->status = stat;
+
+ pkt_print(NULL, dev, pipe, buffer,
+ transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
+
+ return stat;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* common code for handling submit messages - used for all but root hub */
+/* accesses. */
+int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int interval,
+ int timeout)
+{
+ struct usb_host *host = dev->host;
+ struct ohci *ohci = to_ohci(host);
+ int ret, stat = 0;
+ int maxsize = usb_maxpacket(dev, pipe);
+ struct urb_priv *urb;
+ uint64_t start;
+
+ urb = xzalloc(sizeof(struct urb_priv));
+
+ urb->dev = dev;
+ urb->pipe = pipe;
+ urb->transfer_buffer = buffer;
+ urb->transfer_buffer_length = transfer_len;
+ urb->interval = interval;
+
+ urb->actual_length = 0;
+
+ pkt_print(urb, dev, pipe, buffer, transfer_len,
+ setup, "SUB", usb_pipein(pipe));
+
+ if (!maxsize)
+ return -EINVAL;
+
+ ret = sohci_submit_job(urb, setup);
+ if (ret) {
+ err("sohci_submit_job failed with %d\n", ret);
+ return ret;
+ }
+
+ start = get_time_ns();
+
+ /* wait for it to complete */
+ for (;;) {
+ /* check whether the controller is done */
+ stat = hc_interrupt(ohci);
+ if (stat < 0 || urb->finished)
+ break;
+
+ if (is_timeout(start, timeout * MSECOND)) {
+ info("CTL:TIMEOUT\n");
+ debug("%s: TO status %x\n", __func__, stat);
+ urb->finished = 1;
+ ep_unlink(ohci, urb->ed);
+ stat = USB_ST_CRC_ERR;
+ break;
+ }
+ }
+
+ dev->status = stat;
+ dev->act_len = urb->actual_length;
+
+ pkt_print(urb, dev, pipe, buffer, transfer_len,
+ setup, "RET(ctlr)", usb_pipein(pipe));
+
+ /* free TDs in urb_priv */
+ if (!usb_pipeint(pipe))
+ urb_free_priv(urb);
+
+ return 0;
+}
+
+/* submit routines called from usb.c */
+static int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, int timeout)
+{
+ info("submit_bulk_msg\n");
+ return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0, timeout);
+}
+
+static int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int timeout)
+{
+ struct usb_host *host = dev->host;
+ struct ohci *ohci = to_ohci(host);
+ int maxsize = usb_maxpacket(dev, pipe);
+
+ info("submit_control_msg\n");
+
+ pkt_print(NULL, dev, pipe, buffer, transfer_len,
+ setup, "SUB", usb_pipein(pipe));
+
+ if (!maxsize) {
+ err("submit_control_message: pipesize for pipe %lx is zero\n",
+ pipe);
+ return -1;
+ }
+ if (((pipe >> 8) & 0x7f) == ohci->rh.devnum) {
+ ohci->rh.dev = dev;
+ /* root hub - redirect */
+ return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
+ setup);
+ }
+
+ return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0, timeout);
+}
+
+static int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, int interval)
+{
+ info("submit_int_msg\n");
+ return submit_common_msg(dev, pipe, buffer, transfer_len, NULL,
+ interval, 100);
+}
+
+/*-------------------------------------------------------------------------*
+ * HC functions
+ *-------------------------------------------------------------------------*/
+
+/* reset the HC and BUS */
+
+static int hc_reset(struct ohci *ohci)
+{
+ int timeout = 30;
+ int smm_timeout = 50; /* 0,5 sec */
+
+ debug("%s\n", __func__);
+
+ if (readl(&ohci->regs->control) & OHCI_CTRL_IR) {
+ /* SMM owns the HC */
+ writel(OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
+ info("USB HC TakeOver from SMM\n");
+ while (readl(&ohci->regs->control) & OHCI_CTRL_IR) {
+ mdelay(10);
+ if (--smm_timeout == 0) {
+ err("USB HC TakeOver failed!\n");
+ return -1;
+ }
+ }
+ }
+
+ /* Disable HC interrupts */
+ writel(OHCI_INTR_MIE, &ohci->regs->intrdisable);
+
+ debug("USB HC reset_hc usb-%s: ctrl = 0x%X ;\n",
+ ohci->slot_name,
+ readl(&ohci->regs->control));
+
+ /* Reset USB (needed by some controllers) */
+ ohci->hc_control = 0;
+ writel(ohci->hc_control, &ohci->regs->control);
+
+ /* HC Reset requires max 10 us delay */
+ writel(OHCI_HCR, &ohci->regs->cmdstatus);
+ while ((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+ if (--timeout == 0) {
+ err("USB HC reset timed out!\n");
+ return -1;
+ }
+ udelay(1);
+ }
+ return 0;
+}
+
+/*
+ * Start an OHCI controller, set the BUS operational
+ * enable interrupts
+ * connect the virtual root hub
+ */
+static int hc_start(struct ohci *ohci)
+{
+ __u32 mask;
+ unsigned int fminterval;
+
+ ohci->disabled = 1;
+
+ /* Tell the controller where the control and bulk lists are
+ * The lists are empty now. */
+
+ writel(0, &ohci->regs->ed_controlhead);
+ writel(0, &ohci->regs->ed_bulkhead);
+ writel(virt_to_phys((void *)(__u32)ohci->hcca), &ohci->regs->hcca); /* a reset clears this */
+
+ fminterval = 0x2edf;
+ writel((fminterval * 9) / 10, &ohci->regs->periodicstart);
+ fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
+ writel(fminterval, &ohci->regs->fminterval);
+ writel(0x628, &ohci->regs->lsthresh);
+
+ /* start controller operations */
+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ ohci->disabled = 0;
+ writel(ohci->hc_control, &ohci->regs->control);
+
+ /* disable all interrupts */
+ mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
+ OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
+ OHCI_INTR_OC | OHCI_INTR_MIE);
+ writel(mask, &ohci->regs->intrdisable);
+ /* clear all interrupts */
+ mask &= ~OHCI_INTR_MIE;
+ writel(mask, &ohci->regs->intrstatus);
+ /* Choose the interrupts we care about now - but w/o MIE */
+ mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
+ writel(mask, &ohci->regs->intrenable);
+
+#ifdef OHCI_USE_NPS
+ /* required for AMD-756 and some Mac platforms */
+ writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM,
+ &ohci->regs->roothub.a);
+ writel(RH_HS_LPSC, &ohci->regs->roothub.status);
+#endif /* OHCI_USE_NPS */
+
+ /* POTPGT delay is bits 24-31, in 2 ms units. */
+ mdelay((roothub_a(ohci) >> 23) & 0x1fe);
+
+ /* connect the virtual root hub */
+ ohci->rh.devnum = 0;
+
+ return 0;
+}
+
+static int hc_interrupt(struct ohci *ohci)
+{
+ struct ohci_regs *regs = ohci->regs;
+ int ints;
+ int stat = 0;
+
+ ints = readl(&regs->intrstatus);
+ ints &= readl(&regs->intrenable);
+
+ if (!ints)
+ return 0;
+
+ debug("Interrupt: %x frame: %x", ints,
+ le16_to_cpu(ohci->hcca->frame_no));
+
+ if (ints & OHCI_INTR_UE) {
+ ohci->disabled++;
+ err("OHCI Unrecoverable Error, controller usb-%s disabled\n",
+ ohci->slot_name);
+ /* e.g. due to PCI Master/Target Abort */
+
+ ohci_dump(ohci, 1);
+
+ /* FIXME: be optimistic, hope that bug won't repeat often. */
+ /* Make some non-interrupt context restart the controller. */
+ /* Count and limit the retries though; either hardware or */
+ /* software errors can go forever... */
+ hc_reset(ohci);
+ return -EIO;
+ }
+
+ if (ints & OHCI_INTR_WDH) {
+ writel(OHCI_INTR_WDH, &regs->intrdisable);
+ readl(&regs->intrdisable); /* flush */
+
+ stat = dl_done_list(ohci);
+
+ writel(OHCI_INTR_WDH, &regs->intrenable);
+ readl(&regs->intrdisable); /* flush */
+ }
+
+ if (ints & OHCI_INTR_SO) {
+ debug("USB Schedule overrun\n");
+ writel(OHCI_INTR_SO, &regs->intrenable);
+ stat = -EINVAL;
+ }
+
+ writel(ints, &regs->intrstatus);
+
+ return stat;
+}
+
+/* De-allocate all resources.. */
+
+static void hc_release_ohci(struct ohci *ohci)
+{
+ debug("USB HC release ohci usb-%s\n", ohci->slot_name);
+
+ if (!ohci->disabled)
+ hc_reset(ohci);
+}
+
+static int ohci_init(struct usb_host *host)
+{
+ struct ohci *ohci = to_ohci(host);
+
+ info("%s\n", __func__);
+
+ ohci->ptd = dma_alloc_coherent(sizeof(struct td) * NUM_TD);
+ if (!ohci->ptd)
+ return -ENOMEM;
+ memset(ohci->ptd, 0, sizeof(struct td) * NUM_TD);
+
+ ohci->disabled = 1;
+ ohci->irq = -1;
+
+ ohci->flags = 0;
+ ohci->slot_name = "ohci"; /* FIXME */
+
+ if (hc_reset(ohci) < 0) {
+ hc_release_ohci(ohci);
+ err("can't reset usb-%s\n", ohci->slot_name);
+ return -1;
+ }
+
+ if (hc_start(ohci) < 0) {
+ err("can't start usb-%s\n", ohci->slot_name);
+ hc_release_ohci(ohci);
+ /* Initialization failed */
+ return -1;
+ }
+
+ ohci_dump(ohci, 1);
+
+ return 0;
+}
+
+static int ohci_probe(struct device_d *dev)
+{
+ struct usb_host *host;
+ struct ohci *ohci;
+
+ ohci = xzalloc(sizeof(struct ohci));
+ host = &ohci->host;
+
+ host->init = ohci_init;
+ host->submit_int_msg = submit_int_msg;
+ host->submit_control_msg = submit_control_msg;
+ host->submit_bulk_msg = submit_bulk_msg;
+
+ ohci->hcca = dma_alloc_coherent(sizeof(*ohci->hcca));
+ if (!ohci->hcca)
+ return -ENOMEM;
+
+ ohci->ohci_dev = dma_alloc_coherent(sizeof(*ohci->ohci_dev));
+ if (!ohci->ohci_dev)
+ return -ENOMEM;
+ memset(ohci->ohci_dev, 0, sizeof(*ohci->ohci_dev));
+
+ usb_register_host(host);
+
+ ohci->regs = (void *)dev->resource[0].start;
+
+ return 0;
+}
+
+static struct driver_d ohci_driver = {
+ .name = "ohci",
+ .probe = ohci_probe,
+};
+
+static int ohcil_init(void)
+{
+ register_driver(&ohci_driver);
+ return 0;
+}
+
+device_initcall(ohcil_init);
+
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
new file mode 100644
index 0000000000..913296319e
--- /dev/null
+++ b/drivers/usb/host/ohci.h
@@ -0,0 +1,428 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
+ *
+ * usb-ohci.h
+ */
+
+/* functions for doing board or CPU specific setup/cleanup */
+extern int usb_board_init(void);
+extern int usb_board_stop(void);
+extern int usb_board_init_fail(void);
+
+extern int usb_cpu_init(void);
+extern int usb_cpu_stop(void);
+extern int usb_cpu_init_fail(void);
+
+/* map OHCI TD status codes (CC) to errno values */
+static const int __maybe_unused cc_to_error[16] = {
+ /* No Error */ 0,
+ /* CRC Error */ -EILSEQ,
+ /* Bit Stuff */ -EPROTO,
+ /* Data Togg */ -EILSEQ,
+ /* Stall */ -EPIPE,
+ /* DevNotResp */ -ETIME,
+ /* PIDCheck */ -EPROTO,
+ /* UnExpPID */ -EPROTO,
+ /* DataOver */ -EOVERFLOW,
+ /* DataUnder */ -EREMOTEIO,
+ /* (for hw) */ -EIO,
+ /* (for hw) */ -EIO,
+ /* BufferOver */ -ECOMM,
+ /* BuffUnder */ -ENOSR,
+ /* (for HCD) */ -EALREADY,
+ /* (for HCD) */ -EALREADY
+};
+
+static const char __maybe_unused *cc_to_string[16] = {
+ "No Error",
+ "CRC: Last data packet from endpoint contained a CRC error.",
+ "BITSTUFFING: Last data packet from endpoint contained a bit " \
+ "stuffing violation",
+ "DATATOGGLEMISMATCH: Last packet from endpoint had data toggle PID\n" \
+ "that did not match the expected value.",
+ "STALL: TD was moved to the Done Queue because the endpoint returned" \
+ " a STALL PID",
+ "DEVICENOTRESPONDING: Device did not respond to token (IN) or did\n" \
+ "not provide a handshake (OUT)",
+ "PIDCHECKFAILURE: Check bits on PID from endpoint failed on data PID\n"\
+ "(IN) or handshake (OUT)",
+ "UNEXPECTEDPID: Receive PID was not valid when encountered or PID\n" \
+ "value is not defined.",
+ "DATAOVERRUN: The amount of data returned by the endpoint exceeded\n" \
+ "either the size of the maximum data packet allowed\n" \
+ "from the endpoint (found in MaximumPacketSize field\n" \
+ "of ED) or the remaining buffer size.",
+ "DATAUNDERRUN: The endpoint returned less than MaximumPacketSize\n" \
+ "and that amount was not sufficient to fill the\n" \
+ "specified buffer",
+ "reserved1",
+ "reserved2",
+ "BUFFEROVERRUN: During an IN, HC received data from endpoint faster\n" \
+ "than it could be written to system memory",
+ "BUFFERUNDERRUN: During an OUT, HC could not retrieve data from\n" \
+ "system memory fast enough to keep up with data USB " \
+ "data rate.",
+ "NOT ACCESSED: This code is set by software before the TD is placed" \
+ "on a list to be processed by the HC.(1)",
+ "NOT ACCESSED: This code is set by software before the TD is placed" \
+ "on a list to be processed by the HC.(2)",
+};
+
+/* ED States */
+
+#define ED_NEW 0x00
+#define ED_UNLINK 0x01
+#define ED_OPER 0x02
+#define ED_DEL 0x04
+#define ED_URB_DEL 0x08
+
+/* usb_ohci_ed */
+struct ed {
+ __u32 hwINFO;
+ __u32 hwTailP;
+ __u32 hwHeadP;
+ __u32 hwNextED;
+
+ struct ed *ed_prev;
+ __u8 int_period;
+ __u8 int_branch;
+ __u8 int_load;
+ __u8 int_interval;
+ __u8 state;
+ __u8 type;
+ __u16 last_iso;
+ struct ed *ed_rm_list;
+
+ struct usb_device *usb_dev;
+ void *purb;
+ __u32 unused[2];
+} __attribute__((aligned(16)));
+
+/* TD info field */
+#define TD_CC 0xf0000000
+#define TD_CC_GET(td_p) ((td_p >> 28) & 0x0f)
+#define TD_CC_SET(td_p, cc) do { \
+ (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28); \
+ } while (0);
+#define TD_EC 0x0C000000
+#define TD_T 0x03000000
+#define TD_T_DATA0 0x02000000
+#define TD_T_DATA1 0x03000000
+#define TD_T_TOGGLE 0x00000000
+#define TD_R 0x00040000
+#define TD_DI 0x00E00000
+#define TD_DI_SET(X) (((X) & 0x07) << 21)
+#define TD_DP 0x00180000
+#define TD_DP_SETUP 0x00000000
+#define TD_DP_IN 0x00100000
+#define TD_DP_OUT 0x00080000
+
+#define TD_ISO 0x00010000
+#define TD_DEL 0x00020000
+
+/* CC Codes */
+#define TD_CC_NOERROR 0x00
+#define TD_CC_CRC 0x01
+#define TD_CC_BITSTUFFING 0x02
+#define TD_CC_DATATOGGLEM 0x03
+#define TD_CC_STALL 0x04
+#define TD_DEVNOTRESP 0x05
+#define TD_PIDCHECKFAIL 0x06
+#define TD_UNEXPECTEDPID 0x07
+#define TD_DATAOVERRUN 0x08
+#define TD_DATAUNDERRUN 0x09
+#define TD_BUFFEROVERRUN 0x0C
+#define TD_BUFFERUNDERRUN 0x0D
+#define TD_NOTACCESSED 0x0F
+
+
+#define MAXPSW 1
+
+struct td {
+ __u32 hwINFO;
+ __u32 hwCBP; /* Current Buffer Pointer */
+ __u32 hwNextTD; /* Next TD Pointer */
+ __u32 hwBE; /* Memory Buffer End Pointer */
+ __u16 hwPSW[MAXPSW];
+ __u8 unused;
+ __u8 index;
+ struct ed *ed;
+ struct td *next_dl_td;
+ struct usb_device *usb_dev;
+ int transfer_len;
+ __u32 data;
+
+ __u32 unused2[2];
+} __attribute__((aligned(32)));
+
+#define OHCI_ED_SKIP (1 << 14)
+
+/*
+ * The HCCA (Host Controller Communications Area) is a 256 byte
+ * structure defined in the OHCI spec. that the host controller is
+ * told the base address of. It must be 256-byte aligned.
+ */
+
+#define NUM_INTS 32 /* part of the OHCI standard */
+struct ohci_hcca {
+ __u32 int_table[NUM_INTS]; /* Interrupt ED table */
+ /*
+ * OHCI defines u16 frame_no, followed by u16 zero pad.
+ * Since some processors can't do 16 bit bus accesses,
+ * portable access must be a 32 bits wide.
+ */
+ __u16 frame_no; /* current frame number */
+ __u16 pad1;
+ __u32 done_head; /* info returned for an interrupt */
+ u8 reserved_for_hc[116];
+} __attribute__((aligned(256)));
+
+/*
+ * This is the structure of the OHCI controller's memory mapped I/O
+ * region. This is Memory Mapped I/O. You must use the readl() and
+ * writel() macros defined in asm/io.h to access these!!
+ */
+struct ohci_regs {
+ /* control and status registers */
+ __u32 revision;
+ __u32 control;
+ __u32 cmdstatus;
+ __u32 intrstatus;
+ __u32 intrenable;
+ __u32 intrdisable;
+ /* memory pointers */
+ __u32 hcca;
+ __u32 ed_periodcurrent;
+ __u32 ed_controlhead;
+ __u32 ed_controlcurrent;
+ __u32 ed_bulkhead;
+ __u32 ed_bulkcurrent;
+ __u32 donehead;
+ /* frame counters */
+ __u32 fminterval;
+ __u32 fmremaining;
+ __u32 fmnumber;
+ __u32 periodicstart;
+ __u32 lsthresh;
+ /* Root hub ports */
+ struct ohci_roothub_regs {
+ __u32 a;
+ __u32 b;
+ __u32 status;
+ __u32 portstatus[15];
+ } roothub;
+} __attribute__((aligned(32)));
+
+/* Some EHCI controls */
+#define EHCI_USBCMD_OFF 0x20
+#define EHCI_USBCMD_HCRESET (1 << 1)
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
+#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
+#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
+#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
+#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
+#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
+#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
+#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
+#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+# define OHCI_USB_RESET (0 << 6)
+# define OHCI_USB_RESUME (1 << 6)
+# define OHCI_USB_OPER (2 << 6)
+# define OHCI_USB_SUSPEND (3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR (1 << 0) /* host controller reset */
+#define OHCI_CLF (1 << 1) /* control list filled */
+#define OHCI_BLF (1 << 2) /* bulk list filled */
+#define OHCI_OCR (1 << 3) /* ownership change request */
+#define OHCI_SOC (3 << 16) /* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
+#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
+#define OHCI_INTR_SF (1 << 2) /* start frame */
+#define OHCI_INTR_RD (1 << 3) /* resume detect */
+#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
+#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
+#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
+#define OHCI_INTR_OC (1 << 30) /* ownership change */
+#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
+
+
+/* Virtual Root HUB */
+struct virt_root_hub {
+ int devnum; /* Address of Root Hub endpoint */
+ void *dev; /* was urb */
+ void *int_addr;
+ int send;
+ int interval;
+};
+
+/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
+
+/* destination of request */
+#define RH_INTERFACE 0x01
+#define RH_ENDPOINT 0x02
+#define RH_OTHER 0x03
+
+#define RH_CLASS 0x20
+#define RH_VENDOR 0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS 0x0080
+#define RH_CLEAR_FEATURE 0x0100
+#define RH_SET_FEATURE 0x0300
+#define RH_SET_ADDRESS 0x0500
+#define RH_GET_DESCRIPTOR 0x0680
+#define RH_SET_DESCRIPTOR 0x0700
+#define RH_GET_CONFIGURATION 0x0880
+#define RH_SET_CONFIGURATION 0x0900
+#define RH_GET_STATE 0x0280
+#define RH_GET_INTERFACE 0x0A80
+#define RH_SET_INTERFACE 0x0B00
+#define RH_SYNC_FRAME 0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP 0x2000
+
+
+/* Hub port features */
+#define RH_PORT_CONNECTION 0x00
+#define RH_PORT_ENABLE 0x01
+#define RH_PORT_SUSPEND 0x02
+#define RH_PORT_OVER_CURRENT 0x03
+#define RH_PORT_RESET 0x04
+#define RH_PORT_POWER 0x08
+#define RH_PORT_LOW_SPEED 0x09
+
+#define RH_C_PORT_CONNECTION 0x10
+#define RH_C_PORT_ENABLE 0x11
+#define RH_C_PORT_SUSPEND 0x12
+#define RH_C_PORT_OVER_CURRENT 0x13
+#define RH_C_PORT_RESET 0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER 0x00
+#define RH_C_HUB_OVER_CURRENT 0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP 0x00
+#define RH_ENDPOINT_STALL 0x01
+
+#define RH_ACK 0x01
+#define RH_REQ_ERR -1
+#define RH_NACK 0x00
+
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS 0x00000001 /* current connect status */
+#define RH_PS_PES 0x00000002 /* port enable status*/
+#define RH_PS_PSS 0x00000004 /* port suspend status */
+#define RH_PS_POCI 0x00000008 /* port over current indicator */
+#define RH_PS_PRS 0x00000010 /* port reset status */
+#define RH_PS_PPS 0x00000100 /* port power status */
+#define RH_PS_LSDA 0x00000200 /* low speed device attached */
+#define RH_PS_CSC 0x00010000 /* connect status change */
+#define RH_PS_PESC 0x00020000 /* port enable status change */
+#define RH_PS_PSSC 0x00040000 /* port suspend status change */
+#define RH_PS_OCIC 0x00080000 /* over current indicator change */
+#define RH_PS_PRSC 0x00100000 /* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS 0x00000001 /* local power status */
+#define RH_HS_OCI 0x00000002 /* over current indicator */
+#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
+#define RH_HS_LPSC 0x00010000 /* local power status change */
+#define RH_HS_OCIC 0x00020000 /* over current indicator change */
+#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR 0x0000ffff /* device removable flags */
+#define RH_B_PPCM 0xffff0000 /* port power control mask */
+
+/* roothub.a masks */
+#define RH_A_NDP (0xff << 0) /* number of downstream ports */
+#define RH_A_PSM (1 << 8) /* power switching mode */
+#define RH_A_NPS (1 << 9) /* no power switching */
+#define RH_A_DT (1 << 10) /* device type (mbz) */
+#define RH_A_OCPM (1 << 11) /* over current protection mode */
+#define RH_A_NOCP (1 << 12) /* no over current protection */
+#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
+
+/* urb */
+#define N_URB_TD 48
+struct urb_priv {
+ struct ed *ed;
+ __u16 length; /* number of tds associated with this request */
+ __u16 td_cnt; /* number of tds already serviced */
+ struct usb_device *dev;
+ int state;
+ unsigned long pipe;
+ void *transfer_buffer;
+ int transfer_buffer_length;
+ int interval;
+ int actual_length;
+ int finished;
+ struct td *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */
+};
+#define URB_DEL 1
+
+/*
+ * This is the full ohci controller description
+ *
+ * Note how the "proper" USB information is just
+ * a subset of what the full implementation needs. (Linus)
+ */
+
+#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
+
+struct ohci_device {
+ struct ed ed[NUM_EDS];
+ int ed_cnt;
+};
+
+struct ohci {
+ struct usb_host host;
+ struct ohci_hcca *hcca; /* hcca */
+ /*dma_addr_t hcca_dma;*/
+
+ int irq;
+ int disabled; /* e.g. got a UE, we're hung */
+ unsigned long flags; /* for HC bugs */
+
+ struct ohci_regs *regs; /* OHCI controller's memory */
+
+ int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load balancing)*/
+ struct ed *ed_rm_list[2]; /* lists of all endpoints to be removed */
+ struct ed *ed_bulktail; /* last endpoint of bulk list */
+ struct ed *ed_controltail; /* last endpoint of control list */
+ int intrstatus;
+ __u32 hc_control; /* copy of the hc control reg */
+ struct virt_root_hub rh;
+
+ const char *slot_name;
+ struct ohci_device *ohci_dev;
+ struct td *ptd;
+};
+
+/* we need more TDs than EDs */
+#define NUM_TD 64
+
diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c
index 4a898fb223..6ed6f01e8e 100644
--- a/drivers/usb/otg/ulpi.c
+++ b/drivers/usb/otg/ulpi.c
@@ -17,7 +17,7 @@
*/
#include <common.h>
-#include <asm/io.h>
+#include <io.h>
#include <errno.h>
#include <usb/ulpi.h>
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
new file mode 100644
index 0000000000..f6c8c06b1e
--- /dev/null
+++ b/drivers/usb/storage/Kconfig
@@ -0,0 +1,2 @@
+config USB_STORAGE
+ tristate "USB Mass Storage support"
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
new file mode 100644
index 0000000000..adf08433d5
--- /dev/null
+++ b/drivers/usb/storage/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_USB_STORAGE) += usb-storage.o
+
+usb-storage-objs := usb.o transport.o
+
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
new file mode 100644
index 0000000000..e7a5972750
--- /dev/null
+++ b/drivers/usb/storage/transport.c
@@ -0,0 +1,251 @@
+/*
+ * Most of this source has been derived from the Linux and
+ * U-Boot USB Mass Storage driver implementations.
+ *
+ * Adapted for barebox:
+ * Copyright (c) 2011, AMK Drives & Controls Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <clock.h>
+#include <scsi.h>
+#include <errno.h>
+
+#undef USB_STOR_DEBUG
+
+#include "usb.h"
+#include "transport.h"
+
+
+/* The timeout argument of usb_bulk_msg() is actually ignored
+ and the timeout is hardcoded in the host driver */
+#define USB_BULK_TO 5000
+
+static __u32 cbw_tag = 0;
+
+/* direction table -- this indicates the direction of the data
+ * transfer for each command code (bit-encoded) -- 1 indicates input
+ * note that this doesn't work for shared command codes
+ */
+static const unsigned char us_direction[256/8] = {
+ 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
+ 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x40, 0x09, 0x01, 0x80, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
+
+
+/*
+ * Bulk only transport
+ */
+
+/* Clear a stall on an endpoint - special for bulk-only devices */
+int usb_stor_Bulk_clear_endpt_stall(struct us_data *us, unsigned int pipe)
+{
+ return usb_clear_halt(us->pusb_dev, pipe);
+}
+
+/* Determine what the maximum LUN supported is */
+int usb_stor_Bulk_max_lun(struct us_data *us)
+{
+ int len;
+ unsigned char iobuf[1];
+
+ /* issue the command */
+ iobuf[0] = 0;
+ len = usb_control_msg(us->pusb_dev,
+ usb_rcvctrlpipe(us->pusb_dev, 0),
+ US_BULK_GET_MAX_LUN,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, us->ifnum, iobuf, 1, USB_CNTL_TIMEOUT);
+
+ US_DEBUGP("GetMaxLUN command result is %d, data is %d\n",
+ len, (int)iobuf[0]);
+
+ /* if we have a successful request, return the result */
+ if (len > 0)
+ return (int)iobuf[0];
+
+ /*
+ * Some devices don't like GetMaxLUN. They may STALL the control
+ * pipe, they may return a zero-length result, they may do nothing at
+ * all and timeout, or they may fail in even more bizarrely creative
+ * ways. In these cases the best approach is to use the default
+ * value: only one LUN.
+ */
+ return 0;
+}
+
+int usb_stor_Bulk_transport(ccb *srb, struct us_data *us)
+{
+ struct bulk_cb_wrap cbw;
+ struct bulk_cs_wrap csw;
+ int actlen, data_actlen;
+ int result;
+ unsigned int residue;
+ unsigned int pipein = usb_rcvbulkpipe(us->pusb_dev, us->recv_bulk_ep);
+ unsigned int pipeout = usb_sndbulkpipe(us->pusb_dev, us->send_bulk_ep);
+ int dir_in = US_DIRECTION(srb->cmd[0]);
+
+ srb->trans_bytes = 0;
+
+ /* set up the command wrapper */
+ cbw.Signature = cpu_to_le32(US_BULK_CB_SIGN);
+ cbw.DataTransferLength = cpu_to_le32(srb->datalen);
+ cbw.Flags = (dir_in ? US_BULK_FLAG_IN : US_BULK_FLAG_OUT);
+ cbw.Tag = ++cbw_tag;
+ cbw.Lun = srb->lun;
+ cbw.Length = srb->cmdlen;
+
+ /* copy the command payload */
+ memcpy(cbw.CDB, srb->cmd, cbw.Length);
+
+ /* send it to out endpoint */
+ US_DEBUGP("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
+ le32_to_cpu(cbw.Signature), cbw.Tag,
+ le32_to_cpu(cbw.DataTransferLength), cbw.Flags,
+ (cbw.Lun >> 4), (cbw.Lun & 0x0F),
+ cbw.Length);
+ result = usb_bulk_msg(us->pusb_dev, pipeout, &cbw, US_BULK_CB_WRAP_LEN,
+ &actlen, USB_BULK_TO);
+ US_DEBUGP("Bulk command transfer result=%d\n", result);
+ if (result < 0) {
+ usb_stor_Bulk_reset(us);
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+
+ /* DATA STAGE */
+ /* send/receive data payload, if there is any */
+
+ wait_ms(1);
+
+ data_actlen = 0;
+ if (srb->datalen) {
+ unsigned int pipe = dir_in ? pipein : pipeout;
+ result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata,
+ srb->datalen, &data_actlen, USB_BULK_TO);
+ US_DEBUGP("Bulk data transfer result 0x%x\n", result);
+ /* special handling of STALL in DATA phase */
+ if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
+ US_DEBUGP("DATA: stall\n");
+ /* clear the STALL on the endpoint */
+ result = usb_stor_Bulk_clear_endpt_stall(us, pipe);
+ }
+ if (result < 0) {
+ US_DEBUGP("Device status: %lx\n", us->pusb_dev->status);
+ usb_stor_Bulk_reset(us);
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+ }
+
+ /* STATUS phase + error handling */
+ US_DEBUGP("Attempting to get CSW...\n");
+ result = usb_bulk_msg(us->pusb_dev, pipein, &csw, US_BULK_CS_WRAP_LEN,
+ &actlen, USB_BULK_TO);
+
+ /* did the endpoint stall? */
+ if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
+ US_DEBUGP("STATUS: stall\n");
+ /* clear the STALL on the endpoint */
+ result = usb_stor_Bulk_clear_endpt_stall(us, pipein);
+ if (result >= 0) {
+ US_DEBUGP("Attempting to get CSW...\n");
+ result = usb_bulk_msg(us->pusb_dev, pipein,
+ &csw, US_BULK_CS_WRAP_LEN,
+ &actlen, USB_BULK_TO);
+ }
+ }
+
+ if (result < 0) {
+ US_DEBUGP("Device status: %lx\n", us->pusb_dev->status);
+ usb_stor_Bulk_reset(us);
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+
+ /* check bulk status */
+ residue = le32_to_cpu(csw.Residue);
+ US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
+ le32_to_cpu(csw.Signature), csw.Tag, residue, csw.Status);
+ if (csw.Signature != cpu_to_le32(US_BULK_CS_SIGN)) {
+ US_DEBUGP("Bad CSW signature\n");
+ usb_stor_Bulk_reset(us);
+ return USB_STOR_TRANSPORT_FAILED;
+ } else if (csw.Tag != cbw_tag) {
+ US_DEBUGP("Mismatching tag\n");
+ usb_stor_Bulk_reset(us);
+ return USB_STOR_TRANSPORT_FAILED;
+ } else if (csw.Status >= US_BULK_STAT_PHASE) {
+ US_DEBUGP("Status >= phase\n");
+ usb_stor_Bulk_reset(us);
+ return USB_STOR_TRANSPORT_ERROR;
+ } else if (residue > srb->datalen) {
+ US_DEBUGP("residue (%uB) > req data (%luB)\n",
+ residue, srb->datalen);
+ return USB_STOR_TRANSPORT_FAILED;
+ } else if (csw.Status == US_BULK_STAT_FAIL) {
+ US_DEBUGP("FAILED\n");
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+ srb->trans_bytes = min(srb->datalen - residue, (ulong)data_actlen);
+
+ return 0;
+}
+
+
+/* This issues a Bulk-only Reset to the device in question, including
+ * clearing the subsequent endpoint halts that may occur.
+ */
+int usb_stor_Bulk_reset(struct us_data *us)
+{
+ int result;
+ int result2;
+ unsigned int pipe;
+
+ US_DEBUGP("%s called\n", __func__);
+
+ /* issue the command */
+ result = usb_control_msg(us->pusb_dev,
+ usb_sndctrlpipe(us->pusb_dev, 0),
+ US_BULK_RESET_REQUEST,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, us->ifnum, 0, 0, USB_CNTL_TIMEOUT);
+ if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
+ US_DEBUGP("Soft reset stalled: %d\n", result);
+ return result;
+ }
+ wait_ms(150);
+
+ /* clear the bulk endpoints halt */
+ US_DEBUGP("Soft reset: clearing %s endpoint halt\n", "bulk-in");
+ pipe = usb_rcvbulkpipe(us->pusb_dev, us->recv_bulk_ep);
+ result = usb_clear_halt(us->pusb_dev, pipe);
+ wait_ms(150);
+ US_DEBUGP("Soft reset: clearing %s endpoint halt\n", "bulk-out");
+ pipe = usb_sndbulkpipe(us->pusb_dev, us->send_bulk_ep);
+ result2 = usb_clear_halt(us->pusb_dev, pipe);
+ wait_ms(150);
+
+ if (result >= 0)
+ result = result2;
+ US_DEBUGP("Soft reset %s\n", ((result < 0) ? "failed" : "done"));
+
+ return result;
+}
+
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
new file mode 100644
index 0000000000..1c5c1417db
--- /dev/null
+++ b/drivers/usb/storage/transport.h
@@ -0,0 +1,95 @@
+/*
+ * Most of this source has been derived from the Linux and
+ * U-Boot USB Mass Storage driver implementations.
+ *
+ * Adapted for barebox:
+ * Copyright (c) 2011, AMK Drives & Controls Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef _TRANSPORT_H_
+#define _TRANSPORT_H_
+
+#include <scsi.h>
+
+/*
+ * Bulk only data structures
+ */
+
+/* command block wrapper */
+struct bulk_cb_wrap {
+ __le32 Signature; /* contains 'USBC' */
+ __u32 Tag; /* unique per command id */
+ __le32 DataTransferLength; /* size of data */
+ __u8 Flags; /* direction in bit 7 */
+ __u8 Lun; /* LUN normally 0 */
+ __u8 Length; /* of of the CDB */
+ __u8 CDB[16]; /* max command */
+};
+
+#define US_BULK_CB_WRAP_LEN 31
+#define US_BULK_CB_SIGN 0x43425355 /*spells out USBC */
+#define US_BULK_FLAG_IN (1<<7)
+#define US_BULK_FLAG_OUT (0<<7)
+
+/* command status wrapper */
+struct bulk_cs_wrap {
+ __le32 Signature; /* should = 'USBS' */
+ __u32 Tag; /* same as original command */
+ __le32 Residue; /* amount not transferred */
+ __u8 Status; /* see below */
+ __u8 Filler[18];
+};
+
+#define US_BULK_CS_WRAP_LEN 13
+#define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */
+#define US_BULK_STAT_OK 0
+#define US_BULK_STAT_FAIL 1
+#define US_BULK_STAT_PHASE 2
+
+/* bulk-only class specific requests */
+#define US_BULK_RESET_REQUEST 0xff
+#define US_BULK_GET_MAX_LUN 0xfe
+
+/*
+ * usb_stor_bulk_transfer_xxx() return codes, in order of severity
+ */
+
+#define USB_STOR_XFER_GOOD 0 /* good transfer */
+#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */
+#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
+#define USB_STOR_XFER_LONG 3 /* device tried to send too much */
+#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */
+
+/*
+ * Transport return codes
+ */
+
+#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */
+#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */
+#define USB_STOR_TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */
+#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
+
+
+struct us_data;
+
+extern int usb_stor_Bulk_transport(ccb *, struct us_data *);
+extern int usb_stor_Bulk_max_lun(struct us_data *);
+extern int usb_stor_Bulk_reset(struct us_data *);
+
+#endif
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
new file mode 100644
index 0000000000..d033b291c2
--- /dev/null
+++ b/drivers/usb/storage/usb.c
@@ -0,0 +1,619 @@
+/*
+ * Most of this source has been derived from the Linux and
+ * U-Boot USB Mass Storage driver implementations.
+ *
+ * Adapted for barebox:
+ * Copyright (c) 2011, AMK Drives & Controls Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <errno.h>
+#include <scsi.h>
+#include <usb/usb.h>
+#include <usb/usb_defs.h>
+
+#undef USB_STOR_DEBUG
+
+#include "usb.h"
+#include "transport.h"
+
+
+static LIST_HEAD(us_blkdev_list);
+
+
+/***********************************************************************
+ * USB Storage routines
+ ***********************************************************************/
+
+static int usb_stor_inquiry(ccb *srb, struct us_data *us)
+{
+ int retries, result;
+
+ srb->datalen = min(128UL, srb->datalen);
+ if (srb->datalen < 5) {
+ US_DEBUGP("SCSI_INQUIRY: invalid data buffer size\n");
+ return -EINVAL;
+ }
+
+ retries = 3;
+ do {
+ US_DEBUGP("SCSI_INQUIRY\n");
+ memset(&srb->cmd[0], 0, 6);
+ srb->cmdlen = 6;
+ srb->cmd[0] = SCSI_INQUIRY;
+ srb->cmd[3] = (u8)(srb->datalen >> 8);
+ srb->cmd[4] = (u8)(srb->datalen >> 0);
+ result = us->transport(srb, us);
+ US_DEBUGP("SCSI_INQUIRY returns %d\n", result);
+ } while ((result != USB_STOR_TRANSPORT_GOOD) && retries--);
+
+ return (result != USB_STOR_TRANSPORT_GOOD) ? -EIO : 0;
+}
+
+static int usb_stor_request_sense(ccb *srb, struct us_data *us)
+{
+ unsigned char *pdata = srb->pdata;
+ unsigned long datalen = srb->datalen;
+
+ US_DEBUGP("SCSI_REQ_SENSE\n");
+ srb->pdata = &srb->sense_buf[0];
+ srb->datalen = 18;
+ memset(&srb->cmd[0], 0, 6);
+ srb->cmdlen = 6;
+ srb->cmd[0] = SCSI_REQ_SENSE;
+ srb->cmd[4] = (u8)(srb->datalen >> 0);
+ us->transport(srb, us);
+ US_DEBUGP("Request Sense returned %02X %02X %02X\n",
+ srb->sense_buf[2], srb->sense_buf[12], srb->sense_buf[13]);
+ srb->pdata = pdata;
+ srb->datalen = datalen;
+
+ return 0;
+}
+
+static int usb_stor_test_unit_ready(ccb *srb, struct us_data *us)
+{
+ int retries, result;
+
+ retries = 10;
+ do {
+ US_DEBUGP("SCSI_TST_U_RDY\n");
+ memset(&srb->cmd[0], 0, 6);
+ srb->cmdlen = 6;
+ srb->cmd[0] = SCSI_TST_U_RDY;
+ srb->datalen = 0;
+ result = us->transport(srb, us);
+ US_DEBUGP("SCSI_TST_U_RDY returns %d\n", result);
+ if (result == USB_STOR_TRANSPORT_GOOD)
+ return 0;
+ usb_stor_request_sense(srb, us);
+ wait_ms(100);
+ } while (retries--);
+
+ return -1;
+}
+
+static int usb_stor_read_capacity(ccb *srb, struct us_data *us)
+{
+ int retries, result;
+
+ if (srb->datalen < 8) {
+ US_DEBUGP("SCSI_RD_CAPAC: invalid data buffer size\n");
+ return -EINVAL;
+ }
+
+ retries = 3;
+ do {
+ US_DEBUGP("SCSI_RD_CAPAC\n");
+ memset(&srb->cmd[0], 0, 10);
+ srb->cmdlen = 10;
+ srb->cmd[0] = SCSI_RD_CAPAC;
+ srb->datalen = 8;
+ result = us->transport(srb, us);
+ US_DEBUGP("SCSI_RD_CAPAC returns %d\n", result);
+ } while ((result != USB_STOR_TRANSPORT_GOOD) && retries--);
+
+ return (result != USB_STOR_TRANSPORT_GOOD) ? -EIO : 0;
+}
+
+static int usb_stor_read_10(ccb *srb, struct us_data *us,
+ unsigned long start, unsigned short blocks)
+{
+ int retries, result;
+
+ retries = 2;
+ do {
+ US_DEBUGP("SCSI_READ10: start %lx blocks %x\n", start, blocks);
+ memset(&srb->cmd[0], 0, 10);
+ srb->cmdlen = 10;
+ srb->cmd[0] = SCSI_READ10;
+ srb->cmd[2] = (u8)(start >> 24);
+ srb->cmd[3] = (u8)(start >> 16);
+ srb->cmd[4] = (u8)(start >> 8);
+ srb->cmd[5] = (u8)(start >> 0);
+ srb->cmd[7] = (u8)(blocks >> 8);
+ srb->cmd[8] = (u8)(blocks >> 0);
+ result = us->transport(srb, us);
+ US_DEBUGP("SCSI_READ10 returns %d\n", result);
+ if (result == USB_STOR_TRANSPORT_GOOD)
+ return 0;
+ usb_stor_request_sense(srb, us);
+ } while (retries--);
+
+ return -EIO;
+}
+
+static int usb_stor_write_10(ccb *srb, struct us_data *us,
+ unsigned long start, unsigned short blocks)
+{
+ int retries, result;
+
+ retries = 2;
+ do {
+ US_DEBUGP("SCSI_WRITE10: start %lx blocks %x\n", start, blocks);
+ memset(&srb->cmd[0], 0, 10);
+ srb->cmdlen = 10;
+ srb->cmd[0] = SCSI_WRITE10;
+ srb->cmd[2] = (u8)(start >> 24);
+ srb->cmd[3] = (u8)(start >> 16);
+ srb->cmd[4] = (u8)(start >> 8);
+ srb->cmd[5] = (u8)(start >> 0);
+ srb->cmd[7] = (u8)(blocks >> 8);
+ srb->cmd[8] = (u8)(blocks >> 0);
+ result = us->transport(srb, us);
+ US_DEBUGP("SCSI_WRITE10 returns %d\n", result);
+ if (result == USB_STOR_TRANSPORT_GOOD)
+ return 0;
+ usb_stor_request_sense(srb, us);
+ } while (retries--);
+
+ return us->transport(srb, us);
+}
+
+
+/***********************************************************************
+ * Disk driver interface
+ ***********************************************************************/
+
+#define US_MAX_IO_BLK 32U
+
+enum { io_rd, io_wr };
+
+/* Read / write a chunk of sectors on media */
+static int usb_stor_blk_io(int io_op, struct device_d *disk_dev,
+ uint64_t sector_start, unsigned sector_count,
+ void *buffer)
+{
+ struct ata_interface *pata_if = disk_dev->platform_data;
+ struct us_blk_dev *pblk_dev = (struct us_blk_dev *)pata_if->priv;
+ struct us_data *us = pblk_dev->us;
+ ccb us_ccb;
+ ushort const sector_size = 512;
+ unsigned sectors_done;
+
+ if (sector_count == 0)
+ return 0;
+
+ /* check for unsupported block size */
+ if (pblk_dev->blksz != sector_size) {
+ US_DEBUGP("%s: unsupported block size %lu\n",
+ __func__, pblk_dev->blksz);
+ return -EINVAL;
+ }
+
+ /* check for invalid sector_start */
+ if (sector_start >= pblk_dev->blknum || sector_start > (ulong)-1) {
+ US_DEBUGP("%s: start sector %llu too large\n",
+ __func__, sector_start);
+ return -EINVAL;
+ }
+
+ us_ccb.lun = pblk_dev->lun;
+ usb_disable_asynch(1);
+
+ /* ensure unit ready */
+ US_DEBUGP("Testing for unit ready\n");
+ if (usb_stor_test_unit_ready(&us_ccb, us)) {
+ US_DEBUGP("Device NOT ready\n");
+ usb_disable_asynch(0);
+ return -EIO;
+ }
+
+ /* possibly limit the amount of I/O data */
+ if (sector_count > INT_MAX) {
+ sector_count = INT_MAX;
+ US_DEBUGP("Restricting I/O to %u blocks\n", sector_count);
+ }
+ if (sector_start + sector_count > pblk_dev->blknum) {
+ sector_count = pblk_dev->blknum - sector_start;
+ US_DEBUGP("Restricting I/O to %u blocks\n", sector_count);
+ }
+
+ /* read / write the requested data */
+ US_DEBUGP("%s %u block(s), starting from %llu\n",
+ ((io_op == io_rd) ? "Read" : "Write"),
+ sector_count, sector_start);
+ sectors_done = 0;
+ while (sector_count > 0) {
+ int result;
+ ushort n = (ushort)min(sector_count, US_MAX_IO_BLK);
+ us_ccb.pdata = buffer + sectors_done * sector_size;
+ us_ccb.datalen = n * (ulong)sector_size;
+ if (io_op == io_rd)
+ result = usb_stor_read_10(&us_ccb, us,
+ (ulong)sector_start, n);
+ else
+ result = usb_stor_write_10(&us_ccb, us,
+ (ulong)sector_start, n);
+ if (result != 0) {
+ US_DEBUGP("I/O error at sector %llu\n", sector_start);
+ break;
+ }
+ sector_start += n;
+ sector_count -= n;
+ sectors_done += n;
+ }
+
+ usb_disable_asynch(0);
+
+ US_DEBUGP("Successful I/O of %u blocks\n", sectors_done);
+
+ return (sector_count != 0) ? -EIO : 0;
+}
+
+/* Write a chunk of sectors to media */
+static int usb_stor_blk_write(struct device_d *disk_dev, uint64_t sector_start,
+ unsigned sector_count, const void *buffer)
+{
+ return usb_stor_blk_io(io_wr, disk_dev, sector_start, sector_count,
+ (void *)buffer);
+}
+
+/* Read a chunk of sectors from media */
+static int usb_stor_blk_read(struct device_d *disk_dev, uint64_t sector_start,
+ unsigned sector_count, void *buffer)
+{
+ return usb_stor_blk_io(io_rd, disk_dev, sector_start, sector_count,
+ buffer);
+}
+
+
+/***********************************************************************
+ * Block device routines
+ ***********************************************************************/
+
+static unsigned char us_io_buf[512];
+
+/* Prepare a disk device */
+static int usb_stor_init_blkdev(struct us_blk_dev *pblk_dev)
+{
+ struct us_data *us = pblk_dev->us;
+ ccb us_ccb;
+ unsigned long *pcap;
+ int result = 0;
+
+ us_ccb.pdata = us_io_buf;
+ us_ccb.lun = pblk_dev->lun;
+
+ pblk_dev->blknum = 0;
+ usb_disable_asynch(1);
+
+ /* get device info */
+ US_DEBUGP("Reading device info\n");
+ us_ccb.datalen = 36;
+ if (usb_stor_inquiry(&us_ccb, us)) {
+ US_DEBUGP("Cannot read device info\n");
+ result = -ENODEV;
+ goto Exit;
+ }
+ US_DEBUGP("Peripheral type: %x, removable: %x\n",
+ us_io_buf[0], (us_io_buf[1] >> 7));
+ US_DEBUGP("ISO ver: %x, resp format: %x\n", us_io_buf[2], us_io_buf[3]);
+ US_DEBUGP("Vendor/product/rev: %28s\n", &us_io_buf[8]);
+ // TODO: process and store device info
+
+ /* ensure unit ready */
+ US_DEBUGP("Testing for unit ready\n");
+ us_ccb.datalen = 0;
+ if (usb_stor_test_unit_ready(&us_ccb, us)) {
+ US_DEBUGP("Device NOT ready\n");
+ result = -ENODEV;
+ goto Exit;
+ }
+
+ /* read capacity */
+ US_DEBUGP("Reading capacity\n");
+ memset(us_ccb.pdata, 0, 8);
+ us_ccb.datalen = sizeof(us_io_buf);
+ if (usb_stor_read_capacity(&us_ccb, us) != 0) {
+ US_DEBUGP("Cannot read device capacity\n");
+ result = -EIO;
+ goto Exit;
+ }
+ pcap = (unsigned long *)us_ccb.pdata;
+ US_DEBUGP("Read Capacity returns: 0x%lx, 0x%lx\n", pcap[0], pcap[1]);
+ pblk_dev->blknum = be32_to_cpu(pcap[0]);
+ pblk_dev->blksz = be32_to_cpu(pcap[1]);
+ pblk_dev->blknum++;
+ US_DEBUGP("Capacity = 0x%llx, blocksz = 0x%lx\n",
+ pblk_dev->blknum, pblk_dev->blksz);
+
+Exit:
+ usb_disable_asynch(0);
+ return result;
+}
+
+/* Create and register a disk device for the specified LUN */
+static int usb_stor_add_blkdev(struct us_data *us, unsigned char lun)
+{
+ struct us_blk_dev *pblk_dev;
+ struct device_d *pdev;
+ struct ata_interface *pata_if;
+ int result;
+
+ /* allocate blk dev data */
+ pblk_dev = (struct us_blk_dev *)malloc(sizeof(struct us_blk_dev));
+ if (!pblk_dev)
+ return -ENOMEM;
+ memset(pblk_dev, 0, sizeof(struct us_blk_dev));
+
+ /* initialize blk dev data */
+ pblk_dev->us = us;
+ pblk_dev->lun = lun;
+ pata_if = &pblk_dev->ata_if;
+ pata_if->read = &usb_stor_blk_read;
+ pata_if->write = &usb_stor_blk_write;
+ pata_if->priv = pblk_dev;
+ pdev = &pblk_dev->dev;
+ strcpy(pdev->name, "disk");
+ pdev->platform_data = pata_if;
+
+ /* read some info and get the unit ready */
+ result = usb_stor_init_blkdev(pblk_dev);
+ if (result < 0)
+ goto BadDevice;
+
+ /* register disk device */
+ result = register_device(pdev);
+ if (result < 0)
+ goto BadDevice;
+ list_add_tail(&pblk_dev->list, &us_blkdev_list);
+ US_DEBUGP("USB disk device successfully added\n");
+
+ return 0;
+
+BadDevice:
+ US_DEBUGP("%s failed with %d\n", __func__, result);
+ free(pblk_dev);
+ return result;
+}
+
+/***********************************************************************
+ * USB Mass Storage device probe and initialization
+ ***********************************************************************/
+
+/* Get the transport settings */
+static void get_transport(struct us_data *us)
+{
+ switch (us->protocol) {
+ case US_PR_BULK:
+ us->transport_name = "Bulk";
+ us->transport = &usb_stor_Bulk_transport;
+ us->transport_reset = &usb_stor_Bulk_reset;
+ break;
+ }
+
+ US_DEBUGP("Transport: %s\n", us->transport_name);
+}
+
+/* Get the endpoint settings */
+static int get_pipes(struct us_data *us, struct usb_interface_descriptor *intf)
+{
+ unsigned int i;
+ struct usb_endpoint_descriptor *ep;
+ struct usb_endpoint_descriptor *ep_in = NULL;
+ struct usb_endpoint_descriptor *ep_out = NULL;
+ struct usb_endpoint_descriptor *ep_int = NULL;
+
+ /*
+ * Find the first endpoint of each type we need.
+ * We are expecting a minimum of 2 endpoints - in and out (bulk).
+ * An optional interrupt-in is OK (necessary for CBI protocol).
+ * We will ignore any others.
+ */
+ for (i = 0; i < intf->bNumEndpoints; i++) {
+ ep = &intf->ep_desc[i];
+
+ if (USB_EP_IS_XFER_BULK(ep)) {
+ if (USB_EP_IS_DIR_IN(ep)) {
+ if ( !ep_in )
+ ep_in = ep;
+ }
+ else {
+ if ( !ep_out )
+ ep_out = ep;
+ }
+ }
+ else if (USB_EP_IS_INT_IN(ep)) {
+ if (!ep_int)
+ ep_int = ep;
+ }
+ }
+ if (!ep_in || !ep_out || (us->protocol == US_PR_CBI && !ep_int)) {
+ US_DEBUGP("Endpoint sanity check failed! Rejecting dev.\n");
+ return -EIO;
+ }
+
+ /* Store the pipe values */
+ us->send_bulk_ep = USB_EP_NUM(ep_out);
+ us->recv_bulk_ep = USB_EP_NUM(ep_in);
+ if (ep_int) {
+ us->recv_intr_ep = USB_EP_NUM(ep_int);
+ us->ep_bInterval = ep_int->bInterval;
+ }
+ return 0;
+}
+
+/* Scan device's LUNs, registering a disk device for each LUN */
+static int usb_stor_scan(struct usb_device *usbdev, struct us_data *us)
+{
+ unsigned char lun;
+ int num_devs = 0;
+
+ /* obtain the max LUN */
+ us->max_lun = 0;
+ if (us->protocol == US_PR_BULK)
+ us->max_lun = usb_stor_Bulk_max_lun(us);
+
+ /* register a disk device for each active LUN */
+ for (lun=0; lun<=us->max_lun; lun++) {
+ if (usb_stor_add_blkdev(us, lun) == 0)
+ num_devs++;
+ }
+
+ US_DEBUGP("Found %d block devices on %s\n", num_devs, usbdev->dev.name);
+
+ return num_devs ? 0 : -ENODEV;
+}
+
+/* Probe routine for standard devices */
+static int usb_stor_probe(struct usb_device *usbdev,
+ const struct usb_device_id *id)
+{
+ struct us_data *us;
+ int result;
+ int ifno;
+ struct usb_interface_descriptor *intf;
+
+ US_DEBUGP("Supported USB Mass Storage device detected\n");
+
+ /* scan usbdev interfaces again to find one that we can handle */
+ for (ifno=0; ifno<usbdev->config.no_of_if; ifno++) {
+ intf = &usbdev->config.if_desc[ifno];
+
+ if (intf->bInterfaceClass == USB_CLASS_MASS_STORAGE &&
+ intf->bInterfaceSubClass == US_SC_SCSI &&
+ intf->bInterfaceProtocol == US_PR_BULK)
+ break;
+ }
+ if (ifno >= usbdev->config.no_of_if)
+ return -ENXIO;
+
+ /* select the right interface */
+ result = usb_set_interface(usbdev, intf->bInterfaceNumber, 0);
+ if (result)
+ return result;
+
+ US_DEBUGP("Selected interface %d\n", (int)intf->bInterfaceNumber);
+
+ /* allocate us_data structure */
+ us = (struct us_data *)malloc(sizeof(struct us_data));
+ if (!us)
+ return -ENOMEM;
+ memset(us, 0, sizeof(struct us_data));
+
+ /* initialize the us_data structure */
+ us->pusb_dev = usbdev;
+ us->flags = 0;
+ us->ifnum = intf->bInterfaceNumber;
+ us->subclass = intf->bInterfaceSubClass;
+ us->protocol = intf->bInterfaceProtocol;
+
+ /* get standard transport and protocol settings */
+ get_transport(us);
+
+ /* find the endpoints needed by the transport */
+ result = get_pipes(us, intf);
+ if (result)
+ goto BadDevice;
+
+ /* register a disk device for each LUN */
+ usb_stor_scan(usbdev, us);
+
+ /* associate the us_data structure with the usb_device */
+ usbdev->drv_data = us;
+
+ return 0;
+
+BadDevice:
+ US_DEBUGP("%s failed with %d\n", __func__, result);
+ free(us);
+ return result;
+}
+
+/* Handle a USB mass-storage disconnect */
+static void usb_stor_disconnect(struct usb_device *usbdev)
+{
+#if 0
+ struct us_data *us = (struct us_data *)usbdev->drv_data;
+ struct us_blk_dev *bdev, *bdev_tmp;
+
+ US_DEBUGP("Disconnecting USB Mass Storage device %s\n",
+ usbdev->dev.name);
+
+ /* release all block devices of this mass storage device */
+ list_for_each_entry_safe(bdev, bdev_tmp, &us_blkdev_list, list) {
+ if (bdev->us == us) {
+ US_DEBUGP("Releasing %s\n", bdev->dev.name);
+ list_del(&bdev->list);
+ unregister_device(&bdev->dev);
+ free(bdev);
+ }
+ }
+
+ /* release device's private data */
+ usbdev->drv_data = 0;
+ free(us);
+#else
+ dev_err(&usbdev->dev, "Disk/partition removal not yet implemented "
+ "in the ATA disk driver.");
+#endif
+}
+
+#define USUAL_DEV(use_proto, use_trans, drv_info) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, use_proto, use_trans), \
+ .driver_info = (drv_info) }
+
+/* Table with supported devices, most specific first. */
+static struct usb_device_id usb_storage_usb_ids[] = {
+ USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0), // SCSI intf, BBB proto
+ { }
+};
+
+
+/***********************************************************************
+ * USB Storage driver initialization and registration
+ ***********************************************************************/
+
+static struct usb_driver usb_storage_driver = {
+ .driver.name = "usb-storage",
+ .id_table = usb_storage_usb_ids,
+ .probe = usb_stor_probe,
+ .disconnect = usb_stor_disconnect,
+};
+
+static int __init usb_stor_init(void)
+{
+ usb_storage_driver.name = usb_storage_driver.driver.name;
+ return usb_driver_register(&usb_storage_driver);
+}
+device_initcall(usb_stor_init);
+
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
new file mode 100644
index 0000000000..17a1e1263e
--- /dev/null
+++ b/drivers/usb/storage/usb.h
@@ -0,0 +1,96 @@
+/*
+ * Most of this source has been derived from the Linux and
+ * U-Boot USB Mass Storage driver implementations.
+ *
+ * Adapted for barebox:
+ * Copyright (c) 2011, AMK Drives & Controls Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef _STORAGE_USB_H_
+#define _STORAGE_USB_H_
+
+#include <usb/usb.h>
+#include <ata.h>
+#include <scsi.h>
+#include <linux/list.h>
+
+
+#ifdef USB_STOR_DEBUG
+#define US_DEBUGP(fmt, args...) printf(fmt , ##args)
+#else
+#define US_DEBUGP(fmt, args...)
+#endif
+
+
+/* some defines, similar to ch9.h */
+#define USB_EP_NUM(epd) \
+ ((epd)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
+#define USB_EP_IS_DIR_IN(epd) \
+ (((epd)->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
+#define USB_EP_IS_XFER_BULK(epd) \
+ (((epd)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == \
+ USB_ENDPOINT_XFER_BULK)
+#define USB_EP_IS_XFER_INT(epd) \
+ (((epd)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == \
+ USB_ENDPOINT_XFER_INT)
+#define USB_EP_IS_INT_IN(epd) \
+ (USB_EP_IS_XFER_INT(epd) && USB_EP_IS_DIR_IN(epd))
+
+
+struct us_data;
+
+typedef int (*trans_cmnd)(ccb *cb, struct us_data *data);
+typedef int (*trans_reset)(struct us_data *data);
+
+/* one us_data object allocated per usb storage device */
+struct us_data {
+ struct usb_device *pusb_dev; /* this usb_device */
+ unsigned int flags; /* from filter */
+ unsigned char send_bulk_ep; /* used endpoints */
+ unsigned char recv_bulk_ep;
+ unsigned char recv_intr_ep;
+ unsigned char ifnum; /* interface number */
+
+ unsigned char subclass;
+ unsigned char protocol;
+
+ unsigned char max_lun;
+ unsigned char ep_bInterval;
+
+ char *transport_name;
+
+ trans_cmnd transport; /* transport function */
+ trans_reset transport_reset;/* transport device reset */
+
+ /* SCSI interfaces */
+ ccb *srb; /* current srb */
+};
+
+/* one us_blk_dev object allocated per LUN */
+struct us_blk_dev {
+ struct us_data *us; /* LUN's enclosing dev */
+ struct device_d dev; /* intf to generic driver */
+ struct ata_interface ata_if; /* intf to "disk" driver */
+ uint64_t blknum; /* capacity */
+ unsigned long blksz; /* block size */
+ unsigned char lun; /* the LUN of this blk dev */
+ struct list_head list; /* siblings */
+};
+
+#endif
diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
index 5ae8c4b389..dce2a9e47c 100644
--- a/drivers/video/imx-ipu-fb.c
+++ b/drivers/video/imx-ipu-fb.c
@@ -23,7 +23,7 @@
#include <common.h>
#include <init.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <fb.h>
#include <mach/imxfb.h>
diff --git a/drivers/video/imx.c b/drivers/video/imx.c
index c19e83e50f..7ffbcb550b 100644
--- a/drivers/video/imx.c
+++ b/drivers/video/imx.c
@@ -16,7 +16,7 @@
#include <common.h>
#include <fb.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imxfb.h>
#include <driver.h>
#include <malloc.h>
diff --git a/drivers/video/s3c.c b/drivers/video/s3c.c
index d079fdea59..b17aeb69ff 100644
--- a/drivers/video/s3c.c
+++ b/drivers/video/s3c.c
@@ -29,7 +29,7 @@
#include <driver.h>
#include <malloc.h>
#include <errno.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/gpio.h>
#include <mach/s3c24xx-generic.h>
#include <mach/fb.h>
diff --git a/drivers/video/stm.c b/drivers/video/stm.c
index 78acad7372..c109352565 100644
--- a/drivers/video/stm.c
+++ b/drivers/video/stm.c
@@ -23,7 +23,7 @@
#include <malloc.h>
#include <errno.h>
#include <xfuncs.h>
-#include <asm/io.h>
+#include <io.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
#include <mach/fb.h>
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
new file mode 100644
index 0000000000..3f0f5a2536
--- /dev/null
+++ b/include/asm-generic/io.h
@@ -0,0 +1,222 @@
+/* Generic I/O port emulation, based on MN10300 code
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef __ASM_GENERIC_IO_H
+#define __ASM_GENERIC_IO_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+/*****************************************************************************/
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the simple architectures, we just read/write the
+ * memory location directly.
+ */
+
+#ifndef __raw_readb
+#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
+#endif
+
+#ifndef __raw_readw
+#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
+#endif
+
+#ifndef __raw_readl
+#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
+#endif
+
+#define readb __raw_readb
+#define readw(addr) __le16_to_cpu(__raw_readw(addr))
+#define readl(addr) __le32_to_cpu(__raw_readl(addr))
+
+#ifndef __raw_writeb
+#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
+#endif
+
+#ifndef __raw_writew
+#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
+#endif
+
+#ifndef __raw_writel
+#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
+#endif
+
+#define writeb __raw_writeb
+#define writew(b,addr) __raw_writew(__cpu_to_le16(b),addr)
+#define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr)
+
+#ifdef CONFIG_64BIT
+static inline u64 __raw_readq(const volatile void __iomem *addr)
+{
+ return *(const volatile u64 __force *) addr;
+}
+#define readq(addr) __le64_to_cpu(__raw_readq(addr))
+
+static inline void __raw_writeq(u64 b, volatile void __iomem *addr)
+{
+ *(volatile u64 __force *) addr = b;
+}
+#define writeq(b,addr) __raw_writeq(__cpu_to_le64(b),addr)
+#endif
+
+#ifndef PCI_IOBASE
+#define PCI_IOBASE ((void __iomem *) 0)
+#endif
+
+/*****************************************************************************/
+/*
+ * traditional input/output functions
+ */
+
+static inline u8 inb(unsigned long addr)
+{
+ return readb(addr + PCI_IOBASE);
+}
+
+static inline u16 inw(unsigned long addr)
+{
+ return readw(addr + PCI_IOBASE);
+}
+
+static inline u32 inl(unsigned long addr)
+{
+ return readl(addr + PCI_IOBASE);
+}
+
+static inline void outb(u8 b, unsigned long addr)
+{
+ writeb(b, addr + PCI_IOBASE);
+}
+
+static inline void outw(u16 b, unsigned long addr)
+{
+ writew(b, addr + PCI_IOBASE);
+}
+
+static inline void outl(u32 b, unsigned long addr)
+{
+ writel(b, addr + PCI_IOBASE);
+}
+
+#define inb_p(addr) inb(addr)
+#define inw_p(addr) inw(addr)
+#define inl_p(addr) inl(addr)
+#define outb_p(x, addr) outb((x), (addr))
+#define outw_p(x, addr) outw((x), (addr))
+#define outl_p(x, addr) outl((x), (addr))
+
+#ifndef insb
+static inline void insb(unsigned long addr, void *buffer, int count)
+{
+ if (count) {
+ u8 *buf = buffer;
+ do {
+ u8 x = inb(addr);
+ *buf++ = x;
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef insw
+static inline void insw(unsigned long addr, void *buffer, int count)
+{
+ if (count) {
+ u16 *buf = buffer;
+ do {
+ u16 x = inw(addr);
+ *buf++ = x;
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef insl
+static inline void insl(unsigned long addr, void *buffer, int count)
+{
+ if (count) {
+ u32 *buf = buffer;
+ do {
+ u32 x = inl(addr);
+ *buf++ = x;
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef outsb
+static inline void outsb(unsigned long addr, const void *buffer, int count)
+{
+ if (count) {
+ const u8 *buf = buffer;
+ do {
+ outb(*buf++, addr);
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef outsw
+static inline void outsw(unsigned long addr, const void *buffer, int count)
+{
+ if (count) {
+ const u16 *buf = buffer;
+ do {
+ outw(*buf++, addr);
+ } while (--count);
+ }
+}
+#endif
+
+#ifndef outsl
+static inline void outsl(unsigned long addr, const void *buffer, int count)
+{
+ if (count) {
+ const u32 *buf = buffer;
+ do {
+ outl(*buf++, addr);
+ } while (--count);
+ }
+}
+#endif
+
+static inline void readsl(const void __iomem *addr, void *buf, int len)
+{
+ insl(addr - PCI_IOBASE, buf, len);
+}
+
+static inline void readsw(const void __iomem *addr, void *buf, int len)
+{
+ insw(addr - PCI_IOBASE, buf, len);
+}
+
+static inline void readsb(const void __iomem *addr, void *buf, int len)
+{
+ insb(addr - PCI_IOBASE, buf, len);
+}
+
+static inline void writesl(const void __iomem *addr, const void *buf, int len)
+{
+ outsl(addr - PCI_IOBASE, buf, len);
+}
+
+static inline void writesw(const void __iomem *addr, const void *buf, int len)
+{
+ outsw(addr - PCI_IOBASE, buf, len);
+}
+
+static inline void writesb(const void __iomem *addr, const void *buf, int len)
+{
+ outsb(addr - PCI_IOBASE, buf, len);
+}
+
+#endif /* __ASM_GENERIC_IO_H */
diff --git a/include/common.h b/include/common.h
index 0ce4a70b56..e34bbea82f 100644
--- a/include/common.h
+++ b/include/common.h
@@ -94,7 +94,7 @@ void __noreturn hang (void);
void __noreturn panic(const char *fmt, ...);
/* */
-long int initdram (int);
+void initdram (int);
char *size_human_readable(ulong size);
/* common/main.c */
diff --git a/include/driver.h b/include/driver.h
index e9ac7279f4..80de0c8377 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -205,6 +205,13 @@ struct device_d *add_generic_device(const char* devname, int id, const char *res
void *pdata);
/*
+ * register a generic device
+ * with multiple resources
+ */
+struct device_d *add_generic_device_res(const char* devname, int id,
+ struct resource *res, int nb, void *pdata);
+
+/*
* register a memory device
*/
static inline struct device_d *add_mem_device(const char *name, resource_size_t start,
diff --git a/include/i2c/i2c.h b/include/i2c/i2c.h
index 2507d68a34..ccbf518c97 100644
--- a/include/i2c/i2c.h
+++ b/include/i2c/i2c.h
@@ -30,6 +30,7 @@ struct i2c_platform_data {
#define I2C_NAME_SIZE 20
#define I2C_M_RD 0x0001 /* read data, from slave to master */
+#define I2C_M_DATA_ONLY 0x0002 /* transfer data bytes only */
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
diff --git a/include/image.h b/include/image.h
index 8932947b7e..691bf2d88b 100644
--- a/include/image.h
+++ b/include/image.h
@@ -188,9 +188,16 @@ typedef struct image_header {
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
+struct image_handle_data {
+ void *data;
+ ulong len;
+};
+
struct image_handle {
image_header_t header;
void *data;
+ struct image_handle_data *data_entries;
+ int nb_data_entries;
#define IH_MALLOC 1
int flags;
};
@@ -320,13 +327,13 @@ static inline void image_set_name(image_header_t *hdr, const char *name)
strncpy(image_get_name(hdr), name, IH_NMLEN);
}
-ulong image_multi_count(const image_header_t *hdr);
-void image_multi_getimg(const image_header_t *hdr, ulong idx,
- ulong *data, ulong *len);
+ulong image_multi_count(void *data);
+void image_multi_getimg(void *data, ulong idx,
+ ulong *img_data, ulong *len);
void image_print_size(uint32_t size);
-void image_print_contents(const void *ptr);
+void image_print_contents(const image_header_t *hdr, void *data);
/* commamds/bootm.c */
void print_image_hdr (image_header_t *hdr);
@@ -337,6 +344,7 @@ void print_image_hdr (image_header_t *hdr);
*/
struct image_handle *map_image(const char *filename, int verify);
void unmap_image(struct image_handle *handle);
+struct image_handle_data* gen_image_handle_data(void* data, ulong len);
/*
* Relocate an image to load_address by uncompressing
diff --git a/include/io.h b/include/io.h
new file mode 100644
index 0000000000..39b5e614b7
--- /dev/null
+++ b/include/io.h
@@ -0,0 +1,23 @@
+#ifndef __IO_H
+#define __IO_H
+
+#include <asm/io.h>
+
+/* cpu_read/cpu_write: cpu native io accessors */
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_readb(a) readb(a)
+#define cpu_readw(a) in_be16(a)
+#define cpu_readl(a) in_be32(a)
+#define cpu_writeb(v, a) writeb((v), (a))
+#define cpu_writew(v, a) out_be16((a), (v))
+#define cpu_writel(v, a) out_be32((a), (v))
+#else
+#define cpu_readb(a) readb(a)
+#define cpu_readw(a) readw(a)
+#define cpu_readl(a) readl(a)
+#define cpu_writeb(v, a) writeb((v), (a))
+#define cpu_writew(v, a) writew((v), (a))
+#define cpu_writel(v, a) writel((v), (a))
+#endif
+
+#endif /* __IO_H */
diff --git a/include/linux/ctype.h b/include/linux/ctype.h
index 728040efd3..74fb735778 100644
--- a/include/linux/ctype.h
+++ b/include/linux/ctype.h
@@ -2,7 +2,6 @@
#define _LINUX_CTYPE_H
#include <common.h>
-#include <reloc.h>
/*
* NOTE! This ctype does not handle EOF like the standard C
@@ -20,7 +19,7 @@
extern unsigned char _ctype[];
-#define __ismask(x) (RELOC_VAR(_ctype[(int)(unsigned char)(x)]))
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
diff --git a/include/mem_malloc.h b/include/mem_malloc.h
deleted file mode 100644
index 67b19d7ff1..0000000000
--- a/include/mem_malloc.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __MEM_MALLOC_H
-#define __MEM_MALLOC_H
-
-#include <linux/types.h>
-
-void mem_malloc_init(void *start, void *end);
-ulong mem_malloc_start(void);
-ulong mem_malloc_end(void);
-
-#endif
diff --git a/include/memory.h b/include/memory.h
new file mode 100644
index 0000000000..cb185afa65
--- /dev/null
+++ b/include/memory.h
@@ -0,0 +1,25 @@
+#ifndef __MEM_MALLOC_H
+#define __MEM_MALLOC_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+void mem_malloc_init(void *start, void *end);
+ulong mem_malloc_start(void);
+ulong mem_malloc_end(void);
+
+struct memory_bank {
+ struct list_head list;
+ struct device_d *dev;
+ unsigned long start;
+ unsigned long size;
+};
+
+extern struct list_head memory_banks;
+
+void barebox_add_memory_bank(const char *name, resource_size_t start,
+ resource_size_t size);
+
+#define for_each_memory_bank(mem) list_for_each_entry(mem, &memory_banks, list)
+
+#endif
diff --git a/include/reloc.h b/include/reloc.h
deleted file mode 100644
index cc998665b5..0000000000
--- a/include/reloc.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef __RELOC_H
-#define __RELOC_H
-
-extern unsigned long _text_base;
-
-#ifdef CONFIG_HAS_EARLY_INIT
-
-extern ulong __early_init_data_begin, __early_init_data_end;
-
-/*
- * The difference between our link address and the address we're
- * currently running at.
- */
-unsigned long reloc_offset(void);
-
-/*
- * When not running at link address, relocate a pointer by
- * taking reloc_offset() into account
- */
-#define RELOC(a) (typeof(*a) *)((unsigned long)a + reloc_offset())
-
-/*
- * dito, used for variables
- */
-#define RELOC_VAR(v) *(typeof(v)* )((unsigned long)&v + reloc_offset())
-
-void early_init(void);
-
-/*
- * put a variable into early init RAM. This section will
- * be relocated into SRAM during early init
- */
-#define __early_initdata __attribute__ ((__section__ (".early_init_data")))
-
-/* Access init data */
-#define INITDATA(var) *(typeof(var) *)((ulong)(&var) - \
- (ulong)&__early_init_data_begin + \
- (ulong)RELOC_VAR(init_data_ptr))
-
-extern void *init_data_ptr;
-
-#else
-
-static inline int reloc_offset(void)
-{
- return 0;
-}
-
-static inline void early_init(void)
-{
-}
-
-#define RELOC(a) a
-#define RELOC_VAR(v) v
-
-#define __early_initdata
-
-#define INITDATA(var) var
-
-#endif /* CONFIG_HAS_EARLY_INIT */
-
-#endif /* __RELOC_H */
diff --git a/include/scsi.h b/include/scsi.h
new file mode 100644
index 0000000000..931d03da9d
--- /dev/null
+++ b/include/scsi.h
@@ -0,0 +1,208 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+ #ifndef _SCSI_H
+ #define _SCSI_H
+
+typedef struct SCSI_cmd_block {
+ unsigned char cmd[16]; /* command */
+ unsigned char sense_buf[64]; /* for request sense */
+ unsigned char status; /* SCSI Status */
+ unsigned char target; /* Target ID */
+ unsigned char lun; /* Target LUN */
+ unsigned char cmdlen; /* command len */
+ unsigned long datalen; /* Total data length */
+ unsigned char * pdata; /* pointer to data */
+ unsigned char msgout[12]; /* Messge out buffer (NOT USED) */
+ unsigned char msgin[12]; /* Message in buffer */
+ unsigned char sensecmdlen; /* Sense command len */
+ unsigned long sensedatalen; /* Sense data len */
+ unsigned char sensecmd[6]; /* Sense command */
+ unsigned long contr_stat; /* Controller Status */
+ unsigned long trans_bytes; /* tranfered bytes */
+
+ unsigned int priv;
+} ccb;
+
+/*-----------------------------------------------------------
+**
+** SCSI constants.
+**
+**-----------------------------------------------------------
+*/
+
+/*
+** Messages
+*/
+
+#define M_COMPLETE (0x00)
+#define M_EXTENDED (0x01)
+#define M_SAVE_DP (0x02)
+#define M_RESTORE_DP (0x03)
+#define M_DISCONNECT (0x04)
+#define M_ID_ERROR (0x05)
+#define M_ABORT (0x06)
+#define M_REJECT (0x07)
+#define M_NOOP (0x08)
+#define M_PARITY (0x09)
+#define M_LCOMPLETE (0x0a)
+#define M_FCOMPLETE (0x0b)
+#define M_RESET (0x0c)
+#define M_ABORT_TAG (0x0d)
+#define M_CLEAR_QUEUE (0x0e)
+#define M_INIT_REC (0x0f)
+#define M_REL_REC (0x10)
+#define M_TERMINATE (0x11)
+#define M_SIMPLE_TAG (0x20)
+#define M_HEAD_TAG (0x21)
+#define M_ORDERED_TAG (0x22)
+#define M_IGN_RESIDUE (0x23)
+#define M_IDENTIFY (0x80)
+
+#define M_X_MODIFY_DP (0x00)
+#define M_X_SYNC_REQ (0x01)
+#define M_X_WIDE_REQ (0x03)
+#define M_X_PPR_REQ (0x04)
+
+
+/*
+** Status
+*/
+
+#define S_GOOD (0x00)
+#define S_CHECK_COND (0x02)
+#define S_COND_MET (0x04)
+#define S_BUSY (0x08)
+#define S_INT (0x10)
+#define S_INT_COND_MET (0x14)
+#define S_CONFLICT (0x18)
+#define S_TERMINATED (0x20)
+#define S_QUEUE_FULL (0x28)
+#define S_ILLEGAL (0xff)
+#define S_SENSE (0x80)
+
+/*
+ * Sense_keys
+ */
+
+#define SENSE_NO_SENSE 0x0
+#define SENSE_RECOVERED_ERROR 0x1
+#define SENSE_NOT_READY 0x2
+#define SENSE_MEDIUM_ERROR 0x3
+#define SENSE_HARDWARE_ERROR 0x4
+#define SENSE_ILLEGAL_REQUEST 0x5
+#define SENSE_UNIT_ATTENTION 0x6
+#define SENSE_DATA_PROTECT 0x7
+#define SENSE_BLANK_CHECK 0x8
+#define SENSE_VENDOR_SPECIFIC 0x9
+#define SENSE_COPY_ABORTED 0xA
+#define SENSE_ABORTED_COMMAND 0xB
+#define SENSE_VOLUME_OVERFLOW 0xD
+#define SENSE_MISCOMPARE 0xE
+
+
+#define SCSI_CHANGE_DEF 0x40 /* Change Definition (Optional) */
+#define SCSI_COMPARE 0x39 /* Compare (O) */
+#define SCSI_COPY 0x18 /* Copy (O) */
+#define SCSI_COP_VERIFY 0x3A /* Copy and Verify (O) */
+#define SCSI_INQUIRY 0x12 /* Inquiry (MANDATORY) */
+#define SCSI_LOG_SELECT 0x4C /* Log Select (O) */
+#define SCSI_LOG_SENSE 0x4D /* Log Sense (O) */
+#define SCSI_MODE_SEL6 0x15 /* Mode Select 6-byte (Device Specific) */
+#define SCSI_MODE_SEL10 0x55 /* Mode Select 10-byte (Device Specific) */
+#define SCSI_MODE_SEN6 0x1A /* Mode Sense 6-byte (Device Specific) */
+#define SCSI_MODE_SEN10 0x5A /* Mode Sense 10-byte (Device Specific) */
+#define SCSI_READ_BUFF 0x3C /* Read Buffer (O) */
+#define SCSI_REQ_SENSE 0x03 /* Request Sense (MANDATORY) */
+#define SCSI_SEND_DIAG 0x1D /* Send Diagnostic (O) */
+#define SCSI_TST_U_RDY 0x00 /* Test Unit Ready (MANDATORY) */
+#define SCSI_WRITE_BUFF 0x3B /* Write Buffer (O) */
+/***************************************************************************
+ * %%% Commands Unique to Direct Access Devices %%%
+ ***************************************************************************/
+#define SCSI_COMPARE 0x39 /* Compare (O) */
+#define SCSI_FORMAT 0x04 /* Format Unit (MANDATORY) */
+#define SCSI_LCK_UN_CAC 0x36 /* Lock Unlock Cache (O) */
+#define SCSI_PREFETCH 0x34 /* Prefetch (O) */
+#define SCSI_MED_REMOVL 0x1E /* Prevent/Allow medium Removal (O) */
+#define SCSI_READ6 0x08 /* Read 6-byte (MANDATORY) */
+#define SCSI_READ10 0x28 /* Read 10-byte (MANDATORY) */
+#define SCSI_RD_CAPAC 0x25 /* Read Capacity (MANDATORY) */
+#define SCSI_RD_DEFECT 0x37 /* Read Defect Data (O) */
+#define SCSI_READ_LONG 0x3E /* Read Long (O) */
+#define SCSI_REASS_BLK 0x07 /* Reassign Blocks (O) */
+#define SCSI_RCV_DIAG 0x1C /* Receive Diagnostic Results (O) */
+#define SCSI_RELEASE 0x17 /* Release Unit (MANDATORY) */
+#define SCSI_REZERO 0x01 /* Rezero Unit (O) */
+#define SCSI_SRCH_DAT_E 0x31 /* Search Data Equal (O) */
+#define SCSI_SRCH_DAT_H 0x30 /* Search Data High (O) */
+#define SCSI_SRCH_DAT_L 0x32 /* Search Data Low (O) */
+#define SCSI_SEEK6 0x0B /* Seek 6-Byte (O) */
+#define SCSI_SEEK10 0x2B /* Seek 10-Byte (O) */
+#define SCSI_SEND_DIAG 0x1D /* Send Diagnostics (MANDATORY) */
+#define SCSI_SET_LIMIT 0x33 /* Set Limits (O) */
+#define SCSI_START_STP 0x1B /* Start/Stop Unit (O) */
+#define SCSI_SYNC_CACHE 0x35 /* Synchronize Cache (O) */
+#define SCSI_VERIFY 0x2F /* Verify (O) */
+#define SCSI_WRITE6 0x0A /* Write 6-Byte (MANDATORY) */
+#define SCSI_WRITE10 0x2A /* Write 10-Byte (MANDATORY) */
+#define SCSI_WRT_VERIFY 0x2E /* Write and Verify (O) */
+#define SCSI_WRITE_LONG 0x3F /* Write Long (O) */
+#define SCSI_WRITE_SAME 0x41 /* Write Same (O) */
+
+
+/****************************************************************************
+ * decleration of functions which have to reside in the LowLevel Part Driver
+ */
+
+void scsi_print_error(ccb *pccb);
+int scsi_exec(ccb *pccb);
+void scsi_bus_reset(void);
+void scsi_low_level_init(int busdevfunc);
+
+
+/***************************************************************************
+ * functions residing inside cmd_scsi.c
+ */
+void scsi_init(void);
+
+
+#define SCSI_IDENTIFY 0xC0 /* not used */
+
+/* Hardware errors */
+#define SCSI_SEL_TIME_OUT 0x00000101 /* Selection time out */
+#define SCSI_HNS_TIME_OUT 0x00000102 /* Handshake */
+#define SCSI_MA_TIME_OUT 0x00000103 /* Phase error */
+#define SCSI_UNEXP_DIS 0x00000104 /* unexpected disconnect */
+
+#define SCSI_INT_STATE 0x00010000 /* unknown Interrupt number is stored in 16 LSB */
+
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#endif /* _SCSI_H */
diff --git a/include/spi/spi.h b/include/spi/spi.h
index 948e0501cd..9d01d068da 100644
--- a/include/spi/spi.h
+++ b/include/spi/spi.h
@@ -37,7 +37,8 @@ struct spi_board_info {
* powers of two bytes (e.g. 20 bit samples use 32 bits).
* This may be changed by the device's driver, or left at the
* default (0) indicating protocol words are eight bit bytes.
- * The spi_transfer.bits_per_word can override this for each transfer.
+ * The spi_transfer.bits_per_word can override this for each transfer
+ * (FIXME: not currently implemented).
* @irq: Negative, or the number passed to request_irq() to receive
* interrupts from this device.
* @controller_state: Controller's runtime state
diff --git a/include/usb/usb.h b/include/usb/usb.h
index 6ef9977497..08fd1a1185 100644
--- a/include/usb/usb.h
+++ b/include/usb/usb.h
@@ -205,9 +205,9 @@ struct usb_host {
int (*init)(struct usb_host *);
int (*exit)(struct usb_host *);
int (*submit_bulk_msg)(struct usb_device *dev, unsigned long pipe,
- void *buffer, int transfer_len);
+ void *buffer, int transfer_len, int timeout);
int (*submit_control_msg)(struct usb_device *dev, unsigned long pipe, void *buffer,
- int transfer_len, struct devrequest *setup);
+ int transfer_len, struct devrequest *setup, int timeout);
int (*submit_int_msg)(struct usb_device *dev, unsigned long pipe, void *buffer,
int transfer_len, int interval);
void (*usb_event_poll)(void);
@@ -480,6 +480,13 @@ struct usb_device_id {
#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
#define USB_DEVICE_ID_MATCH_DEVICE \
(USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
+#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
+#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
+#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
+#define USB_DEVICE_ID_MATCH_INT_INFO \
+ (USB_DEVICE_ID_MATCH_INT_CLASS | \
+ USB_DEVICE_ID_MATCH_INT_SUBCLASS | \
+ USB_DEVICE_ID_MATCH_INT_PROTOCOL)
/**
* USB_DEVICE - macro used to describe a specific usb device
@@ -494,6 +501,21 @@ struct usb_device_id {
.idVendor = (vend), \
.idProduct = (prod)
+/**
+ * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces
+ * @cl: bInterfaceClass value
+ * @sc: bInterfaceSubClass value
+ * @pr: bInterfaceProtocol value
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific class of interfaces.
+ */
+#define USB_INTERFACE_INFO(cl, sc, pr) \
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \
+ .bInterfaceClass = (cl), \
+ .bInterfaceSubClass = (sc), \
+ .bInterfaceProtocol = (pr)
+
#define USB_CTRL_SET_TIMEOUT 5000
#define USB_CTRL_GET_TIMEOUT 5000
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index ccccc5df0d..54e162f063 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -19,7 +19,6 @@
#include <common.h>
#include <led.h>
-#include <reloc.h>
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
{
diff --git a/net/net.c b/net/net.c
index f1ab667b35..84168613f2 100644
--- a/net/net.c
+++ b/net/net.c
@@ -113,8 +113,10 @@ int string_to_ip(const char *s, IPaddr_t *ip)
return -EINVAL;
val = simple_strtoul(s, &e, 10);
- addr <<= 8;
- addr |= (val & 0xFF);
+ if (val > 255)
+ return -EINVAL;
+
+ addr = (addr << 8) | val;
if (*e != '.' && i != 3)
return -EINVAL;
@@ -134,7 +136,8 @@ IPaddr_t getenv_ip(const char *name)
if (!var)
return 0;
- string_to_ip(var, &ip);
+ if (string_to_ip(var, &ip))
+ return 0;
return ip;
}
diff --git a/scripts/mkimage.c b/scripts/mkimage.c
index 40a3483138..d3a8bfb887 100644
--- a/scripts/mkimage.c
+++ b/scripts/mkimage.c
@@ -255,7 +255,8 @@ NXTARG: ;
}
/* for multi-file images we need the data part, too */
- image_print_contents((image_header_t *)ptr);
+ image_print_contents((image_header_t *)ptr,
+ (void*)image_get_data((image_header_t *)ptr));
(void) munmap((void *)ptr, sbuf.st_size);
(void) close (ifd);
@@ -381,7 +382,7 @@ NXTARG: ;
image_set_hcrc(hdr, checksum);
- image_print_contents(hdr);
+ image_print_contents(hdr, (void*)image_get_data(hdr));
(void) munmap((void *)ptr, sbuf.st_size);