[PATCH v17 3/7] drm/rockchip: cdn-dp: Do not run worker while suspended

2017-02-04 Thread Chris Zhong
From: Guenter Roeck 

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 fec0.dp: [drm:cdn_dp_pd_event_work] *ERROR* Enable dp failed -19
cdn-dp fec0.dp: [drm:cdn_dp_pd_event_work] Connected, not enabled. Enabling 
cdn
Bad mode in Error handler detected, code 0xbf02 -- 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: ffc0cda67080 ti: ffc0b9b8 task.ti: ffc0b9b8
PC is at cdn_dp_clock_reset+0x30/0xa8
LR is at cdn_dp_enable+0x1e0/0x69c
...
Call trace:
[] cdn_dp_pd_event_work+0x58/0x3f4
[] process_one_work+0x240/0x424
[] worker_thread+0x2fc/0x424
[] kthread+0x10c/0x114
[] 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 
Signed-off-by: Sean Paul 
Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 15 +--
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b8d0dd7..a70eedc 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -939,6 +939,10 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
u8 sink_count;
 
mutex_lock(>lock);
+
+   if (dp->suspended)
+   goto out;
+
ret = cdn_dp_request_firmware(dp);
if (ret)
goto out;
@@ -1123,19 +1127,26 @@ static const struct component_ops cdn_dp_component_ops 
= {
 int cdn_dp_suspend(struct device *dev)
 {
struct cdn_dp_device *dp = dev_get_drvdata(dev);
+   int ret = 0;
 
+   mutex_lock(>lock);
if (dp->active)
-   return cdn_dp_disable(dp);
+   ret = cdn_dp_disable(dp);
+   dp->suspended = true;
+   mutex_unlock(>lock);
 
-   return 0;
+   return ret;
 }
 
 int cdn_dp_resume(struct device *dev)
 {
struct cdn_dp_device *dp = dev_get_drvdata(dev);
 
+   mutex_lock(>lock);
+   dp->suspended = false;
if (dp->fw_loaded)
schedule_work(>event_work);
+   mutex_unlock(>lock);
 
return 0;
 }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 3bea4b8..7d48661 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -82,6 +82,7 @@ struct cdn_dp_device {
struct mutex lock;
bool connected;
bool active;
+   bool suspended;
 
const struct firmware *fw;  /* cdn dp firmware */
unsigned int fw_version;/* cdn fw version */
-- 
2.6.3



[PATCH v17 2/7] drm/rockchip: cdn-dp: Load firmware if no monitor connected

2017-02-04 Thread Chris Zhong
From: Guenter Roeck 

If no monitor is connected, suspend/resume cycles result in firmware
load errors because the driver attempts to load the firmware while
the system is in suspend state. This results in a kernel warning and
traceback.

Loading the firmware during boot fixes the problem. Note that we can not
just call schedule_work conditionally in cdn_dp_pd_event() if the insertion
status changed. The problem would still be seen if a monitor is connected
for the first time during suspend.

Signed-off-by: Guenter Roeck 
Signed-off-by: Sean Paul 
Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 7db2508..b8d0dd7 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1021,7 +1021,6 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
struct cdn_dp_port *port;
struct drm_device *drm_dev = data;
int ret, i;
-   bool schedule_event = false;
 
ret = cdn_dp_parse_dt(dp);
if (ret < 0)
@@ -1083,15 +1082,11 @@ static int cdn_dp_bind(struct device *dev, struct 
device *master, void *data)
  "register EXTCON_DISP_DP notifier err\n");
goto err_free_connector;
}
-
-   if (extcon_get_state(port->extcon, EXTCON_DISP_DP))
-   schedule_event = true;
}
 
pm_runtime_enable(dev);
 
-   if (schedule_event)
-   schedule_work(>event_work);
+   schedule_work(>event_work);
 
return 0;
 
-- 
2.6.3



[PATCH v17 3/7] drm/rockchip: cdn-dp: Do not run worker while suspended

2017-02-04 Thread Chris Zhong
From: Guenter Roeck 

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 fec0.dp: [drm:cdn_dp_pd_event_work] *ERROR* Enable dp failed -19
cdn-dp fec0.dp: [drm:cdn_dp_pd_event_work] Connected, not enabled. Enabling 
cdn
Bad mode in Error handler detected, code 0xbf02 -- 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: ffc0cda67080 ti: ffc0b9b8 task.ti: ffc0b9b8
PC is at cdn_dp_clock_reset+0x30/0xa8
LR is at cdn_dp_enable+0x1e0/0x69c
...
Call trace:
[] cdn_dp_pd_event_work+0x58/0x3f4
[] process_one_work+0x240/0x424
[] worker_thread+0x2fc/0x424
[] kthread+0x10c/0x114
[] 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 
Signed-off-by: Sean Paul 
Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 15 +--
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b8d0dd7..a70eedc 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -939,6 +939,10 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
u8 sink_count;
 
mutex_lock(>lock);
+
+   if (dp->suspended)
+   goto out;
+
ret = cdn_dp_request_firmware(dp);
if (ret)
goto out;
@@ -1123,19 +1127,26 @@ static const struct component_ops cdn_dp_component_ops 
= {
 int cdn_dp_suspend(struct device *dev)
 {
struct cdn_dp_device *dp = dev_get_drvdata(dev);
+   int ret = 0;
 
+   mutex_lock(>lock);
if (dp->active)
-   return cdn_dp_disable(dp);
+   ret = cdn_dp_disable(dp);
+   dp->suspended = true;
+   mutex_unlock(>lock);
 
-   return 0;
+   return ret;
 }
 
 int cdn_dp_resume(struct device *dev)
 {
struct cdn_dp_device *dp = dev_get_drvdata(dev);
 
+   mutex_lock(>lock);
+   dp->suspended = false;
if (dp->fw_loaded)
schedule_work(>event_work);
+   mutex_unlock(>lock);
 
return 0;
 }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 3bea4b8..7d48661 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -82,6 +82,7 @@ struct cdn_dp_device {
struct mutex lock;
bool connected;
bool active;
+   bool suspended;
 
const struct firmware *fw;  /* cdn dp firmware */
unsigned int fw_version;/* cdn fw version */
-- 
2.6.3



[PATCH v17 2/7] drm/rockchip: cdn-dp: Load firmware if no monitor connected

2017-02-04 Thread Chris Zhong
From: Guenter Roeck 

If no monitor is connected, suspend/resume cycles result in firmware
load errors because the driver attempts to load the firmware while
the system is in suspend state. This results in a kernel warning and
traceback.

Loading the firmware during boot fixes the problem. Note that we can not
just call schedule_work conditionally in cdn_dp_pd_event() if the insertion
status changed. The problem would still be seen if a monitor is connected
for the first time during suspend.

Signed-off-by: Guenter Roeck 
Signed-off-by: Sean Paul 
Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 7db2508..b8d0dd7 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1021,7 +1021,6 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
struct cdn_dp_port *port;
struct drm_device *drm_dev = data;
int ret, i;
-   bool schedule_event = false;
 
ret = cdn_dp_parse_dt(dp);
if (ret < 0)
@@ -1083,15 +1082,11 @@ static int cdn_dp_bind(struct device *dev, struct 
device *master, void *data)
  "register EXTCON_DISP_DP notifier err\n");
goto err_free_connector;
}
-
-   if (extcon_get_state(port->extcon, EXTCON_DISP_DP))
-   schedule_event = true;
}
 
pm_runtime_enable(dev);
 
-   if (schedule_event)
-   schedule_work(>event_work);
+   schedule_work(>event_work);
 
return 0;
 
-- 
2.6.3



[PATCH v17 5/7] drm/rockchip: cdn-dp: Move mutex_init to probe

2017-02-04 Thread Chris Zhong
From: Jeffy Chen 

We're trying to lock mutex when cdn-dp shutdown, so we need to make
sure the mutex is inited in cdn-dp's probe.

Signed-off-by: Jeffy Chen 
Reviewed-by: Guenter Roeck 
Reviewed-by: Chris Zhong 
Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 62e02a4..799e826 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1041,7 +1041,6 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
dp->connected = false;
dp->active = false;
 
-   mutex_init(>lock);
INIT_WORK(>event_work, cdn_dp_pd_event_work);
 
encoder = >encoder;
@@ -1204,6 +1203,7 @@ static int cdn_dp_probe(struct platform_device *pdev)
return -EINVAL;
}
 
+   mutex_init(>lock);
dev_set_drvdata(dev, dp);
 
return component_add(dev, _dp_component_ops);
-- 
2.6.3



[PATCH v17 5/7] drm/rockchip: cdn-dp: Move mutex_init to probe

2017-02-04 Thread Chris Zhong
From: Jeffy Chen 

We're trying to lock mutex when cdn-dp shutdown, so we need to make
sure the mutex is inited in cdn-dp's probe.

Signed-off-by: Jeffy Chen 
Reviewed-by: Guenter Roeck 
Reviewed-by: Chris Zhong 
Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 62e02a4..799e826 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -1041,7 +1041,6 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
dp->connected = false;
dp->active = false;
 
-   mutex_init(>lock);
INIT_WORK(>event_work, cdn_dp_pd_event_work);
 
encoder = >encoder;
@@ -1204,6 +1203,7 @@ static int cdn_dp_probe(struct platform_device *pdev)
return -EINVAL;
}
 
+   mutex_init(>lock);
dev_set_drvdata(dev, dp);
 
return component_add(dev, _dp_component_ops);
-- 
2.6.3



[PATCH v17 6/7] drm/rockchip: cdn-dp: retry to check sink count

2017-02-04 Thread Chris Zhong
Sometimes the Dock is disconnected, but cdn_dp_encoder_disable is not
triggered by DRM. For example, unplug the Dock in console mode, and
re-plug it again, the cdn_dp_event_work will try to get the sink count
of Dock, since the DP is still active. But the Dock has been powered
down, it need re-power on, and wait for a while until it is ready to
DPCD communication.

Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 91 +++---
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
 2 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 799e826..a630b0d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -197,6 +197,39 @@ static struct cdn_dp_port *cdn_dp_connected_port(struct 
cdn_dp_device *dp)
return NULL;
 }
 
+static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
+{
+   unsigned long timeout = jiffies + msecs_to_jiffies(CDN_DPCD_TIMEOUT_MS);
+   struct cdn_dp_port *port;
+   u8 sink_count = 0;
+
+   if (dp->active_port < 0 || dp->active_port >= dp->ports) {
+   DRM_DEV_ERROR(dp->dev, "active_port is wrong!\n");
+   return false;
+   }
+
+   port = dp->port[dp->active_port];
+
+   /*
+* Attempt to read sink count, retry in case the sink may not be ready.
+*
+* Sinks are *supposed* to come up within 1ms from an off state, but
+* some docks need more time to power up.
+*/
+   while (time_before(jiffies, timeout)) {
+   if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
+   return false;
+
+   if (!cdn_dp_get_sink_count(dp, _count))
+   return sink_count ? true : false;
+
+   usleep_range(5000, 1);
+   }
+
+   DRM_DEV_ERROR(dp->dev, "Get sink capability timed out\n");
+   return false;
+}
+
 static enum drm_connector_status
 cdn_dp_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -345,47 +378,24 @@ static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
return cdn_dp_event_config(dp);
 }
 
-static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp,
- struct cdn_dp_port *port,
- u8 *sink_count)
+static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
 {
int ret;
-   unsigned long timeout = jiffies + msecs_to_jiffies(CDN_DPCD_TIMEOUT_MS);
 
-   /*
-* Attempt to read sink count & sink capability, retry in case the sink
-* may not be ready.
-*
-* Sinks are *supposed* to come up within 1ms from an off state, but
-* some docks need more time to power up.
-*/
-   while (time_before(jiffies, timeout)) {
-   if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
-   return -ENODEV;
-
-   if (cdn_dp_get_sink_count(dp, sink_count)) {
-   usleep_range(5000, 1);
-   continue;
-   }
-
-   if (!*sink_count)
-   return -ENODEV;
-
-   ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
-  DP_RECEIVER_CAP_SIZE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
-   return ret;
-   }
+   if (!cdn_dp_check_sink_connection(dp))
+   return -ENODEV;
 
-   kfree(dp->edid);
-   dp->edid = drm_do_get_edid(>connector,
-  cdn_dp_get_edid_block, dp);
-   return 0;
+   ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
+  DP_RECEIVER_CAP_SIZE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
+   return ret;
}
 
-   DRM_DEV_ERROR(dp->dev, "Get sink capability timed out\n");
-   return -ETIMEDOUT;
+   kfree(dp->edid);
+   dp->edid = drm_do_get_edid(>connector,
+  cdn_dp_get_edid_block, dp);
+   return 0;
 }
 
 static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port 
*port)
@@ -437,6 +447,7 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, 
struct cdn_dp_port *port)
goto err_power_on;
}
 
+   dp->active_port = port->id;
return 0;
 
 err_power_on:
@@ -466,6 +477,7 @@ static int cdn_dp_disable_phy(struct cdn_dp_device *dp,
 
port->phy_enabled = false;
port->lanes = 0;
+   dp->active_port = -1;
return 0;
 }
 
@@ -504,7 +516,6 @@ static int cdn_dp_enable(struct cdn_dp_device *dp)
 {
int ret, i, lanes;
struct cdn_dp_port *port;
-  

[PATCH v17 4/7] drm/rockchip: cdn-dp: do not use drm_helper_hpd_irq_event

2017-02-04 Thread Chris Zhong
The cdn_dp_pd_event_work is using drm_helper_hpd_irq_event to update the
connector status, this function is used to update all connectors of
drm_device. Therefore, the detect of other connector will be call, when
cdn_dp_pd_event_work is triggered, every time. It is not necessary, and
it may cause system crash. replace drm_helper_hpd_irq_event with
drm_kms_helper_hotplug_event, only update cdn-dp status.

Signed-off-by: Chris Zhong 
Tested-by: Guenter Roeck 
Reviewed-by: Guenter Roeck 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index a70eedc..62e02a4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -935,6 +935,9 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 {
struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
event_work);
+   struct drm_connector *connector = >connector;
+   enum drm_connector_status old_status;
+
int ret;
u8 sink_count;
 
@@ -997,7 +1000,11 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 
 out:
mutex_unlock(>lock);
-   drm_helper_hpd_irq_event(dp->drm_dev);
+
+   old_status = connector->status;
+   connector->status = connector->funcs->detect(connector, false);
+   if (old_status != connector->status)
+   drm_kms_helper_hotplug_event(dp->drm_dev);
 }
 
 static int cdn_dp_pd_event(struct notifier_block *nb,
-- 
2.6.3



[PATCH v17 7/7] drm/rockchip: cdn-dp: don't configure hardware in mode_set

2017-02-04 Thread Chris Zhong
With atomic modesetting the hardware will be powered off when the
mode_set function is called.  We should configure the hardware in the
enable function.

Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 49 +-
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index a630b0d..9ab67a6 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -568,9 +568,7 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder 
*encoder,
 {
struct cdn_dp_device *dp = encoder_to_dp(encoder);
struct drm_display_info *display_info = >connector.display_info;
-   struct rockchip_crtc_state *state;
struct video_info *video = >video_info;
-   int ret, val;
 
switch (display_info->bpc) {
case 10:
@@ -585,31 +583,9 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder 
*encoder,
}
 
video->color_fmt = PXL_RGB;
-
video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
 
-   ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
-   if (ret < 0) {
-   DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
-   return;
-   }
-
-   DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n",
- (ret) ? "LIT" : "BIG");
-   state = to_rockchip_crtc_state(encoder->crtc->state);
-   if (ret) {
-   val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
-   state->output_mode = ROCKCHIP_OUT_MODE_P888;
-   } else {
-   val = DP_SEL_VOP_LIT << 16;
-   state->output_mode = ROCKCHIP_OUT_MODE_;
-   }
-
-   ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val);
-   if (ret)
-   return;
-
memcpy(>mode, adjusted, sizeof(*mode));
 }
 
@@ -635,9 +611,32 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device 
*dp)
 static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
 {
struct cdn_dp_device *dp = encoder_to_dp(encoder);
-   int ret;
+   int ret, val;
+   struct rockchip_crtc_state *state;
+
+   ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
+   if (ret < 0) {
+   DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
+   return;
+   }
+
+   DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n",
+ (ret) ? "LIT" : "BIG");
+   state = to_rockchip_crtc_state(encoder->crtc->state);
+   if (ret) {
+   val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
+   state->output_mode = ROCKCHIP_OUT_MODE_P888;
+   } else {
+   val = DP_SEL_VOP_LIT << 16;
+   state->output_mode = ROCKCHIP_OUT_MODE_;
+   }
+
+   ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val);
+   if (ret)
+   return;
 
mutex_lock(>lock);
+
ret = cdn_dp_enable(dp);
if (ret) {
DRM_DEV_ERROR(dp->dev, "Failed to enable encoder %d\n",
-- 
2.6.3



[PATCH v17 6/7] drm/rockchip: cdn-dp: retry to check sink count

2017-02-04 Thread Chris Zhong
Sometimes the Dock is disconnected, but cdn_dp_encoder_disable is not
triggered by DRM. For example, unplug the Dock in console mode, and
re-plug it again, the cdn_dp_event_work will try to get the sink count
of Dock, since the DP is still active. But the Dock has been powered
down, it need re-power on, and wait for a while until it is ready to
DPCD communication.

Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 91 +++---
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
 2 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 799e826..a630b0d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -197,6 +197,39 @@ static struct cdn_dp_port *cdn_dp_connected_port(struct 
cdn_dp_device *dp)
return NULL;
 }
 
+static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
+{
+   unsigned long timeout = jiffies + msecs_to_jiffies(CDN_DPCD_TIMEOUT_MS);
+   struct cdn_dp_port *port;
+   u8 sink_count = 0;
+
+   if (dp->active_port < 0 || dp->active_port >= dp->ports) {
+   DRM_DEV_ERROR(dp->dev, "active_port is wrong!\n");
+   return false;
+   }
+
+   port = dp->port[dp->active_port];
+
+   /*
+* Attempt to read sink count, retry in case the sink may not be ready.
+*
+* Sinks are *supposed* to come up within 1ms from an off state, but
+* some docks need more time to power up.
+*/
+   while (time_before(jiffies, timeout)) {
+   if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
+   return false;
+
+   if (!cdn_dp_get_sink_count(dp, _count))
+   return sink_count ? true : false;
+
+   usleep_range(5000, 1);
+   }
+
+   DRM_DEV_ERROR(dp->dev, "Get sink capability timed out\n");
+   return false;
+}
+
 static enum drm_connector_status
 cdn_dp_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -345,47 +378,24 @@ static int cdn_dp_firmware_init(struct cdn_dp_device *dp)
return cdn_dp_event_config(dp);
 }
 
-static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp,
- struct cdn_dp_port *port,
- u8 *sink_count)
+static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
 {
int ret;
-   unsigned long timeout = jiffies + msecs_to_jiffies(CDN_DPCD_TIMEOUT_MS);
 
-   /*
-* Attempt to read sink count & sink capability, retry in case the sink
-* may not be ready.
-*
-* Sinks are *supposed* to come up within 1ms from an off state, but
-* some docks need more time to power up.
-*/
-   while (time_before(jiffies, timeout)) {
-   if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
-   return -ENODEV;
-
-   if (cdn_dp_get_sink_count(dp, sink_count)) {
-   usleep_range(5000, 1);
-   continue;
-   }
-
-   if (!*sink_count)
-   return -ENODEV;
-
-   ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
-  DP_RECEIVER_CAP_SIZE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
-   return ret;
-   }
+   if (!cdn_dp_check_sink_connection(dp))
+   return -ENODEV;
 
-   kfree(dp->edid);
-   dp->edid = drm_do_get_edid(>connector,
-  cdn_dp_get_edid_block, dp);
-   return 0;
+   ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
+  DP_RECEIVER_CAP_SIZE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
+   return ret;
}
 
-   DRM_DEV_ERROR(dp->dev, "Get sink capability timed out\n");
-   return -ETIMEDOUT;
+   kfree(dp->edid);
+   dp->edid = drm_do_get_edid(>connector,
+  cdn_dp_get_edid_block, dp);
+   return 0;
 }
 
 static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port 
*port)
@@ -437,6 +447,7 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, 
struct cdn_dp_port *port)
goto err_power_on;
}
 
+   dp->active_port = port->id;
return 0;
 
 err_power_on:
@@ -466,6 +477,7 @@ static int cdn_dp_disable_phy(struct cdn_dp_device *dp,
 
port->phy_enabled = false;
port->lanes = 0;
+   dp->active_port = -1;
return 0;
 }
 
@@ -504,7 +516,6 @@ static int cdn_dp_enable(struct cdn_dp_device *dp)
 {
int ret, i, lanes;
struct cdn_dp_port *port;
-   u8 sink_count;
 
   

[PATCH v17 4/7] drm/rockchip: cdn-dp: do not use drm_helper_hpd_irq_event

2017-02-04 Thread Chris Zhong
The cdn_dp_pd_event_work is using drm_helper_hpd_irq_event to update the
connector status, this function is used to update all connectors of
drm_device. Therefore, the detect of other connector will be call, when
cdn_dp_pd_event_work is triggered, every time. It is not necessary, and
it may cause system crash. replace drm_helper_hpd_irq_event with
drm_kms_helper_hotplug_event, only update cdn-dp status.

Signed-off-by: Chris Zhong 
Tested-by: Guenter Roeck 
Reviewed-by: Guenter Roeck 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index a70eedc..62e02a4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -935,6 +935,9 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 {
struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
event_work);
+   struct drm_connector *connector = >connector;
+   enum drm_connector_status old_status;
+
int ret;
u8 sink_count;
 
@@ -997,7 +1000,11 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 
 out:
mutex_unlock(>lock);
-   drm_helper_hpd_irq_event(dp->drm_dev);
+
+   old_status = connector->status;
+   connector->status = connector->funcs->detect(connector, false);
+   if (old_status != connector->status)
+   drm_kms_helper_hotplug_event(dp->drm_dev);
 }
 
 static int cdn_dp_pd_event(struct notifier_block *nb,
-- 
2.6.3



[PATCH v17 7/7] drm/rockchip: cdn-dp: don't configure hardware in mode_set

2017-02-04 Thread Chris Zhong
With atomic modesetting the hardware will be powered off when the
mode_set function is called.  We should configure the hardware in the
enable function.

Signed-off-by: Chris Zhong 
---

Changes in v17: None

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 49 +-
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index a630b0d..9ab67a6 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -568,9 +568,7 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder 
*encoder,
 {
struct cdn_dp_device *dp = encoder_to_dp(encoder);
struct drm_display_info *display_info = >connector.display_info;
-   struct rockchip_crtc_state *state;
struct video_info *video = >video_info;
-   int ret, val;
 
switch (display_info->bpc) {
case 10:
@@ -585,31 +583,9 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder 
*encoder,
}
 
video->color_fmt = PXL_RGB;
-
video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
 
-   ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
-   if (ret < 0) {
-   DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
-   return;
-   }
-
-   DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n",
- (ret) ? "LIT" : "BIG");
-   state = to_rockchip_crtc_state(encoder->crtc->state);
-   if (ret) {
-   val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
-   state->output_mode = ROCKCHIP_OUT_MODE_P888;
-   } else {
-   val = DP_SEL_VOP_LIT << 16;
-   state->output_mode = ROCKCHIP_OUT_MODE_;
-   }
-
-   ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val);
-   if (ret)
-   return;
-
memcpy(>mode, adjusted, sizeof(*mode));
 }
 
@@ -635,9 +611,32 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device 
*dp)
 static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
 {
struct cdn_dp_device *dp = encoder_to_dp(encoder);
-   int ret;
+   int ret, val;
+   struct rockchip_crtc_state *state;
+
+   ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder);
+   if (ret < 0) {
+   DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
+   return;
+   }
+
+   DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n",
+ (ret) ? "LIT" : "BIG");
+   state = to_rockchip_crtc_state(encoder->crtc->state);
+   if (ret) {
+   val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
+   state->output_mode = ROCKCHIP_OUT_MODE_P888;
+   } else {
+   val = DP_SEL_VOP_LIT << 16;
+   state->output_mode = ROCKCHIP_OUT_MODE_;
+   }
+
+   ret = cdn_dp_grf_write(dp, GRF_SOC_CON9, val);
+   if (ret)
+   return;
 
mutex_lock(>lock);
+
ret = cdn_dp_enable(dp);
if (ret) {
DRM_DEV_ERROR(dp->dev, "Failed to enable encoder %d\n",
-- 
2.6.3



[PATCH v17 0/7] drm/rockchip: Add CDN DP driver

2017-02-04 Thread Chris Zhong
This series adds support for the CDN DP controller to the rockchip drm
driver. This version fixes some coding style error in v16, it post by
Sean Paul, you can find it here:
https://patchwork.kernel.org/patch/9442135/

And I sorted out a few patches to fix the following problems:
- suspend/resume crash cause by drm_helper_hpd_irq_event
- crash during shutdown when cdn-dp failed to bind
- check sink count failed after reconnection
- suspend/reusme crash in mode_set function

I also added these 2 patches to this series, although nothing changed:
https://patchwork.kernel.org/patch/9442141/
https://patchwork.kernel.org/patch/9442151/


Changes in v17:
- Correct the clock check condition
- Correct the coding style
- change LANE_REF_CYC to 0x8000

Chris Zhong (4):
  drm/rockchip: cdn-dp: add cdn DP support for rk3399
  drm/rockchip: cdn-dp: do not use drm_helper_hpd_irq_event
  drm/rockchip: cdn-dp: retry to check sink count
  drm/rockchip: cdn-dp: don't configure hardware in mode_set

Guenter Roeck (2):
  drm/rockchip: cdn-dp: Load firmware if no monitor connected
  drm/rockchip: cdn-dp: Do not run worker while suspended

Jeffy Chen (1):
  drm/rockchip: cdn-dp: Move mutex_init to probe

 drivers/gpu/drm/rockchip/Kconfig|   10 +
 drivers/gpu/drm/rockchip/Makefile   |2 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  | 1260 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.h  |  112 +++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  979 +
 drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  483 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |9 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |2 +
 9 files changed, 2867 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h

-- 
2.6.3



[PATCH v17 1/7] drm/rockchip: cdn-dp: add cdn DP support for rk3399

2017-02-04 Thread Chris Zhong
Add support for cdn DP controller which is embedded in the rk3399
SoCs. The DP is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work,
please put the firmware file to /lib/firmware/rockchip/dptx.bin. The
uCPU in charge of aux communication and link training, the host use
mailbox to communicate with the ucpu.
The dclk pin_pol of vop must not be invert for DP.

Signed-off-by: Chris Zhong 
[seanpaul fixed up some races between the worker and modeset]
[seanpaul squashed ~15 commits from chromium.org gerrit]
Signed-off-by: Sean Paul 
[groeck fixed compilation errors when building as module]
Signed-off-by: Guenter Roeck 

---

Changes in v17:
- Correct the clock check condition
- Correct the coding style
- change LANE_REF_CYC to 0x8000

 drivers/gpu/drm/rockchip/Kconfig|   10 +
 drivers/gpu/drm/rockchip/Makefile   |2 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  | 1237 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.h  |  110 +++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  979 +
 drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  483 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |9 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |2 +
 9 files changed, 2842 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 6f7f9c5..ad31b3e 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -21,6 +21,16 @@ config ROCKCHIP_ANALOGIX_DP
  for the Analogix Core DP driver. If you want to enable DP
  on RK3288 based SoC, you should selet this option.
 
+config ROCKCHIP_CDN_DP
+tristate "Rockchip cdn DP"
+depends on DRM_ROCKCHIP
+   select SND_SOC_HDMI_CODEC if SND_SOC
+help
+ This selects support for Rockchip SoC specific extensions
+ for the cdn DP driver. If you want to enable Dp on
+ RK3399 based SoC, you should select this
+ option.
+
 config ROCKCHIP_DW_HDMI
 tristate "Rockchip specific extensions for Synopsys DW HDMI"
 depends on DRM_ROCKCHIP
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 9746365..c931e2a 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -7,6 +7,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
 
 obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
+obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp.o
+cdn-dp-objs := cdn-dp-core.o cdn-dp-reg.o
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
 obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
new file mode 100644
index 000..7db2508
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -0,0 +1,1237 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "cdn-dp-core.h"
+#include "cdn-dp-reg.h"
+#include "rockchip_drm_vop.h"
+
+#define connector_to_dp(c) \
+   container_of(c, struct cdn_dp_device, connector)
+
+#define encoder_to_dp(c) \
+   container_of(c, struct cdn_dp_device, encoder)
+
+#define GRF_SOC_CON9   0x6224
+#define DP_SEL_VOP_LIT BIT(12)
+#define GRF_SOC_CON26  0x6268
+#define UPHY_SEL_BIT   3
+#define UPHY_SEL_MASK  BIT(19)
+#define DPTX_HPD_SEL   (3 << 12)
+#define DPTX_HPD_DEL   (2 << 12)
+#define DPTX_HPD_SEL_MASK  (3 << 28)
+
+#define CDN_FW_TIMEOUT_MS  (64 * 1000)
+#define CDN_DPCD_TIMEOUT_MS5000
+#define CDN_DP_FIRMWARE"rockchip/dptx.bin"
+
+struct cdn_dp_data {
+   u8 max_phy;
+};
+

[PATCH v17 0/7] drm/rockchip: Add CDN DP driver

2017-02-04 Thread Chris Zhong
This series adds support for the CDN DP controller to the rockchip drm
driver. This version fixes some coding style error in v16, it post by
Sean Paul, you can find it here:
https://patchwork.kernel.org/patch/9442135/

And I sorted out a few patches to fix the following problems:
- suspend/resume crash cause by drm_helper_hpd_irq_event
- crash during shutdown when cdn-dp failed to bind
- check sink count failed after reconnection
- suspend/reusme crash in mode_set function

I also added these 2 patches to this series, although nothing changed:
https://patchwork.kernel.org/patch/9442141/
https://patchwork.kernel.org/patch/9442151/


Changes in v17:
- Correct the clock check condition
- Correct the coding style
- change LANE_REF_CYC to 0x8000

Chris Zhong (4):
  drm/rockchip: cdn-dp: add cdn DP support for rk3399
  drm/rockchip: cdn-dp: do not use drm_helper_hpd_irq_event
  drm/rockchip: cdn-dp: retry to check sink count
  drm/rockchip: cdn-dp: don't configure hardware in mode_set

Guenter Roeck (2):
  drm/rockchip: cdn-dp: Load firmware if no monitor connected
  drm/rockchip: cdn-dp: Do not run worker while suspended

Jeffy Chen (1):
  drm/rockchip: cdn-dp: Move mutex_init to probe

 drivers/gpu/drm/rockchip/Kconfig|   10 +
 drivers/gpu/drm/rockchip/Makefile   |2 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  | 1260 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.h  |  112 +++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  979 +
 drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  483 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |9 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |2 +
 9 files changed, 2867 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h

-- 
2.6.3



[PATCH v17 1/7] drm/rockchip: cdn-dp: add cdn DP support for rk3399

2017-02-04 Thread Chris Zhong
Add support for cdn DP controller which is embedded in the rk3399
SoCs. The DP is compliant with DisplayPort Specification,
Version 1.3, This IP is compatible with the rockchip type-c PHY IP.
There is a uCPU in DP controller, it need a firmware to work,
please put the firmware file to /lib/firmware/rockchip/dptx.bin. The
uCPU in charge of aux communication and link training, the host use
mailbox to communicate with the ucpu.
The dclk pin_pol of vop must not be invert for DP.

Signed-off-by: Chris Zhong 
[seanpaul fixed up some races between the worker and modeset]
[seanpaul squashed ~15 commits from chromium.org gerrit]
Signed-off-by: Sean Paul 
[groeck fixed compilation errors when building as module]
Signed-off-by: Guenter Roeck 

---

Changes in v17:
- Correct the clock check condition
- Correct the coding style
- change LANE_REF_CYC to 0x8000

 drivers/gpu/drm/rockchip/Kconfig|   10 +
 drivers/gpu/drm/rockchip/Makefile   |2 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c  | 1237 +++
 drivers/gpu/drm/rockchip/cdn-dp-core.h  |  110 +++
 drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  979 +
 drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  483 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   13 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |9 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |2 +
 9 files changed, 2842 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-core.h
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c
 create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 6f7f9c5..ad31b3e 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -21,6 +21,16 @@ config ROCKCHIP_ANALOGIX_DP
  for the Analogix Core DP driver. If you want to enable DP
  on RK3288 based SoC, you should selet this option.
 
+config ROCKCHIP_CDN_DP
+tristate "Rockchip cdn DP"
+depends on DRM_ROCKCHIP
+   select SND_SOC_HDMI_CODEC if SND_SOC
+help
+ This selects support for Rockchip SoC specific extensions
+ for the cdn DP driver. If you want to enable Dp on
+ RK3399 based SoC, you should select this
+ option.
+
 config ROCKCHIP_DW_HDMI
 tristate "Rockchip specific extensions for Synopsys DW HDMI"
 depends on DRM_ROCKCHIP
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index 9746365..c931e2a 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -7,6 +7,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
 
 obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
+obj-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp.o
+cdn-dp-objs := cdn-dp-core.o cdn-dp-reg.o
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
 obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
 obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
new file mode 100644
index 000..7db2508
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -0,0 +1,1237 @@
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "cdn-dp-core.h"
+#include "cdn-dp-reg.h"
+#include "rockchip_drm_vop.h"
+
+#define connector_to_dp(c) \
+   container_of(c, struct cdn_dp_device, connector)
+
+#define encoder_to_dp(c) \
+   container_of(c, struct cdn_dp_device, encoder)
+
+#define GRF_SOC_CON9   0x6224
+#define DP_SEL_VOP_LIT BIT(12)
+#define GRF_SOC_CON26  0x6268
+#define UPHY_SEL_BIT   3
+#define UPHY_SEL_MASK  BIT(19)
+#define DPTX_HPD_SEL   (3 << 12)
+#define DPTX_HPD_DEL   (2 << 12)
+#define DPTX_HPD_SEL_MASK  (3 << 28)
+
+#define CDN_FW_TIMEOUT_MS  (64 * 1000)
+#define CDN_DPCD_TIMEOUT_MS5000
+#define CDN_DP_FIRMWARE"rockchip/dptx.bin"
+
+struct cdn_dp_data {
+   u8 max_phy;
+};
+
+struct cdn_dp_data rk3399_cdn_dp = {
+   .max_phy = 2,
+};
+
+static const struct 

Re: [RFC 1/1] shiftfs: uid/gid shifting bind mount

2017-02-04 Thread Amir Goldstein
On Sat, Feb 4, 2017 at 9:19 PM, James Bottomley
 wrote:
> This allows any subtree to be uid/gid shifted and bound elsewhere.  It
> does this by operating simlarly to overlayfs.  Its primary use is for
> shifting the underlying uids of filesystems used to support
> unpriviliged (uid shifted) containers.  The usual use case here is
> that the container is operating with an uid shifted unprivileged root
> but sometimes needs to make use of or work with a filesystem image
> that has root at real uid 0.
>
> The mechanism is to allow any subordinate mount namespace to mount a
> shiftfs filesystem (by marking it FS_USERNS_MOUNT) but only allowing
> it to mount marked subtrees (using the -o mark option as root).  Once
> mounted, the subtree is mapped via the super block user namespace so
> that the interior ids of the mounting user namespace are the ids
> written to the filesystem.
>
> Signed-off-by: James Bottomley 
>

James,

Allow me to point out some problems in this patch and offer a slightly different
approach.

First of all, the subject says "uid/gid shifting bind mount", but it's not
really a bind mount. What it is is a stackable mount and 2 levels of
stack no less.
So one thing that is missing is increasing of sb->s_stack_depth and that
also means that shiftfs cannot be used to recursively shift uids in child userns
if that was ever the intention.

The other problem is that by forking overlayfs functionality, shiftfs is going
to miss out on overlayfs bug fixes related to user credentials differ
from mounter
credentials, like fd3220d ("ovl: update S_ISGID when setting posix ACLs").
I am not sure that this specific case is relevant to shiftfs, but
there could be other.

So how about, instead of forking a new containers specialized stackable fs,
that the needed functionality be merged into overlayfs code?
I think overlayfs container users may also benefit from shiftfs
functionality, no?
In any case, overlayfs has considerable millage used as fs for containers,
so many issues related to running with different userns may have already been
addressed.

Overlayfs already stores the mounter's credentials and uses them to perform
most of the operations on upper.

I know it wasn't the original purpose of overlayfs to run as a single layer, but
there is nothing really preventing from doing that. In fact, I am
doing just that
with my snapshot mount patches, see:
https://github.com/amir73il/linux/commit/acc6c25eab03c176c9ef736544fab3fba663765d#diff-2b85a3c5bea4263d08a2bdff639192c3
I registered a new fs type ("snapshot"), which reuses most of the existing
overlayfs operations.
With this patch it is possible to mount an overlay with only upper layer, so all
the operations are pass through except for the credentials, e.g.:

mount -t snapshot -o upper= shiftfs_test 

If you think this concept is workable, then the functionality of
mounting overlayfs
with only upper should be integrated into plain overlayfs and shiftfs could be
a very thin variant of overlayfs mount using shitfs_fs_type, just for the sake
of having FS_USERNS_MOUNT, e.g:

+ /*
+  * XXX: reusing ovl_mount()/ovl_fill_super(), but could also just reuse
+  * 
ovl_dentry_operations/ovl_super_operations/ovl_xattr_handlers/ovl_new_inode()
+  */
+static struct file_system_type shiftfs_type = {
+   .owner  = THIS_MODULE,
+   .name   = "shiftfs",
+   .mount  = ovl_mount,
+   .kill_sb= kill_anon_super,
+   .fs_flags   = FS_USERNS_MOUNT,
+};
+MODULE_ALIAS_FS("shiftfs");
+MODULE_ALIAS("shiftfs");
+#define IS_SHIFTFS_SB(sb) ((sb)->s_type == _type)

And instead of verifying that shiftfs is mounted inside container over shiftfs,
verify that it is mounted over an overlayfs noexec mount e.g.:

+   if (IS_SHIFTFS_SB(sb)) {
+   /*
+* this leg executes if we're admin capable in
+* the namespace, so be very careful
+*/
+   if (path.dentry->d_sb->s_magic != OVERLAYFS_MAGIC ||
!(path.dentry->d_sb->s_iflags & SB_I_NOEXEC))
+   goto out_put;

>From users manual POV:

in host:
mount -t overlay -o noexec,upper= container_visible 

in container:
mount -t shiftfs -o upper= container_writable


Thought?


Re: [RFC 1/1] shiftfs: uid/gid shifting bind mount

2017-02-04 Thread Amir Goldstein
On Sat, Feb 4, 2017 at 9:19 PM, James Bottomley
 wrote:
> This allows any subtree to be uid/gid shifted and bound elsewhere.  It
> does this by operating simlarly to overlayfs.  Its primary use is for
> shifting the underlying uids of filesystems used to support
> unpriviliged (uid shifted) containers.  The usual use case here is
> that the container is operating with an uid shifted unprivileged root
> but sometimes needs to make use of or work with a filesystem image
> that has root at real uid 0.
>
> The mechanism is to allow any subordinate mount namespace to mount a
> shiftfs filesystem (by marking it FS_USERNS_MOUNT) but only allowing
> it to mount marked subtrees (using the -o mark option as root).  Once
> mounted, the subtree is mapped via the super block user namespace so
> that the interior ids of the mounting user namespace are the ids
> written to the filesystem.
>
> Signed-off-by: James Bottomley 
>

James,

Allow me to point out some problems in this patch and offer a slightly different
approach.

First of all, the subject says "uid/gid shifting bind mount", but it's not
really a bind mount. What it is is a stackable mount and 2 levels of
stack no less.
So one thing that is missing is increasing of sb->s_stack_depth and that
also means that shiftfs cannot be used to recursively shift uids in child userns
if that was ever the intention.

The other problem is that by forking overlayfs functionality, shiftfs is going
to miss out on overlayfs bug fixes related to user credentials differ
from mounter
credentials, like fd3220d ("ovl: update S_ISGID when setting posix ACLs").
I am not sure that this specific case is relevant to shiftfs, but
there could be other.

So how about, instead of forking a new containers specialized stackable fs,
that the needed functionality be merged into overlayfs code?
I think overlayfs container users may also benefit from shiftfs
functionality, no?
In any case, overlayfs has considerable millage used as fs for containers,
so many issues related to running with different userns may have already been
addressed.

Overlayfs already stores the mounter's credentials and uses them to perform
most of the operations on upper.

I know it wasn't the original purpose of overlayfs to run as a single layer, but
there is nothing really preventing from doing that. In fact, I am
doing just that
with my snapshot mount patches, see:
https://github.com/amir73il/linux/commit/acc6c25eab03c176c9ef736544fab3fba663765d#diff-2b85a3c5bea4263d08a2bdff639192c3
I registered a new fs type ("snapshot"), which reuses most of the existing
overlayfs operations.
With this patch it is possible to mount an overlay with only upper layer, so all
the operations are pass through except for the credentials, e.g.:

mount -t snapshot -o upper= shiftfs_test 

If you think this concept is workable, then the functionality of
mounting overlayfs
with only upper should be integrated into plain overlayfs and shiftfs could be
a very thin variant of overlayfs mount using shitfs_fs_type, just for the sake
of having FS_USERNS_MOUNT, e.g:

+ /*
+  * XXX: reusing ovl_mount()/ovl_fill_super(), but could also just reuse
+  * 
ovl_dentry_operations/ovl_super_operations/ovl_xattr_handlers/ovl_new_inode()
+  */
+static struct file_system_type shiftfs_type = {
+   .owner  = THIS_MODULE,
+   .name   = "shiftfs",
+   .mount  = ovl_mount,
+   .kill_sb= kill_anon_super,
+   .fs_flags   = FS_USERNS_MOUNT,
+};
+MODULE_ALIAS_FS("shiftfs");
+MODULE_ALIAS("shiftfs");
+#define IS_SHIFTFS_SB(sb) ((sb)->s_type == _type)

And instead of verifying that shiftfs is mounted inside container over shiftfs,
verify that it is mounted over an overlayfs noexec mount e.g.:

+   if (IS_SHIFTFS_SB(sb)) {
+   /*
+* this leg executes if we're admin capable in
+* the namespace, so be very careful
+*/
+   if (path.dentry->d_sb->s_magic != OVERLAYFS_MAGIC ||
!(path.dentry->d_sb->s_iflags & SB_I_NOEXEC))
+   goto out_put;

>From users manual POV:

in host:
mount -t overlay -o noexec,upper= container_visible 

in container:
mount -t shiftfs -o upper= container_writable


Thought?


Re: [PATCH v3 3/5] drm/rockchip/dsi: remove mode_valid function

2017-02-04 Thread Mark yao

On 2017年02月05日 11:42, Chris Zhong wrote:



On 02/02/2017 02:12 AM, Sean Paul wrote:

On Tue, Jan 24, 2017 at 10:27:27AM +0800, Chris Zhong wrote:

Hi Sean

On 01/24/2017 01:48 AM, Sean Paul wrote:

On Fri, Jan 20, 2017 at 06:10:49PM +0800, Chris Zhong wrote:

The MIPI DSI do not need check the validity of resolution, the max
resolution should depend VOP. Hence, remove 
rk3288_mipi_dsi_mode_valid

here.
Does vop actually enforce this, though? I see that 
mode_config.max_width is

4096, but there is no bounds checking in mode_fixup().

The connector is currently rejecting everything greater than 2047. 
So I think

you're going to regress behavior here.

Sean

The mipi controller has not this width limit, it depend the VOP,
such as RK3399, VOP_LIT only support 2560,
but VOP_BIG support 4K. So this driver should check the width here.
I don't see anything in the vop driver that rejects large modes for 
little vop.
So, while I agree the check shouldn't be here, you should move it to 
where it

should be instead of removing it entirely.

Sean


drm_mode_validate_size will check the dev->mode_config.max_width and
dev->mode_config.max_height, these 2 value come from 
rockchip_drm_mode_config_init,
currently, they are both 4096. So you are right, drm driver does not 
distinguish

between vop lit and big.

I think Mark Yao already have a local solution, and he will post it soon.

Hi

See follow patches, support mode valid with vop callback.

[0] https://patchwork.kernel.org/patch/9555943/
[1] https://patchwork.kernel.org/patch/9555945/








Signed-off-by: Chris Zhong 
---

Changes in v3: None

  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 
--

  1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c

index a93ce97..6f0e252 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -278,8 +278,6 @@ struct dw_mipi_dsi_plat_data {
  u32 grf_dsi0_mode;
  u32 grf_dsi0_mode_reg;
  unsigned int max_data_lanes;
-enum drm_mode_status (*mode_valid)(struct drm_connector 
*connector,

-   struct drm_display_mode *mode);
  };
  struct dw_mipi_dsi {
@@ -1081,23 +1079,8 @@ static int 
dw_mipi_dsi_connector_get_modes(struct drm_connector *connector)

  return drm_panel_get_modes(dsi->panel);
  }
-static enum drm_mode_status dw_mipi_dsi_mode_valid(
-struct drm_connector *connector,
-struct drm_display_mode *mode)
-{
-struct dw_mipi_dsi *dsi = con_to_dsi(connector);
-
-enum drm_mode_status mode_status = MODE_OK;
-
-if (dsi->pdata->mode_valid)
-mode_status = dsi->pdata->mode_valid(connector, mode);
-
-return mode_status;
-}
-
  static struct drm_connector_helper_funcs 
dw_mipi_dsi_connector_helper_funcs = {

  .get_modes = dw_mipi_dsi_connector_get_modes,
-.mode_valid = dw_mipi_dsi_mode_valid,
  };
  static void dw_mipi_dsi_drm_connector_destroy(struct 
drm_connector *connector)
@@ -1168,33 +1151,11 @@ static int rockchip_mipi_parse_dt(struct 
dw_mipi_dsi *dsi)

  return 0;
  }
-static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
-struct drm_connector *connector,
-struct drm_display_mode *mode)
-{
-/*
- * The VID_PKT_SIZE field in the DSI_VID_PKT_CFG
- * register is 11-bit.
- */
-if (mode->hdisplay > 0x7ff)
-return MODE_BAD_HVALUE;
-
-/*
- * The V_ACTIVE_LINES field in the DSI_VTIMING_CFG
- * register is 11-bit.
- */
-if (mode->vdisplay > 0x7ff)
-return MODE_BAD_VVALUE;
-
-return MODE_OK;
-}
-
  static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
  .dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
  .dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
  .grf_switch_reg = RK3288_GRF_SOC_CON6,
  .max_data_lanes = 4,
-.mode_valid = rk3288_mipi_dsi_mode_valid,
  };
  static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
--
2.6.3

___
dri-devel mailing list
dri-de...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-de...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel








--
Mark Yao




Re: [PATCH v3 3/5] drm/rockchip/dsi: remove mode_valid function

2017-02-04 Thread Mark yao

On 2017年02月05日 11:42, Chris Zhong wrote:



On 02/02/2017 02:12 AM, Sean Paul wrote:

On Tue, Jan 24, 2017 at 10:27:27AM +0800, Chris Zhong wrote:

Hi Sean

On 01/24/2017 01:48 AM, Sean Paul wrote:

On Fri, Jan 20, 2017 at 06:10:49PM +0800, Chris Zhong wrote:

The MIPI DSI do not need check the validity of resolution, the max
resolution should depend VOP. Hence, remove 
rk3288_mipi_dsi_mode_valid

here.
Does vop actually enforce this, though? I see that 
mode_config.max_width is

4096, but there is no bounds checking in mode_fixup().

The connector is currently rejecting everything greater than 2047. 
So I think

you're going to regress behavior here.

Sean

The mipi controller has not this width limit, it depend the VOP,
such as RK3399, VOP_LIT only support 2560,
but VOP_BIG support 4K. So this driver should check the width here.
I don't see anything in the vop driver that rejects large modes for 
little vop.
So, while I agree the check shouldn't be here, you should move it to 
where it

should be instead of removing it entirely.

Sean


drm_mode_validate_size will check the dev->mode_config.max_width and
dev->mode_config.max_height, these 2 value come from 
rockchip_drm_mode_config_init,
currently, they are both 4096. So you are right, drm driver does not 
distinguish

between vop lit and big.

I think Mark Yao already have a local solution, and he will post it soon.

Hi

See follow patches, support mode valid with vop callback.

[0] https://patchwork.kernel.org/patch/9555943/
[1] https://patchwork.kernel.org/patch/9555945/








Signed-off-by: Chris Zhong 
---

Changes in v3: None

  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 
--

  1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c

index a93ce97..6f0e252 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -278,8 +278,6 @@ struct dw_mipi_dsi_plat_data {
  u32 grf_dsi0_mode;
  u32 grf_dsi0_mode_reg;
  unsigned int max_data_lanes;
-enum drm_mode_status (*mode_valid)(struct drm_connector 
*connector,

-   struct drm_display_mode *mode);
  };
  struct dw_mipi_dsi {
@@ -1081,23 +1079,8 @@ static int 
dw_mipi_dsi_connector_get_modes(struct drm_connector *connector)

  return drm_panel_get_modes(dsi->panel);
  }
-static enum drm_mode_status dw_mipi_dsi_mode_valid(
-struct drm_connector *connector,
-struct drm_display_mode *mode)
-{
-struct dw_mipi_dsi *dsi = con_to_dsi(connector);
-
-enum drm_mode_status mode_status = MODE_OK;
-
-if (dsi->pdata->mode_valid)
-mode_status = dsi->pdata->mode_valid(connector, mode);
-
-return mode_status;
-}
-
  static struct drm_connector_helper_funcs 
dw_mipi_dsi_connector_helper_funcs = {

  .get_modes = dw_mipi_dsi_connector_get_modes,
-.mode_valid = dw_mipi_dsi_mode_valid,
  };
  static void dw_mipi_dsi_drm_connector_destroy(struct 
drm_connector *connector)
@@ -1168,33 +1151,11 @@ static int rockchip_mipi_parse_dt(struct 
dw_mipi_dsi *dsi)

  return 0;
  }
-static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
-struct drm_connector *connector,
-struct drm_display_mode *mode)
-{
-/*
- * The VID_PKT_SIZE field in the DSI_VID_PKT_CFG
- * register is 11-bit.
- */
-if (mode->hdisplay > 0x7ff)
-return MODE_BAD_HVALUE;
-
-/*
- * The V_ACTIVE_LINES field in the DSI_VTIMING_CFG
- * register is 11-bit.
- */
-if (mode->vdisplay > 0x7ff)
-return MODE_BAD_VVALUE;
-
-return MODE_OK;
-}
-
  static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
  .dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
  .dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
  .grf_switch_reg = RK3288_GRF_SOC_CON6,
  .max_data_lanes = 4,
-.mode_valid = rk3288_mipi_dsi_mode_valid,
  };
  static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
--
2.6.3

___
dri-devel mailing list
dri-de...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-de...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel








--
Mark Yao




Re: [PATCH v2] usb: misc: add USB251xB/xBi Hi-Speed Hub Controller Driver

2017-02-04 Thread Greg KH
On Fri, Feb 03, 2017 at 11:55:24AM +0100, Richard Leitner wrote:
> +/**
> + * ascii2utf16le() - Helper routine for producing UTF-16LE string descriptors
> + * @s: Null-terminated ASCII (actually ISO-8859-1) string
> + * @buf: Buffer for UTF-16LE string
> + * @len: Length (in bytes; may be odd) of UTF-16LE buffer.
> + *
> + * Return: The number of bytes filled in: 2*strlen(s) or @len, whichever is 
> less
> + *
> + * Note:
> + * The UTF-16LE USB String descriptors can contain at most 31 characters (as
> + * specified in the datasheet); input strings longer than that are truncated.
> + *
> + * Based on ascii2desc from drivers/usb/core/hcd.c
> + */
> +static unsigned int ascii2utf16le(char const *s, u8 *buf, unsigned int len)
> +{
> + unsigned int n, t = 2 * strlen(s);
> +
> + if (t > USB251XB_STRING_BUFSIZE)
> + t = USB251XB_STRING_BUFSIZE;
> + if (len > t)
> + len = t;
> + n = len;
> + while (n--) {
> + t = (unsigned char)*s++;
> + *buf++ = t;
> + if (!n--)
> + break;
> + *buf++ = t >> 8;
> + }
> + return len;
> +}

Don't we have a kernel function for this already?  If we need to export
ascii2desc() from the USB core, we can do that, or better yet, move both
of them to a string library function in the core part of the kernel.  We
shouldn't have to duplicate this type of thin in an individual driver.

> --- /dev/null
> +++ b/include/linux/platform_data/usb251xb.h
> @@ -0,0 +1,33 @@
> +#ifndef __USB251XB_H__
> +#define __USB251XB_H__
> +
> +struct usb251xb_platform_data {
> + int gpio_reset;
> + u16 vendor_id;
> + u16 product_id;
> + u16 device_id;
> + u8 conf_data1;
> + u8 conf_data2;
> + u8 conf_data3;
> + u8 non_rem_dev;
> + u8 port_disable_sp;
> + u8 port_disable_bp;
> + u8 max_power_sp;
> + u8 max_power_bp;
> + u8 max_current_sp;
> + u8 max_current_bp;
> + u8 power_on_time;
> + u16 lang_id;
> + char manufacturer[31];  /* NULL terminated ASCII string */
> + char product[31];   /* NULL terminated ASCII string */
> + char serial[31];/* NULL terminated ASCII string */
> + u8 bat_charge_en;
> + u8 boost_up;
> + u8 boost_x;
> + u8 port_swap;
> + u8 port_map12;
> + u8 port_map34;
> + u8 status;
> +};

Do you need a platform data structure here?  Shouldn't we be only using
DT now?

thanks,

greg k-h


Re: [PATCH v2] usb: misc: add USB251xB/xBi Hi-Speed Hub Controller Driver

2017-02-04 Thread Greg KH
On Fri, Feb 03, 2017 at 11:55:24AM +0100, Richard Leitner wrote:
> +/**
> + * ascii2utf16le() - Helper routine for producing UTF-16LE string descriptors
> + * @s: Null-terminated ASCII (actually ISO-8859-1) string
> + * @buf: Buffer for UTF-16LE string
> + * @len: Length (in bytes; may be odd) of UTF-16LE buffer.
> + *
> + * Return: The number of bytes filled in: 2*strlen(s) or @len, whichever is 
> less
> + *
> + * Note:
> + * The UTF-16LE USB String descriptors can contain at most 31 characters (as
> + * specified in the datasheet); input strings longer than that are truncated.
> + *
> + * Based on ascii2desc from drivers/usb/core/hcd.c
> + */
> +static unsigned int ascii2utf16le(char const *s, u8 *buf, unsigned int len)
> +{
> + unsigned int n, t = 2 * strlen(s);
> +
> + if (t > USB251XB_STRING_BUFSIZE)
> + t = USB251XB_STRING_BUFSIZE;
> + if (len > t)
> + len = t;
> + n = len;
> + while (n--) {
> + t = (unsigned char)*s++;
> + *buf++ = t;
> + if (!n--)
> + break;
> + *buf++ = t >> 8;
> + }
> + return len;
> +}

Don't we have a kernel function for this already?  If we need to export
ascii2desc() from the USB core, we can do that, or better yet, move both
of them to a string library function in the core part of the kernel.  We
shouldn't have to duplicate this type of thin in an individual driver.

> --- /dev/null
> +++ b/include/linux/platform_data/usb251xb.h
> @@ -0,0 +1,33 @@
> +#ifndef __USB251XB_H__
> +#define __USB251XB_H__
> +
> +struct usb251xb_platform_data {
> + int gpio_reset;
> + u16 vendor_id;
> + u16 product_id;
> + u16 device_id;
> + u8 conf_data1;
> + u8 conf_data2;
> + u8 conf_data3;
> + u8 non_rem_dev;
> + u8 port_disable_sp;
> + u8 port_disable_bp;
> + u8 max_power_sp;
> + u8 max_power_bp;
> + u8 max_current_sp;
> + u8 max_current_bp;
> + u8 power_on_time;
> + u16 lang_id;
> + char manufacturer[31];  /* NULL terminated ASCII string */
> + char product[31];   /* NULL terminated ASCII string */
> + char serial[31];/* NULL terminated ASCII string */
> + u8 bat_charge_en;
> + u8 boost_up;
> + u8 boost_x;
> + u8 port_swap;
> + u8 port_map12;
> + u8 port_map34;
> + u8 status;
> +};

Do you need a platform data structure here?  Shouldn't we be only using
DT now?

thanks,

greg k-h


[PATCH 2/2] drm/rockchip: dw_hdmi: check display mode with crtc mode valid

2017-02-04 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 47 +++--
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index a6d4a02..64408bc 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -158,18 +158,59 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
struct drm_display_mode *mode)
 {
const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
+   struct drm_device *dev = connector->dev;
+   struct drm_encoder *encoder = connector->encoder;
+   struct rockchip_drm_private *priv = dev->dev_private;
int pclk = mode->clock * 1000;
-   bool valid = false;
+   enum drm_mode_status status = MODE_BAD;
+   struct drm_crtc *crtc;
int i;
 
for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
if (pclk == mpll_cfg[i].mpixelclock) {
-   valid = true;
+   status = MODE_OK;
break;
}
}
 
-   return (valid) ? MODE_OK : MODE_BAD;
+
+   if (status != MODE_OK)
+   return status;
+
+   if (!encoder) {
+   const struct drm_connector_helper_funcs *funcs;
+
+   funcs = connector->helper_private;
+   if (funcs->atomic_best_encoder)
+   encoder = funcs->atomic_best_encoder(connector,
+connector->state);
+   else
+   encoder = funcs->best_encoder(connector);
+   }
+
+   if (!encoder || !encoder->possible_crtcs)
+   return MODE_BAD;
+   /*
+* ensure all drm display mode can work, if someone want support more
+* resolutions, please limit the possible_crtc, only connect to
+* needed crtc.
+*/
+   drm_for_each_crtc(crtc, connector->dev) {
+   int pipe = drm_crtc_index(crtc);
+   const struct rockchip_crtc_funcs *funcs =
+   priv->crtc_funcs[pipe];
+
+   if (!(encoder->possible_crtcs & drm_crtc_mask(crtc)))
+   continue;
+   if (!funcs || !funcs->mode_valid)
+   continue;
+
+   status = funcs->mode_valid(crtc, mode);
+   if (status != MODE_OK)
+   return status;
+   }
+
+   return status;
 }
 
 static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
-- 
1.9.1




[PATCH 1/2] drm/rockchip: support mode_valid for crtc

2017-02-04 Thread Mark Yao
drm crtc already has mode_fixup callback to can do mode check, but
We actually want to valid display mode on connector getmode time,
mode_fixup can't do it.

So add a private mode_valid callback to rockchip crtc, connectors can
check mode with this mode_valid callback.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  2 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  7 +++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +
 4 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..d10b15c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -39,6 +39,8 @@
 struct rockchip_crtc_funcs {
int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc);
+   enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+  const struct drm_display_mode *mode);
 };
 
 struct rockchip_crtc_state {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index fb5f001..256fe73 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -853,9 +853,24 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
spin_unlock_irqrestore(>irq_lock, flags);
 }
 
+static enum drm_mode_status
+vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
+{
+   struct vop *vop = to_vop(crtc);
+   const struct vop_data *vop_data = vop->data;
+
+   if (mode->hdisplay > vop_data->max_output.width)
+   return MODE_BAD_HVALUE;
+   if (mode->vdisplay > vop_data->max_output.height)
+   return MODE_BAD_VVALUE;
+
+   return MODE_OK;
+}
+
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
.enable_vblank = vop_crtc_enable_vblank,
.disable_vblank = vop_crtc_disable_vblank,
+   .mode_valid = vop_crtc_mode_valid,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 1dbc526..9e9dba1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -133,6 +133,11 @@ struct vop_win_data {
enum drm_plane_type type;
 };
 
+struct vop_rect {
+   int width;
+   int height;
+};
+
 struct vop_data {
const struct vop_reg_data *init_table;
unsigned int table_size;
@@ -140,6 +145,8 @@ struct vop_data {
const struct vop_intr *intr;
const struct vop_win_data *win;
unsigned int win_size;
+   struct vop_rect max_input;
+   struct vop_rect max_output;
 };
 
 /* interrupt define */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 35c51f3..0c72361 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -132,6 +132,8 @@
 };
 
 static const struct vop_data rk3036_vop = {
+   .max_input = { 1920, 1080},
+   .max_output = { 1920, 1080},
.init_table = rk3036_vop_init_reg_table,
.table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
.ctrl = _ctrl_data,
@@ -273,6 +275,13 @@
 };
 
 static const struct vop_data rk3288_vop = {
+   .max_input = { 4096, 8192},
+   /*
+* TODO: rk3288 have two vop, big one support 3840x2160,
+* little one only support 2560x1600.
+* Now force use 3840x2160.
+*/
+   .max_output = { 3840, 2160},
.init_table = rk3288_init_reg_table,
.table_size = ARRAY_SIZE(rk3288_init_reg_table),
.intr = _vop_intr,
@@ -339,6 +348,8 @@
 };
 
 static const struct vop_data rk3399_vop_big = {
+   .max_input = { 4096, 8192},
+   .max_output = { 4096, 2160},
.init_table = rk3399_init_reg_table,
.table_size = ARRAY_SIZE(rk3399_init_reg_table),
.intr = _vop_intr,
@@ -358,6 +369,8 @@
 };
 
 static const struct vop_data rk3399_vop_lit = {
+   .max_input = { 4096, 8192},
+   .max_output = { 2560, 1600},
.init_table = rk3399_init_reg_table,
.table_size = ARRAY_SIZE(rk3399_init_reg_table),
.intr = _vop_intr,
-- 
1.9.1




[PATCH 2/2] drm/rockchip: dw_hdmi: check display mode with crtc mode valid

2017-02-04 Thread Mark Yao
Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 47 +++--
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index a6d4a02..64408bc 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -158,18 +158,59 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi 
*hdmi)
struct drm_display_mode *mode)
 {
const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
+   struct drm_device *dev = connector->dev;
+   struct drm_encoder *encoder = connector->encoder;
+   struct rockchip_drm_private *priv = dev->dev_private;
int pclk = mode->clock * 1000;
-   bool valid = false;
+   enum drm_mode_status status = MODE_BAD;
+   struct drm_crtc *crtc;
int i;
 
for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
if (pclk == mpll_cfg[i].mpixelclock) {
-   valid = true;
+   status = MODE_OK;
break;
}
}
 
-   return (valid) ? MODE_OK : MODE_BAD;
+
+   if (status != MODE_OK)
+   return status;
+
+   if (!encoder) {
+   const struct drm_connector_helper_funcs *funcs;
+
+   funcs = connector->helper_private;
+   if (funcs->atomic_best_encoder)
+   encoder = funcs->atomic_best_encoder(connector,
+connector->state);
+   else
+   encoder = funcs->best_encoder(connector);
+   }
+
+   if (!encoder || !encoder->possible_crtcs)
+   return MODE_BAD;
+   /*
+* ensure all drm display mode can work, if someone want support more
+* resolutions, please limit the possible_crtc, only connect to
+* needed crtc.
+*/
+   drm_for_each_crtc(crtc, connector->dev) {
+   int pipe = drm_crtc_index(crtc);
+   const struct rockchip_crtc_funcs *funcs =
+   priv->crtc_funcs[pipe];
+
+   if (!(encoder->possible_crtcs & drm_crtc_mask(crtc)))
+   continue;
+   if (!funcs || !funcs->mode_valid)
+   continue;
+
+   status = funcs->mode_valid(crtc, mode);
+   if (status != MODE_OK)
+   return status;
+   }
+
+   return status;
 }
 
 static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
-- 
1.9.1




[PATCH 1/2] drm/rockchip: support mode_valid for crtc

2017-02-04 Thread Mark Yao
drm crtc already has mode_fixup callback to can do mode check, but
We actually want to valid display mode on connector getmode time,
mode_fixup can't do it.

So add a private mode_valid callback to rockchip crtc, connectors can
check mode with this mode_valid callback.

Signed-off-by: Mark Yao 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  2 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  7 +++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 13 +
 4 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..d10b15c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -39,6 +39,8 @@
 struct rockchip_crtc_funcs {
int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc);
+   enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+  const struct drm_display_mode *mode);
 };
 
 struct rockchip_crtc_state {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index fb5f001..256fe73 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -853,9 +853,24 @@ static void vop_crtc_disable_vblank(struct drm_crtc *crtc)
spin_unlock_irqrestore(>irq_lock, flags);
 }
 
+static enum drm_mode_status
+vop_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
+{
+   struct vop *vop = to_vop(crtc);
+   const struct vop_data *vop_data = vop->data;
+
+   if (mode->hdisplay > vop_data->max_output.width)
+   return MODE_BAD_HVALUE;
+   if (mode->vdisplay > vop_data->max_output.height)
+   return MODE_BAD_VVALUE;
+
+   return MODE_OK;
+}
+
 static const struct rockchip_crtc_funcs private_crtc_funcs = {
.enable_vblank = vop_crtc_enable_vblank,
.disable_vblank = vop_crtc_disable_vblank,
+   .mode_valid = vop_crtc_mode_valid,
 };
 
 static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 1dbc526..9e9dba1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -133,6 +133,11 @@ struct vop_win_data {
enum drm_plane_type type;
 };
 
+struct vop_rect {
+   int width;
+   int height;
+};
+
 struct vop_data {
const struct vop_reg_data *init_table;
unsigned int table_size;
@@ -140,6 +145,8 @@ struct vop_data {
const struct vop_intr *intr;
const struct vop_win_data *win;
unsigned int win_size;
+   struct vop_rect max_input;
+   struct vop_rect max_output;
 };
 
 /* interrupt define */
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c 
b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 35c51f3..0c72361 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -132,6 +132,8 @@
 };
 
 static const struct vop_data rk3036_vop = {
+   .max_input = { 1920, 1080},
+   .max_output = { 1920, 1080},
.init_table = rk3036_vop_init_reg_table,
.table_size = ARRAY_SIZE(rk3036_vop_init_reg_table),
.ctrl = _ctrl_data,
@@ -273,6 +275,13 @@
 };
 
 static const struct vop_data rk3288_vop = {
+   .max_input = { 4096, 8192},
+   /*
+* TODO: rk3288 have two vop, big one support 3840x2160,
+* little one only support 2560x1600.
+* Now force use 3840x2160.
+*/
+   .max_output = { 3840, 2160},
.init_table = rk3288_init_reg_table,
.table_size = ARRAY_SIZE(rk3288_init_reg_table),
.intr = _vop_intr,
@@ -339,6 +348,8 @@
 };
 
 static const struct vop_data rk3399_vop_big = {
+   .max_input = { 4096, 8192},
+   .max_output = { 4096, 2160},
.init_table = rk3399_init_reg_table,
.table_size = ARRAY_SIZE(rk3399_init_reg_table),
.intr = _vop_intr,
@@ -358,6 +369,8 @@
 };
 
 static const struct vop_data rk3399_vop_lit = {
+   .max_input = { 4096, 8192},
+   .max_output = { 2560, 1600},
.init_table = rk3399_init_reg_table,
.table_size = ARRAY_SIZE(rk3399_init_reg_table),
.intr = _vop_intr,
-- 
1.9.1




Re: pciehp is broken from 4.10-rc1

2017-02-04 Thread Lukas Wunner
On Sat, Feb 04, 2017 at 08:22:59PM -0800, Yinghai Lu wrote:
> On Sat, Feb 4, 2017 at 3:34 PM, Lukas Wunner  wrote:
> > On Sat, Feb 04, 2017 at 01:44:34PM -0800, Yinghai Lu wrote:
> >> On Sat, Feb 4, 2017 at 10:56 AM, Lukas Wunner  wrote:
> >> > On Sat, Feb 04, 2017 at 09:12:54AM +0100, Lukas Wunner wrote:
> >> > Section 6.7.3.4 of the PCIe Base spec seems to support the theory above,
> >> > so here's a tentative patch.
> >> >
> >> > -- >8 --
> >> > Subject: [PATCH] PCI: pciehp: Don't enable PME on runtime suspend
> >>
> >> it works:
> >
> > Thanks a lot for the report and for testing the patch!
> 
> Wait, Commit 68db9bc still has problem with another server (skylake
> based), and this patch does not help.
[...]
> sca05-0a81fd8d:~ # echo 1 > /sys/bus/pci/slots/11/power
> [  375.376609] pci_hotplug: power_write_file: power = 1
> [  375.382175] pciehp :b3:00.0:pcie004: pciehp_get_power_status: SLOTCTRL 
> a8 value read 17f1
> [  375.392695] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  375.401370] pciehp :b3:00.0:pcie004: pciehp_power_on_slot: SLOTCTRL a8 
> write cmd 0
> [  375.410231] pciehp :b3:00.0:pcie004: pciehp_green_led_blink: SLOTCTRL 
> a8 write cmd 200
> [  375.411071] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  375.445222] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  377.00] pciehp :b3:00.0:pcie004: Data Link Layer Link Active not 
> set in 1000 msec
> [  378.960364] pci :b4:00.0 id reading try 50 times with interval 20 ms 
> to get 
> [  378.969406] pciehp :b3:00.0:pcie004: pciehp_check_link_status: 
> lnk_status = 5001
> [  378.978059] pciehp :b3:00.0:pcie004: link training error: status 0x5001
> [  378.985834] pciehp :b3:00.0:pcie004: Failed to check link status
> [  378.987185] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  378.987253] pciehp :b3:00.0:pcie004: pciehp_power_off_slot: SLOTCTRL 
> a8 write cmd 400
> [  380.000409] pciehp :b3:00.0:pcie004: pciehp_green_led_off: SLOTCTRL a8 
> write cmd 300
> [  380.000674] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  380.018020] pciehp :b3:00.0:pcie004: pciehp_set_attention_status: 
> SLOTCTRL a8 write cmd 40
> [  380.019053] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status

So on this Skylake machine link training fails after resuming from D3hot
to D0.

One thing that's a bit fishy is that normally the Link Disable bit is
cleared when powering on the slot.  This results in a debug message
in dmesg containg the string "lnk_ctrl = ", and that line is missing
from the output you've pasted above, suggesting that the machine is
not running a stock v4.10 kernel after all but something else.  Could
you check why this message is not printed?  Could you check with lspci
if the Link Disable bit is set before you invoke "echo 1"?

This is the call stack:
pciehp_sysfs_enable_slot()
  pciehp_enable_slot()
board_added()
  pciehp_power_on_slot()
pciehp_link_enable()
  __pciehp_link_set()

Another theory is that the link is generally unreliable on this machine
since the Link Bandwidth Management Status bit is set in the Link Status
Register ("lnk_status = 5001"), which according to the spec means:

"Hardware has changed Link speed or width to attempt to correct unreliable
Link operation, either through an LTSSM timeout or a higher level process.
This bit must be set if the Physical Layer reports a speed or width change
was initiated by the Downstream component that was not indicated as an
autonomous change."

In this case it would be good to know which hardware exactly we're dealing
with so that we might quirk it to not runtime suspend the port.  To that
end, could you attach a full dmesg log to the bugzilla entry I've created?
https://bugzilla.kernel.org/show_bug.cgi?id=193951

@Mika, Rafael: Are you aware of Skylake machines with unreliable link
training, or perhaps errata of Skylake chips related to link training
on hotplug ports?

Thanks,

Lukas


Re: pciehp is broken from 4.10-rc1

2017-02-04 Thread Lukas Wunner
On Sat, Feb 04, 2017 at 08:22:59PM -0800, Yinghai Lu wrote:
> On Sat, Feb 4, 2017 at 3:34 PM, Lukas Wunner  wrote:
> > On Sat, Feb 04, 2017 at 01:44:34PM -0800, Yinghai Lu wrote:
> >> On Sat, Feb 4, 2017 at 10:56 AM, Lukas Wunner  wrote:
> >> > On Sat, Feb 04, 2017 at 09:12:54AM +0100, Lukas Wunner wrote:
> >> > Section 6.7.3.4 of the PCIe Base spec seems to support the theory above,
> >> > so here's a tentative patch.
> >> >
> >> > -- >8 --
> >> > Subject: [PATCH] PCI: pciehp: Don't enable PME on runtime suspend
> >>
> >> it works:
> >
> > Thanks a lot for the report and for testing the patch!
> 
> Wait, Commit 68db9bc still has problem with another server (skylake
> based), and this patch does not help.
[...]
> sca05-0a81fd8d:~ # echo 1 > /sys/bus/pci/slots/11/power
> [  375.376609] pci_hotplug: power_write_file: power = 1
> [  375.382175] pciehp :b3:00.0:pcie004: pciehp_get_power_status: SLOTCTRL 
> a8 value read 17f1
> [  375.392695] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  375.401370] pciehp :b3:00.0:pcie004: pciehp_power_on_slot: SLOTCTRL a8 
> write cmd 0
> [  375.410231] pciehp :b3:00.0:pcie004: pciehp_green_led_blink: SLOTCTRL 
> a8 write cmd 200
> [  375.411071] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  375.445222] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  377.00] pciehp :b3:00.0:pcie004: Data Link Layer Link Active not 
> set in 1000 msec
> [  378.960364] pci :b4:00.0 id reading try 50 times with interval 20 ms 
> to get 
> [  378.969406] pciehp :b3:00.0:pcie004: pciehp_check_link_status: 
> lnk_status = 5001
> [  378.978059] pciehp :b3:00.0:pcie004: link training error: status 0x5001
> [  378.985834] pciehp :b3:00.0:pcie004: Failed to check link status
> [  378.987185] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  378.987253] pciehp :b3:00.0:pcie004: pciehp_power_off_slot: SLOTCTRL 
> a8 write cmd 400
> [  380.000409] pciehp :b3:00.0:pcie004: pciehp_green_led_off: SLOTCTRL a8 
> write cmd 300
> [  380.000674] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status
> [  380.018020] pciehp :b3:00.0:pcie004: pciehp_set_attention_status: 
> SLOTCTRL a8 write cmd 40
> [  380.019053] pciehp :b3:00.0:pcie004: pending interrupts 0x0010 from 
> Slot Status

So on this Skylake machine link training fails after resuming from D3hot
to D0.

One thing that's a bit fishy is that normally the Link Disable bit is
cleared when powering on the slot.  This results in a debug message
in dmesg containg the string "lnk_ctrl = ", and that line is missing
from the output you've pasted above, suggesting that the machine is
not running a stock v4.10 kernel after all but something else.  Could
you check why this message is not printed?  Could you check with lspci
if the Link Disable bit is set before you invoke "echo 1"?

This is the call stack:
pciehp_sysfs_enable_slot()
  pciehp_enable_slot()
board_added()
  pciehp_power_on_slot()
pciehp_link_enable()
  __pciehp_link_set()

Another theory is that the link is generally unreliable on this machine
since the Link Bandwidth Management Status bit is set in the Link Status
Register ("lnk_status = 5001"), which according to the spec means:

"Hardware has changed Link speed or width to attempt to correct unreliable
Link operation, either through an LTSSM timeout or a higher level process.
This bit must be set if the Physical Layer reports a speed or width change
was initiated by the Downstream component that was not indicated as an
autonomous change."

In this case it would be good to know which hardware exactly we're dealing
with so that we might quirk it to not runtime suspend the port.  To that
end, could you attach a full dmesg log to the bugzilla entry I've created?
https://bugzilla.kernel.org/show_bug.cgi?id=193951

@Mika, Rafael: Are you aware of Skylake machines with unreliable link
training, or perhaps errata of Skylake chips related to link training
on hotplug ports?

Thanks,

Lukas


Re: [PATCH v3 08/10] dmaengine: sun6i: allow build on ARM64 platforms (sun50i)

2017-02-04 Thread Vinod Koul
On Sun, Jan 29, 2017 at 10:33:29AM +0800, Icenowy Zheng wrote:
> As 64-bit Allwinner H5 SoC has the same DMA engine with H3, the DMA
> driver should be allowed to be built for ARM64, in order to make it work on 
> H5.

Applied, thanks

-- 
~Vinod


Re: [PATCH v3 08/10] dmaengine: sun6i: allow build on ARM64 platforms (sun50i)

2017-02-04 Thread Vinod Koul
On Sun, Jan 29, 2017 at 10:33:29AM +0800, Icenowy Zheng wrote:
> As 64-bit Allwinner H5 SoC has the same DMA engine with H3, the DMA
> driver should be allowed to be built for ARM64, in order to make it work on 
> H5.

Applied, thanks

-- 
~Vinod


Re: [PATCH] somedriver: remove the initialization of static pointers.

2017-02-04 Thread AbdAllah MEZITI
On Sun, 5 Feb 2017 01:29:43 +0100
Greg Kroah-Hartman  wrote:

> On Sat, Feb 04, 2017 at 08:39:21PM +0100, AbdAllah-MEZITI wrote:
> > In C a static pointer will be initialized to NULL (e.g: draft C99
> > standard $6.7.8): "If an object that has static storage duration is
> > not initialized explicitly, then:
> >  __ if it has pointer type, it is initialized to a null pointer;"
> > 
> > Signed-off-by: AbdAllah-MEZITI   
> 
> Your subject is very odd :(
> 
> And is that the correct spelling of your name that you use for legal
> documents?  If not, please fix up when you resend this.
> 
> Also, fix the line-wrapping of your changelog, and the C99 standard is
> not a "draft" anymore, it was released in 1999 :)
> 
> thanks,
> 
> greg k-h


Do not worry, this is just an answer to the Task 10 of the Eudyptula Challenge.

yes, this is the correct spelling of my name that i use for legal documents.

OK.

AbdAllah MEZITI.


Re: [PATCH] somedriver: remove the initialization of static pointers.

2017-02-04 Thread AbdAllah MEZITI
On Sun, 5 Feb 2017 01:29:43 +0100
Greg Kroah-Hartman  wrote:

> On Sat, Feb 04, 2017 at 08:39:21PM +0100, AbdAllah-MEZITI wrote:
> > In C a static pointer will be initialized to NULL (e.g: draft C99
> > standard $6.7.8): "If an object that has static storage duration is
> > not initialized explicitly, then:
> >  __ if it has pointer type, it is initialized to a null pointer;"
> > 
> > Signed-off-by: AbdAllah-MEZITI   
> 
> Your subject is very odd :(
> 
> And is that the correct spelling of your name that you use for legal
> documents?  If not, please fix up when you resend this.
> 
> Also, fix the line-wrapping of your changelog, and the C99 standard is
> not a "draft" anymore, it was released in 1999 :)
> 
> thanks,
> 
> greg k-h


Do not worry, this is just an answer to the Task 10 of the Eudyptula Challenge.

yes, this is the correct spelling of my name that i use for legal documents.

OK.

AbdAllah MEZITI.


[PATCH 2/2] staging: vchip_shim: Remove unneeded stddef.h include

2017-02-04 Thread Stafford Horne
Building on openrisc musl toolchain this causes the allyesconfig build
to fail.

  drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c:42:20:
  fatal error: stddef.h: No such file or directory

Removing this causes no issues with the build.

Signed-off-by: Stafford Horne 
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
index d977139..70c530c 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
@@ -39,8 +39,6 @@
 
 #include "vchiq_util.h"
 
-#include 
-
 #define vchiq_status_to_vchi(status) ((int32_t)status)
 
 typedef struct {
-- 
2.9.3



[PATCH 1/2] libceph: Remove unneeded stddef.h include

2017-02-04 Thread Stafford Horne
This was causing a build failure for openrisc when using musl and
gcc 5.4.0 since the file is not available in the toolchain.

It doesnt seem this is needed and removing it does not cause any build
warnings for me.

Signed-off-by: Stafford Horne 
---
 net/ceph/snapshot.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/net/ceph/snapshot.c b/net/ceph/snapshot.c
index 154683f..705414e 100644
--- a/net/ceph/snapshot.c
+++ b/net/ceph/snapshot.c
@@ -18,8 +18,6 @@
  * 02110-1301, USA.
  */
 
-#include 
-
 #include 
 #include 
 #include 
-- 
2.9.3



[PATCH 1/2] libceph: Remove unneeded stddef.h include

2017-02-04 Thread Stafford Horne
This was causing a build failure for openrisc when using musl and
gcc 5.4.0 since the file is not available in the toolchain.

It doesnt seem this is needed and removing it does not cause any build
warnings for me.

Signed-off-by: Stafford Horne 
---
 net/ceph/snapshot.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/net/ceph/snapshot.c b/net/ceph/snapshot.c
index 154683f..705414e 100644
--- a/net/ceph/snapshot.c
+++ b/net/ceph/snapshot.c
@@ -18,8 +18,6 @@
  * 02110-1301, USA.
  */
 
-#include 
-
 #include 
 #include 
 #include 
-- 
2.9.3



[PATCH 2/2] staging: vchip_shim: Remove unneeded stddef.h include

2017-02-04 Thread Stafford Horne
Building on openrisc musl toolchain this causes the allyesconfig build
to fail.

  drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c:42:20:
  fatal error: stddef.h: No such file or directory

Removing this causes no issues with the build.

Signed-off-by: Stafford Horne 
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
index d977139..70c530c 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
@@ -39,8 +39,6 @@
 
 #include "vchiq_util.h"
 
-#include 
-
 #define vchiq_status_to_vchi(status) ((int32_t)status)
 
 typedef struct {
-- 
2.9.3



[PATCH 0/2] Remove unneeded stddef.h includes

2017-02-04 Thread Stafford Horne
Hi All,

These were causing openrisc build to fail when building with allyesconfig
using a musl toolchain.  Removing them doesnt seem to cause any issues. 

The line removed was:

  #include 

Perhaps what was wanted was 'linux/stddef.h' but there did seem to be any
special uses so I just removed it.  Also, sending these patches should help
the kbuild robots verify that.

If I can get acks I will push it in with my openrisc branch.  But if this
should got through the net and staging paths I am happy with that.

-Stafford

Stafford Horne (2):
  libceph: Remove unneeded stddef.h include
  staging: vchip_shim: Remove unneeded stddef.h include

 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c | 2 --
 net/ceph/snapshot.c| 2 --
 2 files changed, 4 deletions(-)

-- 
2.9.3



[PATCH 0/2] Remove unneeded stddef.h includes

2017-02-04 Thread Stafford Horne
Hi All,

These were causing openrisc build to fail when building with allyesconfig
using a musl toolchain.  Removing them doesnt seem to cause any issues. 

The line removed was:

  #include 

Perhaps what was wanted was 'linux/stddef.h' but there did seem to be any
special uses so I just removed it.  Also, sending these patches should help
the kbuild robots verify that.

If I can get acks I will push it in with my openrisc branch.  But if this
should got through the net and staging paths I am happy with that.

-Stafford

Stafford Horne (2):
  libceph: Remove unneeded stddef.h include
  staging: vchip_shim: Remove unneeded stddef.h include

 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c | 2 --
 net/ceph/snapshot.c| 2 --
 2 files changed, 4 deletions(-)

-- 
2.9.3



[PATCH 0/4] md: use bio_clone_fast()

2017-02-04 Thread Ming Lei
Hi,

This patches replaces bio_clone() with bio_fast_clone() in
bio_clone_mddev() because:

1) bio_clone_mddev() is used in raid normal I/O and isn't in
resync I/O path, and all the direct access to bvec table in
raid happens on resync I/O only except for write behind of raid1.
Write behind is treated specially, so the replacement is safe.

2) for write behind, bio_clone() is kept, but this patchset
introduces bio_clone_bioset_partial() to just clone one specific 
bvecs range instead of whole table. Then write behind is improved
too.


Thanks,
Ming

Ming Lei (4):
  block: introduce bio_clone_bioset_partial()
  md: introduce bio_clone_slow_mddev_partial()
  md/raid1: use bio_clone_slow_mddev_partial in case of write behind
  md: fast clone bio in bio_clone_mddev()

 block/bio.c | 61 +
 drivers/md/md.c | 24 +++--
 drivers/md/md.h |  3 +++
 drivers/md/raid1.c  | 21 +-
 include/linux/bio.h | 11 --
 5 files changed, 98 insertions(+), 22 deletions(-)

-- 
2.7.4



[PATCH 0/4] md: use bio_clone_fast()

2017-02-04 Thread Ming Lei
Hi,

This patches replaces bio_clone() with bio_fast_clone() in
bio_clone_mddev() because:

1) bio_clone_mddev() is used in raid normal I/O and isn't in
resync I/O path, and all the direct access to bvec table in
raid happens on resync I/O only except for write behind of raid1.
Write behind is treated specially, so the replacement is safe.

2) for write behind, bio_clone() is kept, but this patchset
introduces bio_clone_bioset_partial() to just clone one specific 
bvecs range instead of whole table. Then write behind is improved
too.


Thanks,
Ming

Ming Lei (4):
  block: introduce bio_clone_bioset_partial()
  md: introduce bio_clone_slow_mddev_partial()
  md/raid1: use bio_clone_slow_mddev_partial in case of write behind
  md: fast clone bio in bio_clone_mddev()

 block/bio.c | 61 +
 drivers/md/md.c | 24 +++--
 drivers/md/md.h |  3 +++
 drivers/md/raid1.c  | 21 +-
 include/linux/bio.h | 11 --
 5 files changed, 98 insertions(+), 22 deletions(-)

-- 
2.7.4



[PATCH 1/4] block: introduce bio_clone_bioset_partial()

2017-02-04 Thread Ming Lei
md still need bio clone(not the fast version) for behind write,
and it is more efficient to use bio_clone_bioset_partial().

The idea is simple and just copy the bvecs range specified from
parameters.

Signed-off-by: Ming Lei 
---
 block/bio.c | 61 +
 include/linux/bio.h | 11 --
 2 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 4b564d0c3e29..5eec5e08417f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -625,21 +625,20 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t 
gfp_mask, struct bio_set *bs)
 }
 EXPORT_SYMBOL(bio_clone_fast);
 
-/**
- * bio_clone_bioset - clone a bio
- * @bio_src: bio to clone
- * @gfp_mask: allocation priority
- * @bs: bio_set to allocate from
- *
- * Clone bio. Caller will own the returned bio, but not the actual data it
- * points to. Reference count of returned bio will be one.
- */
-struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
-struct bio_set *bs)
+static struct bio *__bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
+ struct bio_set *bs, int offset,
+ int size)
 {
struct bvec_iter iter;
struct bio_vec bv;
struct bio *bio;
+   struct bvec_iter iter_src = bio_src->bi_iter;
+
+   /* for supporting partial clone */
+   if (offset || size != bio_src->bi_iter.bi_size) {
+   bio_advance_iter(bio_src, _src, offset);
+   iter_src.bi_size = size;
+   }
 
/*
 * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
@@ -663,7 +662,8 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t 
gfp_mask,
 *__bio_clone_fast() anyways.
 */
 
-   bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
+   bio = bio_alloc_bioset(gfp_mask, __bio_segments(bio_src,
+  _src), bs);
if (!bio)
return NULL;
bio->bi_bdev= bio_src->bi_bdev;
@@ -680,7 +680,7 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t 
gfp_mask,
bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
break;
default:
-   bio_for_each_segment(bv, bio_src, iter)
+   __bio_for_each_segment(bv, bio_src, iter, iter_src)
bio->bi_io_vec[bio->bi_vcnt++] = bv;
break;
}
@@ -699,9 +699,44 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t 
gfp_mask,
 
return bio;
 }
+
+/**
+ * bio_clone_bioset - clone a bio
+ * @bio_src: bio to clone
+ * @gfp_mask: allocation priority
+ * @bs: bio_set to allocate from
+ *
+ * Clone bio. Caller will own the returned bio, but not the actual data it
+ * points to. Reference count of returned bio will be one.
+ */
+struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
+struct bio_set *bs)
+{
+   return __bio_clone_bioset(bio_src, gfp_mask, bs, 0,
+ bio_src->bi_iter.bi_size);
+}
 EXPORT_SYMBOL(bio_clone_bioset);
 
 /**
+ * bio_clone_bioset_partial - clone a partial bio
+ * @bio_src: bio to clone
+ * @gfp_mask: allocation priority
+ * @bs: bio_set to allocate from
+ * @offset: cloned starting from the offset
+ * @size: size for the cloned bio
+ *
+ * Clone bio. Caller will own the returned bio, but not the actual data it
+ * points to. Reference count of returned bio will be one.
+ */
+struct bio *bio_clone_bioset_partial(struct bio *bio_src, gfp_t gfp_mask,
+struct bio_set *bs, int offset,
+int size)
+{
+   return __bio_clone_bioset(bio_src, gfp_mask, bs, offset, size);
+}
+EXPORT_SYMBOL(bio_clone_bioset_partial);
+
+/**
  * bio_add_pc_page -   attempt to add page to bio
  * @q: the target queue
  * @bio: destination bio
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7cf8a6c70a3f..8e521194f6fc 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -183,7 +183,7 @@ static inline void bio_advance_iter(struct bio *bio, struct 
bvec_iter *iter,
 
 #define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
 
-static inline unsigned bio_segments(struct bio *bio)
+static inline unsigned __bio_segments(struct bio *bio, struct bvec_iter *bvec)
 {
unsigned segs = 0;
struct bio_vec bv;
@@ -205,12 +205,17 @@ static inline unsigned bio_segments(struct bio *bio)
break;
}
 
-   bio_for_each_segment(bv, bio, iter)
+   __bio_for_each_segment(bv, bio, iter, *bvec)
segs++;
 
return segs;
 }
 
+static inline unsigned bio_segments(struct bio *bio)
+{
+   return __bio_segments(bio, >bi_iter);
+}
+
 /*
  

[PATCH 1/4] block: introduce bio_clone_bioset_partial()

2017-02-04 Thread Ming Lei
md still need bio clone(not the fast version) for behind write,
and it is more efficient to use bio_clone_bioset_partial().

The idea is simple and just copy the bvecs range specified from
parameters.

Signed-off-by: Ming Lei 
---
 block/bio.c | 61 +
 include/linux/bio.h | 11 --
 2 files changed, 57 insertions(+), 15 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 4b564d0c3e29..5eec5e08417f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -625,21 +625,20 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t 
gfp_mask, struct bio_set *bs)
 }
 EXPORT_SYMBOL(bio_clone_fast);
 
-/**
- * bio_clone_bioset - clone a bio
- * @bio_src: bio to clone
- * @gfp_mask: allocation priority
- * @bs: bio_set to allocate from
- *
- * Clone bio. Caller will own the returned bio, but not the actual data it
- * points to. Reference count of returned bio will be one.
- */
-struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
-struct bio_set *bs)
+static struct bio *__bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
+ struct bio_set *bs, int offset,
+ int size)
 {
struct bvec_iter iter;
struct bio_vec bv;
struct bio *bio;
+   struct bvec_iter iter_src = bio_src->bi_iter;
+
+   /* for supporting partial clone */
+   if (offset || size != bio_src->bi_iter.bi_size) {
+   bio_advance_iter(bio_src, _src, offset);
+   iter_src.bi_size = size;
+   }
 
/*
 * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
@@ -663,7 +662,8 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t 
gfp_mask,
 *__bio_clone_fast() anyways.
 */
 
-   bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs);
+   bio = bio_alloc_bioset(gfp_mask, __bio_segments(bio_src,
+  _src), bs);
if (!bio)
return NULL;
bio->bi_bdev= bio_src->bi_bdev;
@@ -680,7 +680,7 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t 
gfp_mask,
bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
break;
default:
-   bio_for_each_segment(bv, bio_src, iter)
+   __bio_for_each_segment(bv, bio_src, iter, iter_src)
bio->bi_io_vec[bio->bi_vcnt++] = bv;
break;
}
@@ -699,9 +699,44 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t 
gfp_mask,
 
return bio;
 }
+
+/**
+ * bio_clone_bioset - clone a bio
+ * @bio_src: bio to clone
+ * @gfp_mask: allocation priority
+ * @bs: bio_set to allocate from
+ *
+ * Clone bio. Caller will own the returned bio, but not the actual data it
+ * points to. Reference count of returned bio will be one.
+ */
+struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
+struct bio_set *bs)
+{
+   return __bio_clone_bioset(bio_src, gfp_mask, bs, 0,
+ bio_src->bi_iter.bi_size);
+}
 EXPORT_SYMBOL(bio_clone_bioset);
 
 /**
+ * bio_clone_bioset_partial - clone a partial bio
+ * @bio_src: bio to clone
+ * @gfp_mask: allocation priority
+ * @bs: bio_set to allocate from
+ * @offset: cloned starting from the offset
+ * @size: size for the cloned bio
+ *
+ * Clone bio. Caller will own the returned bio, but not the actual data it
+ * points to. Reference count of returned bio will be one.
+ */
+struct bio *bio_clone_bioset_partial(struct bio *bio_src, gfp_t gfp_mask,
+struct bio_set *bs, int offset,
+int size)
+{
+   return __bio_clone_bioset(bio_src, gfp_mask, bs, offset, size);
+}
+EXPORT_SYMBOL(bio_clone_bioset_partial);
+
+/**
  * bio_add_pc_page -   attempt to add page to bio
  * @q: the target queue
  * @bio: destination bio
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 7cf8a6c70a3f..8e521194f6fc 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -183,7 +183,7 @@ static inline void bio_advance_iter(struct bio *bio, struct 
bvec_iter *iter,
 
 #define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)
 
-static inline unsigned bio_segments(struct bio *bio)
+static inline unsigned __bio_segments(struct bio *bio, struct bvec_iter *bvec)
 {
unsigned segs = 0;
struct bio_vec bv;
@@ -205,12 +205,17 @@ static inline unsigned bio_segments(struct bio *bio)
break;
}
 
-   bio_for_each_segment(bv, bio, iter)
+   __bio_for_each_segment(bv, bio, iter, *bvec)
segs++;
 
return segs;
 }
 
+static inline unsigned bio_segments(struct bio *bio)
+{
+   return __bio_segments(bio, >bi_iter);
+}
+
 /*
  * get a reference to a 

[PATCH 2/4] md: introduce bio_clone_slow_mddev_partial()

2017-02-04 Thread Ming Lei
In raid1/raid10, most users of bio_clone_mddev() need bio_trim() too,
that means only part of the bio is required to be cloned, and not
necessary to clone the whole bio each time, and it is just enough
to clone the specified bvecs range.

So this patch introduces bio_clone_slow_mddev_partial() to improve
the situation, and it is named as slow because the following patch
will switch to bio_clone_fast() in bio_clone_mddev().

Signed-off-by: Ming Lei 
---
 drivers/md/md.c | 16 
 drivers/md/md.h |  3 +++
 2 files changed, 19 insertions(+)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4c1b82defa78..704be11355a9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -200,6 +200,22 @@ struct bio *bio_clone_mddev(struct bio *bio, gfp_t 
gfp_mask,
 }
 EXPORT_SYMBOL_GPL(bio_clone_mddev);
 
+struct bio *bio_clone_slow_mddev_partial(struct bio *bio, gfp_t gfp_mask,
+struct mddev *mddev, int offset,
+int size)
+{
+   struct bio_set *bs;
+
+   if (!mddev || !mddev->bio_set)
+   bs = fs_bio_set;
+   else
+   bs = mddev->bio_set;
+
+   return bio_clone_bioset_partial(bio, gfp_mask, bs, offset << 9,
+   size << 9);
+}
+EXPORT_SYMBOL_GPL(bio_clone_slow_mddev_partial);
+
 /*
  * We have a system wide 'event count' that is incremented
  * on any 'interesting' event, and readers of /proc/mdstat
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 968bbe72b237..4f4e6ded59e5 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -675,6 +675,9 @@ extern void mddev_suspend(struct mddev *mddev);
 extern void mddev_resume(struct mddev *mddev);
 extern struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
   struct mddev *mddev);
+extern struct bio *bio_clone_slow_mddev_partial(struct bio *bio, gfp_t 
gfp_mask,
+   struct mddev *mddev, int offset,
+   int size);
 extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
   struct mddev *mddev);
 
-- 
2.7.4



[PATCH 2/4] md: introduce bio_clone_slow_mddev_partial()

2017-02-04 Thread Ming Lei
In raid1/raid10, most users of bio_clone_mddev() need bio_trim() too,
that means only part of the bio is required to be cloned, and not
necessary to clone the whole bio each time, and it is just enough
to clone the specified bvecs range.

So this patch introduces bio_clone_slow_mddev_partial() to improve
the situation, and it is named as slow because the following patch
will switch to bio_clone_fast() in bio_clone_mddev().

Signed-off-by: Ming Lei 
---
 drivers/md/md.c | 16 
 drivers/md/md.h |  3 +++
 2 files changed, 19 insertions(+)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4c1b82defa78..704be11355a9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -200,6 +200,22 @@ struct bio *bio_clone_mddev(struct bio *bio, gfp_t 
gfp_mask,
 }
 EXPORT_SYMBOL_GPL(bio_clone_mddev);
 
+struct bio *bio_clone_slow_mddev_partial(struct bio *bio, gfp_t gfp_mask,
+struct mddev *mddev, int offset,
+int size)
+{
+   struct bio_set *bs;
+
+   if (!mddev || !mddev->bio_set)
+   bs = fs_bio_set;
+   else
+   bs = mddev->bio_set;
+
+   return bio_clone_bioset_partial(bio, gfp_mask, bs, offset << 9,
+   size << 9);
+}
+EXPORT_SYMBOL_GPL(bio_clone_slow_mddev_partial);
+
 /*
  * We have a system wide 'event count' that is incremented
  * on any 'interesting' event, and readers of /proc/mdstat
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 968bbe72b237..4f4e6ded59e5 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -675,6 +675,9 @@ extern void mddev_suspend(struct mddev *mddev);
 extern void mddev_resume(struct mddev *mddev);
 extern struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
   struct mddev *mddev);
+extern struct bio *bio_clone_slow_mddev_partial(struct bio *bio, gfp_t 
gfp_mask,
+   struct mddev *mddev, int offset,
+   int size);
 extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
   struct mddev *mddev);
 
-- 
2.7.4



[PATCH 4/4] md: fast clone bio in bio_clone_mddev()

2017-02-04 Thread Ming Lei
Firstly bio_clone_mddev() is used in raid normal I/O and isn't
in resync I/O path.

Secondly all the direct access to bvec table in raid happens on
resync I/O except for write behind of raid1, in which we still
use bio_clone() for allocating new bvec table.

So this patch replaces bio_clone() with bio_clone_fast()
in bio_clone_mddev().

Signed-off-by: Ming Lei 
---
 drivers/md/md.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 704be11355a9..7d176f025add 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -193,10 +193,14 @@ EXPORT_SYMBOL_GPL(bio_alloc_mddev);
 struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
struct mddev *mddev)
 {
+   struct bio_set *bs;
+
if (!mddev || !mddev->bio_set)
-   return bio_clone(bio, gfp_mask);
+   bs = fs_bio_set;
+   else
+   bs = mddev->bio_set;
 
-   return bio_clone_bioset(bio, gfp_mask, mddev->bio_set);
+   return bio_clone_fast(bio, gfp_mask, bs);
 }
 EXPORT_SYMBOL_GPL(bio_clone_mddev);
 
-- 
2.7.4



[PATCH 3/4] md/raid1: use bio_clone_slow_mddev_partial in case of write behind

2017-02-04 Thread Ming Lei
Write behind need to replace pages in bio's bvecs, and we have
to clone a fresh bio with new bvec table, so use the introduced
bio_clone_slow_mddev_partial() for it.

For other bio_clone_mddev() cases, we will use fast clone since
they don't need to touch bvec table.

Signed-off-by: Ming Lei 
---
 drivers/md/raid1.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 830ff2b20346..e1c5639febdb 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1341,13 +1341,12 @@ static void raid1_write_request(struct mddev *mddev, 
struct bio *bio,
 
first_clone = 1;
for (i = 0; i < disks; i++) {
-   struct bio *mbio;
+   struct bio *mbio = NULL;
+   int offset;
if (!r1_bio->bios[i])
continue;
 
-   mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-   bio_trim(mbio, r1_bio->sector - bio->bi_iter.bi_sector,
-max_sectors);
+   offset = r1_bio->sector - bio->bi_iter.bi_sector;
 
if (first_clone) {
/* do behind I/O ?
@@ -1357,8 +1356,14 @@ static void raid1_write_request(struct mddev *mddev, 
struct bio *bio,
if (bitmap &&
(atomic_read(>behind_writes)
 < mddev->bitmap_info.max_write_behind) &&
-   !waitqueue_active(>behind_wait))
+   !waitqueue_active(>behind_wait)) {
+   mbio = bio_clone_slow_mddev_partial(bio,
+   GFP_NOIO,
+   mddev,
+   offset,
+   
max_sectors);
alloc_behind_pages(mbio, r1_bio);
+   }
 
bitmap_startwrite(bitmap, r1_bio->sector,
  r1_bio->sectors,
@@ -1366,6 +1371,12 @@ static void raid1_write_request(struct mddev *mddev, 
struct bio *bio,
   _bio->state));
first_clone = 0;
}
+
+   if (!mbio) {
+   mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+   bio_trim(mbio, offset, max_sectors);
+   }
+
if (r1_bio->behind_bvecs) {
struct bio_vec *bvec;
int j;
-- 
2.7.4



[PATCH 4/4] md: fast clone bio in bio_clone_mddev()

2017-02-04 Thread Ming Lei
Firstly bio_clone_mddev() is used in raid normal I/O and isn't
in resync I/O path.

Secondly all the direct access to bvec table in raid happens on
resync I/O except for write behind of raid1, in which we still
use bio_clone() for allocating new bvec table.

So this patch replaces bio_clone() with bio_clone_fast()
in bio_clone_mddev().

Signed-off-by: Ming Lei 
---
 drivers/md/md.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 704be11355a9..7d176f025add 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -193,10 +193,14 @@ EXPORT_SYMBOL_GPL(bio_alloc_mddev);
 struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
struct mddev *mddev)
 {
+   struct bio_set *bs;
+
if (!mddev || !mddev->bio_set)
-   return bio_clone(bio, gfp_mask);
+   bs = fs_bio_set;
+   else
+   bs = mddev->bio_set;
 
-   return bio_clone_bioset(bio, gfp_mask, mddev->bio_set);
+   return bio_clone_fast(bio, gfp_mask, bs);
 }
 EXPORT_SYMBOL_GPL(bio_clone_mddev);
 
-- 
2.7.4



[PATCH 3/4] md/raid1: use bio_clone_slow_mddev_partial in case of write behind

2017-02-04 Thread Ming Lei
Write behind need to replace pages in bio's bvecs, and we have
to clone a fresh bio with new bvec table, so use the introduced
bio_clone_slow_mddev_partial() for it.

For other bio_clone_mddev() cases, we will use fast clone since
they don't need to touch bvec table.

Signed-off-by: Ming Lei 
---
 drivers/md/raid1.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 830ff2b20346..e1c5639febdb 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1341,13 +1341,12 @@ static void raid1_write_request(struct mddev *mddev, 
struct bio *bio,
 
first_clone = 1;
for (i = 0; i < disks; i++) {
-   struct bio *mbio;
+   struct bio *mbio = NULL;
+   int offset;
if (!r1_bio->bios[i])
continue;
 
-   mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
-   bio_trim(mbio, r1_bio->sector - bio->bi_iter.bi_sector,
-max_sectors);
+   offset = r1_bio->sector - bio->bi_iter.bi_sector;
 
if (first_clone) {
/* do behind I/O ?
@@ -1357,8 +1356,14 @@ static void raid1_write_request(struct mddev *mddev, 
struct bio *bio,
if (bitmap &&
(atomic_read(>behind_writes)
 < mddev->bitmap_info.max_write_behind) &&
-   !waitqueue_active(>behind_wait))
+   !waitqueue_active(>behind_wait)) {
+   mbio = bio_clone_slow_mddev_partial(bio,
+   GFP_NOIO,
+   mddev,
+   offset,
+   
max_sectors);
alloc_behind_pages(mbio, r1_bio);
+   }
 
bitmap_startwrite(bitmap, r1_bio->sector,
  r1_bio->sectors,
@@ -1366,6 +1371,12 @@ static void raid1_write_request(struct mddev *mddev, 
struct bio *bio,
   _bio->state));
first_clone = 0;
}
+
+   if (!mbio) {
+   mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+   bio_trim(mbio, offset, max_sectors);
+   }
+
if (r1_bio->behind_bvecs) {
struct bio_vec *bvec;
int j;
-- 
2.7.4



Re: [PATCH 5/6] dmaengine: Add Broadcom SBA RAID driver

2017-02-04 Thread Vinod Koul
On Thu, Feb 02, 2017 at 10:17:15AM +0530, Anup Patel wrote:
> +config BCM_SBA_RAID
> +tristate "Broadcom SBA RAID engine support"
> +depends on (ARM64 && MAILBOX && RAID6_PQ) || COMPILE_TEST
> +select DMA_ENGINE
> +select DMA_ENGINE_RAID
> + select ASYNC_TX_ENABLE_CHANNEL_SWITCH
> + default ARCH_BCM_IPROC

whats with the funny alignement?

> +/* SBA command related defines */
> +#define SBA_TYPE_SHIFT   48
> +#define SBA_TYPE_MASK0x3
> +#define SBA_TYPE_A   0x0
> +#define SBA_TYPE_B   0x2
> +#define SBA_TYPE_C   0x3
> +#define SBA_USER_DEF_SHIFT   32
> +#define SBA_USER_DEF_MASK0x
> +#define SBA_R_MDATA_SHIFT24
> +#define SBA_R_MDATA_MASK 0xff
> +#define SBA_C_MDATA_MS_SHIFT 18
> +#define SBA_C_MDATA_MS_MASK  0x3
> +#define SBA_INT_SHIFT17
> +#define SBA_INT_MASK 0x1
> +#define SBA_RESP_SHIFT   16
> +#define SBA_RESP_MASK0x1
> +#define SBA_C_MDATA_SHIFT8
> +#define SBA_C_MDATA_MASK 0xff
> +#define SBA_CMD_SHIFT0
> +#define SBA_CMD_MASK 0xf
> +#define SBA_CMD_ZERO_ALL_BUFFERS 0x8
> +#define SBA_CMD_LOAD_BUFFER  0x9
> +#define SBA_CMD_XOR  0xa
> +#define SBA_CMD_GALOIS_XOR   0xb
> +#define SBA_CMD_ZERO_BUFFER  0x4
> +#define SBA_CMD_WRITE_BUFFER 0xc

Try using BIT and GENMAST for hardware descriptions

> +
> +/* SBA C_MDATA helper macros */
> +#define SBA_C_MDATA_LOAD_VAL(__bnum0)((__bnum0) & 0x3)
> +#define SBA_C_MDATA_WRITE_VAL(__bnum0)   ((__bnum0) & 0x3)
> +#define SBA_C_MDATA_XOR_VAL(__bnum1, __bnum0)\
> + ({  u32 __v = ((__bnum0) & 0x3);\
> + __v |= ((__bnum1) & 0x3) << 2;  \
> + __v;\
> + })
> +#define SBA_C_MDATA_PQ_VAL(__dnum, __bnum1, __bnum0) \
> + ({  u32 __v = ((__bnum0) & 0x3);\
> + __v |= ((__bnum1) & 0x3) << 2;  \
> + __v |= ((__dnum) & 0x1f) << 5;  \
> + __v;\
> + })

ah why are we usig complex macros, why can't these be simple functions..

> +#define SBA_C_MDATA_LS(__c_mdata_val)((__c_mdata_val) & 0xff)
> +#define SBA_C_MDATA_MS(__c_mdata_val)(((__c_mdata_val) >> 8) & 0x3)
> +
> +/* Driver helper macros */
> +#define to_sba_request(tx)   \
> + container_of(tx, struct sba_request, tx)
> +#define to_sba_device(dchan) \
> + container_of(dchan, struct sba_device, dma_chan)
> +
> +enum sba_request_state {
> + SBA_REQUEST_STATE_FREE = 1,
> + SBA_REQUEST_STATE_ALLOCED = 2,
> + SBA_REQUEST_STATE_PENDING = 3,
> + SBA_REQUEST_STATE_ACTIVE = 4,
> + SBA_REQUEST_STATE_COMPLETED = 5,
> + SBA_REQUEST_STATE_ABORTED = 6,

whats up with a very funny indentation setting, we use 8 chars.

Please re-read the Documentation/process/coding-style.rst

> +static int sba_alloc_chan_resources(struct dma_chan *dchan)
> +{
> + /*
> +  * We only have one channel so we have pre-alloced
> +  * channel resources. Over here we just return number
> +  * of free request.
> +  */
> + return sba_free_request_count(to_sba_device(dchan));
> +}

essentially you are not doing much, so you can skip it. Its an optional
call.

> +static void sba_free_chan_resources(struct dma_chan *dchan)
> +{
> + /*
> +  * Channel resources are pre-alloced so we just free-up
> +  * whatever we can so that we can re-use pre-alloced
> +  * channel resources next time.
> +  */
> + sba_cleanup_inflight_requests(to_sba_device(dchan));

well this one checks for pending requests as well, which shouldn't be there
when freeing a channel, something seems not quite right here..

> +static int sba_send_mbox_request(struct sba_device *sba,
> +  struct sba_request *req)
> +{
> + int mchans_idx, ret = 0;
> +
> + /* Select mailbox channel in round-robin fashion */
> + mchans_idx = atomic_inc_return(>mchans_current);
> + mchans_idx = mchans_idx % sba->mchans_count;
> +
> + /* Send batch message for the request */
> + req->bmsg.batch.msgs_queued = 0;
> + ret = 

Re: [PATCH 5/6] dmaengine: Add Broadcom SBA RAID driver

2017-02-04 Thread Vinod Koul
On Thu, Feb 02, 2017 at 10:17:15AM +0530, Anup Patel wrote:
> +config BCM_SBA_RAID
> +tristate "Broadcom SBA RAID engine support"
> +depends on (ARM64 && MAILBOX && RAID6_PQ) || COMPILE_TEST
> +select DMA_ENGINE
> +select DMA_ENGINE_RAID
> + select ASYNC_TX_ENABLE_CHANNEL_SWITCH
> + default ARCH_BCM_IPROC

whats with the funny alignement?

> +/* SBA command related defines */
> +#define SBA_TYPE_SHIFT   48
> +#define SBA_TYPE_MASK0x3
> +#define SBA_TYPE_A   0x0
> +#define SBA_TYPE_B   0x2
> +#define SBA_TYPE_C   0x3
> +#define SBA_USER_DEF_SHIFT   32
> +#define SBA_USER_DEF_MASK0x
> +#define SBA_R_MDATA_SHIFT24
> +#define SBA_R_MDATA_MASK 0xff
> +#define SBA_C_MDATA_MS_SHIFT 18
> +#define SBA_C_MDATA_MS_MASK  0x3
> +#define SBA_INT_SHIFT17
> +#define SBA_INT_MASK 0x1
> +#define SBA_RESP_SHIFT   16
> +#define SBA_RESP_MASK0x1
> +#define SBA_C_MDATA_SHIFT8
> +#define SBA_C_MDATA_MASK 0xff
> +#define SBA_CMD_SHIFT0
> +#define SBA_CMD_MASK 0xf
> +#define SBA_CMD_ZERO_ALL_BUFFERS 0x8
> +#define SBA_CMD_LOAD_BUFFER  0x9
> +#define SBA_CMD_XOR  0xa
> +#define SBA_CMD_GALOIS_XOR   0xb
> +#define SBA_CMD_ZERO_BUFFER  0x4
> +#define SBA_CMD_WRITE_BUFFER 0xc

Try using BIT and GENMAST for hardware descriptions

> +
> +/* SBA C_MDATA helper macros */
> +#define SBA_C_MDATA_LOAD_VAL(__bnum0)((__bnum0) & 0x3)
> +#define SBA_C_MDATA_WRITE_VAL(__bnum0)   ((__bnum0) & 0x3)
> +#define SBA_C_MDATA_XOR_VAL(__bnum1, __bnum0)\
> + ({  u32 __v = ((__bnum0) & 0x3);\
> + __v |= ((__bnum1) & 0x3) << 2;  \
> + __v;\
> + })
> +#define SBA_C_MDATA_PQ_VAL(__dnum, __bnum1, __bnum0) \
> + ({  u32 __v = ((__bnum0) & 0x3);\
> + __v |= ((__bnum1) & 0x3) << 2;  \
> + __v |= ((__dnum) & 0x1f) << 5;  \
> + __v;\
> + })

ah why are we usig complex macros, why can't these be simple functions..

> +#define SBA_C_MDATA_LS(__c_mdata_val)((__c_mdata_val) & 0xff)
> +#define SBA_C_MDATA_MS(__c_mdata_val)(((__c_mdata_val) >> 8) & 0x3)
> +
> +/* Driver helper macros */
> +#define to_sba_request(tx)   \
> + container_of(tx, struct sba_request, tx)
> +#define to_sba_device(dchan) \
> + container_of(dchan, struct sba_device, dma_chan)
> +
> +enum sba_request_state {
> + SBA_REQUEST_STATE_FREE = 1,
> + SBA_REQUEST_STATE_ALLOCED = 2,
> + SBA_REQUEST_STATE_PENDING = 3,
> + SBA_REQUEST_STATE_ACTIVE = 4,
> + SBA_REQUEST_STATE_COMPLETED = 5,
> + SBA_REQUEST_STATE_ABORTED = 6,

whats up with a very funny indentation setting, we use 8 chars.

Please re-read the Documentation/process/coding-style.rst

> +static int sba_alloc_chan_resources(struct dma_chan *dchan)
> +{
> + /*
> +  * We only have one channel so we have pre-alloced
> +  * channel resources. Over here we just return number
> +  * of free request.
> +  */
> + return sba_free_request_count(to_sba_device(dchan));
> +}

essentially you are not doing much, so you can skip it. Its an optional
call.

> +static void sba_free_chan_resources(struct dma_chan *dchan)
> +{
> + /*
> +  * Channel resources are pre-alloced so we just free-up
> +  * whatever we can so that we can re-use pre-alloced
> +  * channel resources next time.
> +  */
> + sba_cleanup_inflight_requests(to_sba_device(dchan));

well this one checks for pending requests as well, which shouldn't be there
when freeing a channel, something seems not quite right here..

> +static int sba_send_mbox_request(struct sba_device *sba,
> +  struct sba_request *req)
> +{
> + int mchans_idx, ret = 0;
> +
> + /* Select mailbox channel in round-robin fashion */
> + mchans_idx = atomic_inc_return(>mchans_current);
> + mchans_idx = mchans_idx % sba->mchans_count;
> +
> + /* Send batch message for the request */
> + req->bmsg.batch.msgs_queued = 0;
> + ret = 

Re: pciehp is broken from 4.10-rc1

2017-02-04 Thread Yinghai Lu
On Sat, Feb 4, 2017 at 8:22 PM, Yinghai Lu  wrote:
> On Sat, Feb 4, 2017 at 3:34 PM, Lukas Wunner  wrote:
>> On Sat, Feb 04, 2017 at 01:44:34PM -0800, Yinghai Lu wrote:
>>> On Sat, Feb 4, 2017 at 10:56 AM, Lukas Wunner  wrote:
>>> > On Sat, Feb 04, 2017 at 09:12:54AM +0100, Lukas Wunner wrote:
>>> > Section 6.7.3.4 of the PCIe Base spec seems to support the theory above,
>>> > so here's a tentative patch.
>>> >
>>> >
>>> > -- >8 --
>>> > Subject: [PATCH] PCI: pciehp: Don't enable PME on runtime suspend
>>>
>>> it works:
>>
>> Thanks a lot for the report and for testing the patch!
>
> Wait, Commit 68db9bc still has problem with another server (skylake
> based), and this patch does not help.
>
>
> sca05-0a81fd8d:~ # echo 0 > /sys/bus/pci/slots/11/power
> [  362.721197] pci_hotplug: power_write_file: power = 0
> [  362.726887] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
> SLOTCTRL a8 value read 11f1
> [  362.736431] pciehp :b3:00.0:pcie004: pciehp_unconfigure_device:
> domain:bus:dev = :b4:00
> [  362.746160] mlx4_core :b4:00.0: PME# disabled
> [  364.494033] pcieport :b3:00.0:   root_bridge ACPI_HANDLE
> 9e56b8811550 : pci:b3
> [  364.503274] pcieport :b3:00.0:  pciehp is native
> [  364.508863] pci :b4:00.0: freeing pci_dev info
> [  364.514718] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  364.523443] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
> SLOTCTRL a8 write cmd 400
> [  364.587047] pciehp :b3:00.0:pcie004: pending interrupts 0x0108
> from Slot Status
> [  364.595592] pciehp :b3:00.0:pcie004: Slot(11): Link Down
> [  364.602325] pciehp :b3:00.0:pcie004: Slot(11): Link Down event
> ignored; already powering off
> [  365.568415] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
> SLOTCTRL a8 write cmd 300
> [  365.569338] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
>
> sca05-0a81fd8d:~ # echo 1 > /sys/bus/pci/slots/11/power
> [  375.376609] pci_hotplug: power_write_file: power = 1
> [  375.382175] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
> SLOTCTRL a8 value read 17f1
> [  375.392695] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  375.401370] pciehp :b3:00.0:pcie004: pciehp_power_on_slot:
> SLOTCTRL a8 write cmd 0
> [  375.410231] pciehp :b3:00.0:pcie004: pciehp_green_led_blink:
> SLOTCTRL a8 write cmd 200
> [  375.411071] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  375.445222] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  377.00] pciehp :b3:00.0:pcie004: Data Link Layer Link
> Active not set in 1000 msec
> [  378.960364] pci :b4:00.0 id reading try 50 times with interval
> 20 ms to get 
> [  378.969406] pciehp :b3:00.0:pcie004: pciehp_check_link_status:
> lnk_status = 5001
> [  378.978059] pciehp :b3:00.0:pcie004: link training error: status 0x5001
> [  378.985834] pciehp :b3:00.0:pcie004: Failed to check link status
> [  378.987185] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  378.987253] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
> SLOTCTRL a8 write cmd 400
> [  380.000409] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
> SLOTCTRL a8 write cmd 300
> [  380.000674] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  380.018020] pciehp :b3:00.0:pcie004:
> pciehp_set_attention_status: SLOTCTRL a8 write cmd 40
> [  380.019053] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> -bash: echo: write error: Operation not permitted
>
> revert commit 68db9bc, also make it working again.

output after reverting 68db9bc

sca05-0a81fd8d:~ # echo 0 > /sys/bus/pci/slots/11/power
[  359.966115] pci_hotplug: power_write_file: power = 0
[  359.971759] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
SLOTCTRL a8 value read 11f1
[  359.981284] pciehp :b3:00.0:pcie004: pciehp_unconfigure_device:
domain:bus:dev = :b4:00
[  359.991017] mlx4_core :b4:00.0: PME# disabled
[  361.579571] pci :b4:00.0: freeing pci_dev info
[  361.585390] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  361.594116] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
SLOTCTRL a8 write cmd 400
[  361.657705] pciehp :b3:00.0:pcie004: pending interrupts 0x0108
from Slot Status
[  361.666268] pciehp :b3:00.0:pcie004: Slot(11): Link Down
[  361.673076] pciehp :b3:00.0:pcie004: Slot(11): Link Down event
ignored; already powering off
[  362.621894] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
SLOTCTRL a8 write cmd 300
[  362.622499] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
sca05-0a81fd8d:~ #
sca05-0a81fd8d:~ # echo 1 > /sys/bus/pci/slots/11/power
[  368.797970] pci_hotplug: power_write_file: power = 1
[  368.803544] pciehp 

Re: pciehp is broken from 4.10-rc1

2017-02-04 Thread Yinghai Lu
On Sat, Feb 4, 2017 at 8:22 PM, Yinghai Lu  wrote:
> On Sat, Feb 4, 2017 at 3:34 PM, Lukas Wunner  wrote:
>> On Sat, Feb 04, 2017 at 01:44:34PM -0800, Yinghai Lu wrote:
>>> On Sat, Feb 4, 2017 at 10:56 AM, Lukas Wunner  wrote:
>>> > On Sat, Feb 04, 2017 at 09:12:54AM +0100, Lukas Wunner wrote:
>>> > Section 6.7.3.4 of the PCIe Base spec seems to support the theory above,
>>> > so here's a tentative patch.
>>> >
>>> >
>>> > -- >8 --
>>> > Subject: [PATCH] PCI: pciehp: Don't enable PME on runtime suspend
>>>
>>> it works:
>>
>> Thanks a lot for the report and for testing the patch!
>
> Wait, Commit 68db9bc still has problem with another server (skylake
> based), and this patch does not help.
>
>
> sca05-0a81fd8d:~ # echo 0 > /sys/bus/pci/slots/11/power
> [  362.721197] pci_hotplug: power_write_file: power = 0
> [  362.726887] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
> SLOTCTRL a8 value read 11f1
> [  362.736431] pciehp :b3:00.0:pcie004: pciehp_unconfigure_device:
> domain:bus:dev = :b4:00
> [  362.746160] mlx4_core :b4:00.0: PME# disabled
> [  364.494033] pcieport :b3:00.0:   root_bridge ACPI_HANDLE
> 9e56b8811550 : pci:b3
> [  364.503274] pcieport :b3:00.0:  pciehp is native
> [  364.508863] pci :b4:00.0: freeing pci_dev info
> [  364.514718] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  364.523443] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
> SLOTCTRL a8 write cmd 400
> [  364.587047] pciehp :b3:00.0:pcie004: pending interrupts 0x0108
> from Slot Status
> [  364.595592] pciehp :b3:00.0:pcie004: Slot(11): Link Down
> [  364.602325] pciehp :b3:00.0:pcie004: Slot(11): Link Down event
> ignored; already powering off
> [  365.568415] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
> SLOTCTRL a8 write cmd 300
> [  365.569338] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
>
> sca05-0a81fd8d:~ # echo 1 > /sys/bus/pci/slots/11/power
> [  375.376609] pci_hotplug: power_write_file: power = 1
> [  375.382175] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
> SLOTCTRL a8 value read 17f1
> [  375.392695] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  375.401370] pciehp :b3:00.0:pcie004: pciehp_power_on_slot:
> SLOTCTRL a8 write cmd 0
> [  375.410231] pciehp :b3:00.0:pcie004: pciehp_green_led_blink:
> SLOTCTRL a8 write cmd 200
> [  375.411071] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  375.445222] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  377.00] pciehp :b3:00.0:pcie004: Data Link Layer Link
> Active not set in 1000 msec
> [  378.960364] pci :b4:00.0 id reading try 50 times with interval
> 20 ms to get 
> [  378.969406] pciehp :b3:00.0:pcie004: pciehp_check_link_status:
> lnk_status = 5001
> [  378.978059] pciehp :b3:00.0:pcie004: link training error: status 0x5001
> [  378.985834] pciehp :b3:00.0:pcie004: Failed to check link status
> [  378.987185] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  378.987253] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
> SLOTCTRL a8 write cmd 400
> [  380.000409] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
> SLOTCTRL a8 write cmd 300
> [  380.000674] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> [  380.018020] pciehp :b3:00.0:pcie004:
> pciehp_set_attention_status: SLOTCTRL a8 write cmd 40
> [  380.019053] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
> from Slot Status
> -bash: echo: write error: Operation not permitted
>
> revert commit 68db9bc, also make it working again.

output after reverting 68db9bc

sca05-0a81fd8d:~ # echo 0 > /sys/bus/pci/slots/11/power
[  359.966115] pci_hotplug: power_write_file: power = 0
[  359.971759] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
SLOTCTRL a8 value read 11f1
[  359.981284] pciehp :b3:00.0:pcie004: pciehp_unconfigure_device:
domain:bus:dev = :b4:00
[  359.991017] mlx4_core :b4:00.0: PME# disabled
[  361.579571] pci :b4:00.0: freeing pci_dev info
[  361.585390] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  361.594116] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
SLOTCTRL a8 write cmd 400
[  361.657705] pciehp :b3:00.0:pcie004: pending interrupts 0x0108
from Slot Status
[  361.666268] pciehp :b3:00.0:pcie004: Slot(11): Link Down
[  361.673076] pciehp :b3:00.0:pcie004: Slot(11): Link Down event
ignored; already powering off
[  362.621894] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
SLOTCTRL a8 write cmd 300
[  362.622499] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
sca05-0a81fd8d:~ #
sca05-0a81fd8d:~ # echo 1 > /sys/bus/pci/slots/11/power
[  368.797970] pci_hotplug: power_write_file: power = 1
[  368.803544] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
SLOTCTRL a8 

Re: [PATCH v9 2/3] MAINTAINERS: add zx2967 watchdog controller driver to ARM ZTE architecture

2017-02-04 Thread Shawn Guo
Hi Guenter,

On Sat, Feb 04, 2017 at 08:29:27PM -0800, Guenter Roeck wrote:
> Yes. One of the problems is that the patch doesn't apply to my tree
> (which is based on v4.10-rc3), and it doesn't have a common anchestor,
> meaning it is most likely not based on mainline. I would prefer to avoid
> conflicts with the arm tree if possible.

Understood.  You only need to handle patch #1 and #3, and we will sort
out MAINTAINERS update separately.  Thanks.

Shawn


Re: [PATCH v9 2/3] MAINTAINERS: add zx2967 watchdog controller driver to ARM ZTE architecture

2017-02-04 Thread Shawn Guo
Hi Guenter,

On Sat, Feb 04, 2017 at 08:29:27PM -0800, Guenter Roeck wrote:
> Yes. One of the problems is that the patch doesn't apply to my tree
> (which is based on v4.10-rc3), and it doesn't have a common anchestor,
> meaning it is most likely not based on mainline. I would prefer to avoid
> conflicts with the arm tree if possible.

Understood.  You only need to handle patch #1 and #3, and we will sort
out MAINTAINERS update separately.  Thanks.

Shawn


Re: [PATCH v9 2/3] MAINTAINERS: add zx2967 watchdog controller driver to ARM ZTE architecture

2017-02-04 Thread Guenter Roeck

On 02/04/2017 07:45 PM, Shawn Guo wrote:

Hi Baoyou,

On Sun, Feb 05, 2017 at 10:36:38AM +0800, Baoyou Xie wrote:

On 5 February 2017 at 08:05, Guenter Roeck  wrote:


On 02/03/2017 05:34 PM, Baoyou Xie wrote:


Add the zx2967 watchdog controller driver as maintained by ARM ZTE
architecture maintainers, as they're parts of the core IP.

Signed-off-by: Baoyou Xie 



Reviewed-by: Guenter Roeck 

I assume you'll submit this patch through the arm tree ?


Could you please submit all three patches through your tree? Thanks a lot
:)


Patch #2 is the only one that Guenter is concerned about, as there are
other subsystem related updates on the file.  I think Guenter's
suggestion is good, i.e. we have patch #1 and #3 go upstream through
watchdog tree, and later we update MAINTAINERS as needed via arm-soc
tree.



Yes. One of the problems is that the patch doesn't apply to my tree
(which is based on v4.10-rc3), and it doesn't have a common anchestor,
meaning it is most likely not based on mainline. I would prefer to avoid
conflicts with the arm tree if possible.

Guenter




Re: [PATCH v9 2/3] MAINTAINERS: add zx2967 watchdog controller driver to ARM ZTE architecture

2017-02-04 Thread Guenter Roeck

On 02/04/2017 07:45 PM, Shawn Guo wrote:

Hi Baoyou,

On Sun, Feb 05, 2017 at 10:36:38AM +0800, Baoyou Xie wrote:

On 5 February 2017 at 08:05, Guenter Roeck  wrote:


On 02/03/2017 05:34 PM, Baoyou Xie wrote:


Add the zx2967 watchdog controller driver as maintained by ARM ZTE
architecture maintainers, as they're parts of the core IP.

Signed-off-by: Baoyou Xie 



Reviewed-by: Guenter Roeck 

I assume you'll submit this patch through the arm tree ?


Could you please submit all three patches through your tree? Thanks a lot
:)


Patch #2 is the only one that Guenter is concerned about, as there are
other subsystem related updates on the file.  I think Guenter's
suggestion is good, i.e. we have patch #1 and #3 go upstream through
watchdog tree, and later we update MAINTAINERS as needed via arm-soc
tree.



Yes. One of the problems is that the patch doesn't apply to my tree
(which is based on v4.10-rc3), and it doesn't have a common anchestor,
meaning it is most likely not based on mainline. I would prefer to avoid
conflicts with the arm tree if possible.

Guenter




Re: pciehp is broken from 4.10-rc1

2017-02-04 Thread Yinghai Lu
On Sat, Feb 4, 2017 at 3:34 PM, Lukas Wunner  wrote:
> On Sat, Feb 04, 2017 at 01:44:34PM -0800, Yinghai Lu wrote:
>> On Sat, Feb 4, 2017 at 10:56 AM, Lukas Wunner  wrote:
>> > On Sat, Feb 04, 2017 at 09:12:54AM +0100, Lukas Wunner wrote:
>> > Section 6.7.3.4 of the PCIe Base spec seems to support the theory above,
>> > so here's a tentative patch.
>> >
>> >
>> > -- >8 --
>> > Subject: [PATCH] PCI: pciehp: Don't enable PME on runtime suspend
>>
>> it works:
>
> Thanks a lot for the report and for testing the patch!

Wait, Commit 68db9bc still has problem with another server (skylake
based), and this patch does not help.


sca05-0a81fd8d:~ # echo 0 > /sys/bus/pci/slots/11/power
[  362.721197] pci_hotplug: power_write_file: power = 0
[  362.726887] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
SLOTCTRL a8 value read 11f1
[  362.736431] pciehp :b3:00.0:pcie004: pciehp_unconfigure_device:
domain:bus:dev = :b4:00
[  362.746160] mlx4_core :b4:00.0: PME# disabled
[  364.494033] pcieport :b3:00.0:   root_bridge ACPI_HANDLE
9e56b8811550 : pci:b3
[  364.503274] pcieport :b3:00.0:  pciehp is native
[  364.508863] pci :b4:00.0: freeing pci_dev info
[  364.514718] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  364.523443] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
SLOTCTRL a8 write cmd 400
[  364.587047] pciehp :b3:00.0:pcie004: pending interrupts 0x0108
from Slot Status
[  364.595592] pciehp :b3:00.0:pcie004: Slot(11): Link Down
[  364.602325] pciehp :b3:00.0:pcie004: Slot(11): Link Down event
ignored; already powering off
[  365.568415] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
SLOTCTRL a8 write cmd 300
[  365.569338] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status

sca05-0a81fd8d:~ # echo 1 > /sys/bus/pci/slots/11/power
[  375.376609] pci_hotplug: power_write_file: power = 1
[  375.382175] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
SLOTCTRL a8 value read 17f1
[  375.392695] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  375.401370] pciehp :b3:00.0:pcie004: pciehp_power_on_slot:
SLOTCTRL a8 write cmd 0
[  375.410231] pciehp :b3:00.0:pcie004: pciehp_green_led_blink:
SLOTCTRL a8 write cmd 200
[  375.411071] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  375.445222] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  377.00] pciehp :b3:00.0:pcie004: Data Link Layer Link
Active not set in 1000 msec
[  378.960364] pci :b4:00.0 id reading try 50 times with interval
20 ms to get 
[  378.969406] pciehp :b3:00.0:pcie004: pciehp_check_link_status:
lnk_status = 5001
[  378.978059] pciehp :b3:00.0:pcie004: link training error: status 0x5001
[  378.985834] pciehp :b3:00.0:pcie004: Failed to check link status
[  378.987185] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  378.987253] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
SLOTCTRL a8 write cmd 400
[  380.000409] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
SLOTCTRL a8 write cmd 300
[  380.000674] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  380.018020] pciehp :b3:00.0:pcie004:
pciehp_set_attention_status: SLOTCTRL a8 write cmd 40
[  380.019053] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
-bash: echo: write error: Operation not permitted

revert commit 68db9bc, also make it working again.


Thanks


Yinghai


Re: pciehp is broken from 4.10-rc1

2017-02-04 Thread Yinghai Lu
On Sat, Feb 4, 2017 at 3:34 PM, Lukas Wunner  wrote:
> On Sat, Feb 04, 2017 at 01:44:34PM -0800, Yinghai Lu wrote:
>> On Sat, Feb 4, 2017 at 10:56 AM, Lukas Wunner  wrote:
>> > On Sat, Feb 04, 2017 at 09:12:54AM +0100, Lukas Wunner wrote:
>> > Section 6.7.3.4 of the PCIe Base spec seems to support the theory above,
>> > so here's a tentative patch.
>> >
>> >
>> > -- >8 --
>> > Subject: [PATCH] PCI: pciehp: Don't enable PME on runtime suspend
>>
>> it works:
>
> Thanks a lot for the report and for testing the patch!

Wait, Commit 68db9bc still has problem with another server (skylake
based), and this patch does not help.


sca05-0a81fd8d:~ # echo 0 > /sys/bus/pci/slots/11/power
[  362.721197] pci_hotplug: power_write_file: power = 0
[  362.726887] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
SLOTCTRL a8 value read 11f1
[  362.736431] pciehp :b3:00.0:pcie004: pciehp_unconfigure_device:
domain:bus:dev = :b4:00
[  362.746160] mlx4_core :b4:00.0: PME# disabled
[  364.494033] pcieport :b3:00.0:   root_bridge ACPI_HANDLE
9e56b8811550 : pci:b3
[  364.503274] pcieport :b3:00.0:  pciehp is native
[  364.508863] pci :b4:00.0: freeing pci_dev info
[  364.514718] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  364.523443] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
SLOTCTRL a8 write cmd 400
[  364.587047] pciehp :b3:00.0:pcie004: pending interrupts 0x0108
from Slot Status
[  364.595592] pciehp :b3:00.0:pcie004: Slot(11): Link Down
[  364.602325] pciehp :b3:00.0:pcie004: Slot(11): Link Down event
ignored; already powering off
[  365.568415] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
SLOTCTRL a8 write cmd 300
[  365.569338] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status

sca05-0a81fd8d:~ # echo 1 > /sys/bus/pci/slots/11/power
[  375.376609] pci_hotplug: power_write_file: power = 1
[  375.382175] pciehp :b3:00.0:pcie004: pciehp_get_power_status:
SLOTCTRL a8 value read 17f1
[  375.392695] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  375.401370] pciehp :b3:00.0:pcie004: pciehp_power_on_slot:
SLOTCTRL a8 write cmd 0
[  375.410231] pciehp :b3:00.0:pcie004: pciehp_green_led_blink:
SLOTCTRL a8 write cmd 200
[  375.411071] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  375.445222] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  377.00] pciehp :b3:00.0:pcie004: Data Link Layer Link
Active not set in 1000 msec
[  378.960364] pci :b4:00.0 id reading try 50 times with interval
20 ms to get 
[  378.969406] pciehp :b3:00.0:pcie004: pciehp_check_link_status:
lnk_status = 5001
[  378.978059] pciehp :b3:00.0:pcie004: link training error: status 0x5001
[  378.985834] pciehp :b3:00.0:pcie004: Failed to check link status
[  378.987185] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  378.987253] pciehp :b3:00.0:pcie004: pciehp_power_off_slot:
SLOTCTRL a8 write cmd 400
[  380.000409] pciehp :b3:00.0:pcie004: pciehp_green_led_off:
SLOTCTRL a8 write cmd 300
[  380.000674] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
[  380.018020] pciehp :b3:00.0:pcie004:
pciehp_set_attention_status: SLOTCTRL a8 write cmd 40
[  380.019053] pciehp :b3:00.0:pcie004: pending interrupts 0x0010
from Slot Status
-bash: echo: write error: Operation not permitted

revert commit 68db9bc, also make it working again.


Thanks


Yinghai


Re: [PATCH v2 2/2] arm: dts: mt2701: add nor flash node

2017-02-04 Thread Guochun Mao
On Wed, 2017-01-25 at 11:38 +0800, Guochun Mao wrote:
> Add Mediatek nor flash node.
> 
> Signed-off-by: Guochun Mao 
> ---
>  arch/arm/boot/dts/mt2701-evb.dts |   25 +
>  arch/arm/boot/dts/mt2701.dtsi|   12 
>  2 files changed, 37 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/mt2701-evb.dts 
> b/arch/arm/boot/dts/mt2701-evb.dts
> index 082ca88..85e5ae8 100644
> --- a/arch/arm/boot/dts/mt2701-evb.dts
> +++ b/arch/arm/boot/dts/mt2701-evb.dts
> @@ -24,6 +24,31 @@
>   };
>  };
>  
> +_flash {
> + pinctrl-names = "default";
> + pinctrl-0 = <_pins_default>;
> + status = "okay";
> + flash@0 {
> + compatible = "jedec,spi-nor";
> + reg = <0>;
> + };
> +};
> +
> + {
> + nor_pins_default: nor {
> + pins1 {
> + pinmux = ,
> +  ,
> +  ,
> +  ,
> +  ,
> +  ;
> + drive-strength = ;
> + bias-pull-up;
> + };
> + };
> +};
> +
>   {
>   status = "okay";
>  };
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index bdf8954..1eefce4 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -227,6 +227,18 @@
>   status = "disabled";
>   };
>  
> + nor_flash: spi@11014000 {
> + compatible = "mediatek,mt2701-nor",
> +  "mediatek,mt8173-nor";
> + reg = <0 0x11014000 0 0xe0>;
> + clocks = < CLK_PERI_FLASH>,
> +  < CLK_TOP_FLASH_SEL>;
> + clock-names = "spi", "sf";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + status = "disabled";
> + };
> +
>   mmsys: syscon@1400 {
>   compatible = "mediatek,mt2701-mmsys", "syscon";
>   reg = <0 0x1400 0 0x1000>;

Hi,
mtk-quadspi.txt had been updated as suggested.
Is there suggestion about this patch?
Thanks.

BR,
Guochun



Re: [PATCH v2 2/2] arm: dts: mt2701: add nor flash node

2017-02-04 Thread Guochun Mao
On Wed, 2017-01-25 at 11:38 +0800, Guochun Mao wrote:
> Add Mediatek nor flash node.
> 
> Signed-off-by: Guochun Mao 
> ---
>  arch/arm/boot/dts/mt2701-evb.dts |   25 +
>  arch/arm/boot/dts/mt2701.dtsi|   12 
>  2 files changed, 37 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/mt2701-evb.dts 
> b/arch/arm/boot/dts/mt2701-evb.dts
> index 082ca88..85e5ae8 100644
> --- a/arch/arm/boot/dts/mt2701-evb.dts
> +++ b/arch/arm/boot/dts/mt2701-evb.dts
> @@ -24,6 +24,31 @@
>   };
>  };
>  
> +_flash {
> + pinctrl-names = "default";
> + pinctrl-0 = <_pins_default>;
> + status = "okay";
> + flash@0 {
> + compatible = "jedec,spi-nor";
> + reg = <0>;
> + };
> +};
> +
> + {
> + nor_pins_default: nor {
> + pins1 {
> + pinmux = ,
> +  ,
> +  ,
> +  ,
> +  ,
> +  ;
> + drive-strength = ;
> + bias-pull-up;
> + };
> + };
> +};
> +
>   {
>   status = "okay";
>  };
> diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
> index bdf8954..1eefce4 100644
> --- a/arch/arm/boot/dts/mt2701.dtsi
> +++ b/arch/arm/boot/dts/mt2701.dtsi
> @@ -227,6 +227,18 @@
>   status = "disabled";
>   };
>  
> + nor_flash: spi@11014000 {
> + compatible = "mediatek,mt2701-nor",
> +  "mediatek,mt8173-nor";
> + reg = <0 0x11014000 0 0xe0>;
> + clocks = < CLK_PERI_FLASH>,
> +  < CLK_TOP_FLASH_SEL>;
> + clock-names = "spi", "sf";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + status = "disabled";
> + };
> +
>   mmsys: syscon@1400 {
>   compatible = "mediatek,mt2701-mmsys", "syscon";
>   reg = <0 0x1400 0 0x1000>;

Hi,
mtk-quadspi.txt had been updated as suggested.
Is there suggestion about this patch?
Thanks.

BR,
Guochun



[PATCH v5 6/6] drm/rockchip/dsi: add dw-mipi power domain support

2017-02-04 Thread Chris Zhong
Reference the power domain incase dw-mipi power down when
in use.

Signed-off-by: Chris Zhong 
Reviewed-by: Sean Paul 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 35f22bc..d263352 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -293,6 +294,7 @@ struct dw_mipi_dsi {
struct clk *pclk;
struct clk *phy_cfg_clk;
 
+   int dpms_mode;
unsigned int lane_mbps; /* per lane */
u32 channel;
u32 lanes;
@@ -969,6 +971,9 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder 
*encoder)
 {
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
 
+   if (dsi->dpms_mode != DRM_MODE_DPMS_ON)
+   return;
+
if (clk_prepare_enable(dsi->pclk)) {
dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__);
return;
@@ -980,7 +985,9 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder 
*encoder)
drm_panel_unprepare(dsi->panel);
 
dw_mipi_dsi_disable(dsi);
+   pm_runtime_put(dsi->dev);
clk_disable_unprepare(dsi->pclk);
+   dsi->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
 static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
@@ -990,11 +997,15 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder 
*encoder)
int mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node, encoder);
u32 val;
 
+   if (dsi->dpms_mode == DRM_MODE_DPMS_ON)
+   return;
+
if (clk_prepare_enable(dsi->pclk)) {
dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__);
return;
}
 
+   pm_runtime_get_sync(dsi->dev);
dw_mipi_dsi_init(dsi);
dw_mipi_dsi_dpi_config(dsi);
dw_mipi_dsi_packet_handler_config(dsi);
@@ -1030,6 +1041,7 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder 
*encoder)
 
regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val);
dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
+   dsi->dpms_mode = DRM_MODE_DPMS_ON;
 }
 
 static int
@@ -1198,6 +1210,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
 
dsi->dev = dev;
dsi->pdata = pdata;
+   dsi->dpms_mode = DRM_MODE_DPMS_OFF;
 
ret = rockchip_mipi_parse_dt(dsi);
if (ret)
@@ -1278,6 +1291,8 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
 
dev_set_drvdata(dev, dsi);
 
+   pm_runtime_enable(dev);
+
dsi->dsi_host.ops = _mipi_dsi_host_ops;
dsi->dsi_host.dev = dev;
ret = mipi_dsi_host_register(>dsi_host);
@@ -1300,6 +1315,7 @@ static void dw_mipi_dsi_unbind(struct device *dev, struct 
device *master,
struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
 
mipi_dsi_host_unregister(>dsi_host);
+   pm_runtime_disable(dev);
clk_disable_unprepare(dsi->pllref_clk);
 }
 
-- 
2.6.3



[PATCH v5 5/6] dt-bindings: add power domain node for dw-mipi-rockchip

2017-02-04 Thread Chris Zhong
Signed-off-by: Chris Zhong 
Acked-by: Rob Herring 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt  | 3 +++
 1 file changed, 3 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 0f82568..188f6f7 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -15,6 +15,9 @@ Required properties:
 - ports: contain a port node with endpoint definitions as defined in [2].
   For vopb,set the reg = <0> and set the reg = <1> for vopl.
 
+Optional properties:
+- power-domains: a phandle to mipi dsi power domain node.
+
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 [2] Documentation/devicetree/bindings/media/video-interfaces.txt
 
-- 
2.6.3



[PATCH v5 4/6] drm/rockchip/dsi: remove mode_valid function

2017-02-04 Thread Chris Zhong
The MIPI DSI do not need check the validity of resolution, the max
resolution should depend VOP. Hence, remove rk3288_mipi_dsi_mode_valid
here.

Signed-off-by: Chris Zhong 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 --
 1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 89a8941..35f22bc 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -278,8 +278,6 @@ struct dw_mipi_dsi_plat_data {
u32 grf_dsi0_mode;
u32 grf_dsi0_mode_reg;
unsigned int max_data_lanes;
-   enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
-  struct drm_display_mode *mode);
 };
 
 struct dw_mipi_dsi {
@@ -1081,23 +1079,8 @@ static int dw_mipi_dsi_connector_get_modes(struct 
drm_connector *connector)
return drm_panel_get_modes(dsi->panel);
 }
 
-static enum drm_mode_status dw_mipi_dsi_mode_valid(
-   struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   struct dw_mipi_dsi *dsi = con_to_dsi(connector);
-
-   enum drm_mode_status mode_status = MODE_OK;
-
-   if (dsi->pdata->mode_valid)
-   mode_status = dsi->pdata->mode_valid(connector, mode);
-
-   return mode_status;
-}
-
 static struct drm_connector_helper_funcs dw_mipi_dsi_connector_helper_funcs = {
.get_modes = dw_mipi_dsi_connector_get_modes,
-   .mode_valid = dw_mipi_dsi_mode_valid,
 };
 
 static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
@@ -1168,33 +1151,11 @@ static int rockchip_mipi_parse_dt(struct dw_mipi_dsi 
*dsi)
return 0;
 }
 
-static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
-   struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   /*
-* The VID_PKT_SIZE field in the DSI_VID_PKT_CFG
-* register is 11-bit.
-*/
-   if (mode->hdisplay > 0x7ff)
-   return MODE_BAD_HVALUE;
-
-   /*
-* The V_ACTIVE_LINES field in the DSI_VTIMING_CFG
-* register is 11-bit.
-*/
-   if (mode->vdisplay > 0x7ff)
-   return MODE_BAD_VVALUE;
-
-   return MODE_OK;
-}
-
 static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
.dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
.dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
.grf_switch_reg = RK3288_GRF_SOC_CON6,
.max_data_lanes = 4,
-   .mode_valid = rk3288_mipi_dsi_mode_valid,
 };
 
 static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
-- 
2.6.3



[PATCH v5 6/6] drm/rockchip/dsi: add dw-mipi power domain support

2017-02-04 Thread Chris Zhong
Reference the power domain incase dw-mipi power down when
in use.

Signed-off-by: Chris Zhong 
Reviewed-by: Sean Paul 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 35f22bc..d263352 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -293,6 +294,7 @@ struct dw_mipi_dsi {
struct clk *pclk;
struct clk *phy_cfg_clk;
 
+   int dpms_mode;
unsigned int lane_mbps; /* per lane */
u32 channel;
u32 lanes;
@@ -969,6 +971,9 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder 
*encoder)
 {
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
 
+   if (dsi->dpms_mode != DRM_MODE_DPMS_ON)
+   return;
+
if (clk_prepare_enable(dsi->pclk)) {
dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__);
return;
@@ -980,7 +985,9 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder 
*encoder)
drm_panel_unprepare(dsi->panel);
 
dw_mipi_dsi_disable(dsi);
+   pm_runtime_put(dsi->dev);
clk_disable_unprepare(dsi->pclk);
+   dsi->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
 static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
@@ -990,11 +997,15 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder 
*encoder)
int mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node, encoder);
u32 val;
 
+   if (dsi->dpms_mode == DRM_MODE_DPMS_ON)
+   return;
+
if (clk_prepare_enable(dsi->pclk)) {
dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__);
return;
}
 
+   pm_runtime_get_sync(dsi->dev);
dw_mipi_dsi_init(dsi);
dw_mipi_dsi_dpi_config(dsi);
dw_mipi_dsi_packet_handler_config(dsi);
@@ -1030,6 +1041,7 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder 
*encoder)
 
regmap_write(dsi->grf_regmap, pdata->grf_switch_reg, val);
dev_dbg(dsi->dev, "vop %s output to dsi0\n", (mux) ? "LIT" : "BIG");
+   dsi->dpms_mode = DRM_MODE_DPMS_ON;
 }
 
 static int
@@ -1198,6 +1210,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
 
dsi->dev = dev;
dsi->pdata = pdata;
+   dsi->dpms_mode = DRM_MODE_DPMS_OFF;
 
ret = rockchip_mipi_parse_dt(dsi);
if (ret)
@@ -1278,6 +1291,8 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
 
dev_set_drvdata(dev, dsi);
 
+   pm_runtime_enable(dev);
+
dsi->dsi_host.ops = _mipi_dsi_host_ops;
dsi->dsi_host.dev = dev;
ret = mipi_dsi_host_register(>dsi_host);
@@ -1300,6 +1315,7 @@ static void dw_mipi_dsi_unbind(struct device *dev, struct 
device *master,
struct dw_mipi_dsi *dsi = dev_get_drvdata(dev);
 
mipi_dsi_host_unregister(>dsi_host);
+   pm_runtime_disable(dev);
clk_disable_unprepare(dsi->pllref_clk);
 }
 
-- 
2.6.3



[PATCH v5 5/6] dt-bindings: add power domain node for dw-mipi-rockchip

2017-02-04 Thread Chris Zhong
Signed-off-by: Chris Zhong 
Acked-by: Rob Herring 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt  | 3 +++
 1 file changed, 3 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 0f82568..188f6f7 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -15,6 +15,9 @@ Required properties:
 - ports: contain a port node with endpoint definitions as defined in [2].
   For vopb,set the reg = <0> and set the reg = <1> for vopl.
 
+Optional properties:
+- power-domains: a phandle to mipi dsi power domain node.
+
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 [2] Documentation/devicetree/bindings/media/video-interfaces.txt
 
-- 
2.6.3



[PATCH v5 4/6] drm/rockchip/dsi: remove mode_valid function

2017-02-04 Thread Chris Zhong
The MIPI DSI do not need check the validity of resolution, the max
resolution should depend VOP. Hence, remove rk3288_mipi_dsi_mode_valid
here.

Signed-off-by: Chris Zhong 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 --
 1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 89a8941..35f22bc 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -278,8 +278,6 @@ struct dw_mipi_dsi_plat_data {
u32 grf_dsi0_mode;
u32 grf_dsi0_mode_reg;
unsigned int max_data_lanes;
-   enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
-  struct drm_display_mode *mode);
 };
 
 struct dw_mipi_dsi {
@@ -1081,23 +1079,8 @@ static int dw_mipi_dsi_connector_get_modes(struct 
drm_connector *connector)
return drm_panel_get_modes(dsi->panel);
 }
 
-static enum drm_mode_status dw_mipi_dsi_mode_valid(
-   struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   struct dw_mipi_dsi *dsi = con_to_dsi(connector);
-
-   enum drm_mode_status mode_status = MODE_OK;
-
-   if (dsi->pdata->mode_valid)
-   mode_status = dsi->pdata->mode_valid(connector, mode);
-
-   return mode_status;
-}
-
 static struct drm_connector_helper_funcs dw_mipi_dsi_connector_helper_funcs = {
.get_modes = dw_mipi_dsi_connector_get_modes,
-   .mode_valid = dw_mipi_dsi_mode_valid,
 };
 
 static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
@@ -1168,33 +1151,11 @@ static int rockchip_mipi_parse_dt(struct dw_mipi_dsi 
*dsi)
return 0;
 }
 
-static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
-   struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   /*
-* The VID_PKT_SIZE field in the DSI_VID_PKT_CFG
-* register is 11-bit.
-*/
-   if (mode->hdisplay > 0x7ff)
-   return MODE_BAD_HVALUE;
-
-   /*
-* The V_ACTIVE_LINES field in the DSI_VTIMING_CFG
-* register is 11-bit.
-*/
-   if (mode->vdisplay > 0x7ff)
-   return MODE_BAD_VVALUE;
-
-   return MODE_OK;
-}
-
 static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
.dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
.dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
.grf_switch_reg = RK3288_GRF_SOC_CON6,
.max_data_lanes = 4,
-   .mode_valid = rk3288_mipi_dsi_mode_valid,
 };
 
 static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
-- 
2.6.3



[PATCH v5 2/6] drm/rockchip/dsi: dw-mipi: support RK3399 mipi dsi

2017-02-04 Thread Chris Zhong
The vopb/vopl switch register of RK3399 mipi is different from RK3288,
the default setting for mipi dsi mode is different too, so add a
of_device_id structure to distinguish them, and make sure set the
correct mode before mipi phy init.

Signed-off-by: Chris Zhong 
Signed-off-by: Mark Yao 

---

Changes in v5:
- check the error of phy_cfg_clk in dw_mipi_dsi_bind

Changes in v4:
- remove the unrelated change

Changes in v3:
- base on John Keeping's patch series

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 75 +-
 1 file changed, 65 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 45af890..7d337e2 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -29,9 +29,17 @@
 
 #define DRIVER_NAME"dw-mipi-dsi"
 
-#define GRF_SOC_CON60x025c
-#define DSI0_SEL_VOP_LIT(1 << 6)
-#define DSI1_SEL_VOP_LIT(1 << 9)
+#define RK3288_GRF_SOC_CON60x025c
+#define RK3288_DSI0_SEL_VOP_LITBIT(6)
+#define RK3288_DSI1_SEL_VOP_LITBIT(9)
+
+#define RK3399_GRF_SOC_CON19   0x6250
+#define RK3399_DSI0_SEL_VOP_LITBIT(0)
+#define RK3399_DSI1_SEL_VOP_LITBIT(4)
+
+/* disable turnrequest, turndisable, forcetxstopmode, forcerxmode */
+#define RK3399_GRF_SOC_CON22   0x6258
+#define RK3399_GRF_DSI_MODE0x
 
 #define DSI_VERSION0x00
 #define DSI_PWR_UP 0x04
@@ -265,6 +273,11 @@ enum {
 };
 
 struct dw_mipi_dsi_plat_data {
+   u32 dsi0_en_bit;
+   u32 dsi1_en_bit;
+   u32 grf_switch_reg;
+   u32 grf_dsi0_mode;
+   u32 grf_dsi0_mode_reg;
unsigned int max_data_lanes;
enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
   struct drm_display_mode *mode);
@@ -281,6 +294,7 @@ struct dw_mipi_dsi {
 
struct clk *pllref_clk;
struct clk *pclk;
+   struct clk *phy_cfg_clk;
 
unsigned int lane_mbps; /* per lane */
u32 channel;
@@ -426,6 +440,14 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
 
+   if (dsi->phy_cfg_clk) {
+   ret = clk_prepare_enable(dsi->phy_cfg_clk);
+   if (ret) {
+   dev_err(dsi->dev, "Failed to enable phy_cfg_clk\n");
+   return ret;
+   }
+   }
+
dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE |
 VCO_RANGE_CON_SEL(vco) |
 VCO_IN_CAP_CON_LOW |
@@ -479,17 +501,19 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
if (ret < 0) {
dev_err(dsi->dev, "failed to wait for phy lock state\n");
-   return ret;
+   goto phy_init_end;
}
 
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
 val, val & STOP_STATE_CLK_LANE, 1000,
 PHY_STATUS_TIMEOUT_US);
-   if (ret < 0) {
+   if (ret < 0)
dev_err(dsi->dev,
"failed to wait for phy clk lane stop state\n");
-   return ret;
-   }
+
+phy_init_end:
+   if (dsi->phy_cfg_clk)
+   clk_disable_unprepare(dsi->phy_cfg_clk);
 
return ret;
 }
@@ -965,6 +989,7 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder 
*encoder)
 static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
 {
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
+   const struct dw_mipi_dsi_plat_data *pdata = dsi->pdata;
int mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node, encoder);
u32 val;
 
@@ -985,6 +1010,10 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder 
*encoder)
dw_mipi_dsi_dphy_interface_config(dsi);
dw_mipi_dsi_clear_err(dsi);
 
+   if (pdata->grf_dsi0_mode_reg)
+   regmap_write(dsi->grf_regmap, pdata->grf_dsi0_mode_reg,
+pdata->grf_dsi0_mode);
+
dw_mipi_dsi_phy_init(dsi);
dw_mipi_dsi_wait_for_two_frames(dsi);
 
@@ -998,11 +1027,11 @@ static void dw_mipi_dsi_encoder_enable(struct 
drm_encoder *encoder)
clk_disable_unprepare(dsi->pclk);
 
if (mux)
-   val = DSI0_SEL_VOP_LIT | (DSI0_SEL_VOP_LIT << 16);
+   val = pdata->dsi0_en_bit | (pdata->dsi0_en_bit << 16);
else
-   val = DSI0_SEL_VOP_LIT << 16;
+   val = pdata->dsi0_en_bit << 16;
 
-   regmap_write(dsi->grf_regmap, GRF_SOC_CON6, val);
+   

[PATCH v5 2/6] drm/rockchip/dsi: dw-mipi: support RK3399 mipi dsi

2017-02-04 Thread Chris Zhong
The vopb/vopl switch register of RK3399 mipi is different from RK3288,
the default setting for mipi dsi mode is different too, so add a
of_device_id structure to distinguish them, and make sure set the
correct mode before mipi phy init.

Signed-off-by: Chris Zhong 
Signed-off-by: Mark Yao 

---

Changes in v5:
- check the error of phy_cfg_clk in dw_mipi_dsi_bind

Changes in v4:
- remove the unrelated change

Changes in v3:
- base on John Keeping's patch series

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 75 +-
 1 file changed, 65 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 45af890..7d337e2 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -29,9 +29,17 @@
 
 #define DRIVER_NAME"dw-mipi-dsi"
 
-#define GRF_SOC_CON60x025c
-#define DSI0_SEL_VOP_LIT(1 << 6)
-#define DSI1_SEL_VOP_LIT(1 << 9)
+#define RK3288_GRF_SOC_CON60x025c
+#define RK3288_DSI0_SEL_VOP_LITBIT(6)
+#define RK3288_DSI1_SEL_VOP_LITBIT(9)
+
+#define RK3399_GRF_SOC_CON19   0x6250
+#define RK3399_DSI0_SEL_VOP_LITBIT(0)
+#define RK3399_DSI1_SEL_VOP_LITBIT(4)
+
+/* disable turnrequest, turndisable, forcetxstopmode, forcerxmode */
+#define RK3399_GRF_SOC_CON22   0x6258
+#define RK3399_GRF_DSI_MODE0x
 
 #define DSI_VERSION0x00
 #define DSI_PWR_UP 0x04
@@ -265,6 +273,11 @@ enum {
 };
 
 struct dw_mipi_dsi_plat_data {
+   u32 dsi0_en_bit;
+   u32 dsi1_en_bit;
+   u32 grf_switch_reg;
+   u32 grf_dsi0_mode;
+   u32 grf_dsi0_mode_reg;
unsigned int max_data_lanes;
enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
   struct drm_display_mode *mode);
@@ -281,6 +294,7 @@ struct dw_mipi_dsi {
 
struct clk *pllref_clk;
struct clk *pclk;
+   struct clk *phy_cfg_clk;
 
unsigned int lane_mbps; /* per lane */
u32 channel;
@@ -426,6 +440,14 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
 
+   if (dsi->phy_cfg_clk) {
+   ret = clk_prepare_enable(dsi->phy_cfg_clk);
+   if (ret) {
+   dev_err(dsi->dev, "Failed to enable phy_cfg_clk\n");
+   return ret;
+   }
+   }
+
dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE |
 VCO_RANGE_CON_SEL(vco) |
 VCO_IN_CAP_CON_LOW |
@@ -479,17 +501,19 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
if (ret < 0) {
dev_err(dsi->dev, "failed to wait for phy lock state\n");
-   return ret;
+   goto phy_init_end;
}
 
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
 val, val & STOP_STATE_CLK_LANE, 1000,
 PHY_STATUS_TIMEOUT_US);
-   if (ret < 0) {
+   if (ret < 0)
dev_err(dsi->dev,
"failed to wait for phy clk lane stop state\n");
-   return ret;
-   }
+
+phy_init_end:
+   if (dsi->phy_cfg_clk)
+   clk_disable_unprepare(dsi->phy_cfg_clk);
 
return ret;
 }
@@ -965,6 +989,7 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder 
*encoder)
 static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
 {
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
+   const struct dw_mipi_dsi_plat_data *pdata = dsi->pdata;
int mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node, encoder);
u32 val;
 
@@ -985,6 +1010,10 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder 
*encoder)
dw_mipi_dsi_dphy_interface_config(dsi);
dw_mipi_dsi_clear_err(dsi);
 
+   if (pdata->grf_dsi0_mode_reg)
+   regmap_write(dsi->grf_regmap, pdata->grf_dsi0_mode_reg,
+pdata->grf_dsi0_mode);
+
dw_mipi_dsi_phy_init(dsi);
dw_mipi_dsi_wait_for_two_frames(dsi);
 
@@ -998,11 +1027,11 @@ static void dw_mipi_dsi_encoder_enable(struct 
drm_encoder *encoder)
clk_disable_unprepare(dsi->pclk);
 
if (mux)
-   val = DSI0_SEL_VOP_LIT | (DSI0_SEL_VOP_LIT << 16);
+   val = pdata->dsi0_en_bit | (pdata->dsi0_en_bit << 16);
else
-   val = DSI0_SEL_VOP_LIT << 16;
+   val = pdata->dsi0_en_bit << 16;
 
-   regmap_write(dsi->grf_regmap, GRF_SOC_CON6, val);
+   regmap_write(dsi->grf_regmap, 

[PATCH v5 0/6] Rockchip dw-mipi-dsi driver

2017-02-04 Thread Chris Zhong
Hi all

This patch serial is for RK3399 MIPI DSI. The MIPI DSI controller of
RK3399 is almost the same as RK3288, except a little bit of difference
in phy clock controlling and port id selection register. These patches
add RK3399 support and the power domain support.

And these patches base on John Keeping's series[0], it fixes many bugs,
they have been tested on rk3288 evb board.

[0]:
[01/26] https://patchwork.kernel.org/patch/9340213
[02/26] https://patchwork.kernel.org/patch/9340145
[03/26] https://patchwork.kernel.org/patch/9340235
[04/26] https://patchwork.kernel.org/patch/9340123
[05/26] https://patchwork.kernel.org/patch/9340161
[06/26] https://patchwork.kernel.org/patch/9340203
[07/26] https://patchwork.kernel.org/patch/9340229
[08/26] https://patchwork.kernel.org/patch/9340131
[09/26] https://patchwork.kernel.org/patch/9340191
[10/26] https://patchwork.kernel.org/patch/9340175
[11/26] https://patchwork.kernel.org/patch/9340237
[12/26] https://patchwork.kernel.org/patch/9340207
[13/26] https://patchwork.kernel.org/patch/9340233
[14/26] https://patchwork.kernel.org/patch/9340205
[15/26] https://patchwork.kernel.org/patch/9340189
[16/26] https://patchwork.kernel.org/patch/9340143
[17/26] https://patchwork.kernel.org/patch/9340117
[18/26] https://patchwork.kernel.org/patch/9340193
[19/26] https://patchwork.kernel.org/patch/9340151
[20/26] https://patchwork.kernel.org/patch/9340183
[23/26] https://patchwork.kernel.org/patch/9340173
[24/26] https://patchwork.kernel.org/patch/9340251
[25/26] https://patchwork.kernel.org/patch/9340127
[26/26] https://patchwork.kernel.org/patch/9340139


Changes in v5:
- check the error of phy_cfg_clk in dw_mipi_dsi_bind

Changes in v4:
- remove the unrelated change

Changes in v3:
- base on John Keeping's patch series

Chris Zhong (6):
  dt-bindings: add rk3399 support for dw-mipi-rockchip
  drm/rockchip/dsi: dw-mipi: support RK3399 mipi dsi
  drm/rockchip/dsi: dw-mipi: correct the coding style
  drm/rockchip/dsi: remove mode_valid function
  dt-bindings: add power domain node for dw-mipi-rockchip
  drm/rockchip/dsi: add dw-mipi power domain support

 .../display/rockchip/dw_mipi_dsi_rockchip.txt  |   7 +-
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 163 -
 2 files changed, 103 insertions(+), 67 deletions(-)

-- 
2.6.3



[PATCH v5 0/6] Rockchip dw-mipi-dsi driver

2017-02-04 Thread Chris Zhong
Hi all

This patch serial is for RK3399 MIPI DSI. The MIPI DSI controller of
RK3399 is almost the same as RK3288, except a little bit of difference
in phy clock controlling and port id selection register. These patches
add RK3399 support and the power domain support.

And these patches base on John Keeping's series[0], it fixes many bugs,
they have been tested on rk3288 evb board.

[0]:
[01/26] https://patchwork.kernel.org/patch/9340213
[02/26] https://patchwork.kernel.org/patch/9340145
[03/26] https://patchwork.kernel.org/patch/9340235
[04/26] https://patchwork.kernel.org/patch/9340123
[05/26] https://patchwork.kernel.org/patch/9340161
[06/26] https://patchwork.kernel.org/patch/9340203
[07/26] https://patchwork.kernel.org/patch/9340229
[08/26] https://patchwork.kernel.org/patch/9340131
[09/26] https://patchwork.kernel.org/patch/9340191
[10/26] https://patchwork.kernel.org/patch/9340175
[11/26] https://patchwork.kernel.org/patch/9340237
[12/26] https://patchwork.kernel.org/patch/9340207
[13/26] https://patchwork.kernel.org/patch/9340233
[14/26] https://patchwork.kernel.org/patch/9340205
[15/26] https://patchwork.kernel.org/patch/9340189
[16/26] https://patchwork.kernel.org/patch/9340143
[17/26] https://patchwork.kernel.org/patch/9340117
[18/26] https://patchwork.kernel.org/patch/9340193
[19/26] https://patchwork.kernel.org/patch/9340151
[20/26] https://patchwork.kernel.org/patch/9340183
[23/26] https://patchwork.kernel.org/patch/9340173
[24/26] https://patchwork.kernel.org/patch/9340251
[25/26] https://patchwork.kernel.org/patch/9340127
[26/26] https://patchwork.kernel.org/patch/9340139


Changes in v5:
- check the error of phy_cfg_clk in dw_mipi_dsi_bind

Changes in v4:
- remove the unrelated change

Changes in v3:
- base on John Keeping's patch series

Chris Zhong (6):
  dt-bindings: add rk3399 support for dw-mipi-rockchip
  drm/rockchip/dsi: dw-mipi: support RK3399 mipi dsi
  drm/rockchip/dsi: dw-mipi: correct the coding style
  drm/rockchip/dsi: remove mode_valid function
  dt-bindings: add power domain node for dw-mipi-rockchip
  drm/rockchip/dsi: add dw-mipi power domain support

 .../display/rockchip/dw_mipi_dsi_rockchip.txt  |   7 +-
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 163 -
 2 files changed, 103 insertions(+), 67 deletions(-)

-- 
2.6.3



[PATCH v5 1/6] dt-bindings: add rk3399 support for dw-mipi-rockchip

2017-02-04 Thread Chris Zhong
The dw-mipi-dsi of rk3399 is almost the same as rk3288, the rk3399 has
additional phy config clock.

Signed-off-by: Chris Zhong 
Acked-by: Rob Herring 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 1753f0c..0f82568 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -5,10 +5,12 @@ Required properties:
 - #address-cells: Should be <1>.
 - #size-cells: Should be <0>.
 - compatible: "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi".
+ "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi".
 - reg: Represent the physical address range of the controller.
 - interrupts: Represent the controller's interrupt to the CPU(s).
 - clocks, clock-names: Phandles to the controller's pll reference
-  clock(ref) and APB clock(pclk), as described in [1].
+  clock(ref) and APB clock(pclk). For RK3399, a phy config clock
+  (phy_cfg) is additional required. As described in [1].
 - rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
 - ports: contain a port node with endpoint definitions as defined in [2].
   For vopb,set the reg = <0> and set the reg = <1> for vopl.
-- 
2.6.3



[PATCH v5 3/6] drm/rockchip/dsi: dw-mipi: correct the coding style

2017-02-04 Thread Chris Zhong
correct the coding style, according the checkpatch scripts

Signed-off-by: Chris Zhong 
Reviewed-by: Sean Paul 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 7d337e2..89a8941 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -157,7 +157,6 @@
 #define LPRX_TO_CNT(p) ((p) & 0x)
 
 #define DSI_BTA_TO_CNT 0x8c
-
 #define DSI_LPCLK_CTRL 0x94
 #define AUTO_CLKLANE_CTRL  BIT(1)
 #define PHY_TXREQUESTCLKHS BIT(0)
@@ -223,11 +222,11 @@
 
 #define HSFREQRANGE_SEL(val)   (((val) & 0x3f) << 1)
 
-#define INPUT_DIVIDER(val) ((val - 1) & 0x7f)
+#define INPUT_DIVIDER(val) (((val) - 1) & 0x7f)
 #define LOW_PROGRAM_EN 0
 #define HIGH_PROGRAM_ENBIT(7)
-#define LOOP_DIV_LOW_SEL(val)  ((val - 1) & 0x1f)
-#define LOOP_DIV_HIGH_SEL(val) (((val - 1) >> 5) & 0x1f)
+#define LOOP_DIV_LOW_SEL(val)  (((val) - 1) & 0x1f)
+#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0x1f)
 #define PLL_LOOP_DIV_ENBIT(5)
 #define PLL_INPUT_DIV_EN   BIT(4)
 
@@ -370,6 +369,7 @@ static inline struct dw_mipi_dsi *encoder_to_dsi(struct 
drm_encoder *encoder)
 {
return container_of(encoder, struct dw_mipi_dsi, encoder);
 }
+
 static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
 {
writel(val, dsi->base + reg);
@@ -381,7 +381,7 @@ static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
 }
 
 static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code,
-u8 test_data)
+ u8 test_data)
 {
/*
 * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
@@ -496,7 +496,6 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
 PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
 
-
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
if (ret < 0) {
@@ -572,7 +571,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
 
if (device->lanes > dsi->pdata->max_data_lanes) {
dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
-   device->lanes);
+   device->lanes);
return -EINVAL;
}
 
@@ -960,8 +959,8 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
 }
 
 static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
-   struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+struct drm_display_mode *mode,
+struct drm_display_mode *adjusted_mode)
 {
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
 
@@ -1063,7 +1062,7 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder 
*encoder,
return 0;
 }
 
-static struct drm_encoder_helper_funcs
+static const struct drm_encoder_helper_funcs
 dw_mipi_dsi_encoder_helper_funcs = {
.enable = dw_mipi_dsi_encoder_enable,
.mode_set = dw_mipi_dsi_encoder_mode_set,
@@ -1071,7 +1070,7 @@ dw_mipi_dsi_encoder_helper_funcs = {
.atomic_check = dw_mipi_dsi_encoder_atomic_check,
 };
 
-static struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
+static const struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
.destroy = drm_encoder_cleanup,
 };
 
@@ -1107,7 +1106,7 @@ static void dw_mipi_dsi_drm_connector_destroy(struct 
drm_connector *connector)
drm_connector_cleanup(connector);
 }
 
-static struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
+static const struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = dw_mipi_dsi_drm_connector_destroy,
@@ -1117,7 +1116,7 @@ static struct drm_connector_funcs 
dw_mipi_dsi_atomic_connector_funcs = {
 };
 
 static int dw_mipi_dsi_register(struct drm_device *drm,
- struct dw_mipi_dsi *dsi)
+   struct dw_mipi_dsi *dsi)
 {
struct drm_encoder *encoder = >encoder;
struct drm_connector *connector = >connector;
@@ -1138,14 +1137,14 @@ static int dw_mipi_dsi_register(struct drm_device *drm,
drm_encoder_helper_add(>encoder,
   _mipi_dsi_encoder_helper_funcs);
ret = 

[PATCH v5 1/6] dt-bindings: add rk3399 support for dw-mipi-rockchip

2017-02-04 Thread Chris Zhong
The dw-mipi-dsi of rk3399 is almost the same as rk3288, the rk3399 has
additional phy config clock.

Signed-off-by: Chris Zhong 
Acked-by: Rob Herring 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 1753f0c..0f82568 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -5,10 +5,12 @@ Required properties:
 - #address-cells: Should be <1>.
 - #size-cells: Should be <0>.
 - compatible: "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi".
+ "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi".
 - reg: Represent the physical address range of the controller.
 - interrupts: Represent the controller's interrupt to the CPU(s).
 - clocks, clock-names: Phandles to the controller's pll reference
-  clock(ref) and APB clock(pclk), as described in [1].
+  clock(ref) and APB clock(pclk). For RK3399, a phy config clock
+  (phy_cfg) is additional required. As described in [1].
 - rockchip,grf: this soc should set GRF regs to mux vopl/vopb.
 - ports: contain a port node with endpoint definitions as defined in [2].
   For vopb,set the reg = <0> and set the reg = <1> for vopl.
-- 
2.6.3



[PATCH v5 3/6] drm/rockchip/dsi: dw-mipi: correct the coding style

2017-02-04 Thread Chris Zhong
correct the coding style, according the checkpatch scripts

Signed-off-by: Chris Zhong 
Reviewed-by: Sean Paul 
---

Changes in v5: None
Changes in v4: None
Changes in v3: None

 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 7d337e2..89a8941 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -157,7 +157,6 @@
 #define LPRX_TO_CNT(p) ((p) & 0x)
 
 #define DSI_BTA_TO_CNT 0x8c
-
 #define DSI_LPCLK_CTRL 0x94
 #define AUTO_CLKLANE_CTRL  BIT(1)
 #define PHY_TXREQUESTCLKHS BIT(0)
@@ -223,11 +222,11 @@
 
 #define HSFREQRANGE_SEL(val)   (((val) & 0x3f) << 1)
 
-#define INPUT_DIVIDER(val) ((val - 1) & 0x7f)
+#define INPUT_DIVIDER(val) (((val) - 1) & 0x7f)
 #define LOW_PROGRAM_EN 0
 #define HIGH_PROGRAM_ENBIT(7)
-#define LOOP_DIV_LOW_SEL(val)  ((val - 1) & 0x1f)
-#define LOOP_DIV_HIGH_SEL(val) (((val - 1) >> 5) & 0x1f)
+#define LOOP_DIV_LOW_SEL(val)  (((val) - 1) & 0x1f)
+#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0x1f)
 #define PLL_LOOP_DIV_ENBIT(5)
 #define PLL_INPUT_DIV_EN   BIT(4)
 
@@ -370,6 +369,7 @@ static inline struct dw_mipi_dsi *encoder_to_dsi(struct 
drm_encoder *encoder)
 {
return container_of(encoder, struct dw_mipi_dsi, encoder);
 }
+
 static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
 {
writel(val, dsi->base + reg);
@@ -381,7 +381,7 @@ static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
 }
 
 static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code,
-u8 test_data)
+ u8 test_data)
 {
/*
 * With the falling edge on TESTCLK, the TESTDIN[7:0] signal content
@@ -496,7 +496,6 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
 PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
 
-
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
 val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
if (ret < 0) {
@@ -572,7 +571,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
 
if (device->lanes > dsi->pdata->max_data_lanes) {
dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
-   device->lanes);
+   device->lanes);
return -EINVAL;
}
 
@@ -960,8 +959,8 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
 }
 
 static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
-   struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+struct drm_display_mode *mode,
+struct drm_display_mode *adjusted_mode)
 {
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
 
@@ -1063,7 +1062,7 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder 
*encoder,
return 0;
 }
 
-static struct drm_encoder_helper_funcs
+static const struct drm_encoder_helper_funcs
 dw_mipi_dsi_encoder_helper_funcs = {
.enable = dw_mipi_dsi_encoder_enable,
.mode_set = dw_mipi_dsi_encoder_mode_set,
@@ -1071,7 +1070,7 @@ dw_mipi_dsi_encoder_helper_funcs = {
.atomic_check = dw_mipi_dsi_encoder_atomic_check,
 };
 
-static struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
+static const struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = {
.destroy = drm_encoder_cleanup,
 };
 
@@ -1107,7 +1106,7 @@ static void dw_mipi_dsi_drm_connector_destroy(struct 
drm_connector *connector)
drm_connector_cleanup(connector);
 }
 
-static struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
+static const struct drm_connector_funcs dw_mipi_dsi_atomic_connector_funcs = {
.dpms = drm_atomic_helper_connector_dpms,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = dw_mipi_dsi_drm_connector_destroy,
@@ -1117,7 +1116,7 @@ static struct drm_connector_funcs 
dw_mipi_dsi_atomic_connector_funcs = {
 };
 
 static int dw_mipi_dsi_register(struct drm_device *drm,
- struct dw_mipi_dsi *dsi)
+   struct dw_mipi_dsi *dsi)
 {
struct drm_encoder *encoder = >encoder;
struct drm_connector *connector = >connector;
@@ -1138,14 +1137,14 @@ static int dw_mipi_dsi_register(struct drm_device *drm,
drm_encoder_helper_add(>encoder,
   _mipi_dsi_encoder_helper_funcs);
ret = drm_encoder_init(drm, >encoder, _mipi_dsi_encoder_funcs,
-  

Re: [PATCH v9 2/3] MAINTAINERS: add zx2967 watchdog controller driver to ARM ZTE architecture

2017-02-04 Thread Shawn Guo
Hi Baoyou,

On Sun, Feb 05, 2017 at 10:36:38AM +0800, Baoyou Xie wrote:
> On 5 February 2017 at 08:05, Guenter Roeck  wrote:
> 
> > On 02/03/2017 05:34 PM, Baoyou Xie wrote:
> >
> >> Add the zx2967 watchdog controller driver as maintained by ARM ZTE
> >> architecture maintainers, as they're parts of the core IP.
> >>
> >> Signed-off-by: Baoyou Xie 
> >>
> >
> > Reviewed-by: Guenter Roeck 
> >
> > I assume you'll submit this patch through the arm tree ?
> >
> Could you please submit all three patches through your tree? Thanks a lot
> :)

Patch #2 is the only one that Guenter is concerned about, as there are
other subsystem related updates on the file.  I think Guenter's
suggestion is good, i.e. we have patch #1 and #3 go upstream through
watchdog tree, and later we update MAINTAINERS as needed via arm-soc
tree.

Shawn


Re: [PATCH v9 2/3] MAINTAINERS: add zx2967 watchdog controller driver to ARM ZTE architecture

2017-02-04 Thread Shawn Guo
Hi Baoyou,

On Sun, Feb 05, 2017 at 10:36:38AM +0800, Baoyou Xie wrote:
> On 5 February 2017 at 08:05, Guenter Roeck  wrote:
> 
> > On 02/03/2017 05:34 PM, Baoyou Xie wrote:
> >
> >> Add the zx2967 watchdog controller driver as maintained by ARM ZTE
> >> architecture maintainers, as they're parts of the core IP.
> >>
> >> Signed-off-by: Baoyou Xie 
> >>
> >
> > Reviewed-by: Guenter Roeck 
> >
> > I assume you'll submit this patch through the arm tree ?
> >
> Could you please submit all three patches through your tree? Thanks a lot
> :)

Patch #2 is the only one that Guenter is concerned about, as there are
other subsystem related updates on the file.  I think Guenter's
suggestion is good, i.e. we have patch #1 and #3 go upstream through
watchdog tree, and later we update MAINTAINERS as needed via arm-soc
tree.

Shawn


Re: [PATCH v3 3/5] drm/rockchip/dsi: remove mode_valid function

2017-02-04 Thread Chris Zhong



On 02/02/2017 02:12 AM, Sean Paul wrote:

On Tue, Jan 24, 2017 at 10:27:27AM +0800, Chris Zhong wrote:

Hi Sean

On 01/24/2017 01:48 AM, Sean Paul wrote:

On Fri, Jan 20, 2017 at 06:10:49PM +0800, Chris Zhong wrote:

The MIPI DSI do not need check the validity of resolution, the max
resolution should depend VOP. Hence, remove rk3288_mipi_dsi_mode_valid
here.

Does vop actually enforce this, though? I see that mode_config.max_width is
4096, but there is no bounds checking in mode_fixup().

The connector is currently rejecting everything greater than 2047. So I think
you're going to regress behavior here.

Sean

The mipi controller has not this width limit, it depend the VOP,
such as RK3399, VOP_LIT only support 2560,
but VOP_BIG support 4K. So this driver should check the width here.

I don't see anything in the vop driver that rejects large modes for little vop.
So, while I agree the check shouldn't be here, you should move it to where it
should be instead of removing it entirely.

Sean


drm_mode_validate_size will check the dev->mode_config.max_width and
dev->mode_config.max_height, these 2 value come from 
rockchip_drm_mode_config_init,
currently, they are both 4096. So you are right, drm driver does not 
distinguish

between vop lit and big.

I think Mark Yao already have a local solution, and he will post it soon.






Signed-off-by: Chris Zhong 
---

Changes in v3: None

  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 --
  1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index a93ce97..6f0e252 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -278,8 +278,6 @@ struct dw_mipi_dsi_plat_data {
u32 grf_dsi0_mode;
u32 grf_dsi0_mode_reg;
unsigned int max_data_lanes;
-   enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
-  struct drm_display_mode *mode);
  };
  struct dw_mipi_dsi {
@@ -1081,23 +1079,8 @@ static int dw_mipi_dsi_connector_get_modes(struct 
drm_connector *connector)
return drm_panel_get_modes(dsi->panel);
  }
-static enum drm_mode_status dw_mipi_dsi_mode_valid(
-   struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   struct dw_mipi_dsi *dsi = con_to_dsi(connector);
-
-   enum drm_mode_status mode_status = MODE_OK;
-
-   if (dsi->pdata->mode_valid)
-   mode_status = dsi->pdata->mode_valid(connector, mode);
-
-   return mode_status;
-}
-
  static struct drm_connector_helper_funcs dw_mipi_dsi_connector_helper_funcs = 
{
.get_modes = dw_mipi_dsi_connector_get_modes,
-   .mode_valid = dw_mipi_dsi_mode_valid,
  };
  static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
@@ -1168,33 +1151,11 @@ static int rockchip_mipi_parse_dt(struct dw_mipi_dsi 
*dsi)
return 0;
  }
-static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
-   struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   /*
-* The VID_PKT_SIZE field in the DSI_VID_PKT_CFG
-* register is 11-bit.
-*/
-   if (mode->hdisplay > 0x7ff)
-   return MODE_BAD_HVALUE;
-
-   /*
-* The V_ACTIVE_LINES field in the DSI_VTIMING_CFG
-* register is 11-bit.
-*/
-   if (mode->vdisplay > 0x7ff)
-   return MODE_BAD_VVALUE;
-
-   return MODE_OK;
-}
-
  static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
.dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
.dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
.grf_switch_reg = RK3288_GRF_SOC_CON6,
.max_data_lanes = 4,
-   .mode_valid = rk3288_mipi_dsi_mode_valid,
  };
  static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
--
2.6.3

___
dri-devel mailing list
dri-de...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-de...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel





Re: [PATCH v3 3/5] drm/rockchip/dsi: remove mode_valid function

2017-02-04 Thread Chris Zhong



On 02/02/2017 02:12 AM, Sean Paul wrote:

On Tue, Jan 24, 2017 at 10:27:27AM +0800, Chris Zhong wrote:

Hi Sean

On 01/24/2017 01:48 AM, Sean Paul wrote:

On Fri, Jan 20, 2017 at 06:10:49PM +0800, Chris Zhong wrote:

The MIPI DSI do not need check the validity of resolution, the max
resolution should depend VOP. Hence, remove rk3288_mipi_dsi_mode_valid
here.

Does vop actually enforce this, though? I see that mode_config.max_width is
4096, but there is no bounds checking in mode_fixup().

The connector is currently rejecting everything greater than 2047. So I think
you're going to regress behavior here.

Sean

The mipi controller has not this width limit, it depend the VOP,
such as RK3399, VOP_LIT only support 2560,
but VOP_BIG support 4K. So this driver should check the width here.

I don't see anything in the vop driver that rejects large modes for little vop.
So, while I agree the check shouldn't be here, you should move it to where it
should be instead of removing it entirely.

Sean


drm_mode_validate_size will check the dev->mode_config.max_width and
dev->mode_config.max_height, these 2 value come from 
rockchip_drm_mode_config_init,
currently, they are both 4096. So you are right, drm driver does not 
distinguish

between vop lit and big.

I think Mark Yao already have a local solution, and he will post it soon.






Signed-off-by: Chris Zhong 
---

Changes in v3: None

  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 39 --
  1 file changed, 39 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index a93ce97..6f0e252 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -278,8 +278,6 @@ struct dw_mipi_dsi_plat_data {
u32 grf_dsi0_mode;
u32 grf_dsi0_mode_reg;
unsigned int max_data_lanes;
-   enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
-  struct drm_display_mode *mode);
  };
  struct dw_mipi_dsi {
@@ -1081,23 +1079,8 @@ static int dw_mipi_dsi_connector_get_modes(struct 
drm_connector *connector)
return drm_panel_get_modes(dsi->panel);
  }
-static enum drm_mode_status dw_mipi_dsi_mode_valid(
-   struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   struct dw_mipi_dsi *dsi = con_to_dsi(connector);
-
-   enum drm_mode_status mode_status = MODE_OK;
-
-   if (dsi->pdata->mode_valid)
-   mode_status = dsi->pdata->mode_valid(connector, mode);
-
-   return mode_status;
-}
-
  static struct drm_connector_helper_funcs dw_mipi_dsi_connector_helper_funcs = 
{
.get_modes = dw_mipi_dsi_connector_get_modes,
-   .mode_valid = dw_mipi_dsi_mode_valid,
  };
  static void dw_mipi_dsi_drm_connector_destroy(struct drm_connector *connector)
@@ -1168,33 +1151,11 @@ static int rockchip_mipi_parse_dt(struct dw_mipi_dsi 
*dsi)
return 0;
  }
-static enum drm_mode_status rk3288_mipi_dsi_mode_valid(
-   struct drm_connector *connector,
-   struct drm_display_mode *mode)
-{
-   /*
-* The VID_PKT_SIZE field in the DSI_VID_PKT_CFG
-* register is 11-bit.
-*/
-   if (mode->hdisplay > 0x7ff)
-   return MODE_BAD_HVALUE;
-
-   /*
-* The V_ACTIVE_LINES field in the DSI_VTIMING_CFG
-* register is 11-bit.
-*/
-   if (mode->vdisplay > 0x7ff)
-   return MODE_BAD_VVALUE;
-
-   return MODE_OK;
-}
-
  static struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_drv_data = {
.dsi0_en_bit = RK3288_DSI0_SEL_VOP_LIT,
.dsi1_en_bit = RK3288_DSI1_SEL_VOP_LIT,
.grf_switch_reg = RK3288_GRF_SOC_CON6,
.max_data_lanes = 4,
-   .mode_valid = rk3288_mipi_dsi_mode_valid,
  };
  static struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_drv_data = {
--
2.6.3

___
dri-devel mailing list
dri-de...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


___
dri-devel mailing list
dri-de...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel





[RESEND PATCH 0/1] add multiple clock handling for dwc2 driver

2017-02-04 Thread Frank Wang
The original posting on Jan 19th have not received any responses, so I resend 
them.

The Current default dwc2 just handle one clock named otg, however, it may have
two or more clock need to manage for some new SoCs(such as RK3328), so this
adds change clk to clk's array of dwc2_hsotg to handle more clocks operation.

Frank Wang (1):
  usb: dwc2: add multiple clock handling

 drivers/usb/dwc2/core.h |  5 -
 drivers/usb/dwc2/platform.c | 39 ++-
 2 files changed, 30 insertions(+), 14 deletions(-)

-- 
1.9.1




[RESEND PATCH 1/1] usb: dwc2: add multiple clock handling

2017-02-04 Thread Frank Wang
Originally, dwc2 just handle one clock named otg, however, it may have
two or more clock need to manage for some new SoCs, so this adds
change clk to clk's array of dwc2_hsotg to handle more clocks operation.

Signed-off-by: Frank Wang 
---
 drivers/usb/dwc2/core.h |  5 -
 drivers/usb/dwc2/platform.c | 39 ++-
 2 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 1a7e830..d10a466 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -121,6 +121,9 @@ static inline void dwc2_writel(u32 value, void __iomem 
*addr)
 /* Maximum number of Endpoints/HostChannels */
 #define MAX_EPS_CHANNELS   16
 
+/* Maximum number of dwc2 clocks */
+#define DWC2_MAX_CLKS 3
+
 /* dwc2-hsotg declarations */
 static const char * const dwc2_hsotg_supply_names[] = {
"vusb_d",   /* digital USB supply, 1.2V */
@@ -913,7 +916,7 @@ struct dwc2_hsotg {
spinlock_t lock;
void *priv;
int irq;
-   struct clk *clk;
+   struct clk *clks[DWC2_MAX_CLKS];
struct reset_control *reset;
 
unsigned int queuing_high_bandwidth:1;
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 9564bc7..795fc43b 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -123,17 +123,20 @@ static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg)
 static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 {
struct platform_device *pdev = to_platform_device(hsotg->dev);
-   int ret;
+   int clk, ret;
 
ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
hsotg->supplies);
if (ret)
return ret;
 
-   if (hsotg->clk) {
-   ret = clk_prepare_enable(hsotg->clk);
-   if (ret)
+   for (clk = 0; clk < DWC2_MAX_CLKS && hsotg->clks[clk]; clk++) {
+   ret = clk_prepare_enable(hsotg->clks[clk]);
+   if (ret) {
+   while (--clk >= 0)
+   clk_disable_unprepare(hsotg->clks[clk]);
return ret;
+   }
}
 
if (hsotg->uphy) {
@@ -168,7 +171,7 @@ int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
 {
struct platform_device *pdev = to_platform_device(hsotg->dev);
-   int ret = 0;
+   int clk, ret = 0;
 
if (hsotg->uphy) {
usb_phy_shutdown(hsotg->uphy);
@@ -182,8 +185,9 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg 
*hsotg)
if (ret)
return ret;
 
-   if (hsotg->clk)
-   clk_disable_unprepare(hsotg->clk);
+   for (clk = DWC2_MAX_CLKS - 1; clk >= 0; clk--)
+   if (hsotg->clks[clk])
+   clk_disable_unprepare(hsotg->clks[clk]);
 
ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
 hsotg->supplies);
@@ -209,7 +213,7 @@ int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
 
 static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 {
-   int i, ret;
+   int i, clk, ret;
 
hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2");
if (IS_ERR(hsotg->reset)) {
@@ -282,11 +286,20 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
hsotg->phyif = GUSBCFG_PHYIF8;
}
 
-   /* Clock */
-   hsotg->clk = devm_clk_get(hsotg->dev, "otg");
-   if (IS_ERR(hsotg->clk)) {
-   hsotg->clk = NULL;
-   dev_dbg(hsotg->dev, "cannot get otg clock\n");
+   /* Clocks */
+   for (clk = 0; clk < DWC2_MAX_CLKS; clk++) {
+   hsotg->clks[clk] = of_clk_get(hsotg->dev->of_node, clk);
+   if (IS_ERR(hsotg->clks[clk])) {
+   ret = PTR_ERR(hsotg->clks[clk]);
+   if (ret == -EPROBE_DEFER) {
+   while (--clk >= 0)
+   clk_put(hsotg->clks[clk]);
+   return ret;
+   }
+
+   hsotg->clks[clk] = NULL;
+   break;
+   }
}
 
/* Regulators */
-- 
1.9.1




[RESEND PATCH 0/1] add multiple clock handling for dwc2 driver

2017-02-04 Thread Frank Wang
The original posting on Jan 19th have not received any responses, so I resend 
them.

The Current default dwc2 just handle one clock named otg, however, it may have
two or more clock need to manage for some new SoCs(such as RK3328), so this
adds change clk to clk's array of dwc2_hsotg to handle more clocks operation.

Frank Wang (1):
  usb: dwc2: add multiple clock handling

 drivers/usb/dwc2/core.h |  5 -
 drivers/usb/dwc2/platform.c | 39 ++-
 2 files changed, 30 insertions(+), 14 deletions(-)

-- 
1.9.1




[RESEND PATCH 1/1] usb: dwc2: add multiple clock handling

2017-02-04 Thread Frank Wang
Originally, dwc2 just handle one clock named otg, however, it may have
two or more clock need to manage for some new SoCs, so this adds
change clk to clk's array of dwc2_hsotg to handle more clocks operation.

Signed-off-by: Frank Wang 
---
 drivers/usb/dwc2/core.h |  5 -
 drivers/usb/dwc2/platform.c | 39 ++-
 2 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 1a7e830..d10a466 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -121,6 +121,9 @@ static inline void dwc2_writel(u32 value, void __iomem 
*addr)
 /* Maximum number of Endpoints/HostChannels */
 #define MAX_EPS_CHANNELS   16
 
+/* Maximum number of dwc2 clocks */
+#define DWC2_MAX_CLKS 3
+
 /* dwc2-hsotg declarations */
 static const char * const dwc2_hsotg_supply_names[] = {
"vusb_d",   /* digital USB supply, 1.2V */
@@ -913,7 +916,7 @@ struct dwc2_hsotg {
spinlock_t lock;
void *priv;
int irq;
-   struct clk *clk;
+   struct clk *clks[DWC2_MAX_CLKS];
struct reset_control *reset;
 
unsigned int queuing_high_bandwidth:1;
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 9564bc7..795fc43b 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -123,17 +123,20 @@ static int dwc2_get_dr_mode(struct dwc2_hsotg *hsotg)
 static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 {
struct platform_device *pdev = to_platform_device(hsotg->dev);
-   int ret;
+   int clk, ret;
 
ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies),
hsotg->supplies);
if (ret)
return ret;
 
-   if (hsotg->clk) {
-   ret = clk_prepare_enable(hsotg->clk);
-   if (ret)
+   for (clk = 0; clk < DWC2_MAX_CLKS && hsotg->clks[clk]; clk++) {
+   ret = clk_prepare_enable(hsotg->clks[clk]);
+   if (ret) {
+   while (--clk >= 0)
+   clk_disable_unprepare(hsotg->clks[clk]);
return ret;
+   }
}
 
if (hsotg->uphy) {
@@ -168,7 +171,7 @@ int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
 static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
 {
struct platform_device *pdev = to_platform_device(hsotg->dev);
-   int ret = 0;
+   int clk, ret = 0;
 
if (hsotg->uphy) {
usb_phy_shutdown(hsotg->uphy);
@@ -182,8 +185,9 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg 
*hsotg)
if (ret)
return ret;
 
-   if (hsotg->clk)
-   clk_disable_unprepare(hsotg->clk);
+   for (clk = DWC2_MAX_CLKS - 1; clk >= 0; clk--)
+   if (hsotg->clks[clk])
+   clk_disable_unprepare(hsotg->clks[clk]);
 
ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies),
 hsotg->supplies);
@@ -209,7 +213,7 @@ int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg)
 
 static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 {
-   int i, ret;
+   int i, clk, ret;
 
hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2");
if (IS_ERR(hsotg->reset)) {
@@ -282,11 +286,20 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
hsotg->phyif = GUSBCFG_PHYIF8;
}
 
-   /* Clock */
-   hsotg->clk = devm_clk_get(hsotg->dev, "otg");
-   if (IS_ERR(hsotg->clk)) {
-   hsotg->clk = NULL;
-   dev_dbg(hsotg->dev, "cannot get otg clock\n");
+   /* Clocks */
+   for (clk = 0; clk < DWC2_MAX_CLKS; clk++) {
+   hsotg->clks[clk] = of_clk_get(hsotg->dev->of_node, clk);
+   if (IS_ERR(hsotg->clks[clk])) {
+   ret = PTR_ERR(hsotg->clks[clk]);
+   if (ret == -EPROBE_DEFER) {
+   while (--clk >= 0)
+   clk_put(hsotg->clks[clk]);
+   return ret;
+   }
+
+   hsotg->clks[clk] = NULL;
+   break;
+   }
}
 
/* Regulators */
-- 
1.9.1




Re: [PATCH v3 0/2] iov_iter: allow iov_iter_get_pages_alloc to allocate more pages per call

2017-02-04 Thread Al Viro
On Sat, Feb 04, 2017 at 11:11:27PM +0100, Miklos Szeredi wrote:

> Well, it's not historical; at least not yet.  The deadlock is there
> alright: mmap fuse file to addr; read byte from mapped page -> page
> locked; this triggeres read request served in same process but
> separate thread; write addr-headerlen to fuse dev; trying to lock same
> page -> deadlock.

Let me see if I got it straight - you have the same fuse file mmapped
in two processes, one of them being fuse server (either sharing the
entire address space, or the same area mapped in both).  Another process
faults the sucker in; filemap_fault() locks the page and goes
fuse_readpage() -> fuse_do_readpage() -> fuse_send_read() ->
-> fuse_request_send() -> __fuse_request_send() which puts request into
queue and goes to sleep in request_wait_answer().  Eventually, read()
on /dev/fuse (or splice(), whatever) by server picks that request and reply
is formed and fed back into /dev/fuse.  There we (in fuse_do_dev_write())
call copy_out_args(), which tries to copy into our (still locked) page
a piece of data coming from server-supplied iovec.  As it is, you
are calling get_user_pages_fast(), triggering handle_mm_fault().  Since that
malicous FPOS of a server tried to feed you the _same_ mmapped file, you
hit a deadlock.  In server's context.  Correct?

Convoluted, but possible.  But.  Why the hell do we care whether that deadlock
hits in get_user_pages_fast() or in copy_from_user()?  Put it another way,
what difference does it make whether we take that fault with or without
FR_LOCKED in req->flags?

> The deadlock can be broken by aborting or force unmounting: return
> error for original read request; page unlocked; device write can get
> page lock and return.
> 
> The reason we need to prohibit pagefault while copying is that when
> request is aborted and the caller returns the memory in the request
> may become invalid (e.g. data from stack).

???

IDGI.  Your request is marked aborted and should presumably fail, so
that when request_wait_answer() wakes up and finds it screwed, fuse_readpage()
would just return an error and filemap_fault() will return VM_FAULT_SIGBUS,
with page left not uptodate and _not_ inserted into page tables.  What's
leaking where?


Re: [PATCH v3 0/2] iov_iter: allow iov_iter_get_pages_alloc to allocate more pages per call

2017-02-04 Thread Al Viro
On Sat, Feb 04, 2017 at 11:11:27PM +0100, Miklos Szeredi wrote:

> Well, it's not historical; at least not yet.  The deadlock is there
> alright: mmap fuse file to addr; read byte from mapped page -> page
> locked; this triggeres read request served in same process but
> separate thread; write addr-headerlen to fuse dev; trying to lock same
> page -> deadlock.

Let me see if I got it straight - you have the same fuse file mmapped
in two processes, one of them being fuse server (either sharing the
entire address space, or the same area mapped in both).  Another process
faults the sucker in; filemap_fault() locks the page and goes
fuse_readpage() -> fuse_do_readpage() -> fuse_send_read() ->
-> fuse_request_send() -> __fuse_request_send() which puts request into
queue and goes to sleep in request_wait_answer().  Eventually, read()
on /dev/fuse (or splice(), whatever) by server picks that request and reply
is formed and fed back into /dev/fuse.  There we (in fuse_do_dev_write())
call copy_out_args(), which tries to copy into our (still locked) page
a piece of data coming from server-supplied iovec.  As it is, you
are calling get_user_pages_fast(), triggering handle_mm_fault().  Since that
malicous FPOS of a server tried to feed you the _same_ mmapped file, you
hit a deadlock.  In server's context.  Correct?

Convoluted, but possible.  But.  Why the hell do we care whether that deadlock
hits in get_user_pages_fast() or in copy_from_user()?  Put it another way,
what difference does it make whether we take that fault with or without
FR_LOCKED in req->flags?

> The deadlock can be broken by aborting or force unmounting: return
> error for original read request; page unlocked; device write can get
> page lock and return.
> 
> The reason we need to prohibit pagefault while copying is that when
> request is aborted and the caller returns the memory in the request
> may become invalid (e.g. data from stack).

???

IDGI.  Your request is marked aborted and should presumably fail, so
that when request_wait_answer() wakes up and finds it screwed, fuse_readpage()
would just return an error and filemap_fault() will return VM_FAULT_SIGBUS,
with page left not uptodate and _not_ inserted into page tables.  What's
leaking where?


scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file or directory

2017-02-04 Thread kbuild test robot
Hi Emese,

FYI, the error/warning still remains.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   a572a1b999489efb591287632279c6c9eca3e4ed
commit: 543c37cb165049c3be24a0d4733e67caa2b33eef Add sancov plugin
date:   8 months ago
config: x86_64-randconfig-in0-02050939 (attached as .config)
compiler: gcc-4.6 (Debian 4.6.4-7) 4.6.4
reproduce:
git checkout 543c37cb165049c3be24a0d4733e67caa2b33eef
# save the attached .config to linux build tree
make ARCH=x86_64 

All errors (new ones prefixed by >>):

   scripts/Makefile.kasan:19: Cannot use CONFIG_KASAN: 
-fsanitize=kernel-address is not supported by compiler
   scripts/Makefile.gcc-plugins:17: warning: cannot use CONFIG_KCOV: 
-fsanitize-coverage=trace-pc is not supported by compiler
   ++(scripts/gcc-plugin.sh:2): main(): dirname scripts/gcc-plugin.sh
   +(scripts/gcc-plugin.sh:2): main(): srctree=scripts
   ++(scripts/gcc-plugin.sh:3): main(): gcc-4.6 -print-file-name=plugin
   +(scripts/gcc-plugin.sh:3): main(): gccplugins_dir=plugin
   ++(scripts/gcc-plugin.sh:12): main(): gcc-4.6 -E -x c++ - -o /dev/null 
-Iscripts/gcc-plugins -Iplugin/include
   +(scripts/gcc-plugin.sh:12): main(): plugincc='In file included from 
:1:0:
>> scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file 
>> or directory
   compilation terminated.'
   +(scripts/gcc-plugin.sh:14): main(): '[' 1 -ne 0 ']'
   +(scripts/gcc-plugin.sh:16): main(): exit 1
   scripts/Makefile.gcc-plugins:30: warning: your gcc installation does not 
support plugins, perhaps the necessary headers are missing?
   Makefile:677: Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: -fstack-protector 
not supported by compiler
   scripts/Makefile.kasan:19: Cannot use CONFIG_KASAN: 
-fsanitize=kernel-address is not supported by compiler
   In file included from scripts/gcc-plugins/sancov_plugin.c:22:0:
>> scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file 
>> or directory
#include "bversion.h"
 ^
   compilation terminated.
   In file included from scripts/gcc-plugins/cyc_complexity_plugin.c:21:0:
>> scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file 
>> or directory
#include "bversion.h"
 ^
   compilation terminated.
   make[2]: *** [scripts/gcc-plugins/cyc_complexity_plugin.o] Error 1
   make[2]: *** [scripts/gcc-plugins/sancov_plugin.o] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [gcc-plugins] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +4 scripts/gcc-plugins/gcc-common.h

6b90bd4b Emese Revfy 2016-05-24  1  #ifndef GCC_COMMON_H_INCLUDED
6b90bd4b Emese Revfy 2016-05-24  2  #define GCC_COMMON_H_INCLUDED
6b90bd4b Emese Revfy 2016-05-24  3  
6b90bd4b Emese Revfy 2016-05-24 @4  #include "bversion.h"
6b90bd4b Emese Revfy 2016-05-24  5  #if BUILDING_GCC_VERSION >= 6000
6b90bd4b Emese Revfy 2016-05-24  6  #include "gcc-plugin.h"
6b90bd4b Emese Revfy 2016-05-24  7  #else

:: The code at line 4 was first introduced by commit
:: 6b90bd4ba40b38dc13c2782469c1c77e4ed79915 GCC plugin infrastructure

:: TO: Emese Revfy 
:: CC: Michal Marek 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file or directory

2017-02-04 Thread kbuild test robot
Hi Emese,

FYI, the error/warning still remains.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   a572a1b999489efb591287632279c6c9eca3e4ed
commit: 543c37cb165049c3be24a0d4733e67caa2b33eef Add sancov plugin
date:   8 months ago
config: x86_64-randconfig-in0-02050939 (attached as .config)
compiler: gcc-4.6 (Debian 4.6.4-7) 4.6.4
reproduce:
git checkout 543c37cb165049c3be24a0d4733e67caa2b33eef
# save the attached .config to linux build tree
make ARCH=x86_64 

All errors (new ones prefixed by >>):

   scripts/Makefile.kasan:19: Cannot use CONFIG_KASAN: 
-fsanitize=kernel-address is not supported by compiler
   scripts/Makefile.gcc-plugins:17: warning: cannot use CONFIG_KCOV: 
-fsanitize-coverage=trace-pc is not supported by compiler
   ++(scripts/gcc-plugin.sh:2): main(): dirname scripts/gcc-plugin.sh
   +(scripts/gcc-plugin.sh:2): main(): srctree=scripts
   ++(scripts/gcc-plugin.sh:3): main(): gcc-4.6 -print-file-name=plugin
   +(scripts/gcc-plugin.sh:3): main(): gccplugins_dir=plugin
   ++(scripts/gcc-plugin.sh:12): main(): gcc-4.6 -E -x c++ - -o /dev/null 
-Iscripts/gcc-plugins -Iplugin/include
   +(scripts/gcc-plugin.sh:12): main(): plugincc='In file included from 
:1:0:
>> scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file 
>> or directory
   compilation terminated.'
   +(scripts/gcc-plugin.sh:14): main(): '[' 1 -ne 0 ']'
   +(scripts/gcc-plugin.sh:16): main(): exit 1
   scripts/Makefile.gcc-plugins:30: warning: your gcc installation does not 
support plugins, perhaps the necessary headers are missing?
   Makefile:677: Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: -fstack-protector 
not supported by compiler
   scripts/Makefile.kasan:19: Cannot use CONFIG_KASAN: 
-fsanitize=kernel-address is not supported by compiler
   In file included from scripts/gcc-plugins/sancov_plugin.c:22:0:
>> scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file 
>> or directory
#include "bversion.h"
 ^
   compilation terminated.
   In file included from scripts/gcc-plugins/cyc_complexity_plugin.c:21:0:
>> scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file 
>> or directory
#include "bversion.h"
 ^
   compilation terminated.
   make[2]: *** [scripts/gcc-plugins/cyc_complexity_plugin.o] Error 1
   make[2]: *** [scripts/gcc-plugins/sancov_plugin.o] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [gcc-plugins] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +4 scripts/gcc-plugins/gcc-common.h

6b90bd4b Emese Revfy 2016-05-24  1  #ifndef GCC_COMMON_H_INCLUDED
6b90bd4b Emese Revfy 2016-05-24  2  #define GCC_COMMON_H_INCLUDED
6b90bd4b Emese Revfy 2016-05-24  3  
6b90bd4b Emese Revfy 2016-05-24 @4  #include "bversion.h"
6b90bd4b Emese Revfy 2016-05-24  5  #if BUILDING_GCC_VERSION >= 6000
6b90bd4b Emese Revfy 2016-05-24  6  #include "gcc-plugin.h"
6b90bd4b Emese Revfy 2016-05-24  7  #else

:: The code at line 4 was first introduced by commit
:: 6b90bd4ba40b38dc13c2782469c1c77e4ed79915 GCC plugin infrastructure

:: TO: Emese Revfy 
:: CC: Michal Marek 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 4/5] Input: xpad - restore LED state after device resume

2017-02-04 Thread Cameron Gutman

On 02/04/2017 05:17 PM, kbuild test robot wrote:
> Hi Cameron,
> 
> [auto build test ERROR on input/next]
> [also build test ERROR on v4.10-rc6 next-20170203]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
> 
> url:
> https://github.com/0day-ci/linux/commits/Cameron-Gutman/Correctly-support-some-quirky-Xbox-One-pads/20170205-083659
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
> config: x86_64-randconfig-x016-201706 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64 
> 
> All errors (new ones prefixed by >>):
> 
>drivers/input/joystick/xpad.c: In function 'xpad_resume':
>>> drivers/input/joystick/xpad.c:1700:10: error: 'struct usb_xpad' has no 
>>> member named 'led'
>  if (xpad->led)
>  ^~
>>> drivers/input/joystick/xpad.c:1701:3: error: implicit declaration of 
>>> function 'xpad_send_led_command' [-Werror=implicit-function-declaration]
>   xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
>   ^
>drivers/input/joystick/xpad.c:1701:35: error: 'struct usb_xpad' has no 
> member named 'led'
>   xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
>   ^~
>cc1: some warnings being treated as errors

Whoops, missed a CONFIG_JOYSTICK_XPAD_LEDS guard around that.

I'll send a v2 in the next day or two, incorporating this fix plus any review
comments made in the meantime.

> 
> vim +1700 drivers/input/joystick/xpad.c
> 
>   1694retval = xpad_start_xbox_one(xpad);
>   1695}
>   1696mutex_unlock(>mutex);
>   1697}
>   1698
>   1699/* LED state is lost across resume, so resend the last 
> command */
>> 1700 if (xpad->led)
>> 1701 xpad_send_led_command(xpad, 
>> xpad->led->led_cdev.brightness);
>   1702
>   1703return retval;
>   1704}
> 
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation
> 

Regards,
Cameron


Re: [PATCH 4/5] Input: xpad - restore LED state after device resume

2017-02-04 Thread Cameron Gutman

On 02/04/2017 05:17 PM, kbuild test robot wrote:
> Hi Cameron,
> 
> [auto build test ERROR on input/next]
> [also build test ERROR on v4.10-rc6 next-20170203]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
> 
> url:
> https://github.com/0day-ci/linux/commits/Cameron-Gutman/Correctly-support-some-quirky-Xbox-One-pads/20170205-083659
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
> config: x86_64-randconfig-x016-201706 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64 
> 
> All errors (new ones prefixed by >>):
> 
>drivers/input/joystick/xpad.c: In function 'xpad_resume':
>>> drivers/input/joystick/xpad.c:1700:10: error: 'struct usb_xpad' has no 
>>> member named 'led'
>  if (xpad->led)
>  ^~
>>> drivers/input/joystick/xpad.c:1701:3: error: implicit declaration of 
>>> function 'xpad_send_led_command' [-Werror=implicit-function-declaration]
>   xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
>   ^
>drivers/input/joystick/xpad.c:1701:35: error: 'struct usb_xpad' has no 
> member named 'led'
>   xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
>   ^~
>cc1: some warnings being treated as errors

Whoops, missed a CONFIG_JOYSTICK_XPAD_LEDS guard around that.

I'll send a v2 in the next day or two, incorporating this fix plus any review
comments made in the meantime.

> 
> vim +1700 drivers/input/joystick/xpad.c
> 
>   1694retval = xpad_start_xbox_one(xpad);
>   1695}
>   1696mutex_unlock(>mutex);
>   1697}
>   1698
>   1699/* LED state is lost across resume, so resend the last 
> command */
>> 1700 if (xpad->led)
>> 1701 xpad_send_led_command(xpad, 
>> xpad->led->led_cdev.brightness);
>   1702
>   1703return retval;
>   1704}
> 
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation
> 

Regards,
Cameron


Re: [PATCH v4 6/8] ARM: dts: sun8i: Add audio codec, dai and card for A33

2017-02-04 Thread kbuild test robot
Hi Mylène,

[auto build test ERROR on asoc/for-next]
[also build test ERROR on v4.10-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Myl-ne-Josserand/Add-sun8i-A33-audio-driver/20170202-173022
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 
for-next
config: arm-vf610m4_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm 

All errors (new ones prefixed by >>):

>> ERROR: Input tree has errors, aborting (use -f to force output)

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH v4 6/8] ARM: dts: sun8i: Add audio codec, dai and card for A33

2017-02-04 Thread kbuild test robot
Hi Mylène,

[auto build test ERROR on asoc/for-next]
[also build test ERROR on v4.10-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Myl-ne-Josserand/Add-sun8i-A33-audio-driver/20170202-173022
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 
for-next
config: arm-vf610m4_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm 

All errors (new ones prefixed by >>):

>> ERROR: Input tree has errors, aborting (use -f to force output)

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: Regression on next-20170203 spi/for-next 3f87493930a0f qemu on x86_64

2017-02-04 Thread Guenter Roeck

On 02/04/2017 12:05 PM, Luis R. Rodriguez wrote:

I could not boot next-20170203 on my x86_64 qemu instance. It stalls at:

[0.015549] CPU: Physical Processor ID: 0
[0.015842] mce: CPU supports 10 MCE banks
[0.016032] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0
[0.016393] Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0, 1GB 0
[0.016871] Freeing SMP alternatives memory: 24K
[0.017710] ftrace: allocating 25888 entries in 102 pages
[0.024102] smpboot: Max logical packages: 4
[0.024524] x2apic enabled
[0.024851] Switched APIC routing to physical x2apic.
[0.025755] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1



There may be a possible problem or change in the timer code. For the most
part the "kvm64" cpu works for me, but I saw this once:

smpboot: Max logical packages: 1
..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
..MP-BIOS bug: 8254 timer not connected to IO-APIC
...trying to set up timer (IRQ0) through the 8259A ...
. (found apic 0 pin 2) ...
... failed.
...trying to set up timer as Virtual Wire IRQ...
. failed.
...trying to set up timer as ExtINT IRQ...
. failed :(.
Kernel panic - not syncing: IO-APIC + timer doesn't work!  Boot with apic=debug 
and send a report.  Then try booting with the 'noapic' option.

The "normal" log with -next looks as follows:

smpboot: Max logical packages: 4
..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
..MP-BIOS bug: 8254 timer not connected to IO-APIC
...trying to set up timer (IRQ0) through the 8259A ...
. (found apic 0 pin 2) ...
... failed.
...trying to set up timer as Virtual Wire IRQ...
. failed.
...trying to set up timer as ExtINT IRQ...
. works.

Upstream (v4.10-rc6-193-ga572a1b99948), the same command yields no error at all:

..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
smpboot: CPU0: Intel Common KVM processor (family: 0xf, model: 0x6, stepping: 
0x1)

The "new" error message is also seen with other CPUs, not just with "kvm64".

I am using qemu 2.8.

Maybe we should try to figure out where the new error messages come from ?

Thanks,
Guenter



Re: Regression on next-20170203 spi/for-next 3f87493930a0f qemu on x86_64

2017-02-04 Thread Guenter Roeck

On 02/04/2017 12:05 PM, Luis R. Rodriguez wrote:

I could not boot next-20170203 on my x86_64 qemu instance. It stalls at:

[0.015549] CPU: Physical Processor ID: 0
[0.015842] mce: CPU supports 10 MCE banks
[0.016032] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0
[0.016393] Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0, 1GB 0
[0.016871] Freeing SMP alternatives memory: 24K
[0.017710] ftrace: allocating 25888 entries in 102 pages
[0.024102] smpboot: Max logical packages: 4
[0.024524] x2apic enabled
[0.024851] Switched APIC routing to physical x2apic.
[0.025755] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1



There may be a possible problem or change in the timer code. For the most
part the "kvm64" cpu works for me, but I saw this once:

smpboot: Max logical packages: 1
..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
..MP-BIOS bug: 8254 timer not connected to IO-APIC
...trying to set up timer (IRQ0) through the 8259A ...
. (found apic 0 pin 2) ...
... failed.
...trying to set up timer as Virtual Wire IRQ...
. failed.
...trying to set up timer as ExtINT IRQ...
. failed :(.
Kernel panic - not syncing: IO-APIC + timer doesn't work!  Boot with apic=debug 
and send a report.  Then try booting with the 'noapic' option.

The "normal" log with -next looks as follows:

smpboot: Max logical packages: 4
..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
..MP-BIOS bug: 8254 timer not connected to IO-APIC
...trying to set up timer (IRQ0) through the 8259A ...
. (found apic 0 pin 2) ...
... failed.
...trying to set up timer as Virtual Wire IRQ...
. failed.
...trying to set up timer as ExtINT IRQ...
. works.

Upstream (v4.10-rc6-193-ga572a1b99948), the same command yields no error at all:

..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
smpboot: CPU0: Intel Common KVM processor (family: 0xf, model: 0x6, stepping: 
0x1)

The "new" error message is also seen with other CPUs, not just with "kvm64".

I am using qemu 2.8.

Maybe we should try to figure out where the new error messages come from ?

Thanks,
Guenter



Re: [PATCH 4/5] Input: xpad - restore LED state after device resume

2017-02-04 Thread kbuild test robot
Hi Cameron,

[auto build test ERROR on input/next]
[also build test ERROR on v4.10-rc6 next-20170203]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Cameron-Gutman/Correctly-support-some-quirky-Xbox-One-pads/20170205-083659
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
config: x86_64-randconfig-x016-201706 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/input/joystick/xpad.c: In function 'xpad_resume':
>> drivers/input/joystick/xpad.c:1700:10: error: 'struct usb_xpad' has no 
>> member named 'led'
 if (xpad->led)
 ^~
>> drivers/input/joystick/xpad.c:1701:3: error: implicit declaration of 
>> function 'xpad_send_led_command' [-Werror=implicit-function-declaration]
  xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
  ^
   drivers/input/joystick/xpad.c:1701:35: error: 'struct usb_xpad' has no 
member named 'led'
  xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
  ^~
   cc1: some warnings being treated as errors

vim +1700 drivers/input/joystick/xpad.c

  1694  retval = xpad_start_xbox_one(xpad);
  1695  }
  1696  mutex_unlock(>mutex);
  1697  }
  1698  
  1699  /* LED state is lost across resume, so resend the last command 
*/
> 1700  if (xpad->led)
> 1701  xpad_send_led_command(xpad, 
> xpad->led->led_cdev.brightness);
  1702  
  1703  return retval;
  1704  }

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 4/5] Input: xpad - restore LED state after device resume

2017-02-04 Thread kbuild test robot
Hi Cameron,

[auto build test ERROR on input/next]
[also build test ERROR on v4.10-rc6 next-20170203]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Cameron-Gutman/Correctly-support-some-quirky-Xbox-One-pads/20170205-083659
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
config: x86_64-randconfig-x016-201706 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/input/joystick/xpad.c: In function 'xpad_resume':
>> drivers/input/joystick/xpad.c:1700:10: error: 'struct usb_xpad' has no 
>> member named 'led'
 if (xpad->led)
 ^~
>> drivers/input/joystick/xpad.c:1701:3: error: implicit declaration of 
>> function 'xpad_send_led_command' [-Werror=implicit-function-declaration]
  xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
  ^
   drivers/input/joystick/xpad.c:1701:35: error: 'struct usb_xpad' has no 
member named 'led'
  xpad_send_led_command(xpad, xpad->led->led_cdev.brightness);
  ^~
   cc1: some warnings being treated as errors

vim +1700 drivers/input/joystick/xpad.c

  1694  retval = xpad_start_xbox_one(xpad);
  1695  }
  1696  mutex_unlock(>mutex);
  1697  }
  1698  
  1699  /* LED state is lost across resume, so resend the last command 
*/
> 1700  if (xpad->led)
> 1701  xpad_send_led_command(xpad, 
> xpad->led->led_cdev.brightness);
  1702  
  1703  return retval;
  1704  }

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: rtlwifi: rtl8192c_common: "BUG: KASAN: slab-out-of-bounds"

2017-02-04 Thread Larry Finger

On 02/04/2017 01:32 PM, Dmitry Osipenko wrote:

On 04.02.2017 21:41, Larry Finger wrote:

On 02/04/2017 10:58 AM, Dmitry Osipenko wrote:

Seems the problem is caused by rtl92c_dm_*() casting .priv to "struct
rtl_pci_priv", while it is "struct rtl_usb_priv".


Those routines are shared by rtl8192ce and rtl8192cu, thus we need to make that
difference in cast to be immaterial. I think we need to move "struct
bt_coexist_info" to the beginning of both rtlpci_priv and rtl_usb_priv. Then it
should not matter.

I do not have a gcc version new enough to turn KASAN testing on, thus the
attached patch is only compile tested. Does it fix the problem?


Thank you for the patch, it indeed fixes the bug.

I noticed that struct rtl_priv contains .btcoexist, isn't it duplicated in the
struct rtl_pci_priv?


Thanks for testing. When I submit the patch, is it OK to cite your reporting and 
testing?


Yes, the bt_coexist_info structure is in two different places. I will change the 
code in rtl8192c-common and rtl8192ce to use only the one in rtlpriv. That 
should satisfy the problem you reported, as well as clean up the code.


Thanks again,

Larry




Re: rtlwifi: rtl8192c_common: "BUG: KASAN: slab-out-of-bounds"

2017-02-04 Thread Larry Finger

On 02/04/2017 01:32 PM, Dmitry Osipenko wrote:

On 04.02.2017 21:41, Larry Finger wrote:

On 02/04/2017 10:58 AM, Dmitry Osipenko wrote:

Seems the problem is caused by rtl92c_dm_*() casting .priv to "struct
rtl_pci_priv", while it is "struct rtl_usb_priv".


Those routines are shared by rtl8192ce and rtl8192cu, thus we need to make that
difference in cast to be immaterial. I think we need to move "struct
bt_coexist_info" to the beginning of both rtlpci_priv and rtl_usb_priv. Then it
should not matter.

I do not have a gcc version new enough to turn KASAN testing on, thus the
attached patch is only compile tested. Does it fix the problem?


Thank you for the patch, it indeed fixes the bug.

I noticed that struct rtl_priv contains .btcoexist, isn't it duplicated in the
struct rtl_pci_priv?


Thanks for testing. When I submit the patch, is it OK to cite your reporting and 
testing?


Yes, the bt_coexist_info structure is in two different places. I will change the 
code in rtl8192c-common and rtl8192ce to use only the one in rtlpriv. That 
should satisfy the problem you reported, as well as clean up the code.


Thanks again,

Larry




Re: [PATCH 1/2] watchdog: sama5d4: Cache MR instead of a partial config

2017-02-04 Thread Guenter Roeck

On 01/30/2017 09:18 AM, Alexandre Belloni wrote:

.config is used to cache a part of WDT_MR at probe time and is not used
afterwards. Instead of doing that, actually cache MR and avoid reading it
every time it is modified.

Signed-off-by: Alexandre Belloni 


Reviewed-by: Guenter Roeck 

[ hoping that you'll remember to fix the problem in the set_timeout function ]


---
 drivers/watchdog/sama5d4_wdt.c | 45 ++
 1 file changed, 19 insertions(+), 26 deletions(-)

diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
index a49634cdc1cc..6dd07bef515a 100644
--- a/drivers/watchdog/sama5d4_wdt.c
+++ b/drivers/watchdog/sama5d4_wdt.c
@@ -28,7 +28,7 @@
 struct sama5d4_wdt {
struct watchdog_device  wdd;
void __iomem*reg_base;
-   u32 config;
+   u32 mr;
 };

 static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
@@ -53,11 +53,9 @@ MODULE_PARM_DESC(nowayout,
 static int sama5d4_wdt_start(struct watchdog_device *wdd)
 {
struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
-   u32 reg;

-   reg = wdt_read(wdt, AT91_WDT_MR);
-   reg &= ~AT91_WDT_WDDIS;
-   wdt_write(wdt, AT91_WDT_MR, reg);
+   wdt->mr &= ~AT91_WDT_WDDIS;
+   wdt_write(wdt, AT91_WDT_MR, wdt->mr);

return 0;
 }
@@ -65,11 +63,9 @@ static int sama5d4_wdt_start(struct watchdog_device *wdd)
 static int sama5d4_wdt_stop(struct watchdog_device *wdd)
 {
struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
-   u32 reg;

-   reg = wdt_read(wdt, AT91_WDT_MR);
-   reg |= AT91_WDT_WDDIS;
-   wdt_write(wdt, AT91_WDT_MR, reg);
+   wdt->mr |= AT91_WDT_WDDIS;
+   wdt_write(wdt, AT91_WDT_MR, wdt->mr);

return 0;
 }
@@ -88,14 +84,12 @@ static int sama5d4_wdt_set_timeout(struct watchdog_device 
*wdd,
 {
struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
u32 value = WDT_SEC2TICKS(timeout);
-   u32 reg;

-   reg = wdt_read(wdt, AT91_WDT_MR);
-   reg &= ~AT91_WDT_WDV;
-   reg &= ~AT91_WDT_WDD;
-   reg |= AT91_WDT_SET_WDV(value);
-   reg |= AT91_WDT_SET_WDD(value);
-   wdt_write(wdt, AT91_WDT_MR, reg);
+   wdt->mr &= ~AT91_WDT_WDV;
+   wdt->mr &= ~AT91_WDT_WDD;
+   wdt->mr |= AT91_WDT_SET_WDV(value);
+   wdt->mr |= AT91_WDT_SET_WDD(value);
+   wdt_write(wdt, AT91_WDT_MR, wdt->mr);

wdd->timeout = timeout;

@@ -132,19 +126,19 @@ static int of_sama5d4_wdt_init(struct device_node *np, 
struct sama5d4_wdt *wdt)
 {
const char *tmp;

-   wdt->config = AT91_WDT_WDDIS;
+   wdt->mr = AT91_WDT_WDDIS;

if (!of_property_read_string(np, "atmel,watchdog-type", ) &&
!strcmp(tmp, "software"))
-   wdt->config |= AT91_WDT_WDFIEN;
+   wdt->mr |= AT91_WDT_WDFIEN;
else
-   wdt->config |= AT91_WDT_WDRSTEN;
+   wdt->mr |= AT91_WDT_WDRSTEN;

if (of_property_read_bool(np, "atmel,idle-halt"))
-   wdt->config |= AT91_WDT_WDIDLEHLT;
+   wdt->mr |= AT91_WDT_WDIDLEHLT;

if (of_property_read_bool(np, "atmel,dbg-halt"))
-   wdt->config |= AT91_WDT_WDDBGHLT;
+   wdt->mr |= AT91_WDT_WDDBGHLT;

return 0;
 }
@@ -163,11 +157,10 @@ static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
reg &= ~AT91_WDT_WDDIS;
wdt_write(wdt, AT91_WDT_MR, reg);

-   reg = wdt->config;
-   reg |= AT91_WDT_SET_WDD(value);
-   reg |= AT91_WDT_SET_WDV(value);
+   wdt->mr |= AT91_WDT_SET_WDD(value);
+   wdt->mr |= AT91_WDT_SET_WDV(value);

-   wdt_write(wdt, AT91_WDT_MR, reg);
+   wdt_write(wdt, AT91_WDT_MR, wdt->mr);

return 0;
 }
@@ -211,7 +204,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
return ret;
}

-   if ((wdt->config & AT91_WDT_WDFIEN) && irq) {
+   if ((wdt->mr & AT91_WDT_WDFIEN) && irq) {
ret = devm_request_irq(>dev, irq, sama5d4_wdt_irq_handler,
   IRQF_SHARED | IRQF_IRQPOLL |
   IRQF_NO_SUSPEND, pdev->name, pdev);





Re: [PATCH 1/2] watchdog: sama5d4: Cache MR instead of a partial config

2017-02-04 Thread Guenter Roeck

On 01/30/2017 09:18 AM, Alexandre Belloni wrote:

.config is used to cache a part of WDT_MR at probe time and is not used
afterwards. Instead of doing that, actually cache MR and avoid reading it
every time it is modified.

Signed-off-by: Alexandre Belloni 


Reviewed-by: Guenter Roeck 

[ hoping that you'll remember to fix the problem in the set_timeout function ]


---
 drivers/watchdog/sama5d4_wdt.c | 45 ++
 1 file changed, 19 insertions(+), 26 deletions(-)

diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
index a49634cdc1cc..6dd07bef515a 100644
--- a/drivers/watchdog/sama5d4_wdt.c
+++ b/drivers/watchdog/sama5d4_wdt.c
@@ -28,7 +28,7 @@
 struct sama5d4_wdt {
struct watchdog_device  wdd;
void __iomem*reg_base;
-   u32 config;
+   u32 mr;
 };

 static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
@@ -53,11 +53,9 @@ MODULE_PARM_DESC(nowayout,
 static int sama5d4_wdt_start(struct watchdog_device *wdd)
 {
struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
-   u32 reg;

-   reg = wdt_read(wdt, AT91_WDT_MR);
-   reg &= ~AT91_WDT_WDDIS;
-   wdt_write(wdt, AT91_WDT_MR, reg);
+   wdt->mr &= ~AT91_WDT_WDDIS;
+   wdt_write(wdt, AT91_WDT_MR, wdt->mr);

return 0;
 }
@@ -65,11 +63,9 @@ static int sama5d4_wdt_start(struct watchdog_device *wdd)
 static int sama5d4_wdt_stop(struct watchdog_device *wdd)
 {
struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
-   u32 reg;

-   reg = wdt_read(wdt, AT91_WDT_MR);
-   reg |= AT91_WDT_WDDIS;
-   wdt_write(wdt, AT91_WDT_MR, reg);
+   wdt->mr |= AT91_WDT_WDDIS;
+   wdt_write(wdt, AT91_WDT_MR, wdt->mr);

return 0;
 }
@@ -88,14 +84,12 @@ static int sama5d4_wdt_set_timeout(struct watchdog_device 
*wdd,
 {
struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
u32 value = WDT_SEC2TICKS(timeout);
-   u32 reg;

-   reg = wdt_read(wdt, AT91_WDT_MR);
-   reg &= ~AT91_WDT_WDV;
-   reg &= ~AT91_WDT_WDD;
-   reg |= AT91_WDT_SET_WDV(value);
-   reg |= AT91_WDT_SET_WDD(value);
-   wdt_write(wdt, AT91_WDT_MR, reg);
+   wdt->mr &= ~AT91_WDT_WDV;
+   wdt->mr &= ~AT91_WDT_WDD;
+   wdt->mr |= AT91_WDT_SET_WDV(value);
+   wdt->mr |= AT91_WDT_SET_WDD(value);
+   wdt_write(wdt, AT91_WDT_MR, wdt->mr);

wdd->timeout = timeout;

@@ -132,19 +126,19 @@ static int of_sama5d4_wdt_init(struct device_node *np, 
struct sama5d4_wdt *wdt)
 {
const char *tmp;

-   wdt->config = AT91_WDT_WDDIS;
+   wdt->mr = AT91_WDT_WDDIS;

if (!of_property_read_string(np, "atmel,watchdog-type", ) &&
!strcmp(tmp, "software"))
-   wdt->config |= AT91_WDT_WDFIEN;
+   wdt->mr |= AT91_WDT_WDFIEN;
else
-   wdt->config |= AT91_WDT_WDRSTEN;
+   wdt->mr |= AT91_WDT_WDRSTEN;

if (of_property_read_bool(np, "atmel,idle-halt"))
-   wdt->config |= AT91_WDT_WDIDLEHLT;
+   wdt->mr |= AT91_WDT_WDIDLEHLT;

if (of_property_read_bool(np, "atmel,dbg-halt"))
-   wdt->config |= AT91_WDT_WDDBGHLT;
+   wdt->mr |= AT91_WDT_WDDBGHLT;

return 0;
 }
@@ -163,11 +157,10 @@ static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
reg &= ~AT91_WDT_WDDIS;
wdt_write(wdt, AT91_WDT_MR, reg);

-   reg = wdt->config;
-   reg |= AT91_WDT_SET_WDD(value);
-   reg |= AT91_WDT_SET_WDV(value);
+   wdt->mr |= AT91_WDT_SET_WDD(value);
+   wdt->mr |= AT91_WDT_SET_WDV(value);

-   wdt_write(wdt, AT91_WDT_MR, reg);
+   wdt_write(wdt, AT91_WDT_MR, wdt->mr);

return 0;
 }
@@ -211,7 +204,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
return ret;
}

-   if ((wdt->config & AT91_WDT_WDFIEN) && irq) {
+   if ((wdt->mr & AT91_WDT_WDFIEN) && irq) {
ret = devm_request_irq(>dev, irq, sama5d4_wdt_irq_handler,
   IRQF_SHARED | IRQF_IRQPOLL |
   IRQF_NO_SUSPEND, pdev->name, pdev);





Re: [PATCH] xen-netfront: Improve error handling during initialization

2017-02-04 Thread David Miller
From: Ross Lagerwall 
Date: Wed, 1 Feb 2017 15:50:22 +

> * Delay timer creation so that if initializing a queue fails, the timer
> has not been setup yet.

setup_timer() doesn't do anything that must be "undone" if an error
occurs and we have to cleanup.

It just assigns some values to some timer struct fields, that's it.

Therefore this change is extraneous and unnecessary.


Re: [PATCH] xen-netfront: Improve error handling during initialization

2017-02-04 Thread David Miller
From: Ross Lagerwall 
Date: Wed, 1 Feb 2017 15:50:22 +

> * Delay timer creation so that if initializing a queue fails, the timer
> has not been setup yet.

setup_timer() doesn't do anything that must be "undone" if an error
occurs and we have to cleanup.

It just assigns some values to some timer struct fields, that's it.

Therefore this change is extraneous and unnecessary.


  1   2   3   4   5   >