1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2016 NVIDIA CORPORATION, All Rights Reserved.
5 #include <linux/module.h>
7 #include <linux/of_device.h>
8 #include <linux/of_irq.h>
9 #include <linux/irqchip/arm-gic.h>
10 #include <linux/platform_device.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/slab.h>
15 unsigned int num_clocks
;
16 const char *const *clocks
;
20 struct gic_chip_data
*chip_data
;
21 const struct gic_clk_data
*clk_data
;
22 struct clk_bulk_data
*clks
;
25 static int gic_runtime_resume(struct device
*dev
)
27 struct gic_chip_pm
*chip_pm
= dev_get_drvdata(dev
);
28 struct gic_chip_data
*gic
= chip_pm
->chip_data
;
29 const struct gic_clk_data
*data
= chip_pm
->clk_data
;
32 ret
= clk_bulk_prepare_enable(data
->num_clocks
, chip_pm
->clks
);
34 dev_err(dev
, "clk_enable failed: %d\n", ret
);
39 * On the very first resume, the pointer to chip_pm->chip_data
40 * will be NULL and this is intentional, because we do not
41 * want to restore the GIC on the very first resume. So if
42 * the pointer is not valid just return.
47 gic_dist_restore(gic
);
53 static int gic_runtime_suspend(struct device
*dev
)
55 struct gic_chip_pm
*chip_pm
= dev_get_drvdata(dev
);
56 struct gic_chip_data
*gic
= chip_pm
->chip_data
;
57 const struct gic_clk_data
*data
= chip_pm
->clk_data
;
62 clk_bulk_disable_unprepare(data
->num_clocks
, chip_pm
->clks
);
67 static int gic_probe(struct platform_device
*pdev
)
69 struct device
*dev
= &pdev
->dev
;
70 const struct gic_clk_data
*data
;
71 struct gic_chip_pm
*chip_pm
;
74 data
= of_device_get_match_data(&pdev
->dev
);
76 dev_err(&pdev
->dev
, "no device match found\n");
80 chip_pm
= devm_kzalloc(dev
, sizeof(*chip_pm
), GFP_KERNEL
);
84 irq
= irq_of_parse_and_map(dev
->of_node
, 0);
86 dev_err(dev
, "no parent interrupt found!\n");
90 chip_pm
->clks
= devm_kcalloc(dev
, data
->num_clocks
,
91 sizeof(*chip_pm
->clks
), GFP_KERNEL
);
95 for (i
= 0; i
< data
->num_clocks
; i
++)
96 chip_pm
->clks
[i
].id
= data
->clocks
[i
];
98 ret
= devm_clk_bulk_get(dev
, data
->num_clocks
, chip_pm
->clks
);
102 chip_pm
->clk_data
= data
;
103 dev_set_drvdata(dev
, chip_pm
);
105 pm_runtime_enable(dev
);
107 ret
= pm_runtime_get_sync(dev
);
111 ret
= gic_of_init_child(dev
, &chip_pm
->chip_data
, irq
);
117 dev_info(dev
, "GIC IRQ controller registered\n");
122 pm_runtime_put_sync(dev
);
124 pm_runtime_disable(dev
);
126 irq_dispose_mapping(irq
);
131 static const struct dev_pm_ops gic_pm_ops
= {
132 SET_RUNTIME_PM_OPS(gic_runtime_suspend
,
133 gic_runtime_resume
, NULL
)
134 SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
135 pm_runtime_force_resume
)
138 static const char * const gic400_clocks
[] = {
142 static const struct gic_clk_data gic400_data
= {
143 .num_clocks
= ARRAY_SIZE(gic400_clocks
),
144 .clocks
= gic400_clocks
,
147 static const struct of_device_id gic_match
[] = {
148 { .compatible
= "nvidia,tegra210-agic", .data
= &gic400_data
},
151 MODULE_DEVICE_TABLE(of
, gic_match
);
153 static struct platform_driver gic_driver
= {
157 .of_match_table
= gic_match
,
162 builtin_platform_driver(gic_driver
);