More Qualcomm driver updates for 6.3

The qcom_scm.h file is moved into firmware/qcom, to avoid having any
 Qualcomm-specific files directly in include/linux.
 
 Support for PMIC GLINK is introduced, which on newer Qualcomm platforms
 provides an interface to the firmware implementing battery management
 and USB Type-C handling. Together with the base driver comes the custom
 altmode support driver.
 
 SMD RPM gains support for IPQ9574, and socinfo is extended with support
 for revision 17 of the information format and soc_id for IPQ5332 and
 IPQ8064 are added.
 
 The qcom_stats  is changes not to fail when not all parts are
 initialized.
 -----BEGIN PGP SIGNATURE-----
 
 iQJJBAABCAAzFiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmPmiz4VHGFuZGVyc3Nv
 bkBrZXJuZWwub3JnAAoJEAsfOT8Nma3FMZ8QANXJEr7U2KX/yd4riBju6Btn0unl
 I8TR5XlaQAoBUbyp4yTcCUfCe0mEiNcE/YgJwzSKY3mNxc9vLhn1GgqdF+5RFTZw
 0H8GBjUpQiRoCC2+pq3YCEisQ49HYXy9W3ys6t1Y3l8xUDLhw5CkeKOGQCqeBDX7
 pCflPy7HFUQwPhGt7AOmpNj8+Kh4GnpJHF3D2ShAMFNOn4+l0v8Gh7zDw62FmhBg
 gjA7eS2aZS7KmqEJMAC4dEFdmhvvN+a80KaWNOOQn2sdLtD64pRW2hknxinPRN+t
 dGQKeD+VGFHLfxWO40Lv0nP8P/EWjXiZdhO8HXLmVjHC56G/MG8AW0BkvxW9jPAa
 QGlzY0TbEbi0MbbAnyCJTy6USGtVUZbEmfcZ8r3rUJX5xO8eszSjueD6fH/nKIgo
 hDIIG8nSLf5TCY+NJzGr8dKENiElsgsfdNAypoX6kpXCRUCXxkiKlWzy/3oywVcO
 bKm5xs76YNNaANFf46oO6kts7nrOcegyTAdvauFemy1Q3KSWQuFP4jNpcRvWnVMN
 8/BlQ+a5uGofN/wwHS2CPmE1r8njEqlPc7wWNc0ugoRO4kAUtB2UldjjS/ZfaFvH
 BZiDDXhjScPj8lKk4kzGOb34W5AKkwFbTwSR1oN0ckW9UNDx51pNu72YlU8WLydV
 VHmzD9ndTkWSmp7W
 =+KgT
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmPqVbkACgkQmmx57+YA
 GNnlFRAAuaoe9/7kOAliVks4vkJ8284POk50kuS5llzNAP4BPsQIJakE6dOOiTY1
 01qbvTlu5pK+f2ls+3WQYr5Rhgck4BUEFD+t9WcPtOpB1uq0puyWj3fwuErjDFJv
 S6nKp2P0tpru5VzQFPROyrBCw5Zlkc0U9FID4P1Ub5ulxxDWJ4ODb9Q+C9DtDxJo
 HuUGRnGPLmAJd4ymKzCtnqcg3gocFdrl9K+msFuJwAgdZ0xB893l3wyOFn2k97Uh
 8m8WEI/NbCTfDEjag3+yx9Sl3rZhtav0EnlIqowBHQFvxFaBDnvW6H4QmNRugAog
 +kH1hVzojj35jDllwL07OJzdjqW497Z9i+MEGz45h/8FvvdqJ+71UTkOwr+vnWKu
 zuEzEfM+bB434UBCQihJ7emx7eCac3TP3Von/NigDDBIXDu8iqNgUNmB8eNyN+gJ
 Db1mdatG4TuSEqnzetX4XKLP3eydxG8lkEZDOcWlhRz8CSWx9KkBU7W+hVNCBLdV
 kdhjvZpb5cRcqc/KsS22hmB3HIoISGkLrBOvqs375+Sg9PFxBGst+q24kf9MEDFz
 ypj/CRiMzkNq8IBwGF003CVhDHmlloq2afQ7YX0w1sEE0XOCIDE0YWNNb9fcoTAC
 MeDL9R4VgfjR/8Bj7zgnYOMAt6hRoHXsZ1gtS29doIH5iLdTXVI=
 =8eLr
 -----END PGP SIGNATURE-----

Merge tag 'qcom-drivers-for-6.3-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers

More Qualcomm driver updates for 6.3

The qcom_scm.h file is moved into firmware/qcom, to avoid having any
Qualcomm-specific files directly in include/linux.

Support for PMIC GLINK is introduced, which on newer Qualcomm platforms
provides an interface to the firmware implementing battery management
and USB Type-C handling. Together with the base driver comes the custom
altmode support driver.

SMD RPM gains support for IPQ9574, and socinfo is extended with support
for revision 17 of the information format and soc_id for IPQ5332 and
IPQ8064 are added.

The qcom_stats  is changes not to fail when not all parts are
initialized.

* tag 'qcom-drivers-for-6.3-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux:
  soc: qcom: socinfo: Add IDs for IPQ5332 and its variant
  dt-bindings: arm: qcom,ids: Add IDs for IPQ5332 and its variant
  dt-bindings: power: qcom,rpmpd: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1
  firmware: qcom_scm: Move qcom_scm.h to include/linux/firmware/qcom/
  MAINTAINERS: Update qcom CPR maintainer entry
  dt-bindings: firmware: document Qualcomm SM8550 SCM
  dt-bindings: firmware: qcom,scm: add qcom,scm-sa8775p compatible
  soc: qcom: socinfo: Add Soc IDs for IPQ8064 and variants
  dt-bindings: arm: qcom,ids: Add Soc IDs for IPQ8064 and variants
  soc: qcom: socinfo: Add support for new field in revision 17
  soc: qcom: smd-rpm: Add IPQ9574 compatible
  soc: qcom: pmic_glink: remove redundant calculation of svid
  soc: qcom: stats: Populate all subsystem debugfs files
  dt-bindings: soc: qcom,rpmh-rsc: Update to allow for generic nodes
  soc: qcom: pmic_glink: add CONFIG_NET/CONFIG_OF dependencies
  soc: qcom: pmic_glink: Introduce altmode support
  soc: qcom: pmic_glink: Introduce base PMIC GLINK driver
  dt-bindings: soc: qcom: Introduce PMIC GLINK binding
  soc: qcom: dcc: Drop driver for now

Link: https://lore.kernel.org/r/20230210182242.2023901-1-andersson@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2023-02-13 16:22:32 +01:00
Родитель 01e9d2c6be b0bc8c893a
Коммит 68907175ec
41 изменённых файлов: 1022 добавлений и 1352 удалений

Просмотреть файл

@ -39,6 +39,7 @@ properties:
- qcom,scm-msm8996
- qcom,scm-msm8998
- qcom,scm-qdu1000
- qcom,scm-sa8775p
- qcom,scm-sc7180
- qcom,scm-sc7280
- qcom,scm-sc8280xp
@ -54,6 +55,7 @@ properties:
- qcom,scm-sm8250
- qcom,scm-sm8350
- qcom,scm-sm8450
- qcom,scm-sm8550
- qcom,scm-qcs404
- const: qcom,scm
@ -165,6 +167,7 @@ allOf:
contains:
enum:
- qcom,scm-sm8450
- qcom,scm-sm8550
then:
properties:
interconnects: false
@ -177,6 +180,7 @@ allOf:
contains:
enum:
- qcom,scm-sm8450
- qcom,scm-sm8550
then:
properties:
interrupts: false

Просмотреть файл

@ -0,0 +1,95 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/qcom/qcom,pmic-glink.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm PMIC GLINK firmware interface for battery management, USB
Type-C and other things.
maintainers:
- Bjorn Andersson <andersson@kernel.org>
description:
The PMIC GLINK service, running on a coprocessor on some modern Qualcomm
platforms and implement USB Type-C handling and battery management. This
binding describes the component in the OS used to communicate with the
firmware and connect it's resources to those described in the Devicetree,
particularly the USB Type-C controllers relationship with USB and DisplayPort
components.
properties:
compatible:
items:
- enum:
- qcom,sc8180x-pmic-glink
- qcom,sc8280xp-pmic-glink
- qcom,sm8350-pmic-glink
- const: qcom,pmic-glink
'#address-cells':
const: 1
'#size-cells':
const: 0
patternProperties:
'^connector@\d$':
$ref: /schemas/connector/usb-connector.yaml#
properties:
reg: true
required:
- reg
unevaluatedProperties: false
required:
- compatible
additionalProperties: false
examples:
- |+
pmic-glink {
compatible = "qcom,sc8280xp-pmic-glink", "qcom,pmic-glink";
#address-cells = <1>;
#size-cells = <0>;
connector@0 {
compatible = "usb-c-connector";
reg = <0>;
power-role = "dual";
data-role = "dual";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
endpoint {
remote-endpoint = <&usb_role>;
};
};
port@1 {
reg = <1>;
endpoint {
remote-endpoint = <&ss_phy_out>;
};
};
port@2 {
reg = <2>;
endpoint {
remote-endpoint = <&sbu_mux>;
};
};
};
};
};
...

Просмотреть файл

@ -112,8 +112,9 @@ properties:
$ref: /schemas/power/qcom,rpmpd.yaml#
patternProperties:
'-regulators$':
'^regulators(-[0-9])?$':
$ref: /schemas/regulator/qcom,rpmh-regulator.yaml#
unevaluatedProperties: false
required:
- compatible

Просмотреть файл

@ -5821,14 +5821,6 @@ W: http://lists.twibble.org/mailman/listinfo/dc395x/
F: Documentation/scsi/dc395x.rst
F: drivers/scsi/dc395x.*
DCC QTI DRIVER
M: Souradeep Chowdhury <quic_schowdhu@quicinc.com>
L: linux-arm-msm@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/debugfs-driver-dcc
F: Documentation/devicetree/bindings/soc/qcom/qcom,dcc.yaml
F: drivers/soc/qcom/dcc.c
DCCP PROTOCOL
L: dccp@vger.kernel.org
S: Orphan
@ -17263,7 +17255,8 @@ F: drivers/clk/qcom/
F: include/dt-bindings/clock/qcom,*
QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER
M: Niklas Cassel <nks@flawful.org>
M: Bjorn Andersson <andersson@kernel.org>
M: Konrad Dybcio <konrad.dybcio@linaro.org>
L: linux-pm@vger.kernel.org
L: linux-arm-msm@vger.kernel.org
S: Maintained

Просмотреть файл

@ -14,7 +14,7 @@
#include <linux/of_address.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <asm/smp_plat.h>

Просмотреть файл

@ -17,7 +17,7 @@
#include <linux/platform_device.h>
#include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <soc/qcom/spm.h>
#include <asm/proc-fns.h>

Просмотреть файл

@ -9,7 +9,7 @@
#include <linux/mutex.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/arm-smccc.h>
#include <linux/dma-mapping.h>

Просмотреть файл

@ -8,7 +8,7 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/arm-smccc.h>
#include <linux/dma-mapping.h>

Просмотреть файл

@ -12,7 +12,7 @@
#include <linux/interconnect.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

Просмотреть файл

@ -5,7 +5,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/cpumask.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/pm_opp.h>
#include <linux/nvmem-consumer.h>
#include <linux/slab.h>

Просмотреть файл

@ -8,7 +8,7 @@
#include <linux/ascii85.h>
#include <linux/interconnect.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/kernel.h>
#include <linux/of_address.h>
#include <linux/pm_opp.h>

Просмотреть файл

@ -3,7 +3,7 @@
*/
#include "hdmi.h"
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#define HDCP_REG_ENABLE 0x01
#define HDCP_REG_DISABLE 0x00

Просмотреть файл

@ -4,7 +4,7 @@
*/
#include <linux/of_device.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/ratelimit.h>
#include "arm-smmu.h"

Просмотреть файл

@ -7,7 +7,7 @@
#include <linux/adreno-smmu-priv.h>
#include <linux/delay.h>
#include <linux/of_device.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include "arm-smmu.h"
#include "arm-smmu-qcom.h"

Просмотреть файл

@ -27,7 +27,7 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

Просмотреть файл

@ -12,7 +12,7 @@
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/sizes.h>
#include <linux/soc/qcom/mdt_loader.h>

Просмотреть файл

@ -18,7 +18,7 @@
#include <linux/rpmsg.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <uapi/misc/fastrpc.h>
#include <linux/of_reserved_mem.h>

Просмотреть файл

@ -13,7 +13,7 @@
#include <linux/pm_opp.h>
#include <linux/slab.h>
#include <linux/iopoll.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/regulator/consumer.h>
#include <linux/interconnect.h>
#include <linux/pinctrl/consumer.h>

Просмотреть файл

@ -16,7 +16,7 @@
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/pm_runtime.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/soc/qcom/mdt_loader.h>
#include "ipa.h"

Просмотреть файл

@ -13,7 +13,7 @@
#include <linux/module.h>
#include <linux/net.h>
#include <linux/platform_device.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/soc/qcom/smem.h>
#include <linux/string.h>
#include <net/sock.h>

Просмотреть файл

@ -14,7 +14,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/reboot.h>
#include <linux/seq_file.h>
#include <linux/slab.h>

Просмотреть файл

@ -34,7 +34,7 @@
#include "qcom_pil_info.h"
#include "qcom_q6v5.h"
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#define MPSS_CRASH_REASON_SMEM 421

Просмотреть файл

@ -18,7 +18,7 @@
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/regulator/consumer.h>
#include <linux/remoteproc.h>
#include <linux/soc/qcom/mdt_loader.h>

Просмотреть файл

@ -19,7 +19,7 @@
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/regulator/consumer.h>
#include <linux/remoteproc.h>
#include <linux/soc/qcom/mdt_loader.h>

Просмотреть файл

@ -70,14 +70,6 @@ config QCOM_LLCC
SDM845. This provides interfaces to clients that use the LLCC.
Say yes here to enable LLCC slice driver.
config QCOM_DCC
tristate "Qualcomm Technologies, Inc. Data Capture and Compare(DCC) engine driver"
depends on ARCH_QCOM || COMPILE_TEST
help
This option enables driver for Data Capture and Compare engine. DCC
driver provides interface to configure DCC block and read back
captured data from DCC's internal SRAM.
config QCOM_KRYO_L2_ACCESSORS
bool
depends on ARCH_QCOM && ARM64 || COMPILE_TEST
@ -99,6 +91,24 @@ config QCOM_OCMEM
config QCOM_PDR_HELPERS
tristate
select QCOM_QMI_HELPERS
depends on NET
config QCOM_PMIC_GLINK
tristate "Qualcomm PMIC GLINK driver"
depends on RPMSG
depends on TYPEC
depends on DRM
depends on NET
depends on OF
select AUXILIARY_BUS
select QCOM_PDR_HELPERS
help
The Qualcomm PMIC GLINK driver provides access, over GLINK, to the
USB and battery firmware running on one of the coprocessors in
several modern Qualcomm platforms.
Say yes here to support USB-C and battery status on modern Qualcomm
platforms.
config QCOM_QMI_HELPERS
tristate

Просмотреть файл

@ -4,11 +4,12 @@ obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
obj-$(CONFIG_QCOM_CPR) += cpr.o
obj-$(CONFIG_QCOM_DCC) += dcc.o
obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
obj-$(CONFIG_QCOM_OCMEM) += ocmem.o
obj-$(CONFIG_QCOM_PDR_HELPERS) += pdr_interface.o
obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink.o
obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink_altmode.o
obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
qmi_helpers-y += qmi_encdec.o qmi_interface.o
obj-$(CONFIG_QCOM_RAMP_CTRL) += ramp_controller.o

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -12,7 +12,7 @@
#include <linux/firmware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/soc/qcom/mdt_loader.h>

Просмотреть файл

@ -16,7 +16,7 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/types.h>

Просмотреть файл

@ -0,0 +1,336 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Linaro Ltd
*/
#include <linux/auxiliary_bus.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rpmsg.h>
#include <linux/slab.h>
#include <linux/soc/qcom/pdr.h>
#include <linux/soc/qcom/pmic_glink.h>
struct pmic_glink {
struct device *dev;
struct pdr_handle *pdr;
struct rpmsg_endpoint *ept;
struct auxiliary_device altmode_aux;
struct auxiliary_device ps_aux;
struct auxiliary_device ucsi_aux;
/* serializing client_state and pdr_state updates */
struct mutex state_lock;
unsigned int client_state;
unsigned int pdr_state;
/* serializing clients list updates */
struct mutex client_lock;
struct list_head clients;
};
static struct pmic_glink *__pmic_glink;
static DEFINE_MUTEX(__pmic_glink_lock);
struct pmic_glink_client {
struct list_head node;
struct pmic_glink *pg;
unsigned int id;
void (*cb)(const void *data, size_t len, void *priv);
void (*pdr_notify)(void *priv, int state);
void *priv;
};
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;
mutex_lock(&pg->client_lock);
list_del(&client->node);
mutex_unlock(&pg->client_lock);
}
struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
unsigned int id,
void (*cb)(const void *, size_t, void *),
void (*pdr)(void *, int),
void *priv)
{
struct pmic_glink_client *client;
struct pmic_glink *pg = dev_get_drvdata(dev->parent);
client = devres_alloc(_devm_pmic_glink_release_client, sizeof(*client), GFP_KERNEL);
if (!client)
return ERR_PTR(-ENOMEM);
client->pg = pg;
client->id = id;
client->cb = cb;
client->pdr_notify = pdr;
client->priv = priv;
mutex_lock(&pg->client_lock);
list_add(&client->node, &pg->clients);
mutex_unlock(&pg->client_lock);
devres_add(dev, client);
return client;
}
EXPORT_SYMBOL_GPL(devm_pmic_glink_register_client);
int pmic_glink_send(struct pmic_glink_client *client, void *data, size_t len)
{
struct pmic_glink *pg = client->pg;
return rpmsg_send(pg->ept, data, len);
}
EXPORT_SYMBOL_GPL(pmic_glink_send);
static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
int len, void *priv, u32 addr)
{
struct pmic_glink_client *client;
struct pmic_glink_hdr *hdr;
struct pmic_glink *pg = dev_get_drvdata(&rpdev->dev);
if (len < sizeof(*hdr)) {
dev_warn(pg->dev, "ignoring truncated message\n");
return 0;
}
hdr = data;
list_for_each_entry(client, &pg->clients, node) {
if (client->id == le32_to_cpu(hdr->owner))
client->cb(data, len, client->priv);
}
return 0;
}
static void pmic_glink_aux_release(struct device *dev) {}
static int pmic_glink_add_aux_device(struct pmic_glink *pg,
struct auxiliary_device *aux,
const char *name)
{
struct device *parent = pg->dev;
int ret;
aux->name = name;
aux->dev.parent = parent;
aux->dev.release = pmic_glink_aux_release;
device_set_of_node_from_dev(&aux->dev, parent);
ret = auxiliary_device_init(aux);
if (ret)
return ret;
ret = auxiliary_device_add(aux);
if (ret)
auxiliary_device_uninit(aux);
return ret;
}
static void pmic_glink_del_aux_device(struct pmic_glink *pg,
struct auxiliary_device *aux)
{
auxiliary_device_delete(aux);
auxiliary_device_uninit(aux);
}
static void pmic_glink_state_notify_clients(struct pmic_glink *pg)
{
struct pmic_glink_client *client;
unsigned int new_state = pg->client_state;
if (pg->client_state != SERVREG_SERVICE_STATE_UP) {
if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept)
new_state = SERVREG_SERVICE_STATE_UP;
} else {
if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept)
new_state = SERVREG_SERVICE_STATE_DOWN;
}
if (new_state != pg->client_state) {
list_for_each_entry(client, &pg->clients, node)
client->pdr_notify(client->priv, new_state);
pg->client_state = new_state;
}
}
static void pmic_glink_pdr_callback(int state, char *svc_path, void *priv)
{
struct pmic_glink *pg = priv;
mutex_lock(&pg->state_lock);
pg->pdr_state = state;
pmic_glink_state_notify_clients(pg);
mutex_unlock(&pg->state_lock);
}
static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev)
{
struct pmic_glink *pg = __pmic_glink;
int ret = 0;
mutex_lock(&__pmic_glink_lock);
if (!pg) {
ret = dev_err_probe(&rpdev->dev, -ENODEV, "no pmic_glink device to attach to\n");
goto out_unlock;
}
dev_set_drvdata(&rpdev->dev, pg);
mutex_lock(&pg->state_lock);
pg->ept = rpdev->ept;
pmic_glink_state_notify_clients(pg);
mutex_unlock(&pg->state_lock);
out_unlock:
mutex_unlock(&__pmic_glink_lock);
return ret;
}
static void pmic_glink_rpmsg_remove(struct rpmsg_device *rpdev)
{
struct pmic_glink *pg;
mutex_lock(&__pmic_glink_lock);
pg = __pmic_glink;
if (!pg)
goto out_unlock;
mutex_lock(&pg->state_lock);
pg->ept = NULL;
pmic_glink_state_notify_clients(pg);
mutex_unlock(&pg->state_lock);
out_unlock:
mutex_unlock(&__pmic_glink_lock);
}
static const struct rpmsg_device_id pmic_glink_rpmsg_id_match[] = {
{ "PMIC_RTR_ADSP_APPS" },
{}
};
static struct rpmsg_driver pmic_glink_rpmsg_driver = {
.probe = pmic_glink_rpmsg_probe,
.remove = pmic_glink_rpmsg_remove,
.callback = pmic_glink_rpmsg_callback,
.id_table = pmic_glink_rpmsg_id_match,
.drv = {
.name = "qcom_pmic_glink_rpmsg",
},
};
static int pmic_glink_probe(struct platform_device *pdev)
{
struct pdr_service *service;
struct pmic_glink *pg;
int ret;
pg = devm_kzalloc(&pdev->dev, sizeof(*pg), GFP_KERNEL);
if (!pg)
return -ENOMEM;
dev_set_drvdata(&pdev->dev, pg);
pg->dev = &pdev->dev;
INIT_LIST_HEAD(&pg->clients);
mutex_init(&pg->client_lock);
mutex_init(&pg->state_lock);
ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode");
if (ret)
return ret;
ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply");
if (ret)
goto out_release_altmode_aux;
pg->pdr = pdr_handle_alloc(pmic_glink_pdr_callback, pg);
if (IS_ERR(pg->pdr)) {
ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->pdr), "failed to initialize pdr\n");
goto out_release_aux_devices;
}
service = pdr_add_lookup(pg->pdr, "tms/servreg", "msm/adsp/charger_pd");
if (IS_ERR(service)) {
ret = dev_err_probe(&pdev->dev, PTR_ERR(service),
"failed adding pdr lookup for charger_pd\n");
goto out_release_pdr_handle;
}
mutex_lock(&__pmic_glink_lock);
__pmic_glink = pg;
mutex_unlock(&__pmic_glink_lock);
return 0;
out_release_pdr_handle:
pdr_handle_release(pg->pdr);
out_release_aux_devices:
pmic_glink_del_aux_device(pg, &pg->ps_aux);
out_release_altmode_aux:
pmic_glink_del_aux_device(pg, &pg->altmode_aux);
return ret;
}
static int pmic_glink_remove(struct platform_device *pdev)
{
struct pmic_glink *pg = dev_get_drvdata(&pdev->dev);
pdr_handle_release(pg->pdr);
pmic_glink_del_aux_device(pg, &pg->ps_aux);
pmic_glink_del_aux_device(pg, &pg->altmode_aux);
mutex_lock(&__pmic_glink_lock);
__pmic_glink = NULL;
mutex_unlock(&__pmic_glink_lock);
return 0;
}
static const struct of_device_id pmic_glink_of_match[] = {
{ .compatible = "qcom,pmic-glink", },
{}
};
MODULE_DEVICE_TABLE(of, pmic_glink_of_match);
static struct platform_driver pmic_glink_driver = {
.probe = pmic_glink_probe,
.remove = pmic_glink_remove,
.driver = {
.name = "qcom_pmic_glink",
.of_match_table = pmic_glink_of_match,
},
};
static int pmic_glink_init(void)
{
platform_driver_register(&pmic_glink_driver);
register_rpmsg_driver(&pmic_glink_rpmsg_driver);
return 0;
};
module_init(pmic_glink_init);
static void pmic_glink_exit(void)
{
unregister_rpmsg_driver(&pmic_glink_rpmsg_driver);
platform_driver_unregister(&pmic_glink_driver);
};
module_exit(pmic_glink_exit);
MODULE_DESCRIPTION("Qualcomm PMIC GLINK driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -0,0 +1,478 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Linaro Ltd
*/
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/soc/qcom/pdr.h>
#include <drm/drm_bridge.h>
#include <linux/usb/typec_altmode.h>
#include <linux/usb/typec_dp.h>
#include <linux/usb/typec_mux.h>
#include <linux/soc/qcom/pmic_glink.h>
#define PMIC_GLINK_MAX_PORTS 2
#define USBC_SC8180X_NOTIFY_IND 0x13
#define USBC_CMD_WRITE_REQ 0x15
#define USBC_NOTIFY_IND 0x16
#define ALTMODE_PAN_EN 0x10
#define ALTMODE_PAN_ACK 0x11
struct usbc_write_req {
struct pmic_glink_hdr hdr;
__le32 cmd;
__le32 arg;
__le32 reserved;
};
#define NOTIFY_PAYLOAD_SIZE 16
struct usbc_notify {
struct pmic_glink_hdr hdr;
char payload[NOTIFY_PAYLOAD_SIZE];
u32 reserved;
};
struct usbc_sc8180x_notify {
struct pmic_glink_hdr hdr;
__le32 notification;
__le32 reserved[2];
};
enum pmic_glink_altmode_pin_assignment {
DPAM_HPD_OUT,
DPAM_HPD_A,
DPAM_HPD_B,
DPAM_HPD_C,
DPAM_HPD_D,
DPAM_HPD_E,
DPAM_HPD_F,
};
struct pmic_glink_altmode;
#define work_to_altmode_port(w) container_of((w), struct pmic_glink_altmode_port, work)
struct pmic_glink_altmode_port {
struct pmic_glink_altmode *altmode;
unsigned int index;
struct typec_switch *typec_switch;
struct typec_mux *typec_mux;
struct typec_mux_state state;
struct typec_altmode dp_alt;
struct work_struct work;
struct drm_bridge bridge;
enum typec_orientation orientation;
u16 svid;
u8 dp_data;
u8 mode;
u8 hpd_state;
u8 hpd_irq;
};
#define work_to_altmode(w) container_of((w), struct pmic_glink_altmode, enable_work)
struct pmic_glink_altmode {
struct device *dev;
unsigned int owner_id;
/* To synchronize WRITE_REQ acks */
struct mutex lock;
struct completion pan_ack;
struct pmic_glink_client *client;
struct work_struct enable_work;
struct pmic_glink_altmode_port ports[PMIC_GLINK_MAX_PORTS];
};
static int pmic_glink_altmode_request(struct pmic_glink_altmode *altmode, u32 cmd, u32 arg)
{
struct usbc_write_req req = {};
unsigned long left;
int ret;
/*
* The USBC_CMD_WRITE_REQ ack doesn't identify the request, so wait for
* one ack at a time.
*/
mutex_lock(&altmode->lock);
req.hdr.owner = cpu_to_le32(altmode->owner_id);
req.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP);
req.hdr.opcode = cpu_to_le32(USBC_CMD_WRITE_REQ);
req.cmd = cpu_to_le32(cmd);
req.arg = cpu_to_le32(arg);
ret = pmic_glink_send(altmode->client, &req, sizeof(req));
if (ret) {
dev_err(altmode->dev, "failed to send altmode request: %#x (%d)\n", cmd, ret);
goto out_unlock;
}
left = wait_for_completion_timeout(&altmode->pan_ack, 5 * HZ);
if (!left) {
dev_err(altmode->dev, "timeout waiting for altmode request ack for: %#x\n", cmd);
ret = -ETIMEDOUT;
}
out_unlock:
mutex_unlock(&altmode->lock);
return ret;
}
static void pmic_glink_altmode_enable_dp(struct pmic_glink_altmode *altmode,
struct pmic_glink_altmode_port *port,
u8 mode, bool hpd_state,
bool hpd_irq)
{
struct typec_displayport_data dp_data = {};
int ret;
dp_data.status = DP_STATUS_ENABLED;
if (hpd_state)
dp_data.status |= DP_STATUS_HPD_STATE;
if (hpd_irq)
dp_data.status |= DP_STATUS_IRQ_HPD;
dp_data.conf = DP_CONF_SET_PIN_ASSIGN(mode);
port->state.alt = &port->dp_alt;
port->state.data = &dp_data;
port->state.mode = TYPEC_MODAL_STATE(mode);
ret = typec_mux_set(port->typec_mux, &port->state);
if (ret)
dev_err(altmode->dev, "failed to switch mux to DP\n");
}
static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode,
struct pmic_glink_altmode_port *port)
{
int ret;
port->state.alt = NULL;
port->state.data = NULL;
port->state.mode = TYPEC_STATE_USB;
ret = typec_mux_set(port->typec_mux, &port->state);
if (ret)
dev_err(altmode->dev, "failed to switch mux to USB\n");
}
static void pmic_glink_altmode_worker(struct work_struct *work)
{
struct pmic_glink_altmode_port *alt_port = work_to_altmode_port(work);
struct pmic_glink_altmode *altmode = alt_port->altmode;
typec_switch_set(alt_port->typec_switch, alt_port->orientation);
if (alt_port->svid == USB_TYPEC_DP_SID)
pmic_glink_altmode_enable_dp(altmode, alt_port, alt_port->mode,
alt_port->hpd_state, alt_port->hpd_irq);
else
pmic_glink_altmode_enable_usb(altmode, alt_port);
if (alt_port->hpd_state)
drm_bridge_hpd_notify(&alt_port->bridge, connector_status_connected);
else
drm_bridge_hpd_notify(&alt_port->bridge, connector_status_disconnected);
pmic_glink_altmode_request(altmode, ALTMODE_PAN_ACK, alt_port->index);
};
static enum typec_orientation pmic_glink_altmode_orientation(unsigned int orientation)
{
if (orientation == 0)
return TYPEC_ORIENTATION_NORMAL;
else if (orientation == 1)
return TYPEC_ORIENTATION_REVERSE;
else
return TYPEC_ORIENTATION_NONE;
}
#define SC8180X_PORT_MASK 0x000000ff
#define SC8180X_ORIENTATION_MASK 0x0000ff00
#define SC8180X_MUX_MASK 0x00ff0000
#define SC8180X_MODE_MASK 0x3f000000
#define SC8180X_HPD_STATE_MASK 0x40000000
#define SC8180X_HPD_IRQ_MASK 0x80000000
static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmode,
const void *data, size_t len)
{
struct pmic_glink_altmode_port *alt_port;
const struct usbc_sc8180x_notify *msg;
u32 notification;
u8 orientation;
u8 hpd_state;
u8 hpd_irq;
u16 svid;
u8 port;
u8 mode;
u8 mux;
if (len != sizeof(*msg)) {
dev_warn(altmode->dev, "invalid length of USBC_NOTIFY indication: %zd\n", len);
return;
}
msg = data;
notification = le32_to_cpu(msg->notification);
port = FIELD_GET(SC8180X_PORT_MASK, notification);
orientation = FIELD_GET(SC8180X_ORIENTATION_MASK, notification);
mux = FIELD_GET(SC8180X_MUX_MASK, notification);
mode = FIELD_GET(SC8180X_MODE_MASK, notification);
hpd_state = FIELD_GET(SC8180X_HPD_STATE_MASK, notification);
hpd_irq = FIELD_GET(SC8180X_HPD_IRQ_MASK, notification);
svid = mux == 2 ? USB_TYPEC_DP_SID : 0;
if (!altmode->ports[port].altmode) {
dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
return;
}
alt_port = &altmode->ports[port];
alt_port->orientation = pmic_glink_altmode_orientation(orientation);
alt_port->svid = svid;
alt_port->mode = mode;
alt_port->hpd_state = hpd_state;
alt_port->hpd_irq = hpd_irq;
schedule_work(&alt_port->work);
}
#define SC8280XP_DPAM_MASK 0x3f
#define SC8280XP_HPD_STATE_MASK BIT(6)
#define SC8280XP_HPD_IRQ_MASK BIT(7)
static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmode,
u16 svid, const void *data, size_t len)
{
struct pmic_glink_altmode_port *alt_port;
const struct usbc_notify *notify;
u8 orientation;
u8 hpd_state;
u8 hpd_irq;
u8 mode;
u8 port;
if (len != sizeof(*notify)) {
dev_warn(altmode->dev, "invalid length USBC_NOTIFY_IND: %zd\n",
len);
return;
}
notify = data;
port = notify->payload[0];
orientation = notify->payload[1];
mode = FIELD_GET(SC8280XP_DPAM_MASK, notify->payload[8]) - DPAM_HPD_A;
hpd_state = FIELD_GET(SC8280XP_HPD_STATE_MASK, notify->payload[8]);
hpd_irq = FIELD_GET(SC8280XP_HPD_IRQ_MASK, notify->payload[8]);
if (!altmode->ports[port].altmode) {
dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
return;
}
alt_port = &altmode->ports[port];
alt_port->orientation = pmic_glink_altmode_orientation(orientation);
alt_port->svid = svid;
alt_port->mode = mode;
alt_port->hpd_state = hpd_state;
alt_port->hpd_irq = hpd_irq;
schedule_work(&alt_port->work);
}
static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv)
{
struct pmic_glink_altmode *altmode = priv;
const struct pmic_glink_hdr *hdr = data;
u16 opcode;
u16 svid;
opcode = le32_to_cpu(hdr->opcode) & 0xff;
svid = le32_to_cpu(hdr->opcode) >> 16;
switch (opcode) {
case USBC_CMD_WRITE_REQ:
complete(&altmode->pan_ack);
break;
case USBC_NOTIFY_IND:
pmic_glink_altmode_sc8280xp_notify(altmode, svid, data, len);
break;
case USBC_SC8180X_NOTIFY_IND:
pmic_glink_altmode_sc8180xp_notify(altmode, data, len);
break;
}
}
static int pmic_glink_altmode_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL;
}
static const struct drm_bridge_funcs pmic_glink_altmode_bridge_funcs = {
.attach = pmic_glink_altmode_attach,
};
static void pmic_glink_altmode_put_mux(void *data)
{
typec_mux_put(data);
}
static void pmic_glink_altmode_put_switch(void *data)
{
typec_switch_put(data);
}
static void pmic_glink_altmode_enable_worker(struct work_struct *work)
{
struct pmic_glink_altmode *altmode = work_to_altmode(work);
int ret;
ret = pmic_glink_altmode_request(altmode, ALTMODE_PAN_EN, 0);
if (ret)
dev_err(altmode->dev, "failed to request altmode notifications\n");
}
static void pmic_glink_altmode_pdr_notify(void *priv, int state)
{
struct pmic_glink_altmode *altmode = priv;
if (state == SERVREG_SERVICE_STATE_UP)
schedule_work(&altmode->enable_work);
}
static const struct of_device_id pmic_glink_altmode_of_quirks[] = {
{ .compatible = "qcom,sc8180x-pmic-glink", .data = (void *)PMIC_GLINK_OWNER_USBC },
{}
};
static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
struct pmic_glink_altmode_port *alt_port;
struct pmic_glink_altmode *altmode;
struct typec_altmode_desc mux_desc = {};
const struct of_device_id *match;
struct fwnode_handle *fwnode;
struct device *dev = &adev->dev;
u32 port;
int ret;
altmode = devm_kzalloc(dev, sizeof(*altmode), GFP_KERNEL);
if (!altmode)
return -ENOMEM;
altmode->dev = dev;
match = of_match_device(pmic_glink_altmode_of_quirks, dev->parent);
if (match)
altmode->owner_id = (unsigned long)match->data;
else
altmode->owner_id = PMIC_GLINK_OWNER_USBC_PAN;
INIT_WORK(&altmode->enable_work, pmic_glink_altmode_enable_worker);
init_completion(&altmode->pan_ack);
mutex_init(&altmode->lock);
device_for_each_child_node(dev, fwnode) {
ret = fwnode_property_read_u32(fwnode, "reg", &port);
if (ret < 0) {
dev_err(dev, "missing reg property of %pOFn\n", fwnode);
return ret;
}
if (port >= ARRAY_SIZE(altmode->ports)) {
dev_warn(dev, "invalid connector number, ignoring\n");
continue;
}
if (altmode->ports[port].altmode) {
dev_err(dev, "multiple connector definition for port %u\n", port);
return -EINVAL;
}
alt_port = &altmode->ports[port];
alt_port->altmode = altmode;
alt_port->index = port;
INIT_WORK(&alt_port->work, pmic_glink_altmode_worker);
alt_port->bridge.funcs = &pmic_glink_altmode_bridge_funcs;
alt_port->bridge.of_node = to_of_node(fwnode);
alt_port->bridge.ops = DRM_BRIDGE_OP_HPD;
alt_port->bridge.type = DRM_MODE_CONNECTOR_USB;
ret = devm_drm_bridge_add(dev, &alt_port->bridge);
if (ret)
return ret;
alt_port->dp_alt.svid = USB_TYPEC_DP_SID;
alt_port->dp_alt.mode = USB_TYPEC_DP_MODE;
alt_port->dp_alt.active = 1;
mux_desc.svid = USB_TYPEC_DP_SID;
mux_desc.mode = USB_TYPEC_DP_MODE;
alt_port->typec_mux = fwnode_typec_mux_get(fwnode, &mux_desc);
if (IS_ERR(alt_port->typec_mux))
return dev_err_probe(dev, PTR_ERR(alt_port->typec_mux),
"failed to acquire mode-switch for port: %d\n",
port);
ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_mux,
alt_port->typec_mux);
if (ret)
return ret;
alt_port->typec_switch = fwnode_typec_switch_get(fwnode);
if (IS_ERR(alt_port->typec_switch))
return dev_err_probe(dev, PTR_ERR(alt_port->typec_switch),
"failed to acquire orientation-switch for port: %d\n",
port);
ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_switch,
alt_port->typec_switch);
if (ret)
return ret;
}
altmode->client = devm_pmic_glink_register_client(dev,
altmode->owner_id,
pmic_glink_altmode_callback,
pmic_glink_altmode_pdr_notify,
altmode);
return PTR_ERR_OR_ZERO(altmode->client);
}
static const struct auxiliary_device_id pmic_glink_altmode_id_table[] = {
{ .name = "pmic_glink.altmode", },
{},
};
MODULE_DEVICE_TABLE(auxiliary, pmic_glink_altmode_id_table);
static struct auxiliary_driver pmic_glink_altmode_driver = {
.name = "pmic_glink_altmode",
.probe = pmic_glink_altmode_probe,
.id_table = pmic_glink_altmode_id_table,
};
module_auxiliary_driver(pmic_glink_altmode_driver);
MODULE_DESCRIPTION("Qualcomm PMIC GLINK Altmode driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -92,7 +92,7 @@ static int qcom_subsystem_sleep_stats_show(struct seq_file *s, void *unused)
/* Items are allocated lazily, so lookup pointer each time */
stat = qcom_smem_get(subsystem->pid, subsystem->smem_item, NULL);
if (IS_ERR(stat))
return -EIO;
return 0;
qcom_print_stats(s, stat);
@ -170,20 +170,14 @@ static void qcom_create_soc_sleep_stat_files(struct dentry *root, void __iomem *
static void qcom_create_subsystem_stat_files(struct dentry *root,
const struct stats_config *config)
{
const struct sleep_stats *stat;
int i;
if (!config->subsystem_stats_in_smem)
return;
for (i = 0; i < ARRAY_SIZE(subsystems); i++) {
stat = qcom_smem_get(subsystems[i].pid, subsystems[i].smem_item, NULL);
if (IS_ERR(stat))
continue;
for (i = 0; i < ARRAY_SIZE(subsystems); i++)
debugfs_create_file(subsystems[i].name, 0400, root, (void *)&subsystems[i],
&qcom_subsystem_sleep_stats_fops);
}
}
static int qcom_stats_probe(struct platform_device *pdev)

Просмотреть файл

@ -14,7 +14,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#define QCOM_RMTFS_MEM_DEV_MAX (MINORMASK + 1)
#define NUM_MAX_VMIDS 2

Просмотреть файл

@ -233,6 +233,7 @@ static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev)
static const struct of_device_id qcom_smd_rpm_of_match[] = {
{ .compatible = "qcom,rpm-apq8084" },
{ .compatible = "qcom,rpm-ipq6018" },
{ .compatible = "qcom,rpm-ipq9574" },
{ .compatible = "qcom,rpm-msm8226" },
{ .compatible = "qcom,rpm-msm8909" },
{ .compatible = "qcom,rpm-msm8916" },

Просмотреть файл

@ -174,6 +174,8 @@ struct socinfo {
__le32 pcode;
__le32 npartnamemap_offset;
__le32 nnum_partname_mapping;
/* Version 17 */
__le32 oem_variant;
};
#ifdef CONFIG_DEBUG_FS
@ -196,6 +198,7 @@ struct socinfo_params {
u32 nmodem_supported;
u32 feature_code;
u32 pcode;
u32 oem_variant;
};
struct smem_image_version {
@ -281,6 +284,10 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(MSM8126) },
{ qcom_board_id(APQ8026) },
{ qcom_board_id(MSM8926) },
{ qcom_board_id(IPQ8062) },
{ qcom_board_id(IPQ8064) },
{ qcom_board_id(IPQ8066) },
{ qcom_board_id(IPQ8068) },
{ qcom_board_id(MSM8326) },
{ qcom_board_id(MSM8916) },
{ qcom_board_id(MSM8994) },
@ -336,6 +343,8 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(MSM8609) },
{ qcom_board_id(APQ8076) },
{ qcom_board_id(MSM8976) },
{ qcom_board_id(IPQ8065) },
{ qcom_board_id(IPQ8069) },
{ qcom_board_id(MDM9650) },
{ qcom_board_id(MDM9655) },
{ qcom_board_id(MDM9250) },
@ -439,6 +448,8 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(QRU1032) },
{ qcom_board_id(QRU1052) },
{ qcom_board_id(QRU1062) },
{ qcom_board_id(IPQ5332) },
{ qcom_board_id(IPQ5322) },
};
static const char *socinfo_machine(struct device *dev, unsigned int id)
@ -593,6 +604,11 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo,
&qcom_socinfo->info.fmt);
switch (qcom_socinfo->info.fmt) {
case SOCINFO_VERSION(0, 17):
qcom_socinfo->info.oem_variant = __le32_to_cpu(info->oem_variant);
debugfs_create_u32("oem_variant", 0444, qcom_socinfo->dbg_root,
&qcom_socinfo->info.oem_variant);
fallthrough;
case SOCINFO_VERSION(0, 16):
qcom_socinfo->info.feature_code = __le32_to_cpu(info->feature_code);
qcom_socinfo->info.pcode = __le32_to_cpu(info->pcode);

Просмотреть файл

@ -10,7 +10,7 @@
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#define LMH_NODE_DCVS 0x44435653
#define LMH_CLUSTER0_NODE_ID 0x6370302D

Просмотреть файл

@ -8,7 +8,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/qcom_scm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include "ufs-qcom.h"

Просмотреть файл

@ -71,6 +71,10 @@
#define QCOM_ID_MSM8126 198
#define QCOM_ID_APQ8026 199
#define QCOM_ID_MSM8926 200
#define QCOM_ID_IPQ8062 201
#define QCOM_ID_IPQ8064 202
#define QCOM_ID_IPQ8066 203
#define QCOM_ID_IPQ8068 204
#define QCOM_ID_MSM8326 205
#define QCOM_ID_MSM8916 206
#define QCOM_ID_MSM8994 207
@ -127,6 +131,8 @@
#define QCOM_ID_APQ8076 277
#define QCOM_ID_MSM8976 278
#define QCOM_ID_MDM9650 279
#define QCOM_ID_IPQ8065 280
#define QCOM_ID_IPQ8069 281
#define QCOM_ID_MDM9655 283
#define QCOM_ID_MDM9250 284
#define QCOM_ID_MDM9255 285
@ -229,6 +235,8 @@
#define QCOM_ID_QRU1032 588
#define QCOM_ID_QRU1052 589
#define QCOM_ID_QRU1062 590
#define QCOM_ID_IPQ5332 592
#define QCOM_ID_IPQ5322 593
/*
* The board type and revision information, used by Qualcomm bootloaders and

Просмотреть файл

@ -210,6 +210,7 @@
#define RPMH_REGULATOR_LEVEL_RETENTION 16
#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
#define RPMH_REGULATOR_LEVEL_SVS 128
#define RPMH_REGULATOR_LEVEL_SVS_L0 144
#define RPMH_REGULATOR_LEVEL_SVS_L1 192

Просмотреть файл

Просмотреть файл

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022, Linaro Ltd
*/
#ifndef __SOC_QCOM_PMIC_GLINK_H__
#define __SOC_QCOM_PMIC_GLINK_H__
struct pmic_glink;
struct pmic_glink_client;
#define PMIC_GLINK_OWNER_BATTMGR 32778
#define PMIC_GLINK_OWNER_USBC 32779
#define PMIC_GLINK_OWNER_USBC_PAN 32780
#define PMIC_GLINK_REQ_RESP 1
#define PMIC_GLINK_NOTIFY 2
struct pmic_glink_hdr {
__le32 owner;
__le32 type;
__le32 opcode;
};
int pmic_glink_send(struct pmic_glink_client *client, void *data, size_t len);
struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
unsigned int id,
void (*cb)(const void *, size_t, void *),
void (*pdr)(void *, int),
void *priv);
#endif