mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

If the driver is in suspended mode, the dp block may be disabled, and chip registers may not be accessible. Yet, the worker may be triggered in this situation by an extcon event. If that happens, the following crash will be seen. cdn-dp fec00000.dp: [drm:cdn_dp_pd_event_work] *ERROR* Enable dp failed -19 cdn-dp fec00000.dp: [drm:cdn_dp_pd_event_work] Connected, not enabled. Enabling cdn Bad mode in Error handler detected, code 0xbf000002 -- SError CPU: 1 PID: 10357 Comm: kworker/1:2 Not tainted 4.4.21-05903-ge0514ea #1 Hardware name: Google Kevin (DT) Workqueue: events cdn_dp_pd_event_work task: ffffffc0cda67080 ti: ffffffc0b9b80000 task.ti: ffffffc0b9b80000 PC is at cdn_dp_clock_reset+0x30/0xa8 LR is at cdn_dp_enable+0x1e0/0x69c ... Call trace: [<ffffffc0005a7e24>] cdn_dp_pd_event_work+0x58/0x3f4 [<ffffffc0002397f0>] process_one_work+0x240/0x424 [<ffffffc00023a28c>] worker_thread+0x2fc/0x424 [<ffffffc00023f5fc>] kthread+0x10c/0x114 [<ffffffc000203dd0>] ret_from_fork+0x10/0x40 Problem is two-fold: The worker should not run while suspended, and the suspend function should not call cdn_dp_disable() while the worker is running. Signed-off-by: Guenter Roeck <groeck@chromium.org> Signed-off-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
111 lines
2.5 KiB
C
111 lines
2.5 KiB
C
/*
|
|
* Copyright (C) 2016 Chris Zhong <zyw@rock-chips.com>
|
|
* Copyright (C) 2016 ROCKCHIP, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#ifndef _CDN_DP_CORE_H
|
|
#define _CDN_DP_CORE_H
|
|
|
|
#include <drm/drmP.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include <drm/drm_dp_helper.h>
|
|
#include <drm/drm_panel.h>
|
|
#include "rockchip_drm_drv.h"
|
|
|
|
#define MAX_PHY 2
|
|
|
|
enum audio_format {
|
|
AFMT_I2S = 0,
|
|
AFMT_SPDIF = 1,
|
|
AFMT_UNUSED,
|
|
};
|
|
|
|
struct audio_info {
|
|
enum audio_format format;
|
|
int sample_rate;
|
|
int channels;
|
|
int sample_width;
|
|
};
|
|
|
|
enum vic_pxl_encoding_format {
|
|
PXL_RGB = 0x1,
|
|
YCBCR_4_4_4 = 0x2,
|
|
YCBCR_4_2_2 = 0x4,
|
|
YCBCR_4_2_0 = 0x8,
|
|
Y_ONLY = 0x10,
|
|
};
|
|
|
|
struct video_info {
|
|
bool h_sync_polarity;
|
|
bool v_sync_polarity;
|
|
bool interlaced;
|
|
int color_depth;
|
|
enum vic_pxl_encoding_format color_fmt;
|
|
};
|
|
|
|
struct cdn_firmware_header {
|
|
u32 size_bytes; /* size of the entire header+image(s) in bytes */
|
|
u32 header_size; /* size of just the header in bytes */
|
|
u32 iram_size; /* size of iram */
|
|
u32 dram_size; /* size of dram */
|
|
};
|
|
|
|
struct cdn_dp_port {
|
|
struct cdn_dp_device *dp;
|
|
struct notifier_block event_nb;
|
|
struct extcon_dev *extcon;
|
|
struct phy *phy;
|
|
u8 lanes;
|
|
bool phy_enabled;
|
|
u8 id;
|
|
};
|
|
|
|
struct cdn_dp_device {
|
|
struct device *dev;
|
|
struct drm_device *drm_dev;
|
|
struct drm_connector connector;
|
|
struct drm_encoder encoder;
|
|
struct drm_display_mode mode;
|
|
struct platform_device *audio_pdev;
|
|
struct work_struct event_work;
|
|
struct edid *edid;
|
|
|
|
struct mutex lock;
|
|
bool connected;
|
|
bool active;
|
|
bool suspended;
|
|
|
|
const struct firmware *fw; /* cdn dp firmware */
|
|
unsigned int fw_version; /* cdn fw version */
|
|
bool fw_loaded;
|
|
|
|
void __iomem *regs;
|
|
struct regmap *grf;
|
|
struct clk *core_clk;
|
|
struct clk *pclk;
|
|
struct clk *spdif_clk;
|
|
struct clk *grf_clk;
|
|
struct reset_control *spdif_rst;
|
|
struct reset_control *dptx_rst;
|
|
struct reset_control *apb_rst;
|
|
struct reset_control *core_rst;
|
|
struct audio_info audio_info;
|
|
struct video_info video_info;
|
|
struct drm_dp_link link;
|
|
struct cdn_dp_port *port[MAX_PHY];
|
|
u8 ports;
|
|
u8 lanes;
|
|
|
|
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
|
bool sink_has_audio;
|
|
};
|
|
#endif /* _CDN_DP_CORE_H */
|