Skip to content

Commit e2837df

Browse files
committed
Merge tag 'imx-drivers-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers
i.MX drivers change for 5.9: - Update SCU irq code to call pm_system_wakeup() in general MU IRQ handler, so that system can be waked up when MU IRQ arrives. - Move i.MX SCU soc driver into imx firmware folder to get it initialized from i.MX SCU firmware driver. - Clean up soc-imx-scu driver a bit by using devm_kasprintf(). - Correct postfix setting for cm40 power domain in scu-pd driver. - Add resource management support for IMX_SCU firmware driver. - Add more cm4 resources to i.MX SCU power domain driver. - Select ARM_GIC_V3 from SOC_IMX8M for being able to use GICv3 driver in AARCH32 mode Linux on AARCH64 hardware. * tag 'imx-drivers-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux: soc: imx: select ARM_GIC_V3 for i.MX8M firmware: imx: Move i.MX SCU soc driver into imx firmware folder firmware: imx: scu-pd: add more cm4 resources firmware: imx: add resource management api firmware: imx: scu-pd: fix cm40 power domain soc: imx: scu: use devm_kasprintf firmware: imx: make sure MU irq can wake up system from suspend mode Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnd Bergmann <[email protected]>
2 parents 9e586c8 + d82bcef commit e2837df

File tree

11 files changed

+153
-80
lines changed

11 files changed

+153
-80
lines changed

arch/arm64/configs/defconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,6 @@ CONFIG_OWL_PM_DOMAINS=y
850850
CONFIG_RASPBERRYPI_POWER=y
851851
CONFIG_FSL_DPAA=y
852852
CONFIG_FSL_MC_DPIO=y
853-
CONFIG_IMX_SCU_SOC=y
854853
CONFIG_QCOM_AOSS_QMP=y
855854
CONFIG_QCOM_GENI_SE=y
856855
CONFIG_QCOM_RMTFS_MEM=m

drivers/firmware/imx/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# SPDX-License-Identifier: GPL-2.0
22
obj-$(CONFIG_IMX_DSP) += imx-dsp.o
3-
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o
3+
obj-$(CONFIG_IMX_SCU) += imx-scu.o misc.o imx-scu-irq.o rm.o imx-scu-soc.o
44
obj-$(CONFIG_IMX_SCU_PD) += scu-pd.o

drivers/firmware/imx/imx-scu-irq.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/firmware/imx/ipc.h>
1111
#include <linux/firmware/imx/sci.h>
1212
#include <linux/mailbox_client.h>
13+
#include <linux/suspend.h>
1314

1415
#define IMX_SC_IRQ_FUNC_ENABLE 1
1516
#define IMX_SC_IRQ_FUNC_STATUS 2
@@ -91,6 +92,7 @@ static void imx_scu_irq_work_handler(struct work_struct *work)
9192
if (!irq_status)
9293
continue;
9394

95+
pm_system_wakeup();
9496
imx_scu_irq_notifier_call_chain(irq_status, &i);
9597
}
9698
}

drivers/soc/imx/soc-imx-scu.c renamed to drivers/firmware/imx/imx-scu-soc.c

Lines changed: 17 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
#include <linux/platform_device.h>
1111
#include <linux/of.h>
1212

13-
#define IMX_SCU_SOC_DRIVER_NAME "imx-scu-soc"
14-
15-
static struct imx_sc_ipc *soc_ipc_handle;
13+
static struct imx_sc_ipc *imx_sc_soc_ipc_handle;
1614

1715
struct imx_sc_msg_misc_get_soc_id {
1816
struct imx_sc_rpc_msg hdr;
@@ -44,7 +42,7 @@ static int imx_scu_soc_uid(u64 *soc_uid)
4442
hdr->func = IMX_SC_MISC_FUNC_UNIQUE_ID;
4543
hdr->size = 1;
4644

47-
ret = imx_scu_call_rpc(soc_ipc_handle, &msg, true);
45+
ret = imx_scu_call_rpc(imx_sc_soc_ipc_handle, &msg, true);
4846
if (ret) {
4947
pr_err("%s: get soc uid failed, ret %d\n", __func__, ret);
5048
return ret;
@@ -71,7 +69,7 @@ static int imx_scu_soc_id(void)
7169
msg.data.req.control = IMX_SC_C_ID;
7270
msg.data.req.resource = IMX_SC_R_SYSTEM;
7371

74-
ret = imx_scu_call_rpc(soc_ipc_handle, &msg, true);
72+
ret = imx_scu_call_rpc(imx_sc_soc_ipc_handle, &msg, true);
7573
if (ret) {
7674
pr_err("%s: get soc info failed, ret %d\n", __func__, ret);
7775
return ret;
@@ -80,19 +78,19 @@ static int imx_scu_soc_id(void)
8078
return msg.data.resp.id;
8179
}
8280

83-
static int imx_scu_soc_probe(struct platform_device *pdev)
81+
int imx_scu_soc_init(struct device *dev)
8482
{
8583
struct soc_device_attribute *soc_dev_attr;
8684
struct soc_device *soc_dev;
8785
int id, ret;
8886
u64 uid = 0;
8987
u32 val;
9088

91-
ret = imx_scu_get_handle(&soc_ipc_handle);
89+
ret = imx_scu_get_handle(&imx_sc_soc_ipc_handle);
9290
if (ret)
9391
return ret;
9492

95-
soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr),
93+
soc_dev_attr = devm_kzalloc(dev, sizeof(*soc_dev_attr),
9694
GFP_KERNEL);
9795
if (!soc_dev_attr)
9896
return -ENOMEM;
@@ -115,73 +113,26 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
115113

116114
/* format soc_id value passed from SCU firmware */
117115
val = id & 0x1f;
118-
soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x", val);
116+
soc_dev_attr->soc_id = devm_kasprintf(dev, GFP_KERNEL, "0x%x", val);
119117
if (!soc_dev_attr->soc_id)
120118
return -ENOMEM;
121119

122120
/* format revision value passed from SCU firmware */
123121
val = (id >> 5) & 0xf;
124122
val = (((val >> 2) + 1) << 4) | (val & 0x3);
125-
soc_dev_attr->revision = kasprintf(GFP_KERNEL,
126-
"%d.%d",
127-
(val >> 4) & 0xf,
128-
val & 0xf);
129-
if (!soc_dev_attr->revision) {
130-
ret = -ENOMEM;
131-
goto free_soc_id;
132-
}
123+
soc_dev_attr->revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
124+
(val >> 4) & 0xf, val & 0xf);
125+
if (!soc_dev_attr->revision)
126+
return -ENOMEM;
133127

134-
soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX", uid);
135-
if (!soc_dev_attr->serial_number) {
136-
ret = -ENOMEM;
137-
goto free_revision;
138-
}
128+
soc_dev_attr->serial_number = devm_kasprintf(dev, GFP_KERNEL,
129+
"%016llX", uid);
130+
if (!soc_dev_attr->serial_number)
131+
return -ENOMEM;
139132

140133
soc_dev = soc_device_register(soc_dev_attr);
141-
if (IS_ERR(soc_dev)) {
142-
ret = PTR_ERR(soc_dev);
143-
goto free_serial_number;
144-
}
134+
if (IS_ERR(soc_dev))
135+
return PTR_ERR(soc_dev);
145136

146137
return 0;
147-
148-
free_serial_number:
149-
kfree(soc_dev_attr->serial_number);
150-
free_revision:
151-
kfree(soc_dev_attr->revision);
152-
free_soc_id:
153-
kfree(soc_dev_attr->soc_id);
154-
return ret;
155-
}
156-
157-
static struct platform_driver imx_scu_soc_driver = {
158-
.driver = {
159-
.name = IMX_SCU_SOC_DRIVER_NAME,
160-
},
161-
.probe = imx_scu_soc_probe,
162-
};
163-
164-
static int __init imx_scu_soc_init(void)
165-
{
166-
struct platform_device *pdev;
167-
struct device_node *np;
168-
int ret;
169-
170-
np = of_find_compatible_node(NULL, NULL, "fsl,imx-scu");
171-
if (!np)
172-
return -ENODEV;
173-
174-
of_node_put(np);
175-
176-
ret = platform_driver_register(&imx_scu_soc_driver);
177-
if (ret)
178-
return ret;
179-
180-
pdev = platform_device_register_simple(IMX_SCU_SOC_DRIVER_NAME,
181-
-1, NULL, 0);
182-
if (IS_ERR(pdev))
183-
platform_driver_unregister(&imx_scu_soc_driver);
184-
185-
return PTR_ERR_OR_ZERO(pdev);
186138
}
187-
device_initcall(imx_scu_soc_init);

drivers/firmware/imx/imx-scu.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,10 @@ static int imx_scu_probe(struct platform_device *pdev)
328328

329329
imx_sc_ipc_handle = sc_ipc;
330330

331+
ret = imx_scu_soc_init(dev);
332+
if (ret)
333+
dev_warn(dev, "failed to initialize SoC info: %d\n", ret);
334+
331335
ret = imx_scu_enable_general_irq_channel(dev);
332336
if (ret)
333337
dev_warn(dev,

drivers/firmware/imx/rm.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* Copyright 2020 NXP
4+
*
5+
* File containing client-side RPC functions for the RM service. These
6+
* function are ported to clients that communicate to the SC.
7+
*/
8+
9+
#include <linux/firmware/imx/svc/rm.h>
10+
11+
struct imx_sc_msg_rm_rsrc_owned {
12+
struct imx_sc_rpc_msg hdr;
13+
u16 resource;
14+
} __packed __aligned(4);
15+
16+
/*
17+
* This function check @resource is owned by current partition or not
18+
*
19+
* @param[in] ipc IPC handle
20+
* @param[in] resource resource the control is associated with
21+
*
22+
* @return Returns 0 for not owned and 1 for owned.
23+
*/
24+
bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
25+
{
26+
struct imx_sc_msg_rm_rsrc_owned msg;
27+
struct imx_sc_rpc_msg *hdr = &msg.hdr;
28+
29+
hdr->ver = IMX_SC_RPC_VERSION;
30+
hdr->svc = IMX_SC_RPC_SVC_RM;
31+
hdr->func = IMX_SC_RM_FUNC_IS_RESOURCE_OWNED;
32+
hdr->size = 2;
33+
34+
msg.resource = resource;
35+
36+
/*
37+
* SCU firmware only returns value 0 or 1
38+
* for resource owned check which means not owned or owned.
39+
* So it is always successful.
40+
*/
41+
imx_scu_call_rpc(ipc, &msg, true);
42+
43+
return hdr->func;
44+
}
45+
EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);

drivers/firmware/imx/scu-pd.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,18 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
167167
{ "dc0-pll", IMX_SC_R_DC_0_PLL_0, 2, true, 0 },
168168

169169
/* CM40 SS */
170-
{ "cm40_i2c", IMX_SC_R_M4_0_I2C, 1, 0 },
171-
{ "cm40_intmux", IMX_SC_R_M4_0_INTMUX, 1, 0 },
170+
{ "cm40-i2c", IMX_SC_R_M4_0_I2C, 1, false, 0 },
171+
{ "cm40-intmux", IMX_SC_R_M4_0_INTMUX, 1, false, 0 },
172+
{ "cm40-pid", IMX_SC_R_M4_0_PID0, 5, true, 0},
173+
{ "cm40-mu-a1", IMX_SC_R_M4_0_MU_1A, 1, false, 0},
174+
{ "cm40-lpuart", IMX_SC_R_M4_0_UART, 1, false, 0},
175+
176+
/* CM41 SS */
177+
{ "cm41-i2c", IMX_SC_R_M4_1_I2C, 1, false, 0 },
178+
{ "cm41-intmux", IMX_SC_R_M4_1_INTMUX, 1, false, 0 },
179+
{ "cm41-pid", IMX_SC_R_M4_1_PID0, 5, true, 0},
180+
{ "cm41-mu-a1", IMX_SC_R_M4_1_MU_1A, 1, false, 0},
181+
{ "cm41-lpuart", IMX_SC_R_M4_1_UART, 1, false, 0},
172182
};
173183

174184
static const struct imx_sc_pd_soc imx8qxp_scu_pd = {

drivers/soc/imx/Kconfig

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,12 @@ config IMX_GPCV2_PM_DOMAINS
88
select PM_GENERIC_DOMAINS
99
default y if SOC_IMX7D
1010

11-
config IMX_SCU_SOC
12-
bool "i.MX System Controller Unit SoC info support"
13-
depends on IMX_SCU
14-
select SOC_BUS
15-
help
16-
If you say yes here you get support for the NXP i.MX System
17-
Controller Unit SoC info module, it will provide the SoC info
18-
like SoC family, ID and revision etc.
19-
2011
config SOC_IMX8M
2112
bool "i.MX8M SoC family support"
2213
depends on ARCH_MXC || COMPILE_TEST
2314
default ARCH_MXC && ARM64
2415
select SOC_BUS
16+
select ARM_GIC_V3 if ARCH_MXC
2517
help
2618
If you say yes here you get support for the NXP i.MX8M family
2719
support, it will provide the SoC info like SoC family,

drivers/soc/imx/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@ endif
55
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
66
obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
77
obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
8-
obj-$(CONFIG_IMX_SCU_SOC) += soc-imx-scu.o

include/linux/firmware/imx/sci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414

1515
#include <linux/firmware/imx/svc/misc.h>
1616
#include <linux/firmware/imx/svc/pm.h>
17+
#include <linux/firmware/imx/svc/rm.h>
1718

1819
int imx_scu_enable_general_irq_channel(struct device *dev);
1920
int imx_scu_irq_register_notifier(struct notifier_block *nb);
2021
int imx_scu_irq_unregister_notifier(struct notifier_block *nb);
2122
int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable);
23+
int imx_scu_soc_init(struct device *dev);
2224
#endif /* _SC_SCI_H */

0 commit comments

Comments
 (0)