Blame view

drivers/mailbox/qcom-apcs-ipc-mailbox.c 5.13 KB
97fb5e8d9   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
25bfee16d   Bjorn Andersson   mailbox: Introduc...
2
3
  /*
   * Copyright (c) 2017, Linaro Ltd
25bfee16d   Bjorn Andersson   mailbox: Introduc...
4
5
6
7
8
9
10
11
12
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/io.h>
  #include <linux/slab.h>
  #include <linux/of.h>
  #include <linux/of_platform.h>
  #include <linux/platform_device.h>
c6a8b171c   Georgi Djakov   mailbox: qcom: Co...
13
  #include <linux/regmap.h>
25bfee16d   Bjorn Andersson   mailbox: Introduc...
14
15
16
17
18
19
20
  #include <linux/mailbox_controller.h>
  
  #define QCOM_APCS_IPC_BITS	32
  
  struct qcom_apcs_ipc {
  	struct mbox_controller mbox;
  	struct mbox_chan mbox_chans[QCOM_APCS_IPC_BITS];
c6a8b171c   Georgi Djakov   mailbox: qcom: Co...
21
  	struct regmap *regmap;
25bfee16d   Bjorn Andersson   mailbox: Introduc...
22
  	unsigned long offset;
c815d769b   Georgi Djakov   mailbox: qcom: Cr...
23
  	struct platform_device *clk;
25bfee16d   Bjorn Andersson   mailbox: Introduc...
24
  };
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
25
26
27
28
  struct qcom_apcs_ipc_data {
  	int offset;
  	char *clk_name;
  };
e9f901dc0   Sivaprakash Murugesan   mailbox: qcom: Ad...
29
30
31
  static const struct qcom_apcs_ipc_data ipq6018_apcs_data = {
  	.offset = 8, .clk_name = "qcom,apss-ipq6018-clk"
  };
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
32
33
34
35
36
37
38
  static const struct qcom_apcs_ipc_data ipq8074_apcs_data = {
  	.offset = 8, .clk_name = NULL
  };
  
  static const struct qcom_apcs_ipc_data msm8916_apcs_data = {
  	.offset = 8, .clk_name = "qcom-apcs-msm8916-clk"
  };
dde680569   Konrad Dybcio   mailbox: qcom: Ad...
39
40
41
  static const struct qcom_apcs_ipc_data msm8994_apcs_data = {
  	.offset = 8, .clk_name = NULL
  };
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
42
43
44
45
46
47
48
  static const struct qcom_apcs_ipc_data msm8996_apcs_data = {
  	.offset = 16, .clk_name = NULL
  };
  
  static const struct qcom_apcs_ipc_data msm8998_apcs_data = {
  	.offset = 8, .clk_name = NULL
  };
cfbf813e5   Konrad Dybcio   mailbox: qcom: Ad...
49
50
51
  static const struct qcom_apcs_ipc_data sdm660_apcs_data = {
  	.offset = 8, .clk_name = NULL
  };
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
52
53
54
  static const struct qcom_apcs_ipc_data apps_shared_apcs_data = {
  	.offset = 12, .clk_name = NULL
  };
c6a8b171c   Georgi Djakov   mailbox: qcom: Co...
55
56
57
58
  static const struct regmap_config apcs_regmap_config = {
  	.reg_bits = 32,
  	.reg_stride = 4,
  	.val_bits = 32,
556a0964e   Jorge Ramirez-Ortiz   mailbox: qcom-apc...
59
  	.max_register = 0xFFC,
c6a8b171c   Georgi Djakov   mailbox: qcom: Co...
60
61
  	.fast_io = true,
  };
25bfee16d   Bjorn Andersson   mailbox: Introduc...
62
63
64
65
66
  static int qcom_apcs_ipc_send_data(struct mbox_chan *chan, void *data)
  {
  	struct qcom_apcs_ipc *apcs = container_of(chan->mbox,
  						  struct qcom_apcs_ipc, mbox);
  	unsigned long idx = (unsigned long)chan->con_priv;
c6a8b171c   Georgi Djakov   mailbox: qcom: Co...
67
  	return regmap_write(apcs->regmap, apcs->offset, BIT(idx));
25bfee16d   Bjorn Andersson   mailbox: Introduc...
68
69
70
71
72
73
74
75
76
  }
  
  static const struct mbox_chan_ops qcom_apcs_ipc_ops = {
  	.send_data = qcom_apcs_ipc_send_data,
  };
  
  static int qcom_apcs_ipc_probe(struct platform_device *pdev)
  {
  	struct qcom_apcs_ipc *apcs;
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
77
  	const struct qcom_apcs_ipc_data *apcs_data;
c6a8b171c   Georgi Djakov   mailbox: qcom: Co...
78
  	struct regmap *regmap;
25bfee16d   Bjorn Andersson   mailbox: Introduc...
79
  	struct resource *res;
25bfee16d   Bjorn Andersson   mailbox: Introduc...
80
81
82
83
84
85
86
87
88
89
90
91
  	void __iomem *base;
  	unsigned long i;
  	int ret;
  
  	apcs = devm_kzalloc(&pdev->dev, sizeof(*apcs), GFP_KERNEL);
  	if (!apcs)
  		return -ENOMEM;
  
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	base = devm_ioremap_resource(&pdev->dev, res);
  	if (IS_ERR(base))
  		return PTR_ERR(base);
c6a8b171c   Georgi Djakov   mailbox: qcom: Co...
92
93
94
  	regmap = devm_regmap_init_mmio(&pdev->dev, base, &apcs_regmap_config);
  	if (IS_ERR(regmap))
  		return PTR_ERR(regmap);
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
95
  	apcs_data = of_device_get_match_data(&pdev->dev);
25bfee16d   Bjorn Andersson   mailbox: Introduc...
96

c6a8b171c   Georgi Djakov   mailbox: qcom: Co...
97
  	apcs->regmap = regmap;
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
98
  	apcs->offset = apcs_data->offset;
25bfee16d   Bjorn Andersson   mailbox: Introduc...
99
100
101
102
103
104
105
106
107
  
  	/* Initialize channel identifiers */
  	for (i = 0; i < ARRAY_SIZE(apcs->mbox_chans); i++)
  		apcs->mbox_chans[i].con_priv = (void *)i;
  
  	apcs->mbox.dev = &pdev->dev;
  	apcs->mbox.ops = &qcom_apcs_ipc_ops;
  	apcs->mbox.chans = apcs->mbox_chans;
  	apcs->mbox.num_chans = ARRAY_SIZE(apcs->mbox_chans);
83dd44a17   Thierry Reding   mailbox: qcom-apc...
108
  	ret = devm_mbox_controller_register(&pdev->dev, &apcs->mbox);
25bfee16d   Bjorn Andersson   mailbox: Introduc...
109
110
111
112
113
  	if (ret) {
  		dev_err(&pdev->dev, "failed to register APCS IPC controller
  ");
  		return ret;
  	}
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
114
  	if (apcs_data->clk_name) {
c815d769b   Georgi Djakov   mailbox: qcom: Cr...
115
  		apcs->clk = platform_device_register_data(&pdev->dev,
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
116
  							  apcs_data->clk_name,
16d52f336   Jorge Ramirez-Ortiz   mbox: qcom: repla...
117
118
  							  PLATFORM_DEVID_NONE,
  							  NULL, 0);
c815d769b   Georgi Djakov   mailbox: qcom: Cr...
119
120
121
122
  		if (IS_ERR(apcs->clk))
  			dev_err(&pdev->dev, "failed to register APCS clk
  ");
  	}
25bfee16d   Bjorn Andersson   mailbox: Introduc...
123
124
125
126
127
128
129
130
  	platform_set_drvdata(pdev, apcs);
  
  	return 0;
  }
  
  static int qcom_apcs_ipc_remove(struct platform_device *pdev)
  {
  	struct qcom_apcs_ipc *apcs = platform_get_drvdata(pdev);
c815d769b   Georgi Djakov   mailbox: qcom: Cr...
131
  	struct platform_device *clk = apcs->clk;
25bfee16d   Bjorn Andersson   mailbox: Introduc...
132

c815d769b   Georgi Djakov   mailbox: qcom: Cr...
133
  	platform_device_unregister(clk);
25bfee16d   Bjorn Andersson   mailbox: Introduc...
134
135
136
137
138
139
  
  	return 0;
  }
  
  /* .data is the offset of the ipc register within the global block */
  static const struct of_device_id qcom_apcs_ipc_of_match[] = {
e9f901dc0   Sivaprakash Murugesan   mailbox: qcom: Ad...
140
  	{ .compatible = "qcom,ipq6018-apcs-apps-global", .data = &ipq6018_apcs_data },
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
141
142
  	{ .compatible = "qcom,ipq8074-apcs-apps-global", .data = &ipq8074_apcs_data },
  	{ .compatible = "qcom,msm8916-apcs-kpss-global", .data = &msm8916_apcs_data },
dde680569   Konrad Dybcio   mailbox: qcom: Ad...
143
  	{ .compatible = "qcom,msm8994-apcs-kpss-global", .data = &msm8994_apcs_data },
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
144
145
146
147
  	{ .compatible = "qcom,msm8996-apcs-hmss-global", .data = &msm8996_apcs_data },
  	{ .compatible = "qcom,msm8998-apcs-hmss-global", .data = &msm8998_apcs_data },
  	{ .compatible = "qcom,qcs404-apcs-apps-global", .data = &msm8916_apcs_data },
  	{ .compatible = "qcom,sc7180-apss-shared", .data = &apps_shared_apcs_data },
cfbf813e5   Konrad Dybcio   mailbox: qcom: Ad...
148
  	{ .compatible = "qcom,sdm660-apcs-hmss-global", .data = &sdm660_apcs_data },
9b007938a   Sivaprakash Murugesan   mailbox: qcom: Ad...
149
150
  	{ .compatible = "qcom,sdm845-apss-shared", .data = &apps_shared_apcs_data },
  	{ .compatible = "qcom,sm8150-apss-shared", .data = &apps_shared_apcs_data },
25bfee16d   Bjorn Andersson   mailbox: Introduc...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  	{}
  };
  MODULE_DEVICE_TABLE(of, qcom_apcs_ipc_of_match);
  
  static struct platform_driver qcom_apcs_ipc_driver = {
  	.probe = qcom_apcs_ipc_probe,
  	.remove = qcom_apcs_ipc_remove,
  	.driver = {
  		.name = "qcom_apcs_ipc",
  		.of_match_table = qcom_apcs_ipc_of_match,
  	},
  };
  
  static int __init qcom_apcs_ipc_init(void)
  {
  	return platform_driver_register(&qcom_apcs_ipc_driver);
  }
  postcore_initcall(qcom_apcs_ipc_init);
  
  static void __exit qcom_apcs_ipc_exit(void)
  {
  	platform_driver_unregister(&qcom_apcs_ipc_driver);
  }
  module_exit(qcom_apcs_ipc_exit);
  
  MODULE_LICENSE("GPL v2");
  MODULE_DESCRIPTION("Qualcomm APCS IPC driver");