* [PATCH 1/4] dt-bindings: mfd: Add Altera Arria10 SR Monitor
From: Rob Herring @ 2016-10-18 14:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476394329-31696-2-git-send-email-tthayer@opensource.altera.com>
On Thu, Oct 13, 2016 at 04:32:06PM -0500, tthayer at opensource.altera.com wrote:
> From: Thor Thayer <tthayer@opensource.altera.com>
>
> Add the Arria10 DevKit System Resource Chip register and state
> monitoring module to the MFD.
>
> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
> ---
> Note: This needs to be applied to the bindings document that
> was Acked & Applied but didn't reach the for-next branch.
> See https://patchwork.ozlabs.org/patch/629397/
> ---
> ---
> .../devicetree/bindings/mfd/altera-a10sr.txt | 9 +++++++++
> 1 file changed, 9 insertions(+)
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH v2 5/6] clk: stm32f469: Add QSPI clock
From: Rob Herring @ 2016-10-18 14:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476436699-21879-6-git-send-email-gabriel.fernandez@st.com>
On Fri, Oct 14, 2016 at 11:18:18AM +0200, gabriel.fernandez at st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>
> This patch adds the QSPI clock for stm32f469 discovery board.
> The gate mapping is a little bit different from stm32f429 soc.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---
> .../devicetree/bindings/clock/st,stm32-rcc.txt | 4 +-
> drivers/clk/clk-stm32f4.c | 173 ++++++++++++++++++---
> 2 files changed, 158 insertions(+), 19 deletions(-)
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH] crypto: sun4i-ss: support the Security System PRNG
From: Stephan Mueller @ 2016-10-18 14:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476794067-28563-1-git-send-email-clabbe.montjoie@gmail.com>
Am Dienstag, 18. Oktober 2016, 14:34:27 CEST schrieb Corentin Labbe:
Hi Corentin,
> diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c
> b/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c new file mode 100644
> index 0000000..95fadb7
> --- /dev/null
> +++ b/drivers/crypto/sunxi-ss/sun4i-ss-hwrng.c
> @@ -0,0 +1,70 @@
> +#include "sun4i-ss.h"
> +
> +static int sun4i_ss_hwrng_init(struct hwrng *hwrng)
> +{
> + struct sun4i_ss_ctx *ss;
> +
> + ss = container_of(hwrng, struct sun4i_ss_ctx, hwrng);
> + get_random_bytes(ss->seed, SS_SEED_LEN);
Is it wise to call get_random_bytes once in the init function and never
thereafter?
This init function may be called during boot time of the kernel at which the
input_pool may not yet have received sufficient amounts of entropy.
What about registering a callback with add_random_ready_callback and seed
again when sufficient entropy was collected?
Ciao
Stephan
^ permalink raw reply
* [PATCH 4/9] regulator: lp873x: Add support for populating input supply
From: Rob Herring @ 2016-10-18 14:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161014130033.14172-5-lokeshvutla@ti.com>
On Fri, Oct 14, 2016 at 06:30:28PM +0530, Lokesh Vutla wrote:
> In order to have a proper topology of regulators for a platform, each
> registering regulator needs to populate supply_name field for identifying
> its supply's name. Add supply_name field for lp873x regulators.
>
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Keerthy <j-keerthy@ti.com>
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
> Documentation/devicetree/bindings/mfd/lp873x.txt | 8 ++++++++
> drivers/regulator/lp873x-regulator.c | 1 +
> 2 files changed, 9 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mfd/lp873x.txt b/Documentation/devicetree/bindings/mfd/lp873x.txt
> index 52766c2..936cba3 100644
> --- a/Documentation/devicetree/bindings/mfd/lp873x.txt
> +++ b/Documentation/devicetree/bindings/mfd/lp873x.txt
> @@ -7,6 +7,9 @@ Required properties:
> - #gpio-cells: Should be two. The first cell is the pin number and
> the second cell is used to specify flags.
> See ../gpio/gpio.txt for more information.
> + - xxx-supply: Phandle to parent supply node of each regulator
> + populated under regulators node. xxx should match
> + the supply_name populated in driver.
xxx-in-supply?
> - regulators: List of child nodes that specify the regulator
> initialization data.
> Example:
> @@ -17,6 +20,11 @@ pmic: lp8733 at 60 {
> gpio-controller;
> #gpio-cells = <2>;
>
> + buck0-in-supply = <&vsys_3v3>;
> + buck1-in-supply = <&vsys_3v3>;
> + ldo0-in-supply = <&vsys_3v3>;
> + ldo1-in-supply = <&vsys_3v3>;
> +
> regulators {
> lp8733_buck0: buck0 {
> regulator-name = "lp8733-buck0";
^ permalink raw reply
* [PATCH 5/9] ARM: OMAP2+: board-generic: add support for DRA71x family
From: Rob Herring @ 2016-10-18 14:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161014130033.14172-6-lokeshvutla@ti.com>
On Fri, Oct 14, 2016 at 06:30:29PM +0530, Lokesh Vutla wrote:
> DRA71x processor family is a derivative of DRA722 ES2.0 targeted for
> infotainment systems.
>
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
> Documentation/devicetree/bindings/arm/omap/omap.txt | 6 ++++++
> arch/arm/mach-omap2/board-generic.c | 1 +
> 2 files changed, 7 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt
> index f53e2ee..454b1be 100644
> --- a/Documentation/devicetree/bindings/arm/omap/omap.txt
> +++ b/Documentation/devicetree/bindings/arm/omap/omap.txt
> @@ -86,6 +86,9 @@ SoCs:
> - DRA722
> compatible = "ti,dra722", "ti,dra72", "ti,dra7"
>
> +- DRA718
> + compatible = "ti,dra718", "ti,dra722", "ti,dra72", "ti,dra7"
Are dra72 and dra7 really useful? Your list is a bit long. Perhaps it is
time to drop those on new parts at least.
Either way:
Acked-by: Rob Herring <robh@kernel.org>
> +
> - AM5728
> compatible = "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7"
>
> @@ -181,6 +184,9 @@ Boards:
> - DRA722 EVM: Software Development Board for DRA722
> compatible = "ti,dra72-evm", "ti,dra722", "ti,dra72", "ti,dra7"
>
> +- DRA718 EVM: Software Development Board for DRA718
> + compatible = "ti,dra718-evm", "ti,dra718", "ti,dra722", "ti,dra72", "ti,dra7"
> +
> - DM3730 Logic PD Torpedo + Wireless: Commercial System on Module with WiFi and Bluetooth
> compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap3630", "ti,omap3"
>
> diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
> index bab814d..981b23a 100644
> --- a/arch/arm/mach-omap2/board-generic.c
> +++ b/arch/arm/mach-omap2/board-generic.c
> @@ -341,6 +341,7 @@ static const char *const dra72x_boards_compat[] __initconst = {
> "ti,am5718",
> "ti,am5716",
> "ti,dra722",
> + "ti,dra718",
> NULL,
> };
>
> --
> 2.9.3
>
^ permalink raw reply
* [v17 2/2] drm/bridge: Add I2C based driver for ps8640 bridge
From: Enric Balletbo Serra @ 2016-10-18 14:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1472280263-18177-2-git-send-email-jitao.shi@mediatek.com>
Hi Jitao,
2016-08-27 8:44 GMT+02:00 Jitao Shi <jitao.shi@mediatek.com>:
> This patch adds drm_bridge driver for parade DSI to eDP bridge chip.
>
> Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
> Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
> ---
> Changes since v16:
> - Disable ps8640 DSI MCS Function.
> - Rename gpios name more clearly.
> - Tune the ps8640 power on sequence.
>
> Changes since v15:
> - Drop drm_connector_(un)register calls from parade ps8640.
> The main DRM driver mtk_drm_drv now calls
> drm_connector_register_all() after drm_dev_register() in the
> mtk_drm_bind() function. That function should iterate over all
> connectors and call drm_connector_register() for each of them.
> So, remove drm_connector_(un)register calls from parade ps8640.
>
> Changes since v14:
> - update copyright info.
> - change bridge_to_ps8640 and connector_to_ps8640 to inline function.
> - fix some coding style.
> - use sizeof as array counter.
> - use drm_get_edid when read edid.
> - add mutex when firmware updating.
>
> Changes since v13:
> - add const on data, ps8640_write_bytes(struct i2c_client *client, const u8 *data, u16 data_len)
> - fix PAGE2_SW_REST tyro.
> - move the buf[3] init to entrance of the function.
>
> Changes since v12:
> - fix hw_chip_id build warning
>
> Changes since v11:
> - Remove depends on I2C, add DRM depends
> - Reuse ps8640_write_bytes() in ps8640_write_byte()
> - Use timer check for polling like the routines in <linux/iopoll.h>
> - Fix no drm_connector_unregister/drm_connector_cleanup when ps8640_bridge_attach fail
> - Check the ps8640 hardware id in ps8640_validate_firmware
> - Remove fw_version check
> - Move ps8640_validate_firmware before ps8640_enter_bl
> - Add ddc_i2c unregister when probe fail and ps8640_remove
> ---
> drivers/gpu/drm/bridge/Kconfig | 12 +
> drivers/gpu/drm/bridge/Makefile | 1 +
> drivers/gpu/drm/bridge/parade-ps8640.c | 1077 ++++++++++++++++++++++++++++++++
> 3 files changed, 1090 insertions(+)
> create mode 100644 drivers/gpu/drm/bridge/parade-ps8640.c
>
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index b590e67..c59d043 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -50,6 +50,18 @@ config DRM_PARADE_PS8622
> ---help---
> Parade eDP-LVDS bridge chip driver.
>
> +config DRM_PARADE_PS8640
> + tristate "Parade PS8640 MIPI DSI to eDP Converter"
> + depends on DRM
> + depends on OF
> + select DRM_KMS_HELPER
> + select DRM_MIPI_DSI
> + select DRM_PANEL
> + ---help---
> + Choose this option if you have PS8640 for display
> + The PS8640 is a high-performance and low-power
> + MIPI DSI to eDP converter
> +
> config DRM_SII902X
> tristate "Silicon Image sii902x RGB/HDMI bridge"
> depends on OF
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index efdb07e..3360537 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -5,6 +5,7 @@ obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
> obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
> obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
> obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
> +obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
> obj-$(CONFIG_DRM_SII902X) += sii902x.o
> obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
> obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
> diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
> new file mode 100644
> index 0000000..7d67431
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/parade-ps8640.c
> @@ -0,0 +1,1077 @@
> +/*
> + * Copyright (c) 2016 MediaTek Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/firmware.h>
> +#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_graph.h>
> +#include <linux/regulator/consumer.h>
> +#include <asm/unaligned.h>
> +#include <drm/drm_panel.h>
> +
> +#include <drmP.h>
> +#include <drm_atomic_helper.h>
> +#include <drm_crtc_helper.h>
> +#include <drm_crtc.h>
> +#include <drm_edid.h>
> +#include <drm_mipi_dsi.h>
> +
> +#define PAGE1_VSTART 0x6b
> +#define PAGE2_SPI_CFG3 0x82
> +#define I2C_TO_SPI_RESET 0x20
> +#define PAGE2_ROMADD_BYTE1 0x8e
> +#define PAGE2_ROMADD_BYTE2 0x8f
> +#define PAGE2_SWSPI_WDATA 0x90
> +#define PAGE2_SWSPI_RDATA 0x91
> +#define PAGE2_SWSPI_LEN 0x92
> +#define PAGE2_SWSPI_CTL 0x93
> +#define TRIGGER_NO_READBACK 0x05
> +#define TRIGGER_READBACK 0x01
> +#define PAGE2_SPI_STATUS 0x9e
> +#define SPI_READY 0x0c
> +#define PAGE2_GPIO_L 0xa6
> +#define PAGE2_GPIO_H 0xa7
> +#define PS_GPIO9 BIT(1)
> +#define PAGE2_IROM_CTRL 0xb0
> +#define IROM_ENABLE 0xc0
> +#define IROM_DISABLE 0x80
> +#define PAGE2_SW_RESET 0xbc
> +#define SPI_SW_RESET BIT(7)
> +#define MPU_SW_RESET BIT(6)
> +#define PAGE2_ENCTLSPI_WR 0xda
> +#define PAGE2_I2C_BYPASS 0xea
> +#define I2C_BYPASS_EN 0xd0
> +#define PAGE2_MCS_EN 0xf3
> +#define MCS_EN BIT(0)
> +#define PAGE3_SET_ADD 0xfe
> +#define PAGE3_SET_VAL 0xff
> +#define VDO_CTL_ADD 0x13
> +#define VDO_DIS 0x18
> +#define VDO_EN 0x1c
> +#define PAGE4_REV_L 0xf0
> +#define PAGE4_REV_H 0xf1
> +#define PAGE4_CHIP_L 0xf2
> +#define PAGE4_CHIP_H 0xf3
> +
> +/* Firmware */
> +#define PS_FW_NAME "ps864x_fw.bin"
> +
>From where I can download this firmware image?
> +#define FW_CHIP_ID_OFFSET 0
> +#define FW_VERSION_OFFSET 2
> +#define EDID_I2C_ADDR 0x50
> +
> +#define WRITE_STATUS_REG_CMD 0x01
> +#define READ_STATUS_REG_CMD 0x05
> +#define BUSY BIT(0)
> +#define CLEAR_ALL_PROTECT 0x00
> +#define BLK_PROTECT_BITS 0x0c
> +#define STATUS_REG_PROTECT BIT(7)
> +#define WRITE_ENABLE_CMD 0x06
> +#define CHIP_ERASE_CMD 0xc7
> +#define MAX_DEVS 0x8
> +
> +struct ps8640_info {
> + u8 family_id;
> + u8 variant_id;
> + u16 version;
> +};
> +
> +struct ps8640 {
> + struct drm_connector connector;
> + struct drm_bridge bridge;
> + struct edid *edid;
> + struct mipi_dsi_device dsi;
> + struct i2c_client *page[MAX_DEVS];
> + struct i2c_client *ddc_i2c;
> + struct regulator_bulk_data supplies[2];
> + struct drm_panel *panel;
> + struct gpio_desc *gpio_reset;
> + struct gpio_desc *gpio_power_down;
> + struct gpio_desc *gpio_mode_sel;
> + bool enabled;
> +
> + /* firmware file info */
> + struct ps8640_info info;
> + bool in_fw_update;
> + /* for firmware update protect */
> + struct mutex fw_mutex;
> +};
> +
> +static const u8 enc_ctrl_code[6] = { 0xaa, 0x55, 0x50, 0x41, 0x52, 0x44 };
> +static const u8 hw_chip_id[4] = { 0x00, 0x0a, 0x00, 0x30 };
> +
> +static inline struct ps8640 *bridge_to_ps8640(struct drm_bridge *e)
> +{
> + return container_of(e, struct ps8640, bridge);
> +}
> +
> +static inline struct ps8640 *connector_to_ps8640(struct drm_connector *e)
> +{
> + return container_of(e, struct ps8640, connector);
> +}
> +
> +static int ps8640_read(struct i2c_client *client, u8 reg, u8 *data,
> + u16 data_len)
> +{
> + int ret;
> + struct i2c_msg msgs[] = {
> + {
> + .addr = client->addr,
> + .flags = 0,
> + .len = 1,
> + .buf = ®,
> + },
> + {
> + .addr = client->addr,
> + .flags = I2C_M_RD,
> + .len = data_len,
> + .buf = data,
> + }
> + };
> +
> + ret = i2c_transfer(client->adapter, msgs, 2);
> +
> + if (ret == 2)
> + return 0;
> + if (ret < 0)
> + return ret;
> + else
> + return -EIO;
> +}
> +
> +static int ps8640_write_bytes(struct i2c_client *client, const u8 *data,
> + u16 data_len)
> +{
> + int ret;
> + struct i2c_msg msg;
> +
> + msg.addr = client->addr;
> + msg.flags = 0;
> + msg.len = data_len;
> + msg.buf = (u8 *)data;
> +
> + ret = i2c_transfer(client->adapter, &msg, 1);
> + if (ret == 1)
> + return 0;
> + if (ret < 0)
> + return ret;
> + else
> + return -EIO;
> +}
> +
> +static int ps8640_write_byte(struct i2c_client *client, u8 reg, u8 data)
> +{
> + u8 buf[] = { reg, data };
> +
> + return ps8640_write_bytes(client, buf, sizeof(buf));
> +}
> +
> +static void ps8640_get_mcu_fw_version(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[5];
> + u8 fw_ver[2];
> +
> + ps8640_read(client, 0x4, fw_ver, sizeof(fw_ver));
> + ps_bridge->info.version = (fw_ver[0] << 8) | fw_ver[1];
> +
> + DRM_INFO_ONCE("ps8640 rom fw version %d.%d\n", fw_ver[0], fw_ver[1]);
> +}
> +
> +static int ps8640_bridge_unmute(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[3];
> + u8 vdo_ctrl_buf[3] = { PAGE3_SET_ADD, VDO_CTL_ADD, VDO_EN };
> +
> + return ps8640_write_bytes(client, vdo_ctrl_buf, sizeof(vdo_ctrl_buf));
> +}
> +
> +static int ps8640_bridge_mute(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[3];
> + u8 vdo_ctrl_buf[3] = { PAGE3_SET_ADD, VDO_CTL_ADD, VDO_DIS };
> +
> + return ps8640_write_bytes(client, vdo_ctrl_buf, sizeof(vdo_ctrl_buf));
> +}
> +
> +static void ps8640_pre_enable(struct drm_bridge *bridge)
> +{
> + struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
> + struct i2c_client *client = ps_bridge->page[2];
> + struct i2c_client *page1 = ps_bridge->page[1];
> + int err;
> + u8 set_vdo_done, mcs_en, vstart;
> + ktime_t timeout;
> +
> + if (ps_bridge->in_fw_update)
> + return;
> +
> + if (ps_bridge->enabled)
> + return;
> +
> + err = drm_panel_prepare(ps_bridge->panel);
> + if (err < 0) {
> + DRM_ERROR("failed to prepare panel: %d\n", err);
> + return;
> + }
> +
> + err = regulator_bulk_enable(ARRAY_SIZE(ps_bridge->supplies),
> + ps_bridge->supplies);
> + if (err < 0) {
> + DRM_ERROR("cannot enable regulators %d\n", err);
> + goto err_panel_unprepare;
> + }
> +
> + gpiod_set_value(ps_bridge->gpio_power_down, 1);
> + gpiod_set_value(ps_bridge->gpio_reset, 0);
> + usleep_range(2000, 2500);
> + gpiod_set_value(ps_bridge->gpio_reset, 1);
> +
> + /*
> + * Wait for the ps8640 embed mcu ready
> + * First wait 200ms and then check the mcu ready flag every 20ms
> + */
> + msleep(200);
> +
> + timeout = ktime_add_ms(ktime_get(), 200);
> + for (;;) {
> + err = ps8640_read(client, PAGE2_GPIO_H, &set_vdo_done, 1);
> + if (err < 0) {
> + DRM_ERROR("failed read PAGE2_GPIO_H: %d\n", err);
> + goto err_regulators_disable;
> + }
> + if ((set_vdo_done & PS_GPIO9) == PS_GPIO9)
> + break;
> + if (ktime_compare(ktime_get(), timeout) > 0)
> + break;
> + msleep(20);
> + }
> +
> + msleep(50);
> +
> + ps8640_read(page1, PAGE1_VSTART, &vstart, 1);
> + DRM_INFO("PS8640 PAGE1.0x6B = 0x%x\n", vstart);
> +
> + /**
> + * The Manufacturer Command Set (MCS) is a device dependent interface
> + * intended for factory programming of the display module default
> + * parameters. Once the display module is configured, the MCS shall be
> + * disabled by the manufacturer. Once disabled, all MCS commands are
> + * ignored by the display interface.
> + */
> + ps8640_read(client, PAGE2_MCS_EN, &mcs_en, 1);
> + ps8640_write_byte(client, PAGE2_MCS_EN, mcs_en & ~MCS_EN);
> +
> + if (ps_bridge->info.version == 0)
> + ps8640_get_mcu_fw_version(ps_bridge);
> +
> + err = ps8640_bridge_unmute(ps_bridge);
> + if (err)
> + DRM_ERROR("failed to enable unmutevideo: %d\n", err);
> + /* Switch access edp panel's edid through i2c */
> + ps8640_write_byte(client, PAGE2_I2C_BYPASS, I2C_BYPASS_EN);
> + ps_bridge->enabled = true;
> +
> + return;
> +
> +err_regulators_disable:
> + regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
> + ps_bridge->supplies);
> +err_panel_unprepare:
> + drm_panel_unprepare(ps_bridge->panel);
> +}
> +
> +static void ps8640_enable(struct drm_bridge *bridge)
> +{
> + struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
> + int err;
> +
> + err = drm_panel_enable(ps_bridge->panel);
> + if (err < 0)
> + DRM_ERROR("failed to enable panel: %d\n", err);
> +}
> +
> +static void ps8640_disable(struct drm_bridge *bridge)
> +{
> + struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
> + int err;
> +
> + err = drm_panel_disable(ps_bridge->panel);
> + if (err < 0)
> + DRM_ERROR("failed to disable panel: %d\n", err);
> +}
> +
> +static void ps8640_post_disable(struct drm_bridge *bridge)
> +{
> + struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
> + int err;
> +
> + if (ps_bridge->in_fw_update)
> + return;
> +
> + if (!ps_bridge->enabled)
> + return;
> +
> + ps_bridge->enabled = false;
> +
> + err = ps8640_bridge_mute(ps_bridge);
> + if (err < 0)
> + DRM_ERROR("failed to unmutevideo: %d\n", err);
> +
> + gpiod_set_value(ps_bridge->gpio_reset, 0);
> + gpiod_set_value(ps_bridge->gpio_power_down, 0);
> + err = regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
> + ps_bridge->supplies);
> + if (err < 0)
> + DRM_ERROR("cannot disable regulators %d\n", err);
> +
> + err = drm_panel_unprepare(ps_bridge->panel);
> + if (err)
> + DRM_ERROR("failed to unprepare panel: %d\n", err);
> +}
> +
> +static int ps8640_get_modes(struct drm_connector *connector)
> +{
> + struct ps8640 *ps_bridge = connector_to_ps8640(connector);
> + struct edid *edid;
> + int num_modes = 0;
> + bool power_off;
> +
> + if (ps_bridge->edid)
> + return drm_add_edid_modes(connector, ps_bridge->edid);
> +
> + power_off = !ps_bridge->enabled;
> + ps8640_pre_enable(&ps_bridge->bridge);
> +
> + edid = drm_get_edid(connector, ps_bridge->ddc_i2c->adapter);
> + if (!edid)
> + goto out;
> +
> + ps_bridge->edid = edid;
> + drm_mode_connector_update_edid_property(connector, ps_bridge->edid);
> + num_modes = drm_add_edid_modes(connector, ps_bridge->edid);
> +
> +out:
> + if (power_off)
> + ps8640_post_disable(&ps_bridge->bridge);
> +
> + return num_modes;
> +}
> +
> +static struct drm_encoder *ps8640_best_encoder(struct drm_connector *connector)
> +{
> + struct ps8640 *ps_bridge = connector_to_ps8640(connector);
> +
> + return ps_bridge->bridge.encoder;
> +}
> +
> +static const struct drm_connector_helper_funcs ps8640_connector_helper_funcs = {
> + .get_modes = ps8640_get_modes,
> + .best_encoder = ps8640_best_encoder,
> +};
> +
> +static enum drm_connector_status ps8640_detect(struct drm_connector *connector,
> + bool force)
> +{
> + return connector_status_connected;
> +}
> +
> +static const struct drm_connector_funcs ps8640_connector_funcs = {
> + .dpms = drm_atomic_helper_connector_dpms,
> + .fill_modes = drm_helper_probe_single_connector_modes,
> + .detect = ps8640_detect,
> + .reset = drm_atomic_helper_connector_reset,
> + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +int ps8640_bridge_attach(struct drm_bridge *bridge)
> +{
> + struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
> + struct device *dev = &ps_bridge->page[0]->dev;
> + struct device_node *port, *in_ep;
> + struct device_node *dsi_node = NULL;
> + struct mipi_dsi_host *host = NULL;
> + int ret;
> +
> + ret = drm_connector_init(bridge->dev, &ps_bridge->connector,
> + &ps8640_connector_funcs,
> + DRM_MODE_CONNECTOR_eDP);
> +
> + if (ret) {
> + DRM_ERROR("Failed to initialize connector with drm: %d\n", ret);
> + return ret;
> + }
> +
> + drm_connector_helper_add(&ps_bridge->connector,
> + &ps8640_connector_helper_funcs);
> +
> + ps_bridge->connector.dpms = DRM_MODE_DPMS_ON;
> + drm_mode_connector_attach_encoder(&ps_bridge->connector,
> + bridge->encoder);
> +
> + if (ps_bridge->panel)
> + drm_panel_attach(ps_bridge->panel, &ps_bridge->connector);
> +
> + /* port at 0 is ps8640 dsi input port */
> + port = of_graph_get_port_by_id(dev->of_node, 0);
> + if (port) {
> + in_ep = of_get_child_by_name(port, "endpoint");
> + of_node_put(port);
> + if (in_ep) {
> + dsi_node = of_graph_get_remote_port_parent(in_ep);
> + of_node_put(in_ep);
> + }
> + }
> + if (dsi_node) {
> + host = of_find_mipi_dsi_host_by_node(dsi_node);
> + of_node_put(dsi_node);
> + if (!host) {
> + ret = -ENODEV;
> + goto err;
> + }
> + }
> +
> + ps_bridge->dsi.host = host;
> + ps_bridge->dsi.mode_flags = MIPI_DSI_MODE_VIDEO |
> + MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
> + ps_bridge->dsi.format = MIPI_DSI_FMT_RGB888;
> + ps_bridge->dsi.lanes = 4;
> + ret = mipi_dsi_attach(&ps_bridge->dsi);
> + if (ret)
> + goto err;
> +
> + return 0;
> +err:
> + if (ps_bridge->panel)
> + drm_panel_detach(ps_bridge->panel);
> + drm_connector_cleanup(&ps_bridge->connector);
> + return ret;
> +}
> +
> +static const struct drm_bridge_funcs ps8640_bridge_funcs = {
> + .attach = ps8640_bridge_attach,
> + .disable = ps8640_disable,
> + .post_disable = ps8640_post_disable,
> + .pre_enable = ps8640_pre_enable,
> + .enable = ps8640_enable,
> +};
> +
> +/* Firmware Version is returned as Major.Minor */
> +static ssize_t ps8640_fw_version_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct ps8640 *ps_bridge = dev_get_drvdata(dev);
> + struct ps8640_info *info = &ps_bridge->info;
> +
> + return scnprintf(buf, PAGE_SIZE, "%u.%u\n", info->version >> 8,
> + info->version & 0xff);
> +}
> +
> +/* Hardware Version is returned as FamilyID.VariantID */
> +static ssize_t ps8640_hw_version_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct ps8640 *ps_bridge = dev_get_drvdata(dev);
> + struct ps8640_info *info = &ps_bridge->info;
> +
> + return scnprintf(buf, PAGE_SIZE, "ps%u.%u\n", info->family_id,
> + info->variant_id);
> +}
> +
> +static int ps8640_spi_send_cmd(struct ps8640 *ps_bridge, u8 *cmd, u8 cmd_len)
> +{
> + struct i2c_client *client = ps_bridge->page[2];
> + u8 i, buf[3] = { PAGE2_SWSPI_LEN, cmd_len - 1, TRIGGER_NO_READBACK };
> + int ret;
> +
> + ret = ps8640_write_byte(client, PAGE2_IROM_CTRL, IROM_ENABLE);
> + if (ret)
> + goto err;
> +
> + /* write command in write port */
> + for (i = 0; i < cmd_len; i++) {
> + ret = ps8640_write_byte(client, PAGE2_SWSPI_WDATA, cmd[i]);
> + if (ret)
> + goto err_irom_disable;
> + }
> +
> + ret = ps8640_write_bytes(client, buf, sizeof(buf));
> + if (ret)
> + goto err_irom_disable;
> +
> + ret = ps8640_write_byte(client, PAGE2_IROM_CTRL, IROM_DISABLE);
> + if (ret)
> + goto err;
> +
> + return 0;
> +err_irom_disable:
> + ps8640_write_byte(client, PAGE2_IROM_CTRL, IROM_DISABLE);
> +err:
> + dev_err(&client->dev, "send command err: %d\n", ret);
> + return ret;
> +}
> +
> +static int ps8640_wait_spi_ready(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[2];
> + u8 spi_rdy_st;
> + ktime_t timeout;
> +
> + timeout = ktime_add_ms(ktime_get(), 200);
> + for (;;) {
> + ps8640_read(client, PAGE2_SPI_STATUS, &spi_rdy_st, 1);
> + if ((spi_rdy_st & SPI_READY) != SPI_READY)
> + break;
> +
> + if (ktime_compare(ktime_get(), timeout) > 0) {
> + dev_err(&client->dev, "wait spi ready timeout\n");
> + return -EBUSY;
> + }
> +
> + msleep(20);
> + }
> +
> + return 0;
> +}
> +
> +static int ps8640_wait_spi_nobusy(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[2];
> + u8 spi_status, buf[3] = { PAGE2_SWSPI_LEN, 0, TRIGGER_READBACK };
> + int ret;
> + ktime_t timeout;
> +
> + timeout = ktime_add_ms(ktime_get(), 500);
> + for (;;) {
> + /* 0x05 RDSR; Read-Status-Register */
> + ret = ps8640_write_byte(client, PAGE2_SWSPI_WDATA,
> + READ_STATUS_REG_CMD);
> + if (ret)
> + goto err_send_cmd_exit;
> +
> + ret = ps8640_write_bytes(client, buf, 3);
> + if (ret)
> + goto err_send_cmd_exit;
> +
> + /* delay for cmd send */
> + usleep_range(300, 500);
> + /* wait for SPI ROM until not busy */
> + ret = ps8640_read(client, PAGE2_SWSPI_RDATA, &spi_status, 1);
> + if (ret)
> + goto err_send_cmd_exit;
> +
> + if (!(spi_status & BUSY))
> + break;
> +
> + if (ktime_compare(ktime_get(), timeout) > 0) {
> + dev_err(&client->dev, "wait spi no busy timeout: %d\n",
> + ret);
> + return -EBUSY;
> + }
> + }
> +
> + return 0;
> +
> +err_send_cmd_exit:
> + dev_err(&client->dev, "send command err: %d\n", ret);
> + return ret;
> +}
> +
> +static int ps8640_wait_rom_idle(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[0];
> + int ret;
> +
> + ret = ps8640_write_byte(client, PAGE2_IROM_CTRL, IROM_ENABLE);
> + if (ret)
> + goto exit;
> +
> + ret = ps8640_wait_spi_ready(ps_bridge);
> + if (ret)
> + goto err_spi;
> +
> + ret = ps8640_wait_spi_nobusy(ps_bridge);
> + if (ret)
> + goto err_spi;
> +
> + ret = ps8640_write_byte(client, PAGE2_IROM_CTRL, IROM_DISABLE);
> + if (ret)
> + goto exit;
> +
> + return 0;
> +
> +err_spi:
> + ps8640_write_byte(client, PAGE2_IROM_CTRL, IROM_DISABLE);
> +exit:
> + dev_err(&client->dev, "wait ps8640 rom idle fail: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static int ps8640_spi_dl_mode(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[2];
> + int ret;
> +
> + /* switch ps8640 mode to spi dl mode */
> + if (ps_bridge->gpio_mode_sel)
> + gpiod_set_value(ps_bridge->gpio_mode_sel, 0);
> +
> + /* reset spi interface */
> + ret = ps8640_write_byte(client, PAGE2_SW_RESET,
> + SPI_SW_RESET | MPU_SW_RESET);
> + if (ret)
> + goto exit;
> +
> + ret = ps8640_write_byte(client, PAGE2_SW_RESET, MPU_SW_RESET);
> + if (ret)
> + goto exit;
> +
> + return 0;
> +
> +exit:
> + dev_err(&client->dev, "fail reset spi interface: %d\n", ret);
> +
> + return ret;
> +}
> +
> +static int ps8640_rom_prepare(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[2];
> + struct device *dev = &client->dev;
> + u8 i, cmd[2];
> + int ret;
> +
> + cmd[0] = WRITE_ENABLE_CMD;
> + ret = ps8640_spi_send_cmd(ps_bridge, cmd, 1);
> + if (ret) {
> + dev_err(dev, "failed enable-write-status-register: %d\n", ret);
> + return ret;
> + }
> +
> + cmd[0] = WRITE_STATUS_REG_CMD;
> + cmd[1] = CLEAR_ALL_PROTECT;
> + ret = ps8640_spi_send_cmd(ps_bridge, cmd, 2);
> + if (ret) {
> + dev_err(dev, "fail disable all protection: %d\n", ret);
> + return ret;
> + }
> +
> + /* wait for SPI module ready */
> + ret = ps8640_wait_rom_idle(ps_bridge);
> + if (ret) {
> + dev_err(dev, "fail wait rom idle: %d\n", ret);
> + return ret;
> + }
> +
> + ps8640_write_byte(client, PAGE2_IROM_CTRL, IROM_ENABLE);
> + for (i = 0; i < ARRAY_SIZE(enc_ctrl_code); i++)
> + ps8640_write_byte(client, PAGE2_ENCTLSPI_WR, enc_ctrl_code[i]);
> + ps8640_write_byte(client, PAGE2_IROM_CTRL, IROM_DISABLE);
> +
> + /* Enable-Write-Status-Register */
> + cmd[0] = WRITE_ENABLE_CMD;
> + ret = ps8640_spi_send_cmd(ps_bridge, cmd, 1);
> + if (ret) {
> + dev_err(dev, "fail enable-write-status-register: %d\n", ret);
> + return ret;
> + }
> +
> + /* chip erase command */
> + cmd[0] = CHIP_ERASE_CMD;
> + ret = ps8640_spi_send_cmd(ps_bridge, cmd, 1);
> + if (ret) {
> + dev_err(dev, "fail disable all protection: %d\n", ret);
> + return ret;
> + }
> +
> + ret = ps8640_wait_rom_idle(ps_bridge);
> + if (ret) {
> + dev_err(dev, "fail wait rom idle: %d\n", ret);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int ps8640_check_chip_id(struct ps8640 *ps_bridge)
> +{
> + struct i2c_client *client = ps_bridge->page[4];
> + u8 buf[4];
> +
> + ps8640_read(client, PAGE4_REV_L, buf, 4);
> + return memcmp(buf, hw_chip_id, sizeof(buf));
> +}
> +
> +static int ps8640_validate_firmware(struct ps8640 *ps_bridge,
> + const struct firmware *fw)
> +{
> + struct i2c_client *client = ps_bridge->page[0];
> + u16 fw_chip_id;
> +
> + /*
> + * Get the chip_id from the firmware. Make sure that it is the
> + * right controller to do the firmware and config update.
> + */
> + fw_chip_id = get_unaligned_le16(fw->data + FW_CHIP_ID_OFFSET);
> +
> + if (fw_chip_id != 0x8640 && ps8640_check_chip_id(ps_bridge) == 0) {
> + dev_err(&client->dev,
> + "chip id mismatch: fw 0x%x vs. chip 0x8640\n",
> + fw_chip_id);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int ps8640_write_rom(struct ps8640 *ps_bridge, const struct firmware *fw)
> +{
> + struct i2c_client *client = ps_bridge->page[0];
> + struct device *dev = &client->dev;
> + struct i2c_client *client2 = ps_bridge->page[2];
> + struct i2c_client *client7 = ps_bridge->page[7];
> + size_t pos, cpy_len;
> + u8 buf[257];
> + int ret;
> +
> + ps8640_write_byte(client2, PAGE2_SPI_CFG3, I2C_TO_SPI_RESET);
> + msleep(100);
> + ps8640_write_byte(client2, PAGE2_SPI_CFG3, 0x00);
> +
> + for (pos = 0; pos < fw->size; pos += cpy_len) {
> + buf[0] = PAGE2_ROMADD_BYTE1;
> + buf[1] = pos >> 8;
> + buf[2] = pos >> 16;
> + ret = ps8640_write_bytes(client2, buf, 3);
> + if (ret)
> + goto error;
> + cpy_len = fw->size >= 256 + pos ? 256 : fw->size - pos;
> + buf[0] = 0;
> + memcpy(buf + 1, fw->data + pos, cpy_len);
> + ret = ps8640_write_bytes(client7, buf, cpy_len + 1);
> + if (ret)
> + goto error;
> +
> + dev_dbg(dev, "fw update completed %zu / %zu bytes\n", pos,
> + fw->size);
> + }
> + return 0;
> +
> +error:
> + dev_err(dev, "failed write external flash, %d\n", ret);
> + return ret;
> +}
> +
> +static int ps8640_spi_normal_mode(struct ps8640 *ps_bridge)
> +{
> + u8 cmd[2];
> + struct i2c_client *client = ps_bridge->page[2];
> +
> + /* Enable-Write-Status-Register */
> + cmd[0] = WRITE_ENABLE_CMD;
> + ps8640_spi_send_cmd(ps_bridge, cmd, 1);
> +
> + /* protect BPL/BP0/BP1 */
> + cmd[0] = WRITE_STATUS_REG_CMD;
> + cmd[1] = BLK_PROTECT_BITS | STATUS_REG_PROTECT;
> + ps8640_spi_send_cmd(ps_bridge, cmd, 2);
> +
> + /* wait for SPI rom ready */
> + ps8640_wait_rom_idle(ps_bridge);
> +
> + /* disable PS8640 mapping function */
> + ps8640_write_byte(client, PAGE2_ENCTLSPI_WR, 0x00);
> +
> + if (ps_bridge->gpio_mode_sel)
> + gpiod_set_value(ps_bridge->gpio_mode_sel, 1);
> + return 0;
> +}
> +
> +static int ps8640_enter_bl(struct ps8640 *ps_bridge)
> +{
> + ps_bridge->in_fw_update = true;
> + return ps8640_spi_dl_mode(ps_bridge);
> +}
> +
> +static void ps8640_exit_bl(struct ps8640 *ps_bridge, const struct firmware *fw)
> +{
> + ps8640_spi_normal_mode(ps_bridge);
> + ps_bridge->in_fw_update = false;
> +}
> +
> +static int ps8640_load_fw(struct ps8640 *ps_bridge, const struct firmware *fw)
> +{
> + struct i2c_client *client = ps_bridge->page[0];
> + struct device *dev = &client->dev;
> + int ret;
> + bool ps8640_status_backup = ps_bridge->enabled;
> +
> + ret = ps8640_validate_firmware(ps_bridge, fw);
> + if (ret)
> + return ret;
> +
> + mutex_lock(&ps_bridge->fw_mutex);
> + if (!ps_bridge->in_fw_update) {
> + if (!ps8640_status_backup)
> + ps8640_pre_enable(&ps_bridge->bridge);
> +
> + ret = ps8640_enter_bl(ps_bridge);
> + if (ret)
> + goto exit;
> + }
> +
> + ret = ps8640_rom_prepare(ps_bridge);
> + if (ret)
> + goto exit;
> +
> + ret = ps8640_write_rom(ps_bridge, fw);
> +
> +exit:
> + if (ret)
> + dev_err(dev, "Failed to load firmware, %d\n", ret);
> +
> + ps8640_exit_bl(ps_bridge, fw);
> + if (!ps8640_status_backup)
> + ps8640_post_disable(&ps_bridge->bridge);
> + mutex_unlock(&ps_bridge->fw_mutex);
> + return ret;
> +}
> +
> +static ssize_t ps8640_update_fw_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct i2c_client *client = to_i2c_client(dev);
> + struct ps8640 *ps_bridge = i2c_get_clientdata(client);
> + const struct firmware *fw;
> + int error;
> +
> + error = request_firmware(&fw, PS_FW_NAME, dev);
> + if (error) {
> + dev_err(dev, "Unable to open firmware %s: %d\n",
> + PS_FW_NAME, error);
> + return error;
> + }
> +
> + error = ps8640_load_fw(ps_bridge, fw);
> + if (error)
> + dev_err(dev, "The firmware update failed(%d)\n", error);
> + else
> + dev_info(dev, "The firmware update succeeded\n");
> +
> + release_firmware(fw);
> + return error ? error : count;
> +}
> +
> +static DEVICE_ATTR(fw_version, S_IRUGO, ps8640_fw_version_show, NULL);
> +static DEVICE_ATTR(hw_version, S_IRUGO, ps8640_hw_version_show, NULL);
> +static DEVICE_ATTR(update_fw, S_IWUSR, NULL, ps8640_update_fw_store);
> +
> +static struct attribute *ps8640_attrs[] = {
> + &dev_attr_fw_version.attr,
> + &dev_attr_hw_version.attr,
> + &dev_attr_update_fw.attr,
> + NULL
> +};
> +
> +static const struct attribute_group ps8640_attr_group = {
> + .attrs = ps8640_attrs,
> +};
> +
> +static void ps8640_remove_sysfs_group(void *data)
> +{
> + struct ps8640 *ps_bridge = data;
> +
> + sysfs_remove_group(&ps_bridge->page[0]->dev.kobj, &ps8640_attr_group);
> +}
> +
> +static int ps8640_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct device *dev = &client->dev;
> + struct ps8640 *ps_bridge;
> + struct device_node *np = dev->of_node;
> + struct device_node *port, *out_ep;
> + struct device_node *panel_node = NULL;
> + int ret;
> + u32 i;
> +
> + ps_bridge = devm_kzalloc(dev, sizeof(*ps_bridge), GFP_KERNEL);
> + if (!ps_bridge)
> + return -ENOMEM;
> +
> + /* port at 1 is ps8640 output port */
> + port = of_graph_get_port_by_id(np, 1);
> + if (port) {
> + out_ep = of_get_child_by_name(port, "endpoint");
> + of_node_put(port);
> + if (out_ep) {
> + panel_node = of_graph_get_remote_port_parent(out_ep);
> + of_node_put(out_ep);
> + }
> + }
> + if (panel_node) {
> + ps_bridge->panel = of_drm_find_panel(panel_node);
> + of_node_put(panel_node);
> + if (!ps_bridge->panel)
> + return -EPROBE_DEFER;
> + }
> +
> + mutex_init(&ps_bridge->fw_mutex);
> + ps_bridge->supplies[0].supply = "vdd33";
> + ps_bridge->supplies[1].supply = "vdd12";
> + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies),
> + ps_bridge->supplies);
> + if (ret) {
> + dev_info(dev, "failed to get regulators: %d\n", ret);
> + return ret;
> + }
> +
> + ps_bridge->gpio_mode_sel = devm_gpiod_get_optional(&client->dev,
> + "mode-sel",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(ps_bridge->gpio_mode_sel)) {
> + ret = PTR_ERR(ps_bridge->gpio_mode_sel);
> + dev_err(dev, "cannot get mode-sel %d\n", ret);
> + return ret;
> + }
> +
> + ps_bridge->gpio_power_down = devm_gpiod_get(&client->dev, "sleep",
> + GPIOD_OUT_LOW);
> + if (IS_ERR(ps_bridge->gpio_power_down)) {
> + ret = PTR_ERR(ps_bridge->gpio_power_down);
> + dev_err(dev, "cannot get sleep: %d\n", ret);
> + return ret;
> + }
> +
> + /*
> + * Request the reset pin low to avoid the bridge being
> + * initialized prematurely
> + */
> + ps_bridge->gpio_reset = devm_gpiod_get(&client->dev, "reset",
> + GPIOD_OUT_LOW);
> + if (IS_ERR(ps_bridge->gpio_reset)) {
> + ret = PTR_ERR(ps_bridge->gpio_reset);
> + dev_err(dev, "cannot get reset: %d\n", ret);
> + return ret;
> + }
> +
> + ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
> + ps_bridge->bridge.of_node = dev->of_node;
> +
> + ps_bridge->page[0] = client;
> + ps_bridge->ddc_i2c = i2c_new_dummy(client->adapter, EDID_I2C_ADDR);
> + if (!ps_bridge->ddc_i2c) {
> + dev_err(dev, "failed ddc_i2c dummy device, address%02x\n",
> + EDID_I2C_ADDR);
> + return -EBUSY;
> + }
> + /*
> + * ps8640 uses multiple addresses, use dummy devices for them
> + * page[0]: for DP control
> + * page[1]: for VIDEO Bridge
> + * page[2]: for control top
> + * page[3]: for DSI Link Control1
> + * page[4]: for MIPI Phy
> + * page[5]: for VPLL
> + * page[6]: for DSI Link Control2
> + * page[7]: for spi rom mapping
> + */
> + for (i = 1; i < MAX_DEVS; i++) {
> + ps_bridge->page[i] = i2c_new_dummy(client->adapter,
> + client->addr + i);
> + if (!ps_bridge->page[i]) {
> + dev_err(dev, "failed i2c dummy device, address%02x\n",
> + client->addr + i);
> + ret = -EBUSY;
> + goto exit_dummy;
> + }
> + }
> + i2c_set_clientdata(client, ps_bridge);
> +
> + ret = sysfs_create_group(&client->dev.kobj, &ps8640_attr_group);
> + if (ret) {
> + dev_err(dev, "failed to create sysfs entries: %d\n", ret);
> + goto exit_dummy;
> + }
> +
> + ret = devm_add_action(dev, ps8640_remove_sysfs_group, ps_bridge);
> + if (ret) {
> + dev_err(dev, "failed to add sysfs cleanup action: %d\n", ret);
> + goto exit_remove_sysfs;
> + }
> +
> + ret = drm_bridge_add(&ps_bridge->bridge);
> + if (ret) {
> + dev_err(dev, "Failed to add bridge: %d\n", ret);
> + goto exit_remove_sysfs;
> + }
> + return 0;
> +
> +exit_remove_sysfs:
> + sysfs_remove_group(&ps_bridge->page[0]->dev.kobj, &ps8640_attr_group);
> +exit_dummy:
> + while (--i)
> + i2c_unregister_device(ps_bridge->page[i]);
> + i2c_unregister_device(ps_bridge->ddc_i2c);
> + return ret;
> +}
> +
> +static int ps8640_remove(struct i2c_client *client)
> +{
> + struct ps8640 *ps_bridge = i2c_get_clientdata(client);
> + int i = MAX_DEVS;
> +
> + drm_bridge_remove(&ps_bridge->bridge);
> + sysfs_remove_group(&ps_bridge->page[0]->dev.kobj, &ps8640_attr_group);
> + while (--i)
> + i2c_unregister_device(ps_bridge->page[i]);
> +
> + i2c_unregister_device(ps_bridge->ddc_i2c);
> + return 0;
> +}
> +
> +static const struct i2c_device_id ps8640_i2c_table[] = {
> + { "parade,ps8640", 0 },
> + {},
> +};
> +MODULE_DEVICE_TABLE(i2c, ps8640_i2c_table);
> +
> +static const struct of_device_id ps8640_match[] = {
> + { .compatible = "parade,ps8640" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, ps8640_match);
> +
> +static struct i2c_driver ps8640_driver = {
> + .id_table = ps8640_i2c_table,
> + .probe = ps8640_probe,
> + .remove = ps8640_remove,
> + .driver = {
> + .name = "parade,ps8640",
> + .of_match_table = ps8640_match,
> + },
> +};
> +module_i2c_driver(ps8640_driver);
> +
> +MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
> +MODULE_AUTHOR("CK Hu <ck.hu@mediatek.com>");
> +MODULE_DESCRIPTION("PARADE ps8640 DSI-eDP converter driver");
> +MODULE_LICENSE("GPL v2");
> --
> 1.7.9.5
>
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply
* [PATCH v4 0/4] add support for impedance control for TI dp83867 phy and fix 2nd ethernet on dra72 rev C evm
From: David Miller @ 2016-10-18 14:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018112020.30273-1-mugunthanvnm@ti.com>
From: Mugunthan V N <mugunthanvnm@ti.com>
Date: Tue, 18 Oct 2016 16:50:16 +0530
> Add support for configurable impedance control for TI dp83867
> phy via devicetree. More documentation in [1].
> CPSW second ethernet is not working, fix it by enabling
> impedance configuration on the phy.
Series applied to net-next, thanks.
^ permalink raw reply
* [RESEND PATCH v10 00/11] Add support for FDMA DMA controller and slim core rproc found on STi chipsets
From: Vinod Koul @ 2016-10-18 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476783556-2501-1-git-send-email-peter.griffin@linaro.org>
On Tue, Oct 18, 2016 at 10:39:05AM +0100, Peter Griffin wrote:
> Hi Vinod and Bjorn,
>
> This patchset adds support for the Flexible Direct Memory Access (FDMA) core
> found on STi chipsets from STMicroelectronics. The FDMA is a slim core CPU
> with a dedicated firmware. It is a general purpose DMA controller supporting
> 16 independent channels and data can be moved from memory to memory or between
> memory and paced latency critical real time targets.
>
> [..]
>
> V10 series updates remoteproc kconfig subsystem to use 'depends on' rather
> than select for the remoteproc core. Remoteproc client drivers now need to
> 'depends on' for the core part.
>
> This avoids the Kconfig recursive dependency errors and reliance on the DRM
> patch included with the v9 series. Patches are also included for enabling the
> remoteproc core in the multi_v7 defconfig. All patches for DRM subsystem have
> been removed.
>
> Note there is no longer a depedency with the DRM_VIRTIO_GPU driver in this series,
> only remoteproc and dmaengine subsystems.
That is a better approach and I have applied this now...
--
~Vinod
^ permalink raw reply
* [PATCH] Revert "dmaengine: pxa_dma: add support for legacy transition"
From: Vinod Koul @ 2016-10-18 14:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476773192-23715-1-git-send-email-robert.jarzmik@free.fr>
On Tue, Oct 18, 2016 at 08:46:32AM +0200, Robert Jarzmik wrote:
> This reverts commit c91134d9194478144ba579ca6efeddf628055650.
>
> The conversion of the pxa architecture is now finished for all
> drivers, so this functions has fullfilled its purpose and can
> now be removed.
Applied, thanks
--
~Vinod
^ permalink raw reply
* [PATCH 4/5] staging/vchi: Add a TODO file of things I know we need to deal with.
From: popcorn mix @ 2016-10-18 14:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161017194406.1080-5-eric@anholt.net>
On Mon, Oct 17, 2016 at 8:44 PM, Eric Anholt <eric@anholt.net> wrote:
>
> I've also left out VC-CMA, which appears to be about having Linux
> manage a CMA area that the firmware gets to make allocations out of.
> I'm not clear on if this is useful (the firmware's need for memory
> drops massively with vc4 present, and may drop even more depending on
> how we resolve dmabuf handling for camera and video decode)
VC-CMA allows unused memory from the gpu to be used as CMA on the
linux side in a dynamic way.
However it has always had some issues, so is not enabled by default.
The main reason for wanting the gpu side to have significant memory is
for textures used
by the gpu side 3D driver. In the vc4-kms-v3d driver world the
requirement for significant amounts
of gpu memory goes away.
For most camera and video decode usage, the default gpu_mem=64M is sufficient.
As such, I'd ignore VC-CMA upstream, and assume it will disappear
downstream eventually.
vc_mem is used by vcdbg to get gpu side addresses for debug features
(e.g. extracting gpu debug log and viewing its memory heaps and vchiq state).
vcsm is currently used for allocating arm accessible memory from the gpu.
It is used by mmal when in zero copy mode (typically enabled) and as Eric says,
is likely to be used for dmabuf allocation.
^ permalink raw reply
* [PATCH] arm64: mm: Fix memmap to be initialized for the entire section
From: Robert Richter @ 2016-10-18 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018101715.GA15639@leverpostej>
Mark,
thanks for your answer. See below. I also attached the full crash
dump.
On 18.10.16 11:18:36, Mark Rutland wrote:
> Hi Robert, Ard,
>
> Sorry for the delay in getting to this; I've been travelling a lot
> lately and in the meantime this managed to get buried in my inbox.
>
> On Thu, Oct 06, 2016 at 06:11:14PM +0200, Robert Richter wrote:
> > On 06.10.16 11:00:33, Ard Biesheuvel wrote:
> > > On 6 October 2016 at 10:52, Robert Richter <rrichter@cavium.com> wrote:
> > > > There is a memory setup problem on ThunderX systems with certain
> > > > memory configurations. The symptom is
> > > >
> > > > kernel BUG at mm/page_alloc.c:1848!
> > > >
> > > > This happens for some configs with 64k page size enabled. The bug
> > > > triggers for page zones with some pages in the zone not assigned to
> > > > this particular zone. In my case some pages that are marked as nomap
> > > > were not reassigned to the new zone of node 1, so those are still
> > > > assigned to node 0.
> > > >
> > > > The reason for the mis-configuration is a change in pfn_valid() which
> > > > reports pages marked nomap as invalid:
> > > >
> > > > 68709f45385a arm64: only consider memblocks with NOMAP cleared for linear mapping
> > >
> > > These pages are owned by the firmware, which may map it with
> > > attributes that conflict with the attributes we use for the linear
> > > mapping. This means they should not be covered by the linear mapping.
> > >
> > > > This causes pages marked as nomap being no long reassigned to the new
> > > > zone in memmap_init_zone() by calling __init_single_pfn().
>
> Why do we have pages for a nomap region? Given the region shouldn't be
> in the linear mapping, and isn't suitable for general allocation, I
> don't believe it makes sense to have a struct page for any part of it.
>
> Am I missing some reason that we require a struct page?
>
> e.g. is it just easier to allocate an unused struct page than to carve
> it out?
Pages are handled in blocks with size MAX_ORDER_NR_PAGES. The start
and end pfn of a memory region is aligned then to fit the mem block
size (see memmap_init_zone()). Therefore a memblock may contain pages
without underlying physical memory.
mm code requires the whole memmap to be initialized, this means that
for each page in the whole mem block there is a valid struct page. See
e.g. move_freepages_block() and move_freepages(), stuct page is
accessed even before pfn_valid() is used. I assume there are other
occurrences of that too.
My interpretation is that pfn_valid() checks for the existence of a
valid struct page, there must not necessarily phys memory mapped to
it. This is the reason why I changed pfn_valid() to use
memblock_is_memory() which is sufficient for generic mm code. Only in
arm64 mm code I additinally added the memblock_is_map_memory() check
where pfn_valid() was used.
>
> > > This sounds like the root cause of your issue. Could we not fix that instead?
> >
> > Yes, this is proposal b) from my last mail that would work too: I
> > implemented an arm64 private early_pfn_valid() function that uses
> > memblock_is_memory() to setup all pages of a zone. Though, I think
> > this is the wrong way and thus I prefer this patch instead. I see
> > serveral reasons for this:
> >
> > Inconsistent use of struct *page, it is initialized but never used
> > again.
>
> As above, I don't believe we should have a struct page to initialise in
> the first place.
>
> > Other archs only do a basic range check in pfn_valid(), the default
> > implementation just returns if the whole section is valid. As I
> > understand the code, if the mem range is not aligned to the section,
> > then there will be pfn's in the section that don't have physical mem
> > attached. The page is then just initialized, it's not marked reserved
> > nor the refcount is non-zero. It is then simply not used. This is how
> > no-map pages should be handled too.
> >
> > I think pfn_valid() is just a quick check if the pfn's struct *page
> > can be used. There is a good description for this in include/linux/
> > mmzone.h. So there can be memory holes that have a valid pfn.
>
> I take it you mean the comment in the CONFIG_ARCH_HAS_HOLES_MEMORYMODEL
> ifdef (line 1266 in v4.9-rc1)?
Yes.
>
> I'm not sufficiently acquainted with the memmap code to follow; I'll
> need to dig into that a bit further.
>
> > If the no-map memory needs special handling, then additional checks
> > need to be added to the particular code (as in ioremap.c). It's imo
> > wrong to (mis-)use pfn_valid for that.
> >
> > Variant b) involves generic mm code to fix it for arm64, this patch is
> > an arm64 change only. This makes it harder to get a fix for it.
> > (Though maybe only a problem of patch logistics.)
> >
> > > > Fixing this by restoring the old behavior of pfn_valid() to use
> > > > memblock_is_memory().
> > >
> > > This is incorrect imo. In general, pfn_valid() means ordinary memory
> > > covered by the linear mapping and the struct page array. Returning
> > > reserved ranges that the kernel should not even touch only to please
> > > the NUMA code seems like an inappropriate way to deal with this issue.
> >
> > As said above, it is not marked as reserved, it is treated like
> > non-existing memory.
>
> I think Ard was using "reserved" in the more general sense than the
> Linux-specific meaning. NOMAP is distinct from the Linux concept of
> "reserved" memory, but is "reserved" in some sense.
>
> Memory with NOMAP is meant to be treated as non-existent for the purpose
> of the linear mapping (and thus for the purpose of struct page).
Yes, it's not marked reserved and can never be freed.
Thanks,
-Robert
>
> > This has been observed for non-numa kernels too and can happen for
> > each zone that is only partly initialized.
> >
> > I think the patch addresses your concerns. I can't see there the
> > kernel uses memory marked as nomap in a wrong way.
>
> I'll have to dig into this locally; I'm still not familiar enough with
> this code to know what the right thing to do is.
>
> Thanks,
> Mark.
EFI stub: Booting Linux Kernel...
EFI stub: Using DTB from configuration table
EFI stub: Exiting boot services and installing virtual address map...
Booting Linux on physical CPU 0x0
Linux version 4.8.0-rc4-00267-g664e88c (root at crb2spass2rric.localdomain) (gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.1) ) #3 SMP Wed Sep 7 06:38:13 UTC 2016
Boot CPU: AArch64 Processor [431f0a10]
efi: Getting EFI parameters from FDT:
efi: EFI v2.40 by Cavium Thunder cn88xx EFI ThunderX-Firmware-Release-1.22.10-0-g4e85766 Aug 24 2016 15:59:03
efi: ACPI=0xfffff000 ACPI 2.0=0xfffff014 SMBIOS 3.0=0x10ffafcf000
cma: Reserved 512 MiB at 0x00000000c0000000
NUMA: Adding memblock [0x1400000 - 0xfffffffff] on node 0
NUMA: Adding memblock [0x10000400000 - 0x10fffffffff] on node 1
NUMA: parsing numa-distance-map-v1
NUMA: Initmem setup node 0 [mem 0x01400000-0xfffffffff]
NUMA: NODE_DATA [mem 0xfffff2580-0xfffffffff]
NUMA: Initmem setup node 1 [mem 0x10000400000-0x10fffffffff]
NUMA: NODE_DATA [mem 0x10ffffa2500-0x10ffffaff7f]
kmemleak: Kernel memory leak detector disabled
Zone ranges:
DMA [mem 0x0000000001400000-0x00000000ffffffff]
Normal [mem 0x0000000100000000-0x0000010fffffffff]
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000001400000-0x00000000fffdffff]
node 0: [mem 0x00000000fffe0000-0x00000000ffffffff]
node 0: [mem 0x0000000100000000-0x0000000fffffffff]
node 1: [mem 0x0000010000400000-0x0000010ff9e8ffff]
node 1: [mem 0x0000010ff9e90000-0x0000010ff9f2ffff]
node 1: [mem 0x0000010ff9f30000-0x0000010ffaeaffff]
node 1: [mem 0x0000010ffaeb0000-0x0000010ffaffffff]
node 1: [mem 0x0000010ffb000000-0x0000010ffffaffff]
node 1: [mem 0x0000010ffffb0000-0x0000010fffffffff]
Initmem setup node 0 [mem 0x0000000001400000-0x0000000fffffffff]
Initmem setup node 1 [mem 0x0000010000400000-0x0000010fffffffff]
psci: probing for conduit method from DT.
psci: PSCIv0.2 detected in firmware.
psci: Using standard PSCI v0.2 function IDs
psci: Trusted OS resident on physical CPU 0x0
Number of cores (96) exceeds configured maximum of 8 - clipping
percpu: Embedded 3 pages/cpu @ffffff0fffce0000 s117704 r8192 d70712 u196608
Detected VIPT I-cache on CPU0
CPU features: enabling workaround for Cavium erratum 27456
Built 2 zonelists in Node order, mobility grouping on. Total pages: 2094720
Policy zone: Normal
Kernel command line: BOOT_IMAGE=/vmlinuz root=UUID=9a418ae5-231a-40c7-b7ba-ca70cfadfc5e ro LANG=en_US.UTF-8
PID hash table entries: 4096 (order: -1, 32768 bytes)
software IO TLB [mem 0xfbfd0000-0xfffd0000] (64MB) mapped at [fffffe00fbfd0000-fffffe00fffcffff]
Memory: 133196160K/134193152K available (9084K kernel code, 1545K rwdata, 3712K rodata, 1536K init, 15826K bss, 472704K reserved, 524288K cma-reserved)
Virtual kernel memory layout:
modules : 0xfffffc0000000000 - 0xfffffc0008000000 ( 128 MB)
vmalloc : 0xfffffc0008000000 - 0xfffffdff5fff0000 ( 2045 GB)
.text : 0xfffffc0008080000 - 0xfffffc0008960000 ( 9088 KB)
.rodata : 0xfffffc0008960000 - 0xfffffc0008d10000 ( 3776 KB)
.init : 0xfffffc0008d10000 - 0xfffffc0008e90000 ( 1536 KB)
.data : 0xfffffc0008e90000 - 0xfffffc0009012600 ( 1546 KB)
.bss : 0xfffffc0009012600 - 0xfffffc0009f86fc8 ( 15827 KB)
fixed : 0xfffffdff7e7d0000 - 0xfffffdff7ec00000 ( 4288 KB)
PCI I/O : 0xfffffdff7ee00000 - 0xfffffdff7fe00000 ( 16 MB)
vmemmap : 0xfffffdff80000000 - 0xfffffe0000000000 ( 2 GB maximum)
0xfffffdff80005000 - 0xfffffdffc4000000 ( 1087 MB actual)
memory : 0xfffffe0001400000 - 0xffffff1000000000 (1114092 MB)
SLUB: HWalign=128, Order=0-3, MinObjects=0, CPUs=8, Nodes=2
Running RCU self tests
Hierarchical RCU implementation.
RCU lockdep checking is enabled.
Build-time adjustment of leaf fanout to 64.
NR_IRQS:64 nr_irqs:64 0
GICv3: GIC: Using split EOI/Deactivate mode
ITS: /interrupt-controller at 801000000000/gic-its at 801000020000
ITS at 0x0000801000020000: allocated 2097152 Devices @ff5000000 (flat, esz 8, psz 64K, shr 1)
ITS: /interrupt-controller at 801000000000/gic-its at 901000020000
ITS at 0x0000901000020000: allocated 2097152 Devices @ffa000000 (flat, esz 8, psz 64K, shr 1)
GIC: using LPI property table @0x0000000ff4140000
ITS: Allocated 32512 chunks for LPIs
GICv3: CPU0: found redistributor 0 region 0:0x0000801080000000
CPU0: using LPI pending table @0x0000000ff4150000
arm_arch_timer: Architected cp15 timer(s) running at 100.00MHz (phys).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x171024e7e0, max_idle_ns: 440795205315 ns
sched_clock: 56 bits at 100MHz, resolution 10ns, wraps every 4398046511100ns
Console: colour dummy device 80x25
console [tty0] enabled
Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
... MAX_LOCKDEP_SUBCLASSES: 8
... MAX_LOCK_DEPTH: 48
... MAX_LOCKDEP_KEYS: 8191
... CLASSHASH_SIZE: 4096
... MAX_LOCKDEP_ENTRIES: 32768
... MAX_LOCKDEP_CHAINS: 65536
... CHAINHASH_SIZE: 32768
memory used by lock dependency info: 8159 kB
per task-struct memory footprint: 1920 bytes
mempolicy: Enabling automatic NUMA balancing. Configure with numa_balancing= or the kernel.numa_balancing sysctl
Calibrating delay loop (skipped), value calculated using timer frequency.. 200.00 BogoMIPS (lpj=100000)
pid_max: default: 32768 minimum: 301
Security Framework initialized
Yama: becoming mindful.
SELinux: Initializing.
Dentry cache hash table entries: 16777216 (order: 11, 134217728 bytes)
Inode-cache hash table entries: 8388608 (order: 10, 67108864 bytes)
Mount-cache hash table entries: 262144 (order: 5, 2097152 bytes)
Mountpoint-cache hash table entries: 262144 (order: 5, 2097152 bytes)
ftrace: allocating 29244 entries in 8 pages
Unable to find CPU node for /cpus/cpu at 8
/cpus/cpu-map/cluster0/core8: Can't get CPU for leaf core
ASID allocator initialised with 65536 entries
PCI/MSI: /interrupt-controller at 801000000000/gic-its at 801000020000 domain created
PCI/MSI: /interrupt-controller at 801000000000/gic-its at 901000020000 domain created
Platform MSI: /interrupt-controller at 801000000000/gic-its at 801000020000 domain created
Platform MSI: /interrupt-controller at 801000000000/gic-its at 901000020000 domain created
Remapping and enabling EFI services.
UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?
------------[ cut here ]------------
WARNING: CPU: 0 PID: 1 at arch/arm64/kernel/efi.c:34 efi_create_mapping+0x5c/0x11c
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.8.0-rc4-00267-g664e88c #3
Hardware name: Cavium ThunderX CN88XX board (DT)
task: fffffe0fee55a200 task.stack: ffffff00004a4000
PC is at efi_create_mapping+0x5c/0x11c
LR is at efi_create_mapping+0x5c/0x11c
pc : [<fffffc0008d14f68>] lr : [<fffffc0008d14f68>] pstate: 60000045
sp : ffffff00004a7d00
x29: ffffff00004a7d00 x28: 0000000000000000
x27: 0000000000000000 x26: 0000000000000000
x25: 0000000000000000 x24: fffffc0008f9c730
x23: fffffc0008f9c730 x22: fffffc0008c60ac0
x21: fffffc0008f9c730 x20: 00c8000000000713
x19: ffffff0ff76b0c08 x18: 0000000000000010
x17: 00000000c9cbbfc7 x16: 0000000000000000
x15: fffffc0089c956f7 x14: 3f657261776d7269
x13: 6620796767756220 x12: 2d2d20424b203436
x11: 206f742064656e67 x10: 0000000000000077
x9 : 65726120736e6f69 x8 : 0000000000000001
x7 : ffffff00004a4000 x6 : fffffc000814a288
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000001 x2 : ffffff00004a4000
x1 : fffffe0fee55a200 x0 : 0000000000000040
---[ end trace fcdd7f8cb96cdb3b ]---
Call trace:
Exception stack(0xffffff00004a7b20 to 0xffffff00004a7c50)
7b20: ffffff0ff76b0c08 0000040000000000 ffffff00004a7d00 fffffc0008d14f68
7b40: 0000000060000045 000000000000003d 0000000000000001 fffffc000814a9fc
7b60: ffffff00004a7c00 fffffc000814adcc ffffff00004a7c60 fffffc0008baf420
7b80: fffffc0008f9c730 fffffc0008c60ac0 fffffc0008f9c730 fffffc0008f9c730
7ba0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7bc0: fffffc00080d6d70 0000000000000000 0000000000000040 fffffe0fee55a200
7be0: ffffff00004a4000 0000000000000001 0000000000000001 0000000000000000
7c00: fffffc000814a288 ffffff00004a4000 0000000000000001 65726120736e6f69
7c20: 0000000000000077 206f742064656e67 2d2d20424b203436 6620796767756220
7c40: 3f657261776d7269 fffffc0089c956f7
[<fffffc0008d14f68>] efi_create_mapping+0x5c/0x11c
[<fffffc0008d5e1ec>] arm_enable_runtime_services+0x12c/0x210
[<fffffc0008082ff4>] do_one_initcall+0x44/0x138
[<fffffc0008d10d30>] kernel_init_freeable+0x17c/0x2e0
[<fffffc000893c888>] kernel_init+0x20/0xf8
[<fffffc0008082b80>] ret_from_fork+0x10/0x50
EFI remap 0x0000010ff9e98000 => 0000000020008000
EFI remap 0x0000010ffaeb6000 => 00000000200a6000
EFI remap 0x0000010ffafc9000 => 00000000201b9000
EFI remap 0x0000010ffafcd000 => 00000000201bd000
EFI remap 0x0000010ffffb9000 => 00000000201f9000
EFI remap 0x0000010ffffcd000 => 000000002020d000
EFI remap 0x0000804000001000 => 0000000020241000
EFI remap 0x000087e0d0001000 => 0000000020251000
Detected VIPT I-cache on CPU1
GICv3: CPU1: found redistributor 1 region 0:0x0000801080020000
CPU1: using LPI pending table @0x0000010014060000
CPU1: Booted secondary processor [431f0a10]
------------[ cut here ]------------
WARNING: CPU: 1 PID: 0 at ./include/linux/cpumask.h:121 gic_raise_softirq+0x14c/0x1e0
Modules linked in:
CPU: 1 PID: 0 Comm: swapper/1 Tainted: G W 4.8.0-rc4-00267-g664e88c #3
Hardware name: Cavium ThunderX CN88XX board (DT)
task: fffffe0fee57b600 task.stack: fffffe0fe4038000
PC is at gic_raise_softirq+0x14c/0x1e0
LR is at gic_raise_softirq+0xc0/0x1e0
pc : [<fffffc00084c07a4>] lr : [<fffffc00084c0718>] pstate: 600001c5
sp : fffffe0fe403bcd0
x29: fffffe0fe403bcd0 x28: 0000000000000001
x27: fffffc0008fd7b1d x26: 0000000000000000
x25: fffffc0008ec2000 x24: fffffc0008ecebc8
x23: fffffc0008998688 x22: 0000000000000001
x21: fffffc0008ec2e34 x20: 0000000000000000
x19: 0000000000000008 x18: 0000000000000030
x17: 0000000000000000 x16: 0000000000000000
x15: fffffc0009c97f08 x14: 0000000000000002
x13: 0000000000000332 x12: 0000000000000335
x11: fffffc0009bf3de0 x10: 0000000000000332
x9 : fffffe0fe4038000 x8 : 0000000000000000
x7 : 00000000ffffffff x6 : 0000000000000000
x5 : fffffffffffffffe x4 : 0000000000000040
x3 : 0000000000000000 x2 : 0000000000000000
x1 : 0000000000000008 x0 : 0000000000000001
---[ end trace fcdd7f8cb96cdb3c ]---
Call trace:
Exception stack(0xfffffe0fe403baf0 to 0xfffffe0fe403bc20)
bae0: 0000000000000008 0000040000000000
bb00: fffffe0fe403bcd0 fffffc00084c07a4 00000000600001c5 000000000000003d
bb20: fffffe0fee57bec0 ffffffffffffffd8 0000000000000028 fffffe0fee57be70
bb40: fffffc000925fe88 0000000000000002 fffffc00080886c0 fffffe0fee57b600
bb60: fffffe0fe403bb90 fffffc0008088974 fffffc00099b4d60 fffffe0fee57b600
bb80: fffffc000925fe88 fffffe0fe403bd4c fffffe0fe403bbe0 fffffc00080889e8
bba0: 0000000000000001 0000000000000008 0000000000000000 0000000000000000
bbc0: 0000000000000040 fffffffffffffffe 0000000000000000 00000000ffffffff
bbe0: 0000000000000000 fffffe0fe4038000 0000000000000332 fffffc0009bf3de0
bc00: 0000000000000335 0000000000000332 0000000000000002 fffffc0009c97f08
[<fffffc00084c07a4>] gic_raise_softirq+0x14c/0x1e0
[<fffffc000808e028>] smp_cross_call+0x80/0x238
[<fffffc000808efa4>] smp_send_reschedule+0x3c/0x48
[<fffffc00081021a8>] resched_curr+0x58/0x90
[<fffffc0008103fd8>] check_preempt_curr+0x70/0xe8
[<fffffc0008104090>] ttwu_do_wakeup+0x40/0x2e8
[<fffffc00081043cc>] ttwu_do_activate+0x94/0xc0
[<fffffc00081058a8>] try_to_wake_up+0x200/0x580
[<fffffc0008105d3c>] default_wake_function+0x34/0x48
[<fffffc0008126afc>] __wake_up_common+0x64/0xa8
[<fffffc0008126bec>] __wake_up_locked+0x3c/0x50
[<fffffc0008127b58>] complete+0x48/0x68
[<fffffc000808e630>] secondary_start_kernel+0x180/0x208
[<0000000001482e08>] 0x1482e08
Detected VIPT I-cache on CPU2
GICv3: CPU2: found redistributor 2 region 0:0x0000801080040000
CPU2: using LPI pending table @0x0000010014070000
CPU2: Booted secondary processor [431f0a10]
Detected VIPT I-cache on CPU3
GICv3: CPU3: found redistributor 3 region 0:0x0000801080060000
CPU3: using LPI pending table @0x0000010014080000
CPU3: Booted secondary processor [431f0a10]
Detected VIPT I-cache on CPU4
GICv3: CPU4: found redistributor 4 region 0:0x0000801080080000
CPU4: using LPI pending table @0x0000010014090000
CPU4: Booted secondary processor [431f0a10]
Detected VIPT I-cache on CPU5
GICv3: CPU5: found redistributor 5 region 0:0x00008010800a0000
CPU5: using LPI pending table @0x00000100140a0000
CPU5: Booted secondary processor [431f0a10]
Detected VIPT I-cache on CPU6
GICv3: CPU6: found redistributor 6 region 0:0x00008010800c0000
CPU6: using LPI pending table @0x00000100140b0000
CPU6: Booted secondary processor [431f0a10]
Detected VIPT I-cache on CPU7
GICv3: CPU7: found redistributor 7 region 0:0x00008010800e0000
CPU7: using LPI pending table @0x00000100140c0000
CPU7: Booted secondary processor [431f0a10]
Brought up 8 CPUs
SMP: Total of 8 processors activated.
CPU features: detected feature: GIC system register CPU interface
CPU features: detected feature: LSE atomic instructions
CPU features: detected feature: Software prefetching using PRFM
CPU: All CPU(s) started at EL2
alternatives: patching kernel code
devtmpfs: initialized
SMBIOS 3.0.0 present.
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
atomic64_test: passed
pinctrl core: initialized pinctrl subsystem
NET: Registered protocol family 16
cpuidle: using governor menu
vdso: 2 pages (1 code @ fffffc0008980000, 1 data @ fffffc0008eb0000)
hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
DMA: preallocated 256 KiB pool for atomic allocations
Serial: AMBA PL011 UART driver
87e024000000.serial: ttyAMA0 at MMIO 0x87e024000000 (irq = 7, base_baud = 0) is a PL011 rev3
console [ttyAMA0] enabled
87e025000000.serial: ttyAMA1 at MMIO 0x87e025000000 (irq = 8, base_baud = 0) is a PL011 rev3
OF: /soc at 0/pci at 848000000000: arguments longer than property
OF: /soc at 0/pci at 849000000000: arguments longer than property
OF: /soc at 0/pci at 84a000000000: arguments longer than property
OF: /soc at 0/pci at 84b000000000: arguments longer than property
OF: /soc at 0/pci at 87e0c0000000: arguments longer than property
OF: /soc at 100000000000/pci at 848000000000: arguments longer than property
OF: /soc at 100000000000/pci at 849000000000: arguments longer than property
OF: /soc at 100000000000/pci at 84a000000000: arguments longer than property
OF: /soc at 100000000000/pci at 84b000000000: arguments longer than property
HugeTLB registered 2 MB page size, pre-allocated 0 pages
HugeTLB registered 512 MB page size, pre-allocated 0 pages
ACPI: Interpreter disabled.
arm-smmu 830000000000.smmu0: probing hardware configuration...
arm-smmu 830000000000.smmu0: SMMUv2 with:
arm-smmu 830000000000.smmu0: stage 1 translation
arm-smmu 830000000000.smmu0: stage 2 translation
arm-smmu 830000000000.smmu0: nested translation
arm-smmu 830000000000.smmu0: non-coherent table walk
arm-smmu 830000000000.smmu0: (IDR0.CTTW overridden by dma-coherent property)
arm-smmu 830000000000.smmu0: stream matching with 128 register groups, mask 0x7fff
arm-smmu 830000000000.smmu0: 128 context banks (0 stage-2 only)
arm-smmu 830000000000.smmu0: Supported page sizes: 0x62215000
arm-smmu 830000000000.smmu0: Stage-1: 48-bit VA -> 48-bit IPA
arm-smmu 830000000000.smmu0: Stage-2: 48-bit IPA -> 48-bit PA
arm-smmu 830000000000.smmu0: registered 1 master devices
arm-smmu 831000000000.smmu1: probing hardware configuration...
arm-smmu 831000000000.smmu1: SMMUv2 with:
arm-smmu 831000000000.smmu1: stage 1 translation
arm-smmu 831000000000.smmu1: stage 2 translation
arm-smmu 831000000000.smmu1: nested translation
arm-smmu 831000000000.smmu1: non-coherent table walk
arm-smmu 831000000000.smmu1: (IDR0.CTTW overridden by dma-coherent property)
arm-smmu 831000000000.smmu1: stream matching with 128 register groups, mask 0x7fff
arm-smmu 831000000000.smmu1: 128 context banks (0 stage-2 only)
arm-smmu 831000000000.smmu1: Supported page sizes: 0x62215000
arm-smmu 831000000000.smmu1: Stage-1: 48-bit VA -> 48-bit IPA
arm-smmu 831000000000.smmu1: Stage-2: 48-bit IPA -> 48-bit PA
arm-smmu 831000000000.smmu1: registered 2 master devices
arm-smmu 832000000000.smmu2: probing hardware configuration...
arm-smmu 832000000000.smmu2: SMMUv2 with:
arm-smmu 832000000000.smmu2: stage 1 translation
arm-smmu 832000000000.smmu2: stage 2 translation
arm-smmu 832000000000.smmu2: nested translation
arm-smmu 832000000000.smmu2: non-coherent table walk
arm-smmu 832000000000.smmu2: (IDR0.CTTW overridden by dma-coherent property)
arm-smmu 832000000000.smmu2: stream matching with 128 register groups, mask 0x7fff
arm-smmu 832000000000.smmu2: 128 context banks (0 stage-2 only)
arm-smmu 832000000000.smmu2: Supported page sizes: 0x62215000
arm-smmu 832000000000.smmu2: Stage-1: 48-bit VA -> 48-bit IPA
arm-smmu 832000000000.smmu2: Stage-2: 48-bit IPA -> 48-bit PA
arm-smmu 832000000000.smmu2: registered 1 master devices
arm-smmu 833000000000.smmu3: probing hardware configuration...
arm-smmu 833000000000.smmu3: SMMUv2 with:
arm-smmu 833000000000.smmu3: stage 1 translation
arm-smmu 833000000000.smmu3: stage 2 translation
arm-smmu 833000000000.smmu3: nested translation
arm-smmu 833000000000.smmu3: non-coherent table walk
arm-smmu 833000000000.smmu3: (IDR0.CTTW overridden by dma-coherent property)
arm-smmu 833000000000.smmu3: stream matching with 128 register groups, mask 0x7fff
arm-smmu 833000000000.smmu3: 128 context banks (0 stage-2 only)
arm-smmu 833000000000.smmu3: Supported page sizes: 0x62215000
arm-smmu 833000000000.smmu3: Stage-1: 48-bit VA -> 48-bit IPA
arm-smmu 833000000000.smmu3: Stage-2: 48-bit IPA -> 48-bit PA
arm-smmu 833000000000.smmu3: registered 1 master devices
arm-smmu 930000000000.smmu4: probing hardware configuration...
arm-smmu 930000000000.smmu4: SMMUv2 with:
arm-smmu 930000000000.smmu4: stage 1 translation
arm-smmu 930000000000.smmu4: stage 2 translation
arm-smmu 930000000000.smmu4: nested translation
arm-smmu 930000000000.smmu4: non-coherent table walk
arm-smmu 930000000000.smmu4: (IDR0.CTTW overridden by dma-coherent property)
arm-smmu 930000000000.smmu4: stream matching with 128 register groups, mask 0x7fff
arm-smmu 930000000000.smmu4: 128 context banks (0 stage-2 only)
arm-smmu 930000000000.smmu4: Supported page sizes: 0x62215000
arm-smmu 930000000000.smmu4: Stage-1: 48-bit VA -> 48-bit IPA
arm-smmu 930000000000.smmu4: Stage-2: 48-bit IPA -> 48-bit PA
arm-smmu 930000000000.smmu4: registered 1 master devices
arm-smmu 931000000000.smmu5: probing hardware configuration...
arm-smmu 931000000000.smmu5: SMMUv2 with:
arm-smmu 931000000000.smmu5: stage 1 translation
arm-smmu 931000000000.smmu5: stage 2 translation
arm-smmu 931000000000.smmu5: nested translation
arm-smmu 931000000000.smmu5: non-coherent table walk
arm-smmu 931000000000.smmu5: (IDR0.CTTW overridden by dma-coherent property)
arm-smmu 931000000000.smmu5: stream matching with 128 register groups, mask 0x7fff
arm-smmu 931000000000.smmu5: 128 context banks (0 stage-2 only)
arm-smmu 931000000000.smmu5: Supported page sizes: 0x62215000
arm-smmu 931000000000.smmu5: Stage-1: 48-bit VA -> 48-bit IPA
arm-smmu 931000000000.smmu5: Stage-2: 48-bit IPA -> 48-bit PA
arm-smmu 931000000000.smmu5: registered 1 master devices
arm-smmu 932000000000.smmu6: probing hardware configuration...
arm-smmu 932000000000.smmu6: SMMUv2 with:
arm-smmu 932000000000.smmu6: stage 1 translation
arm-smmu 932000000000.smmu6: stage 2 translation
arm-smmu 932000000000.smmu6: nested translation
arm-smmu 932000000000.smmu6: non-coherent table walk
arm-smmu 932000000000.smmu6: (IDR0.CTTW overridden by dma-coherent property)
arm-smmu 932000000000.smmu6: stream matching with 128 register groups, mask 0x7fff
arm-smmu 932000000000.smmu6: 128 context banks (0 stage-2 only)
arm-smmu 932000000000.smmu6: Supported page sizes: 0x62215000
arm-smmu 932000000000.smmu6: Stage-1: 48-bit VA -> 48-bit IPA
arm-smmu 932000000000.smmu6: Stage-2: 48-bit IPA -> 48-bit PA
arm-smmu 932000000000.smmu6: registered 1 master devices
arm-smmu 933000000000.smmu7: probing hardware configuration...
arm-smmu 933000000000.smmu7: SMMUv2 with:
arm-smmu 933000000000.smmu7: stage 1 translation
arm-smmu 933000000000.smmu7: stage 2 translation
arm-smmu 933000000000.smmu7: nested translation
arm-smmu 933000000000.smmu7: non-coherent table walk
arm-smmu 933000000000.smmu7: (IDR0.CTTW overridden by dma-coherent property)
arm-smmu 933000000000.smmu7: stream matching with 128 register groups, mask 0x7fff
arm-smmu 933000000000.smmu7: 128 context banks (0 stage-2 only)
arm-smmu 933000000000.smmu7: Supported page sizes: 0x62215000
arm-smmu 933000000000.smmu7: Stage-1: 48-bit VA -> 48-bit IPA
arm-smmu 933000000000.smmu7: Stage-2: 48-bit IPA -> 48-bit PA
arm-smmu 933000000000.smmu7: registered 1 master devices
iommu: Adding device 848000000000.pci to group 0
iommu: Adding device 849000000000.pci to group 1
iommu: Adding device 84a000000000.pci to group 2
iommu: Adding device 84b000000000.pci to group 3
iommu: Adding device 88001f000000.pci to group 4
iommu: Adding device 948000000000.pci to group 5
iommu: Adding device 949000000000.pci to group 6
iommu: Adding device 94a000000000.pci to group 7
iommu: Adding device 94b000000000.pci to group 8
vgaarb: loaded
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NetLabel: Initializing
NetLabel: domain hash size = 128
NetLabel: protocols = UNLABELED CIPSOv4
NetLabel: unlabeled traffic allowed by default
DMA-API: preallocated 4096 debug entries
DMA-API: debugging enabled by kernel config
clocksource: Switched to clocksource arch_sys_counter
VFS: Disk quotas dquot_6.6.0
VFS: Dquot-cache hash table entries: 8192 (order 0, 65536 bytes)
pnp: PnP ACPI: disabled
NET: Registered protocol family 2
TCP established hash table entries: 524288 (order: 6, 4194304 bytes)
TCP bind hash table entries: 65536 (order: 6, 4194304 bytes)
TCP: Hash tables configured (established 524288 bind 65536)
UDP hash table entries: 65536 (order: 7, 10485760 bytes)
UDP-Lite hash table entries: 65536 (order: 7, 10485760 bytes)
NET: Registered protocol family 1
Unpacking initramfs...
------------[ cut here ]------------
kernel BUG at mm/page_alloc.c:1844!
Internal error: Oops - BUG: 0 [#1] SMP
Modules linked in:
CPU: 4 PID: 1 Comm: swapper/0 Tainted: G W 4.8.0-rc4-00267-g664e88c #3
Hardware name: www.cavium.com ThunderX CRB-2S/ThunderX CRB-2S, BIOS 0.3 Aug 24 2016
task: fffffe0fee55a200 task.stack: ffffff00004a4000
PC is at move_freepages+0x158/0x168
LR is at move_freepages_block+0xac/0xc0
pc : [<fffffc0008227618>] lr : [<fffffc00082276d4>] pstate: 800000c5
sp : ffffff00004a7480
x29: ffffff00004a7480 x28: fffffdffc3fc0020
x27: fffffdffc3fc0000 x26: 000000000000000a
x25: 000000000000000a x24: ffffff0ffffa3190
x23: ffffff0fffdbf530 x22: 0000000000000000
x21: fffffdffc3ffffc0 x20: ffffff0ffffa2c80
x19: fffffdffc3f80000 x18: fffffe0fdc0c2548
x17: 0000000000000000 x16: 0000000100000000
x15: 00000000000000c1 x14: 04000000001b2000
x13: 00aedf01c7040000 x12: 00001b00000033f5
x11: 01c604000000001b x10: 0000ae7401c50430
x9 : 0000000000000000 x8 : fffffc0008f53000
x7 : fffffc00082295f0 x6 : 0000000000000001
x5 : 0000000000000000 x4 : fffffe0fffff2580
x3 : ffffff0ffffa2500 x2 : 0000000000000001
x1 : fffffe0fffff2580 x0 : ffffff0ffffa2c80
Process swapper/0 (pid: 1, stack limit = 0xffffff00004a4020)
Stack: (0xffffff00004a7480 to 0xffffff00004a8000)
7480: ffffff00004a74e0 fffffc00082276d4 0000000000000000 ffffff0ffffa2c80
74a0: fffffdffc3f80000 0000000000000000 ffffff0fffdbf530 ffffff0ffffa3190
74c0: 000000000000000a 000000000000000a fffffdffc3fc0000 fffffdffc3fc0020
74e0: ffffff00004a7510 fffffc0008227f00 ffffff0ffffa2c80 0000000000000000
7500: fffffdffc3fc0000 0000000000000028 ffffff00004a75b0 fffffc0008229654
7520: ffffff0fffdbf530 ffffff0ffffa2c80 fffffc0008e5f520 0000000000000000
7540: ffffff0fffdbf530 ffffff0fffdbf520 0000030ff6f60000 0000000000000001
7560: 0000000000000000 0000000000000000 ffffff0ffffa3200 fffffc00082295f0
7580: fffffc0008e5f520 fffffc0008ec1000 0000000000000000 0000000000000001
75a0: 0000000000000010 01ffff0ffffa2c80 ffffff00004a76a0 fffffc000822a5ec
75c0: 00000000024200c2 0000000000000000 0000000000000000 00000000024200c2
75e0: fffffc0008ec4000 0000000000000001 0000000000000000 fffffc0008ec2000
7600: 00000000024200c2 fffffc00082886c8 ffffffffffffffff 0000000000000040
7620: 00000012004a7640 fffffc0008e587e8 0000000100000000 0000000000000000
7640: ffffff00024200c2 fffffc00081007bc ffffff0ffffa2c80 0000000000000010
7660: fffffc0008e5f520 0000000000000040 0000000000000000 ffffff0ffffa3200
7680: 0000000000000001 ffffff0ffffa3b80 ffffff0ffffa3b80 ffffff00004a77b8
76a0: ffffff00004a77e0 fffffc00082886c8 0000000000000000 fffffc0008ec0c48
76c0: ffffff0ffffa3b80 0000000000000000 0000000000000000 0000000000000001
76e0: ffffff00004a4000 0000000000000000 fffffe0fee55a200 00000000000053d4
7700: fffffe0fee55a200 0000000000000000 0000000000000000 fffffc0008eec160
7720: 0000000000000000 0000000000000002 fffffe0fee55aa98 fffffc0008ec2000
7740: fffffe0fee55a200 fffffc0009c95000 0000000000000000 fffffc0008eec160
7760: 0000000000000000 fffffc0008e587e8 0000000000000000 0000000100400000
7780: 0000000000000000 0000000000000000 0000000000000000 0000000000000002
77a0: 0000000000000000 0000000000000000 fffffc000821d070 ffffff0ffffa3b80
77c0: 0000000000000000 ffffff0ffffa3b80 0000000100000000 0000000000000000
77e0: ffffff00004a7810 fffffc0008288d20 fffffc0008e587e8 fffffe0fec01a8f0
7800: 00000000024200c2 fffffc000821e62c ffffff00004a7870 fffffc000821e62c
7820: 0000000000000000 ffffff00004a4000 00000000024200c2 fffffe0fe0249410
7840: fffffc000821e788 00000000024200c2 fffffc0008f01d28 0000000002493ee0
7860: 0000000000002c2c 0000000000000040 ffffff00004a78d0 fffffc000821e788
7880: 0000000000000000 000000000000000e 00000000024200c2 fffffe0fe0249410
78a0: 0000000000000001 fffffc0008fd76ac fffffc0008f01d28 0000000002493ee0
78c0: 0000000000002c2c fffffc000821e850 ffffff00004a7930 fffffc000821e9b0
78e0: fffffe0fe0249410 0000000000000001 0000000000000001 0000000000002c2c
7900: ffffff00004a7a20 fffffe0fcc140400 00000000000053d4 fffffc00089b8900
7920: 0000000000002c2c fffffc000821e440 ffffff00004a7960 fffffc00082eb758
7940: fffffe0fe0249410 0000000000000001 0000000000010000 ffffff00004a7b18
7960: ffffff00004a79a0 fffffc000821e3bc 0000000000010000 ffffff00004a7b18
7980: fffffe0fe0249410 0000000000010000 0000000000000000 fffffc000821e434
79a0: ffffff00004a7a30 fffffc00082200e0 0000000000000000 fffffe0fcc140400
79c0: fffffe0fe0249210 ffffff00004a7af0 fffffe0fe0249410 ffffff00004a7b18
79e0: fffffc0008d40e70 0000000000008000 fffffc0009040078 ffffff0f83f26000
7a00: 0000000000000000 fffffc0008bd0300 00002c2c00000001 ffffff00004a4000
7a20: fffffdff83f20840 0000000027e02140 ffffff00004a7a80 fffffc00082201fc
7a40: 0000000000008000 ffffff00004a7af0 fffffe0fe02492e8 ffffff00004a7b18
7a60: ffffff00004a7bb8 0000000000000007 fffffc0008d40e70 0000000000008000
7a80: ffffff00004a7ab0 fffffc00082ba89c fffffe0fcc140400 0000000000008000
7aa0: ffffff00004a7bb8 fffffe0fdd350000 ffffff00004a7b40 fffffc00082bb588
7ac0: 0000000000000000 0000000000008000 fffffe0fcc140400 fffffe0fdd350000
7ae0: fffffe0fdd350000 0000000000008000 fffffe0fcc140400 000000000000ac2c
7b00: 0000000000000000 0000000000000000 0000000000000000 fffffc0000000003
7b20: 00000000000053d4 0000000000002c2c ffffff00004a7ae0 0000000000000001
7b40: ffffff00004a7b80 fffffc00082bc5b4 fffffe0fcc140400 fffffe0fcc140400
7b60: fffffe0fdd350000 0000000000008000 fffffc0008babe88 ffffff0f8ea0e439
7b80: ffffff00004a7bc0 fffffc0008d120f0 0000000000000000 0000000000008000
7ba0: fffffe0fdd350000 0000000000000000 fffffe0fdc3fa280 000000000000ac2c
7bc0: ffffff00004a7bf0 fffffc0008d121d4 fffffc0008d75000 fffffc0008d75b60
7be0: fffffc0008d75bb8 fffffe0fdd350000 ffffff00004a7c10 fffffc0008d11eac
7c00: fffffc0008d75b60 0000000000008000 ffffff00004a7c40 fffffc0008d11f10
7c20: 0000000000008000 0000000000008000 fffffc0008d75b60 fffffc00089e42c0
7c40: ffffff00004a7c80 fffffc0008d410f4 fffffe0fdc3fa280 ffffff0f83f26000
7c60: 0000000000000000 fffffe0fdd350000 fffffc0008d11d74 fffffc0008d11ec8
7c80: ffffff00004a7cf0 fffffc0008d411b4 fffffc0008d75000 ffffff0f83f26000
7ca0: 000000000e7f20bc 0000000000000000 fffffc0008d4119c fffffc0008ff1f38
7cc0: fffffc0008babf90 fffffc0009040000 fffffc0008e3d9a0 0000000000000000
7ce0: 0000000008d75000 0000000000008000 ffffff00004a7d00 fffffc0008d127c4
7d00: ffffff00004a7d60 fffffc0008d1294c fffffc0009040000 fffffc0008d128dc
7d20: fffffc0009040000 fffffc0009040000 fffffc0009040000 fffffc0008d1045c
7d40: fffffc0008cfc468 fffffc0008d74290 0000000000001b57 fffffc0008c04958
7d60: ffffff00004a7d90 fffffc0008082ff4 ffffff00004a4000 fffffc0008d128dc
7d80: 0000000000000000 0000000000000005 ffffff00004a7e00 fffffc0008d10df4
7da0: 0000000000000101 fffffc0009040000 fffffc0008d742a8 0000000000000005
7dc0: fffffc0008e3d700 0000000000000000 fffffc0008ee2370 fffffc0008bb79f8
7de0: 0000000000000000 0000000500000005 0000000000000000 fffffc0008d1045c
7e00: ffffff00004a7ea0 fffffc000893c888 fffffc0009040000 fffffc0009040000
7e20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7e40: 0000000000000000 0000000000000000 0000000000000000 ffffff00004a4000
7e60: 0000000000000003 0000000000000000 0000000000000000 0000000000000000
7e80: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7ea0: 0000000000000000 fffffc0008082b80 fffffc000893c868 0000000000000000
7ec0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7ee0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7f00: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7f20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7f40: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7f60: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7f80: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7fa0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
7fc0: 0000000000000000 0000000000000005 0000000000000000 0000000000000000
7fe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
Call trace:
Exception stack(0xffffff00004a72a0 to 0xffffff00004a73d0)
72a0: fffffdffc3f80000 0000040000000000 ffffff00004a7480 fffffc0008227618
72c0: 00000000800000c5 000000000000003d fffffc0008ec4000 0000000000000030
72e0: ffffff00004a7300 fffffc00081593b0 fffffc0008f53000 0000000000000000
7300: ffffff00004a7320 fffffc000822abac fffffc0008fd76be ffffff00004a7438
7320: ffffff00004a7460 fffffc00082886c8 ffffff00004a7380 fffffc0008135d08
7340: 0000000000000001 0000000000000007 ffffff0ffffa2c80 fffffe0fffff2580
7360: 0000000000000001 ffffff0ffffa2500 fffffe0fffff2580 0000000000000000
7380: 0000000000000001 fffffc00082295f0 fffffc0008f53000 0000000000000000
73a0: 0000ae7401c50430 01c604000000001b 00001b00000033f5 00aedf01c7040000
73c0: 04000000001b2000 00000000000000c1
[<fffffc0008227618>] move_freepages+0x158/0x168
[<fffffc00082276d4>] move_freepages_block+0xac/0xc0
[<fffffc0008227f00>] __rmqueue+0x740/0x898
[<fffffc0008229654>] get_page_from_freelist+0x3e4/0xca0
[<fffffc000822a5ec>] __alloc_pages_nodemask+0x1ac/0xfd8
[<fffffc00082886c8>] alloc_page_interleave+0x60/0xb8
[<fffffc0008288d20>] alloc_pages_current+0x168/0x1c8
[<fffffc000821e62c>] __page_cache_alloc+0x17c/0x1c0
[<fffffc000821e788>] pagecache_get_page+0x118/0x2f8
[<fffffc000821e9b0>] grab_cache_page_write_begin+0x48/0x68
[<fffffc00082eb758>] simple_write_begin+0x40/0x168
[<fffffc000821e3bc>] generic_perform_write+0xc4/0x1b8
[<fffffc00082200e0>] __generic_file_write_iter+0x178/0x1c8
[<fffffc00082201fc>] generic_file_write_iter+0xcc/0x1c8
[<fffffc00082ba89c>] __vfs_write+0xcc/0x140
[<fffffc00082bb588>] vfs_write+0xa8/0x1c0
[<fffffc00082bc5b4>] SyS_write+0x54/0xb0
[<fffffc0008d120f0>] xwrite+0x34/0x7c
[<fffffc0008d121d4>] do_copy+0x9c/0xf4
[<fffffc0008d11eac>] write_buffer+0x34/0x50
[<fffffc0008d11f10>] flush_buffer+0x48/0xb8
[<fffffc0008d410f4>] __gunzip+0x27c/0x324
[<fffffc0008d411b4>] gunzip+0x18/0x20
[<fffffc0008d127c4>] unpack_to_rootfs+0x168/0x280
[<fffffc0008d1294c>] populate_rootfs+0x70/0x138
[<fffffc0008082ff4>] do_one_initcall+0x44/0x138
[<fffffc0008d10df4>] kernel_init_freeable+0x240/0x2e0
[<fffffc000893c888>] kernel_init+0x20/0xf8
[<fffffc0008082b80>] ret_from_fork+0x10/0x50
Code: 913dc021 9400d2db d4210000 d503201f (d4210000)
---[ end trace fcdd7f8cb96cdb3d ]---
note: swapper/0[1] exited with preempt_count 1
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
SMP: stopping secondary CPUs
---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
^ permalink raw reply
* [PATCH] dmaengine: qcom_hidma: prevent disable in error
From: Vinod Koul @ 2016-10-18 15:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475782394-27887-1-git-send-email-okaya@codeaurora.org>
On Thu, Oct 06, 2016 at 03:33:14PM -0400, Sinan Kaya wrote:
> When an error is observed, we try to disable the channel and prevent
> further accesses from the client.
>
> Depending on the type of error, transitioning into disabled state might
> not be possible. Adding a check to make sure that HW is in enabled/running
> state before the disable transition happens.
Applied, thanks
--
~Vinod
^ permalink raw reply
* [PATCH V3 2/3] Revert "ACPI,PCI,IRQ: remove SCI penalize function"
From: Sinan Kaya @ 2016-10-18 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018140543.GE18903@localhost>
On 10/18/2016 7:05 AM, Bjorn Helgaas wrote:
> I think you should squash patches 2 & 3 and not bother with trying to
> make this a revert followed by a fix. Squashing them makes the git
> history much easier to follow, plus you don't have to deal with the
> headache of ensuring the intermediate state is correct and bisectable.
OK. I can do that.
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH 1/2] scripts/gdb: add lx-fdtdump command
From: Peter Griffin @ 2016-10-18 15:07 UTC (permalink / raw)
To: linux-arm-kernel
lx-fdtdump dumps the flatenned device tree passed to the kernel
from the bootloader to a file called fdtdump.dtb to allow further
post processing on the machine running GDB. The fdt header is also
also printed in the GDB console. For example:
(gdb) lx-fdtdump
fdt_magic: 0xD00DFEED
fdt_totalsize: 0xC108
off_dt_struct: 0x38
off_dt_strings: 0x3804
off_mem_rsvmap: 0x28
version: 17
last_comp_version: 16
Dumped fdt to fdtdump.dtb
>fdtdump fdtdump.dtb | less
This command is useful as the bootloader can often re-write parts
of the device tree, and this can sometimes cause the kernel to not
boot.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
scripts/gdb/linux/constants.py.in | 8 +++++
scripts/gdb/linux/proc.py | 70 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 77 insertions(+), 1 deletion(-)
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
index 7986f4e..43c6241 100644
--- a/scripts/gdb/linux/constants.py.in
+++ b/scripts/gdb/linux/constants.py.in
@@ -14,6 +14,7 @@
#include <linux/fs.h>
#include <linux/mount.h>
+#include <linux/of_fdt.h>
/* We need to stringify expanded macros so that they can be parsed */
@@ -50,3 +51,10 @@ LX_VALUE(MNT_NOEXEC)
LX_VALUE(MNT_NOATIME)
LX_VALUE(MNT_NODIRATIME)
LX_VALUE(MNT_RELATIME)
+
+/* linux/of_fdt.h> */
+LX_VALUE(OF_DT_HEADER)
+
+/* Kernel Configs */
+LX_CONFIG(CONFIG_OF)
+
diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
index 38b1f09..f20fcfa 100644
--- a/scripts/gdb/linux/proc.py
+++ b/scripts/gdb/linux/proc.py
@@ -16,7 +16,7 @@ from linux import constants
from linux import utils
from linux import tasks
from linux import lists
-
+from struct import *
class LxCmdLine(gdb.Command):
""" Report the Linux Commandline used in the current kernel.
@@ -195,3 +195,71 @@ values of that process namespace"""
info_opts(MNT_INFO, m_flags)))
LxMounts()
+
+class LxFdtDump(gdb.Command):
+ """Output Flattened Device Tree header and dump FDT blob to a file
+ Equivalent to 'cat /proc/fdt > fdtdump.dtb' on a running target"""
+
+ def __init__(self):
+ super(LxFdtDump, self).__init__("lx-fdtdump", gdb.COMMAND_DATA)
+
+ def fdthdr_to_cpu(self, fdt_header):
+
+ fdt_header_be = ">IIIIIII"
+ fdt_header_le = "<IIIIIII"
+
+ if utils.get_target_endianness() == 1:
+ output_fmt = fdt_header_le
+ else:
+ output_fmt = fdt_header_be
+
+ return unpack(output_fmt, pack(fdt_header_be,
+ fdt_header['magic'],
+ fdt_header['totalsize'],
+ fdt_header['off_dt_struct'],
+ fdt_header['off_dt_strings'],
+ fdt_header['off_mem_rsvmap'],
+ fdt_header['version'],
+ fdt_header['last_comp_version']))
+
+ def invoke(self, arg, from_tty):
+
+ if constants.LX_CONFIG_OF:
+
+ filename = "fdtdump.dtb"
+
+ py_fdt_header_ptr = gdb.parse_and_eval(
+ "(const struct fdt_header *) initial_boot_params")
+ py_fdt_header = py_fdt_header_ptr.dereference()
+
+ fdt_header = self.fdthdr_to_cpu(py_fdt_header)
+
+ if fdt_header[0] != constants.LX_OF_DT_HEADER:
+ raise gdb.GdbError("No flattened device tree magic found\n")
+
+ gdb.write("fdt_magic: 0x{:02X}\n".format(fdt_header[0]))
+ gdb.write("fdt_totalsize: 0x{:02X}\n".format(fdt_header[1]))
+ gdb.write("off_dt_struct: 0x{:02X}\n".format(fdt_header[2]))
+ gdb.write("off_dt_strings: 0x{:02X}\n".format(fdt_header[3]))
+ gdb.write("off_mem_rsvmap: 0x{:02X}\n".format(fdt_header[4]))
+ gdb.write("version: {}\n".format(fdt_header[5]))
+ gdb.write("last_comp_version: {}\n".format(fdt_header[6]))
+
+ inf = gdb.inferiors()[0]
+ fdt_buf = utils.read_memoryview(inf, py_fdt_header_ptr,
+ fdt_header[1]).tobytes()
+
+ try:
+ f = open(filename, 'wb')
+ except:
+ raise gdb.GdbError("Could not open file to dump fdt")
+
+ f.write(fdt_buf)
+ f.close()
+
+ gdb.write("Dumped fdt to " + filename + "\n")
+
+ else:
+ gdb.write("Kernel not compiled with CONFIG_OF\n")
+
+LxFdtDump()
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] scripts/gdb: fixup some pep8 errors in proc.py
From: Peter Griffin @ 2016-10-18 15:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476803249-23328-1-git-send-email-peter.griffin@linaro.org>
proc.py:22:1: E302 expected 2 blank lines, found 1
proc.py:200:1: E302 expected 2 blank lines, found 1
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
scripts/gdb/linux/proc.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
index f20fcfa..2d6f74e 100644
--- a/scripts/gdb/linux/proc.py
+++ b/scripts/gdb/linux/proc.py
@@ -18,6 +18,7 @@ from linux import tasks
from linux import lists
from struct import *
+
class LxCmdLine(gdb.Command):
""" Report the Linux Commandline used in the current kernel.
Equivalent to cat /proc/cmdline on a running target"""
@@ -196,6 +197,7 @@ values of that process namespace"""
LxMounts()
+
class LxFdtDump(gdb.Command):
"""Output Flattened Device Tree header and dump FDT blob to a file
Equivalent to 'cat /proc/fdt > fdtdump.dtb' on a running target"""
--
1.9.1
^ permalink raw reply related
* [PATCH] coresight: reset "enable_sink" flag when need be
From: Suzuki K Poulose @ 2016-10-18 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1475874643-9464-1-git-send-email-mathieu.poirier@linaro.org>
On 07/10/16 22:10, Mathieu Poirier wrote:
> When using coresight from the perf interface sinks are specified
> as part of the perf command line. As such the sink needs to be
> disabled once it has been acknowledged by the coresight framework.
> Otherwise the sink stays enabled, which may interfere with other
> sessions.
>
I personally think the descriptions needs to be a bit more clearer
from here on.
> This patch removes the sink selection check from the build path
> process and make it a function on it's own. The function is
> then used when operating from sysFS or perf to determine what
> sink has been selected.
I think you should mention that the helper function provides an
option to "de-activate" the enabled sink, once it has been "found"
by a lookup. Perf uses this option to de-activate the sink, while
sysfs leaves it to the user to do the same.
We don't have a mechanism to ensure that the "enabled" sink is
the one perf really enabled for us. But there is nothing much we
could do and should rely on the user to do it right for us.
So, with the changes to description :
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
^ permalink raw reply
* [PATCH] ASoC: PXA: Brownstone needs I2C
From: Arnd Bergmann @ 2016-10-18 15:18 UTC (permalink / raw)
To: linux-arm-kernel
I rand into a new build error with SND_MMP_SOC_BROWNSTONE:
warning: (SND_MMP_SOC_BROWNSTONE && SND_SOC_SAMSUNG_SMDK_WM8994 && SND_SOC_SMDK_WM8994_PCM && SND_SOC_LITTLEMILL) selects MFD_WM8994 which has unmet direct dependencies (HAS_IOMEM && I2C)
drivers/mfd/wm8994-core.c:688:1: error: data definition has no type or storage class [-Werror]
drivers/mfd/wm8994-core.c:688:1: error: type defaults to 'int' in declaration of 'module_i2c_driver' [-Werror=implicit-int]
I don't see why this never showed up before, as the dependency seems to
have been missing since the symbol was first introduced several years
ago. This adds a dependency like the other drivers have.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
sound/soc/pxa/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f2bf8661dd21..823b5a236d8d 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -208,7 +208,7 @@ config SND_PXA2XX_SOC_IMOTE2
config SND_MMP_SOC_BROWNSTONE
tristate "SoC Audio support for Marvell Brownstone"
- depends on SND_MMP_SOC && MACH_BROWNSTONE
+ depends on SND_MMP_SOC && MACH_BROWNSTONE && I2C
select SND_MMP_SOC_SSPA
select MFD_WM8994
select SND_SOC_WM8994
--
2.9.0
^ permalink raw reply related
* [PATCH V3 1/3] ACPI, PCI IRQ: add PCI_USING penalty for ISA interrupts
From: Sinan Kaya @ 2016-10-18 15:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018135912.GD18903@localhost>
On 10/18/2016 6:59 AM, Bjorn Helgaas wrote:
>> However, this function only gets called if the IRQ number is greater than
>> > 16 and acpi_irq_get_penalty function gets called before ACPI start in
>> > acpi_isa_irq_available and acpi_penalize_isa_irq functions. We can't rely
>> > on iterating the link list.
Maybe, I am missing context here. I can add this paragraph to the commit.
When we started cleaning the code we got rid of the acpi_irq_penalty_init function
in favor of acpi_irq_pci_sharing_penalty function as it does have some fair
amount of code duplication.
I tried putting back the acpi_irq_pci_sharing_penalty function into the ISA
IRQ path again during the debug and the machine died way too early. We couldn't
collect any debug message.
This is telling me that we can't even iterate the link list when these two API
is called. ISA IRQ need to be handled with special care due to calling order.
> It seems wrong to me that we call acpi_irq_get_penalty() from
> acpi_irq_penalty_update() and acpi_penalize_isa_irq(). It seems like they
> should just manipulate acpi_isa_irq_penalty[irq] directly.
>
> acpi_irq_penalty_update() is for command-line parameters, so it certainly
> doesn't need the acpi_irq_pci_sharing_penalty() information (the
> acpi_link_list should be empty at the time we process the command-line
> parameters).
>
> acpi_penalize_isa_irq() is telling us that a PNP or ACPI device is using
> the IRQ -- this should modify the IRQ's penalty, but it shouldn't depend on
> the acpi_irq_pci_sharing_penalty() value at all.
>
acpi_irq_get_penalty function knows how to deal with ISA IRQ. So, it is harmless
to call it. Also, reading the acpi_isa_irq_penalty array directly isn't also right.
It doesn't contain the SCI penalty. So, it returns incorrect penalty value.
The rule of thumb is:
- all PCI/SCI penalty reads need to go through acpi_isa_irq_penalty function
- all ISA penalty writes need to go through acpi_isa_irq_penalty array directly.
- we do not support modifying the PCI IRQ penalties greater than the ISA IRQ numbers.
The original code supported this.
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH 2/2] scripts/gdb: fixup some pep8 errors in proc.py
From: Kieran Bingham @ 2016-10-18 15:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476803249-23328-2-git-send-email-peter.griffin@linaro.org>
Hi Pete,
On 18/10/16 16:07, Peter Griffin wrote:
> proc.py:22:1: E302 expected 2 blank lines, found 1
> proc.py:200:1: E302 expected 2 blank lines, found 1
>
> Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
> ---
> scripts/gdb/linux/proc.py | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
> index f20fcfa..2d6f74e 100644
> --- a/scripts/gdb/linux/proc.py
> +++ b/scripts/gdb/linux/proc.py
> @@ -18,6 +18,7 @@ from linux import tasks
> from linux import lists
> from struct import *
>
> +
This was added by patch 1, and can be squashed there.
> class LxCmdLine(gdb.Command):
> """ Report the Linux Commandline used in the current kernel.
> Equivalent to cat /proc/cmdline on a running target"""
> @@ -196,6 +197,7 @@ values of that process namespace"""
>
> LxMounts()
>
> +
Likewise...
> class LxFdtDump(gdb.Command):
> """Output Flattened Device Tree header and dump FDT blob to a file
> Equivalent to 'cat /proc/fdt > fdtdump.dtb' on a running target"""
>
--
Regards
Kieran Bingham
^ permalink raw reply
* [PATCH v2 2/4] ARM: dts: pxa: add pxa25x cpu operating points
From: Robert Jarzmik @ 2016-10-18 15:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018113944.GC11471@vireshk-i7>
Viresh Kumar <viresh.kumar@linaro.org> writes:
> On 15-10-16, 21:57, Robert Jarzmik wrote:
>> Add the relevant data taken from the PXA 25x Electrical, Mechanical, and
>> Thermal Specfication. This will be input data for cpufreq-dt driver.
>>
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>> ---
>> arch/arm/boot/dts/pxa25x.dtsi | 25 +++++++++++++++++++++++++
>> 1 file changed, 25 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/pxa25x.dtsi b/arch/arm/boot/dts/pxa25x.dtsi
>> index 0d1e012178c4..16b4e8bad4a5 100644
>> --- a/arch/arm/boot/dts/pxa25x.dtsi
>> +++ b/arch/arm/boot/dts/pxa25x.dtsi
>> @@ -89,4 +89,29 @@
>> clocks = <&clktimer>;
>> status = "okay";
>> };
>> +
>> + pxa250_opp_table: opp_table0 {
>> + compatible = "operating-points-v2";
>> +
>> + opp at 99500 {
>
> We have been keeping the values in ^^^ same as the values present
> below. Any specific reason for making it different here ?
No, that's a good comment, I'll change that.
I wrote this incrementaly, first the node, then the opp-hz. Then I realized that
the source crystal, at 3.8684 MHz didn't provide a round 99.5 MHz core clock,
but a 99.5328 MHz clock.
Anyway, I'll change that ... let's say into opp at 99533 in this case ?
--
Robert
^ permalink raw reply
* [PATCH 00/10] mm: adjust get_user_pages* functions to explicitly pass FOLL_* flags
From: Michal Hocko @ 2016-10-18 15:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161013002020.3062-1-lstoakes@gmail.com>
On Thu 13-10-16 01:20:10, Lorenzo Stoakes wrote:
> This patch series adjusts functions in the get_user_pages* family such that
> desired FOLL_* flags are passed as an argument rather than implied by flags.
>
> The purpose of this change is to make the use of FOLL_FORCE explicit so it is
> easier to grep for and clearer to callers that this flag is being used. The use
> of FOLL_FORCE is an issue as it overrides missing VM_READ/VM_WRITE flags for the
> VMA whose pages we are reading from/writing to, which can result in surprising
> behaviour.
>
> The patch series came out of the discussion around commit 38e0885, which
> addressed a BUG_ON() being triggered when a page was faulted in with PROT_NONE
> set but having been overridden by FOLL_FORCE. do_numa_page() was run on the
> assumption the page _must_ be one marked for NUMA node migration as an actual
> PROT_NONE page would have been dealt with prior to this code path, however
> FOLL_FORCE introduced a situation where this assumption did not hold.
>
> See https://marc.info/?l=linux-mm&m=147585445805166 for the patch proposal.
I like this cleanup. Tracking FOLL_FORCE users was always a nightmare
and the flag behavior is really subtle so we should better be explicit
about it. I haven't gone through each patch separately but rather
applied the whole series and checked the resulting diff. This all seems
OK to me and feel free to add
Acked-by: Michal Hocko <mhocko@suse.com>
I am wondering whether we can go further. E.g. it is not really clear to
me whether we need an explicit FOLL_REMOTE when we can in fact check
mm != current->mm and imply that. Maybe there are some contexts which
wouldn't work, I haven't checked.
Then I am also wondering about FOLL_TOUCH behavior.
__get_user_pages_unlocked has only few callers which used to be
get_user_pages_unlocked before 1e9877902dc7e ("mm/gup: Introduce
get_user_pages_remote()"). To me a dropped FOLL_TOUCH seems
unintentional. Now that get_user_pages_unlocked has gup_flags argument I
guess we might want to get rid of the __g-u-p-u version altogether, no?
__get_user_pages is quite low level and imho shouldn't be exported. It's
only user - kvm - should rather pull those two functions to gup instead
and export them. There is nothing really KVM specific in them.
I also cannot say I would be entirely thrilled about get_user_pages_locked,
we only have one user which can simply do lock g-u-p unlock AFAICS.
I guess there is more work in that area and I do not want to impose all
that work on you, but I couldn't resist once I saw you playing in that
area ;) Definitely a good start!
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* [PATCH V3 1/3] ACPI, PCI IRQ: add PCI_USING penalty for ISA interrupts
From: Sinan Kaya @ 2016-10-18 15:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b4a8995e-1454-3b84-0681-1491788087ec@codeaurora.org>
Sorry, I think I didn't have enough morning coffee.
Looking at these again and trying to be specific.
On 10/18/2016 8:20 AM, Sinan Kaya wrote:
> It seems wrong to me that we call acpi_irq_get_penalty() from
>> acpi_irq_penalty_update() and acpi_penalize_isa_irq(). It seems like they
>> should just manipulate acpi_isa_irq_penalty[irq] directly.
>>
>> acpi_irq_penalty_update() is for command-line parameters, so it certainly
>> doesn't need the acpi_irq_pci_sharing_penalty() information (the
>> acpi_link_list should be empty at the time we process the command-line
>> parameters).
Calling acpi_irq_get_penalty for ISA IRQ is OK as long as it doesn't have
any dynamic IRQ calculation such that acpi_isa_irq_penalty[irq] = acpi_irq_get_penalty.
If this is broken, then we need special care so that we don't assign
dynamically calcualted sci_penalty back to acpi_isa_irq_penalty[irq]. This
results in returning incorrect penalty as
acpi_irq_get_penalty = acpi_isa_irq_original_penalty[irq] + 2 * sci_penalty.
Now that we added sci_penalty into the acpi_irq_get_penalty function,
calling acpi_irq_get_penalty is not correct anymore. This line here needs to
be replaced with acpi_isa_irq_penalty[irq] as you suggested.
if (used)
new_penalty = acpi_irq_get_penalty(irq) +
PIRQ_PENALTY_ISA_USED;
else
new_penalty = 0;
acpi_isa_irq_penalty[irq] = new_penalty;
>>
>> acpi_penalize_isa_irq() is telling us that a PNP or ACPI device is using
>> the IRQ -- this should modify the IRQ's penalty, but it shouldn't depend on
>> the acpi_irq_pci_sharing_penalty() value at all.
>>
Same problem here. This line will be broken after the sci_penalty change.
acpi_isa_irq_penalty[irq] = acpi_irq_get_penalty(irq) +
(active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING);
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH v2 1/4] cpufreq: pxa: use generic platdev driver for device-tree
From: Robert Jarzmik @ 2016-10-18 15:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161018113835.GB11471@vireshk-i7>
Viresh Kumar <viresh.kumar@linaro.org> writes:
> On 15-10-16, 21:57, Robert Jarzmik wrote:
>> For device-tree based pxa25x and pxa27x platforms, cpufreq-dt driver is
>> doing the job as well as pxa2xx-cpufreq, so add these platforms to the
>> compatibility list.
>>
>> This won't work for legacy non device-tree platforms where
>> pxa2xx-cpufreq is still required.
>>
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>> ---
>> drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
>> index 0bb44d5b5df4..356825b5c9b8 100644
>> --- a/drivers/cpufreq/cpufreq-dt-platdev.c
>> +++ b/drivers/cpufreq/cpufreq-dt-platdev.c
>> @@ -32,6 +32,8 @@ static const struct of_device_id machines[] __initconst = {
>> { .compatible = "fsl,imx7d", },
>>
>> { .compatible = "marvell,berlin", },
>> + { .compatible = "marvell,pxa250", },
>> + { .compatible = "marvell,pxa270", },
>>
>> { .compatible = "samsung,exynos3250", },
>> { .compatible = "samsung,exynos4210", },
>
> Isn't there a race between cpufreq-dt and the platform driver to
> register first ?
Ah, could you be more specific about the race you're talking of ?
My understanding was that cpufreq-dt-platdev does create the device, and
cpufreq-dt is a driver for it, so there is no race but a direct relationship
AFAIU.
> Also, it seems that atleast the next two patches are required before
> applying this? You need to fix the order if that is the case.
Ok, as you wish, let it become number 3 and (2, 3) become (1, 2).
Cheers.
--
Robert
^ permalink raw reply
* [PATCH] ARM: sti: stih410-clocks: Add PROC_STFE as a critical clock
From: Peter Griffin @ 2016-10-18 15:35 UTC (permalink / raw)
To: linux-arm-kernel
Once the ST frontend demux HW IP has been enabled, the clock can't
be disabled otherwise the system will hang and the board will
be unserviceable.
To allow balanced clock enable/disable calls in the driver we use
the critical clock infrastructure to take an extra reference on the
clock so the clock will never actually be disabled.
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
---
arch/arm/boot/dts/stih410-clock.dtsi | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stih410-clock.dtsi b/arch/arm/boot/dts/stih410-clock.dtsi
index 8598eff..07c8ef9 100644
--- a/arch/arm/boot/dts/stih410-clock.dtsi
+++ b/arch/arm/boot/dts/stih410-clock.dtsi
@@ -208,7 +208,8 @@
"clk-clust-hades",
"clk-hwpe-hades",
"clk-fc-hades";
- clock-critical = <CLK_ICN_CPU>,
+ clock-critical = <CLK_PROC_STFE>,
+ <CLK_ICN_CPU>,
<CLK_TX_ICN_DMU>,
<CLK_EXT2F_A9>,
<CLK_ICN_LMI>,
--
1.9.1
^ permalink raw reply related
* [PATCH V7 1/3] tracing: add a possibility of exporting function trace to other places instead of ring buffer only
From: Steven Rostedt @ 2016-10-18 15:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1476778140-10319-2-git-send-email-zhang.chunyan@linaro.org>
On Tue, 18 Oct 2016 16:08:58 +0800
Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
> Currently Function traces can be only exported to ring buffer, this
> patch added trace_export concept which can process traces and export
> them to a registered destination as an addition to the current only
> one output of Ftrace - i.e. ring buffer.
>
> In this way, if we want Function traces to be sent to other destination
> rather than ring buffer only, we just need to register a new trace_export
> and implement its own .write() function for writing traces to storage.
>
> With this patch, only Function trace (trace type is TRACE_FN)
> is supported.
This is getting better, but I still have some nits.
>
> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
> ---
> include/linux/trace.h | 28 +++++++++++
> kernel/trace/trace.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 159 insertions(+), 1 deletion(-)
> create mode 100644 include/linux/trace.h
>
> diff --git a/include/linux/trace.h b/include/linux/trace.h
> new file mode 100644
> index 0000000..eb1c5b8
> --- /dev/null
> +++ b/include/linux/trace.h
> @@ -0,0 +1,28 @@
> +#ifndef _LINUX_TRACE_H
> +#define _LINUX_TRACE_H
> +
> +#ifdef CONFIG_TRACING
> +/*
> + * The trace export - an export of Ftrace output. The trace_export
> + * can process traces and export them to a registered destination as
> + * an addition to the current only output of Ftrace - i.e. ring buffer.
> + *
> + * If you want traces to be sent to some other place rather than ring
> + * buffer only, just need to register a new trace_export and implement
> + * its own .write() function for writing traces to the storage.
> + *
> + * next - pointer to the next trace_export
> + * write - copy traces which have been delt with ->commit() to
> + * the destination
> + */
> +struct trace_export {
> + struct trace_export __rcu *next;
> + void (*write)(const char *, unsigned int);
Why const char*? Why not const void *? This will never be a string.
> +};
> +
> +int register_ftrace_export(struct trace_export *export);
> +int unregister_ftrace_export(struct trace_export *export);
> +
> +#endif /* CONFIG_TRACING */
> +
> +#endif /* _LINUX_TRACE_H */
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 8696ce6..db94ec1 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -40,6 +40,7 @@
> #include <linux/poll.h>
> #include <linux/nmi.h>
> #include <linux/fs.h>
> +#include <linux/trace.h>
> #include <linux/sched/rt.h>
>
> #include "trace.h"
> @@ -2128,6 +2129,132 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
> ftrace_trace_userstack(buffer, flags, pc);
> }
>
> +static void
> +trace_process_export(struct trace_export *export,
> + struct ring_buffer_event *event)
> +{
> + struct trace_entry *entry;
> + unsigned int size = 0;
> +
> + entry = ring_buffer_event_data(event);
> +
> + size = ring_buffer_event_length(event);
> +
> + if (export->write)
> + export->write((char *)entry, size);
Is there ever going to be a time where export->write wont be set?
And if there is, this can be racy. As in
CPU 0: CPU 1:
------ ------
if (export->write)
export->write = NULL;
export->write(entry, size);
BOOM!
-- Steve
> +}
> +
> +static DEFINE_MUTEX(ftrace_export_lock);
> +
> +static struct trace_export __rcu *ftrace_exports_list __read_mostly;
> +
> +static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);
> +
> +static inline void ftrace_exports_enable(void)
> +{
> + static_branch_enable(&ftrace_exports_enabled);
> +}
> +
> +static inline void ftrace_exports_disable(void)
> +{
> + static_branch_disable(&ftrace_exports_enabled);
> +}
> +
> +void ftrace_exports(struct ring_buffer_event *event)
> +{
> + struct trace_export *export;
> +
> + preempt_disable_notrace();
> +
> + export = rcu_dereference_raw_notrace(ftrace_exports_list);
> + while (export) {
> + trace_process_export(export, event);
> + export = rcu_dereference_raw_notrace(export->next);
> + }
> +
> + preempt_enable_notrace();
> +}
> +
> +static inline void
> +add_trace_export(struct trace_export **list, struct trace_export *export)
> +{
> + rcu_assign_pointer(export->next, *list);
> + /*
> + * We are entering export into the list but another
> + * CPU might be walking that list. We need to make sure
> + * the export->next pointer is valid before another CPU sees
> + * the export pointer included into the list.
> + */
> + rcu_assign_pointer(*list, export);
> +}
> +
> +static inline int
> +rm_trace_export(struct trace_export **list, struct trace_export *export)
> +{
> + struct trace_export **p;
> +
> + for (p = list; *p != NULL; p = &(*p)->next)
> + if (*p == export)
> + break;
> +
> + if (*p != export)
> + return -1;
> +
> + rcu_assign_pointer(*p, (*p)->next);
> +
> + return 0;
> +}
> +
> +static inline void
> +add_ftrace_export(struct trace_export **list, struct trace_export *export)
> +{
> + if (*list == NULL)
> + ftrace_exports_enable();
> +
> + add_trace_export(list, export);
> +}
> +
> +static inline int
> +rm_ftrace_export(struct trace_export **list, struct trace_export *export)
> +{
> + int ret;
> +
> + ret = rm_trace_export(list, export);
> + if (*list == NULL)
> + ftrace_exports_disable();
> +
> + return ret;
> +}
> +
> +int register_ftrace_export(struct trace_export *export)
> +{
> + if (WARN_ON_ONCE(!export->write))
> + return -1;
> +
> + mutex_lock(&ftrace_export_lock);
> +
> + add_ftrace_export(&ftrace_exports_list, export);
> +
> + mutex_unlock(&ftrace_export_lock);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(register_ftrace_export);
> +
> +int unregister_ftrace_export(struct trace_export *export)
> +{
> + int ret;
> +
> + mutex_lock(&ftrace_export_lock);
> +
> + ret = rm_ftrace_export(&ftrace_exports_list, export);
> +
> + mutex_unlock(&ftrace_export_lock);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(unregister_ftrace_export);
> +
> void
> trace_function(struct trace_array *tr,
> unsigned long ip, unsigned long parent_ip, unsigned long flags,
> @@ -2146,8 +2273,11 @@ trace_function(struct trace_array *tr,
> entry->ip = ip;
> entry->parent_ip = parent_ip;
>
> - if (!call_filter_check_discard(call, entry, buffer, event))
> + if (!call_filter_check_discard(call, entry, buffer, event)) {
> + if (static_branch_unlikely(&ftrace_exports_enabled))
> + ftrace_exports(event);
> __buffer_unlock_commit(buffer, event);
> + }
> }
>
> #ifdef CONFIG_STACKTRACE
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox