linux/drivers/platform/surface/aggregator/ssh_request_layer.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * SSH request transport layer.
   4 *
   5 * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
   6 */
   7
   8#ifndef _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H
   9#define _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H
  10
  11#include <linux/atomic.h>
  12#include <linux/ktime.h>
  13#include <linux/list.h>
  14#include <linux/spinlock.h>
  15#include <linux/workqueue.h>
  16
  17#include <linux/surface_aggregator/serial_hub.h>
  18#include <linux/surface_aggregator/controller.h>
  19
  20#include "ssh_packet_layer.h"
  21
  22/**
  23 * enum ssh_rtl_state_flags - State-flags for &struct ssh_rtl.
  24 *
  25 * @SSH_RTL_SF_SHUTDOWN_BIT:
  26 *      Indicates that the request transport layer has been shut down or is
  27 *      being shut down and should not accept any new requests.
  28 */
  29enum ssh_rtl_state_flags {
  30        SSH_RTL_SF_SHUTDOWN_BIT,
  31};
  32
  33/**
  34 * struct ssh_rtl_ops - Callback operations for request transport layer.
  35 * @handle_event: Function called when a SSH event has been received. The
  36 *                specified function takes the request layer, received command
  37 *                struct, and corresponding payload as arguments. If the event
  38 *                has no payload, the payload span is empty (not %NULL).
  39 */
  40struct ssh_rtl_ops {
  41        void (*handle_event)(struct ssh_rtl *rtl, const struct ssh_command *cmd,
  42                             const struct ssam_span *data);
  43};
  44
  45/**
  46 * struct ssh_rtl - SSH request transport layer.
  47 * @ptl:           Underlying packet transport layer.
  48 * @state:         State(-flags) of the transport layer.
  49 * @queue:         Request submission queue.
  50 * @queue.lock:    Lock for modifying the request submission queue.
  51 * @queue.head:    List-head of the request submission queue.
  52 * @pending:       Set/list of pending requests.
  53 * @pending.lock:  Lock for modifying the request set.
  54 * @pending.head:  List-head of the pending set/list.
  55 * @pending.count: Number of currently pending requests.
  56 * @tx:            Transmitter subsystem.
  57 * @tx.work:       Transmitter work item.
  58 * @rtx_timeout:   Retransmission timeout subsystem.
  59 * @rtx_timeout.lock:    Lock for modifying the retransmission timeout reaper.
  60 * @rtx_timeout.timeout: Timeout interval for retransmission.
  61 * @rtx_timeout.expires: Time specifying when the reaper work is next scheduled.
  62 * @rtx_timeout.reaper:  Work performing timeout checks and subsequent actions.
  63 * @ops:           Request layer operations.
  64 */
  65struct ssh_rtl {
  66        struct ssh_ptl ptl;
  67        unsigned long state;
  68
  69        struct {
  70                spinlock_t lock;
  71                struct list_head head;
  72        } queue;
  73
  74        struct {
  75                spinlock_t lock;
  76                struct list_head head;
  77                atomic_t count;
  78        } pending;
  79
  80        struct {
  81                struct work_struct work;
  82        } tx;
  83
  84        struct {
  85                spinlock_t lock;
  86                ktime_t timeout;
  87                ktime_t expires;
  88                struct delayed_work reaper;
  89        } rtx_timeout;
  90
  91        struct ssh_rtl_ops ops;
  92};
  93
  94#define rtl_dbg(r, fmt, ...)  ptl_dbg(&(r)->ptl, fmt, ##__VA_ARGS__)
  95#define rtl_info(p, fmt, ...) ptl_info(&(p)->ptl, fmt, ##__VA_ARGS__)
  96#define rtl_warn(r, fmt, ...) ptl_warn(&(r)->ptl, fmt, ##__VA_ARGS__)
  97#define rtl_err(r, fmt, ...)  ptl_err(&(r)->ptl, fmt, ##__VA_ARGS__)
  98#define rtl_dbg_cond(r, fmt, ...) __ssam_prcond(rtl_dbg, r, fmt, ##__VA_ARGS__)
  99
 100#define to_ssh_rtl(ptr, member) \
 101        container_of(ptr, struct ssh_rtl, member)
 102
 103/**
 104 * ssh_rtl_get_device() - Get device associated with request transport layer.
 105 * @rtl: The request transport layer.
 106 *
 107 * Return: Returns the device on which the given request transport layer
 108 * builds upon.
 109 */
 110static inline struct device *ssh_rtl_get_device(struct ssh_rtl *rtl)
 111{
 112        return ssh_ptl_get_device(&rtl->ptl);
 113}
 114
 115/**
 116 * ssh_request_rtl() - Get request transport layer associated with request.
 117 * @rqst: The request to get the request transport layer reference for.
 118 *
 119 * Return: Returns the &struct ssh_rtl associated with the given SSH request.
 120 */
 121static inline struct ssh_rtl *ssh_request_rtl(struct ssh_request *rqst)
 122{
 123        struct ssh_ptl *ptl;
 124
 125        ptl = READ_ONCE(rqst->packet.ptl);
 126        return likely(ptl) ? to_ssh_rtl(ptl, ptl) : NULL;
 127}
 128
 129int ssh_rtl_submit(struct ssh_rtl *rtl, struct ssh_request *rqst);
 130bool ssh_rtl_cancel(struct ssh_request *rqst, bool pending);
 131
 132int ssh_rtl_init(struct ssh_rtl *rtl, struct serdev_device *serdev,
 133                 const struct ssh_rtl_ops *ops);
 134
 135int ssh_rtl_start(struct ssh_rtl *rtl);
 136int ssh_rtl_flush(struct ssh_rtl *rtl, unsigned long timeout);
 137void ssh_rtl_shutdown(struct ssh_rtl *rtl);
 138void ssh_rtl_destroy(struct ssh_rtl *rtl);
 139
 140int ssh_request_init(struct ssh_request *rqst, enum ssam_request_flags flags,
 141                     const struct ssh_request_ops *ops);
 142
 143#endif /* _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H */
 144