soc: qcom: smd: Squash away the last differences from v4.7-rc1
authorBjorn Andersson <bjorn.andersson@linaro.org>
Tue, 7 Jun 2016 03:52:09 +0000 (20:52 -0700)
committerNicolas Dechesne <nicolas.dechesne@linaro.org>
Tue, 21 Jun 2016 08:02:16 +0000 (11:02 +0300)
This merges awy the last differences between the 4.4 release branch and
v4.7-rc1.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/soc/qcom/smd.c
include/linux/soc/qcom/smd.h

index 05cb300..0b08b9d 100644 (file)
@@ -123,7 +123,7 @@ struct qcom_smd_edge {
        int ipc_bit;
 
        struct list_head channels;
-       rwlock_t channels_lock;
+       spinlock_t channels_lock;
 
        DECLARE_BITMAP(allocated[SMD_ALLOC_TBL_COUNT], SMD_ALLOC_TBL_SIZE);
 
@@ -135,6 +135,71 @@ struct qcom_smd_edge {
        struct work_struct state_work;
 };
 
+/*
+ * SMD channel states.
+ */
+enum smd_channel_state {
+       SMD_CHANNEL_CLOSED,
+       SMD_CHANNEL_OPENING,
+       SMD_CHANNEL_OPENED,
+       SMD_CHANNEL_FLUSHING,
+       SMD_CHANNEL_CLOSING,
+       SMD_CHANNEL_RESET,
+       SMD_CHANNEL_RESET_OPENING
+};
+
+/**
+ * struct qcom_smd_channel - smd channel struct
+ * @edge:              qcom_smd_edge this channel is living on
+ * @qsdev:             reference to a associated smd client device
+ * @name:              name of the channel
+ * @state:             local state of the channel
+ * @remote_state:      remote state of the channel
+ * @info:              byte aligned outgoing/incoming channel info
+ * @info_word:         word aligned outgoing/incoming channel info
+ * @tx_lock:           lock to make writes to the channel mutually exclusive
+ * @fblockread_event:  wakeup event tied to tx fBLOCKREADINTR
+ * @tx_fifo:           pointer to the outgoing ring buffer
+ * @rx_fifo:           pointer to the incoming ring buffer
+ * @fifo_size:         size of each ring buffer
+ * @bounce_buffer:     bounce buffer for reading wrapped packets
+ * @cb:                        callback function registered for this channel
+ * @recv_lock:         guard for rx info modifications and cb pointer
+ * @pkt_size:          size of the currently handled packet
+ * @list:              lite entry for @channels in qcom_smd_edge
+ */
+struct qcom_smd_channel {
+       struct qcom_smd_edge *edge;
+
+       struct qcom_smd_device *qsdev;
+
+       char *name;
+       enum smd_channel_state state;
+       enum smd_channel_state remote_state;
+
+       struct smd_channel_info_pair *info;
+       struct smd_channel_info_word_pair *info_word;
+
+       struct mutex tx_lock;
+       wait_queue_head_t fblockread_event;
+
+       void *tx_fifo;
+       void *rx_fifo;
+       int fifo_size;
+
+       void *bounce_buffer;
+       qcom_smd_cb_t cb;
+
+       spinlock_t recv_lock;
+
+       int pkt_size;
+
+       void *drvdata;
+
+       struct list_head list;
+       struct list_head dev_list;
+};
+
 /**
  * struct qcom_smd - smd struct
  * @dev:       device struct
@@ -555,18 +620,19 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data)
        struct qcom_smd_edge *edge = data;
        struct qcom_smd_channel *channel;
        unsigned available;
-       bool kick_worker = false;
+       bool kick_scanner = false;
+       bool kick_state = false;
 
        /*
         * Handle state changes or data on each of the channels on this edge
         */
-       read_lock(&edge->channels_lock);
+       spin_lock(&edge->channels_lock);
        list_for_each_entry(channel, &edge->channels, list) {
                spin_lock(&channel->recv_lock);
-               kick_worker |= qcom_smd_channel_intr(channel);
+               kick_state |= qcom_smd_channel_intr(channel);
                spin_unlock(&channel->recv_lock);
        }
-       read_unlock(&edge->channels_lock);
+       spin_unlock(&edge->channels_lock);
 
        /*
         * Creating a new channel requires allocating an smem entry, so we only
@@ -576,11 +642,13 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data)
        available = qcom_smem_get_free_space(edge->remote_pid);
        if (available != edge->smem_available) {
                edge->smem_available = available;
-               kick_worker = true;
+               kick_scanner = true;
        }
 
-       if (kick_worker)
+       if (kick_scanner)
                schedule_work(&edge->scan_work);
+       if (kick_state)
+               schedule_work(&edge->state_work);
 
        return IRQ_HANDLED;
 }
@@ -665,7 +733,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
 {
        __le32 hdr[5] = { cpu_to_le32(len), };
        int tlen = sizeof(hdr) + len;
-       int ret, length;
+       int ret;
 
        /* Word aligned channels only accept word size aligned data */
        if (channel->info_word && len % 4)
@@ -675,13 +743,10 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
        if (tlen >= channel->fifo_size)
                return -EINVAL;
 
-       length = qcom_smd_get_tx_avail(channel);
-
        ret = mutex_lock_interruptible(&channel->tx_lock);
        if (ret)
                return ret;
 
-       length = qcom_smd_get_tx_avail(channel);
        while (qcom_smd_get_tx_avail(channel) < tlen) {
                if (channel->state != SMD_CHANNEL_OPENED) {
                        ret = -EPIPE;
@@ -701,7 +766,6 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
 
        SET_TX_CHANNEL_FLAG(channel, fTAIL, 0);
 
-       length = qcom_smd_get_tx_avail(channel);
        qcom_smd_write_fifo(channel, hdr, sizeof(hdr));
        qcom_smd_write_fifo(channel, data, len);
 
@@ -1000,9 +1064,10 @@ qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name)
 {
        struct qcom_smd_channel *channel;
        struct qcom_smd_channel *ret = NULL;
+       unsigned long flags;
        unsigned state;
 
-       read_lock(&edge->channels_lock);
+       spin_lock_irqsave(&edge->channels_lock, flags);
        list_for_each_entry(channel, &edge->channels, list) {
                if (strcmp(channel->name, name))
                        continue;
@@ -1015,7 +1080,7 @@ qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name)
                ret = channel;
                break;
        }
-       read_unlock(&edge->channels_lock);
+       spin_unlock_irqrestore(&edge->channels_lock, flags);
 
        return ret;
 }
@@ -1127,7 +1192,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
        /* The channel consist of a rx and tx fifo of equal size */
        fifo_size /= 2;
 
-       dev_err(smd->dev, "new channel '%s' info-size: %zu fifo-size: %zu\n",
+       dev_dbg(smd->dev, "new channel '%s' info-size: %zu fifo-size: %zu\n",
                          name, info_size, fifo_size);
 
        channel->tx_fifo = fifo_base;
@@ -1196,9 +1261,9 @@ static void qcom_channel_scan_worker(struct work_struct *work)
                        if (IS_ERR(channel))
                                continue;
 
-                       write_lock_irqsave(&edge->channels_lock, flags);
+                       spin_lock_irqsave(&edge->channels_lock, flags);
                        list_add(&channel->list, &edge->channels);
-                       write_unlock_irqrestore(&edge->channels_lock, flags);
+                       spin_unlock_irqrestore(&edge->channels_lock, flags);
 
                        dev_dbg(smd->dev, "new channel found: '%s'\n", channel->name);
                        set_bit(i, edge->allocated[tbl]);
@@ -1225,12 +1290,13 @@ static void qcom_channel_state_worker(struct work_struct *work)
                                                  struct qcom_smd_edge,
                                                  state_work);
        unsigned remote_state;
+       unsigned long flags;
 
        /*
         * Register a device for any closed channel where the remote processor
         * is showing interest in opening the channel.
         */
-       read_lock(&edge->channels_lock);
+       spin_lock_irqsave(&edge->channels_lock, flags);
        list_for_each_entry(channel, &edge->channels, list) {
                if (channel->state != SMD_CHANNEL_CLOSED)
                        continue;
@@ -1240,9 +1306,9 @@ static void qcom_channel_state_worker(struct work_struct *work)
                    remote_state != SMD_CHANNEL_OPENED)
                        continue;
 
-               read_unlock(&edge->channels_lock);
+               spin_unlock_irqrestore(&edge->channels_lock, flags);
                qcom_smd_create_device(channel);
-               read_lock(&edge->channels_lock);
+               spin_lock_irqsave(&edge->channels_lock, flags);
        }
 
        /*
@@ -1259,11 +1325,11 @@ static void qcom_channel_state_worker(struct work_struct *work)
                    remote_state == SMD_CHANNEL_OPENED)
                        continue;
 
-               read_unlock(&edge->channels_lock);
+               spin_unlock_irqrestore(&edge->channels_lock, flags);
                qcom_smd_destroy_device(channel);
-               read_lock(&edge->channels_lock);
+               spin_lock_irqsave(&edge->channels_lock, flags);
        }
-       read_unlock(&edge->channels_lock);
+       spin_unlock_irqrestore(&edge->channels_lock, flags);
 }
 
 /*
@@ -1279,7 +1345,7 @@ static int qcom_smd_parse_edge(struct device *dev,
        int ret;
 
        INIT_LIST_HEAD(&edge->channels);
-       rwlock_init(&edge->channels_lock);
+       spin_lock_init(&edge->channels_lock);
 
        INIT_WORK(&edge->scan_work, qcom_channel_scan_worker);
        INIT_WORK(&edge->state_work, qcom_channel_state_worker);
index 1df0341..cbb0f06 100644 (file)
@@ -5,72 +5,8 @@
 #include <linux/mod_devicetable.h>
 
 struct qcom_smd;
+struct qcom_smd_channel;
 struct qcom_smd_lookup;
-struct qcom_smd_device;
-
-/*
- * SMD channel states.
- */
-enum smd_channel_state {
-       SMD_CHANNEL_CLOSED,
-       SMD_CHANNEL_OPENING,
-       SMD_CHANNEL_OPENED,
-       SMD_CHANNEL_FLUSHING,
-       SMD_CHANNEL_CLOSING,
-       SMD_CHANNEL_RESET,
-       SMD_CHANNEL_RESET_OPENING
-};
-
-/**
- * struct qcom_smd_channel - smd channel struct
- * @edge:              qcom_smd_edge this channel is living on
- * @qsdev:             reference to a associated smd client device
- * @name:              name of the channel
- * @state:             local state of the channel
- * @remote_state:      remote state of the channel
- * @info:              byte aligned outgoing/incoming channel info
- * @info_word:         word aligned outgoing/incoming channel info
- * @tx_lock:           lock to make writes to the channel mutually exclusive
- * @fblockread_event:  wakeup event tied to tx fBLOCKREADINTR
- * @tx_fifo:           pointer to the outgoing ring buffer
- * @rx_fifo:           pointer to the incoming ring buffer
- * @fifo_size:         size of each ring buffer
- * @bounce_buffer:     bounce buffer for reading wrapped packets
- * @cb:                        callback function registered for this channel
- * @recv_lock:         guard for rx info modifications and cb pointer
- * @pkt_size:          size of the currently handled packet
- * @list:              lite entry for @channels in qcom_smd_edge
- */
-
-struct qcom_smd_channel {
-       struct qcom_smd_edge *edge;
-
-       struct qcom_smd_device *qsdev;
-
-       char *name;
-       enum smd_channel_state state;
-       enum smd_channel_state remote_state;
-
-       struct smd_channel_info_pair *info;
-       struct smd_channel_info_word_pair *info_word;
-
-       struct mutex tx_lock;
-       wait_queue_head_t fblockread_event;
-
-       void *tx_fifo;
-       void *rx_fifo;
-       int fifo_size;
-
-       void *bounce_buffer;
-       qcom_smd_cb_t cb;
-
-       spinlock_t recv_lock;
-
-       int pkt_size;
-
-       struct list_head list;
-       struct list_head dev_list;
-};
 
 /**
  * struct qcom_smd_id - struct used for matching a smd device
@@ -111,20 +47,68 @@ struct qcom_smd_driver {
        qcom_smd_cb_t callback;
 };
 
+#if IS_ENABLED(CONFIG_QCOM_SMD)
+
 int qcom_smd_driver_register(struct qcom_smd_driver *drv);
 void qcom_smd_driver_unregister(struct qcom_smd_driver *drv);
 
+struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *channel,
+                                              const char *name,
+                                              qcom_smd_cb_t cb);
 void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel);
 void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data);
+int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len);
+
+
+#else
+
+static inline int qcom_smd_driver_register(struct qcom_smd_driver *drv)
+{
+       return -ENXIO;
+}
+
+static inline void qcom_smd_driver_unregister(struct qcom_smd_driver *drv)
+{
+       /* This shouldn't be possible */
+       WARN_ON(1);
+}
+
+static inline struct qcom_smd_channel *
+qcom_smd_open_channel(struct qcom_smd_channel *channel,
+                     const char *name,
+                     qcom_smd_cb_t cb)
+{
+       /* This shouldn't be possible */
+       WARN_ON(1);
+       return NULL;
+}
+
+void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel)
+{
+       /* This shouldn't be possible */
+       WARN_ON(1);
+       return NULL;
+}
+
+void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data)
+{
+       /* This shouldn't be possible */
+       WARN_ON(1);
+}
+
+static inline int qcom_smd_send(struct qcom_smd_channel *channel,
+                               const void *data, int len)
+{
+       /* This shouldn't be possible */
+       WARN_ON(1);
+       return -ENXIO;
+}
+
+#endif
 
 #define module_qcom_smd_driver(__smd_driver) \
        module_driver(__smd_driver, qcom_smd_driver_register, \
                      qcom_smd_driver_unregister)
 
-int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len);
-
-struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *channel,
-                                              const char *name,
-                                              qcom_smd_cb_t cb);
 
 #endif