summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rwxr-xr-xMAKEALL6
-rw-r--r--Makefile38
-rw-r--r--arch/arm/Makefile23
-rw-r--r--arch/arm/boards/at91rm9200ek/env/config2
-rw-r--r--arch/arm/boards/at91sam9260ek/env/config4
-rw-r--r--arch/arm/boards/at91sam9261ek/env/config4
-rw-r--r--arch/arm/boards/at91sam9263ek/env/config2
-rw-r--r--arch/arm/boards/at91sam9m10g45ek/env/config2
-rw-r--r--arch/arm/boards/at91sam9x5ek/env/config2
-rw-r--r--arch/arm/boards/chumby_falconwing/env/config2
-rw-r--r--arch/arm/boards/crystalfontz-cfa10036/cfa10036.c9
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/env/config14
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/env/config14
-rw-r--r--arch/arm/boards/eukrea_cpuimx51/env/config14
-rw-r--r--arch/arm/boards/freescale-mx28-evk/env/config12
-rw-r--r--arch/arm/boards/freescale-mx28-evk/mx28-evk.c10
-rw-r--r--arch/arm/boards/freescale-mx35-3-stack/env/config14
-rw-r--r--arch/arm/boards/freescale-mx53-loco/env/config16
-rw-r--r--arch/arm/boards/freescale-mx53-smd/env/config14
-rw-r--r--arch/arm/boards/freescale-mx6-arm2/board.c43
-rw-r--r--arch/arm/boards/freescale-mx6-sabrelite/board.c41
-rw-r--r--arch/arm/boards/friendlyarm-mini2440/env/config14
-rw-r--r--arch/arm/boards/guf-cupid/env/config14
-rw-r--r--arch/arm/boards/guf-neso/env/config14
-rw-r--r--arch/arm/boards/imx233-olinuxino/Makefile1
-rw-r--r--arch/arm/boards/imx233-olinuxino/config.h21
-rw-r--r--arch/arm/boards/imx233-olinuxino/env/bin/boot32
-rw-r--r--arch/arm/boards/imx233-olinuxino/env/bin/init15
-rw-r--r--arch/arm/boards/imx233-olinuxino/env/config42
-rw-r--r--arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c254
-rw-r--r--arch/arm/boards/karo-tx25/env/config14
-rw-r--r--arch/arm/boards/karo-tx28/env/config14
-rw-r--r--arch/arm/boards/karo-tx28/tx28-stk5.c12
-rw-r--r--arch/arm/boards/karo-tx53/Makefile2
-rw-r--r--arch/arm/boards/karo-tx53/board.c240
-rw-r--r--arch/arm/boards/karo-tx53/config.h24
-rw-r--r--arch/arm/boards/karo-tx53/env/init/bootargs-base8
-rw-r--r--arch/arm/boards/karo-tx53/env/init/hostname8
-rw-r--r--arch/arm/boards/karo-tx53/flash_header.c147
-rw-r--r--arch/arm/boards/panda/env/config12
-rw-r--r--arch/arm/boards/pcm027/env/config14
-rw-r--r--arch/arm/boards/pcm037/env/config14
-rw-r--r--arch/arm/boards/pcm043/env/config14
-rw-r--r--arch/arm/boards/pcm049/env/bin/nand_bootstrap2
-rw-r--r--arch/arm/boards/pcm049/env/config14
-rw-r--r--arch/arm/boards/phycard-a-l1/env/config18
-rw-r--r--arch/arm/boards/phycard-a-xl2/env/config14
-rw-r--r--arch/arm/boards/phycard-i.MX27/env/config14
-rw-r--r--arch/arm/boards/phycard-i.MX27/lowlevel_init.S5
-rw-r--r--arch/arm/boards/phycard-i.MX27/pca100.c8
-rw-r--r--arch/arm/boards/qil-a9260/env/config2
-rw-r--r--arch/arm/boards/scb9328/env/config14
-rw-r--r--arch/arm/boards/tny-a926x/env/config6
-rw-r--r--arch/arm/boards/usb-a926x/env/config6
-rw-r--r--arch/arm/configs/freescale_mx51_babbage_defconfig2
-rw-r--r--arch/arm/configs/imx233-olinuxino_defconfig63
-rw-r--r--arch/arm/configs/phycard_a_l1_defconfig2
-rw-r--r--arch/arm/configs/tx51stk5_defconfig2
-rw-r--r--arch/arm/configs/tx53stk5_defconfig76
-rw-r--r--arch/arm/cpu/mmu.c2
-rw-r--r--arch/arm/cpu/start-pbl.c21
-rw-r--r--arch/arm/cpu/start-reset.c3
-rw-r--r--arch/arm/cpu/start.c17
-rw-r--r--arch/arm/include/asm/barebox-arm.h2
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/lib/armlinux.c5
-rw-r--r--arch/arm/lib/barebox.lds.S2
-rw-r--r--arch/arm/lib/runtime-offset.S17
-rw-r--r--arch/arm/mach-imx/Kconfig8
-rw-r--r--arch/arm/mach-imx/clocksource.c89
-rw-r--r--arch/arm/mach-imx/gpio.c113
-rw-r--r--arch/arm/mach-imx/imx1.c9
-rw-r--r--arch/arm/mach-imx/imx21.c14
-rw-r--r--arch/arm/mach-imx/imx25.c10
-rw-r--r--arch/arm/mach-imx/imx27.c15
-rw-r--r--arch/arm/mach-imx/imx31.c7
-rw-r--r--arch/arm/mach-imx/imx35.c7
-rw-r--r--arch/arm/mach-imx/imx51.c9
-rw-r--r--arch/arm/mach-imx/imx53.c16
-rw-r--r--arch/arm/mach-imx/imx6.c15
-rw-r--r--arch/arm/mach-imx/include/mach/imx1-regs.h23
-rw-r--r--arch/arm/mach-imx/include/mach/imx21-regs.h24
-rw-r--r--arch/arm/mach-imx/include/mach/imx25-regs.h27
-rw-r--r--arch/arm/mach-imx/include/mach/imx27-regs.h23
-rw-r--r--arch/arm/mach-imx/include/mach/imx31-regs.h27
-rw-r--r--arch/arm/mach-imx/include/mach/imx35-regs.h28
-rw-r--r--arch/arm/mach-imx/include/mach/imx51-regs.h19
-rw-r--r--arch/arm/mach-imx/include/mach/imx53-regs.h19
-rw-r--r--arch/arm/mach-imx/include/mach/imx6-regs.h19
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-mx51.h14
-rw-r--r--arch/arm/mach-imx/include/mach/usb.h3
-rw-r--r--arch/arm/mach-imx/iomux-v3.c4
-rw-r--r--arch/arm/mach-mxs/Kconfig7
-rw-r--r--arch/arm/mach-mxs/imx.c24
-rw-r--r--arch/arm/mach-nomadik/8815.c9
-rw-r--r--arch/arm/mach-omap/include/mach/emac_defs.h48
-rw-r--r--arch/arm/mach-versatile/core.c7
-rw-r--r--arch/arm/pbl/zbarebox.lds.S2
-rw-r--r--arch/mips/include/asm/mipsregs.h4
-rw-r--r--arch/nios2/include/asm/dma-mapping.h14
-rw-r--r--arch/ppc/boards/pcm030/pcm030.c5
-rw-r--r--arch/ppc/mach-mpc5xxx/include/mach/fec.h14
-rw-r--r--arch/ppc/mach-mpc85xx/eth-devices.c6
-rw-r--r--arch/sandbox/board/Makefile1
-rw-r--r--arch/sandbox/board/console.c2
-rw-r--r--arch/sandbox/board/devices.c33
-rw-r--r--arch/sandbox/board/hostfile.c19
-rw-r--r--arch/sandbox/mach-sandbox/include/mach/linux.h3
-rw-r--r--arch/sandbox/os/common.c12
-rw-r--r--commands/Kconfig12
-rw-r--r--commands/echo.c12
-rw-r--r--commands/global.c51
-rw-r--r--commands/oftree.c28
-rw-r--r--common/Kconfig5
-rw-r--r--common/Makefile1
-rw-r--r--common/filetype.c68
-rw-r--r--common/globalvar.c10
-rw-r--r--common/meminfo.c23
-rw-r--r--common/oftree.c4
-rw-r--r--common/startup.c21
-rw-r--r--defaultenv-2/base/bin/boot4
-rw-r--r--defaultenv-2/base/bin/bootargs-ip4
-rw-r--r--defaultenv-2/base/bin/bootargs-ip-barebox2
-rw-r--r--defaultenv-2/base/bin/bootargs-ip-dhcp2
-rw-r--r--defaultenv-2/base/bin/bootargs-ip-none2
-rw-r--r--defaultenv-2/base/bin/bootargs-root-disk2
-rw-r--r--defaultenv-2/base/bin/bootargs-root-ext2
-rw-r--r--defaultenv-2/base/bin/bootargs-root-initrd2
-rw-r--r--defaultenv-2/base/bin/bootargs-root-jffs22
-rw-r--r--defaultenv-2/base/bin/bootargs-root-nfs2
-rw-r--r--defaultenv-2/base/bin/bootargs-root-ubi2
-rw-r--r--defaultenv-2/base/bin/init5
-rw-r--r--defaultenv-2/base/boot/initrd2
-rw-r--r--defaultenv-2/base/data/ansi-colors4
-rw-r--r--defaultenv-2/base/network/eth01
-rw-r--r--defaultenv-2/menu/menu/mainmenu4
-rw-r--r--defaultenv/bin/boot12
-rw-r--r--defaultenv/bin/init2
-rw-r--r--defaultenv/config18
-rw-r--r--drivers/Kconfig1
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/amba/Makefile2
-rw-r--r--drivers/amba/bus.c210
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/bus.c37
-rw-r--r--drivers/base/driver.c63
-rw-r--r--drivers/base/platform.c36
-rw-r--r--drivers/eeprom/at25.c2
-rw-r--r--drivers/gpio/gpio-stmpe.c2
-rw-r--r--drivers/i2c/i2c.c30
-rw-r--r--drivers/mci/imx-esdhc.c24
-rw-r--r--drivers/mci/mci_spi.c10
-rw-r--r--drivers/mci/omap_hsmmc.c2
-rw-r--r--drivers/mfd/lp3972.c2
-rw-r--r--drivers/mfd/mc13xxx.c40
-rw-r--r--drivers/mfd/mc34704.c4
-rw-r--r--drivers/mfd/mc34708.c29
-rw-r--r--drivers/mfd/mc9sdz60.c2
-rw-r--r--drivers/mfd/stmpe-i2c.c2
-rw-r--r--drivers/mfd/twl4030.c2
-rw-r--r--drivers/mfd/twl6030.c2
-rw-r--r--drivers/mtd/core.c4
-rw-r--r--drivers/mtd/mtdraw.c5
-rw-r--r--drivers/mtd/nand/nand_base.c97
-rw-r--r--drivers/mtd/nand/nand_ids.c30
-rw-r--r--drivers/net/Kconfig42
-rw-r--r--drivers/net/Makefile4
-rw-r--r--drivers/net/altera_tse.c48
-rw-r--r--drivers/net/altera_tse.h3
-rw-r--r--drivers/net/at91_ether.c49
-rw-r--r--drivers/net/davinci_emac.c618
-rw-r--r--drivers/net/davinci_emac.h289
-rw-r--r--drivers/net/designware.c62
-rw-r--r--drivers/net/dm9k.c50
-rw-r--r--drivers/net/ep93xx.c35
-rw-r--r--drivers/net/ep93xx.h2
-rw-r--r--drivers/net/fec_imx.c89
-rw-r--r--drivers/net/fec_imx.h6
-rw-r--r--drivers/net/fec_mpc5200.c58
-rw-r--r--drivers/net/fec_mpc5200.h4
-rw-r--r--drivers/net/gianfar.c61
-rw-r--r--drivers/net/gianfar.h2
-rw-r--r--drivers/net/ks8851_mll.c36
-rw-r--r--drivers/net/ksz8864rmn.c191
-rw-r--r--drivers/net/macb.c79
-rw-r--r--drivers/net/miidev.c331
-rw-r--r--drivers/net/netx_eth.c26
-rw-r--r--drivers/net/phy/Kconfig17
-rw-r--r--drivers/net/phy/Makefile2
-rw-r--r--drivers/net/phy/generic.c36
-rw-r--r--drivers/net/phy/mdio_bus.c250
-rw-r--r--drivers/net/phy/phy.c583
-rw-r--r--drivers/net/smc91111.c47
-rw-r--r--drivers/net/smc911x.c43
-rw-r--r--drivers/net/tap.c5
-rw-r--r--drivers/net/usb/Kconfig4
-rw-r--r--drivers/net/usb/asix.c29
-rw-r--r--drivers/net/usb/smsc95xx.c41
-rw-r--r--drivers/net/usb/usbnet.c11
-rw-r--r--drivers/nor/cfi_flash.c37
-rw-r--r--drivers/nor/cfi_flash.h2
-rw-r--r--drivers/nor/m25p80.c76
-rw-r--r--drivers/nor/m25p80.h2
-rw-r--r--drivers/of/Kconfig2
-rw-r--r--drivers/of/Makefile3
-rw-r--r--drivers/of/base.c802
-rw-r--r--drivers/of/gpio.c28
-rw-r--r--drivers/of/partition.c64
-rw-r--r--drivers/serial/amba-pl011.c74
-rw-r--r--drivers/serial/serial_imx.c17
-rw-r--r--drivers/spi/imx_spi.c49
-rw-r--r--drivers/spi/spi.c61
-rw-r--r--drivers/usb/core/usb.c5
-rw-r--r--drivers/video/fb.c31
-rw-r--r--fs/fat/ff.c37
-rw-r--r--fs/fs.c14
-rw-r--r--fs/nfs.c6
-rw-r--r--include/common.h4
-rw-r--r--include/driver.h45
-rw-r--r--include/fb.h2
-rw-r--r--include/fec.h3
-rw-r--r--include/filetype.h2
-rw-r--r--include/globalvar.h23
-rw-r--r--include/i2c/i2c.h8
-rw-r--r--include/linux/amba/bus.h153
-rw-r--r--include/linux/amba/serial.h29
-rw-r--r--include/linux/ethtool.h114
-rw-r--r--include/linux/mii.h421
-rw-r--r--include/linux/phy.h269
-rw-r--r--include/miidev.h77
-rw-r--r--include/net.h6
-rw-r--r--include/net/davinci_emac.h10
-rw-r--r--include/of.h113
-rw-r--r--include/spi/spi.h13
-rw-r--r--include/usb/usbnet.h5
-rw-r--r--lib/libbb.c1
-rw-r--r--lib/uncompress.c2
-rw-r--r--logo/LICENCE22
-rw-r--r--logo/png24/100x100/color/barebox.pngbin0 -> 22724 bytes
-rw-r--r--logo/png24/100x100/white/barebox.pngbin0 -> 12053 bytes
-rw-r--r--logo/png24/200x200/color/barebox.pngbin0 -> 71557 bytes
-rw-r--r--logo/png24/200x200/white/barebox.pngbin0 -> 31132 bytes
-rw-r--r--logo/png24/400x400/color/barebox.pngbin0 -> 217170 bytes
-rw-r--r--logo/png24/400x400/white/barebox.pngbin0 -> 78591 bytes
-rw-r--r--logo/png24/600x600/color/barebox.pngbin0 -> 406788 bytes
-rw-r--r--logo/png24/600x600/while/barebox.pngbin0 -> 137235 bytes
-rw-r--r--logo/png24/800x800/color/barebox.pngbin0 -> 627433 bytes
-rw-r--r--logo/png24/800x800/white/barebox.pngbin0 -> 210397 bytes
-rw-r--r--logo/png8/100x100/color/blackbg/barebox.pngbin0 -> 8279 bytes
-rw-r--r--logo/png8/100x100/white/blackbg/barebox.pngbin0 -> 6089 bytes
-rw-r--r--logo/png8/200x200/color/blackbg/barebox.pngbin0 -> 23616 bytes
-rw-r--r--logo/png8/200x200/white/blackbg/barebox.pngbin0 -> 14838 bytes
-rw-r--r--logo/png8/400x400/color/blackbg/barebox.pngbin0 -> 71295 bytes
-rw-r--r--logo/png8/400x400/white/blackbg/barebox.pngbin0 -> 38480 bytes
-rw-r--r--logo/png8/600x600/color/blackbg/barebox.pngbin0 -> 130709 bytes
-rw-r--r--logo/png8/600x600/while/blackbg/barebox.pngbin0 -> 68648 bytes
-rw-r--r--logo/png8/800x800/color/blackbg/barebox.pngbin0 -> 205281 bytes
-rw-r--r--logo/png8/800x800/white/blackbg/barebox.pngbin0 -> 104173 bytes
-rw-r--r--net/dhcp.c167
-rw-r--r--net/eth.c73
-rw-r--r--net/net.c18
-rw-r--r--net/tftp.c3
-rw-r--r--scripts/Kbuild.include2
-rwxr-xr-xscripts/genenv6
-rw-r--r--scripts/kconfig/.gitignore1
-rw-r--r--scripts/kconfig/zconf.lex.c2420
267 files changed, 7441 insertions, 4272 deletions
diff --git a/.gitignore b/.gitignore
index 85d3f03895..9af6710290 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,6 +36,7 @@ barebox.netx
barebox.s5p
barebox.spi
barebox.ubl
+barebox.uimage
barebox.map
System.map
Module.symvers
diff --git a/MAKEALL b/MAKEALL
index 056a4d0547..c08e484cda 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -96,8 +96,10 @@ do_build_target() {
mkdir -p "${LOGDIR}/${target}"
printf "Building ${arch} ${target} \n" >&2 | tee -a "${log_report}"
- cross_compile=`eval echo '$CROSS_COMPILE_'${target}`
- cross_compile_set=`eval echo '${CROSS_COMPILE_'${target}'+set}'`
+ tmp=`echo "${target}" | tr - _`
+
+ cross_compile=`eval echo '$CROSS_COMPILE_'${tmp}`
+ cross_compile_set=`eval echo '${CROSS_COMPILE_'${tmp}'+set}'`
if [ "${cross_compile_set}" = "" ]
then
cross_compile=`eval echo '$CROSS_COMPILE_'${arch}`
diff --git a/Makefile b/Makefile
index ebad5042c9..3d60927dae 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
VERSION = 2012
-PATCHLEVEL = 09
+PATCHLEVEL = 10
SUBLEVEL = 0
EXTRAVERSION =
NAME = Amissive Actinocutious Kiwi
@@ -462,12 +462,18 @@ CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signed / unsigned warnings in gcc 4.0
CFLAGS += $(call cc-option,-Wno-pointer-sign,)
-# Default kernel image to build when no specific target is given.
-# KBUILD_IMAGE may be overruled on the command line or
-# set in the environment
-# Also any assignments in arch/$(ARCH)/Makefile take precedence over
-# this default value
+# KBUILD_IMAGE: Default barebox image to build
+# Depending on the architecture, this can be either compressed or not.
+# It will also include any necessary headers to be bootable.
export KBUILD_IMAGE ?= barebox.bin
+# KBUILD_BINARY: Raw barebox binary
+# This variable is set in case the architecture prepends a header and
+# points to a binary that can be loaded directly into RAM and executed.
+export KBUILD_BINARY ?= barebox.bin
+# KBUILD_IMAGE and _BINARY may be overruled on the command line or
+# set in the environment.
+# Also any assignments in arch/$(ARCH)/Makefile take precedence over
+# the default value.
barebox-flash-image: $(KBUILD_IMAGE)
$(call if_changed,ln)
@@ -680,6 +686,22 @@ ifndef CONFIG_PBL_IMAGE
$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
endif
+# By default the uImage load address is 2MB below CONFIG_TEXT_BASE,
+# leaving space for the compressed PBL image at 1MB below CONFIG_TEXT_BASE.
+UIMAGE_BASE ?= $(shell printf "0x%08x" $$(($(CONFIG_TEXT_BASE) - 0x200000)))
+
+# For development provide a target which makes barebox loadable by an
+# unmodified u-boot
+quiet_cmd_barebox_mkimage = MKIMAGE $@
+ cmd_barebox_mkimage = $(srctree)/scripts/mkimage -A $(ARCH) -T firmware -C none \
+ -O barebox -a $(UIMAGE_BASE) -e $(UIMAGE_BASE) \
+ -n "barebox $(KERNELRELEASE)" -d $< $@
+
+# barebox.uimage is build from the raw barebox binary, without any other
+# headers.
+barebox.uimage: $(KBUILD_BINARY) FORCE
+ $(call if_changed,barebox_mkimage)
+
ifdef CONFIG_X86
barebox.S: barebox
ifdef CONFIG_X86_HDBOOT
@@ -1009,8 +1031,8 @@ CLEAN_FILES += barebox System.map include/generated/barebox_default_env.h \
.tmp_version .tmp_barebox* barebox.bin barebox.map barebox.S \
.tmp_kallsyms* barebox_default_env* barebox.ldr \
scripts/bareboxenv-target barebox-flash-image \
- Doxyfile.version barebox.srec barebox.s5p \
- barebox.spi
+ Doxyfile.version barebox.srec barebox.s5p barebox.ubl \
+ barebox.uimage barebox.spi
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include2 usr/include
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index f02b1602d8..855043aedf 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -92,6 +92,7 @@ board-$(CONFIG_MACH_FREESCALE_MX25_3STACK) := freescale-mx25-3-stack
board-$(CONFIG_MACH_FREESCALE_MX35_3STACK) := freescale-mx35-3-stack
board-$(CONFIG_MACH_IMX21ADS) := imx21ads
board-$(CONFIG_MACH_IMX27ADS) := imx27ads
+board-$(CONFIG_MACH_IMX233_OLINUXINO) := imx233-olinuxino
board-$(CONFIG_MACH_MIOA701) := mioa701
board-$(CONFIG_MACH_MMCCPU) := mmccpu
board-$(CONFIG_MACH_NOMADIK_8815NHK) := nhk8815
@@ -141,6 +142,7 @@ board-$(CONFIG_MACH_TOSHIBA_AC100) := toshiba-ac100
board-$(CONFIG_MACH_CCMX51) := ccxmx51
board-$(CONFIG_MACH_TINY210) := friendlyarm-tiny210
board-$(CONFIG_MACH_SABRELITE) := freescale-mx6-sabrelite
+board-$(CONFIG_MACH_TX53) := karo-tx53
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
@@ -179,7 +181,7 @@ barebox.netx: $(KBUILD_BINARY)
ifeq ($(machine-y),netx)
KBUILD_TARGET := barebox.netx
-KBUILD_BINARY := $(KBUILD_TARGET)
+KBUILD_IMAGE := barebox.netx
endif
barebox.s5p: $(KBUILD_BINARY)
@@ -187,7 +189,7 @@ barebox.s5p: $(KBUILD_BINARY)
ifeq ($(CONFIG_ARCH_S5PCxx),y)
KBUILD_TARGET := barebox.s5p
-KBUILD_BINARY := $(KBUILD_TARGET)
+KBUILD_IMAGE := barebox.s5p
endif
quiet_cmd_mlo ?= IFT $@
@@ -199,17 +201,20 @@ MLO: $(KBUILD_BINARY)
ifeq ($(CONFIG_OMAP_BUILD_IFT),y)
KBUILD_TARGET := MLO
-KBUILD_BINARY := $(KBUILD_TARGET)
+KBUILD_IMAGE := MLO
endif
-barebox.ubl: $(KBUILD_BINARY)
- @echo " UBL " $@
- $(Q)scripts/mkublheader $< > barebox.ubl
- $(Q)cat $< >> barebox.ubl
+quiet_cmd_davinci_ubl_image = UBL-IMG $@
+ cmd_davinci_ubl_image = set -e; \
+ scripts/mkublheader $< > $@; \
+ cat $< >> $@
+
+barebox.ubl: $(KBUILD_BINARY) FORCE
+ $(call if_changed,davinci_ubl_image)
ifeq ($(CONFIG_ARCH_DAVINCI),y)
KBUILD_TARGET := barebox.ubl
-KBUILD_BINARY := $(KBUILD_TARGET)
+KBUILD_IMAGE := barebox.ubl
endif
quiet_cmd_am35xx_spi_image = SPI-IMG $@
@@ -230,7 +235,7 @@ zbarebox.S zbarebox.bin zbarebox: barebox.bin
archclean:
$(MAKE) $(clean)=$(pbl)
-KBUILD_IMAGE := $(KBUILD_BINARY)
+KBUILD_IMAGE ?= $(KBUILD_BINARY)
archprepare: maketools
maketools:
diff --git a/arch/arm/boards/at91rm9200ek/env/config b/arch/arm/boards/at91rm9200ek/env/config
index 735bb107aa..a3830cb31a 100644
--- a/arch/arm/boards/at91rm9200ek/env/config
+++ b/arch/arm/boards/at91rm9200ek/env/config
@@ -3,7 +3,7 @@
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp-barebox
-dhcp_vendor_id=barebox-at91rm9200ek
+global.dhcp.vendor_id=barebox-at91rm9200ek
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
diff --git a/arch/arm/boards/at91sam9260ek/env/config b/arch/arm/boards/at91sam9260ek/env/config
index 06b9fafb81..8e88186217 100644
--- a/arch/arm/boards/at91sam9260ek/env/config
+++ b/arch/arm/boards/at91sam9260ek/env/config
@@ -6,9 +6,9 @@ ip=dhcp-barebox
if [ x$armlinux_architecture = x1099 ]
then
- dhcp_vendor_id=barebox-at91sam9260ek
+ global.dhcp.vendor_id=barebox-at91sam9260ek
else
- dhcp_vendor_id=barebox-at91sam9g20ek
+ global.dhcp.vendor_id=barebox-at91sam9g20ek
fi
# or set your networking parameters here
diff --git a/arch/arm/boards/at91sam9261ek/env/config b/arch/arm/boards/at91sam9261ek/env/config
index 820485dea8..7d855779ca 100644
--- a/arch/arm/boards/at91sam9261ek/env/config
+++ b/arch/arm/boards/at91sam9261ek/env/config
@@ -6,9 +6,9 @@ ip=dhcp-barebox
if [ x$armlinux_architecture = x848 ]
then
- dhcp_vendor_id=barebox-at91sam9261ek
+ global.dhcp.vendor_id=barebox-at91sam9261ek
else
- dhcp_vendor_id=barebox-at91sam9g10ek
+ global.dhcp.vendor_id=barebox-at91sam9g10ek
fi
# or set your networking parameters here
diff --git a/arch/arm/boards/at91sam9263ek/env/config b/arch/arm/boards/at91sam9263ek/env/config
index a09bc26080..5125020a73 100644
--- a/arch/arm/boards/at91sam9263ek/env/config
+++ b/arch/arm/boards/at91sam9263ek/env/config
@@ -3,7 +3,7 @@
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp-barebox
-dhcp_vendor_id=barebox-at91sam9263ek
+global.dhcp.vendor_id=barebox-at91sam9263ek
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
diff --git a/arch/arm/boards/at91sam9m10g45ek/env/config b/arch/arm/boards/at91sam9m10g45ek/env/config
index 37a20e93f2..54ed2cb9df 100644
--- a/arch/arm/boards/at91sam9m10g45ek/env/config
+++ b/arch/arm/boards/at91sam9m10g45ek/env/config
@@ -3,7 +3,7 @@
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp-barebox
-dhcp_vendor_id=barebox-at91sam9m10g45ek
+global.dhcp.vendor_id=barebox-at91sam9m10g45ek
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
diff --git a/arch/arm/boards/at91sam9x5ek/env/config b/arch/arm/boards/at91sam9x5ek/env/config
index dafe875664..6a985cedc5 100644
--- a/arch/arm/boards/at91sam9x5ek/env/config
+++ b/arch/arm/boards/at91sam9x5ek/env/config
@@ -3,7 +3,7 @@
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp-barebox
-dhcp_vendor_id=barebox-at91sam9x5ek
+global.dhcp.vendor_id=barebox-at91sam9x5ek
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
diff --git a/arch/arm/boards/chumby_falconwing/env/config b/arch/arm/boards/chumby_falconwing/env/config
index bf48da614d..3839b40584 100644
--- a/arch/arm/boards/chumby_falconwing/env/config
+++ b/arch/arm/boards/chumby_falconwing/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=falconwing
+global.hostname=falconwing
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
diff --git a/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c b/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
index e454afd36c..522d2d783d 100644
--- a/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
+++ b/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c
@@ -23,6 +23,8 @@
#include <init.h>
#include <mci.h>
#include <io.h>
+#include <net.h>
+#include <sizes.h>
#include <mach/clock.h>
#include <mach/imx-regs.h>
@@ -89,16 +91,19 @@ static int cfa10036_devices_init(void)
armlinux_set_bootparams((void *)IMX_MEMORY_BASE + 0x100);
armlinux_set_architecture(MACH_TYPE_CFA10036);
- add_generic_device("mxs_mci", 0, NULL, IMX_SSP0_BASE, 0,
+ add_generic_device("mxs_mci", 0, NULL, IMX_SSP0_BASE, SZ_8K,
IORESOURCE_MEM, &mci_pdata);
+ add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, SZ_8K,
+ IORESOURCE_MEM, NULL);
+
return 0;
}
device_initcall(cfa10036_devices_init);
static int cfa10036_console_init(void)
{
- add_generic_device("stm_serial", 0, NULL, IMX_DBGUART_BASE, 8192,
+ add_generic_device("stm_serial", 0, NULL, IMX_DBGUART_BASE, SZ_8K,
IORESOURCE_MEM, NULL);
return 0;
diff --git a/arch/arm/boards/eukrea_cpuimx25/env/config b/arch/arm/boards/eukrea_cpuimx25/env/config
index b6bf93f58f..63a85b27eb 100644
--- a/arch/arm/boards/eukrea_cpuimx25/env/config
+++ b/arch/arm/boards/eukrea_cpuimx25/env/config
@@ -5,7 +5,7 @@ otg_mode="device"
# video : can be CMO-QVGA, URT-WVGA, DVI-VGA or DVI-SVGA
video="CMO-QVGA"
-hostname=eukrea-cpuimx25
+global.hostname=eukrea-cpuimx25
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
@@ -24,16 +24,16 @@ rootfs_loc=nand
# rootfs
rootfs_type=ubifs
-rootfsimage=$hostname/rootfs.$rootfs_type
+rootfsimage=${global.hostname}/rootfs.$rootfs_type
# kernel
-kernelimage=$hostname/uImage-${hostname}.bin
+kernelimage=${global.hostname}/uImage-${global.hostname}.bin
# barebox and it's env
-bareboximage=$hostname/barebox-${hostname}.bin
-bareboxenvimage=$hostname/bareboxenv-${hostname}.bin
+bareboximage=${global.hostname}/barebox-${global.hostname}.bin
+bareboxenvimage=${global.hostname}/bareboxenv-${global.hostname}.bin
-nfsroot="$eth0.serverip:/srv/nfs/$hostname"
+nfsroot="$eth0.serverip:/srv/nfs/${global.hostname}"
autoboot_timeout=1
@@ -42,7 +42,7 @@ bootargs="console=ttymxc0,115200 otg_mode=$otg_mode video=imxfb:$video"
nand_parts="256k(barebox)ro,128k(bareboxenv),3M(kernel),-(root)"
rootfs_mtdblock_nand=3
nand_device="mxc_nand"
-ubiroot="$hostname-rootfs"
+ubiroot="${global.hostname}-rootfs"
device_type="nand"
# set a fancy prompt (if support is compiled in)
diff --git a/arch/arm/boards/eukrea_cpuimx35/env/config b/arch/arm/boards/eukrea_cpuimx35/env/config
index 01cbfe9b06..50d33a46c3 100644
--- a/arch/arm/boards/eukrea_cpuimx35/env/config
+++ b/arch/arm/boards/eukrea_cpuimx35/env/config
@@ -5,7 +5,7 @@ otg_mode="device"
# video : can be CMO-QVGA, URT-WVGA, DVI-VGA or DVI-SVGA
video="CMO-QVGA"
-hostname=eukrea-cpuimx35
+global.hostname=eukrea-cpuimx35
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
@@ -24,16 +24,16 @@ rootfs_loc=nand
# rootfs
rootfs_type=ubifs
-rootfsimage=$hostname/rootfs.$rootfs_type
+rootfsimage=${global.hostname}/rootfs.$rootfs_type
# kernel
-kernelimage=$hostname/uImage-${hostname}.bin
+kernelimage=${global.hostname}/uImage-${global.hostname}.bin
# barebox and it's env
-bareboximage=$hostname/barebox-${hostname}.bin
-bareboxenvimage=$hostname/bareboxenv-${hostname}.bin
+bareboximage=${global.hostname}/barebox-${global.hostname}.bin
+bareboxenvimage=${global.hostname}/bareboxenv-${global.hostname}.bin
-nfsroot="$eth0.serverip:/srv/nfs/$hostname"
+nfsroot="$eth0.serverip:/srv/nfs/${global.hostname}"
autoboot_timeout=1
@@ -42,7 +42,7 @@ bootargs="console=ttymxc0,115200 otg_mode=$otg_mode video=mx3fb:$video"
nand_parts="256k(barebox)ro,128k(bareboxenv),3M(kernel),-(root)"
rootfs_mtdblock_nand=3
nand_device="mxc_nand"
-ubiroot="$hostname-rootfs"
+ubiroot="${global.hostname}-rootfs"
device_type="nand"
# set a fancy prompt (if support is compiled in)
diff --git a/arch/arm/boards/eukrea_cpuimx51/env/config b/arch/arm/boards/eukrea_cpuimx51/env/config
index 163d026158..17f8337f73 100644
--- a/arch/arm/boards/eukrea_cpuimx51/env/config
+++ b/arch/arm/boards/eukrea_cpuimx51/env/config
@@ -8,7 +8,7 @@ video="CMO-QVGA"
# screen type : can be 'tft' or 'dvi'
screen_type="tft"
-hostname=eukrea-cpuimx51
+global.hostname=eukrea-cpuimx51
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
@@ -27,16 +27,16 @@ rootfs_loc=nand
# rootfs
rootfs_type=ubifs
-rootfsimage=$hostname/rootfs.$rootfs_type
+rootfsimage=${global.hostname}/rootfs.$rootfs_type
# kernel
-kernelimage=$hostname/uImage-${hostname}.bin
+kernelimage=${global.hostname}/uImage-${global.hostname}.bin
# barebox and it's env
-bareboximage=$hostname/barebox-${hostname}.bin
-bareboxenvimage=$hostname/bareboxenv-${hostname}.bin
+bareboximage=${global.hostname}/barebox-${global.hostname}.bin
+bareboxenvimage=${global.hostname}/bareboxenv-${global.hostname}.bin
-nfsroot="$eth0.serverip:/srv/nfs/$hostname"
+nfsroot="$eth0.serverip:/srv/nfs/${global.hostname}"
autoboot_timeout=1
@@ -45,7 +45,7 @@ bootargs="console=ttymxc0,115200 otg_mode=$otg_mode video=$video screen_type=$sc
nand_parts="256k(barebox)ro,128k(bareboxenv),3M(kernel),-(root)"
rootfs_mtdblock_nand=3
nand_device="mxc_nand"
-ubiroot="$hostname-rootfs"
+ubiroot="${global.hostname}-rootfs"
device_type="nand"
# set a fancy prompt (if support is compiled in)
diff --git a/arch/arm/boards/freescale-mx28-evk/env/config b/arch/arm/boards/freescale-mx28-evk/env/config
index 3951c5bd06..4e2c90d4b1 100644
--- a/arch/arm/boards/freescale-mx28-evk/env/config
+++ b/arch/arm/boards/freescale-mx28-evk/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=mx28-evk
+global.hostname=mx28-evk
#user=
# use 'dhcp' to do dhcp in barebox and in kernel
@@ -24,21 +24,21 @@ rootfs_loc=net
rootfs_type=ext2
# where is the rootfs in case of 'rootfs_loc=disk' (linux name)
rootfs_part_linux_dev=mmcblk0p4
-rootfsimage=rootfs-${hostname}.$rootfs_type
+rootfsimage=rootfs-${global.hostname}.$rootfs_type
# where is the kernel image in case of 'kernel_loc=disk'
kernel_part=disk0.2
-kernelimage=zImage-$hostname
-bareboximage=barebox-${hostname}.bin
-bareboxenvimage=barebox-${hostname}.bin
+kernelimage=zImage-${global.hostname}
+bareboximage=barebox-${global.hostname}.bin
+bareboxenvimage=barebox-${global.hostname}.bin
if [ -n $user ]; then
bareboximage="$user"-"$bareboximage"
bareboxenvimage="$user"-"$bareboxenvimage"
kernelimage="$user"-"$kernelimage"
rootfsimage="$user"-"$rootfsimage"
- nfsroot="/home/$user/nfsroot/$hostname"
+ nfsroot="/home/$user/nfsroot/${global.hostname}"
else
nfsroot="/path/to/nfs/root"
fi
diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
index 1283e1769a..7cd61f9e96 100644
--- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
+++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
@@ -224,19 +224,19 @@ static int mx28_evk_devices_init(void)
armlinux_set_bootparams((void *)IMX_MEMORY_BASE + 0x100);
armlinux_set_architecture(MACH_TYPE_MX28EVK);
- add_generic_device("mxs_mci", 0, NULL, IMX_SSP0_BASE, 0,
+ add_generic_device("mxs_mci", 0, NULL, IMX_SSP0_BASE, 0x2000,
IORESOURCE_MEM, &mci_pdata);
- add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 4096,
+ add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 0x2000,
IORESOURCE_MEM, &mx28_evk_fb_pdata);
- add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0,
+ add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0x2000,
IORESOURCE_MEM, NULL);
mx28_evk_get_ethaddr(); /* must be after registering ocotp */
imx_enable_enetclk();
mx28_evk_fec_reset();
- add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0,
+ add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0x4000,
IORESOURCE_MEM, &fec_info);
return 0;
@@ -245,7 +245,7 @@ device_initcall(mx28_evk_devices_init);
static int mx28_evk_console_init(void)
{
- add_generic_device("stm_serial", 0, NULL, IMX_DBGUART_BASE, 8192,
+ add_generic_device("stm_serial", 0, NULL, IMX_DBGUART_BASE, 0x2000,
IORESOURCE_MEM, NULL);
return 0;
diff --git a/arch/arm/boards/freescale-mx35-3-stack/env/config b/arch/arm/boards/freescale-mx35-3-stack/env/config
index 171ae8c9bf..122c0fcaba 100644
--- a/arch/arm/boards/freescale-mx35-3-stack/env/config
+++ b/arch/arm/boards/freescale-mx35-3-stack/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=mx35-3stack
+global.hostname=mx35-3stack
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/freescale-mx53-loco/env/config b/arch/arm/boards/freescale-mx53-loco/env/config
index bceddafa97..2ab126828b 100644
--- a/arch/arm/boards/freescale-mx53-loco/env/config
+++ b/arch/arm/boards/freescale-mx53-loco/env/config
@@ -1,13 +1,13 @@
#!/bin/sh
-hostname=loco
+global.hostname=loco
eth0.serverip=
user=
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp
-dhcp_vendor_id=barebox-mx53-loco
+global.dhcp.vendor_id=barebox-mx53-loco
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
@@ -22,16 +22,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/freescale-mx53-smd/env/config b/arch/arm/boards/freescale-mx53-smd/env/config
index d2afb291e8..d92beb9ee4 100644
--- a/arch/arm/boards/freescale-mx53-smd/env/config
+++ b/arch/arm/boards/freescale-mx53-smd/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=loco
+global.hostname=loco
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/freescale-mx6-arm2/board.c b/arch/arm/boards/freescale-mx6-arm2/board.c
index e4a9a49b55..0e853a6926 100644
--- a/arch/arm/boards/freescale-mx6-arm2/board.c
+++ b/arch/arm/boards/freescale-mx6-arm2/board.c
@@ -26,7 +26,7 @@
#include <asm/armlinux.h>
#include <generated/mach-types.h>
#include <partition.h>
-#include <miidev.h>
+#include <linux/phy.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <mach/generic.h>
@@ -104,50 +104,39 @@ static int arm2_mem_init(void)
}
mem_initcall(arm2_mem_init);
-static struct fec_platform_data fec_info = {
- .xcv_type = RGMII,
- .phy_addr = 0,
-};
-
-static int mx6_rgmii_rework(void)
+static void mx6_rgmii_rework(struct phy_device *dev)
{
- struct mii_device *mdev;
u16 val;
- mdev = mii_open("phy0");
- if (!mdev) {
- printf("unable to open phy0\n");
- return -ENODEV;
- }
-
/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
- mii_write(mdev, mdev->address, 0xd, 0x7);
- mii_write(mdev, mdev->address, 0xe, 0x8016);
- mii_write(mdev, mdev->address, 0xd, 0x4007);
+ phy_write(dev, 0xd, 0x7);
+ phy_write(dev, 0xe, 0x8016);
+ phy_write(dev, 0xd, 0x4007);
- val = mii_read(mdev, mdev->address, 0xe);
+ val = phy_read(dev, 0xe);
val &= 0xffe3;
val |= 0x18;
- mii_write(mdev, mdev->address, 0xe, val);
+ phy_write(dev, 0xe, val);
/* introduce tx clock delay */
- mii_write(mdev, mdev->address, 0x1d, 0x5);
+ phy_write(dev, 0x1d, 0x5);
- val = mii_read(mdev, mdev->address, 0x1e);
+ val = phy_read(dev, 0x1e);
val |= 0x0100;
- mii_write(mdev, mdev->address, 0x1e, val);
-
- mii_close(mdev);
-
- return 0;
+ phy_write(dev, 0x1e, val);
}
+static struct fec_platform_data fec_info = {
+ .xcv_type = RGMII,
+ .phy_init = mx6_rgmii_rework,
+ .phy_addr = 0,
+};
+
static int arm2_devices_init(void)
{
imx6_add_mmc3(NULL);
imx6_add_fec(&fec_info);
- mx6_rgmii_rework();
armlinux_set_bootparams((void *)0x10000100);
armlinux_set_architecture(3837);
diff --git a/arch/arm/boards/freescale-mx6-sabrelite/board.c b/arch/arm/boards/freescale-mx6-sabrelite/board.c
index 1ac401ebb1..6070e2e167 100644
--- a/arch/arm/boards/freescale-mx6-sabrelite/board.c
+++ b/arch/arm/boards/freescale-mx6-sabrelite/board.c
@@ -28,7 +28,7 @@
#include <asm/armlinux.h>
#include <generated/mach-types.h>
#include <partition.h>
-#include <miidev.h>
+#include <linux/phy.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <mach/generic.h>
@@ -40,6 +40,7 @@
#include <mach/gpio.h>
#include <spi/spi.h>
#include <mach/spi.h>
+#include <mach/usb.h>
#define SABRELITE_SD3_WP IMX_GPIO_NR(7, 1)
#define SABRELITE_SD3_CD IMX_GPIO_NR(7, 0)
@@ -135,38 +136,27 @@ static int sabrelite_mem_init(void)
}
mem_initcall(sabrelite_mem_init);
-static struct fec_platform_data fec_info = {
- .xcv_type = RGMII,
- .phy_addr = 6,
-};
-
-int mx6_rgmii_rework(void)
+static void mx6_rgmii_rework(struct phy_device *dev)
{
- struct mii_device *mdev;
-
- mdev = mii_open("phy0");
- if (!mdev) {
- printf("unable to open phy0\n");
- return -ENODEV;
- }
-
- mii_write(mdev, mdev->address, 0x09, 0x0f00);
+ phy_write(dev, 0x09, 0x0f00);
/* do same as linux kernel */
/* min rx data delay */
- mii_write(mdev, mdev->address, 0x0b, 0x8105);
- mii_write(mdev, mdev->address, 0x0c, 0x0000);
+ phy_write(dev, 0x0b, 0x8105);
+ phy_write(dev, 0x0c, 0x0000);
/* max rx/tx clock delay, min rx/tx control delay */
- mii_write(mdev, mdev->address, 0x0b, 0x8104);
- mii_write(mdev, mdev->address, 0x0c, 0xf0f0);
- mii_write(mdev, mdev->address, 0x0b, 0x104);
-
- mii_close(mdev);
-
- return 0;
+ phy_write(dev, 0x0b, 0x8104);
+ phy_write(dev, 0x0c, 0xf0f0);
+ phy_write(dev, 0x0b, 0x104);
}
+static struct fec_platform_data fec_info = {
+ .xcv_type = RGMII,
+ .phy_init = mx6_rgmii_rework,
+ .phy_addr = 6,
+};
+
static int sabrelite_ksz9021rn_setup(void)
{
mxc_iomux_v3_setup_multiple_pads(sabrelite_enet_pads, ARRAY_SIZE(sabrelite_enet_pads));
@@ -265,7 +255,6 @@ static int sabrelite_devices_init(void)
sabrelite_ksz9021rn_setup();
imx6_iim_register_fec_ethaddr();
imx6_add_fec(&fec_info);
- mx6_rgmii_rework();
sabrelite_ehci_init();
diff --git a/arch/arm/boards/friendlyarm-mini2440/env/config b/arch/arm/boards/friendlyarm-mini2440/env/config
index 77cc34f575..69d431a4ac 100644
--- a/arch/arm/boards/friendlyarm-mini2440/env/config
+++ b/arch/arm/boards/friendlyarm-mini2440/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=mini2440
+global.hostname=mini2440
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-${hostname}.${rootfs_type}
+rootfsimage=root-${global.hostname}.${rootfs_type}
-kernelimage=zImage-${hostname}
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="${user}"-"${kernelimage}"
- nfsroot="${eth0.serverip}:/home/${user}/nfsroot/${hostname}"
+ nfsroot="${eth0.serverip}:/home/${user}/nfsroot/${global.hostname}"
rootfsimage="${user}"-"${rootfsimage}"
else
nfsroot="${eth0.serverip}:/path/to/nfs/root"
diff --git a/arch/arm/boards/guf-cupid/env/config b/arch/arm/boards/guf-cupid/env/config
index 1be875d048..17b11a1943 100644
--- a/arch/arm/boards/guf-cupid/env/config
+++ b/arch/arm/boards/guf-cupid/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=cupid
+global.hostname=cupid
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/guf-neso/env/config b/arch/arm/boards/guf-neso/env/config
index 3013728263..1758c91454 100644
--- a/arch/arm/boards/guf-neso/env/config
+++ b/arch/arm/boards/guf-neso/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=guf-neso
+global.hostname=guf-neso
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/imx233-olinuxino/Makefile b/arch/arm/boards/imx233-olinuxino/Makefile
new file mode 100644
index 0000000000..6d71450edb
--- /dev/null
+++ b/arch/arm/boards/imx233-olinuxino/Makefile
@@ -0,0 +1 @@
+obj-y = imx23-olinuxino.o
diff --git a/arch/arm/boards/imx233-olinuxino/config.h b/arch/arm/boards/imx233-olinuxino/config.h
new file mode 100644
index 0000000000..87d9e2f476
--- /dev/null
+++ b/arch/arm/boards/imx233-olinuxino/config.h
@@ -0,0 +1,21 @@
+/*
+ * 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 _CONFIG_H_
+# define _CONFIG_H_
+
+#endif /* _CONFIG_H_ */
diff --git a/arch/arm/boards/imx233-olinuxino/env/bin/boot b/arch/arm/boards/imx233-olinuxino/env/bin/boot
new file mode 100644
index 0000000000..60dd93f297
--- /dev/null
+++ b/arch/arm/boards/imx233-olinuxino/env/bin/boot
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+. /env/config
+
+if [ x$1 = xdisk ]; then
+ rootfs_loc=disk
+ kernel_loc=disk
+elif [ x$1 = xnet ]; then
+ rootfs_loc=net
+ kernel_loc=net
+fi
+
+if [ x$ip = xdhcp ]; then
+ bootargs="$bootargs ip=dhcp"
+elif [ x$ip = xnone ]; then
+ bootargs="$bootargs ip=none"
+else
+ bootargs="$bootargs ip=$eth0.ipaddr::$eth0.gateway:$eth0.netmask:::"
+fi
+
+if [ x$rootfs_loc = xdisk ]; then
+ bootargs="$bootargs noinitrd rootfstype=$rootfs_type root=/dev/$rootfs_part"
+elif [ x$rootfs_loc = xnet ]; then
+ bootargs="$bootargs root=/dev/nfs nfsroot=$nfsroot,v3,tcp noinitrd"
+elif [ x$rootfs_loc = xinitrd ]; then
+ bootargs="$bootargs root=/dev/ram0 rdinit=/sbin/init"
+fi
+
+
+bootm -o $oftree_loc/imx23-olinuxino.dtb /dev/$kernel_part
+
+echo "Booting failed. Correct setup of 'kernel_part'?"
diff --git a/arch/arm/boards/imx233-olinuxino/env/bin/init b/arch/arm/boards/imx233-olinuxino/env/bin/init
new file mode 100644
index 0000000000..3ed68f76c5
--- /dev/null
+++ b/arch/arm/boards/imx233-olinuxino/env/bin/init
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+PATH=/env/bin
+export PATH
+
+. /env/config
+
+echo
+echo -n "Hit any key to stop autoboot: "
+timeout -a $autoboot_timeout
+if [ $? != 0 ]; then
+ exit
+fi
+
+boot
diff --git a/arch/arm/boards/imx233-olinuxino/env/config b/arch/arm/boards/imx233-olinuxino/env/config
new file mode 100644
index 0000000000..0e95373b19
--- /dev/null
+++ b/arch/arm/boards/imx233-olinuxino/env/config
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+hostname=imx23-olinuxino
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=none
+
+# or set your networking parameters here (if a USB network adapter is attached)
+#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 'net' or 'disk'
+kernel_loc=disk
+
+# can be either 'net', or 'disk' or 'initrd'
+rootfs_loc=disk
+
+# can be any regular filesystem like ext2, ext3, reiserfs in case of 'rootfs_loc=disk'
+rootfs_type=ext3
+
+# Where is the rootfs in case of 'rootfs_loc=disk'
+rootfs_part=mmcblk0p4
+
+# Where is the rootfs in case of 'rootfs_loc=net'
+nfsroot=FIXME
+
+# Where to get the kernel image in case of 'kernel_loc=disk'
+kernel_part=disk0.2
+
+# Where to get the device tree image in case of 'kernel_loc=disk'
+oftree_loc=env/oftree
+
+# base kernel parameter
+bootargs="console=ttyAMA0,115200 rw rootwait"
+
+autoboot_timeout=2
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m "
diff --git a/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c b/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c
new file mode 100644
index 0000000000..04826388d4
--- /dev/null
+++ b/arch/arm/boards/imx233-olinuxino/imx23-olinuxino.c
@@ -0,0 +1,254 @@
+/*
+ * (C) Copyright 2012 Fadil Berisha, <fadil.r.berisha@gmail.com>
+ * based on falconwing.c & mx23-evk.c
+ *
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ * (C) Copyright 2011 Wolfram Sang - Pengutronix
+ *
+ * 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 <gpio.h>
+#include <environment.h>
+#include <errno.h>
+#include <mci.h>
+#include <asm/armlinux.h>
+#include <usb/ehci.h>
+#include <mach/usb.h>
+#include <generated/mach-types.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <mach/mci.h>
+
+static struct mxs_mci_platform_data mci_pdata = {
+ .caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz,
+ .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, /* fixed to 3.3 V */
+ .f_min = 400000,
+};
+
+static const uint32_t pad_setup[] = {
+ /* debug port */
+ PWM1_DUART_TX | STRENGTH(S4MA), /* PWM0/DUART_TXD - U_DEBUG PIN 2 */
+ PWM0_DUART_RX | STRENGTH(S4MA), /* PWM0/DUART_RXD - U_DEBUG PIN 1 */
+
+ /* auart */
+ I2C_SDA_AUART1_RX | STRENGTH(S4MA),
+ I2C_CLK_AUART1_TX | STRENGTH(S4MA),
+
+ /* lcd */
+ LCD_D17 | STRENGTH(S12MA), /*PIN18/LCD_D17 - GPIO PIN 3 */
+ LCD_D16 | STRENGTH(S12MA),
+ LCD_D15 | STRENGTH(S12MA),
+ LCD_D14 | STRENGTH(S12MA),
+ LCD_D13 | STRENGTH(S12MA),
+ LCD_D12 | STRENGTH(S12MA),
+ LCD_D11 | STRENGTH(S12MA),
+ LCD_D10 | STRENGTH(S12MA),
+ LCD_D9 | STRENGTH(S12MA),
+ LCD_D8 | STRENGTH(S12MA),
+ LCD_D7 | STRENGTH(S12MA),
+ LCD_D6 | STRENGTH(S12MA),
+ LCD_D5 | STRENGTH(S12MA),
+ LCD_D4 | STRENGTH(S12MA),
+ LCD_D3 | STRENGTH(S12MA),
+ LCD_D2 | STRENGTH(S12MA), /* PIN3/LCD_D02 - GPIO PIN 31*/
+ LCD_D1 | STRENGTH(S12MA), /* PIN2/LCD_D01 - GPIO PIN 33*/
+ LCD_D0 | STRENGTH(S12MA), /* PIN1/LCD_D00 - GPIO PIN 35*/
+ LCD_CS, /* PIN26/LCD_CS - GPIO PIN 20*/
+ LCD_RS, /* PIN25/LCD_RS - GPIO PIN 18*/
+ LCD_WR, /* PIN24/LCD_WR - GPIO PIN 16*/
+ LCD_RESET, /* PIN23/LCD_DISP - GPIO PIN 14*/
+ LCD_ENABE | STRENGTH(S12MA), /* PIN22/LCD_EN/I2C_SCL - GPIO PIN 12*/
+ LCD_VSYNC | STRENGTH(S12MA), /* PIN21/LCD_HSYNC/I2C_SDA- GPIO PIN 10*/
+ LCD_HSYNC | STRENGTH(S12MA), /* PIN20/LCD_VSYNC - GPIO PIN 8*/
+ LCD_DOTCLOCK | STRENGTH(S12MA), /* PIN19/LCD_DOTCLK - GPIO PIN 6*/
+
+
+ /* SD card interface */
+ SSP1_DATA0 | PULLUP(1),
+ SSP1_DATA1 | PULLUP(1),
+ SSP1_DATA2 | PULLUP(1),
+ SSP1_DATA3 | PULLUP(1),
+ SSP1_SCK,
+ SSP1_CMD | PULLUP(1),
+ SSP1_DETECT | PULLUP(1),
+
+ /* led */
+ SSP1_DETECT_GPIO | GPIO_OUT | GPIO_VALUE(1),
+
+ /* gpio - USB hub LAN9512-JZX*/
+ GPMI_ALE_GPIO | GPIO_OUT | GPIO_VALUE(1),
+};
+
+static int imx23_olinuxino_mem_init(void)
+{
+ arm_add_mem_device("ram0", IMX_MEMORY_BASE, 64 * 1024 * 1024);
+
+ return 0;
+}
+mem_initcall(imx23_olinuxino_mem_init);
+
+static void olinuxino_init_usb(void)
+{
+
+ imx23_usb_phy_enable();
+
+ add_generic_usb_ehci_device(DEVICE_ID_DYNAMIC, IMX_USB_BASE, NULL);
+}
+
+/**
+ * Try to register an environment storage on the attached MCI card
+ * @return 0 on success
+ *
+ * We rely on the existence of a usable SD card, already attached to
+ * our system, to get something like a persistent memory for our environment.
+ * If this SD card is also the boot media, we can use the second partition
+ * for our environment purpose (if present!).
+ */
+static int register_persistant_environment(void)
+{
+ struct cdev *cdev;
+
+ /*
+ * The imx23-olinuxino only has one MCI card socket.
+ * So, we expect its name as "disk0".
+ */
+ cdev = cdev_by_name("disk0");
+ if (cdev == NULL) {
+ pr_err("No MCI card preset\n");
+ return -ENODEV;
+ }
+
+
+
+ /* MCI card is present, also a useable partition on it? */
+ cdev = cdev_by_name("disk0.1");
+ if (cdev == NULL) {
+ pr_err("No second partition available\n");
+ pr_info("Please create at least a second partition with"
+ " 256 kiB...512 kiB in size (your choice)\n");
+ return -ENODEV;
+ }
+
+ /* use the full partition as our persistent environment storage */
+ return devfs_add_partition("disk0.1", 0, cdev->size,
+ DEVFS_PARTITION_FIXED, "env0");
+}
+
+
+static int imx23_olinuxino_devices_init(void)
+{
+ int i, rc;
+
+
+ /* initizalize gpios */
+ for (i = 0; i < ARRAY_SIZE(pad_setup); i++)
+ imx_gpio_mode(pad_setup[i]);
+
+ armlinux_set_bootparams((void *)IMX_MEMORY_BASE + 0x100);
+ armlinux_set_architecture(MACH_TYPE_IMX233_OLINUXINO);
+
+ /* enable IOCLK to run at the PLL frequency */
+ imx_set_ioclk(480000000);
+
+ /* run the SSP unit clock at 100,000 kHz */
+ imx_set_sspclk(0, 100000000, 1);
+
+ add_generic_device("mxs_mci", DEVICE_ID_DYNAMIC, NULL, IMX_SSP1_BASE,
+ 0x8000, IORESOURCE_MEM, &mci_pdata);
+
+ olinuxino_init_usb();
+
+ rc = register_persistant_environment();
+ if (rc != 0)
+ printf("Cannot create the 'env0' persistant "
+ "environment storage (%d)\n", rc);
+
+ return 0;
+}
+
+device_initcall(imx23_olinuxino_devices_init);
+
+static int imx23_olinuxino_console_init(void)
+{
+ add_generic_device("stm_serial", 0, NULL, IMX_DBGUART_BASE, 8192,
+ IORESOURCE_MEM, NULL);
+
+ return 0;
+}
+
+console_initcall(imx23_olinuxino_console_init);
+
+/** @page olinuxino Olimex.ltd's i.MX23 evaluation kit
+
+This CPU card is based on an i.MX23 CPU. The card is shipped with:
+
+- 64 MiB synchronous dynamic RAM (mobile DDR type)
+
+
+Memory layout when @b barebox is running:
+
+- 0x40000000 start of SDRAM
+- 0x40000100 start of kernel's boot parameters
+ - below malloc area: stack area
+ - below barebox: malloc area
+- 0x42000000 start of @b barebox
+
+@section get_imx23_olinuxino_binary How to get the bootloader binary image:
+
+Using the default configuration:
+
+@verbatim
+make ARCH=arm imx23_olinuxino_defconfig
+@endverbatim
+
+Build the bootloader binary image:
+
+@verbatim
+make ARCH=arm CROSS_COMPILE=armv5compiler
+@endverbatim
+
+@note replace the armv5compiler with your ARM v5 cross compiler.
+
+@section imx233-olinuxino How to prepare an MCI card to boot
+the imx233-olinuxino with barebox
+
+- Create four primary partitions on the MCI card
+ - the first one for the bootlets (about 256 kiB)
+ - the second one for the persistant environment
+ (size is up to you, at least 256k)
+ - the third one for the kernel (2 MiB ... 4 MiB in size)
+ - the 4th one for the root filesystem which can fill the
+ rest of the available space
+
+- Mark the first partition with the partition ID "53" and copy the bootlets
+ into this partition (currently not part of @b barebox!).
+
+- @b barebox expect device tree blob file imx23-olinuxino.dtb
+ into directory env/oftree. At compile time, copy blob file into directory
+ arch/arm/boards/imx233-olinuxino/env/oftree/.
+
+- Copy the default @b barebox environment into the second partition
+ (no filesystem required).
+
+- Copy the kernel into the third partition (no filesystem required).
+
+- Create the root filesystem in the 4th partition. You may copy an
+ image into this partition or you can do it in the classic way:
+ mkfs on it, mount it and copy all required data and programs into it.
+*/
diff --git a/arch/arm/boards/karo-tx25/env/config b/arch/arm/boards/karo-tx25/env/config
index 28a5e7f27c..87beb6d64b 100644
--- a/arch/arm/boards/karo-tx25/env/config
+++ b/arch/arm/boards/karo-tx25/env/config
@@ -1,5 +1,5 @@
-hostname=tx25
+global.hostname=tx25
baseboard=tx28stk5
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/karo-tx28/env/config b/arch/arm/boards/karo-tx28/env/config
index b5222e99dc..52593761a7 100644
--- a/arch/arm/boards/karo-tx28/env/config
+++ b/arch/arm/boards/karo-tx28/env/config
@@ -1,7 +1,7 @@
#
#
-hostname=tx28
+global.hostname=tx28
baseboard=tx28stk5
# use 'dhcp' to do dhcp in barebox and in kernel
@@ -22,16 +22,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c
index 04fdbc37b9..961787669b 100644
--- a/arch/arm/boards/karo-tx28/tx28-stk5.c
+++ b/arch/arm/boards/karo-tx28/tx28-stk5.c
@@ -376,7 +376,7 @@ void base_board_init(void)
/* run the SSP unit clock at 100 MHz */
imx_set_sspclk(0, 100000000, 1);
- add_generic_device("mxs_mci", 0, NULL, IMX_SSP0_BASE, 0,
+ add_generic_device("mxs_mci", 0, NULL, IMX_SSP0_BASE, 0x2000,
IORESOURCE_MEM, &mci_pdata);
if (tx28_fb_pdata.fixed_screen < (void *)&_end) {
@@ -384,16 +384,16 @@ void base_board_init(void)
tx28_fb_pdata.fixed_screen = NULL;
}
- add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 4096,
+ add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 0x2000,
IORESOURCE_MEM, &tx28_fb_pdata);
- add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0,
+ add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0x2000,
IORESOURCE_MEM, NULL);
tx28_get_ethaddr();
imx_enable_enetclk();
- add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0,
+ add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0x4000,
IORESOURCE_MEM, &fec_info);
ret = register_persistent_environment();
@@ -404,9 +404,9 @@ void base_board_init(void)
static int tx28kit_console_init(void)
{
- add_generic_device("stm_serial", 0, NULL, IMX_DBGUART_BASE, 8192,
+ add_generic_device("stm_serial", 0, NULL, IMX_DBGUART_BASE, 0x2000,
IORESOURCE_MEM, NULL);
-
+
return 0;
}
diff --git a/arch/arm/boards/karo-tx53/Makefile b/arch/arm/boards/karo-tx53/Makefile
new file mode 100644
index 0000000000..b56ce7f50d
--- /dev/null
+++ b/arch/arm/boards/karo-tx53/Makefile
@@ -0,0 +1,2 @@
+obj-y += board.o
+obj-y += flash_header.o
diff --git a/arch/arm/boards/karo-tx53/board.c b/arch/arm/boards/karo-tx53/board.c
new file mode 100644
index 0000000000..c8509bebcb
--- /dev/null
+++ b/arch/arm/boards/karo-tx53/board.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ *
+ */
+#include <common.h>
+#include <environment.h>
+#include <fcntl.h>
+#include <fec.h>
+#include <fs.h>
+#include <init.h>
+#include <nand.h>
+#include <net.h>
+#include <partition.h>
+#include <sizes.h>
+
+#include <generated/mach-types.h>
+
+#include <mach/imx-regs.h>
+#include <mach/iomux-mx53.h>
+#include <mach/devices-imx53.h>
+#include <mach/generic.h>
+#include <mach/gpio.h>
+#include <mach/imx-nand.h>
+#include <mach/iim.h>
+#include <mach/imx5.h>
+
+#include <asm/armlinux.h>
+#include <io.h>
+#include <asm/mmu.h>
+
+static struct fec_platform_data fec_info = {
+ .xcv_type = RMII,
+};
+
+static iomux_v3_cfg_t tx53_pads[] = {
+ /* UART1 */
+ MX53_PAD_PATA_DIOW__UART1_TXD_MUX,
+ MX53_PAD_PATA_DMACK__UART1_RXD_MUX,
+
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX,
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX,
+
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
+
+ /* setup FEC PHY pins for GPIO function */
+ MX53_PAD_FEC_REF_CLK__GPIO1_23,
+ MX53_PAD_FEC_MDC__GPIO1_31,
+ MX53_PAD_FEC_MDIO__GPIO1_22,
+ MX53_PAD_FEC_RXD0__GPIO1_27,
+ MX53_PAD_FEC_RXD1__GPIO1_26,
+ MX53_PAD_FEC_RX_ER__GPIO1_24,
+ MX53_PAD_FEC_TX_EN__GPIO1_28,
+ MX53_PAD_FEC_TXD0__GPIO1_30,
+ MX53_PAD_FEC_TXD1__GPIO1_29,
+ MX53_PAD_FEC_CRS_DV__GPIO1_25,
+
+ /* FEC PHY reset */
+ MX53_PAD_PATA_DA_0__GPIO7_6,
+ /* FEC PHY power */
+ MX53_PAD_EIM_D20__GPIO3_20,
+
+ /* SD1 */
+ MX53_PAD_SD1_CMD__ESDHC1_CMD,
+ MX53_PAD_SD1_CLK__ESDHC1_CLK,
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
+
+ /* SD1_CD */
+ MX53_PAD_EIM_D24__GPIO3_24,
+
+ MX53_PAD_GPIO_3__I2C3_SCL,
+ MX53_PAD_GPIO_6__I2C3_SDA,
+
+ MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12,
+ MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13,
+ MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14,
+ MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15,
+ MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16,
+ MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17,
+ MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18,
+ MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19,
+ MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC,
+ MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC,
+ MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK,
+};
+
+static int tx53_mem_init(void)
+{
+ arm_add_mem_device("ram0", 0x70000000, SZ_1G);
+
+ return 0;
+}
+mem_initcall(tx53_mem_init);
+
+#define TX53_SD1_CD IMX_GPIO_NR(3, 24)
+
+static struct esdhc_platform_data tx53_sd1_data = {
+ .cd_gpio = TX53_SD1_CD,
+ .cd_type = ESDHC_CD_GPIO,
+ .wp_type = ESDHC_WP_NONE,
+};
+
+struct imx_nand_platform_data nand_info = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+#define FEC_POWER_GPIO IMX_GPIO_NR(3, 20)
+#define FEC_RESET_GPIO IMX_GPIO_NR(7, 6)
+
+static struct tx53_fec_gpio_setup {
+ iomux_v3_cfg_t pad;
+ unsigned gpio:9,
+ dir:1,
+ level:1;
+} tx53_fec_gpios[] = {
+ { MX53_PAD_PATA_DA_0__GPIO7_6, FEC_RESET_GPIO, 1, 0, }, /* PHY reset */
+ { MX53_PAD_EIM_D20__GPIO3_20, FEC_POWER_GPIO, 1, 1, }, /* PHY power enable */
+ { MX53_PAD_FEC_REF_CLK__GPIO1_23, IMX_GPIO_NR(1, 23), 0, }, /* ENET_CLK */
+ { MX53_PAD_FEC_MDC__GPIO1_31, IMX_GPIO_NR(1, 31), 1, 0, }, /* MDC */
+ { MX53_PAD_FEC_MDIO__GPIO1_22, IMX_GPIO_NR(1, 22), 1, 0, }, /* MDIO */
+ { MX53_PAD_FEC_RXD0__GPIO1_27, IMX_GPIO_NR(1, 27), 1, 1, }, /* Mode0/RXD0 */
+ { MX53_PAD_FEC_RXD1__GPIO1_26, IMX_GPIO_NR(1, 26), 1, 1, }, /* Mode1/RXD1 */
+ { MX53_PAD_FEC_RX_ER__GPIO1_24, IMX_GPIO_NR(1, 24), 0, }, /* RX_ER */
+ { MX53_PAD_FEC_TX_EN__GPIO1_28, IMX_GPIO_NR(1, 28), 1, 0, }, /* TX_EN */
+ { MX53_PAD_FEC_TXD0__GPIO1_30, IMX_GPIO_NR(1, 30), 1, 0, }, /* TXD0 */
+ { MX53_PAD_FEC_TXD1__GPIO1_29, IMX_GPIO_NR(1, 29), 1, 0, }, /* TXD1 */
+ { MX53_PAD_FEC_CRS_DV__GPIO1_25, IMX_GPIO_NR(1, 25), 1, 1, }, /* Mode2/CRS_DV */
+};
+
+static iomux_v3_cfg_t tx53_fec_pads[] = {
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
+ MX53_PAD_FEC_MDC__FEC_MDC,
+ MX53_PAD_FEC_MDIO__FEC_MDIO,
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0,
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1,
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER,
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0,
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1,
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
+};
+
+static inline void tx53_fec_init(void)
+{
+ int i;
+
+ /* Configure LAN8700 pads as GPIO and set up
+ * necessary strap options for PHY
+ */
+ for (i = 0; i < ARRAY_SIZE(tx53_fec_gpios); i++) {
+ struct tx53_fec_gpio_setup *gs = &tx53_fec_gpios[i];
+
+ if (gs->dir)
+ gpio_direction_output(gs->gpio, gs->level);
+ else
+ gpio_direction_input(gs->gpio);
+
+ mxc_iomux_v3_setup_pad(gs->pad);
+ }
+
+ /*
+ *Turn on phy power, leave in reset state
+ */
+ gpio_set_value(FEC_POWER_GPIO, 1);
+
+ /*
+ * Wait some time to let the phy activate the internal regulator
+ */
+ mdelay(10);
+
+ /*
+ * Deassert reset, phy latches the rest of bootstrap pins
+ */
+ gpio_set_value(FEC_RESET_GPIO, 1);
+
+ /* LAN7800 has an internal Power On Reset (POR) signal (OR'ed with
+ * the external RESET signal) which is deactivated 21ms after
+ * power on and latches the strap options.
+ * Delay for 22ms to ensure, that the internal POR is inactive
+ * before reconfiguring the strap pins.
+ */
+ mdelay(22);
+
+ /*
+ * The phy is ready, now configure imx51 pads for fec operation
+ */
+ mxc_iomux_v3_setup_multiple_pads(tx53_fec_pads,
+ ARRAY_SIZE(tx53_fec_pads));
+}
+
+static int tx53_devices_init(void)
+{
+ imx53_iim_register_fec_ethaddr();
+ tx53_fec_init();
+ imx53_add_fec(&fec_info);
+ imx53_add_mmc0(&tx53_sd1_data);
+ imx53_add_nand(&nand_info);
+
+ armlinux_set_bootparams((void *)0x70000100);
+ armlinux_set_architecture(MACH_TYPE_TX53);
+
+ return 0;
+}
+
+device_initcall(tx53_devices_init);
+
+static int tx53_part_init(void)
+{
+ devfs_add_partition("disk0", 0x00000, SZ_512K, DEVFS_PARTITION_FIXED, "self0");
+ devfs_add_partition("disk0", SZ_512K, SZ_1M, DEVFS_PARTITION_FIXED, "env0");
+
+ return 0;
+}
+late_initcall(tx53_part_init);
+
+static int tx53_console_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(tx53_pads, ARRAY_SIZE(tx53_pads));
+
+ imx53_init_lowlevel(1000);
+
+ imx53_add_uart0();
+ return 0;
+}
+console_initcall(tx53_console_init);
diff --git a/arch/arm/boards/karo-tx53/config.h b/arch/arm/boards/karo-tx53/config.h
new file mode 100644
index 0000000000..b7effe5d28
--- /dev/null
+++ b/arch/arm/boards/karo-tx53/config.h
@@ -0,0 +1,24 @@
+/**
+ * @file
+ * @brief Global defintions for the ARM i.MX51 based babbage board
+ *
+ * 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 __CONFIG_H
+#define __CONFIG_H
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/karo-tx53/env/init/bootargs-base b/arch/arm/boards/karo-tx53/env/init/bootargs-base
new file mode 100644
index 0000000000..d86975406e
--- /dev/null
+++ b/arch/arm/boards/karo-tx53/env/init/bootargs-base
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ "$1" = menu ]; then
+ init-menu-add-entry "$0" "Base bootargs"
+ exit
+fi
+
+global.linux.bootargs.base="console=ttymxc0,115200"
diff --git a/arch/arm/boards/karo-tx53/env/init/hostname b/arch/arm/boards/karo-tx53/env/init/hostname
new file mode 100644
index 0000000000..2de91305e5
--- /dev/null
+++ b/arch/arm/boards/karo-tx53/env/init/hostname
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ "$1" = menu ]; then
+ init-menu-add-entry "$0" "hostname"
+ exit
+fi
+
+global.hostname=tx53
diff --git a/arch/arm/boards/karo-tx53/flash_header.c b/arch/arm/boards/karo-tx53/flash_header.c
new file mode 100644
index 0000000000..9b97fab2df
--- /dev/null
+++ b/arch/arm/boards/karo-tx53/flash_header.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2011 Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <asm/byteorder.h>
+#include <mach/imx-flash-header.h>
+#include <asm/barebox-arm-head.h>
+
+void __naked __flash_header_start go(void)
+{
+ barebox_arm_head();
+}
+
+/*
+ * FIXME: These are the dcd values for a Ka-Ro TX53 1011 which
+ * is not in production. It has 1GB DDR2 memory.
+ */
+struct imx_dcd_v2_entry __dcd_entry_section dcd_entry[] = {
+ { .addr = cpu_to_be32(0x53fd406c), .val = cpu_to_be32(0xffffffff), },
+ { .addr = cpu_to_be32(0x53fd4070), .val = cpu_to_be32(0xffffffff), },
+ { .addr = cpu_to_be32(0x53fd4074), .val = cpu_to_be32(0xffffffff), },
+ { .addr = cpu_to_be32(0x53fd4078), .val = cpu_to_be32(0xffffffff), },
+ { .addr = cpu_to_be32(0x53fd407c), .val = cpu_to_be32(0xffffffff), },
+ { .addr = cpu_to_be32(0x53fd4080), .val = cpu_to_be32(0xffffffff), },
+ { .addr = cpu_to_be32(0x53fd4088), .val = cpu_to_be32(0xffffffff), },
+ { .addr = cpu_to_be32(0x53fa8174), .val = cpu_to_be32(0x00000011), },
+ { .addr = cpu_to_be32(0x63fd800c), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa8554), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa8560), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa8594), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa8584), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa8558), .val = cpu_to_be32(0x00200040), },
+ { .addr = cpu_to_be32(0x53fa8568), .val = cpu_to_be32(0x00200040), },
+ { .addr = cpu_to_be32(0x53fa8590), .val = cpu_to_be32(0x00200040), },
+ { .addr = cpu_to_be32(0x53fa857c), .val = cpu_to_be32(0x00200040), },
+ { .addr = cpu_to_be32(0x53fa8564), .val = cpu_to_be32(0x00200040), },
+ { .addr = cpu_to_be32(0x53fa8580), .val = cpu_to_be32(0x00200040), },
+ { .addr = cpu_to_be32(0x53fa8570), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa8578), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa872c), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa8728), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa871c), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa8718), .val = cpu_to_be32(0x00200000), },
+ { .addr = cpu_to_be32(0x53fa8574), .val = cpu_to_be32(0x00280000), },
+ { .addr = cpu_to_be32(0x53fa8588), .val = cpu_to_be32(0x00280000), },
+ { .addr = cpu_to_be32(0x53fa86f0), .val = cpu_to_be32(0x00280000), },
+ { .addr = cpu_to_be32(0x53fa8720), .val = cpu_to_be32(0x00280000), },
+ { .addr = cpu_to_be32(0x53fa86fc), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa86f4), .val = cpu_to_be32(0x00000200), },
+ { .addr = cpu_to_be32(0x53fa8714), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa8724), .val = cpu_to_be32(0x06000000), },
+ { .addr = cpu_to_be32(0x63fd9088), .val = cpu_to_be32(0x36353b38), },
+ { .addr = cpu_to_be32(0x63fd9090), .val = cpu_to_be32(0x49434942), },
+ { .addr = cpu_to_be32(0x63fd90f8), .val = cpu_to_be32(0x00000800), },
+ { .addr = cpu_to_be32(0x63fd907c), .val = cpu_to_be32(0x01350138), },
+ { .addr = cpu_to_be32(0x63fd9080), .val = cpu_to_be32(0x01380139), },
+ { .addr = cpu_to_be32(0x63fd9018), .val = cpu_to_be32(0x00001710), },
+ { .addr = cpu_to_be32(0x63fd9000), .val = cpu_to_be32(0x84110000), },
+ { .addr = cpu_to_be32(0x63fd900c), .val = cpu_to_be32(0x4d5122d2), },
+ { .addr = cpu_to_be32(0x63fd9010), .val = cpu_to_be32(0xb6f18a22), },
+ { .addr = cpu_to_be32(0x63fd9014), .val = cpu_to_be32(0x00c700db), },
+ { .addr = cpu_to_be32(0x63fd902c), .val = cpu_to_be32(0x000026d2), },
+ { .addr = cpu_to_be32(0x63fd9030), .val = cpu_to_be32(0x009f000e), },
+ { .addr = cpu_to_be32(0x63fd9008), .val = cpu_to_be32(0x12272000), },
+ { .addr = cpu_to_be32(0x63fd9004), .val = cpu_to_be32(0x00030012), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008010), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008020), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008020), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0a528030), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x03868031), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00068031), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008032), },
+ { .addr = cpu_to_be32(0x63fd9020), .val = cpu_to_be32(0x00005800), },
+ { .addr = cpu_to_be32(0x63fd9058), .val = cpu_to_be32(0x00033332), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00448031), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008018), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x63fd9040), .val = cpu_to_be32(0x04b80003), },
+ { .addr = cpu_to_be32(0x53fa8004), .val = cpu_to_be32(0x00194005), },
+ { .addr = cpu_to_be32(0x53fa819c), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81a0), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81a4), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81a8), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81ac), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81b0), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81b4), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81b8), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81dc), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa81e0), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa8228), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa822c), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa8230), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa8234), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa8238), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa84ec), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa84f0), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa84f4), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa84f8), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa84fc), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa8500), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa8504), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa8508), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa852c), .val = cpu_to_be32(0x00000004), },
+ { .addr = cpu_to_be32(0x53fa8530), .val = cpu_to_be32(0x00000004), },
+ { .addr = cpu_to_be32(0x53fa85a0), .val = cpu_to_be32(0x00000004), },
+ { .addr = cpu_to_be32(0x53fa85a4), .val = cpu_to_be32(0x00000004), },
+ { .addr = cpu_to_be32(0x53fa85a8), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa85ac), .val = cpu_to_be32(0x000000e4), },
+ { .addr = cpu_to_be32(0x53fa85b0), .val = cpu_to_be32(0x00000004), },
+};
+
+#define APP_DEST 0x70000000
+
+struct imx_flash_header_v2 __flash_header_section flash_header = {
+ .header.tag = IVT_HEADER_TAG,
+ .header.length = cpu_to_be16(32),
+ .header.version = IVT_VERSION,
+
+ .entry = APP_DEST + 0x1000,
+ .dcd_ptr = APP_DEST + 0x400 + offsetof(struct imx_flash_header_v2, dcd),
+ .boot_data_ptr = APP_DEST + 0x400 + offsetof(struct imx_flash_header_v2, boot_data),
+ .self = APP_DEST + 0x400,
+
+ .boot_data.start = APP_DEST,
+ .boot_data.size = DCD_BAREBOX_SIZE,
+
+ .dcd.header.tag = DCD_HEADER_TAG,
+ .dcd.header.length = cpu_to_be16(sizeof(struct imx_dcd) + sizeof(dcd_entry)),
+ .dcd.header.version = DCD_VERSION,
+
+ .dcd.command.tag = DCD_COMMAND_WRITE_TAG,
+ .dcd.command.length = cpu_to_be16(sizeof(struct imx_dcd_command) + sizeof(dcd_entry)),
+ .dcd.command.param = DCD_COMMAND_WRITE_PARAM,
+};
diff --git a/arch/arm/boards/panda/env/config b/arch/arm/boards/panda/env/config
index 29a63f333b..1cd7eaa352 100644
--- a/arch/arm/boards/panda/env/config
+++ b/arch/arm/boards/panda/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=panda
+global.hostname=panda
user=
# use 'dhcp' to do dhcp in barebox and in kernel
@@ -18,14 +18,14 @@ kernel_loc=tftp
# can be either 'net', 'nor', 'nand' or 'initrd'
rootfs_loc=net
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-${hostname}.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/pcm027/env/config b/arch/arm/boards/pcm027/env/config
index 3ed963c67b..ec2752a65d 100644
--- a/arch/arm/boards/pcm027/env/config
+++ b/arch/arm/boards/pcm027/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=pcm027
+global.hostname=pcm027
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/pcm037/env/config b/arch/arm/boards/pcm037/env/config
index fcdb77764c..569bfe4b68 100644
--- a/arch/arm/boards/pcm037/env/config
+++ b/arch/arm/boards/pcm037/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=pcm037
+global.hostname=pcm037
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/pcm043/env/config b/arch/arm/boards/pcm043/env/config
index 644c7fb839..491305352e 100644
--- a/arch/arm/boards/pcm043/env/config
+++ b/arch/arm/boards/pcm043/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=pcm043
+global.hostname=pcm043
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/pcm049/env/bin/nand_bootstrap b/arch/arm/boards/pcm049/env/bin/nand_bootstrap
index f8873fabe2..49e38dc4f0 100644
--- a/arch/arm/boards/pcm049/env/bin/nand_bootstrap
+++ b/arch/arm/boards/pcm049/env/bin/nand_bootstrap
@@ -1,4 +1,4 @@
-
+#!/bin/sh
echo "copying barebox to nand..."
mci0.probe=1
diff --git a/arch/arm/boards/pcm049/env/config b/arch/arm/boards/pcm049/env/config
index 70e374f5ae..0ae3e1bc3c 100644
--- a/arch/arm/boards/pcm049/env/config
+++ b/arch/arm/boards/pcm049/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=pcm049
+global.hostname=pcm049
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-${hostname}.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-${hostname}.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/phycard-a-l1/env/config b/arch/arm/boards/phycard-a-l1/env/config
index 5bc48d7a8a..6de97ed5d5 100644
--- a/arch/arm/boards/phycard-a-l1/env/config
+++ b/arch/arm/boards/phycard-a-l1/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=pcaal1
+global.hostname=pcaal1
#user=
# Enter MAC address here if not retrieved automatically
@@ -26,26 +26,26 @@ rootfs_loc=nand
rootfs_type=jffs2
# where is the rootfs in case of 'rootfs_loc=disk' (linux name)
rootfs_part_linux_dev=mmcblk0p4
-rootfsimage=rootfs-${hostname}.$rootfs_type
+rootfsimage=rootfs-${global.hostname}.$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=zImage-$hostname
-kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+#kernelimage=zImage-${global.hostname}
+kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
-bareboximage=barebox-${hostname}.bin
-bareboxenvimage=barebox-${hostname}.bin
+bareboximage=barebox-${global.hostname}.bin
+bareboxenvimage=barebox-${global.hostname}.bin
if [ -n $user ]; then
bareboximage="$user"-"$bareboximage"
bareboxenvimage="$user"-"$bareboxenvimage"
kernelimage="$user"-"$kernelimage"
rootfsimage="$user"-"$rootfsimage"
- nfsroot="/home/$user/nfsroot/$hostname"
+ nfsroot="/home/$user/nfsroot/${global.hostname}"
else
nfsroot="/path/to/nfs/root"
fi
diff --git a/arch/arm/boards/phycard-a-xl2/env/config b/arch/arm/boards/phycard-a-xl2/env/config
index 44a4181355..349a51fb43 100644
--- a/arch/arm/boards/phycard-a-xl2/env/config
+++ b/arch/arm/boards/phycard-a-xl2/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=pcaaxl2
+global.hostname=pcaaxl2
user=
# use 'dhcp' to do dhcp in barebox and in kernel
@@ -20,16 +20,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-${hostname}.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-${hostname}.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/phycard-i.MX27/env/config b/arch/arm/boards/phycard-i.MX27/env/config
index 367029bee5..5f77440196 100644
--- a/arch/arm/boards/phycard-i.MX27/env/config
+++ b/arch/arm/boards/phycard-i.MX27/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=pca100
+global.hostname=pca100
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/phycard-i.MX27/lowlevel_init.S b/arch/arm/boards/phycard-i.MX27/lowlevel_init.S
index c24edd49da..f98364267d 100644
--- a/arch/arm/boards/phycard-i.MX27/lowlevel_init.S
+++ b/arch/arm/boards/phycard-i.MX27/lowlevel_init.S
@@ -116,7 +116,10 @@ copy_loop:
ldr pc, =1f /* Jump to SDRAM */
1:
- b nand_boot /* Load barebox from NAND Flash */
+ ldr r0,=_text
+ ldr r1,=_barebox_image_size
+ bl imx_nand_load_image
+ b board_init_lowlevel_return
#endif /* CONFIG_NAND_IMX_BOOT */
diff --git a/arch/arm/boards/phycard-i.MX27/pca100.c b/arch/arm/boards/phycard-i.MX27/pca100.c
index 614bfc65eb..53eec8f6b6 100644
--- a/arch/arm/boards/phycard-i.MX27/pca100.c
+++ b/arch/arm/boards/phycard-i.MX27/pca100.c
@@ -324,11 +324,3 @@ static int pca100_console_init(void)
}
console_initcall(pca100_console_init);
-
-#ifdef CONFIG_NAND_IMX_BOOT
-void __bare_init nand_boot(void)
-{
- imx_nand_load_image(_text, barebox_image_size);
-}
-#endif
-
diff --git a/arch/arm/boards/qil-a9260/env/config b/arch/arm/boards/qil-a9260/env/config
index c0b554625c..99711062f8 100644
--- a/arch/arm/boards/qil-a9260/env/config
+++ b/arch/arm/boards/qil-a9260/env/config
@@ -3,7 +3,7 @@
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp-barebox
-dhcp_vendor_id=barebox-qil-a9260
+global.dhcp.vendor_id=barebox-qil-a9260
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
diff --git a/arch/arm/boards/scb9328/env/config b/arch/arm/boards/scb9328/env/config
index a8eace7b24..ce6310b67d 100644
--- a/arch/arm/boards/scb9328/env/config
+++ b/arch/arm/boards/scb9328/env/config
@@ -1,6 +1,6 @@
#!/bin/sh
-hostname=scb9328
+global.hostname=scb9328
eth0.serverip=
user=
@@ -21,16 +21,16 @@ rootfs_loc=net
# can be either 'jffs2' or 'ubifs'
rootfs_type=ubifs
-rootfsimage=root-$hostname.$rootfs_type
+rootfsimage=root-${global.hostname}.$rootfs_type
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
if [ -n $user ]; then
kernelimage="$user"-"$kernelimage"
- nfsroot="$eth0.serverip:/home/$user/nfsroot/$hostname"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/${global.hostname}"
rootfsimage="$user"-"$rootfsimage"
else
nfsroot="$eth0.serverip:/path/to/nfs/root"
diff --git a/arch/arm/boards/tny-a926x/env/config b/arch/arm/boards/tny-a926x/env/config
index 514fc9f142..c19ec4fd61 100644
--- a/arch/arm/boards/tny-a926x/env/config
+++ b/arch/arm/boards/tny-a926x/env/config
@@ -3,9 +3,9 @@
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp-barebox
-[ x$armlinux_architecture = x2058 ] && dhcp_vendor_id=barebox-tny-a9260
-[ x$armlinux_architecture = x2059 ] && dhcp_vendor_id=barebox-tny-a9g20
-[ x$armlinux_architecture = x2140 ] && dhcp_vendor_id=barebox-tny-a9263
+[ x$armlinux_architecture = x2058 ] && global.dhcp.vendor_id=barebox-tny-a9260
+[ x$armlinux_architecture = x2059 ] && global.dhcp.vendor_id=barebox-tny-a9g20
+[ x$armlinux_architecture = x2140 ] && global.dhcp.vendor_id=barebox-tny-a9263
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
diff --git a/arch/arm/boards/usb-a926x/env/config b/arch/arm/boards/usb-a926x/env/config
index dc0a264056..49199ba391 100644
--- a/arch/arm/boards/usb-a926x/env/config
+++ b/arch/arm/boards/usb-a926x/env/config
@@ -3,9 +3,9 @@
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp-barebox
-[ x$armlinux_architecture = x1709 ] && dhcp_vendor_id=barebox-usb-a9260
-[ x$armlinux_architecture = x1710 ] && dhcp_vendor_id=barebox-usb-a9263
-[ x$armlinux_architecture = x1841 ] && dhcp_vendor_id=barebox-usb-a9g20
+[ x$armlinux_architecture = x1709 ] && global.dhcp.vendor_id=barebox-usb-a9260
+[ x$armlinux_architecture = x1710 ] && global.dhcp.vendor_id=barebox-usb-a9263
+[ x$armlinux_architecture = x1841 ] && global.dhcp.vendor_id=barebox-usb-a9g20
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
diff --git a/arch/arm/configs/freescale_mx51_babbage_defconfig b/arch/arm/configs/freescale_mx51_babbage_defconfig
index 22ef163a4b..0817cfa957 100644
--- a/arch/arm/configs/freescale_mx51_babbage_defconfig
+++ b/arch/arm/configs/freescale_mx51_babbage_defconfig
@@ -17,6 +17,7 @@ CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED_LZO=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/freescale-mx51-pdk/env/"
CONFIG_CMD_EDIT=y
CONFIG_CMD_SLEEP=y
@@ -39,7 +40,6 @@ CONFIG_CMD_BOOTM_INITRD=y
CONFIG_CMD_BOOTM_OFTREE=y
CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
CONFIG_CMD_UIMAGE=y
-# CONFIG_CMD_BOOTZ is not set
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
diff --git a/arch/arm/configs/imx233-olinuxino_defconfig b/arch/arm/configs/imx233-olinuxino_defconfig
new file mode 100644
index 0000000000..40b7e1df2e
--- /dev/null
+++ b/arch/arm/configs/imx233-olinuxino_defconfig
@@ -0,0 +1,63 @@
+CONFIG_ARCH_MXS=y
+CONFIG_MACH_IMX233_OLINUXINO=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_BROKEN=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_MODULES=y
+CONFIG_LONGHELP=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/imx233-olinuxino/env"
+CONFIG_BAREBOXENV_TARGET=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_FLASH_NOISE=y
+CONFIG_ENABLE_PARTITION_NOISE=y
+CONFIG_ENABLE_DEVICE_NOISE=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=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_NET_USB=y
+CONFIG_NET_USB_SMSC95XX=y
+CONFIG_DISK_INTF_PLATFORM_IDE=y
+CONFIG_USB=y
+CONFIG_USB_EHCI=y
+CONFIG_USB_STORAGE=y
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_STM=y
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_MXS=y
+CONFIG_LED=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_MXS_APBH_DMA=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_FS_FAT=y
diff --git a/arch/arm/configs/phycard_a_l1_defconfig b/arch/arm/configs/phycard_a_l1_defconfig
index cf980f7ffb..4cf2d210c9 100644
--- a/arch/arm/configs/phycard_a_l1_defconfig
+++ b/arch/arm/configs/phycard_a_l1_defconfig
@@ -134,7 +134,7 @@ CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
CONFIG_DRIVER_SERIAL_NS16550=y
CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS=y
-CONFIG_MIIDEV=y
+CONFIG_PHYLIB=y
CONFIG_DRIVER_NET_SMC911X=y
CONFIG_DRIVER_NET_SMC911X_ADDRESS_SHIFT=0
CONFIG_SPI=n
diff --git a/arch/arm/configs/tx51stk5_defconfig b/arch/arm/configs/tx51stk5_defconfig
index 7fff0f0d10..2c831890c7 100644
--- a/arch/arm/configs/tx51stk5_defconfig
+++ b/arch/arm/configs/tx51stk5_defconfig
@@ -110,7 +110,7 @@ CONFIG_NET_TFTP=y
CONFIG_NET_TFTP_PUSH=y
CONFIG_DRIVER_SERIAL_IMX=y
CONFIG_ARCH_HAS_FEC_IMX=y
-CONFIG_MIIDEV=y
+CONFIG_PHYLIB=y
CONFIG_DRIVER_NET_FEC_IMX=y
CONFIG_DRIVER_SPI_IMX_2_3=y
CONFIG_MTD=y
diff --git a/arch/arm/configs/tx53stk5_defconfig b/arch/arm/configs/tx53stk5_defconfig
new file mode 100644
index 0000000000..95cf460b47
--- /dev/null
+++ b/arch/arm/configs/tx53stk5_defconfig
@@ -0,0 +1,76 @@
+CONFIG_ARCH_IMX=y
+CONFIG_ARCH_IMX53=y
+CONFIG_MACH_TX53=y
+CONFIG_IMX_IIM=y
+CONFIG_AEABI=y
+CONFIG_THUMB2_BAREBOX=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_ARM_UNWIND=y
+CONFIG_MMU=y
+CONFIG_TEXT_BASE=0x97f00000
+CONFIG_MALLOC_SIZE=0x2000000
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_LONGHELP=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED_LZO=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/karo-tx53/env"
+CONFIG_RESET_SOURCE=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_MSLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_DIRNAME=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_LED=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+CONFIG_MTD=y
+CONFIG_NAND=y
+CONFIG_NAND_IMX=y
+CONFIG_UBI=y
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_IMX_ESDHC=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_FS_FAT=y
+CONFIG_ZLIB=y
+CONFIG_LZO_DECOMPRESS=y
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index dad8092e9f..e3ca722300 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -144,7 +144,7 @@ static int arm_mmu_remap_sdram(struct memory_bank *bank)
if ((phys & (SZ_1M - 1)) || (bank->size & (SZ_1M - 1)))
return -EINVAL;
- ptes = memalign(PAGE_SIZE, num_ptes * sizeof(u32));
+ ptes = xmemalign(PAGE_SIZE, num_ptes * sizeof(u32));
debug("ptes: 0x%p ttb_start: 0x%08lx ttb_end: 0x%08lx\n",
ptes, ttb_start, ttb_end);
diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c
index 932a3da9e2..04b54304e1 100644
--- a/arch/arm/cpu/start-pbl.c
+++ b/arch/arm/cpu/start-pbl.c
@@ -36,6 +36,9 @@
unsigned long free_mem_ptr;
unsigned long free_mem_end_ptr;
+/*
+ * First instructions in the pbl image
+ */
void __naked __section(.text_head_entry) pbl_start(void)
{
barebox_arm_head();
@@ -116,7 +119,11 @@ static void mmu_disable(void)
static void barebox_uncompress(void *compressed_start, unsigned int len)
{
void (*barebox)(void);
- int use_mmu = IS_ENABLED(CONFIG_MMU);
+ /*
+ * remap_cached currently does not work rendering the feature
+ * of enabling the MMU in the PBL useless. disable for now.
+ */
+ int use_mmu = 0;
/* set 128 KiB at the end of the MALLOC_BASE for early malloc */
free_mem_ptr = MALLOC_BASE + MALLOC_SIZE - SZ_128K;
@@ -149,23 +156,17 @@ static void barebox_uncompress(void *compressed_start, unsigned int len)
* Board code can jump here by either returning from board_init_lowlevel
* or by calling this function directly.
*/
-void __naked __section(.text_ll_return) board_init_lowlevel_return(void)
+void __naked board_init_lowlevel_return(void)
{
- uint32_t r, addr, offset;
+ uint32_t r, offset;
uint32_t pg_start, pg_end, pg_len;
- /*
- * Get runtime address of this function. Do not
- * put any code above this.
- */
- __asm__ __volatile__("1: adr %0, 1b":"=r"(addr));
-
/* Setup the stack */
r = STACK_BASE + STACK_SIZE - 16;
__asm__ __volatile__("mov sp, %0" : : "r"(r));
/* Get offset between linked address and runtime address */
- offset = (uint32_t)__ll_return - addr;
+ offset = get_runtime_offset();
pg_start = (uint32_t)&input_data - offset;
pg_end = (uint32_t)&input_data_end - offset;
diff --git a/arch/arm/cpu/start-reset.c b/arch/arm/cpu/start-reset.c
index e0df676274..fcfdce6bff 100644
--- a/arch/arm/cpu/start-reset.c
+++ b/arch/arm/cpu/start-reset.c
@@ -29,6 +29,9 @@
/*
* The actual reset vector. This code is position independent and usually
* does not run at the address it's linked at.
+ *
+ * This is either executed in the pbl image (if enabled) or in the regular
+ * image.
*/
void __naked __bare_init reset(void)
{
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 07e7dfe822..1c6a7ddfcc 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -30,7 +30,7 @@
#ifdef CONFIG_PBL_IMAGE
/*
- * First function in the pbl image. We get here from
+ * First function in the uncompressed image. We get here from
* the pbl.
*/
void __naked __section(.text_entry) start(void)
@@ -47,6 +47,9 @@ void __naked __section(.text_entry) start(void)
}
#else
+/*
+ * First function in the image without pbl support
+ */
void __naked __section(.text_entry) start(void)
{
barebox_arm_head();
@@ -56,22 +59,16 @@ void __naked __section(.text_entry) start(void)
* Board code can jump here by either returning from board_init_lowlevel
* or by calling this function directly.
*/
-void __naked __section(.text_ll_return) board_init_lowlevel_return(void)
+void __naked board_init_lowlevel_return(void)
{
- uint32_t r, addr, offset;
-
- /*
- * Get runtime address of this function. Do not
- * put any code above this.
- */
- __asm__ __volatile__("1: adr %0, 1b":"=r"(addr));
+ uint32_t r, offset;
/* Setup the stack */
r = STACK_BASE + STACK_SIZE - 16;
__asm__ __volatile__("mov sp, %0" : : "r"(r));
/* Get offset between linked address and runtime address */
- offset = (uint32_t)__ll_return - addr;
+ offset = get_runtime_offset();
/* relocate to link address if necessary */
if (offset)
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index b880dd49b3..a71f420ed5 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -37,10 +37,10 @@ int board_init(void);
int dram_init (void);
extern char __exceptions_start[], __exceptions_stop[];
-extern char __ll_return[];
void board_init_lowlevel(void);
void board_init_lowlevel_return(void);
void arch_init_lowlevel(void);
+uint32_t get_runtime_offset(void);
#endif /* _BAREBOX_ARM_H_ */
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 9d0ff7a856..2e624cdf84 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -16,6 +16,8 @@ obj-y += lib1funcs.o
obj-y += ashrdi3.o
obj-y += ashldi3.o
obj-y += lshrdi3.o
+obj-y += runtime-offset.o
+pbl-y += runtime-offset.o
obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o
obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index 9f9dea8754..74d59a9c0b 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -80,7 +80,7 @@ void armlinux_set_revision(unsigned int rev)
#ifdef CONFIG_ENVIRONMENT_VARIABLES
export_env_ull("armlinux_system_rev", rev);
#else
- return armlinux_system_rev;
+ armlinux_system_rev = rev;
#endif
}
@@ -264,6 +264,7 @@ void start_linux(void *adr, int swap, unsigned long initrd_address,
setup_tags(initrd_address, initrd_size, swap);
params = armlinux_bootparams;
}
+ architecture = armlinux_get_architecture();
shutdown_barebox();
if (swap) {
@@ -273,8 +274,6 @@ void start_linux(void *adr, int swap, unsigned long initrd_address,
__asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg));
}
- architecture = armlinux_get_architecture();
-
#ifdef CONFIG_THUMB2_BAREBOX
__asm__ __volatile__ (
"mov r0, #0\n"
diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
index a69013f7f5..40af705730 100644
--- a/arch/arm/lib/barebox.lds.S
+++ b/arch/arm/lib/barebox.lds.S
@@ -40,8 +40,6 @@ SECTIONS
_stext = .;
_text = .;
*(.text_entry*)
- __ll_return = .;
- *(.text_ll_return*)
__bare_init_start = .;
*(.text_bare_init*)
__bare_init_end = .;
diff --git a/arch/arm/lib/runtime-offset.S b/arch/arm/lib/runtime-offset.S
new file mode 100644
index 0000000000..ffa668cd7e
--- /dev/null
+++ b/arch/arm/lib/runtime-offset.S
@@ -0,0 +1,17 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Get the offset between the link address and the address
+ * we are currently running at.
+ */
+ENTRY(get_runtime_offset)
+1: adr r0, 1b
+ ldr r1, linkadr
+ subs r0, r1, r0
+THUMB( subs r0, r0, #1)
+ mov pc, lr
+
+linkadr:
+.word get_runtime_offset
+ENDPROC(get_runtime_offset)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index ce5edaa336..7ab812abc5 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -27,6 +27,7 @@ config ARCH_TEXT_BASE
default 0x4fc00000 if MACH_MX6Q_ARM2
default 0x97f00000 if MACH_CCMX51
default 0x4fc00000 if MACH_SABRELITE
+ default 0x7fe00000 if MACH_TX53
config BOARDINFO
default "Eukrea CPUIMX25" if MACH_EUKREA_CPUIMX25
@@ -53,6 +54,7 @@ config BOARDINFO
default "Freescale i.MX6q armadillo2" if MACH_MX6Q_ARM2
default "ConnectCore i.MX51" if MACH_CCMX51
default "Sabre Lite" if MACH_SABRELITE
+ default "Ka-Ro tx53" if MACH_TX53
choice
prompt "Select boot mode"
@@ -459,6 +461,12 @@ config MACH_TQMA53_1GB_RAM
help
use 1GiB of SDRAM (512MiB otherwise)
+config MACH_TX53
+ bool "Ka-Ro TX53"
+ select HAVE_DEFAULT_ENVIRONMENT_NEW
+ help
+ Say Y here if you are using the Ka-Ro tx53 board
+
endchoice
endif
diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
index 4e77ece7f3..c725f8c23a 100644
--- a/arch/arm/mach-imx/clocksource.c
+++ b/arch/arm/mach-imx/clocksource.c
@@ -32,17 +32,45 @@
#include <common.h>
#include <init.h>
#include <clock.h>
+#include <errno.h>
#include <notifier.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
#include <io.h>
-#define GPT(x) __REG(IMX_TIM1_BASE + (x))
-#define timer_base IOMEM(IMX_TIM1_BASE)
+/* Part 1: Registers */
+# define GPT_TCTL 0x00
+# define GPT_TPRER 0x04
+
+/* Part 2: Bitfields */
+#define TCTL_SWR (1 << 15) /* Software reset */
+#define IMX1_TCTL_FRR (1 << 8) /* Freerun / restart */
+#define IMX31_TCTL_FRR (1 << 9) /* Freerun / restart */
+#define IMX1_TCTL_CLKSOURCE_IPG (1 << 1) /* Clock source bit position */
+#define IMX31_TCTL_CLKSOURCE_IPG (1 << 6) /* Clock source bit position */
+#define TCTL_TEN (1 << 0) /* Timer enable */
+
+struct imx_gpt_regs {
+ unsigned int tcn;
+ uint32_t tctl_val;
+};
+
+static struct imx_gpt_regs regs_imx1 = {
+ .tcn = 0x10,
+ .tctl_val = IMX1_TCTL_FRR | IMX1_TCTL_CLKSOURCE_IPG | TCTL_TEN,
+};
+
+static struct imx_gpt_regs regs_imx31 = {
+ .tcn = 0x24,
+ .tctl_val = IMX31_TCTL_FRR | IMX31_TCTL_CLKSOURCE_IPG | TCTL_TEN,
+};
+
+static struct imx_gpt_regs *regs;
+static void __iomem *timer_base;
static uint64_t imx_clocksource_read(void)
{
- return readl(timer_base + GPT_TCN);
+ return readl(timer_base + regs->tcn);
}
static struct clocksource cs = {
@@ -61,10 +89,20 @@ static struct notifier_block imx_clock_notifier = {
.notifier_call = imx_clocksource_clock_change,
};
-static int clocksource_init (void)
+static int imx_gpt_probe(struct device_d *dev)
{
int i;
- uint32_t val;
+ int ret;
+
+ /* one timer is enough */
+ if (timer_base)
+ return -EBUSY;
+
+ ret = dev_get_drvdata(dev, (unsigned long *)&regs);
+ if (ret)
+ return ret;
+
+ timer_base = dev_request_mem_region(dev, 0);
/* setup GP Timer 1 */
writel(TCTL_SWR, timer_base + GPT_TCTL);
@@ -85,9 +123,7 @@ static int clocksource_init (void)
writel(0, timer_base + GPT_TCTL); /* We have no udelay by now */
writel(0, timer_base + GPT_TPRER);
- val = readl(timer_base + GPT_TCTL);
- val |= TCTL_FRR | (1 << TCTL_CLKSOURCE) | TCTL_TEN; /* Freerun Mode, PERCLK1 input */
- writel(val, timer_base + GPT_TCTL);
+ writel(regs->tctl_val, timer_base + GPT_TCTL);
cs.mult = clocksource_hz2mult(imx_get_gptclk(), cs.shift);
@@ -98,7 +134,42 @@ static int clocksource_init (void)
return 0;
}
-core_initcall(clocksource_init);
+static __maybe_unused struct of_device_id imx_gpt_dt_ids[] = {
+ {
+ .compatible = "fsl,imx1-gpt",
+ .data = (unsigned long)&regs_imx1,
+ }, {
+ .compatible = "fsl,imx31-gpt",
+ .data = (unsigned long)&regs_imx31,
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct platform_device_id imx_gpt_ids[] = {
+ {
+ .name = "imx1-gpt",
+ .driver_data = (unsigned long)&regs_imx1,
+ }, {
+ .name = "imx31-gpt",
+ .driver_data = (unsigned long)&regs_imx31,
+ }, {
+ /* sentinel */
+ },
+};
+
+static struct driver_d imx_gpt_driver = {
+ .name = "imx-gpt",
+ .probe = imx_gpt_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_gpt_dt_ids),
+ .id_table = imx_gpt_ids,
+};
+
+static int imx_gpt_init(void)
+{
+ return register_driver(&imx_gpt_driver);
+}
+coredevice_initcall(imx_gpt_init);
/*
* Watchdog Registers
diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c
index 8d5d4ce2b0..e78a36e219 100644
--- a/arch/arm/mach-imx/gpio.c
+++ b/arch/arm/mach-imx/gpio.c
@@ -30,28 +30,28 @@
#include <gpio.h>
#include <init.h>
-#if defined CONFIG_ARCH_IMX1 || defined CONFIG_ARCH_IMX21 || defined CONFIG_ARCH_IMX27
-#define GPIO_DR 0x1c
-#define GPIO_GDIR 0x00
-#define GPIO_PSR 0x24
-#define GPIO_ICR1 0x28
-#define GPIO_ICR2 0x2C
-#define GPIO_IMR 0x30
-#define GPIO_ISR 0x34
-#else
-#define GPIO_DR 0x00
-#define GPIO_GDIR 0x04
-#define GPIO_PSR 0x08
-#define GPIO_ICR1 0x0C
-#define GPIO_ICR2 0x10
-#define GPIO_IMR 0x14
-#define GPIO_ISR 0x18
-#define GPIO_ISR 0x18
-#endif
-
struct imx_gpio_chip {
void __iomem *base;
struct gpio_chip chip;
+ struct imx_gpio_regs *regs;
+};
+
+struct imx_gpio_regs {
+ unsigned int dr;
+ unsigned int gdir;
+ unsigned int psr;
+};
+
+static struct imx_gpio_regs regs_imx1 = {
+ .dr = 0x1c,
+ .gdir = 0x00,
+ .psr = 0x24,
+};
+
+static struct imx_gpio_regs regs_imx31 = {
+ .dr = 0x00,
+ .gdir = 0x04,
+ .psr = 0x08,
};
static void imx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
@@ -63,14 +63,14 @@ static void imx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
if (!base)
return;
- val = readl(base + GPIO_DR);
+ val = readl(base + imxgpio->regs->dr);
if (value)
val |= 1 << gpio;
else
val &= ~(1 << gpio);
- writel(val, base + GPIO_DR);
+ writel(val, base + imxgpio->regs->dr);
}
static int imx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
@@ -82,9 +82,9 @@ static int imx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
if (!base)
return -EINVAL;
- val = readl(base + GPIO_GDIR);
+ val = readl(base + imxgpio->regs->gdir);
val &= ~(1 << gpio);
- writel(val, base + GPIO_GDIR);
+ writel(val, base + imxgpio->regs->gdir);
return 0;
}
@@ -98,9 +98,9 @@ static int imx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int
gpio_set_value(gpio + chip->base, value);
- val = readl(base + GPIO_GDIR);
+ val = readl(base + imxgpio->regs->gdir);
val |= 1 << gpio;
- writel(val, base + GPIO_GDIR);
+ writel(val, base + imxgpio->regs->gdir);
return 0;
}
@@ -111,7 +111,7 @@ static int imx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
void __iomem *base = imxgpio->base;
u32 val;
- val = readl(base + GPIO_PSR);
+ val = readl(base + imxgpio->regs->psr);
return val & (1 << gpio) ? 1 : 0;
}
@@ -126,23 +126,80 @@ static struct gpio_ops imx_gpio_ops = {
static int imx_gpio_probe(struct device_d *dev)
{
struct imx_gpio_chip *imxgpio;
+ struct imx_gpio_regs *regs;
+ int ret;
+
+ ret = dev_get_drvdata(dev, (unsigned long *)&regs);
+ if (ret)
+ return ret;
imxgpio = xzalloc(sizeof(*imxgpio));
imxgpio->base = dev_request_mem_region(dev, 0);
imxgpio->chip.ops = &imx_gpio_ops;
- imxgpio->chip.base = -1;
+ if (dev->id < 0) {
+ imxgpio->chip.base = of_alias_get_id(dev->device_node, "gpio");
+ if (imxgpio->chip.base < 0)
+ return imxgpio->chip.base;
+ } else {
+ imxgpio->chip.base = dev->id * 32;
+ }
imxgpio->chip.ngpio = 32;
imxgpio->chip.dev = dev;
+ imxgpio->regs = regs;
gpiochip_add(&imxgpio->chip);
- dev_info(dev, "probed gpiochip%d with base %d\n", dev->id, imxgpio->chip.base);
+ dev_dbg(dev, "probed gpiochip%d with base %d\n", dev->id, imxgpio->chip.base);
return 0;
}
+static __maybe_unused struct of_device_id imx_gpio_dt_ids[] = {
+ {
+ .compatible = "fsl,imx1-gpio",
+ .data = (unsigned long)&regs_imx1,
+ }, {
+ .compatible = "fsl,imx21-gpio",
+ .data = (unsigned long)&regs_imx1,
+ }, {
+ .compatible = "fsl,imx27-gpio",
+ .data = (unsigned long)&regs_imx1,
+ }, {
+ .compatible = "fsl,imx31-gpio",
+ .data = (unsigned long)&regs_imx31,
+ }, {
+ .compatible = "fsl,imx35-gpio",
+ .data = (unsigned long)&regs_imx31,
+ }, {
+ .compatible = "fsl,imx51-gpio",
+ .data = (unsigned long)&regs_imx31,
+ }, {
+ .compatible = "fsl,imx53-gpio",
+ .data = (unsigned long)&regs_imx31,
+ }, {
+ .compatible = "fsl,imx6q-gpio",
+ .data = (unsigned long)&regs_imx31,
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct platform_device_id imx_gpio_ids[] = {
+ {
+ .name = "imx1-gpio",
+ .driver_data = (unsigned long)&regs_imx1,
+ }, {
+ .name = "imx31-gpio",
+ .driver_data = (unsigned long)&regs_imx31,
+ }, {
+ /* sentinel */
+ },
+};
+
static struct driver_d imx_gpio_driver = {
.name = "imx-gpio",
.probe = imx_gpio_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_gpio_dt_ids),
+ .id_table = imx_gpio_ids,
};
static int imx_gpio_add(void)
diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c
index 5a000bc96a..5dd71f50a3 100644
--- a/arch/arm/mach-imx/imx1.c
+++ b/arch/arm/mach-imx/imx1.c
@@ -20,10 +20,11 @@
static int imx1_init(void)
{
- add_generic_device("imx-gpio", 0, NULL, 0x0021c000, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x0021c100, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x0021c200, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x0021c300, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpt", 0, NULL, 0x00202000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 0, NULL, 0x0021c000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 1, NULL, 0x0021c100, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 2, NULL, 0x0021c200, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 3, NULL, 0x0021c300, 0x100, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c
index 85590ee8f4..4973491f43 100644
--- a/arch/arm/mach-imx/imx21.c
+++ b/arch/arm/mach-imx/imx21.c
@@ -16,6 +16,7 @@
*/
#include <common.h>
+#include <init.h>
#include <mach/imx-regs.h>
int imx_silicon_revision(void)
@@ -28,12 +29,13 @@ int imx_silicon_revision(void)
static int imx21_init(void)
{
- add_generic_device("imx-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpt", 0, NULL, 0x10003000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c
index d605022516..397ddde253 100644
--- a/arch/arm/mach-imx/imx25.c
+++ b/arch/arm/mach-imx/imx25.c
@@ -48,10 +48,12 @@ static int imx25_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, &imx25_iim_pdata);
- add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x53f9c000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 3, NULL, 0x53f9c000, 0x1000, IORESOURCE_MEM, NULL);
+
return 0;
}
coredevice_initcall(imx25_init);
diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c
index c6e6942c58..6c8f3fcd5d 100644
--- a/arch/arm/mach-imx/imx27.c
+++ b/arch/arm/mach-imx/imx27.c
@@ -73,12 +73,13 @@ static int imx27_init(void)
imx27_init_max();
- add_generic_device("imx-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpt", 0, NULL, 0x10003000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 0, NULL, 0x10015000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 1, NULL, 0x10015100, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 2, NULL, 0x10015200, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 3, NULL, 0x10015300, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 4, NULL, 0x10015400, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx1-gpio", 5, NULL, 0x10015500, 0x100, IORESOURCE_MEM, NULL);
return 0;
}
-coredevice_initcall(imx27_init);
+console_initcall(imx27_init);
diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c
index 90dc4e3180..08f9143765 100644
--- a/arch/arm/mach-imx/imx31.c
+++ b/arch/arm/mach-imx/imx31.c
@@ -25,9 +25,10 @@ static int imx31_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c
index efbee985d3..7f49582b5a 100644
--- a/arch/arm/mach-imx/imx35.c
+++ b/arch/arm/mach-imx/imx35.c
@@ -56,9 +56,10 @@ static int imx35_init(void)
add_generic_device("imx_iim", 0, NULL, IMX_IIM_BASE, SZ_4K,
IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x53f90000, 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, 0x53fcc000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, 0x53fd0000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, 0x53fa4000, 0x1000, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index e43cc65ecd..117bda9c0a 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -78,10 +78,11 @@ static int imx51_init(void)
add_generic_device("imx_iim", 0, NULL, MX51_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 0, NULL, 0x73f84000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, 0x73f88000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, 0x73f8c000, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, 0x73f90000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x73fa0000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, 0x73f84000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, 0x73f88000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, 0x73f8c000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 3, NULL, 0x73f90000, 0x1000, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index cb945753b0..9fc44e506c 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -74,13 +74,15 @@ static int imx53_init(void)
add_generic_device("imx_iim", 0, NULL, MX53_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 0, NULL, MX53_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, MX53_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, MX53_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, MX53_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0X53fa0000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, MX53_GPIO1_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, MX53_GPIO2_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, MX53_GPIO3_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 3, NULL, MX53_GPIO4_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 4, NULL, MX53_GPIO5_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 5, NULL, MX53_GPIO6_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 6, NULL, MX53_GPIO7_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
+
return 0;
}
coredevice_initcall(imx53_init);
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index c693724a51..66c44e1391 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -58,13 +58,14 @@ void imx6_init_lowlevel(void)
static int imx6_init(void)
{
- add_generic_device("imx-gpio", 0, NULL, MX6_GPIO1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 1, NULL, MX6_GPIO2_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 2, NULL, MX6_GPIO3_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 3, NULL, MX6_GPIO4_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 4, NULL, MX6_GPIO5_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
- add_generic_device("imx-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpt", 0, NULL, 0x02098000, 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 0, NULL, MX6_GPIO1_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 1, NULL, MX6_GPIO2_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 2, NULL, MX6_GPIO3_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 3, NULL, MX6_GPIO4_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 4, NULL, MX6_GPIO5_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 5, NULL, MX6_GPIO6_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
+ add_generic_device("imx31-gpio", 6, NULL, MX6_GPIO7_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/include/mach/imx1-regs.h b/arch/arm/mach-imx/include/mach/imx1-regs.h
index f940cdb4b2..d5ee3f58a6 100644
--- a/arch/arm/mach-imx/include/mach/imx1-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx1-regs.h
@@ -207,27 +207,4 @@
#define PD31_PF_TMR2OUT ( GPIO_PORTD | GPIO_PF | 31 )
#define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 )
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#endif /* _IMX1_REGS_H */
diff --git a/arch/arm/mach-imx/include/mach/imx21-regs.h b/arch/arm/mach-imx/include/mach/imx21-regs.h
index a2c4d03643..98e73ef27e 100644
--- a/arch/arm/mach-imx/include/mach/imx21-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx21-regs.h
@@ -107,30 +107,6 @@
#define CCSR_32K_SR (1 << 15)
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_CC (1<<10) /* counter clear */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_CAPEN (1<<5) /* compare interrupt enable */
-#define TCTL_COMPEN (1<<4) /* compare interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define IMX_CS0_BASE 0xC8000000
#define IMX_CS1_BASE 0xCC000000
#define IMX_CS2_BASE 0xD0000000
diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h
index 73307c452e..a35d9e3475 100644
--- a/arch/arm/mach-imx/include/mach/imx25-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx25-regs.h
@@ -108,33 +108,6 @@
#define CSCR_A(x) (WEIM_BASE + 8 + (x) * 0x10)
/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX35
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
-/*
* Watchdog Registers
*/
#define WCR __REG16(IMX_WDT_BASE + 0x00) /* Watchdog Control Register */
diff --git a/arch/arm/mach-imx/include/mach/imx27-regs.h b/arch/arm/mach-imx/include/mach/imx27-regs.h
index 19dcad9e9b..8686a9dfc3 100644
--- a/arch/arm/mach-imx/include/mach/imx27-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx27-regs.h
@@ -221,29 +221,6 @@
#define ESDCFG_TWTR (1 << 20)
#define ESDCFG_TXP(x) (((x) & 0x3) << 21)
-/*
- * Definitions for the clocksource driver
- */
-/* Part 1: Registers */
-# define GPT_TCTL 0x00
-# define GPT_TPRER 0x04
-# define GPT_TCMP 0x08
-# define GPT_TCR 0x0c
-# define GPT_TCN 0x10
-# define GPT_TSTAT 0x14
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<8) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (1) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define IMX_CS0_BASE 0xC0000000
#define IMX_CS1_BASE 0xC8000000
#define IMX_CS2_BASE 0xD0000000
diff --git a/arch/arm/mach-imx/include/mach/imx31-regs.h b/arch/arm/mach-imx/include/mach/imx31-regs.h
index 536bf0dad4..062af751c8 100644
--- a/arch/arm/mach-imx/include/mach/imx31-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx31-regs.h
@@ -57,33 +57,6 @@
#define IMX_CS5_BASE 0xB6000000
#define IMX_CS5_RANGE (32 * 1024 * 1024)
-/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX31
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#if 0
#define IMX_IO_BASE 0x00200000
diff --git a/arch/arm/mach-imx/include/mach/imx35-regs.h b/arch/arm/mach-imx/include/mach/imx35-regs.h
index 91d4b9bf52..5f000521f4 100644
--- a/arch/arm/mach-imx/include/mach/imx35-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx35-regs.h
@@ -116,32 +116,4 @@
#define CSCR_L(x) (WEIM_BASE + 4 + (x) * 0x10)
#define CSCR_A(x) (WEIM_BASE + 8 + (x) * 0x10)
-/*
- * Definitions for the clocksource driver
- *
- * These defines are using the i.MX1/27 notation
- * to reuse the clocksource code for these CPUs
- * on the i.MX35
- */
-/* Part 1: Registers */
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#endif /* __ASM_ARCH_MX35_REGS_H */
-
diff --git a/arch/arm/mach-imx/include/mach/imx51-regs.h b/arch/arm/mach-imx/include/mach/imx51-regs.h
index b51aa67c6f..c451004ecc 100644
--- a/arch/arm/mach-imx/include/mach/imx51-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx51-regs.h
@@ -5,13 +5,6 @@
#define IMX_WDT_BASE 0x73f98000
#define IMX_IOMUXC_BASE 0x73fa8000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
/* WEIM registers */
#define WEIM_CSxGCR1(n) (((n) * 0x18) + 0x00)
#define WEIM_CSxGCR2(n) (((n) * 0x18) + 0x04)
@@ -22,18 +15,6 @@
#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 */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX51_IROM_BASE_ADDR 0x0
/*
diff --git a/arch/arm/mach-imx/include/mach/imx53-regs.h b/arch/arm/mach-imx/include/mach/imx53-regs.h
index 8fefc5463e..e57d1abdd0 100644
--- a/arch/arm/mach-imx/include/mach/imx53-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx53-regs.h
@@ -5,25 +5,6 @@
#define IMX_WDT_BASE 0X53F98000
#define IMX_IOMUXC_BASE 0X53FA8000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX53_IROM_BASE_ADDR 0x0
/*
diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h
index c7b7481d0f..eca4fa663a 100644
--- a/arch/arm/mach-imx/include/mach/imx6-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx6-regs.h
@@ -5,25 +5,6 @@
#define IMX_WDT_BASE 0x020bc000
#define IMX_IOMUXC_BASE 0x020e0000
-#define GPT_TCTL 0x00
-#define GPT_TPRER 0x04
-#define GPT_TCMP 0x10
-#define GPT_TCR 0x1c
-#define GPT_TCN 0x24
-#define GPT_TSTAT 0x08
-
-/* Part 2: Bitfields */
-#define TCTL_SWR (1<<15) /* Software reset */
-#define TCTL_FRR (1<<9) /* Freerun / restart */
-#define TCTL_CAP (3<<6) /* Capture Edge */
-#define TCTL_OM (1<<5) /* output mode */
-#define TCTL_IRQEN (1<<4) /* interrupt enable */
-#define TCTL_CLKSOURCE (6) /* Clock source bit position */
-#define TCTL_TEN (1) /* Timer enable */
-#define TPRER_PRES (0xff) /* Prescale */
-#define TSTAT_CAPT (1<<1) /* Capture event */
-#define TSTAT_COMP (1) /* Compare event */
-
#define MX6_AIPS1_ARB_BASE_ADDR 0x02000000
#define MX6_AIPS2_ARB_BASE_ADDR 0x02100000
diff --git a/arch/arm/mach-imx/include/mach/iomux-mx51.h b/arch/arm/mach-imx/include/mach/iomux-mx51.h
index 36c8989d9d..0252d412c6 100644
--- a/arch/arm/mach-imx/include/mach/iomux-mx51.h
+++ b/arch/arm/mach-imx/include/mach/iomux-mx51.h
@@ -649,20 +649,20 @@
#define MX51_PAD_DI2_PIN2__DI2_PIN2 IOMUX_PAD(0x74c, 0x344, 0, __NA_, 0, NO_PAD_CTRL)
#define MX51_PAD_DI2_PIN2__FEC_MDC IOMUX_PAD(0x74c, 0x344, 2, __NA_, 0, MX51_PAD_CTRL_5)
#define MX51_PAD_DI2_PIN3__DI2_PIN3 IOMUX_PAD(0x750, 0x348, 0, __NA_, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_PIN3__FEC_MDIO IOMUX_PAD(0x750, 0x348, 2, 0x954, 1, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN3__FEC_MDIO IOMUX_PAD(0x750, 0x348, 2, 0x954, 1, MX51_PAD_CTRL_5)
#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK IOMUX_PAD(0x754, 0x34c, 0, __NA_, 0, NO_PAD_CTRL)
#define MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 IOMUX_PAD(0x754, 0x34c, 2, 0x95c, 1, NO_PAD_CTRL)
#define MX51_PAD_DI_GP4__DI2_PIN15 IOMUX_PAD(0x758, 0x350, 4, __NA_, 0, NO_PAD_CTRL)
#define MX51_PAD_DI_GP4__DISP1_SER_DIN IOMUX_PAD(0x758, 0x350, 0, 0x9c0, 1, NO_PAD_CTRL)
#define MX51_PAD_DI_GP4__DISP2_PIN1 IOMUX_PAD(0x758, 0x350, 3, __NA_, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP4__FEC_RDATA2 IOMUX_PAD(0x758, 0x350, 2, 0x960, 1, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP4__FEC_RDATA2 IOMUX_PAD(0x758, 0x350, 2, 0x960, 1, MX51_PAD_CTRL_5)
#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 IOMUX_PAD(0x75c, 0x354, 0, __NA_, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT0__FEC_RDATA3 IOMUX_PAD(0x75c, 0x354, 2, 0x964, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT0__FEC_RDATA3 IOMUX_PAD(0x75c, 0x354, 2, 0x964, 1, MX51_PAD_CTRL_5)
#define MX51_PAD_DISP2_DAT0__KEY_COL6 IOMUX_PAD(0x75c, 0x354, 4, 0x9c8, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT0__UART3_RXD IOMUX_PAD(0x75c, 0x354, 5, 0x9f4, 8, MX51_UART_PAD_CTRL)
#define MX51_PAD_DISP2_DAT0__USBH3_CLK IOMUX_PAD(0x75c, 0x354, 3, 0x9f8, 1, MX51_UART_PAD_CTRL)
#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 IOMUX_PAD(0x760, 0x358, 0, __NA_, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT1__FEC_RX_ER IOMUX_PAD(0x760, 0x358, 2, 0x970, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT1__FEC_RX_ER IOMUX_PAD(0x760, 0x358, 2, 0x970, 1, MX51_PAD_CTRL_5)
#define MX51_PAD_DISP2_DAT1__KEY_COL7 IOMUX_PAD(0x760, 0x358, 4, 0x9cc, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT1__UART3_TXD IOMUX_PAD(0x760, 0x358, 5, __NA_, 0, MX51_UART_PAD_CTRL)
#define MX51_PAD_DISP2_DAT1__USBH3_DIR IOMUX_PAD(0x760, 0x358, 3, 0xa1c, 1, NO_PAD_CTRL)
@@ -692,17 +692,17 @@
#define MX51_PAD_DISP2_DAT9__USBH3_DATA1 IOMUX_PAD(0x780, 0x378, 3, 0xa00, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37c, 0, __NA_, 0, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT10__DISP2_SER_CS IOMUX_PAD(0x784, 0x37c, 5, __NA_, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT10__FEC_COL IOMUX_PAD(0x784, 0x37c, 2, 0x94c, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT10__FEC_COL IOMUX_PAD(0x784, 0x37c, 2, 0x94c, 1, MX51_PAD_CTRL_5)
#define MX51_PAD_DISP2_DAT10__KEY_ROW7 IOMUX_PAD(0x784, 0x37c, 4, 0x9dc, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT10__USBH3_DATA2 IOMUX_PAD(0x784, 0x37c, 3, 0xa04, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT11__AUD6_TXD IOMUX_PAD(0x788, 0x380, 4, 0x8f0, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, __NA_, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT11__FEC_RX_CLK IOMUX_PAD(0x788, 0x380, 2, 0x968, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT11__FEC_RX_CLK IOMUX_PAD(0x788, 0x380, 2, 0x968, 1, MX51_PAD_CTRL_5)
#define MX51_PAD_DISP2_DAT11__GPIO1_10 IOMUX_PAD(0x788, 0x380, 7, __NA_, 0, MX51_GPIO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT11__USBH3_DATA3 IOMUX_PAD(0x788, 0x380, 3, 0xa08, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT12__AUD6_RXD IOMUX_PAD(0x78c, 0x384, 4, 0x8ec, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78c, 0x384, 0, __NA_, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT12__FEC_RX_DV IOMUX_PAD(0x78c, 0x384, 2, 0x96c, 1, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT12__FEC_RX_DV IOMUX_PAD(0x78c, 0x384, 2, 0x96c, 1, MX51_PAD_CTRL_5)
#define MX51_PAD_DISP2_DAT12__USBH3_DATA4 IOMUX_PAD(0x78c, 0x384, 3, 0xa0c, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT13__AUD6_TXC IOMUX_PAD(0x790, 0x388, 4, 0x8fc, 1, NO_PAD_CTRL)
#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, __NA_, 0, NO_PAD_CTRL)
diff --git a/arch/arm/mach-imx/include/mach/usb.h b/arch/arm/mach-imx/include/mach/usb.h
index 5d6670d067..9244989118 100644
--- a/arch/arm/mach-imx/include/mach/usb.h
+++ b/arch/arm/mach-imx/include/mach/usb.h
@@ -11,4 +11,7 @@
#define MX35_H1_USBTE_BIT (1 << 4)
#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0)
+int imx6_usb_phy1_disable_oc(void);
+int imx6_usb_phy1_enable(void);
+
#endif /* __MACH_USB_H_*/
diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c
index 680d26088f..5d7a2449a2 100644
--- a/arch/arm/mach-imx/iomux-v3.c
+++ b/arch/arm/mach-imx/iomux-v3.c
@@ -37,6 +37,10 @@ int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
u32 pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
+ debug("%s: mux 0x%08x -> 0x%04x pad: 0x%08x -> 0x%04x sel_inp: 0x%08x -> 0x%04x\n",
+ __func__, mux_mode, mux_ctrl_ofs, pad_ctrl, pad_ctrl_ofs, sel_input,
+ sel_input_ofs);
+
if (mux_ctrl_ofs)
__raw_writel(mux_mode, base + mux_ctrl_ofs);
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 6f324a0af8..ff295f144c 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -4,6 +4,7 @@ config ARCH_TEXT_BASE
hex
default 0x41000000 if MACH_MX23EVK
default 0x42000000 if MACH_CHUMBY
+ default 0x42000000 if MACH_IMX233_OLINUXINO
default 0x47000000 if MACH_TX28
default 0x47000000 if MACH_MX28EVK
default 0x47000000 if MACH_CFA10036
@@ -11,6 +12,7 @@ config ARCH_TEXT_BASE
config BOARDINFO
default "Freescale i.MX23-EVK" if MACH_MX23EVK
default "Chumby Falconwing" if MACH_CHUMBY
+ default "Olimex.ltd imx233-olinuxino" if MACH_IMX233_OLINUXINO
default "Karo TX28" if MACH_TX28
default "Freescale i.MX28-EVK" if MACH_MX28EVK
default "Crystalfontz CFA-10036" if MACH_CFA10036
@@ -47,6 +49,11 @@ config MACH_CHUMBY
Say Y here if you are using the "chumby one" aka falconwing from
Chumby Industries
+config MACH_IMX233_OLINUXINO
+ bool "Olimex.ltd imx223-olinuxino"
+ help
+ Say Y here if you are using the imx233-olinuxino
+
endchoice
endif
diff --git a/arch/arm/mach-mxs/imx.c b/arch/arm/mach-mxs/imx.c
index c64f23ceb5..db878fb5c7 100644
--- a/arch/arm/mach-mxs/imx.c
+++ b/arch/arm/mach-mxs/imx.c
@@ -20,6 +20,30 @@
#include <common.h>
#include <command.h>
#include <complete.h>
+#include <init.h>
+#include <io.h>
+#include <mach/imx-regs.h>
+
+#define HW_RTC_PERSISTENT1 0x070
+
+static int imx_reset_usb_bootstrap(void)
+{
+ /*
+ * Clear USB boot mode.
+ *
+ * When the i.MX28 boots from USB, the ROM code sets this bit. When
+ * after a reset the ROM code detects that this bit is set it will
+ * boot from USB again. This means that if we boot once from USB the
+ * chip will continue to boot from USB until the next power cycle.
+ *
+ * To prevent this (and boot from the configured bootsource instead)
+ * clear this bit here.
+ */
+ writel(0x2, IMX_WDT_BASE + HW_RTC_PERSISTENT1 + BIT_CLR);
+
+ return 0;
+}
+device_initcall(imx_reset_usb_bootstrap);
extern void imx_dump_clocks(void);
diff --git a/arch/arm/mach-nomadik/8815.c b/arch/arm/mach-nomadik/8815.c
index e3855981fd..aecd9e0f52 100644
--- a/arch/arm/mach-nomadik/8815.c
+++ b/arch/arm/mach-nomadik/8815.c
@@ -25,6 +25,7 @@
#include <mach/hardware.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
+#include <linux/amba/bus.h>
#include "clock.h"
@@ -32,12 +33,15 @@ static struct clk st8815_clk_48 = {
.rate = 48 * 1000 * 1000,
};
+static struct clk st8815_dummy;
+
void st8815_add_device_sdram(u32 size)
{
arm_add_mem_device("ram0", 0x00000000, size);
}
static struct clk_lookup clocks_lookups[] = {
+ CLKDEV_CON_ID("apb_pclk", &st8815_dummy),
CLKDEV_DEV_ID("uart-pl0110", &st8815_clk_48),
CLKDEV_DEV_ID("uart-pl0111", &st8815_clk_48),
};
@@ -53,7 +57,6 @@ postcore_initcall(st8815_clkdev_init);
void st8815_register_uart(unsigned id)
{
resource_size_t start;
- struct device_d *dev;
switch (id) {
case 0:
@@ -63,7 +66,5 @@ void st8815_register_uart(unsigned id)
start = NOMADIK_UART1_BASE;
break;
}
- dev = add_generic_device("uart-pl011", id, NULL, start, 4096,
- IORESOURCE_MEM, NULL);
- nmdk_clk_create(&st8815_clk_48, dev_name(dev));
+ amba_apb_device_add(NULL, "uart-pl011", id, start, 4096, NULL, 0);
}
diff --git a/arch/arm/mach-omap/include/mach/emac_defs.h b/arch/arm/mach-omap/include/mach/emac_defs.h
new file mode 100644
index 0000000000..568de6a12a
--- /dev/null
+++ b/arch/arm/mach-omap/include/mach/emac_defs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.h
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+
+ * Modifications:
+ * ver. 1.0: Sep 2005, TI PSP Team - Created EMAC version for uBoot.
+ *
+ */
+
+#ifndef _AM3517_EMAC_H_
+#define _AM3517_EMAC_H_
+
+#define EMAC_BASE_ADDR 0x5C010000
+#define EMAC_WRAPPER_BASE_ADDR 0x5C000000
+#define EMAC_WRAPPER_RAM_ADDR 0x5C020000
+#define EMAC_MDIO_BASE_ADDR 0x5C030000
+#define EMAC_HW_RAM_ADDR 0x01E20000
+
+#define EMAC_MDIO_BUS_FREQ 166000000 /* 166 MHZ check */
+#define EMAC_MDIO_CLOCK_FREQ 1000000 /* 2.0 MHz */
+
+#endif /* _AM3517_EMAC_H_ */
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index bdf48f97a2..86cc755788 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -34,6 +34,7 @@
#include <linux/clkdev.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/amba/bus.h>
#include <io.h>
#include <asm/hardware/arm_timer.h>
@@ -51,6 +52,8 @@ struct clk {
unsigned long rate;
};
+static struct clk ref_clk_dummy;
+
static struct clk ref_clk_24 = {
.rate = 24000000,
};
@@ -145,6 +148,7 @@ static int vpb_clocksource_init(void)
core_initcall(vpb_clocksource_init);
static struct clk_lookup clocks_lookups[] = {
+ CLKDEV_CON_ID("apb_pclk", &ref_clk_dummy),
CLKDEV_DEV_ID("uart-pl0110", &ref_clk_24),
CLKDEV_DEV_ID("uart-pl0111", &ref_clk_24),
CLKDEV_DEV_ID("uart-pl0112", &ref_clk_24),
@@ -179,8 +183,7 @@ void versatile_register_uart(unsigned id)
default:
return;
}
- add_generic_device("uart-pl011", id, NULL, start, 4096,
- IORESOURCE_MEM, NULL);
+ amba_apb_device_add(NULL, "uart-pl011", id, start, 4096, NULL, 0);
}
void __noreturn reset_cpu (unsigned long ignored)
diff --git a/arch/arm/pbl/zbarebox.lds.S b/arch/arm/pbl/zbarebox.lds.S
index 2dca278318..37af4e913e 100644
--- a/arch/arm/pbl/zbarebox.lds.S
+++ b/arch/arm/pbl/zbarebox.lds.S
@@ -39,8 +39,6 @@ SECTIONS
_stext = .;
_text = .;
*(.text_head_entry*)
- __ll_return = .;
- *(.text_ll_return*)
__bare_init_start = .;
*(.text_bare_init*)
__bare_init_end = .;
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 16ba38e50d..87c48ed693 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -568,7 +568,6 @@ do { \
unsigned long long __val; \
unsigned long __flags; \
\
- local_irq_save(__flags); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
@@ -587,7 +586,6 @@ do { \
"dsra\t%L0, %L0, 32\n\t" \
".set\tmips0" \
: "=r" (__val)); \
- local_irq_restore(__flags); \
\
__val; \
})
@@ -596,7 +594,6 @@ do { \
do { \
unsigned long __flags; \
\
- local_irq_save(__flags); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
@@ -617,7 +614,6 @@ do { \
"dmtc0\t%L0, " #source ", " #sel "\n\t" \
".set\tmips0" \
: : "r" (val)); \
- local_irq_restore(__flags); \
} while (0)
#define read_c0_index() __read_32bit_c0_register($0, 0)
diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h
index 9819a973e7..620c207a03 100644
--- a/arch/nios2/include/asm/dma-mapping.h
+++ b/arch/nios2/include/asm/dma-mapping.h
@@ -6,7 +6,6 @@
#include <asm/cache.h>
-
/* dma_alloc_coherent() return cache-line aligned allocation which is mapped
* to uncached io region.
*
@@ -14,6 +13,7 @@
* 0x80000000 for nommu, 0xe0000000 for mmu
*/
+#if (DCACHE_SIZE != 0)
static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
{
void *addr = malloc(len + DCACHE_LINE_SIZE);
@@ -25,11 +25,23 @@ static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
~(DCACHE_LINE_SIZE - 1) & ~(IO_REGION_BASE);
return (void *)(*handle | IO_REGION_BASE);
}
+#else
+static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
+{
+ void *addr = malloc(len);
+ if (!addr)
+ return 0;
+ *handle = (unsigned long)addr;
+ return (void *)(*handle | IO_REGION_BASE);
+}
+#endif
+#if (DCACHE_SIZE != 0)
#define dma_alloc dma_alloc
static inline void *dma_alloc(size_t size)
{
return xmemalign(DCACHE_LINE_SIZE, ALIGN(size, DCACHE_LINE_SIZE));
}
+#endif
#endif /* __ASM_NIOS2_DMA_MAPPING_H */
diff --git a/arch/ppc/boards/pcm030/pcm030.c b/arch/ppc/boards/pcm030/pcm030.c
index ba6aa43182..89083e91d8 100644
--- a/arch/ppc/boards/pcm030/pcm030.c
+++ b/arch/ppc/boards/pcm030/pcm030.c
@@ -30,8 +30,7 @@
#include <common.h>
#include <driver.h>
#include <init.h>
-#include <mach/mpc5xxx.h>
-#include <mach/fec.h>
+#include <fec.h>
#include <types.h>
#include <partition.h>
#include <memory.h>
@@ -39,7 +38,7 @@
#include <linux/stat.h>
#include <fs.h>
-static struct mpc5xxx_fec_platform_data fec_info = {
+static struct fec_platform_data fec_info = {
.xcv_type = MII100,
};
diff --git a/arch/ppc/mach-mpc5xxx/include/mach/fec.h b/arch/ppc/mach-mpc5xxx/include/mach/fec.h
deleted file mode 100644
index a3e04b4e9d..0000000000
--- a/arch/ppc/mach-mpc5xxx/include/mach/fec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __INCLUDE_ASM_ARCH_FEC_H
-#define __INCLUDE_ASM_ARCH_FEC_H
-
-struct mpc5xxx_fec_platform_data {
- ulong xcv_type;
-};
-
-typedef enum {
- SEVENWIRE, /* 7-wire */
- MII10, /* MII 10Mbps */
- MII100 /* MII 100Mbps */
-} xceiver_type;
-
-#endif /* __INCLUDE_ASM_ARCH_FEC_H */
diff --git a/arch/ppc/mach-mpc85xx/eth-devices.c b/arch/ppc/mach-mpc85xx/eth-devices.c
index 02a3722136..c6e8f3660d 100644
--- a/arch/ppc/mach-mpc85xx/eth-devices.c
+++ b/arch/ppc/mach-mpc85xx/eth-devices.c
@@ -32,15 +32,15 @@ int fsl_eth_init(int num, struct gfar_info_struct *gf)
res = xzalloc(3 * sizeof(struct resource));
/* TSEC interface registers */
res[0].start = GFAR_BASE_ADDR + ((num - 1) * 0x1000);
- res[0].end = res[0].start + 0x1000;
+ res[0].end = res[0].start + 0x1000 - 1;
res[0].flags = IORESOURCE_MEM;
/* External PHY access always through eTSEC1 */
res[1].start = MDIO_BASE_ADDR;
- res[1].end = res[1].start + 0x1000;
+ res[1].end = res[1].start + 0x1000 - 1;
res[1].flags = IORESOURCE_MEM;
/* Access to TBI/RTBI interface. */
res[2].start = MDIO_BASE_ADDR + ((num - 1) * 0x1000);
- res[2].end = res[2].start + 0x1000;
+ res[2].end = res[2].start + 0x1000 - 1;
res[2].flags = IORESOURCE_MEM;
add_generic_device_res("gfar", DEVICE_ID_DYNAMIC, res, 3, gf);
diff --git a/arch/sandbox/board/Makefile b/arch/sandbox/board/Makefile
index 266c3a3cec..5104f5cb26 100644
--- a/arch/sandbox/board/Makefile
+++ b/arch/sandbox/board/Makefile
@@ -2,5 +2,6 @@ obj-y += board.o
obj-y += clock.o
obj-y += hostfile.o
obj-y += console.o
+obj-y += devices.o
extra-y += barebox.lds
diff --git a/arch/sandbox/board/console.c b/arch/sandbox/board/console.c
index 2959e85c7a..e762521b7a 100644
--- a/arch/sandbox/board/console.c
+++ b/arch/sandbox/board/console.c
@@ -47,6 +47,6 @@ int barebox_register_console(char *name, int stdinfd, int stdoutfd)
data->stdoutfd = stdoutfd;
data->stdinfd = stdinfd;
- return register_device(dev);
+ return sandbox_add_device(dev);
}
diff --git a/arch/sandbox/board/devices.c b/arch/sandbox/board/devices.c
new file mode 100644
index 0000000000..dba0d5d893
--- /dev/null
+++ b/arch/sandbox/board/devices.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+
+static LIST_HEAD(sandbox_device_list);
+
+int sandbox_add_device(struct device_d *dev)
+{
+ list_add(&dev->list, &sandbox_device_list);
+
+ return 0;
+}
+
+static int sandbox_device_init(void)
+{
+ struct device_d *dev, *tmp;
+
+ list_for_each_entry_safe(dev, tmp, &sandbox_device_list, list) {
+ /* reset the list_head before registering for real */
+ dev->list.prev = NULL;
+ dev->list.next = NULL;
+ register_device(dev);
+ }
+
+ return 0;
+}
+postcore_initcall(sandbox_device_init);
diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c
index 96fa100011..00e46e22d4 100644
--- a/arch/sandbox/board/hostfile.c
+++ b/arch/sandbox/board/hostfile.c
@@ -102,7 +102,22 @@ device_initcall(hf_init);
int barebox_register_filedev(struct hf_platform_data *hf)
{
- return !add_generic_device("hostfile", DEVICE_ID_DYNAMIC, NULL, hf->base, hf->size,
- IORESOURCE_MEM, hf);
+ struct device_d *dev;
+ struct resource *res;
+
+ dev = xzalloc(sizeof(*dev));
+ strcpy(dev->name, "hostfile");
+ dev->id = DEVICE_ID_DYNAMIC;
+ dev->platform_data = hf;
+
+ res = xzalloc(sizeof(struct resource));
+ res[0].start = hf->base;
+ res[0].end = hf->base + hf->size - 1;
+ res[0].flags = IORESOURCE_MEM;
+
+ dev->resource = res;
+ dev->num_resources = 1;
+
+ return sandbox_add_device(dev);
}
diff --git a/arch/sandbox/mach-sandbox/include/mach/linux.h b/arch/sandbox/mach-sandbox/include/mach/linux.h
index 5917fe93de..259f2d8ee3 100644
--- a/arch/sandbox/mach-sandbox/include/mach/linux.h
+++ b/arch/sandbox/mach-sandbox/include/mach/linux.h
@@ -1,6 +1,9 @@
#ifndef __ASM_ARCH_LINUX_H
#define __ASM_ARCH_LINUX_H
+struct device_d;
+
+int sandbox_add_device(struct device_d *dev);
int linux_register_device(const char *name, void *start, void *end);
int tap_alloc(char *dev);
uint64_t linux_get_time(void);
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index e296574c93..38c6596195 100644
--- a/arch/sandbox/os/common.c
+++ b/arch/sandbox/os/common.c
@@ -355,10 +355,6 @@ int main(int argc, char *argv[])
break;
switch (opt) {
- case 'h':
- break;
- case 'm':
- break;
case 'i':
sprintf(str, "fd%d", fdno);
ret = add_image(optarg, str);
@@ -366,14 +362,8 @@ int main(int argc, char *argv[])
exit(1);
fdno++;
break;
- case 'e':
- break;
- case 'O':
- break;
- case 'I':
- break;
default:
- exit(1);
+ break;
}
}
diff --git a/commands/Kconfig b/commands/Kconfig
index f2756cc400..8a3edfa43d 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -468,7 +468,17 @@ config CMD_OFTREE
tristate
select OFTREE
prompt "oftree"
- select FDT
+ help
+ The oftree command has support for dumping devicetrees and, if
+ enabled, to probe devices from the devicetree
+
+config CMD_OFTREE_PROBE
+ bool
+ depends on CMD_OFTREE
+ select OFDEVICE
+ prompt "oftree probe support"
+ help
+ This enables the -p option to probe devices from the devicetree
endmenu
diff --git a/commands/echo.c b/commands/echo.c
index a19d99292f..4a5c981408 100644
--- a/commands/echo.c
+++ b/commands/echo.c
@@ -33,10 +33,9 @@ static int do_echo(int argc, char *argv[])
int fd = stdout, opt, newline = 1;
char *file = NULL;
int oflags = O_WRONLY | O_CREAT;
-#ifdef CONFIG_CMD_ECHO_E
char str[CONFIG_CBSIZE];
int process_escape = 0;
-#endif
+
/* We can't use getopt() here because we want to
* echo all things we don't understand.
*/
@@ -66,11 +65,9 @@ static int do_echo(int argc, char *argv[])
goto no_optarg_out;
optind++;
break;
-#ifdef CONFIG_CMD_ECHO_E
case 'e':
- process_escape = 1;
+ process_escape = IS_ENABLED(CONFIG_CMD_ECHO_E);
break;
-#endif
default:
goto exit_parse;
}
@@ -89,13 +86,12 @@ exit_parse:
for (i = optind; i < argc; i++) {
if (i > optind)
fputc(fd, ' ');
-#ifdef CONFIG_CMD_ECHO_E
if (process_escape) {
process_escape_sequence(argv[i], str, CONFIG_CBSIZE);
fputs(fd, str);
- } else
-#endif
+ } else {
fputs(fd, argv[i]);
+ }
}
if (newline)
diff --git a/commands/global.c b/commands/global.c
index de6b13e7bd..b7c37433c4 100644
--- a/commands/global.c
+++ b/commands/global.c
@@ -24,39 +24,68 @@
#include <command.h>
#include <globalvar.h>
#include <environment.h>
+#include <getopt.h>
-static int do_global(int argc, char *argv[])
+static int globalvar_set(char* name, char* value)
{
int ret;
+
+ ret = globalvar_add_simple(name);
+
+ if (value) {
+ char *tmp = asprintf("global.%s", name);
+ ret = setenv(tmp, value);
+ free(tmp);
+ }
+
+ return ret ? 1 : 0;
+}
+
+static int do_global(int argc, char *argv[])
+{
+ int opt;
+ int do_set_match = 0;
char *value;
- if (argc != 2)
+ while ((opt = getopt(argc, argv, "r")) > 0) {
+ switch (opt) {
+ case 'r':
+ do_set_match = 1;
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
return COMMAND_ERROR_USAGE;
- value = strchr(argv[1], '=');
+ value = strchr(argv[0], '=');
if (value) {
*value = 0;
value++;
}
- ret = globalvar_add_simple(argv[1]);
+ if (do_set_match) {
+ if (!value)
+ value = "";
- if (value) {
- char *name = asprintf("global.%s", argv[1]);
- ret = setenv(name, value);
- free(name);
+ globalvar_set_match(argv[0], value);
+ return 0;
}
- return ret ? 1 : 0;
+ return globalvar_set(argv[0], value);
}
BAREBOX_CMD_HELP_START(global)
-BAREBOX_CMD_HELP_USAGE("global <var>[=<value]\n")
+BAREBOX_CMD_HELP_USAGE("global [-r] <var>[=<value]\n")
BAREBOX_CMD_HELP_SHORT("add a new global variable named <var>, optionally set to <value>\n")
+BAREBOX_CMD_HELP_SHORT("-r to set a value to of all globalvars beginning with 'match'")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(global)
.cmd = do_global,
- .usage = "create global variables",
+ .usage = "create or set global variables",
BAREBOX_CMD_HELP(cmd_global_help)
BAREBOX_CMD_END
diff --git a/commands/oftree.c b/commands/oftree.c
index 77afbc5a19..6479fa4e94 100644
--- a/commands/oftree.c
+++ b/commands/oftree.c
@@ -48,7 +48,8 @@ static int do_oftree(int argc, char *argv[])
char *file = NULL;
const char *node = "/";
int dump = 0;
- int parse = 0;
+ int probe = 0;
+ int ret;
while ((opt = getopt(argc, argv, "dpfn:")) > 0) {
switch (opt) {
@@ -56,7 +57,12 @@ static int do_oftree(int argc, char *argv[])
dump = 1;
break;
case 'p':
- parse = 1;
+ if (IS_ENABLED(CONFIG_CMD_OFTREE_PROBE)) {
+ probe = 1;
+ } else {
+ printf("oftree device probe support disabled\n");
+ return COMMAND_ERROR_USAGE;
+ }
break;
case 'f':
free(barebox_fdt);
@@ -71,7 +77,7 @@ static int do_oftree(int argc, char *argv[])
if (optind < argc)
file = argv[optind];
- if (!dump && !parse)
+ if (!dump && !probe)
return COMMAND_ERROR_USAGE;
if (dump) {
@@ -95,7 +101,7 @@ static int do_oftree(int argc, char *argv[])
return 0;
}
- if (parse) {
+ if (probe) {
if (!file)
return COMMAND_ERROR_USAGE;
@@ -105,17 +111,13 @@ static int do_oftree(int argc, char *argv[])
return 1;
}
- fdt = xrealloc(fdt, size + 0x8000);
- fdt_open_into(fdt, fdt, size + 0x8000);
- if (!fdt) {
- printf("unable to read %s\n", file);
+ ret = of_parse_dtb(fdt);
+ if (ret) {
+ printf("parse oftree: %s\n", strerror(-ret));
return 1;
}
- if (barebox_fdt)
- free(barebox_fdt);
-
- barebox_fdt = fdt;
+ of_probe();
}
return 0;
@@ -123,7 +125,7 @@ static int do_oftree(int argc, char *argv[])
BAREBOX_CMD_HELP_START(oftree)
BAREBOX_CMD_HELP_USAGE("oftree [OPTIONS]\n")
-BAREBOX_CMD_HELP_OPT ("-p <FILE>", "parse and store oftree from <file>\n")
+BAREBOX_CMD_HELP_OPT ("-p <FILE>", "probe devices in oftree from <file>\n")
BAREBOX_CMD_HELP_OPT ("-d [FILE]", "dump oftree from [FILE] or the parsed tree if no file is given\n")
BAREBOX_CMD_HELP_OPT ("-f", "free stored oftree\n")
BAREBOX_CMD_HELP_END
diff --git a/common/Kconfig b/common/Kconfig
index b97392cfdb..0597c9cb62 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -96,6 +96,10 @@ config BANNER
bool "display banner"
default y
+config MEMINFO
+ bool "display memory info"
+ default y
+
config ENVIRONMENT_VARIABLES
bool "environment variables support"
@@ -575,6 +579,7 @@ config DEFAULT_ENVIRONMENT_GENERIC
select CMD_CRC
select CMD_CRC_CMP
select CMD_AUTOMOUNT if HAVE_DEFAULT_ENVIRONMENT_NEW
+ select CMD_GLOBAL
prompt "Default environment generic"
help
With this option barebox will use the generic default
diff --git a/common/Makefile b/common/Makefile
index df9f301234..68582b78e1 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_MALLOC_TLSF) += tlsf.o
obj-$(CONFIG_MALLOC_DUMMY) += dummy_malloc.o
obj-y += clock.o
obj-$(CONFIG_BANNER) += version.o
+obj-$(CONFIG_MEMINFO) += meminfo.o
obj-$(CONFIG_COMMAND_SUPPORT) += command.o
obj-$(CONFIG_CONSOLE_FULL) += console.o
obj-$(CONFIG_CONSOLE_SIMPLE) += console_simple.o
diff --git a/common/filetype.c b/common/filetype.c
index 6306fdcb74..3d544cd6ce 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -26,6 +26,7 @@
#include <fcntl.h>
#include <fs.h>
#include <malloc.h>
+#include <errno.h>
static const char *filetype_str[] = {
[filetype_unknown] = "unknown",
@@ -42,6 +43,7 @@ static const char *filetype_str[] = {
[filetype_sh] = "Bourne Shell",
[filetype_mips_barebox] = "MIPS barebox image",
[filetype_fat] = "FAT filesytem",
+ [filetype_mbr] = "MBR sector",
};
const char *file_type_to_string(enum filetype f)
@@ -52,26 +54,51 @@ const char *file_type_to_string(enum filetype f)
return NULL;
}
-static int is_fat(u8 *buf)
+#define MBR_StartSector 8 /* MBR: Offset of Starting Sector in Partition Table Entry */
+#define BS_55AA 510 /* Boot sector signature (2) */
+#define MBR_Table 446 /* MBR: Partition table offset (2) */
+#define BS_FilSysType32 82 /* File system type (1) */
+#define BS_FilSysType 54 /* File system type (1) */
+
+enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec)
{
- if (get_unaligned_le16(&buf[510]) != 0xAA55)
- return 0;
+ /*
+ * bootsec can be used to return index of the first sector in the
+ * first partition
+ */
+ if (bootsec)
+ *bootsec = 0;
+
+ /*
+ * Check record signature (always placed at offset 510 even if the
+ * sector size is > 512)
+ */
+ if (get_unaligned_le16(&sector[BS_55AA]) != 0xAA55)
+ return filetype_unknown;
+
+ /* Check "FAT" string */
+ if ((get_unaligned_le32(&sector[BS_FilSysType]) & 0xFFFFFF) == 0x544146)
+ return filetype_fat;
- /* FAT */
- if ((get_unaligned_le32(&buf[54]) & 0xFFFFFF) == 0x544146)
- return 1;
+ if ((get_unaligned_le32(&sector[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)
+ return filetype_fat;
- /* FAT32 */
- if ((get_unaligned_le32(&buf[82]) & 0xFFFFFF) == 0x544146)
- return 1;
+ if (bootsec)
+ /*
+ * This must be an MBR, so return the starting sector of the
+ * first partition so we could check if there is a FAT boot
+ * sector there
+ */
+ *bootsec = get_unaligned_le16(&sector[MBR_Table + MBR_StartSector]);
- return 0;
+ return filetype_mbr;
}
enum filetype file_detect_type(void *_buf)
{
u32 *buf = _buf;
u8 *buf8 = _buf;
+ enum filetype type;
if (strncmp(buf8, "#!/bin/sh", 9) == 0)
return filetype_sh;
@@ -99,8 +126,9 @@ enum filetype file_detect_type(void *_buf)
return filetype_aimage;
if (strncmp(buf8 + 0x10, "barebox", 7) == 0)
return filetype_mips_barebox;
- if (is_fat(buf8))
- return filetype_fat;
+ type = is_fat_or_mbr(buf8, NULL);
+ if (type != filetype_unknown)
+ return type;
return filetype_unknown;
}
@@ -110,6 +138,7 @@ enum filetype file_name_detect_type(const char *filename)
int fd, ret;
void *buf;
enum filetype type = filetype_unknown;
+ unsigned long bootsec;
fd = open(filename, O_RDONLY);
if (fd < 0)
@@ -123,6 +152,21 @@ enum filetype file_name_detect_type(const char *filename)
type = file_detect_type(buf);
+ if (type == filetype_mbr) {
+ /*
+ * Get the first partition start sector
+ * and check for FAT in it
+ */
+ is_fat_or_mbr(buf, &bootsec);
+ ret = lseek(fd, (bootsec) * 512, SEEK_SET);
+ if (ret < 0)
+ goto err_out;
+ ret = read(fd, buf, 512);
+ if (ret < 0)
+ goto err_out;
+ type = is_fat_or_mbr((u8 *)buf, NULL);
+ }
+
err_out:
close(fd);
free(buf);
diff --git a/common/globalvar.c b/common/globalvar.c
index 71296ff5a3..a8aaa72553 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -46,6 +46,16 @@ char *globalvar_get_match(const char *match, const char *seperator)
return val;
}
+void globalvar_set_match(const char *match, const char *val)
+{
+ struct param_d *param;
+
+ list_for_each_entry(param, &global_device.parameters, list) {
+ if (!strncmp(match, param->name, strlen(match)))
+ dev_set_param(&global_device, param->name, val);
+ }
+}
+
/*
* globalvar_add_simple
*
diff --git a/common/meminfo.c b/common/meminfo.c
new file mode 100644
index 0000000000..06fce5afb4
--- /dev/null
+++ b/common/meminfo.c
@@ -0,0 +1,23 @@
+#include <common.h>
+#include <init.h>
+#include <memory.h>
+#include <asm-generic/memory_layout.h>
+
+static int display_meminfo(void)
+{
+ ulong mstart = mem_malloc_start();
+ ulong mend = mem_malloc_end();
+ ulong msize = mend - mstart + 1;
+
+ debug("barebox code: 0x%p -> 0x%p\n", _stext, _etext);
+ debug("bss segment: 0x%p -> 0x%p\n", __bss_start, __bss_stop);
+ printf("malloc space: 0x%08lx -> 0x%08lx (size %s)\n",
+ mstart, mend, size_human_readable(msize));
+#ifdef CONFIG_ARM
+ printf("stack space: 0x%08x -> 0x%08x (size %s)\n",
+ STACK_BASE, STACK_BASE + STACK_SIZE,
+ size_human_readable(STACK_SIZE));
+#endif
+ return 0;
+}
+late_initcall(display_meminfo);
diff --git a/common/oftree.c b/common/oftree.c
index 677e934a98..3e8c6f8c65 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -57,7 +57,7 @@ static int is_printable_string(const void *data, int len)
* a string, concatenated strings, a byte, word, double word, or (if all
* else fails) it is printed as a stream of bytes.
*/
-static void print_data(const void *data, int len)
+void of_print_property(const void *data, int len)
{
int j;
@@ -169,7 +169,7 @@ int fdt_print(struct fdt_header *working_fdt, const char *pathp)
printf_indent(level, "%s;\n", pathp);
} else {
printf_indent(level, "%s = ", pathp);
- print_data(nodep, len);
+ of_print_property(nodep, len);
printf(";\n");
}
break;
diff --git a/common/startup.c b/common/startup.c
index abd1b774bd..e639d05cc7 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -33,34 +33,15 @@
#include <init.h>
#include <command.h>
#include <malloc.h>
-#include <memory.h>
#include <debug_ll.h>
#include <fs.h>
#include <linux/stat.h>
#include <environment.h>
-#include <asm-generic/memory_layout.h>
#include <asm/sections.h>
extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[],
__barebox_initcalls_end[];
-static void display_meminfo(void)
-{
- ulong mstart = mem_malloc_start();
- ulong mend = mem_malloc_end();
- ulong msize = mend - mstart + 1;
-
- debug("barebox code: 0x%p -> 0x%p\n", _stext, _etext);
- debug("bss segment: 0x%p -> 0x%p\n", __bss_start, __bss_stop);
- printf("Malloc space: 0x%08lx -> 0x%08lx (size %s)\n",
- mstart, mend, size_human_readable(msize));
-#ifdef CONFIG_ARM
- printf("Stack space : 0x%08x -> 0x%08x (size %s)\n",
- STACK_BASE, STACK_BASE + STACK_SIZE,
- size_human_readable(STACK_SIZE));
-#endif
-}
-
#ifdef CONFIG_DEFAULT_ENVIRONMENT
#include <generated/barebox_default_env.h>
@@ -128,8 +109,6 @@ void start_barebox (void)
debug("initcalls done\n");
- display_meminfo();
-
#ifdef CONFIG_ENV_HANDLING
if (envfs_load(default_environment_path, "/env")) {
#ifdef CONFIG_DEFAULT_ENVIRONMENT
diff --git a/defaultenv-2/base/bin/boot b/defaultenv-2/base/bin/boot
index 4ebda3f4b2..103eb8767e 100644
--- a/defaultenv-2/base/bin/boot
+++ b/defaultenv-2/base/bin/boot
@@ -33,6 +33,10 @@ while getopt "vdhl" opt; do
fi
done
+# clear linux.bootargs.dyn.* and bootm.*
+global -r linux.bootargs.dyn.
+global -r bootm.
+
if [ $# = 0 ]; then
scr="$global.boot.default"
else
diff --git a/defaultenv-2/base/bin/bootargs-ip b/defaultenv-2/base/bin/bootargs-ip
index 15041c6359..2d4486caf8 100644
--- a/defaultenv-2/base/bin/bootargs-ip
+++ b/defaultenv-2/base/bin/bootargs-ip
@@ -5,7 +5,7 @@
. /env/network/eth0
if [ $ip = dhcp ]; then
- global.linux.bootargs.ip="ip=dhcp"
+ global.linux.bootargs.dyn.ip="ip=dhcp"
else
- global.linux.bootargs.ip="ip=$ipaddr:$serverip:$gateway:$netmask::eth0:"
+ global.linux.bootargs.dyn.ip="ip=$ipaddr:$serverip:$gateway:$netmask::eth0:"
fi
diff --git a/defaultenv-2/base/bin/bootargs-ip-barebox b/defaultenv-2/base/bin/bootargs-ip-barebox
index 986c142286..5a3b984069 100644
--- a/defaultenv-2/base/bin/bootargs-ip-barebox
+++ b/defaultenv-2/base/bin/bootargs-ip-barebox
@@ -4,4 +4,4 @@
ifup eth0
-global.linux.bootargs.ip="ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask::eth0:"
+global.linux.bootargs.dyn.ip="ip=$eth0.ipaddr:$eth0.serverip:$eth0.gateway:$eth0.netmask::eth0:"
diff --git a/defaultenv-2/base/bin/bootargs-ip-dhcp b/defaultenv-2/base/bin/bootargs-ip-dhcp
index c542b248f0..dec8ae452a 100644
--- a/defaultenv-2/base/bin/bootargs-ip-dhcp
+++ b/defaultenv-2/base/bin/bootargs-ip-dhcp
@@ -2,4 +2,4 @@
# Do dhcp in Linux
-global.linux.bootargs.ip="ip=dhcp"
+global.linux.bootargs.dyn.ip="ip=dhcp"
diff --git a/defaultenv-2/base/bin/bootargs-ip-none b/defaultenv-2/base/bin/bootargs-ip-none
index c010154650..88aaa21a78 100644
--- a/defaultenv-2/base/bin/bootargs-ip-none
+++ b/defaultenv-2/base/bin/bootargs-ip-none
@@ -2,4 +2,4 @@
# disable ip setup in Linux
-global.linux.bootargs.ip="ip=none"
+global.linux.bootargs.dyn.ip="ip=none"
diff --git a/defaultenv-2/base/bin/bootargs-root-disk b/defaultenv-2/base/bin/bootargs-root-disk
index df8750e46d..aa60cf33f0 100644
--- a/defaultenv-2/base/bin/bootargs-root-disk
+++ b/defaultenv-2/base/bin/bootargs-root-disk
@@ -23,4 +23,4 @@ if [ -z "${fstype}" ]; then
exit 1
fi
-global.linux.bootargs.root="root=/dev/$part rootfstype=$fstype rootwait"
+global.linux.bootargs.dyn.root="root=/dev/$part rootfstype=$fstype rootwait"
diff --git a/defaultenv-2/base/bin/bootargs-root-ext b/defaultenv-2/base/bin/bootargs-root-ext
index 45fcd5acfb..dbdddb9fcc 100644
--- a/defaultenv-2/base/bin/bootargs-root-ext
+++ b/defaultenv-2/base/bin/bootargs-root-ext
@@ -9,4 +9,4 @@ while getopt "m:r:" opt; do
fi
done
-global.linux.bootargs.root="root=/dev/$part rootfstype=ext$type rootwait"
+global.linux.bootargs.dyn.root="root=/dev/$part rootfstype=ext$type rootwait"
diff --git a/defaultenv-2/base/bin/bootargs-root-initrd b/defaultenv-2/base/bin/bootargs-root-initrd
index 7072cea65b..cc711a1051 100644
--- a/defaultenv-2/base/bin/bootargs-root-initrd
+++ b/defaultenv-2/base/bin/bootargs-root-initrd
@@ -13,4 +13,4 @@ while getopt "i:h" opt; do
fi
done
-global.linux.bootargs.root="root=/dev/ram0 rdinit=${rdinit}"
+global.linux.bootargs.dyn.root="root=/dev/ram0 rdinit=${rdinit}"
diff --git a/defaultenv-2/base/bin/bootargs-root-jffs2 b/defaultenv-2/base/bin/bootargs-root-jffs2
index 74d59afe39..a8eb5e7bb8 100644
--- a/defaultenv-2/base/bin/bootargs-root-jffs2
+++ b/defaultenv-2/base/bin/bootargs-root-jffs2
@@ -18,4 +18,4 @@ if [ -z "$mtd" ]; then
exit 1
fi
-global.linux.bootargs.root="root=$mtd rootfstype=jffs2"
+global.linux.bootargs.dyn.root="root=$mtd rootfstype=jffs2"
diff --git a/defaultenv-2/base/bin/bootargs-root-nfs b/defaultenv-2/base/bin/bootargs-root-nfs
index 27bb6c40fa..355f93dbe3 100644
--- a/defaultenv-2/base/bin/bootargs-root-nfs
+++ b/defaultenv-2/base/bin/bootargs-root-nfs
@@ -17,4 +17,4 @@ if [ -n ${serverip} ]; then
nfsroot="$serverip:$nfsroot"
fi
-global.linux.bootargs.root="root=/dev/nfs nfsroot=$nfsroot,v3,tcp"
+global.linux.bootargs.dyn.root="root=/dev/nfs nfsroot=$nfsroot,v3,tcp"
diff --git a/defaultenv-2/base/bin/bootargs-root-ubi b/defaultenv-2/base/bin/bootargs-root-ubi
index fb7f328bef..4260336915 100644
--- a/defaultenv-2/base/bin/bootargs-root-ubi
+++ b/defaultenv-2/base/bin/bootargs-root-ubi
@@ -21,4 +21,4 @@ if [ -z "$mtd" ]; then
exit 1
fi
-global.linux.bootargs.root="root=ubi0:$ubiroot ubi.mtd=$mtd rootfstype=ubifs"
+global.linux.bootargs.dyn.root="root=ubi0:$ubiroot ubi.mtd=$mtd rootfstype=ubifs"
diff --git a/defaultenv-2/base/bin/init b/defaultenv-2/base/bin/init
index 9d7eb2eea7..8e8871d10a 100644
--- a/defaultenv-2/base/bin/init
+++ b/defaultenv-2/base/bin/init
@@ -8,8 +8,9 @@ global autoboot_timeout=3
global boot.default=net
global allow_color=true
global linux.bootargs.base
-global linux.bootargs.ip
-global linux.bootargs.root
+#linux.bootargs.dyn.* will be clearer at the beginning of boot
+global linux.bootargs.dyn.ip
+global linux.bootargs.dyn.root
global editcmd=sedit
/env/init/general
diff --git a/defaultenv-2/base/boot/initrd b/defaultenv-2/base/boot/initrd
index 79a353a10a..7c44d07a6e 100644
--- a/defaultenv-2/base/boot/initrd
+++ b/defaultenv-2/base/boot/initrd
@@ -11,7 +11,7 @@ global.bootm.initrd="${path}/initramfs"
bootargs-root-initrd
#global.bootm.oftree=<path to oftree>
-global.linux.bootargs.root="root=/dev/ram0"
+global.linux.bootargs.dyn.root="root=/dev/ram0"
#bootargs-root-nfs -n "<path on server>" -s <serverip>
#bootargs-root-ubi -r <volume> -m <mtdname>
diff --git a/defaultenv-2/base/data/ansi-colors b/defaultenv-2/base/data/ansi-colors
index c71b6b7998..636532979a 100644
--- a/defaultenv-2/base/data/ansi-colors
+++ b/defaultenv-2/base/data/ansi-colors
@@ -1,5 +1,9 @@
#!/bin/sh
+if [ ${global.allow_color} != "true" ]; then
+ exit
+fi
+
# Colors
export RED='\e[1;31m'
export BLUE='\e[1;34m'
diff --git a/defaultenv-2/base/network/eth0 b/defaultenv-2/base/network/eth0
index 048a288245..7e731cae00 100644
--- a/defaultenv-2/base/network/eth0
+++ b/defaultenv-2/base/network/eth0
@@ -2,6 +2,7 @@
# ip setting (static/dhcp)
ip=dhcp
+global.dhcp.vendor_id=barebox-${global.hostname}
# static setup used if ip=static
ipaddr=
diff --git a/defaultenv-2/menu/menu/mainmenu b/defaultenv-2/menu/menu/mainmenu
index d7b0033220..5bd7027e2a 100644
--- a/defaultenv-2/menu/menu/mainmenu
+++ b/defaultenv-2/menu/menu/mainmenu
@@ -3,9 +3,7 @@
savepath=$PATH
export menupath=$PATH:/env/menu
-if [ ${global.allow_color} = "true" ]; then
- . /env/data/ansi-colors
-fi
+. /env/data/ansi-colors
while true; do
export PATH=${menupath}
diff --git a/defaultenv/bin/boot b/defaultenv/bin/boot
index 61b893a724..c17ccdb8f5 100644
--- a/defaultenv/bin/boot
+++ b/defaultenv/bin/boot
@@ -44,14 +44,14 @@ fi
if [ x$ip = xdhcp -o x$ip = "xdhcp-barebox" ]; then
if [ x$kernel_loc = xnfs -o x$kernel_loc = xtftp ]; then
dhcp
- if [ x$rootpath != x ]; then
- nfsroot=$rootpath
+ if [ x${global.dhcp.rootpath} != x ]; then
+ nfsroot=${global.dhcp.rootpath}
fi
- if [ x$bootfile != x ]; then
- kernelimage=$bootfile
+ if [ x${global.dhcp.bootfile} != x ]; then
+ kernelimage=${global.dhcp.bootfile}
fi
- if [ x$dhcp_oftree_file != x ]; then
- oftreeimage=$dhcp_oftree_file
+ if [ x$global.dhcp.oftree_file} != x ]; then
+ oftreeimage=${global.dhcp.oftree_file}
fi
fi
fi
diff --git a/defaultenv/bin/init b/defaultenv/bin/init
index f535e3781c..adb3c43a66 100644
--- a/defaultenv/bin/init
+++ b/defaultenv/bin/init
@@ -3,6 +3,8 @@
PATH=/env/bin
export PATH
+global hostname
+
. /env/config
if [ -e /dev/nor0 -a -n "$nor_parts" ]; then
addpart /dev/nor0 $nor_parts
diff --git a/defaultenv/config b/defaultenv/config
index 7b61d29730..391ba47c18 100644
--- a/defaultenv/config
+++ b/defaultenv/config
@@ -11,7 +11,7 @@ fi
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp
-dhcp_vendor_id=barebox
+global.dhcp.vendor_id=barebox
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
@@ -31,25 +31,25 @@ oftree_loc=tftp
rootfs_type=ubifs
# where is the rootfs in case of 'rootfs_loc=disk' (linux name)
rootfs_part_linux_dev=mmcblk0p4
-rootfsimage=rootfs-${hostname}.$rootfs_type
+rootfsimage=rootfs-${global.hostname}.$rootfs_type
# where is the kernel image in case of 'kernel_loc=disk'
kernel_part=disk0.2
-kernelimage=zImage-$hostname
-#kernelimage=uImage-$hostname
-#kernelimage=Image-$hostname
-#kernelimage=Image-$hostname.lzo
+kernelimage=zImage-${global.hostname}
+#kernelimage=uImage-${global.hostname}
+#kernelimage=Image-${global.hostname}
+#kernelimage=Image-${global.hostname}.lzo
-bareboximage=barebox-${hostname}.bin
-bareboxenvimage=barebox-${hostname}.bin
+bareboximage=barebox-${global.hostname}.bin
+bareboxenvimage=barebox-${global.hostname}.bin
if [ -n $user ]; then
bareboximage="$user"-"$bareboximage"
bareboxenvimage="$user"-"$bareboxenvimage"
kernelimage="$user"-"$kernelimage"
rootfsimage="$user"-"$rootfsimage"
- nfsroot="/home/$user/nfsroot/$hostname"
+ nfsroot="/home/$user/nfsroot/${global.hostname}"
else
nfsroot="/path/to/nfs/root"
fi
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 70797c182c..d0b5e3abdb 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -20,5 +20,6 @@ source "drivers/watchdog/Kconfig"
source "drivers/pwm/Kconfig"
source "drivers/dma/Kconfig"
source "drivers/gpio/Kconfig"
+source "drivers/of/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 28a5cb8f35..2a1f8b0f23 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -1,4 +1,5 @@
obj-y += base/
+obj-$(CONFIG_ARM_AMBA) += amba/
obj-y += net/
obj-y += serial/
obj-y += mtd/
@@ -19,3 +20,4 @@ obj-y += misc/
obj-y += dma/
obj-y += watchdog/
obj-y += gpio/
+obj-$(CONFIG_OFDEVICE) += of/
diff --git a/drivers/amba/Makefile b/drivers/amba/Makefile
new file mode 100644
index 0000000000..a4a511b322
--- /dev/null
+++ b/drivers/amba/Makefile
@@ -0,0 +1,2 @@
+
+obj-y += bus.o
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
new file mode 100644
index 0000000000..383c77ee13
--- /dev/null
+++ b/drivers/amba/bus.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
+ * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2.
+ */
+#include <common.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <linux/amba/bus.h>
+#include <io.h>
+
+#define to_amba_driver(d) container_of(d, struct amba_driver, drv)
+
+static const struct amba_id *
+amba_lookup(const struct amba_id *table, struct amba_device *dev)
+{
+ int ret = 0;
+
+ while (table->mask) {
+ ret = (dev->periphid & table->mask) == table->id;
+ if (ret)
+ break;
+ table++;
+ }
+
+ return ret ? table : NULL;
+}
+
+static int amba_match(struct device_d *dev, struct driver_d *drv)
+{
+ struct amba_device *pcdev = to_amba_device(dev);
+
+ struct amba_driver *pcdrv = to_amba_driver(drv);
+
+ return amba_lookup(pcdrv->id_table, pcdev) == NULL;
+}
+
+static int amba_get_enable_pclk(struct amba_device *pcdev)
+{
+ struct clk *pclk = clk_get(&pcdev->dev, "apb_pclk");
+ int ret;
+
+ pcdev->pclk = pclk;
+
+ if (IS_ERR(pclk))
+ return PTR_ERR(pclk);
+
+ ret = clk_enable(pclk);
+ if (ret) {
+ clk_put(pclk);
+ }
+
+ return ret;
+}
+
+static int amba_probe(struct device_d *dev)
+{
+ struct amba_device *pcdev = to_amba_device(dev);
+ struct amba_driver *pcdrv = to_amba_driver(dev->driver);
+ const struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev);
+
+ return pcdrv->probe(pcdev, id);
+}
+
+static void amba_remove(struct device_d *dev)
+{
+ struct amba_device *pcdev = to_amba_device(dev);
+ struct amba_driver *drv = to_amba_driver(dev->driver);
+
+ drv->remove(pcdev);
+}
+
+struct bus_type amba_bustype = {
+ .name = "amba",
+ .match = amba_match,
+ .probe = amba_probe,
+ .remove = amba_remove,
+};
+
+int amba_driver_register(struct amba_driver *drv)
+{
+ drv->drv.bus = &amba_bustype;
+
+ if (drv->probe)
+ drv->drv.probe = amba_probe;
+ if (drv->remove)
+ drv->drv.remove = amba_remove;
+
+ return register_driver(&drv->drv);
+}
+
+/**
+ * amba_device_add - add a previously allocated AMBA device structure
+ * @dev: AMBA device allocated by amba_device_alloc
+ * @parent: resource parent for this devices resources
+ *
+ * Claim the resource, and read the device cell ID if not already
+ * initialized. Register the AMBA device with the Linux device
+ * manager.
+ */
+int amba_device_add(struct amba_device *dev)
+{
+ u32 size;
+ void __iomem *tmp;
+ int i, ret;
+ struct resource *res = NULL;
+
+ dev->dev.bus = &amba_bustype;
+
+ /*
+ * Dynamically calculate the size of the resource
+ * and use this for iomap
+ */
+ size = resource_size(&dev->res);
+ res = request_iomem_region("amba", dev->res.start, dev->res.end);
+ if (!res)
+ return -ENOMEM;
+ dev->base = tmp = (void __force __iomem *)res->start;
+ if (!tmp) {
+ ret = -ENOMEM;
+ goto err_release;
+ }
+
+ /* Hard-coded primecell ID instead of plug-n-play */
+ if (dev->periphid != 0)
+ goto skip_probe;
+
+ ret = amba_get_enable_pclk(dev);
+ if (ret == 0) {
+ u32 pid, cid;
+
+ /*
+ * Read pid and cid based on size of resource
+ * they are located at end of region
+ */
+ for (pid = 0, i = 0; i < 4; i++)
+ pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) <<
+ (i * 8);
+ for (cid = 0, i = 0; i < 4; i++)
+ cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) <<
+ (i * 8);
+
+ if (cid == AMBA_CID)
+ dev->periphid = pid;
+
+ if (!dev->periphid)
+ ret = -ENODEV;
+ }
+
+ if (ret)
+ goto err_release;
+
+ skip_probe:
+ ret = register_device(&dev->dev);
+ if (ret)
+ goto err_release;
+
+ return ret;
+ err_release:
+ release_region(res);
+ return ret;
+}
+
+struct amba_device *
+amba_aphb_device_add(struct device_d *parent, const char *name, int id,
+ resource_size_t base, size_t size,
+ void *pdata, unsigned int periphid)
+{
+ struct amba_device *dev;
+ int ret;
+
+ dev = amba_device_alloc(name, id, base, size);
+
+ dev->periphid = periphid;
+ dev->dev.platform_data = pdata;
+ dev->dev.parent = parent;
+
+ ret = amba_device_add(dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return dev;
+}
+
+/**
+ * amba_device_alloc - allocate an AMBA device
+ * @name: sysfs name of the AMBA device
+ * @base: base of AMBA device
+ * @size: size of AMBA device
+ *
+ * Allocate and initialize an AMBA device structure. Returns %NULL
+ * on failure.
+ */
+struct amba_device *amba_device_alloc(const char *name, int id, resource_size_t base,
+ size_t size)
+{
+ struct amba_device *dev;
+
+ dev = xzalloc(sizeof(*dev));
+
+ strcpy(dev->dev.name, name);
+ dev->dev.id = id;
+ dev->res.start = base;
+ dev->res.end = base + size - 1;
+ dev->res.flags = IORESOURCE_MEM;
+
+ return dev;
+}
+
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 957ca5ac2a..e1f1c7a0ad 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -1,3 +1,4 @@
+obj-y += bus.o
obj-y += driver.o
obj-y += platform.o
obj-y += resource.o
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
new file mode 100644
index 0000000000..1dd139f7a3
--- /dev/null
+++ b/drivers/base/bus.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <errno.h>
+
+LIST_HEAD(bus_list);
+EXPORT_SYMBOL(bus_list);
+
+struct bus_type *get_bus_by_name(const char *name)
+{
+ struct bus_type *bus;
+
+ for_each_bus(bus) {
+ if(!strcmp(bus->name, name))
+ return bus;
+ }
+
+ return NULL;
+}
+
+int bus_register(struct bus_type *bus)
+{
+ if (get_bus_by_name(bus->name))
+ return -EEXIST;
+
+ INIT_LIST_HEAD(&bus->device_list);
+ INIT_LIST_HEAD(&bus->driver_list);
+
+ list_add_tail(&bus->list, &bus_list);
+
+ return 0;
+}
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 6cd428681f..c55fd23d76 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -85,8 +85,6 @@ static int match(struct driver_d *drv, struct device_d *dev)
dev->driver = drv;
- if (dev->bus != drv->bus)
- goto err_out;
if (dev->bus->match(dev, drv))
goto err_out;
if (dev->bus->probe(dev))
@@ -116,18 +114,29 @@ int register_device(struct device_d *new_device)
debug ("register_device: %s\n", dev_name(new_device));
- if (!new_device->bus) {
-// dev_err(new_device, "no bus type associated. Needs fixup\n");
+ if (!new_device->bus)
new_device->bus = &platform_bus;
+
+ if (new_device->bus == &platform_bus && new_device->resource) {
+ struct device_d *dev;
+
+ bus_for_each_device(new_device->bus, dev) {
+ if (!dev->resource)
+ continue;
+ if (dev->resource->start == new_device->resource->start) {
+ return -EBUSY;
+ }
+ }
}
list_add_tail(&new_device->list, &device_list);
+ list_add_tail(&new_device->bus_list, &new_device->bus->device_list);
INIT_LIST_HEAD(&new_device->children);
INIT_LIST_HEAD(&new_device->cdevs);
INIT_LIST_HEAD(&new_device->parameters);
INIT_LIST_HEAD(&new_device->active);
- for_each_driver(drv) {
+ bus_for_each_driver(new_device->bus, drv) {
if (!match(drv, new_device))
break;
}
@@ -159,6 +168,7 @@ int unregister_device(struct device_d *old_dev)
}
list_del(&old_dev->list);
+ list_del(&old_dev->bus_list);
list_del(&old_dev->active);
/* remove device from parents child list */
@@ -212,13 +222,14 @@ int register_driver(struct driver_d *drv)
}
list_add_tail(&drv->list, &driver_list);
+ list_add_tail(&drv->bus_list, &drv->bus->driver_list);
if (!drv->info)
drv->info = noinfo;
if (!drv->shortinfo)
drv->shortinfo = noshortinfo;
- for_each_device(dev)
+ bus_for_each_device(drv->bus, dev)
match(drv, dev);
return 0;
@@ -313,6 +324,25 @@ const char *dev_id(const struct device_d *dev)
return buf;
}
+int dev_printf(const struct device_d *dev, const char *format, ...)
+{
+ va_list args;
+ int ret = 0;
+
+ if (dev->driver && dev->driver->name)
+ ret += printf("%s ", dev->driver->name);
+
+ ret += printf("%s: ", dev_name(dev));
+
+ va_start(args, format);
+
+ ret += vprintf(format, args);
+
+ va_end(args);
+
+ return ret;
+}
+
void devices_shutdown(void)
{
struct device_d *dev;
@@ -357,6 +387,21 @@ static int do_devinfo_subtree(struct device_d *dev, int depth)
return 0;
}
+int dev_get_drvdata(struct device_d *dev, unsigned long *data)
+{
+ if (dev->of_id_entry) {
+ *data = dev->of_id_entry->data;
+ return 0;
+ }
+
+ if (dev->id_entry) {
+ *data = dev->id_entry->driver_data;
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
static int do_devinfo(int argc, char *argv[])
{
struct device_d *dev;
@@ -406,6 +451,12 @@ static int do_devinfo(int argc, char *argv[])
list_for_each_entry(param, &dev->parameters, list)
printf("%16s = %s\n", param->name, dev_get_param(dev, param->name));
+#ifdef CONFIG_OFDEVICE
+ if (dev->device_node) {
+ printf("\ndevice node: %s\n", dev->device_node->full_name);
+ of_print_nodes(dev->device_node, 0);
+ }
+#endif
}
return 0;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index e0dd9ea58e..8c80e8e26d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -21,10 +21,31 @@
*/
#include <common.h>
#include <driver.h>
+#include <errno.h>
+#include <init.h>
static int platform_match(struct device_d *dev, struct driver_d *drv)
{
- return strcmp(dev->name, drv->name) ? -1 : 0;
+ if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node &&
+ drv->of_compatible)
+ return of_match(dev, drv);
+
+ if (!strcmp(dev->name, drv->name))
+ return 0;
+
+ if (drv->id_table) {
+ struct platform_device_id *id = drv->id_table;
+
+ while (id->name) {
+ if (!strcmp(id->name, dev->name)) {
+ dev->id_entry = id;
+ return 0;
+ }
+ id++;
+ }
+ }
+
+ return -1;
}
static int platform_probe(struct device_d *dev)
@@ -44,15 +65,8 @@ struct bus_type platform_bus = {
.remove = platform_remove,
};
-#if 0
-LIST_HEAD(bus_list);
-EXPORT_SYMBOL(bus_list);
-
-int bus_register(struct bus_type *bus)
+static int plarform_init(void)
{
- list_add_tail(&bus->list, &bus_list);
-
- return 0;
+ return bus_register(&platform_bus);
}
-#endif
-
+pure_initcall(plarform_init);
diff --git a/drivers/eeprom/at25.c b/drivers/eeprom/at25.c
index 03d191eb90..5578c783ad 100644
--- a/drivers/eeprom/at25.c
+++ b/drivers/eeprom/at25.c
@@ -312,7 +312,7 @@ static struct driver_d at25_driver = {
static int at25_init(void)
{
- register_driver(&at25_driver);
+ spi_register_driver(&at25_driver);
return 0;
}
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index fa3b041534..118135182d 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -145,7 +145,7 @@ static int stmpe_gpio_probe(struct device_d *dev)
return ret;
}
- dev_info(dev, "probed stmpe gpiochip%d with base %d\n", dev->id, stmpegpio->chip.base);
+ dev_dbg(dev, "probed stmpe gpiochip%d with base %d\n", dev->id, stmpegpio->chip.base);
return 0;
}
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 3af2b3e66c..27fd256cf7 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <malloc.h>
#include <xfuncs.h>
+#include <init.h>
#include <i2c/i2c.h>
@@ -251,6 +252,7 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
strcpy(client->dev.name, chip->type);
client->dev.type_data = client;
client->dev.platform_data = chip->platform_data;
+ client->dev.bus = &i2c_bus;
client->adapter = adapter;
client->addr = chip->addr;
@@ -372,3 +374,31 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
return 0;
}
EXPORT_SYMBOL(i2c_add_numbered_adapter);
+
+static int i2c_match(struct device_d *dev, struct driver_d *drv)
+{
+ return strcmp(dev->name, drv->name) ? -1 : 0;
+}
+
+static int i2c_probe(struct device_d *dev)
+{
+ return dev->driver->probe(dev);
+}
+
+static void i2c_remove(struct device_d *dev)
+{
+ dev->driver->remove(dev);
+}
+
+struct bus_type i2c_bus = {
+ .name = "i2c",
+ .match = i2c_match,
+ .probe = i2c_probe,
+ .remove = i2c_remove,
+};
+
+static int i2c_bus_init(void)
+{
+ return bus_register(&i2c_bus);
+}
+pure_initcall(i2c_bus_init);
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index 585cab9e54..bb318e4e2d 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -335,7 +335,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
esdhc_write32(&regs->irqstat, -1);
/* Wait for the bus to be idle */
- ret = wait_on_timeout(100 * MSECOND,
+ ret = wait_on_timeout(SECOND,
!(esdhc_read32(&regs->prsstat) &
(PRSSTAT_CICHB | PRSSTAT_CIDHB)));
if (ret) {
@@ -567,16 +567,28 @@ static int fsl_esdhc_probe(struct device_d *dev)
return 0;
}
+static __maybe_unused struct of_device_id fsl_esdhc_compatible[] = {
+ {
+ .compatible = "fsl,imx51-esdhc",
+ }, {
+ .compatible = "fsl,imx53-esdhc",
+ }, {
+ .compatible = "fsl,imx6q-usdhc",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d fsl_esdhc_driver = {
- .name = "imx-esdhc",
- .probe = fsl_esdhc_probe,
+ .name = "imx-esdhc",
+ .probe = fsl_esdhc_probe,
+ .of_compatible = DRV_OF_COMPAT(fsl_esdhc_compatible),
};
static int fsl_esdhc_init_driver(void)
{
- register_driver(&fsl_esdhc_driver);
- return 0;
+ register_driver(&fsl_esdhc_driver);
+ return 0;
}
device_initcall(fsl_esdhc_init_driver);
-
diff --git a/drivers/mci/mci_spi.c b/drivers/mci/mci_spi.c
index a659ebb274..94f0ee3118 100644
--- a/drivers/mci/mci_spi.c
+++ b/drivers/mci/mci_spi.c
@@ -181,7 +181,7 @@ static uint mmc_spi_readdata(struct mmc_spi_host *host, void *xbuf,
mmc_spi_readbytes(host, bsize, buf);
mmc_spi_readbytes(host, 2, &crc);
#ifdef CONFIG_MMC_SPI_CRC_ON
- if (swab16(cyg_crc16(buf, bsize)) != crc) {
+ if (be16_to_cpu(cyg_crc16(buf, bsize)) != crc) {
dev_dbg(host->dev, "%s: CRC error\n", __func__);
r1 = R1_SPI_COM_CRC;
break;
@@ -212,7 +212,7 @@ static uint mmc_spi_writedata(struct mmc_spi_host *host, const void *xbuf,
while (bcnt--) {
#ifdef CONFIG_MMC_SPI_CRC_ON
- crc = swab16(cyg_crc16((u8 *)buf, bsize));
+ crc = be16_to_cpu(cyg_crc16((u8 *)buf, bsize));
#endif
mmc_spi_writebytes(host, 2, tok);
mmc_spi_writebytes(host, bsize, (void *)buf);
@@ -291,7 +291,7 @@ static int mmc_spi_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci
} else if (cmd->resp_type == MMC_RSP_R2) {
r1 = mmc_spi_readdata(host, cmd->response, 1, 16);
for (i = 0; i < 4; i++)
- cmd->response[i] = swab32(cmd->response[i]);
+ cmd->response[i] = be32_to_cpu(cmd->response[i]);
dev_dbg(host->dev, "MMC_RSP_R2 -> %x %x %x %x\n", cmd->response[0], cmd->response[1],
cmd->response[2], cmd->response[3]);
} else if (!data) {
@@ -299,7 +299,7 @@ static int mmc_spi_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci
case SD_CMD_SEND_IF_COND:
case MMC_CMD_SPI_READ_OCR:
mmc_spi_readbytes(host, 4, cmd->response);
- cmd->response[0] = swab32(cmd->response[0]);
+ cmd->response[0] = be32_to_cpu(cmd->response[0]);
break;
}
} else {
@@ -423,7 +423,7 @@ static struct driver_d spi_mci_driver = {
static int spi_mci_init_driver(void)
{
- register_driver(&spi_mci_driver);
+ spi_register_driver(&spi_mci_driver);
return 0;
}
diff --git a/drivers/mci/omap_hsmmc.c b/drivers/mci/omap_hsmmc.c
index e0b245b51c..e6f4e479f9 100644
--- a/drivers/mci/omap_hsmmc.c
+++ b/drivers/mci/omap_hsmmc.c
@@ -238,7 +238,7 @@ static int mmc_init_setup(struct mci_host *mci, struct device_d *dev)
start = get_time_ns();
while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
if (is_timeout(start, SECOND)) {
- dev_dbg(hsmmc->dev, "timedout waiting for cc2!\n");
+ dev_dbg(hsmmc->dev, "timeout waiting for reset done\n");
return -ETIMEDOUT;
}
}
diff --git a/drivers/mfd/lp3972.c b/drivers/mfd/lp3972.c
index 0f3093bd15..c5e6baae43 100644
--- a/drivers/mfd/lp3972.c
+++ b/drivers/mfd/lp3972.c
@@ -103,7 +103,7 @@ static struct driver_d lp_driver = {
static int lp_init(void)
{
- register_driver(&lp_driver);
+ i2c_register_driver(&lp_driver);
return 0;
}
diff --git a/drivers/mfd/mc13xxx.c b/drivers/mfd/mc13xxx.c
index 704446d019..4577816662 100644
--- a/drivers/mfd/mc13xxx.c
+++ b/drivers/mfd/mc13xxx.c
@@ -336,31 +336,51 @@ static int mc_probe(struct device_d *dev, enum mc13xxx_mode mode)
return 0;
}
+static __maybe_unused struct of_device_id mc13892_dt_ids[] = {
+ {
+ .compatible = "fsl,mc13892",
+ }, {
+ .compatible = "fsl,mc13783",
+ }, {
+ /* sentinel */
+ }
+};
+
+#ifdef CONFIG_I2C
static int mc_i2c_probe(struct device_d *dev)
{
return mc_probe(dev, MC13XXX_MODE_I2C);
}
-static int mc_spi_probe(struct device_d *dev)
-{
- return mc_probe(dev, MC13XXX_MODE_SPI);
-}
-
static struct driver_d mc_i2c_driver = {
.name = "mc13xxx-i2c",
.probe = mc_i2c_probe,
+ .of_compatible = DRV_OF_COMPAT(mc13892_dt_ids),
};
+static int mc_i2c_init(void)
+{
+ return i2c_register_driver(&mc_i2c_driver);
+}
+device_initcall(mc_i2c_init);
+#endif
+
+#ifdef CONFIG_SPI
+static int mc_spi_probe(struct device_d *dev)
+{
+ return mc_probe(dev, MC13XXX_MODE_SPI);
+}
+
static struct driver_d mc_spi_driver = {
.name = "mc13xxx-spi",
.probe = mc_spi_probe,
+ .of_compatible = DRV_OF_COMPAT(mc13892_dt_ids),
};
-static int mc_init(void)
+static int mc_spi_init(void)
{
- register_driver(&mc_i2c_driver);
- register_driver(&mc_spi_driver);
- return 0;
+ return spi_register_driver(&mc_spi_driver);
}
-device_initcall(mc_init);
+device_initcall(mc_spi_init);
+#endif
diff --git a/drivers/mfd/mc34704.c b/drivers/mfd/mc34704.c
index 0432a98f57..e22fb38393 100644
--- a/drivers/mfd/mc34704.c
+++ b/drivers/mfd/mc34704.c
@@ -134,7 +134,7 @@ static struct driver_d mc34704_driver = {
static int mc34704_init(void)
{
- register_driver(&mc34704_driver);
- return 0;
+ i2c_register_driver(&mc34704_driver);
+ return 0;
}
device_initcall(mc34704_init);
diff --git a/drivers/mfd/mc34708.c b/drivers/mfd/mc34708.c
index 02c58a997d..fdcc7d7d4b 100644
--- a/drivers/mfd/mc34708.c
+++ b/drivers/mfd/mc34708.c
@@ -266,31 +266,40 @@ static int mc_probe(struct device_d *dev, enum mc34708_mode mode)
return 0;
}
+#ifdef CONFIG_I2C
static int mc_i2c_probe(struct device_d *dev)
{
return mc_probe(dev, MC34708_MODE_I2C);
}
-static int mc_spi_probe(struct device_d *dev)
-{
- return mc_probe(dev, MC34708_MODE_SPI);
-}
-
static struct driver_d mc_i2c_driver = {
.name = "mc34708-i2c",
.probe = mc_i2c_probe,
};
+static int mc_i2c_init(void)
+{
+ return i2c_register_driver(&mc_i2c_driver);
+}
+
+device_initcall(mc_i2c_init);
+#endif
+
+#ifdef CONFIG_SPI
+static int mc_spi_probe(struct device_d *dev)
+{
+ return mc_probe(dev, MC34708_MODE_SPI);
+}
+
static struct driver_d mc_spi_driver = {
.name = "mc34708-spi",
.probe = mc_spi_probe,
};
-static int mc_init(void)
+static int mc_spi_init(void)
{
- register_driver(&mc_i2c_driver);
- register_driver(&mc_spi_driver);
- return 0;
+ return spi_register_driver(&mc_spi_driver);
}
-device_initcall(mc_init);
+device_initcall(mc_spi_init);
+#endif
diff --git a/drivers/mfd/mc9sdz60.c b/drivers/mfd/mc9sdz60.c
index 75d0789435..612817d502 100644
--- a/drivers/mfd/mc9sdz60.c
+++ b/drivers/mfd/mc9sdz60.c
@@ -146,7 +146,7 @@ static struct driver_d mc_driver = {
static int mc_init(void)
{
- register_driver(&mc_driver);
+ i2c_register_driver(&mc_driver);
return 0;
}
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
index 4af8b7b88c..12e95c16b4 100644
--- a/drivers/mfd/stmpe-i2c.c
+++ b/drivers/mfd/stmpe-i2c.c
@@ -146,7 +146,7 @@ static struct driver_d stmpe_driver = {
static int stmpe_init(void)
{
- register_driver(&stmpe_driver);
+ i2c_register_driver(&stmpe_driver);
return 0;
}
diff --git a/drivers/mfd/twl4030.c b/drivers/mfd/twl4030.c
index 191c91f36a..93097659c6 100644
--- a/drivers/mfd/twl4030.c
+++ b/drivers/mfd/twl4030.c
@@ -53,7 +53,7 @@ static struct driver_d twl_driver = {
static int twl_init(void)
{
- register_driver(&twl_driver);
+ i2c_register_driver(&twl_driver);
return 0;
}
diff --git a/drivers/mfd/twl6030.c b/drivers/mfd/twl6030.c
index 7ecfed8062..01728fd317 100644
--- a/drivers/mfd/twl6030.c
+++ b/drivers/mfd/twl6030.c
@@ -49,7 +49,7 @@ static struct driver_d twl_driver = {
static int twl_init(void)
{
- register_driver(&twl_driver);
+ i2c_register_driver(&twl_driver);
return 0;
}
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index a6132e8ac5..68ab70d4c6 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -79,7 +79,7 @@ static ssize_t mtd_write(struct cdev* cdev, const void *buf, size_t _count,
return -EINVAL;
}
- dev_dbg(cdev->dev, "write: 0x%08lx 0x%08lx\n", offset, count);
+ dev_dbg(cdev->dev, "write: offset: 0x%08lx count: 0x%zx\n", offset, count);
while (count) {
now = count > mtd->writesize ? mtd->writesize : count;
@@ -100,7 +100,7 @@ static ssize_t mtd_write(struct cdev* cdev, const void *buf, size_t _count,
ret = mtd->write(mtd, offset, now, &retlen,
buf);
dev_dbg(cdev->dev,
- "offset: 0x%08lx now: 0x%08lx retlen: 0x%08lx\n",
+ "offset: 0x%08lx now: 0x%zx retlen: 0x%zx\n",
offset, now, retlen);
}
if (ret)
diff --git a/drivers/mtd/mtdraw.c b/drivers/mtd/mtdraw.c
index 16157e9f48..f541802a84 100644
--- a/drivers/mtd/mtdraw.c
+++ b/drivers/mtd/mtdraw.c
@@ -128,7 +128,8 @@ static ssize_t mtdraw_read(struct cdev *cdev, void *buf, size_t count,
skip = offset % (mtd->writesize + mtd->oobsize);
while (ret > 0 && count > 0) {
- toread = min_t(int, count, mtd->writesize + mtd->oobsize);
+ toread = min_t(int, count,
+ mtd->writesize + mtd->oobsize - skip);
ret = mtdraw_read_unaligned(mtd, buf, toread,
skip, numpage++ * mtd->writesize);
buf += ret;
@@ -137,7 +138,7 @@ static ssize_t mtdraw_read(struct cdev *cdev, void *buf, size_t count,
retlen += ret;
}
if (ret < 0)
- printf("err %lu\n", ret);
+ printf("err %zd\n", ret);
else
ret = retlen;
return ret;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 37e57b32ce..fe9a6e7ab3 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1137,7 +1137,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
{
struct nand_flash_dev *type = NULL;
int i, dev_id, maf_idx;
- int tmp_id, tmp_manf;
+ int id_data[8];
int ret;
/* Select the device */
@@ -1166,13 +1166,13 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
/* Read manufacturer and device IDs */
- tmp_manf = chip->read_byte(mtd);
- tmp_id = chip->read_byte(mtd);
+ id_data[0] = chip->read_byte(mtd);
+ id_data[1] = chip->read_byte(mtd);
- if (tmp_manf != *maf_id || tmp_id != dev_id) {
+ if (id_data[0] != *maf_id || id_data[1] != dev_id) {
printk(KERN_ERR "%s: second ID read did not match "
"%02x,%02x against %02x,%02x\n", __func__,
- *maf_id, dev_id, tmp_manf, tmp_id);
+ *maf_id, dev_id, id_data[0], id_data[1]);
return ERR_PTR(-ENODEV);
}
@@ -1196,29 +1196,75 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
}
}
+ chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+
+ /* Read entire ID string */
+
+ for (i = 0; i < 8; i++)
+ id_data[i] = chip->read_byte(mtd);
+
if (!mtd->name)
mtd->name = type->name;
chip->chipsize = type->chipsize << 20;
- /* Newer devices have all the information in additional id bytes */
if (!type->pagesize) {
int extid;
/* The 3rd id byte holds MLC / multichip data */
- chip->cellinfo = chip->read_byte(mtd);
+ chip->cellinfo = id_data[2];
/* The 4th id byte is the important one */
- extid = chip->read_byte(mtd);
- /* Calc pagesize */
- mtd->writesize = 1024 << (extid & 0x3);
- extid >>= 2;
- /* Calc oobsize */
- mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
- extid >>= 2;
- /* Calc blocksize. Blocksize is multiples of 64KiB */
- mtd->erasesize = (64 * 1024) << (extid & 0x03);
- extid >>= 2;
- /* Get buswidth information */
- busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+ extid = id_data[3];
+
+ /*
+ * Field definitions are in the following datasheets:
+ * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
+ * New style (6 byte ID): Samsung K9GBG08U0M (p.40)
+ *
+ * Check for wraparound + Samsung ID + nonzero 6th byte
+ * to decide what to do.
+ */
+ if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
+ id_data[0] == NAND_MFR_SAMSUNG &&
+ (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+ id_data[5] != 0x00) {
+ /* Calc pagesize */
+ mtd->writesize = 2048 << (extid & 0x03);
+ extid >>= 2;
+ /* Calc oobsize */
+ switch (extid & 0x03) {
+ case 1:
+ mtd->oobsize = 128;
+ break;
+ case 2:
+ mtd->oobsize = 218;
+ break;
+ case 3:
+ mtd->oobsize = 400;
+ break;
+ default:
+ mtd->oobsize = 436;
+ break;
+ }
+ extid >>= 2;
+ /* Calc blocksize */
+ mtd->erasesize = (128 * 1024) <<
+ (((extid >> 1) & 0x04) | (extid & 0x03));
+ busw = 0;
+ } else {
+ /* Calc pagesize */
+ mtd->writesize = 1024 << (extid & 0x03);
+ extid >>= 2;
+ /* Calc oobsize */
+ mtd->oobsize = (8 << (extid & 0x01)) *
+ (mtd->writesize >> 9);
+ extid >>= 2;
+ /* Calc blocksize. Blocksize is multiples of 64KiB */
+ mtd->erasesize = (64 * 1024) << (extid & 0x03);
+ extid >>= 2;
+ /* Get buswidth information */
+ busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+ }
+
} else {
/*
@@ -1228,6 +1274,19 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
mtd->writesize = type->pagesize;
mtd->oobsize = mtd->writesize / 32;
busw = type->options & NAND_BUSWIDTH_16;
+
+ /*
+ * Check for Spansion/AMD ID + repeating 5th, 6th byte since
+ * some Spansion chips have erasesize that conflicts with size
+ * listed in nand_ids table
+ * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
+ */
+ if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
+ id_data[5] == 0x00 && id_data[6] == 0x00 &&
+ id_data[7] == 0x00 && mtd->writesize == 512) {
+ mtd->erasesize = 128 * 1024;
+ mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
+ }
}
/* Try to identify manufacturer */
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index cb53fc61ca..72593d44a8 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -118,6 +118,36 @@ struct nand_flash_dev nand_flash_ids[] = {
{__NANDSTR("NAND 2GiB 1,8V 16-bit"), 0xB5, 0, 2048, 0, LP_OPTIONS16},
{__NANDSTR("NAND 2GiB 3,3V 16-bit"), 0xC5, 0, 2048, 0, LP_OPTIONS16},
+ /* 32 Gigabit */
+ {__NANDSTR("NAND 4GiB 1,8V 8-bit"), 0xA7, 0, 4096, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 4GiB 3,3V 8-bit"), 0xD7, 0, 4096, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 4GiB 1,8V 16-bit"), 0xB7, 0, 4096, 0, LP_OPTIONS16},
+ {__NANDSTR("NAND 4GiB 3,3V 16-bit"), 0xC7, 0, 4096, 0, LP_OPTIONS16},
+
+ /* 64 Gigabit */
+ {__NANDSTR("NAND 8GiB 1,8V 8-bit"), 0xAE, 0, 8192, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 8GiB 3,3V 8-bit"), 0xDE, 0, 8192, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 8GiB 1,8V 16-bit"), 0xBE, 0, 8192, 0, LP_OPTIONS16},
+ {__NANDSTR("NAND 8GiB 3,3V 16-bit"), 0xCE, 0, 8192, 0, LP_OPTIONS16},
+
+ /* 128 Gigabit */
+ {__NANDSTR("NAND 16GiB 1,8V 8-bit"), 0x1A, 0, 16384, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 16GiB 3,3V 8-bit"), 0x3A, 0, 16384, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 16GiB 1,8V 16-bit"), 0x2A, 0, 16384, 0, LP_OPTIONS16},
+ {__NANDSTR("NAND 16GiB 3,3V 16-bit"), 0x4A, 0, 16384, 0, LP_OPTIONS16},
+
+ /* 256 Gigabit */
+ {__NANDSTR("NAND 32GiB 1,8V 8-bit"), 0x1C, 0, 32768, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 32GiB 3,3V 8-bit"), 0x3C, 0, 32768, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 32GiB 1,8V 16-bit"), 0x2C, 0, 32768, 0, LP_OPTIONS16},
+ {__NANDSTR("NAND 32GiB 3,3V 16-bit"), 0x4C, 0, 32768, 0, LP_OPTIONS16},
+
+ /* 512 Gigabit */
+ {__NANDSTR("NAND 64GiB 1,8V 8-bit"), 0x1E, 0, 65536, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 64GiB 3,3V 8-bit"), 0x3E, 0, 65536, 0, LP_OPTIONS},
+ {__NANDSTR("NAND 64GiB 1,8V 16-bit"), 0x2E, 0, 65536, 0, LP_OPTIONS16},
+ {__NANDSTR("NAND 64GiB 3,3V 16-bit"), 0x4E, 0, 65536, 0, LP_OPTIONS16},
+
/*
* Renesas AND 1 Gigabit. Those chips do not support extended id and
* have a strange page/block layout ! The chosen minimum erasesize is
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3c5f729db3..b3e5a83dc1 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -19,64 +19,71 @@ config HAS_DESIGNWARE_ETH
config ARCH_HAS_FEC_IMX
bool
-config MIIDEV
+config PHYLIB
bool
menu "Network drivers "
depends on NET
+source "drivers/net/phy/Kconfig"
+
config DRIVER_NET_CS8900
bool "cs8900 ethernet driver"
depends on HAS_CS8900
config DRIVER_NET_SMC911X
bool "smc911x ethernet driver"
- select MIIDEV
+ select PHYLIB
help
This option enables support for the SMSC LAN9[12]1[567]
ethernet chip.
config DRIVER_NET_SMC91111
bool "smc91111 ethernet driver"
- select MIIDEV
+ select PHYLIB
help
This option enables support for the SMSC LAN91C111
ethernet chip.
+config DRIVER_NET_DAVINCI_EMAC
+ bool "TI Davinci/OMAP EMAC ethernet driver"
+ depends on ARCH_DAVINCI || ARCH_OMAP3
+ select PHYLIB
+
config DRIVER_NET_DM9K
bool "Davicom dm9k[E|A|B] ethernet driver"
depends on HAS_DM9000
- select MIIDEV
+ select PHYLIB
config DRIVER_NET_NETX
bool "Hilscher Netx ethernet driver"
depends on HAS_NETX_ETHER
- select MIIDEV
+ select PHYLIB
config DRIVER_NET_AT91_ETHER
bool "at91 ethernet driver"
depends on HAS_AT91_ETHER
- select MIIDEV
+ select PHYLIB
config DRIVER_NET_MPC5200
bool "MPC5200 Ethernet driver"
depends on ARCH_MPC5200
- select MIIDEV
+ select PHYLIB
config DRIVER_NET_FEC_IMX
bool "i.MX FEC Ethernet driver"
depends on ARCH_HAS_FEC_IMX
- select MIIDEV
+ select PHYLIB
config DRIVER_NET_EP93XX
bool "EP93xx Ethernet driver"
depends on ARCH_EP93XX
- select MIIDEV
+ select PHYLIB
config DRIVER_NET_MACB
bool "macb Ethernet driver"
depends on HAS_MACB
- select MIIDEV
+ select PHYLIB
config DRIVER_NET_TAP
bool "tap Ethernet driver"
@@ -85,7 +92,7 @@ config DRIVER_NET_TAP
config DRIVER_NET_TSE
depends on NIOS2
bool "Altera TSE ethernet driver"
- select MIIDEV
+ select PHYLIB
help
This option enables support for the Altera TSE MAC.
@@ -100,14 +107,14 @@ config TSE_USE_DEDICATED_DESC_MEM
config DRIVER_NET_KS8851_MLL
bool "ks8851 mll ethernet driver"
- select MIIDEV
+ select PHYLIB
help
This option enables support for the Micrel KS8851 MLL
ethernet chip.
config DRIVER_NET_DESIGNWARE
bool "Designware Universal MAC ethernet driver"
- select MIIDEV
+ select PHYLIB
depends on HAS_DESIGNWARE_ETH
help
This option enables support for the Synopsys
@@ -121,9 +128,16 @@ config DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR
config DRIVER_NET_GIANFAR
bool "Gianfar Ethernet"
depends on ARCH_MPC85XX
- select MIIDEV
+ select PHYLIB
source "drivers/net/usb/Kconfig"
+config DRIVER_NET_MICREL
+ depends on SPI
+ bool "Micrel KSZ8864RMN Ethernet Switch driver"
+ help
+ This option enables support for enabling the Micrel
+ KSZ8864RMN Ethernet Switch over SPI.
+
endmenu
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 4d960e856f..4e6b49b191 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_DRIVER_NET_CS8900) += cs8900.o
obj-$(CONFIG_DRIVER_NET_SMC911X) += smc911x.o
obj-$(CONFIG_DRIVER_NET_SMC91111) += smc91111.o
+obj-$(CONFIG_DRIVER_NET_DAVINCI_EMAC) += davinci_emac.o
obj-$(CONFIG_DRIVER_NET_DM9K) += dm9k.o
obj-$(CONFIG_DRIVER_NET_NETX) += netx_eth.o
obj-$(CONFIG_DRIVER_NET_AT91_ETHER) += at91_ether.o
@@ -9,9 +10,10 @@ obj-$(CONFIG_DRIVER_NET_FEC_IMX) += fec_imx.o
obj-$(CONFIG_DRIVER_NET_EP93XX) += ep93xx.o
obj-$(CONFIG_DRIVER_NET_MACB) += macb.o
obj-$(CONFIG_DRIVER_NET_TAP) += tap.o
-obj-$(CONFIG_MIIDEV) += miidev.o
+obj-$(CONFIG_PHYLIB) += phy/
obj-$(CONFIG_NET_USB) += usb/
obj-$(CONFIG_DRIVER_NET_TSE) += altera_tse.o
obj-$(CONFIG_DRIVER_NET_KS8851_MLL) += ks8851_mll.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE) += designware.o
obj-$(CONFIG_DRIVER_NET_GIANFAR) += gianfar.o
+obj-$(CONFIG_DRIVER_NET_MICREL) += ksz8864rmn.o
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index 5353a68b85..aedd5dac5c 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -26,10 +26,10 @@
#include <common.h>
#include <net.h>
-#include <miidev.h>
#include <init.h>
#include <clock.h>
#include <linux/mii.h>
+#include <linux/phy.h>
#include <io.h>
#include <asm/dma-mapping.h>
@@ -247,10 +247,9 @@ static int tse_set_ethaddr(struct eth_device *edev, unsigned char *m)
return 0;
}
-static int tse_phy_read(struct mii_device *mdev, int phy_addr, int reg)
+static int tse_phy_read(struct mii_bus *bus, int phy_addr, int reg)
{
- struct eth_device *edev = mdev->edev;
- struct altera_tse_priv *priv = edev->priv;
+ struct altera_tse_priv *priv = bus->priv;
struct alt_tse_mac *mac_dev = priv->tse_regs;
uint32_t *mdio_regs;
@@ -261,10 +260,9 @@ static int tse_phy_read(struct mii_device *mdev, int phy_addr, int reg)
return readl(&mdio_regs[reg]) & 0xFFFF;
}
-static int tse_phy_write(struct mii_device *mdev, int phy_addr, int reg, int val)
+static int tse_phy_write(struct mii_bus *bus, int phy_addr, int reg, u16 val)
{
- struct eth_device *edev = mdev->edev;
- struct altera_tse_priv *priv = edev->priv;
+ struct altera_tse_priv *priv = bus->priv;
struct alt_tse_mac *mac_dev = priv->tse_regs;
uint32_t *mdio_regs;
@@ -347,9 +345,12 @@ static void tse_reset(struct eth_device *edev)
static int tse_eth_open(struct eth_device *edev)
{
struct altera_tse_priv *priv = edev->priv;
+ int ret;
- miidev_wait_aneg(priv->miidev);
- miidev_print_status(priv->miidev);
+ ret = phy_device_connect(edev, priv->miibus, priv->phy_addr, NULL, 0,
+ PHY_INTERFACE_MODE_NA);
+ if (ret)
+ return ret;
return 0;
}
@@ -488,15 +489,13 @@ static int tse_init_dev(struct eth_device *edev)
/* enable MAC */
writel(ALTERA_TSE_CMD_TX_ENA_MSK | ALTERA_TSE_CMD_RX_ENA_MSK, &mac_dev->command_config);
- miidev_restart_aneg(priv->miidev);
-
return 0;
}
static int tse_probe(struct device_d *dev)
{
struct altera_tse_priv *priv;
- struct mii_device *miidev;
+ struct mii_bus *miibus;
struct eth_device *edev;
struct alt_sgdma_descriptor *rx_desc;
struct alt_sgdma_descriptor *tx_desc;
@@ -505,7 +504,7 @@ static int tse_probe(struct device_d *dev)
#endif
edev = xzalloc(sizeof(struct eth_device));
priv = xzalloc(sizeof(struct altera_tse_priv));
- miidev = xzalloc(sizeof(struct mii_device));
+ miibus = xzalloc(sizeof(struct mii_bus));
edev->priv = priv;
@@ -527,7 +526,7 @@ static int tse_probe(struct device_d *dev)
if (!tx_desc) {
free(edev);
- free(miidev);
+ free(miibus);
return 0;
}
#endif
@@ -541,22 +540,19 @@ static int tse_probe(struct device_d *dev)
priv->rx_desc = rx_desc;
priv->tx_desc = tx_desc;
- priv->miidev = miidev;
+ priv->miibus = miibus;
- miidev->read = tse_phy_read;
- miidev->write = tse_phy_write;
- miidev->flags = 0;
- miidev->edev = edev;
- miidev->parent = dev;
+ miibus->read = tse_phy_read;
+ miibus->write = tse_phy_write;
+ miibus->priv = priv;
+ miibus->parent = dev;
if (dev->platform_data != NULL)
- miidev->address = *((int8_t *)(dev->platform_data));
- else {
- printf("No PHY address specified.\n");
- return -ENODEV;
- }
+ priv->phy_addr = *((int8_t *)(dev->platform_data));
+ else
+ priv->phy_addr = -1;
- mii_register(miidev);
+ mdiobus_register(miibus);
return eth_register(edev);
}
diff --git a/drivers/net/altera_tse.h b/drivers/net/altera_tse.h
index 866dbce8c3..5a66a7d289 100644
--- a/drivers/net/altera_tse.h
+++ b/drivers/net/altera_tse.h
@@ -292,7 +292,8 @@ struct altera_tse_priv {
void __iomem *sgdma_tx_regs;
void __iomem *rx_desc;
void __iomem *tx_desc;
- struct mii_device *miidev;
+ int phy_addr;
+ struct mii_bus *miibus;
};
#endif /* _ALTERA_TSE_H_ */
diff --git a/drivers/net/at91_ether.c b/drivers/net/at91_ether.c
index 3592141fc6..13ca745372 100644
--- a/drivers/net/at91_ether.c
+++ b/drivers/net/at91_ether.c
@@ -30,7 +30,6 @@
#include <driver.h>
#include <xfuncs.h>
#include <init.h>
-#include <miidev.h>
#include <asm/io.h>
#include <mach/hardware.h>
#include <mach/at91rm9200_emac.h>
@@ -40,18 +39,18 @@
#include <linux/mii.h>
#include <errno.h>
#include <asm/mmu.h>
+#include <linux/phy.h>
#include "at91_ether.h"
-#define SPEED_100 1
-#define DUPLEX_FULL 1
-
struct ether_device {
struct eth_device netdev;
- struct mii_device miidev;
+ struct mii_bus miibus;
struct rbf_t *rbfp;
struct rbf_t *rbfdt;
unsigned char *rbf_framebuf;
+ int phy_addr;
+ phy_interface_t interface;
};
#define to_ether(_nd) container_of(_nd, struct ether_device, netdev)
@@ -98,7 +97,7 @@ static inline int at91_phy_wait(void)
return 0;
}
-static int at91_ether_mii_read(struct mii_device *dev, int addr, int reg)
+static int at91_ether_mii_read(struct mii_bus *dev, int addr, int reg)
{
int value;
@@ -120,7 +119,7 @@ out:
return value;
}
-static int at91_ether_mii_write(struct mii_device *dev, int addr, int reg, int val)
+static int at91_ether_mii_write(struct mii_bus *dev, int addr, int reg, u16 val)
{
int ret;
@@ -136,19 +135,19 @@ static int at91_ether_mii_write(struct mii_device *dev, int addr, int reg, int v
return ret;
}
-static void update_linkspeed(struct mii_device *dev, int speed, int duplex)
+static void update_linkspeed(struct eth_device *edev)
{
unsigned int mac_cfg;
/* Update the MAC */
mac_cfg = at91_emac_read(AT91_EMAC_CFG) & ~(AT91_EMAC_SPD | AT91_EMAC_FD);
- if (speed == SPEED_100) {
- if (duplex == DUPLEX_FULL) /* 100 Full Duplex */
+ if (edev->phydev->speed == SPEED_100) {
+ if (edev->phydev->duplex)
mac_cfg |= AT91_EMAC_SPD | AT91_EMAC_FD;
else /* 100 Half Duplex */
mac_cfg |= AT91_EMAC_SPD;
} else {
- if (duplex == DUPLEX_FULL) /* 10 Full Duplex */
+ if (edev->phydev->duplex)
mac_cfg |= AT91_EMAC_FD;
else {} /* 10 Half Duplex */
}
@@ -161,11 +160,12 @@ static int at91_ether_open(struct eth_device *edev)
unsigned long ctl;
struct ether_device *etdev = to_ether(edev);
unsigned char *rbf_framebuf = etdev->rbf_framebuf;
+ int ret;
- miidev_wait_aneg(&etdev->miidev);
- miidev_print_status(&etdev->miidev);
-
- update_linkspeed(&etdev->miidev, SPEED_100, DUPLEX_FULL);
+ ret = phy_device_connect(edev, &etdev->miibus, etdev->phy_addr,
+ update_linkspeed, 0, etdev->interface);
+ if (ret)
+ return ret;
/* Clear internal statistics */
ctl = at91_emac_read(AT91_EMAC_CTL);
@@ -299,7 +299,7 @@ static int at91_ether_probe(struct device_d *dev)
unsigned int mac_cfg;
struct ether_device *ether_dev;
struct eth_device *edev;
- struct mii_device *miidev;
+ struct mii_bus *miibus;
unsigned long ether_hz;
struct clk *pclk;
struct at91_ether_platform_data *pdata;
@@ -314,7 +314,7 @@ static int at91_ether_probe(struct device_d *dev)
ether_dev = xzalloc(sizeof(struct ether_device));
edev = &ether_dev->netdev;
- miidev = &ether_dev->miidev;
+ miibus = &ether_dev->miibus;
edev->priv = ether_dev;
edev->init = at91_ether_init;
@@ -327,10 +327,9 @@ static int at91_ether_probe(struct device_d *dev)
ether_dev->rbf_framebuf = dma_alloc_coherent(MAX_RX_DESCR * MAX_RBUFF_SZ);
ether_dev->rbfdt = dma_alloc_coherent(sizeof(struct rbf_t) * MAX_RX_DESCR);
- miidev->address = pdata->phy_addr;
- miidev->read = at91_ether_mii_read;
- miidev->write = at91_ether_mii_write;
- miidev->edev = edev;
+ ether_dev->phy_addr = pdata->phy_addr;
+ miibus->read = at91_ether_mii_read;
+ miibus->write = at91_ether_mii_write;
/* Sanitize the clocks */
mac_cfg = at91_emac_read(AT91_EMAC_CFG);
@@ -347,12 +346,16 @@ static int at91_ether_probe(struct device_d *dev)
mac_cfg |= AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG;
- if (pdata->flags & AT91SAM_ETHER_RMII)
+ if (pdata->flags & AT91SAM_ETHER_RMII) {
+ ether_dev->interface = PHY_INTERFACE_MODE_RGMII;
mac_cfg |= AT91_EMAC_RMII;
+ } else {
+ ether_dev->interface = PHY_INTERFACE_MODE_MII;
+ }
at91_emac_write(AT91_EMAC_CFG, mac_cfg);
- mii_register(miidev);
+ mdiobus_register(miibus);
eth_register(edev);
return 0;
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
new file mode 100644
index 0000000000..7d4dbdcdd9
--- /dev/null
+++ b/drivers/net/davinci_emac.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de>
+ *
+ * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
+ * follows:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.c
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+
+ * Modifications:
+ * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
+ * ver 1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <clock.h>
+#include <net.h>
+#include <malloc.h>
+#include <init.h>
+#include <asm/mmu.h>
+#include <asm/system.h>
+#include <linux/phy.h>
+#include <mach/emac_defs.h>
+#include <net/davinci_emac.h>
+#include "davinci_emac.h"
+
+struct davinci_emac_priv {
+ struct device_d *dev;
+ struct eth_device edev;
+ struct mii_bus miibus;
+
+ /* EMAC Addresses */
+ void __iomem *adap_emac; /* = EMAC_BASE_ADDR */
+ void __iomem *adap_ewrap; /* = EMAC_WRAPPER_BASE_ADDR */
+ void __iomem *adap_mdio; /* = EMAC_MDIO_BASE_ADDR */
+
+ /* EMAC descriptors */
+ void __iomem *emac_desc_base; /* = EMAC_WRAPPER_RAM_ADDR */
+ void __iomem *emac_rx_desc; /* = EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE */
+ void __iomem *emac_tx_desc; /* = EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE */
+ void __iomem *emac_rx_active_head; /* = 0 */
+ void __iomem *emac_rx_active_tail; /* = 0 */
+ int emac_rx_queue_active; /* = 0 */
+
+ /* Receive packet buffers */
+ unsigned char *emac_rx_buffers; /* [EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)] */
+
+ /* PHY-specific information */
+ phy_interface_t interface;
+ uint8_t phy_addr;
+ uint32_t phy_flags;
+
+ /* mac_addr[0] goes out on the wire first */
+ uint8_t mac_addr[6];
+};
+
+#ifdef EMAC_HW_RAM_ADDR
+static inline uint32_t BD_TO_HW(void __iomem *x)
+{
+ if (x == 0)
+ return 0;
+
+ return (uint32_t)(x) - EMAC_WRAPPER_RAM_ADDR + EMAC_HW_RAM_ADDR;
+}
+
+static inline void __iomem *HW_TO_BD(uint32_t x)
+{
+ if (x == 0)
+ return 0;
+
+ return (struct emac_desc*)(x - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR);
+}
+#else
+#define BD_TO_HW(x) (x)
+#define HW_TO_BD(x) (x)
+#endif
+
+static void davinci_eth_mdio_enable(struct davinci_emac_priv *priv)
+{
+ uint32_t clkdiv;
+
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+
+ dev_dbg(priv->dev, "mdio_enable + 0x%08x\n",
+ readl(priv->adap_mdio + EMAC_MDIO_CONTROL));
+ writel((clkdiv & 0xff) |
+ MDIO_CONTROL_ENABLE |
+ MDIO_CONTROL_FAULT |
+ MDIO_CONTROL_FAULT_ENABLE,
+ priv->adap_mdio + EMAC_MDIO_CONTROL);
+ dev_dbg(priv->dev, "mdio_enable - 0x%08x\n",
+ readl(priv->adap_mdio + EMAC_MDIO_CONTROL));
+
+ while (readl(priv->adap_mdio + EMAC_MDIO_CONTROL) & MDIO_CONTROL_IDLE);
+}
+
+static int davinci_miibus_read(struct mii_bus *bus, int addr, int reg)
+{
+ struct davinci_emac_priv *priv = bus->priv;
+ uint16_t value;
+ int tmp;
+
+ while (readl(priv->adap_mdio + EMAC_MDIO_USERACCESS0) & MDIO_USERACCESS0_GO);
+
+ writel(MDIO_USERACCESS0_GO |
+ MDIO_USERACCESS0_WRITE_READ |
+ ((reg & 0x1f) << 21) |
+ ((addr & 0x1f) << 16),
+ priv->adap_mdio + EMAC_MDIO_USERACCESS0);
+
+ /* Wait for command to complete */
+ while ((tmp = readl(priv->adap_mdio + EMAC_MDIO_USERACCESS0)) & MDIO_USERACCESS0_GO);
+
+ if (tmp & MDIO_USERACCESS0_ACK) {
+ value = tmp & 0xffff;
+ dev_dbg(priv->dev, "davinci_miibus_read: addr=0x%02x reg=0x%02x value=0x%04x\n",
+ addr, reg, value);
+ return value;
+ }
+
+ return -1;
+}
+
+static int davinci_miibus_write(struct mii_bus *bus, int addr, int reg, u16 value)
+{
+ struct davinci_emac_priv *priv = bus->priv;
+ while (readl(priv->adap_mdio + EMAC_MDIO_USERACCESS0) & MDIO_USERACCESS0_GO);
+
+ dev_dbg(priv->dev, "davinci_miibus_write: addr=0x%02x reg=0x%02x value=0x%04x\n",
+ addr, reg, value);
+ writel(MDIO_USERACCESS0_GO |
+ MDIO_USERACCESS0_WRITE_WRITE |
+ ((reg & 0x1f) << 21) |
+ ((addr & 0x1f) << 16) |
+ (value & 0xffff),
+ priv->adap_mdio + EMAC_MDIO_USERACCESS0);
+
+ /* Wait for command to complete */
+ while (readl(priv->adap_mdio + EMAC_MDIO_USERACCESS0) & MDIO_USERACCESS0_GO);
+
+ return 0;
+}
+
+static int davinci_emac_get_ethaddr(struct eth_device *edev, unsigned char *adr)
+{
+ return -1;
+}
+
+/*
+ * This function must be called before emac_open() if you want to override
+ * the default mac address.
+ */
+static int davinci_emac_set_ethaddr(struct eth_device *edev, unsigned char *addr)
+{
+ struct davinci_emac_priv *priv = edev->priv;
+ int i;
+
+ for (i = 0; i < sizeof(priv->mac_addr); i++)
+ priv->mac_addr[i] = addr[i];
+ return 0;
+}
+
+static int davinci_emac_init(struct eth_device *edev)
+{
+ dev_dbg(&edev->dev, "* emac_init\n");
+ return 0;
+}
+
+static int davinci_emac_open(struct eth_device *edev)
+{
+ struct davinci_emac_priv *priv = edev->priv;
+ uint32_t clkdiv, cnt;
+ void __iomem *rx_desc;
+ unsigned long mac_hi, mac_lo;
+ int ret;
+
+ dev_dbg(priv->dev, "+ emac_open\n");
+
+ dev_dbg(priv->dev, "emac->TXIDVER: 0x%08x\n",
+ readl(priv->adap_emac + EMAC_TXIDVER));
+ dev_dbg(priv->dev, "emac->RXIDVER: 0x%08x\n",
+ readl(priv->adap_emac + EMAC_RXIDVER));
+
+ /* Reset EMAC module and disable interrupts in wrapper */
+ writel(1, priv->adap_emac + EMAC_SOFTRESET);
+ while (readl(priv->adap_emac + EMAC_SOFTRESET) != 0);
+ writel(1, priv->adap_ewrap + EMAC_EWRAP_SOFTRESET);
+ while (readl(priv->adap_ewrap + EMAC_EWRAP_SOFTRESET) != 0);
+
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C0RXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C1RXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C2RXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C0TXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C1TXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C2TXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C0MISCEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C1MISCEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C2MISCEN);
+
+ rx_desc = priv->emac_rx_desc;
+
+ /*
+ * Set MAC Addresses & Init multicast Hash to 0 (disable any multicast
+ * receive)
+ * Use channel 0 only - other channels are disabled
+ */
+ writel(0, priv->adap_emac + EMAC_MACINDEX);
+ mac_hi = (priv->mac_addr[3] << 24) |
+ (priv->mac_addr[2] << 16) |
+ (priv->mac_addr[1] << 8) |
+ (priv->mac_addr[0]);
+ mac_lo = (priv->mac_addr[5] << 8) |
+ (priv->mac_addr[4]);
+
+ writel(mac_hi, priv->adap_emac + EMAC_MACADDRHI);
+ writel(mac_lo | EMAC_MAC_ADDR_IS_VALID | EMAC_MAC_ADDR_MATCH,
+ priv->adap_emac + EMAC_MACADDRLO);
+
+ /* Set source MAC address - REQUIRED */
+ writel(mac_hi, priv->adap_emac + EMAC_MACSRCADDRHI);
+ writel(mac_lo, priv->adap_emac + EMAC_MACSRCADDRLO);
+
+ /* Set DMA head and completion pointers to 0 */
+ for(cnt = 0; cnt < 8; cnt++) {
+ writel(0, (void *)priv->adap_emac + EMAC_TX0HDP + 4 * cnt);
+ writel(0, (void *)priv->adap_emac + EMAC_RX0HDP + 4 * cnt);
+ writel(0, (void *)priv->adap_emac + EMAC_TX0CP + 4 * cnt);
+ writel(0, (void *)priv->adap_emac + EMAC_RX0CP + 4 * cnt);
+ }
+
+ /* Clear Statistics (do this before setting MacControl register) */
+ for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
+ writel(0, (void *)priv->adap_emac + EMAC_RXGOODFRAMES + 4 * cnt);
+
+ /* No multicast addressing */
+ writel(0, priv->adap_emac + EMAC_MACHASH1);
+ writel(0, priv->adap_emac + EMAC_MACHASH2);
+
+ writel(0x01, priv->adap_emac + EMAC_TXCONTROL);
+ writel(0x01, priv->adap_emac + EMAC_RXCONTROL);
+
+ /* Create RX queue and set receive process in place */
+ priv->emac_rx_active_head = priv->emac_rx_desc;
+ for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
+ writel(BD_TO_HW(rx_desc + EMAC_DESC_SIZE), rx_desc + EMAC_DESC_NEXT);
+ writel(&priv->emac_rx_buffers[cnt * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN)], rx_desc + EMAC_DESC_BUFFER);
+ writel(EMAC_MAX_ETHERNET_PKT_SIZE, rx_desc + EMAC_DESC_BUFF_OFF_LEN);
+ writel(EMAC_CPPI_OWNERSHIP_BIT, rx_desc + EMAC_DESC_PKT_FLAG_LEN);
+ rx_desc += EMAC_DESC_SIZE;
+ }
+
+ /* Set the last descriptor's "next" parameter to 0 to end the RX desc list */
+ rx_desc -= EMAC_DESC_SIZE;
+ writel(0, rx_desc + EMAC_DESC_NEXT);
+ priv->emac_rx_active_tail = rx_desc;
+ priv->emac_rx_queue_active = 1;
+
+ /* Enable TX/RX */
+ writel(EMAC_MAX_ETHERNET_PKT_SIZE, priv->adap_emac + EMAC_RXMAXLEN);
+ writel(0, priv->adap_emac + EMAC_RXBUFFEROFFSET);
+
+ /* No fancy configs - Use this for promiscous for debug - EMAC_RXMBPENABLE_RXCAFEN_ENABLE */
+ writel(EMAC_RXMBPENABLE_RXBROADEN, priv->adap_emac + EMAC_RXMBPENABLE);
+
+ /* Enable ch 0 only */
+ writel(0x01, priv->adap_emac + EMAC_RXUNICASTSET);
+
+ /* Enable MII interface and full duplex mode (using RMMI) */
+ writel((EMAC_MACCONTROL_MIIEN_ENABLE |
+ EMAC_MACCONTROL_FULLDUPLEX_ENABLE |
+ EMAC_MACCONTROL_RMIISPEED_100),
+ priv->adap_emac + EMAC_MACCONTROL);
+
+ /* Init MDIO & get link state */
+ clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1;
+ writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
+ priv->adap_mdio + EMAC_MDIO_CONTROL);
+
+ /* Start receive process */
+ writel(BD_TO_HW(priv->emac_rx_desc), priv->adap_emac + EMAC_RX0HDP);
+
+ ret = phy_device_connect(edev, &priv->miibus, priv->phy_addr, NULL,
+ priv->phy_flags, priv->interface);
+ if (ret)
+ return ret;
+
+ dev_dbg(priv->dev, "- emac_open\n");
+
+ return 0;
+}
+
+/* EMAC Channel Teardown */
+static void davinci_eth_ch_teardown(struct davinci_emac_priv *priv, int ch)
+{
+ uint32_t dly = 0xff;
+ uint32_t cnt;
+
+ dev_dbg(priv->dev, "+ emac_ch_teardown\n");
+
+ if (ch == EMAC_CH_TX) {
+ /* Init TX channel teardown */
+ writel(0, priv->adap_emac + EMAC_TXTEARDOWN);
+ for(cnt = 0; cnt != 0xfffffffc; cnt = readl(priv->adap_emac + EMAC_TX0CP)) {
+ /* Wait here for Tx teardown completion interrupt to occur
+ * Note: A task delay can be called here to pend rather than
+ * occupying CPU cycles - anyway it has been found that teardown
+ * takes very few cpu cycles and does not affect functionality */
+ dly--;
+ udelay(1);
+ if (dly == 0)
+ break;
+ }
+ writel(cnt, priv->adap_emac + EMAC_TX0CP);
+ writel(0, priv->adap_emac + EMAC_TX0HDP);
+ } else {
+ /* Init RX channel teardown */
+ writel(0, priv->adap_emac + EMAC_RXTEARDOWN);
+ for(cnt = 0; cnt != 0xfffffffc; cnt = readl(priv->adap_emac + EMAC_RX0CP)) {
+ /* Wait here for Rx teardown completion interrupt to occur
+ * Note: A task delay can be called here to pend rather than
+ * occupying CPU cycles - anyway it has been found that teardown
+ * takes very few cpu cycles and does not affect functionality */
+ dly--;
+ udelay(1);
+ if (dly == 0)
+ break;
+ }
+ writel(cnt, priv->adap_emac + EMAC_RX0CP);
+ writel(0, priv->adap_emac + EMAC_RX0HDP);
+ }
+
+ dev_dbg(priv->dev, "- emac_ch_teardown\n");
+}
+
+static void davinci_emac_halt(struct eth_device *edev)
+{
+ struct davinci_emac_priv *priv = edev->priv;
+
+ dev_dbg(priv->dev, "+ emac_halt\n");
+
+ davinci_eth_ch_teardown(priv, EMAC_CH_TX); /* TX Channel teardown */
+ davinci_eth_ch_teardown(priv, EMAC_CH_RX); /* RX Channel teardown */
+
+ /* Reset EMAC module and disable interrupts in wrapper */
+ writel(1, priv->adap_emac + EMAC_SOFTRESET);
+ writel(1, priv->adap_ewrap + EMAC_EWRAP_SOFTRESET);
+
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C0RXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C1RXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C2RXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C0TXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C1TXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C2TXEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C0MISCEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C1MISCEN);
+ writel(0, priv->adap_ewrap + EMAC_EWRAP_C2MISCEN);
+
+ dev_dbg(priv->dev, "- emac_halt\n");
+}
+
+/*
+ * This function sends a single packet on the network and returns
+ * positive number (number of bytes transmitted) or negative for error
+ */
+static int davinci_emac_send(struct eth_device *edev, void *packet, int length)
+{
+ struct davinci_emac_priv *priv = edev->priv;
+ uint64_t start;
+ int ret_status;
+
+ dev_dbg(priv->dev, "+ emac_send (length %d)\n", length);
+
+ /* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
+ if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
+ length = EMAC_MIN_ETHERNET_PKT_SIZE;
+ }
+
+ /* Populate the TX descriptor */
+ writel(0, priv->emac_tx_desc + EMAC_DESC_NEXT);
+ writel((uint8_t *) packet, priv->emac_tx_desc + EMAC_DESC_BUFFER);
+ writel((length & 0xffff), priv->emac_tx_desc + EMAC_DESC_BUFF_OFF_LEN);
+ writel(((length & 0xffff) | EMAC_CPPI_SOP_BIT |
+ EMAC_CPPI_OWNERSHIP_BIT |
+ EMAC_CPPI_EOP_BIT),
+ priv->emac_tx_desc + EMAC_DESC_PKT_FLAG_LEN);
+ dma_flush_range((ulong) packet, (ulong)packet + length);
+ /* Send the packet */
+ writel(BD_TO_HW(priv->emac_tx_desc), priv->adap_emac + EMAC_TX0HDP);
+
+ /* Wait for packet to complete or link down */
+ start = get_time_ns();
+ while (1) {
+ if (readl(priv->adap_emac + EMAC_TXINTSTATRAW) & 0x01) {
+ /* Acknowledge the TX descriptor */
+ writel(BD_TO_HW(priv->emac_tx_desc), priv->adap_emac + EMAC_TX0CP);
+ ret_status = 0;
+ break;
+ }
+ if (is_timeout(start, 100 * MSECOND)) {
+ ret_status = -ETIMEDOUT;
+ break;
+ }
+ }
+
+ dev_dbg(priv->dev, "- emac_send (ret_status %i)\n", ret_status);
+ return ret_status;
+}
+
+/*
+ * This function handles receipt of a packet from the network
+ */
+static int davinci_emac_recv(struct eth_device *edev)
+{
+ struct davinci_emac_priv *priv = edev->priv;
+ void __iomem *rx_curr_desc, *curr_desc, *tail_desc;
+ unsigned char *pkt;
+ int status, len, ret = -1;
+
+ dev_dbg(priv->dev, "+ emac_recv\n");
+
+ rx_curr_desc = priv->emac_rx_active_head;
+ status = readl(rx_curr_desc + EMAC_DESC_PKT_FLAG_LEN);
+ if (status & EMAC_CPPI_OWNERSHIP_BIT) {
+ ret = 0;
+ goto out;
+ }
+
+ if (status & EMAC_CPPI_RX_ERROR_FRAME) {
+ /* Error in packet - discard it and requeue desc */
+ dev_warn(priv->dev, "WARN: emac_rcv_pkt: Error in packet\n");
+ } else {
+ pkt = (unsigned char *)readl(rx_curr_desc + EMAC_DESC_BUFFER);
+ len = readl(rx_curr_desc + EMAC_DESC_BUFF_OFF_LEN) & 0xffff;
+ dev_dbg(priv->dev, "| emac_recv got packet (length %i)\n", len);
+ dma_inv_range((ulong)pkt,
+ (ulong)readl(rx_curr_desc + EMAC_DESC_BUFFER) + len);
+ net_receive(pkt, len);
+ ret = len;
+ }
+
+ /* Ack received packet descriptor */
+ writel(BD_TO_HW(rx_curr_desc), priv->adap_emac + EMAC_RX0CP);
+ curr_desc = rx_curr_desc;
+ priv->emac_rx_active_head = HW_TO_BD(readl(rx_curr_desc + EMAC_DESC_NEXT));
+
+ if (status & EMAC_CPPI_EOQ_BIT) {
+ if (priv->emac_rx_active_head) {
+ writel(BD_TO_HW(priv->emac_rx_active_head),
+ priv->adap_emac + EMAC_RX0HDP);
+ } else {
+ priv->emac_rx_queue_active = 0;
+ dev_info(priv->dev, "INFO:emac_rcv_packet: RX Queue not active\n");
+ }
+ }
+
+ /* Recycle RX descriptor */
+ writel(EMAC_MAX_ETHERNET_PKT_SIZE, rx_curr_desc + EMAC_DESC_BUFF_OFF_LEN);
+ writel(EMAC_CPPI_OWNERSHIP_BIT, rx_curr_desc + EMAC_DESC_PKT_FLAG_LEN);
+ writel(0, rx_curr_desc + EMAC_DESC_NEXT);
+
+ if (priv->emac_rx_active_head == 0) {
+ dev_info(priv->dev, "INFO: emac_rcv_pkt: active queue head = 0\n");
+ priv->emac_rx_active_head = curr_desc;
+ priv->emac_rx_active_tail = curr_desc;
+ if (priv->emac_rx_queue_active != 0) {
+ writel(BD_TO_HW(priv->emac_rx_active_head), priv->adap_emac + EMAC_RX0HDP);
+ dev_info(priv->dev, "INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
+ priv->emac_rx_queue_active = 1;
+ }
+ } else {
+ tail_desc = priv->emac_rx_active_tail;
+ priv->emac_rx_active_tail = curr_desc;
+ writel(BD_TO_HW(curr_desc), tail_desc + EMAC_DESC_NEXT);
+ status = readl(tail_desc + EMAC_DESC_PKT_FLAG_LEN);
+ if (status & EMAC_CPPI_EOQ_BIT) {
+ writel(BD_TO_HW(curr_desc), priv->adap_emac + EMAC_RX0HDP);
+ status &= ~EMAC_CPPI_EOQ_BIT;
+ writel(status, tail_desc + EMAC_DESC_PKT_FLAG_LEN);
+ }
+ }
+
+out:
+ dev_dbg(priv->dev, "- emac_recv\n");
+
+ return ret;
+}
+
+static int davinci_emac_probe(struct device_d *dev)
+{
+ struct davinci_emac_platform_data *pdata;
+ struct davinci_emac_priv *priv;
+ uint64_t start;
+ uint32_t phy_mask;
+
+ dev_dbg(dev, "+ emac_probe\n");
+
+ if (!dev->platform_data) {
+ dev_err(dev, "no platform_data\n");
+ return -ENODEV;
+ }
+ pdata = dev->platform_data;
+
+ priv = xzalloc(sizeof(*priv));
+ dev->priv = priv;
+
+ priv->dev = dev;
+
+ priv->adap_emac = dev_request_mem_region(dev, 0);
+ priv->adap_ewrap = dev_request_mem_region(dev, 1);
+ priv->adap_mdio = dev_request_mem_region(dev, 2);
+ priv->emac_desc_base = dev_request_mem_region(dev, 3);
+
+ /* EMAC descriptors */
+ priv->emac_rx_desc = priv->emac_desc_base + EMAC_RX_DESC_BASE;
+ priv->emac_tx_desc = priv->emac_desc_base + EMAC_TX_DESC_BASE;
+ priv->emac_rx_active_head = NULL;
+ priv->emac_rx_active_tail = NULL;
+ priv->emac_rx_queue_active = 0;
+
+ /* Receive packet buffers */
+ priv->emac_rx_buffers = xmemalign(4096, EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN));
+
+ priv->edev.priv = priv;
+ priv->edev.init = davinci_emac_init;
+ priv->edev.open = davinci_emac_open;
+ priv->edev.halt = davinci_emac_halt;
+ priv->edev.send = davinci_emac_send;
+ priv->edev.recv = davinci_emac_recv;
+ priv->edev.get_ethaddr = davinci_emac_get_ethaddr;
+ priv->edev.set_ethaddr = davinci_emac_set_ethaddr;
+ priv->edev.parent = dev;
+
+ davinci_eth_mdio_enable(priv);
+
+ start = get_time_ns();
+ while (1) {
+ phy_mask = readl(priv->adap_mdio + EMAC_MDIO_ALIVE);
+ if (phy_mask) {
+ dev_info(dev, "detected phy mask 0x%x\n", phy_mask);
+ phy_mask = ~phy_mask;
+ break;
+ }
+ if (is_timeout(start, 256 * MSECOND)) {
+ dev_err(dev, "no live phy, scanning all\n");
+ phy_mask = 0;
+ break;
+ }
+ }
+
+ if (pdata->interface_rmii)
+ priv->interface = PHY_INTERFACE_MODE_RMII;
+ else
+ priv->interface = PHY_INTERFACE_MODE_MII;
+ priv->phy_addr = pdata->phy_addr;
+ priv->phy_flags = pdata->force_link ? PHYLIB_FORCE_LINK : 0;
+
+ priv->miibus.read = davinci_miibus_read;
+ priv->miibus.write = davinci_miibus_write;
+ priv->miibus.priv = priv;
+ priv->miibus.parent = dev;
+ priv->miibus.phy_mask = phy_mask;
+
+ mdiobus_register(&priv->miibus);
+
+ eth_register(&priv->edev);
+
+ dev_dbg(dev, "- emac_probe\n");
+ return 0;
+}
+
+static void davinci_emac_remove(struct device_d *dev)
+{
+ struct davinci_emac_priv *priv = dev->priv;
+
+ davinci_emac_halt(&priv->edev);
+}
+
+static struct driver_d davinci_emac_driver = {
+ .name = "davinci_emac",
+ .probe = davinci_emac_probe,
+ .remove = davinci_emac_remove,
+};
+
+static int davinci_emac_register(void)
+{
+ register_driver(&davinci_emac_driver);
+ return 0;
+}
+
+device_initcall(davinci_emac_register);
diff --git a/drivers/net/davinci_emac.h b/drivers/net/davinci_emac.h
new file mode 100644
index 0000000000..c5fa018fb3
--- /dev/null
+++ b/drivers/net/davinci_emac.h
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Based on:
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * dm644x_emac.h
+ *
+ * TI DaVinci (DM644X) EMAC peripheral driver header for DV-EVM
+ *
+ * Copyright (C) 2005 Texas Instruments.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef _DAVINCI_EMAC_H_
+#define _DAVINCI_EMAC_H_
+
+/* PHY mask - set only those phy number bits where phy is/can be connected */
+#define EMAC_MDIO_PHY_NUM 1
+#define EMAC_MDIO_PHY_MASK (1 << EMAC_MDIO_PHY_NUM)
+
+/* Ethernet Min/Max packet size */
+#define EMAC_MIN_ETHERNET_PKT_SIZE 60
+#define EMAC_MAX_ETHERNET_PKT_SIZE 1518
+#define EMAC_PKT_ALIGN 18 /* 1518 + 18 = 1536 (packet aligned on 32 byte boundry) */
+
+/* Number of RX packet buffers
+ * NOTE: Only 1 buffer supported as of now
+ */
+#define EMAC_MAX_RX_BUFFERS 10
+
+/***********************************************
+ ******** Internally used macros ***************
+ ***********************************************/
+
+#define EMAC_CH_TX 1
+#define EMAC_CH_RX 0
+
+/* Each descriptor occupies 4 words, lets start RX desc's at 0 and
+ * reserve space for 64 descriptors max
+ */
+#define EMAC_RX_DESC_BASE 0x0
+#define EMAC_TX_DESC_BASE 0x1000
+
+/* EMAC Teardown value */
+#define EMAC_TEARDOWN_VALUE 0xfffffffc
+
+/* MII Status Register */
+#define MII_STATUS_REG 1
+
+/* Number of statistics registers */
+#define EMAC_NUM_STATS 36
+
+/* EMAC Descriptor Offsets */
+#define EMAC_DESC_NEXT 0x0 /* Pointer to next descriptor in chain */
+#define EMAC_DESC_BUFFER 0x4 /* Pointer to data buffer */
+#define EMAC_DESC_BUFF_OFF_LEN 0x8 /* Buffer Offset(MSW) and Length(LSW) */
+#define EMAC_DESC_PKT_FLAG_LEN 0xc /* Packet Flags(MSW) and Length(LSW) */
+#define EMAC_DESC_SIZE 0x10
+
+/* CPPI bit positions */
+#define EMAC_CPPI_SOP_BIT (0x80000000)
+#define EMAC_CPPI_EOP_BIT (0x40000000)
+#define EMAC_CPPI_OWNERSHIP_BIT (0x20000000)
+#define EMAC_CPPI_EOQ_BIT (0x10000000)
+#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT (0x08000000)
+#define EMAC_CPPI_PASS_CRC_BIT (0x04000000)
+
+#define EMAC_CPPI_RX_ERROR_FRAME (0x03fc0000)
+
+#define EMAC_MACCONTROL_MIIEN_ENABLE (0x20)
+#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1)
+#define EMAC_MACCONTROL_GIGABIT_ENABLE (1 << 7)
+#define EMAC_MACCONTROL_GIGFORCE (1 << 17)
+#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15)
+
+#define EMAC_MAC_ADDR_MATCH (1 << 19)
+#define EMAC_MAC_ADDR_IS_VALID (1 << 20)
+
+#define EMAC_RXMBPENABLE_RXCAFEN_ENABLE (0x200000)
+#define EMAC_RXMBPENABLE_RXBROADEN (0x2000)
+
+#define MDIO_CONTROL_IDLE (0x80000000)
+#define MDIO_CONTROL_ENABLE (0x40000000)
+#define MDIO_CONTROL_FAULT_ENABLE (0x40000)
+#define MDIO_CONTROL_FAULT (0x80000)
+#define MDIO_USERACCESS0_GO (0x80000000)
+#define MDIO_USERACCESS0_WRITE_READ (0x0)
+#define MDIO_USERACCESS0_WRITE_WRITE (0x40000000)
+#define MDIO_USERACCESS0_ACK (0x20000000)
+
+/* Ethernet MAC Registers */
+#define EMAC_TXIDVER 0x000
+#define EMAC_TXCONTROL 0x004
+#define EMAC_TXTEARDOWN 0x008
+#define EMAC_RXIDVER 0x010
+#define EMAC_RXCONTROL 0x014
+#define EMAC_RXTEARDOWN 0x018
+#define EMAC_TXINTSTATRAW 0x080
+#define EMAC_TXINTSTATMASKED 0x084
+#define EMAC_TXINTMASKSET 0x088
+#define EMAC_TXINTMASKCLEAR 0x08c
+#define EMAC_MACINVECTOR 0x090
+#define EMAC_MACEOIVECTOR 0x094
+#define EMAC_RXINTSTATRAW 0x0a0
+#define EMAC_RXINTSTATMASKED 0x0a4
+#define EMAC_RXINTMASKSET 0x0a8
+#define EMAC_RXINTMASKCLEAR 0x0ac
+#define EMAC_MACINTSTATRAW 0x0b0
+#define EMAC_MACINTSTATMASKED 0x0b4
+#define EMAC_MACINTMASKSET 0x0b8
+#define EMAC_MACINTMASKCLEAR 0x0bc
+#define EMAC_RXMBPENABLE 0x100
+#define EMAC_RXUNICASTSET 0x104
+#define EMAC_RXUNICASTCLEAR 0x108
+#define EMAC_RXMAXLEN 0x10c
+#define EMAC_RXBUFFEROFFSET 0x110
+#define EMAC_RXFILTERLOWTHRESH 0x114
+#define EMAC_RX0FLOWTHRESH 0x120
+#define EMAC_RX1FLOWTHRESH 0x124
+#define EMAC_RX2FLOWTHRESH 0x128
+#define EMAC_RX3FLOWTHRESH 0x12c
+#define EMAC_RX4FLOWTHRESH 0x130
+#define EMAC_RX5FLOWTHRESH 0x134
+#define EMAC_RX6FLOWTHRESH 0x138
+#define EMAC_RX7FLOWTHRESH 0x13c
+#define EMAC_RX0FREEBUFFER 0x140
+#define EMAC_RX1FREEBUFFER 0x144
+#define EMAC_RX2FREEBUFFER 0x148
+#define EMAC_RX3FREEBUFFER 0x14c
+#define EMAC_RX4FREEBUFFER 0x150
+#define EMAC_RX5FREEBUFFER 0x154
+#define EMAC_RX6FREEBUFFER 0x158
+#define EMAC_RX7FREEBUFFER 0x15c
+#define EMAC_MACCONTROL 0x160
+#define EMAC_MACSTATUS 0x164
+#define EMAC_EMCONTROL 0x168
+#define EMAC_FIFOCONTROL 0x16c
+#define EMAC_MACCONFIG 0x170
+#define EMAC_SOFTRESET 0x174
+#define EMAC_MACSRCADDRLO 0x1d0
+#define EMAC_MACSRCADDRHI 0x1d4
+#define EMAC_MACHASH1 0x1d8
+#define EMAC_MACHASH2 0x1dc
+#define EMAC_BOFFTEST 0x1e0
+#define EMAC_TPACETEST 0x1e4
+#define EMAC_RXPAUSE 0x1e8
+#define EMAC_TXPAUSE 0x1ec
+#define EMAC_RXGOODFRAMES 0x200
+#define EMAC_RXBCASTFRAMES 0x204
+#define EMAC_RXMCASTFRAMES 0x208
+#define EMAC_RXPAUSEFRAMES 0x20c
+#define EMAC_RXCRCERRORS 0x210
+#define EMAC_RXALIGNCODEERRORS 0x214
+#define EMAC_RXOVERSIZED 0x218
+#define EMAC_RXJABBER 0x21c
+#define EMAC_RXUNDERSIZED 0x220
+#define EMAC_RXFRAGMENTS 0x224
+#define EMAC_RXFILTERED 0x228
+#define EMAC_RXQOSFILTERED 0x22c
+#define EMAC_RXOCTETS 0x230
+#define EMAC_TXGOODFRAMES 0x234
+#define EMAC_TXBCASTFRAMES 0x238
+#define EMAC_TXMCASTFRAMES 0x23c
+#define EMAC_TXPAUSEFRAMES 0x240
+#define EMAC_TXDEFERRED 0x244
+#define EMAC_TXCOLLISION 0x248
+#define EMAC_TXSINGLECOLL 0x24c
+#define EMAC_TXMULTICOLL 0x250
+#define EMAC_TXEXCESSIVECOLL 0x254
+#define EMAC_TXLATECOLL 0x258
+#define EMAC_TXUNDERRUN 0x25c
+#define EMAC_TXCARRIERSENSE 0x260
+#define EMAC_TXOCTETS 0x264
+#define EMAC_FRAME64 0x268
+#define EMAC_FRAME65T127 0x26c
+#define EMAC_FRAME128T255 0x270
+#define EMAC_FRAME256T511 0x274
+#define EMAC_FRAME512T1023 0x278
+#define EMAC_FRAME1024TUP 0x27c
+#define EMAC_NETOCTETS 0x280
+#define EMAC_RXSOFOVERRUNS 0x284
+#define EMAC_RXMOFOVERRUNS 0x288
+#define EMAC_RXDMAOVERRUNS 0x28c
+#define EMAC_MACADDRLO 0x500
+#define EMAC_MACADDRHI 0x504
+#define EMAC_MACINDEX 0x508
+#define EMAC_TX0HDP 0x600
+#define EMAC_TX1HDP 0x604
+#define EMAC_TX2HDP 0x608
+#define EMAC_TX3HDP 0x60c
+#define EMAC_TX4HDP 0x610
+#define EMAC_TX5HDP 0x614
+#define EMAC_TX6HDP 0x618
+#define EMAC_TX7HDP 0x61c
+#define EMAC_RX0HDP 0x620
+#define EMAC_RX1HDP 0x624
+#define EMAC_RX2HDP 0x628
+#define EMAC_RX3HDP 0x62c
+#define EMAC_RX4HDP 0x630
+#define EMAC_RX5HDP 0x634
+#define EMAC_RX6HDP 0x638
+#define EMAC_RX7HDP 0x63c
+#define EMAC_TX0CP 0x640
+#define EMAC_TX1CP 0x644
+#define EMAC_TX2CP 0x648
+#define EMAC_TX3CP 0x64c
+#define EMAC_TX4CP 0x650
+#define EMAC_TX5CP 0x654
+#define EMAC_TX6CP 0x658
+#define EMAC_TX7CP 0x65c
+#define EMAC_RX0CP 0x660
+#define EMAC_RX1CP 0x664
+#define EMAC_RX2CP 0x668
+#define EMAC_RX3CP 0x66c
+#define EMAC_RX4CP 0x670
+#define EMAC_RX5CP 0x674
+#define EMAC_RX6CP 0x678
+#define EMAC_RX7CP 0x67c
+
+/* EMAC Wrapper Registers */
+#define EMAC_EWRAP_IDVER 0x00
+#define EMAC_EWRAP_SOFTRESET 0x04
+#define EMAC_EWRAP_INTCTRL 0x0c
+#define EMAC_EWRAP_C0RXTHRESHEN 0x10
+#define EMAC_EWRAP_C0RXEN 0x14
+#define EMAC_EWRAP_C0TXEN 0x18
+#define EMAC_EWRAP_C0MISCEN 0x1c
+#define EMAC_EWRAP_C1RXTHRESHEN 0x20
+#define EMAC_EWRAP_C1RXEN 0x24
+#define EMAC_EWRAP_C1TXEN 0x28
+#define EMAC_EWRAP_C1MISCEN 0x2c
+#define EMAC_EWRAP_C2RXTHRESHEN 0x30
+#define EMAC_EWRAP_C2RXEN 0x34
+#define EMAC_EWRAP_C2TXEN 0x38
+#define EMAC_EWRAP_C2MISCEN 0x3c
+#define EMAC_EWRAP_C0RXTHRESHSTAT 0x40
+#define EMAC_EWRAP_C0RXSTAT 0x44
+#define EMAC_EWRAP_C0TXSTAT 0x48
+#define EMAC_EWRAP_C0MISCSTAT 0x4c
+#define EMAC_EWRAP_C1RXTHRESHSTAT 0x50
+#define EMAC_EWRAP_C1RXSTAT 0x54
+#define EMAC_EWRAP_C1TXSTAT 0x58
+#define EMAC_EWRAP_C1MISCSTAT 0x5c
+#define EMAC_EWRAP_C2RXTHRESHSTAT 0x60
+#define EMAC_EWRAP_C2RXSTAT 0x64
+#define EMAC_EWRAP_C2TXSTAT 0x68
+#define EMAC_EWRAP_C2MISCSTAT 0x6c
+#define EMAC_EWRAP_C0RXIMAX 0x70
+#define EMAC_EWRAP_C0TXIMAX 0x74
+#define EMAC_EWRAP_C1RXIMAX 0x78
+#define EMAC_EWRAP_C1TXIMAX 0x7c
+#define EMAC_EWRAP_C2RXIMAX 0x80
+#define EMAC_EWRAP_C2TXIMAX 0x84
+
+/* EMAC MDIO Registers */
+#define EMAC_MDIO_VERSION 0x00
+#define EMAC_MDIO_CONTROL 0x04
+#define EMAC_MDIO_ALIVE 0x08
+#define EMAC_MDIO_LINK 0x0c
+#define EMAC_MDIO_LINKINTRAW 0x10
+#define EMAC_MDIO_LINKINTMASKED 0x14
+#define EMAC_MDIO_USERINTRAW 0x20
+#define EMAC_MDIO_USERINTMASKED 0x24
+#define EMAC_MDIO_USERINTMASKSET 0x28
+#define EMAC_MDIO_USERINTMASKCLEAR 0x2c
+#define EMAC_MDIO_USERACCESS0 0x80
+#define EMAC_MDIO_USERPHYSEL0 0x84
+#define EMAC_MDIO_USERACCESS1 0x88
+#define EMAC_MDIO_USERPHYSEL1 0x8c
+
+#endif /* _DAVINCI_EMAC_H_ */
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 379b4e39a5..2a87d26a51 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -29,15 +29,15 @@
#include <init.h>
#include <io.h>
#include <net.h>
-#include <miidev.h>
#include <asm/mmu.h>
#include <net/designware.h>
+#include <linux/phy.h>
#include "designware.h"
struct dw_eth_dev {
struct eth_device netdev;
- struct mii_device miidev;
+ struct mii_bus miibus;
void (*fix_mac_speed)(int speed);
u8 macaddr[6];
@@ -52,6 +52,7 @@ struct dw_eth_dev {
struct eth_mac_regs *mac_regs_p;
struct eth_dma_regs *dma_regs_p;
+ int phy_addr;
};
/* Speed specific definitions */
@@ -64,9 +65,9 @@ struct dw_eth_dev {
#define FULL_DUPLEX 2
-static int dwc_ether_mii_read(struct mii_device *dev, int addr, int reg)
+static int dwc_ether_mii_read(struct mii_bus *dev, int addr, int reg)
{
- struct dw_eth_dev *priv = dev->edev->priv;
+ struct dw_eth_dev *priv = dev->priv;
struct eth_mac_regs *mac_p = priv->mac_regs_p;
u64 start;
u32 miiaddr;
@@ -86,9 +87,9 @@ static int dwc_ether_mii_read(struct mii_device *dev, int addr, int reg)
return readl(&mac_p->miidata) & 0xffff;
}
-static int dwc_ether_mii_write(struct mii_device *dev, int addr, int reg, int val)
+static int dwc_ether_mii_write(struct mii_bus *dev, int addr, int reg, u16 val)
{
- struct dw_eth_dev *priv = dev->edev->priv;
+ struct dw_eth_dev *priv = dev->priv;
struct eth_mac_regs *mac_p = priv->mac_regs_p;
u64 start;
u32 miiaddr;
@@ -222,34 +223,37 @@ static int dwc_ether_init(struct eth_device *dev)
return 0;
}
-static int dwc_ether_open(struct eth_device *dev)
+static void dwc_update_linkspeed(struct eth_device *edev)
{
- struct dw_eth_dev *priv = dev->priv;
- struct eth_mac_regs *mac_p = priv->mac_regs_p;
- struct eth_dma_regs *dma_p = priv->dma_regs_p;
+ struct dw_eth_dev *priv = edev->priv;
u32 conf;
- int link, speed;
- miidev_wait_aneg(&priv->miidev);
- miidev_print_status(&priv->miidev);
- link = miidev_get_status(&priv->miidev);
-
- if (priv->fix_mac_speed) {
- speed = link & MIIDEV_STATUS_IS_1000MBIT ? 1000 :
- (link & MIIDEV_STATUS_IS_100MBIT ? 100 : 10);
- priv->fix_mac_speed(speed);
- }
+ if (priv->fix_mac_speed)
+ priv->fix_mac_speed(edev->phydev->speed);
conf = readl(&mac_p->conf);
- if (link & MIIDEV_STATUS_IS_FULL_DUPLEX)
+ if (edev->phydev->duplex)
conf |= FULLDPLXMODE;
else
conf &= ~FULLDPLXMODE;
- if (link & MIIDEV_STATUS_IS_1000MBIT)
+ if (edev->phydev->speed == SPEED_1000)
conf &= ~MII_PORTSELECT;
else
conf |= MII_PORTSELECT;
writel(conf, &mac_p->conf);
+}
+
+static int dwc_ether_open(struct eth_device *dev)
+{
+ struct dw_eth_dev *priv = dev->priv;
+ struct eth_mac_regs *mac_p = priv->mac_regs_p;
+ struct eth_dma_regs *dma_p = priv->dma_regs_p;
+ int ret;
+
+ ret = phy_device_connect(dev, &priv->miibus, priv->phy_addr,
+ 0, PHY_INTERFACE_MODE_NA);
+ if (ret)
+ return ret;
descs_init(dev);
@@ -373,7 +377,7 @@ static int dwc_ether_probe(struct device_d *dev)
{
struct dw_eth_dev *priv;
struct eth_device *edev;
- struct mii_device *miidev;
+ struct mii_bus *miibus;
void __iomem *base;
struct dwc_ether_platform_data *pdata = dev->platform_data;
@@ -397,7 +401,7 @@ static int dwc_ether_probe(struct device_d *dev)
priv->fix_mac_speed = pdata->fix_mac_speed;
edev = &priv->netdev;
- miidev = &priv->miidev;
+ miibus = &priv->miibus;
edev->priv = priv;
edev->init = dwc_ether_init;
@@ -408,12 +412,12 @@ static int dwc_ether_probe(struct device_d *dev)
edev->get_ethaddr = dwc_ether_get_ethaddr;
edev->set_ethaddr = dwc_ether_set_ethaddr;
- miidev->address = pdata->phy_addr;
- miidev->read = dwc_ether_mii_read;
- miidev->write = dwc_ether_mii_write;
- miidev->edev = edev;
+ priv->phy_addr = pdata->phy_addr;
+ miibus->read = dwc_ether_mii_read;
+ miibus->write = dwc_ether_mii_write;
+ miibus->priv = priv;
- mii_register(miidev);
+ mdiobus_register(miibus);
eth_register(edev);
return 0;
}
diff --git a/drivers/net/dm9k.c b/drivers/net/dm9k.c
index 0222d98f7b..ac18be26c0 100644
--- a/drivers/net/dm9k.c
+++ b/drivers/net/dm9k.c
@@ -26,12 +26,12 @@
#include <init.h>
#include <common.h>
#include <driver.h>
-#include <miidev.h>
#include <net.h>
#include <io.h>
#include <xfuncs.h>
#include <dm9000.h>
#include <errno.h>
+#include <linux/phy.h>
#define DM9K_ID 0x90000A46
#define CHIPR_DM9000A 0x19
@@ -160,7 +160,7 @@
struct dm9k {
void __iomem *iobase;
void __iomem *iodata;
- struct mii_device miidev;
+ struct mii_bus miibus;
int buswidth;
int srom;
uint8_t pckt[2048];
@@ -353,12 +353,11 @@ static void dm9k_wd(int b_width, void __iomem *port, const void *src, int length
/* ----------------- end of data move functions -------------------------- */
-static int dm9k_phy_read(struct mii_device *mdev, int addr, int reg)
+static int dm9k_phy_read(struct mii_bus *bus, int addr, int reg)
{
unsigned val;
- struct eth_device *edev = mdev->edev;
- struct device_d *dev = edev->parent;
- struct dm9k *priv = edev->priv;
+ struct dm9k *priv = bus->priv;
+ struct device_d *dev = &bus->dev;
/* Fill the phyxcer register into REG_0C */
dm9k_iow(priv, DM9K_EPAR, DM9K_PHY | reg);
@@ -374,11 +373,10 @@ static int dm9k_phy_read(struct mii_device *mdev, int addr, int reg)
return val;
}
-static int dm9k_phy_write(struct mii_device *mdev, int addr, int reg, int val)
+static int dm9k_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
{
- struct eth_device *edev = mdev->edev;
- struct device_d *dev = edev->parent;
- struct dm9k *priv = edev->priv;
+ struct dm9k *priv = bus->priv;
+ struct device_d *dev = &bus->dev;
/* Fill the phyxcer register into REG_0C */
dm9k_iow(priv, DM9K_EPAR, DM9K_PHY | reg);
@@ -397,7 +395,7 @@ static int dm9k_phy_write(struct mii_device *mdev, int addr, int reg, int val)
static int dm9k_check_id(struct dm9k *priv)
{
- struct device_d *dev = priv->miidev.parent;
+ struct device_d *dev = priv->miibus.parent;
u32 id;
char c;
@@ -461,7 +459,7 @@ static void dm9k_enable(struct dm9k *priv)
static void dm9k_reset(struct dm9k *priv)
{
- struct device_d *dev = priv->miidev.parent;
+ struct device_d *dev = priv->miibus.parent;
dev_dbg(dev, "%s\n", __func__);
dm9k_iow(priv, DM9K_NCR, NCR_RST);
@@ -472,9 +470,8 @@ static int dm9k_eth_open(struct eth_device *edev)
{
struct dm9k *priv = (struct dm9k *)edev->priv;
- miidev_wait_aneg(&priv->miidev);
- miidev_print_status(&priv->miidev);
- return 0;
+ return phy_device_connect(edev, &priv->miibus, 0, NULL,
+ 0, PHY_INTERFACE_MODE_NA);
}
static void dm9k_write_length(struct dm9k *priv, unsigned length)
@@ -485,7 +482,7 @@ static void dm9k_write_length(struct dm9k *priv, unsigned length)
static int dm9k_wait_for_trans_end(struct dm9k *priv)
{
- struct device_d *dev = priv->miidev.parent;
+ struct device_d *dev = priv->miibus.parent;
static const uint64_t toffs = 1 * SECOND;
uint8_t status;
uint64_t start = get_time_ns();
@@ -511,7 +508,7 @@ static int dm9k_wait_for_trans_end(struct dm9k *priv)
static int dm9k_eth_send(struct eth_device *edev, void *packet, int length)
{
struct dm9k *priv = (struct dm9k *)edev->priv;
- struct device_d *dev = priv->miidev.parent;
+ struct device_d *dev = priv->miibus.parent;
dev_dbg(dev, "%s: %d bytes\n", __func__, length);
@@ -537,7 +534,7 @@ static int dm9k_eth_send(struct eth_device *edev, void *packet, int length)
static int dm9k_check_for_rx_packet(struct dm9k *priv)
{
uint8_t status;
- struct device_d *dev = priv->miidev.parent;
+ struct device_d *dev = priv->miibus.parent;
status = dm9k_ior(priv, DM9K_ISR);
if (!(status & ISR_PR))
@@ -550,7 +547,7 @@ static int dm9k_check_for_rx_packet(struct dm9k *priv)
static int dm9k_validate_entry(struct dm9k *priv)
{
- struct device_d *dev = priv->miidev.parent;
+ struct device_d *dev = priv->miibus.parent;
uint8_t p_stat;
/*
@@ -696,9 +693,6 @@ static int dm9k_set_ethaddr(struct eth_device *edev, unsigned char *adr)
static int dm9k_init_dev(struct eth_device *edev)
{
- struct dm9k *priv = (struct dm9k *)edev->priv;
-
- miidev_restart_aneg(&priv->miidev);
return 0;
}
@@ -740,12 +734,10 @@ static int dm9k_probe(struct device_d *dev)
edev->get_ethaddr = dm9k_get_ethaddr;
edev->parent = dev;
- priv->miidev.read = dm9k_phy_read;
- priv->miidev.write = dm9k_phy_write;
- priv->miidev.address = 0;
- priv->miidev.flags = 0;
- priv->miidev.edev = edev;
- priv->miidev.parent = dev;
+ priv->miibus.read = dm9k_phy_read;
+ priv->miibus.write = dm9k_phy_write;
+ priv->miibus.priv = priv;
+ priv->miibus.parent = dev;
/* RESET device */
dm9k_reset(priv);
@@ -778,7 +770,7 @@ static int dm9k_probe(struct device_d *dev)
dm9k_enable(priv);
- mii_register(&priv->miidev);
+ mdiobus_register(&priv->miibus);
eth_register(edev);
return 0;
diff --git a/drivers/net/ep93xx.c b/drivers/net/ep93xx.c
index c28fb79e45..a14c0ea8e3 100644
--- a/drivers/net/ep93xx.c
+++ b/drivers/net/ep93xx.c
@@ -34,17 +34,17 @@
#include <command.h>
#include <init.h>
#include <malloc.h>
-#include <miidev.h>
#include <io.h>
#include <linux/types.h>
#include <mach/ep93xx-regs.h>
+#include <linux/phy.h>
#include "ep93xx.h"
#define EP93XX_MAX_PKT_SIZE 1536
-static int ep93xx_phy_read(struct mii_device *mdev, int phy_addr, int phy_reg);
-static int ep93xx_phy_write(struct mii_device *mdev, int phy_addr, int phy_reg,
- int value);
+static int ep93xx_phy_read(struct mii_bus *bus, int phy_addr, int phy_reg);
+static int ep93xx_phy_write(struct mii_bus *bus, int phy_addr, int phy_reg,
+ u16 value);
static inline struct ep93xx_eth_priv *ep93xx_get_priv(struct eth_device *edev)
{
@@ -199,9 +199,15 @@ static int ep93xx_eth_open(struct eth_device *edev)
struct ep93xx_eth_priv *priv = ep93xx_get_priv(edev);
struct mac_regs *regs = ep93xx_get_regs(edev);
int i;
+ int ret;
pr_debug("+ep93xx_eth_open\n");
+ ret = phy_device_connect(edev, &priv->miibus, 0, NULL,
+ 0, PHY_INTERFACE_MODE_NA);
+ if (ret)
+ return ret;
+
ep93xx_eth_reset(edev);
/* Reset the descriptor queues' current and end address values */
@@ -498,11 +504,10 @@ static int ep93xx_eth_probe(struct device_d *dev)
edev->set_ethaddr = ep93xx_eth_set_ethaddr;
edev->parent = dev;
- priv->miidev.read = ep93xx_phy_read;
- priv->miidev.write = ep93xx_phy_write;
- priv->miidev.address = 0;
- priv->miidev.flags = 0;
- priv->miidev.parent = dev;
+ priv->miibus.read = ep93xx_phy_read;
+ priv->miibus.write = ep93xx_phy_write;
+ priv->miibus.parent = dev;
+ priv->miibus.priv = edev;
priv->tx_dq.base = calloc(NUMTXDESC,
sizeof(struct tx_descriptor));
@@ -532,7 +537,7 @@ static int ep93xx_eth_probe(struct device_d *dev)
goto eth_probe_failed_3;
}
- mii_register(&priv->miidev);
+ mdiobus_register(&priv->miibus);
eth_register(edev);
ret = 0;
@@ -575,9 +580,9 @@ eth_probe_done:
/**
* Read a 16-bit value from an MII register.
*/
-static int ep93xx_phy_read(struct mii_device *mdev, int phy_addr, int phy_reg)
+static int ep93xx_phy_read(struct mii_bus *bus, int phy_addr, int phy_reg)
{
- struct mac_regs *regs = ep93xx_get_regs(mdev->edev);
+ struct mac_regs *regs = ep93xx_get_regs(bus->priv);
int value = -1;
uint32_t self_ctl;
@@ -618,10 +623,10 @@ static int ep93xx_phy_read(struct mii_device *mdev, int phy_addr, int phy_reg)
/**
* Write a 16-bit value to an MII register.
*/
-static int ep93xx_phy_write(struct mii_device *mdev, int phy_addr,
- int phy_reg, int value)
+static int ep93xx_phy_write(struct mii_bus *bus, int phy_addr,
+ int phy_reg, u16 value)
{
- struct mac_regs *regs = ep93xx_get_regs(mdev->edev);
+ struct mac_regs *regs = ep93xx_get_regs(bus->priv);
uint32_t self_ctl;
pr_debug("+ep93xx_phy_write\n");
diff --git a/drivers/net/ep93xx.h b/drivers/net/ep93xx.h
index 875715f9f6..4d50f70fe8 100644
--- a/drivers/net/ep93xx.h
+++ b/drivers/net/ep93xx.h
@@ -141,7 +141,7 @@ struct ep93xx_eth_priv {
struct tx_descriptor_queue tx_dq;
struct tx_status_queue tx_sq;
- struct mii_device miidev;
+ struct mii_bus miibus;
};
#endif
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 599a9b4099..453185a9f6 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -23,11 +23,11 @@
#include <net.h>
#include <init.h>
#include <driver.h>
-#include <miidev.h>
#include <fec.h>
#include <io.h>
#include <clock.h>
#include <xfuncs.h>
+#include <linux/phy.h>
#include <asm/mmu.h>
@@ -50,10 +50,9 @@ struct fec_frame {
/*
* MII-interface related functions
*/
-static int fec_miidev_read(struct mii_device *mdev, int phyAddr, int regAddr)
+static int fec_miibus_read(struct mii_bus *bus, int phyAddr, int regAddr)
{
- struct eth_device *edev = mdev->edev;
- struct fec_priv *fec = (struct fec_priv *)edev->priv;
+ struct fec_priv *fec = (struct fec_priv *)bus->priv;
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
@@ -93,11 +92,10 @@ static int fec_miidev_read(struct mii_device *mdev, int phyAddr, int regAddr)
return readl(fec->regs + FEC_MII_DATA);
}
-static int fec_miidev_write(struct mii_device *mdev, int phyAddr,
- int regAddr, int data)
+static int fec_miibus_write(struct mii_bus *bus, int phyAddr,
+ int regAddr, u16 data)
{
- struct eth_device *edev = mdev->edev;
- struct fec_priv *fec = (struct fec_priv *)edev->priv;
+ struct fec_priv *fec = (struct fec_priv *)bus->priv;
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
@@ -347,12 +345,20 @@ static int fec_init(struct eth_device *dev)
/* size of each buffer */
writel(FEC_MAX_PKT_SIZE, fec->regs + FEC_EMRBR);
- if (fec->xcv_type != SEVENWIRE)
- miidev_restart_aneg(&fec->miidev);
-
return 0;
}
+static void fec_update_linkspeed(struct eth_device *edev)
+{
+ struct fec_priv *fec = (struct fec_priv *)edev->priv;
+
+ if (edev->phydev->speed == SPEED_10) {
+ u32 rcntl = readl(fec->regs + FEC_R_CNTRL);
+ rcntl |= FEC_R_CNTRL_RMII_10T;
+ writel(rcntl, fec->regs + FEC_R_CNTRL);
+ }
+}
+
/**
* Start the FEC engine
* @param[in] edev Our device to handle
@@ -363,6 +369,17 @@ static int fec_open(struct eth_device *edev)
int ret;
u32 ecr;
+ if (fec->xcv_type != SEVENWIRE) {
+ ret = phy_device_connect(edev, &fec->miibus, fec->phy_addr,
+ fec_update_linkspeed, fec->phy_flags,
+ fec->interface);
+ if (ret)
+ return ret;
+
+ if (fec->phy_init)
+ fec->phy_init(edev->phydev);
+ }
+
/*
* Initialize RxBD/TxBD rings
*/
@@ -388,24 +405,6 @@ static int fec_open(struct eth_device *edev)
*/
fec_rx_task_enable(fec);
- if (fec->xcv_type != SEVENWIRE) {
- ret = miidev_wait_aneg(&fec->miidev);
- if (ret)
- return ret;
-
- ret = miidev_get_status(&fec->miidev);
- if (ret < 0)
- return ret;
-
- if (ret & MIIDEV_STATUS_IS_10MBIT) {
- u32 rcntl = readl(fec->regs + FEC_R_CNTRL);
- rcntl |= FEC_R_CNTRL_RMII_10T;
- writel(rcntl, fec->regs + FEC_R_CNTRL);
- }
-
- miidev_print_status(&fec->miidev);
- }
-
return 0;
}
@@ -659,14 +658,30 @@ static int fec_probe(struct device_d *dev)
fec->xcv_type = pdata->xcv_type;
if (fec->xcv_type != SEVENWIRE) {
- fec->miidev.read = fec_miidev_read;
- fec->miidev.write = fec_miidev_write;
- fec->miidev.address = pdata->phy_addr;
- fec->miidev.flags = pdata->xcv_type == MII10 ? MIIDEV_FORCE_10 : 0;
- fec->miidev.edev = edev;
- fec->miidev.parent = dev;
-
- mii_register(&fec->miidev);
+ fec->phy_init = pdata->phy_init;
+ fec->miibus.read = fec_miibus_read;
+ fec->miibus.write = fec_miibus_write;
+ fec->phy_addr = pdata->phy_addr;
+ switch (pdata->xcv_type) {
+ case RMII:
+ fec->interface = PHY_INTERFACE_MODE_RMII;
+ break;
+ case RGMII:
+ fec->interface = PHY_INTERFACE_MODE_RGMII;
+ break;
+ case MII10:
+ fec->phy_flags = PHYLIB_FORCE_10;
+ case MII100:
+ fec->interface = PHY_INTERFACE_MODE_MII;
+ break;
+ case SEVENWIRE:
+ fec->interface = PHY_INTERFACE_MODE_NA;
+ break;
+ }
+ fec->miibus.priv = fec;
+ fec->miibus.parent = dev;
+
+ mdiobus_register(&fec->miibus);
}
eth_register(edev);
diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h
index b75b4d6084..c8e758bc13 100644
--- a/drivers/net/fec_imx.h
+++ b/drivers/net/fec_imx.h
@@ -137,7 +137,11 @@ struct fec_priv {
int rbd_index; /* next receive BD to read */
struct buffer_descriptor __iomem *tbd_base; /* TBD ring */
int tbd_index; /* next transmit BD to write */
- struct mii_device miidev;
+ int phy_addr;
+ phy_interface_t interface;
+ u32 phy_flags;
+ struct mii_bus miibus;
+ void (*phy_init)(struct phy_device *dev);
};
/**
diff --git a/drivers/net/fec_mpc5200.c b/drivers/net/fec_mpc5200.c
index c3f2099b0f..c42d86f513 100644
--- a/drivers/net/fec_mpc5200.c
+++ b/drivers/net/fec_mpc5200.c
@@ -10,13 +10,12 @@
#include <mach/mpc5xxx.h>
#include <malloc.h>
#include <net.h>
+#include <fec.h>
#include <init.h>
-#include <miidev.h>
#include <driver.h>
#include <mach/sdma.h>
-#include <mach/fec.h>
#include <mach/clocks.h>
-#include <miidev.h>
+#include <linux/phy.h>
#include "fec_mpc5200.h"
#define CONFIG_PHY_ADDR 1 /* FIXME */
@@ -31,10 +30,9 @@ typedef struct {
/*
* MII-interface related functions
*/
-static int fec5xxx_miidev_read(struct mii_device *mdev, int phyAddr, int regAddr)
+static int fec5xxx_miibus_read(struct mii_bus *bus, int phyAddr, int regAddr)
{
- struct eth_device *edev = mdev->edev;
- mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)edev->priv;
+ mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)bus->priv;
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
@@ -70,11 +68,10 @@ static int fec5xxx_miidev_read(struct mii_device *mdev, int phyAddr, int regAddr
return fec->eth->mii_data;
}
-static int fec5xxx_miidev_write(struct mii_device *mdev, int phyAddr,
- int regAddr, int data)
+static int fec5xxx_miibus_write(struct mii_bus *bus, int phyAddr,
+ int regAddr, u16 data)
{
- struct eth_device *edev = mdev->edev;
- mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)edev->priv;
+ mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)bus->priv;
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
@@ -381,9 +378,6 @@ static int mpc5xxx_fec_init(struct eth_device *dev)
debug("mpc5xxx_fec_init... Done \n");
- if (fec->xcv_type != SEVENWIRE)
- miidev_restart_aneg(&fec->miidev);
-
return 0;
}
@@ -413,8 +407,8 @@ static int mpc5xxx_fec_open(struct eth_device *edev)
SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
if (fec->xcv_type != SEVENWIRE) {
- miidev_wait_aneg(&fec->miidev);
- miidev_print_status(&fec->miidev);
+ return phy_device_connect(edev, &fec->miibus, CONFIG_PHY_ADDR,
+ NULL, fec->phy_flags, fec->interface);
}
return 0;
@@ -556,7 +550,7 @@ static int mpc5xxx_fec_send(struct eth_device *dev, void *eth_data,
*/
if (fec->xcv_type != SEVENWIRE) {
uint16_t phyStatus;
- phyStatus = fec5xxx_miidev_read(&fec->miidev, 0, 0x1);
+ phyStatus = fec5xxx_miibus_read(&fec->miibus, 0, 0x1);
}
/*
@@ -657,7 +651,7 @@ static int mpc5xxx_fec_recv(struct eth_device *dev)
int mpc5xxx_fec_probe(struct device_d *dev)
{
- struct mpc5xxx_fec_platform_data *pdata = (struct mpc5xxx_fec_platform_data *)dev->platform_data;
+ struct fec_platform_data *pdata = dev->platform_data;
struct eth_device *edev;
mpc5xxx_fec_priv *fec;
@@ -683,14 +677,28 @@ int mpc5xxx_fec_probe(struct device_d *dev)
loadtask(0, 2);
if (fec->xcv_type != SEVENWIRE) {
- fec->miidev.read = fec5xxx_miidev_read;
- fec->miidev.write = fec5xxx_miidev_write;
- fec->miidev.address = CONFIG_PHY_ADDR;
- fec->miidev.flags = pdata->xcv_type == MII10 ? MIIDEV_FORCE_10 : 0;
- fec->miidev.edev = edev;
- fec->miidev.parent = dev;
-
- mii_register(&fec->miidev);
+ fec->miibus.read = fec5xxx_miibus_read;
+ fec->miibus.write = fec5xxx_miibus_write;
+ switch (pdata->xcv_type) {
+ case RMII:
+ fec->interface = PHY_INTERFACE_MODE_RMII;
+ break;
+ case RGMII:
+ fec->interface = PHY_INTERFACE_MODE_RGMII;
+ break;
+ case MII10:
+ fec->phy_flags = PHYLIB_FORCE_10;
+ case MII100:
+ fec->interface = PHY_INTERFACE_MODE_MII;
+ break;
+ case SEVENWIRE:
+ fec->interface = PHY_INTERFACE_MODE_NA;
+ break;
+ }
+ fec->miibus.priv = fec;
+ fec->miibus.parent = dev;
+
+ mdiobus_register(&fec->miibus);
}
eth_register(edev);
diff --git a/drivers/net/fec_mpc5200.h b/drivers/net/fec_mpc5200.h
index f6da3e598f..20ac60731c 100644
--- a/drivers/net/fec_mpc5200.h
+++ b/drivers/net/fec_mpc5200.h
@@ -260,7 +260,9 @@ typedef struct {
uint16_t usedTbdIndex; /* next transmit BD to clean */
uint16_t cleanTbdNum; /* the number of available transmit BDs */
- struct mii_device miidev;
+ phy_interface_t interface;
+ u32 phy_flags;
+ struct mii_bus miibus;
} mpc5xxx_fec_priv;
/* Ethernet parameter area */
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 19544de261..20fd102c7e 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -17,10 +17,10 @@
#include <net.h>
#include <init.h>
#include <driver.h>
-#include <miidev.h>
#include <command.h>
#include <errno.h>
#include <asm/io.h>
+#include <linux/phy.h>
#include "gianfar.h"
/* 2 seems to be the minimum number of TX descriptors to make it work. */
@@ -80,22 +80,16 @@ static void gfar_init_registers(void __iomem *regs)
static void gfar_adjust_link(struct eth_device *edev)
{
struct gfar_private *priv = edev->priv;
- struct device_d *mdev = priv->miidev.parent;
void __iomem *regs = priv->regs;
u32 ecntrl, maccfg2;
uint32_t status;
- status = miidev_get_status(&priv->miidev);
+ priv->link = edev->phydev->link;
+ priv->duplexity =edev->phydev->duplex;
- priv->link = status & MIIDEV_STATUS_IS_UP;
- if (status & MIIDEV_STATUS_IS_FULL_DUPLEX)
- priv->duplexity = 1;
- else
- priv->duplexity = 0;
-
- if (status & MIIDEV_STATUS_IS_1000MBIT)
+ if (edev->phydev->speed == SPEED_1000)
priv->speed = 1000;
- else if (status & MIIDEV_STATUS_IS_100MBIT)
+ if (edev->phydev->speed == SPEED_100)
priv->speed = 100;
else
priv->speed = 10;
@@ -128,18 +122,18 @@ static void gfar_adjust_link(struct eth_device *edev)
ecntrl |= GFAR_ECNTRL_R100;
break;
default:
- dev_info(mdev, "Speed is unknown\n");
+ dev_info(&edev->dev, "Speed is unknown\n");
break;
}
out_be32(regs + GFAR_ECNTRL_OFFSET, ecntrl);
out_be32(regs + GFAR_MACCFG2_OFFSET, maccfg2);
- dev_info(mdev, "Speed: %d, %s duplex\n", priv->speed,
+ dev_info(&edev->dev, "Speed: %d, %s duplex\n", priv->speed,
(priv->duplexity) ? "full" : "half");
} else {
- dev_info(mdev, "No link.\n");
+ dev_info(&edev->dev, "No link.\n");
}
}
@@ -184,8 +178,6 @@ static int gfar_init(struct eth_device *edev)
gfar_init_registers(regs);
- miidev_restart_aneg(&priv->miidev);
-
return 0;
}
@@ -194,6 +186,12 @@ static int gfar_open(struct eth_device *edev)
int ix;
struct gfar_private *priv = edev->priv;
void __iomem *regs = priv->regs;
+ int ret;
+
+ ret = phy_device_connect(edev, &priv->miibus, priv->phyaddr,
+ gfar_adjust_link, 0, PHY_INTERFACE_MODE_NA);
+ if (ret)
+ return ret;
/* Point to the buffer descriptors */
out_be32(regs + GFAR_TBASE0_OFFSET, (unsigned int)priv->txbd);
@@ -215,9 +213,6 @@ static int gfar_open(struct eth_device *edev)
}
priv->txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP;
- miidev_wait_aneg(&priv->miidev);
- gfar_adjust_link(edev);
-
/* Enable Transmit and Receive */
setbits_be32(regs + GFAR_MACCFG1_OFFSET, GFAR_MACCFG1_RX_EN |
GFAR_MACCFG1_TX_EN);
@@ -437,11 +432,10 @@ static int gfar_recv(struct eth_device *edev)
}
/* Read a MII PHY register. */
-static int gfar_miiphy_read(struct mii_device *mdev, int addr, int reg)
+static int gfar_miiphy_read(struct mii_bus *bus, int addr, int reg)
{
- struct eth_device *edev = mdev->edev;
- struct device_d *dev = edev->parent;
- struct gfar_private *priv = edev->priv;
+ struct device_d *dev = bus->parent;
+ struct gfar_private *priv = bus->priv;
int ret;
ret = gfar_local_mdio_read(priv->phyregs, addr, reg);
@@ -452,12 +446,11 @@ static int gfar_miiphy_read(struct mii_device *mdev, int addr, int reg)
}
/* Write a MII PHY register. */
-static int gfar_miiphy_write(struct mii_device *mdev, int addr, int reg,
- int value)
+static int gfar_miiphy_write(struct mii_bus *bus, int addr, int reg,
+ u16 value)
{
- struct eth_device *edev = mdev->edev;
- struct device_d *dev = edev->parent;
- struct gfar_private *priv = edev->priv;
+ struct device_d *dev = bus->parent;
+ struct gfar_private *priv = bus->priv;
unsigned short val = value;
int ret;
@@ -520,16 +513,14 @@ static int gfar_probe(struct device_d *dev)
udelay(2);
clrbits_be32(priv->regs + GFAR_MACCFG1_OFFSET, GFAR_MACCFG1_SOFT_RESET);
- priv->miidev.read = gfar_miiphy_read;
- priv->miidev.write = gfar_miiphy_write;
- priv->miidev.address = priv->phyaddr;
- priv->miidev.flags = 0;
- priv->miidev.edev = edev;
- priv->miidev.parent = dev;
+ priv->miibus.read = gfar_miiphy_read;
+ priv->miibus.write = gfar_miiphy_write;
+ priv->miibus.priv = priv;
+ priv->miibus.parent = dev;
gfar_init_phy(edev);
- mii_register(&priv->miidev);
+ mdiobus_register(&priv->miibus);
return eth_register(edev);
}
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index a4ad99e3b7..b52cc5ab3b 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -269,7 +269,7 @@ struct gfar_private {
void __iomem *phyregs;
void __iomem *phyregs_sgmii;
struct phy_info *phyinfo;
- struct mii_device miidev;
+ struct mii_bus miibus;
volatile struct txbd8 *txbd;
volatile struct rxbd8 *rxbd;
uint txidx;
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
index 71391cc763..926c4335ea 100644
--- a/drivers/net/ks8851_mll.c
+++ b/drivers/net/ks8851_mll.c
@@ -26,13 +26,13 @@
#include <command.h>
#include <net.h>
-#include <miidev.h>
#include <malloc.h>
#include <init.h>
#include <xfuncs.h>
#include <errno.h>
#include <clock.h>
#include <io.h>
+#include <linux/phy.h>
#define MAX_RECV_FRAMES 32
#define MAX_BUF_SIZE 2048
@@ -372,7 +372,7 @@
struct ks_net {
struct eth_device edev;
- struct mii_device miidev;
+ struct mii_bus miibus;
void __iomem *hw_addr;
void __iomem *hw_addr_cmd;
struct platform_device *pdev;
@@ -536,10 +536,9 @@ static int ks_phy_reg(int reg)
* caller. The mii-tool that the driver was tested with takes any -ve error
* as real PHY capabilities, thus displaying incorrect data to the user.
*/
-static int ks_phy_read(struct mii_device *mdev, int addr, int reg)
+static int ks_phy_read(struct mii_bus *bus, int addr, int reg)
{
- struct eth_device *edev = mdev->edev;
- struct ks_net *priv = (struct ks_net *)edev->priv;
+ struct ks_net *priv = (struct ks_net *)bus->priv;
int ksreg;
int result;
@@ -552,10 +551,9 @@ static int ks_phy_read(struct mii_device *mdev, int addr, int reg)
return result;
}
-static int ks_phy_write(struct mii_device *mdev, int addr, int reg, int val)
+static int ks_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
{
- struct eth_device *edev = mdev->edev;
- struct ks_net *priv = (struct ks_net *)edev->priv;
+ struct ks_net *priv = (struct ks_net *)bus->priv;
int ksreg;
ksreg = ks_phy_reg(reg);
@@ -783,11 +781,14 @@ static int ks8851_eth_open(struct eth_device *edev)
{
struct ks_net *priv = (struct ks_net *)edev->priv;
struct device_d *dev = &edev->dev;
+ int ret;
ks_enable_qmu(priv);
- miidev_wait_aneg(&priv->miidev);
- miidev_print_status(&priv->miidev);
+ ret = phy_device_connect(edev, &priv->miibus, 1, NULL,
+ 0, PHY_INTERFACE_MODE_NA);
+ if (ret)
+ return ret;
dev_dbg(dev, "eth_open\n");
@@ -796,9 +797,6 @@ static int ks8851_eth_open(struct eth_device *edev)
static int ks8851_init_dev(struct eth_device *edev)
{
- struct ks_net *priv = (struct ks_net *)edev->priv;
-
- miidev_restart_aneg(&priv->miidev);
return 0;
}
@@ -842,12 +840,10 @@ static int ks8851_probe(struct device_d *dev)
edev->parent = dev;
/* setup mii state */
- ks->miidev.read = ks_phy_read;
- ks->miidev.write = ks_phy_write;
- ks->miidev.address = 1;
- ks->miidev.flags = 0;
- ks->miidev.edev = edev;
- ks->miidev.parent = dev;
+ ks->miibus.read = ks_phy_read;
+ ks->miibus.write = ks_phy_write;
+ ks->miibus.priv = ks;
+ ks->miibus.parent = dev;
/* simple check for a valid chip being connected to the bus */
@@ -868,7 +864,7 @@ static int ks8851_probe(struct device_d *dev)
ks_soft_reset(ks, GRR_GSR);
ks_setup(ks);
- mii_register(&ks->miidev);
+ mdiobus_register(&ks->miibus);
eth_register(edev);
dev_dbg(dev, "%s MARL 0x%04x MARM 0x%04x MARH 0x%04x\n", __func__,
ks_rdreg16(ks, KS_MARL), ks_rdreg16(ks, KS_MARM),
diff --git a/drivers/net/ksz8864rmn.c b/drivers/net/ksz8864rmn.c
new file mode 100644
index 0000000000..5845960f6c
--- /dev/null
+++ b/drivers/net/ksz8864rmn.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2012 Jan Luebbe, Pengutronix
+ *
+ * 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 <spi/spi.h>
+#include <errno.h>
+
+#define REG_ID0 0x00
+#define REG_ID1 0x01
+
+#define REG_GC00 0x02
+#define REG_GC01 0x03
+#define REG_GC02 0x04
+#define REG_GC03 0x05
+#define REG_GC04 0x06
+#define REG_GC05 0x07
+#define REG_GC06 0x08
+#define REG_GC07 0x09
+#define REG_GC08 0x0a
+#define REG_GC09 0x0b
+#define REG_GC10 0x0c
+#define REG_GC11 0x0d
+
+#define REG_PSTAT1(p) (0x10 * p + 0xe)
+#define REG_PSTAT2(p) (0x10 * p + 0xf)
+
+#define CMD_WRITE 0x02
+#define CMD_READ 0x03
+
+struct micrel_switch_priv {
+ struct cdev cdev;
+ struct spi_device *spi;
+};
+
+static int micrel_switch_read_reg(struct spi_device *spi, uint8_t reg)
+{
+ uint8_t tx[2];
+ uint8_t rx[1];
+ int ret;
+
+ tx[0] = CMD_READ;
+ tx[1] = reg;
+
+ ret = spi_write_then_read(spi, tx, 2, rx, 1);
+ if (ret < 0)
+ return ret;
+
+ return rx[0];
+}
+
+static void micrel_switch_write_reg(struct spi_device *spi, uint8_t reg, uint8_t val)
+{
+ uint8_t tx[3];
+
+ tx[0] = CMD_WRITE;
+ tx[1] = reg;
+ tx[2] = val;
+
+ spi_write_then_read(spi, tx, 3, NULL, 0);
+}
+
+static int micrel_switch_enable_set(struct device_d *dev, struct param_d *param,
+ const char *val)
+{
+ struct spi_device *spi = (struct spi_device *)dev->type_data;
+ int enable;
+ char *new;
+
+ if (!val)
+ return dev_param_set_generic(dev, param, NULL);
+
+ enable = simple_strtoul(val, NULL, 0);
+
+ if (enable) {
+ micrel_switch_write_reg(spi, REG_ID1, 1);
+ new = "1";
+ } else {
+ micrel_switch_write_reg(spi, REG_ID1, 0);
+ new = "0";
+ }
+
+ dev_param_set_generic(dev, param, new);
+
+ return 0;
+}
+
+static ssize_t micel_switch_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
+{
+ int i, ret;
+ uint8_t *buf = _buf;
+ struct micrel_switch_priv *priv = cdev->priv;
+
+ for (i = 0; i < count; i++) {
+ ret = micrel_switch_read_reg(priv->spi, offset);
+ if (ret < 0)
+ return ret;
+ *buf = ret;
+ buf++;
+ offset++;
+ }
+
+ return count;
+}
+
+static ssize_t micel_switch_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
+{
+ int i;
+ const uint8_t *buf = _buf;
+ struct micrel_switch_priv *priv = cdev->priv;
+
+ for (i = 0; i < count; i++) {
+ micrel_switch_write_reg(priv->spi, offset, *buf);
+ buf++;
+ offset++;
+ }
+
+ return count;
+}
+
+static struct file_operations micrel_switch_ops = {
+ .read = micel_switch_read,
+ .write = micel_switch_write,
+ .lseek = dev_lseek_default,
+};
+
+static int micrel_switch_probe(struct device_d *dev)
+{
+ struct micrel_switch_priv *priv;
+ int ret = 0;
+
+ priv = xzalloc(sizeof(*priv));
+
+ dev->priv = priv;
+
+ priv->spi = (struct spi_device *)dev->type_data;
+ priv->spi->mode = SPI_MODE_0;
+ priv->spi->bits_per_word = 8;
+
+ ret = micrel_switch_read_reg(priv->spi, REG_ID0);
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "failed to read device id\n");
+ return ret;
+ }
+ if (ret != 0x95) {
+ dev_err(&priv->spi->dev, "unknown device id: %02x\n", ret);
+ return -ENODEV;
+ }
+
+ priv->cdev.name = asprintf("switch%d", dev->id);
+ priv->cdev.size = 256;
+ priv->cdev.ops = &micrel_switch_ops;
+ priv->cdev.priv = priv;
+ priv->cdev.dev = dev;
+ devfs_create(&priv->cdev);
+
+ dev_add_param(dev, "enable", micrel_switch_enable_set, NULL, 0);
+ dev_set_param(dev, "enable", "1");
+
+ return 0;
+}
+
+static struct driver_d micrel_switch_driver = {
+ .name = "ksz8864rmn",
+ .probe = micrel_switch_probe,
+};
+
+static int micrel_switch_init(void)
+{
+ spi_register_driver(&micrel_switch_driver);
+ return 0;
+}
+device_initcall(micrel_switch_init);
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index feffea5f09..7012172471 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -44,13 +44,13 @@
#include <malloc.h>
#include <xfuncs.h>
#include <init.h>
-#include <miidev.h>
#include <errno.h>
#include <io.h>
#include <mach/board.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <asm/mmu.h>
+#include <linux/phy.h>
#include "macb.h"
@@ -97,12 +97,16 @@ struct macb_device {
struct macb_dma_desc *rx_ring;
struct macb_dma_desc *tx_ring;
+ int phy_addr;
+
const struct device *dev;
struct eth_device netdev;
- struct mii_device miidev;
+ phy_interface_t interface;
+
+ struct mii_bus miibus;
- unsigned int flags;
+ unsigned int phy_flags;
};
static int macb_send(struct eth_device *edev, void *packet,
@@ -214,26 +218,32 @@ static int macb_recv(struct eth_device *edev)
return 0;
}
-static int macb_open(struct eth_device *edev)
+static void macb_adjust_link(struct eth_device *edev)
{
struct macb_device *macb = edev->priv;
- int duplex = 1, speed = 1;
- u32 ncfgr;
+ u32 reg;
- debug("%s\n", __func__);
+ reg = readl(macb->regs + MACB_NCFGR);
+ reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
- miidev_wait_aneg(&macb->miidev);
- miidev_print_status(&macb->miidev);
+ if (edev->phydev->duplex)
+ reg |= MACB_BIT(FD);
+ if (edev->phydev->speed == SPEED_100)
+ reg |= MACB_BIT(SPD);
- ncfgr = readl(macb->regs + MACB_NCFGR);
- ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
- if (speed)
- ncfgr |= MACB_BIT(SPD);
- if (duplex)
- ncfgr |= MACB_BIT(FD);
- writel(ncfgr, macb->regs + MACB_NCFGR);
+ writel(reg, macb->regs + MACB_NCFGR);
+}
- return 0;
+static int macb_open(struct eth_device *edev)
+{
+ struct macb_device *macb = edev->priv;
+
+ debug("%s\n", __func__);
+
+ /* Obtain the PHY's address/id */
+ return phy_device_connect(edev, &macb->miibus, macb->phy_addr,
+ macb_adjust_link, macb->phy_flags,
+ macb->interface);
}
static int macb_init(struct eth_device *edev)
@@ -267,7 +277,7 @@ static int macb_init(struct eth_device *edev)
writel((ulong)macb->rx_ring, macb->regs + MACB_RBQP);
writel((ulong)macb->tx_ring, macb->regs + MACB_TBQP);
- if (macb->flags & AT91SAM_ETHER_RMII)
+ if (macb->interface == PHY_INTERFACE_MODE_RMII)
val |= MACB_BIT(RMII);
else
val &= ~MACB_BIT(RMII);
@@ -301,10 +311,9 @@ static void macb_halt(struct eth_device *edev)
writel(MACB_BIT(CLRSTAT), macb->regs + MACB_NCR);
}
-static int macb_phy_read(struct mii_device *mdev, int addr, int reg)
+static int macb_phy_read(struct mii_bus *bus, int addr, int reg)
{
- struct eth_device *edev = mdev->edev;
- struct macb_device *macb = edev->priv;
+ struct macb_device *macb = bus->priv;
unsigned long netctl;
unsigned long netstat;
@@ -344,10 +353,9 @@ static int macb_phy_read(struct mii_device *mdev, int addr, int reg)
return value;
}
-static int macb_phy_write(struct mii_device *mdev, int addr, int reg, int value)
+static int macb_phy_write(struct mii_bus *bus, int addr, int reg, u16 value)
{
- struct eth_device *edev = mdev->edev;
- struct macb_device *macb = edev->priv;
+ struct macb_device *macb = bus->priv;
unsigned long netctl;
unsigned long netstat;
unsigned long frame;
@@ -428,14 +436,19 @@ static int macb_probe(struct device_d *dev)
edev->set_ethaddr = macb_set_ethaddr;
edev->parent = dev;
- macb->miidev.read = macb_phy_read;
- macb->miidev.write = macb_phy_write;
- macb->miidev.address = pdata->phy_addr;
- macb->miidev.flags = pdata->flags & AT91SAM_ETHER_FORCE_LINK ?
- MIIDEV_FORCE_LINK : 0;
- macb->miidev.edev = edev;
- macb->miidev.parent = dev;
- macb->flags = pdata->flags;
+ macb->miibus.read = macb_phy_read;
+ macb->miibus.write = macb_phy_write;
+ macb->phy_addr = pdata->phy_addr;
+ macb->miibus.priv = macb;
+ macb->miibus.parent = dev;
+
+ if (pdata->flags & AT91SAM_ETHER_RMII)
+ macb->interface = PHY_INTERFACE_MODE_RMII;
+ else
+ macb->interface = PHY_INTERFACE_MODE_MII;
+
+ macb->phy_flags = pdata->flags & AT91SAM_ETHER_FORCE_LINK ?
+ PHYLIB_FORCE_LINK : 0;
macb->rx_buffer = dma_alloc_coherent(CFG_MACB_RX_BUFFER_SIZE);
macb->rx_ring = dma_alloc_coherent(CFG_MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc));
@@ -470,7 +483,7 @@ static int macb_probe(struct device_d *dev)
writel(ncfgr, macb->regs + MACB_NCFGR);
- mii_register(&macb->miidev);
+ mdiobus_register(&macb->miibus);
eth_register(edev);
return 0;
diff --git a/drivers/net/miidev.c b/drivers/net/miidev.c
deleted file mode 100644
index 75b53e3c5c..0000000000
--- a/drivers/net/miidev.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * miidev.c - generic phy abstraction
- *
- * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * 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 version 2
- * as published by the Free Software Foundation.
- *
- * 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 <driver.h>
-#include <init.h>
-#include <miidev.h>
-#include <clock.h>
-#include <net.h>
-#include <malloc.h>
-
-static LIST_HEAD(miidev_list);
-
-int miidev_restart_aneg(struct mii_device *mdev)
-{
- int status, timeout;
- uint64_t start;
-
- status = mii_write(mdev, mdev->address, MII_BMCR, BMCR_RESET);
- if (status)
- return status;
-
- start = get_time_ns();
- do {
- status = mii_read(mdev, mdev->address, MII_BMCR);
- if (status < 0)
- return status;
-
- if (is_timeout(start, SECOND))
- return -ETIMEDOUT;
-
- } while (status & BMCR_RESET);
-
- if (mdev->flags & MIIDEV_FORCE_LINK)
- return 0;
-
- if (mdev->flags & MIIDEV_FORCE_10) {
- printf("Forcing 10 Mbps ethernet link... ");
-
- status = mii_read(mdev, mdev->address, MII_BMSR);
- if (status < 0)
- return status;
-
- status = mii_write(mdev, mdev->address, MII_BMCR, BMCR_FULLDPLX | BMCR_CTST);
- if (status)
- return status;
-
- timeout = 20;
- do { /* wait for link status to go down */
- udelay(10000);
- if ((timeout--) == 0) {
- debug("hmmm, should not have waited...");
- break;
- }
- status = mii_read(mdev, mdev->address, MII_BMSR);
- if (status < 0)
- return status;
- } while (status & BMSR_LSTATUS);
-
- } else { /* MII100 */
- /*
- * Set the auto-negotiation advertisement register bits
- */
- status = mii_read(mdev, mdev->address, MII_ADVERTISE);
- if (status < 0)
- return status;
-
- status |= ADVERTISE_ALL;
-
- status = mii_write(mdev, mdev->address, MII_ADVERTISE, status);
- if (status)
- return status;
-
- status = mii_write(mdev, mdev->address, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
- if (status)
- return status;
- }
-
- return 0;
-}
-
-int miidev_wait_aneg(struct mii_device *mdev)
-{
- int status;
- uint64_t start = get_time_ns();
-
- if (mdev->flags & MIIDEV_FORCE_LINK)
- return 0;
-
- do {
- status = mii_read(mdev, mdev->address, MII_BMSR);
- if (status < 0)
- return status;
-
- if (is_timeout(start, 5 * SECOND)) {
- printf("%s: Autonegotiation timeout\n", mdev->cdev.name);
- return -ETIMEDOUT;
- }
-
- } while (!(status & BMSR_ANEGCOMPLETE));
-
- return 0;
-}
-
-int miidev_get_status(struct mii_device *mdev)
-{
- int ret, status, adv, lpa;
-
- ret = mii_read(mdev, mdev->address, MII_BMSR);
- if (ret < 0)
- goto err_out;
-
- status = ret & BMSR_LSTATUS ? MIIDEV_STATUS_IS_UP : 0;
-
- ret = mii_read(mdev, mdev->address, MII_BMCR);
- if (ret < 0)
- goto err_out;
-
- if (ret & BMCR_ANENABLE) {
- if (mdev->capabilities & MIIDEV_CAPABLE_1000M) {
- lpa = mii_read(mdev, mdev->address, MII_STAT1000);
- if (lpa < 0)
- goto err_out;
- adv = mii_read(mdev, mdev->address, MII_CTRL1000);
- if (adv < 0)
- goto err_out;
- lpa &= adv << 2;
- if (lpa & (LPA_1000FULL | LPA_1000HALF)) {
- if (lpa & LPA_1000FULL)
- status |= MIIDEV_STATUS_IS_FULL_DUPLEX;
- status |= MIIDEV_STATUS_IS_1000MBIT;
- return status;
- }
- }
- lpa = mii_read(mdev, mdev->address, MII_LPA);
- if (lpa < 0)
- goto err_out;
- adv = mii_read(mdev, mdev->address, MII_ADVERTISE);
- if (adv < 0)
- goto err_out;
- lpa &= adv;
- status |= lpa & LPA_DUPLEX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
- status |= lpa & LPA_100 ? MIIDEV_STATUS_IS_100MBIT :
- MIIDEV_STATUS_IS_10MBIT;
- } else {
- status |= ret & BMCR_FULLDPLX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
- status |= ret & BMCR_SPEED100 ? MIIDEV_STATUS_IS_100MBIT :
- MIIDEV_STATUS_IS_10MBIT;
- }
-
- return status;
-err_out:
- printf("%s: failed to read (%d)\n", mdev->cdev.name, ret);
- return ret;
-}
-
-int miidev_print_status(struct mii_device *mdev)
-{
- char *duplex;
- int speed, status;
-
- if (mdev->flags & MIIDEV_FORCE_LINK) {
- printf("Forcing link present...\n");
- return 0;
- }
-
- status = miidev_get_status(mdev);
- if (status < 0)
- return status;
-
- duplex = status & MIIDEV_STATUS_IS_FULL_DUPLEX ? "Full" : "Half";
- speed = status & MIIDEV_STATUS_IS_1000MBIT ? 1000 :
- (status & MIIDEV_STATUS_IS_100MBIT ? 100 : 10);
-
- printf("%s: Link is %s", mdev->cdev.name,
- status & MIIDEV_STATUS_IS_UP ? "up" : "down");
- printf(" - %d/%s\n", speed, duplex);
-
- return 0;
-}
-
-static ssize_t miidev_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
-{
- int i = count;
- uint16_t *buf = _buf;
- struct mii_device *mdev = cdev->priv;
-
- while (i > 0) {
- *buf = mii_read(mdev, mdev->address, offset / 2);
- buf++;
- i -= 2;
- offset += 2;
- }
-
- return count;
-}
-
-static ssize_t miidev_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
-{
- int i = count;
- const uint16_t *buf = _buf;
- struct mii_device *mdev = cdev->priv;
-
- while (i > 0) {
- mii_write(mdev, mdev->address, offset / 2, *buf);
- buf++;
- i -= 2;
- offset += 2;
- }
-
- return count;
-}
-
-static struct file_operations miidev_ops = {
- .read = miidev_read,
- .write = miidev_write,
- .lseek = dev_lseek_default,
-};
-
-static int miidev_probe(struct device_d *dev)
-{
- struct mii_device *mdev = dev->priv;
- int val;
- int caps = 0;
-
- val = mii_read(mdev, mdev->address, MII_PHYSID1);
- if (val < 0 || val == 0xffff)
- goto err_out;
- val = mii_read(mdev, mdev->address, MII_PHYSID2);
- if (val < 0 || val == 0xffff)
- goto err_out;
- val = mii_read(mdev, mdev->address, MII_BMSR);
- if (val < 0)
- goto err_out;
- if (val & BMSR_ESTATEN) {
- val = mii_read(mdev, mdev->address, MII_ESTATUS);
- if (val < 0)
- goto err_out;
- if (val & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
- caps = MIIDEV_CAPABLE_1000M;
- }
-
- mdev->capabilities = caps;
- mdev->cdev.name = asprintf("phy%d", dev->id);
- mdev->cdev.size = 64;
- mdev->cdev.ops = &miidev_ops;
- mdev->cdev.priv = mdev;
- mdev->cdev.dev = dev;
- devfs_create(&mdev->cdev);
- list_add_tail(&mdev->list, &miidev_list);
- return 0;
-
-err_out:
- dev_err(dev, "cannot read PHY registers (addr %d)\n", mdev->address);
- return -ENODEV;
-}
-
-static void miidev_remove(struct device_d *dev)
-{
- struct mii_device *mdev = dev->priv;
-
- list_del(&mdev->list);
-
- free(mdev->cdev.name);
- devfs_remove(&mdev->cdev);
-}
-
-struct mii_device *mii_open(const char *name)
-{
- struct mii_device *mdev;
-
- list_for_each_entry(mdev, &miidev_list, list) {
- if (!strcmp(name, mdev->cdev.name))
- return mdev;
- }
- return NULL;
-}
-
-void mii_close(struct mii_device *mdev)
-{
-}
-
-static struct driver_d miidev_drv = {
- .name = "miidev",
- .probe = miidev_probe,
- .remove = miidev_remove,
-};
-
-int mii_register(struct mii_device *mdev)
-{
- mdev->dev.priv = mdev;
- mdev->dev.id = DEVICE_ID_DYNAMIC;
- strcpy(mdev->dev.name, "miidev");
- if (mdev->parent)
- dev_add_child(mdev->parent, &mdev->dev);
-
- return register_device(&mdev->dev);
-}
-
-void mii_unregister(struct mii_device *mdev)
-{
- unregister_device(&mdev->dev);
-}
-
-static int miidev_init(void)
-{
- register_driver(&miidev_drv);
- return 0;
-}
-
-device_initcall(miidev_init);
-
diff --git a/drivers/net/netx_eth.c b/drivers/net/netx_eth.c
index 2d92a2e4dc..a4764258c1 100644
--- a/drivers/net/netx_eth.c
+++ b/drivers/net/netx_eth.c
@@ -2,13 +2,13 @@
#include <command.h>
#include <net.h>
#include <io.h>
-#include <miidev.h>
#include <mach/netx-xc.h>
#include <mach/netx-eth.h>
#include <mach/netx-regs.h>
#include <xfuncs.h>
#include <init.h>
#include <driver.h>
+#include <linux/phy.h>
#define ETH_MAC_LOCAL_CONFIG 0x1560
#define ETH_MAC_4321 0x1564
@@ -47,7 +47,7 @@
#define CON_FIFO_PORT_LO(xcno) (6 + ((xcno) << 3)) /* Index of the FIFO where sent Data packages are confirmed */
struct netx_eth_priv {
- struct mii_device miidev;
+ struct mii_bus miibus;
int xcno;
};
@@ -118,7 +118,7 @@ static int netx_eth_rx (struct eth_device *edev)
return 0;
}
-static int netx_miidev_read(struct mii_device *mdev, int phy_addr, int reg)
+static int netx_miibus_read(struct mii_bus *bus, int phy_addr, int reg)
{
int value;
@@ -135,8 +135,8 @@ static int netx_miidev_read(struct mii_device *mdev, int phy_addr, int reg)
return value;
}
-static int netx_miidev_write(struct mii_device *mdev, int phy_addr,
- int reg, int val)
+static int netx_miibus_write(struct mii_bus *bus, int phy_addr,
+ int reg, u16 val)
{
debug("%s: addr: 0x%02x reg: 0x%02x val: 0x%04x\n",__func__,
phy_addr, reg, val);
@@ -189,13 +189,15 @@ static int netx_eth_init_dev(struct eth_device *edev)
for (i = 2; i <= 18; i++)
PFIFO_REG( PFIFO_BASE(EMPTY_PTR_FIFO(xcno)) ) = FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(xcno);
- miidev_restart_aneg(&priv->miidev);
return 0;
}
static int netx_eth_open(struct eth_device *edev)
{
- return 0;
+ struct netx_eth_priv *priv = (struct netx_eth_priv *)edev->priv;
+
+ return phy_device_connect(edev, &priv->miibus, 0, NULL,
+ 0, PHY_INTERFACE_MODE_NA);
}
static void netx_eth_halt (struct eth_device *edev)
@@ -259,14 +261,12 @@ static int netx_eth_probe(struct device_d *dev)
edev->set_ethaddr = netx_eth_set_ethaddr;
edev->parent = dev;
- priv->miidev.read = netx_miidev_read;
- priv->miidev.write = netx_miidev_write;
- priv->miidev.address = 0;
- priv->miidev.flags = 0;
- priv->miidev.parent = dev;
+ priv->miibus.read = netx_miibus_read;
+ priv->miibus.write = netx_miibus_write;
+ priv->miibus.parent = dev;
netx_eth_init_phy();
- mii_register(&priv->miidev);
+ mdiobus_register(&priv->miibus);
eth_register(edev);
return 0;
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
new file mode 100644
index 0000000000..b66261ae99
--- /dev/null
+++ b/drivers/net/phy/Kconfig
@@ -0,0 +1,17 @@
+#
+# PHY Layer Configuration
+#
+
+menu "phylib "
+
+if PHYLIB
+
+comment "MII PHY device drivers"
+
+config GENERIC_PHY
+ bool "Drivers for the Generic PHYs"
+ default y
+
+endif
+
+endmenu
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
new file mode 100644
index 0000000000..82e90d426a
--- /dev/null
+++ b/drivers/net/phy/Makefile
@@ -0,0 +1,2 @@
+obj-y += phy.o mdio_bus.o
+obj-$(CONFIG_GENERIC_PHY) += generic.o
diff --git a/drivers/net/phy/generic.c b/drivers/net/phy/generic.c
new file mode 100644
index 0000000000..3f5f127065
--- /dev/null
+++ b/drivers/net/phy/generic.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2009 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 <linux/phy.h>
+#include <init.h>
+
+static struct phy_driver generic_phy = {
+ .drv.name = "Generic PHY",
+ .phy_id = PHY_ANY_UID,
+ .phy_id_mask = PHY_ANY_UID,
+ .features = 0,
+};
+
+static int generic_phy_register(void)
+{
+ return phy_driver_register(&generic_phy);
+}
+device_initcall(generic_phy_register);
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
new file mode 100644
index 0000000000..93d6fe15e1
--- /dev/null
+++ b/drivers/net/phy/mdio_bus.c
@@ -0,0 +1,250 @@
+/*
+ * drivers/net/phy/mdio_bus.c
+ *
+ * MDIO Bus interface
+ *
+ * Author: Andy Fleming
+ *
+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <clock.h>
+#include <net.h>
+#include <errno.h>
+#include <linux/phy.h>
+#include <linux/err.h>
+
+/**
+ * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
+ * @bus: target mii_bus
+ *
+ * Description: Called by a bus driver to bring up all the PHYs
+ * on a given bus, and attach them to the bus.
+ *
+ * Returns 0 on success or < 0 on error.
+ */
+int mdiobus_register(struct mii_bus *bus)
+{
+ int i, err;
+
+ if (NULL == bus ||
+ NULL == bus->read ||
+ NULL == bus->write)
+ return -EINVAL;
+
+ bus->dev.priv = bus;
+ bus->dev.id = DEVICE_ID_DYNAMIC;
+ strcpy(bus->dev.name, "miibus");
+ bus->dev.parent = bus->parent;
+ if (bus->parent)
+ dev_add_child(bus->parent, &bus->dev);
+
+ err = register_device(&bus->dev);
+ if (err) {
+ pr_err("mii_bus %s failed to register\n", bus->dev.name);
+ return -EINVAL;
+ }
+
+ if (bus->reset)
+ bus->reset(bus);
+
+ for (i = 0; i < PHY_MAX_ADDR; i++) {
+ if ((bus->phy_mask & (1 << i)) == 0) {
+ struct phy_device *phydev;
+
+ phydev = mdiobus_scan(bus, i);
+ if (IS_ERR(phydev)) {
+ err = PTR_ERR(phydev);
+ goto error;
+ }
+ }
+ }
+
+ pr_info("%s: probed\n", dev_name(&bus->dev));
+ return 0;
+
+error:
+ while (--i >= 0) {
+ if (bus->phy_map[i]) {
+ kfree(bus->phy_map[i]);
+ bus->phy_map[i] = NULL;
+ }
+ }
+ return err;
+}
+EXPORT_SYMBOL(mdiobus_register);
+
+void mdiobus_unregister(struct mii_bus *bus)
+{
+ int i;
+
+ for (i = 0; i < PHY_MAX_ADDR; i++) {
+ if (bus->phy_map[i])
+ unregister_device(&bus->phy_map[i]->dev);
+ bus->phy_map[i] = NULL;
+ }
+}
+EXPORT_SYMBOL(mdiobus_unregister);
+
+struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
+{
+ struct phy_device *phydev;
+
+ phydev = get_phy_device(bus, addr);
+ if (IS_ERR(phydev) || phydev == NULL)
+ return phydev;
+
+ bus->phy_map[addr] = phydev;
+
+ return phydev;
+}
+EXPORT_SYMBOL(mdiobus_scan);
+
+/**
+ * mdio_bus_match - determine if given PHY driver supports the given PHY device
+ * @dev: target PHY device
+ * @drv: given PHY driver
+ *
+ * Description: Given a PHY device, and a PHY driver, return 1 if
+ * the driver supports the device. Otherwise, return 0.
+ */
+static int mdio_bus_match(struct device_d *dev, struct driver_d *drv)
+{
+ struct phy_device *phydev = to_phy_device(dev);
+ struct phy_driver *phydrv = to_phy_driver(drv);
+
+ return ((phydrv->phy_id & phydrv->phy_id_mask) ==
+ (phydev->phy_id & phydrv->phy_id_mask));
+}
+
+static ssize_t phydev_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
+{
+ int i = count;
+ uint16_t *buf = _buf;
+ struct phy_device *phydev = cdev->priv;
+
+ while (i > 0) {
+ *buf = phy_read(phydev, offset / 2);
+ buf++;
+ i -= 2;
+ offset += 2;
+ }
+
+ return count;
+}
+
+static ssize_t phydev_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
+{
+ int i = count;
+ const uint16_t *buf = _buf;
+ struct phy_device *phydev = cdev->priv;
+
+ while (i > 0) {
+ phy_write(phydev, offset / 2, *buf);
+ buf++;
+ i -= 2;
+ offset += 2;
+ }
+
+ return count;
+}
+
+static struct file_operations phydev_ops = {
+ .read = phydev_read,
+ .write = phydev_write,
+ .lseek = dev_lseek_default,
+};
+
+static int mdio_bus_probe(struct device_d *_dev)
+{
+ struct phy_device *dev = to_phy_device(_dev);
+ struct phy_driver *drv = to_phy_driver(_dev->driver);
+
+ char str[16];
+
+ dev->attached_dev->phydev = dev;
+ dev->dev.parent = &dev->attached_dev->dev;
+ dev_add_child(dev->dev.parent, _dev);
+
+ if (drv->probe) {
+ int ret;
+
+ ret = drv->probe(dev);
+ if (ret) {
+ dev->attached_dev->phydev = NULL;
+ dev->attached_dev = NULL;
+ return ret;
+ }
+ }
+
+ if (dev->dev_flags) {
+ if (dev->dev_flags & PHYLIB_FORCE_10) {
+ dev->speed = SPEED_10;
+ dev->duplex = DUPLEX_FULL;
+ dev->autoneg = !AUTONEG_ENABLE;
+ }
+ }
+
+ /* Start out supporting everything. Eventually,
+ * a controller will attach, and may modify one
+ * or both of these values */
+ dev->supported = drv->features;
+ dev->advertising = drv->features;
+
+ drv->config_init(dev);
+
+ /* Sanitize settings based on PHY capabilities */
+ if ((dev->supported & SUPPORTED_Autoneg) == 0)
+ dev->autoneg = AUTONEG_DISABLE;
+
+ sprintf(str, "%d", dev->addr);
+ dev_add_param_fixed(&dev->dev, "phy_addr", str);
+
+ dev->cdev.name = asprintf("phy%d", _dev->id);
+ dev->cdev.size = 64;
+ dev->cdev.ops = &phydev_ops;
+ dev->cdev.priv = dev;
+ dev->cdev.dev = _dev;
+ devfs_create(&dev->cdev);
+
+ return 0;
+}
+
+static void mdio_bus_remove(struct device_d *_dev)
+{
+ struct phy_device *dev = to_phy_device(_dev);
+ struct phy_driver *drv = to_phy_driver(_dev->driver);
+
+ if (drv->remove)
+ drv->remove(dev);
+
+ free(dev->cdev.name);
+ devfs_remove(&dev->cdev);
+}
+
+struct bus_type mdio_bus_type = {
+ .name = "mdio_bus",
+ .match = mdio_bus_match,
+ .probe = mdio_bus_probe,
+ .remove = mdio_bus_remove,
+};
+EXPORT_SYMBOL(mdio_bus_type);
+
+#if 0
+static int mdio_bus_init(void)
+{
+ return bus_register(&mdio_bus_type);
+}
+pure_initcall(mdio_bus_init);
+#endif
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
new file mode 100644
index 0000000000..88c3ff7723
--- /dev/null
+++ b/drivers/net/phy/phy.c
@@ -0,0 +1,583 @@
+/*
+ * drivers/net/phy/phy.c
+ *
+ * Framework for finding and configuring PHYs.
+ * Also contains generic PHY driver
+ *
+ * Copyright (c) 2009-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Author: Andy Fleming
+ *
+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <net.h>
+#include <malloc.h>
+#include <linux/phy.h>
+#include <linux/phy.h>
+#include <linux/err.h>
+
+#define PHY_AN_TIMEOUT 10
+
+static int genphy_config_init(struct phy_device *phydev);
+
+int phy_update_status(struct phy_device *dev)
+{
+ struct phy_driver *drv = to_phy_driver(dev->dev.driver);
+ struct eth_device *edev = dev->attached_dev;
+ int ret;
+ int oldspeed = dev->speed, oldduplex = dev->duplex;
+
+ ret = drv->read_status(dev);
+ if (ret)
+ return ret;
+
+ if (dev->speed == oldspeed && dev->duplex == oldduplex)
+ return 0;
+
+ if (dev->adjust_link)
+ dev->adjust_link(edev);
+
+ if (dev->link)
+ printf("%dMbps %s duplex link detected\n", dev->speed,
+ dev->duplex ? "full" : "half");
+
+ return 0;
+}
+
+struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id)
+{
+ struct phy_device *dev;
+
+ /* We allocate the device, and initialize the
+ * default values */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+
+ if (NULL == dev)
+ return (struct phy_device*) PTR_ERR((void*)-ENOMEM);
+
+ dev->speed = 0;
+ dev->duplex = -1;
+ dev->pause = dev->asym_pause = 0;
+ dev->link = 1;
+ dev->autoneg = AUTONEG_ENABLE;
+
+ dev->addr = addr;
+ dev->phy_id = phy_id;
+
+ dev->bus = bus;
+ dev->dev.parent = bus->parent;
+ dev->dev.bus = &mdio_bus_type;
+
+ strcpy(dev->dev.name, "phy");
+ dev->dev.id = DEVICE_ID_DYNAMIC;
+
+ return dev;
+}
+/**
+ * get_phy_id - reads the specified addr for its ID.
+ * @bus: the target MII bus
+ * @addr: PHY address on the MII bus
+ * @phy_id: where to store the ID retrieved.
+ *
+ * Description: Reads the ID registers of the PHY at @addr on the
+ * @bus, stores it in @phy_id and returns zero on success.
+ */
+int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
+{
+ int phy_reg;
+
+ /* Grab the bits from PHYIR1, and put them
+ * in the upper half */
+ phy_reg = mdiobus_read(bus, addr, MII_PHYSID1);
+
+ if (phy_reg < 0)
+ return -EIO;
+
+ *phy_id = (phy_reg & 0xffff) << 16;
+
+ /* Grab the bits from PHYIR2, and put them in the lower half */
+ phy_reg = mdiobus_read(bus, addr, MII_PHYSID2);
+
+ if (phy_reg < 0)
+ return -EIO;
+
+ *phy_id |= (phy_reg & 0xffff);
+
+ return 0;
+}
+
+/**
+ * get_phy_device - reads the specified PHY device and returns its @phy_device struct
+ * @bus: the target MII bus
+ * @addr: PHY address on the MII bus
+ *
+ * Description: Reads the ID registers of the PHY at @addr on the
+ * @bus, then allocates and returns the phy_device to represent it.
+ */
+struct phy_device *get_phy_device(struct mii_bus *bus, int addr)
+{
+ struct phy_device *dev = NULL;
+ u32 phy_id = 0;
+ int r;
+
+ r = get_phy_id(bus, addr, &phy_id);
+ if (r)
+ return ERR_PTR(r);
+
+ /* If the phy_id is mostly Fs, there is no device there */
+ if ((phy_id & 0x1fffffff) == 0x1fffffff)
+ return NULL;
+
+ dev = phy_device_create(bus, addr, phy_id);
+
+ return dev;
+}
+
+/* Automatically gets and returns the PHY device */
+int phy_device_connect(struct eth_device *edev, struct mii_bus *bus, int addr,
+ void (*adjust_link) (struct eth_device *edev),
+ u32 flags, phy_interface_t interface)
+{
+ struct phy_driver* drv;
+ struct phy_device* dev = NULL;
+ unsigned int i;
+ int ret = -EINVAL;
+
+ if (!edev->phydev) {
+ if (addr >= 0) {
+ dev = bus->phy_map[addr];
+ if (!dev) {
+ ret = -EIO;
+ goto fail;
+ }
+
+ dev->attached_dev = edev;
+ dev->interface = interface;
+ dev->dev_flags = flags;
+
+ ret = register_device(&dev->dev);
+ if (ret)
+ goto fail;
+ } else {
+ for (i = 0; i < PHY_MAX_ADDR && !edev->phydev; i++) {
+ dev = bus->phy_map[i];
+ if (!dev || dev->attached_dev)
+ continue;
+
+ dev->attached_dev = edev;
+ dev->interface = interface;
+ dev->dev_flags = flags;
+
+ ret = register_device(&dev->dev);
+ if (ret)
+ goto fail;
+
+ break;
+ }
+ }
+
+ if (!edev->phydev) {
+ ret = -EIO;
+ goto fail;
+ }
+ }
+
+ dev = edev->phydev;
+ drv = to_phy_driver(dev->dev.driver);
+
+ drv->config_aneg(dev);
+
+ dev->adjust_link = adjust_link;
+
+ return 0;
+
+fail:
+ if (dev)
+ dev->attached_dev = NULL;
+ puts("Unable to find a PHY (unknown ID?)\n");
+ return ret;
+}
+
+/* Generic PHY support and helper functions */
+
+/**
+ * genphy_config_advert - sanitize and advertise auto-negotiation parameters
+ * @phydev: target phy_device struct
+ *
+ * Description: Writes MII_ADVERTISE with the appropriate values,
+ * after sanitizing the values to make sure we only advertise
+ * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
+ * hasn't changed, and > 0 if it has changed.
+ */
+int genphy_config_advert(struct phy_device *phydev)
+{
+ u32 advertise;
+ int oldadv, adv;
+ int err, changed = 0;
+
+ /* Only allow advertising what
+ * this PHY supports */
+ phydev->advertising &= phydev->supported;
+ advertise = phydev->advertising;
+
+ /* Setup standard advertisement */
+ oldadv = adv = phy_read(phydev, MII_ADVERTISE);
+
+ if (adv < 0)
+ return adv;
+
+ adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
+ ADVERTISE_PAUSE_ASYM);
+ adv |= ethtool_adv_to_mii_adv_t(advertise);
+
+ if (adv != oldadv) {
+ err = phy_write(phydev, MII_ADVERTISE, adv);
+
+ if (err < 0)
+ return err;
+ changed = 1;
+ }
+
+ /* Configure gigabit if it's supported */
+ if (phydev->supported & (SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full)) {
+ oldadv = adv = phy_read(phydev, MII_CTRL1000);
+
+ if (adv < 0)
+ return adv;
+
+ adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+ adv |= ethtool_adv_to_mii_ctrl1000_t(advertise);
+
+ if (adv != oldadv) {
+ err = phy_write(phydev, MII_CTRL1000, adv);
+
+ if (err < 0)
+ return err;
+ changed = 1;
+ }
+ }
+
+ return changed;
+}
+
+/**
+ * genphy_setup_forced - configures/forces speed/duplex from @phydev
+ * @phydev: target phy_device struct
+ *
+ * Description: Configures MII_BMCR to force speed/duplex
+ * to the values in phydev. Assumes that the values are valid.
+ * Please see phy_sanitize_settings().
+ */
+int genphy_setup_forced(struct phy_device *phydev)
+{
+ int err;
+ int ctl = 0;
+
+ phydev->pause = phydev->asym_pause = 0;
+
+ if (SPEED_1000 == phydev->speed)
+ ctl |= BMCR_SPEED1000;
+ else if (SPEED_100 == phydev->speed)
+ ctl |= BMCR_SPEED100;
+
+ if (DUPLEX_FULL == phydev->duplex)
+ ctl |= BMCR_FULLDPLX;
+
+ err = phy_write(phydev, MII_BMCR, ctl);
+
+ return err;
+}
+
+static int phy_aneg_done(struct phy_device *phydev)
+{
+ uint64_t start = get_time_ns();
+ int ctl;
+
+ while (!is_timeout(start, PHY_AN_TIMEOUT * SECOND)) {
+ ctl = phy_read(phydev, MII_BMSR);
+ if (ctl & BMSR_ANEGCOMPLETE) {
+ phydev->link = 1;
+ return 0;
+ }
+
+ /* Restart auto-negotiation if remote fault */
+ if (ctl & BMSR_RFAULT) {
+ puts("PHY remote fault detected\n"
+ "PHY restarting auto-negotiation\n");
+ phy_write(phydev, MII_BMCR,
+ BMCR_ANENABLE | BMCR_ANRESTART);
+ }
+ }
+
+ phydev->link = 0;
+ return -ETIMEDOUT;
+}
+
+/**
+ * genphy_restart_aneg - Enable and Restart Autonegotiation
+ * @phydev: target phy_device struct
+ */
+int genphy_restart_aneg(struct phy_device *phydev)
+{
+ int ctl;
+
+ ctl = phy_read(phydev, MII_BMCR);
+
+ if (ctl < 0)
+ return ctl;
+
+ ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+
+ /* Don't isolate the PHY if we're negotiating */
+ ctl &= ~(BMCR_ISOLATE);
+
+ ctl = phy_write(phydev, MII_BMCR, ctl);
+
+ if (ctl < 0)
+ return ctl;
+
+ return phy_aneg_done(phydev);
+}
+
+/**
+ * genphy_config_aneg - restart auto-negotiation or write BMCR
+ * @phydev: target phy_device struct
+ *
+ * Description: If auto-negotiation is enabled, we configure the
+ * advertising, and then restart auto-negotiation. If it is not
+ * enabled, then we write the BMCR.
+ */
+int genphy_config_aneg(struct phy_device *phydev)
+{
+ int result;
+
+ if (AUTONEG_ENABLE != phydev->autoneg)
+ return genphy_setup_forced(phydev);
+
+ result = genphy_config_advert(phydev);
+
+ if (result < 0) /* error */
+ return result;
+
+ if (result == 0) {
+ /* Advertisement hasn't changed, but maybe aneg was never on to
+ * begin with? Or maybe phy was isolated? */
+ int ctl = phy_read(phydev, MII_BMCR);
+
+ if (ctl < 0)
+ return ctl;
+
+ if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
+ result = 1; /* do restart aneg */
+ }
+
+ /* Only restart aneg if we are advertising something different
+ * than we were before. */
+ if (result > 0)
+ result = genphy_restart_aneg(phydev);
+
+ return result;
+}
+
+/**
+ * genphy_update_link - update link status in @phydev
+ * @phydev: target phy_device struct
+ *
+ * Description: Update the value in phydev->link to reflect the
+ * current link value. In order to do this, we need to read
+ * the status register twice, keeping the second value.
+ */
+int genphy_update_link(struct phy_device *phydev)
+{
+ int status;
+
+ /* Do a fake read */
+ status = phy_read(phydev, MII_BMSR);
+
+ if (status < 0)
+ return status;
+
+ /* wait phy status update in the phy */
+ udelay(1000);
+
+ /* Read link and autonegotiation status */
+ status = phy_read(phydev, MII_BMSR);
+
+ if (status < 0)
+ return status;
+
+ if ((status & BMSR_LSTATUS) == 0)
+ phydev->link = 0;
+ else
+ phydev->link = 1;
+
+ return 0;
+}
+
+/**
+ * genphy_read_status - check the link status and update current link state
+ * @phydev: target phy_device struct
+ *
+ * Description: Check the link, then figure out the current state
+ * by comparing what we advertise with what the link partner
+ * advertises. Start by checking the gigabit possibilities,
+ * then move on to 10/100.
+ */
+int genphy_read_status(struct phy_device *phydev)
+{
+ int adv;
+ int err;
+ int lpa;
+ int lpagb = 0;
+
+ /* Update the link, but return if there
+ * was an error */
+ err = genphy_update_link(phydev);
+ if (err)
+ return err;
+
+ if (AUTONEG_ENABLE == phydev->autoneg) {
+ if (phydev->supported & (SUPPORTED_1000baseT_Half
+ | SUPPORTED_1000baseT_Full)) {
+ lpagb = phy_read(phydev, MII_STAT1000);
+
+ if (lpagb < 0)
+ return lpagb;
+
+ adv = phy_read(phydev, MII_CTRL1000);
+
+ if (adv < 0)
+ return adv;
+
+ lpagb &= adv << 2;
+ }
+
+ lpa = phy_read(phydev, MII_LPA);
+
+ if (lpa < 0)
+ return lpa;
+
+ adv = phy_read(phydev, MII_ADVERTISE);
+
+ if (adv < 0)
+ return adv;
+
+ lpa &= adv;
+
+ phydev->speed = SPEED_10;
+ phydev->duplex = DUPLEX_HALF;
+ phydev->pause = phydev->asym_pause = 0;
+
+ if (lpagb & (LPA_1000FULL | LPA_1000HALF)) {
+ phydev->speed = SPEED_1000;
+
+ if (lpagb & LPA_1000FULL)
+ phydev->duplex = DUPLEX_FULL;
+ } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
+ phydev->speed = SPEED_100;
+
+ if (lpa & LPA_100FULL)
+ phydev->duplex = DUPLEX_FULL;
+ } else
+ if (lpa & LPA_10FULL)
+ phydev->duplex = DUPLEX_FULL;
+
+ if (phydev->duplex == DUPLEX_FULL) {
+ phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
+ phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
+ }
+ } else {
+ int bmcr = phy_read(phydev, MII_BMCR);
+ if (bmcr < 0)
+ return bmcr;
+
+ if (bmcr & BMCR_FULLDPLX)
+ phydev->duplex = DUPLEX_FULL;
+ else
+ phydev->duplex = DUPLEX_HALF;
+
+ if (bmcr & BMCR_SPEED1000)
+ phydev->speed = SPEED_1000;
+ else if (bmcr & BMCR_SPEED100)
+ phydev->speed = SPEED_100;
+ else
+ phydev->speed = SPEED_10;
+
+ phydev->pause = phydev->asym_pause = 0;
+ }
+
+ return 0;
+}
+
+static int genphy_config_init(struct phy_device *phydev)
+{
+ int val;
+ u32 features;
+
+ /* For now, I'll claim that the generic driver supports
+ * all possible port types */
+ features = (SUPPORTED_TP | SUPPORTED_MII
+ | SUPPORTED_AUI | SUPPORTED_FIBRE |
+ SUPPORTED_BNC);
+
+ /* Do we support autonegotiation? */
+ val = phy_read(phydev, MII_BMSR);
+
+ if (val < 0)
+ return val;
+
+ if (val & BMSR_ANEGCAPABLE)
+ features |= SUPPORTED_Autoneg;
+
+ if (val & BMSR_100FULL)
+ features |= SUPPORTED_100baseT_Full;
+ if (val & BMSR_100HALF)
+ features |= SUPPORTED_100baseT_Half;
+ if (val & BMSR_10FULL)
+ features |= SUPPORTED_10baseT_Full;
+ if (val & BMSR_10HALF)
+ features |= SUPPORTED_10baseT_Half;
+
+ if (val & BMSR_ESTATEN) {
+ val = phy_read(phydev, MII_ESTATUS);
+
+ if (val < 0)
+ return val;
+
+ if (val & ESTATUS_1000_TFULL)
+ features |= SUPPORTED_1000baseT_Full;
+ if (val & ESTATUS_1000_THALF)
+ features |= SUPPORTED_1000baseT_Half;
+ }
+
+ phydev->supported = features;
+ phydev->advertising = features;
+
+ return 0;
+}
+
+int phy_driver_register(struct phy_driver *phydrv)
+{
+ phydrv->drv.bus = &mdio_bus_type;
+
+ if (!phydrv->config_init)
+ phydrv->config_init = genphy_config_init;
+
+ if (!phydrv->config_aneg)
+ phydrv->config_aneg = genphy_config_aneg;
+
+ if (!phydrv->read_status)
+ phydrv->read_status = genphy_read_status;
+
+ return register_driver(&phydrv->drv);
+}
diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c
index cbd9f48808..3da7b82a20 100644
--- a/drivers/net/smc91111.c
+++ b/drivers/net/smc91111.c
@@ -67,13 +67,13 @@
#include <command.h>
#include <net.h>
-#include <miidev.h>
#include <malloc.h>
#include <init.h>
#include <xfuncs.h>
#include <errno.h>
#include <clock.h>
#include <io.h>
+#include <linux/phy.h>
/*---------------------------------------------------------------
.
@@ -451,7 +451,7 @@ struct accessors {
};
struct smc91c111_priv {
- struct mii_device miidev;
+ struct mii_bus miibus;
struct accessors a;
void __iomem *base;
};
@@ -621,11 +621,10 @@ static void smc_wait_mmu_release_complete(struct smc91c111_priv *priv)
}
}
-static int smc91c111_phy_write(struct mii_device *mdev, int phyaddr,
- int phyreg, int phydata)
+static int smc91c111_phy_write(struct mii_bus *bus, int phyaddr,
+ int phyreg, u16 phydata)
{
- struct eth_device *edev = mdev->edev;
- struct smc91c111_priv *priv = (struct smc91c111_priv *)edev->priv;
+ struct smc91c111_priv *priv = (struct smc91c111_priv *)bus->priv;
int oldBank;
int i;
unsigned mask;
@@ -723,10 +722,9 @@ static int smc91c111_phy_write(struct mii_device *mdev, int phyaddr,
return 0;
}
-static int smc91c111_phy_read(struct mii_device *mdev, int phyaddr, int phyreg)
+static int smc91c111_phy_read(struct mii_bus *bus, int phyaddr, int phyreg)
{
- struct eth_device *edev = mdev->edev;
- struct smc91c111_priv *priv = (struct smc91c111_priv *)edev->priv;
+ struct smc91c111_priv *priv = (struct smc91c111_priv *)bus->priv;
int oldBank;
int i;
unsigned char mask;
@@ -892,12 +890,15 @@ static void smc91c111_enable(struct eth_device *edev)
static int smc91c111_eth_open(struct eth_device *edev)
{
struct smc91c111_priv *priv = (struct smc91c111_priv *)edev->priv;
- smc91c111_enable(edev);
- miidev_wait_aneg(&priv->miidev);
- miidev_print_status(&priv->miidev);
+ /* Configure the Receive/Phy Control register */
+ SMC_SELECT_BANK(priv, 0);
+ SMC_outw(priv, RPC_DEFAULT, RPC_REG);
- return 0;
+ smc91c111_enable(edev);
+
+ return phy_device_connect(edev, &priv->miibus, 0, NULL,
+ 0, PHY_INTERFACE_MODE_NA);
}
static int smc91c111_eth_send(struct eth_device *edev, void *packet,
@@ -1279,14 +1280,6 @@ static void print_packet( unsigned char * buf, int length )
static int smc91c111_init_dev(struct eth_device *edev)
{
- struct smc91c111_priv *priv = (struct smc91c111_priv *)edev->priv;
-
- /* Configure the Receive/Phy Control register */
- SMC_SELECT_BANK(priv, 0);
- SMC_outw(priv, RPC_DEFAULT, RPC_REG);
-
- miidev_restart_aneg(&priv->miidev);
-
return 0;
}
@@ -1312,17 +1305,15 @@ static int smc91c111_probe(struct device_d *dev)
edev->set_ethaddr = smc91c111_set_ethaddr;
edev->parent = dev;
- priv->miidev.read = smc91c111_phy_read;
- priv->miidev.write = smc91c111_phy_write;
- priv->miidev.address = 0;
- priv->miidev.flags = 0;
- priv->miidev.edev = edev;
- priv->miidev.parent = dev;
+ priv->miibus.read = smc91c111_phy_read;
+ priv->miibus.write = smc91c111_phy_write;
+ priv->miibus.priv = priv;
+ priv->miibus.parent = dev;
priv->base = dev_request_mem_region(dev, 0);
smc91c111_reset(edev);
- mii_register(&priv->miidev);
+ mdiobus_register(&priv->miibus);
eth_register(edev);
return 0;
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 3ccb0efe96..c58ea72564 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -30,7 +30,6 @@
#include <command.h>
#include <net.h>
-#include <miidev.h>
#include <malloc.h>
#include <init.h>
#include <xfuncs.h>
@@ -38,12 +37,13 @@
#include <clock.h>
#include <io.h>
#include <smc911x.h>
+#include <linux/phy.h>
#include "smc911x.h"
struct smc911x_priv {
struct eth_device edev;
- struct mii_device miidev;
+ struct mii_bus miibus;
void __iomem *base;
int shift;
@@ -198,9 +198,9 @@ static int smc911x_set_ethaddr(struct eth_device *edev, unsigned char *m)
return 0;
}
-static int smc911x_phy_read(struct mii_device *mdev, int phy_addr, int reg)
+static int smc911x_phy_read(struct mii_bus *bus, int phy_addr, int reg)
{
- struct eth_device *edev = mdev->edev;
+ struct eth_device *edev = bus->priv;
while (smc911x_get_mac_csr(edev, MII_ACC) & MII_ACC_MII_BUSY);
@@ -212,10 +212,10 @@ static int smc911x_phy_read(struct mii_device *mdev, int phy_addr, int reg)
return smc911x_get_mac_csr(edev, MII_DATA);
}
-static int smc911x_phy_write(struct mii_device *mdev, int phy_addr,
- int reg, int val)
+static int smc911x_phy_write(struct mii_bus *bus, int phy_addr,
+ int reg, u16 val)
{
- struct eth_device *edev = mdev->edev;
+ struct eth_device *edev = bus->priv;
while (smc911x_get_mac_csr(edev, MII_ACC) & MII_ACC_MII_BUSY);
@@ -308,9 +308,12 @@ static void smc911x_enable(struct eth_device *edev)
static int smc911x_eth_open(struct eth_device *edev)
{
struct smc911x_priv *priv = (struct smc911x_priv *)edev->priv;
+ int ret;
- miidev_wait_aneg(&priv->miidev);
- miidev_print_status(&priv->miidev);
+ ret = phy_device_connect(edev, &priv->miibus, 1, NULL,
+ 0, PHY_INTERFACE_MODE_NA);
+ if (ret)
+ return ret;
/* Turn on Tx + Rx */
smc911x_enable(edev);
@@ -405,13 +408,9 @@ static int smc911x_eth_rx(struct eth_device *edev)
static int smc911x_init_dev(struct eth_device *edev)
{
- struct smc911x_priv *priv = (struct smc911x_priv *)edev->priv;
-
smc911x_set_mac_csr(edev, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN |
MAC_CR_HBDIS);
- miidev_restart_aneg(&priv->miidev);
-
return 0;
}
@@ -435,7 +434,7 @@ static int smc911x_probe(struct device_d *dev)
priv->shift = pdata->shift;
if (is_32bit) {
- if (pdata->shift) {
+ if (priv->shift) {
priv->reg_read = __smc911x_reg_readl_shift;
priv->reg_write = __smc911x_reg_writel_shift;
} else {
@@ -443,7 +442,7 @@ static int smc911x_probe(struct device_d *dev)
priv->reg_write = __smc911x_reg_writel;
}
} else {
- if (pdata->shift) {
+ if (priv->shift) {
priv->reg_read = __smc911x_reg_readw_shift;
priv->reg_write = __smc911x_reg_writew_shift;
} else {
@@ -456,7 +455,7 @@ static int smc911x_probe(struct device_d *dev)
* poll the READY bit in PMT_CTRL. Any other access to the device is
* forbidden while this bit isn't set. Try for 100ms
*/
- ret = wait_on_timeout(100 * MSECOND, smc911x_reg_read(priv, PMT_CTRL) & PMT_CTRL_READY);
+ ret = wait_on_timeout(100 * MSECOND, !smc911x_reg_read(priv, PMT_CTRL) & PMT_CTRL_READY);
if (!ret) {
dev_err(dev, "Device not READY in 100ms aborting\n");
return -ENODEV;
@@ -536,17 +535,15 @@ static int smc911x_probe(struct device_d *dev)
edev->set_ethaddr = smc911x_set_ethaddr;
edev->parent = dev;
- priv->miidev.read = smc911x_phy_read;
- priv->miidev.write = smc911x_phy_write;
- priv->miidev.address = 1;
- priv->miidev.flags = 0;
- priv->miidev.edev = edev;
- priv->miidev.parent = dev;
+ priv->miibus.read = smc911x_phy_read;
+ priv->miibus.write = smc911x_phy_write;
+ priv->miibus.priv = edev;
+ priv->miibus.parent = dev;
smc911x_reset(edev);
smc911x_phy_reset(edev);
- mii_register(&priv->miidev);
+ mdiobus_register(&priv->miibus);
eth_register(edev);
return 0;
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index 32496a8de7..309f1587ca 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -79,7 +79,7 @@ int tap_probe(struct device_d *dev)
struct tap_priv *priv;
int ret = 0;
- priv = xmalloc(sizeof(struct tap_priv));
+ priv = xzalloc(sizeof(struct tap_priv));
priv->name = "barebox";
priv->fd = tap_alloc(priv->name);
@@ -88,8 +88,9 @@ int tap_probe(struct device_d *dev)
goto out;
}
- edev = xmalloc(sizeof(struct eth_device));
+ edev = xzalloc(sizeof(struct eth_device));
edev->priv = priv;
+ edev->parent = dev;
edev->init = tap_eth_open;
edev->open = tap_eth_open;
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index b53dcc7c46..adb1b0b097 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -5,11 +5,11 @@ menuconfig NET_USB
if NET_USB
config NET_USB_ASIX
- select MIIDEV
+ select PHYLIB
bool "Asix compatible"
config NET_USB_SMSC95XX
- select MIIDEV
+ select PHYLIB
bool "SMSC95xx"
endif
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index be5a170d71..97680cfb54 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -1,7 +1,7 @@
#include <common.h>
#include <init.h>
#include <net.h>
-#include <miidev.h>
+#include <linux/phy.h>
#include <usb/usb.h>
#include <usb/usbnet.h>
#include <errno.h>
@@ -231,10 +231,9 @@ static inline int asix_set_hw_mii(struct usbnet *dev)
return ret;
}
-static int asix_mdio_read(struct mii_device *mdev, int phy_id, int loc)
+static int asix_mdio_read(struct mii_bus *bus, int phy_id, int loc)
{
- struct eth_device *eth = mdev->edev;
- struct usbnet *dev = eth->priv;
+ struct usbnet *dev = bus->priv;
__le16 res;
asix_set_sw_mii(dev);
@@ -248,10 +247,9 @@ static int asix_mdio_read(struct mii_device *mdev, int phy_id, int loc)
return le16_to_cpu(res);
}
-static int asix_mdio_write(struct mii_device *mdev, int phy_id, int loc, int val)
+static int asix_mdio_write(struct mii_bus *bus, int phy_id, int loc, u16 val)
{
- struct eth_device *eth = mdev->edev;
- struct usbnet *dev = eth->priv;
+ struct usbnet *dev = bus->priv;
__le16 res = cpu_to_le16(val);
dev_dbg(&dev->edev.dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x",
@@ -469,14 +467,13 @@ static int asix_tx_fixup(struct usbnet *dev,
static int asix_init_mii(struct usbnet *dev)
{
- dev->miidev.read = asix_mdio_read;
- dev->miidev.write = asix_mdio_write;
- dev->miidev.address = asix_get_phy_addr(dev);
- dev->miidev.flags = 0;
- dev->miidev.edev = &dev->edev;
- dev->miidev.parent = &dev->udev->dev;
-
- return mii_register(&dev->miidev);
+ dev->miibus.read = asix_mdio_read;
+ dev->miibus.write = asix_mdio_write;
+ dev->phy_addr = asix_get_phy_addr(dev);
+ dev->miibus.priv = dev;
+ dev->miibus.parent = &dev->udev->dev;
+
+ return mdiobus_register(&dev->miibus);
}
static int ax88172_link_reset(struct usbnet *dev)
@@ -631,7 +628,7 @@ out:
static void asix_unbind(struct usbnet *dev)
{
- mii_unregister(&dev->miidev);
+ mdiobus_unregister(&dev->miibus);
}
static struct driver_info ax8817x_info = {
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index c21705eb80..11f2795fb9 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -27,7 +27,7 @@
#include <malloc.h>
#include <asm/byteorder.h>
#include <errno.h>
-#include <miidev.h>
+#include <linux/phy.h>
#include "smsc95xx.h"
#define SMSC_CHIPNAME "smsc95xx"
@@ -123,10 +123,9 @@ static int smsc95xx_phy_wait_not_busy(struct usbnet *dev)
return -EIO;
}
-static int smsc95xx_mdio_read(struct mii_device *mdev, int phy_id, int idx)
+static int smsc95xx_mdio_read(struct mii_bus *bus, int phy_id, int idx)
{
- struct eth_device *eth = mdev->edev;
- struct usbnet *dev = eth->priv;
+ struct usbnet *dev = bus->priv;
u32 val, addr;
/* confirm MII not busy */
@@ -149,11 +148,10 @@ static int smsc95xx_mdio_read(struct mii_device *mdev, int phy_id, int idx)
return val & 0xffff;
}
-static int smsc95xx_mdio_write(struct mii_device *mdev, int phy_id, int idx,
- int regval)
+static int smsc95xx_mdio_write(struct mii_bus *bus, int phy_id, int idx,
+ u16 regval)
{
- struct eth_device *eth = mdev->edev;
- struct usbnet *dev = eth->priv;
+ struct usbnet *dev = bus->priv;
u32 val, addr;
/* confirm MII not busy */
@@ -439,20 +437,19 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
uint16_t val, bmcr;
/* Initialize MII structure */
- dev->miidev.read = smsc95xx_mdio_read;
- dev->miidev.write = smsc95xx_mdio_write;
- dev->miidev.address = 1; /* FIXME: asix_get_phy_addr(dev); */
- dev->miidev.flags = 0;
- dev->miidev.edev = &dev->edev;
- dev->miidev.parent = &dev->udev->dev;
-// dev->miidev.name = dev->edev.name;
+ dev->miibus.read = smsc95xx_mdio_read;
+ dev->miibus.write = smsc95xx_mdio_write;
+ dev->phy_addr = 1; /* FIXME: asix_get_phy_addr(dev); */
+ dev->miibus.priv = dev;
+ dev->miibus.parent = &dev->udev->dev;
+// dev->miibus.name = dev->edev.name;
/* reset phy and wait for reset to complete */
- smsc95xx_mdio_write(&dev->miidev, phy_id, MII_BMCR, BMCR_RESET);
+ smsc95xx_mdio_write(&dev->miibus, phy_id, MII_BMCR, BMCR_RESET);
do {
udelay(10 * 1000);
- bmcr = smsc95xx_mdio_read(&dev->miidev, phy_id, MII_BMCR);
+ bmcr = smsc95xx_mdio_read(&dev->miibus, phy_id, MII_BMCR);
timeout++;
} while ((bmcr & MII_BMCR) && (timeout < 100));
@@ -461,14 +458,14 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
return -EIO;
}
- smsc95xx_mdio_write(&dev->miidev, phy_id, MII_ADVERTISE,
+ smsc95xx_mdio_write(&dev->miibus, phy_id, MII_ADVERTISE,
ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
ADVERTISE_PAUSE_ASYM);
/* read to clear */
- val = smsc95xx_mdio_read(&dev->miidev, phy_id, PHY_INT_SRC);
+ val = smsc95xx_mdio_read(&dev->miibus, phy_id, PHY_INT_SRC);
- smsc95xx_mdio_write(&dev->miidev, phy_id, PHY_INT_MASK,
+ smsc95xx_mdio_write(&dev->miibus, phy_id, PHY_INT_MASK,
PHY_INT_MASK_DEFAULT_);
netif_dbg(dev, ifup, dev->net, "phy initialised successfully\n");
@@ -751,7 +748,7 @@ static int smsc95xx_bind(struct usbnet *dev)
dev->edev.get_ethaddr = smsc95xx_get_ethaddr;
dev->edev.set_ethaddr = smsc95xx_set_ethaddr;
- mii_register(&dev->miidev);
+ mdiobus_register(&dev->miibus);
return 0;
}
@@ -760,7 +757,7 @@ static void smsc95xx_unbind(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
- mii_unregister(&dev->miidev);
+ mdiobus_unregister(&dev->miibus);
if (pdata) {
netif_dbg(dev, ifdown, dev->net, "free pdata\n");
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index c7e360690e..80b4ae7b9e 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -4,6 +4,7 @@
#include <asm/byteorder.h>
#include <errno.h>
#include <malloc.h>
+#include <linux/phy.h>
static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
{
@@ -160,8 +161,6 @@ static int usbnet_init(struct eth_device *edev)
return ret;
}
- miidev_restart_aneg(&dev->miidev);
-
return 0;
}
@@ -171,12 +170,8 @@ static int usbnet_open(struct eth_device *edev)
dev_dbg(&edev->dev, "%s\n",__func__);
- if (miidev_wait_aneg(&dev->miidev))
- return -1;
-
- miidev_print_status(&dev->miidev);
-
- return 0;
+ return phy_device_connect(edev, &dev->miibus, dev->phy_addr, NULL,
+ 0, PHY_INTERFACE_MODE_NA);
}
static void usbnet_halt(struct eth_device *edev)
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 16885c0af9..246a2a7bed 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -917,7 +917,6 @@ struct file_operations cfi_ops = {
.memmap = generic_memmap_ro,
};
-#ifdef CONFIG_PARTITION_NEED_MTD
static int cfi_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
@@ -977,11 +976,11 @@ static void cfi_init_mtd(struct flash_info *info)
mtd->flags = MTD_CAP_NORFLASH;
info->cdev.mtd = mtd;
}
-#endif
static int cfi_probe (struct device_d *dev)
{
struct flash_info *info = xzalloc(sizeof(*info));
+ int cfinum;
dev->priv = (void *)info;
@@ -1000,30 +999,46 @@ static int cfi_probe (struct device_d *dev)
dev_info(dev, "found cfi flash at %p, size %ld\n",
info->base, info->size);
- info->cdev.name = asprintf("nor%d", dev->id);
+ if (dev->id < 0)
+ cfinum = cdev_find_free_index("nor");
+ else
+ cfinum = dev->id;
+
+ info->cdev.name = asprintf("nor%d", cfinum);
info->cdev.size = info->size;
info->cdev.dev = dev;
info->cdev.ops = &cfi_ops;
info->cdev.priv = info;
-#ifdef CONFIG_PARTITION_NEED_MTD
- cfi_init_mtd(info);
-#endif
+ if (IS_ENABLED(CONFIG_PARTITION_NEED_MTD))
+ cfi_init_mtd(info);
+
devfs_create(&info->cdev);
+ if (dev->device_node)
+ of_parse_partitions(info->cdev.name, dev->device_node);
+
return 0;
}
+static __maybe_unused struct of_device_id cfi_dt_ids[] = {
+ {
+ .compatible = "cfi-flash",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d cfi_driver = {
- .name = "cfi_flash",
- .probe = cfi_probe,
- .info = cfi_info,
+ .name = "cfi_flash",
+ .probe = cfi_probe,
+ .info = cfi_info,
+ .of_compatible = DRV_OF_COMPAT(cfi_dt_ids),
};
static int cfi_init(void)
{
- return register_driver(&cfi_driver);
+ return register_driver(&cfi_driver);
}
device_initcall(cfi_init);
-
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index fec08940ab..1bfe81c381 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -75,9 +75,7 @@ struct flash_info {
ulong addr_unlock2; /* unlock address 2 for AMD flash roms */
struct cfi_cmd_set *cfi_cmd_set;
struct cdev cdev;
-#ifdef CONFIG_PARTITION_NEED_MTD
struct mtd_info mtd;
-#endif
int numeraseregions;
struct mtd_erase_region_info *eraseregions;
void *base;
diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
index 5713ad58fe..e3b5b95443 100644
--- a/drivers/nor/m25p80.c
+++ b/drivers/nor/m25p80.c
@@ -648,6 +648,9 @@ static const struct spi_device_id m25p_ids[] = {
{ "cat25c09", CAT25_INFO( 128, 8, 32, 2) },
{ "cat25c17", CAT25_INFO( 256, 8, 32, 2) },
{ "cat25128", CAT25_INFO(2048, 8, 64, 2) },
+
+ /* Micron */
+ { "n25q128", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
{ },
};
@@ -694,6 +697,74 @@ static struct file_operations m25p80_ops = {
.lseek = dev_lseek_default,
};
+static int m25p_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct m25p *flash = container_of(mtd, struct m25p, mtd);
+ ssize_t ret;
+
+ ret = flash->cdev.ops->read(&flash->cdev, buf, len, from, 0);
+ if (ret < 0) {
+ *retlen = 0;
+ return ret;
+ }
+
+ *retlen = ret;
+ return 0;
+}
+
+static int m25p_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct m25p *flash = container_of(mtd, struct m25p, mtd);
+ ssize_t ret;
+
+ ret = flash->cdev.ops->write(&flash->cdev, buf, len, to, 0);
+ if (ret < 0) {
+ *retlen = 0;
+ return ret;
+ }
+
+ *retlen = ret;
+ return 0;
+}
+
+static int m25p_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct m25p *flash = container_of(mtd, struct m25p, mtd);
+ ssize_t ret;
+
+ ret = flash->cdev.ops->erase(&flash->cdev, instr->len, instr->addr);
+
+ if (ret) {
+ instr->state = MTD_ERASE_FAILED;
+ return -EIO;
+ }
+
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
+}
+
+static void m25p_init_mtd(struct m25p *flash)
+{
+ struct mtd_info *mtd = &flash->mtd;
+
+ mtd->read = m25p_mtd_read;
+ mtd->write = m25p_mtd_write;
+ mtd->erase = m25p_mtd_erase;
+ mtd->size = flash->size;
+ mtd->name = flash->cdev.name;
+ mtd->erasesize = flash->erasesize;
+ mtd->writesize = 1;
+ mtd->subpage_sft = 0;
+ mtd->eraseregions = NULL;
+ mtd->numeraseregions = 0;
+ mtd->flags = MTD_CAP_NORFLASH;
+ flash->cdev.mtd = mtd;
+}
+
/*
* board specific setup should have ensured the SPI clock used here
* matches what the READ command supports, at least until this driver
@@ -825,6 +896,9 @@ static int m25p_probe(struct device_d *dev)
dev_info(dev, "%s (%lld Kbytes)\n", id->name, (long long)flash->size >> 10);
+ if (IS_ENABLED(CONFIG_PARTITION_NEED_MTD))
+ m25p_init_mtd(flash);
+
devfs_create(&flash->cdev);
return 0;
@@ -838,7 +912,7 @@ static struct driver_d epcs_flash_driver = {
static int epcs_init(void)
{
- register_driver(&epcs_flash_driver);
+ spi_register_driver(&epcs_flash_driver);
return 0;
}
diff --git a/drivers/nor/m25p80.h b/drivers/nor/m25p80.h
index 34bf2e259a..957900e3a2 100644
--- a/drivers/nor/m25p80.h
+++ b/drivers/nor/m25p80.h
@@ -46,7 +46,7 @@ struct spi_device_id {
struct m25p {
struct spi_device *spi;
struct flash_info *info;
- struct mtd_info mtd;
+ struct mtd_info mtd;
struct cdev cdev;
char *name;
u32 erasesize;
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
new file mode 100644
index 0000000000..95f10d025c
--- /dev/null
+++ b/drivers/of/Kconfig
@@ -0,0 +1,2 @@
+config OFDEVICE
+ bool
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
new file mode 100644
index 0000000000..c14aaec79f
--- /dev/null
+++ b/drivers/of/Makefile
@@ -0,0 +1,3 @@
+obj-y += base.o
+obj-y += gpio.o
+obj-y += partition.o
diff --git a/drivers/of/base.c b/drivers/of/base.c
new file mode 100644
index 0000000000..ebbaef85c1
--- /dev/null
+++ b/drivers/of/base.c
@@ -0,0 +1,802 @@
+/*
+ * base.c - basic devicetree functions
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#include <common.h>
+#include <of.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <malloc.h>
+#include <init.h>
+#include <linux/ctype.h>
+
+/**
+ * struct alias_prop - Alias property in 'aliases' node
+ * @link: List node to link the structure in aliases_lookup list
+ * @alias: Alias property name
+ * @np: Pointer to device_node that the alias stands for
+ * @id: Index value from end of alias name
+ * @stem: Alias string without the index
+ *
+ * The structure represents one alias property of 'aliases' node as
+ * an entry in aliases_lookup list.
+ */
+struct alias_prop {
+ struct list_head link;
+ const char *alias;
+ struct device_node *np;
+ int id;
+ char stem[0];
+};
+
+static LIST_HEAD(aliases_lookup);
+
+static LIST_HEAD(phandle_list);
+
+static LIST_HEAD(allnodes);
+
+struct device_node *root_node;
+
+struct device_node *of_aliases;
+
+int of_n_addr_cells(struct device_node *np)
+{
+ const __be32 *ip;
+
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = of_get_property(np, "#address-cells", NULL);
+ if (ip)
+ return be32_to_cpup(ip);
+ } while (np->parent);
+ /* No #address-cells property for the root node */
+ return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+}
+EXPORT_SYMBOL(of_n_addr_cells);
+
+int of_n_size_cells(struct device_node *np)
+{
+ const __be32 *ip;
+
+ do {
+ if (np->parent)
+ np = np->parent;
+ ip = of_get_property(np, "#size-cells", NULL);
+ if (ip)
+ return be32_to_cpup(ip);
+ } while (np->parent);
+ /* No #size-cells property for the root node */
+ return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+}
+EXPORT_SYMBOL(of_n_size_cells);
+
+static void of_bus_default_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = of_n_addr_cells(dev);
+ if (sizec)
+ *sizec = of_n_size_cells(dev);
+}
+
+void of_bus_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ of_bus_default_count_cells(dev, addrc, sizec);
+}
+
+struct property *of_find_property(const struct device_node *node, const char *name)
+{
+ struct property *p;
+
+ list_for_each_entry(p, &node->properties, list)
+ if (!strcmp(p->name, name))
+ return p;
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_property);
+
+static void of_alias_add(struct alias_prop *ap, struct device_node *np,
+ int id, const char *stem, int stem_len)
+{
+ ap->np = np;
+ ap->id = id;
+ strncpy(ap->stem, stem, stem_len);
+ ap->stem[stem_len] = 0;
+ list_add_tail(&ap->link, &aliases_lookup);
+ pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
+ ap->alias, ap->stem, ap->id, np->full_name);
+}
+
+/**
+ * of_alias_scan - Scan all properties of 'aliases' node
+ *
+ * The function scans all the properties of 'aliases' node and populates
+ * the global lookup table with the properties. It returns the
+ * number of alias_prop found, or error code in error case.
+ */
+void of_alias_scan(void)
+{
+ struct property *pp;
+
+ of_aliases = of_find_node_by_path("/aliases");
+ if (!of_aliases)
+ return;
+
+ list_for_each_entry(pp, &of_aliases->properties, list) {
+ const char *start = pp->name;
+ const char *end = start + strlen(start);
+ struct device_node *np;
+ struct alias_prop *ap;
+ int id, len;
+
+ /* Skip those we do not want to proceed */
+ if (!strcmp(pp->name, "name") ||
+ !strcmp(pp->name, "phandle") ||
+ !strcmp(pp->name, "linux,phandle"))
+ continue;
+
+ np = of_find_node_by_path(pp->value);
+ if (!np)
+ continue;
+
+ /* walk the alias backwards to extract the id and work out
+ * the 'stem' string */
+ while (isdigit(*(end-1)) && end > start)
+ end--;
+ len = end - start;
+
+ id = simple_strtol(end, 0, 10);
+ if (id < 0)
+ continue;
+
+ /* Allocate an alias_prop with enough space for the stem */
+ ap = xzalloc(sizeof(*ap) + len + 1);
+ if (!ap)
+ continue;
+ ap->alias = start;
+ of_alias_add(ap, np, id, start, len);
+ }
+}
+
+/**
+ * of_alias_get_id - Get alias id for the given device_node
+ * @np: Pointer to the given device_node
+ * @stem: Alias stem of the given device_node
+ *
+ * The function travels the lookup table to get alias id for the given
+ * device_node and alias stem. It returns the alias id if find it.
+ */
+int of_alias_get_id(struct device_node *np, const char *stem)
+{
+ struct alias_prop *app;
+ int id = -ENODEV;
+
+ list_for_each_entry(app, &aliases_lookup, link) {
+ if (strcmp(app->stem, stem) != 0)
+ continue;
+
+ if (np == app->np) {
+ id = app->id;
+ break;
+ }
+ }
+
+ return id;
+}
+EXPORT_SYMBOL_GPL(of_alias_get_id);
+
+u64 of_translate_address(struct device_node *node, const __be32 *in_addr)
+{
+ struct property *p;
+ u64 addr = be32_to_cpu(*in_addr);
+
+ while (1) {
+ int na, nc;
+
+ if (!node->parent)
+ return addr;
+
+ node = node->parent;
+ p = of_find_property(node, "ranges");
+ if (!p && node->parent)
+ return OF_BAD_ADDR;
+ of_bus_count_cells(node, &na, &nc);
+ if (na != 1 || nc != 1) {
+ printk("%s: #size-cells != 1 or #address-cells != 1 "
+ "currently not supported\n", node->name);
+ return OF_BAD_ADDR;
+ }
+ }
+}
+EXPORT_SYMBOL(of_translate_address);
+
+/*
+ * of_find_node_by_phandle - Find a node given a phandle
+ * @handle: phandle of the node to find
+ */
+struct device_node *of_find_node_by_phandle(phandle phandle)
+{
+ struct device_node *node;
+
+ list_for_each_entry(node, &phandle_list, phandles)
+ if (node->phandle == phandle)
+ return node;
+ return NULL;
+}
+EXPORT_SYMBOL(of_find_node_by_phandle);
+
+/*
+ * Find a property with a given name for a given node
+ * and return the value.
+ */
+const void *of_get_property(const struct device_node *np, const char *name,
+ int *lenp)
+{
+ struct property *pp = of_find_property(np, name);
+
+ if (!pp)
+ return NULL;
+
+ if (lenp)
+ *lenp = pp->length;
+
+ return pp ? pp->value : NULL;
+}
+EXPORT_SYMBOL(of_get_property);
+
+/** Checks if the given "compat" string matches one of the strings in
+ * the device's "compatible" property
+ */
+int of_device_is_compatible(const struct device_node *device,
+ const char *compat)
+{
+ const char *cp;
+ int cplen, l;
+
+ cp = of_get_property(device, "compatible", &cplen);
+ if (cp == NULL)
+ return 0;
+ while (cplen > 0) {
+ if (strcmp(cp, compat) == 0)
+ return 1;
+ l = strlen(cp) + 1;
+ cp += l;
+ cplen -= l;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(of_device_is_compatible);
+
+int of_match(struct device_d *dev, struct driver_d *drv)
+{
+ struct of_device_id *id;
+
+ id = drv->of_compatible;
+
+ while (id->compatible) {
+ if (of_device_is_compatible(dev->device_node, id->compatible) == 1) {
+ dev->of_id_entry = id;
+ return 0;
+ }
+ id++;
+ }
+
+ return 1;
+}
+EXPORT_SYMBOL(of_match);
+
+/**
+ * of_property_read_u32_array - Find and read an array of 32 bit integers
+ * from a property.
+ *
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @out_value: pointer to return value, modified only if return value is 0.
+ *
+ * Search for a property in a device node and read 32-bit value(s) from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+ * The out_value is modified only if a valid u32 value can be decoded.
+ */
+int of_property_read_u32_array(const struct device_node *np,
+ const char *propname, u32 *out_values,
+ size_t sz)
+{
+ struct property *prop = of_find_property(np, propname);
+ const __be32 *val;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+ if ((sz * sizeof(*out_values)) > prop->length)
+ return -EOVERFLOW;
+
+ val = prop->value;
+ while (sz--)
+ *out_values++ = be32_to_cpup(val++);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_property_read_u32_array);
+
+/**
+ * of_parse_phandles_with_args - Find a node pointed by phandle in a list
+ * @np: pointer to a device tree node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name: property name that specifies phandles' arguments count
+ * @index: index of a phandle to parse out
+ * @out_node: optional pointer to device_node struct pointer (will be filled)
+ * @out_args: optional pointer to arguments pointer (will be filled)
+ *
+ * This function is useful to parse lists of phandles and their arguments.
+ * Returns 0 on success and fills out_node and out_args, on error returns
+ * appropriate errno value.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ * #list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ * #list-cells = <1>;
+ * }
+ *
+ * node3 {
+ * list = <&phandle1 1 2 &phandle2 3>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args);
+ */
+int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
+ const char *cells_name, int index,
+ struct device_node **out_node,
+ const void **out_args)
+{
+ int ret = -EINVAL;
+ const __be32 *list;
+ const __be32 *list_end;
+ int size;
+ int cur_index = 0;
+ struct device_node *node = NULL;
+ const void *args = NULL;
+
+ list = of_get_property(np, list_name, &size);
+ if (!list) {
+ ret = -ENOENT;
+ goto err0;
+ }
+ list_end = list + size / sizeof(*list);
+
+ while (list < list_end) {
+ const __be32 *cells;
+ phandle phandle;
+
+ phandle = be32_to_cpup(list++);
+ args = list;
+
+ /* one cell hole in the list = <>; */
+ if (!phandle)
+ goto next;
+
+ node = of_find_node_by_phandle(phandle);
+ if (!node) {
+ pr_debug("%s: could not find phandle %d\n",
+ np->full_name, phandle);
+ goto err0;
+ }
+
+ cells = of_get_property(node, cells_name, &size);
+ if (!cells || size != sizeof(*cells)) {
+ pr_debug("%s: could not get %s for %s\n",
+ np->full_name, cells_name, node->full_name);
+ goto err1;
+ }
+
+ list += be32_to_cpup(cells);
+ if (list > list_end) {
+ pr_debug("%s: insufficient arguments length\n",
+ np->full_name);
+ goto err1;
+ }
+next:
+ if (cur_index == index)
+ break;
+
+ node = NULL;
+ args = NULL;
+ cur_index++;
+ }
+
+ if (!node) {
+ /*
+ * args w/o node indicates that the loop above has stopped at
+ * the 'hole' cell. Report this differently.
+ */
+ if (args)
+ ret = -EEXIST;
+ else
+ ret = -ENOENT;
+ goto err0;
+ }
+
+ if (out_node)
+ *out_node = node;
+ if (out_args)
+ *out_args = args;
+
+ return 0;
+err1:
+err0:
+ pr_debug("%s failed with status %d\n", __func__, ret);
+ return ret;
+}
+EXPORT_SYMBOL(of_parse_phandles_with_args);
+
+/**
+ * of_machine_is_compatible - Test root of device tree for a given compatible value
+ * @compat: compatible string to look for in root node's compatible property.
+ *
+ * Returns true if the root node has the given value in its
+ * compatible property.
+ */
+int of_machine_is_compatible(const char *compat)
+{
+ if (!root_node)
+ return 0;
+
+ return of_device_is_compatible(root_node, compat);
+}
+EXPORT_SYMBOL(of_machine_is_compatible);
+
+/**
+ * of_find_node_by_path - Find a node matching a full OF path
+ * @path: The full path to match
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_find_node_by_path(const char *path)
+{
+ struct device_node *np;
+
+ list_for_each_entry(np, &allnodes, list) {
+ if (np->full_name && (strcmp(np->full_name, path) == 0))
+ break;
+ }
+ return np;
+}
+EXPORT_SYMBOL(of_find_node_by_path);
+
+struct device_node *of_get_root_node(void)
+{
+ return root_node;
+}
+
+static int of_node_disabled(struct device_node *node)
+{
+ struct property *p;
+
+ p = of_find_property(node, "status");
+ if (p) {
+ if (!strcmp("disabled", p->value))
+ return 1;
+ }
+ return 0;
+}
+
+void of_print_nodes(struct device_node *node, int indent)
+{
+ struct device_node *n;
+ struct property *p;
+ int i;
+
+ if (!node)
+ return;
+
+ if (of_node_disabled(node))
+ return;
+
+ for (i = 0; i < indent; i++)
+ printf("\t");
+
+ printf("%s%s\n", node->name, node->name ? " {" : "{");
+
+ list_for_each_entry(p, &node->properties, list) {
+ for (i = 0; i < indent + 1; i++)
+ printf("\t");
+ printf("%s: ", p->name);
+ of_print_property(p->value, p->length);
+ printf("\n");
+ }
+
+ list_for_each_entry(n, &node->children, parent_list) {
+ of_print_nodes(n, indent + 1);
+ }
+
+ for (i = 0; i < indent; i++)
+ printf("\t");
+ printf("};\n");
+}
+
+static struct device_node *new_device_node(struct device_node *parent)
+{
+ struct device_node *node;
+
+ node = xzalloc(sizeof(*node));
+ node->parent = parent;
+ if (parent)
+ list_add_tail(&node->parent_list, &parent->children);
+
+ INIT_LIST_HEAD(&node->children);
+ INIT_LIST_HEAD(&node->properties);
+
+ return node;
+}
+
+static struct property *new_property(struct device_node *node, const char *name,
+ const void *data, int len)
+{
+ struct property *prop;
+
+ prop = xzalloc(sizeof(*prop));
+
+ prop->name = strdup(name);
+ prop->length = len;
+ prop->value = xzalloc(len);
+ memcpy(prop->value, data, len);
+
+ list_add_tail(&prop->list, &node->properties);
+
+ return prop;
+}
+
+static struct device_d *add_of_device(struct device_node *node)
+{
+ struct device_d *dev;
+ char *name, *at;
+ const struct property *cp;
+
+ if (of_node_disabled(node))
+ return NULL;
+
+ cp = of_get_property(node, "compatible", NULL);
+ if (!cp)
+ return NULL;
+
+ dev = xzalloc(sizeof(*dev));
+
+ name = xstrdup(node->name);
+ at = strchr(name, '@');
+ if (at) {
+ *at = 0;
+ snprintf(dev->name, MAX_DRIVER_NAME, "%s.%s", at + 1, name);
+ } else {
+ strncpy(dev->name, node->name, MAX_DRIVER_NAME);
+ }
+
+ dev->id = DEVICE_ID_SINGLE;
+ dev->resource = node->resource;
+ dev->num_resources = 1;
+ dev->device_node = node;
+ node->device = dev;
+
+ debug("register device 0x%08x\n", node->resource[0].start);
+
+ register_device(dev);
+
+ free(name);
+
+ return dev;
+}
+EXPORT_SYMBOL(add_of_device);
+
+static int add_of_device_resource(struct device_node *node)
+{
+ struct property *reg;
+ u64 address, size;
+ struct resource *res;
+ struct device_d *dev;
+ phandle phandle;
+ int ret;
+
+ ret = of_property_read_u32(node, "phandle", &phandle);
+ if (!ret) {
+ node->phandle = phandle;
+ list_add_tail(&node->phandles, &phandle_list);
+ }
+
+ reg = of_find_property(node, "reg");
+ if (!reg)
+ return -ENODEV;
+
+ address = of_translate_address(node, reg->value);
+ if (address == OF_BAD_ADDR)
+ return -EINVAL;
+
+ size = be32_to_cpu(((u32 *)reg->value)[1]);
+
+ /*
+ * A device may already be registered as platform_device.
+ * Instead of registering the same device again, just
+ * add this node to the existing device.
+ */
+ for_each_device(dev) {
+ if (!dev->resource)
+ continue;
+ if (dev->resource->start == address) {
+ debug("connecting %s to %s\n", node->name, dev_name(dev));
+ node->device = dev;
+ dev->device_node = node;
+ node->resource = dev->resource;
+ return 0;
+ }
+ }
+
+ res = xzalloc(sizeof(*res));
+ res->start = address;
+ res->end = address + size - 1;
+ res->flags = IORESOURCE_MEM;
+
+ node->resource = res;
+
+ add_of_device(node);
+
+ return 0;
+}
+
+void of_free(struct device_node *node)
+{
+ struct device_node *n, *nt;
+ struct property *p, *pt;
+
+ if (!node)
+ return;
+
+ list_for_each_entry_safe(p, pt, &node->properties, list) {
+ list_del(&p->list);
+ free(p->name);
+ free(p->value);
+ free(p);
+ }
+
+ list_for_each_entry_safe(n, nt, &node->children, parent_list) {
+ of_free(n);
+ }
+
+ if (node->parent)
+ list_del(&node->parent_list);
+
+ if (node->device)
+ node->device->device_node = NULL;
+ else
+ free(node->resource);
+
+ free(node->name);
+ free(node->full_name);
+ free(node);
+}
+
+static void __of_probe(struct device_node *node)
+{
+ struct device_node *n;
+
+ if (node->device)
+ return;
+
+ add_of_device_resource(node);
+
+ list_for_each_entry(n, &node->children, parent_list)
+ __of_probe(n);
+}
+
+int of_probe(void)
+{
+ if(!root_node)
+ return -ENODEV;
+
+ __of_probe(root_node);
+
+ return 0;
+}
+
+/*
+ * Parse a flat device tree binary blob and store it in the barebox
+ * internal tree format,
+ */
+int of_parse_dtb(struct fdt_header *fdt)
+{
+ const void *nodep; /* property node pointer */
+ int nodeoffset; /* node offset from libfdt */
+ int nextoffset; /* next node offset from libfdt */
+ uint32_t tag; /* tag */
+ int len; /* length of the property */
+ int level = 0; /* keep track of nesting level */
+ const struct fdt_property *fdt_prop;
+ const char *pathp;
+ int depth = 10000;
+ struct device_node *node = NULL;
+ char buf[1024];
+ int ret;
+
+ if (root_node)
+ return -EBUSY;
+
+ nodeoffset = fdt_path_offset(fdt, "/");
+ if (nodeoffset < 0) {
+ /*
+ * Not found or something else bad happened.
+ */
+ printf ("libfdt fdt_path_offset() returned %s\n",
+ fdt_strerror(nodeoffset));
+ return -EINVAL;
+ }
+
+ while (1) {
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ pathp = fdt_get_name(fdt, nodeoffset, NULL);
+
+ if (pathp == NULL)
+ pathp = "/* NULL pointer error */";
+
+ ret = fdt_get_path(fdt, nodeoffset, buf, 1024);
+ if (ret)
+ return -EINVAL;
+
+ node = new_device_node(node);
+ if (!node->parent)
+ root_node = node;
+ node->full_name = xstrdup(buf);
+ node->name = xstrdup(pathp);
+ list_add_tail(&node->list, &allnodes);
+ break;
+ case FDT_END_NODE:
+ node = node->parent;
+ break;
+ case FDT_PROP:
+ fdt_prop = fdt_offset_ptr(fdt, nodeoffset,
+ sizeof(*fdt_prop));
+ pathp = fdt_string(fdt,
+ fdt32_to_cpu(fdt_prop->nameoff));
+ len = fdt32_to_cpu(fdt_prop->len);
+ nodep = fdt_prop->data;
+ new_property(node, pathp, nodep, len);
+ break;
+ case FDT_NOP:
+ break;
+ case FDT_END:
+ of_alias_scan();
+ return 0;
+ default:
+ if (level <= depth)
+ printf("Unknown tag 0x%08X\n", tag);
+ return -EINVAL;
+ }
+ nodeoffset = nextoffset;
+ }
+
+ return 0;
+}
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
new file mode 100644
index 0000000000..d4314f3e28
--- /dev/null
+++ b/drivers/of/gpio.c
@@ -0,0 +1,28 @@
+#define DEBUG
+
+#include <common.h>
+#include <errno.h>
+#include <of.h>
+#include <gpio.h>
+
+int of_get_named_gpio(struct device_node *np,
+ const char *propname, int index)
+{
+ int ret;
+ struct device_node *gpio_np;
+ const void *gpio_spec;
+
+ ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index,
+ &gpio_np, &gpio_spec);
+ if (ret) {
+ pr_debug("%s: can't parse gpios property: %d\n", __func__, ret);
+ return -EINVAL;
+ }
+
+ ret = gpio_get_num(gpio_np->device, be32_to_cpup(gpio_spec));
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+
diff --git a/drivers/of/partition.c b/drivers/of/partition.c
new file mode 100644
index 0000000000..6a57a6036e
--- /dev/null
+++ b/drivers/of/partition.c
@@ -0,0 +1,64 @@
+/*
+ * partition.c - devicetree partition parsing
+ *
+ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * based on Linux devicetree support
+ *
+ * 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 version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#include <common.h>
+#include <of.h>
+#include <malloc.h>
+#include <linux/mtd/mtd.h>
+
+int of_parse_partitions(const char *cdevname,
+ struct device_node *node)
+{
+ struct device_node *n;
+ const char *partname;
+ char *filename;
+
+ device_node_for_nach_child(node, n) {
+ const __be32 *reg;
+ unsigned long offset, size;
+ const char *name;
+ int len;
+ unsigned long flags = 0;
+
+ reg = of_get_property(n, "reg", &len);
+ if (!reg)
+ continue;
+
+ offset = be32_to_cpu(reg[0]);
+ size = be32_to_cpu(reg[1]);
+
+ partname = of_get_property(n, "label", &len);
+ if (!partname)
+ partname = of_get_property(n, "name", &len);
+ name = (char *)partname;
+
+ debug("add partition: %s.%s 0x%08lx 0x%08lx\n", cdevname, partname, offset, size);
+
+ if (of_get_property(n, "read-only", &len))
+ flags = DEVFS_PARTITION_READONLY;
+
+ filename = asprintf("%s.%s", cdevname, partname);
+
+ devfs_add_partition(cdevname, offset, size, flags, filename);
+
+ free(filename);
+ }
+
+ return 0;
+}
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index f8c55c4b54..b62dc9ff3c 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -35,6 +35,7 @@
#include <linux/amba/serial.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/amba/bus.h>
/*
* We wrap our port structure around the generic console_device.
@@ -44,6 +45,23 @@ struct amba_uart_port {
struct console_device uart; /* uart */
struct clk *clk; /* uart clock */
u32 uartclk;
+ struct vendor_data *vendor;
+};
+
+/* There is by now at least one vendor with differing details, so handle it */
+struct vendor_data {
+ unsigned int lcrh_tx;
+ unsigned int lcrh_rx;
+};
+
+static struct vendor_data vendor_arm = {
+ .lcrh_tx = UART011_LCRH,
+ .lcrh_rx = UART011_LCRH,
+};
+
+static struct vendor_data vendor_st = {
+ .lcrh_tx = ST_UART011_LCRH_TX,
+ .lcrh_rx = ST_UART011_LCRH_RX,
};
static inline struct amba_uart_port *
@@ -116,13 +134,27 @@ static int pl011_tstc(struct console_device *cdev)
return !(readl(uart->base + UART01x_FR) & UART01x_FR_RXFE);
}
+static void pl011_rlcr(struct amba_uart_port *uart, u32 lcr)
+{
+ struct vendor_data *vendor = uart->vendor;
+
+ writew(lcr, uart->base + vendor->lcrh_rx);
+ if (vendor->lcrh_tx != vendor->lcrh_rx) {
+ int i;
+ /*
+ * Wait 10 PCLKs before writing LCRH_TX register,
+ * to get this delay write read only register 10 times
+ */
+ for (i = 0; i < 10; ++i)
+ writew(0xff, uart->base + UART011_MIS);
+ writew(lcr, uart->base + vendor->lcrh_tx);
+ }
+}
+
int pl011_init_port (struct console_device *cdev)
{
- struct device_d *dev = cdev->dev;
struct amba_uart_port *uart = to_amba_uart_port(cdev);
- uart->base = dev_request_mem_region(dev, 0);
-
/*
** First, disable everything.
*/
@@ -142,8 +174,7 @@ int pl011_init_port (struct console_device *cdev)
/*
** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled.
*/
- writel((UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN),
- uart->base + UART011_LCRH);
+ pl011_rlcr(uart, UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN);
/*
** Finally, enable the UART
@@ -154,19 +185,21 @@ int pl011_init_port (struct console_device *cdev)
return 0;
}
-static int pl011_probe(struct device_d *dev)
+static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
{
struct amba_uart_port *uart;
struct console_device *cdev;
uart = xzalloc(sizeof(struct amba_uart_port));
- uart->clk = clk_get(dev, NULL);
+ uart->clk = clk_get(&dev->dev, NULL);
+ uart->base = amba_get_mem_region(dev);
+ uart->vendor = (void*)id->data;
if (IS_ERR(uart->clk))
return PTR_ERR(uart->clk);
cdev = &uart->uart;
- cdev->dev = dev;
+ cdev->dev = &dev->dev;
cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
cdev->tstc = pl011_tstc;
cdev->putc = pl011_putc;
@@ -182,14 +215,31 @@ static int pl011_probe(struct device_d *dev)
return 0;
}
-static struct driver_d pl011_driver = {
- .name = "uart-pl011",
- .probe = pl011_probe,
+static struct amba_id pl011_ids[] = {
+ {
+ .id = 0x00041011,
+ .mask = 0x000fffff,
+ .data = &vendor_arm,
+ },
+ {
+ .id = 0x00380802,
+ .mask = 0x00ffffff,
+ .data = &vendor_st,
+ },
+ { 0, 0 },
+};
+
+struct amba_driver pl011_driver = {
+ .drv = {
+ .name = "uart-pl011",
+ },
+ .probe = pl011_probe,
+ .id_table = pl011_ids,
};
static int pl011_init(void)
{
- register_driver(&pl011_driver);
+ amba_driver_register(&pl011_driver);
return 0;
}
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index 1e1e8e3157..9d150383f3 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -357,10 +357,23 @@ static void imx_serial_remove(struct device_d *dev)
free(priv);
}
+static __maybe_unused struct of_device_id imx_serial_dt_ids[] = {
+ {
+ .compatible = "fsl,imx1-uart",
+ .data = 0,
+ }, {
+ .compatible = "fsl,imx21-uart",
+ .data = 1,
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d imx_serial_driver = {
- .name = "imx_serial",
- .probe = imx_serial_probe,
+ .name = "imx_serial",
+ .probe = imx_serial_probe,
.remove = imx_serial_remove,
+ .of_compatible = DRV_OF_COMPAT(imx_serial_dt_ids),
};
static int imx_serial_init(void)
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 80a14504f0..299c1a40b9 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -24,6 +24,7 @@
#include <spi/spi.h>
#include <xfuncs.h>
#include <io.h>
+#include <errno.h>
#include <gpio.h>
#include <mach/spi.h>
#include <mach/generic.h>
@@ -495,6 +496,32 @@ static struct spi_imx_devtype_data spi_imx_devtype_data[] = {
#endif
};
+static int imx_spi_dt_probe(struct imx_spi *imx)
+{
+ struct device_node *node = imx->master.dev->device_node;
+ int ret, i;
+ u32 num_cs;
+
+ if (!node)
+ return -ENODEV;
+
+ ret = of_property_read_u32(node, "fsl,spi-num-chipselects", &num_cs);
+ if (ret)
+ return ret;
+
+ imx->master.num_chipselect = num_cs;
+ imx->cs_array = xzalloc(sizeof(u32) * num_cs);
+
+ for (i = 0; i < num_cs; i++) {
+ int cs_gpio = of_get_named_gpio(node, "cs-gpios", i);
+ imx->cs_array[i] = cs_gpio;
+ }
+
+ spi_of_register_slaves(&imx->master, node);
+
+ return 0;
+}
+
static int imx_spi_probe(struct device_d *dev)
{
struct spi_master *master;
@@ -509,8 +536,13 @@ static int imx_spi_probe(struct device_d *dev)
master->setup = imx_spi_setup;
master->transfer = imx_spi_transfer;
- master->num_chipselect = pdata->num_chipselect;
- imx->cs_array = pdata->chipselect;
+ if (pdata) {
+ master->num_chipselect = pdata->num_chipselect;
+ imx->cs_array = pdata->chipselect;
+ } else {
+ if (IS_ENABLED(CONFIG_OFDEVICE))
+ imx_spi_dt_probe(imx);
+ }
#ifdef CONFIG_DRIVER_SPI_IMX_0_0
if (cpu_is_mx27())
@@ -536,9 +568,22 @@ static int imx_spi_probe(struct device_d *dev)
return 0;
}
+static __maybe_unused struct of_device_id imx_spi_dt_ids[] = {
+ {
+ .compatible = "fsl,imx27-cspi",
+ }, {
+ .compatible = "fsl,imx35-cspi",
+ }, {
+ .compatible = "fsl,imx51-ecspi",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d imx_spi_driver = {
.name = "imx_spi",
.probe = imx_spi_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_spi_dt_ids),
};
static int imx_spi_init(void)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a7fe10cba0..b40678ce3d 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -27,6 +27,8 @@
#include <xfuncs.h>
#include <malloc.h>
#include <errno.h>
+#include <init.h>
+#include <of.h>
/* SPI devices should normally not be created by SPI device drivers; that
* would make them board-specific. Similarly with SPI master drivers.
@@ -77,10 +79,12 @@ struct spi_device *spi_new_device(struct spi_master *master,
proxy->mode = chip->mode;
proxy->bits_per_word = chip->bits_per_word ? chip->bits_per_word : 8;
proxy->dev.platform_data = chip->platform_data;
+ proxy->dev.bus = &spi_bus;
strcpy(proxy->dev.name, chip->name);
/* allocate a free id for this chip */
proxy->dev.id = DEVICE_ID_DYNAMIC;
proxy->dev.type_data = proxy;
+ proxy->dev.device_node = chip->device_node;
dev_add_child(master->dev, &proxy->dev);
/* drivers may modify this initial i/o setup */
@@ -100,6 +104,27 @@ fail:
}
EXPORT_SYMBOL(spi_new_device);
+#ifdef CONFIG_OFDEVICE
+void spi_of_register_slaves(struct spi_master *master, struct device_node *node)
+{
+ struct device_node *n;
+ struct spi_board_info chip;
+ struct property *reg;
+
+ device_node_for_nach_child(node, n) {
+ chip.name = n->name;
+ chip.bus_num = master->bus_num;
+ chip.max_speed_hz = 300000; /* FIXME */
+ reg = of_find_property(n, "reg");
+ if (!reg)
+ continue;
+ chip.chip_select = of_read_number(reg->value, 1);
+ chip.device_node = n;
+ spi_register_board_info(&chip, 1);
+ }
+}
+#endif
+
/**
* spi_register_board_info - register SPI devices for a given board
* @info: array of chip descriptors
@@ -154,6 +179,8 @@ static void scan_boardinfo(struct spi_master *master)
}
}
+static LIST_HEAD(spi_master_list);
+
/**
* spi_register_master - register SPI master controller
* @master: initialized master, originally from spi_alloc_master()
@@ -186,6 +213,8 @@ int spi_register_master(struct spi_master *master)
if (master->num_chipselect == 0)
return -EINVAL;
+ list_add_tail(&master->list, &spi_master_list);
+
/* populate children from any spi device tables */
scan_boardinfo(master);
status = 0;
@@ -240,3 +269,35 @@ int spi_write_then_read(struct spi_device *spi,
return status;
}
EXPORT_SYMBOL(spi_write_then_read);
+
+static int spi_match(struct device_d *dev, struct driver_d *drv)
+{
+ if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node &&
+ drv->of_compatible)
+ return of_match(dev, drv);
+
+ return strcmp(dev->name, drv->name) ? -1 : 0;
+}
+
+static int spi_probe(struct device_d *dev)
+{
+ return dev->driver->probe(dev);
+}
+
+static void spi_remove(struct device_d *dev)
+{
+ dev->driver->remove(dev);
+}
+
+struct bus_type spi_bus = {
+ .name = "spi",
+ .match = spi_match,
+ .probe = spi_probe,
+ .remove = spi_remove,
+};
+
+static int spi_bus_init(void)
+{
+ return bus_register(&spi_bus);
+}
+pure_initcall(spi_bus_init);
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 48bc121160..3ab06589d4 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1422,3 +1422,8 @@ struct bus_type usb_bus_type = {
.remove = usb_remove,
};
+static int usb_bus_init(void)
+{
+ return bus_register(&usb_bus_type);
+}
+pure_initcall(usb_bus_init);
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index d885570b24..ae6ff74cab 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -125,6 +125,7 @@ int register_framebuffer(struct fb_info *info)
sprintf(dev->name, "fb");
+ info->dev.bus = &fb_bus;
register_device(&info->dev);
dev_add_param(dev, "enable", fb_enable_set, NULL, 0);
dev_set_param(dev, "enable", "0");
@@ -160,19 +161,41 @@ static void fb_info(struct device_d *dev)
printf("\n");
}
-static int fb_probe(struct device_d *hw_dev)
+static struct driver_d fb_driver = {
+ .name = "fb",
+ .info = fb_info,
+};
+
+static int fb_match(struct device_d *dev, struct driver_d *drv)
{
return 0;
}
-static struct driver_d fb_driver = {
- .name = "fb",
+static int fb_probe(struct device_d *dev)
+{
+ return 0;
+}
+
+static void fb_remove(struct device_d *dev)
+{
+}
+
+struct bus_type fb_bus = {
+ .name = "fb",
+ .match = fb_match,
.probe = fb_probe,
- .info = fb_info,
+ .remove = fb_remove,
};
+static int fb_bus_init(void)
+{
+ return bus_register(&fb_bus);
+}
+pure_initcall(fb_bus_init);
+
static int fb_init_driver(void)
{
+ fb_driver.bus = &fb_bus;
register_driver(&fb_driver);
return 0;
}
diff --git a/fs/fat/ff.c b/fs/fat/ff.c
index 66db1d6b50..33f8b6195d 100644
--- a/fs/fat/ff.c
+++ b/fs/fat/ff.c
@@ -93,6 +93,7 @@
#include <errno.h>
#include <malloc.h>
#include <linux/ctype.h>
+#include <filetype.h>
#include "ff.h" /* FatFs configurations and declarations */
#include "diskio.h" /* Declarations of low level disk I/O functions */
@@ -1531,29 +1532,20 @@ int follow_path ( /* 0(0): successful, !=0: error code */
/*
* Load boot record and check if it is an FAT boot record
*/
-static int check_fs ( /* 0:The FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */
+static enum filetype check_fs ( /* 0:The FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */
FATFS *fs, /* File system object */
- DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
+ DWORD sect, /* Sector# (lba) to check if it is an FAT boot record or not */
+ DWORD *bootsec
)
{
- int ret;
+ enum filetype ret;
/* Load boot record */
ret = disk_read(fs, fs->win, sect, 1);
if (ret)
- return ret;
- /* Check record signature (always placed at offset 510 even if the sector size is>512) */
- if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55)
- return -ENODEV;
-
- /* Check "FAT" string */
- if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146)
- return 0;
-
- if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)
- return 0;
+ return filetype_unknown;
- return -ENODEV;
+ return is_fat_or_mbr(fs->win, bootsec);
}
/*
@@ -1565,8 +1557,10 @@ static int chk_mounted ( /* 0(0): successful, !=0: any error occurred */
)
{
BYTE fmt, b;
+ DWORD first_boot_sect;
DWORD bsect, fasize, tsect, sysect, nclst, szbfat;
WORD nrsv;
+ enum filetype type;
INIT_LIST_HEAD(&fs->dirtylist);
@@ -1579,9 +1573,16 @@ static int chk_mounted ( /* 0(0): successful, !=0: any error occurred */
return -EIO;
#endif
/* Search FAT partition on the drive. Supports only generic partitionings, FDISK and SFD. */
- fmt = check_fs(fs, bsect = 0); /* Check sector 0 if it is a VBR */
- if (fmt)
- return fmt; /* No FAT volume is found */
+ type = check_fs(fs, bsect = 0, &first_boot_sect); /* Check sector 0 if it is a VBR */
+ if (type == filetype_mbr) {
+ /* Sector 0 is an MBR, now check for FAT in the first partition */
+ type = check_fs(fs, bsect = first_boot_sect, NULL);
+ if (type != filetype_fat)
+ return -ENODEV;
+ }
+
+ if (type == filetype_unknown)
+ return -ENODEV;
/* Following code initializes the file system object */
diff --git a/fs/fs.c b/fs/fs.c
index 38917bf72b..b11878a748 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1141,6 +1141,12 @@ struct bus_type fs_bus = {
.remove = fs_remove,
};
+static int fs_bus_init(void)
+{
+ return bus_register(&fs_bus);
+}
+pure_initcall(fs_bus_init);
+
int register_fs_driver(struct fs_driver_d *fsdrv)
{
fsdrv->drv.bus = &fs_bus;
@@ -1525,7 +1531,9 @@ ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulon
return -1;
dev = cdev->dev;
- size = min((loff_t)count, resource_size(&dev->resource[0]) - offset);
+ size = min((resource_size_t)count,
+ resource_size(&dev->resource[0]) -
+ (resource_size_t)offset);
memcpy_sz(buf, dev_get_mem_region(dev, 0) + offset, size, flags & O_RWSIZE_MASK);
return size;
}
@@ -1540,7 +1548,9 @@ ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, loff_t offse
return -1;
dev = cdev->dev;
- size = min((loff_t)count, resource_size(&dev->resource[0]) - offset);
+ size = min((resource_size_t)count,
+ resource_size(&dev->resource[0]) -
+ (resource_size_t)offset);
memcpy_sz(dev_get_mem_region(dev, 0) + offset, buf, size, flags & O_RWSIZE_MASK);
return size;
}
diff --git a/fs/nfs.c b/fs/nfs.c
index 4a880cd302..797e3bd471 100644
--- a/fs/nfs.c
+++ b/fs/nfs.c
@@ -819,7 +819,11 @@ static int nfs_read(struct device_d *dev, FILE *file, void *buf, size_t insize)
insize -= now;
if (insize) {
- now = 1024;
+ /* do not use min as insize is a size_t */
+ if (insize < 1024)
+ now = insize;
+ else
+ now = 1024;
if (pos + now > file->size)
now = file->size - pos;
diff --git a/include/common.h b/include/common.h
index df12083944..30c1dc6548 100644
--- a/include/common.h
+++ b/include/common.h
@@ -150,11 +150,11 @@ static inline void dump_stack(void)
#define MEMAREA_SIZE_SPECIFIED 1
struct memarea_info {
- struct device_d *device;
+ struct device_d *device;
unsigned long start;
unsigned long end;
unsigned long size;
- unsigned long flags;
+ unsigned long flags;
};
int parse_area_spec(const char *str, loff_t *start, loff_t *size);
diff --git a/include/driver.h b/include/driver.h
index 0fecc7a670..4a24295276 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -25,6 +25,7 @@
#include <linux/list.h>
#include <linux/ioport.h>
+#include <of.h>
#define MAX_DRIVER_NAME 32
#define FORMAT_DRIVER_NAME_ID "%s%d"
@@ -60,6 +61,11 @@
struct filep;
struct bus_type;
+struct platform_device_id {
+ const char *name;
+ unsigned long driver_data;
+};
+
/** @brief Describes a particular device present in the system */
struct device_d {
/*! This member (and 'type' described below) is used to match with a
@@ -86,6 +92,7 @@ struct device_d {
struct driver_d *driver; /*! The driver for this device */
struct list_head list; /* The list of all devices */
+ struct list_head bus_list; /* our bus */
struct list_head children; /* our children */
struct list_head sibling;
struct list_head active; /* The list of all devices which have a driver */
@@ -99,6 +106,11 @@ struct device_d {
struct list_head parameters;
struct list_head cdevs;
+
+ struct platform_device_id *id_entry;
+ struct device_node *device_node;
+
+ struct of_device_id *of_id_entry;
};
/** @brief Describes a driver present in the system */
@@ -108,6 +120,7 @@ struct driver_d {
const char *name;
struct list_head list;
+ struct list_head bus_list; /* our bus */
/*! Called if an instance of a device is found */
int (*probe) (struct device_d *);
@@ -119,6 +132,9 @@ struct driver_d {
void (*shortinfo) (struct device_d *);
struct bus_type *bus;
+
+ struct platform_device_id *id_table;
+ struct of_device_id *of_compatible;
};
/*@}*/ /* do not delete, doxygen relevant */
@@ -333,9 +349,9 @@ static inline int dev_close_default(struct device_d *dev, struct filep *f)
/* debugging and troubleshooting/diagnostic helpers. */
-#define dev_printf(dev, format, arg...) \
- printf("%s@%s: " format , (dev)->name , \
- dev_name(dev) , ## arg)
+int dev_printf(const struct device_d *dev, const char *format, ...)
+ __attribute__ ((format(__printf__, 2, 3)));
+
#define dev_emerg(dev, format, arg...) \
dev_printf((dev) , format , ## arg)
@@ -367,8 +383,26 @@ struct bus_type {
void (*remove)(struct device_d *dev);
struct list_head list;
+ struct list_head device_list;
+ struct list_head driver_list;
};
+int bus_register(struct bus_type *bus);
+
+extern struct list_head bus_list;
+
+/* Iterate over all buses
+ */
+#define for_each_bus(bus) list_for_each_entry(bus, &bus_list, list)
+
+/* Iterate over all devices of a bus
+ */
+#define bus_for_each_device(bus, dev) list_for_each_entry(dev, &bus->device_list, bus_list)
+
+/* Iterate over all drivers of a bus
+ */
+#define bus_for_each_driver(bus, drv) list_for_each_entry(drv, &bus->driver_list, bus_list)
+
extern struct bus_type platform_bus;
struct file_operations {
@@ -423,5 +457,10 @@ int devfs_add_partition(const char *devname, loff_t offset, loff_t size,
int flags, const char *name);
int devfs_del_partition(const char *name);
+#define DRV_OF_COMPAT(compat) \
+ IS_ENABLED(CONFIG_OFDEVICE) ? (compat) : NULL
+
+int dev_get_drvdata(struct device_d *dev, unsigned long *data);
+
#endif /* DRIVER_H */
diff --git a/include/fb.h b/include/fb.h
index 41deb8c696..c5944184b1 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -110,5 +110,7 @@ int register_framebuffer(struct fb_info *info);
#define FBIO_ENABLE _IO('F', 2)
#define FBIO_DISABLE _IO('F', 3)
+extern struct bus_type fb_bus;
+
#endif /* __FB_H */
diff --git a/include/fec.h b/include/fec.h
index f56b02309d..6e1e1cd132 100644
--- a/include/fec.h
+++ b/include/fec.h
@@ -25,6 +25,8 @@
#ifndef __INCLUDE_NETWORK_FEC_H
#define __INCLUDE_NETWORK_FEC_H
+#include <linux/phy.h>
+
/*
* Supported phy types on this platform
*/
@@ -43,6 +45,7 @@ typedef enum {
struct fec_platform_data {
xceiver_type xcv_type;
int phy_addr;
+ void (*phy_init)(struct phy_device *dev);
};
#endif /* __INCLUDE_NETWORK_FEC_H */
diff --git a/include/filetype.h b/include/filetype.h
index ed3664dfa5..209dc11a3d 100644
--- a/include/filetype.h
+++ b/include/filetype.h
@@ -19,11 +19,13 @@ enum filetype {
filetype_sh,
filetype_mips_barebox,
filetype_fat,
+ filetype_mbr,
};
const char *file_type_to_string(enum filetype f);
enum filetype file_detect_type(void *_buf);
enum filetype file_name_detect_type(const char *filename);
+enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec);
#define ARM_HEAD_SIZE 0x30
#define ARM_HEAD_MAGICWORD_OFFSET 0x20
diff --git a/include/globalvar.h b/include/globalvar.h
index 7cc3976f6b..ddf885f18e 100644
--- a/include/globalvar.h
+++ b/include/globalvar.h
@@ -1,6 +1,7 @@
#ifndef __GLOBALVAR_H
#define __GLOBALVAR_H
+#ifdef CONFIG_GLOBALVAR
int globalvar_add_simple(const char *name);
int globalvar_add(const char *name,
@@ -8,5 +9,27 @@ int globalvar_add(const char *name,
const char *(*get)(struct device_d *, struct param_d *p),
unsigned long flags);
char *globalvar_get_match(const char *match, const char *seperator);
+void globalvar_set_match(const char *match, const char *val);
+#else
+static inline int globalvar_add_simple(const char *name)
+{
+ return 0;
+}
+
+static inline int globalvar_add(const char *name,
+ int (*set)(struct device_d *dev, struct param_d *p, const char *val),
+ const char *(*get)(struct device_d *, struct param_d *p),
+ unsigned long flags)
+{
+ return 0;
+}
+
+static inline char *globalvar_get_match(const char *match, const char *seperator)
+{
+ return NULL;
+}
+
+static inline void globalvar_set_match(const char *match, const char *val) {}
+#endif
#endif /* __GLOBALVAR_H */
diff --git a/include/i2c/i2c.h b/include/i2c/i2c.h
index c3e176354d..de2a7ea27d 100644
--- a/include/i2c/i2c.h
+++ b/include/i2c/i2c.h
@@ -139,4 +139,12 @@ extern int i2c_write_reg(struct i2c_client *client, u32 addr, const u8 *buf, u16
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+extern struct bus_type i2c_bus;
+
+static inline int i2c_register_driver(struct driver_d *drv)
+{
+ drv->bus = &i2c_bus;
+ return register_driver(drv);
+}
+
#endif /* I2C_I2C_H */
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
new file mode 100644
index 0000000000..cb3e3bd3b1
--- /dev/null
+++ b/include/linux/amba/bus.h
@@ -0,0 +1,153 @@
+/*
+ * linux/include/amba/bus.h
+ *
+ * This device type deals with ARM PrimeCells and anything else that
+ * presents a proper CID (0xB105F00D) at the end of the I/O register
+ * region or that is derived from a PrimeCell.
+ *
+ * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
+ *
+ * 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 ASMARM_AMBA_H
+#define ASMARM_AMBA_H
+
+#include <linux/clk.h>
+#include <driver.h>
+#include <linux/err.h>
+
+#define AMBA_CID 0xb105f00d
+
+/**
+ * struct amba_id - identifies a device on an AMBA bus
+ * @id: The significant bits if the hardware device ID
+ * @mask: Bitmask specifying which bits of the id field are significant when
+ * matching. A driver binds to a device when ((hardware device ID) & mask)
+ * == id.
+ * @data: Private data used by the driver.
+ */
+struct amba_id {
+ unsigned int id;
+ unsigned int mask;
+ void *data;
+};
+
+struct clk;
+
+struct amba_device {
+ struct device_d dev;
+ struct resource res;
+ void __iomem *base;
+ struct clk *pclk;
+ unsigned int periphid;
+};
+
+struct amba_driver {
+ struct driver_d drv;
+ int (*probe)(struct amba_device *, const struct amba_id *);
+ int (*remove)(struct amba_device *);
+ const struct amba_id *id_table;
+};
+
+enum amba_vendor {
+ AMBA_VENDOR_ARM = 0x41,
+ AMBA_VENDOR_ST = 0x80,
+};
+
+extern struct bus_type amba_bustype;
+
+#define to_amba_device(d) container_of(d, struct amba_device, dev)
+
+#define amba_get_drvdata(d) dev_get_drvdata(&d->dev)
+#define amba_set_drvdata(d,p) dev_set_drvdata(&d->dev, p)
+
+int amba_driver_register(struct amba_driver *);
+void amba_driver_unregister(struct amba_driver *);
+struct amba_device *amba_device_alloc(const char *, int id, resource_size_t, size_t);
+void amba_device_put(struct amba_device *);
+int amba_device_add(struct amba_device *);
+int amba_device_register(struct amba_device *, struct resource *);
+
+struct amba_device *
+amba_aphb_device_add(struct device_d *parent, const char *name, int id,
+ resource_size_t base, size_t size,
+ void *pdata, unsigned int periphid);
+
+static inline struct amba_device *
+amba_apb_device_add(struct device_d *parent, const char *name, int id,
+ resource_size_t base, size_t size,
+ void *pdata, unsigned int periphid)
+{
+ return amba_aphb_device_add(parent, name, id, base, size, pdata,
+ periphid);
+}
+
+static inline struct amba_device *
+amba_ahb_device_add(struct device_d *parent, const char *name, int id,
+ resource_size_t base, size_t size,
+ void *pdata, unsigned int periphid)
+{
+ return amba_aphb_device_add(parent, name, id, base, size, pdata,
+ periphid);
+}
+
+
+void amba_device_unregister(struct amba_device *);
+struct amba_device *amba_find_device(const char *, struct device_d *, unsigned int, unsigned int);
+int amba_request_regions(struct amba_device *, const char *);
+void amba_release_regions(struct amba_device *);
+
+static inline void __iomem *amba_get_mem_region(struct amba_device *dev)
+{
+ return dev->base;
+}
+
+#define amba_pclk_enable(d) \
+ (IS_ERR((d)->pclk) ? 0 : clk_enable((d)->pclk))
+
+#define amba_pclk_disable(d) \
+ do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0)
+
+/* Some drivers don't use the struct amba_device */
+#define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff)
+#define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f)
+#define AMBA_MANF_BITS(a) (((a) >> 12) & 0xff)
+#define AMBA_PART_BITS(a) ((a) & 0xfff)
+
+#define amba_config(d) AMBA_CONFIG_BITS((d)->periphid)
+#define amba_rev(d) AMBA_REV_BITS((d)->periphid)
+#define amba_manf(d) AMBA_MANF_BITS((d)->periphid)
+#define amba_part(d) AMBA_PART_BITS((d)->periphid)
+
+#define __AMBA_DEV(busid, data) \
+ { \
+ .init_name = busid, \
+ .platform_data = data, \
+ }
+
+/*
+ * APB devices do not themselves have the ability to address memory,
+ * so DMA masks should be zero (much like USB peripheral devices.)
+ * The DMA controller DMA masks should be used instead (much like
+ * USB host controllers in conventional PCs.)
+ */
+#define AMBA_APB_DEVICE(name, busid, id, base, data) \
+struct amba_device name##_device = { \
+ .dev = __AMBA_DEV(busid, data), \
+ .res = DEFINE_RES_MEM(base, SZ_4K), \
+ .periphid = id, \
+}
+
+/*
+ * AHB devices are DMA capable, so set their DMA masks
+ */
+#define AMBA_AHB_DEVICE(name, busid, id, base, data) \
+struct amba_device name##_device = { \
+ .dev = __AMBA_DEV(busid, data), \
+ .res = DEFINE_RES_MEM(base, SZ_4K), \
+ .periphid = id, \
+}
+
+#endif
diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h
index f4d7bf8d0b..6670f1f49e 100644
--- a/include/linux/amba/serial.h
+++ b/include/linux/amba/serial.h
@@ -32,16 +32,20 @@
#define UART01x_RSR 0x04 /* Receive status register (Read). */
#define UART01x_ECR 0x04 /* Error clear register (Write). */
#define UART010_LCRH 0x08 /* Line control register, high byte. */
+#define ST_UART011_DMAWM 0x08 /* DMA watermark configure register. */
#define UART010_LCRM 0x0C /* Line control register, middle byte. */
+#define ST_UART011_TIMEOUT 0x0C /* Timeout period register. */
#define UART010_LCRL 0x10 /* Line control register, low byte. */
#define UART010_CR 0x14 /* Control register. */
#define UART01x_FR 0x18 /* Flag register (Read only). */
#define UART010_IIR 0x1C /* Interrupt indentification register (Read). */
#define UART010_ICR 0x1C /* Interrupt clear register (Write). */
+#define ST_UART011_LCRH_RX 0x1C /* Rx line control register. */
#define UART01x_ILPR 0x20 /* IrDA low power counter register. */
#define UART011_IBRD 0x24 /* Integer baud rate divisor register. */
#define UART011_FBRD 0x28 /* Fractional baud rate divisor register. */
#define UART011_LCRH 0x2c /* Line control register. */
+#define ST_UART011_LCRH_TX 0x2c /* Tx Line control register. */
#define UART011_CR 0x30 /* Control register. */
#define UART011_IFLS 0x34 /* Interrupt fifo level select. */
#define UART011_IMSC 0x38 /* Interrupt mask. */
@@ -49,6 +53,15 @@
#define UART011_MIS 0x40 /* Masked interrupt status. */
#define UART011_ICR 0x44 /* Interrupt clear register. */
#define UART011_DMACR 0x48 /* DMA control register. */
+#define ST_UART011_XFCR 0x50 /* XON/XOFF control register. */
+#define ST_UART011_XON1 0x54 /* XON1 register. */
+#define ST_UART011_XON2 0x58 /* XON2 register. */
+#define ST_UART011_XOFF1 0x5C /* XON1 register. */
+#define ST_UART011_XOFF2 0x60 /* XON2 register. */
+#define ST_UART011_ITCR 0x80 /* Integration test control register. */
+#define ST_UART011_ITIP 0x84 /* Integration test input register. */
+#define ST_UART011_ABCR 0x100 /* Autobaud control register. */
+#define ST_UART011_ABIMSC 0x15C /* Autobaud interrupt mask/clear register. */
#define UART011_DR_OE (1 << 11)
#define UART011_DR_BE (1 << 10)
@@ -84,6 +97,7 @@
#define UART010_CR_TIE 0x0020
#define UART010_CR_RIE 0x0010
#define UART010_CR_MSIE 0x0008
+#define ST_UART011_CR_OVSFACT 0x0008 /* Oversampling factor */
#define UART01x_CR_IIRLP 0x0004 /* SIR low power mode */
#define UART01x_CR_SIREN 0x0002 /* SIR enable */
#define UART01x_CR_UARTEN 0x0001 /* UART enable */
@@ -99,6 +113,21 @@
#define UART01x_LCRH_PEN 0x02
#define UART01x_LCRH_BRK 0x01
+#define ST_UART011_DMAWM_RX_1 (0 << 3)
+#define ST_UART011_DMAWM_RX_2 (1 << 3)
+#define ST_UART011_DMAWM_RX_4 (2 << 3)
+#define ST_UART011_DMAWM_RX_8 (3 << 3)
+#define ST_UART011_DMAWM_RX_16 (4 << 3)
+#define ST_UART011_DMAWM_RX_32 (5 << 3)
+#define ST_UART011_DMAWM_RX_48 (6 << 3)
+#define ST_UART011_DMAWM_TX_1 0
+#define ST_UART011_DMAWM_TX_2 1
+#define ST_UART011_DMAWM_TX_4 2
+#define ST_UART011_DMAWM_TX_8 3
+#define ST_UART011_DMAWM_TX_16 4
+#define ST_UART011_DMAWM_TX_32 5
+#define ST_UART011_DMAWM_TX_48 6
+
#define UART010_IIR_RTIS 0x08
#define UART010_IIR_TIS 0x04
#define UART010_IIR_RIS 0x02
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
new file mode 100644
index 0000000000..4d83fe019e
--- /dev/null
+++ b/include/linux/ethtool.h
@@ -0,0 +1,114 @@
+/*
+ * ethtool.h: Defines for Linux ethtool.
+ *
+ * Copyright (C) 1998 David S. Miller (davem@redhat.com)
+ * Copyright 2001 Jeff Garzik <jgarzik@pobox.com>
+ * Portions Copyright 2001 Sun Microsystems (thockin@sun.com)
+ * Portions Copyright 2002 Intel (eli.kupermann@intel.com,
+ * christopher.leech@intel.com,
+ * scott.feldman@intel.com)
+ * Portions Copyright (C) Sun Microsystems 2008
+ */
+
+#ifndef _LINUX_ETHTOOL_H
+#define _LINUX_ETHTOOL_H
+
+/* Indicates what features are supported by the interface. */
+#define SUPPORTED_10baseT_Half (1 << 0)
+#define SUPPORTED_10baseT_Full (1 << 1)
+#define SUPPORTED_100baseT_Half (1 << 2)
+#define SUPPORTED_100baseT_Full (1 << 3)
+#define SUPPORTED_1000baseT_Half (1 << 4)
+#define SUPPORTED_1000baseT_Full (1 << 5)
+#define SUPPORTED_Autoneg (1 << 6)
+#define SUPPORTED_TP (1 << 7)
+#define SUPPORTED_AUI (1 << 8)
+#define SUPPORTED_MII (1 << 9)
+#define SUPPORTED_FIBRE (1 << 10)
+#define SUPPORTED_BNC (1 << 11)
+#define SUPPORTED_10000baseT_Full (1 << 12)
+#define SUPPORTED_Pause (1 << 13)
+#define SUPPORTED_Asym_Pause (1 << 14)
+#define SUPPORTED_2500baseX_Full (1 << 15)
+#define SUPPORTED_Backplane (1 << 16)
+#define SUPPORTED_1000baseKX_Full (1 << 17)
+#define SUPPORTED_10000baseKX4_Full (1 << 18)
+#define SUPPORTED_10000baseKR_Full (1 << 19)
+#define SUPPORTED_10000baseR_FEC (1 << 20)
+
+/* Indicates what features are advertised by the interface. */
+#define ADVERTISED_10baseT_Half (1 << 0)
+#define ADVERTISED_10baseT_Full (1 << 1)
+#define ADVERTISED_100baseT_Half (1 << 2)
+#define ADVERTISED_100baseT_Full (1 << 3)
+#define ADVERTISED_1000baseT_Half (1 << 4)
+#define ADVERTISED_1000baseT_Full (1 << 5)
+#define ADVERTISED_Autoneg (1 << 6)
+#define ADVERTISED_TP (1 << 7)
+#define ADVERTISED_AUI (1 << 8)
+#define ADVERTISED_MII (1 << 9)
+#define ADVERTISED_FIBRE (1 << 10)
+#define ADVERTISED_BNC (1 << 11)
+#define ADVERTISED_10000baseT_Full (1 << 12)
+#define ADVERTISED_Pause (1 << 13)
+#define ADVERTISED_Asym_Pause (1 << 14)
+#define ADVERTISED_2500baseX_Full (1 << 15)
+#define ADVERTISED_Backplane (1 << 16)
+#define ADVERTISED_1000baseKX_Full (1 << 17)
+#define ADVERTISED_10000baseKX4_Full (1 << 18)
+#define ADVERTISED_10000baseKR_Full (1 << 19)
+#define ADVERTISED_10000baseR_FEC (1 << 20)
+
+/* The following are all involved in forcing a particular link
+ * mode for the device for setting things. When getting the
+ * devices settings, these indicate the current mode and whether
+ * it was foced up into this mode or autonegotiated.
+ */
+
+/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
+#define SPEED_10 10
+#define SPEED_100 100
+#define SPEED_1000 1000
+#define SPEED_2500 2500
+#define SPEED_10000 10000
+
+/* Duplex, half or full. */
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
+
+/* Which connector port. */
+#define PORT_TP 0x00
+#define PORT_AUI 0x01
+#define PORT_MII 0x02
+#define PORT_FIBRE 0x03
+#define PORT_BNC 0x04
+#define PORT_OTHER 0xff
+
+/* Which transceiver to use. */
+#define XCVR_INTERNAL 0x00
+#define XCVR_EXTERNAL 0x01
+#define XCVR_DUMMY1 0x02
+#define XCVR_DUMMY2 0x03
+#define XCVR_DUMMY3 0x04
+
+/* Enable or disable autonegotiation. If this is set to enable,
+ * the forced link modes above are completely ignored.
+ */
+#define AUTONEG_DISABLE 0x00
+#define AUTONEG_ENABLE 0x01
+
+/* Mode MDI or MDI-X */
+#define ETH_TP_MDI_INVALID 0x00
+#define ETH_TP_MDI 0x01
+#define ETH_TP_MDI_X 0x02
+
+/* Wake-On-Lan options. */
+#define WAKE_PHY (1 << 0)
+#define WAKE_UCAST (1 << 1)
+#define WAKE_MCAST (1 << 2)
+#define WAKE_BCAST (1 << 3)
+#define WAKE_ARP (1 << 4)
+#define WAKE_MAGIC (1 << 5)
+#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
+
+#endif /* _LINUX_ETHTOOL_H */
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 734517268f..5bac6c229a 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -8,137 +8,149 @@
#ifndef __LINUX_MII_H__
#define __LINUX_MII_H__
-/* Generic MII registers. */
+#include <linux/types.h>
+#include <linux/ethtool.h>
-#define MII_BMCR 0x00 /* Basic mode control register */
-#define MII_BMSR 0x01 /* Basic mode status register */
-#define MII_PHYSID1 0x02 /* PHYS ID 1 */
-#define MII_PHYSID2 0x03 /* PHYS ID 2 */
-#define MII_ADVERTISE 0x04 /* Advertisement control reg */
-#define MII_LPA 0x05 /* Link partner ability reg */
-#define MII_EXPANSION 0x06 /* Expansion register */
-#define MII_CTRL1000 0x09 /* 1000BASE-T control */
-#define MII_STAT1000 0x0a /* 1000BASE-T status */
-#define MII_ESTATUS 0x0f /* Extended Status */
-#define MII_DCOUNTER 0x12 /* Disconnect counter */
-#define MII_FCSCOUNTER 0x13 /* False carrier counter */
-#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
-#define MII_RERRCOUNTER 0x15 /* Receive error counter */
-#define MII_SREVISION 0x16 /* Silicon revision */
-#define MII_RESV1 0x17 /* Reserved... */
-#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
-#define MII_PHYADDR 0x19 /* PHY address */
-#define MII_RESV2 0x1a /* Reserved... */
-#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
-#define MII_NCONFIG 0x1c /* Network interface config */
+/* Generic MII registers. */
+#define MII_BMCR 0x00 /* Basic mode control register */
+#define MII_BMSR 0x01 /* Basic mode status register */
+#define MII_PHYSID1 0x02 /* PHYS ID 1 */
+#define MII_PHYSID2 0x03 /* PHYS ID 2 */
+#define MII_ADVERTISE 0x04 /* Advertisement control reg */
+#define MII_LPA 0x05 /* Link partner ability reg */
+#define MII_EXPANSION 0x06 /* Expansion register */
+#define MII_CTRL1000 0x09 /* 1000BASE-T control */
+#define MII_STAT1000 0x0a /* 1000BASE-T status */
+#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
+#define MII_MMD_DATA 0x0e /* MMD Access Data Register */
+#define MII_ESTATUS 0x0f /* Extended Status */
+#define MII_DCOUNTER 0x12 /* Disconnect counter */
+#define MII_FCSCOUNTER 0x13 /* False carrier counter */
+#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
+#define MII_RERRCOUNTER 0x15 /* Receive error counter */
+#define MII_SREVISION 0x16 /* Silicon revision */
+#define MII_RESV1 0x17 /* Reserved... */
+#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
+#define MII_PHYADDR 0x19 /* PHY address */
+#define MII_RESV2 0x1a /* Reserved... */
+#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
+#define MII_NCONFIG 0x1c /* Network interface config */
/* Basic mode control register. */
-#define BMCR_SPEED_MASK 0x2040 /* 10/100/1000 */
-#define BMCR_SPEED10 0x0000 /* Select 10Mbps */
-#define BMCR_RESV 0x003f /* Unused... */
-#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
-#define BMCR_CTST 0x0080 /* Collision test */
-#define BMCR_FULLDPLX 0x0100 /* Full duplex */
-#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
-#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
-#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
-#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
-#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
-#define BMCR_RESET 0x8000 /* Reset the DP83840 */
+#define BMCR_RESV 0x003f /* Unused... */
+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
+#define BMCR_CTST 0x0080 /* Collision test */
+#define BMCR_FULLDPLX 0x0100 /* Full duplex */
+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
+#define BMCR_ISOLATE 0x0400 /* Isolate data paths from MII */
+#define BMCR_PDOWN 0x0800 /* Enable low power state */
+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
+#define BMCR_RESET 0x8000 /* Reset to default state */
/* Basic mode status register. */
-#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
-#define BMSR_JCD 0x0002 /* Jabber detected */
-#define BMSR_LSTATUS 0x0004 /* Link status */
-#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
-#define BMSR_RFAULT 0x0010 /* Remote fault detected */
-#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
-#define BMSR_RESV 0x00c0 /* Unused... */
-#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
-#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
-#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
-#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
-#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
-#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
-#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
-#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
+#define BMSR_JCD 0x0002 /* Jabber detected */
+#define BMSR_LSTATUS 0x0004 /* Link status */
+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+#define BMSR_RESV 0x00c0 /* Unused... */
+#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
+#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
/* Advertisement control register. */
-#define ADVERTISE_SLCT 0x001f /* Selector bits */
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
-#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
-#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
-#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
-#define ADVERTISE_RESV 0x1000 /* Unused... */
-#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
-#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
-#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
-
-#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
- ADVERTISE_CSMA)
-#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
- ADVERTISE_100HALF | ADVERTISE_100FULL)
+#define ADVERTISE_SLCT 0x001f /* Selector bits */
+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
+#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
+#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
+#define ADVERTISE_RESV 0x1000 /* Unused... */
+#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
+#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
+#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+ ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+ ADVERTISE_100HALF | ADVERTISE_100FULL)
/* Link partner ability register. */
-#define LPA_SLCT 0x001f /* Same as advertise selector */
-#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
-#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
-#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
-#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
-#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
-#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
-#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
-#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
-#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
-#define LPA_PAUSE_CAP 0x0400 /* Can pause */
-#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
-#define LPA_RESV 0x1000 /* Unused... */
-#define LPA_RFAULT 0x2000 /* Link partner faulted */
-#define LPA_LPACK 0x4000 /* Link partner acked us */
-#define LPA_NPAGE 0x8000 /* Next page bit */
+#define LPA_SLCT 0x001f /* Same as advertise selector */
+#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
+#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
+#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
+#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
+#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
+#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
+#define LPA_PAUSE_CAP 0x0400 /* Can pause */
+#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
+#define LPA_RESV 0x1000 /* Unused... */
+#define LPA_RFAULT 0x2000 /* Link partner faulted */
+#define LPA_LPACK 0x4000 /* Link partner acked us */
+#define LPA_NPAGE 0x8000 /* Next page bit */
#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
/* Expansion register for auto-negotiation. */
-#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
-#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
-#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
-#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
-#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
-#define EXPANSION_RESV 0xffe0 /* Unused... */
+#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
+#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
+#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
+#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
+#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
+#define EXPANSION_RESV 0xffe0 /* Unused... */
-#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
-#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
+#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
+#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
/* N-way test register. */
-#define NWAYTEST_RESV1 0x00ff /* Unused... */
-#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
-#define NWAYTEST_RESV2 0xfe00 /* Unused... */
+#define NWAYTEST_RESV1 0x00ff /* Unused... */
+#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
+#define NWAYTEST_RESV2 0xfe00 /* Unused... */
/* 1000BASE-T Control register */
-#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
-#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
+#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
+#define CTL1000_AS_MASTER 0x0800
+#define CTL1000_ENABLE_MASTER 0x1000
/* 1000BASE-T Status register */
-#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
-#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
-#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
-#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
+#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
+#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
+#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
/* Flow control flags */
#define FLOW_CTRL_TX 0x01
#define FLOW_CTRL_RX 0x02
+/* MMD Access Control register fields */
+#define MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
+#define MII_MMD_CTRL_ADDR 0x0000 /* Address */
+#define MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */
+#define MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
+#define MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
+
+
/**
* mii_nway_result
* @negotiated: value of MII ANAR and'd with ANLPAR
@@ -191,6 +203,205 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock,
}
/**
+ * ethtool_adv_to_mii_adv_t
+ * @ethadv: the ethtool advertisement settings
+ *
+ * A small helper function that translates ethtool advertisement
+ * settings to phy autonegotiation advertisements for the
+ * MII_ADVERTISE register.
+ */
+static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv)
+{
+ u32 result = 0;
+
+ if (ethadv & ADVERTISED_10baseT_Half)
+ result |= ADVERTISE_10HALF;
+ if (ethadv & ADVERTISED_10baseT_Full)
+ result |= ADVERTISE_10FULL;
+ if (ethadv & ADVERTISED_100baseT_Half)
+ result |= ADVERTISE_100HALF;
+ if (ethadv & ADVERTISED_100baseT_Full)
+ result |= ADVERTISE_100FULL;
+ if (ethadv & ADVERTISED_Pause)
+ result |= ADVERTISE_PAUSE_CAP;
+ if (ethadv & ADVERTISED_Asym_Pause)
+ result |= ADVERTISE_PAUSE_ASYM;
+
+ return result;
+}
+
+/**
+ * mii_adv_to_ethtool_adv_t
+ * @adv: value of the MII_ADVERTISE register
+ *
+ * A small helper function that translates MII_ADVERTISE bits
+ * to ethtool advertisement settings.
+ */
+static inline u32 mii_adv_to_ethtool_adv_t(u32 adv)
+{
+ u32 result = 0;
+
+ if (adv & ADVERTISE_10HALF)
+ result |= ADVERTISED_10baseT_Half;
+ if (adv & ADVERTISE_10FULL)
+ result |= ADVERTISED_10baseT_Full;
+ if (adv & ADVERTISE_100HALF)
+ result |= ADVERTISED_100baseT_Half;
+ if (adv & ADVERTISE_100FULL)
+ result |= ADVERTISED_100baseT_Full;
+ if (adv & ADVERTISE_PAUSE_CAP)
+ result |= ADVERTISED_Pause;
+ if (adv & ADVERTISE_PAUSE_ASYM)
+ result |= ADVERTISED_Asym_Pause;
+
+ return result;
+}
+
+/**
+ * ethtool_adv_to_mii_ctrl1000_t
+ * @ethadv: the ethtool advertisement settings
+ *
+ * A small helper function that translates ethtool advertisement
+ * settings to phy autonegotiation advertisements for the
+ * MII_CTRL1000 register when in 1000T mode.
+ */
+static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv)
+{
+ u32 result = 0;
+
+ if (ethadv & ADVERTISED_1000baseT_Half)
+ result |= ADVERTISE_1000HALF;
+ if (ethadv & ADVERTISED_1000baseT_Full)
+ result |= ADVERTISE_1000FULL;
+
+ return result;
+}
+
+/**
+ * mii_ctrl1000_to_ethtool_adv_t
+ * @adv: value of the MII_CTRL1000 register
+ *
+ * A small helper function that translates MII_CTRL1000
+ * bits, when in 1000Base-T mode, to ethtool
+ * advertisement settings.
+ */
+static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv)
+{
+ u32 result = 0;
+
+ if (adv & ADVERTISE_1000HALF)
+ result |= ADVERTISED_1000baseT_Half;
+ if (adv & ADVERTISE_1000FULL)
+ result |= ADVERTISED_1000baseT_Full;
+
+ return result;
+}
+
+/**
+ * mii_lpa_to_ethtool_lpa_t
+ * @adv: value of the MII_LPA register
+ *
+ * A small helper function that translates MII_LPA
+ * bits, when in 1000Base-T mode, to ethtool
+ * LP advertisement settings.
+ */
+static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa)
+{
+ u32 result = 0;
+
+ if (lpa & LPA_LPACK)
+ result |= ADVERTISED_Autoneg;
+
+ return result | mii_adv_to_ethtool_adv_t(lpa);
+}
+
+/**
+ * mii_stat1000_to_ethtool_lpa_t
+ * @adv: value of the MII_STAT1000 register
+ *
+ * A small helper function that translates MII_STAT1000
+ * bits, when in 1000Base-T mode, to ethtool
+ * advertisement settings.
+ */
+static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
+{
+ u32 result = 0;
+
+ if (lpa & LPA_1000HALF)
+ result |= ADVERTISED_1000baseT_Half;
+ if (lpa & LPA_1000FULL)
+ result |= ADVERTISED_1000baseT_Full;
+
+ return result;
+}
+
+/**
+ * ethtool_adv_to_mii_adv_x
+ * @ethadv: the ethtool advertisement settings
+ *
+ * A small helper function that translates ethtool advertisement
+ * settings to phy autonegotiation advertisements for the
+ * MII_CTRL1000 register when in 1000Base-X mode.
+ */
+static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv)
+{
+ u32 result = 0;
+
+ if (ethadv & ADVERTISED_1000baseT_Half)
+ result |= ADVERTISE_1000XHALF;
+ if (ethadv & ADVERTISED_1000baseT_Full)
+ result |= ADVERTISE_1000XFULL;
+ if (ethadv & ADVERTISED_Pause)
+ result |= ADVERTISE_1000XPAUSE;
+ if (ethadv & ADVERTISED_Asym_Pause)
+ result |= ADVERTISE_1000XPSE_ASYM;
+
+ return result;
+}
+
+/**
+ * mii_adv_to_ethtool_adv_x
+ * @adv: value of the MII_CTRL1000 register
+ *
+ * A small helper function that translates MII_CTRL1000
+ * bits, when in 1000Base-X mode, to ethtool
+ * advertisement settings.
+ */
+static inline u32 mii_adv_to_ethtool_adv_x(u32 adv)
+{
+ u32 result = 0;
+
+ if (adv & ADVERTISE_1000XHALF)
+ result |= ADVERTISED_1000baseT_Half;
+ if (adv & ADVERTISE_1000XFULL)
+ result |= ADVERTISED_1000baseT_Full;
+ if (adv & ADVERTISE_1000XPAUSE)
+ result |= ADVERTISED_Pause;
+ if (adv & ADVERTISE_1000XPSE_ASYM)
+ result |= ADVERTISED_Asym_Pause;
+
+ return result;
+}
+
+/**
+ * mii_lpa_to_ethtool_lpa_x
+ * @adv: value of the MII_LPA register
+ *
+ * A small helper function that translates MII_LPA
+ * bits, when in 1000Base-X mode, to ethtool
+ * LP advertisement settings.
+ */
+static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa)
+{
+ u32 result = 0;
+
+ if (lpa & LPA_LPACK)
+ result |= ADVERTISED_Autoneg;
+
+ return result | mii_adv_to_ethtool_adv_x(lpa);
+}
+
+/**
* mii_advertise_flowctrl - get flow control advertisement flags
* @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
*/
diff --git a/include/linux/phy.h b/include/linux/phy.h
new file mode 100644
index 0000000000..76f9edb237
--- /dev/null
+++ b/include/linux/phy.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2009-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Author: Andy Fleming
+ *
+ * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __PHY_H
+#define __PHY_H
+
+#include <linux/list.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#define PHY_BASIC_FEATURES (SUPPORTED_10baseT_Half | \
+ SUPPORTED_10baseT_Full | \
+ SUPPORTED_100baseT_Half | \
+ SUPPORTED_100baseT_Full | \
+ SUPPORTED_Autoneg | \
+ SUPPORTED_TP | \
+ SUPPORTED_MII)
+
+#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \
+ SUPPORTED_1000baseT_Half | \
+ SUPPORTED_1000baseT_Full)
+
+/* Interface Mode definitions */
+typedef enum {
+ PHY_INTERFACE_MODE_NA,
+ PHY_INTERFACE_MODE_MII,
+ PHY_INTERFACE_MODE_GMII,
+ PHY_INTERFACE_MODE_SGMII,
+ PHY_INTERFACE_MODE_TBI,
+ PHY_INTERFACE_MODE_RMII,
+ PHY_INTERFACE_MODE_RGMII,
+ PHY_INTERFACE_MODE_RGMII_ID,
+ PHY_INTERFACE_MODE_RGMII_RXID,
+ PHY_INTERFACE_MODE_RGMII_TXID,
+ PHY_INTERFACE_MODE_RTBI,
+ PHY_INTERFACE_MODE_SMII,
+} phy_interface_t;
+
+#define PHY_INIT_TIMEOUT 100000
+#define PHY_FORCE_TIMEOUT 10
+#define PHY_AN_TIMEOUT 10
+
+#define PHY_MAX_ADDR 32
+
+/*
+ * Need to be a little smaller than phydev->dev.bus_id to leave room
+ * for the ":%02x"
+ */
+#define MII_BUS_ID_SIZE (20 - 3)
+
+#define PHYLIB_FORCE_10 (1 << 0)
+#define PHYLIB_FORCE_LINK (1 << 1)
+
+#define PHYLIB_CAPABLE_1000M (1 << 0)
+
+/*
+ * The Bus class for PHYs. Devices which provide access to
+ * PHYs should register using this structure
+ */
+struct mii_bus {
+ void *priv;
+ int (*read)(struct mii_bus *bus, int phy_id, int regnum);
+ int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);
+ int (*reset)(struct mii_bus *bus);
+
+ struct device_d *parent;
+
+ struct device_d dev;
+
+ /* list of all PHYs on bus */
+ struct phy_device *phy_map[PHY_MAX_ADDR];
+
+ /* PHY addresses to be ignored when probing */
+ u32 phy_mask;
+};
+#define to_mii_bus(d) container_of(d, struct mii_bus, dev)
+
+int mdiobus_register(struct mii_bus *bus);
+void mdiobus_unregister(struct mii_bus *bus);
+struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
+
+/**
+ * mdiobus_read - Convenience function for reading a given MII mgmt register
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @regnum: register number to read
+ */
+static inline int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
+{
+ return bus->read(bus, addr, regnum);
+}
+
+/**
+ * mdiobus_write - Convenience function for writing a given MII mgmt register
+ * @bus: the mii_bus struct
+ * @addr: the phy address
+ * @regnum: register number to write
+ * @val: value to write to @regnum
+ */
+static inline int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val)
+{
+ return bus->write(bus, addr, regnum, val);
+}
+
+/* phy_device: An instance of a PHY
+ *
+ * bus: Pointer to the bus this PHY is on
+ * dev: driver model device structure for this PHY
+ * phy_id: UID for this device found during discovery
+ * dev_flags: Device-specific flags used by the PHY driver.
+ * addr: Bus address of PHY
+ * attached_dev: The attached enet driver's device instance ptr
+ *
+ * speed, duplex, pause, supported, advertising, and
+ * autoneg are used like in mii_if_info
+ */
+struct phy_device {
+ struct mii_bus *bus;
+
+ struct device_d dev;
+
+ u32 phy_id;
+
+ u32 dev_flags;
+
+ phy_interface_t interface;
+
+ /* Bus address of the PHY (0-31) */
+ int addr;
+
+ /*
+ * forced speed & duplex (no autoneg)
+ * partner speed & duplex & pause (autoneg)
+ */
+ int speed;
+ int duplex;
+ int pause;
+ int asym_pause;
+
+ /* The most recently read link state */
+ int link;
+
+ /* Union of PHY and Attached devices' supported modes */
+ /* See mii.h for more info */
+ u32 supported;
+ u32 advertising;
+
+ int autoneg;
+
+
+ /* private data pointer */
+ /* For use by PHYs to maintain extra state */
+ void *priv;
+
+ struct eth_device *attached_dev;
+ void (*adjust_link)(struct eth_device *dev);
+
+ struct cdev cdev;
+};
+#define to_phy_device(d) container_of(d, struct phy_device, dev)
+
+/* struct phy_driver: Driver structure for a particular PHY type
+ *
+ * phy_id: The result of reading the UID registers of this PHY
+ * type, and ANDing them with the phy_id_mask. This driver
+ * only works for PHYs with IDs which match this field
+ * phy_id_mask: Defines the important bits of the phy_id
+ * features: A list of features (speed, duplex, etc) supported
+ * by this PHY
+ *
+ * The drivers must implement config_aneg and read_status. All
+ * other functions are optional. Note that none of these
+ * functions should be called from interrupt time. The goal is
+ * for the bus read/write functions to be able to block when the
+ * bus transaction is happening, and be freed up by an interrupt
+ * (The MPC85xx has this ability, though it is not currently
+ * supported in the driver).
+ */
+struct phy_driver {
+ u32 phy_id;
+ unsigned int phy_id_mask;
+ u32 features;
+
+ /*
+ * Called to initialize the PHY,
+ * including after a reset
+ */
+ int (*config_init)(struct phy_device *phydev);
+
+ /*
+ * Called during discovery. Used to set
+ * up device-specific structures, if any
+ */
+ int (*probe)(struct phy_device *phydev);
+
+ /*
+ * Configures the advertisement and resets
+ * autonegotiation if phydev->autoneg is on,
+ * forces the speed to the current settings in phydev
+ * if phydev->autoneg is off
+ */
+ int (*config_aneg)(struct phy_device *phydev);
+
+ /* Determines the negotiated speed and duplex */
+ int (*read_status)(struct phy_device *phydev);
+
+ /* Clears up any memory if needed */
+ void (*remove)(struct phy_device *phydev);
+
+ struct driver_d drv;
+};
+#define to_phy_driver(d) container_of(d, struct phy_driver, drv)
+
+#define PHY_ANY_ID "MATCH ANY PHY"
+#define PHY_ANY_UID 0xffffffff
+
+int phy_driver_register(struct phy_driver *drv);
+struct phy_device *get_phy_device(struct mii_bus *bus, int addr);
+int phy_init(void);
+
+/**
+ * phy_read - Convenience function for reading a given PHY register
+ * @phydev: the phy_device struct
+ * @regnum: register number to read
+ */
+static inline int phy_read(struct phy_device *phydev, u32 regnum)
+{
+ return mdiobus_read(phydev->bus, phydev->addr, regnum);
+}
+
+/**
+ * phy_write - Convenience function for writing a given PHY register
+ * @phydev: the phy_device struct
+ * @regnum: register number to write
+ * @val: value to write to @regnum
+ */
+static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val)
+{
+ return mdiobus_write(phydev->bus, phydev->addr, regnum, val);
+}
+
+int phy_device_connect(struct eth_device *dev, struct mii_bus *bus, int addr,
+ void (*adjust_link) (struct eth_device *edev),
+ u32 flags, phy_interface_t interface);
+
+int phy_update_status(struct phy_device *phydev);
+
+/* Generic PHY support and helper functions */
+int genphy_restart_aneg(struct phy_device *phydev);
+int genphy_config_aneg(struct phy_device *phydev);
+int genphy_update_link(struct phy_device *phydev);
+int genphy_read_status(struct phy_device *phydev);
+int genphy_config_advert(struct phy_device *phydev);
+int genphy_setup_forced(struct phy_device *phydev);
+int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
+
+extern struct bus_type mdio_bus_type;
+#endif /* __PHYDEV_H__ */
diff --git a/include/miidev.h b/include/miidev.h
deleted file mode 100644
index 4bbf94c237..0000000000
--- a/include/miidev.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * (C) Copyright 2001
- * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
- *
- * (C) Copyright 2009 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; 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 __MIIDEV_H__
-#define __MIIDEV_H__
-
-#include <driver.h>
-#include <linux/mii.h>
-
-#define MIIDEV_FORCE_10 (1 << 0)
-#define MIIDEV_FORCE_LINK (1 << 1)
-
-#define MIIDEV_CAPABLE_1000M (1 << 0)
-
-struct mii_device {
- struct device_d dev;
- struct device_d *parent;
-
- int address; /* The address the phy has on the bus */
- int (*read) (struct mii_device *dev, int addr, int reg);
- int (*write) (struct mii_device *dev, int addr, int reg, int value);
-
- int flags;
- int capabilities;
-
- struct eth_device *edev;
- struct cdev cdev;
- struct list_head list;
-};
-
-int mii_register(struct mii_device *dev);
-void mii_unregister(struct mii_device *mdev);
-int miidev_restart_aneg(struct mii_device *mdev);
-int miidev_wait_aneg(struct mii_device *mdev);
-int miidev_get_status(struct mii_device *mdev);
-#define MIIDEV_STATUS_IS_UP (1 << 0)
-#define MIIDEV_STATUS_IS_FULL_DUPLEX (1 << 1)
-#define MIIDEV_STATUS_IS_10MBIT (1 << 2)
-#define MIIDEV_STATUS_IS_100MBIT (1 << 3)
-#define MIIDEV_STATUS_IS_1000MBIT (1 << 4)
-int miidev_print_status(struct mii_device *mdev);
-
-static int inline mii_write(struct mii_device *dev, int addr, int reg, int value)
-{
- return dev->write(dev, addr, reg, value);
-}
-
-static int inline mii_read(struct mii_device *dev, int addr, int reg)
-{
- return dev->read(dev, addr, reg);
-}
-
-struct mii_device *mii_open(const char *name);
-void mii_close(struct mii_device *mdev);
-
-#endif /* __MIIDEV_H__ */
diff --git a/include/net.h b/include/net.h
index 9152943812..e4f6f86ad0 100644
--- a/include/net.h
+++ b/include/net.h
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <clock.h>
#include <led.h>
+#include <linux/phy.h>
#include <asm/byteorder.h> /* for nton* / ntoh* stuff */
/* How often do we retry to send packages */
@@ -44,6 +45,9 @@ struct eth_device {
struct eth_device *next;
void *priv;
+ /* phy device may attach itself for hardware timestamping */
+ struct phy_device *phydev;
+
struct device_d dev;
struct device_d *parent;
@@ -55,10 +59,8 @@ struct eth_device {
int eth_register(struct eth_device* dev); /* Register network device */
void eth_unregister(struct eth_device* dev); /* Unregister network device */
-int eth_open(void); /* open the device */
int eth_send(void *packet, int length); /* Send a packet */
int eth_rx(void); /* Check for received packets */
-void eth_halt(void); /* stop SCC */
/* associate a MAC address to a ethernet device. Should be called by
* board code for boards which store their MAC address at some unusual
diff --git a/include/net/davinci_emac.h b/include/net/davinci_emac.h
new file mode 100644
index 0000000000..caead1fecf
--- /dev/null
+++ b/include/net/davinci_emac.h
@@ -0,0 +1,10 @@
+#ifndef __NET_DAVINCI_EMAC_H__
+#define __NET_DAVINCI_EMAC_H__
+
+struct davinci_emac_platform_data {
+ int phy_addr;
+ bool force_link;
+ bool interface_rmii;
+};
+
+#endif /* __NET_DAVINCI_EMAC_H__ */
diff --git a/include/of.h b/include/of.h
index 609b3b587b..7b6a23ad71 100644
--- a/include/of.h
+++ b/include/of.h
@@ -2,6 +2,8 @@
#define __OF_H
#include <fdt.h>
+#include <errno.h>
+#include <asm/byteorder.h>
extern struct fdt_header *barebox_fdt;
@@ -19,4 +21,115 @@ void do_fixup_by_path_u32(struct fdt_header *fdt, const char *path, const char *
u32 val, int create);
int fdt_get_path_or_create(struct fdt_header *fdt, const char *path);
+#define OF_BAD_ADDR ((u64)-1)
+
+typedef u32 phandle;
+
+struct property {
+ char *name;
+ int length;
+ void *value;
+ struct list_head list;
+};
+
+struct device_node {
+ char *name;
+ char *full_name;
+
+ struct list_head properties;
+ struct device_node *parent;
+ struct list_head children;
+ struct list_head parent_list;
+ struct list_head list;
+ struct resource *resource;
+ struct device_d *device;
+ struct list_head phandles;
+ phandle phandle;
+};
+
+struct of_device_id {
+ char *compatible;
+ unsigned long data;
+};
+
+struct driver_d;
+
+int of_match(struct device_d *dev, struct driver_d *drv);
+
+struct property *of_find_property(const struct device_node *node, const char *name);
+
+struct device_node *of_find_node_by_path(const char *path);
+
+struct fdt_header *fdt_get_tree(void);
+
+#define device_node_for_nach_child(node, child) \
+ list_for_each_entry(child, &node->children, parent_list)
+
+/* Helper to read a big number; size is in cells (not bytes) */
+static inline u64 of_read_number(const __be32 *cell, int size)
+{
+ u64 r = 0;
+ while (size--)
+ r = (r << 32) | be32_to_cpu(*(cell++));
+ return r;
+}
+
+int of_property_read_u32_array(const struct device_node *np,
+ const char *propname, u32 *out_values,
+ size_t sz);
+
+static inline int of_property_read_u32(const struct device_node *np,
+ const char *propname,
+ u32 *out_value)
+{
+ return of_property_read_u32_array(np, propname, out_value, 1);
+}
+
+const void *of_get_property(const struct device_node *np, const char *name,
+ int *lenp);
+
+int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
+ const char *cells_name, int index,
+ struct device_node **out_node,
+ const void **out_args);
+
+int of_get_named_gpio(struct device_node *np,
+ const char *propname, int index);
+
+struct device_node *of_find_node_by_phandle(phandle phandle);
+void of_print_property(const void *data, int len);
+
+int of_machine_is_compatible(const char *compat);
+
+#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
+
+void of_print_nodes(struct device_node *node, int indent);
+int of_probe(void);
+int of_parse_dtb(struct fdt_header *fdt);
+
+#ifdef CONFIG_OFDEVICE
+int of_parse_partitions(const char *cdevname,
+ struct device_node *node);
+
+struct device_node *of_get_root_node(void);
+int of_alias_get_id(struct device_node *np, const char *stem);
+#else
+static inline int of_parse_partitions(const char *cdevname,
+ struct device_node *node)
+{
+ return -EINVAL;
+}
+
+static inline struct device_node *of_get_root_node(void)
+{
+ return NULL;
+}
+
+static inline int of_alias_get_id(struct device_node *np, const char *stem)
+{
+ return -ENOENT;
+}
+#endif
+
#endif /* __OF_H */
diff --git a/include/spi/spi.h b/include/spi/spi.h
index 9d01d068da..1773ca22e5 100644
--- a/include/spi/spi.h
+++ b/include/spi/spi.h
@@ -17,6 +17,7 @@ struct spi_board_info {
u8 mode;
u8 bits_per_word;
void *platform_data;
+ struct device_node *device_node;
};
/**
@@ -163,6 +164,8 @@ struct spi_master {
/* called on release() to free memory provided by spi_master */
void (*cleanup)(struct spi_device *spi);
+
+ struct list_head list;
};
/*---------------------------------------------------------------------------*/
@@ -427,4 +430,14 @@ static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd)
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+extern struct bus_type spi_bus;
+
+static inline int spi_register_driver(struct driver_d *drv)
+{
+ drv->bus = &spi_bus;
+ return register_driver(drv);
+}
+
+void spi_of_register_slaves(struct spi_master *master, struct device_node *node);
+
#endif /* __INCLUDE_SPI_H */
diff --git a/include/usb/usbnet.h b/include/usb/usbnet.h
index 1609b2eb26..cb8ff038b2 100644
--- a/include/usb/usbnet.h
+++ b/include/usb/usbnet.h
@@ -23,7 +23,7 @@
#define __LINUX_USB_USBNET_H
#include <net.h>
-#include <miidev.h>
+#include <linux/phy.h>
/* interface from usbnet core to each USB networking link we handle */
struct usbnet {
@@ -40,7 +40,8 @@ struct usbnet {
/* protocol/interface state */
struct eth_device edev;
- struct mii_device miidev;
+ struct mii_bus miibus;
+ int phy_addr;
int msg_enable;
unsigned long data [5];
diff --git a/lib/libbb.c b/lib/libbb.c
index 9a0a60bdb8..e0d7481594 100644
--- a/lib/libbb.c
+++ b/lib/libbb.c
@@ -1,4 +1,3 @@
-/* vi: set sw=8 ts=8: */
/*
* Utility routines.
*
diff --git a/lib/uncompress.c b/lib/uncompress.c
index cdfebe9173..3cf98dd928 100644
--- a/lib/uncompress.c
+++ b/lib/uncompress.c
@@ -80,8 +80,6 @@ int uncompress(unsigned char *inbuf, int len,
int ret;
char *err;
- BUG_ON(uncompress_size);
-
if (inbuf) {
ft = file_detect_type(inbuf);
uncompress_buf = NULL;
diff --git a/logo/LICENCE b/logo/LICENCE
new file mode 100644
index 0000000000..91f6c06ef3
--- /dev/null
+++ b/logo/LICENCE
@@ -0,0 +1,22 @@
+Barebox Logo Licence
+
+Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Copyright (C) 2012 JCrosoft.Ling Limited
+
+This logo or a modified version may be used by anyone to refer to the Barebox
+project only, but does not indicate endorsement by the project.
+
+The logo can be modified in the limit of the respect of the image to the
+Barebox project.
+
+In particular, we encourage you to use the logo for the purpose of advertising
+support for Barebox. This includes, but is not limited to, the following
+uses:
+ - systems that come preloaded with Barebox and such that support
+ Barebox through a flash upgrade.
+ - Barebox documentation
+ - posters, clothing, presentations and other promotion material referring to the
+ Barebox project
+
+Please make the image a link to http://www.barebox.org/ if you use it on a
+web page.
diff --git a/logo/png24/100x100/color/barebox.png b/logo/png24/100x100/color/barebox.png
new file mode 100644
index 0000000000..cc571fc6a4
--- /dev/null
+++ b/logo/png24/100x100/color/barebox.png
Binary files differ
diff --git a/logo/png24/100x100/white/barebox.png b/logo/png24/100x100/white/barebox.png
new file mode 100644
index 0000000000..e29678575c
--- /dev/null
+++ b/logo/png24/100x100/white/barebox.png
Binary files differ
diff --git a/logo/png24/200x200/color/barebox.png b/logo/png24/200x200/color/barebox.png
new file mode 100644
index 0000000000..1e00b8ca9a
--- /dev/null
+++ b/logo/png24/200x200/color/barebox.png
Binary files differ
diff --git a/logo/png24/200x200/white/barebox.png b/logo/png24/200x200/white/barebox.png
new file mode 100644
index 0000000000..03f1f86b00
--- /dev/null
+++ b/logo/png24/200x200/white/barebox.png
Binary files differ
diff --git a/logo/png24/400x400/color/barebox.png b/logo/png24/400x400/color/barebox.png
new file mode 100644
index 0000000000..9cb9db2e48
--- /dev/null
+++ b/logo/png24/400x400/color/barebox.png
Binary files differ
diff --git a/logo/png24/400x400/white/barebox.png b/logo/png24/400x400/white/barebox.png
new file mode 100644
index 0000000000..fbd89ee7af
--- /dev/null
+++ b/logo/png24/400x400/white/barebox.png
Binary files differ
diff --git a/logo/png24/600x600/color/barebox.png b/logo/png24/600x600/color/barebox.png
new file mode 100644
index 0000000000..5a0e553242
--- /dev/null
+++ b/logo/png24/600x600/color/barebox.png
Binary files differ
diff --git a/logo/png24/600x600/while/barebox.png b/logo/png24/600x600/while/barebox.png
new file mode 100644
index 0000000000..71105f62d3
--- /dev/null
+++ b/logo/png24/600x600/while/barebox.png
Binary files differ
diff --git a/logo/png24/800x800/color/barebox.png b/logo/png24/800x800/color/barebox.png
new file mode 100644
index 0000000000..aebca6bb0a
--- /dev/null
+++ b/logo/png24/800x800/color/barebox.png
Binary files differ
diff --git a/logo/png24/800x800/white/barebox.png b/logo/png24/800x800/white/barebox.png
new file mode 100644
index 0000000000..6fc76cb3d1
--- /dev/null
+++ b/logo/png24/800x800/white/barebox.png
Binary files differ
diff --git a/logo/png8/100x100/color/blackbg/barebox.png b/logo/png8/100x100/color/blackbg/barebox.png
new file mode 100644
index 0000000000..dd999e7077
--- /dev/null
+++ b/logo/png8/100x100/color/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/100x100/white/blackbg/barebox.png b/logo/png8/100x100/white/blackbg/barebox.png
new file mode 100644
index 0000000000..84c05e1012
--- /dev/null
+++ b/logo/png8/100x100/white/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/200x200/color/blackbg/barebox.png b/logo/png8/200x200/color/blackbg/barebox.png
new file mode 100644
index 0000000000..4a5868819b
--- /dev/null
+++ b/logo/png8/200x200/color/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/200x200/white/blackbg/barebox.png b/logo/png8/200x200/white/blackbg/barebox.png
new file mode 100644
index 0000000000..0afed11297
--- /dev/null
+++ b/logo/png8/200x200/white/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/400x400/color/blackbg/barebox.png b/logo/png8/400x400/color/blackbg/barebox.png
new file mode 100644
index 0000000000..4451769e99
--- /dev/null
+++ b/logo/png8/400x400/color/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/400x400/white/blackbg/barebox.png b/logo/png8/400x400/white/blackbg/barebox.png
new file mode 100644
index 0000000000..8fb2a91478
--- /dev/null
+++ b/logo/png8/400x400/white/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/600x600/color/blackbg/barebox.png b/logo/png8/600x600/color/blackbg/barebox.png
new file mode 100644
index 0000000000..79929b242c
--- /dev/null
+++ b/logo/png8/600x600/color/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/600x600/while/blackbg/barebox.png b/logo/png8/600x600/while/blackbg/barebox.png
new file mode 100644
index 0000000000..223da3e0cd
--- /dev/null
+++ b/logo/png8/600x600/while/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/800x800/color/blackbg/barebox.png b/logo/png8/800x800/color/blackbg/barebox.png
new file mode 100644
index 0000000000..2ffc11101c
--- /dev/null
+++ b/logo/png8/800x800/color/blackbg/barebox.png
Binary files differ
diff --git a/logo/png8/800x800/white/blackbg/barebox.png b/logo/png8/800x800/white/blackbg/barebox.png
new file mode 100644
index 0000000000..e164aac0ba
--- /dev/null
+++ b/logo/png8/800x800/white/blackbg/barebox.png
Binary files differ
diff --git a/net/dhcp.c b/net/dhcp.c
index 79efa3e30e..768255e184 100644
--- a/net/dhcp.c
+++ b/net/dhcp.c
@@ -19,6 +19,10 @@
#include <magicvar.h>
#include <linux/err.h>
#include <getopt.h>
+#include <globalvar.h>
+#include <init.h>
+
+#define DHCP_DEFAULT_RETRY 20
#define OPT_SIZE 312 /* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */
@@ -78,11 +82,39 @@ static IPaddr_t net_dhcp_server_ip;
static uint64_t dhcp_start;
static char dhcp_tftpname[256];
+static const char* dhcp_get_barebox_global(const char * var)
+{
+ char * var_global = asprintf("global.dhcp.%s", var);
+ const char *val;
+
+ if (!var_global)
+ return NULL;
+
+ val = getenv(var_global);
+ free(var_global);
+ return val;
+}
+
+static int dhcp_set_barebox_global(const char * var, char *val)
+{
+ char * var_global = asprintf("global.dhcp.%s", var);
+ int ret;
+
+ if (!var_global)
+ return -ENOMEM;
+
+ ret = setenv(var_global, val);
+ free(var_global);
+ return ret;
+}
+
struct dhcp_opt {
unsigned char option;
/* request automatically the option when creating the DHCP request */
bool optional;
+ bool copy_only_if_valid;
const char *barebox_var_name;
+ const char *barebox_dhcp_global;
void (*handle)(struct dhcp_opt *opt, unsigned char *data, int tlen);
void *data;
@@ -123,7 +155,15 @@ static void env_str_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen
memcpy(tmp, popt, optlen);
tmp[optlen] = 0;
- setenv(opt->barebox_var_name, tmp);
+
+ if (opt->copy_only_if_valid && !strlen(tmp))
+ return;
+
+ if (opt->barebox_var_name)
+ setenv(opt->barebox_var_name, tmp);
+ if (opt->barebox_dhcp_global)
+ dhcp_set_barebox_global(opt->barebox_dhcp_global, tmp);
+
}
static void copy_uint32_handle(struct dhcp_opt *opt, unsigned char *popt, int optlen)
@@ -174,8 +214,9 @@ struct dhcp_opt dhcp_options[] = {
.barebox_var_name = "net.nameserver",
}, {
.option = 12,
+ .copy_only_if_valid = 1,
.handle = env_str_handle,
- .barebox_var_name = "hostname",
+ .barebox_var_name = "global.hostname",
}, {
.option = 15,
.handle = env_str_handle,
@@ -183,7 +224,7 @@ struct dhcp_opt dhcp_options[] = {
}, {
.option = 17,
.handle = env_str_handle,
- .barebox_var_name = "rootpath",
+ .barebox_dhcp_global = "rootpath",
}, {
.option = 51,
.handle = copy_uint32_handle,
@@ -196,22 +237,23 @@ struct dhcp_opt dhcp_options[] = {
}, {
.option = 66,
.handle = env_str_handle,
- .barebox_var_name = "dhcp_tftp_server_name",
+ .barebox_dhcp_global = "tftp_server_name",
.data = dhcp_tftpname,
}, {
.option = 67,
.handle = bootfile_vendorex_handle,
- .barebox_var_name = "bootfile",
+ .barebox_dhcp_global = "bootfile",
}, {
.option = 224,
.handle = env_str_handle,
- .barebox_var_name = "dhcp_oftree_file",
+ .barebox_dhcp_global = "oftree_file",
},
};
struct dhcp_param {
unsigned char option;
const char *barebox_var_name;
+ const char *barebox_dhcp_global;
int (*handle)(struct dhcp_param *param, u8 *e);
void *data;
};
@@ -224,6 +266,9 @@ static int dhcp_set_string_options(struct dhcp_param *param, u8 *e)
if (!str && param->barebox_var_name)
str = (char*)getenv(param->barebox_var_name);
+ if (!str && param->barebox_dhcp_global)
+ str = (char*)dhcp_get_barebox_global(param->barebox_dhcp_global);
+
if (!str)
return 0;
@@ -248,23 +293,23 @@ struct dhcp_param dhcp_params[] = {
{
.option = DHCP_HOSTNAME,
.handle = dhcp_set_string_options,
- .barebox_var_name = "hostname",
+ .barebox_var_name = "global.hostname",
}, {
.option = DHCP_VENDOR_ID,
.handle = dhcp_set_string_options,
- .barebox_var_name = "dhcp_vendor_id",
+ .barebox_dhcp_global = "vendor_id",
}, {
.option = DHCP_CLIENT_ID,
.handle = dhcp_set_string_options,
- .barebox_var_name = "dhcp_client_id",
+ .barebox_dhcp_global = "client_id",
}, {
.option = DHCP_USER_CLASS,
.handle = dhcp_set_string_options,
- .barebox_var_name = "dhcp_user_class",
+ .barebox_dhcp_global = "user_class",
}, {
.option = DHCP_CLIENT_UUID,
.handle = dhcp_set_string_options,
- .barebox_var_name = "dhcp_client_uuid",
+ .barebox_dhcp_global = "client_uuid",
}
};
@@ -345,8 +390,10 @@ static void bootp_copy_net_params(struct bootp *bp)
if (tmp_ip != 0)
net_set_serverip(tmp_ip);
- if (strlen(bp->bp_file) > 0)
+ if (strlen(bp->bp_file) > 0) {
setenv("bootfile", bp->bp_file);
+ dhcp_set_barebox_global("bootfile", bp->bp_file);
+ }
debug("bootfile: %s\n", bp->bp_file);
}
@@ -607,20 +654,74 @@ static void dhcp_reset_env(void)
for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
opt = &dhcp_options[i];
- if (!opt->barebox_var_name)
+ if (!opt->barebox_var_name || opt->copy_only_if_valid)
continue;
setenv(opt->barebox_var_name,"");
+ if (opt->barebox_dhcp_global)
+ dhcp_set_barebox_global(opt->barebox_dhcp_global,"");
+ }
+}
+
+static void dhcp_global_add(const char *var)
+{
+ char * var_global = asprintf("dhcp.%s", var);
+
+ if (!var_global)
+ return;
+
+ globalvar_add_simple(var_global);
+ free(var_global);
+}
+
+static int dhcp_global_init(void)
+{
+ struct dhcp_opt *opt;
+ struct dhcp_param *param;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dhcp_options); i++) {
+ opt = &dhcp_options[i];
+
+ if (!opt->barebox_dhcp_global)
+ continue;
+
+ dhcp_global_add(opt->barebox_dhcp_global);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(dhcp_params); i++) {
+ param = &dhcp_params[i];
+
+ if (!param->barebox_dhcp_global)
+ continue;
+
+ dhcp_global_add(param->barebox_dhcp_global);
}
+
+ return 0;
+}
+late_initcall(dhcp_global_init);
+
+static void dhcp_getenv_int(const char *name, int *i)
+{
+ const char* str = getenv(name);
+
+ if (!str)
+ return;
+
+ *i = simple_strtoul(str, NULL, 10);
}
static int do_dhcp(int argc, char *argv[])
{
int ret, opt;
+ int retries = DHCP_DEFAULT_RETRY;
dhcp_reset_env();
- while((opt = getopt(argc, argv, "H:v:c:u:U:")) > 0) {
+ dhcp_getenv_int("global.dhcp.retries", &retries);
+
+ while((opt = getopt(argc, argv, "H:v:c:u:U:r:")) > 0) {
switch(opt) {
case 'H':
dhcp_set_param_data(DHCP_HOSTNAME, optarg);
@@ -637,9 +738,17 @@ static int do_dhcp(int argc, char *argv[])
case 'U':
dhcp_set_param_data(DHCP_USER_CLASS, optarg);
break;
+ case 'r':
+ retries = simple_strtoul(optarg, NULL, 10);
+ break;
}
}
+ if (!retries) {
+ printf("retries is set to zero, set it to %d\n", DHCP_DEFAULT_RETRY);
+ retries = DHCP_DEFAULT_RETRY;
+ }
+
dhcp_con = net_udp_new(0xffffffff, PORT_BOOTPS, dhcp_handler, NULL);
if (IS_ERR(dhcp_con)) {
ret = PTR_ERR(dhcp_con);
@@ -660,11 +769,17 @@ static int do_dhcp(int argc, char *argv[])
while (dhcp_state != BOUND) {
if (ctrlc())
break;
+ if (!retries) {
+ ret = -ETIMEDOUT;
+ goto out1;
+ }
net_poll();
if (is_timeout(dhcp_start, 3 * SECOND)) {
dhcp_start = get_time_ns();
printf("T ");
ret = bootp_request();
+ /* no need to check if retries > 0 as we check if != 0 */
+ retries--;
if (ret)
goto out1;
}
@@ -676,7 +791,7 @@ out:
if (ret)
printf("dhcp failed: %s\n", strerror(-ret));
- return ret ? 1 : 0;
+ return ret;
}
BAREBOX_CMD_HELP_START(dhcp)
@@ -699,7 +814,8 @@ BAREBOX_CMD_HELP_OPT ("-u <client_uuid>",
BAREBOX_CMD_HELP_OPT ("-U <user_class>",
"DHCP User class (code 77) submitted in DHCP requests. It can\n"
"be used in the DHCP server's configuration to select options\n"
-"(e.g. bootfile or server) which are valid for barebox clients only.\n");
+"(e.g. bootfile or server) which are valid for barebox clients only.\n")
+BAREBOX_CMD_HELP_OPT ("-r <retry>", "retry limit by default "__stringify(DHCP_DEFAULT_RETRY)"\n");
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(dhcp)
@@ -709,12 +825,13 @@ BAREBOX_CMD_START(dhcp)
BAREBOX_CMD_COMPLETE(empty_complete)
BAREBOX_CMD_END
-BAREBOX_MAGICVAR(bootfile, "bootfile returned from DHCP request");
-BAREBOX_MAGICVAR(hostname, "hostname to send or returned from DHCP request");
-BAREBOX_MAGICVAR(rootpath, "rootpath returned from DHCP request");
-BAREBOX_MAGICVAR(dhcp_vendor_id, "vendor id to send to the DHCP server");
-BAREBOX_MAGICVAR(dhcp_client_uuid, "cliend uuid to send to the DHCP server");
-BAREBOX_MAGICVAR(dhcp_client_id, "cliend id to send to the DHCP server");
-BAREBOX_MAGICVAR(dhcp_user_class, "user class to send to the DHCP server");
-BAREBOX_MAGICVAR(dhcp_tftp_server_name, "TFTP server Name returned from DHCP request");
-BAREBOX_MAGICVAR(dhcp_oftree_file, "OF tree returned from DHCP request (option 224)");
+BAREBOX_MAGICVAR_NAMED(global_hostname, global.hostname, "hostname to send or returned from DHCP request");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_bootfile, global.dhcp.bootfile, "bootfile returned from DHCP request");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_rootpath, global.dhcp.rootpath, "rootpath returned from DHCP request");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_vendor_id, global.dhcp.vendor_id, "vendor id to send to the DHCP server");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_client_uuid, global.dhcp.client_uuid, "cliend uuid to send to the DHCP server");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_client_id, global.dhcp.client_id, "cliend id to send to the DHCP server");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_user_class, global.dhcp.user_class, "user class to send to the DHCP server");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_tftp_server_name, global.dhcp.tftp_server_name, "TFTP server Name returned from DHCP request");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_oftree_file, global.dhcp.oftree_file, "OF tree returned from DHCP request (option 224)");
+BAREBOX_MAGICVAR_NAMED(global_dhcp_retries, global.dhcp.retries, "retry limit");
diff --git a/net/eth.c b/net/eth.c
index c034eaae25..9f528709d3 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -27,11 +27,12 @@
#include <driver.h>
#include <init.h>
#include <net.h>
-#include <miidev.h>
+#include <linux/phy.h>
#include <errno.h>
#include <malloc.h>
static struct eth_device *eth_current;
+static uint64_t last_link_check;
static LIST_HEAD(netdev_list);
@@ -128,20 +129,64 @@ int eth_complete(struct string_list *sl, char *instr)
}
#endif
-int eth_send(void *packet, int length)
+/*
+ * Check for link if we haven't done so for longer.
+ */
+static int eth_carrier_check(int force)
{
int ret;
- if (!eth_current)
- return -ENODEV;
+ if (!IS_ENABLED(CONFIG_PHYLIB))
+ return 0;
+
+ if (!eth_current->phydev)
+ return 0;
- if (!eth_current->active) {
- ret = eth_current->open(eth_current);
+ if (force || is_timeout(last_link_check, 5 * SECOND)) {
+ ret = phy_update_status(eth_current->phydev);
if (ret)
return ret;
- eth_current->active = 1;
+ last_link_check = get_time_ns();
}
+ return eth_current->phydev->link ? 0 : -ENETDOWN;
+}
+
+/*
+ * Check if we have a current ethernet device and
+ * eventually open it if we have to.
+ */
+static int eth_check_open(void)
+{
+ int ret;
+
+ if (!eth_current)
+ return -ENODEV;
+
+ if (eth_current->active)
+ return 0;
+
+ ret = eth_current->open(eth_current);
+ if (ret)
+ return ret;
+
+ eth_current->active = 1;
+
+ return eth_carrier_check(1);
+}
+
+int eth_send(void *packet, int length)
+{
+ int ret;
+
+ ret = eth_check_open();
+ if (ret)
+ return ret;
+
+ ret = eth_carrier_check(0);
+ if (ret)
+ return ret;
+
led_trigger_network(LED_TRIGGER_NET_TX);
return eth_current->send(eth_current, packet, length);
@@ -151,15 +196,13 @@ int eth_rx(void)
{
int ret;
- if (!eth_current)
- return -ENODEV;
+ ret = eth_check_open();
+ if (ret)
+ return ret;
- if (!eth_current->active) {
- ret = eth_current->open(eth_current);
- if (ret)
- return ret;
- eth_current->active = 1;
- }
+ ret = eth_carrier_check(0);
+ if (ret)
+ return ret;
return eth_current->recv(eth_current);
}
diff --git a/net/net.c b/net/net.c
index 54d8c25d49..d056dd7e0b 100644
--- a/net/net.c
+++ b/net/net.c
@@ -219,6 +219,7 @@ static int arp_request(IPaddr_t dest, unsigned char *ether)
static char *arp_packet;
struct ethernet *et;
unsigned retries = 0;
+ int ret;
if (!arp_packet) {
arp_packet = net_alloc_packet();
@@ -262,7 +263,9 @@ static int arp_request(IPaddr_t dest, unsigned char *ether)
arp_ether = ether;
- eth_send(arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
+ ret = eth_send(arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
+ if (ret)
+ return ret;
arp_start = get_time_ns();
while (arp_wait_ip) {
@@ -272,7 +275,9 @@ static int arp_request(IPaddr_t dest, unsigned char *ether)
if (is_timeout(arp_start, 3 * SECOND)) {
printf("T ");
arp_start = get_time_ns();
- eth_send(arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
+ ret = eth_send(arp_packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
+ if (ret)
+ return ret;
retries++;
}
@@ -454,9 +459,7 @@ static int net_ip_send(struct net_connection *con, int len)
con->ip->check = 0;
con->ip->check = ~net_checksum((unsigned char *)con->ip, sizeof(struct iphdr));
- eth_send(con->packet, ETHER_HDR_SIZE + sizeof(struct iphdr) + len);
-
- return 0;
+ return eth_send(con->packet, ETHER_HDR_SIZE + sizeof(struct iphdr) + len);
}
int net_udp_send(struct net_connection *con, int len)
@@ -480,6 +483,7 @@ static int net_answer_arp(unsigned char *pkt, int len)
struct arprequest *arp = (struct arprequest *)(pkt + ETHER_HDR_SIZE);
struct ethernet *et = (struct ethernet *)pkt;
unsigned char *packet;
+ int ret;
debug("%s\n", __func__);
@@ -497,10 +501,10 @@ static int net_answer_arp(unsigned char *pkt, int len)
if (!packet)
return 0;
memcpy(packet, pkt, ETHER_HDR_SIZE + ARP_HDR_SIZE);
- eth_send(packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
+ ret = eth_send(packet, ETHER_HDR_SIZE + ARP_HDR_SIZE);
free(packet);
- return 0;
+ return ret;
}
static void net_bad_packet(unsigned char *pkt, int len)
diff --git a/net/tftp.c b/net/tftp.c
index ca12638353..053b8f3cd3 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -354,7 +354,8 @@ static int do_tftpb(int argc, char *argv[])
tftp_retries++;
}
- if (tftp_retries > PKT_NUM_RETRIES) {
+ /* Wait for two TIMEOUT periods and add some */
+ if (tftp_retries > 2 * TIMEOUT + 1) {
tftp_err = -ETIMEDOUT;
break;
}
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 912cfd83db..c7faf67a2b 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -209,7 +209,7 @@ endif
# >$< substitution to preserve $ when reloading .cmd file
# note: when using inline perl scripts [perl -e '...$$t=1;...']
# in $(cmd_xxx) double $$ your perl vars
-make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))
+make-cmd = $(subst \\,\\\\,$(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))))
# Find any prerequisites that is newer than target or that does not exist.
# PHONY targets skipped in both cases.
diff --git a/scripts/genenv b/scripts/genenv
index c84af0c015..ff7972bb95 100755
--- a/scripts/genenv
+++ b/scripts/genenv
@@ -11,7 +11,11 @@ shift 2
tempdir=$(mktemp -d tmp.XXXXXX)
for i in $*; do
- cp -r $i/* $tempdir
+ if [ -d $i ]; then
+ cp -r $i/* $tempdir
+ else
+ cp -a $i $tempdir
+ fi
done
find $tempdir -name '.svn' -o -name '*~' | xargs --no-run-if-empty rm -r
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index 624f6502e0..9cd51202ac 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -3,6 +3,7 @@
#
config*
lex.*.c
+*.lex.c
*.tab.c
*.tab.h
zconf.hash.c
diff --git a/scripts/kconfig/zconf.lex.c b/scripts/kconfig/zconf.lex.c
deleted file mode 100644
index c32b1a49f5..0000000000
--- a/scripts/kconfig/zconf.lex.c
+++ /dev/null
@@ -1,2420 +0,0 @@
-
-#line 3 "scripts/kconfig/zconf.lex.c_shipped"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define yy_create_buffer zconf_create_buffer
-#define yy_delete_buffer zconf_delete_buffer
-#define yy_flex_debug zconf_flex_debug
-#define yy_init_buffer zconf_init_buffer
-#define yy_flush_buffer zconf_flush_buffer
-#define yy_load_buffer_state zconf_load_buffer_state
-#define yy_switch_to_buffer zconf_switch_to_buffer
-#define yyin zconfin
-#define yyleng zconfleng
-#define yylex zconflex
-#define yylineno zconflineno
-#define yyout zconfout
-#define yyrestart zconfrestart
-#define yytext zconftext
-#define yywrap zconfwrap
-#define yyalloc zconfalloc
-#define yyrealloc zconfrealloc
-#define yyfree zconffree
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN (yy_start) = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START (((yy_start) - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE zconfrestart(zconfin )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-extern int zconfleng;
-
-extern FILE *zconfin, *zconfout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- #define YY_LESS_LINENO(n)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up zconftext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = (yy_hold_char); \
- YY_RESTORE_YY_MORE_OFFSET \
- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up zconftext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, (yytext_ptr) )
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via zconfrestart()), so that the user can continue scanning by
- * just pointing zconfin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
- : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
-
-/* yy_hold_char holds the character lost when zconftext is formed. */
-static char yy_hold_char;
-static int yy_n_chars; /* number of characters read into yy_ch_buf */
-int zconfleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 0; /* whether we need to initialize */
-static int yy_start = 0; /* start state number */
-
-/* Flag which is used to allow zconfwrap()'s to do buffer switches
- * instead of setting up a fresh zconfin. A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void zconfrestart (FILE *input_file );
-void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer );
-YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size );
-void zconf_delete_buffer (YY_BUFFER_STATE b );
-void zconf_flush_buffer (YY_BUFFER_STATE b );
-void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer );
-void zconfpop_buffer_state (void );
-
-static void zconfensure_buffer_stack (void );
-static void zconf_load_buffer_state (void );
-static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file );
-
-#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER )
-
-YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size );
-YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str );
-YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len );
-
-void *zconfalloc (yy_size_t );
-void *zconfrealloc (void *,yy_size_t );
-void zconffree (void * );
-
-#define yy_new_buffer zconf_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- zconfensure_buffer_stack (); \
- YY_CURRENT_BUFFER_LVALUE = \
- zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- zconfensure_buffer_stack (); \
- YY_CURRENT_BUFFER_LVALUE = \
- zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define zconfwrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0;
-
-typedef int yy_state_type;
-
-extern int zconflineno;
-
-int zconflineno = 1;
-
-extern char *zconftext;
-#define yytext_ptr zconftext
-static yyconst flex_int16_t yy_nxt[][17] =
- {
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0
- },
-
- {
- 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12
- },
-
- {
- 11, 12, 13, 14, 12, 12, 15, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12
- },
-
- {
- 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 18, 16, 16, 16
- },
-
- {
- 11, 16, 16, 17, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 18, 16, 16, 16
-
- },
-
- {
- 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19
- },
-
- {
- 11, 19, 20, 21, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19
- },
-
- {
- 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
- 22, 22, 22, 22, 22, 25, 22
- },
-
- {
- 11, 22, 22, 23, 22, 24, 22, 22, 24, 22,
- 22, 22, 22, 22, 22, 25, 22
- },
-
- {
- 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
- 33, 34, 35, 35, 36, 37, 38
-
- },
-
- {
- 11, 26, 26, 27, 28, 29, 30, 31, 29, 32,
- 33, 34, 35, 35, 36, 37, 38
- },
-
- {
- -11, -11, -11, -11, -11, -11, -11, -11, -11, -11,
- -11, -11, -11, -11, -11, -11, -11
- },
-
- {
- 11, -12, -12, -12, -12, -12, -12, -12, -12, -12,
- -12, -12, -12, -12, -12, -12, -12
- },
-
- {
- 11, -13, 39, 40, -13, -13, 41, -13, -13, -13,
- -13, -13, -13, -13, -13, -13, -13
- },
-
- {
- 11, -14, -14, -14, -14, -14, -14, -14, -14, -14,
- -14, -14, -14, -14, -14, -14, -14
-
- },
-
- {
- 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42
- },
-
- {
- 11, -16, -16, -16, -16, -16, -16, -16, -16, -16,
- -16, -16, -16, -16, -16, -16, -16
- },
-
- {
- 11, -17, -17, -17, -17, -17, -17, -17, -17, -17,
- -17, -17, -17, -17, -17, -17, -17
- },
-
- {
- 11, -18, -18, -18, -18, -18, -18, -18, -18, -18,
- -18, -18, -18, 44, -18, -18, -18
- },
-
- {
- 11, 45, 45, -19, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45
-
- },
-
- {
- 11, -20, 46, 47, -20, -20, -20, -20, -20, -20,
- -20, -20, -20, -20, -20, -20, -20
- },
-
- {
- 11, 48, -21, -21, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48
- },
-
- {
- 11, 49, 49, 50, 49, -22, 49, 49, -22, 49,
- 49, 49, 49, 49, 49, -22, 49
- },
-
- {
- 11, -23, -23, -23, -23, -23, -23, -23, -23, -23,
- -23, -23, -23, -23, -23, -23, -23
- },
-
- {
- 11, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -24
-
- },
-
- {
- 11, 51, 51, 52, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51
- },
-
- {
- 11, -26, -26, -26, -26, -26, -26, -26, -26, -26,
- -26, -26, -26, -26, -26, -26, -26
- },
-
- {
- 11, -27, -27, -27, -27, -27, -27, -27, -27, -27,
- -27, -27, -27, -27, -27, -27, -27
- },
-
- {
- 11, -28, -28, -28, -28, -28, -28, -28, -28, -28,
- -28, -28, -28, -28, 53, -28, -28
- },
-
- {
- 11, -29, -29, -29, -29, -29, -29, -29, -29, -29,
- -29, -29, -29, -29, -29, -29, -29
-
- },
-
- {
- 11, 54, 54, -30, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54
- },
-
- {
- 11, -31, -31, -31, -31, -31, -31, 55, -31, -31,
- -31, -31, -31, -31, -31, -31, -31
- },
-
- {
- 11, -32, -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32
- },
-
- {
- 11, -33, -33, -33, -33, -33, -33, -33, -33, -33,
- -33, -33, -33, -33, -33, -33, -33
- },
-
- {
- 11, -34, -34, -34, -34, -34, -34, -34, -34, -34,
- -34, 56, 57, 57, -34, -34, -34
-
- },
-
- {
- 11, -35, -35, -35, -35, -35, -35, -35, -35, -35,
- -35, 57, 57, 57, -35, -35, -35
- },
-
- {
- 11, -36, -36, -36, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -36, -36, -36, -36
- },
-
- {
- 11, -37, -37, 58, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -37, -37, -37
- },
-
- {
- 11, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -38, -38, -38, -38, -38, -38, 59
- },
-
- {
- 11, -39, 39, 40, -39, -39, 41, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -39
-
- },
-
- {
- 11, -40, -40, -40, -40, -40, -40, -40, -40, -40,
- -40, -40, -40, -40, -40, -40, -40
- },
-
- {
- 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42
- },
-
- {
- 11, 42, 42, 43, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42
- },
-
- {
- 11, -43, -43, -43, -43, -43, -43, -43, -43, -43,
- -43, -43, -43, -43, -43, -43, -43
- },
-
- {
- 11, -44, -44, -44, -44, -44, -44, -44, -44, -44,
- -44, -44, -44, 44, -44, -44, -44
-
- },
-
- {
- 11, 45, 45, -45, 45, 45, 45, 45, 45, 45,
- 45, 45, 45, 45, 45, 45, 45
- },
-
- {
- 11, -46, 46, 47, -46, -46, -46, -46, -46, -46,
- -46, -46, -46, -46, -46, -46, -46
- },
-
- {
- 11, 48, -47, -47, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48
- },
-
- {
- 11, -48, -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48
- },
-
- {
- 11, 49, 49, 50, 49, -49, 49, 49, -49, 49,
- 49, 49, 49, 49, 49, -49, 49
-
- },
-
- {
- 11, -50, -50, -50, -50, -50, -50, -50, -50, -50,
- -50, -50, -50, -50, -50, -50, -50
- },
-
- {
- 11, -51, -51, 52, -51, -51, -51, -51, -51, -51,
- -51, -51, -51, -51, -51, -51, -51
- },
-
- {
- 11, -52, -52, -52, -52, -52, -52, -52, -52, -52,
- -52, -52, -52, -52, -52, -52, -52
- },
-
- {
- 11, -53, -53, -53, -53, -53, -53, -53, -53, -53,
- -53, -53, -53, -53, -53, -53, -53
- },
-
- {
- 11, 54, 54, -54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54
-
- },
-
- {
- 11, -55, -55, -55, -55, -55, -55, -55, -55, -55,
- -55, -55, -55, -55, -55, -55, -55
- },
-
- {
- 11, -56, -56, -56, -56, -56, -56, -56, -56, -56,
- -56, 60, 57, 57, -56, -56, -56
- },
-
- {
- 11, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, 57, 57, 57, -57, -57, -57
- },
-
- {
- 11, -58, -58, -58, -58, -58, -58, -58, -58, -58,
- -58, -58, -58, -58, -58, -58, -58
- },
-
- {
- 11, -59, -59, -59, -59, -59, -59, -59, -59, -59,
- -59, -59, -59, -59, -59, -59, -59
-
- },
-
- {
- 11, -60, -60, -60, -60, -60, -60, -60, -60, -60,
- -60, 57, 57, 57, -60, -60, -60
- },
-
- } ;
-
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[] );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up zconftext.
- */
-#define YY_DO_BEFORE_ACTION \
- (yytext_ptr) = yy_bp; \
- zconfleng = (size_t) (yy_cp - yy_bp); \
- (yy_hold_char) = *yy_cp; \
- *yy_cp = '\0'; \
- (yy_c_buf_p) = yy_cp;
-
-#define YY_NUM_RULES 33
-#define YY_END_OF_BUFFER 34
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static yyconst flex_int16_t yy_accept[61] =
- { 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 34, 5, 4, 2, 3, 7, 8, 6, 32, 29,
- 31, 24, 28, 27, 26, 22, 17, 13, 16, 20,
- 22, 11, 12, 19, 19, 14, 22, 22, 4, 2,
- 3, 3, 1, 6, 32, 29, 31, 30, 24, 23,
- 26, 25, 15, 20, 9, 19, 19, 21, 10, 18
- } ;
-
-static yyconst flex_int32_t yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 4, 5, 6, 1, 1, 7, 8, 9,
- 10, 1, 1, 1, 11, 12, 12, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 1, 1, 1,
- 14, 1, 1, 1, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 1, 15, 1, 1, 13, 1, 13, 13, 13, 13,
-
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 13, 1, 16, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-extern int zconf_flex_debug;
-int zconf_flex_debug = 0;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *zconftext;
-#define YY_NO_INPUT 1
-
-/*
- * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "lkc.h"
-
-#define START_STRSIZE 16
-
-static struct {
- struct file *file;
- int lineno;
-} current_pos;
-
-static char *text;
-static int text_size, text_asize;
-
-struct buffer {
- struct buffer *parent;
- YY_BUFFER_STATE state;
-};
-
-struct buffer *current_buf;
-
-static int last_ts, first_ts;
-
-static void zconf_endhelp(void);
-static void zconf_endfile(void);
-
-static void new_string(void)
-{
- text = malloc(START_STRSIZE);
- text_asize = START_STRSIZE;
- text_size = 0;
- *text = 0;
-}
-
-static void append_string(const char *str, int size)
-{
- int new_size = text_size + size + 1;
- if (new_size > text_asize) {
- new_size += START_STRSIZE - 1;
- new_size &= -START_STRSIZE;
- text = realloc(text, new_size);
- text_asize = new_size;
- }
- memcpy(text + text_size, str, size);
- text_size += size;
- text[text_size] = 0;
-}
-
-static void alloc_string(const char *str, int size)
-{
- text = malloc(size + 1);
- memcpy(text, str, size);
- text[size] = 0;
-}
-
-#define INITIAL 0
-#define COMMAND 1
-#define HELP 2
-#define STRING 3
-#define PARAM 4
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-static int yy_init_globals (void );
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int zconflex_destroy (void );
-
-int zconfget_debug (void );
-
-void zconfset_debug (int debug_flag );
-
-YY_EXTRA_TYPE zconfget_extra (void );
-
-void zconfset_extra (YY_EXTRA_TYPE user_defined );
-
-FILE *zconfget_in (void );
-
-void zconfset_in (FILE * in_str );
-
-FILE *zconfget_out (void );
-
-void zconfset_out (FILE * out_str );
-
-int zconfget_leng (void );
-
-char *zconfget_text (void );
-
-int zconfget_lineno (void );
-
-void zconfset_lineno (int line_number );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int zconfwrap (void );
-#else
-extern int zconfwrap (void );
-#endif
-#endif
-
- static void yyunput (int c,char *buf_ptr );
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (void );
-#else
-static int input (void );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- errno=0; \
- while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(zconfin); \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int zconflex (void);
-
-#define YY_DECL int zconflex (void)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after zconftext and zconfleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
-
- int str = 0;
- int ts, i;
-
- if ( !(yy_init) )
- {
- (yy_init) = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! (yy_start) )
- (yy_start) = 1; /* first start state */
-
- if ( ! zconfin )
- zconfin = stdin;
-
- if ( ! zconfout )
- zconfout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- zconfensure_buffer_stack ();
- YY_CURRENT_BUFFER_LVALUE =
- zconf_create_buffer(zconfin,YY_BUF_SIZE );
- }
-
- zconf_load_buffer_state( );
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yy_cp = (yy_c_buf_p);
-
- /* Support of zconftext. */
- *yy_cp = (yy_hold_char);
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = (yy_start);
-yy_match:
- while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)] ]) > 0 )
- ++yy_cp;
-
- yy_current_state = -yy_current_state;
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
-
- YY_DO_BEFORE_ACTION;
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
-case 1:
-/* rule 1 can match eol */
-case 2:
-/* rule 2 can match eol */
-YY_RULE_SETUP
-{
- current_file->lineno++;
- return T_EOL;
-}
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-{
- BEGIN(COMMAND);
-}
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-{
- unput(zconftext[0]);
- BEGIN(COMMAND);
-}
- YY_BREAK
-
-case 6:
-YY_RULE_SETUP
-{
- const struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
- BEGIN(PARAM);
- current_pos.file = current_file;
- current_pos.lineno = current_file->lineno;
- if (id && id->flags & TF_COMMAND) {
- zconflval.id = id;
- return id->token;
- }
- alloc_string(zconftext, zconfleng);
- zconflval.string = text;
- return T_WORD;
- }
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-
- YY_BREAK
-case 8:
-/* rule 8 can match eol */
-YY_RULE_SETUP
-{
- BEGIN(INITIAL);
- current_file->lineno++;
- return T_EOL;
- }
- YY_BREAK
-
-case 9:
-YY_RULE_SETUP
-return T_AND;
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-return T_OR;
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-return T_OPEN_PAREN;
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-return T_CLOSE_PAREN;
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-return T_NOT;
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-return T_EQUAL;
- YY_BREAK
-case 15:
-YY_RULE_SETUP
-return T_UNEQUAL;
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-{
- str = zconftext[0];
- new_string();
- BEGIN(STRING);
- }
- YY_BREAK
-case 17:
-/* rule 17 can match eol */
-YY_RULE_SETUP
-BEGIN(INITIAL); current_file->lineno++; return T_EOL;
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-/* ignore */
- YY_BREAK
-case 19:
-YY_RULE_SETUP
-{
- const struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
- if (id && id->flags & TF_PARAM) {
- zconflval.id = id;
- return id->token;
- }
- alloc_string(zconftext, zconfleng);
- zconflval.string = text;
- return T_WORD;
- }
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-/* comment */
- YY_BREAK
-case 21:
-/* rule 21 can match eol */
-YY_RULE_SETUP
-current_file->lineno++;
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-
- YY_BREAK
-case YY_STATE_EOF(PARAM):
-{
- BEGIN(INITIAL);
- }
- YY_BREAK
-
-case 23:
-/* rule 23 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
- append_string(zconftext, zconfleng);
- zconflval.string = text;
- return T_WORD_QUOTE;
- }
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-{
- append_string(zconftext, zconfleng);
- }
- YY_BREAK
-case 25:
-/* rule 25 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
- append_string(zconftext + 1, zconfleng - 1);
- zconflval.string = text;
- return T_WORD_QUOTE;
- }
- YY_BREAK
-case 26:
-YY_RULE_SETUP
-{
- append_string(zconftext + 1, zconfleng - 1);
- }
- YY_BREAK
-case 27:
-YY_RULE_SETUP
-{
- if (str == zconftext[0]) {
- BEGIN(PARAM);
- zconflval.string = text;
- return T_WORD_QUOTE;
- } else
- append_string(zconftext, 1);
- }
- YY_BREAK
-case 28:
-/* rule 28 can match eol */
-YY_RULE_SETUP
-{
- printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
- current_file->lineno++;
- BEGIN(INITIAL);
- return T_EOL;
- }
- YY_BREAK
-case YY_STATE_EOF(STRING):
-{
- BEGIN(INITIAL);
- }
- YY_BREAK
-
-case 29:
-YY_RULE_SETUP
-{
- ts = 0;
- for (i = 0; i < zconfleng; i++) {
- if (zconftext[i] == '\t')
- ts = (ts & ~7) + 8;
- else
- ts++;
- }
- last_ts = ts;
- if (first_ts) {
- if (ts < first_ts) {
- zconf_endhelp();
- return T_HELPTEXT;
- }
- ts -= first_ts;
- while (ts > 8) {
- append_string(" ", 8);
- ts -= 8;
- }
- append_string(" ", ts);
- }
- }
- YY_BREAK
-case 30:
-/* rule 30 can match eol */
-*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
-(yy_c_buf_p) = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up zconftext again */
-YY_RULE_SETUP
-{
- current_file->lineno++;
- zconf_endhelp();
- return T_HELPTEXT;
- }
- YY_BREAK
-case 31:
-/* rule 31 can match eol */
-YY_RULE_SETUP
-{
- current_file->lineno++;
- append_string("\n", 1);
- }
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-{
- while (zconfleng) {
- if ((zconftext[zconfleng-1] != ' ') && (zconftext[zconfleng-1] != '\t'))
- break;
- zconfleng--;
- }
- append_string(zconftext, zconfleng);
- if (!first_ts)
- first_ts = last_ts;
- }
- YY_BREAK
-case YY_STATE_EOF(HELP):
-{
- zconf_endhelp();
- return T_HELPTEXT;
- }
- YY_BREAK
-
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(COMMAND):
-{
- if (current_file) {
- zconf_endfile();
- return T_EOL;
- }
- fclose(zconfin);
- yyterminate();
-}
- YY_BREAK
-case 33:
-YY_RULE_SETUP
-YY_FATAL_ERROR( "flex scanner jammed" );
- YY_BREAK
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = (yy_hold_char);
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed zconfin at a new source and called
- * zconflex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state );
-
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++(yy_c_buf_p);
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = (yy_c_buf_p);
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- (yy_did_buffer_switch_on_eof) = 0;
-
- if ( zconfwrap( ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * zconftext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! (yy_did_buffer_switch_on_eof) )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- (yy_c_buf_p) =
- (yytext_ptr) + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( );
-
- yy_cp = (yy_c_buf_p);
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- (yy_c_buf_p) =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
-
- yy_current_state = yy_get_previous_state( );
-
- yy_cp = (yy_c_buf_p);
- yy_bp = (yytext_ptr) + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
-} /* end of zconflex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (void)
-{
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = (yytext_ptr);
- register int number_to_move, i;
- int ret_val;
-
- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
- int yy_c_buf_p_offset =
- (int) ((yy_c_buf_p) - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- (yy_n_chars), (size_t) num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- if ( (yy_n_chars) == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- zconfrestart(zconfin );
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
- /* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) zconfrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
- }
-
- (yy_n_chars) += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
-
- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (void)
-{
- register yy_state_type yy_current_state;
- register char *yy_cp;
-
- yy_current_state = (yy_start);
-
- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
- {
- yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
-{
- register int yy_is_jam;
-
- yy_current_state = yy_nxt[yy_current_state][1];
- yy_is_jam = (yy_current_state <= 0);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
- static void yyunput (int c, register char * yy_bp )
-{
- register char *yy_cp;
-
- yy_cp = (yy_c_buf_p);
-
- /* undo effects of setting up zconftext */
- *yy_cp = (yy_hold_char);
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = (yy_n_chars) + 2;
- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
- register char *source =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
- (yytext_ptr) = yy_bp;
- (yy_hold_char) = *yy_cp;
- (yy_c_buf_p) = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (void)
-#else
- static int input (void)
-#endif
-
-{
- int c;
-
- *(yy_c_buf_p) = (yy_hold_char);
-
- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
- /* This was really a NUL. */
- *(yy_c_buf_p) = '\0';
-
- else
- { /* need more input */
- int offset = (yy_c_buf_p) - (yytext_ptr);
- ++(yy_c_buf_p);
-
- switch ( yy_get_next_buffer( ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- zconfrestart(zconfin );
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( zconfwrap( ) )
- return EOF;
-
- if ( ! (yy_did_buffer_switch_on_eof) )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput();
-#else
- return input();
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- (yy_c_buf_p) = (yytext_ptr) + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
- *(yy_c_buf_p) = '\0'; /* preserve zconftext */
- (yy_hold_char) = *++(yy_c_buf_p);
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- *
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void zconfrestart (FILE * input_file )
-{
-
- if ( ! YY_CURRENT_BUFFER ){
- zconfensure_buffer_stack ();
- YY_CURRENT_BUFFER_LVALUE =
- zconf_create_buffer(zconfin,YY_BUF_SIZE );
- }
-
- zconf_init_buffer(YY_CURRENT_BUFFER,input_file );
- zconf_load_buffer_state( );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- *
- */
- void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer )
-{
-
- /* TODO. We should be able to replace this entire function body
- * with
- * zconfpop_buffer_state();
- * zconfpush_buffer_state(new_buffer);
- */
- zconfensure_buffer_stack ();
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *(yy_c_buf_p) = (yy_hold_char);
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- zconf_load_buffer_state( );
-
- /* We don't actually know whether we did this switch during
- * EOF (zconfwrap()) processing, but the only time this flag
- * is looked at is after zconfwrap() is called, so it's safe
- * to go ahead and always set it.
- */
- (yy_did_buffer_switch_on_eof) = 1;
-}
-
-static void zconf_load_buffer_state (void)
-{
- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- (yy_hold_char) = *(yy_c_buf_p);
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- *
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE zconf_create_buffer (FILE * file, int size )
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2 );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- zconf_init_buffer(b,file );
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with zconf_create_buffer()
- *
- */
- void zconf_delete_buffer (YY_BUFFER_STATE b )
-{
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- zconffree((void *) b->yy_ch_buf );
-
- zconffree((void *) b );
-}
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a zconfrestart() or at EOF.
- */
- static void zconf_init_buffer (YY_BUFFER_STATE b, FILE * file )
-
-{
- int oerrno = errno;
-
- zconf_flush_buffer(b );
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then zconf_init_buffer was _probably_
- * called from zconfrestart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
- }
-
- b->yy_is_interactive = 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- *
- */
- void zconf_flush_buffer (YY_BUFFER_STATE b )
-{
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- zconf_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- *
- */
-void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
- if (new_buffer == NULL)
- return;
-
- zconfensure_buffer_stack();
-
- /* This block is copied from zconf_switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *(yy_c_buf_p) = (yy_hold_char);
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- (yy_buffer_stack_top)++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from zconf_switch_to_buffer. */
- zconf_load_buffer_state( );
- (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- *
- */
-void zconfpop_buffer_state (void)
-{
- if (!YY_CURRENT_BUFFER)
- return;
-
- zconf_delete_buffer(YY_CURRENT_BUFFER );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if ((yy_buffer_stack_top) > 0)
- --(yy_buffer_stack_top);
-
- if (YY_CURRENT_BUFFER) {
- zconf_load_buffer_state( );
- (yy_did_buffer_switch_on_eof) = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void zconfensure_buffer_stack (void)
-{
- int num_to_alloc;
-
- if (!(yy_buffer_stack)) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1;
- (yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- );
- if ( ! (yy_buffer_stack) )
- YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" );
-
- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- (yy_buffer_stack_max) = num_to_alloc;
- (yy_buffer_stack_top) = 0;
- return;
- }
-
- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = (yy_buffer_stack_max) + grow_size;
- (yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc
- ((yy_buffer_stack),
- num_to_alloc * sizeof(struct yy_buffer_state*)
- );
- if ( ! (yy_buffer_stack) )
- YY_FATAL_ERROR( "out of dynamic memory in zconfensure_buffer_stack()" );
-
- /* zero only the new slots.*/
- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
- (yy_buffer_stack_max) = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- zconf_switch_to_buffer(b );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to zconflex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- *
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * zconf_scan_bytes() instead.
- */
-YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
-{
-
- return zconf_scan_bytes(yystr,strlen(yystr) );
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- *
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE zconf_scan_bytes (yyconst char * yybytes, int _yybytes_len )
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) zconfalloc(n );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = zconf_scan_buffer(buf,n );
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg )
-{
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up zconftext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- zconftext[zconfleng] = (yy_hold_char); \
- (yy_c_buf_p) = zconftext + yyless_macro_arg; \
- (yy_hold_char) = *(yy_c_buf_p); \
- *(yy_c_buf_p) = '\0'; \
- zconfleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the current line number.
- *
- */
-int zconfget_lineno (void)
-{
-
- return zconflineno;
-}
-
-/** Get the input stream.
- *
- */
-FILE *zconfget_in (void)
-{
- return zconfin;
-}
-
-/** Get the output stream.
- *
- */
-FILE *zconfget_out (void)
-{
- return zconfout;
-}
-
-/** Get the length of the current token.
- *
- */
-int zconfget_leng (void)
-{
- return zconfleng;
-}
-
-/** Get the current token.
- *
- */
-
-char *zconfget_text (void)
-{
- return zconftext;
-}
-
-/** Set the current line number.
- * @param line_number
- *
- */
-void zconfset_lineno (int line_number )
-{
-
- zconflineno = line_number;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- *
- * @see zconf_switch_to_buffer
- */
-void zconfset_in (FILE * in_str )
-{
- zconfin = in_str ;
-}
-
-void zconfset_out (FILE * out_str )
-{
- zconfout = out_str ;
-}
-
-int zconfget_debug (void)
-{
- return zconf_flex_debug;
-}
-
-void zconfset_debug (int bdebug )
-{
- zconf_flex_debug = bdebug ;
-}
-
-static int yy_init_globals (void)
-{
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from zconflex_destroy(), so don't allocate here.
- */
-
- (yy_buffer_stack) = 0;
- (yy_buffer_stack_top) = 0;
- (yy_buffer_stack_max) = 0;
- (yy_c_buf_p) = (char *) 0;
- (yy_init) = 0;
- (yy_start) = 0;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- zconfin = stdin;
- zconfout = stdout;
-#else
- zconfin = (FILE *) 0;
- zconfout = (FILE *) 0;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * zconflex_init()
- */
- return 0;
-}
-
-/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
-int zconflex_destroy (void)
-{
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- zconf_delete_buffer(YY_CURRENT_BUFFER );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- zconfpop_buffer_state();
- }
-
- /* Destroy the stack itself. */
- zconffree((yy_buffer_stack) );
- (yy_buffer_stack) = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * zconflex() is called, initialization will occur. */
- yy_init_globals( );
-
- return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *zconfalloc (yy_size_t size )
-{
- return (void *) malloc( size );
-}
-
-void *zconfrealloc (void * ptr, yy_size_t size )
-{
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
-}
-
-void zconffree (void * ptr )
-{
- free( (char *) ptr ); /* see zconfrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-void zconf_starthelp(void)
-{
- new_string();
- last_ts = first_ts = 0;
- BEGIN(HELP);
-}
-
-static void zconf_endhelp(void)
-{
- zconflval.string = text;
- BEGIN(INITIAL);
-}
-
-/*
- * Try to open specified file with following names:
- * ./name
- * $(srctree)/name
- * The latter is used when srctree is separate from objtree
- * when compiling the kernel.
- * Return NULL if file is not found.
- */
-FILE *zconf_fopen(const char *name)
-{
- char *env, fullname[PATH_MAX+1];
- FILE *f;
-
- f = fopen(name, "r");
- if (!f && name != NULL && name[0] != '/') {
- env = getenv(SRCTREE);
- if (env) {
- sprintf(fullname, "%s/%s", env, name);
- f = fopen(fullname, "r");
- }
- }
- return f;
-}
-
-void zconf_initscan(const char *name)
-{
- zconfin = zconf_fopen(name);
- if (!zconfin) {
- printf("can't find file %s\n", name);
- exit(1);
- }
-
- current_buf = malloc(sizeof(*current_buf));
- memset(current_buf, 0, sizeof(*current_buf));
-
- current_file = file_lookup(name);
- current_file->lineno = 1;
-}
-
-void zconf_nextfile(const char *name)
-{
- struct file *iter;
- struct file *file = file_lookup(name);
- struct buffer *buf = malloc(sizeof(*buf));
- memset(buf, 0, sizeof(*buf));
-
- current_buf->state = YY_CURRENT_BUFFER;
- zconfin = zconf_fopen(file->name);
- if (!zconfin) {
- printf("%s:%d: can't open file \"%s\"\n",
- zconf_curname(), zconf_lineno(), file->name);
- exit(1);
- }
- zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
- buf->parent = current_buf;
- current_buf = buf;
-
- for (iter = current_file->parent; iter; iter = iter->parent ) {
- if (!strcmp(current_file->name,iter->name) ) {
- printf("%s:%d: recursive inclusion detected. "
- "Inclusion path:\n current file : '%s'\n",
- zconf_curname(), zconf_lineno(),
- zconf_curname());
- iter = current_file->parent;
- while (iter && \
- strcmp(iter->name,current_file->name)) {
- printf(" included from: '%s:%d'\n",
- iter->name, iter->lineno-1);
- iter = iter->parent;
- }
- if (iter)
- printf(" included from: '%s:%d'\n",
- iter->name, iter->lineno+1);
- exit(1);
- }
- }
- file->lineno = 1;
- file->parent = current_file;
- current_file = file;
-}
-
-static void zconf_endfile(void)
-{
- struct buffer *parent;
-
- current_file = current_file->parent;
-
- parent = current_buf->parent;
- if (parent) {
- fclose(zconfin);
- zconf_delete_buffer(YY_CURRENT_BUFFER);
- zconf_switch_to_buffer(parent->state);
- }
- free(current_buf);
- current_buf = parent;
-}
-
-int zconf_lineno(void)
-{
- return current_pos.lineno;
-}
-
-const char *zconf_curname(void)
-{
- return current_pos.file ? current_pos.file->name : "<none>";
-}
-