* [PATCH v4 17/19] staging: sm750fb: move while to follow do close brace
From: Juston Li @ 2015-06-29 17:55 UTC (permalink / raw)
To: sudipm.mukherjee, teddy.wang, gregkh, linux-fbdev, devel,
linux-kernel, dan.carpenter
Cc: Juston Li
In-Reply-To: <CAFow2F-+fT0iRmFd+H_X-1gBmvCsgehxXeyr7A8Zk9TtfD0aBA@mail.gmail.com>
Fixes checkpatch.pl error:
ERROR: while should follow close brace '}'
Signed-off-by: Juston Li <juston.h.li@gmail.com>
---
drivers/staging/sm750fb/ddk750_display.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c
index a64ea32..abd6283 100644
--- a/drivers/staging/sm750fb/ddk750_display.c
+++ b/drivers/staging/sm750fb/ddk750_display.c
@@ -139,16 +139,14 @@ static void waitNextVerticalSync(int ctrl, int delay)
status = FIELD_GET(PEEK32(SYSTEM_CTRL),
SYSTEM_CTRL,
PANEL_VSYNC);
- }
- while (status = SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
+ } while (status = SYSTEM_CTRL_PANEL_VSYNC_ACTIVE);
/* Wait for start of vsync. */
do {
status = FIELD_GET(PEEK32(SYSTEM_CTRL),
SYSTEM_CTRL,
PANEL_VSYNC);
- }
- while (status = SYSTEM_CTRL_PANEL_VSYNC_INACTIVE);
+ } while (status = SYSTEM_CTRL_PANEL_VSYNC_INACTIVE);
}
} else {
@@ -168,16 +166,14 @@ static void waitNextVerticalSync(int ctrl, int delay)
status = FIELD_GET(PEEK32(SYSTEM_CTRL),
SYSTEM_CTRL,
CRT_VSYNC);
- }
- while (status = SYSTEM_CTRL_CRT_VSYNC_ACTIVE);
+ } while (status = SYSTEM_CTRL_CRT_VSYNC_ACTIVE);
/* Wait for start of vsync. */
do {
status = FIELD_GET(PEEK32(SYSTEM_CTRL),
SYSTEM_CTRL,
CRT_VSYNC);
- }
- while (status = SYSTEM_CTRL_CRT_VSYNC_INACTIVE);
+ } while (status = SYSTEM_CTRL_CRT_VSYNC_INACTIVE);
}
}
}
--
2.4.4
^ permalink raw reply related
* [PATCH v4 18/19] staging: sm750fb: remove unnecessary braces
From: Juston Li @ 2015-06-29 17:55 UTC (permalink / raw)
To: sudipm.mukherjee, teddy.wang, gregkh, linux-fbdev, devel,
linux-kernel, dan.carpenter
Cc: Juston Li
In-Reply-To: <CAFow2F-+fT0iRmFd+H_X-1gBmvCsgehxXeyr7A8Zk9TtfD0aBA@mail.gmail.com>
Fixes checkpatch.pl warning:
WARNING: braces {} are not necessary for single statement blocks
Signed-off-by: Juston Li <juston.h.li@gmail.com>
---
drivers/staging/sm750fb/sm750_accel.c | 9 +++------
drivers/staging/sm750fb/sm750_hw.c | 6 ++----
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
index f7a617e..291a47b 100644
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -259,9 +259,8 @@ unsigned int rop2) /* ROP value */
FIELD_VALUE(0, DE_WINDOW_WIDTH, DESTINATION, (dPitch/Bpp)) |
FIELD_VALUE(0, DE_WINDOW_WIDTH, SOURCE, (sPitch/Bpp))); /* dpr3c */
- if (accel->de_wait() != 0) {
+ if (accel->de_wait() != 0)
return -1;
- }
{
@@ -332,9 +331,8 @@ int hw_imageblit(struct lynx_accel *accel,
ul4BytesPerScan = ulBytesPerScan & ~3;
ulBytesRemain = ulBytesPerScan & 3;
- if (accel->de_wait() != 0) {
+ if (accel->de_wait() != 0)
return -1;
- }
/* 2D Source Base.
Use 0 for HOST Blt.
@@ -402,9 +400,8 @@ int hw_imageblit(struct lynx_accel *accel,
/* Write MONO data (line by line) to 2D Engine data port */
for (i = 0; i < height; i++) {
/* For each line, send the data in chunks of 4 bytes */
- for (j = 0; j < (ul4BytesPerScan/4); j++) {
+ for (j = 0; j < (ul4BytesPerScan/4); j++)
write_dpPort(accel, *(unsigned int *)(pSrcbuf + (j * 4)));
- }
if (ulBytesRemain) {
memcpy(ajRemain, pSrcbuf+ul4BytesPerScan, ulBytesRemain);
diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c
index 20a8d3b..97a0f63 100644
--- a/drivers/staging/sm750fb/sm750_hw.c
+++ b/drivers/staging/sm750fb/sm750_hw.c
@@ -187,9 +187,8 @@ int hw_sm750_inithw(struct lynx_share *share, struct pci_dev *pdev)
}
/* init 2d engine */
- if (!share->accel_off) {
+ if (!share->accel_off)
hw_sm750_initAccel(share);
- }
return 0;
}
@@ -536,9 +535,8 @@ int hw_sm750_setBLANK(struct lynxfb_output* output, int blank)
POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, BLANK, crtdb));
}
- if (output->paths & sm750_panel) {
+ if (output->paths & sm750_panel)
POKE32(PANEL_DISPLAY_CTRL, FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, DATA, pps));
- }
return 0;
}
--
2.4.4
^ permalink raw reply related
* [PATCH v4 19/19] staging: sm750fb: add missing blank line after declarations
From: Juston Li @ 2015-06-29 17:55 UTC (permalink / raw)
To: sudipm.mukherjee, teddy.wang, gregkh, linux-fbdev, devel,
linux-kernel, dan.carpenter
Cc: Juston Li
In-Reply-To: <CAFow2F-+fT0iRmFd+H_X-1gBmvCsgehxXeyr7A8Zk9TtfD0aBA@mail.gmail.com>
Fixes checkpatch.pl
WARNING: Missing a blank line after declarations
Signed-off-by: Juston Li <juston.h.li@gmail.com>
---
drivers/staging/sm750fb/ddk750_chip.c | 1 +
drivers/staging/sm750fb/ddk750_display.c | 2 ++
drivers/staging/sm750fb/ddk750_dvi.c | 1 +
drivers/staging/sm750fb/ddk750_mode.c | 3 +++
drivers/staging/sm750fb/ddk750_power.c | 1 +
drivers/staging/sm750fb/ddk750_sii164.c | 1 +
drivers/staging/sm750fb/sm750_accel.c | 1 +
drivers/staging/sm750fb/sm750_cursor.c | 2 ++
drivers/staging/sm750fb/sm750_hw.c | 7 +++++++
9 files changed, 19 insertions(+)
diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c
index d7435d7..5e6798e 100644
--- a/drivers/staging/sm750fb/ddk750_chip.c
+++ b/drivers/staging/sm750fb/ddk750_chip.c
@@ -474,6 +474,7 @@ unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
M += (fl_quo*X % 10000) > 5000?1:0;
if (M < 256 && M > 0) {
unsigned int diff;
+
tmpClock = pll->inputFreq * M / N / X;
diff = absDiff(tmpClock, request_orig);
if (diff < miniDiff) {
diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c
index abd6283..8348113 100644
--- a/drivers/staging/sm750fb/ddk750_display.c
+++ b/drivers/staging/sm750fb/ddk750_display.c
@@ -121,6 +121,7 @@ static void setDisplayControl(int ctrl, int dispState)
static void waitNextVerticalSync(int ctrl, int delay)
{
unsigned int status;
+
if (!ctrl) {
/* primary controller */
@@ -210,6 +211,7 @@ static void swPanelPowerSequence(int disp, int delay)
void ddk750_setLogicalDispOut(disp_output_t output)
{
unsigned int reg;
+
if (output & PNL_2_USAGE) {
/* set panel path controller select */
reg = PEEK32(PANEL_DISPLAY_CTRL);
diff --git a/drivers/staging/sm750fb/ddk750_dvi.c b/drivers/staging/sm750fb/ddk750_dvi.c
index a18bb4c..a7a2351 100644
--- a/drivers/staging/sm750fb/ddk750_dvi.c
+++ b/drivers/staging/sm750fb/ddk750_dvi.c
@@ -43,6 +43,7 @@ int dviInit(
)
{
dvi_ctrl_device_t *pCurrentDviCtrl;
+
pCurrentDviCtrl = g_dcftSupportedDviController;
if (pCurrentDviCtrl->pfnInit != NULL) {
return pCurrentDviCtrl->pfnInit(edgeSelect, busSelect, dualEdgeClkSelect, hsyncEnable,
diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c
index 9d10446..2399b17 100644
--- a/drivers/staging/sm750fb/ddk750_mode.c
+++ b/drivers/staging/sm750fb/ddk750_mode.c
@@ -80,6 +80,7 @@ static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t *pll)
int ret = 0;
int cnt = 0;
unsigned int ulTmpValue, ulReg;
+
if (pll->clockType = SECONDARY_PLL) {
/* programe secondary pixel clock */
POKE32(CRT_PLL_CTRL, formatPllReg(pll));
@@ -120,6 +121,7 @@ static int programModeRegisters(mode_parameter_t *pModeParam, pll_value_t *pll)
} else if (pll->clockType = PRIMARY_PLL) {
unsigned int ulReservedBits;
+
POKE32(PANEL_PLL_CTRL, formatPllReg(pll));
POKE32(PANEL_HORIZONTAL_TOTAL,
@@ -184,6 +186,7 @@ int ddk750_setModeTiming(mode_parameter_t *parm, clock_type_t clock)
{
pll_value_t pll;
unsigned int uiActualPixelClk;
+
pll.inputFreq = DEFAULT_INPUT_CLOCK;
pll.clockType = clock;
diff --git a/drivers/staging/sm750fb/ddk750_power.c b/drivers/staging/sm750fb/ddk750_power.c
index c545c2d..c8c51be 100644
--- a/drivers/staging/sm750fb/ddk750_power.c
+++ b/drivers/staging/sm750fb/ddk750_power.c
@@ -5,6 +5,7 @@
void ddk750_setDPMS(DPMS_t state)
{
unsigned int value;
+
if (getChipType() = SM750LE) {
value = PEEK32(CRT_DISPLAY_CTRL);
POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(value, CRT_DISPLAY_CTRL, DPMS, state));
diff --git a/drivers/staging/sm750fb/ddk750_sii164.c b/drivers/staging/sm750fb/ddk750_sii164.c
index a5153be..0bdf3db 100644
--- a/drivers/staging/sm750fb/ddk750_sii164.c
+++ b/drivers/staging/sm750fb/ddk750_sii164.c
@@ -340,6 +340,7 @@ void sii164EnableHotPlugDetection(
)
{
unsigned char detectReg;
+
detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
/* Depending on each DVI controller, need to enable the hot plug based on each
diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
index 291a47b..b75ffbd 100644
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -152,6 +152,7 @@ unsigned int rop2) /* ROP value */
{
unsigned int nDirection, de_ctrl;
int opSign;
+
nDirection = LEFT_TO_RIGHT;
/* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left */
opSign = 1;
diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c
index ab61fe6..2400c6c 100644
--- a/drivers/staging/sm750fb/sm750_cursor.c
+++ b/drivers/staging/sm750fb/sm750_cursor.c
@@ -61,6 +61,7 @@ writel((data), cursor->mmio + (addr))
void hw_cursor_enable(struct lynx_cursor *cursor)
{
u32 reg;
+
reg = FIELD_VALUE(0, HWC_ADDRESS, ADDRESS, cursor->offset)|
FIELD_SET(0, HWC_ADDRESS, EXT, LOCAL)|
FIELD_SET(0, HWC_ADDRESS, ENABLE, ENABLE);
@@ -81,6 +82,7 @@ void hw_cursor_setPos(struct lynx_cursor *cursor,
int x, int y)
{
u32 reg;
+
reg = FIELD_VALUE(0, HWC_LOCATION, Y, y)|
FIELD_VALUE(0, HWC_LOCATION, X, x);
POKE32(HWC_LOCATION, reg);
diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c
index 97a0f63..10f15b5 100644
--- a/drivers/staging/sm750fb/sm750_hw.c
+++ b/drivers/staging/sm750fb/sm750_hw.c
@@ -243,6 +243,7 @@ int hw_sm750_output_setMode(struct lynxfb_output* output,
} else {
/* just open DISPLAY_CONTROL_750LE register bit 3:0*/
u32 reg;
+
reg = PEEK32(DISPLAY_CONTROL_750LE);
reg |= 0xf;
POKE32(DISPLAY_CONTROL_750LE, reg);
@@ -417,6 +418,7 @@ int hw_sm750_setColReg(struct lynxfb_crtc* crtc, ushort index,
ushort red, ushort green, ushort blue)
{
static unsigned int add[] = {PANEL_PALETTE_RAM, CRT_PALETTE_RAM};
+
POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue);
return 0;
}
@@ -545,6 +547,7 @@ int hw_sm750_setBLANK(struct lynxfb_output* output, int blank)
void hw_sm750_initAccel(struct lynx_share *share)
{
u32 reg;
+
enable2DEngine(1);
if (getChipType() = SM750LE) {
@@ -574,8 +577,10 @@ void hw_sm750_initAccel(struct lynx_share *share)
int hw_sm750le_deWait(void)
{
int i = 0x10000000;
+
while (i--) {
unsigned int dwVal = PEEK32(DE_STATE2);
+
if ((FIELD_GET(dwVal, DE_STATE2, DE_STATUS) = DE_STATE2_DE_STATUS_IDLE) &&
(FIELD_GET(dwVal, DE_STATE2, DE_FIFO) = DE_STATE2_DE_FIFO_EMPTY) &&
(FIELD_GET(dwVal, DE_STATE2, DE_MEM_FIFO) = DE_STATE2_DE_MEM_FIFO_EMPTY)) {
@@ -590,8 +595,10 @@ int hw_sm750le_deWait(void)
int hw_sm750_deWait(void)
{
int i = 0x10000000;
+
while (i--) {
unsigned int dwVal = PEEK32(SYSTEM_CTRL);
+
if ((FIELD_GET(dwVal, SYSTEM_CTRL, DE_STATUS) = SYSTEM_CTRL_DE_STATUS_IDLE) &&
(FIELD_GET(dwVal, SYSTEM_CTRL, DE_FIFO) = SYSTEM_CTRL_DE_FIFO_EMPTY) &&
(FIELD_GET(dwVal, SYSTEM_CTRL, DE_MEM_FIFO) = SYSTEM_CTRL_DE_MEM_FIFO_EMPTY)) {
--
2.4.4
^ permalink raw reply related
* Re: [RFC 1/6] drm: Add top level Kconfig option for DRM fbdev emulation
From: Daniel Vetter @ 2015-06-30 7:10 UTC (permalink / raw)
To: Archit Taneja, Clark, Rob, Dave Airlie, Thierry Reding,
Philipp Zabel, Benjamin Gaignard, dri-devel,
Linux Kernel Mailing List, linux-arm-msm, Jani Nikula,
Linux Fbdev development list, Tomi Valkeinen
In-Reply-To: <20150325092111.GT1349@phenom.ffwll.local>
Any updates on this or too much distractions? I really think doing
this would be awesome for the drm subsystem, instead of reinventing
this wheel for each driver.
-Daniel
On Wed, Mar 25, 2015 at 10:21 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Wed, Mar 25, 2015 at 01:47:54PM +0530, Archit Taneja wrote:
>> Hi,
>>
>> On 03/13/2015 02:36 PM, Daniel Vetter wrote:
>> >On Fri, Mar 13, 2015 at 11:55:07AM +0530, Archit Taneja wrote:
>> >>
>> >>
>> >>On 03/11/2015 08:47 PM, Daniel Vetter wrote:
>> >>>On Wed, Mar 11, 2015 at 01:51:02PM +0530, Archit Taneja wrote:
>> >>>>
>> >>>>
>> >>>>On 03/10/2015 05:47 PM, Daniel Vetter wrote:
>> >>>>>On Tue, Mar 10, 2015 at 03:52:41PM +0530, Archit Taneja wrote:
>> >>>>>>On 03/10/2015 03:35 PM, Daniel Vetter wrote:
>> >>>>>>>On Tue, Mar 10, 2015 at 03:22:49PM +0530, Archit Taneja wrote:
>> >>>>>>>>On 03/10/2015 03:17 PM, Daniel Vetter wrote:
>> >>>>>>>>>On Tue, Mar 10, 2015 at 03:11:28PM +0530, Archit Taneja wrote:
>> >>>>>>>>>>diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>> >>>>>>>>>>index 151a050..38f83a0 100644
>> >>>>>>>>>>--- a/drivers/gpu/drm/Kconfig
>> >>>>>>>>>>+++ b/drivers/gpu/drm/Kconfig
>> >>>>>>>>>>@@ -40,6 +40,24 @@ config DRM_KMS_FB_HELPER
>> >>>>>>>>>> help
>> >>>>>>>>>> FBDEV helpers for KMS drivers.
>> >>>>>>>>>>
>> >>>>>>>>>>+config DRM_FBDEV_EMULATION
>> >>>>>>>>>>+ bool "Enable legacy fbdev support for your modesetting driver"
>> >>>>>>>>>>+ depends on DRM
>> >>>>>>>>>>+ select DRM_KMS_HELPER
>> >>>>>>>>>>+ select DRM_KMS_FB_HELPER
>> >>>>>>>>>>+ select FB_SYS_FILLRECT
>> >>>>>>>>>>+ select FB_SYS_COPYAREA
>> >>>>>>>>>>+ select FB_SYS_IMAGEBLIT
>> >>>>>>>>>>+ select FB_SYS_FOPS
>> >>>>>>>>>>+ select FB_CFB_FILLRECT
>> >>>>>>>>>>+ select FB_CFB_COPYAREA
>> >>>>>>>>>>+ select FB_CFB_IMAGEBLIT
>> >>>>>>>>>>+ default y
>> >>>>>>>>>>+ help
>> >>>>>>>>>>+ Choose this option if you have a need for the legacy fbdev
>> >>>>>>>>>>+ support. Note that this support also provide the linux console
>> >>>>>>>>>>+ support on top of your modesetting driver.
>> >>>>>>>>>
>> >>>>>>>>>Maybe clarify that for linux console support you also need
>> >>>>>>>>>CONFIG_FRAMEBUFFER_CONSOLE? fbdev alone isn't enough.
>> >>>>>>>>
>> >>>>>>>>DRM_KMS_FB_HELPER selects that for us, right?
>> >>>>>>>
>> >>>>>>>Hm right I've missed that. Reminds me that you need one more patch at the
>> >>>>>>>end to remove all the various select DRM_KMS_FB_HELPER from all drm
>> >>>>>>>drivers. Otherwise this knob here won't work by default if you e.g. select
>> >>>>>>>radeon. In general we can't mix explicit options with menu entries with a
>> >>>>>>>select.
>> >>>>>>
>> >>>>>>I was trying that out. Removing DRM_KMS_FB_HELPER and having
>> >>>>>>DRM_FBDEV_EMULATION disabled breaks drivers which use FB stuff internally in
>> >>>>>>their respective xyz_fbdev.c files.
>> >>>>>
>> >>>>>But with the stubbed out functions that should work, right? Why doesn't
>> >>>>>it?
>> >>>>
>> >>>>There are still calls to functions from fb core like fb_set_suspend and
>> >>>>register_framebuffer which aren't covered by the drm fb helper functions.
>> >>>
>> >>>Hm, sounds like we need another patch to stub out fb_set_suspend when
>> >>>fbdev isn't enabled. Is there anything else?
>> >>
>> >>There are a handful of fb core functions which are called by drm drivers:
>> >>
>> >>fb_alloc_cmap/fb_dealloc_cmap
>> >>
>> >>fb_sys_read/fb_sys_write
>> >>
>> >>register_framebuffer/unregister_framebuffer/unlink_framebuffer/
>> >>remove_conflicting_framebuffers
>> >>
>> >>fb_set_suspend
>> >>
>> >>fb_deferred_io_init/fb_deferred_io_cleanup
>> >>
>> >>framebuffer_alloc/framebuffer_release
>> >
>> >Hm yeah that's somewhat annoying indeed. What about the following:
>> >1. We move all the #include <linux/fb.h> from drivers into drm_fb_helper.h
>> >
>> >2. Then we add stubs for these functions in drm_fb_helper.h, like this
>> >
>> >#if defined(CONFIG_FB)
>> >#include <linux/fb.h>
>> >#else
>> >
>> >/* static inline stubs for all the fb stuff used by kms drivers */
>> >#endif
>> >
>> >Imo this makes sense since kms drivers really have a bit a special
>> >situation with fbdev. They're not full-blown fbdev drivers and can be
>> >useful fully without fbdev.
>> >
>>
>> I was trying this out. Removing 'linux/fb.h' and replacing stub fb funcs
>> won't really work because struct declarations(like fb_info) also get
>> removed.
>>
>> I considered placing '#if IS_ENABLED(CONFIG_FB)' within linux/fb.h itself,
>> but that seemed a bit too intrusive.
>>
>> This is what I'm currently doing:
>>
>> - Some funcs, like framebufer_alloc/release, alloc_cmap/dealloc_cmap would
>> actually benefit if we have drm fb helpers for them. They are used in
>> exactly the same manner by all the drivers.
>>
>> - For the rest of the functions that are sparsely used, I was considering
>> making very simple drm_fb_* wrapper functions. Something like:
>>
>> void drm_fb_helper_deferred_io_init(struct drm_fb_helper *helper)
>> {
>> if (helper->fbdev)
>> fb_deferred_io_init(helper->fbdev);
>> }
>>
>> We could have all fb calls called within drm_fb_helper.c, creating
>> drm_fb_helper_* stub functions would then be an easier task. What do you
>> think?
>
> That's actually an option I considered, but I hoped we could do it with
> less work. If this indeed works and you can create the patch that would be
> awesome.
>
> Thanks, Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply
* Re: [PATCH v3 11/19] staging: sm750fb: consistent spacing around operators
From: Sudip Mukherjee @ 2015-06-30 7:47 UTC (permalink / raw)
To: Juston Li
Cc: teddy.wang, Greg KH, linux-fbdev, devel, linux-kernel,
Dan Carpenter
In-Reply-To: <CAFow2F9y-ux5_hoQmG-WNHCzA3aw0EB9wxJ57+zOWnYt6ds-JA@mail.gmail.com>
On Thu, Jun 25, 2015 at 10:53:33PM -0700, Juston Li wrote:
> On Thu, Jun 25, 2015 at 9:05 PM, Sudip Mukherjee
> <sudipm.mukherjee@gmail.com> wrote:
> > Usually I use the checkpatch which is in linux-next. That will be the
> > latest version. If you compare, last commit on checkpatch of staging
> > tree was on April 16th, where as last commit in linux-next is on
> > June 19th. And if you use this checkpatch you will see these warnings
> > also. :)
>
> Just wanted to clarify. So even with the linux-next checkpatch.pl, no
> errors/warnings show for me. Only when I run checkpatch.pl with the
> '--strict' option does it give the following checks for various operators:
> CHECK: space preferred before that '|' (ctx:VxE)
>
> Are these the warnings you are referring too? Do you want me to fix all
> of these for this patch?
Hi,
Sorry for the late reply, was a bit busy.
since your commit message was saying "spacing around operators"
and you were fixing the spacing around all types of operators so there
is no point leaving few not fixed on the same line.
But anyways, since you have already sent new series, its ok.
regards
sudip
^ permalink raw reply
* Re: [RFC 1/6] drm: Add top level Kconfig option for DRM fbdev emulation
From: Archit Taneja @ 2015-06-30 7:56 UTC (permalink / raw)
To: Daniel Vetter, Clark, Rob, Dave Airlie, Thierry Reding,
Philipp Zabel, Benjamin Gaignard, dri-devel,
Linux Kernel Mailing List, linux-arm-msm, Jani Nikula,
Linux Fbdev development list, Tomi Valkeinen
In-Reply-To: <CAKMK7uESo7hF1h2PbcteLOUqiubXv0c7nqR=etOp6gH8=+EDjQ@mail.gmail.com>
Hi,
On 06/30/2015 12:40 PM, Daniel Vetter wrote:
> Any updates on this or too much distractions? I really think doing
> this would be awesome for the drm subsystem, instead of reinventing
> this wheel for each driver.
I'd started on this again. I've got more free time now than before, so I
should have something in a week or so. I agree it will help a lot (there
are already two new drivers since we started discussing this!)
Archit
> -Daniel
>
> On Wed, Mar 25, 2015 at 10:21 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
>> On Wed, Mar 25, 2015 at 01:47:54PM +0530, Archit Taneja wrote:
>>> Hi,
>>>
>>> On 03/13/2015 02:36 PM, Daniel Vetter wrote:
>>>> On Fri, Mar 13, 2015 at 11:55:07AM +0530, Archit Taneja wrote:
>>>>>
>>>>>
>>>>> On 03/11/2015 08:47 PM, Daniel Vetter wrote:
>>>>>> On Wed, Mar 11, 2015 at 01:51:02PM +0530, Archit Taneja wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 03/10/2015 05:47 PM, Daniel Vetter wrote:
>>>>>>>> On Tue, Mar 10, 2015 at 03:52:41PM +0530, Archit Taneja wrote:
>>>>>>>>> On 03/10/2015 03:35 PM, Daniel Vetter wrote:
>>>>>>>>>> On Tue, Mar 10, 2015 at 03:22:49PM +0530, Archit Taneja wrote:
>>>>>>>>>>> On 03/10/2015 03:17 PM, Daniel Vetter wrote:
>>>>>>>>>>>> On Tue, Mar 10, 2015 at 03:11:28PM +0530, Archit Taneja wrote:
>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>> index 151a050..38f83a0 100644
>>>>>>>>>>>>> --- a/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>> +++ b/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>> @@ -40,6 +40,24 @@ config DRM_KMS_FB_HELPER
>>>>>>>>>>>>> help
>>>>>>>>>>>>> FBDEV helpers for KMS drivers.
>>>>>>>>>>>>>
>>>>>>>>>>>>> +config DRM_FBDEV_EMULATION
>>>>>>>>>>>>> + bool "Enable legacy fbdev support for your modesetting driver"
>>>>>>>>>>>>> + depends on DRM
>>>>>>>>>>>>> + select DRM_KMS_HELPER
>>>>>>>>>>>>> + select DRM_KMS_FB_HELPER
>>>>>>>>>>>>> + select FB_SYS_FILLRECT
>>>>>>>>>>>>> + select FB_SYS_COPYAREA
>>>>>>>>>>>>> + select FB_SYS_IMAGEBLIT
>>>>>>>>>>>>> + select FB_SYS_FOPS
>>>>>>>>>>>>> + select FB_CFB_FILLRECT
>>>>>>>>>>>>> + select FB_CFB_COPYAREA
>>>>>>>>>>>>> + select FB_CFB_IMAGEBLIT
>>>>>>>>>>>>> + default y
>>>>>>>>>>>>> + help
>>>>>>>>>>>>> + Choose this option if you have a need for the legacy fbdev
>>>>>>>>>>>>> + support. Note that this support also provide the linux console
>>>>>>>>>>>>> + support on top of your modesetting driver.
>>>>>>>>>>>>
>>>>>>>>>>>> Maybe clarify that for linux console support you also need
>>>>>>>>>>>> CONFIG_FRAMEBUFFER_CONSOLE? fbdev alone isn't enough.
>>>>>>>>>>>
>>>>>>>>>>> DRM_KMS_FB_HELPER selects that for us, right?
>>>>>>>>>>
>>>>>>>>>> Hm right I've missed that. Reminds me that you need one more patch at the
>>>>>>>>>> end to remove all the various select DRM_KMS_FB_HELPER from all drm
>>>>>>>>>> drivers. Otherwise this knob here won't work by default if you e.g. select
>>>>>>>>>> radeon. In general we can't mix explicit options with menu entries with a
>>>>>>>>>> select.
>>>>>>>>>
>>>>>>>>> I was trying that out. Removing DRM_KMS_FB_HELPER and having
>>>>>>>>> DRM_FBDEV_EMULATION disabled breaks drivers which use FB stuff internally in
>>>>>>>>> their respective xyz_fbdev.c files.
>>>>>>>>
>>>>>>>> But with the stubbed out functions that should work, right? Why doesn't
>>>>>>>> it?
>>>>>>>
>>>>>>> There are still calls to functions from fb core like fb_set_suspend and
>>>>>>> register_framebuffer which aren't covered by the drm fb helper functions.
>>>>>>
>>>>>> Hm, sounds like we need another patch to stub out fb_set_suspend when
>>>>>> fbdev isn't enabled. Is there anything else?
>>>>>
>>>>> There are a handful of fb core functions which are called by drm drivers:
>>>>>
>>>>> fb_alloc_cmap/fb_dealloc_cmap
>>>>>
>>>>> fb_sys_read/fb_sys_write
>>>>>
>>>>> register_framebuffer/unregister_framebuffer/unlink_framebuffer/
>>>>> remove_conflicting_framebuffers
>>>>>
>>>>> fb_set_suspend
>>>>>
>>>>> fb_deferred_io_init/fb_deferred_io_cleanup
>>>>>
>>>>> framebuffer_alloc/framebuffer_release
>>>>
>>>> Hm yeah that's somewhat annoying indeed. What about the following:
>>>> 1. We move all the #include <linux/fb.h> from drivers into drm_fb_helper.h
>>>>
>>>> 2. Then we add stubs for these functions in drm_fb_helper.h, like this
>>>>
>>>> #if defined(CONFIG_FB)
>>>> #include <linux/fb.h>
>>>> #else
>>>>
>>>> /* static inline stubs for all the fb stuff used by kms drivers */
>>>> #endif
>>>>
>>>> Imo this makes sense since kms drivers really have a bit a special
>>>> situation with fbdev. They're not full-blown fbdev drivers and can be
>>>> useful fully without fbdev.
>>>>
>>>
>>> I was trying this out. Removing 'linux/fb.h' and replacing stub fb funcs
>>> won't really work because struct declarations(like fb_info) also get
>>> removed.
>>>
>>> I considered placing '#if IS_ENABLED(CONFIG_FB)' within linux/fb.h itself,
>>> but that seemed a bit too intrusive.
>>>
>>> This is what I'm currently doing:
>>>
>>> - Some funcs, like framebufer_alloc/release, alloc_cmap/dealloc_cmap would
>>> actually benefit if we have drm fb helpers for them. They are used in
>>> exactly the same manner by all the drivers.
>>>
>>> - For the rest of the functions that are sparsely used, I was considering
>>> making very simple drm_fb_* wrapper functions. Something like:
>>>
>>> void drm_fb_helper_deferred_io_init(struct drm_fb_helper *helper)
>>> {
>>> if (helper->fbdev)
>>> fb_deferred_io_init(helper->fbdev);
>>> }
>>>
>>> We could have all fb calls called within drm_fb_helper.c, creating
>>> drm_fb_helper_* stub functions would then be an easier task. What do you
>>> think?
>>
>> That's actually an option I considered, but I hoped we could do it with
>> less work. If this indeed works and you can create the patch that would be
>> awesome.
>>
>> Thanks, Daniel
>> --
>> Daniel Vetter
>> Software Engineer, Intel Corporation
>> http://blog.ffwll.ch
>
>
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [RFC 1/6] drm: Add top level Kconfig option for DRM fbdev emulation
From: Benjamin Gaignard @ 2015-06-30 8:31 UTC (permalink / raw)
To: Archit Taneja
Cc: Linux Fbdev development list, linux-arm-msm,
Linux Kernel Mailing List, dri-devel, Tomi Valkeinen,
Thierry Reding
In-Reply-To: <55924BA6.4050309@codeaurora.org>
Hi,
I think that what have been done by Rob with module_param is also a good idea:
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/gpu/drm/msm/msm_drv.c?idé0dfec78ec288d6c89a7b508a5c5d4ae8b7f934
Can you mix compilation flag and module param ?
Benjamin
2015-06-30 9:56 GMT+02:00 Archit Taneja <architt@codeaurora.org>:
> Hi,
>
> On 06/30/2015 12:40 PM, Daniel Vetter wrote:
>>
>> Any updates on this or too much distractions? I really think doing
>> this would be awesome for the drm subsystem, instead of reinventing
>> this wheel for each driver.
>
>
> I'd started on this again. I've got more free time now than before, so I
> should have something in a week or so. I agree it will help a lot (there are
> already two new drivers since we started discussing this!)
>
> Archit
>
>
>> -Daniel
>>
>> On Wed, Mar 25, 2015 at 10:21 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
>>>
>>> On Wed, Mar 25, 2015 at 01:47:54PM +0530, Archit Taneja wrote:
>>>>
>>>> Hi,
>>>>
>>>> On 03/13/2015 02:36 PM, Daniel Vetter wrote:
>>>>>
>>>>> On Fri, Mar 13, 2015 at 11:55:07AM +0530, Archit Taneja wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 03/11/2015 08:47 PM, Daniel Vetter wrote:
>>>>>>>
>>>>>>> On Wed, Mar 11, 2015 at 01:51:02PM +0530, Archit Taneja wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On 03/10/2015 05:47 PM, Daniel Vetter wrote:
>>>>>>>>>
>>>>>>>>> On Tue, Mar 10, 2015 at 03:52:41PM +0530, Archit Taneja wrote:
>>>>>>>>>>
>>>>>>>>>> On 03/10/2015 03:35 PM, Daniel Vetter wrote:
>>>>>>>>>>>
>>>>>>>>>>> On Tue, Mar 10, 2015 at 03:22:49PM +0530, Archit Taneja wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> On 03/10/2015 03:17 PM, Daniel Vetter wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Tue, Mar 10, 2015 at 03:11:28PM +0530, Archit Taneja wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>>> index 151a050..38f83a0 100644
>>>>>>>>>>>>>> --- a/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>>> +++ b/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>>> @@ -40,6 +40,24 @@ config DRM_KMS_FB_HELPER
>>>>>>>>>>>>>> help
>>>>>>>>>>>>>> FBDEV helpers for KMS drivers.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> +config DRM_FBDEV_EMULATION
>>>>>>>>>>>>>> + bool "Enable legacy fbdev support for your modesetting
>>>>>>>>>>>>>> driver"
>>>>>>>>>>>>>> + depends on DRM
>>>>>>>>>>>>>> + select DRM_KMS_HELPER
>>>>>>>>>>>>>> + select DRM_KMS_FB_HELPER
>>>>>>>>>>>>>> + select FB_SYS_FILLRECT
>>>>>>>>>>>>>> + select FB_SYS_COPYAREA
>>>>>>>>>>>>>> + select FB_SYS_IMAGEBLIT
>>>>>>>>>>>>>> + select FB_SYS_FOPS
>>>>>>>>>>>>>> + select FB_CFB_FILLRECT
>>>>>>>>>>>>>> + select FB_CFB_COPYAREA
>>>>>>>>>>>>>> + select FB_CFB_IMAGEBLIT
>>>>>>>>>>>>>> + default y
>>>>>>>>>>>>>> + help
>>>>>>>>>>>>>> + Choose this option if you have a need for the legacy
>>>>>>>>>>>>>> fbdev
>>>>>>>>>>>>>> + support. Note that this support also provide the linux
>>>>>>>>>>>>>> console
>>>>>>>>>>>>>> + support on top of your modesetting driver.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Maybe clarify that for linux console support you also need
>>>>>>>>>>>>> CONFIG_FRAMEBUFFER_CONSOLE? fbdev alone isn't enough.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> DRM_KMS_FB_HELPER selects that for us, right?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Hm right I've missed that. Reminds me that you need one more
>>>>>>>>>>> patch at the
>>>>>>>>>>> end to remove all the various select DRM_KMS_FB_HELPER from all
>>>>>>>>>>> drm
>>>>>>>>>>> drivers. Otherwise this knob here won't work by default if you
>>>>>>>>>>> e.g. select
>>>>>>>>>>> radeon. In general we can't mix explicit options with menu
>>>>>>>>>>> entries with a
>>>>>>>>>>> select.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I was trying that out. Removing DRM_KMS_FB_HELPER and having
>>>>>>>>>> DRM_FBDEV_EMULATION disabled breaks drivers which use FB stuff
>>>>>>>>>> internally in
>>>>>>>>>> their respective xyz_fbdev.c files.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> But with the stubbed out functions that should work, right? Why
>>>>>>>>> doesn't
>>>>>>>>> it?
>>>>>>>>
>>>>>>>>
>>>>>>>> There are still calls to functions from fb core like fb_set_suspend
>>>>>>>> and
>>>>>>>> register_framebuffer which aren't covered by the drm fb helper
>>>>>>>> functions.
>>>>>>>
>>>>>>>
>>>>>>> Hm, sounds like we need another patch to stub out fb_set_suspend when
>>>>>>> fbdev isn't enabled. Is there anything else?
>>>>>>
>>>>>>
>>>>>> There are a handful of fb core functions which are called by drm
>>>>>> drivers:
>>>>>>
>>>>>> fb_alloc_cmap/fb_dealloc_cmap
>>>>>>
>>>>>> fb_sys_read/fb_sys_write
>>>>>>
>>>>>> register_framebuffer/unregister_framebuffer/unlink_framebuffer/
>>>>>> remove_conflicting_framebuffers
>>>>>>
>>>>>> fb_set_suspend
>>>>>>
>>>>>> fb_deferred_io_init/fb_deferred_io_cleanup
>>>>>>
>>>>>> framebuffer_alloc/framebuffer_release
>>>>>
>>>>>
>>>>> Hm yeah that's somewhat annoying indeed. What about the following:
>>>>> 1. We move all the #include <linux/fb.h> from drivers into
>>>>> drm_fb_helper.h
>>>>>
>>>>> 2. Then we add stubs for these functions in drm_fb_helper.h, like this
>>>>>
>>>>> #if defined(CONFIG_FB)
>>>>> #include <linux/fb.h>
>>>>> #else
>>>>>
>>>>> /* static inline stubs for all the fb stuff used by kms drivers */
>>>>> #endif
>>>>>
>>>>> Imo this makes sense since kms drivers really have a bit a special
>>>>> situation with fbdev. They're not full-blown fbdev drivers and can be
>>>>> useful fully without fbdev.
>>>>>
>>>>
>>>> I was trying this out. Removing 'linux/fb.h' and replacing stub fb funcs
>>>> won't really work because struct declarations(like fb_info) also get
>>>> removed.
>>>>
>>>> I considered placing '#if IS_ENABLED(CONFIG_FB)' within linux/fb.h
>>>> itself,
>>>> but that seemed a bit too intrusive.
>>>>
>>>> This is what I'm currently doing:
>>>>
>>>> - Some funcs, like framebufer_alloc/release, alloc_cmap/dealloc_cmap
>>>> would
>>>> actually benefit if we have drm fb helpers for them. They are used in
>>>> exactly the same manner by all the drivers.
>>>>
>>>> - For the rest of the functions that are sparsely used, I was
>>>> considering
>>>> making very simple drm_fb_* wrapper functions. Something like:
>>>>
>>>> void drm_fb_helper_deferred_io_init(struct drm_fb_helper *helper)
>>>> {
>>>> if (helper->fbdev)
>>>> fb_deferred_io_init(helper->fbdev);
>>>> }
>>>>
>>>> We could have all fb calls called within drm_fb_helper.c, creating
>>>> drm_fb_helper_* stub functions would then be an easier task. What do you
>>>> think?
>>>
>>>
>>> That's actually an option I considered, but I hoped we could do it with
>>> less work. If this indeed works and you can create the patch that would
>>> be
>>> awesome.
>>>
>>> Thanks, Daniel
>>> --
>>> Daniel Vetter
>>> Software Engineer, Intel Corporation
>>> http://blog.ffwll.ch
>>
>>
>>
>>
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
--
Benjamin Gaignard
Graphic Working Group
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [RFC 1/6] drm: Add top level Kconfig option for DRM fbdev emulation
From: Daniel Vetter @ 2015-06-30 9:04 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: linux-arm-msm, Linux Kernel Mailing List, dri-devel,
Linux Fbdev development list, Tomi Valkeinen, Thierry Reding
In-Reply-To: <CA+M3ks4vtDfA3rxBhEoiuZ8Tv_k15ddHRvAWP+MNgLkOMArTaw@mail.gmail.com>
On Tue, Jun 30, 2015 at 10:31 AM, Benjamin Gaignard
<benjamin.gaignard@linaro.org> wrote:
> I think that what have been done by Rob with module_param is also a good idea:
> https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/gpu/drm/msm/msm_drv.c?idé0dfec78ec288d6c89a7b508a5c5d4ae8b7f934
>
> Can you mix compilation flag and module param ?
Hm, the point of the kconfig is to not require all the legacy baggage
from fbdev. But I guess a module option could be added later on too.
bochs has it too.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply
* Re: [RFC 1/6] drm: Add top level Kconfig option for DRM fbdev emulation
From: Archit Taneja @ 2015-06-30 9:18 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: Linux Fbdev development list, linux-arm-msm,
Linux Kernel Mailing List, dri-devel, Tomi Valkeinen,
Thierry Reding
In-Reply-To: <CA+M3ks4vtDfA3rxBhEoiuZ8Tv_k15ddHRvAWP+MNgLkOMArTaw@mail.gmail.com>
Hi,
On 06/30/2015 02:01 PM, Benjamin Gaignard wrote:
> Hi,
>
> I think that what have been done by Rob with module_param is also a good idea:
> https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/gpu/drm/msm/msm_drv.c?idé0dfec78ec288d6c89a7b508a5c5d4ae8b7f934
>
> Can you mix compilation flag and module param ?
I guess this won't be hard to do once we have a common fbdev emulation
config option. We could consider this as a drm top level module param.
I'll keep this in mind.
Thanks,
Archit
>
> Benjamin
>
> 2015-06-30 9:56 GMT+02:00 Archit Taneja <architt@codeaurora.org>:
>> Hi,
>>
>> On 06/30/2015 12:40 PM, Daniel Vetter wrote:
>>>
>>> Any updates on this or too much distractions? I really think doing
>>> this would be awesome for the drm subsystem, instead of reinventing
>>> this wheel for each driver.
>>
>>
>> I'd started on this again. I've got more free time now than before, so I
>> should have something in a week or so. I agree it will help a lot (there are
>> already two new drivers since we started discussing this!)
>>
>> Archit
>>
>>
>>> -Daniel
>>>
>>> On Wed, Mar 25, 2015 at 10:21 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
>>>>
>>>> On Wed, Mar 25, 2015 at 01:47:54PM +0530, Archit Taneja wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> On 03/13/2015 02:36 PM, Daniel Vetter wrote:
>>>>>>
>>>>>> On Fri, Mar 13, 2015 at 11:55:07AM +0530, Archit Taneja wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 03/11/2015 08:47 PM, Daniel Vetter wrote:
>>>>>>>>
>>>>>>>> On Wed, Mar 11, 2015 at 01:51:02PM +0530, Archit Taneja wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 03/10/2015 05:47 PM, Daniel Vetter wrote:
>>>>>>>>>>
>>>>>>>>>> On Tue, Mar 10, 2015 at 03:52:41PM +0530, Archit Taneja wrote:
>>>>>>>>>>>
>>>>>>>>>>> On 03/10/2015 03:35 PM, Daniel Vetter wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> On Tue, Mar 10, 2015 at 03:22:49PM +0530, Archit Taneja wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 03/10/2015 03:17 PM, Daniel Vetter wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Tue, Mar 10, 2015 at 03:11:28PM +0530, Archit Taneja wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>>>> index 151a050..38f83a0 100644
>>>>>>>>>>>>>>> --- a/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>>>> +++ b/drivers/gpu/drm/Kconfig
>>>>>>>>>>>>>>> @@ -40,6 +40,24 @@ config DRM_KMS_FB_HELPER
>>>>>>>>>>>>>>> help
>>>>>>>>>>>>>>> FBDEV helpers for KMS drivers.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> +config DRM_FBDEV_EMULATION
>>>>>>>>>>>>>>> + bool "Enable legacy fbdev support for your modesetting
>>>>>>>>>>>>>>> driver"
>>>>>>>>>>>>>>> + depends on DRM
>>>>>>>>>>>>>>> + select DRM_KMS_HELPER
>>>>>>>>>>>>>>> + select DRM_KMS_FB_HELPER
>>>>>>>>>>>>>>> + select FB_SYS_FILLRECT
>>>>>>>>>>>>>>> + select FB_SYS_COPYAREA
>>>>>>>>>>>>>>> + select FB_SYS_IMAGEBLIT
>>>>>>>>>>>>>>> + select FB_SYS_FOPS
>>>>>>>>>>>>>>> + select FB_CFB_FILLRECT
>>>>>>>>>>>>>>> + select FB_CFB_COPYAREA
>>>>>>>>>>>>>>> + select FB_CFB_IMAGEBLIT
>>>>>>>>>>>>>>> + default y
>>>>>>>>>>>>>>> + help
>>>>>>>>>>>>>>> + Choose this option if you have a need for the legacy
>>>>>>>>>>>>>>> fbdev
>>>>>>>>>>>>>>> + support. Note that this support also provide the linux
>>>>>>>>>>>>>>> console
>>>>>>>>>>>>>>> + support on top of your modesetting driver.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Maybe clarify that for linux console support you also need
>>>>>>>>>>>>>> CONFIG_FRAMEBUFFER_CONSOLE? fbdev alone isn't enough.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> DRM_KMS_FB_HELPER selects that for us, right?
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Hm right I've missed that. Reminds me that you need one more
>>>>>>>>>>>> patch at the
>>>>>>>>>>>> end to remove all the various select DRM_KMS_FB_HELPER from all
>>>>>>>>>>>> drm
>>>>>>>>>>>> drivers. Otherwise this knob here won't work by default if you
>>>>>>>>>>>> e.g. select
>>>>>>>>>>>> radeon. In general we can't mix explicit options with menu
>>>>>>>>>>>> entries with a
>>>>>>>>>>>> select.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> I was trying that out. Removing DRM_KMS_FB_HELPER and having
>>>>>>>>>>> DRM_FBDEV_EMULATION disabled breaks drivers which use FB stuff
>>>>>>>>>>> internally in
>>>>>>>>>>> their respective xyz_fbdev.c files.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> But with the stubbed out functions that should work, right? Why
>>>>>>>>>> doesn't
>>>>>>>>>> it?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> There are still calls to functions from fb core like fb_set_suspend
>>>>>>>>> and
>>>>>>>>> register_framebuffer which aren't covered by the drm fb helper
>>>>>>>>> functions.
>>>>>>>>
>>>>>>>>
>>>>>>>> Hm, sounds like we need another patch to stub out fb_set_suspend when
>>>>>>>> fbdev isn't enabled. Is there anything else?
>>>>>>>
>>>>>>>
>>>>>>> There are a handful of fb core functions which are called by drm
>>>>>>> drivers:
>>>>>>>
>>>>>>> fb_alloc_cmap/fb_dealloc_cmap
>>>>>>>
>>>>>>> fb_sys_read/fb_sys_write
>>>>>>>
>>>>>>> register_framebuffer/unregister_framebuffer/unlink_framebuffer/
>>>>>>> remove_conflicting_framebuffers
>>>>>>>
>>>>>>> fb_set_suspend
>>>>>>>
>>>>>>> fb_deferred_io_init/fb_deferred_io_cleanup
>>>>>>>
>>>>>>> framebuffer_alloc/framebuffer_release
>>>>>>
>>>>>>
>>>>>> Hm yeah that's somewhat annoying indeed. What about the following:
>>>>>> 1. We move all the #include <linux/fb.h> from drivers into
>>>>>> drm_fb_helper.h
>>>>>>
>>>>>> 2. Then we add stubs for these functions in drm_fb_helper.h, like this
>>>>>>
>>>>>> #if defined(CONFIG_FB)
>>>>>> #include <linux/fb.h>
>>>>>> #else
>>>>>>
>>>>>> /* static inline stubs for all the fb stuff used by kms drivers */
>>>>>> #endif
>>>>>>
>>>>>> Imo this makes sense since kms drivers really have a bit a special
>>>>>> situation with fbdev. They're not full-blown fbdev drivers and can be
>>>>>> useful fully without fbdev.
>>>>>>
>>>>>
>>>>> I was trying this out. Removing 'linux/fb.h' and replacing stub fb funcs
>>>>> won't really work because struct declarations(like fb_info) also get
>>>>> removed.
>>>>>
>>>>> I considered placing '#if IS_ENABLED(CONFIG_FB)' within linux/fb.h
>>>>> itself,
>>>>> but that seemed a bit too intrusive.
>>>>>
>>>>> This is what I'm currently doing:
>>>>>
>>>>> - Some funcs, like framebufer_alloc/release, alloc_cmap/dealloc_cmap
>>>>> would
>>>>> actually benefit if we have drm fb helpers for them. They are used in
>>>>> exactly the same manner by all the drivers.
>>>>>
>>>>> - For the rest of the functions that are sparsely used, I was
>>>>> considering
>>>>> making very simple drm_fb_* wrapper functions. Something like:
>>>>>
>>>>> void drm_fb_helper_deferred_io_init(struct drm_fb_helper *helper)
>>>>> {
>>>>> if (helper->fbdev)
>>>>> fb_deferred_io_init(helper->fbdev);
>>>>> }
>>>>>
>>>>> We could have all fb calls called within drm_fb_helper.c, creating
>>>>> drm_fb_helper_* stub functions would then be an easier task. What do you
>>>>> think?
>>>>
>>>>
>>>> That's actually an option I considered, but I hoped we could do it with
>>>> less work. If this indeed works and you can create the patch that would
>>>> be
>>>> awesome.
>>>>
>>>> Thanks, Daniel
>>>> --
>>>> Daniel Vetter
>>>> Software Engineer, Intel Corporation
>>>> http://blog.ffwll.ch
>>>
>>>
>>>
>>>
>>
>> --
>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>> a Linux Foundation Collaborative Project
>
>
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH] OMAPDSS: fix probing if rfbi device is enabled
From: Tomi Valkeinen @ 2015-06-30 12:03 UTC (permalink / raw)
To: linux-fbdev
After the commit 736e60ddc215b85e73bbf7da26e1cde84cc9500f ("OMAPDSS:
componentize omapdss") the dss core device will wait until all the
subdevices have been successfully probed. However, we don't have a
working driver for RFBI, so if RFBI device exists, omapdss will never
get probed.
All the .dtsi files set RFBI as disabled, except am4372.dtsi. This
causes omapdss probe to not finish on AM4 devices.
This patch makes omapdss driver skip adding rfbi device as a
subcomponent, solving the issue.
This should be reverted when we have a working RFBI driver.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reported-by: Felipe Balbi <balbi@ti.com>
---
drivers/video/fbdev/omap2/dss/dss.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 612b093831d5..9200a8668b49 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -1225,6 +1225,15 @@ static int dss_add_child_component(struct device *dev, void *data)
{
struct component_match **match = data;
+ /*
+ * HACK
+ * We don't have a working driver for rfbi, so skip it here always.
+ * Otherwise dss will never get probed successfully, as it will wait
+ * for rfbi to get probed.
+ */
+ if (strstr(dev_name(dev), "rfbi"))
+ return 0;
+
component_match_add(dev->parent, match, dss_component_compare, dev);
return 0;
--
2.1.4
^ permalink raw reply related
* [PATCH 1/2] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
From: K. Y. Srinivasan @ 2015-06-30 21:12 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang,
hdegoede, linux-fbdev, haiyangz
Cc: jakeo@microsoft.com, K. Y. Srinivasan
In-Reply-To: <1435703668-23486-1-git-send-email-kys@microsoft.com>
From: jakeo@microsoft.com <jakeo@microsoft.com>
This patch changes the logic in hv_vmbus to record all of the ranges in the
VM's firmware (BIOS or UEFI) that offer regions of memory-mapped I/O space for
use by paravirtual front-end drivers. The old logic just found one range
above 4GB and called it good. This logic will find any ranges above 1MB.
It would have been possible with this patch to just use existing resource
allocation functions, rather than keep track of the entire set of Hyper-V
related MMIO regions in VMBus. This strategy, however, is not sufficient
when the resource allocator needs to be aware of the constraints of a
Hyper-V virtual machine, which is what happens in the next patch in the series.
So this first patch exists to show the first steps in reworking the MMIO
allocation paths for Hyper-V front-end drivers.
Signed-off-by: Jake Oshins <jakeo@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/vmbus_drv.c | 116 ++++++++++++++++++++++++++++++---------
drivers/video/fbdev/hyperv_fb.c | 2 +-
include/linux/hyperv.h | 2 +-
3 files changed, 92 insertions(+), 28 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index b6114cc..21bb287 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -102,10 +102,7 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
};
-struct resource hyperv_mmio = {
- .name = "hyperv mmio",
- .flags = IORESOURCE_MEM,
-};
+struct resource *hyperv_mmio;
EXPORT_SYMBOL_GPL(hyperv_mmio);
static int vmbus_exists(void)
@@ -1013,30 +1010,105 @@ void vmbus_device_unregister(struct hv_device *device_obj)
/*
- * VMBUS is an acpi enumerated device. Get the the information we
+ * VMBUS is an acpi enumerated device. Get the information we
* need from DSDT.
*/
-
+#define VTPM_BASE_ADDRESS 0xfed40000
static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
{
+ resource_size_t start = 0;
+ resource_size_t end = 0;
+ struct resource *new_res;
+ struct resource **old_res = &hyperv_mmio;
+ struct resource **prev_res = NULL;
+
switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ:
irq = res->data.irq.interrupts[0];
+ return AE_OK;
+
+ /*
+ * "Address" descriptors are for bus windows. Ignore
+ * "memory" descriptors, which are for registers on
+ * devices.
+ */
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ start = res->data.address32.address.minimum;
+ end = res->data.address32.address.maximum;
break;
case ACPI_RESOURCE_TYPE_ADDRESS64:
- hyperv_mmio.start = res->data.address64.address.minimum;
- hyperv_mmio.end = res->data.address64.address.maximum;
+ start = res->data.address64.address.minimum;
+ end = res->data.address64.address.maximum;
break;
+
+ default:
+ /* Unused resource type */
+ return AE_OK;
+
}
+ /*
+ * Ignore ranges that are below 1MB, as they're not
+ * necessary or useful here.
+ */
+ if (end < 0x100000)
+ return AE_OK;
+
+ new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC);
+ if (!new_res)
+ return AE_NO_MEMORY;
+
+ /* If this range overlaps the virtual TPM, truncate it. */
+ if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS)
+ end = VTPM_BASE_ADDRESS;
+
+ new_res->name = "hyperv mmio";
+ new_res->flags = IORESOURCE_MEM;
+ new_res->start = start;
+ new_res->end = end;
+
+ do {
+ if (!*old_res) {
+ *old_res = new_res;
+ break;
+ }
+
+ if ((*old_res)->end < new_res->start) {
+ new_res->sibling = *old_res;
+ if (prev_res)
+ (*prev_res)->sibling = new_res;
+ *old_res = new_res;
+ break;
+ }
+
+ prev_res = old_res;
+ old_res = &(*old_res)->sibling;
+
+ } while (1);
return AE_OK;
}
+static int vmbus_acpi_remove(struct acpi_device *device)
+{
+ struct resource *cur_res;
+ struct resource *next_res;
+
+ if (hyperv_mmio) {
+ for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
+ next_res = cur_res->sibling;
+ kfree(cur_res);
+ }
+ }
+
+ return 0;
+}
+
static int vmbus_acpi_add(struct acpi_device *device)
{
acpi_status result;
int ret_val = -ENODEV;
+ struct acpi_device *ancestor;
hv_acpi_dev = device;
@@ -1046,35 +1118,27 @@ static int vmbus_acpi_add(struct acpi_device *device)
if (ACPI_FAILURE(result))
goto acpi_walk_err;
/*
- * The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that
- * has the mmio ranges. Get that.
+ * Some ancestor of the vmbus acpi device (Gen1 or Gen2
+ * firmware) is the VMOD that has the mmio ranges. Get that.
*/
- if (device->parent) {
- result = acpi_walk_resources(device->parent->handle,
- METHOD_NAME__CRS,
- vmbus_walk_resources, NULL);
+ for (ancestor = device->parent; ancestor; ancestor = ancestor->parent) {
+ result = acpi_walk_resources(ancestor->handle, METHOD_NAME__CRS,
+ vmbus_walk_resources, NULL);
if (ACPI_FAILURE(result))
- goto acpi_walk_err;
- if (hyperv_mmio.start && hyperv_mmio.end)
- request_resource(&iomem_resource, &hyperv_mmio);
+ continue;
+ if (hyperv_mmio)
+ break;
}
ret_val = 0;
acpi_walk_err:
complete(&probe_event);
+ if (ret_val)
+ vmbus_acpi_remove(device);
return ret_val;
}
-static int vmbus_acpi_remove(struct acpi_device *device)
-{
- int ret = 0;
-
- if (hyperv_mmio.start && hyperv_mmio.end)
- ret = release_resource(&hyperv_mmio);
- return ret;
-}
-
static const struct acpi_device_id vmbus_acpi_device_ids[] = {
{"VMBUS", 0},
{"VMBus", 0},
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 807ee22..b54ee1c 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -688,7 +688,7 @@ static int hvfb_getmem(struct fb_info *info)
par->mem.name = KBUILD_MODNAME;
par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
if (gen2vm) {
- ret = allocate_resource(&hyperv_mmio, &par->mem,
+ ret = allocate_resource(hyperv_mmio, &par->mem,
screen_fb_size,
0, -1,
screen_fb_size,
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 30d3a1f..217e14b 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1233,7 +1233,7 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *,
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
-extern struct resource hyperv_mmio;
+extern struct resource *hyperv_mmio;
/*
* Negotiated version with the Host.
--
1.7.4.1
^ permalink raw reply related
* [PATCH 2/2] drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus
From: K. Y. Srinivasan @ 2015-06-30 21:12 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang,
hdegoede, linux-fbdev, haiyangz
Cc: jakeo@microsoft.com, K. Y. Srinivasan
In-Reply-To: <1435703702-23525-1-git-send-email-kys@microsoft.com>
From: jakeo@microsoft.com <jakeo@microsoft.com>
This patch deletes the logic from hyperv_fb which picked a range of MMIO space
for the frame buffer and adds new logic to hv_vmbus which picks ranges for
child drivers. The new logic isn't quite the same as the old, as it considers
more possible ranges.
Signed-off-by: Jake Oshins <jakeo@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
---
drivers/hv/vmbus_drv.c | 88 +++++++++++++++++++++++++++++++++++++--
drivers/video/fbdev/hyperv_fb.c | 46 +++++++++-----------
include/linux/hyperv.h | 7 ++-
3 files changed, 110 insertions(+), 31 deletions(-)
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 21bb287..83759c1 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -39,6 +39,7 @@
#include <asm/mshyperv.h>
#include <linux/notifier.h>
#include <linux/ptrace.h>
+#include <linux/screen_info.h>
#include <linux/kdebug.h>
#include "hyperv_vmbus.h"
@@ -103,7 +104,6 @@ static struct notifier_block hyperv_panic_block = {
};
struct resource *hyperv_mmio;
-EXPORT_SYMBOL_GPL(hyperv_mmio);
static int vmbus_exists(void)
{
@@ -891,8 +891,8 @@ err_cleanup:
}
/**
- * __vmbus_child_driver_register - Register a vmbus's driver
- * @drv: Pointer to driver structure you want to register
+ * __vmbus_child_driver_register() - Register a vmbus's driver
+ * @hv_driver: Pointer to driver structure you want to register
* @owner: owner module of the drv
* @mod_name: module name string
*
@@ -924,7 +924,8 @@ EXPORT_SYMBOL_GPL(__vmbus_driver_register);
/**
* vmbus_driver_unregister() - Unregister a vmbus's driver
- * @drv: Pointer to driver structure you want to un-register
+ * @hv_driver: Pointer to driver structure you want to
+ * un-register
*
* Un-register the given driver that was previous registered with a call to
* vmbus_driver_register()
@@ -1104,6 +1105,85 @@ static int vmbus_acpi_remove(struct acpi_device *device)
return 0;
}
+/**
+ * vmbus_allocate_mmio() - Pick a memory-mapped I/O range.
+ * @new: If successful, supplied a pointer to the
+ * allocated MMIO space.
+ * @device_obj: Identifies the caller
+ * @min: Minimum guest physical address of the
+ * allocation
+ * @max: Maximum guest physical address
+ * @size: Size of the range to be allocated
+ * @align: Alignment of the range to be allocated
+ * @fb_overlap_ok: Whether this allocation can be allowed
+ * to overlap the video frame buffer.
+ *
+ * This function walks the resources granted to VMBus by the
+ * _CRS object in the ACPI namespace underneath the parent
+ * "bridge" whether that's a root PCI bus in the Generation 1
+ * case or a Module Device in the Generation 2 case. It then
+ * attempts to allocate from the global MMIO pool in a way that
+ * matches the constraints supplied in these parameters and by
+ * that _CRS.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+ resource_size_t min, resource_size_t max,
+ resource_size_t size, resource_size_t align,
+ bool fb_overlap_ok)
+{
+ struct resource *iter;
+ resource_size_t range_min, range_max, start, local_min, local_max;
+ const char *dev_n = dev_name(&device_obj->device);
+ u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
+ int i;
+
+ for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+ if ((iter->start >= max) || (iter->end <= min))
+ continue;
+
+ range_min = iter->start;
+ range_max = iter->end;
+
+ /* If this range overlaps the frame buffer, split it into
+ two tries. */
+ for (i = 0; i < 2; i++) {
+ local_min = range_min;
+ local_max = range_max;
+ if (fb_overlap_ok || (range_min >= fb_end) ||
+ (range_max <= screen_info.lfb_base)) {
+ i++;
+ } else {
+ if ((range_min <= screen_info.lfb_base) &&
+ (range_max >= screen_info.lfb_base)) {
+ /*
+ * The frame buffer is in this window,
+ * so trim this into the part that
+ * preceeds the frame buffer.
+ */
+ local_max = screen_info.lfb_base - 1;
+ range_min = fb_end;
+ } else {
+ range_min = fb_end;
+ continue;
+ }
+ }
+
+ start = (local_min + align - 1) & ~(align - 1);
+ for (; start + size - 1 <= local_max; start += align) {
+ *new = request_mem_region_exclusive(start, size,
+ dev_n);
+ if (*new)
+ return 0;
+ }
+ }
+ }
+
+ return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
+
static int vmbus_acpi_add(struct acpi_device *device)
{
acpi_status result;
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index b54ee1c..e2451bd 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -213,7 +213,7 @@ struct synthvid_msg {
struct hvfb_par {
struct fb_info *info;
- struct resource mem;
+ struct resource *mem;
bool fb_ready; /* fb device is ready */
struct completion wait;
u32 synthvid_version;
@@ -677,26 +677,18 @@ static void hvfb_get_option(struct fb_info *info)
/* Get framebuffer memory from Hyper-V video pci space */
-static int hvfb_getmem(struct fb_info *info)
+static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
{
struct hvfb_par *par = info->par;
struct pci_dev *pdev = NULL;
void __iomem *fb_virt;
int gen2vm = efi_enabled(EFI_BOOT);
+ resource_size_t pot_start, pot_end;
int ret;
- par->mem.name = KBUILD_MODNAME;
- par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
if (gen2vm) {
- ret = allocate_resource(hyperv_mmio, &par->mem,
- screen_fb_size,
- 0, -1,
- screen_fb_size,
- NULL, NULL);
- if (ret != 0) {
- pr_err("Unable to allocate framebuffer memory\n");
- return -ENODEV;
- }
+ pot_start = 0;
+ pot_end = -1;
} else {
pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
@@ -709,16 +701,18 @@ static int hvfb_getmem(struct fb_info *info)
pci_resource_len(pdev, 0) < screen_fb_size)
goto err1;
- par->mem.end = pci_resource_end(pdev, 0);
- par->mem.start = par->mem.end - screen_fb_size + 1;
- ret = request_resource(&pdev->resource[0], &par->mem);
- if (ret != 0) {
- pr_err("Unable to request framebuffer memory\n");
- goto err1;
- }
+ pot_end = pci_resource_end(pdev, 0);
+ pot_start = pot_end - screen_fb_size + 1;
+ }
+
+ ret = vmbus_allocate_mmio(&par->mem, hdev, pot_start, pot_end,
+ screen_fb_size, 0x100000, true);
+ if (ret != 0) {
+ pr_err("Unable to allocate framebuffer memory\n");
+ goto err1;
}
- fb_virt = ioremap(par->mem.start, screen_fb_size);
+ fb_virt = ioremap(par->mem->start, screen_fb_size);
if (!fb_virt)
goto err2;
@@ -736,7 +730,7 @@ static int hvfb_getmem(struct fb_info *info)
info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
}
- info->fix.smem_start = par->mem.start;
+ info->fix.smem_start = par->mem->start;
info->fix.smem_len = screen_fb_size;
info->screen_base = fb_virt;
info->screen_size = screen_fb_size;
@@ -749,7 +743,8 @@ static int hvfb_getmem(struct fb_info *info)
err3:
iounmap(fb_virt);
err2:
- release_resource(&par->mem);
+ release_mem_region(par->mem->start, screen_fb_size);
+ par->mem = NULL;
err1:
if (!gen2vm)
pci_dev_put(pdev);
@@ -763,7 +758,8 @@ static void hvfb_putmem(struct fb_info *info)
struct hvfb_par *par = info->par;
iounmap(info->screen_base);
- release_resource(&par->mem);
+ release_mem_region(par->mem->start, screen_fb_size);
+ par->mem = NULL;
}
@@ -794,7 +790,7 @@ static int hvfb_probe(struct hv_device *hdev,
goto error1;
}
- ret = hvfb_getmem(info);
+ ret = hvfb_getmem(hdev, info);
if (ret) {
pr_err("No memory for framebuffer\n");
goto error2;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 217e14b..54733d5 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -977,6 +977,11 @@ int __must_check __vmbus_driver_register(struct hv_driver *hv_driver,
const char *mod_name);
void vmbus_driver_unregister(struct hv_driver *hv_driver);
+int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+ resource_size_t min, resource_size_t max,
+ resource_size_t size, resource_size_t align,
+ bool fb_overlap_ok);
+
/**
* VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
*
@@ -1233,8 +1238,6 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *,
void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
-extern struct resource *hyperv_mmio;
-
/*
* Negotiated version with the Host.
*/
--
1.7.4.1
^ permalink raw reply related
* [PATCH 0/2] Drivers: hv: vmbus: Change memory-mapped I/O management for Hyper-V paravirt
From: K. Y. Srinivasan @ 2015-06-30 21:19 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang,
hdegoede, linux-fbdev, haiyangz
Cc: K. Y. Srinivasan
This patch series changes the way that hv_vmbus searches for ranges of
memory-mapped I/O space (MMIO) which can be used by its children. The old
way just found the one and only range above 4GB. This one makes all ranges
exposed in the VM's firmware potential candidates. It also moves the code
which chooses ranges from hyperv_fb (the video front-end driver for Hyper-V)
to hv_vmbus.
jakeo@microsoft.com (2):
drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus
drivers/hv/vmbus_drv.c | 204 +++++++++++++++++++++++++++++++++------
drivers/video/fbdev/hyperv_fb.c | 46 ++++-----
include/linux/hyperv.h | 7 +-
3 files changed, 200 insertions(+), 57 deletions(-)
--
1.7.4.1
^ permalink raw reply
* Re: [PATCH 1/2] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
From: Dan Carpenter @ 2015-07-01 8:00 UTC (permalink / raw)
To: K. Y. Srinivasan
Cc: gregkh, linux-kernel, devel, olaf, apw, vkuznets, jasowang,
hdegoede, linux-fbdev, haiyangz, jakeo@microsoft.com
In-Reply-To: <1435703702-23525-1-git-send-email-kys@microsoft.com>
On Tue, Jun 30, 2015 at 03:35:01PM -0700, K. Y. Srinivasan wrote:
> From: jakeo@microsoft.com <jakeo@microsoft.com>
Jake, fix your git config.
regards,
dan carpenter
^ permalink raw reply
* Re: [PATCH v2] backlight: lp8788: Deletion of a check before backlight_device_unregister()
From: Lee Jones @ 2015-07-01 8:06 UTC (permalink / raw)
To: SF Markus Elfring
Cc: Bryan Wu, Jean-Christophe Plagniol-Villard, Jingoo Han,
Tomi Valkeinen, linux-fbdev, LKML, kernel-janitors, Julia Lawall
In-Reply-To: <558FE386.7060704@users.sourceforge.net>
On Sun, 28 Jun 2015, SF Markus Elfring wrote:
> > From: Markus Elfring <elfring@users.sourceforge.net>
> >
> > The backlight_device_unregister() function tests whether its argument is NULL
> > and then returns immediately. Thus the test around the call is not needed.
> >
> > This issue was detected by using the Coccinelle software.
> >
> > Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
> > ---
> > drivers/video/backlight/lp8788_bl.c | 3 +--
> > 1 file changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c
> > index d6c4f6a..24a055c 100644
> > --- a/drivers/video/backlight/lp8788_bl.c
> > +++ b/drivers/video/backlight/lp8788_bl.c
> > @@ -221,8 +221,7 @@ static void lp8788_backlight_unregister(struct lp8788_bl *bl)
> > {
> > struct backlight_device *bl_dev = bl->bl_dev;
> >
> > - if (bl_dev)
> > - backlight_device_unregister(bl_dev);
> > + backlight_device_unregister(bl_dev);
> > }
> >
> > static ssize_t lp8788_get_bl_ctl_mode(struct device *dev,
> >
>
> Would you like to integrate this update suggestion
> into another source code repository?
If this patch has not received any attention in some time, it's
possible that it may have slipped through the gaps. Please
re-submit the set.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [RFC PATCH 00/15] pwm: add support for atomic update
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
Hello Thierry,
This series adds support for atomic PWM update, or ITO, the capability
to update all the parameters of a PWM device (enabled/disabled, period,
duty and polarity) in one go.
This implementation is still experimental, and I may have missed some key
aspect, so any feedback are welcome.
Also note that I haven't protected the state update with any locking.
That's because the existing config does not protect against concurrent
access to a requested PWM device (see the pwm_config implementation).
I guess the PWM framework assume the user will implement the proper locking
scheme if it has to concurrently access the device.
The 5 first patches prepare the addition of the pwm_state concept, which
will be used to allow atomic updates.
The following patches introduce the pwm_state struct, initial state
retrieval and atomic update concepts.
Patches 12 and 13 are showing how one can implement the initial state
retrieval and atomic update features in a PWM driver (in this specific
case I implemented it in the rockchip driver).
The last 2 patches are making use of those changes to improve the
pwm-regulator driver (initializing the regulator state based on the
initial PWM state).
Best Regards,
Boris
Boris Brezillon (15):
pwm: add the pwm_is_enabled() helper
pwm: fix pwm_get_period and pwm_get_duty_cycle prototypes
pwm: add pwm_get_polarity helper function
pwm: make use of pwm_get_xxx helpers where appropriate
pwm: introduce default period and polarity concepts
pwm: define a new pwm_state struct
pwm: move the enabled/disabled info to pwm_state struct
backlight: pwm_bl: remove useless call to pwm_set_period
pwm: declare a default PWM state
pwm: add the PWM initial state retrieval infra
pwm: add the core infrastructure to allow atomic update
pwm: rockchip: add initial state retrieval
pwm: rockchip: add support for atomic update
regulator: pwm: implement ->enable(), ->disable() and ->is_enabled
methods
regulator: pwm: properly initialize the ->state field
drivers/leds/leds-pwm.c | 2 +-
drivers/pwm/core.c | 136 ++++++++++++++++++++++++++++++-----
drivers/pwm/pwm-atmel-tcb.c | 2 +-
drivers/pwm/pwm-atmel.c | 6 +-
drivers/pwm/pwm-bcm-kona.c | 7 +-
drivers/pwm/pwm-ep93xx.c | 4 +-
drivers/pwm/pwm-imx.c | 5 +-
drivers/pwm/pwm-mxs.c | 4 +-
drivers/pwm/pwm-pxa.c | 2 +-
drivers/pwm/pwm-renesas-tpu.c | 2 +-
drivers/pwm/pwm-rockchip.c | 122 ++++++++++++++++++++++++-------
drivers/pwm/pwm-sun4i.c | 3 +-
drivers/pwm/pwm-tegra.c | 6 +-
drivers/pwm/pwm-tiecap.c | 10 +--
drivers/pwm/pwm-tiehrpwm.c | 6 +-
drivers/pwm/sysfs.c | 13 ++--
drivers/regulator/pwm-regulator.c | 60 ++++++++++++++--
drivers/video/backlight/lm3630a_bl.c | 4 +-
drivers/video/backlight/pwm_bl.c | 6 +-
drivers/video/fbdev/ssd1307fb.c | 2 +-
include/linux/pwm.h | 82 ++++++++++++++++++---
21 files changed, 380 insertions(+), 104 deletions(-)
--
1.9.1
^ permalink raw reply
* [RFC PATCH 01/15] pwm: add the pwm_is_enabled() helper
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
Some PWM drivers are testing the PWMF_ENABLED flag. Create an helper
function to hide the logic behind enabled test.
This will allow us to smoothly move from the current approach to an atomic
PWM update approach.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/core.c | 4 ++--
drivers/pwm/pwm-atmel-tcb.c | 2 +-
drivers/pwm/pwm-atmel.c | 6 +++---
drivers/pwm/pwm-bcm-kona.c | 4 ++--
drivers/pwm/pwm-ep93xx.c | 4 ++--
drivers/pwm/pwm-imx.c | 2 +-
drivers/pwm/pwm-mxs.c | 4 ++--
drivers/pwm/pwm-renesas-tpu.c | 2 +-
drivers/pwm/pwm-tegra.c | 6 +++---
drivers/pwm/pwm-tiecap.c | 10 +++++-----
drivers/pwm/pwm-tiehrpwm.c | 6 +++---
drivers/pwm/sysfs.c | 2 +-
include/linux/pwm.h | 5 +++++
13 files changed, 31 insertions(+), 26 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 3a7769f..f7c11d2 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -455,7 +455,7 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
if (!pwm->chip->ops->set_polarity)
return -ENOSYS;
- if (test_bit(PWMF_ENABLED, &pwm->flags))
+ if (pwm_is_enabled(pwm))
return -EBUSY;
err = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
@@ -853,7 +853,7 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
if (test_bit(PWMF_REQUESTED, &pwm->flags))
seq_puts(s, " requested");
- if (test_bit(PWMF_ENABLED, &pwm->flags))
+ if (pwm_is_enabled(pwm))
seq_puts(s, " enabled");
seq_puts(s, "\n");
diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index d14e067..6da01b3 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -347,7 +347,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
tcbpwm->duty = duty;
/* If the PWM is enabled, call enable to apply the new conf */
- if (test_bit(PWMF_ENABLED, &pwm->flags))
+ if (pwm_is_enabled(pwm))
atmel_tcb_pwm_enable(chip, pwm);
return 0;
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index a947c90..b3b294d 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -114,7 +114,7 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
u32 val;
int ret;
- if (test_bit(PWMF_ENABLED, &pwm->flags) && (period_ns != pwm->period)) {
+ if (pwm_is_enabled(pwm) && (period_ns != pwm->period)) {
dev_err(chip->dev, "cannot change PWM period while enabled\n");
return -EBUSY;
}
@@ -176,7 +176,7 @@ static void atmel_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm,
* If the PWM channel is enabled, only update CDTY by using the update
* register, it needs to set bit 10 of CMR to 0
*/
- if (test_bit(PWMF_ENABLED, &pwm->flags))
+ if (pwm_is_enabled(pwm))
return;
/*
* If the PWM channel is disabled, write value to duty and period
@@ -191,7 +191,7 @@ static void atmel_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm,
{
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
- if (test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (pwm_is_enabled(pwm)) {
/*
* If the PWM channel is enabled, using the duty update register
* to update the value.
diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c
index 7af8fea..dfdcf88 100644
--- a/drivers/pwm/pwm-bcm-kona.c
+++ b/drivers/pwm/pwm-bcm-kona.c
@@ -134,7 +134,7 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
}
/* If the PWM channel is enabled, write the settings to the HW */
- if (test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (pwm_is_enabled(pwm)) {
value = readl(kp->base + PRESCALE_OFFSET);
value &= ~PRESCALE_MASK(chan);
value |= prescale << PRESCALE_SHIFT(chan);
@@ -287,7 +287,7 @@ static int kona_pwmc_remove(struct platform_device *pdev)
unsigned int chan;
for (chan = 0; chan < kp->chip.npwm; chan++)
- if (test_bit(PWMF_ENABLED, &kp->chip.pwms[chan].flags))
+ if (pwm_is_enabled(&kp->chip.pwms[chan]))
clk_disable_unprepare(kp->clk);
return pwmchip_remove(&kp->chip);
diff --git a/drivers/pwm/pwm-ep93xx.c b/drivers/pwm/pwm-ep93xx.c
index e593e9c..bbf10ae 100644
--- a/drivers/pwm/pwm-ep93xx.c
+++ b/drivers/pwm/pwm-ep93xx.c
@@ -82,7 +82,7 @@ static int ep93xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* The clock needs to be enabled to access the PWM registers.
* Configuration can be changed at any time.
*/
- if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (!pwm_is_enabled(pwm)) {
ret = clk_enable(ep93xx_pwm->clk);
if (ret)
return ret;
@@ -113,7 +113,7 @@ static int ep93xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
ret = -EINVAL;
}
- if (!test_bit(PWMF_ENABLED, &pwm->flags))
+ if (!pwm_is_enabled(pwm))
clk_disable(ep93xx_pwm->clk);
return ret;
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 66d6f0c..008dc64 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -114,7 +114,7 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
unsigned long long c;
unsigned long period_cycles, duty_cycles, prescale;
unsigned int period_ms;
- bool enable = test_bit(PWMF_ENABLED, &pwm->flags);
+ bool enable = pwm_is_enabled(pwm);
int wait_count = 0, fifoav;
u32 cr, sr;
diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c
index b430811..9a59632 100644
--- a/drivers/pwm/pwm-mxs.c
+++ b/drivers/pwm/pwm-mxs.c
@@ -77,7 +77,7 @@ static int mxs_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* If the PWM channel is disabled, make sure to turn on the clock
* before writing the register. Otherwise, keep it enabled.
*/
- if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (!pwm_is_enabled(pwm)) {
ret = clk_prepare_enable(mxs->clk);
if (ret)
return ret;
@@ -92,7 +92,7 @@ static int mxs_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
/*
* If the PWM is not enabled, turn the clock off again to save power.
*/
- if (!test_bit(PWMF_ENABLED, &pwm->flags))
+ if (!pwm_is_enabled(pwm))
clk_disable_unprepare(mxs->clk);
return 0;
diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c
index ee63f9e..075c1a7 100644
--- a/drivers/pwm/pwm-renesas-tpu.c
+++ b/drivers/pwm/pwm-renesas-tpu.c
@@ -301,7 +301,7 @@ static int tpu_pwm_config(struct pwm_chip *chip, struct pwm_device *_pwm,
pwm->duty = duty;
/* If the channel is disabled we're done. */
- if (!test_bit(PWMF_ENABLED, &_pwm->flags))
+ if (!pwm_is_enabled(_pwm))
return 0;
if (duty_only && pwm->timer_on) {
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index cabd7d8..d4de060 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -112,7 +112,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* If the PWM channel is disabled, make sure to turn on the clock
* before writing the register. Otherwise, keep it enabled.
*/
- if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (!pwm_is_enabled(pwm)) {
err = clk_prepare_enable(pc->clk);
if (err < 0)
return err;
@@ -124,7 +124,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
/*
* If the PWM is not enabled, turn the clock off again to save power.
*/
- if (!test_bit(PWMF_ENABLED, &pwm->flags))
+ if (!pwm_is_enabled(pwm))
clk_disable_unprepare(pc->clk);
return 0;
@@ -214,7 +214,7 @@ static int tegra_pwm_remove(struct platform_device *pdev)
for (i = 0; i < NUM_PWM; i++) {
struct pwm_device *pwm = &pc->chip.pwms[i];
- if (!test_bit(PWMF_ENABLED, &pwm->flags))
+ if (!pwm_is_enabled(pwm))
if (clk_prepare_enable(pc->clk) < 0)
continue;
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index e557bef..616af76 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -97,7 +97,7 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
writew(reg_val, pc->mmio_base + ECCTL2);
- if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (!pwm_is_enabled(pwm)) {
/* Update active registers if not running */
writel(duty_cycles, pc->mmio_base + CAP2);
writel(period_cycles, pc->mmio_base + CAP1);
@@ -111,7 +111,7 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
writel(period_cycles, pc->mmio_base + CAP3);
}
- if (!test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (!pwm_is_enabled(pwm)) {
reg_val = readw(pc->mmio_base + ECCTL2);
/* Disable APWM mode to put APWM output Low */
reg_val &= ~ECCTL2_APWM_MODE;
@@ -179,7 +179,7 @@ static void ecap_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
static void ecap_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
- if (test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (pwm_is_enabled(pwm)) {
dev_warn(chip->dev, "Removing PWM device without disabling\n");
pm_runtime_put_sync(chip->dev);
}
@@ -306,7 +306,7 @@ static int ecap_pwm_suspend(struct device *dev)
ecap_pwm_save_context(pc);
/* Disable explicitly if PWM is running */
- if (test_bit(PWMF_ENABLED, &pwm->flags))
+ if (pwm_is_enabled(pwm))
pm_runtime_put_sync(dev);
return 0;
@@ -318,7 +318,7 @@ static int ecap_pwm_resume(struct device *dev)
struct pwm_device *pwm = pc->chip.pwms;
/* Enable explicitly if PWM was running */
- if (test_bit(PWMF_ENABLED, &pwm->flags))
+ if (pwm_is_enabled(pwm))
pm_runtime_get_sync(dev);
ecap_pwm_restore_context(pc);
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index 694b3cf..6a41e66 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -407,7 +407,7 @@ static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
- if (test_bit(PWMF_ENABLED, &pwm->flags)) {
+ if (pwm_is_enabled(pwm)) {
dev_warn(chip->dev, "Removing PWM device without disabling\n");
pm_runtime_put_sync(chip->dev);
}
@@ -565,7 +565,7 @@ static int ehrpwm_pwm_suspend(struct device *dev)
for (i = 0; i < pc->chip.npwm; i++) {
struct pwm_device *pwm = &pc->chip.pwms[i];
- if (!test_bit(PWMF_ENABLED, &pwm->flags))
+ if (!pwm_is_enabled(pwm))
continue;
/* Disable explicitly if PWM is running */
@@ -582,7 +582,7 @@ static int ehrpwm_pwm_resume(struct device *dev)
for (i = 0; i < pc->chip.npwm; i++) {
struct pwm_device *pwm = &pc->chip.pwms[i];
- if (!test_bit(PWMF_ENABLED, &pwm->flags))
+ if (!pwm_is_enabled(pwm))
continue;
/* Enable explicitly if PWM was running */
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 4bd0c63..eecf21d 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -97,7 +97,7 @@ static ssize_t pwm_enable_show(struct device *child,
char *buf)
{
const struct pwm_device *pwm = child_to_pwm_device(child);
- int enabled = test_bit(PWMF_ENABLED, &pwm->flags);
+ int enabled = pwm_is_enabled(pwm);
return sprintf(buf, "%d\n", enabled);
}
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 36262d0..ec34f4d 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -92,6 +92,11 @@ struct pwm_device {
enum pwm_polarity polarity;
};
+static inline bool pwm_is_enabled(const struct pwm_device *pwm)
+{
+ return test_bit(PWMF_ENABLED, &pwm->flags);
+}
+
static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
{
if (pwm)
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 02/15] pwm: fix pwm_get_period and pwm_get_duty_cycle prototypes
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
The pwm argument is not modified in pwm_get helpers, make it a const
argument so that they can be used from the sysfs functions.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
include/linux/pwm.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index ec34f4d..d8f6913 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -103,7 +103,7 @@ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
pwm->period = period;
}
-static inline unsigned int pwm_get_period(struct pwm_device *pwm)
+static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
{
return pwm ? pwm->period : 0;
}
@@ -114,7 +114,7 @@ static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
pwm->duty_cycle = duty;
}
-static inline unsigned int pwm_get_duty_cycle(struct pwm_device *pwm)
+static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
{
return pwm ? pwm->duty_cycle : 0;
}
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 03/15] pwm: add pwm_get_polarity helper function
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
Some drivers are directly accessing the ->polarity field in pwm_device.
Add an helper to retrieve the current polarity so that we can easily move
this field elsewhere (required to support atomic update).
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
include/linux/pwm.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index d8f6913..6f286df 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -124,6 +124,11 @@ static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
*/
int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
+static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
+{
+ return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;
+}
+
/**
* struct pwm_ops - PWM controller operations
* @request: optional hook for requesting a PWM
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 04/15] pwm: make use of pwm_get_xxx helpers where appropriate
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
Use the pwm_get_xxx helpers instead of directly accessing the fields in
pwm_device. This will allow us to smoothly move to the atomic update
approach.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/pwm-atmel.c | 2 +-
drivers/pwm/pwm-bcm-kona.c | 3 ++-
drivers/pwm/pwm-imx.c | 3 ++-
drivers/pwm/pwm-rockchip.c | 2 +-
drivers/pwm/sysfs.c | 11 ++++++-----
5 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index b3b294d..0e4bd4e 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -114,7 +114,7 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
u32 val;
int ret;
- if (pwm_is_enabled(pwm) && (period_ns != pwm->period)) {
+ if (pwm_is_enabled(pwm) && (period_ns != pwm_get_period(pwm))) {
dev_err(chip->dev, "cannot change PWM period while enabled\n");
return -EBUSY;
}
diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c
index dfdcf88..920cd1b 100644
--- a/drivers/pwm/pwm-bcm-kona.c
+++ b/drivers/pwm/pwm-bcm-kona.c
@@ -194,7 +194,8 @@ static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm)
return ret;
}
- ret = kona_pwmc_config(chip, pwm, pwm->duty_cycle, pwm->period);
+ ret = kona_pwmc_config(chip, pwm, pwm_get_duty_cycle(pwm),
+ pwm_get_period(pwm));
if (ret < 0) {
clk_disable_unprepare(kp->clk);
return ret;
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 008dc64..d600fd5 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -129,7 +129,8 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
sr = readl(imx->mmio_base + MX3_PWMSR);
fifoav = sr & MX3_PWMSR_FIFOAV_MASK;
if (fifoav = MX3_PWMSR_FIFOAV_4WORDS) {
- period_ms = DIV_ROUND_UP(pwm->period, NSEC_PER_MSEC);
+ period_ms = DIV_ROUND_UP(pwm_get_period(pwm),
+ NSEC_PER_MSEC);
msleep(period_ms);
sr = readl(imx->mmio_base + MX3_PWMSR);
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 9442df2..7d9cc90 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -83,7 +83,7 @@ static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
PWM_CONTINUOUS;
u32 val;
- if (pwm->polarity = PWM_POLARITY_INVERSED)
+ if (pwm_get_polarity(pwm) = PWM_POLARITY_INVERSED)
enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE;
else
enable_conf |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index eecf21d..ac0abec 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -46,7 +46,7 @@ static ssize_t pwm_period_show(struct device *child,
{
const struct pwm_device *pwm = child_to_pwm_device(child);
- return sprintf(buf, "%u\n", pwm->period);
+ return sprintf(buf, "%u\n", pwm_get_period(pwm));
}
static ssize_t pwm_period_store(struct device *child,
@@ -61,7 +61,7 @@ static ssize_t pwm_period_store(struct device *child,
if (ret)
return ret;
- ret = pwm_config(pwm, pwm->duty_cycle, val);
+ ret = pwm_config(pwm, pwm_get_duty_cycle(pwm), val);
return ret ? : size;
}
@@ -72,7 +72,7 @@ static ssize_t pwm_duty_cycle_show(struct device *child,
{
const struct pwm_device *pwm = child_to_pwm_device(child);
- return sprintf(buf, "%u\n", pwm->duty_cycle);
+ return sprintf(buf, "%u\n", pwm_get_duty_cycle(pwm));
}
static ssize_t pwm_duty_cycle_store(struct device *child,
@@ -87,7 +87,7 @@ static ssize_t pwm_duty_cycle_store(struct device *child,
if (ret)
return ret;
- ret = pwm_config(pwm, val, pwm->period);
+ ret = pwm_config(pwm, val, pwm_get_period(pwm));
return ret ? : size;
}
@@ -134,7 +134,8 @@ static ssize_t pwm_polarity_show(struct device *child,
{
const struct pwm_device *pwm = child_to_pwm_device(child);
- return sprintf(buf, "%s\n", pwm->polarity ? "inversed" : "normal");
+ return sprintf(buf, "%s\n",
+ pwm_get_polarity(pwm) ? "inversed" : "normal");
}
static ssize_t pwm_polarity_store(struct device *child,
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 05/15] pwm: introduce default period and polarity concepts
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
When requested by a user, the PWM is assigned a default period and polarity
extracted from the DT, the platform data or statically set by the driver.
Those default values are currently stored in the period and polarity
fields of the pwm_device struct, but they will be stored somewhere else
once we have introduced the architecture allowing for hardware state
retrieval.
The pwm_set_default_polarity and pwm_set_default_period should only be
used by PWM drivers or the PWM core infrastructure to specify the
default period and polarity values.
PWM users might call the pwm_get_default_period to query the default
period value. There is currently no helper to query the default
polarity, but it might be added later on if there is a need for it.
This patch also modifies all the places where the default helpers should
be used in place of the standard ones.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/leds/leds-pwm.c | 2 +-
drivers/pwm/core.c | 14 +++++++-------
drivers/pwm/pwm-pxa.c | 2 +-
drivers/pwm/pwm-sun4i.c | 3 ++-
drivers/regulator/pwm-regulator.c | 2 +-
drivers/video/backlight/lm3630a_bl.c | 4 ++--
drivers/video/backlight/pwm_bl.c | 2 +-
drivers/video/fbdev/ssd1307fb.c | 2 +-
include/linux/pwm.h | 15 +++++++++++++++
9 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 1d07e3e..2c564d1 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -125,7 +125,7 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
if (led_data->can_sleep)
INIT_WORK(&led_data->work, led_pwm_work);
- led_data->period = pwm_get_period(led_data->pwm);
+ led_data->period = pwm_get_default_period(led_data->pwm);
if (!led_data->period && (led->pwm_period_ns > 0))
led_data->period = led->pwm_period_ns;
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index f7c11d2..7ffad2b 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -146,12 +146,12 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;
- pwm_set_period(pwm, args->args[1]);
+ pwm_set_default_period(pwm, args->args[1]);
if (args->args[2] & PWM_POLARITY_INVERTED)
- pwm_set_polarity(pwm, PWM_POLARITY_INVERSED);
+ pwm_set_default_polarity(pwm, PWM_POLARITY_INVERSED);
else
- pwm_set_polarity(pwm, PWM_POLARITY_NORMAL);
+ pwm_set_default_polarity(pwm, PWM_POLARITY_NORMAL);
return pwm;
}
@@ -172,7 +172,7 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;
- pwm_set_period(pwm, args->args[1]);
+ pwm_set_default_period(pwm, args->args[1]);
return pwm;
}
@@ -262,7 +262,7 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
pwm->chip = chip;
pwm->pwm = chip->base + i;
pwm->hwpwm = i;
- pwm->polarity = polarity;
+ pwm_set_default_polarity(pwm, polarity);
radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
}
@@ -704,8 +704,8 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
if (IS_ERR(pwm))
goto out;
- pwm_set_period(pwm, chosen->period);
- pwm_set_polarity(pwm, chosen->polarity);
+ pwm_set_default_period(pwm, chosen->period);
+ pwm_set_default_polarity(pwm, chosen->polarity);
out:
mutex_unlock(&pwm_lookup_lock);
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index cb2f702..65b80aa 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -160,7 +160,7 @@ pxa_pwm_of_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
if (IS_ERR(pwm))
return pwm;
- pwm_set_period(pwm, args->args[0]);
+ pwm_set_default_period(pwm, args->args[0]);
return pwm;
}
diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
index cd9dde5..a364fb7 100644
--- a/drivers/pwm/pwm-sun4i.c
+++ b/drivers/pwm/pwm-sun4i.c
@@ -333,7 +333,8 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
val = sun4i_pwm_readl(pwm, PWM_CTRL_REG);
for (i = 0; i < pwm->chip.npwm; i++)
if (!(val & BIT_CH(PWM_ACT_STATE, i)))
- pwm->chip.pwms[i].polarity = PWM_POLARITY_INVERSED;
+ pwm_set_default_polarity(&pwm->chip.pwms[i],
+ PWM_POLARITY_INVERSED);
clk_disable_unprepare(pwm->clk);
return 0;
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c
index ffa9612..12b4d9d 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -46,7 +46,7 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
int dutycycle;
int ret;
- pwm_reg_period = pwm_get_period(drvdata->pwm);
+ pwm_reg_period = pwm_get_default_period(drvdata->pwm);
dutycycle = (pwm_reg_period *
drvdata->duty_cycle_table[selector].dutycycle) / 100;
diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c
index 35fe482..449ebc3 100644
--- a/drivers/video/backlight/lm3630a_bl.c
+++ b/drivers/video/backlight/lm3630a_bl.c
@@ -162,7 +162,7 @@ static int lm3630a_intr_config(struct lm3630a_chip *pchip)
static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max)
{
- unsigned int period = pwm_get_period(pchip->pwmd);
+ unsigned int period = pwm_get_default_period(pchip->pwmd);
unsigned int duty = br * period / br_max;
pwm_config(pchip->pwmd, duty, period);
@@ -425,7 +425,7 @@ static int lm3630a_probe(struct i2c_client *client,
return PTR_ERR(pchip->pwmd);
}
}
- pchip->pwmd->period = pdata->pwm_period;
+ pwm_set_default_period(pchip->pwmd, pdata->pwm_period);
/* interrupt enable : irq 0 is not allowed */
pchip->irq = client->irq;
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index eff379b..ae498c1 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -294,7 +294,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
* set the period from platform data if it has not already been set
* via the PWM lookup table.
*/
- pb->period = pwm_get_period(pb->pwm);
+ pb->period = pwm_get_default_period(pb->pwm);
if (!pb->period && (data->pwm_period_ns > 0)) {
pb->period = data->pwm_period_ns;
pwm_set_period(pb->pwm, data->pwm_period_ns);
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index 3e153c0..6949626 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -294,7 +294,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
return PTR_ERR(par->pwm);
}
- par->pwm_period = pwm_get_period(par->pwm);
+ par->pwm_period = pwm_get_default_period(par->pwm);
/* Enable the PWM */
pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
pwm_enable(par->pwm);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 6f286df..72a21d5 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -103,11 +103,21 @@ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
pwm->period = period;
}
+static inline void pwm_set_default_period(struct pwm_device *pwm, unsigned int period)
+{
+ pwm_set_period(pwm, period);
+}
+
static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
{
return pwm ? pwm->period : 0;
}
+static inline unsigned int pwm_get_default_period(const struct pwm_device *pwm)
+{
+ return pwm_get_period(pwm);
+}
+
static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
{
if (pwm)
@@ -124,6 +134,11 @@ static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
*/
int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
+static inline void pwm_set_default_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
+{
+ pwm_set_polarity(pwm, polarity);
+}
+
static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
{
return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 06/15] pwm: define a new pwm_state struct
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
The PWM state, represented by its period, duty_cycle and polarity,
is currently directly stored in the PWM device.
Declare a pwm_state structure embedding those field so that we can later
use this struct to atomically update all the PWM parameters at once.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/core.c | 6 +++---
include/linux/pwm.h | 20 ++++++++++++--------
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 7ffad2b..a6bc8e6 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -431,8 +431,8 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
if (err)
return err;
- pwm->duty_cycle = duty_ns;
- pwm->period = period_ns;
+ pwm->state.duty_cycle = duty_ns;
+ pwm->state.period = period_ns;
return 0;
}
@@ -462,7 +462,7 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
if (err)
return err;
- pwm->polarity = polarity;
+ pwm->state.polarity = polarity;
return 0;
}
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 72a21d5..bed7234 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -79,6 +79,12 @@ enum {
PWMF_EXPORTED = 1 << 2,
};
+struct pwm_state {
+ unsigned int period; /* in nanoseconds */
+ unsigned int duty_cycle; /* in nanoseconds */
+ enum pwm_polarity polarity;
+};
+
struct pwm_device {
const char *label;
unsigned long flags;
@@ -87,9 +93,7 @@ struct pwm_device {
struct pwm_chip *chip;
void *chip_data;
- unsigned int period; /* in nanoseconds */
- unsigned int duty_cycle; /* in nanoseconds */
- enum pwm_polarity polarity;
+ struct pwm_state state;
};
static inline bool pwm_is_enabled(const struct pwm_device *pwm)
@@ -100,7 +104,7 @@ static inline bool pwm_is_enabled(const struct pwm_device *pwm)
static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
{
if (pwm)
- pwm->period = period;
+ pwm->state.period = period;
}
static inline void pwm_set_default_period(struct pwm_device *pwm, unsigned int period)
@@ -110,7 +114,7 @@ static inline void pwm_set_default_period(struct pwm_device *pwm, unsigned int p
static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
{
- return pwm ? pwm->period : 0;
+ return pwm ? pwm->state.period : 0;
}
static inline unsigned int pwm_get_default_period(const struct pwm_device *pwm)
@@ -121,12 +125,12 @@ static inline unsigned int pwm_get_default_period(const struct pwm_device *pwm)
static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
{
if (pwm)
- pwm->duty_cycle = duty;
+ pwm->state.duty_cycle = duty;
}
static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
{
- return pwm ? pwm->duty_cycle : 0;
+ return pwm ? pwm->state.duty_cycle : 0;
}
/*
@@ -141,7 +145,7 @@ static inline void pwm_set_default_polarity(struct pwm_device *pwm, enum pwm_pol
static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
{
- return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;
+ return pwm ? pwm->state.polarity : PWM_POLARITY_NORMAL;
}
/**
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 07/15] pwm: move the enabled/disabled info to pwm_state struct
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
Prepare the transition to PWM atomic update by moving the enabled/disabled
state into the pwm_state struct. This way we can easily update the whole
PWM state by copying the new state in the ->state field.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/pwm/core.c | 15 ++++++++++++---
include/linux/pwm.h | 6 +++---
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a6bc8e6..3e830ce 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -474,8 +474,15 @@ EXPORT_SYMBOL_GPL(pwm_set_polarity);
*/
int pwm_enable(struct pwm_device *pwm)
{
- if (pwm && !test_and_set_bit(PWMF_ENABLED, &pwm->flags))
- return pwm->chip->ops->enable(pwm->chip, pwm);
+ if (pwm && !pwm_is_enabled(pwm)) {
+ int err;
+
+ err = pwm->chip->ops->enable(pwm->chip, pwm);
+ if (!err)
+ pwm->state.enabled = true;
+
+ return err;
+ }
return pwm ? 0 : -EINVAL;
}
@@ -487,8 +494,10 @@ EXPORT_SYMBOL_GPL(pwm_enable);
*/
void pwm_disable(struct pwm_device *pwm)
{
- if (pwm && test_and_clear_bit(PWMF_ENABLED, &pwm->flags))
+ if (pwm && pwm_is_enabled(pwm)) {
pwm->chip->ops->disable(pwm->chip, pwm);
+ pwm->state.enabled = false;
+ }
}
EXPORT_SYMBOL_GPL(pwm_disable);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index bed7234..fd3e0f0 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -75,14 +75,14 @@ enum pwm_polarity {
enum {
PWMF_REQUESTED = 1 << 0,
- PWMF_ENABLED = 1 << 1,
- PWMF_EXPORTED = 1 << 2,
+ PWMF_EXPORTED = 1 << 1,
};
struct pwm_state {
unsigned int period; /* in nanoseconds */
unsigned int duty_cycle; /* in nanoseconds */
enum pwm_polarity polarity;
+ bool enabled;
};
struct pwm_device {
@@ -98,7 +98,7 @@ struct pwm_device {
static inline bool pwm_is_enabled(const struct pwm_device *pwm)
{
- return test_bit(PWMF_ENABLED, &pwm->flags);
+ return pwm->state.enabled;
}
static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 08/15] backlight: pwm_bl: remove useless call to pwm_set_period
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
The PWM period will be set when calling pwm_config. Remove this useless
call to pwm_set_period, which might mess up with the initial PWM state
once we have added proper support for PWM init state retrieval.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/video/backlight/pwm_bl.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index ae498c1..fe5597c 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -295,10 +295,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
* via the PWM lookup table.
*/
pb->period = pwm_get_default_period(pb->pwm);
- if (!pb->period && (data->pwm_period_ns > 0)) {
+ if (!pb->period && (data->pwm_period_ns > 0))
pb->period = data->pwm_period_ns;
- pwm_set_period(pb->pwm, data->pwm_period_ns);
- }
pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);
--
1.9.1
^ permalink raw reply related
* [RFC PATCH 09/15] pwm: declare a default PWM state
From: Boris Brezillon @ 2015-07-01 8:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1435738921-25027-1-git-send-email-boris.brezillon@free-electrons.com>
Prepare the addition of the PWM initial state retrieval by adding a default
state where all the parameters retrieved from DT, platform data or
statically forced by the hardware will be stored.
Once done we will be able to store the initial state in the ->state field
without risking to loose the default parameters.
Update the pwm_set/get_default_xxx helpers accordingly.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
include/linux/pwm.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index fd3e0f0..0f36a06 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -94,6 +94,7 @@ struct pwm_device {
void *chip_data;
struct pwm_state state;
+ struct pwm_state default_state;
};
static inline bool pwm_is_enabled(const struct pwm_device *pwm)
@@ -109,7 +110,8 @@ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
static inline void pwm_set_default_period(struct pwm_device *pwm, unsigned int period)
{
- pwm_set_period(pwm, period);
+ if (pwm)
+ pwm->default_state.period = period;
}
static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
@@ -119,7 +121,7 @@ static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
static inline unsigned int pwm_get_default_period(const struct pwm_device *pwm)
{
- return pwm_get_period(pwm);
+ return pwm ? pwm->default_state.period : 0;
}
static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
@@ -140,7 +142,8 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
static inline void pwm_set_default_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
{
- pwm_set_polarity(pwm, polarity);
+ if (pwm)
+ pwm->default_state.polarity = polarity;
}
static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)
--
1.9.1
^ permalink raw reply related
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