Skip to content

Commit

Permalink
soc: qcom: smd: Transition client drivers from smd to rpmsg
Browse files Browse the repository at this point in the history
By moving these client drivers to use RPMSG instead of the direct SMD
API we can reuse them ontop of the newly added GLINK wire-protocol
support found in the 820 and 835 Qualcomm platforms.

As the new (RPMSG-based) and old SMD implementations are mutually
exclusive we have to change all client drivers in one commit, to make
sure we have a working system before and after this transition.

Acked-by: Andy Gross <andy.gross@linaro.org>
Acked-by: Kalle Valo <kvalo@codeaurora.org>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Bjorn Andersson authored and David S. Miller committed Mar 29, 2017
1 parent def499c commit 5052de8
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 104 deletions.
2 changes: 1 addition & 1 deletion drivers/bluetooth/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ config BT_WILINK

config BT_QCOMSMD
tristate "Qualcomm SMD based HCI support"
depends on QCOM_SMD || (COMPILE_TEST && QCOM_SMD=n)
depends on RPMSG || (COMPILE_TEST && RPMSG=n)
depends on QCOM_WCNSS_CTRL || (COMPILE_TEST && QCOM_WCNSS_CTRL=n)
select BT_QCA
help
Expand Down
32 changes: 16 additions & 16 deletions drivers/bluetooth/btqcomsmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/soc/qcom/smd.h>
#include <linux/rpmsg.h>
#include <linux/soc/qcom/wcnss_ctrl.h>
#include <linux/platform_device.h>

Expand All @@ -26,8 +26,8 @@
struct btqcomsmd {
struct hci_dev *hdev;

struct qcom_smd_channel *acl_channel;
struct qcom_smd_channel *cmd_channel;
struct rpmsg_endpoint *acl_channel;
struct rpmsg_endpoint *cmd_channel;
};

static int btqcomsmd_recv(struct hci_dev *hdev, unsigned int type,
Expand All @@ -48,19 +48,19 @@ static int btqcomsmd_recv(struct hci_dev *hdev, unsigned int type,
return hci_recv_frame(hdev, skb);
}

static int btqcomsmd_acl_callback(struct qcom_smd_channel *channel,
const void *data, size_t count)
static int btqcomsmd_acl_callback(struct rpmsg_device *rpdev, void *data,
int count, void *priv, u32 addr)
{
struct btqcomsmd *btq = qcom_smd_get_drvdata(channel);
struct btqcomsmd *btq = priv;

btq->hdev->stat.byte_rx += count;
return btqcomsmd_recv(btq->hdev, HCI_ACLDATA_PKT, data, count);
}

static int btqcomsmd_cmd_callback(struct qcom_smd_channel *channel,
const void *data, size_t count)
static int btqcomsmd_cmd_callback(struct rpmsg_device *rpdev, void *data,
int count, void *priv, u32 addr)
{
struct btqcomsmd *btq = qcom_smd_get_drvdata(channel);
struct btqcomsmd *btq = priv;

return btqcomsmd_recv(btq->hdev, HCI_EVENT_PKT, data, count);
}
Expand All @@ -72,12 +72,12 @@ static int btqcomsmd_send(struct hci_dev *hdev, struct sk_buff *skb)

switch (hci_skb_pkt_type(skb)) {
case HCI_ACLDATA_PKT:
ret = qcom_smd_send(btq->acl_channel, skb->data, skb->len);
ret = rpmsg_send(btq->acl_channel, skb->data, skb->len);
hdev->stat.acl_tx++;
hdev->stat.byte_tx += skb->len;
break;
case HCI_COMMAND_PKT:
ret = qcom_smd_send(btq->cmd_channel, skb->data, skb->len);
ret = rpmsg_send(btq->cmd_channel, skb->data, skb->len);
hdev->stat.cmd_tx++;
break;
default:
Expand Down Expand Up @@ -114,18 +114,15 @@ static int btqcomsmd_probe(struct platform_device *pdev)
wcnss = dev_get_drvdata(pdev->dev.parent);

btq->acl_channel = qcom_wcnss_open_channel(wcnss, "APPS_RIVA_BT_ACL",
btqcomsmd_acl_callback);
btqcomsmd_acl_callback, btq);
if (IS_ERR(btq->acl_channel))
return PTR_ERR(btq->acl_channel);

btq->cmd_channel = qcom_wcnss_open_channel(wcnss, "APPS_RIVA_BT_CMD",
btqcomsmd_cmd_callback);
btqcomsmd_cmd_callback, btq);
if (IS_ERR(btq->cmd_channel))
return PTR_ERR(btq->cmd_channel);

qcom_smd_set_drvdata(btq->acl_channel, btq);
qcom_smd_set_drvdata(btq->cmd_channel, btq);

hdev = hci_alloc_dev();
if (!hdev)
return -ENOMEM;
Expand Down Expand Up @@ -158,6 +155,9 @@ static int btqcomsmd_remove(struct platform_device *pdev)
hci_unregister_dev(btq->hdev);
hci_free_dev(btq->hdev);

rpmsg_destroy_ept(btq->cmd_channel);
rpmsg_destroy_ept(btq->acl_channel);

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/wcn36xx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ config WCN36XX
tristate "Qualcomm Atheros WCN3660/3680 support"
depends on MAC80211 && HAS_DMA
depends on QCOM_WCNSS_CTRL || QCOM_WCNSS_CTRL=n
depends on QCOM_SMD || QCOM_SMD=n
depends on RPMSG || RPMSG=n
---help---
This module adds support for wireless adapters based on
Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets.
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/ath/wcn36xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/soc/qcom/smd.h>
#include <linux/rpmsg.h>
#include <linux/soc/qcom/smem_state.h>
#include <linux/soc/qcom/wcnss_ctrl.h>
#include "wcn36xx.h"
Expand Down Expand Up @@ -1218,15 +1218,13 @@ static int wcn36xx_probe(struct platform_device *pdev)

INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);

wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process);
wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw);
if (IS_ERR(wcn->smd_channel)) {
wcn36xx_err("failed to open WLAN_CTRL channel\n");
ret = PTR_ERR(wcn->smd_channel);
goto out_wq;
}

qcom_smd_set_drvdata(wcn->smd_channel, hw);

addr = of_get_property(pdev->dev.of_node, "local-mac-address", &ret);
if (addr && ret != ETH_ALEN) {
wcn36xx_err("invalid local-mac-address\n");
Expand Down
10 changes: 5 additions & 5 deletions drivers/net/wireless/ath/wcn36xx/smd.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <linux/bitops.h>
#include <linux/soc/qcom/smd.h>
#include <linux/rpmsg.h>
#include "smd.h"

struct wcn36xx_cfg_val {
Expand Down Expand Up @@ -254,7 +254,7 @@ static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len)

init_completion(&wcn->hal_rsp_compl);
start = jiffies;
ret = qcom_smd_send(wcn->smd_channel, wcn->hal_buf, len);
ret = rpmsg_send(wcn->smd_channel, wcn->hal_buf, len);
if (ret) {
wcn36xx_err("HAL TX failed\n");
goto out;
Expand Down Expand Up @@ -2205,11 +2205,11 @@ int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn,
return ret;
}

int wcn36xx_smd_rsp_process(struct qcom_smd_channel *channel,
const void *buf, size_t len)
int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
void *buf, int len, void *priv, u32 addr)
{
const struct wcn36xx_hal_msg_header *msg_header = buf;
struct ieee80211_hw *hw = qcom_smd_get_drvdata(channel);
struct ieee80211_hw *hw = priv;
struct wcn36xx *wcn = hw->priv;
struct wcn36xx_hal_ind_msg *msg_ind;
wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "SMD <<< ", buf, len);
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/wireless/ath/wcn36xx/smd.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct wcn36xx_hal_ind_msg {
};

struct wcn36xx;
struct qcom_smd_channel;
struct rpmsg_device;

int wcn36xx_smd_open(struct wcn36xx *wcn);
void wcn36xx_smd_close(struct wcn36xx *wcn);
Expand Down Expand Up @@ -129,8 +129,8 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index);

int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value);

int wcn36xx_smd_rsp_process(struct qcom_smd_channel *channel,
const void *buf, size_t len);
int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
void *buf, int len, void *priv, u32 addr);

int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn,
struct ieee80211_vif *vif,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/wcn36xx/wcn36xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ struct wcn36xx {
void __iomem *ccu_base;
void __iomem *dxe_base;

struct qcom_smd_channel *smd_channel;
struct rpmsg_endpoint *smd_channel;

struct qcom_smem_state *tx_enable_state;
unsigned tx_enable_state_bit;
Expand Down
6 changes: 4 additions & 2 deletions drivers/soc/qcom/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ config QCOM_SMD

config QCOM_SMD_RPM
tristate "Qualcomm Resource Power Manager (RPM) over SMD"
depends on QCOM_SMD && OF
depends on ARCH_QCOM
depends on RPMSG && OF
help
If you say yes to this option, support will be included for the
Resource Power Manager system found in the Qualcomm 8974 based
Expand Down Expand Up @@ -76,7 +77,8 @@ config QCOM_SMSM

config QCOM_WCNSS_CTRL
tristate "Qualcomm WCNSS control driver"
depends on QCOM_SMD
depends on ARCH_QCOM
depends on RPMSG
help
Client driver for the WCNSS_CTRL SMD channel, used to download nv
firmware to a newly booted WCNSS chip.
43 changes: 21 additions & 22 deletions drivers/soc/qcom/smd-rpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <linux/interrupt.h>
#include <linux/slab.h>

#include <linux/soc/qcom/smd.h>
#include <linux/rpmsg.h>
#include <linux/soc/qcom/smd-rpm.h>

#define RPM_REQUEST_TIMEOUT (5 * HZ)
Expand All @@ -32,7 +32,7 @@
* @ack_status: result of the rpm request
*/
struct qcom_smd_rpm {
struct qcom_smd_channel *rpm_channel;
struct rpmsg_endpoint *rpm_channel;
struct device *dev;

struct completion ack;
Expand Down Expand Up @@ -133,7 +133,7 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
pkt->req.data_len = cpu_to_le32(count);
memcpy(pkt->payload, buf, count);

ret = qcom_smd_send(rpm->rpm_channel, pkt, size);
ret = rpmsg_send(rpm->rpm_channel, pkt, size);
if (ret)
goto out;

Expand All @@ -150,14 +150,16 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
}
EXPORT_SYMBOL(qcom_rpm_smd_write);

static int qcom_smd_rpm_callback(struct qcom_smd_channel *channel,
const void *data,
size_t count)
static int qcom_smd_rpm_callback(struct rpmsg_device *rpdev,
void *data,
int count,
void *priv,
u32 addr)
{
const struct qcom_rpm_header *hdr = data;
size_t hdr_length = le32_to_cpu(hdr->length);
const struct qcom_rpm_message *msg;
struct qcom_smd_rpm *rpm = qcom_smd_get_drvdata(channel);
struct qcom_smd_rpm *rpm = dev_get_drvdata(&rpdev->dev);
const u8 *buf = data + sizeof(struct qcom_rpm_header);
const u8 *end = buf + hdr_length;
char msgbuf[32];
Expand Down Expand Up @@ -196,29 +198,27 @@ static int qcom_smd_rpm_callback(struct qcom_smd_channel *channel,
return 0;
}

static int qcom_smd_rpm_probe(struct qcom_smd_device *sdev)
static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev)
{
struct qcom_smd_rpm *rpm;

rpm = devm_kzalloc(&sdev->dev, sizeof(*rpm), GFP_KERNEL);
rpm = devm_kzalloc(&rpdev->dev, sizeof(*rpm), GFP_KERNEL);
if (!rpm)
return -ENOMEM;

mutex_init(&rpm->lock);
init_completion(&rpm->ack);

rpm->dev = &sdev->dev;
rpm->rpm_channel = sdev->channel;
qcom_smd_set_drvdata(sdev->channel, rpm);
rpm->dev = &rpdev->dev;
rpm->rpm_channel = rpdev->ept;
dev_set_drvdata(&rpdev->dev, rpm);

dev_set_drvdata(&sdev->dev, rpm);

return of_platform_populate(sdev->dev.of_node, NULL, NULL, &sdev->dev);
return of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev);
}

static void qcom_smd_rpm_remove(struct qcom_smd_device *sdev)
static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev)
{
of_platform_depopulate(&sdev->dev);
of_platform_depopulate(&rpdev->dev);
}

static const struct of_device_id qcom_smd_rpm_of_match[] = {
Expand All @@ -229,26 +229,25 @@ static const struct of_device_id qcom_smd_rpm_of_match[] = {
};
MODULE_DEVICE_TABLE(of, qcom_smd_rpm_of_match);

static struct qcom_smd_driver qcom_smd_rpm_driver = {
static struct rpmsg_driver qcom_smd_rpm_driver = {
.probe = qcom_smd_rpm_probe,
.remove = qcom_smd_rpm_remove,
.callback = qcom_smd_rpm_callback,
.driver = {
.drv = {
.name = "qcom_smd_rpm",
.owner = THIS_MODULE,
.of_match_table = qcom_smd_rpm_of_match,
},
};

static int __init qcom_smd_rpm_init(void)
{
return qcom_smd_driver_register(&qcom_smd_rpm_driver);
return register_rpmsg_driver(&qcom_smd_rpm_driver);
}
arch_initcall(qcom_smd_rpm_init);

static void __exit qcom_smd_rpm_exit(void)
{
qcom_smd_driver_unregister(&qcom_smd_rpm_driver);
unregister_rpmsg_driver(&qcom_smd_rpm_driver);
}
module_exit(qcom_smd_rpm_exit);

Expand Down
Loading

0 comments on commit 5052de8

Please sign in to comment.