blob: b378d3b5d3639a9e5b6d2c6a10d48de2a2d8fa23 [file] [log] [blame]
Praveen Chidambaramc0750ca2012-01-08 10:03:28 -07001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/delay.h>
17#include <linux/init.h>
18#include <linux/io.h>
19#include <linux/slab.h>
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -060020#include <linux/of.h>
21#include <linux/of_address.h>
22#include <linux/platform_device.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070023#include <mach/msm_iomap.h>
Praveen Chidambaram76679d42011-12-16 14:19:02 -070024#include <mach/socinfo.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070025#include "spm.h"
26#include "spm_driver.h"
27
28struct msm_spm_power_modes {
29 uint32_t mode;
30 bool notify_rpm;
31 uint32_t start_addr;
32
33};
34
35struct msm_spm_device {
36 struct msm_spm_driver_data reg_data;
37 struct msm_spm_power_modes *modes;
38 uint32_t num_modes;
39};
40
Praveen Chidambarambcd483b2012-09-16 14:54:35 -060041struct msm_spm_vdd_info {
42 uint32_t cpu;
43 uint32_t vlevel;
44 int err;
45};
46
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -060047static struct msm_spm_device msm_spm_l2_device;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070048static DEFINE_PER_CPU_SHARED_ALIGNED(struct msm_spm_device, msm_cpu_spm_device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070049
Praveen Chidambarambcd483b2012-09-16 14:54:35 -060050
Praveen Chidambarambcd483b2012-09-16 14:54:35 -060051static void msm_spm_smp_set_vdd(void *data)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070052{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070053 struct msm_spm_device *dev;
Praveen Chidambarambcd483b2012-09-16 14:54:35 -060054 struct msm_spm_vdd_info *info = (struct msm_spm_vdd_info *)data;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070055
Praveen Chidambarambcd483b2012-09-16 14:54:35 -060056 dev = &per_cpu(msm_cpu_spm_device, info->cpu);
57 info->err = msm_spm_drv_set_vdd(&dev->reg_data, info->vlevel);
58}
59
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -060060/**
61 * msm_spm_set_vdd(): Set core voltage
62 * @cpu: core id
63 * @vlevel: Encoded PMIC data.
64 */
Praveen Chidambarambcd483b2012-09-16 14:54:35 -060065int msm_spm_set_vdd(unsigned int cpu, unsigned int vlevel)
66{
67 struct msm_spm_vdd_info info;
68 int ret;
69
70 info.cpu = cpu;
71 info.vlevel = vlevel;
72
Praveen Chidambaram8624ce72012-10-05 17:11:33 -060073 if (cpu_online(cpu)) {
74 /**
75 * We do not want to set the voltage of another core from
76 * this core, as its possible that we may race the vdd change
77 * with the SPM state machine of that core, which could also
78 * be changing the voltage of that core during power collapse.
79 * Hence, set the function to be executed on that core and block
80 * until the vdd change is complete.
81 */
82 ret = smp_call_function_single(cpu, msm_spm_smp_set_vdd,
83 &info, true);
84 if (!ret)
85 ret = info.err;
86 } else {
87 /**
88 * Since the core is not online, it is safe to set the vdd
89 * directly.
90 */
91 msm_spm_smp_set_vdd(&info);
Praveen Chidambarambcd483b2012-09-16 14:54:35 -060092 ret = info.err;
Praveen Chidambaram8624ce72012-10-05 17:11:33 -060093 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070094
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095 return ret;
96}
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -060097EXPORT_SYMBOL(msm_spm_set_vdd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070098
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -060099/**
100 * msm_spm_get_vdd(): Get core voltage
101 * @cpu: core id
102 * @return: Returns encoded PMIC data.
103 */
Praveen Chidambaram4133ba12012-09-29 22:27:03 -0600104unsigned int msm_spm_get_vdd(unsigned int cpu)
105{
106 struct msm_spm_device *dev;
107
108 dev = &per_cpu(msm_cpu_spm_device, cpu);
109 return msm_spm_drv_get_sts_curr_pmic_data(&dev->reg_data);
110}
111EXPORT_SYMBOL(msm_spm_get_vdd);
112
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700113static int msm_spm_dev_set_low_power_mode(struct msm_spm_device *dev,
114 unsigned int mode, bool notify_rpm)
115{
116 uint32_t i;
117 uint32_t start_addr = 0;
118 int ret = -EINVAL;
119
120 if (mode == MSM_SPM_MODE_DISABLED) {
121 ret = msm_spm_drv_set_spm_enable(&dev->reg_data, false);
122 } else if (!msm_spm_drv_set_spm_enable(&dev->reg_data, true)) {
123 for (i = 0; i < dev->num_modes; i++) {
124 if ((dev->modes[i].mode == mode) &&
125 (dev->modes[i].notify_rpm == notify_rpm)) {
126 start_addr = dev->modes[i].start_addr;
127 break;
128 }
129 }
130 ret = msm_spm_drv_set_low_power_mode(&dev->reg_data,
131 start_addr);
132 }
133 return ret;
134}
135
Stephen Boyddb354112012-05-09 14:24:58 -0700136static int __devinit msm_spm_dev_init(struct msm_spm_device *dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137 struct msm_spm_platform_data *data)
138{
139 int i, ret = -ENOMEM;
140 uint32_t offset = 0;
141
142 dev->num_modes = data->num_modes;
143 dev->modes = kmalloc(
144 sizeof(struct msm_spm_power_modes) * dev->num_modes,
145 GFP_KERNEL);
146
147 if (!dev->modes)
148 goto spm_failed_malloc;
149
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600150 dev->reg_data.ver_reg = data->ver_reg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700151 ret = msm_spm_drv_init(&dev->reg_data, data);
152
153 if (ret)
154 goto spm_failed_init;
155
156 for (i = 0; i < dev->num_modes; i++) {
157
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600158 /* Default offset is 0 and gets updated as we write more
159 * sequences into SPM
160 */
161 dev->modes[i].start_addr = offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700162 ret = msm_spm_drv_write_seq_data(&dev->reg_data,
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600163 data->modes[i].cmd, &offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700164 if (ret < 0)
165 goto spm_failed_init;
166
167 dev->modes[i].mode = data->modes[i].mode;
168 dev->modes[i].notify_rpm = data->modes[i].notify_rpm;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700169 }
170 msm_spm_drv_flush_seq_entry(&dev->reg_data);
171 return 0;
172
173spm_failed_init:
174 kfree(dev->modes);
175spm_failed_malloc:
176 return ret;
177}
178
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600179/**
180 * msm_spm_turn_on_cpu_rail(): Power on cpu rail before turning on core
181 * @cpu: core id
182 */
Praveen Chidambaramc0750ca2012-01-08 10:03:28 -0700183int msm_spm_turn_on_cpu_rail(unsigned int cpu)
184{
185 uint32_t val = 0;
186 uint32_t timeout = 0;
187 void *reg = NULL;
Stepan Moskovchenko2b0b06e2012-02-03 15:03:52 -0800188 void *saw_bases[] = {
189 0,
190 MSM_SAW1_BASE,
191 MSM_SAW2_BASE,
192 MSM_SAW3_BASE
193 };
Praveen Chidambaramc0750ca2012-01-08 10:03:28 -0700194
Stepan Moskovchenko2b0b06e2012-02-03 15:03:52 -0800195 if (cpu == 0 || cpu >= num_possible_cpus())
Praveen Chidambaramc0750ca2012-01-08 10:03:28 -0700196 return -EINVAL;
197
Stepan Moskovchenko2b0b06e2012-02-03 15:03:52 -0800198 reg = saw_bases[cpu];
Praveen Chidambaramc0750ca2012-01-08 10:03:28 -0700199
Stepan Moskovchenko5b9e7762012-09-21 20:32:17 -0700200 if (soc_class_is_msm8960() || soc_class_is_msm8930() ||
201 soc_class_is_apq8064()) {
Stepan Moskovchenko2b0b06e2012-02-03 15:03:52 -0800202 val = 0xA4;
203 reg += 0x14;
204 timeout = 512;
Praveen Chidambaramc0750ca2012-01-08 10:03:28 -0700205 } else {
206 return -ENOSYS;
207 }
208
209 writel_relaxed(val, reg);
210 mb();
211 udelay(timeout);
212
213 return 0;
214}
215EXPORT_SYMBOL(msm_spm_turn_on_cpu_rail);
216
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600217void msm_spm_reinit(void)
218{
219 unsigned int cpu;
220 for_each_possible_cpu(cpu)
221 msm_spm_drv_reinit(&per_cpu(msm_cpu_spm_device.reg_data, cpu));
222}
223EXPORT_SYMBOL(msm_spm_reinit);
224
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600225/**
226 * msm_spm_set_low_power_mode() - Configure SPM start address for low power mode
227 * @mode: SPM LPM mode to enter
228 * @notify_rpm: Notify RPM in this mode
229 */
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600230int msm_spm_set_low_power_mode(unsigned int mode, bool notify_rpm)
231{
232 struct msm_spm_device *dev = &__get_cpu_var(msm_cpu_spm_device);
233 return msm_spm_dev_set_low_power_mode(dev, mode, notify_rpm);
234}
235EXPORT_SYMBOL(msm_spm_set_low_power_mode);
236
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600237/**
238 * msm_spm_init(): Board initalization function
239 * @data: platform specific SPM register configuration data
240 * @nr_devs: Number of SPM devices being initialized
241 */
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600242int __init msm_spm_init(struct msm_spm_platform_data *data, int nr_devs)
243{
244 unsigned int cpu;
245 int ret = 0;
246
247 BUG_ON((nr_devs < num_possible_cpus()) || !data);
248
249 for_each_possible_cpu(cpu) {
250 struct msm_spm_device *dev = &per_cpu(msm_cpu_spm_device, cpu);
251 ret = msm_spm_dev_init(dev, &data[cpu]);
252 if (ret < 0) {
253 pr_warn("%s():failed CPU:%u ret:%d\n", __func__,
254 cpu, ret);
255 break;
256 }
257 }
258
259 return ret;
260}
261
262#ifdef CONFIG_MSM_L2_SPM
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700263
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600264/**
265 * msm_spm_l2_set_low_power_mode(): Configure L2 SPM start address
266 * for low power mode
267 * @mode: SPM LPM mode to enter
268 * @notify_rpm: Notify RPM in this mode
269 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700270int msm_spm_l2_set_low_power_mode(unsigned int mode, bool notify_rpm)
271{
272 return msm_spm_dev_set_low_power_mode(
273 &msm_spm_l2_device, mode, notify_rpm);
274}
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600275EXPORT_SYMBOL(msm_spm_l2_set_low_power_mode);
Maheshkumar Sivasubramanian4ac23762011-11-02 10:03:06 -0600276
277void msm_spm_l2_reinit(void)
278{
279 msm_spm_drv_reinit(&msm_spm_l2_device.reg_data);
280}
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600281EXPORT_SYMBOL(msm_spm_l2_reinit);
282
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600283/**
284 * msm_spm_apcs_set_vdd(): Set Apps processor core sub-system voltage
285 * @vlevel: Encoded PMIC data.
286 */
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600287int msm_spm_apcs_set_vdd(unsigned int vlevel)
288{
289 return msm_spm_drv_set_vdd(&msm_spm_l2_device.reg_data, vlevel);
290}
291EXPORT_SYMBOL(msm_spm_apcs_set_vdd);
292
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600293/**
294 * msm_spm_apcs_set_phase(): Set number of SMPS phases.
295 * phase_cnt: Number of phases to be set active
296 */
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600297int msm_spm_apcs_set_phase(unsigned int phase_cnt)
298{
Praveen Chidambaram1dbe4952012-10-03 17:06:02 -0600299 return msm_spm_drv_set_pmic_data(&msm_spm_l2_device.reg_data,
300 MSM_SPM_PMIC_PHASE_PORT, phase_cnt);
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600301}
302EXPORT_SYMBOL(msm_spm_apcs_set_phase);
303
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600304/** msm_spm_enable_fts_lpm() : Enable FTS to switch to low power
305 * when the cores are in low power modes
306 * @mode: The mode configuration for FTS
307 */
Praveen Chidambaram1dbe4952012-10-03 17:06:02 -0600308int msm_spm_enable_fts_lpm(uint32_t mode)
309{
310 return msm_spm_drv_set_pmic_data(&msm_spm_l2_device.reg_data,
311 MSM_SPM_PMIC_PFM_PORT, mode);
312}
313EXPORT_SYMBOL(msm_spm_enable_fts_lpm);
314
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600315/**
316 * msm_spm_l2_init(): Board initialization function
317 * @data: SPM target specific register configuration
318 */
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600319int __init msm_spm_l2_init(struct msm_spm_platform_data *data)
320{
321 return msm_spm_dev_init(&msm_spm_l2_device, data);
322}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700323#endif
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600324
Sathish Ambley86487e52012-06-11 13:46:11 -0700325static int __devinit msm_spm_dev_probe(struct platform_device *pdev)
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600326{
327 int ret = 0;
328 int cpu = 0;
329 int i = 0;
330 struct device_node *node = pdev->dev.of_node;
331 struct msm_spm_platform_data spm_data;
332 char *key = NULL;
333 uint32_t val = 0;
334 struct msm_spm_seq_entry modes[MSM_SPM_MODE_NR];
335 size_t len = 0;
336 struct msm_spm_device *dev = NULL;
337 struct resource *res = NULL;
338 uint32_t mode_count = 0;
339
340 struct spm_of {
341 char *key;
342 uint32_t id;
343 };
344
345 struct spm_of spm_of_data[] = {
346 {"qcom,saw2-cfg", MSM_SPM_REG_SAW2_CFG},
347 {"qcom,saw2-avs-ctl", MSM_SPM_REG_SAW2_AVS_CTL},
348 {"qcom,saw2-avs-hysteresis", MSM_SPM_REG_SAW2_AVS_HYSTERESIS},
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600349 {"qcom,saw2-avs-limit", MSM_SPM_REG_SAW2_AVS_LIMIT},
Praveen Chidambaram2772d832012-08-22 11:50:34 -0600350 {"qcom,saw2-avs-dly", MSM_SPM_REG_SAW2_AVS_DLY},
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600351 {"qcom,saw2-spm-dly", MSM_SPM_REG_SAW2_SPM_DLY},
Praveen Chidambaram2772d832012-08-22 11:50:34 -0600352 {"qcom,saw2-spm-ctl", MSM_SPM_REG_SAW2_SPM_CTL},
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600353 {"qcom,saw2-pmic-data0", MSM_SPM_REG_SAW2_PMIC_DATA_0},
354 {"qcom,saw2-pmic-data1", MSM_SPM_REG_SAW2_PMIC_DATA_1},
355 {"qcom,saw2-pmic-data2", MSM_SPM_REG_SAW2_PMIC_DATA_2},
356 {"qcom,saw2-pmic-data3", MSM_SPM_REG_SAW2_PMIC_DATA_3},
357 {"qcom,saw2-pmic-data4", MSM_SPM_REG_SAW2_PMIC_DATA_4},
358 {"qcom,saw2-pmic-data5", MSM_SPM_REG_SAW2_PMIC_DATA_5},
359 {"qcom,saw2-pmic-data6", MSM_SPM_REG_SAW2_PMIC_DATA_6},
360 {"qcom,saw2-pmic-data7", MSM_SPM_REG_SAW2_PMIC_DATA_7},
361 };
362
363 struct mode_of {
364 char *key;
365 uint32_t id;
366 uint32_t notify_rpm;
367 };
368
Mahesh Sivasubramanian11373322012-06-14 11:17:20 -0600369 struct mode_of of_cpu_modes[] = {
370 {"qcom,saw2-spm-cmd-wfi", MSM_SPM_MODE_CLOCK_GATING, 0},
371 {"qcom,saw2-spm-cmd-ret", MSM_SPM_MODE_POWER_RETENTION, 0},
372 {"qcom,saw2-spm-cmd-spc", MSM_SPM_MODE_POWER_COLLAPSE, 0},
373 {"qcom,saw2-spm-cmd-pc", MSM_SPM_MODE_POWER_COLLAPSE, 1},
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600374 };
375
Mahesh Sivasubramanian11373322012-06-14 11:17:20 -0600376 struct mode_of of_l2_modes[] = {
377 {"qcom,saw2-spm-cmd-ret", MSM_SPM_L2_MODE_RETENTION, 1},
378 {"qcom,saw2-spm-cmd-gdhs", MSM_SPM_L2_MODE_GDHS, 1},
379 {"qcom,saw2-spm-cmd-pc", MSM_SPM_L2_MODE_POWER_COLLAPSE, 1},
380 };
381
382 struct mode_of *mode_of_data;
383 int num_modes;
384
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600385 memset(&spm_data, 0, sizeof(struct msm_spm_platform_data));
386 memset(&modes, 0,
387 (MSM_SPM_MODE_NR - 2) * sizeof(struct msm_spm_seq_entry));
388
389 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
390 if (!res)
391 goto fail;
392
393 spm_data.reg_base_addr = devm_ioremap(&pdev->dev, res->start,
394 resource_size(res));
395 if (!spm_data.reg_base_addr)
396 return -ENOMEM;
397
398 key = "qcom,core-id";
399 ret = of_property_read_u32(node, key, &val);
400 if (ret)
401 goto fail;
402 cpu = val;
403
404 key = "qcom,saw2-ver-reg";
405 ret = of_property_read_u32(node, key, &val);
406 if (ret)
407 goto fail;
408 spm_data.ver_reg = val;
409
410 key = "qcom,vctl-timeout-us";
411 ret = of_property_read_u32(node, key, &val);
412 if (!ret)
413 spm_data.vctl_timeout_us = val;
414
Mahesh Sivasubramanian11373322012-06-14 11:17:20 -0600415 /*
416 * Device with id 0..NR_CPUS are SPM for apps cores
417 * Device with id 0xFFFF is for L2 SPM.
418 */
419 if (cpu >= 0 && cpu < num_possible_cpus()) {
420 mode_of_data = of_cpu_modes;
421 num_modes = ARRAY_SIZE(of_cpu_modes);
422 dev = &per_cpu(msm_cpu_spm_device, cpu);
423
424 } else {
425 mode_of_data = of_l2_modes;
426 num_modes = ARRAY_SIZE(of_l2_modes);
427 dev = &msm_spm_l2_device;
428 }
429
Praveen Chidambaram1dbe4952012-10-03 17:06:02 -0600430 spm_data.vctl_port = -1;
431 spm_data.phase_port = -1;
432 spm_data.pfm_port = -1;
433
434 /* optional */
435 if (dev == &msm_spm_l2_device) {
436 key = "qcom,vctl-port";
437 ret = of_property_read_u32(node, key, &val);
438 if (!ret)
439 spm_data.vctl_port = val;
440
441 key = "qcom,phase-port";
442 ret = of_property_read_u32(node, key, &val);
443 if (!ret)
444 spm_data.phase_port = val;
445
446 key = "qcom,pfm-port";
447 ret = of_property_read_u32(node, key, &val);
448 if (!ret)
449 spm_data.pfm_port = val;
450 }
451
452 for (i = 0; i < ARRAY_SIZE(spm_of_data); i++) {
453 ret = of_property_read_u32(node, spm_of_data[i].key, &val);
454 if (ret)
455 continue;
456 spm_data.reg_init_values[spm_of_data[i].id] = val;
457 }
458
Mahesh Sivasubramanian11373322012-06-14 11:17:20 -0600459 for (i = 0; i < num_modes; i++) {
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600460 key = mode_of_data[i].key;
461 modes[mode_count].cmd =
462 (uint8_t *)of_get_property(node, key, &len);
463 if (!modes[mode_count].cmd)
464 continue;
465 modes[mode_count].mode = mode_of_data[i].id;
466 modes[mode_count].notify_rpm = mode_of_data[i].notify_rpm;
467 mode_count++;
468 }
469
470 spm_data.modes = modes;
471 spm_data.num_modes = mode_count;
472
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600473 ret = msm_spm_dev_init(dev, &spm_data);
Mahesh Sivasubramanian11373322012-06-14 11:17:20 -0600474
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600475 if (ret < 0)
476 pr_warn("%s():failed core-id:%u ret:%d\n", __func__, cpu, ret);
477
478 return ret;
479
480fail:
481 pr_err("%s: Failed reading node=%s, key=%s\n",
482 __func__, node->full_name, key);
483 return -EFAULT;
484}
485
Sathish Ambley86487e52012-06-11 13:46:11 -0700486static struct of_device_id msm_spm_match_table[] = {
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600487 {.compatible = "qcom,spm-v2"},
488 {},
489};
490
Sathish Ambley86487e52012-06-11 13:46:11 -0700491static struct platform_driver msm_spm_device_driver = {
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600492 .probe = msm_spm_dev_probe,
493 .driver = {
494 .name = "spm-v2",
495 .owner = THIS_MODULE,
496 .of_match_table = msm_spm_match_table,
497 },
498};
499
Praveen Chidambaram7347bfe2012-11-01 15:21:10 -0600500/**
501 * msm_spm_device_init(): Device tree initialization function
502 */
Praveen Chidambaramaa9d52b2012-04-02 11:09:47 -0600503int __init msm_spm_device_init(void)
504{
505 return platform_driver_register(&msm_spm_device_driver);
506}