Skip to content

Commit

Permalink
video: omap: Remove in_interrupt() usage.
Browse files Browse the repository at this point in the history
alloc_req() uses in_interrupt() to detect if it is safe to use down().

The usage of in_interrupt() in drivers is phased out and Linus clearly
requested that code which changes behaviour depending on context should
either be separated or the context be conveyed in an argument passed by the
caller, which usually knows the context.

The semaphore is used as a counting semaphore, initialized with the
number of slots in the request pool minus IRQ_REQ_POOL_SIZE - which are
reserved for the in_interrupt() user to ensure that a request is always
available. The preemptible user will block on the semphore waiting for a
request to become available in case there are no requests available.

Replace in_interrupt() with a `can_sleep' argument to indicate if it is
safe to block on the sempahore.

Cc: [email protected]
Signed-off-by: Ahmed S. Darwish <[email protected]>
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
  • Loading branch information
a-darwish authored and danvet committed Feb 18, 2021
1 parent 92f1d09 commit 6e4863d
Showing 1 changed file with 28 additions and 14 deletions.
42 changes: 28 additions & 14 deletions drivers/video/fbdev/omap/hwa742.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ struct {
struct hwa742_request req_pool[REQ_POOL_SIZE];
struct list_head pending_req_list;
struct list_head free_req_list;

/*
* @req_lock: protect request slots pool and its tracking lists
* @req_sema: counter; slot allocators from task contexts must
* push it down before acquiring a slot. This
* guarantees that atomic contexts will always have
* a minimum of IRQ_REQ_POOL_SIZE slots available.
*/
struct semaphore req_sema;
spinlock_t req_lock;

Expand Down Expand Up @@ -224,13 +232,13 @@ static void disable_tearsync(void)
hwa742_write_reg(HWA742_NDP_CTRL, b);
}

static inline struct hwa742_request *alloc_req(void)
static inline struct hwa742_request *alloc_req(bool can_sleep)
{
unsigned long flags;
struct hwa742_request *req;
int req_flags = 0;

if (!in_interrupt())
if (can_sleep)
down(&hwa742.req_sema);
else
req_flags = REQ_FROM_IRQ_POOL;
Expand Down Expand Up @@ -399,8 +407,8 @@ static void send_frame_complete(void *data)
hwa742.int_ctrl->enable_plane(OMAPFB_PLANE_GFX, 0);
}

#define ADD_PREQ(_x, _y, _w, _h) do { \
req = alloc_req(); \
#define ADD_PREQ(_x, _y, _w, _h, can_sleep) do {\
req = alloc_req(can_sleep); \
req->handler = send_frame_handler; \
req->complete = send_frame_complete; \
req->par.update.x = _x; \
Expand All @@ -413,7 +421,8 @@ static void send_frame_complete(void *data)
} while(0)

static void create_req_list(struct omapfb_update_window *win,
struct list_head *req_head)
struct list_head *req_head,
bool can_sleep)
{
struct hwa742_request *req;
int x = win->x;
Expand All @@ -427,7 +436,7 @@ static void create_req_list(struct omapfb_update_window *win,
color_mode = win->format & OMAPFB_FORMAT_MASK;

if (x & 1) {
ADD_PREQ(x, y, 1, height);
ADD_PREQ(x, y, 1, height, can_sleep);
width--;
x++;
flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
Expand All @@ -439,19 +448,19 @@ static void create_req_list(struct omapfb_update_window *win,

if (xspan * height * 2 > hwa742.max_transmit_size) {
yspan = hwa742.max_transmit_size / (xspan * 2);
ADD_PREQ(x, ystart, xspan, yspan);
ADD_PREQ(x, ystart, xspan, yspan, can_sleep);
ystart += yspan;
yspan = height - yspan;
flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
}

ADD_PREQ(x, ystart, xspan, yspan);
ADD_PREQ(x, ystart, xspan, yspan, can_sleep);
x += xspan;
width -= xspan;
flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
}
if (width)
ADD_PREQ(x, y, 1, height);
ADD_PREQ(x, y, 1, height, can_sleep);
}

static void auto_update_complete(void *data)
Expand All @@ -461,12 +470,12 @@ static void auto_update_complete(void *data)
jiffies + HWA742_AUTO_UPDATE_TIME);
}

static void hwa742_update_window_auto(struct timer_list *unused)
static void __hwa742_update_window_auto(bool can_sleep)
{
LIST_HEAD(req_list);
struct hwa742_request *last;

create_req_list(&hwa742.auto_update_window, &req_list);
create_req_list(&hwa742.auto_update_window, &req_list, can_sleep);
last = list_entry(req_list.prev, struct hwa742_request, entry);

last->complete = auto_update_complete;
Expand All @@ -475,6 +484,11 @@ static void hwa742_update_window_auto(struct timer_list *unused)
submit_req_list(&req_list);
}

static void hwa742_update_window_auto(struct timer_list *unused)
{
__hwa742_update_window_auto(false);
}

int hwa742_update_window_async(struct fb_info *fbi,
struct omapfb_update_window *win,
void (*complete_callback)(void *arg),
Expand All @@ -497,7 +511,7 @@ int hwa742_update_window_async(struct fb_info *fbi,
goto out;
}

create_req_list(win, &req_list);
create_req_list(win, &req_list, true);
last = list_entry(req_list.prev, struct hwa742_request, entry);

last->complete = complete_callback;
Expand Down Expand Up @@ -544,7 +558,7 @@ static void hwa742_sync(void)
struct hwa742_request *req;
struct completion comp;

req = alloc_req();
req = alloc_req(true);

req->handler = sync_handler;
req->complete = NULL;
Expand Down Expand Up @@ -599,7 +613,7 @@ static int hwa742_set_update_mode(enum omapfb_update_mode mode)
omapfb_notify_clients(hwa742.fbdev, OMAPFB_EVENT_READY);
break;
case OMAPFB_AUTO_UPDATE:
hwa742_update_window_auto(0);
__hwa742_update_window_auto(true);
break;
case OMAPFB_UPDATE_DISABLED:
break;
Expand Down

0 comments on commit 6e4863d

Please sign in to comment.