summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/barebox/barebox,environment.rst5
-rw-r--r--Documentation/devicetree/bindings/mtd/m25p80.rst10
-rw-r--r--Makefile2
-rw-r--r--arch/arm/boards/guf-vincell/board.c3
-rw-r--r--arch/arm/boards/phytec-phycore-pxa270/board.c2
-rw-r--r--arch/arm/boards/phytec-phyflex-imx6/board.c31
-rw-r--r--arch/arm/boards/zylonite/board.c3
-rw-r--r--arch/arm/boards/zylonite/env/bin/init25
-rw-r--r--arch/arm/boards/zylonite/env/bin/mtd_env_override4
-rw-r--r--arch/arm/boards/zylonite/env/boot/nand-ubi5
-rw-r--r--arch/arm/boards/zylonite/env/config6
-rw-r--r--arch/arm/boards/zylonite/env/init/mtdparts-nand11
-rw-r--r--arch/arm/boards/zylonite/env/nv/hostname1
-rw-r--r--arch/arm/boards/zylonite/env/nv/linux.bootargs.base1
-rw-r--r--arch/arm/boards/zylonite/env/nv/linux.bootargs.console1
-rw-r--r--arch/arm/configs/zylonite310_defconfig12
-rw-r--r--arch/arm/cpu/cache-l2x0.c48
-rw-r--r--arch/arm/cpu/cache.c2
-rw-r--r--arch/arm/cpu/cpu.c3
-rw-r--r--arch/arm/cpu/exceptions.S4
-rw-r--r--arch/arm/cpu/mmu.c22
-rw-r--r--arch/arm/dts/imx27-phytec-phycore-rdk.dts8
-rw-r--r--arch/arm/dts/imx51-babbage.dts4
-rw-r--r--arch/arm/dts/imx53-qsb-common.dtsi4
-rw-r--r--arch/arm/dts/imx6dl-eltec-hipercam.dts4
-rw-r--r--arch/arm/dts/imx6dl-phytec-pfla02.dtsi4
-rw-r--r--arch/arm/dts/imx6q-phytec-pbab01.dts4
-rw-r--r--arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi8
-rw-r--r--arch/arm/dts/imx6q-phytec-pfla02.dtsi4
-rw-r--r--arch/arm/dts/imx6q-sabresd.dts2
-rw-r--r--arch/arm/dts/imx6q-var-custom.dts2
-rw-r--r--arch/arm/dts/imx6q-var-som.dtsi2
-rw-r--r--arch/arm/dts/imx6qdl-phytec-pbab01.dtsi16
-rw-r--r--arch/arm/dts/imx6qdl-phytec-pfla02.dtsi137
-rw-r--r--arch/arm/dts/imx6qdl-sabresd.dtsi2
-rw-r--r--arch/arm/dts/imx6s-riotboard.dts4
-rw-r--r--arch/arm/include/asm/gpio.h10
-rw-r--r--arch/arm/include/asm/mmu.h1
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h2
-rw-r--r--arch/arm/mach-ep93xx/include/mach/gpio.h1
-rw-r--r--arch/arm/mach-imx/Kconfig3
-rw-r--r--arch/arm/mach-imx/imx6.c35
-rw-r--r--arch/arm/mach-mxs/include/mach/gpio.h21
-rw-r--r--arch/arm/mach-pxa/gpio.c32
-rw-r--r--arch/arm/mach-pxa/include/plat/gpio.h32
-rw-r--r--arch/arm/mach-samsung/gpio-s3c24x0.c2
-rw-r--r--arch/arm/mach-samsung/include/mach/gpio.h18
-rw-r--r--arch/mips/include/asm/gpio.h6
-rw-r--r--arch/ppc/boards/freescale-p1010rdb/p1010rdb.c2
-rw-r--r--arch/ppc/boards/geip-da923rc/da923rc.c1
-rw-r--r--arch/ppc/mach-mpc85xx/include/mach/gpio.h2
-rw-r--r--commands/Kconfig13
-rw-r--r--commands/boot.c26
-rw-r--r--commands/login.c70
-rw-r--r--commands/menutree.c3
-rw-r--r--commands/splash.c21
-rw-r--r--commands/ubiformat.c1
-rw-r--r--common/Kconfig16
-rw-r--r--common/console.c6
-rw-r--r--common/console_common.c27
-rw-r--r--common/console_simple.c6
-rw-r--r--common/hush.c3
-rw-r--r--common/parser.c3
-rw-r--r--common/password.c123
-rw-r--r--common/startup.c7
-rw-r--r--crypto/Kconfig2
-rw-r--r--defaultenv/defaultenv-2-base/bin/init18
-rw-r--r--drivers/eeprom/at24.c38
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c44
-rw-r--r--drivers/i2c/busses/i2c-gpio.c10
-rw-r--r--drivers/i2c/busses/i2c-imx.c12
-rw-r--r--drivers/i2c/busses/i2c-omap.c88
-rw-r--r--drivers/i2c/i2c.c130
-rw-r--r--drivers/mci/mmci.c18
-rw-r--r--drivers/mtd/devices/m25p80.c6
-rw-r--r--drivers/mtd/nand/nand_mrvl_nfc.c5
-rw-r--r--drivers/mtd/spi-nor/cadence-quadspi.c2
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c100
-rw-r--r--drivers/of/of_path.c14
-rw-r--r--drivers/of/partition.c4
-rw-r--r--drivers/spi/imx_spi.c124
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/fb.c51
-rw-r--r--drivers/video/fbconsole.c18
-rw-r--r--drivers/video/imx-ipu-fb.c6
-rw-r--r--drivers/video/imx-ipu-v3/imx-hdmi.c380
-rw-r--r--drivers/video/imx-ipu-v3/imx-hdmi.h3
-rw-r--r--drivers/video/imx-ipu-v3/ipufb.c32
-rw-r--r--drivers/video/simple-panel.c3
-rw-r--r--fs/devfs-core.c13
-rw-r--r--include/asm-generic/gpio.h9
-rw-r--r--include/console.h3
-rw-r--r--include/dma.h1
-rw-r--r--include/driver.h2
-rw-r--r--include/fb.h3
-rw-r--r--include/gpio.h23
-rw-r--r--include/gui/graphic_utils.h6
-rw-r--r--include/gui/gui.h6
-rw-r--r--include/i2c/i2c.h45
-rw-r--r--include/linux/mtd/spi-nor.h4
-rw-r--r--include/password.h22
-rw-r--r--include/spi/imx-spi.h4
-rw-r--r--include/video/backlight.h17
-rw-r--r--include/watchdog.h4
-rw-r--r--lib/gui/graphic_utils.c49
-rw-r--r--lib/libfile.c6
106 files changed, 1363 insertions, 863 deletions
diff --git a/Documentation/devicetree/bindings/barebox/barebox,environment.rst b/Documentation/devicetree/bindings/barebox/barebox,environment.rst
index d472f66398..d5e52ead04 100644
--- a/Documentation/devicetree/bindings/barebox/barebox,environment.rst
+++ b/Documentation/devicetree/bindings/barebox/barebox,environment.rst
@@ -8,8 +8,9 @@ Required properties:
* ``compatible``: should be ``barebox,environment``
* ``device-path``: path to the environment
-The device-path is a multistring property. The first string should be a
-nodepath to the node containing the physical device of the environment.
+The device-path is a multistring property. The first string should contain
+a nodepath to the node containing the physical device of the environment or
+a nodepath to a partition described by the OF partition binding.
The subsequent strings are of the form <type>:<options> to further describe
the path to the environment. Supported values for <type>:
diff --git a/Documentation/devicetree/bindings/mtd/m25p80.rst b/Documentation/devicetree/bindings/mtd/m25p80.rst
new file mode 100644
index 0000000000..d7c8914ec5
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/m25p80.rst
@@ -0,0 +1,10 @@
+MTD SPI driver for ST M25Pxx (and similar) serial flash chips
+=============================================================
+
+Additionally to the Linux bindings in ``dts/Bindings/mtd/m25p80.txt``
+the barebox driver has the following optional properties:
+
+- use-large-blocks : Use large blocks rather than the 4K blocks some devices
+ support. 4K erase blocks do not work with UBIFS which needs
+ a minimum erase block size of 15360 bytes. Also bigger sectors
+ are faster to erase.
diff --git a/Makefile b/Makefile
index 05a905b45c..4991f71155 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
VERSION = 2015
-PATCHLEVEL = 08
+PATCHLEVEL = 09
SUBLEVEL = 0
EXTRAVERSION =
NAME = None
diff --git a/arch/arm/boards/guf-vincell/board.c b/arch/arm/boards/guf-vincell/board.c
index d27d9e4ddf..ad47ee2558 100644
--- a/arch/arm/boards/guf-vincell/board.c
+++ b/arch/arm/boards/guf-vincell/board.c
@@ -40,6 +40,9 @@ static void vincell_fec_reset(void)
static int vincell_devices_init(void)
{
+ if (!of_machine_is_compatible("guf,imx53-vincell"))
+ return 0;
+
writel(0, MX53_M4IF_BASE_ADDR + 0xc);
clk_set_rate(clk_lookup("emi_slow_podf"), 133333334);
diff --git a/arch/arm/boards/phytec-phycore-pxa270/board.c b/arch/arm/boards/phytec-phycore-pxa270/board.c
index 833c4c81e4..1424c9c937 100644
--- a/arch/arm/boards/phytec-phycore-pxa270/board.c
+++ b/arch/arm/boards/phytec-phycore-pxa270/board.c
@@ -26,7 +26,7 @@
#include <partition.h>
#include <linux/sizes.h>
-#include <plat/gpio.h>
+#include <gpio.h>
#include <mach/mfp-pxa27x.h>
#include <mach/pxa-regs.h>
#include <mach/pxafb.h>
diff --git a/arch/arm/boards/phytec-phyflex-imx6/board.c b/arch/arm/boards/phytec-phyflex-imx6/board.c
index 5f65261a9f..d3100c88b3 100644
--- a/arch/arm/boards/phytec-phyflex-imx6/board.c
+++ b/arch/arm/boards/phytec-phyflex-imx6/board.c
@@ -16,6 +16,7 @@
* Foundation.
*
*/
+#define pr_fmt(fmt) "phyFLEX-i.MX6: " fmt
#include <malloc.h>
#include <envfs.h>
@@ -27,12 +28,16 @@
#include <of.h>
#include <mach/bbu.h>
#include <fec.h>
+#include <globalvar.h>
#include <linux/micrel_phy.h>
#include <mach/iomux-mx6.h>
#include <mach/imx6.h>
+#define PHYFLEX_MODULE_REV_1 0x1
+#define PHYFLEX_MODULE_REV_2 0x2
+
#define GPIO_2_11_PD_CTL MX6_PAD_CTL_PUS_100K_DOWN | MX6_PAD_CTL_PUE | MX6_PAD_CTL_PKE | \
MX6_PAD_CTL_SPEED_MED | MX6_PAD_CTL_DSE_40ohm | MX6_PAD_CTL_HYS
@@ -64,10 +69,24 @@ static void phyflex_err006282_workaround(void)
gpio_direction_input(MX6_PHYFLEX_ERR006282);
}
+static unsigned int pfla02_module_revision;
+
+static unsigned int get_module_rev(void)
+{
+ unsigned int val = 0;
+
+ val = gpio_get_value(IMX_GPIO_NR(2, 12));
+ val |= (gpio_get_value(IMX_GPIO_NR(2, 13)) << 1);
+ val |= (gpio_get_value(IMX_GPIO_NR(2, 14)) << 2);
+ val |= (gpio_get_value(IMX_GPIO_NR(2, 15)) << 3);
+
+ return 16 - val;
+}
+
static int phytec_pfla02_init(void)
{
int ret;
- char *environment_path;
+ char *environment_path, *envdev;
if (!of_machine_is_compatible("phytec,imx6q-pfla02") &&
!of_machine_is_compatible("phytec,imx6dl-pfla02") &&
@@ -78,17 +97,25 @@ static int phytec_pfla02_init(void)
imx6_bbu_nand_register_handler("nand", BBU_HANDLER_FLAG_DEFAULT);
+ pfla02_module_revision = get_module_rev();
+ globalvar_add_simple_int("board.revision", &pfla02_module_revision, "%u");
+
+ pr_info("Module Revision: %u\n", pfla02_module_revision);
+
switch (bootsource_get()) {
case BOOTSOURCE_MMC:
environment_path = asprintf("/chosen/environment-sd%d",
bootsource_get_instance() + 1);
+ envdev = "MMC";
break;
case BOOTSOURCE_NAND:
environment_path = asprintf("/chosen/environment-nand");
+ envdev = "NAND flash";
break;
default:
case BOOTSOURCE_SPI:
environment_path = asprintf("/chosen/environment-spinor");
+ envdev = "SPI NOR flash";
break;
}
@@ -99,6 +126,8 @@ static int phytec_pfla02_init(void)
free(environment_path);
+ pr_notice("Using environment in %s\n", envdev);
+
return 0;
}
device_initcall(phytec_pfla02_init);
diff --git a/arch/arm/boards/zylonite/board.c b/arch/arm/boards/zylonite/board.c
index dabc6ffb0b..2caadbcecc 100644
--- a/arch/arm/boards/zylonite/board.c
+++ b/arch/arm/boards/zylonite/board.c
@@ -28,6 +28,7 @@
#include <net/smc91111.h>
#include <platform_data/mtd-nand-mrvl.h>
#include <pwm.h>
+#include <linux/sizes.h>
#include <mach/devices.h>
#include <mach/mfp-pxa3xx.h>
@@ -66,6 +67,8 @@ static int zylonite_devices_init(void)
&smsc91x_pdata);
add_generic_device("mrvl_nand", DEVICE_ID_DYNAMIC, NULL,
0x43100000, 0x1000, IORESOURCE_MEM, &nand_pdata);
+ devfs_add_partition("nand0", SZ_1M, SZ_256K, DEVFS_PARTITION_FIXED,
+ "env0");
return 0;
}
device_initcall(zylonite_devices_init);
diff --git a/arch/arm/boards/zylonite/env/bin/init b/arch/arm/boards/zylonite/env/bin/init
deleted file mode 100644
index a6bc087b22..0000000000
--- a/arch/arm/boards/zylonite/env/bin/init
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-PATH=/env/bin
-export PATH
-
-. /env/config
-addpart /dev/nand0 $mtdparts
-usbserial -s "Zylonite usb gadget"
-
-# Phase1: check for MTD override
-mtd_env_override
-if [ $? = 0 ]; then
- echo "Switching to custom environment"
- /env/init
- exit
-fi
-
-# Phase2: initiate network
-dhcp -H zylonite
-
-# Phase3: activate netconsole, broadcast everywhere
-netconsole.ip=255.255.255.255
-netconsole.active=ioe
-netconsole.port=6666
-
diff --git a/arch/arm/boards/zylonite/env/bin/mtd_env_override b/arch/arm/boards/zylonite/env/bin/mtd_env_override
deleted file mode 100644
index 6ea253a4f0..0000000000
--- a/arch/arm/boards/zylonite/env/bin/mtd_env_override
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-loadenv /dev/nand0.barebox-env
-exit $?
diff --git a/arch/arm/boards/zylonite/env/boot/nand-ubi b/arch/arm/boards/zylonite/env/boot/nand-ubi
new file mode 100644
index 0000000000..2231738224
--- /dev/null
+++ b/arch/arm/boards/zylonite/env/boot/nand-ubi
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+global.bootm.image="/dev/nand0.kernel"
+#global.bootm.oftree="/env/oftree"
+global.linux.bootargs.dyn.root="root=ubi0:linux_root ubi.mtd=nand.root rootfstype=ubifs"
diff --git a/arch/arm/boards/zylonite/env/config b/arch/arm/boards/zylonite/env/config
deleted file mode 100644
index ee66e37cc3..0000000000
--- a/arch/arm/boards/zylonite/env/config
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-autoboot_timeout=3
-
-mtdparts="128k@0(TIMH)ro,128k@128k(OBMI)ro,768k@256k(barebox),256k@1024k(barebox-env),12M@1280k(kernel),38016k@13568k(root)"
-bootargs="$bootargs mtdparts=pxa3xx_nand-0:$mtdparts ubi.mtd=5 rootfstype=ubifs root=ubi0:root ro ram=64M console=ttyS0,115200"
diff --git a/arch/arm/boards/zylonite/env/init/mtdparts-nand b/arch/arm/boards/zylonite/env/init/mtdparts-nand
new file mode 100644
index 0000000000..9db4652c40
--- /dev/null
+++ b/arch/arm/boards/zylonite/env/init/mtdparts-nand
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+if [ "$1" = menu ]; then
+ init-menu-add-entry "$0" "NAND partitions"
+ exit
+fi
+
+mtdparts="128k@0(TIMH)ro,128k@128k(OBMI)ro,768k@256k(barebox),256k@1024k(barebox-env),12M@1280k(kernel),38016k@13568k(root)"
+kernelname="pxa3xx_nand-0"
+
+mtdparts-add -d nand0 -k ${kernelname} -p ${mtdparts}
diff --git a/arch/arm/boards/zylonite/env/nv/hostname b/arch/arm/boards/zylonite/env/nv/hostname
new file mode 100644
index 0000000000..6e6d865eda
--- /dev/null
+++ b/arch/arm/boards/zylonite/env/nv/hostname
@@ -0,0 +1 @@
+zylonite
diff --git a/arch/arm/boards/zylonite/env/nv/linux.bootargs.base b/arch/arm/boards/zylonite/env/nv/linux.bootargs.base
new file mode 100644
index 0000000000..317f8b16a1
--- /dev/null
+++ b/arch/arm/boards/zylonite/env/nv/linux.bootargs.base
@@ -0,0 +1 @@
+ram=64M
diff --git a/arch/arm/boards/zylonite/env/nv/linux.bootargs.console b/arch/arm/boards/zylonite/env/nv/linux.bootargs.console
new file mode 100644
index 0000000000..476b1fbe49
--- /dev/null
+++ b/arch/arm/boards/zylonite/env/nv/linux.bootargs.console
@@ -0,0 +1 @@
+console=ttyS0,115200
diff --git a/arch/arm/configs/zylonite310_defconfig b/arch/arm/configs/zylonite310_defconfig
index fa6587c0ee..ffe3215354 100644
--- a/arch/arm/configs/zylonite310_defconfig
+++ b/arch/arm/configs/zylonite310_defconfig
@@ -8,17 +8,17 @@ CONFIG_ARM_UNWIND=y
# CONFIG_BANNER is not set
CONFIG_MMU=y
CONFIG_BAREBOX_MAX_BARE_INIT_SIZE=0x80000
-CONFIG_MALLOC_SIZE=0x1000000
+CONFIG_MALLOC_SIZE=0x800000
CONFIG_EXPERIMENTAL=y
CONFIG_MODULES=y
CONFIG_KALLSYMS=y
CONFIG_PROMPT="zylonite-barebox:"
-CONFIG_GLOB=y
CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
CONFIG_CONSOLE_ACTIVATE_ALL=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/zylonite/env"
CONFIG_RESET_SOURCE=y
CONFIG_DEFAULT_LOGLEVEL=8
@@ -27,8 +27,6 @@ CONFIG_CMD_DMESG=y
CONFIG_LONGHELP=y
CONFIG_CMD_IOMEM=y
CONFIG_CMD_MEMINFO=y
-CONFIG_FLEXIBLE_BOOTARGS=y
-CONFIG_CMD_BOOT=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_BOOTM_VERBOSE=y
CONFIG_CMD_BOOTM_INITRD=y
@@ -40,26 +38,20 @@ CONFIG_CMD_LOADY=y
CONFIG_CMD_RESET=y
CONFIG_CMD_SAVES=y
CONFIG_CMD_PARTITION=y
-CONFIG_CMD_AUTOMOUNT=y
CONFIG_CMD_UBIFORMAT=y
CONFIG_CMD_EXPORT=y
-CONFIG_CMD_GLOBAL=y
CONFIG_CMD_LOADENV=y
CONFIG_CMD_PRINTENV=y
CONFIG_CMD_SAVEENV=y
-CONFIG_CMD_BASENAME=y
CONFIG_CMD_CMP=y
-CONFIG_CMD_DIRNAME=y
CONFIG_CMD_FILETYPE=y
CONFIG_CMD_LN=y
-CONFIG_CMD_READLINK=y
CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_LET=y
CONFIG_CMD_MSLEEP=y
CONFIG_CMD_SLEEP=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_HOST=y
-CONFIG_NET_CMD_IFUP=y
CONFIG_CMD_MIITOOL=y
CONFIG_CMD_PING=y
CONFIG_CMD_TFTP=y
diff --git a/arch/arm/cpu/cache-l2x0.c b/arch/arm/cpu/cache-l2x0.c
index 2be562d7de..428dd93249 100644
--- a/arch/arm/cpu/cache-l2x0.c
+++ b/arch/arm/cpu/cache-l2x0.c
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) "l2x0: " fmt
+
#include <common.h>
#include <init.h>
#include <io.h>
@@ -7,6 +9,7 @@
#define CACHE_LINE_SIZE 32
static void __iomem *l2x0_base;
+static uint32_t l2x0_way_mask; /* Bitmask of active ways */
static inline void cache_wait(void __iomem *reg, unsigned long mask)
{
@@ -50,8 +53,8 @@ static inline void l2x0_flush_line(unsigned long addr)
static inline void l2x0_inv_all(void)
{
/* invalidate all ways */
- writel(0xff, l2x0_base + L2X0_INV_WAY);
- cache_wait(l2x0_base + L2X0_INV_WAY, 0xff);
+ writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+ cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
cache_sync();
}
@@ -112,6 +115,13 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
cache_sync();
}
+static void l2x0_flush_all(void)
+{
+ writel(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
+ cache_wait(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
+ cache_sync();
+}
+
static void l2x0_disable(void)
{
writel(0xff, l2x0_base + L2X0_CLEAN_INV_WAY);
@@ -122,9 +132,37 @@ static void l2x0_disable(void)
void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
{
__u32 aux;
+ __u32 cache_id;
+ int ways;
+ const char *type;
l2x0_base = base;
+ cache_id = readl(l2x0_base + L2X0_CACHE_ID);
+ aux = readl(l2x0_base + L2X0_AUX_CTRL);
+
+ /* Determine the number of ways */
+ switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+ case L2X0_CACHE_ID_PART_L310:
+ if (aux & (1 << 16))
+ ways = 16;
+ else
+ ways = 8;
+ type = "L310";
+ break;
+ case L2X0_CACHE_ID_PART_L210:
+ ways = (aux >> 13) & 0xf;
+ type = "L210";
+ break;
+ default:
+ /* Assume unknown chips have 8 ways */
+ ways = 8;
+ type = "L2x0 series";
+ break;
+ }
+
+ l2x0_way_mask = (1 << ways) - 1;
+
/*
* Check if l2x0 controller is already enabled.
* If you are booting from non-secure mode
@@ -149,5 +187,9 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
outer_cache.clean_range = l2x0_clean_range;
outer_cache.flush_range = l2x0_flush_range;
outer_cache.disable = l2x0_disable;
-}
+ outer_cache.flush_all = l2x0_flush_all;
+ pr_debug("%s cache controller enabled\n", type);
+ pr_debug("l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
+ ways, cache_id, aux);
+}
diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c
index 7b161d59d6..27ead1c177 100644
--- a/arch/arm/cpu/cache.c
+++ b/arch/arm/cpu/cache.c
@@ -71,6 +71,8 @@ void __mmu_cache_flush(void)
{
if (cache_fns)
cache_fns->mmu_cache_flush();
+ if (outer_cache.flush_all)
+ outer_cache.flush_all();
}
int arm_set_cache_functions(void)
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 5e708023e4..ff8f43d175 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -79,10 +79,9 @@ struct outer_cache_fns outer_cache;
*/
void mmu_disable(void)
{
+ __mmu_cache_flush();
if (outer_cache.disable)
outer_cache.disable();
-
- __mmu_cache_flush();
__mmu_cache_off();
}
diff --git a/arch/arm/cpu/exceptions.S b/arch/arm/cpu/exceptions.S
index f17f1e11e4..eda0d6ab8d 100644
--- a/arch/arm/cpu/exceptions.S
+++ b/arch/arm/cpu/exceptions.S
@@ -220,9 +220,9 @@ _fiq: .word fiq
.align 4
.global arm_ignore_data_abort
arm_ignore_data_abort:
-.word arm_ignore_data_abort /* When != 0 data aborts are ignored */
+.word 0 /* When != 0 data aborts are ignored */
.global arm_data_abort_occurred
arm_data_abort_occurred:
-.word arm_data_abort_occurred /* set != 0 by the data abort handler */
+.word 0 /* set != 0 by the data abort handler */
abort_stack:
.space 8
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 37bfa058a5..7b185d713b 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -66,6 +66,7 @@ static inline void tlb_invalidate(void)
}
#define PTE_FLAGS_CACHED_V7 (PTE_EXT_TEX(1) | PTE_BUFFERABLE | PTE_CACHEABLE)
+#define PTE_FLAGS_WC_V7 PTE_EXT_TEX(1)
#define PTE_FLAGS_UNCACHED_V7 (0)
#define PTE_FLAGS_CACHED_V4 (PTE_SMALL_AP_UNO_SRW | PTE_BUFFERABLE | PTE_CACHEABLE)
#define PTE_FLAGS_UNCACHED_V4 PTE_SMALL_AP_UNO_SRW
@@ -75,6 +76,7 @@ static inline void tlb_invalidate(void)
* This will be determined at runtime.
*/
static uint32_t pte_flags_cached;
+static uint32_t pte_flags_wc;
static uint32_t pte_flags_uncached;
#define PTE_MASK ((1 << 12) - 1)
@@ -159,9 +161,9 @@ static u32 *find_pte(unsigned long adr)
static void dma_flush_range(unsigned long start, unsigned long end)
{
+ __dma_flush_range(start, end);
if (outer_cache.flush_range)
outer_cache.flush_range(start, end);
- __dma_flush_range(start, end);
}
static void dma_inv_range(unsigned long start, unsigned long end)
@@ -325,9 +327,11 @@ static int mmu_init(void)
if (cpu_architecture() >= CPU_ARCH_ARMv7) {
pte_flags_cached = PTE_FLAGS_CACHED_V7;
+ pte_flags_wc = PTE_FLAGS_WC_V7;
pte_flags_uncached = PTE_FLAGS_UNCACHED_V7;
} else {
pte_flags_cached = PTE_FLAGS_CACHED_V4;
+ pte_flags_wc = PTE_FLAGS_UNCACHED_V4;
pte_flags_uncached = PTE_FLAGS_UNCACHED_V4;
}
@@ -408,6 +412,22 @@ void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
return ret;
}
+void *dma_alloc_writecombine(size_t size, dma_addr_t *dma_handle)
+{
+ void *ret;
+
+ size = PAGE_ALIGN(size);
+ ret = xmemalign(PAGE_SIZE, size);
+ if (dma_handle)
+ *dma_handle = (dma_addr_t)ret;
+
+ dma_inv_range((unsigned long)ret, (unsigned long)ret + size);
+
+ remap_range(ret, size, pte_flags_wc);
+
+ return ret;
+}
+
unsigned long virt_to_phys(volatile void *virt)
{
return (unsigned long)virt;
diff --git a/arch/arm/dts/imx27-phytec-phycore-rdk.dts b/arch/arm/dts/imx27-phytec-phycore-rdk.dts
index 9d216afa3a..f602045c7e 100644
--- a/arch/arm/dts/imx27-phytec-phycore-rdk.dts
+++ b/arch/arm/dts/imx27-phytec-phycore-rdk.dts
@@ -10,13 +10,13 @@
environment-nor {
compatible = "barebox,environment";
- device-path = &nor, "partname:env";
+ device-path = &environment_nor;
status = "disabled";
};
environment-nand {
compatible = "barebox,environment";
- device-path = &nfc, "partname:env";
+ device-path = &environment_nand;
status = "disabled";
};
};
@@ -32,7 +32,7 @@
reg = <0x00000000 0x00080000>;
};
- partition@1 {
+ environment_nand: partition@1 {
label = "env";
reg = <0x00080000 0x00020000>;
};
@@ -54,7 +54,7 @@
reg = <0x00000000 0x00080000>;
};
- partition@1 {
+ environment_nor: partition@1 {
label = "env";
reg = <0x00080000 0x00020000>;
};
diff --git a/arch/arm/dts/imx51-babbage.dts b/arch/arm/dts/imx51-babbage.dts
index 909774bd52..f8402ca8fa 100644
--- a/arch/arm/dts/imx51-babbage.dts
+++ b/arch/arm/dts/imx51-babbage.dts
@@ -18,7 +18,7 @@
environment@0 {
compatible = "barebox,environment";
- device-path = &esdhc1, "partname:barebox-environment";
+ device-path = &environment_esdhc1;
};
};
};
@@ -27,7 +27,7 @@
#address-cells = <1>;
#size-cells = <1>;
- partition@0 {
+ environment_esdhc1: partition@0 {
label = "barebox-environment";
reg = <0x80000 0x20000>;
};
diff --git a/arch/arm/dts/imx53-qsb-common.dtsi b/arch/arm/dts/imx53-qsb-common.dtsi
index 4007a092a8..bf634e49d4 100644
--- a/arch/arm/dts/imx53-qsb-common.dtsi
+++ b/arch/arm/dts/imx53-qsb-common.dtsi
@@ -16,7 +16,7 @@
environment@0 {
compatible = "barebox,environment";
- device-path = &esdhc1, "partname:barebox-environment";
+ device-path = &bareboxenv;
};
};
};
@@ -25,7 +25,7 @@
#address-cells = <1>;
#size-cells = <1>;
- partition@0 {
+ bareboxenv: partition@0 {
label = "barebox-environment";
reg = <0x80000 0x20000>;
};
diff --git a/arch/arm/dts/imx6dl-eltec-hipercam.dts b/arch/arm/dts/imx6dl-eltec-hipercam.dts
index 737752f0b1..166f8f1244 100644
--- a/arch/arm/dts/imx6dl-eltec-hipercam.dts
+++ b/arch/arm/dts/imx6dl-eltec-hipercam.dts
@@ -15,7 +15,7 @@
environment@0 {
compatible = "barebox,environment";
- device-path = &norflash0, "partname:bareboxenv";
+ device-path = &environment_nor0;
};
};
};
@@ -39,7 +39,7 @@
reg = <0x0 0xc0000>;
};
- partition@1 {
+ environment_nor0: partition@1 {
label = "bareboxenv";
reg = <0xc0000 0x8000>;
};
diff --git a/arch/arm/dts/imx6dl-phytec-pfla02.dtsi b/arch/arm/dts/imx6dl-phytec-pfla02.dtsi
index 0f801aebc9..47154d5d9f 100644
--- a/arch/arm/dts/imx6dl-phytec-pfla02.dtsi
+++ b/arch/arm/dts/imx6dl-phytec-pfla02.dtsi
@@ -16,7 +16,3 @@
model = "Phytec phyFLEX-i.MX6 Dual Lite";
compatible = "phytec,imx6dl-pfla02", "fsl,imx6dl";
};
-
-&ecspi3 {
- status = "okay";
-};
diff --git a/arch/arm/dts/imx6q-phytec-pbab01.dts b/arch/arm/dts/imx6q-phytec-pbab01.dts
index 580338dff8..2f816dd1ac 100644
--- a/arch/arm/dts/imx6q-phytec-pbab01.dts
+++ b/arch/arm/dts/imx6q-phytec-pbab01.dts
@@ -16,8 +16,4 @@
/ {
model = "Phytec phyFLEX-i.MX6 Quad Carrier-Board";
compatible = "phytec,imx6x-pbab01", "phytec,imx6q-pfla02", "fsl,imx6q";
-
- chosen {
- linux,stdout-path = &uart4;
- };
};
diff --git a/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi b/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi
index 6435ab791d..97cf78a73c 100644
--- a/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi
+++ b/arch/arm/dts/imx6q-phytec-pcaaxl3.dtsi
@@ -19,13 +19,13 @@
chosen {
environment-sd {
compatible = "barebox,environment";
- device-path = &usdhc3, "partname:barebox-environment";
+ device-path = &environment_usdhc3;
status = "disabled";
};
environment-nand {
compatible = "barebox,environment";
- device-path = &gpmi, "partname:barebox-environment";
+ device-path = &environment_nand;
status = "disabled";
};
};
@@ -139,7 +139,7 @@
reg = <0x0 0x400000>;
};
- partition@1 {
+ environment_nand: partition@1 {
label = "barebox-environment";
reg = <0x400000 0x20000>;
};
@@ -183,7 +183,7 @@
label = "barebox";
reg = <0x0 0x80000>;
};
- partition@1 {
+ environment_usdhc3: partition@1 {
label = "barebox-environment";
reg = <0x80000 0x80000>;
};
diff --git a/arch/arm/dts/imx6q-phytec-pfla02.dtsi b/arch/arm/dts/imx6q-phytec-pfla02.dtsi
index b1172dc095..48f1da3cad 100644
--- a/arch/arm/dts/imx6q-phytec-pfla02.dtsi
+++ b/arch/arm/dts/imx6q-phytec-pfla02.dtsi
@@ -17,7 +17,3 @@
model = "Phytec phyFLEX-i.MX6 Quad";
compatible = "phytec,imx6q-pfla02", "fsl,imx6q";
};
-
-&ecspi3 {
- status = "okay";
-};
diff --git a/arch/arm/dts/imx6q-sabresd.dts b/arch/arm/dts/imx6q-sabresd.dts
index 71ca855251..1f92c15242 100644
--- a/arch/arm/dts/imx6q-sabresd.dts
+++ b/arch/arm/dts/imx6q-sabresd.dts
@@ -25,7 +25,7 @@
environment@0 {
compatible = "barebox,environment";
- device-path = &usdhc3, "partname:barebox-environment";
+ device-path = &environment_usdhc3;
};
};
};
diff --git a/arch/arm/dts/imx6q-var-custom.dts b/arch/arm/dts/imx6q-var-custom.dts
index 795114d841..ef6981e3bc 100644
--- a/arch/arm/dts/imx6q-var-custom.dts
+++ b/arch/arm/dts/imx6q-var-custom.dts
@@ -30,7 +30,7 @@
environment@0 {
compatible = "barebox,environment";
- device-path = &gpmi, "partname:barebox-environment";
+ device-path = &environment_nand;
};
};
diff --git a/arch/arm/dts/imx6q-var-som.dtsi b/arch/arm/dts/imx6q-var-som.dtsi
index 792691191e..d005f319d6 100644
--- a/arch/arm/dts/imx6q-var-som.dtsi
+++ b/arch/arm/dts/imx6q-var-som.dtsi
@@ -42,7 +42,7 @@
reg = <0x0 0x200000>;
};
- partition@1 {
+ environment_nand: partition@1 {
label = "barebox-environment";
reg = <0x200000 0x20000>;
};
diff --git a/arch/arm/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/dts/imx6qdl-phytec-pbab01.dtsi
index 157e130ff1..86ab991c91 100644
--- a/arch/arm/dts/imx6qdl-phytec-pbab01.dtsi
+++ b/arch/arm/dts/imx6qdl-phytec-pbab01.dtsi
@@ -9,22 +9,8 @@
* http://www.gnu.org/copyleft/gpl.html
*/
-&fec {
- status = "okay";
-};
+#include <arm/imx6qdl-phytec-pbab01.dtsi>
&uart1 {
status = "okay";
};
-
-&uart4 {
- status = "okay";
-};
-
-&usdhc2 {
- status = "okay";
-};
-
-&usdhc3 {
- status = "okay";
-};
diff --git a/arch/arm/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/dts/imx6qdl-phytec-pfla02.dtsi
index 5ac0ef9431..b79ce2c0f9 100644
--- a/arch/arm/dts/imx6qdl-phytec-pfla02.dtsi
+++ b/arch/arm/dts/imx6qdl-phytec-pfla02.dtsi
@@ -9,7 +9,14 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#include <arm/imx6qdl-phytec-pfla02.dtsi>
+
/ {
+ memory {
+ /* let barebox fill the memory node */
+ reg = <0 0>;
+ };
+
chosen {
environment-nand {
compatible = "barebox,environment";
@@ -50,17 +57,7 @@
};
&ecspi3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ecspi3>;
- status = "disabled";
- fsl,spi-num-chipselects = <1>;
- cs-gpios = <&gpio4 24 0>;
-
- flash: m25p80@0 {
- compatible = "m25p80";
- spi-max-frequency = <20000000>;
- reg = <0>;
-
+ flash: flash@0 {
#address-cells = <1>;
#size-cells = <1>;
@@ -87,12 +84,7 @@
};
&fec {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_enet>;
phy-handle = <&ethphy>;
- phy-mode = "rgmii";
- phy-reset-gpios = <&gpio3 23 0>;
- status = "disabled";
mdio {
#address-cells = <1>;
@@ -108,10 +100,6 @@
};
&gpmi {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpmi_nand>;
- nand-on-flash-bbt;
- status = "okay";
#address-cells = <1>;
#size-cells = <1>;
@@ -143,44 +131,20 @@
&iomuxc {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_hog>;
-
- ecspi3 {
- pinctrl_ecspi3: ecspi3grp {
- fsl,pins = <
- MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
- MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
- MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
- MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 /* SPI NOR chipselect */
- >;
- };
- };
+ pinctrl-0 = <&pinctrl_hog>, <&pinctrl_rev>;
- enet {
- pinctrl_enet: enetgrp {
+ imx6q-phytec-pfla02 {
+ pinctrl_rev: revgrp {
fsl,pins = <
- MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
- MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
- MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
- MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
- MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
- MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
- MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
- MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
- MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
- MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
- MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
- MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
- MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
- MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
- MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
- MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x80000000
+ MX6QDL_PAD_SD4_DAT4__GPIO2_IO12 0x80000000
+ MX6QDL_PAD_SD4_DAT5__GPIO2_IO13 0x80000000
+ MX6QDL_PAD_SD4_DAT6__GPIO2_IO14 0x80000000
+ MX6QDL_PAD_SD4_DAT7__GPIO2_IO15 0x80000000
>;
};
- };
- gpmi-nand {
- pinctrl_gpmi_nand: gpmi-nand {
+ pinctrl_gpmi_nand: gpminandgrp {
fsl,pins = <
MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
@@ -204,79 +168,13 @@
>;
};
};
-
- hog {
- pinctrl_hog: hoggrp {
- fsl,pins = <
- MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x80000000
- MX6QDL_PAD_SD4_DAT3__GPIO2_IO11 0x80000000
- >;
- };
- };
-
- uart4 {
- pinctrl_uart4: uart4grp {
- fsl,pins = <
- MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
- MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
- >;
- };
- };
-
- usdhc2 {
- pinctrl_usdhc2: usdhc2grp {
- fsl,pins = <
- MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059
- MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059
- MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059
- MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059
- MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059
- MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059
- >;
- };
- };
-
- usdhc3 {
- pinctrl_usdhc3: usdhc3grp {
- fsl,pins = <
- MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
- MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
- MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
- MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
- MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
- MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
- MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x80000000
- MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000
- >;
- };
- };
};
&ocotp {
barebox,provide-mac-address = <&fec 0x620>;
};
-&uart4 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart4>;
- status = "disabled";
-};
-
-&usdhc2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc2>;
- cd-gpios = <&gpio1 4 0>;
- wp-gpios = <&gpio1 2 0>;
- status = "disabled";
-};
-
&usdhc3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc3>;
- cd-gpios = <&gpio1 27 0>;
- wp-gpios = <&gpio1 29 0>;
- status = "disabled";
-
#address-cells = <1>;
#size-cells = <1>;
@@ -284,6 +182,7 @@
label = "barebox";
reg = <0x0 0x80000>;
};
+
partition@1 {
label = "barebox-environment";
reg = <0x80000 0x80000>;
diff --git a/arch/arm/dts/imx6qdl-sabresd.dtsi b/arch/arm/dts/imx6qdl-sabresd.dtsi
index 54201bdb7e..32318cf389 100644
--- a/arch/arm/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/dts/imx6qdl-sabresd.dtsi
@@ -34,7 +34,7 @@
reg = <0x0 0x80000>;
};
- partition@1 {
+ environment_usdhc3: partition@1 {
label = "barebox-environment";
reg = <0x80000 0x80000>;
};
diff --git a/arch/arm/dts/imx6s-riotboard.dts b/arch/arm/dts/imx6s-riotboard.dts
index 117c00a575..a522dd9934 100644
--- a/arch/arm/dts/imx6s-riotboard.dts
+++ b/arch/arm/dts/imx6s-riotboard.dts
@@ -17,7 +17,7 @@
environment@0 {
compatible = "barebox,environment";
- device-path = &usdhc4, "partname:barebox-environment";
+ device-path = &environment_usdhc4;
};
};
@@ -232,7 +232,7 @@
reg = <0x0 0x80000>;
};
- partition@1 {
+ environment_usdhc4: partition@1 {
label = "barebox-environment";
reg = <0x80000 0x80000>;
};
diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
deleted file mode 100644
index b3c1efe739..0000000000
--- a/arch/arm/include/asm/gpio.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _ARCH_ARM_GPIO_H
-#define _ARCH_ARM_GPIO_H
-
-#ifndef CONFIG_GPIOLIB
-#include <mach/gpio.h>
-#else
-#include <asm-generic/gpio.h>
-#endif
-
-#endif /* _ARCH_ARM_GPIO_H */
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 97bb0dbeb6..3b19e9ef3c 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -67,6 +67,7 @@ struct outer_cache_fns {
void (*inv_range)(unsigned long, unsigned long);
void (*clean_range)(unsigned long, unsigned long);
void (*flush_range)(unsigned long, unsigned long);
+ void (*flush_all)(void);
void (*disable)(void);
};
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index 4e9d6865ab..bdc0cb6879 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -7,8 +7,6 @@
#ifndef __AT91_GPIO_H__
#define __AT91_GPIO_H__
-#include <asm-generic/gpio.h>
-
#define MAX_NB_GPIO_PER_BANK 32
static inline unsigned pin_to_bank(unsigned pin)
diff --git a/arch/arm/mach-ep93xx/include/mach/gpio.h b/arch/arm/mach-ep93xx/include/mach/gpio.h
deleted file mode 100644
index 306ab4c9f2..0000000000
--- a/arch/arm/mach-ep93xx/include/mach/gpio.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 0de2d3e153..f2dc52d518 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -175,15 +175,18 @@ config ARCH_IMX53
config ARCH_IMX6
bool
+ select ARCH_HAS_L2X0
select ARCH_HAS_FEC_IMX
select CPU_V7
select PINCTRL_IMX_IOMUX_V3
+ select OFTREE
select COMMON_CLK_OF_PROVIDER
select HW_HAS_PCI
config ARCH_IMX6SX
bool
select ARCH_IMX6
+ select OFTREE
select COMMON_CLK_OF_PROVIDER
config IMX_MULTI_BOARDS
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index 7508964bf5..ceabe19dc2 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -22,6 +22,7 @@
#include <mach/imx6-anadig.h>
#include <mach/imx6-regs.h>
#include <mach/generic.h>
+#include <asm/mmu.h>
#define SI_REV 0x260
@@ -193,3 +194,37 @@ int imx6_devices_init(void)
return 0;
}
+
+#define L310_PREFETCH_CTRL 0xF60
+
+static int imx6_mmu_init(void)
+{
+ void __iomem *l2x0_base = IOMEM(0x00a02000);
+ u32 val;
+
+ if (!cpu_is_mx6())
+ return 0;
+
+ /* Configure the L2 PREFETCH and POWER registers */
+ val = readl(l2x0_base + L310_PREFETCH_CTRL);
+ val |= 0x70800000;
+
+ /*
+ * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
+ * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
+ * But according to ARM PL310 errata: 752271
+ * ID: 752271: Double linefill feature can cause data corruption
+ * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
+ * Workaround: The only workaround to this erratum is to disable the
+ * double linefill feature. This is the default behavior.
+ */
+ if (cpu_is_mx6q())
+ val &= ~(1 << 30 | 1 << 23);
+
+ writel(val, l2x0_base + L310_PREFETCH_CTRL);
+
+ l2x0_init(l2x0_base, 0x0, ~0UL);
+
+ return 0;
+}
+postmmu_initcall(imx6_mmu_init);
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
deleted file mode 100644
index 8643c98d5a..0000000000
--- a/arch/arm/mach-mxs/include/mach/gpio.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - 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.
- *
- */
-
-#ifndef __ASM_MACH_GPIO_H
-#define __ASM_MACH_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-#endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
index 4e98493e73..7dd6ac0648 100644
--- a/arch/arm/mach-pxa/gpio.c
+++ b/arch/arm/mach-pxa/gpio.c
@@ -66,3 +66,35 @@ int __init pxa_init_gpio(int start, int end)
return 0;
}
+
+int gpio_get_value(unsigned gpio)
+{
+ return GPLR(gpio) & GPIO_bit(gpio);
+}
+
+void gpio_set_value(unsigned gpio, int value)
+{
+ if (value)
+ GPSR(gpio) = GPIO_bit(gpio);
+ else
+ GPCR(gpio) = GPIO_bit(gpio);
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+ if (__gpio_is_inverted(gpio))
+ GPDR(gpio) |= GPIO_bit(gpio);
+ else
+ GPDR(gpio) &= ~GPIO_bit(gpio);
+ return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ gpio_set_value(gpio, value);
+ if (__gpio_is_inverted(gpio))
+ GPDR(gpio) &= ~GPIO_bit(gpio);
+ else
+ GPDR(gpio) |= GPIO_bit(gpio);
+ return 0;
+}
diff --git a/arch/arm/mach-pxa/include/plat/gpio.h b/arch/arm/mach-pxa/include/plat/gpio.h
index 4c7b5266fb..35f90715e0 100644
--- a/arch/arm/mach-pxa/include/plat/gpio.h
+++ b/arch/arm/mach-pxa/include/plat/gpio.h
@@ -31,38 +31,6 @@
#define GFER_OFFSET 0x3C
#define GEDR_OFFSET 0x48
-static inline int gpio_get_value(unsigned gpio)
-{
- return GPLR(gpio) & GPIO_bit(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- if (value)
- GPSR(gpio) = GPIO_bit(gpio);
- else
- GPCR(gpio) = GPIO_bit(gpio);
-}
-
-static inline int gpio_direction_input(unsigned gpio)
-{
- if (__gpio_is_inverted(gpio))
- GPDR(gpio) |= GPIO_bit(gpio);
- else
- GPDR(gpio) &= ~GPIO_bit(gpio);
- return 0;
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
- gpio_set_value(gpio, value);
- if (__gpio_is_inverted(gpio))
- GPDR(gpio) &= ~GPIO_bit(gpio);
- else
- GPDR(gpio) |= GPIO_bit(gpio);
- return 0;
-}
-
/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
* Those cases currently cause holes in the GPIO number space, the
* actual number of the last GPIO is recorded by 'pxa_last_gpio'.
diff --git a/arch/arm/mach-samsung/gpio-s3c24x0.c b/arch/arm/mach-samsung/gpio-s3c24x0.c
index f62588f0e7..58ca284eab 100644
--- a/arch/arm/mach-samsung/gpio-s3c24x0.c
+++ b/arch/arm/mach-samsung/gpio-s3c24x0.c
@@ -15,7 +15,7 @@
#include <errno.h>
#include <io.h>
#include <mach/s3c-iomap.h>
-#include <mach/gpio.h>
+#include <gpio.h>
#include <mach/s3c24xx-gpio.h>
#include <mach/iomux.h>
diff --git a/arch/arm/mach-samsung/include/mach/gpio.h b/arch/arm/mach-samsung/include/mach/gpio.h
deleted file mode 100644
index 39206676f8..0000000000
--- a/arch/arm/mach-samsung/include/mach/gpio.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __ASM_MACH_GPIO_H
-#define __ASM_MACH_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-#endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/mips/include/asm/gpio.h b/arch/mips/include/asm/gpio.h
deleted file mode 100644
index 41a9589f84..0000000000
--- a/arch/mips/include/asm/gpio.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ARCH_MIPS_GPIO_H
-#define _ARCH_MIPS_GPIO_H
-
-#include <asm-generic/gpio.h>
-
-#endif /* _ARCH_MIPS_GPIO_H */
diff --git a/arch/ppc/boards/freescale-p1010rdb/p1010rdb.c b/arch/ppc/boards/freescale-p1010rdb/p1010rdb.c
index 5bae5849ca..60cae46d25 100644
--- a/arch/ppc/boards/freescale-p1010rdb/p1010rdb.c
+++ b/arch/ppc/boards/freescale-p1010rdb/p1010rdb.c
@@ -21,6 +21,7 @@
#include <net.h>
#include <types.h>
#include <i2c/i2c.h>
+#include <gpio.h>
#include <partition.h>
#include <memory.h>
#include <asm/cache.h>
@@ -32,7 +33,6 @@
#include <mach/immap_85xx.h>
#include <mach/gianfar.h>
#include <mach/clock.h>
-#include <mach/gpio.h>
#include <mach/early_udelay.h>
#include <of.h>
diff --git a/arch/ppc/boards/geip-da923rc/da923rc.c b/arch/ppc/boards/geip-da923rc/da923rc.c
index 3d77349e0d..b6b5d56acd 100644
--- a/arch/ppc/boards/geip-da923rc/da923rc.c
+++ b/arch/ppc/boards/geip-da923rc/da923rc.c
@@ -21,6 +21,7 @@
#include <driver.h>
#include <asm/io.h>
#include <net.h>
+#include <gpio.h>
#include <ns16550.h>
#include <partition.h>
#include <environment.h>
diff --git a/arch/ppc/mach-mpc85xx/include/mach/gpio.h b/arch/ppc/mach-mpc85xx/include/mach/gpio.h
index 61f634922e..b41ecc5214 100644
--- a/arch/ppc/mach-mpc85xx/include/mach/gpio.h
+++ b/arch/ppc/mach-mpc85xx/include/mach/gpio.h
@@ -10,8 +10,6 @@
#ifndef _MACH_PPC_GPIO_H
#define _MACH_PPC_GPIO_H
-#include <asm-generic/gpio.h>
-
extern void fsl_enable_gpiout(void);
#endif /* _MACH_PPC_GPIO_H */
diff --git a/commands/Kconfig b/commands/Kconfig
index 133dcbf22c..630cb12169 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -928,7 +928,7 @@ config CMD_LS
config CMD_MD5SUM
tristate
select COMPILE_HASH
- select MD5
+ select DIGEST_MD5_GENERIC
prompt "md5sum"
help
Usage: md5sum FILE|AREA...
@@ -993,7 +993,7 @@ config CMD_RMDIR
config CMD_SHA1SUM
tristate
select COMPILE_HASH
- select SHA1
+ select DIGEST_SHA1_GENERIC
prompt "sha1sum"
help
Calculate SHA1 digest
@@ -1005,7 +1005,7 @@ config CMD_SHA1SUM
config CMD_SHA224SUM
tristate
select COMPILE_HASH
- select SHA224
+ select DIGEST_SHA224_GENERIC
prompt "sha224sum"
help
Calculate SHA224 digest
@@ -1017,7 +1017,7 @@ config CMD_SHA224SUM
config CMD_SHA256SUM
tristate
select COMPILE_HASH
- select SHA256
+ select DIGEST_SHA256_GENERIC
prompt "sha256sum"
help
sha256sum - calculate SHA256 digest
@@ -1029,7 +1029,7 @@ config CMD_SHA256SUM
config CMD_SHA384SUM
tristate
select COMPILE_HASH
- select SHA384
+ select DIGEST_SHA384_GENERIC
prompt "sha384sum"
help
Calculate SHA384 digest
@@ -1041,7 +1041,7 @@ config CMD_SHA384SUM
config CMD_SHA512SUM
tristate
select COMPILE_HASH
- select SHA512
+ select DIGEST_SHA512_GENERIC
prompt "sha512sum"
help
sha512sum - calculate SHA512 digest
@@ -1458,6 +1458,7 @@ endif
config CMD_SPLASH
bool
select IMAGE_RENDERER
+ depends on VIDEO
prompt "splash"
help
Display a BMP image on a framebuffer device
diff --git a/commands/boot.c b/commands/boot.c
index 3341a05ebd..fd58824d98 100644
--- a/commands/boot.c
+++ b/commands/boot.c
@@ -14,6 +14,7 @@
#include <environment.h>
#include <globalvar.h>
#include <magicvar.h>
+#include <watchdog.h>
#include <command.h>
#include <readkey.h>
#include <common.h>
@@ -24,6 +25,7 @@
#include <clock.h>
#include <boot.h>
#include <glob.h>
+#include <init.h>
#include <menu.h>
#include <fs.h>
#include <complete.h>
@@ -71,10 +73,28 @@ out:
return ret;
}
+static unsigned int boot_watchdog_timeout;
+
+static int init_boot_watchdog_timeout(void)
+{
+ return globalvar_add_simple_int("boot.watchdog_timeout",
+ &boot_watchdog_timeout, "%u");
+}
+late_initcall(init_boot_watchdog_timeout);
+
+BAREBOX_MAGICVAR_NAMED(global_watchdog_timeout, global.boot.watchdog_timeout,
+ "Watchdog enable timeout in seconds before booting");
+
static int boot_entry(struct blspec_entry *be)
{
int ret;
+ if (IS_ENABLED(CONFIG_WATCHDOG) && boot_watchdog_timeout) {
+ ret = watchdog_set_timeout(boot_watchdog_timeout);
+ if (ret)
+ pr_warn("Failed to enable watchdog: %s\n", strerror(-ret));
+ }
+
if (be->scriptpath) {
ret = boot_script(be->scriptpath);
} else {
@@ -375,7 +395,7 @@ static int do_boot(int argc, char *argv[])
dryrun = 0;
timeout = -1;
- while ((opt = getopt(argc, argv, "vldmt:")) > 0) {
+ while ((opt = getopt(argc, argv, "vldmt:w:")) > 0) {
switch (opt) {
case 'v':
verbose++;
@@ -392,6 +412,9 @@ static int do_boot(int argc, char *argv[])
case 't':
timeout = simple_strtoul(optarg, NULL, 0);
break;
+ case 'w':
+ boot_watchdog_timeout = simple_strtoul(optarg, NULL, 0);
+ break;
}
}
@@ -477,6 +500,7 @@ BAREBOX_CMD_HELP_OPT ("-v","Increase verbosity")
BAREBOX_CMD_HELP_OPT ("-d","Dryrun. See what happens but do no actually boot")
BAREBOX_CMD_HELP_OPT ("-l","List available boot sources")
BAREBOX_CMD_HELP_OPT ("-m","Show a menu with boot options")
+BAREBOX_CMD_HELP_OPT ("-w SECS","Start watchdog with timeout SECS before booting")
BAREBOX_CMD_HELP_OPT ("-t SECS","specify timeout in SECS")
BAREBOX_CMD_HELP_END
diff --git a/commands/login.c b/commands/login.c
index bf5085c854..58bb592900 100644
--- a/commands/login.c
+++ b/commands/login.c
@@ -19,89 +19,23 @@
#include <command.h>
#include <complete.h>
#include <password.h>
-#include <getopt.h>
-#include <environment.h>
-#include <globalvar.h>
-#include <magicvar.h>
-#include <init.h>
-#include <console.h>
-
-#define PASSWD_MAX_LENGTH (128 + 1)
-
-#if defined(CONFIG_PASSWD_MODE_STAR)
-#define LOGIN_MODE STAR
-#elif defined(CONFIG_PASSWD_MODE_CLEAR)
-#define LOGIN_MODE CLEAR
-#else
-#define LOGIN_MODE HIDE
-#endif
-
-static int login_timeout = 0;
static int do_login(int argc, char *argv[])
{
- unsigned char passwd[PASSWD_MAX_LENGTH];
- int passwd_len, opt;
- int timeout = login_timeout;
- char *timeout_cmd = "boot";
-
- console_allow_input(true);
- if (!is_passwd_enable()) {
- puts("login: password not set\n");
- return 0;
- }
-
- while((opt = getopt(argc, argv, "t:")) > 0) {
- switch(opt) {
- case 't':
- timeout = simple_strtoul(optarg, NULL, 10);
- break;
- }
- }
-
- if (optind != argc)
- timeout_cmd = argv[optind];
-
- do {
- puts("Password: ");
- passwd_len = password(passwd, PASSWD_MAX_LENGTH, LOGIN_MODE, timeout);
-
- if (passwd_len < 0) {
- console_allow_input(false);
- run_command(timeout_cmd);
- }
-
- if (check_passwd(passwd, passwd_len) == 1)
- return 0;
- } while(1);
+ login();
return 0;
}
BAREBOX_CMD_HELP_START(login)
BAREBOX_CMD_HELP_TEXT("Asks for a password from the console before script execution continues.")
-BAREBOX_CMD_HELP_TEXT("The password can be set with the 'passwd' command. Instead of specifying")
-BAREBOX_CMD_HELP_TEXT("a TIMEOUT the magic variable 'global.login.timeout' could be set.")
-BAREBOX_CMD_HELP_TEXT("")
-BAREBOX_CMD_HELP_TEXT("Options:")
-BAREBOX_CMD_HELP_OPT("-t TIMEOUT", "Execute COMMAND if no login withing TIMEOUT seconds")
+BAREBOX_CMD_HELP_TEXT("The password can be set with the 'passwd' command.")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(login)
.cmd = do_login,
BAREBOX_CMD_DESC("ask for a password")
- BAREBOX_CMD_OPTS("[-t TIMEOUT] COMMAND")
BAREBOX_CMD_GROUP(CMD_GRP_CONSOLE)
BAREBOX_CMD_HELP(cmd_login_help)
BAREBOX_CMD_COMPLETE(empty_complete)
BAREBOX_CMD_END
-
-static int login_global_init(void)
-{
- globalvar_add_simple_int("login.timeout", &login_timeout, "%d");
-
- return 0;
-}
-late_initcall(login_global_init);
-
-BAREBOX_MAGICVAR_NAMED(global_login_timeout, global.login.timeout, "timeout to type the password");
diff --git a/commands/menutree.c b/commands/menutree.c
index 5d30b67ee5..ea5f65f3a1 100644
--- a/commands/menutree.c
+++ b/commands/menutree.c
@@ -12,12 +12,15 @@
#include <common.h>
#include <getopt.h>
#include <menu.h>
+#include <password.h>
static int do_menutree(int argc, char *argv[])
{
int opt, ret;
char *path = "/env/menu";
+ login();
+
while ((opt = getopt(argc, argv, "m:")) > 0) {
switch (opt) {
case 'm':
diff --git a/commands/splash.c b/commands/splash.c
index 90f0a0cdf2..15b296b680 100644
--- a/commands/splash.c
+++ b/commands/splash.c
@@ -15,9 +15,9 @@ static int do_splash(int argc, char *argv[])
int opt;
char *fbdev = "/dev/fb0";
char *image_file;
- int offscreen = 0;
u32 bg_color = 0x00000000;
bool do_bg = false;
+ void *buf;
memset(&s, 0, sizeof(s));
@@ -41,8 +41,6 @@ static int do_splash(int argc, char *argv[])
case 'y':
s.y = simple_strtoul(optarg, NULL, 0);
break;
- case 'o':
- offscreen = 1;
}
}
@@ -52,21 +50,17 @@ static int do_splash(int argc, char *argv[])
}
image_file = argv[optind];
- sc = fb_open(fbdev, offscreen);
+ sc = fb_open(fbdev);
if (IS_ERR(sc)) {
perror("fd_open");
return PTR_ERR(sc);
}
- if (sc->offscreenbuf) {
- if (do_bg)
- gu_memset_pixel(sc->info, sc->offscreenbuf, bg_color,
- sc->s.width * sc->s.height);
- else
- memcpy(sc->offscreenbuf, sc->fb, sc->fbsize);
- } else if (do_bg) {
- gu_memset_pixel(sc->info, sc->fb, bg_color, sc->s.width * sc->s.height);
- }
+ buf = gui_screen_render_buffer(sc);
+
+ if (do_bg)
+ gu_memset_pixel(sc->info, buf, bg_color,
+ sc->s.width * sc->s.height);
ret = image_renderer_file(sc, &s, image_file);
if (ret > 0)
@@ -89,7 +83,6 @@ BAREBOX_CMD_HELP_OPT ("-f FB\t", "framebuffer device (default /dev/fb0)")
BAREBOX_CMD_HELP_OPT ("-x XOFFS", "x offset (default center)")
BAREBOX_CMD_HELP_OPT ("-y YOFFS", "y offset (default center)")
BAREBOX_CMD_HELP_OPT ("-b COLOR", "background color in 0xttrrggbb")
-BAREBOX_CMD_HELP_OPT ("-o\t", "render offscreen")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(splash)
diff --git a/commands/ubiformat.c b/commands/ubiformat.c
index e63f16e351..f9d952cff0 100644
--- a/commands/ubiformat.c
+++ b/commands/ubiformat.c
@@ -779,6 +779,7 @@ BAREBOX_CMD_HELP_OPT("-f FILE\t", "flash image file")
BAREBOX_CMD_HELP_OPT("-e VALUE", "use VALUE as erase counter value for all eraseblocks")
BAREBOX_CMD_HELP_OPT("-x NUM\t", "UBI version number to put to EC headers (default 1)")
BAREBOX_CMD_HELP_OPT("-Q NUM\t", "32-bit UBI image sequence number to use")
+BAREBOX_CMD_HELP_OPT("-y\t", "Assume yes for all questions")
BAREBOX_CMD_HELP_OPT("-q\t", "suppress progress percentage information")
BAREBOX_CMD_HELP_OPT("-v\t", "be verbose")
BAREBOX_CMD_HELP_TEXT("")
diff --git a/common/Kconfig b/common/Kconfig
index 8c6ba7fd42..877d3855a2 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -450,8 +450,14 @@ config PASSWORD
config PASSWORD_DEFAULT
string
- prompt "Password default"
+ prompt "Password default file"
depends on PASSWORD
+ help
+ Set this to a file which is used as default password file. This file
+ has to contain the passwd encoded with the selected password digest.
+ i.e.:
+ echo -ne "MyPassword" | md5sum | while read a b; do echo $a > passwdfile; done
+
if PASSWORD
@@ -460,19 +466,19 @@ choice
config PASSWD_SUM_MD5
bool "MD5"
- select MD5
+ select DIGEST_MD5_GENERIC
config PASSWD_SUM_SHA1
bool "SHA1"
- select SHA1
+ select DIGEST_SHA1_GENERIC
config PASSWD_SUM_SHA256
bool "SHA256"
- select SHA256
+ select DIGEST_SHA256_GENERIC
config PASSWD_SUM_SHA512
bool "SHA512"
- select SHA512
+ select DIGEST_SHA512_GENERIC
config PASSWD_CRYPTO_PBKDF2
bool "PBKDF2"
diff --git a/common/console.c b/common/console.c
index bf64c08b7c..84d4ea714d 100644
--- a/common/console.c
+++ b/common/console.c
@@ -344,9 +344,6 @@ int getc(void)
unsigned char ch;
uint64_t start;
- if (unlikely(!console_is_input_allow()))
- return -EPERM;
-
/*
* For 100us we read the characters from the serial driver
* into a kfifo. This helps us not to lose characters
@@ -381,9 +378,6 @@ EXPORT_SYMBOL(fgetc);
int tstc(void)
{
- if (unlikely(!console_is_input_allow()))
- return 0;
-
return kfifo_len(console_input_fifo) || tstc_raw();
}
EXPORT_SYMBOL(tstc);
diff --git a/common/console_common.c b/common/console_common.c
index 2c82c6fd46..fcf89e8568 100644
--- a/common/console_common.c
+++ b/common/console_common.c
@@ -33,33 +33,6 @@
#ifndef CONFIG_CONSOLE_NONE
-static int console_input_allow;
-
-static int console_global_init(void)
-{
- if (IS_ENABLED(CONFIG_CMD_LOGIN) && is_passwd_enable())
- console_input_allow = 0;
- else
- console_input_allow = 1;
-
- globalvar_add_simple_bool("console.input_allow", &console_input_allow);
-
- return 0;
-}
-late_initcall(console_global_init);
-
-BAREBOX_MAGICVAR_NAMED(global_console_input_allow, global.console.input_allow, "console input allowed");
-
-bool console_is_input_allow(void)
-{
- return console_input_allow;
-}
-
-void console_allow_input(bool val)
-{
- console_input_allow = val;
-}
-
int barebox_loglevel = CONFIG_DEFAULT_LOGLEVEL;
LIST_HEAD(barebox_logbuf);
diff --git a/common/console_simple.c b/common/console_simple.c
index 6cb72bb46a..69e76593ad 100644
--- a/common/console_simple.c
+++ b/common/console_simple.c
@@ -41,9 +41,6 @@ EXPORT_SYMBOL(console_putc);
int tstc(void)
{
- if (unlikely(!console_is_input_allow()))
- return 0;
-
if (!console)
return 0;
@@ -53,9 +50,6 @@ EXPORT_SYMBOL(tstc);
int getc(void)
{
- if (unlikely(!console_is_input_allow()))
- return -EPERM;
-
if (!console)
return -EINVAL;
return console->getc(console);
diff --git a/common/hush.c b/common/hush.c
index ffd251339e..abe87137b5 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -116,6 +116,7 @@
#include <errno.h>
#include <fs.h>
#include <libbb.h>
+#include <password.h>
#include <glob.h>
#include <getopt.h>
#include <libfile.h>
@@ -1914,6 +1915,8 @@ int run_shell(void)
struct p_context ctx;
int exit = 0;
+ login();
+
do {
setup_file_in_str(&input);
rcode = parse_stream_outer(&ctx, &input, FLAG_PARSE_SEMICOLON);
diff --git a/common/parser.c b/common/parser.c
index 207599f429..ed414d04ea 100644
--- a/common/parser.c
+++ b/common/parser.c
@@ -1,5 +1,6 @@
#include <common.h>
#include <command.h>
+#include <password.h>
#include <environment.h>
#include <shell.h>
@@ -266,6 +267,8 @@ int run_shell(void)
int len;
int rc = 1;
+ login();
+
for (;;) {
len = readline (CONFIG_PROMPT, console_buffer, CONFIG_CBSIZE);
diff --git a/common/password.c b/common/password.c
index c8454228d0..43c5e0cc0e 100644
--- a/common/password.c
+++ b/common/password.c
@@ -24,8 +24,11 @@
#include <digest.h>
#include <malloc.h>
#include <xfuncs.h>
+#include <magicvar.h>
#include <clock.h>
+#include <init.h>
#include <stdlib.h>
+#include <globalvar.h>
#include <generated/passwd.h>
#include <crypto/pbkdf2.h>
@@ -73,7 +76,7 @@ int password(unsigned char *passwd, size_t length, int flags, int timeout)
case CTL_CH('c'):
passwd[0] = '\0';
puts("\r\n");
- return 0;
+ return -EINTR;
case CTL_CH('h'):
case BB_KEY_DEL7:
case BB_KEY_DEL:
@@ -104,7 +107,7 @@ int password(unsigned char *passwd, size_t length, int flags, int timeout)
}
} while (!is_timeout(start, timeout * SECOND) || timeout == 0);
- return -1;
+ return -ETIMEDOUT;
}
EXPORT_SYMBOL(password);
@@ -155,17 +158,7 @@ static unsigned char to_hexa(unsigned char c)
return c;
}
-int read_passwd(unsigned char *sum, size_t length)
-{
- if (is_passwd_env_enable())
- return read_env_passwd(sum, length);
- else if (is_passwd_default_enable())
- return read_default_passwd(sum, length);
- else
- return -EINVAL;
-}
-
-int read_default_passwd(unsigned char *sum, size_t length)
+static int read_default_passwd(unsigned char *sum, size_t length)
{
int i = 0;
int len = strlen(default_passwd);
@@ -192,7 +185,7 @@ int read_default_passwd(unsigned char *sum, size_t length)
}
EXPORT_SYMBOL(read_default_passwd);
-int read_env_passwd(unsigned char *sum, size_t length)
+static int read_env_passwd(unsigned char *sum, size_t length)
{
int fd;
int ret = 0;
@@ -283,7 +276,7 @@ exit:
}
EXPORT_SYMBOL(write_env_passwd);
-static int __check_passwd(unsigned char* passwd, size_t length, int std)
+static int check_passwd(unsigned char *passwd, size_t length)
{
struct digest *d = NULL;
unsigned char *passwd1_sum;
@@ -295,6 +288,10 @@ static int __check_passwd(unsigned char* passwd, size_t length, int std)
hash_len = PBKDF2_LENGTH;
} else {
d = digest_alloc(PASSWD_SUM);
+ if (!d) {
+ pr_err("No such digest: %s\n", PASSWD_SUM);
+ return -ENOENT;
+ }
hash_len = digest_length(d);
}
@@ -305,10 +302,12 @@ static int __check_passwd(unsigned char* passwd, size_t length, int std)
passwd2_sum = passwd1_sum + hash_len;
- if (std)
+ if (is_passwd_env_enable())
ret = read_env_passwd(passwd2_sum, hash_len);
- else
+ else if (is_passwd_default_enable())
ret = read_default_passwd(passwd2_sum, hash_len);
+ else
+ ret = -EINVAL;
if (ret < 0)
goto err;
@@ -342,28 +341,6 @@ err:
return ret;
}
-int check_default_passwd(unsigned char* passwd, size_t length)
-{
- return __check_passwd(passwd, length, 0);
-}
-EXPORT_SYMBOL(check_default_passwd);
-
-int check_env_passwd(unsigned char* passwd, size_t length)
-{
- return __check_passwd(passwd, length, 1);
-}
-EXPORT_SYMBOL(check_env_passwd);
-
-int check_passwd(unsigned char* passwd, size_t length)
-{
- if (is_passwd_env_enable())
- return check_env_passwd(passwd, length);
- else if (is_passwd_default_enable())
- return check_default_passwd(passwd, length);
- else
- return -EINVAL;
-}
-
int set_env_passwd(unsigned char* passwd, size_t length)
{
struct digest *d = NULL;
@@ -374,6 +351,8 @@ int set_env_passwd(unsigned char* passwd, size_t length)
hash_len = PBKDF2_LENGTH;
} else {
d = digest_alloc(PASSWD_SUM);
+ if (!d)
+ return -EINVAL;
hash_len = digest_length(d);
}
@@ -406,3 +385,69 @@ err:
return ret;
}
EXPORT_SYMBOL(set_env_passwd);
+
+#define PASSWD_MAX_LENGTH (128 + 1)
+
+#if defined(CONFIG_PASSWD_MODE_STAR)
+#define LOGIN_MODE STAR
+#elif defined(CONFIG_PASSWD_MODE_CLEAR)
+#define LOGIN_MODE CLEAR
+#else
+#define LOGIN_MODE HIDE
+#endif
+
+static int logged_in;
+static int login_timeout = 60;
+static char *login_fail_command;
+
+/**
+ * login() - Prompt for password
+ *
+ * This function only returns when the correct password has been entered or
+ * no password is necessary because either no password is configured or the
+ * correct password has been entered in a previous call to this function.
+ */
+void login(void)
+{
+ unsigned char passwd[PASSWD_MAX_LENGTH];
+ int ret;
+
+ if (!is_passwd_default_enable() && !is_passwd_env_enable())
+ return;
+
+ if (logged_in)
+ return;
+
+ while (1) {
+ printf("Password: ");
+
+ ret = password(passwd, PASSWD_MAX_LENGTH, LOGIN_MODE, login_timeout);
+ if (ret < 0)
+ run_command(login_fail_command);
+
+ if (ret < 0)
+ continue;
+
+ if (check_passwd(passwd, ret) != 1)
+ continue;
+
+ logged_in = 1;
+ return;
+ }
+}
+
+static int login_global_init(void)
+{
+ login_fail_command = xstrdup("boot");
+
+ globalvar_add_simple_int("login.timeout", &login_timeout, "%d");
+ globalvar_add_simple_string("login.fail_command", &login_fail_command);
+
+ return 0;
+}
+late_initcall(login_global_init);
+
+BAREBOX_MAGICVAR_NAMED(global_login_fail_command, global.login.fail_command,
+ "command to run when password entry failed");
+BAREBOX_MAGICVAR_NAMED(global_login_timeout, global.login.timeout,
+ "timeout to type the password");
diff --git a/common/startup.c b/common/startup.c
index 802b90e0e8..4a303b297a 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -108,13 +108,10 @@ void __noreturn start_barebox(void)
if (IS_ENABLED(CONFIG_COMMAND_SUPPORT)) {
pr_info("running /env/bin/init...\n");
- if (!stat("/env/bin/init", &s)) {
+ if (!stat("/env/bin/init", &s))
run_command("source /env/bin/init");
- } else {
+ else
pr_err("/env/bin/init not found\n");
- if (IS_ENABLED(CONFIG_CMD_LOGIN))
- while(run_command("login -t 0"));
- }
}
if (!barebox_main) {
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 24f8b410ed..ef807dec68 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -82,5 +82,5 @@ endif
config CRYPTO_PBKDF2
select DIGEST
- select SHA1
+ select DIGEST_SHA1_GENERIC
bool
diff --git a/defaultenv/defaultenv-2-base/bin/init b/defaultenv/defaultenv-2-base/bin/init
index 30651e55d2..37ee3651ba 100644
--- a/defaultenv/defaultenv-2-base/bin/init
+++ b/defaultenv/defaultenv-2-base/bin/init
@@ -27,25 +27,15 @@ magicvar -a global.allow_color "Allow color on the console (boolean)"
[ -e /env/config-board ] && /env/config-board
/env/config
-# request password to login if a timeout is specified and password set
-if [ -n ${global.login.timeout} ]; then
- [ ${global.login.timeout} -gt 0 ] && login_cmd=login
-fi
-# allow the input if not
-[ -n ${global.console.input_allow} ] && global.console.input_allow=1
-
# allow to stop the boot before execute the /env/init/*
# but without waiting
timeout -s -a -v key 0
autoboot="$?"
if [ "${key}" = "q" ]; then
- ${login_cmd}
exit
fi
-[ -n ${login_cmd} ] && global.console.input_allow=0
-
for i in /env/init/*; do
. $i
done
@@ -56,17 +46,12 @@ else
echo -e -n "\nHit any key to stop autoboot: "
fi
-[ -n ${login_cmd} ] && global.console.input_allow=1
-
if [ "$autoboot" = 0 ]; then
timeout -a $global.autoboot_timeout -v key
autoboot="$?"
fi
-[ -n ${login_cmd} ] && global.console.input_allow=0
-
if [ "${key}" = "q" ]; then
- ${login_cmd}
exit
fi
@@ -75,12 +60,9 @@ if [ "$autoboot" = 0 ]; then
fi
if [ -e /env/menu ]; then
- ${login_cmd}
if [ "${key}" != "m" ]; then
echo -e "\ntype exit to get to the menu"
sh
fi
/env/menu/mainmenu
fi
-
-${login_cmd}
diff --git a/drivers/eeprom/at24.c b/drivers/eeprom/at24.c
index bb2dd533b6..76f30e7e22 100644
--- a/drivers/eeprom/at24.c
+++ b/drivers/eeprom/at24.c
@@ -21,6 +21,8 @@
#include <linux/log2.h>
#include <i2c/i2c.h>
#include <i2c/at24.h>
+#include <gpio.h>
+#include <of_gpio.h>
/*
* I2C EEPROMs from most vendors are inexpensive and mostly interchangeable.
@@ -55,6 +57,8 @@ struct at24_data {
u8 *writebuf;
unsigned write_max;
unsigned num_addresses;
+ int wp_gpio;
+ int wp_active_low;
/*
* Some chips tie up multiple I2C addresses; dummy devices reserve
@@ -345,6 +349,25 @@ static ssize_t at24_cdev_write(struct cdev *cdev, const void *buf, size_t count,
return at24_write(at24, buf, off, count);
}
+static ssize_t at24_cdev_protect(struct cdev *cdev, size_t count, loff_t offset,
+ int prot)
+{
+ struct at24_data *at24 = cdev->priv;
+
+ if (!gpio_is_valid(at24->wp_gpio))
+ return -EOPNOTSUPP;
+
+ prot = !!prot;
+ if (at24->wp_active_low)
+ prot = !prot;
+
+ gpio_set_value(at24->wp_gpio, prot);
+
+ udelay(50);
+
+ return 0;
+}
+
static int at24_probe(struct device_d *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -403,6 +426,7 @@ static int at24_probe(struct device_d *dev)
at24->cdev.ops = &at24->fops;
at24->fops.lseek = dev_lseek_default;
at24->fops.read = at24_cdev_read,
+ at24->fops.protect = at24_cdev_protect,
at24->cdev.size = chip.byte_len;
writable = !(chip.flags & AT24_FLAG_READONLY);
@@ -419,6 +443,19 @@ static int at24_probe(struct device_d *dev)
at24->writebuf = xmalloc(write_max + 2);
}
+ at24->wp_gpio = -1;
+ if (dev->device_node) {
+ enum of_gpio_flags flags;
+ at24->wp_gpio = of_get_named_gpio_flags(dev->device_node,
+ "wp-gpios", 0, &flags);
+ if (gpio_is_valid(at24->wp_gpio)) {
+ at24->wp_active_low = flags & OF_GPIO_ACTIVE_LOW;
+ gpio_request(at24->wp_gpio, "eeprom-wp");
+ gpio_direction_output(at24->wp_gpio,
+ !at24->wp_active_low);
+ }
+ }
+
at24->client[0] = client;
/* use dummy devices for multiple-address chips */
@@ -440,6 +477,7 @@ static int at24_probe(struct device_d *dev)
return 0;
err_clients:
+ gpio_free(at24->wp_gpio);
kfree(at24->writebuf);
kfree(at24);
err_out:
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index dc43eb83a4..2563c0d25a 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -106,9 +106,10 @@ static int sclhi(struct i2c_algo_bit_data *adap)
}
}
#ifdef DEBUG
- if (jiffies != start && i2c_debug >= 3)
- pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go "
- "high\n", jiffies - start);
+ if ((get_time_ns() - start) < 10000)
+ pr_debug("i2c-algo-bit: needed %u usecs for SCL to go "
+ "high\n", (unsigned int)(get_time_ns() - start) /
+ 1000);
#endif
done:
@@ -116,6 +117,31 @@ done:
return 0;
}
+static int wait_busy(struct i2c_algo_bit_data *adap)
+{
+ uint64_t start;
+
+ if (sclhi(adap) < 0)
+ return -ETIMEDOUT;
+
+ start = get_time_ns();
+ while (!getsda(adap)) {
+ if (is_timeout(start, adap->timeout_ms * MSECOND)) {
+ if (getsda(adap))
+ break;
+ return -ETIMEDOUT;
+ }
+ }
+#ifdef DEBUG
+ if ((get_time_ns() - start) < 10000)
+ pr_debug("i2c-algo-bit: needed %u usecs for SDA to go "
+ "high\n", (unsigned int)(get_time_ns() - start) /
+ 1000);
+#endif
+
+ udelay(adap->udelay);
+ return 0;
+}
/* --- other auxiliary functions -------------------------------------- */
static void i2c_start(struct i2c_algo_bit_data *adap)
@@ -426,10 +452,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
count--;
bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n",
- inval,
- (flags & I2C_M_NO_RD_ACK)
- ? "(no ack/nak)"
- : (count ? "A" : "NA"));
+ inval, count ? "A" : "NA");
inval = acknak(i2c_adap, count);
if (inval < 0)
@@ -514,6 +537,13 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
return ret;
}
+ if (wait_busy(adap) < 0) { /* timeout */
+ dev_warn(&i2c_adap->dev, "timeout waiting for bus ready\n");
+ ret = i2c_recover_bus(i2c_adap);
+ if (ret < 0)
+ return ret;
+ }
+
bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
i2c_start(adap);
for (i = 0; i < num; i++) {
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index b4a0ecdb20..9362ed181f 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <driver.h>
+#include <malloc.h>
#include <i2c/i2c.h>
#include <i2c/i2c-algo-bit.h>
#include <i2c/i2c-gpio.h>
@@ -187,6 +188,13 @@ static int i2c_gpio_probe(struct device_d *dev)
adap->algo_data = bit_data;
adap->dev.parent = dev;
adap->dev.device_node = dev->device_node;
+ adap->bus_recovery_info = xzalloc(sizeof(*adap->bus_recovery_info));
+ adap->bus_recovery_info->scl_gpio = pdata->scl_pin;
+ adap->bus_recovery_info->sda_gpio = pdata->sda_pin;
+ adap->bus_recovery_info->get_sda = i2c_get_sda_gpio_value;
+ adap->bus_recovery_info->get_scl = i2c_get_scl_gpio_value;
+ adap->bus_recovery_info->set_scl = i2c_set_scl_gpio_value;
+ adap->bus_recovery_info->recover_bus = i2c_generic_scl_recovery;
adap->nr = dev->id;
ret = i2c_bit_add_numbered_bus(adap);
@@ -201,10 +209,12 @@ static int i2c_gpio_probe(struct device_d *dev)
return 0;
err_add_bus:
+ free(adap->bus_recovery_info);
gpio_free(pdata->scl_pin);
err_request_scl:
gpio_free(pdata->sda_pin);
err_request_sda:
+ free(priv);
return ret;
}
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 714e83c4b9..4cd03e18a8 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -539,8 +539,10 @@ static int __init i2c_fsl_probe(struct device_d *pdev)
#ifdef CONFIG_COMMON_CLK
i2c_fsl->clk = clk_get(pdev, NULL);
- if (IS_ERR(i2c_fsl->clk))
- return PTR_ERR(i2c_fsl->clk);
+ if (IS_ERR(i2c_fsl->clk)) {
+ ret = PTR_ERR(i2c_fsl->clk);
+ goto fail;
+ }
#endif
/* Setup i2c_fsl driver structure */
i2c_fsl->adapter.master_xfer = i2c_fsl_xfer;
@@ -548,8 +550,10 @@ static int __init i2c_fsl_probe(struct device_d *pdev)
i2c_fsl->adapter.dev.parent = pdev;
i2c_fsl->adapter.dev.device_node = pdev->device_node;
i2c_fsl->base = dev_request_mem_region(pdev, 0);
- if (IS_ERR(i2c_fsl->base))
- return PTR_ERR(i2c_fsl->base);
+ if (IS_ERR(i2c_fsl->base)) {
+ ret = PTR_ERR(i2c_fsl->base);
+ goto fail;
+ }
i2c_fsl->dfsrr = -1;
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 330db98982..48c55daeda 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -107,16 +107,20 @@
#define OMAP_I2C_SCLH_HSSCLH 8
/* I2C System Test Register (OMAP_I2C_SYSTEST): */
-#ifdef DEBUG
#define OMAP_I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */
#define OMAP_I2C_SYSTEST_FREE (1 << 14) /* Free running mode */
#define OMAP_I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */
#define OMAP_I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */
+/* Functional mode */
+#define OMAP_I2C_SYSTEST_SCL_I_FUNC (1 << 8) /* SCL line input value */
+#define OMAP_I2C_SYSTEST_SCL_O_FUNC (1 << 7) /* SCL line output value */
+#define OMAP_I2C_SYSTEST_SDA_I_FUNC (1 << 6) /* SDA line input value */
+#define OMAP_I2C_SYSTEST_SDA_O_FUNC (1 << 5) /* SDA line output value */
+/* SDA/SCL IO mode */
#define OMAP_I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense in */
#define OMAP_I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive out */
#define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
#define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
-#endif
/* OCP_SYSSTATUS bit definitions */
#define SYSS_RESETDONE_MASK (1 << 0)
@@ -492,7 +496,7 @@ static int omap_i2c_wait_for_bb(struct i2c_adapter *adapter)
while (omap_i2c_read_reg(i2c_omap, OMAP_I2C_STAT_REG) & OMAP_I2C_STAT_BB) {
if (is_timeout(start, MSECOND)) {
dev_warn(&adapter->dev, "timeout waiting for bus ready\n");
- return -ETIMEDOUT;
+ return i2c_recover_bus(adapter);
}
}
@@ -673,6 +677,10 @@ omap_i2c_isr(struct omap_i2c_struct *dev)
/*
* ProDB0017052: Clear ARDY bit twice
*/
+ if (stat & OMAP_I2C_STAT_ARDY)
+ omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ARDY);
+
+
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
@@ -986,6 +994,79 @@ out:
#define OMAP_I2C_SCHEME_0 0
#define OMAP_I2C_SCHEME_1 1
+static int omap_i2c_get_scl(struct i2c_adapter *adapter)
+{
+ struct omap_i2c_struct *i2c_omap = to_omap_i2c_struct(adapter);
+ u32 reg;
+
+ reg = omap_i2c_read_reg(i2c_omap, OMAP_I2C_SYSTEST_REG);
+
+ return reg & OMAP_I2C_SYSTEST_SCL_I_FUNC;
+}
+
+static int omap_i2c_get_sda(struct i2c_adapter *adapter)
+{
+ struct omap_i2c_struct *i2c_omap = to_omap_i2c_struct(adapter);
+ u32 reg;
+
+ reg = omap_i2c_read_reg(i2c_omap, OMAP_I2C_SYSTEST_REG);
+
+ return reg & OMAP_I2C_SYSTEST_SDA_I_FUNC;
+}
+
+static void omap_i2c_set_scl(struct i2c_adapter *adapter, int val)
+{
+ struct omap_i2c_struct *i2c_omap = to_omap_i2c_struct(adapter);
+ u32 reg;
+
+ reg = omap_i2c_read_reg(i2c_omap, OMAP_I2C_SYSTEST_REG);
+ if (val)
+ reg |= OMAP_I2C_SYSTEST_SCL_O;
+ else
+ reg &= ~OMAP_I2C_SYSTEST_SCL_O;
+ omap_i2c_write_reg(i2c_omap, OMAP_I2C_SYSTEST_REG, reg);
+}
+
+static void omap_i2c_prepare_recovery(struct i2c_adapter *adapter)
+{
+ struct omap_i2c_struct *i2c_omap = to_omap_i2c_struct(adapter);
+ u32 reg;
+
+ reg = omap_i2c_read_reg(i2c_omap, OMAP_I2C_SYSTEST_REG);
+ /* enable test mode */
+ reg |= OMAP_I2C_SYSTEST_ST_EN;
+ /* select SDA/SCL IO mode */
+ reg |= 3 << OMAP_I2C_SYSTEST_TMODE_SHIFT;
+ /* set SCL to high-impedance state (reset value is 0) */
+ reg |= OMAP_I2C_SYSTEST_SCL_O;
+ /* set SDA to high-impedance state (reset value is 0) */
+ reg |= OMAP_I2C_SYSTEST_SDA_O;
+ omap_i2c_write_reg(i2c_omap, OMAP_I2C_SYSTEST_REG, reg);
+}
+
+static void omap_i2c_unprepare_recovery(struct i2c_adapter *adapter)
+{
+ struct omap_i2c_struct *i2c_omap = to_omap_i2c_struct(adapter);
+ u32 reg;
+
+ reg = omap_i2c_read_reg(i2c_omap, OMAP_I2C_SYSTEST_REG);
+ /* restore reset values */
+ reg &= ~OMAP_I2C_SYSTEST_ST_EN;
+ reg &= ~OMAP_I2C_SYSTEST_TMODE_MASK;
+ reg &= ~OMAP_I2C_SYSTEST_SCL_O;
+ reg &= ~OMAP_I2C_SYSTEST_SDA_O;
+ omap_i2c_write_reg(i2c_omap, OMAP_I2C_SYSTEST_REG, reg);
+}
+
+static struct i2c_bus_recovery_info omap_i2c_bus_recovery_info = {
+ .get_scl = omap_i2c_get_scl,
+ .get_sda = omap_i2c_get_sda,
+ .set_scl = omap_i2c_set_scl,
+ .prepare_recovery = omap_i2c_prepare_recovery,
+ .unprepare_recovery = omap_i2c_unprepare_recovery,
+ .recover_bus = i2c_generic_scl_recovery,
+};
+
static int __init
i2c_omap_probe(struct device_d *pdev)
{
@@ -1097,6 +1178,7 @@ i2c_omap_probe(struct device_d *pdev)
i2c_omap->adapter.nr = pdev->id;
i2c_omap->adapter.dev.parent = pdev;
i2c_omap->adapter.dev.device_node = pdev->device_node;
+ i2c_omap->adapter.bus_recovery_info = &omap_i2c_bus_recovery_info;
/* i2c device drivers may be active on return from add_adapter() */
r = i2c_add_numbered_adapter(&i2c_omap->adapter);
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index f0df666b97..52aaea8170 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -23,6 +23,7 @@
#include <xfuncs.h>
#include <init.h>
#include <of.h>
+#include <gpio.h>
#include <i2c/i2c.h>
@@ -228,6 +229,135 @@ int i2c_write_reg(struct i2c_client *client, u32 addr, const u8 *buf, u16 count)
}
EXPORT_SYMBOL(i2c_write_reg);
+/* i2c bus recovery routines */
+int i2c_get_scl_gpio_value(struct i2c_adapter *adap)
+{
+ gpio_direction_input(adap->bus_recovery_info->scl_gpio);
+ return gpio_get_value(adap->bus_recovery_info->scl_gpio);
+}
+
+void i2c_set_scl_gpio_value(struct i2c_adapter *adap, int val)
+{
+ if (val)
+ gpio_direction_input(adap->bus_recovery_info->scl_gpio);
+ else
+ gpio_direction_output(adap->bus_recovery_info->scl_gpio, 0);
+}
+
+int i2c_get_sda_gpio_value(struct i2c_adapter *adap)
+{
+ return gpio_get_value(adap->bus_recovery_info->sda_gpio);
+}
+
+static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap)
+{
+ struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
+ struct device_d *dev = &adap->dev;
+ int ret = 0;
+
+ ret = gpio_request_one(bri->scl_gpio, GPIOF_IN, "i2c-scl");
+ if (ret) {
+ dev_warn(dev, "Can't get SCL gpio: %d\n", bri->scl_gpio);
+ return ret;
+ }
+
+ if (bri->get_sda) {
+ if (gpio_request_one(bri->sda_gpio, GPIOF_IN, "i2c-sda")) {
+ /* work without SDA polling */
+ dev_warn(dev, "Can't get SDA gpio: %d. Not using SDA polling\n",
+ bri->sda_gpio);
+ bri->get_sda = NULL;
+ }
+ }
+
+ return ret;
+}
+
+static void i2c_put_gpios_for_recovery(struct i2c_adapter *adap)
+{
+ struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
+
+ if (bri->get_sda)
+ gpio_free(bri->sda_gpio);
+
+ gpio_free(bri->scl_gpio);
+}
+
+/*
+ * We are generating clock pulses. ndelay() determines durating of clk pulses.
+ * We will generate clock with rate 100 KHz and so duration of both clock levels
+ * is: delay in ns = (10^6 / 100) / 2
+ */
+#define RECOVERY_NDELAY 5000
+#define RECOVERY_CLK_CNT 9
+
+static int i2c_generic_recovery(struct i2c_adapter *adap)
+{
+ struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
+ int i = 0, val = 1, ret = 0;
+
+ if (bri->prepare_recovery)
+ bri->prepare_recovery(adap);
+
+ bri->set_scl(adap, val);
+ ndelay(RECOVERY_NDELAY);
+
+ /*
+ * By this time SCL is high, as we need to give 9 falling-rising edges
+ */
+ while (i++ < RECOVERY_CLK_CNT * 2) {
+ if (val) {
+ /* Break if SDA is high */
+ if (bri->get_sda && bri->get_sda(adap))
+ break;
+ /* SCL shouldn't be low here */
+ if (!bri->get_scl(adap)) {
+ dev_err(&adap->dev,
+ "SCL is stuck low, exit recovery\n");
+ ret = -EBUSY;
+ break;
+ }
+ }
+
+ val = !val;
+ bri->set_scl(adap, val);
+ ndelay(RECOVERY_NDELAY);
+ }
+
+ if (bri->unprepare_recovery)
+ bri->unprepare_recovery(adap);
+
+ return ret;
+}
+
+int i2c_generic_scl_recovery(struct i2c_adapter *adap)
+{
+ return i2c_generic_recovery(adap);
+}
+
+int i2c_generic_gpio_recovery(struct i2c_adapter *adap)
+{
+ int ret;
+
+ ret = i2c_get_gpios_for_recovery(adap);
+ if (ret)
+ return ret;
+
+ ret = i2c_generic_recovery(adap);
+ i2c_put_gpios_for_recovery(adap);
+
+ return ret;
+}
+
+int i2c_recover_bus(struct i2c_adapter *adap)
+{
+ if (!adap->bus_recovery_info)
+ return -EOPNOTSUPP;
+
+ dev_dbg(&adap->dev, "Trying i2c bus recovery\n");
+ return adap->bus_recovery_info->recover_bus(adap);
+}
+
/**
* i2c_new_device - instantiate one new I2C device
*
diff --git a/drivers/mci/mmci.c b/drivers/mci/mmci.c
index 608cac1932..9d1e858917 100644
--- a/drivers/mci/mmci.c
+++ b/drivers/mci/mmci.c
@@ -269,18 +269,18 @@ static int read_bytes(struct mci_host *mci, char *dest, unsigned int blkcount, u
xfercount -= len;
dest += len;
status = mmci_readl(host, MMCISTATUS);
- status_err = status & (MCI_CMDCRCFAIL | MCI_DATATIMEOUT |
- MCI_RXOVERRUN);
+ status_err = status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT |
+ MCI_RXOVERRUN);
} while(xfercount && !status_err);
status_err = status &
- (MCI_CMDCRCFAIL | MCI_DATATIMEOUT | MCI_DATABLOCKEND |
+ (MCI_DATACRCFAIL | MCI_DATATIMEOUT | MCI_DATABLOCKEND |
MCI_RXOVERRUN);
while (!status_err) {
status = mmci_readl(host, MMCISTATUS);
status_err = status &
- (MCI_CMDCRCFAIL | MCI_DATATIMEOUT | MCI_DATABLOCKEND |
+ (MCI_DATACRCFAIL | MCI_DATATIMEOUT | MCI_DATABLOCKEND |
MCI_RXOVERRUN);
}
@@ -288,7 +288,7 @@ static int read_bytes(struct mci_host *mci, char *dest, unsigned int blkcount, u
dev_err(host->hw_dev, "Read data timed out, xfercount: %u, status: 0x%08X\n",
xfercount, status);
return -ETIMEDOUT;
- } else if (status & MCI_CMDCRCFAIL) {
+ } else if (status & MCI_DATACRCFAIL) {
dev_err(host->hw_dev, "Read data bytes CRC error: 0x%x\n", status);
return -EILSEQ;
} else if (status & MCI_RXOVERRUN) {
@@ -351,7 +351,7 @@ static int write_bytes(struct mci_host *mci, char *dest, unsigned int blkcount,
dev_dbg(host->hw_dev, "write_bytes: blkcount=%u blksize=%u\n", blkcount, blksize);
status = mmci_readl(host, MMCISTATUS);
- status_err = status & (MCI_CMDCRCFAIL | MCI_DATATIMEOUT);
+ status_err = status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT);
do {
len = mmci_pio_write(host, dest, xfercount, status);
@@ -359,11 +359,11 @@ static int write_bytes(struct mci_host *mci, char *dest, unsigned int blkcount,
dest += len;
status = mmci_readl(host, MMCISTATUS);
- status_err = status & (MCI_CMDCRCFAIL | MCI_DATATIMEOUT);
+ status_err = status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT);
} while (!status_err && xfercount);
status_err = status &
- (MCI_CMDCRCFAIL | MCI_DATATIMEOUT | MCI_DATABLOCKEND);
+ (MCI_DATACRCFAIL | MCI_DATATIMEOUT | MCI_DATABLOCKEND);
while (!status_err) {
status = mmci_readl(host, MMCISTATUS);
status_err = status &
@@ -374,7 +374,7 @@ static int write_bytes(struct mci_host *mci, char *dest, unsigned int blkcount,
dev_err(host->hw_dev, "Write data timed out, xfercount:%u,status:0x%08X\n",
xfercount, status);
return -ETIMEDOUT;
- } else if (status & MCI_CMDCRCFAIL) {
+ } else if (status & MCI_DATACRCFAIL) {
dev_err(host->hw_dev, "Write data CRC error\n");
return -EILSEQ;
}
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 794c9dbd82..d627690080 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -235,6 +235,7 @@ static int m25p_probe(struct device_d *dev)
enum read_mode mode = SPI_NOR_NORMAL;
const char *flash_name = NULL;
int device_id;
+ bool use_large_blocks;
int ret;
data = dev->platform_data;
@@ -272,7 +273,10 @@ static int m25p_probe(struct device_d *dev)
else
flash_name = NULL; /* auto-detect */
- ret = spi_nor_scan(nor, flash_name, mode);
+ use_large_blocks = of_property_read_bool(dev->device_node,
+ "use-large-blocks");
+
+ ret = spi_nor_scan(nor, flash_name, mode, use_large_blocks);
if (ret)
return ret;
diff --git a/drivers/mtd/nand/nand_mrvl_nfc.c b/drivers/mtd/nand/nand_mrvl_nfc.c
index 258ff75953..1ec48cc09e 100644
--- a/drivers/mtd/nand/nand_mrvl_nfc.c
+++ b/drivers/mtd/nand/nand_mrvl_nfc.c
@@ -881,8 +881,9 @@ static int mrvl_nand_scan(struct mtd_info *mtd)
* We'll use a bad block table stored in-flash and don't
* allow writing the bad block marker to the flash.
*/
- chip->bbt_options |= NAND_BBT_USE_FLASH |
- NAND_BBT_NO_OOB_BBM;
+ chip->bbt_options |=
+ NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB_BBM |
+ NAND_BBT_CREATE_EMPTY;
chip->bbt_td = &bbt_main_descr;
chip->bbt_md = &bbt_mirror_descr;
}
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c
index dce29ca0ea..ff7bb7a5d8 100644
--- a/drivers/mtd/spi-nor/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/cadence-quadspi.c
@@ -1078,7 +1078,7 @@ static int cqspi_setup_flash(struct device_d *dev,
nor->write = cqspi_write;
nor->erase = cqspi_erase;
- ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD);
+ ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD, false);
if (ret)
goto probe_failed;
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c85ed34e06..b357e5adb4 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -370,85 +370,27 @@ erase_err:
static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
- struct spi_nor *nor = mtd_to_spi_nor(mtd);
- uint32_t offset = ofs;
- uint8_t status_old, status_new;
- int ret = 0;
-
- ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK);
- if (ret)
- return ret;
-
- status_old = read_sr(nor);
-
- if (offset < mtd->size - (mtd->size / 2))
- status_new = status_old | SR_BP2 | SR_BP1 | SR_BP0;
- else if (offset < mtd->size - (mtd->size / 4))
- status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1;
- else if (offset < mtd->size - (mtd->size / 8))
- status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0;
- else if (offset < mtd->size - (mtd->size / 16))
- status_new = (status_old & ~(SR_BP0 | SR_BP1)) | SR_BP2;
- else if (offset < mtd->size - (mtd->size / 32))
- status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0;
- else if (offset < mtd->size - (mtd->size / 64))
- status_new = (status_old & ~(SR_BP2 | SR_BP0)) | SR_BP1;
- else
- status_new = (status_old & ~(SR_BP2 | SR_BP1)) | SR_BP0;
-
- /* Only modify protection if it will not unlock other areas */
- if ((status_new & (SR_BP2 | SR_BP1 | SR_BP0)) >
- (status_old & (SR_BP2 | SR_BP1 | SR_BP0))) {
- write_enable(nor);
- ret = write_sr(nor, status_new);
- if (ret)
- goto err;
- }
-
-err:
- spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
- return ret;
+ return 0;
}
static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
struct spi_nor *nor = mtd_to_spi_nor(mtd);
- uint32_t offset = ofs;
- uint8_t status_old, status_new;
- int ret = 0;
+ uint8_t status;
+ int ret;
ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK);
if (ret)
return ret;
- status_old = read_sr(nor);
-
- if (offset+len > mtd->size - (mtd->size / 64))
- status_new = status_old & ~(SR_BP2 | SR_BP1 | SR_BP0);
- else if (offset+len > mtd->size - (mtd->size / 32))
- status_new = (status_old & ~(SR_BP2 | SR_BP1)) | SR_BP0;
- else if (offset+len > mtd->size - (mtd->size / 16))
- status_new = (status_old & ~(SR_BP2 | SR_BP0)) | SR_BP1;
- else if (offset+len > mtd->size - (mtd->size / 8))
- status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0;
- else if (offset+len > mtd->size - (mtd->size / 4))
- status_new = (status_old & ~(SR_BP0 | SR_BP1)) | SR_BP2;
- else if (offset+len > mtd->size - (mtd->size / 2))
- status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0;
- else
- status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1;
+ status = read_sr(nor);
+ status &= ~(SR_BP2 | SR_BP1 | SR_BP0);
+ write_enable(nor);
- /* Only modify protection if it will not lock other areas */
- if ((status_new & (SR_BP2 | SR_BP1 | SR_BP0)) <
- (status_old & (SR_BP2 | SR_BP1 | SR_BP0))) {
- write_enable(nor);
- ret = write_sr(nor, status_new);
- if (ret)
- goto err;
- }
+ ret = write_sr(nor, status);
-err:
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
+
return ret;
}
@@ -523,6 +465,7 @@ static const struct spi_device_id spi_nor_ids[] = {
{ "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
{ "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) },
{ "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
+ { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, 0) },
/* ESMT */
{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) },
@@ -537,6 +480,7 @@ static const struct spi_device_id spi_nor_ids[] = {
/* GigaDevice */
{ "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) },
{ "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
+ { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SECT_4K) },
/* Intel/Numonyx -- xxxs33b */
{ "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
@@ -551,6 +495,7 @@ static const struct spi_device_id spi_nor_ids[] = {
{ "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) },
{ "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) },
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) },
+ { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
@@ -559,14 +504,14 @@ static const struct spi_device_id spi_nor_ids[] = {
{ "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
/* Micron */
- { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, 0) },
- { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
- { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
- { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
+ { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) },
+ { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SPI_NOR_QUAD_READ) },
+ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
+ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
- { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
- { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, USE_FSR) },
- { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, USE_FSR | SPI_NOR_QUAD_READ) },
+ { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+ { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
/* PMC */
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
@@ -646,6 +591,7 @@ static const struct spi_device_id spi_nor_ids[] = {
{ "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) },
/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
+ { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) },
{ "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) },
{ "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) },
{ "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) },
@@ -656,6 +602,7 @@ static const struct spi_device_id spi_nor_ids[] = {
{ "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, SECT_4K) },
{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+ { "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, SECT_4K) },
{ "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
@@ -923,7 +870,8 @@ static int spi_nor_check(struct spi_nor *nor)
return 0;
}
-int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode,
+ bool use_large_blocks)
{
const struct spi_device_id *id = NULL;
struct flash_info *info;
@@ -1012,10 +960,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
/* prefer "small sector" erase if possible */
- if (info->flags & SECT_4K) {
+ if (info->flags & SECT_4K && !use_large_blocks) {
nor->erase_opcode = SPINOR_OP_BE_4K;
mtd->erasesize = 4096;
- } else if (info->flags & SECT_4K_PMC) {
+ } else if (info->flags & SECT_4K_PMC && !use_large_blocks) {
nor->erase_opcode = SPINOR_OP_BE_4K_PMC;
mtd->erasesize = 4096;
} else
diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c
index 2dc784851d..992972c9b5 100644
--- a/drivers/of/of_path.c
+++ b/drivers/of/of_path.c
@@ -117,7 +117,8 @@ out:
* @flags: use OF_FIND_PATH_FLAGS_BB to return the .bb device if available
*
* paths in the devicetree have the form of a multistring property. The first
- * string contains the full path to the physical device containing the path.
+ * string contains the full path to the physical device containing the path or
+ * a full path to a partition described by the OF partition binding.
* The remaining strings have the form "<type>:<options>". Currently supported
* for <type> are:
*
@@ -129,6 +130,7 @@ out:
*
* device-path = &mmc0, "partname:0";
* device-path = &norflash, "partname:barebox-environment";
+ * device-path = &environment_nor;
*/
int of_find_path(struct device_node *node, const char *propname, char **outpath, unsigned flags)
{
@@ -147,13 +149,15 @@ int of_find_path(struct device_node *node, const char *propname, char **outpath,
return -ENODEV;
op.dev = of_find_device_by_node_path(rnode->full_name);
- if (!op.dev)
- return -ENODEV;
+ if (!op.dev) {
+ op.dev = of_find_device_by_node_path(rnode->parent->full_name);
+ if (!op.dev)
+ return -ENODEV;
+ }
device_detect(op.dev);
- if (list_is_singular(&op.dev->cdevs))
- op.cdev = list_first_entry(&op.dev->cdevs, struct cdev, devices_list);
+ op.cdev = cdev_by_device_node(rnode);
i = 1;
diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index 3dce84404f..6017897b02 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -64,8 +64,8 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node)
if (IS_ERR(new))
new = NULL;
- if (new && new->dev)
- new->dev->device_node = node;
+ if (new)
+ new->device_node = node;;
free(filename);
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 6805d22a75..80dfc7819a 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -39,11 +39,18 @@ struct imx_spi {
struct clk *clk;
unsigned int (*xchg_single)(struct imx_spi *imx, u32 data);
+ void (*do_transfer)(struct spi_device *spi);
void (*chipselect)(struct spi_device *spi, int active);
+
+ const void *tx_buf;
+ void *rx_buf;
+ int xfer_len;
+ int bits_per_word;
};
struct spi_imx_devtype_data {
unsigned int (*xchg_single)(struct imx_spi *imx, u32 data);
+ void (*do_transfer)(struct spi_device *spi);
void (*chipselect)(struct spi_device *spi, int active);
void (*init)(struct imx_spi *imx);
};
@@ -230,14 +237,8 @@ static unsigned int cspi_2_3_xchg_single(struct imx_spi *imx, unsigned int data)
{
void __iomem *base = imx->regs;
- unsigned int cfg_reg = readl(base + CSPI_2_3_CTRL);
-
writel(data, base + CSPI_2_3_TXDATA);
- cfg_reg |= CSPI_2_3_CTRL_XCH;
-
- writel(cfg_reg, base + CSPI_2_3_CTRL);
-
while (!(readl(base + CSPI_2_3_STAT) & CSPI_2_3_STAT_RR));
return readl(base + CSPI_2_3_RXDATA);
@@ -306,6 +307,8 @@ static void cspi_2_3_chipselect(struct spi_device *spi, int is_active)
ctrl |= (spi->bits_per_word - 1) << CSPI_2_3_CTRL_BL_OFFSET;
+ ctrl |= CSPI_2_3_CTRL_SMC;
+
cfg |= CSPI_2_3_CONFIG_SBBCTRL(cs);
if (spi->mode & SPI_CPHA)
@@ -336,38 +339,39 @@ static u32 imx_xchg_single(struct spi_device *spi, u32 tx_val)
return imx_spi_maybe_reverse_bits(spi, rx_val);
}
-static void imx_spi_do_transfer(struct spi_device *spi, struct spi_transfer *t)
+static void imx_spi_do_transfer(struct spi_device *spi)
{
+ struct imx_spi *imx = container_of(spi->master, struct imx_spi, master);
unsigned i;
- if (spi->bits_per_word <= 8) {
- const u8 *tx_buf = t->tx_buf;
- u8 *rx_buf = t->rx_buf;
+ if (imx->bits_per_word <= 8) {
+ const u8 *tx_buf = imx->tx_buf;
+ u8 *rx_buf = imx->rx_buf;
u8 rx_val;
- for (i = 0; i < t->len; i++) {
+ for (i = 0; i < imx->xfer_len; i++) {
rx_val = imx_xchg_single(spi, tx_buf ? tx_buf[i] : 0);
if (rx_buf)
rx_buf[i] = rx_val;
}
- } else if (spi->bits_per_word <= 16) {
- const u16 *tx_buf = t->tx_buf;
- u16 *rx_buf = t->rx_buf;
+ } else if (imx->bits_per_word <= 16) {
+ const u16 *tx_buf = imx->tx_buf;
+ u16 *rx_buf = imx->rx_buf;
u16 rx_val;
- for (i = 0; i < t->len >> 1; i++) {
+ for (i = 0; i < imx->xfer_len >> 1; i++) {
rx_val = imx_xchg_single(spi, tx_buf ? tx_buf[i] : 0);
if (rx_buf)
rx_buf[i] = rx_val;
}
- } else if (spi->bits_per_word <= 32) {
- const u32 *tx_buf = t->tx_buf;
- u32 *rx_buf = t->rx_buf;
+ } else if (imx->bits_per_word <= 32) {
+ const u32 *tx_buf = imx->tx_buf;
+ u32 *rx_buf = imx->rx_buf;
u32 rx_val;
- for (i = 0; i < t->len >> 2; i++) {
+ for (i = 0; i < imx->xfer_len >> 2; i++) {
rx_val = imx_xchg_single(spi, tx_buf ? tx_buf[i] : 0);
if (rx_buf)
@@ -376,6 +380,77 @@ static void imx_spi_do_transfer(struct spi_device *spi, struct spi_transfer *t)
}
}
+static int cspi_2_3_xchg_burst(struct spi_device *spi)
+{
+ struct imx_spi *imx = container_of(spi->master, struct imx_spi, master);
+ int now, txlen, rxlen;
+ u32 ctrl;
+ void __iomem *base = imx->regs;
+
+ now = min(imx->xfer_len, 512);
+ now >>= 2;
+
+ if (!now)
+ return 0;
+
+ txlen = rxlen = now;
+
+ ctrl = readl(base + CSPI_2_3_CTRL);
+ ctrl &= ~(0xfff << CSPI_2_3_CTRL_BL_OFFSET);
+ ctrl |= ((txlen * 32) - 1) << CSPI_2_3_CTRL_BL_OFFSET;
+ ctrl |= 1 << 3;
+ writel(ctrl, base + CSPI_2_3_CTRL);
+
+ while (txlen || rxlen) {
+ u32 status = readl(base + CSPI_2_3_STAT);
+
+ if (txlen && !(status & CSPI_2_3_STAT_TF)) {
+ if (imx->tx_buf) {
+ u32 data = swab32(*(u32 *)imx->tx_buf);
+ writel(data, base + CSPI_2_3_TXDATA);
+ imx->tx_buf += sizeof(u32);
+ } else {
+ writel(0, base + CSPI_2_3_TXDATA);
+ }
+ txlen--;
+ }
+
+ if (rxlen && (status & CSPI_2_3_STAT_RR)) {
+ u32 data = readl(base + CSPI_2_3_RXDATA);
+
+ if (imx->rx_buf) {
+ *(u32 *)imx->rx_buf = swab32(data);
+ imx->rx_buf += sizeof(u32);
+ }
+
+ rxlen--;
+ }
+ }
+
+ imx->xfer_len -= now * 4;
+
+ return now;
+}
+
+static void cspi_2_3_do_transfer(struct spi_device *spi)
+{
+ struct imx_spi *imx = container_of(spi->master, struct imx_spi, master);
+ u32 ctrl;
+
+ if (imx->bits_per_word == 8 || imx->bits_per_word == 16 || imx->bits_per_word == 32)
+ while (cspi_2_3_xchg_burst(spi) > 0);
+
+ if (!imx->xfer_len)
+ return;
+
+ ctrl = readl(imx->regs + CSPI_2_3_CTRL);
+ ctrl &= ~(0xfff << CSPI_2_3_CTRL_BL_OFFSET);
+ ctrl |= (spi->bits_per_word - 1) << CSPI_2_3_CTRL_BL_OFFSET;
+ writel(ctrl, imx->regs + CSPI_2_3_CTRL);
+
+ imx_spi_do_transfer(spi);
+}
+
static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
{
struct imx_spi *imx = container_of(spi->master, struct imx_spi, master);
@@ -399,7 +474,12 @@ static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
cs_change = t->cs_change;
- imx_spi_do_transfer(spi, t);
+ imx->tx_buf = t->tx_buf;
+ imx->rx_buf = t->rx_buf;
+ imx->xfer_len = t->len;
+ imx->bits_per_word = spi->bits_per_word;
+ imx->do_transfer(spi);
+
mesg->actual_length += t->len;
if (cs_change)
@@ -415,17 +495,20 @@ static int imx_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
static __maybe_unused struct spi_imx_devtype_data spi_imx_devtype_data_0_0 = {
.chipselect = cspi_0_0_chipselect,
.xchg_single = cspi_0_0_xchg_single,
+ .do_transfer = imx_spi_do_transfer,
.init = cspi_0_0_init,
};
static __maybe_unused struct spi_imx_devtype_data spi_imx_devtype_data_0_7 = {
.chipselect = cspi_0_7_chipselect,
.xchg_single = cspi_0_7_xchg_single,
+ .do_transfer = imx_spi_do_transfer,
.init = cspi_0_7_init,
};
static __maybe_unused struct spi_imx_devtype_data spi_imx_devtype_data_2_3 = {
.chipselect = cspi_2_3_chipselect,
+ .do_transfer = cspi_2_3_do_transfer,
.xchg_single = cspi_2_3_xchg_single,
};
@@ -490,6 +573,7 @@ static int imx_spi_probe(struct device_d *dev)
imx->chipselect = devdata->chipselect;
imx->xchg_single = devdata->xchg_single;
+ imx->do_transfer = devdata->do_transfer;
imx->regs = dev_request_mem_region(dev, 0);
if (devdata->init)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d7f5b07637..501e9fa7d3 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -7,6 +7,7 @@ if VIDEO
config FRAMEBUFFER_CONSOLE
bool
+ depends on !CONSOLE_NONE
select IMAGE_RENDERER
select FONTS
prompt "framebuffer console support"
@@ -119,6 +120,7 @@ comment "Video encoder chips"
config DRIVER_VIDEO_MTL017
bool "MTL017 LVDS encoder"
select VIDEO_VPL
+ depends on I2C
help
The MTL017 is a parallel to lvds video encoder chip found on the
Efika MX Smartbook.
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index 29b4c71014..3672c44202 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -11,10 +11,12 @@
static int fb_ioctl(struct cdev* cdev, int req, void *data)
{
struct fb_info *info = cdev->priv;
+ struct fb_info **fb;
switch (req) {
case FBIOGET_SCREENINFO:
- memcpy(data, info, sizeof(*info));
+ fb = data;
+ *fb = info;
break;
case FBIO_ENABLE:
info->fbops->fb_enable(info);
@@ -29,11 +31,40 @@ static int fb_ioctl(struct cdev* cdev, int req, void *data)
return 0;
}
+static int fb_alloc_shadowfb(struct fb_info *info)
+{
+ if (info->screen_base_shadow && info->shadowfb)
+ return 0;
+
+ if (!info->screen_base_shadow && !info->shadowfb)
+ return 0;
+
+ if (info->shadowfb) {
+ info->screen_base_shadow = memalign(PAGE_SIZE,
+ info->line_length * info->yres);
+ if (!info->screen_base_shadow)
+ return -ENOMEM;
+ memcpy(info->screen_base_shadow, info->screen_base,
+ info->line_length * info->yres);
+ } else {
+ free(info->screen_base_shadow);
+ info->screen_base_shadow = NULL;
+ }
+
+ return 0;
+}
+
int fb_enable(struct fb_info *info)
{
+ int ret;
+
if (info->enabled)
return 0;
+ ret = fb_alloc_shadowfb(info);
+ if (ret)
+ return ret;
+
info->fbops->fb_enable(info);
info->enabled = true;
@@ -186,6 +217,22 @@ static void fb_info(struct device_d *dev)
fb_print_modes(&info->edid_modes);
}
+void *fb_get_screen_base(struct fb_info *info)
+{
+ return info->screen_base_shadow ?
+ info->screen_base_shadow : info->screen_base;
+}
+
+int fb_set_shadowfb(struct param_d *p, void *priv)
+{
+ struct fb_info *info = priv;
+
+ if (!info->enabled)
+ return 0;
+
+ return fb_alloc_shadowfb(info);
+}
+
int register_framebuffer(struct fb_info *info)
{
int id = get_free_deviceid("fb");
@@ -243,6 +290,8 @@ int register_framebuffer(struct fb_info *info)
for (i = 0; i < info->edid_modes.num_modes; i++)
names[i + info->modes.num_modes] = info->edid_modes.modes[i].name;
dev_add_param_enum(dev, "mode_name", fb_set_modename, NULL, &info->current_mode, names, num_modes, info);
+ info->shadowfb = 1;
+ dev_add_param_bool(dev, "shadowfb", fb_set_shadowfb, NULL, &info->shadowfb, info);
info->mode = fb_num_to_mode(info, 0);
diff --git a/drivers/video/fbconsole.c b/drivers/video/fbconsole.c
index b368079992..b10503eb84 100644
--- a/drivers/video/fbconsole.c
+++ b/drivers/video/fbconsole.c
@@ -40,6 +40,7 @@ struct fbc_priv {
u8 csi[256];
int active;
+ int in_console;
};
static int fbc_getc(struct console_device *cdev)
@@ -57,6 +58,7 @@ static void cls(struct fbc_priv *priv)
void *buf = gui_screen_render_buffer(priv->sc);
memset(buf, 0, priv->fb->line_length * priv->fb->yres);
+ gu_screen_blit(priv->sc);
}
struct rgb {
@@ -137,6 +139,8 @@ static void video_invertchar(struct fbc_priv *priv, int x, int y)
gu_invert_area(priv->fb, buf, x * priv->font_width, y * priv->font_height,
priv->font_width, priv->font_height);
+ gu_screen_blit_area(priv->sc, x * priv->font_width, y * priv->font_height,
+ priv->font_width, priv->font_height);
}
static void printchar(struct fbc_priv *priv, int c)
@@ -169,7 +173,10 @@ static void printchar(struct fbc_priv *priv, int c)
default:
drawchar(priv, priv->x, priv->y, c);
- gu_screen_blit(priv->sc);
+
+ gu_screen_blit_area(priv->sc, priv->x * priv->font_width,
+ priv->y * priv->font_height,
+ priv->font_width, priv->font_height);
priv->x++;
if (priv->x > priv->cols) {
@@ -187,6 +194,7 @@ static void printchar(struct fbc_priv *priv, int c)
memcpy(buf, buf + line_height, line_height * (priv->rows + 1));
memset(buf + line_height * priv->rows, 0, line_height);
+ gu_screen_blit(priv->sc);
priv->y = priv->rows;
}
@@ -250,6 +258,7 @@ static void fbc_parse_csi(struct fbc_priv *priv)
return;
case 'J':
cls(priv);
+ video_invertchar(priv, priv->x, priv->y);
return;
case 'H':
video_invertchar(priv, priv->x, priv->y);
@@ -282,6 +291,10 @@ static void fbc_putc(struct console_device *cdev, char c)
struct fbc_priv *priv = container_of(cdev,
struct fbc_priv, cdev);
+ if (priv->in_console)
+ return;
+ priv->in_console = 1;
+
switch (priv->state) {
case LIT:
switch (c) {
@@ -329,6 +342,7 @@ static void fbc_putc(struct console_device *cdev, char c)
}
break;
}
+ priv->in_console = 0;
}
static int setup_font(struct fbc_priv *priv)
@@ -370,7 +384,7 @@ static int fbc_set_active(struct console_device *cdev, unsigned flags)
if (ret)
return ret;
- priv->sc = fb_create_screen(fb, 0);
+ priv->sc = fb_create_screen(fb);
if (IS_ERR(priv->sc))
return PTR_ERR(priv->sc);
diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c
index b56658202c..a87e720d96 100644
--- a/drivers/video/imx-ipu-fb.c
+++ b/drivers/video/imx-ipu-fb.c
@@ -355,7 +355,8 @@ struct ipu_ch_param {
struct ipu_cpmem_word word[2];
};
-void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v)
+static void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base,
+ u32 wbs, u32 v)
{
u32 bit = (wbs >> 8) % 160;
u32 size = wbs & 0xff;
@@ -500,7 +501,8 @@ static int sdc_init_panel(struct fb_info *info, enum disp_data_mapping fmt)
return 0;
}
-int ipu_cpmem_set_format_rgb(struct ipu_ch_param *p, struct imx_ipu_fb_rgb *rgb)
+static int ipu_cpmem_set_format_rgb(struct ipu_ch_param *p,
+ struct imx_ipu_fb_rgb *rgb)
{
int bpp = 0, npb = 0, ro, go, bo, to;
diff --git a/drivers/video/imx-ipu-v3/imx-hdmi.c b/drivers/video/imx-ipu-v3/imx-hdmi.c
index f5a2e3c601..fa55b19c94 100644
--- a/drivers/video/imx-ipu-v3/imx-hdmi.c
+++ b/drivers/video/imx-ipu-v3/imx-hdmi.c
@@ -6,8 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
- * for SLISHDMI13T and SLIPHDMIT IP cores
+ * Designware High-Definition Multimedia Interface (HDMI) driver
*
* Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
*/
@@ -60,7 +59,7 @@ enum hdmi_datamap {
YCbCr422_12B = 0x12,
};
-enum imx_hdmi_devtype {
+enum dw_hdmi_devtype {
IMX6Q_HDMI,
IMX6DL_HDMI,
};
@@ -117,8 +116,8 @@ struct hdmi_data_info {
struct hdmi_vmode video_mode;
};
-struct imx_hdmi {
- enum imx_hdmi_devtype dev_type;
+struct dw_hdmi {
+ enum dw_hdmi_devtype dev_type;
struct device_d *dev;
struct clk *isfr_clk;
struct clk *iahb_clk;
@@ -140,10 +139,12 @@ struct imx_hdmi {
unsigned int sample_rate;
int ratio;
+ struct fb_videomode *mode;
+
struct vpl vpl;
};
-static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
+static void dw_hdmi_set_ipu_di_mux(struct dw_hdmi *hdmi, int ipu_di)
{
void __iomem *gpr3 = (void *)MX6_IOMUXC_BASE_ADDR + 0xc;
uint32_t val;
@@ -156,49 +157,47 @@ static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
writel(val, gpr3);
}
-static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
+static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
{
writeb(val, hdmi->regs + offset);
}
-static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
+static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
{
return readb(hdmi->regs + offset);
}
-static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
+static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
{
u8 val = hdmi_readb(hdmi, reg) & ~mask;
+
val |= data & mask;
hdmi_writeb(hdmi, val, reg);
}
-static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
- u8 shift, u8 mask)
+static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
+ u8 shift, u8 mask)
{
hdmi_modb(hdmi, data << shift, mask, reg);
}
-static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
- unsigned int value)
+static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
+ unsigned int n)
{
- hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
- hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2);
- hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3);
+ /* Must be set/cleared first */
+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
/* nshift factor = 0 */
hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
-}
-
-static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
-{
- /* Must be set/cleared first */
- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
- hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
- hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
+ hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
+ hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
+
+ hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3);
+ hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2);
+ hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1);
}
static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
@@ -334,12 +333,11 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
}
if (ratio == 100)
return cts;
- else
- return (cts * ratio) / 100;
+ return (cts * ratio) / 100;
}
-static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
- unsigned long pixel_clk)
+static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
+ unsigned long pixel_clk)
{
unsigned int clk_n, clk_cts;
@@ -350,7 +348,7 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
if (!clk_cts) {
dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
- __func__, pixel_clk);
+ __func__, pixel_clk);
return;
}
@@ -358,11 +356,10 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
__func__, hdmi->sample_rate, hdmi->ratio,
pixel_clk, clk_n, clk_cts);
- hdmi_set_clock_regenerator_n(hdmi, clk_n);
- hdmi_regenerate_cts(hdmi, clk_cts);
+ hdmi_set_cts_n(hdmi, clk_cts, clk_n);
}
-static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
+static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
{
hdmi_set_clk_regenerator(hdmi, 74250000);
}
@@ -374,7 +371,7 @@ static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
* pin{31~24} <==> G[7:0]
* pin{15~8} <==> B[7:0]
*/
-static void hdmi_video_sample(struct imx_hdmi *hdmi)
+static void hdmi_video_sample(struct dw_hdmi *hdmi)
{
int color_format = 0;
u8 val;
@@ -430,27 +427,32 @@ static void hdmi_video_sample(struct imx_hdmi *hdmi)
hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
}
-static int is_color_space_conversion(struct imx_hdmi *hdmi)
+static int is_color_space_conversion(struct dw_hdmi *hdmi)
{
- return (hdmi->hdmi_data.enc_in_format !=
- hdmi->hdmi_data.enc_out_format);
+ return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format;
}
-static int is_color_space_decimation(struct imx_hdmi *hdmi)
+static int is_color_space_decimation(struct dw_hdmi *hdmi)
{
- return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) &&
- (hdmi->hdmi_data.enc_in_format == RGB ||
- hdmi->hdmi_data.enc_in_format == YCBCR444));
+ if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS)
+ return 0;
+ if (hdmi->hdmi_data.enc_in_format == RGB ||
+ hdmi->hdmi_data.enc_in_format == YCBCR444)
+ return 1;
+ return 0;
}
-static int is_color_space_interpolation(struct imx_hdmi *hdmi)
+static int is_color_space_interpolation(struct dw_hdmi *hdmi)
{
- return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) &&
- (hdmi->hdmi_data.enc_out_format == RGB ||
- hdmi->hdmi_data.enc_out_format == YCBCR444));
+ if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS)
+ return 0;
+ if (hdmi->hdmi_data.enc_out_format == RGB ||
+ hdmi->hdmi_data.enc_out_format == YCBCR444)
+ return 1;
+ return 0;
}
-static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
+static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
{
const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
unsigned i;
@@ -458,12 +460,14 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
if (is_color_space_conversion(hdmi)) {
if (hdmi->hdmi_data.enc_out_format == RGB) {
- if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
+ if (hdmi->hdmi_data.colorimetry ==
+ HDMI_COLORIMETRY_ITU_601)
csc_coeff = &csc_coeff_rgb_out_eitu601;
else
csc_coeff = &csc_coeff_rgb_out_eitu709;
} else if (hdmi->hdmi_data.enc_in_format == RGB) {
- if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
+ if (hdmi->hdmi_data.colorimetry ==
+ HDMI_COLORIMETRY_ITU_601)
csc_coeff = &csc_coeff_rgb_in_eitu601;
else
csc_coeff = &csc_coeff_rgb_in_eitu709;
@@ -489,7 +493,7 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
HDMI_CSC_SCALE);
}
-static void hdmi_video_csc(struct imx_hdmi *hdmi)
+static void hdmi_video_csc(struct dw_hdmi *hdmi)
{
int color_depth = 0;
int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
@@ -517,7 +521,7 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi)
hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
HDMI_CSC_SCALE);
- imx_hdmi_update_csc_coeffs(hdmi);
+ dw_hdmi_update_csc_coeffs(hdmi);
}
/*
@@ -525,7 +529,7 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi)
* for example, if input is YCC422 mode or repeater is used,
* data should be repacked this module can be bypassed.
*/
-static void hdmi_video_packetize(struct imx_hdmi *hdmi)
+static void hdmi_video_packetize(struct dw_hdmi *hdmi)
{
unsigned int color_depth = 0;
unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
@@ -533,21 +537,22 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
u8 val, vp_conf;
- if (hdmi_data->enc_out_format == RGB
- || hdmi_data->enc_out_format == YCBCR444) {
- if (!hdmi_data->enc_color_depth)
+ if (hdmi_data->enc_out_format == RGB ||
+ hdmi_data->enc_out_format == YCBCR444) {
+ if (!hdmi_data->enc_color_depth) {
output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
- else if (hdmi_data->enc_color_depth == 8) {
+ } else if (hdmi_data->enc_color_depth == 8) {
color_depth = 4;
output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
- } else if (hdmi_data->enc_color_depth == 10)
+ } else if (hdmi_data->enc_color_depth == 10) {
color_depth = 5;
- else if (hdmi_data->enc_color_depth == 12)
+ } else if (hdmi_data->enc_color_depth == 12) {
color_depth = 6;
- else if (hdmi_data->enc_color_depth == 16)
+ } else if (hdmi_data->enc_color_depth == 16) {
color_depth = 7;
- else
+ } else {
return;
+ }
} else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
if (!hdmi_data->enc_color_depth ||
hdmi_data->enc_color_depth == 8)
@@ -559,8 +564,9 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
else
return;
output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
- } else
+ } else {
return;
+ }
/* set the packetizer registers */
val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
@@ -620,109 +626,110 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi)
HDMI_VP_CONF);
}
-static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
}
-static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
}
-static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
}
-static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
}
-static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
- unsigned char bit)
+static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi,
+ unsigned char bit)
{
hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
}
-static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
+static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
{
- unsigned char val = 0;
- val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3;
- while (!val) {
- udelay(1000);
+ u32 val;
+
+ while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
if (msec-- == 0)
return false;
- val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3;
+ udelay(1000);
}
+ hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0);
+
return true;
}
-static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
- unsigned char addr)
+static void __hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
+ unsigned char addr)
{
hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
hdmi_writeb(hdmi, (unsigned char)(data >> 8),
- HDMI_PHY_I2CM_DATAO_1_ADDR);
+ HDMI_PHY_I2CM_DATAO_1_ADDR);
hdmi_writeb(hdmi, (unsigned char)(data >> 0),
- HDMI_PHY_I2CM_DATAO_0_ADDR);
+ HDMI_PHY_I2CM_DATAO_0_ADDR);
hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
- HDMI_PHY_I2CM_OPERATION_ADDR);
+ HDMI_PHY_I2CM_OPERATION_ADDR);
hdmi_phy_wait_i2c_done(hdmi, 1000);
}
-static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
- unsigned char addr)
+static int hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
+ unsigned char addr)
{
__hdmi_phy_i2c_write(hdmi, data, addr);
return 0;
}
-static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_power(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_PDZ_OFFSET,
HDMI_PHY_CONF0_PDZ_MASK);
}
-static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_ENTMDS_OFFSET,
HDMI_PHY_CONF0_ENTMDS_MASK);
}
-static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
}
-static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
}
-static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
HDMI_PHY_CONF0_SELDATAENPOL_MASK);
}
-static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
{
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
HDMI_PHY_CONF0_SELDIPIF_OFFSET,
@@ -730,10 +737,10 @@ static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
}
enum {
- RES_8,
- RES_10,
- RES_12,
- RES_MAX,
+ DW_HDMI_RES_8,
+ DW_HDMI_RES_10,
+ DW_HDMI_RES_12,
+ DW_HDMI_RES_MAX,
};
struct mpll_config {
@@ -741,7 +748,7 @@ struct mpll_config {
struct {
u16 cpce;
u16 gmp;
- } res[RES_MAX];
+ } res[DW_HDMI_RES_MAX];
};
static const struct mpll_config mpll_config[] = {
@@ -774,7 +781,7 @@ static const struct mpll_config mpll_config[] = {
struct curr_ctrl {
unsigned long mpixelclock;
- u16 curr[RES_MAX];
+ u16 curr[DW_HDMI_RES_MAX];
};
static const struct curr_ctrl curr_ctrl[] = {
@@ -794,7 +801,7 @@ static const struct curr_ctrl curr_ctrl[] = {
}
};
-static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
+static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
unsigned char res, int cscon)
{
unsigned res_idx, i;
@@ -806,13 +813,13 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
switch (res) {
case 0: /* color resolution 0 is 8 bit colour depth */
case 8:
- res_idx = RES_8;
+ res_idx = DW_HDMI_RES_8;
break;
case 10:
- res_idx = RES_10;
+ res_idx = DW_HDMI_RES_10;
break;
case 12:
- res_idx = RES_12;
+ res_idx = DW_HDMI_RES_12;
break;
default:
return -EINVAL;
@@ -827,10 +834,10 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
/* gen2 tx power off */
- imx_hdmi_phy_gen2_txpwron(hdmi, 0);
+ dw_hdmi_phy_gen2_txpwron(hdmi, 0);
/* gen2 pddq */
- imx_hdmi_phy_gen2_pddq(hdmi, 1);
+ dw_hdmi_phy_gen2_pddq(hdmi, 1);
/* PHY reset */
hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
@@ -840,7 +847,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
hdmi_phy_test_clear(hdmi, 1);
hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
- HDMI_PHY_I2CM_SLAVE_ADDR);
+ HDMI_PHY_I2CM_SLAVE_ADDR);
hdmi_phy_test_clear(hdmi, 0);
/* PLL/MPLL Cfg - always match on final entry */
@@ -878,15 +885,15 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
/* REMOVE CLK TERM */
hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
- imx_hdmi_phy_enable_power(hdmi, 1);
+ dw_hdmi_phy_enable_power(hdmi, 1);
/* toggle TMDS enable */
- imx_hdmi_phy_enable_tmds(hdmi, 0);
- imx_hdmi_phy_enable_tmds(hdmi, 1);
+ dw_hdmi_phy_enable_tmds(hdmi, 0);
+ dw_hdmi_phy_enable_tmds(hdmi, 1);
/* gen2 tx power on */
- imx_hdmi_phy_gen2_txpwron(hdmi, 1);
- imx_hdmi_phy_gen2_pddq(hdmi, 0);
+ dw_hdmi_phy_gen2_txpwron(hdmi, 1);
+ dw_hdmi_phy_gen2_pddq(hdmi, 0);
/*Wait for PHY PLL lock */
msec = 5;
@@ -907,7 +914,7 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
return 0;
}
-static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
+static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
{
int i, ret;
bool cscon = false;
@@ -918,10 +925,10 @@ static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
/* HDMI Phy spec says to do the phy initialization sequence twice */
for (i = 0; i < 2; i++) {
- imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
- imx_hdmi_phy_sel_interface_control(hdmi, 0);
- imx_hdmi_phy_enable_tmds(hdmi, 0);
- imx_hdmi_phy_enable_power(hdmi, 0);
+ dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
+ dw_hdmi_phy_sel_interface_control(hdmi, 0);
+ dw_hdmi_phy_enable_tmds(hdmi, 0);
+ dw_hdmi_phy_enable_power(hdmi, 0);
/* Enable CSC */
ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
@@ -933,7 +940,7 @@ static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
return 0;
}
-static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
+static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
{
u8 de;
@@ -952,19 +959,99 @@ static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
}
-static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
+static void hdmi_av_composer(struct dw_hdmi *hdmi)
+{
+ u8 inv_val;
+ struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
+ int hblank, vblank;
+ struct fb_videomode *mode = hdmi->mode;
+
+ vmode->mhsyncpolarity = !!(mode->sync & FB_SYNC_HOR_HIGH_ACT);
+ vmode->mvsyncpolarity = !!(mode->sync & FB_SYNC_VERT_HIGH_ACT);
+ vmode->minterlaced = !!(mode->vmode & FB_VMODE_INTERLACED);
+ vmode->mpixelclock = PICOS2KHZ(mode->pixclock) * 1000;
+
+ dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
+
+ /* Set up HDMI_FC_INVIDCONF */
+ inv_val = (hdmi->hdmi_data.hdcp_enable ?
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
+
+ inv_val |= (vmode->mvsyncpolarity ?
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
+
+ inv_val |= (vmode->mhsyncpolarity ?
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
+
+ inv_val |= (vmode->mdataenablepolarity ?
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
+
+ if (hdmi->vic == 39)
+ inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
+ else
+ inv_val |= (vmode->minterlaced ?
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
+
+ inv_val |= (vmode->minterlaced ?
+ HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
+ HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
+
+ inv_val |= (vmode->mdvi ?
+ HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
+ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
+
+ hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
+
+ /* Set up horizontal active pixel width */
+ hdmi_writeb(hdmi, mode->xres >> 8, HDMI_FC_INHACTV1);
+ hdmi_writeb(hdmi, mode->xres, HDMI_FC_INHACTV0);
+
+ /* Set up vertical active lines */
+ hdmi_writeb(hdmi, mode->yres >> 8, HDMI_FC_INVACTV1);
+ hdmi_writeb(hdmi, mode->yres, HDMI_FC_INVACTV0);
+
+ /* Set up horizontal blanking pixel region width */
+ hblank = mode->left_margin + mode->right_margin + mode->hsync_len;
+ hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
+ hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
+
+ /* Set up vertical blanking pixel region width */
+ vblank = mode->upper_margin + mode->lower_margin + mode->vsync_len;
+ hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
+
+ /* Set up HSYNC active edge delay width (in pixel clks) */
+ hdmi_writeb(hdmi, mode->right_margin >> 8, HDMI_FC_HSYNCINDELAY1);
+ hdmi_writeb(hdmi, mode->right_margin, HDMI_FC_HSYNCINDELAY0);
+
+ /* Set up VSYNC active edge delay (in lines) */
+ hdmi_writeb(hdmi, mode->lower_margin, HDMI_FC_VSYNCINDELAY);
+
+ /* Set up HSYNC active pulse width (in pixel clks) */
+ hdmi_writeb(hdmi, mode->hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
+ hdmi_writeb(hdmi, mode->hsync_len, HDMI_FC_HSYNCINWIDTH0);
+
+ /* Set up VSYNC active edge delay (in lines) */
+ hdmi_writeb(hdmi, mode->vsync_len, HDMI_FC_VSYNCINWIDTH);
+}
+
+static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
{
if (!hdmi->phy_enabled)
return;
- imx_hdmi_phy_enable_tmds(hdmi, 0);
- imx_hdmi_phy_enable_power(hdmi, 0);
+ dw_hdmi_phy_enable_tmds(hdmi, 0);
+ dw_hdmi_phy_enable_power(hdmi, 0);
hdmi->phy_enabled = false;
}
/* HDMI Initialization Step B.4 */
-static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
+static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
{
u8 clkdis;
@@ -994,7 +1081,7 @@ static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
}
/* Workaround to clear the overflow condition */
-static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
+static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
{
int count;
u8 val;
@@ -1012,12 +1099,10 @@ static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
}
-static int imx_hdmi_setup(struct imx_hdmi *hdmi)
+static int dw_hdmi_setup(struct dw_hdmi *hdmi)
{
int ret;
- hdmi->vic = 0;
-
dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n");
hdmi->hdmi_data.video_mode.mdvi = true;
@@ -1035,28 +1120,28 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi)
hdmi->hdmi_data.hdcp_enable = 0;
hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
+ /* HDMI Initialization Step B.1 */
+ hdmi_av_composer(hdmi);
+
/* HDMI Initializateion Step B.2 */
- ret = imx_hdmi_phy_init(hdmi);
+ ret = dw_hdmi_phy_init(hdmi);
if (ret)
return ret;
/* HDMI Initialization Step B.3 */
- imx_hdmi_enable_video_path(hdmi);
-
- /* not for DVI mode */
- dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
+ dw_hdmi_enable_video_path(hdmi);
hdmi_video_packetize(hdmi);
hdmi_video_csc(hdmi);
hdmi_video_sample(hdmi);
hdmi_tx_hdcp_config(hdmi);
- imx_hdmi_clear_overflow(hdmi);
+ dw_hdmi_clear_overflow(hdmi);
return 0;
}
-static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
+static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
{
u8 ih_mute;
@@ -1108,22 +1193,22 @@ static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
}
-struct imx_hdmi_data {
+struct dw_hdmi_data {
unsigned ipu_mask;
- enum imx_hdmi_devtype devtype;
+ enum dw_hdmi_devtype devtype;
};
-static struct imx_hdmi_data imx6q_hdmi_data = {
+static struct dw_hdmi_data imx6q_hdmi_data = {
.ipu_mask = 0xf,
.devtype = IMX6Q_HDMI,
};
-static struct imx_hdmi_data imx6dl_hdmi_data = {
+static struct dw_hdmi_data imx6dl_hdmi_data = {
.ipu_mask = 0x3,
.devtype = IMX6DL_HDMI,
};
-static struct of_device_id imx_hdmi_dt_ids[] = {
+static struct of_device_id dw_hdmi_dt_ids[] = {
{
.compatible = "fsl,imx6q-hdmi",
.data = &imx6q_hdmi_data,
@@ -1135,7 +1220,7 @@ static struct of_device_id imx_hdmi_dt_ids[] = {
}
};
-static int imx_hdmi_get_modes(struct imx_hdmi *hdmi, struct display_timings *timings)
+static int dw_hdmi_get_modes(struct dw_hdmi *hdmi, struct display_timings *timings)
{
int ret = -ENOENT;
@@ -1155,23 +1240,24 @@ static int imx_hdmi_get_modes(struct imx_hdmi *hdmi, struct display_timings *tim
return ret;
}
-static int imx_hdmi_ioctl(struct vpl *vpl, unsigned int port,
+static int dw_hdmi_ioctl(struct vpl *vpl, unsigned int port,
unsigned int cmd, void *data)
{
- struct imx_hdmi *hdmi = container_of(vpl, struct imx_hdmi, vpl);
+ struct dw_hdmi *hdmi = container_of(vpl, struct dw_hdmi, vpl);
struct ipu_di_mode *mode;
switch (cmd) {
case VPL_ENABLE:
- return imx_hdmi_setup(hdmi);
+ return dw_hdmi_setup(hdmi);
case VPL_DISABLE:
- imx_hdmi_phy_disable(hdmi);
+ dw_hdmi_phy_disable(hdmi);
return 0;
case VPL_PREPARE:
- imx_hdmi_set_ipu_di_mux(hdmi, port);
+ hdmi->mode = data;
+ dw_hdmi_set_ipu_di_mux(hdmi, port);
return 0;
case VPL_GET_VIDEOMODES:
- return imx_hdmi_get_modes(hdmi, data);
+ return dw_hdmi_get_modes(hdmi, data);
case IMX_IPU_VPL_DI_MODE:
mode = data;
@@ -1184,12 +1270,12 @@ static int imx_hdmi_ioctl(struct vpl *vpl, unsigned int port,
return 0;
}
-static int imx_hdmi_probe(struct device_d *dev)
+static int dw_hdmi_probe(struct device_d *dev)
{
struct device_node *np = dev->device_node;
- struct imx_hdmi *hdmi;
+ struct dw_hdmi *hdmi;
int ret;
- const struct imx_hdmi_data *devtype;
+ const struct dw_hdmi_data *devtype;
ret = dev_get_drvdata(dev, (const void **)&devtype);
if (ret)
@@ -1275,7 +1361,7 @@ static int imx_hdmi_probe(struct device_d *dev)
hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
hdmi->vpl.node = np;
- hdmi->vpl.ioctl = imx_hdmi_ioctl;
+ hdmi->vpl.ioctl = dw_hdmi_ioctl;
ret = vpl_register(&hdmi->vpl);
if (ret)
return ret;
@@ -1288,12 +1374,12 @@ err_isfr:
return ret;
}
-static struct driver_d imx_hdmi_driver = {
- .probe = imx_hdmi_probe,
- .of_compatible = imx_hdmi_dt_ids,
+static struct driver_d dw_hdmi_driver = {
+ .probe = dw_hdmi_probe,
+ .of_compatible = dw_hdmi_dt_ids,
.name = "imx-hdmi",
};
-device_platform_driver(imx_hdmi_driver);
+device_platform_driver(dw_hdmi_driver);
MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
diff --git a/drivers/video/imx-ipu-v3/imx-hdmi.h b/drivers/video/imx-ipu-v3/imx-hdmi.h
index 39b677689d..b3e144227f 100644
--- a/drivers/video/imx-ipu-v3/imx-hdmi.h
+++ b/drivers/video/imx-ipu-v3/imx-hdmi.h
@@ -837,7 +837,8 @@ enum {
HDMI_PHY_CONF0_PDZ_OFFSET = 7,
HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
- HDMI_PHY_CONF0_SPARECTRL = 0x20,
+ HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20,
+ HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5,
HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
diff --git a/drivers/video/imx-ipu-v3/ipufb.c b/drivers/video/imx-ipu-v3/ipufb.c
index e804c31b29..ea2e83b7f0 100644
--- a/drivers/video/imx-ipu-v3/ipufb.c
+++ b/drivers/video/imx-ipu-v3/ipufb.c
@@ -75,6 +75,31 @@ static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
return chan << bf->offset;
}
+static int ipu_crtc_adjust_videomode(struct ipufb_info *fbi, struct fb_videomode *mode)
+{
+ u32 diff;
+
+ if (mode->lower_margin >= 2)
+ return 0;
+
+ diff = 2 - mode->lower_margin;
+
+ if (mode->upper_margin >= diff) {
+ mode->upper_margin -= diff;
+ } else if (mode->vsync_len > diff) {
+ mode->vsync_len = mode->vsync_len - diff;
+ } else {
+ dev_warn(fbi->dev, "failed to adjust videomode\n");
+ return -EINVAL;
+ }
+
+ mode->lower_margin = 2;
+
+ dev_warn(fbi->dev, "videomode adapted for IPU restrictions\n");
+
+ return 0;
+}
+
int ipu_crtc_mode_set(struct ipufb_info *fbi,
struct fb_videomode *mode,
int x, int y)
@@ -109,6 +134,11 @@ int ipu_crtc_mode_set(struct ipufb_info *fbi,
sig_cfg.v_start_width = mode->upper_margin;
sig_cfg.v_sync_width = mode->vsync_len;
+
+ ret = ipu_crtc_adjust_videomode(fbi, mode);
+ if (ret)
+ return ret;
+
sig_cfg.v_end_width = mode->lower_margin;
sig_cfg.pixelclock = PICOS2KHZ(mode->pixclock) * 1000UL;
sig_cfg.clkflags = di_mode.di_clkflags;
@@ -184,7 +214,7 @@ static int ipufb_activate_var(struct fb_info *info)
struct ipufb_info *fbi = container_of(info, struct ipufb_info, info);
info->line_length = info->xres * (info->bits_per_pixel >> 3);
- fbi->info.screen_base = dma_alloc_coherent(info->line_length * info->yres,
+ fbi->info.screen_base = dma_alloc_writecombine(info->line_length * info->yres,
DMA_ADDRESS_BROKEN);
if (!fbi->info.screen_base)
return -ENOMEM;
diff --git a/drivers/video/simple-panel.c b/drivers/video/simple-panel.c
index dceedc60c3..3dd760b385 100644
--- a/drivers/video/simple-panel.c
+++ b/drivers/video/simple-panel.c
@@ -82,7 +82,8 @@ static int simple_panel_get_modes(struct simple_panel *panel, struct display_tim
{
int ret = -ENOENT;
- if (panel->ddc_node) {
+ if (panel->ddc_node && IS_ENABLED(CONFIG_DRIVER_VIDEO_EDID) &&
+ IS_ENABLED(CONFIG_I2C)) {
struct i2c_adapter *i2c;
i2c = of_find_i2c_adapter_by_node(panel->ddc_node);
diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index f45f8cadf1..62571fb8a3 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -57,6 +57,19 @@ struct cdev *cdev_by_name(const char *filename)
return NULL;
}
+struct cdev *cdev_by_device_node(struct device_node *node)
+{
+ struct cdev *cdev;
+
+ list_for_each_entry(cdev, &cdev_list, list) {
+ if (!cdev->device_node)
+ continue;
+ if (cdev->device_node == node)
+ return cdev;
+ }
+ return NULL;
+}
+
/**
* device_find_partition - find a partition belonging to a physical device
*
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
deleted file mode 100644
index 767497096a..0000000000
--- a/include/asm-generic/gpio.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __ASM_GENERIC_GPIO_H
-#define __ASM_GENERIC_GPIO_H
-
-void gpio_set_value(unsigned gpio, int value);
-int gpio_get_value(unsigned gpio);
-int gpio_direction_output(unsigned gpio, int value);
-int gpio_direction_input(unsigned gpio);
-
-#endif /* __ASM_GENERIC_GPIO_H */
diff --git a/include/console.h b/include/console.h
index a6737c8581..4b2f134a4c 100644
--- a/include/console.h
+++ b/include/console.h
@@ -71,9 +71,6 @@ extern struct list_head console_list;
#define CFG_PBSIZE (CONFIG_CBSIZE+sizeof(CONFIG_PROMPT)+16)
-bool console_is_input_allow(void);
-void console_allow_input(bool val);
-
extern int barebox_loglevel;
struct console_device *console_get_first_active(void);
diff --git a/include/dma.h b/include/dma.h
index 800d8b155f..4d31797968 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -39,5 +39,6 @@ void dma_sync_single_for_device(unsigned long address, size_t size,
void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle);
void dma_free_coherent(void *mem, dma_addr_t dma_handle, size_t size);
+void *dma_alloc_writecombine(size_t size, dma_addr_t *dma_handle);
#endif /* __DMA_H */
diff --git a/include/driver.h b/include/driver.h
index 728f8abb49..046dd9079d 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -436,6 +436,7 @@ struct cdev {
struct file_operations *ops;
void *priv;
struct device_d *dev;
+ struct device_node *device_node;
struct list_head list;
struct list_head devices_list;
char *name; /* filename under /dev/ */
@@ -456,6 +457,7 @@ int devfs_remove(struct cdev *);
int cdev_find_free_index(const char *);
struct cdev *device_find_partition(struct device_d *dev, const char *name);
struct cdev *cdev_by_name(const char *filename);
+struct cdev *cdev_by_device_node(struct device_node *node);
struct cdev *cdev_open(const char *name, unsigned long flags);
int cdev_do_open(struct cdev *, unsigned long flags);
void cdev_close(struct cdev *cdev);
diff --git a/include/fb.h b/include/fb.h
index 311d5db192..cf113c4300 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -118,6 +118,7 @@ struct fb_info {
struct device_d dev; /* This is this fb device */
void *screen_base;
+ void *screen_base_shadow;
unsigned long screen_size;
void *priv;
@@ -141,6 +142,7 @@ struct fb_info {
int register_simplefb; /* If true a simplefb device node will
* be created.
*/
+ int shadowfb;
};
struct display_timings *of_get_display_timings(struct device_node *np);
@@ -167,5 +169,6 @@ void fb_edid_add_modes(struct fb_info *info);
void fb_of_reserve_add_fixup(struct fb_info *info);
int register_fbconsole(struct fb_info *fb);
+void *fb_get_screen_base(struct fb_info *info);
#endif /* __FB_H */
diff --git a/include/gpio.h b/include/gpio.h
index f116ea6af7..7b3f512b19 100644
--- a/include/gpio.h
+++ b/include/gpio.h
@@ -1,7 +1,28 @@
#ifndef __GPIO_H
#define __GPIO_H
-#include <asm/gpio.h>
+#ifdef CONFIG_GENERIC_GPIO
+void gpio_set_value(unsigned gpio, int value);
+int gpio_get_value(unsigned gpio);
+int gpio_direction_output(unsigned gpio, int value);
+int gpio_direction_input(unsigned gpio);
+#else
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+}
+static inline int gpio_get_value(unsigned gpio)
+{
+ return 0;
+}
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+ return -EINVAL;
+}
+static inline int gpio_direction_input(unsigned gpio)
+{
+ return -EINVAL;
+}
+#endif
#define ARCH_NR_GPIOS 256
diff --git a/include/gui/graphic_utils.h b/include/gui/graphic_utils.h
index ab8c3fcff3..231b3a9414 100644
--- a/include/gui/graphic_utils.h
+++ b/include/gui/graphic_utils.h
@@ -19,11 +19,13 @@ void gu_set_pixel(struct fb_info *info, void *adr, u32 px);
void gu_set_rgb_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b);
void gu_set_rgba_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b, u8 a);
void gu_memset_pixel(struct fb_info *info, void* buf, u32 color, size_t size);
-struct screen *fb_create_screen(struct fb_info *info, bool offscreen);
-struct screen *fb_open(const char *fbdev, bool offscreen);
+struct screen *fb_create_screen(struct fb_info *info);
+struct screen *fb_open(const char *fbdev);
void fb_close(struct screen *sc);
void gu_screen_blit(struct screen *sc);
void gu_invert_area(struct fb_info *info, void *buf, int startx, int starty, int width,
int height);
+void gu_screen_blit_area(struct screen *sc, int startx, int starty, int width,
+ int height);
#endif /* __GRAPHIC_UTILS_H__ */
diff --git a/include/gui/gui.h b/include/gui/gui.h
index 03e60aa0de..133149beef 100644
--- a/include/gui/gui.h
+++ b/include/gui/gui.h
@@ -23,16 +23,12 @@ struct screen {
struct surface s;
void *fb;
- void *offscreenbuf;
int fbsize;
};
static inline void *gui_screen_render_buffer(struct screen *sc)
{
- if (sc->offscreenbuf)
- return sc->offscreenbuf;
- return sc->fb;
+ return fb_get_screen_base(sc->info);
}
-
#endif /* __GUI_H__ */
diff --git a/include/i2c/i2c.h b/include/i2c/i2c.h
index 4696f43e31..12e4827755 100644
--- a/include/i2c/i2c.h
+++ b/include/i2c/i2c.h
@@ -19,6 +19,8 @@
#include <driver.h>
#include <linux/types.h>
+struct i2c_adapter;
+
/*
* struct i2c_platform_data - structure of platform data for MXC I2C driver
* @param bitrate Bus speed measured in Hz
@@ -61,6 +63,47 @@ struct i2c_msg {
__u16 len; /**< Number of data bytes in @buf being read from or written to the I2C slave address. */
};
+/**
+ * struct i2c_bus_recovery_info - I2C bus recovery information
+ * @recover_bus: Recover routine. Either pass driver's recover_bus() routine, or
+ * i2c_generic_scl_recovery() or i2c_generic_gpio_recovery().
+ * @get_scl: This gets current value of SCL line. Mandatory for generic SCL
+ * recovery. Used internally for generic GPIO recovery.
+ * @set_scl: This sets/clears SCL line. Mandatory for generic SCL recovery. Used
+ * internally for generic GPIO recovery.
+ * @get_sda: This gets current value of SDA line. Optional for generic SCL
+ * recovery. Used internally, if sda_gpio is a valid GPIO, for generic GPIO
+ * recovery.
+ * @prepare_recovery: This will be called before starting recovery. Platform may
+ * configure padmux here for SDA/SCL line or something else they want.
+ * @unprepare_recovery: This will be called after completing recovery. Platform
+ * may configure padmux here for SDA/SCL line or something else they want.
+ * @scl_gpio: gpio number of the SCL line. Only required for GPIO recovery.
+ * @sda_gpio: gpio number of the SDA line. Only required for GPIO recovery.
+ */
+struct i2c_bus_recovery_info {
+ int (*recover_bus)(struct i2c_adapter *);
+
+ int (*get_scl)(struct i2c_adapter *);
+ void (*set_scl)(struct i2c_adapter *, int val);
+ int (*get_sda)(struct i2c_adapter *);
+
+ void (*prepare_recovery)(struct i2c_adapter *);
+ void (*unprepare_recovery)(struct i2c_adapter *);
+
+ /* gpio recovery */
+ int scl_gpio;
+ int sda_gpio;
+};
+
+int i2c_recover_bus(struct i2c_adapter *adap);
+
+/* Generic recovery routines */
+int i2c_get_scl_gpio_value(struct i2c_adapter *adap);
+void i2c_set_scl_gpio_value(struct i2c_adapter *adap, int val);
+int i2c_get_sda_gpio_value(struct i2c_adapter *adap);
+int i2c_generic_gpio_recovery(struct i2c_adapter *adap);
+int i2c_generic_scl_recovery(struct i2c_adapter *adap);
/**
* i2c_adapter is the structure used to identify a physical i2c bus
@@ -74,6 +117,8 @@ struct i2c_adapter {
struct list_head list;
int retries;
void *algo_data;
+
+ struct i2c_bus_recovery_info *bus_recovery_info;
};
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index f099406c53..bd2b16dd2a 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -190,6 +190,7 @@ struct spi_nor {
* @nor: the spi_nor structure
* @name: the chip type name
* @mode: the read mode supported by the driver
+ * @use_large_blocks: prefer large blocks even if 4k blocks are supported
*
* The drivers can use this fuction to scan the SPI NOR.
* In the scanning, it will try to get all the necessary information to
@@ -199,6 +200,7 @@ struct spi_nor {
*
* Return: 0 for success, others for failure.
*/
-int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode);
+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode,
+ bool use_large_blocks);
#endif
diff --git a/include/password.h b/include/password.h
index 0dd1054054..8b9961815f 100644
--- a/include/password.h
+++ b/include/password.h
@@ -26,25 +26,15 @@
#define CLEAR (1 << 2)
int password(unsigned char *passwd, size_t length, int flags, int timeout);
-
-int read_passwd(unsigned char *sum, size_t length);
-int check_passwd(unsigned char* passwd, size_t length);
-
-int read_env_passwd(unsigned char *sum, size_t length);
-int write_env_passwd(unsigned char *sum, size_t length);
-
-int read_default_passwd(unsigned char *sum, size_t length);
-int is_passwd_default_enable(void);
-int check_default_passwd(unsigned char* passwd, size_t length);
-
-int is_passwd_env_enable(void);
int passwd_env_disable(void);
-int check_env_passwd(unsigned char* passwd, size_t length);
-int set_env_passwd(unsigned char* passwd, size_t length);
+int set_env_passwd(unsigned char *passwd, size_t length);
-static inline int is_passwd_enable(void)
+#ifdef CONFIG_PASSWORD
+void login(void);
+#else
+static inline void login(void)
{
- return is_passwd_default_enable() || is_passwd_env_enable();
}
+#endif
#endif /* __PASSWORD_H__ */
diff --git a/include/spi/imx-spi.h b/include/spi/imx-spi.h
index 560b092bd2..221c66502f 100644
--- a/include/spi/imx-spi.h
+++ b/include/spi/imx-spi.h
@@ -61,6 +61,7 @@
#define CSPI_2_3_CTRL 0x08
#define CSPI_2_3_CTRL_ENABLE (1 << 0)
#define CSPI_2_3_CTRL_XCH (1 << 2)
+#define CSPI_2_3_CTRL_SMC (1 << 3)
#define CSPI_2_3_CTRL_MODE(cs) (1 << ((cs) + 4))
#define CSPI_2_3_CTRL_POSTDIV_OFFSET 8
#define CSPI_2_3_CTRL_PREDIV_OFFSET 12
@@ -78,6 +79,7 @@
#define CSPI_2_3_INT_RREN (1 << 3)
#define CSPI_2_3_STAT 0x18
-#define CSPI_2_3_STAT_RR (1 << 3)
+#define CSPI_2_3_STAT_TF (1 << 2)
+#define CSPI_2_3_STAT_RR (1 << 3)
#endif /* __SPI_IMX_SPI_H */
diff --git a/include/video/backlight.h b/include/video/backlight.h
index 56e0341ea4..8dc49dc113 100644
--- a/include/video/backlight.h
+++ b/include/video/backlight.h
@@ -1,6 +1,7 @@
#ifndef __VIDEO_BACKLIGHT_H
#define __VIDEO_BACKLIGHT_H
+#ifdef CONFIG_DRIVER_VIDEO_BACKLIGHT
struct backlight_device {
int brightness;
int brightness_cur;
@@ -16,5 +17,21 @@ int backlight_set_brightness(struct backlight_device *, int brightness);
int backlight_set_brightness_default(struct backlight_device *);
int backlight_register(struct backlight_device *);
struct backlight_device *of_backlight_find(struct device_node *node);
+#else
+struct backlight_device ;
+
+static inline int
+backlight_set_brightness(struct backlight_device *dev, int brightness)
+{
+ return 0;
+}
+static inline int
+backlight_set_brightness_default(struct backlight_device *dev)
+{
+ return 0;
+}
+static inline struct backlight_device *
+of_backlight_find(struct device_node *node) { return NULL; }
+#endif
#endif /* __VIDEO_BACKLIGHT_H */
diff --git a/include/watchdog.h b/include/watchdog.h
index fd24b5b79e..6fd896734b 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -31,12 +31,12 @@ static inline int watchdog_register(struct watchdog *w)
return 0;
}
-int watchdog_deregister(struct watchdog *w)
+static inline int watchdog_deregister(struct watchdog *w)
{
return 0;
}
-int watchdog_set_timeout(unsigned t)
+static inline int watchdog_set_timeout(unsigned t)
{
return 0;
}
diff --git a/lib/gui/graphic_utils.c b/lib/gui/graphic_utils.c
index 47003a0837..4c1885d55b 100644
--- a/lib/gui/graphic_utils.c
+++ b/lib/gui/graphic_utils.c
@@ -245,7 +245,7 @@ void gu_rgba_blend(struct fb_info *info, struct image *img, void* buf, int heigh
}
}
-struct screen *fb_create_screen(struct fb_info *info, bool offscreen)
+struct screen *fb_create_screen(struct fb_info *info)
{
struct screen *sc;
@@ -257,19 +257,12 @@ struct screen *fb_create_screen(struct fb_info *info, bool offscreen)
sc->s.height = info->yres;
sc->fbsize = info->line_length * sc->s.height;
sc->fb = info->screen_base;
-
- if (offscreen) {
- /*
- * Don't fail if malloc fails, just continue rendering directly
- * on the framebuffer
- */
- sc->offscreenbuf = malloc(sc->fbsize);
- }
+ sc->info = info;
return sc;
}
-struct screen *fb_open(const char * fbdev, bool offscreen)
+struct screen *fb_open(const char * fbdev)
{
int fd, ret;
struct fb_info *info;
@@ -281,12 +274,12 @@ struct screen *fb_open(const char * fbdev, bool offscreen)
info = xzalloc(sizeof(*info));
- ret = ioctl(fd, FBIOGET_SCREENINFO, info);
+ ret = ioctl(fd, FBIOGET_SCREENINFO, &info);
if (ret) {
goto failed_screeninfo;
}
- sc = fb_create_screen(info, offscreen);
+ sc = fb_create_screen(info);
if (IS_ERR(sc)) {
ret = PTR_ERR(sc);
goto failed_create;
@@ -298,7 +291,6 @@ struct screen *fb_open(const char * fbdev, bool offscreen)
return sc;
failed_create:
- free(sc->offscreenbuf);
free(sc);
failed_screeninfo:
close(fd);
@@ -308,20 +300,35 @@ failed_screeninfo:
void fb_close(struct screen *sc)
{
- free(sc->offscreenbuf);
-
- if (sc->fd > 0) {
+ if (sc->fd > 0)
close(sc->fd);
- free(sc->info);
- }
free(sc);
}
+void gu_screen_blit_area(struct screen *sc, int startx, int starty, int width,
+ int height)
+{
+ struct fb_info *info = sc->info;
+ int bpp = info->bits_per_pixel >> 3;
+
+ if (info->screen_base_shadow) {
+ int y;
+ void *fb = info->screen_base + starty * sc->info->line_length + startx * bpp;
+ void *fboff = info->screen_base_shadow + starty * sc->info->line_length + startx * bpp;
+
+ for (y = starty; y < starty + height; y++) {
+ memcpy(fb, fboff, width * bpp);
+ fb += sc->info->line_length;
+ fboff += sc->info->line_length;
+ }
+ }
+}
+
void gu_screen_blit(struct screen *sc)
{
- if (!sc->offscreenbuf)
- return;
+ struct fb_info *info = sc->info;
- memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
+ if (info->screen_base_shadow)
+ memcpy(info->screen_base, info->screen_base_shadow, sc->fbsize);
}
diff --git a/lib/libfile.c b/lib/libfile.c
index ba03700aba..a27460c10d 100644
--- a/lib/libfile.c
+++ b/lib/libfile.c
@@ -262,7 +262,7 @@ int copy_file(const char *src, const char *dst, int verbose)
char *rw_buf = NULL;
int srcfd = 0, dstfd = 0;
int r, w;
- int ret = 1;
+ int ret = 1, err1 = 0;
void *buf;
int total = 0;
struct stat statbuf;
@@ -326,9 +326,9 @@ out:
if (srcfd > 0)
close(srcfd);
if (dstfd > 0)
- close(dstfd);
+ err1 = close(dstfd);
- return ret;
+ return ret ?: err1;
}
EXPORT_SYMBOL(copy_file);