* [PATCH V3 2/3] OMAPDSS: DISPC: Handle synclost errors in OMAP3
From: Chandrabhanu Mahapatra @ 2012-04-02 15:25 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In-Reply-To: <1333379598-11544-2-git-send-email-cmahapatra@ti.com>
In OMAP3 DISPC video overlays suffer from some undocumented horizontal position
and timing related limitations leading to SYNCLOST errors. Whenever the image
window is moved towards the right of the screen SYNCLOST errors become
frequent. Checks have been implemented to see that DISPC driver rejects
configuration exceeding above limitations.
This code was successfully tested on OMAP3. This code is written based on code
written by Ville Syrj채l채 <ville.syrjala@nokia.com> in Linux OMAP kernel. Ville
Syrj채l채 <ville.syrjala@nokia.com> had added checks for video overlay horizontal
timing and DISPC horizontal blanking length limitations.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dispc.c | 72 +++++++++++++++++++++++++++++++++++++--
1 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 4ab5433..17ffa71 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1664,6 +1664,63 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
}
}
+/*
+ * This function is used to avoid synclosts in OMAP3, because of some
+ * undocumented horizontal position and timing related limitations.
+ */
+static int check_horiz_timing_omap3(enum omap_channel channel, u16 pos_x,
+ u16 width, u16 height, u16 out_width, u16 out_height)
+{
+ int DS = DIV_ROUND_UP(height, out_height);
+ struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
+ struct omap_video_timings t = dssdev->panel.timings;
+ unsigned long nonactive, lclk, pclk;
+ static const u8 limits[3] = { 8, 10, 20 };
+ u64 val, blank;
+ int i;
+
+ nonactive = t.x_res + t.hfp + t.hsw + t.hbp - out_width;
+ pclk = dispc_mgr_pclk_rate(channel);
+ if (dispc_mgr_is_lcd(channel))
+ lclk = dispc_mgr_lclk_rate(channel);
+ else
+ lclk = dispc_fclk_rate();
+
+ i = 0;
+ if (out_height < height)
+ i++;
+ if (out_width < width)
+ i++;
+ blank = div_u64((u64)(t.hbp + t.hsw + t.hfp) * lclk, pclk);
+ DSSDBG("blanking period + ppl = %llu (limit = %u)\n", blank, limits[i]);
+ if (blank <= limits[i])
+ return -EINVAL;
+
+ /*
+ * Pixel data should be prepared before visible display point starts.
+ * So, atleast DS-2 lines must have already been fetched by DISPC
+ * during nonactive - pos_x period.
+ */
+ val = div_u64((u64)(nonactive - pos_x) * lclk, pclk);
+ DSSDBG("(nonactive - pos_x) * pcd = %llu max(0, DS - 2) * width = %d\n",
+ val, max(0, DS - 2) * width);
+ if (val < max(0, DS - 2) * width)
+ return -EINVAL;
+
+ /*
+ * All lines need to be refilled during the nonactive period of which
+ * only one line can be loaded during the active period. So, atleast
+ * DS - 1 lines should be loaded during nonactive period.
+ */
+ val = div_u64((u64)nonactive * lclk, pclk);
+ DSSDBG("nonactive * pcd = %llu, max(0, DS - 1) * width = %d\n",
+ val, max(0, DS - 1) * width);
+ if (val < max(0, DS - 1) * width)
+ return -EINVAL;
+
+ return 0;
+}
+
static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode)
@@ -1748,7 +1805,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
enum omap_channel channel, u16 width, u16 height,
u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
- int *x_predecim, int *y_predecim)
+ int *x_predecim, int *y_predecim, u16 pos_x)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
@@ -1824,6 +1881,9 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
fclk = calc_fclk_five_taps(channel, in_width, in_height,
out_width, out_height, color_mode);
+ error = check_horiz_timing_omap3(channel, pos_x,
+ in_width, in_height, out_width, out_height);
+
if (in_width > maxsinglelinewidth)
if (in_height > out_height &&
in_height < out_height * 2)
@@ -1831,7 +1891,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
if (!*five_taps)
fclk = calc_fclk(channel, in_width, in_height,
out_width, out_height);
- error = (in_width > maxsinglelinewidth * 2 ||
+ error = (error || in_width > maxsinglelinewidth * 2 ||
(in_width > maxsinglelinewidth && *five_taps) ||
!fclk || fclk > dispc_fclk_rate());
if (error) {
@@ -1847,6 +1907,12 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
} while (decim_x <= *x_predecim && decim_y <= *y_predecim
&& error);
+ if (check_horiz_timing_omap3(channel, pos_x, width, height,
+ out_width, out_height)){
+ DSSERR("horizontal timing too tight\n");
+ return -EINVAL;
+ }
+
if (in_width > (maxsinglelinewidth * 2)) {
DSSERR("Cannot setup scaling");
DSSERR("width exceeds maximum width possible");
@@ -1951,7 +2017,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
r = dispc_ovl_calc_scaling(plane, channel, in_width, in_height,
out_width, out_height, oi->color_mode, &five_taps,
- &x_predecim, &y_predecim);
+ &x_predecim, &y_predecim, oi->pos_x);
if (r)
return r;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH V3 3/3] OMAPDSS: DISPC: Correct DISPC functional clock usage
From: Chandrabhanu Mahapatra @ 2012-04-02 15:25 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Chandrabhanu Mahapatra
In-Reply-To: <1333379598-11544-3-git-send-email-cmahapatra@ti.com>
DISPC_FCLK is incorrectly used as functional clock of DISPC in scaling
calculations. So, DISPC_CORE_CLK replaces as functional clock of DISPC.
DISPC_CORE_CLK is derived from DISPC_FCLK divided by an independent DISPC
divisor LCD.
Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com>
---
drivers/video/omap2/dss/dispc.c | 28 ++++++++++++++++++++++------
drivers/video/omap2/dss/dss.h | 1 +
2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 17ffa71..cfde674 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1813,6 +1813,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
const int max_decim_limit = 16;
unsigned long fclk = 0;
+ unsigned long dispc_core_clk = dispc_core_clk_rate(channel);
int decim_x, decim_y, error, min_factor;
u16 in_width, in_height, in_width_max = 0;
@@ -1855,7 +1856,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
fclk = calc_fclk(channel, in_width, in_height,
out_width, out_height);
error = (in_width > maxsinglelinewidth || !fclk ||
- fclk > dispc_fclk_rate());
+ fclk > dispc_core_clk);
if (error) {
if (decim_x = decim_y) {
decim_x = min_factor;
@@ -1893,7 +1894,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
out_width, out_height);
error = (error || in_width > maxsinglelinewidth * 2 ||
(in_width > maxsinglelinewidth && *five_taps) ||
- !fclk || fclk > dispc_fclk_rate());
+ !fclk || fclk > dispc_core_clk);
if (error) {
if (decim_x = decim_y) {
decim_x = min_factor;
@@ -1926,7 +1927,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
} else {
int decim_x_min = decim_x;
in_height = DIV_ROUND_UP(height, decim_y);
- in_width_max = dispc_fclk_rate() /
+ in_width_max = dispc_core_clk /
DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
out_width);
decim_x = DIV_ROUND_UP(width, in_width_max);
@@ -1950,13 +1951,13 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
}
DSSDBG("required fclk rate = %lu Hz\n", fclk);
- DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
+ DSSDBG("current fclk rate = %lu Hz\n", dispc_core_clk);
- if (!fclk || fclk > dispc_fclk_rate()) {
+ if (!fclk || fclk > dispc_core_clk) {
DSSERR("failed to set up scaling, "
"required fclk rate = %lu Hz, "
"current fclk rate = %lu Hz\n",
- fclk, dispc_fclk_rate());
+ fclk, dispc_core_clk);
return -EINVAL;
}
@@ -2646,6 +2647,21 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
}
}
+unsigned long dispc_core_clk_rate(enum omap_channel channel)
+{
+ int lcd = 1;
+ unsigned long r = dispc_fclk_rate();
+
+ if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
+ lcd = REG_GET(DISPC_DIVISOR, 23, 16);
+ } else {
+ if (dispc_mgr_is_lcd(channel))
+ lcd = REG_GET(DISPC_DIVISORo(channel), 23, 16);
+ }
+
+ return r / lcd ;
+}
+
void dispc_dump_clocks(struct seq_file *s)
{
int lcd, pcd;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d4b3dff..4748923 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -451,6 +451,7 @@ void dispc_mgr_set_pol_freq(enum omap_channel channel,
enum omap_panel_config config, u8 acbi, u8 acb);
unsigned long dispc_mgr_lclk_rate(enum omap_channel channel);
unsigned long dispc_mgr_pclk_rate(enum omap_channel channel);
+unsigned long dispc_core_clk_rate(enum omap_channel channel);
int dispc_mgr_set_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
--
1.7.1
^ permalink raw reply related
* [PATCH] userns: Replace netlink uses of cap_raised with capable.
From: Eric W. Biederman @ 2012-04-04 1:55 UTC (permalink / raw)
To: Andrew Morton
Cc: Serge E. Hallyn, Philipp Reisner, Patrick McHardy, Andrew Morgan,
Vasiliy Kulikov, David Howells, Neil Brown, Michal Januszewski,
linux-kernel, linux-security-module, linux-fbdev, linux-raid
In 2009 Philip Reiser notied that a few users of netlink connector
interface needed a capability check and added the idiom
cap_raised(nsp->eff_cap, CAP_SYS_ADMIN) to a few of them, on the premise
that netlink was asynchronous.
In 2011 Patrick McHardy noticed we were being silly because netlink is
synchronous and removed eff_cap from the netlink_skb_params and changed
the idiom to cap_raised(current_cap(), CAP_SYS_ADMIN).
Looking at those spots with a fresh eye we should be calling
capable(CAP_SYS_ADMIN). The only reason I can see for not calling
capable is that it once appeared we were not in the same task as the
caller which would have made calling capable() impossible.
In the initial user_namespace the only difference between between
cap_raised(current_cap(), CAP_SYS_ADMIN) and capable(CAP_SYS_ADMIN)
are a few sanity checks and the fact that capable(CAP_SYS_ADMIN)
sets PF_SUPERPRIV if we use the capability.
Since we are going to be using root privilege setting PF_SUPERPRIV
seems the right thing to do.
The motivation for this that patch is that in a child user namespace
cap_raised(current_cap(),...) tests your capabilities with respect to
that child user namespace not capabilities in the initial user namespace
and thus will allow processes that should be unprivielged to use the
kernel services that are only protected with
cap_raised(current_cap(),..).
To fix possible user_namespace issues and to just clean up the code
replace cap_raised(current_cap(), CAP_SYS_ADMIN) with
capable(CAP_SYS_ADMIN).
Cc: Patrick McHardy <kaber@trash.net>
Cc: Philipp Reisner <philipp.reisner@linbit.com>
Cc: Serge E. Hallyn <serge.hallyn@canonical.com>
Cc: Andrew Morgan <morgan@kernel.org>
Cc: Vasiliy Kulikov <segoon@openwall.com>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
drivers/block/drbd/drbd_nl.c | 2 +-
drivers/md/dm-log-userspace-transfer.c | 2 +-
drivers/video/uvesafb.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index abfaaca..946166e 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -2297,7 +2297,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms
return;
}
- if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) {
+ if (!capable(CAP_SYS_ADMIN)) {
retcode = ERR_PERM;
goto fail;
}
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
index 1f23e04..08d9a20 100644
--- a/drivers/md/dm-log-userspace-transfer.c
+++ b/drivers/md/dm-log-userspace-transfer.c
@@ -134,7 +134,7 @@ static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{
struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
- if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
+ if (!capable(CAP_SYS_ADMIN))
return;
spin_lock(&receiving_list_lock);
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 260cca7..9f7d27a 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -73,7 +73,7 @@ static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *ns
struct uvesafb_task *utask;
struct uvesafb_ktask *task;
- if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
+ if (!capable(CAP_SYS_ADMIN))
return;
if (msg->seq >= UVESAFB_TASKS_MAX)
--
1.7.2.5
^ permalink raw reply related
* Re: [PATCH] userns: Replace netlink uses of cap_raised with capable.
From: Serge E. Hallyn @ 2012-04-04 2:26 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Andrew Morton, Serge E. Hallyn, Philipp Reisner, Patrick McHardy,
Andrew Morgan, Vasiliy Kulikov, David Howells, Neil Brown,
Michal Januszewski, linux-kernel, linux-security-module,
linux-fbdev, linux-raid
In-Reply-To: <m1mx6sz2f2.fsf@fess.ebiederm.org>
Quoting Eric W. Biederman (ebiederm@xmission.com):
>
> In 2009 Philip Reiser notied that a few users of netlink connector
> interface needed a capability check and added the idiom
> cap_raised(nsp->eff_cap, CAP_SYS_ADMIN) to a few of them, on the premise
> that netlink was asynchronous.
>
> In 2011 Patrick McHardy noticed we were being silly because netlink is
> synchronous and removed eff_cap from the netlink_skb_params and changed
> the idiom to cap_raised(current_cap(), CAP_SYS_ADMIN).
>
> Looking at those spots with a fresh eye we should be calling
> capable(CAP_SYS_ADMIN). The only reason I can see for not calling
> capable is that it once appeared we were not in the same task as the
> caller which would have made calling capable() impossible.
And (just to make sure) that is now absolutely not the case?
> In the initial user_namespace the only difference between between
> cap_raised(current_cap(), CAP_SYS_ADMIN) and capable(CAP_SYS_ADMIN)
> are a few sanity checks and the fact that capable(CAP_SYS_ADMIN)
> sets PF_SUPERPRIV if we use the capability.
>
> Since we are going to be using root privilege setting PF_SUPERPRIV
> seems the right thing to do.
>
> The motivation for this that patch is that in a child user namespace
> cap_raised(current_cap(),...) tests your capabilities with respect to
> that child user namespace not capabilities in the initial user namespace
> and thus will allow processes that should be unprivielged to use the
> kernel services that are only protected with
> cap_raised(current_cap(),..).
>
> To fix possible user_namespace issues and to just clean up the code
> replace cap_raised(current_cap(), CAP_SYS_ADMIN) with
> capable(CAP_SYS_ADMIN).
>
> Cc: Patrick McHardy <kaber@trash.net>
> Cc: Philipp Reisner <philipp.reisner@linbit.com>
> Cc: Serge E. Hallyn <serge.hallyn@canonical.com>
Acked-by: Serge E. Hallyn <serge.hallyn@canonical.com>
thanks,
-serge
> Cc: Andrew Morgan <morgan@kernel.org>
> Cc: Vasiliy Kulikov <segoon@openwall.com>
> Cc: David Howells <dhowells@redhat.com>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> ---
> drivers/block/drbd/drbd_nl.c | 2 +-
> drivers/md/dm-log-userspace-transfer.c | 2 +-
> drivers/video/uvesafb.c | 2 +-
> 3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
> index abfaaca..946166e 100644
> --- a/drivers/block/drbd/drbd_nl.c
> +++ b/drivers/block/drbd/drbd_nl.c
> @@ -2297,7 +2297,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms
> return;
> }
>
> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) {
> + if (!capable(CAP_SYS_ADMIN)) {
> retcode = ERR_PERM;
> goto fail;
> }
> diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
> index 1f23e04..08d9a20 100644
> --- a/drivers/md/dm-log-userspace-transfer.c
> +++ b/drivers/md/dm-log-userspace-transfer.c
> @@ -134,7 +134,7 @@ static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
> {
> struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
>
> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
> + if (!capable(CAP_SYS_ADMIN))
> return;
>
> spin_lock(&receiving_list_lock);
> diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
> index 260cca7..9f7d27a 100644
> --- a/drivers/video/uvesafb.c
> +++ b/drivers/video/uvesafb.c
> @@ -73,7 +73,7 @@ static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *ns
> struct uvesafb_task *utask;
> struct uvesafb_ktask *task;
>
> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
> + if (!capable(CAP_SYS_ADMIN))
> return;
>
> if (msg->seq >= UVESAFB_TASKS_MAX)
> --
> 1.7.2.5
^ permalink raw reply
* Re: [PATCH] userns: Replace netlink uses of cap_raised with capable.
From: Eric W. Biederman @ 2012-04-04 2:45 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: Andrew Morton, Philipp Reisner, Patrick McHardy, Andrew Morgan,
Vasiliy Kulikov, David Howells, Neil Brown, Michal Januszewski,
linux-kernel, linux-security-module, linux-fbdev, linux-raid
In-Reply-To: <20120404022652.GA18730@mail.hallyn.com>
"Serge E. Hallyn" <serge@hallyn.com> writes:
> Quoting Eric W. Biederman (ebiederm@xmission.com):
>>
>> In 2009 Philip Reiser notied that a few users of netlink connector
>> interface needed a capability check and added the idiom
>> cap_raised(nsp->eff_cap, CAP_SYS_ADMIN) to a few of them, on the premise
>> that netlink was asynchronous.
>>
>> In 2011 Patrick McHardy noticed we were being silly because netlink is
>> synchronous and removed eff_cap from the netlink_skb_params and changed
>> the idiom to cap_raised(current_cap(), CAP_SYS_ADMIN).
>>
>> Looking at those spots with a fresh eye we should be calling
>> capable(CAP_SYS_ADMIN). The only reason I can see for not calling
>> capable is that it once appeared we were not in the same task as the
>> caller which would have made calling capable() impossible.
>
> And (just to make sure) that is now absolutely not the case?
Absolutely. Netlink is synchronous.
I reread netlink_unicast_kernel() in net/netlink/af_netlink.c while
researching this patch.
Netlink has been synchronous since 2007. In a world of perfect
knowledge transmission these calls could have been calls to capable
from the very beginning.
>> In the initial user_namespace the only difference between between
>> cap_raised(current_cap(), CAP_SYS_ADMIN) and capable(CAP_SYS_ADMIN)
>> are a few sanity checks and the fact that capable(CAP_SYS_ADMIN)
>> sets PF_SUPERPRIV if we use the capability.
>>
>> Since we are going to be using root privilege setting PF_SUPERPRIV
>> seems the right thing to do.
>>
>> The motivation for this that patch is that in a child user namespace
>> cap_raised(current_cap(),...) tests your capabilities with respect to
>> that child user namespace not capabilities in the initial user namespace
>> and thus will allow processes that should be unprivielged to use the
>> kernel services that are only protected with
>> cap_raised(current_cap(),..).
>>
>> To fix possible user_namespace issues and to just clean up the code
>> replace cap_raised(current_cap(), CAP_SYS_ADMIN) with
>> capable(CAP_SYS_ADMIN).
>>
>> Cc: Patrick McHardy <kaber@trash.net>
>> Cc: Philipp Reisner <philipp.reisner@linbit.com>
>> Cc: Serge E. Hallyn <serge.hallyn@canonical.com>
>
> Acked-by: Serge E. Hallyn <serge.hallyn@canonical.com>
>
> thanks,
> -serge
>
>> Cc: Andrew Morgan <morgan@kernel.org>
>> Cc: Vasiliy Kulikov <segoon@openwall.com>
>> Cc: David Howells <dhowells@redhat.com>
>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>> ---
>> drivers/block/drbd/drbd_nl.c | 2 +-
>> drivers/md/dm-log-userspace-transfer.c | 2 +-
>> drivers/video/uvesafb.c | 2 +-
>> 3 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
>> index abfaaca..946166e 100644
>> --- a/drivers/block/drbd/drbd_nl.c
>> +++ b/drivers/block/drbd/drbd_nl.c
>> @@ -2297,7 +2297,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms
>> return;
>> }
>>
>> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) {
>> + if (!capable(CAP_SYS_ADMIN)) {
>> retcode = ERR_PERM;
>> goto fail;
>> }
>> diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
>> index 1f23e04..08d9a20 100644
>> --- a/drivers/md/dm-log-userspace-transfer.c
>> +++ b/drivers/md/dm-log-userspace-transfer.c
>> @@ -134,7 +134,7 @@ static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
>> {
>> struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
>>
>> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
>> + if (!capable(CAP_SYS_ADMIN))
>> return;
>>
>> spin_lock(&receiving_list_lock);
>> diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
>> index 260cca7..9f7d27a 100644
>> --- a/drivers/video/uvesafb.c
>> +++ b/drivers/video/uvesafb.c
>> @@ -73,7 +73,7 @@ static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *ns
>> struct uvesafb_task *utask;
>> struct uvesafb_ktask *task;
>>
>> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
>> + if (!capable(CAP_SYS_ADMIN))
>> return;
>>
>> if (msg->seq >= UVESAFB_TASKS_MAX)
>> --
>> 1.7.2.5
^ permalink raw reply
* Re: [PATCH] userns: Replace netlink uses of cap_raised with capable.
From: James Morris @ 2012-04-04 4:06 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Andrew Morton, Serge E. Hallyn, Philipp Reisner, Patrick McHardy,
Andrew Morgan, Vasiliy Kulikov, David Howells, Neil Brown,
Michal Januszewski, linux-kernel, linux-security-module,
linux-fbdev, linux-raid
In-Reply-To: <m1mx6sz2f2.fsf@fess.ebiederm.org>
On Tue, 3 Apr 2012, Eric W. Biederman wrote:
> In the initial user_namespace the only difference between between
> cap_raised(current_cap(), CAP_SYS_ADMIN) and capable(CAP_SYS_ADMIN)
> are a few sanity checks and the fact that capable(CAP_SYS_ADMIN)
> sets PF_SUPERPRIV if we use the capability.
>
> Since we are going to be using root privilege setting PF_SUPERPRIV
> seems the right thing to do.
Agreed.
Reviewed-by: James Morris <james.l.morris@oracle.com>
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply
* Re: [PATCH] userns: Replace netlink uses of cap_raised with capable.
From: Andrew G. Morgan @ 2012-04-04 4:24 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Serge E. Hallyn, Andrew Morton, Philipp Reisner, Patrick McHardy,
Vasiliy Kulikov, David Howells, Neil Brown, Michal Januszewski,
linux-kernel, linux-security-module, linux-fbdev, linux-raid
In-Reply-To: <m1sjgkxlic.fsf@fess.ebiederm.org>
Acked-by: Andrew G. Morgan <morgan@kernel.org>
Cheers
Andrew
On Tue, Apr 3, 2012 at 7:45 PM, Eric W. Biederman <ebiederm@xmission.com> wrote:
> "Serge E. Hallyn" <serge@hallyn.com> writes:
>
>> Quoting Eric W. Biederman (ebiederm@xmission.com):
>>>
>>> In 2009 Philip Reiser notied that a few users of netlink connector
>>> interface needed a capability check and added the idiom
>>> cap_raised(nsp->eff_cap, CAP_SYS_ADMIN) to a few of them, on the premise
>>> that netlink was asynchronous.
>>>
>>> In 2011 Patrick McHardy noticed we were being silly because netlink is
>>> synchronous and removed eff_cap from the netlink_skb_params and changed
>>> the idiom to cap_raised(current_cap(), CAP_SYS_ADMIN).
>>>
>>> Looking at those spots with a fresh eye we should be calling
>>> capable(CAP_SYS_ADMIN). The only reason I can see for not calling
>>> capable is that it once appeared we were not in the same task as the
>>> caller which would have made calling capable() impossible.
>>
>> And (just to make sure) that is now absolutely not the case?
>
> Absolutely. Netlink is synchronous.
>
> I reread netlink_unicast_kernel() in net/netlink/af_netlink.c while
> researching this patch.
>
> Netlink has been synchronous since 2007. In a world of perfect
> knowledge transmission these calls could have been calls to capable
> from the very beginning.
>
>>> In the initial user_namespace the only difference between between
>>> cap_raised(current_cap(), CAP_SYS_ADMIN) and capable(CAP_SYS_ADMIN)
>>> are a few sanity checks and the fact that capable(CAP_SYS_ADMIN)
>>> sets PF_SUPERPRIV if we use the capability.
>>>
>>> Since we are going to be using root privilege setting PF_SUPERPRIV
>>> seems the right thing to do.
>>>
>>> The motivation for this that patch is that in a child user namespace
>>> cap_raised(current_cap(),...) tests your capabilities with respect to
>>> that child user namespace not capabilities in the initial user namespace
>>> and thus will allow processes that should be unprivielged to use the
>>> kernel services that are only protected with
>>> cap_raised(current_cap(),..).
>>>
>>> To fix possible user_namespace issues and to just clean up the code
>>> replace cap_raised(current_cap(), CAP_SYS_ADMIN) with
>>> capable(CAP_SYS_ADMIN).
>>>
>>> Cc: Patrick McHardy <kaber@trash.net>
>>> Cc: Philipp Reisner <philipp.reisner@linbit.com>
>>> Cc: Serge E. Hallyn <serge.hallyn@canonical.com>
>>
>> Acked-by: Serge E. Hallyn <serge.hallyn@canonical.com>
>>
>> thanks,
>> -serge
>>
>>> Cc: Andrew Morgan <morgan@kernel.org>
>>> Cc: Vasiliy Kulikov <segoon@openwall.com>
>>> Cc: David Howells <dhowells@redhat.com>
>>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>>> ---
>>> drivers/block/drbd/drbd_nl.c | 2 +-
>>> drivers/md/dm-log-userspace-transfer.c | 2 +-
>>> drivers/video/uvesafb.c | 2 +-
>>> 3 files changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
>>> index abfaaca..946166e 100644
>>> --- a/drivers/block/drbd/drbd_nl.c
>>> +++ b/drivers/block/drbd/drbd_nl.c
>>> @@ -2297,7 +2297,7 @@ static void drbd_connector_callback(struct cn_msg *req, struct netlink_skb_parms
>>> return;
>>> }
>>>
>>> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN)) {
>>> + if (!capable(CAP_SYS_ADMIN)) {
>>> retcode = ERR_PERM;
>>> goto fail;
>>> }
>>> diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
>>> index 1f23e04..08d9a20 100644
>>> --- a/drivers/md/dm-log-userspace-transfer.c
>>> +++ b/drivers/md/dm-log-userspace-transfer.c
>>> @@ -134,7 +134,7 @@ static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
>>> {
>>> struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
>>>
>>> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
>>> + if (!capable(CAP_SYS_ADMIN))
>>> return;
>>>
>>> spin_lock(&receiving_list_lock);
>>> diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
>>> index 260cca7..9f7d27a 100644
>>> --- a/drivers/video/uvesafb.c
>>> +++ b/drivers/video/uvesafb.c
>>> @@ -73,7 +73,7 @@ static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *ns
>>> struct uvesafb_task *utask;
>>> struct uvesafb_ktask *task;
>>>
>>> - if (!cap_raised(current_cap(), CAP_SYS_ADMIN))
>>> + if (!capable(CAP_SYS_ADMIN))
>>> return;
>>>
>>> if (msg->seq >= UVESAFB_TASKS_MAX)
>>> --
>>> 1.7.2.5
^ permalink raw reply
* [PATCH] video: s3c-fb: add runtime_get/put to suspend/resume
From: Jingoo Han @ 2012-04-04 6:57 UTC (permalink / raw)
To: linux-fbdev
This patch adds runtime_get/put to suspend/resume, which should be
necessary to prevent the problem to access the fimd register
without block power on.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/s3c-fb.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index f310516..76f3cf2 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -1564,6 +1564,8 @@ static int s3c_fb_suspend(struct device *dev)
struct s3c_fb_win *win;
int win_no;
+ pm_runtime_get_sync(sfb->dev);
+
for (win_no = S3C_FB_MAX_WIN - 1; win_no >= 0; win_no--) {
win = sfb->windows[win_no];
if (!win)
@@ -1577,6 +1579,9 @@ static int s3c_fb_suspend(struct device *dev)
clk_disable(sfb->lcd_clk);
clk_disable(sfb->bus_clk);
+
+ pm_runtime_put_sync(sfb->dev);
+
return 0;
}
@@ -1589,6 +1594,8 @@ static int s3c_fb_resume(struct device *dev)
int win_no;
u32 reg;
+ pm_runtime_get_sync(sfb->dev);
+
clk_enable(sfb->bus_clk);
if (!sfb->variant.has_clksel)
@@ -1633,6 +1640,8 @@ static int s3c_fb_resume(struct device *dev)
s3c_fb_set_par(win->fbinfo);
}
+ pm_runtime_put_sync(sfb->dev);
+
return 0;
}
#endif
--
1.7.1
^ permalink raw reply related
* [PATCH] video: exynos_dp: add analog and pll control setting
From: Jingoo Han @ 2012-04-04 6:58 UTC (permalink / raw)
To: linux-fbdev
This patch adds analog and pll control setting. This control setting
is used for DP TX PHY block.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/exynos/exynos_dp_core.h | 1 +
drivers/video/exynos/exynos_dp_reg.c | 14 ++++++++++++++
drivers/video/exynos/exynos_dp_reg.h | 6 ++++++
3 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 90ceaca..519c3a6 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -39,6 +39,7 @@ struct exynos_dp_device {
void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable);
void exynos_dp_stop_video(struct exynos_dp_device *dp);
void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_init_analog_param(struct exynos_dp_device *dp);
void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
void exynos_dp_reset(struct exynos_dp_device *dp);
void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 6548afa..d9c66fd 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -65,6 +65,19 @@ void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
}
+void exynos_dp_init_analog_param(struct exynos_dp_device *dp)
+{
+ writel(0x10, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1);
+
+ writel(0x0c, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2);
+
+ writel(0x85, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
+
+ writel(0x66, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
+
+ writel(0x0, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL);
+}
+
void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
{
/* Set interrupt pin assertion polarity as high */
@@ -131,6 +144,7 @@ void exynos_dp_reset(struct exynos_dp_device *dp)
writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+ exynos_dp_init_analog_param(dp);
exynos_dp_init_interrupt(dp);
}
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 42f608e..291e852 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -24,6 +24,12 @@
#define EXYNOS_DP_LANE_MAP 0x35C
+#define EXYNOS_DP_ANALOG_CTL_1 0x370
+#define EXYNOS_DP_ANALOG_CTL_2 0x374
+#define EXYNOS_DP_ANALOG_CTL_3 0x378
+#define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C
+#define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380
+
#define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390
#define EXYNOS_DP_COMMON_INT_STA_1 0x3C4
--
1.7.1
^ permalink raw reply related
* [PATCH] video: exynos_dp: check DP PLL Lock status
From: Jingoo Han @ 2012-04-04 6:59 UTC (permalink / raw)
To: linux-fbdev
DP PLL Lock status should be checked in order to prevent unlocked PLL.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/exynos/exynos_dp_reg.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index d9c66fd..661d010 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -285,6 +285,7 @@ void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
{
u32 reg;
+ int timeout_loop = 0;
exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
@@ -296,9 +297,19 @@ void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL);
/* Power up PLL */
- if (exynos_dp_get_pll_lock_status(dp) = PLL_UNLOCKED)
+ if (exynos_dp_get_pll_lock_status(dp) = PLL_UNLOCKED) {
exynos_dp_set_pll_power_down(dp, 0);
+ while (exynos_dp_get_pll_lock_status(dp) = PLL_UNLOCKED) {
+ timeout_loop++;
+ if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+ dev_err(dp->dev, "failed to get pll lock status\n");
+ return;
+ }
+ usleep_range(10, 20);
+ }
+ }
+
/* Enable Serdes FIFO function and Link symbol clock domain module */
reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
--
1.7.1
^ permalink raw reply related
* [PATCH] video: exynos_dp: replace char pointer with char array for adjust_request variable
From: Jingoo Han @ 2012-04-04 7:00 UTC (permalink / raw)
To: linux-fbdev
The char pointer for adjust_request variable is replaced with char array
to fix possible null pointer dereference when clock recovery is failed.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
drivers/video/exynos/exynos_dp_core.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index 2a4481c..6e9f3ce 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -478,7 +478,7 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
int lane_count;
u8 buf[5];
- u8 *adjust_request;
+ u8 adjust_request[2];
u8 voltage_swing;
u8 pre_emphasis;
u8 training_lane;
@@ -493,8 +493,8 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
/* set training pattern 2 for EQ */
exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
- adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
- - DPCD_ADDR_LANE0_1_STATUS);
+ adjust_request[0] = link_status[4];
+ adjust_request[1] = link_status[5];
exynos_dp_get_adjust_train(dp, adjust_request);
@@ -566,7 +566,7 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
u8 buf[5];
u32 reg;
- u8 *adjust_request;
+ u8 adjust_request[2];
udelay(400);
@@ -575,8 +575,8 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
lane_count = dp->link_train.lane_count;
if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
- adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
- - DPCD_ADDR_LANE0_1_STATUS);
+ adjust_request[0] = link_status[4];
+ adjust_request[1] = link_status[5];
if (exynos_dp_channel_eq_ok(link_status, lane_count) = 0) {
/* traing pattern Set to Normal */
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 5/5] fbdev: s/#if CONFIG/#ifdef CONFIG/
From: Jiri Kosina @ 2012-04-06 0:00 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: Geert Uytterhoeven, linux-kernel, linux-fbdev
In-Reply-To: <4F417B3F.2050307@gmx.de>
On Sun, 19 Feb 2012, Florian Tobias Schandinat wrote:
> On 02/19/2012 03:11 PM, Geert Uytterhoeven wrote:
> > Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
> > Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
>
> Acked-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
> (I assume you want that to go mainline via Jiri's tree)
As this doesn't seem to be in linux-next through any other tree as of
today, I have picked it up.
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2] video: s3c-fb: Add device tree support
From: Jingoo Han @ 2012-04-06 3:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1333086797-1625-1-git-send-email-thomas.abraham@linaro.org>
On Fri, Mar 30, 2012 at 2:23, Thomas Abraham <thomas.abraham@linaro.org> wrote:
> Subject: [PATCH v2] video: s3c-fb: Add device tree support
>
> Add device tree based discovery support for Samsung's display controller
> framebuffer driver.
>
> Cc: Jingoo Han <jg1.han@samsung.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> .../devicetree/bindings/fb/samsung-fb.txt | 148 +++++++++++++
> drivers/video/s3c-fb.c | 230 +++++++++++++++++++-
> 2 files changed, 370 insertions(+), 8 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/fb/samsung-fb.txt
>
> diff --git a/Documentation/devicetree/bindings/fb/samsung-fb.txt
> b/Documentation/devicetree/bindings/fb/samsung-fb.txt
> new file mode 100644
> index 0000000..612bd9f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/fb/samsung-fb.txt
> @@ -0,0 +1,148 @@
> +* Samsung Display Controller Framebuffer Controller
> +
> +The display controller is used to transfer image data from memory to a
> +external display device such as an RGB interface LCD panel. It supports
> +various color formats such as rgb and yuv. It also supports multiple window
> +overlays.
> +
> +Required properties:
> +
> + - compatible: should be one of the following
> + - samsung,exynos4210-fimd: for fimd compatible with Exynos4210 fimd
> + - samsung,s5pv210-fimd: for fimd compatible with s5pv210 fimd
> +
> + - reg: physical base address of the controller and length of memory
> + mapped region.
> +
> + - interrupts: Three interrupts should be specified. The format of the
> + interrupt specifier depends on the interrupt controller. The interrupts
> + should be specified in the following order.
> + - VSYNC (Video Frame) interrupt
> + - Video FIFO level interrupt
> + - FIMD System Interrupt
> +
> + - gpios: The gpios used to interface with the external LCD panel. For a
> + panel with rgb interface, the gpio interface consists of video data
> + lines, HSYNC, VSYNC, Pixel Clock and Data Enable. The gpio's used for
> + these interface lines can be listed under this property in any order.
> +
> + - samsung,fimd-display: The fimd controller is interfaced with the a
> + display device such as a lcd panel. This property should specify the
> + phandle of the display device node. For a display device node that
> + represents a RGB type display interface, it is expected to specify the
> + video interface timing using the following properties.
> +
> + - lcd-htiming: Specifies the horizontal timing for the overlay. The
> + horizontal timing includes four parameters in the following order.
> +
> + - horizontal back porch (in number of lcd clocks)
> + - horizontal front porch (in number of lcd clocks)
> + - hsync pulse width (in number of lcd clocks)
> + - Display panels X resolution.
> +
> + - lcd-vtiming: Specifies the vertical timing for the overlay. The
> + vertical timing includes four parameters in the following order.
> +
> + - vertical back porch (in number of lcd lines)
> + - vertical front porch (in number of lcd lines)
> + - vsync pulse width (in number of lcd clocks)
> + - Y resolution.
> +
> + - Overlay/Windows: Multiple overlays/windows can be specified as child
> + nodes. Each window should have the following properties (optional
> + window properties are marked as 'optional').
> +
> + - samsung,fimd-win-id: Specifies the window number of the fimd controller.
> +
> + - samsung,fimd-win-bpp: Specifies the bits per pixel. Two values should
> + be specified in the following order.
> + - default-bpp: bpp supported by the overlay.
> + - max-bpp: maximum required bpp for the overlay.
> +
> + - samsung,fimd-win-res: (OPTIONAL) Specifies the window resolution in
> + pixels. The resolution contains the X and Y pixel values with X being
> + specified first. If this property is not specified, the window
> + resolution is set to be equal to the display panel resolution.
> +
> + - samsung,fimd-win-virtres: (OPTIONAL) Specifies the resolution of the
> + virtual frame buffer for the window. The resolution contains the X
> + and Y resolution in pixels with value of X being the specified first.
> +
> +Optional properties:
> +
> + - samsung,fimd-vidout-rgb: Video output format is RGB.
> + - samsung,fimd-inv-hsync: invert hsync pulse polarity.
> + - samsung,fimd-inv-vsync: invert vsync pulse polarity.
> + - samsung,fimd-inv-vclk: invert video clock polarity.
> + - samsung,fimd-inv-vden: invert video enable signal polarity.
> + - samsung,fimd-frame-rate: Number of video frames per second.
> +
> +Example:
> +
> + The following is an example for the fimd framebuffer controller is split
> + into two portions. The SoC specific portion can be specified in the SoC
> + specific dts file. The board specific portion can be specified in the
> + board specific dts file.
> +
> + - SoC Specific portion
> +
> + fimd@11C00000 {
> + compatible = "samsung,exynos4210-fimd";
> + interrupt-parent = <&combiner>;
> + reg = <0x11C00000 0x8000>;
> + interrupts = <11 1>, <11 0>, <11 2>;
> + };
> +
> + - Board Specific portion
> +
> + fimd@11C00000 {
> + samsung,fimd-display = <&lcd_fimd0>;
> + samsung,fimd-vidout-rgb;
> + samsung,fimd-inv-hsync;
> + samsung,fimd-inv-vsync;
> + samsung,fimd-inv-vclk;
> + samsung,fimd-frame-rate = <60>;
> +
> + gpios = <&gpf0 0 2 0 0>,
> + <&gpf0 1 2 0 0>,
> + <&gpf0 2 2 0 0>,
> + <&gpf0 3 2 0 0>,
> + <&gpf0 4 2 0 0>,
> + <&gpf0 5 2 0 0>,
> + <&gpf0 6 2 0 0>,
> + <&gpf0 7 2 0 0>,
> + <&gpf1 0 2 0 0>,
> + <&gpf1 1 2 0 0>,
> + <&gpf1 2 2 0 0>,
> + <&gpf1 3 2 0 0>,
> + <&gpf1 4 2 0 0>,
> + <&gpf1 5 2 0 0>,
> + <&gpf1 6 2 0 0>,
> + <&gpf1 7 2 0 0>,
> + <&gpf2 0 2 0 0>,
> + <&gpf2 1 2 0 0>,
> + <&gpf2 2 2 0 0>,
> + <&gpf2 3 2 0 0>,
> + <&gpf2 4 2 0 0>,
> + <&gpf2 5 2 0 0>,
> + <&gpf2 6 2 0 0>,
> + <&gpf2 7 2 0 0>,
> + <&gpf3 0 2 0 0>,
> + <&gpf3 1 2 0 0>,
> + <&gpf3 2 2 0 0>,
> + <&gpf3 3 2 0 0>;
> +
> + window0 {
> + samsung,fimd-win-id = <0>;
> + samsung,fimd-win-bpp = <32 24>;
> + samsung,fimd-win-res = <512 300>;
> + samsung,fimd-win-vres = <1024 600>;
> + };
> +
> + window1 {
> + samsung,fimd-win-id = <1>;
> + samsung,fimd-win-bpp = <32 24>;
> + samsung,fimd-win-res = <1024 200>;
> + samsung,fimd-win-vres = <1024 600>;
> + };
> + };
> diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
> index 18c84b8..b8be668 100644
> --- a/drivers/video/s3c-fb.c
> +++ b/drivers/video/s3c-fb.c
> @@ -24,6 +24,8 @@
> #include <linux/uaccess.h>
> #include <linux/interrupt.h>
> #include <linux/pm_runtime.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
>
> #include <mach/map.h>
> #include <plat/regs-fb-v4.h>
> @@ -220,6 +222,7 @@ struct s3c_fb {
> int irq_no;
> unsigned long irq_flags;
> struct s3c_fb_vsync vsync_info;
> + int *gpios;
> };
>
> /**
> @@ -1352,27 +1355,215 @@ static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
> writel(reg & ~SHADOWCON_WINx_PROTECT(win), regs + SHADOWCON);
> }
>
> +#ifdef CONFIG_OF
> +static int s3c_fb_dt_parse_gpios(struct device *dev, struct s3c_fb *sfb,
> + bool request)
> +{
> + int nr_gpios, idx, gpio, ret;
> +
> + nr_gpios = sfb->pdata->win[0]->max_bpp + 4;
> + sfb->gpios = devm_kzalloc(dev, sizeof(int) * nr_gpios, GFP_KERNEL);
> + if (!sfb->gpios) {
> + dev_err(dev, "unable to allocate private data for gpio\n");
> + return -ENOMEM;
> + }
> +
> + for (idx = 0; idx < nr_gpios; idx++) {
> + gpio = of_get_gpio(dev->of_node, idx);
> + if (!gpio_is_valid(gpio)) {
> + dev_err(dev, "invalid gpio[%d]: %d\n", idx, gpio);
> + return -EINVAL;
> + }
> +
> + if (!request)
> + continue;
> +
> + ret = gpio_request(gpio, "fimd");
> + if (ret) {
> + dev_err(dev, "gpio [%d] request failed\n", gpio);
> + goto gpio_free;
> + }
> + sfb->gpios[idx] = gpio;
> + }
> + return 0;
> +
> +gpio_free:
> + while (--idx >= 0)
> + gpio_free(sfb->gpios[idx]);
> + return ret;
> +}
> +
> +static void s3c_fb_dt_free_gpios(struct s3c_fb *sfb)
> +{
> + unsigned int idx, nr_gpio;
> +
> + nr_gpio = sfb->pdata->win[0]->max_bpp + 4;
> + for (idx = 0; idx < nr_gpio; idx++)
> + gpio_free(sfb->gpios[idx]);
> +}
> +
> +static struct s3c_fb_platdata *s3c_fb_dt_parse_pdata(struct device *dev)
> +{
> + struct device_node *np = dev->of_node, *win_np;
> + struct device_node *disp_np;
> + struct s3c_fb_platdata *pd;
> + struct s3c_fb_pd_win *win;
> + u32 wnum = 0, data[4];
> +
> + pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> + if (!pd) {
> + dev_err(dev, "memory allocation for pdata failed\n");
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + pd->vtiming = devm_kzalloc(dev, sizeof(*pd->vtiming), GFP_KERNEL);
> + if (!pd->vtiming) {
> + dev_err(dev, "memory allocation for vtiming failed\n");
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + if (of_get_property(np, "samsung,fimd-vidout-rgb", NULL))
> + pd->vidcon0 |= VIDCON0_VIDOUT_RGB;
> + if (of_get_property(np, "samsung,fimd-vidout-tv", NULL))
> + pd->vidcon0 |= VIDCON0_VIDOUT_TV;
> + if (of_get_property(np, "samsung,fimd-inv-hsync", NULL))
> + pd->vidcon1 |= VIDCON1_INV_HSYNC;
> + if (of_get_property(np, "samsung,fimd-inv-vsync", NULL))
> + pd->vidcon1 |= VIDCON1_INV_VSYNC;
> + if (of_get_property(np, "samsung,fimd-inv-vclk", NULL))
> + pd->vidcon1 |= VIDCON1_INV_VCLK;
> + if (of_get_property(np, "samsung,fimd-inv-vden", NULL))
> + pd->vidcon1 |= VIDCON1_INV_VDEN;
> +
> + disp_np = of_parse_phandle(np, "samsung,fimd-display", 0);
> + if (!disp_np) {
> + dev_err(dev, "unable to find display panel info\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (of_property_read_u32_array(disp_np, "lcd-htiming", data, 4)) {
> + dev_err(dev, "invalid horizontal timing\n");
> + return ERR_PTR(-EINVAL);
> + }
> + pd->vtiming->left_margin = data[0];
> + pd->vtiming->right_margin = data[1];
> + pd->vtiming->hsync_len = data[2];
> + pd->vtiming->xres = data[3];
> +
> + if (of_property_read_u32_array(disp_np, "lcd-vtiming", data, 4)) {
> + dev_err(dev, "invalid vertical timing\n");
> + return ERR_PTR(-EINVAL);
> + }
> + pd->vtiming->upper_margin = data[0];
> + pd->vtiming->lower_margin = data[1];
> + pd->vtiming->vsync_len = data[2];
> + pd->vtiming->yres = data[3];
> +
> + of_property_read_u32_array(np, "samsung,fimd-frame-rate",
> + &pd->vtiming->refresh, 1);
> +
> + for_each_child_of_node(np, win_np) {
> + if (of_property_read_u32_array(win_np, "samsung,fimd-win-id",
> + &wnum, 1)) {
> + dev_err(dev, "window id not specified\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + win = devm_kzalloc(dev, sizeof(*win), GFP_KERNEL);
> + if (!win) {
> + dev_err(dev, "no memory for window[%d] data\n", wnum);
> + return ERR_PTR(-ENOMEM);
> + }
> + pd->win[wnum] = win;
> +
> + if (of_property_read_u32_array(win_np, "samsung,fimd-win-bpp",
> + data, 2)) {
> + dev_err(dev, "invalid window bpp\n");
> + return ERR_PTR(-EINVAL);
> + }
> + win->default_bpp = data[0];
> + win->max_bpp = data[1];
> +
> + if (of_property_read_u32_array(win_np, "samsung,fimd-win-res",
> + data, 2)) {
> + dev_info(dev, "window [%d] resolution not specified. "
> + "Using lcd resolution X[%d] and Y[%d]", wnum,
> + pd->vtiming->xres, pd->vtiming->yres);
> + win->xres = pd->vtiming->xres;
> + win->yres = pd->vtiming->yres;
> + } else {
> + win->xres = data[0];
> + win->yres = data[1];
> + }
> +
> + if (!of_property_read_u32_array(win_np,
> + "samsung,fimd-win-virtres", data, 2)) {
> + win->virtual_x = data[0];
> + win->virtual_y = data[1];
> + }
> + }
> +
> + return pd;
> +}
> +#else
> +static int s3c_fb_dt_parse_gpios(struct device *dev, struct s3c_fb *sfb,
> + bool request)
> +{
> + return 0;
> +}
> +
> +static void s3c_fb_dt_free_gpios(struct s3c_fb *sfb)
> +{
> + return 0;
It makes build warning.
drivers/video/s3c-fb.c: In function 's3c_fb_dt_free_gpios':
drivers/video/s3c-fb.c:1523: warning: 'return' with a value, in function returning void
> +}
> +
> +static int s3c_fb_dt_parse_pdata(struct device *dev,
> + struct s3c_fb_platdata **pdata)
It makes build error when CONFIG_OF is disabled.
Please, do build with disabling CONFIG_OF.
drivers/video/s3c-fb.c: In function 's3c_fb_probe':
drivers/video/s3c-fb.c:1568: error: too few arguments to function 's3c_fb_dt_parse_pdata'
> +{
> + return 0;
> +}
> +#endif /* CONFIG_OF */
> +
> +static const struct of_device_id s3c_fb_dt_match[];
> +
> +static inline struct s3c_fb_driverdata *s3c_fb_get_driver_data(
> + struct platform_device *pdev)
> +{
> +#ifdef CONFIG_OF
> + if (pdev->dev.of_node) {
> + const struct of_device_id *match;
> + match = of_match_node(s3c_fb_dt_match, pdev->dev.of_node);
> + return (struct s3c_fb_driverdata *)match->data;
> + }
> +#endif
> + return (struct s3c_fb_driverdata *)
> + platform_get_device_id(pdev)->driver_data;
> +}
> +
> static int __devinit s3c_fb_probe(struct platform_device *pdev)
> {
> - const struct platform_device_id *platid;
> struct s3c_fb_driverdata *fbdrv;
> struct device *dev = &pdev->dev;
> - struct s3c_fb_platdata *pd;
> + struct s3c_fb_platdata *pd = pdev->dev.platform_data;
> struct s3c_fb *sfb;
> struct resource *res;
> int win;
> int ret = 0;
> u32 reg;
>
> - platid = platform_get_device_id(pdev);
> - fbdrv = (struct s3c_fb_driverdata *)platid->driver_data;
> + fbdrv = s3c_fb_get_driver_data(pdev);
>
> if (fbdrv->variant.nr_windows > S3C_FB_MAX_WIN) {
> dev_err(dev, "too many windows, cannot attach\n");
> return -EINVAL;
> }
>
> - pd = pdev->dev.platform_data;
> + if (pdev->dev.of_node) {
> + pd = s3c_fb_dt_parse_pdata(&pdev->dev);
> + if (IS_ERR(pd))
> + return PTR_ERR(pd);
> + }
> +
> if (!pd) {
> dev_err(dev, "no platform data specified\n");
> return -EINVAL;
> @@ -1449,7 +1640,12 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
>
> /* setup gpio and output polarity controls */
>
> - pd->setup_gpio();
> + if (dev->of_node) {
> + if (s3c_fb_dt_parse_gpios(dev, sfb, true))
> + goto err_lcd_clk;
> + } else {
> + pd->setup_gpio();
> + }
>
> writel(pd->vidcon1, sfb->regs + VIDCON1);
>
> @@ -1499,6 +1695,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
> return 0;
>
> err_pm_runtime:
> + s3c_fb_dt_free_gpios(sfb);
> pm_runtime_put_sync(sfb->dev);
>
> err_lcd_clk:
> @@ -1545,6 +1742,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
>
> pm_runtime_put_sync(sfb->dev);
> pm_runtime_disable(sfb->dev);
> + s3c_fb_dt_free_gpios(sfb);
>
> return 0;
> }
> @@ -1588,7 +1786,10 @@ static int s3c_fb_resume(struct device *dev)
> clk_enable(sfb->lcd_clk);
>
> /* setup gpio and output polarity controls */
> - pd->setup_gpio();
> + if (dev->of_node)
> + s3c_fb_dt_parse_gpios(dev, sfb, false);
> + else
> + pd->setup_gpio();
> writel(pd->vidcon1, sfb->regs + VIDCON1);
>
> /* set video clock running at under-run */
> @@ -1658,7 +1859,10 @@ static int s3c_fb_runtime_resume(struct device *dev)
> clk_enable(sfb->lcd_clk);
>
> /* setup gpio and output polarity controls */
> - pd->setup_gpio();
> + if (dev->of_node)
> + s3c_fb_dt_parse_gpios(dev, sfb, false);
> + else
> + pd->setup_gpio();
> writel(pd->vidcon1, sfb->regs + VIDCON1);
>
> return 0;
> @@ -2028,6 +2232,15 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
> };
> MODULE_DEVICE_TABLE(platform, s3c_fb_driver_ids);
>
> +#ifdef CONFIG_OF
> +static const struct of_device_id s3c_fb_dt_match[] = {
> + { .compatible = "samsung,exynos4210-fimd",
> + .data = (void *)&s3c_fb_data_exynos4 },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, s3c_fb_dt_match);
> +#endif
> +
> static const struct dev_pm_ops s3cfb_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(s3c_fb_suspend, s3c_fb_resume)
> SET_RUNTIME_PM_OPS(s3c_fb_runtime_suspend, s3c_fb_runtime_resume,
> @@ -2042,6 +2255,7 @@ static struct platform_driver s3c_fb_driver = {
> .name = "s3c-fb",
> .owner = THIS_MODULE,
> .pm = &s3cfb_pm_ops,
> + .of_match_table = of_match_ptr(s3c_fb_dt_match),
> },
> };
>
> --
> 1.6.6.rc2
^ permalink raw reply
* Re: [PATCH v3 1/2] backlight: lcd: add driver for raster-type lcd's with gpio controlled panel reset
From: Andrew Morton @ 2012-04-06 23:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1332751600-11371-2-git-send-email-thomas.abraham@linaro.org>
> Cc: rpurdie@rpsys.net, florianSchandinat@gmx.de, devicetree-discuss@lists.ozlabs.org, linux-fbdev@vger.kernel.org, linux-samsung-soc@vger.kernel.org, grant.likely@secretlab.ca, rob.herring@calxeda.com, kgene.kim@samsung.com, jg1.han@samsung.com, broonie@opensource.wolfsonmicro.com, kyungmin.park@samsung.com, augulis.darius@gmail.com, ben-linux@fluff.org, lars@metafoo.de, patches@linaro.org
Poor me. When someone sends a patch like this, I need to go and hunt
down everyone's real names to nicely add them to the changelog's Cc:
list. I prefer that you do this ;)
You can add Cc:'s to the changelog yourself, of course. Often that
works out better than having me try to work out who might be
interested in the patch.
On Mon, 26 Mar 2012 14:16:39 +0530
Thomas Abraham <thomas.abraham@linaro.org> wrote:
> Add a lcd panel driver for simple raster-type lcd's which uses a gpio
> controlled panel reset. The driver controls the nRESET line of the panel
> using a gpio connected from the host system. The Vcc supply to the panel
> is (optionally) controlled using a voltage regulator. This driver excludes
> support for lcd panels that use a serial command interface or direct
> memory mapped IO interface.
>
>
> ...
>
> +struct lcd_pwrctrl {
> + struct device *dev;
> + struct lcd_device *lcd;
> + struct lcd_pwrctrl_data *pdata;
> + struct regulator *regulator;
> + unsigned int power;
> + bool suspended;
> + bool pwr_en;
Generally kernel code will avoid these unpronounceable abbreviations.
So we do
pwr -> power
en -> enable
ctrl -> control
etc. It results in longer identifiers, but the code is more readable
and, more importantly, more *rememberable*.
> +};
> +
> +static int lcd_pwrctrl_get_power(struct lcd_device *lcd)
> +{
> + struct lcd_pwrctrl *lp = lcd_get_data(lcd);
> + return lp->power;
> +}
> +
> +static int lcd_pwrctrl_set_power(struct lcd_device *lcd, int power)
See, shouldn't that have been lcd_pwrctrl_set_pwr?
If we avoid the abbreviations, such issues do not arise.
> +{
> + struct lcd_pwrctrl *lp = lcd_get_data(lcd);
> + struct lcd_pwrctrl_data *pd = lp->pdata;
> + bool lcd_enable;
> + int lcd_reset, ret = 0;
> +
> + lcd_enable = (power = FB_BLANK_POWERDOWN || lp->suspended) ? 0 : 1;
This isn't how to use `bool'. We can use
lcd_enable = (power = FB_BLANK_POWERDOWN) || lp->suspended;
> + lcd_reset = (pd->invert) ? !lcd_enable : lcd_enable;
> +
> + if (lp->pwr_en = lcd_enable)
> + return 0;
> +
> + if (!IS_ERR_OR_NULL(lp->regulator)) {
> + if (lcd_enable) {
> + if (regulator_enable(lp->regulator)) {
> + dev_info(lp->dev, "regulator enable failed\n");
> + ret = -EPERM;
> + }
> + } else {
> + if (regulator_disable(lp->regulator)) {
> + dev_info(lp->dev, "regulator disable failed\n");
> + ret = -EPERM;
> + }
> + }
> + }
> +
> + gpio_direction_output(lp->pdata->gpio, lcd_reset);
> + lp->power = power;
> + lp->pwr_en = lcd_enable;
Again, this could have been any of
lp->[power|pwr] = [power|pwr];
lp->[power|pwr]_[en|enable] = lcd_[en|enable];
zillions of combinations! If we just avoid the abbreviations, there is
only one combination.
> + return ret;
> +}
> +
>
> ...
>
> +static int __devinit lcd_pwrctrl_probe(struct platform_device *pdev)
> +{
> + struct lcd_pwrctrl *lp;
> + struct lcd_pwrctrl_data *pdata = pdev->dev.platform_data;
> + struct device *dev = &pdev->dev;
> + int err;
> +
> +#ifdef CONFIG_OF
> + if (dev->of_node) {
> + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
> + if (!pdata) {
> + dev_err(dev, "memory allocation for pdata failed\n");
> + return -ENOMEM;
> + }
> + lcd_pwrctrl_parse_dt(dev, pdata);
> + }
> +#endif
> +
> + if (!pdata) {
> + dev_err(dev, "platform data not available\n");
> + return -EINVAL;
> + }
> +
> + lp = devm_kzalloc(dev, sizeof(struct lcd_pwrctrl), GFP_KERNEL);
Nit: I prefer sizeof(*lp) here, so I don't have to scroll back and
check the type of lp.
> + if (!lp) {
> + dev_err(dev, "memory allocation failed for private data\n");
> + return -ENOMEM;
> + }
> +
> + err = gpio_request(pdata->gpio, "LCD-nRESET");
> + if (err) {
> + dev_err(dev, "gpio [%d] request failed\n", pdata->gpio);
> + return err;
> + }
> +
>
> ...
>
The code looks OK to me, but I do think the naming decisions should be
revisited, please.
^ permalink raw reply
* Re: [PATCH] kyrofb: fix on x86_64
From: Ondrej Zary @ 2012-04-07 11:38 UTC (permalink / raw)
To: Paul Mundt
Cc: Florian Tobias Schandinat, linux-fbdev, Kernel development list
In-Reply-To: <20120322000104.GB26543@linux-sh.org>
On Thursday 22 March 2012 01:01:05 Paul Mundt wrote:
> On Wed, Mar 21, 2012 at 11:36:50PM +0100, Ondrej Zary wrote:
> > kyrofb is completely broken on x86_64 because the registers are defined
> > as unsigned long. Change them to u32 to make the driver work.
> > Tested with Hercules 3D Prophet 4000XT.
> >
> > Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
>
> Looks fine to me.
>
> Acked-by: Paul Mundt <lethal@linux-sh.org>
When will this go in?
--
Ondrej Zary
^ permalink raw reply
* Re: [PATCH] kyrofb: fix on x86_64
From: Florian Tobias Schandinat @ 2012-04-07 11:48 UTC (permalink / raw)
To: Ondrej Zary; +Cc: Paul Mundt, linux-fbdev, Kernel development list
In-Reply-To: <201204071338.30521.linux@rainbow-software.org>
On 04/07/2012 11:38 AM, Ondrej Zary wrote:
> On Thursday 22 March 2012 01:01:05 Paul Mundt wrote:
>> On Wed, Mar 21, 2012 at 11:36:50PM +0100, Ondrej Zary wrote:
>>> kyrofb is completely broken on x86_64 because the registers are defined
>>> as unsigned long. Change them to u32 to make the driver work.
>>> Tested with Hercules 3D Prophet 4000XT.
>>>
>>> Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
>>
>> Looks fine to me.
>>
>> Acked-by: Paul Mundt <lethal@linux-sh.org>
>
> When will this go in?
Probably between -rc2 and -rc3. I've already applied this in my private
tree, I just needed a few days off after the last merge window.
Best regards,
Florian Tobias Schandinat
^ permalink raw reply
* [PATCH 09/10] cobalt_lcdfb: LCD panel framebuffer support for SEAD-3 platform.
From: Steven J. Hill @ 2012-04-07 16:56 UTC (permalink / raw)
To: linux-mips, ralf
Cc: linux-fbdev, Steven J. Hill, Douglas Leung, Chris Dearman
From: "Steven J. Hill" <sjhill@mips.com>
Add support for LCD panel on MIPS SEAD-3 development platform.
Signed-off-by: Douglas Leung <douglas@mips.com>
Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Steven J. Hill <sjhill@mips.com>
---
drivers/video/Kconfig | 2 +-
drivers/video/cobalt_lcdfb.c | 45 +++++++++++++++++++++++++++++++++++++++++-
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index a8a897a..e921a45 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2210,7 +2210,7 @@ config FB_XILINX
config FB_COBALT
tristate "Cobalt server LCD frame buffer support"
- depends on FB && MIPS_COBALT
+ depends on FB && (MIPS_COBALT || MIPS_SEAD3)
config FB_SH7760
bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c
index f56699d..eae46f6 100644
--- a/drivers/video/cobalt_lcdfb.c
+++ b/drivers/video/cobalt_lcdfb.c
@@ -1,7 +1,8 @@
/*
- * Cobalt server LCD frame buffer driver.
+ * Cobalt/SEAD3 LCD frame buffer driver.
*
* Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ * Copyright (C) 2012 MIPS Technologies, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -62,6 +63,7 @@
#define LCD_CUR_POS(x) ((x) & LCD_CUR_POS_MASK)
#define LCD_TEXT_POS(x) ((x) | LCD_TEXT_MODE)
+#ifdef CONFIG_MIPS_COBALT
static inline void lcd_write_control(struct fb_info *info, u8 control)
{
writel((u32)control << 24, info->screen_base);
@@ -81,6 +83,47 @@ static inline u8 lcd_read_data(struct fb_info *info)
{
return readl(info->screen_base + LCD_DATA_REG_OFFSET) >> 24;
}
+#else
+
+#define LCD_CTL 0x00
+#define LCD_DATA 0x08
+#define CPLD_STATUS 0x10
+#define CPLD_DATA 0x18
+
+static inline void cpld_wait(struct fb_info *info)
+{
+ do {
+ } while (readl(info->screen_base + CPLD_STATUS) & 1);
+}
+
+static inline void lcd_write_control(struct fb_info *info, u8 control)
+{
+ cpld_wait(info);
+ writel(control, info->screen_base + LCD_CTL);
+}
+
+static inline u8 lcd_read_control(struct fb_info *info)
+{
+ cpld_wait(info);
+ readl(info->screen_base + LCD_CTL);
+ cpld_wait(info);
+ return readl(info->screen_base + CPLD_DATA) & 0xff;
+}
+
+static inline void lcd_write_data(struct fb_info *info, u8 data)
+{
+ cpld_wait(info);
+ writel(data, info->screen_base + LCD_DATA);
+}
+
+static inline u8 lcd_read_data(struct fb_info *info)
+{
+ cpld_wait(info);
+ readl(info->screen_base + LCD_DATA);
+ cpld_wait(info);
+ return readl(info->screen_base + CPLD_DATA) & 0xff;
+}
+#endif
static int lcd_busy_wait(struct fb_info *info)
{
--
1.7.9.6
^ permalink raw reply related
* [PATCH] video: exynos: fix build warning and bad pointer deref in dp driver
From: Olof Johansson @ 2012-04-09 4:16 UTC (permalink / raw)
To: Jingoo Han
Cc: Florian Tobias Schandinat, linux-fbdev, linux-kernel,
Olof Johansson
I'm not 100% sure if the fix for 'adjust_request' is correct, since
it's uncertain what the original intent was. But it's so clearly an
uninitialized pointer dereference that my resolution seems to make sense.
drivers/video/exynos/exynos_dp_core.c: In function 'exynos_dp_set_link_train':
drivers/video/exynos/exynos_dp_core.c:521:21: warning: 'adjust_request' may be used uninitialized in this function [-Wuninitialized]
drivers/video/exynos/exynos_dp_core.c:481:6: note: 'adjust_request' was declared here
drivers/video/exynos/exynos_dp_core.c:529:18: warning: 'reg' may be used uninitialized in this function [-Wuninitialized]
drivers/video/exynos/exynos_dp_core.c:395:6: note: 'reg' was declared here
Signed-off-by: Olof Johansson <olof@lixom.net>
---
drivers/video/exynos/exynos_dp_core.c | 23 +++++++++--------------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index 2a4481c..8973e18 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -392,24 +392,19 @@ static unsigned int exynos_dp_get_lane_link_training(
struct exynos_dp_device *dp,
int lane)
{
- u32 reg;
-
switch (lane) {
case 0:
- reg = exynos_dp_get_lane0_link_training(dp);
- break;
+ return exynos_dp_get_lane0_link_training(dp);
case 1:
- reg = exynos_dp_get_lane1_link_training(dp);
- break;
+ return exynos_dp_get_lane1_link_training(dp);
case 2:
- reg = exynos_dp_get_lane2_link_training(dp);
- break;
+ return exynos_dp_get_lane2_link_training(dp);
case 3:
- reg = exynos_dp_get_lane3_link_training(dp);
- break;
+ return exynos_dp_get_lane3_link_training(dp);
}
- return reg;
+ WARN_ON(1);
+ return 0;
}
static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
@@ -489,13 +484,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
6, link_status);
lane_count = dp->link_train.lane_count;
+ adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
+ - DPCD_ADDR_LANE0_1_STATUS);
+
if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
/* set training pattern 2 for EQ */
exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
- adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
- - DPCD_ADDR_LANE0_1_STATUS);
-
exynos_dp_get_adjust_train(dp, adjust_request);
buf[0] = DPCD_SCRAMBLING_DISABLED |
--
1.7.9.2.359.gebfc2
^ permalink raw reply related
* RE: [PATCH] video: exynos: fix build warning and bad pointer deref in dp driver
From: Jingoo Han @ 2012-04-09 8:46 UTC (permalink / raw)
To: 'Olof Johansson'
Cc: 'Florian Tobias Schandinat', linux-fbdev, linux-kernel
In-Reply-To: <1333944982-15859-1-git-send-email-olof@lixom.net>
> -----Original Message-----
> From: Olof Johansson [mailto:olof@lixom.net]
> Sent: Monday, April 09, 2012 1:16 PM
>
> I'm not 100% sure if the fix for 'adjust_request' is correct, since
> it's uncertain what the original intent was. But it's so clearly an
> uninitialized pointer dereference that my resolution seems to make sense.
>
> drivers/video/exynos/exynos_dp_core.c: In function 'exynos_dp_set_link_train':
> drivers/video/exynos/exynos_dp_core.c:521:21: warning: 'adjust_request' may be used uninitialized in
> this function [-Wuninitialized]
> drivers/video/exynos/exynos_dp_core.c:481:6: note: 'adjust_request' was declared here
> drivers/video/exynos/exynos_dp_core.c:529:18: warning: 'reg' may be used uninitialized in this function
> [-Wuninitialized]
> drivers/video/exynos/exynos_dp_core.c:395:6: note: 'reg' was declared here
>
> Signed-off-by: Olof Johansson <olof@lixom.net>
> ---
> drivers/video/exynos/exynos_dp_core.c | 23 +++++++++--------------
> 1 file changed, 9 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index 2a4481c..8973e18 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -392,24 +392,19 @@ static unsigned int exynos_dp_get_lane_link_training(
> struct exynos_dp_device *dp,
> int lane)
> {
> - u32 reg;
> -
> switch (lane) {
> case 0:
> - reg = exynos_dp_get_lane0_link_training(dp);
> - break;
> + return exynos_dp_get_lane0_link_training(dp);
> case 1:
> - reg = exynos_dp_get_lane1_link_training(dp);
> - break;
> + return exynos_dp_get_lane1_link_training(dp);
> case 2:
> - reg = exynos_dp_get_lane2_link_training(dp);
> - break;
> + return exynos_dp_get_lane2_link_training(dp);
> case 3:
> - reg = exynos_dp_get_lane3_link_training(dp);
> - break;
> + return exynos_dp_get_lane3_link_training(dp);
> }
I don't like multi return.
>
> - return reg;
> + WARN_ON(1);
> + return 0;
> }
>
> static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
> @@ -489,13 +484,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
> 6, link_status);
> lane_count = dp->link_train.lane_count;
>
> + adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
> + - DPCD_ADDR_LANE0_1_STATUS);
> +
It makes the problem. adjust_request will be different.
OK, I understand what you want to do.
I will send the version 2 patch which is simpler.
Thank you for sending the patch.
> if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
> /* set training pattern 2 for EQ */
> exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
>
> - adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
> - - DPCD_ADDR_LANE0_1_STATUS);
> -
> exynos_dp_get_adjust_train(dp, adjust_request);
>
> buf[0] = DPCD_SCRAMBLING_DISABLED |
> --
> 1.7.9.2.359.gebfc2
^ permalink raw reply
* RE: [PATCH] video: exynos: fix build warning and bad pointer deref in dp driver
From: Jingoo Han @ 2012-04-09 9:25 UTC (permalink / raw)
To: 'Olof Johansson'
Cc: 'Florian Tobias Schandinat', linux-fbdev, linux-kernel
In-Reply-To: <1333944982-15859-1-git-send-email-olof@lixom.net>
> -----Original Message-----
> From: Olof Johansson [mailto:olof@lixom.net]
> Sent: Monday, April 09, 2012 1:16 PM
>
> I'm not 100% sure if the fix for 'adjust_request' is correct, since
> it's uncertain what the original intent was. But it's so clearly an
> uninitialized pointer dereference that my resolution seems to make sense.
>
> drivers/video/exynos/exynos_dp_core.c: In function 'exynos_dp_set_link_train':
> drivers/video/exynos/exynos_dp_core.c:521:21: warning: 'adjust_request' may be used uninitialized in
> this function [-Wuninitialized]
> drivers/video/exynos/exynos_dp_core.c:481:6: note: 'adjust_request' was declared here
> drivers/video/exynos/exynos_dp_core.c:529:18: warning: 'reg' may be used uninitialized in this function
> [-Wuninitialized]
> drivers/video/exynos/exynos_dp_core.c:395:6: note: 'reg' was declared here
My compiler cannot detect this warning.
What is your compiler version?
>
> Signed-off-by: Olof Johansson <olof@lixom.net>
> ---
> drivers/video/exynos/exynos_dp_core.c | 23 +++++++++--------------
> 1 file changed, 9 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index 2a4481c..8973e18 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -392,24 +392,19 @@ static unsigned int exynos_dp_get_lane_link_training(
> struct exynos_dp_device *dp,
> int lane)
> {
> - u32 reg;
> -
> switch (lane) {
> case 0:
> - reg = exynos_dp_get_lane0_link_training(dp);
> - break;
> + return exynos_dp_get_lane0_link_training(dp);
> case 1:
> - reg = exynos_dp_get_lane1_link_training(dp);
> - break;
> + return exynos_dp_get_lane1_link_training(dp);
> case 2:
> - reg = exynos_dp_get_lane2_link_training(dp);
> - break;
> + return exynos_dp_get_lane2_link_training(dp);
> case 3:
> - reg = exynos_dp_get_lane3_link_training(dp);
> - break;
> + return exynos_dp_get_lane3_link_training(dp);
> }
>
> - return reg;
> + WARN_ON(1);
> + return 0;
> }
>
> static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
> @@ -489,13 +484,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
> 6, link_status);
> lane_count = dp->link_train.lane_count;
>
> + adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
> + - DPCD_ADDR_LANE0_1_STATUS);
> +
> if (exynos_dp_clock_recovery_ok(link_status, lane_count) = 0) {
> /* set training pattern 2 for EQ */
> exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
>
> - adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
> - - DPCD_ADDR_LANE0_1_STATUS);
> -
> exynos_dp_get_adjust_train(dp, adjust_request);
>
> buf[0] = DPCD_SCRAMBLING_DISABLED |
> --
> 1.7.9.2.359.gebfc2
^ permalink raw reply
* Re: [PATCH] video: exynos: fix build warning and bad pointer deref in dp driver
From: Olof Johansson @ 2012-04-09 14:05 UTC (permalink / raw)
To: Jingoo Han; +Cc: Florian Tobias Schandinat, linux-fbdev, linux-kernel
In-Reply-To: <002301cd162d$51bd6b00$f5384100$%han@samsung.com>
On Mon, Apr 9, 2012 at 1:46 AM, Jingoo Han <jg1.han@samsung.com> wrote:
>> -----Original Message-----
>> From: Olof Johansson [mailto:olof@lixom.net]
>> Sent: Monday, April 09, 2012 1:16 PM
>>
>> I'm not 100% sure if the fix for 'adjust_request' is correct, since
>> it's uncertain what the original intent was. But it's so clearly an
>> uninitialized pointer dereference that my resolution seems to make sense.
>>
>> drivers/video/exynos/exynos_dp_core.c: In function 'exynos_dp_set_link_train':
>> drivers/video/exynos/exynos_dp_core.c:521:21: warning: 'adjust_request' may be used uninitialized in
>> this function [-Wuninitialized]
>> drivers/video/exynos/exynos_dp_core.c:481:6: note: 'adjust_request' was declared here
>> drivers/video/exynos/exynos_dp_core.c:529:18: warning: 'reg' may be used uninitialized in this function
>> [-Wuninitialized]
>> drivers/video/exynos/exynos_dp_core.c:395:6: note: 'reg' was declared here
>>
>> Signed-off-by: Olof Johansson <olof@lixom.net>
>> ---
>> drivers/video/exynos/exynos_dp_core.c | 23 +++++++++--------------
>> 1 file changed, 9 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
>> index 2a4481c..8973e18 100644
>> --- a/drivers/video/exynos/exynos_dp_core.c
>> +++ b/drivers/video/exynos/exynos_dp_core.c
>> @@ -392,24 +392,19 @@ static unsigned int exynos_dp_get_lane_link_training(
>> struct exynos_dp_device *dp,
>> int lane)
>> {
>> - u32 reg;
>> -
>> switch (lane) {
>> case 0:
>> - reg = exynos_dp_get_lane0_link_training(dp);
>> - break;
>> + return exynos_dp_get_lane0_link_training(dp);
>> case 1:
>> - reg = exynos_dp_get_lane1_link_training(dp);
>> - break;
>> + return exynos_dp_get_lane1_link_training(dp);
>> case 2:
>> - reg = exynos_dp_get_lane2_link_training(dp);
>> - break;
>> + return exynos_dp_get_lane2_link_training(dp);
>> case 3:
>> - reg = exynos_dp_get_lane3_link_training(dp);
>> - break;
>> + return exynos_dp_get_lane3_link_training(dp);
>> }
>
> I don't like multi return.
In a small helper function like this there's nothing wrong with it.
Larger functions? Sure.
Adding a default in the switch didn't seem like an improvement to me.
But I'll leave it up to you.
>>
>> - return reg;
>> + WARN_ON(1);
>> + return 0;
>> }
>>
>> static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
>> @@ -489,13 +484,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
>> 6, link_status);
>> lane_count = dp->link_train.lane_count;
>>
>> + adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
>> + - DPCD_ADDR_LANE0_1_STATUS);
>> +
>
> It makes the problem. adjust_request will be different.
>
> OK, I understand what you want to do.
> I will send the version 2 patch which is simpler.
>
> Thank you for sending the patch.
Ok, thanks. As I said, I'm not sure what your intent with the second
(else) code path was.
-Olof
^ permalink raw reply
* Re: [PATCH] video: exynos: fix build warning and bad pointer deref in dp driver
From: Olof Johansson @ 2012-04-09 14:07 UTC (permalink / raw)
To: Jingoo Han; +Cc: Florian Tobias Schandinat, linux-fbdev, linux-kernel
In-Reply-To: <002601cd1632$c34b24b0$49e16e10$%han@samsung.com>
On Mon, Apr 9, 2012 at 2:25 AM, Jingoo Han <jg1.han@samsung.com> wrote:
>> -----Original Message-----
>> From: Olof Johansson [mailto:olof@lixom.net]
>> Sent: Monday, April 09, 2012 1:16 PM
>>
>> I'm not 100% sure if the fix for 'adjust_request' is correct, since
>> it's uncertain what the original intent was. But it's so clearly an
>> uninitialized pointer dereference that my resolution seems to make sense.
>>
>> drivers/video/exynos/exynos_dp_core.c: In function 'exynos_dp_set_link_train':
>> drivers/video/exynos/exynos_dp_core.c:521:21: warning: 'adjust_request' may be used uninitialized in
>> this function [-Wuninitialized]
>> drivers/video/exynos/exynos_dp_core.c:481:6: note: 'adjust_request' was declared here
>> drivers/video/exynos/exynos_dp_core.c:529:18: warning: 'reg' may be used uninitialized in this function
>> [-Wuninitialized]
>> drivers/video/exynos/exynos_dp_core.c:395:6: note: 'reg' was declared here
>
> My compiler cannot detect this warning.
> What is your compiler version?
gcc version 4.6.2 (GCC)
-Olof
^ permalink raw reply
* Re: Problem with framebuffer mmap on platforms with large addressing
From: Dmitry Eremin-Solenikov @ 2012-04-09 16:18 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linux-fbdev, Florian Tobias Schandinat, Tony Breeds, linuxppc-dev
In-Reply-To: <1332222008.2982.13.camel@pasglop>
On Tue, Mar 20, 2012 at 9:40 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
>
>> >> That is interesting! Are those patches published or otherwise available
>> >> somewhere? We are also very interested in enabling Canyonlands
>> >> with Radeon KMS!
>> >
>> > You will run into additional problems with 460 due to the fact that it's
>> > not cache coherent for DMA. Tony patches don't address that part of the
>> > problem (they were used on a 476 based platform).
>>
>> Hmm. Could you please spill a little bit more of details? Also are those patches
>> for 476 merged or present somewhere?
>
> Well, DMA on 46x isn't cache coherent. The DRM plays interesting games
> with mapping/unmapping pages for DMA by the chip and I don't think we
> have the right hooks to do the appropriate cache flushing on these guys,
> but Tony might be able to comment, I don't know whether he tried or not.
>
> On the other hand 476 has fully cache coherent DMA so the only problem
> there is the >32-bit physical address space.
>
> As for the patches, you'll have to wait for Tony to respond (I'll poke
> him locally).
Any news on these patches? A dirty and "not for the upstream yet" version
would be sufficient for me for now.
>
> Cheers,
> Ben.
>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: Problem with framebuffer mmap on platforms with large addressing
From: Benjamin Herrenschmidt @ 2012-04-09 21:37 UTC (permalink / raw)
To: Dmitry Eremin-Solenikov
Cc: linux-fbdev, Florian Tobias Schandinat, Tony Breeds, linuxppc-dev
In-Reply-To: <CALT56yOU2FDTNRnr=aLVFTGHiVsGNKVoqLqAWQ7Q+Xzg6_B8qQ@mail.gmail.com>
On Mon, 2012-04-09 at 20:18 +0400, Dmitry Eremin-Solenikov wrote:
> > As for the patches, you'll have to wait for Tony to respond (I'll
> poke
> > him locally).
>
> Any news on these patches? A dirty and "not for the upstream yet"
> version
> would be sufficient for me for now.
I'll poke again..
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH] video:uvesafb: Fix oops that uvesafb try to execute NX-protected page
From: Wang YanQing @ 2012-04-10 6:49 UTC (permalink / raw)
To: Alan Cox, FlorianSchandinat, linux-fbdev, linux-kernel, spock
In-Reply-To: <20120401010530.GA4431@udknight>
On Sun, Apr 01, 2012 at 09:05:30AM +0800, Wang YanQing wrote:
> On Wed, Mar 28, 2012 at 08:52:38AM +0800, Wang YanQing wrote:
> > On Tue, Mar 27, 2012 at 02:32:43PM +0100, Alan Cox wrote:
> > > On Tue, 27 Mar 2012 18:01:36 +0800
> > > Wang YanQing <udknight@gmail.com> wrote:
> > >
> > > >
> > > > Ok! I try to check pcibios_enabled first, but get some opposition by Alan Cox,
> > > > but I want to make thing work and fix the oops, so I choice the simple way to
> > > > check the (__supported_pte_mask & _PAGE_NX) instead of to check this variable plus
> > > > pci kernel boot parameter, pci mmconfig works or not, and more, and more. It is not
> > > > the best method, but it works and maybe all will feel happy.
> > >
> > > Okay let me ask the obvious question - why is it not the best method ?
> > >
> > > Apart from adding a helper in the includes for the arch code of
> > >
> > > static inline is_nx_enabled(void)
> > > {
> > > return !!(__supported_pte_mask & _PAGE_NX);
> > > }
> > >
> > > is there anything else it lacks ?
> > >
> > > Yes ideally we'd set the relevant ROM areas executable, but for a simple
> > > fix is there anything else that's a problem with it ?
> > Ok! Maybe you had missed my previous reply
> > http://permalink.gmane.org/gmane.linux.kernel/1272433
> > It is not the best method, because the check is not enough.
> > I means when NX is actively, the pci bios is NX or not also depend on
> > the code path in pci_arch_init which will be influenced by the acpi on or off, pci kernel boot
> > parameter, even kernel config like pci access method PCI_GOANY, PCI_GOMMCONFIG, or PCI_GODIRECT,
> > but if I check the pcibios_enabled, all the above can be ignored.
> >
> > if uvesafb use the PMI when PCI BIOS is X, it can get the better work efficience then use the redraw
> > method as a fallback when do the panning.
> Alan
>
> I am just curious, I want to know what I describe above is right a little,
> or wrong about all the aspect.
> thanks.
>
Hi Alan, are you decided to not reply this any?
But maybe we are still here to wait for your proposal to
decide the final proper solution to fix the bug in kernel.
Thanks
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox