diff options
Diffstat (limited to 'drivers')
44 files changed, 621 insertions, 64 deletions
diff --git a/drivers/aiodev/mc13xxx_adc.c b/drivers/aiodev/mc13xxx_adc.c index 4e72048169..d445d1ec6e 100644 --- a/drivers/aiodev/mc13xxx_adc.c +++ b/drivers/aiodev/mc13xxx_adc.c @@ -75,8 +75,9 @@ to_mc13xx_adc_data(struct aiochannel *chan) return container_of(chan->aiodev, struct mc13xx_adc_data, aiodev); } -int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, - unsigned int channel, unsigned int *sample) +static int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, + unsigned int channel, + unsigned int *sample) { int i; int timeout = 100; diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 4acc4cfa1e..1fd890542e 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -177,7 +177,7 @@ int register_device(struct device_d *new_device) new_device->id = get_free_deviceid(new_device->name); } else { if (get_device_by_name_id(new_device->name, new_device->id)) { - eprintf("register_device: already registered %s\n", + pr_err("register_device: already registered %s\n", dev_name(new_device)); return -EINVAL; } diff --git a/drivers/bus/omap-gpmc.c b/drivers/bus/omap-gpmc.c index be9ef92851..a3fccb2182 100644 --- a/drivers/bus/omap-gpmc.c +++ b/drivers/bus/omap-gpmc.c @@ -187,7 +187,7 @@ static unsigned int gpmc_ns_to_ticks(unsigned int time_ns) return (time_ns * 1000 + tick_ps - 1) / tick_ps; } -int gpmc_calc_divider(unsigned int sync_clk) +static int gpmc_calc_divider(unsigned int sync_clk) { int div; u32 l; diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 24759b45bb..6a2d8ad178 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -413,7 +413,7 @@ int of_clk_add_provider(struct device_node *np, cp->get = clk_src_get; list_add(&cp->link, &of_clk_providers); - pr_debug("Added clock from %s\n", np->full_name); + pr_debug("Added clock from %s\n", np ? np->full_name : "<none>"); return 0; } diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c index 5ac0ed1789..473500131e 100644 --- a/drivers/clk/imx/clk-cpu.c +++ b/drivers/clk/imx/clk-cpu.c @@ -111,8 +111,10 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name, cpu->clk.num_parents = 1; ret = clk_register(&cpu->clk); - if (ret) + if (ret) { free(cpu); + return NULL; + } return &cpu->clk; } diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index f2e704cdb2..8d5ed7e05c 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -87,7 +87,7 @@ static struct clk_ops clk_gate2_ops = { .is_enabled = clk_gate2_is_enabled, }; -struct clk *clk_gate2_alloc(const char *name, const char *parent, +static struct clk *clk_gate2_alloc(const char *name, const char *parent, void __iomem *reg, u8 shift, u8 cgr_val, unsigned long flags) { @@ -106,13 +106,6 @@ struct clk *clk_gate2_alloc(const char *name, const char *parent, return &g->clk; } -void clk_gate2_free(struct clk *clk) -{ - struct clk_gate2 *g = to_clk_gate2(clk); - - free(g); -} - struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg, u8 shift, u8 cgr_val, unsigned long flags) { diff --git a/drivers/clk/imx/clk-imx5.c b/drivers/clk/imx/clk-imx5.c index ae94e07f23..f59a41b001 100644 --- a/drivers/clk/imx/clk-imx5.c +++ b/drivers/clk/imx/clk-imx5.c @@ -60,6 +60,7 @@ #define CCM_CMEOR 0x84 static struct clk *clks[IMX5_CLK_END]; +static struct clk_onecell_data clk_data; /* This is used multiple times */ static const char *standard_pll_sel[] = { @@ -411,6 +412,10 @@ static int imx51_ccm_probe(struct device_d *dev) mx51_clocks_init(dev, regs); + clk_data.clks = clks; + clk_data.clk_num = IMX5_CLK_END; + of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data); + return 0; } @@ -503,6 +508,10 @@ static int imx53_ccm_probe(struct device_d *dev) mx53_clocks_init(dev, regs); + clk_data.clks = clks; + clk_data.clk_num = IMX5_CLK_END; + of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data); + return 0; } diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 3caf72503a..337a7a2e13 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -1,3 +1,5 @@ +menu "Clocksource" + config ARCH_HAS_IMX_GPT bool @@ -80,3 +82,10 @@ config CLOCKSOURCE_ARM_GLOBAL_TIMER config CLOCKSOURCE_IMX_GPT def_bool y depends on ARCH_HAS_IMX_GPT + +config CLOCKSOURCE_DW_APB_TIMER + bool "DW APB timer driver" + help + Enables the support for the dw_apb timer. + +endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index ce4d74137a..ab78f0700d 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += timer-atmel-pit.o obj-$(CONFIG_CLOCKSOURCE_ARMV8_TIMER) += armv8-timer.o obj-$(CONFIG_CLOCKSOURCE_ARM_GLOBAL_TIMER) += arm_global_timer.o obj-$(CONFIG_CLOCKSOURCE_IMX_GPT) += timer-imx-gpt.o +obj-$(CONFIG_CLOCKSOURCE_DW_APB_TIMER) += dw_apb_timer.o diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c new file mode 100644 index 0000000000..82ad6bccbc --- /dev/null +++ b/drivers/clocksource/dw_apb_timer.c @@ -0,0 +1,148 @@ +/* + * (C) Copyright 2009 Intel Corporation + * Author: Jacob Pan (jacob.jun.pan@intel.com) + * + * Shared with ARM platforms, Jamie Iles, Picochip 2011 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Support for the Synopsys DesignWare APB Timers. + * + * + * Taken from linux-4.9 kernel and adapted to barebox. + */ +#include <common.h> +#include <clock.h> +#include <init.h> + +#include <linux/clk.h> +#include <linux/err.h> + +#define APBT_MIN_PERIOD 4 +#define APBT_MIN_DELTA_USEC 200 + +#define APBTMR_N_LOAD_COUNT 0x00 +#define APBTMR_N_CURRENT_VALUE 0x04 +#define APBTMR_N_CONTROL 0x08 +#define APBTMR_N_EOI 0x0c +#define APBTMR_N_INT_STATUS 0x10 + +#define APBTMRS_INT_STATUS 0xa0 +#define APBTMRS_EOI 0xa4 +#define APBTMRS_RAW_INT_STATUS 0xa8 +#define APBTMRS_COMP_VERSION 0xac + +#define APBTMR_CONTROL_ENABLE (1 << 0) +/* 1: periodic, 0:free running. */ +#define APBTMR_CONTROL_MODE_PERIODIC (1 << 1) +#define APBTMR_CONTROL_INT (1 << 2) + +#define APBTMRS_REG_SIZE 0x14 + +struct dw_apb_timer { + void __iomem *base; + unsigned long freq; + int irq; +}; + +static struct dw_apb_timer timer; + +static inline u32 apbt_readl(struct dw_apb_timer *timer, unsigned long offs) +{ + return readl(timer->base + offs); +} + +static inline void apbt_writel(struct dw_apb_timer *timer, u32 val, + unsigned long offs) +{ + writel(val, timer->base + offs); +} + +/** + * dw_apb_clocksource_start() - start the clocksource counting. + * + * @clksrc: The clocksource to start. + * + * This is used to start the clocksource before registration and can be used + * to enable calibration of timers. + */ +static int dw_apb_clocksource_start(struct clocksource *clksrc) +{ + /* + * start count down from 0xffff_ffff. this is done by toggling the + * enable bit then load initial load count to ~0. + */ + uint32_t ctrl = apbt_readl(&timer, APBTMR_N_CONTROL); + + ctrl &= ~APBTMR_CONTROL_ENABLE; + apbt_writel(&timer, ctrl, APBTMR_N_CONTROL); + apbt_writel(&timer, ~0, APBTMR_N_LOAD_COUNT); + + /* enable, mask interrupt */ + ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; + ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT); + apbt_writel(&timer, ctrl, APBTMR_N_CONTROL); + + return 0; +} + +static uint64_t dw_apb_clocksource_read(void) +{ + return (uint64_t) ~apbt_readl(&timer, APBTMR_N_CURRENT_VALUE); +} + +static struct clocksource dw_apb_clksrc = { + .init = dw_apb_clocksource_start, + .read = dw_apb_clocksource_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 0, +}; + +static int dw_apb_timer_probe(struct device_d *dev) +{ + struct device_node *np = dev->device_node; + struct resource *iores; + struct clk *clk; + uint32_t clk_freq; + + /* use only one timer */ + if (timer.base) + return -EBUSY; + + iores = dev_request_mem_resource(dev, 0); + if (IS_ERR(iores)) { + dev_err(dev, "could not get memory region\n"); + return PTR_ERR(iores); + } + + timer.base = IOMEM(iores->start); + + /* Get clock frequency */ + clk = of_clk_get(np, 0); + if (IS_ERR(clk)) { + pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); + return PTR_ERR(clk); + } + + clk_freq = clk_get_rate(clk); + clk_put(clk); + + dw_apb_clksrc.mult = clocksource_hz2mult(clk_freq, dw_apb_clksrc.shift); + + return init_clock(&dw_apb_clksrc); +} + +static struct of_device_id dw_apb_timer_dt_ids[] = { + { .compatible = "snps,dw-apb-timer", }, + { } +}; + +static struct driver_d dw_apb_timer_driver = { + .name = "dw-apb-timer", + .probe = dw_apb_timer_probe, + .of_compatible = DRV_OF_COMPAT(dw_apb_timer_dt_ids), +}; + +device_platform_driver(dw_apb_timer_driver); diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index 2ab509d110..56b90700b8 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -33,3 +33,27 @@ config CRYPTO_DEV_FSL_CAAM_RNG default y help Selecting this will register the SEC4 hardware rng. + +if CRYPTO_DEV_FSL_CAAM_RNG + +config CRYPTO_DEV_FSL_CAAM_RNG_SELF_TEST + bool "Run RNG software self-test on impacted chips" + depends on ARCH_IMX6 + depends on HABV4 + default y + help + Some chips with HAB >= 4.2.3 have an incorrect implementation of the + RNG self-test in ROM code. In this case, a software self-test should + be run to ensure correctness of the RNG. By enabling this config + option, the software self-test is run automatically when this case + is detected. + + Currently known impacted chips: + * i.MX6DQ+ silicon revision 1.1 + * i.MX6DQ silicon revision 1.6 + * i.MX6DLS silicon revision 1.4 + * i.MX6SX silicon revision 1.4 + * i.MX6UL silicon revision 1.2 + * i.MX67SD silicon revision 1.3 + +endif diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile index 74d32da00e..7bd6f3e23c 100644 --- a/drivers/crypto/caam/Makefile +++ b/drivers/crypto/caam/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += ctrl.o error.o jr.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG) += caamrng.o +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_SELF_TEST) += rng_self_test.o diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 9e62bd6fd6..39910131b1 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -8,6 +8,7 @@ #include <common.h> #include <clock.h> #include <driver.h> +#include <hab.h> #include <init.h> #include <linux/barebox-wrapper.h> #include <linux/spinlock.h> @@ -19,6 +20,7 @@ #include "desc_constr.h" #include "error.h" #include "ctrl.h" +#include "rng_self_test.h" bool caam_little_end; EXPORT_SYMBOL(caam_little_end); @@ -570,6 +572,24 @@ static int caam_probe(struct device_d *dev) cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls); + /* habv4_need_rng_software_self_test is determined by habv4_get_status() */ + if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_SELF_TEST) && + habv4_need_rng_software_self_test) { + u8 caam_era; + u8 rngvid; + u8 rngrev; + + caam_era = (rd_reg32(&ctrl->perfmon.ccb_id) & CCBVID_ERA_MASK) >> CCBVID_ERA_SHIFT; + rngvid = (cha_vid_ls & CHAVID_LS_RNGVID_MASK) >> CHAVID_LS_RNGVID_SHIFT; + rngrev = (rd_reg32(&ctrl->perfmon.cha_rev_ls) & CRNR_LS_RNGRN_MASK) >> CRNR_LS_RNGRN_SHIFT; + + ret = caam_rng_self_test(ctrlpriv->jrpdev[0], caam_era, rngvid, rngrev); + if (ret != 0) { + caam_remove(dev); + return ret; + } + } + /* * If SEC has RNG version >= 4 and RNG state handle has not been * already instantiated, do RNG instantiation diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index 6c9d6d75a0..19e7d6d7e4 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -279,6 +279,8 @@ struct caam_perfmon { /* CAAM Hardware Instantiation Parameters fa0-fbf */ u32 cha_rev_ms; /* CRNR - CHA Rev No. Most significant half*/ +#define CRNR_LS_RNGRN_SHIFT 16 +#define CRNR_LS_RNGRN_MASK (0xfull << CRNR_LS_RNGRN_SHIFT) u32 cha_rev_ls; /* CRNR - CHA Rev No. Least significant half*/ #define CTPR_MS_QI_SHIFT 25 #define CTPR_MS_QI_MASK (0x1ull << CTPR_MS_QI_SHIFT) @@ -311,6 +313,8 @@ struct caam_perfmon { #define CCBVID_ERA_SHIFT 24 u32 ccb_id; /* CCBVID - CCB Version ID */ u32 cha_id_ms; /* CHAVID - CHA Version ID Most Significant*/ +#define CHAVID_LS_RNGVID_SHIFT 16 +#define CHAVID_LS_RNGVID_MASK (0xfull << CHAVID_LS_RNGVID_SHIFT) u32 cha_id_ls; /* CHAVID - CHA Version ID Least Significant*/ u32 cha_num_ms; /* CHANUM - CHA Number Most Significant */ u32 cha_num_ls; /* CHANUM - CHA Number Least Significant*/ diff --git a/drivers/crypto/caam/rng_self_test.c b/drivers/crypto/caam/rng_self_test.c new file mode 100644 index 0000000000..aab4fa2e47 --- /dev/null +++ b/drivers/crypto/caam/rng_self_test.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2018 NXP + * Copyright (C) 2018 Pengutronix, Roland Hieber <r.hieber@pengutronix.de> + * + * CAAM RNG self-test -- based on the vendor patch for U-Boot: + * https://portland.source.codeaurora.org/patches/external/imxsupport/uboot-imx/imx_v2016.03_4.1.15_2.0.0_ga/HAB-238-Run-RNG-self-test-for-impacted-i.MX-chips.zip + * + * | From: Utkarsh Gupta <utkarsh.gupta@nxp.com> + * | Subject: [PATCH] HAB-238 Run RNG self test for impacted i.MX chips + * | + * | Patch is only applicable to imx_v2016.03_4.1.15_2.0.0_ga branch of u-boot. + * | Please adapt the patch for your respective release version. + * | + * | Background: + * | Few i.MX chips which have HAB 4.2.3 or beyond, have oberserved following + * | warning message generated by HAB due to incorrect implementation of drng + * | self test in boot ROM. + * | + * | Event |0xdb|0x0024|0x42| SRCE Field: 69 30 e1 1d + * | | | | | STS = HAB_WARNING (0x69) + * | | | | | RSN = HAB_ENG_FAIL (0x30) + * | | | | | CTX = HAB_CTX_ENTRY (0xE1) + * | | | | | ENG = HAB_ENG_CAAM (0x1D) + * | | | | | Evt Data (hex): + * | | | | | 00 08 00 02 40 00 36 06 55 55 00 03 00 00 00 00 + * | | | | | 00 00 00 00 00 00 00 00 00 00 00 01 + * | + * | It is recommended to run this rng self test before any RNG related crypto + * | implementations are done. + * [...] + * | + * | Signed-off-by: Utkarsh Gupta <utkarsh.gupta@nxp.com> + * + * Known impacted chips: + * + * - i.MX6DQ+ silicon revision 1.1 + * - i.MX6DQ silicon revision 1.6 + * - i.MX6DLS silicon revision 1.4 + * - i.MX6SX silicon revision 1.4 + * - i.MX6UL silicon revision 1.2 + * - i.MX67SD silicon revision 1.3 + */ + +#define pr_fmt(fmt) "rng_self_test: " fmt + +#include <dma.h> +#include <common.h> +#include <linux/kernel.h> + +#include "error.h" +#include "regs.h" +#include "jr.h" + +static const u32 rng_dsc1[] = { + 0xb0800036, 0x04800010, 0x3c85a15b, 0x50a9d0b1, + 0x71a09fee, 0x2eecf20b, 0x02800020, 0xb267292e, + 0x85bf712d, 0xe85ff43a, 0xa716b7fb, 0xc40bb528, + 0x27b6f564, 0x8821cb5d, 0x9b5f6c26, 0x12a00020, + 0x0a20de17, 0x6529357e, 0x316277ab, 0x2846254e, + 0x34d23ba5, 0x6f5e9c32, 0x7abdc1bb, 0x0197a385, + 0x82500405, 0xa2000001, 0x10880004, 0x00000005, + 0x12820004, 0x00000020, 0x82500001, 0xa2000001, + 0x10880004, 0x40000045, 0x02800020, 0x8f389cc7, + 0xe7f7cbb0, 0x6bf2073d, 0xfc380b6d, 0xb22e9d1a, + 0xee64fcb7, 0xa2b48d49, 0xdf9bc3a4, 0x82500009, + 0xa2000001, 0x10880004, 0x00000005, 0x82500001, + 0x60340020, 0xFFFFFFFF, 0xa2000001, 0x10880004, + 0x00000005, 0x8250000d +}; + +static const u8 rng_result1[] = { + 0x3a, 0xfe, 0x2c, 0x87, 0xcc, 0xb6, 0x44, 0x49, + 0x19, 0x16, 0x9a, 0x74, 0xa1, 0x31, 0x8b, 0xef, + 0xf4, 0x86, 0x0b, 0xb9, 0x5e, 0xee, 0xae, 0x91, + 0x92, 0xf4, 0xa9, 0x8f, 0xb0, 0x37, 0x18, 0xa4 +}; + +static const u32 rng_dsc2[] = { + 0xb080003a, 0x04800020, 0x27b73130, 0x30b4b10f, + 0x7c62b1ad, 0x77abe899, 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476, 0x02800020, 0x63f757cf, + 0xb9165584, 0xc3c1b407, 0xcc4ce8ad, 0x1ffe8a58, + 0xfb4fa893, 0xbb5f4af0, 0x3fb946a1, 0x12a00020, + 0x56cbcaa5, 0xfff3adad, 0xe804dcbf, 0x9a900c71, + 0xa42017e3, 0x826948e2, 0xd0cfeb3e, 0xaf1a136a, + 0x82500405, 0xa2000001, 0x10880004, 0x00000005, + 0x12820004, 0x00000020, 0x82500001, 0xa2000001, + 0x10880004, 0x40000045, 0x02800020, 0x2e882f8a, + 0xe929943e, 0x8132c0a8, 0x12037f90, 0x809fbd66, + 0x8684ea04, 0x00cbafa7, 0x7b82d12a, 0x82500009, + 0xa2000001, 0x10880004, 0x00000005, 0x82500001, + 0x60340020, 0xFFFFFFFF, 0xa2000001, 0x10880004, + 0x00000005, 0x8250000d +}; + +static const u8 rng_result2[] = { + 0x76, 0x87, 0x66, 0x4e, 0xd8, 0x1d, 0x1f, 0x43, + 0x76, 0x50, 0x85, 0x5d, 0x1e, 0x1d, 0x9d, 0x0f, + 0x93, 0x75, 0x83, 0xff, 0x9a, 0x9b, 0x61, 0xa9, + 0xa5, 0xeb, 0xa3, 0x28, 0x2a, 0x15, 0xc1, 0x57 +}; + +/* + * construct_rng_self_test_jobdesc() - Implement destination address in RNG self test descriptors + * Returns zero on success, and negative on error. + */ +static void construct_rng_self_test_jobdesc(u32 *desc, const u32 *rng_st_dsc, u8 *res_addr, int desc_size) +{ + int result_addr_idx = desc_size - 5; + int i; + + for (i = 0; i < desc_size; i++) { + desc[i] = rng_st_dsc[i]; + } + + /* Replace destination address in the descriptor */ + desc[result_addr_idx] = (u32)res_addr; +} + +/* rng_self_test_done() - callback for caam_jr_enqueue */ +static void rng_self_test_done(struct device_d *dev, u32 *desc, u32 err, void *arg) +{ + int * job_err = arg; + *job_err = err; +} + +/* + * caam_rng_self_test() - Perform RNG self test + * Returns zero on success, and negative on error. + */ +int caam_rng_self_test(struct device_d *dev, const u8 caam_era, const u8 rngvid, const u8 rngrev) +{ + int ret, desc_size = 0, result_size = 0, job_err = 0; + const u32 *rng_st_dsc; + const u8 *exp_result; + u32 *desc; + u8 *result; + + pr_debug("got CAAM ERA %d, RNG Version ID %d, RNG revision %d\n", + caam_era, rngvid, rngrev); + + if (caam_era < 8 && rngvid == 4 && rngrev < 3) { + /* older affected i.MX chipsets have CAAM < 8 and have RNG4 < 4.3 */ + rng_st_dsc = rng_dsc1; + desc_size = ARRAY_SIZE(rng_dsc1); + exp_result = rng_result1; + result_size = ARRAY_SIZE(rng_result1); + } else if (caam_era >= 8 || (rngvid >= 4 && rngrev >= 3)) { + /* newer affected chipsets have CAAM >= 8 or RNG4 >= 4.3 */ + rng_st_dsc = rng_dsc2; + desc_size = ARRAY_SIZE(rng_dsc2); + exp_result = rng_result2; + result_size = ARRAY_SIZE(rng_result2); + } else { + pr_err("Invalid CAAM version: %d,%d,%d\n", + caam_era, rngvid, rngrev); + return -EINVAL; + } + + result = dma_alloc(sizeof(*result) * result_size); + desc = dma_alloc(sizeof(*desc) * desc_size); + + if (!result || !desc) { + ret = -ENOMEM; + goto err; + } + + construct_rng_self_test_jobdesc(desc, rng_st_dsc, result, desc_size); + + dma_sync_single_for_device((unsigned long)desc, + desc_size * sizeof(*desc), DMA_TO_DEVICE); + dma_sync_single_for_device((unsigned long)result, + result_size * sizeof(*result), DMA_FROM_DEVICE); + + /* wait for job completion */ + ret = caam_jr_enqueue(dev, desc, rng_self_test_done, &job_err); + if (ret) { + pr_err("Running RNG self-test descriptor failed: %d %s\n", + ret, strerror(ret)); + goto err; + } + if (job_err) { + ret = -EINVAL; + pr_err("Job Error:\n"); + caam_jr_strstatus(dev, job_err); + goto err; + } + + dma_sync_single_for_cpu((unsigned long)result, result_size * sizeof(*result), + DMA_FROM_DEVICE); + + if (memcmp(result, exp_result, sizeof(*result) * result_size) != 0) { + pr_err("RNG self-test failed with unexpected result\n"); + ret = -ERANGE; + goto err; + } + + pr_info("RNG software self-test passed\n"); + ret = 0; + +err: + dma_free(desc); + dma_free(result); + return ret; +} diff --git a/drivers/crypto/caam/rng_self_test.h b/drivers/crypto/caam/rng_self_test.h new file mode 100644 index 0000000000..1f5bf32628 --- /dev/null +++ b/drivers/crypto/caam/rng_self_test.h @@ -0,0 +1,24 @@ +/* + * CAAM RNG self test + * + * Copyright (C) 2018 Pengutronix, Roland Hieber <r.hieber@pengutronix.de> + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * 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 RNG_SELF_TEST_H +#define RNG_SELF_TEST_H + +int caam_rng_self_test(struct device_d *dev, const u8 caam_era, const u8 rngvid, const u8 rngrev); + +#endif /* RNG_SELF_TEST_H */ diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c index 79f25109f9..72c2f364c5 100644 --- a/drivers/dma/apbh_dma.c +++ b/drivers/dma/apbh_dma.c @@ -67,7 +67,7 @@ static struct apbh_dma *apbh_dma; /* * Test is the DMA channel is valid channel */ -int mxs_dma_validate_chan(int channel) +static int mxs_dma_validate_chan(int channel) { struct mxs_dma_chan *pchan; diff --git a/drivers/hab/habv3.c b/drivers/hab/habv3.c index 82ae245f8a..47d3caf864 100644 --- a/drivers/hab/habv3.c +++ b/drivers/hab/habv3.c @@ -78,5 +78,9 @@ int imx_habv3_get_status(uint32_t status) int imx25_hab_get_status(void) { + if (!cpu_is_mx25()) + return 0; + return imx_habv3_get_status(readl(IOMEM(0x780018d4))); } +postmmu_initcall(imx25_hab_get_status); diff --git a/drivers/hab/habv4.c b/drivers/hab/habv4.c index 28fd42ecd7..ca95c01e7b 100644 --- a/drivers/hab/habv4.c +++ b/drivers/hab/habv4.c @@ -20,6 +20,7 @@ #include <common.h> #include <hab.h> +#include <init.h> #include <types.h> #include <mach/generic.h> @@ -387,6 +388,39 @@ static void habv4_display_event(uint8_t *data, uint32_t len) habv4_display_event_record((struct hab_event_record *)data); } +/* Some chips with HAB >= 4.2.3 have an incorrect implementation of the RNG + * self-test in ROM code. In this case, an HAB event is generated, and a + * software self-test should be run. This variable is set to @c true by + * habv4_get_status() when this occurs. */ +bool habv4_need_rng_software_self_test = false; +EXPORT_SYMBOL(habv4_need_rng_software_self_test); + +#define RNG_FAIL_EVENT_SIZE 36 +static uint8_t habv4_known_rng_fail_events[][RNG_FAIL_EVENT_SIZE] = { + { 0xdb, 0x00, 0x24, 0x42, 0x69, 0x30, 0xe1, 0x1d, + 0x00, 0x80, 0x00, 0x02, 0x40, 0x00, 0x36, 0x06, + 0x55, 0x55, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 }, + { 0xdb, 0x00, 0x24, 0x42, 0x69, 0x30, 0xe1, 0x1d, + 0x00, 0x04, 0x00, 0x02, 0x40, 0x00, 0x36, 0x06, + 0x55, 0x55, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01 }, +}; + +static bool is_known_rng_fail_event(const uint8_t *data, size_t len) +{ + int i; + for (i = 0; i < ARRAY_SIZE(habv4_known_rng_fail_events); i++) { + if (memcmp(data, habv4_known_rng_fail_events[i], + min(len, (uint32_t)RNG_FAIL_EVENT_SIZE)) == 0) { + return true; + } + } + return false; +} + static int habv4_get_status(const struct habv4_rvt *rvt) { uint8_t data[256]; @@ -413,10 +447,18 @@ static int habv4_get_status(const struct habv4_rvt *rvt) len = sizeof(data); while (rvt->report_event(HAB_STATUS_WARNING, index, data, &len) == HAB_STATUS_SUCCESS) { - pr_err("-------- HAB warning Event %d --------\n", index); - pr_err("event data:\n"); - habv4_display_event(data, len); + /* suppress RNG self-test fail events if they can be handled in software */ + if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_SELF_TEST) && + is_known_rng_fail_event(data, len)) { + pr_debug("RNG self-test failure detected, will run software self-test\n"); + habv4_need_rng_software_self_test = true; + } else { + pr_err("-------- HAB warning Event %d --------\n", index); + pr_err("event data:\n"); + habv4_display_event(data, len); + } + len = sizeof(data); index++; } @@ -460,9 +502,54 @@ int imx6_hab_get_status(void) return -EINVAL; } +static int init_imx6_hab_get_status(void) +{ + int ret = 0; + + if (!cpu_is_mx6()) + /* can happen in multi-image builds and is not an error */ + return 0; + + ret = imx6_hab_get_status(); + + /* + * Nobody will check the return value if there were HAB errors, but the + * initcall will fail spectaculously with a strange error message. + */ + if (ret == -EPERM) + return 0; + return ret; +} + +/* + * Need to run before MMU setup because i.MX6 ROM code is mapped near 0x0, + * which will no longer be accessible when the MMU sets the zero page to + * faulting. + */ +postconsole_initcall(init_imx6_hab_get_status); + int imx28_hab_get_status(void) { const struct habv4_rvt *rvt = (void *)HABV4_RVT_IMX28; return habv4_get_status(rvt); } + +static int init_imx28_hab_get_status(void) +{ + int ret = 0; + + if (!cpu_is_mx28()) + /* can happen in multi-image builds and is not an error */ + return 0; + + ret = imx28_hab_get_status(); + + /* nobody will check the return value if there were HAB errors, but the + * initcall will fail spectaculously with a strange error message. */ + if (ret == -EPERM) + return 0; + return ret; +} +/* i.MX28 ROM code can be run after MMU setup to make use of caching */ +postmmu_initcall(init_imx28_hab_get_status); diff --git a/drivers/mfd/da9063.c b/drivers/mfd/da9063.c index b6114a614b..a7fff2c5bf 100644 --- a/drivers/mfd/da9063.c +++ b/drivers/mfd/da9063.c @@ -201,7 +201,7 @@ static int da9062_device_init(struct da9063 *priv) priv->client1 = i2c_new_dummy(priv->client->adapter, priv->client->addr + 1); - if (!priv) { + if (!priv->client1) { dev_warn(priv->dev, "failed to create bank 1 device\n"); /* TODO: return -EINVAL; i2c api does not return more * details */ diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 797cdc2ba6..4c1725d096 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -788,7 +788,6 @@ static int pmecc_build_galois_table(unsigned int mm, int16_t *index_of, case 3: case 4: case 6: - case 15: p[1] = 1; break; case 5: diff --git a/drivers/mtd/nand/nand_denali.c b/drivers/mtd/nand/nand_denali.c index c530a80bde..2561966243 100644 --- a/drivers/mtd/nand/nand_denali.c +++ b/drivers/mtd/nand/nand_denali.c @@ -1387,7 +1387,7 @@ int denali_init(struct denali_nand_info *denali) } /* allocate a temporary buffer for nand_scan_ident() */ - denali->buf.buf = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL); + denali->buf.buf = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!denali->buf.buf) return -ENOMEM; diff --git a/drivers/mtd/nand/nand_omap_bch_decoder.c b/drivers/mtd/nand/nand_omap_bch_decoder.c index 64e8031785..4dd28a7704 100644 --- a/drivers/mtd/nand/nand_omap_bch_decoder.c +++ b/drivers/mtd/nand/nand_omap_bch_decoder.c @@ -15,6 +15,8 @@ #include <common.h> +#include "nand_omap_bch_decoder.h" + #define mm 13 #define kk_shorten 4096 #define nn 8191 /* Length of codeword, n = 2**mm - 1 */ diff --git a/drivers/mtd/nand/nand_omap_bch_decoder.h b/drivers/mtd/nand/nand_omap_bch_decoder.h new file mode 100644 index 0000000000..74d24be028 --- /dev/null +++ b/drivers/mtd/nand/nand_omap_bch_decoder.h @@ -0,0 +1,6 @@ +#ifndef MTD_OMAP_GPMC_DECODE_BCH_H +#define MTD_OMAP_GPMC_DECODE_BCH_H + +int omap_gpmc_decode_bch(int select_4_8, unsigned char *ecc, unsigned int *err_loc); + +#endif /* MTD_OMAP_GPMC_DECODE_BCH_H */
\ No newline at end of file diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c index d0b1699839..323a9c7532 100644 --- a/drivers/mtd/nand/nand_omap_gpmc.c +++ b/drivers/mtd/nand/nand_omap_gpmc.c @@ -71,6 +71,8 @@ #include <mach/gpmc.h> #include <mach/gpmc_nand.h> +#include "nand_omap_bch_decoder.h" + #define GPMC_ECC_CONFIG_ECCENABLE (1 << 0) #define GPMC_ECC_CONFIG_ECCCS(x) (((x) & 0x7) << 1) #define GPMC_ECC_CONFIG_ECCTOPSECTOR(x) (((x) & 0x7) << 4) @@ -90,8 +92,6 @@ static const uint8_t bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc, 0xac, 0x6b, 0xff, 0x99, 0x7b}; -int omap_gpmc_decode_bch(int select_4_8, unsigned char *ecc, unsigned int *err_loc); - static const char *ecc_mode_strings[] = { "software", "hamming_hw_romcode", diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index c6fc21dc54..6de9851fda 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -1093,8 +1093,8 @@ static int cpsw_probe_dt(struct cpsw_priv *priv) if (!of_find_node_by_name(child, "fixed-link")) { ret = of_property_read_u32_array(child, "phy_id", phy_id, 2); - if (ret) - return ret; + if (!ret) + dev_warn(dev, "phy_id is deprecated, use phy-handle\n"); } slave->dev.device_node = child; @@ -1115,7 +1115,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv) return 0; } -int cpsw_probe(struct device_d *dev) +static int cpsw_probe(struct device_d *dev) { struct resource *iores; struct cpsw_platform_data *data = (struct cpsw_platform_data *)dev->platform_data; diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c index 180b32ede8..c0f2db552a 100644 --- a/drivers/net/e1000/eeprom.c +++ b/drivers/net/e1000/eeprom.c @@ -407,7 +407,7 @@ static void e1000_eeprom_uses_microwire(struct e1000_eeprom_info *eeprom, eeprom->read = e1000_read_eeprom_microwire; } -size_t e1000_igb_get_flash_size(struct e1000_hw *hw) +static size_t e1000_igb_get_flash_size(struct e1000_hw *hw) { struct device_node *node = hw->pdev->dev.device_node; @@ -883,7 +883,7 @@ static int e1000_flash_mode_erase_chunk(struct e1000_hw *hw, loff_t offset, ret = e1000_poll_reg(hw, E1000_FLSWCTL, E1000_FLSWCTL_DONE | E1000_FLSWCTL_FLBUSY, E1000_FLSWCTL_DONE, - 10 * SECOND); + 40 * SECOND); if (ret < 0) { dev_err(hw->dev, "Timeout waiting for FLSWCTL.DONE to be set (erase)\n"); @@ -1504,7 +1504,7 @@ static int e1000_mtd_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) return e1000_mtd_sr_rmw(mtd, SR_BPALL, 0x0); } -int e1000_register_invm(struct e1000_hw *hw) +static int e1000_register_invm(struct e1000_hw *hw) { int ret; u16 word; diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index bb6ab4eb03..caa7274a8d 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -1130,7 +1130,7 @@ static int32_t e1000_set_d3_lplu_state_off(struct e1000_hw *hw) { uint32_t phy_ctrl = 0; int32_t ret_val; - uint16_t phy_data; + uint16_t phy_data = 0; DEBUGFUNC(); /* During driver activity LPLU should not be used or it will attain link diff --git a/drivers/nvmem/ocotp.c b/drivers/nvmem/ocotp.c index e689559ee3..e0cf35f0b7 100644 --- a/drivers/nvmem/ocotp.c +++ b/drivers/nvmem/ocotp.c @@ -70,6 +70,7 @@ #define IMX6_OTP_DATA_ERROR_VAL 0xBADABADA #define DEF_RELAX 20 #define MAC_OFFSET_0 (0x22 * 4) +#define IMX6UL_MAC_OFFSET_1 (0x23 * 4) #define MAC_OFFSET_1 (0x24 * 4) #define MAX_MAC_OFFSETS 2 #define MAC_BYTES 8 @@ -421,10 +422,14 @@ static int imx_ocotp_read_mac(const struct imx_ocotp_data *data, int ret; ret = regmap_bulk_read(map, offset, buf, MAC_BYTES); + if (ret < 0) return ret; - data->format_mac(mac, buf, OCOTP_HW_TO_MAC); + if (offset != IMX6UL_MAC_OFFSET_1) + data->format_mac(mac, buf, OCOTP_HW_TO_MAC); + else + data->format_mac(mac, buf + 2, OCOTP_HW_TO_MAC); return 0; } @@ -639,6 +644,14 @@ static struct imx_ocotp_data imx6sl_ocotp_data = { .format_mac = imx_ocotp_format_mac, }; +static struct imx_ocotp_data imx6ul_ocotp_data = { + .num_regs = 512, + .addr_to_offset = imx6q_addr_to_offset, + .mac_offsets_num = 2, + .mac_offsets = { MAC_OFFSET_0, IMX6UL_MAC_OFFSET_1 }, + .format_mac = imx_ocotp_format_mac, +}; + static struct imx_ocotp_data vf610_ocotp_data = { .num_regs = 512, .addr_to_offset = vf610_addr_to_offset, @@ -667,7 +680,7 @@ static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = { .data = &imx6sl_ocotp_data, }, { .compatible = "fsl,imx6ul-ocotp", - .data = &imx6q_ocotp_data, + .data = &imx6ul_ocotp_data, }, { .compatible = "fsl,imx8mq-ocotp", .data = &imx8mq_ocotp_data, diff --git a/drivers/of/partition.c b/drivers/of/partition.c index aa6e601b7f..2848b9636d 100644 --- a/drivers/of/partition.c +++ b/drivers/of/partition.c @@ -186,11 +186,11 @@ static int of_partition_fixup(struct device_node *root, void *ctx) return ret; } - of_property_write_u32(partnode, "#size-cells", n_cells); + ret = of_property_write_u32(partnode, "#size-cells", n_cells); if (ret) return ret; - of_property_write_u32(partnode, "#address-cells", n_cells); + ret = of_property_write_u32(partnode, "#address-cells", n_cells); if (ret) return ret; diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 3201eb9cb1..11e00833c5 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -32,6 +32,7 @@ #include <mach/at91_pio.h> #include <mach/gpio.h> +#include <mach/iomux.h> #include <pinctrl.h> @@ -46,14 +47,6 @@ struct at91_gpio_chip { struct at91_pinctrl_mux_ops *ops; /* ops */ }; -enum at91_mux { - AT91_MUX_GPIO = 0, - AT91_MUX_PERIPH_A = 1, - AT91_MUX_PERIPH_B = 2, - AT91_MUX_PERIPH_C = 3, - AT91_MUX_PERIPH_D = 4, -}; - #define MAX_GPIO_BANKS 5 #define to_at91_pinctrl(c) container_of(c, struct at91_pinctrl, pctl); #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c index d9b49c57d9..ffb04eebbf 100644 --- a/drivers/pinctrl/pinctrl-tegra30.c +++ b/drivers/pinctrl/pinctrl-tegra30.c @@ -658,8 +658,8 @@ static int pinctrl_tegra30_set_drvstate(struct pinctrl_tegra30 *ctrl, break; } } - /* if no matching drivegroup is found */ - if (i == ctrl->drvdata->num_drvgrps) + + if (!group) return 0; regaddr = ctrl->regs.ctrl + (group->reg >> 2); diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index bb597305e5..f1feee4689 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -348,10 +348,10 @@ static int ds1307_probe(struct device_d *dev) ds1307->regs[1] &= ~DS1341_BIT_ECLK; /* - * Let's set additionale RTC bits to + * Let's set additional RTC bits to * facilitate maximum power saving. */ - ds1307->regs[0] |= DS1341_BIT_DOSF; + ds1307->regs[1] |= DS1341_BIT_DOSF; ds1307->regs[0] &= ~DS1341_BIT_EGFIL; i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 8a56d39f7c..d462c11c16 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -3,6 +3,7 @@ menu "serial drivers" config SERIAL_DEV_BUS bool "Serial device bus" + select POLLER depends on CONSOLE_FULL help Core support for devices connected via a serial port. diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index f63039718f..beea772aa9 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -67,7 +67,7 @@ static void spi_reset(struct spi_master *master) writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, regs + OMAP3_MCSPI_WAKEUPENABLE); } -int spi_claim_bus(struct spi_device *spi) +static int spi_claim_bus(struct spi_device *spi) { struct spi_master *master = spi->master; struct omap3_spi_master *omap3_master = container_of(master, struct omap3_spi_master, master); @@ -144,7 +144,7 @@ int spi_claim_bus(struct spi_device *spi) return 0; } -int omap3_spi_write(struct spi_device *spi, unsigned int len, const u8 *txp, +static int omap3_spi_write(struct spi_device *spi, unsigned int len, const u8 *txp, unsigned long flags) { struct spi_master *master = spi->master; @@ -198,7 +198,7 @@ int omap3_spi_write(struct spi_device *spi, unsigned int len, const u8 *txp, return 0; } -int omap3_spi_read(struct spi_device *spi, unsigned int len, u8 *rxp, +static int omap3_spi_read(struct spi_device *spi, unsigned int len, u8 *rxp, unsigned long flags) { struct spi_master *master = spi->master; @@ -245,7 +245,7 @@ int omap3_spi_read(struct spi_device *spi, unsigned int len, u8 *rxp, return 0; } -int spi_xfer(struct spi_device *spi, struct spi_transfer *t, unsigned long flags) +static int spi_xfer(struct spi_device *spi, struct spi_transfer *t, unsigned long flags) { struct spi_master *master = spi->master; struct omap3_spi_master *omap3_master = container_of(master, struct omap3_spi_master, master); diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 729f752128..243656d443 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -288,8 +288,7 @@ static int at91_ep_enable(struct usb_ep *_ep, u16 maxpacket; u32 tmp; - if (!_ep || !ep - || !desc || ep->desc + if (!desc || ep->desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || (maxpacket = le16_to_cpu(desc->wMaxPacketSize)) == 0 diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index feaa856451..c8f55ac32c 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -110,6 +110,11 @@ static int service_tx_status_request( break; } + if (epnum >= MUSB_C_NUM_EPS) { + handled = -EINVAL; + break; + } + is_in = epnum & USB_DIR_IN; if (is_in) { epnum &= 0x0f; @@ -119,7 +124,7 @@ static int service_tx_status_request( } regs = musb->endpoints[epnum].regs; - if (epnum >= MUSB_C_NUM_EPS || !ep->desc) { + if (!ep->desc) { handled = -EINVAL; break; } diff --git a/drivers/usb/musb/phy-am335x-control.c b/drivers/usb/musb/phy-am335x-control.c index 55a2ed27b7..c84525ec7e 100644 --- a/drivers/usb/musb/phy-am335x-control.c +++ b/drivers/usb/musb/phy-am335x-control.c @@ -4,10 +4,7 @@ #include <linux/err.h> #include <linux/spinlock.h> -struct phy_control { - void (*phy_power)(struct phy_control *phy_ctrl, u32 id, bool on); - void (*phy_wkup)(struct phy_control *phy_ctrl, u32 id, bool on); -}; +#include "am35x-phy-control.h" struct am335x_control_usb { struct device_d *dev; diff --git a/drivers/usb/musb/phy-am335x.c b/drivers/usb/musb/phy-am335x.c index ec8c0f538b..df31255d89 100644 --- a/drivers/usb/musb/phy-am335x.c +++ b/drivers/usb/musb/phy-am335x.c @@ -5,6 +5,7 @@ #include <linux/err.h> #include "am35x-phy-control.h" #include "musb_core.h" +#include "phy-am335x.h" struct am335x_usbphy { void __iomem *base; diff --git a/drivers/video/imx-ipu-v3/imx-pd.c b/drivers/video/imx-ipu-v3/imx-pd.c index 09d8a3ae2a..601be35880 100644 --- a/drivers/video/imx-ipu-v3/imx-pd.c +++ b/drivers/video/imx-ipu-v3/imx-pd.c @@ -45,7 +45,7 @@ static int imx_pd_ioctl(struct vpl *vpl, unsigned int port, case IMX_IPU_VPL_DI_MODE: mode = data; - mode->di_clkflags = IPU_DI_CLKMODE_SYNC; + mode->di_clkflags = IPU_DI_CLKMODE_NON_FRACTIONAL; mode->bus_format = imx_pd->bus_format; return 0; diff --git a/drivers/video/imx-ipu-v3/ipu-di.c b/drivers/video/imx-ipu-v3/ipu-di.c index b6e64fe16a..b4302412e0 100644 --- a/drivers/video/imx-ipu-v3/ipu-di.c +++ b/drivers/video/imx-ipu-v3/ipu-di.c @@ -140,6 +140,7 @@ static int ipu_di_clk_calc_div(unsigned long inrate, unsigned long outrate) int div; tmp *= 16; + tmp += outrate / 2; do_div(tmp, outrate); diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c index d68f0c5056..70077e43a8 100644 --- a/drivers/video/ssd1307fb.c +++ b/drivers/video/ssd1307fb.c @@ -548,8 +548,10 @@ static int ssd1307fb_probe(struct device_d *dev) /* clear display */ array = ssd1307fb_alloc_array(par->width * par->height / 8, SSD1307FB_DATA); - if (!array) - return -ENOMEM; + if (!array) { + ret = -ENOMEM; + goto panel_init_error; + } for (i = 0; i < (par->height / 8); i++) { for (j = 0; j < par->width; j++) { @@ -569,6 +571,7 @@ static int ssd1307fb_probe(struct device_d *dev) panel_init_error: reset_oled_error: + free(vmem); fb_alloc_error: regulator_disable(par->vbat); free(info); diff --git a/drivers/video/vpl.c b/drivers/video/vpl.c index 99ad180eec..82ceeebada 100644 --- a/drivers/video/vpl.c +++ b/drivers/video/vpl.c @@ -36,7 +36,7 @@ int vpl_register(struct vpl *vpl) return 0; } -struct vpl *of_find_vpl(struct device_node *node) +static struct vpl *of_find_vpl(struct device_node *node) { struct vpl *vpl; diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c index a66fae400c..8dba662392 100644 --- a/drivers/watchdog/imxwd.c +++ b/drivers/watchdog/imxwd.c @@ -162,19 +162,23 @@ static void __noreturn imxwd_force_soc_reset(struct restart_handler *rst) static void imx_watchdog_detect_reset_source(struct imx_wd *priv) { u16 val = readw(priv->base + IMX21_WDOG_WSTR); + int priority = RESET_SOURCE_DEFAULT_PRIORITY; + + if (reset_source_get() == RESET_WDG) + priority++; if (val & WSTR_COLDSTART) { - reset_source_set(RESET_POR); + reset_source_set_priority(RESET_POR, priority); return; } if (val & (WSTR_HARDRESET | WSTR_WARMSTART)) { - reset_source_set(RESET_RST); + reset_source_set_priority(RESET_RST, priority); return; } if (val & WSTR_WDOG) { - reset_source_set(RESET_WDG); + reset_source_set_priority(RESET_WDG, priority); return; } |