1010#include <linux/msi.h>
1111#include <linux/of_address.h>
1212#include <linux/of_platform.h>
13+ #include <linux/pm.h>
1314
1415#include <linux/irqchip/irq-msi-lib.h>
1516
@@ -170,6 +171,19 @@ static const struct msi_parent_ops mip_msi_parent_ops = {
170171 .init_dev_msi_info = msi_lib_init_dev_msi_info ,
171172};
172173
174+ static void mip_hw_init (struct mip_priv * mip )
175+ {
176+ /*
177+ * All MSI-X unmasked for the host, masked for the VPU, and edge-triggered.
178+ */
179+ writel (0 , mip -> base + MIP_INT_MASKL_HOST );
180+ writel (0 , mip -> base + MIP_INT_MASKH_HOST );
181+ writel (~0 , mip -> base + MIP_INT_MASKL_VPU );
182+ writel (~0 , mip -> base + MIP_INT_MASKH_VPU );
183+ writel (~0 , mip -> base + MIP_INT_CFGL_HOST );
184+ writel (~0 , mip -> base + MIP_INT_CFGH_HOST );
185+ }
186+
173187static int mip_init_domains (struct mip_priv * mip , struct device_node * np )
174188{
175189 struct irq_domain_info info = {
@@ -184,15 +198,7 @@ static int mip_init_domains(struct mip_priv *mip, struct device_node *np)
184198 if (!msi_create_parent_irq_domain (& info , & mip_msi_parent_ops ))
185199 return - ENOMEM ;
186200
187- /*
188- * All MSI-X unmasked for the host, masked for the VPU, and edge-triggered.
189- */
190- writel (0 , mip -> base + MIP_INT_MASKL_HOST );
191- writel (0 , mip -> base + MIP_INT_MASKH_HOST );
192- writel (~0 , mip -> base + MIP_INT_MASKL_VPU );
193- writel (~0 , mip -> base + MIP_INT_MASKH_VPU );
194- writel (~0 , mip -> base + MIP_INT_CFGL_HOST );
195- writel (~0 , mip -> base + MIP_INT_CFGH_HOST );
201+ mip_hw_init (mip );
196202
197203 return 0 ;
198204}
@@ -244,6 +250,7 @@ static int mip_msi_probe(struct platform_device *pdev, struct device_node *paren
244250
245251 spin_lock_init (& mip -> lock );
246252 mip -> dev = & pdev -> dev ;
253+ platform_set_drvdata (pdev , mip );
247254
248255 ret = mip_parse_dt (mip , node );
249256 if (ret )
@@ -279,9 +286,22 @@ static int mip_msi_probe(struct platform_device *pdev, struct device_node *paren
279286 return ret ;
280287}
281288
289+ static int mip_resume (struct device * dev )
290+ {
291+ struct mip_priv * mip = dev_get_drvdata (dev );
292+
293+ mip_hw_init (mip );
294+
295+ return 0 ;
296+ }
297+
298+ static const struct dev_pm_ops mip_pm_ops = {
299+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (NULL , mip_resume )
300+ };
301+
282302IRQCHIP_PLATFORM_DRIVER_BEGIN (mip_msi )
283303IRQCHIP_MATCH ("brcm,bcm2712-mip" , mip_msi_probe )
284- IRQCHIP_PLATFORM_DRIVER_END (mip_msi )
304+ IRQCHIP_PLATFORM_DRIVER_END (mip_msi , . pm = & mip_pm_ops )
285305MODULE_DESCRIPTION ("Broadcom BCM2712 MSI-X interrupt controller" );
286306MODULE_AUTHOR ("Phil Elwell <phil@raspberrypi.com>" );
287307MODULE_AUTHOR ("Stanimir Varbanov <svarbanov@suse.de>" );
0 commit comments