Skip to content

Commit

Permalink
Merge tag 'qcom-drivers-for-6.10-2' of https://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/qcom/linux into soc/drivers

A few more Qualcomm driver updates for v6.10

This fixes a sleep-while-atomic issue in pmic_glink, stemming from the
fact that the GLINK callback comes from interrupt context.

It fixes the Bluetooth address in the example of qcom,wcnss, and it
enables UEFI variables on SC8180X devices (Primus and Flex 5G).

* tag 'qcom-drivers-for-6.10-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux:
  firmware: qcom: uefisecapp: Allow on sc8180x Primus and Flex 5G
  soc: qcom: pmic_glink: Make client-lock non-sleeping
  dt-bindings: soc: qcom,wcnss: fix bluetooth address example

Link: https://lore.kernel.org/r/20240508020900.204413-1-andersson@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
  • Loading branch information
Arnd Bergmann committed May 8, 2024
2 parents a3116c8 + 4b34d4c commit 1c97fe3
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 12 deletions.
4 changes: 2 additions & 2 deletions Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ examples:
bluetooth {
compatible = "qcom,wcnss-bt";
/* BD address 00:11:22:33:44:55 */
local-bd-address = [ 55 44 33 22 11 00 ];
/* Updated by boot firmware (little-endian order) */
local-bd-address = [ 00 00 00 00 00 00 ];
};
wifi {
Expand Down
2 changes: 2 additions & 0 deletions drivers/firmware/qcom/qcom_scm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1671,7 +1671,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send);
+ any potential issues with this, only allow validated machines for now.
*/
static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
{ .compatible = "lenovo,flex-5g" },
{ .compatible = "lenovo,thinkpad-x13s", },
{ .compatible = "qcom,sc8180x-primus" },
{ }
};

Expand Down
25 changes: 15 additions & 10 deletions drivers/soc/qcom/pmic_glink.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/slab.h>
#include <linux/soc/qcom/pdr.h>
#include <linux/soc/qcom/pmic_glink.h>
#include <linux/spinlock.h>

enum {
PMIC_GLINK_CLIENT_BATT = 0,
Expand All @@ -36,7 +37,7 @@ struct pmic_glink {
unsigned int pdr_state;

/* serializing clients list updates */
struct mutex client_lock;
spinlock_t client_lock;
struct list_head clients;
};

Expand All @@ -58,10 +59,11 @@ static void _devm_pmic_glink_release_client(struct device *dev, void *res)
{
struct pmic_glink_client *client = (struct pmic_glink_client *)res;
struct pmic_glink *pg = client->pg;
unsigned long flags;

mutex_lock(&pg->client_lock);
spin_lock_irqsave(&pg->client_lock, flags);
list_del(&client->node);
mutex_unlock(&pg->client_lock);
spin_unlock_irqrestore(&pg->client_lock, flags);
}

struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
Expand All @@ -72,6 +74,7 @@ struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
{
struct pmic_glink_client *client;
struct pmic_glink *pg = dev_get_drvdata(dev->parent);
unsigned long flags;

client = devres_alloc(_devm_pmic_glink_release_client, sizeof(*client), GFP_KERNEL);
if (!client)
Expand All @@ -84,12 +87,12 @@ struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
client->priv = priv;

mutex_lock(&pg->state_lock);
mutex_lock(&pg->client_lock);
spin_lock_irqsave(&pg->client_lock, flags);

list_add(&client->node, &pg->clients);
client->pdr_notify(client->priv, pg->client_state);

mutex_unlock(&pg->client_lock);
spin_unlock_irqrestore(&pg->client_lock, flags);
mutex_unlock(&pg->state_lock);

devres_add(dev, client);
Expand All @@ -112,6 +115,7 @@ static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
struct pmic_glink_client *client;
struct pmic_glink_hdr *hdr;
struct pmic_glink *pg = dev_get_drvdata(&rpdev->dev);
unsigned long flags;

if (len < sizeof(*hdr)) {
dev_warn(pg->dev, "ignoring truncated message\n");
Expand All @@ -120,12 +124,12 @@ static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data,

hdr = data;

mutex_lock(&pg->client_lock);
spin_lock_irqsave(&pg->client_lock, flags);
list_for_each_entry(client, &pg->clients, node) {
if (client->id == le32_to_cpu(hdr->owner))
client->cb(data, len, client->priv);
}
mutex_unlock(&pg->client_lock);
spin_unlock_irqrestore(&pg->client_lock, flags);

return 0;
}
Expand Down Expand Up @@ -165,6 +169,7 @@ static void pmic_glink_state_notify_clients(struct pmic_glink *pg)
{
struct pmic_glink_client *client;
unsigned int new_state = pg->client_state;
unsigned long flags;

if (pg->client_state != SERVREG_SERVICE_STATE_UP) {
if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept)
Expand All @@ -175,10 +180,10 @@ static void pmic_glink_state_notify_clients(struct pmic_glink *pg)
}

if (new_state != pg->client_state) {
mutex_lock(&pg->client_lock);
spin_lock_irqsave(&pg->client_lock, flags);
list_for_each_entry(client, &pg->clients, node)
client->pdr_notify(client->priv, new_state);
mutex_unlock(&pg->client_lock);
spin_unlock_irqrestore(&pg->client_lock, flags);
pg->client_state = new_state;
}
}
Expand Down Expand Up @@ -265,7 +270,7 @@ static int pmic_glink_probe(struct platform_device *pdev)
pg->dev = &pdev->dev;

INIT_LIST_HEAD(&pg->clients);
mutex_init(&pg->client_lock);
spin_lock_init(&pg->client_lock);
mutex_init(&pg->state_lock);

match_data = (unsigned long *)of_device_get_match_data(&pdev->dev);
Expand Down

0 comments on commit 1c97fe3

Please sign in to comment.