xref: /openbmc/linux/drivers/mfd/twl4030-power.c (revision 32057281)
1 /*
2  * linux/drivers/i2c/chips/twl4030-power.c
3  *
4  * Handle TWL4030 Power initialization
5  *
6  * Copyright (C) 2008 Nokia Corporation
7  * Copyright (C) 2006 Texas Instruments, Inc
8  *
9  * Written by 	Kalle Jokiniemi
10  *		Peter De Schrijver <peter.de-schrijver@nokia.com>
11  * Several fixes by Amit Kucheria <amit.kucheria@verdurent.com>
12  *
13  * This file is subject to the terms and conditions of the GNU General
14  * Public License. See the file "COPYING" in the main directory of this
15  * archive for more details.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26 
27 #include <linux/module.h>
28 #include <linux/pm.h>
29 #include <linux/i2c/twl.h>
30 #include <linux/platform_device.h>
31 #include <linux/of.h>
32 
33 #include <asm/mach-types.h>
34 
35 static u8 twl4030_start_script_address = 0x2b;
36 
37 /* Register bits for P1, P2 and P3_SW_EVENTS */
38 #define PWR_STOPON_PRWON	BIT(6)
39 #define PWR_STOPON_SYSEN	BIT(5)
40 #define PWR_ENABLE_WARMRESET	BIT(4)
41 #define PWR_LVL_WAKEUP		BIT(3)
42 #define PWR_DEVACT		BIT(2)
43 #define PWR_DEVSLP		BIT(1)
44 #define PWR_DEVOFF		BIT(0)
45 
46 #define SEQ_OFFSYNC		(1 << 0)
47 
48 #define PHY_TO_OFF_PM_MASTER(p)		(p - 0x36)
49 #define PHY_TO_OFF_PM_RECEIVER(p)	(p - 0x5b)
50 
51 /* resource - hfclk */
52 #define R_HFCLKOUT_DEV_GRP 	PHY_TO_OFF_PM_RECEIVER(0xe6)
53 
54 /* PM events */
55 #define R_P1_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x46)
56 #define R_P2_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x47)
57 #define R_P3_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x48)
58 #define R_CFG_P1_TRANSITION	PHY_TO_OFF_PM_MASTER(0x36)
59 #define R_CFG_P2_TRANSITION	PHY_TO_OFF_PM_MASTER(0x37)
60 #define R_CFG_P3_TRANSITION	PHY_TO_OFF_PM_MASTER(0x38)
61 
62 #define END_OF_SCRIPT		0x3f
63 
64 #define R_SEQ_ADD_A2S		PHY_TO_OFF_PM_MASTER(0x55)
65 #define R_SEQ_ADD_S2A12		PHY_TO_OFF_PM_MASTER(0x56)
66 #define	R_SEQ_ADD_S2A3		PHY_TO_OFF_PM_MASTER(0x57)
67 #define	R_SEQ_ADD_WARM		PHY_TO_OFF_PM_MASTER(0x58)
68 #define R_MEMORY_ADDRESS	PHY_TO_OFF_PM_MASTER(0x59)
69 #define R_MEMORY_DATA		PHY_TO_OFF_PM_MASTER(0x5a)
70 
71 /* resource configuration registers
72    <RESOURCE>_DEV_GRP   at address 'n+0'
73    <RESOURCE>_TYPE      at address 'n+1'
74    <RESOURCE>_REMAP     at address 'n+2'
75    <RESOURCE>_DEDICATED at address 'n+3'
76 */
77 #define DEV_GRP_OFFSET		0
78 #define TYPE_OFFSET		1
79 #define REMAP_OFFSET		2
80 #define DEDICATED_OFFSET	3
81 
82 /* Bit positions in the registers */
83 
84 /* <RESOURCE>_DEV_GRP */
85 #define DEV_GRP_SHIFT		5
86 #define DEV_GRP_MASK		(7 << DEV_GRP_SHIFT)
87 
88 /* <RESOURCE>_TYPE */
89 #define TYPE_SHIFT		0
90 #define TYPE_MASK		(7 << TYPE_SHIFT)
91 #define TYPE2_SHIFT		3
92 #define TYPE2_MASK		(3 << TYPE2_SHIFT)
93 
94 /* <RESOURCE>_REMAP */
95 #define SLEEP_STATE_SHIFT	0
96 #define SLEEP_STATE_MASK	(0xf << SLEEP_STATE_SHIFT)
97 #define OFF_STATE_SHIFT		4
98 #define OFF_STATE_MASK		(0xf << OFF_STATE_SHIFT)
99 
100 static u8 res_config_addrs[] = {
101 	[RES_VAUX1]	= 0x17,
102 	[RES_VAUX2]	= 0x1b,
103 	[RES_VAUX3]	= 0x1f,
104 	[RES_VAUX4]	= 0x23,
105 	[RES_VMMC1]	= 0x27,
106 	[RES_VMMC2]	= 0x2b,
107 	[RES_VPLL1]	= 0x2f,
108 	[RES_VPLL2]	= 0x33,
109 	[RES_VSIM]	= 0x37,
110 	[RES_VDAC]	= 0x3b,
111 	[RES_VINTANA1]	= 0x3f,
112 	[RES_VINTANA2]	= 0x43,
113 	[RES_VINTDIG]	= 0x47,
114 	[RES_VIO]	= 0x4b,
115 	[RES_VDD1]	= 0x55,
116 	[RES_VDD2]	= 0x63,
117 	[RES_VUSB_1V5]	= 0x71,
118 	[RES_VUSB_1V8]	= 0x74,
119 	[RES_VUSB_3V1]	= 0x77,
120 	[RES_VUSBCP]	= 0x7a,
121 	[RES_REGEN]	= 0x7f,
122 	[RES_NRES_PWRON] = 0x82,
123 	[RES_CLKEN]	= 0x85,
124 	[RES_SYSEN]	= 0x88,
125 	[RES_HFCLKOUT]	= 0x8b,
126 	[RES_32KCLKOUT]	= 0x8e,
127 	[RES_RESET]	= 0x91,
128 	[RES_MAIN_REF]	= 0x94,
129 };
130 
131 static int twl4030_write_script_byte(u8 address, u8 byte)
132 {
133 	int err;
134 
135 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_MEMORY_ADDRESS);
136 	if (err)
137 		goto out;
138 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, byte, R_MEMORY_DATA);
139 out:
140 	return err;
141 }
142 
143 static int twl4030_write_script_ins(u8 address, u16 pmb_message,
144 					   u8 delay, u8 next)
145 {
146 	int err;
147 
148 	address *= 4;
149 	err = twl4030_write_script_byte(address++, pmb_message >> 8);
150 	if (err)
151 		goto out;
152 	err = twl4030_write_script_byte(address++, pmb_message & 0xff);
153 	if (err)
154 		goto out;
155 	err = twl4030_write_script_byte(address++, delay);
156 	if (err)
157 		goto out;
158 	err = twl4030_write_script_byte(address++, next);
159 out:
160 	return err;
161 }
162 
163 static int twl4030_write_script(u8 address, struct twl4030_ins *script,
164 				       int len)
165 {
166 	int err = -EINVAL;
167 
168 	for (; len; len--, address++, script++) {
169 		if (len == 1) {
170 			err = twl4030_write_script_ins(address,
171 						script->pmb_message,
172 						script->delay,
173 						END_OF_SCRIPT);
174 			if (err)
175 				break;
176 		} else {
177 			err = twl4030_write_script_ins(address,
178 						script->pmb_message,
179 						script->delay,
180 						address + 1);
181 			if (err)
182 				break;
183 		}
184 	}
185 	return err;
186 }
187 
188 static int twl4030_config_wakeup3_sequence(u8 address)
189 {
190 	int err;
191 	u8 data;
192 
193 	/* Set SLEEP to ACTIVE SEQ address for P3 */
194 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A3);
195 	if (err)
196 		goto out;
197 
198 	/* P3 LVL_WAKEUP should be on LEVEL */
199 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P3_SW_EVENTS);
200 	if (err)
201 		goto out;
202 	data |= PWR_LVL_WAKEUP;
203 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P3_SW_EVENTS);
204 out:
205 	if (err)
206 		pr_err("TWL4030 wakeup sequence for P3 config error\n");
207 	return err;
208 }
209 
210 static int twl4030_config_wakeup12_sequence(u8 address)
211 {
212 	int err = 0;
213 	u8 data;
214 
215 	/* Set SLEEP to ACTIVE SEQ address for P1 and P2 */
216 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_S2A12);
217 	if (err)
218 		goto out;
219 
220 	/* P1/P2 LVL_WAKEUP should be on LEVEL */
221 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P1_SW_EVENTS);
222 	if (err)
223 		goto out;
224 
225 	data |= PWR_LVL_WAKEUP;
226 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P1_SW_EVENTS);
227 	if (err)
228 		goto out;
229 
230 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, R_P2_SW_EVENTS);
231 	if (err)
232 		goto out;
233 
234 	data |= PWR_LVL_WAKEUP;
235 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, R_P2_SW_EVENTS);
236 	if (err)
237 		goto out;
238 
239 	if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) {
240 		/* Disabling AC charger effect on sleep-active transitions */
241 		err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data,
242 				      R_CFG_P1_TRANSITION);
243 		if (err)
244 			goto out;
245 		data &= ~(1<<1);
246 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data,
247 				       R_CFG_P1_TRANSITION);
248 		if (err)
249 			goto out;
250 	}
251 
252 out:
253 	if (err)
254 		pr_err("TWL4030 wakeup sequence for P1 and P2" \
255 			"config error\n");
256 	return err;
257 }
258 
259 static int twl4030_config_sleep_sequence(u8 address)
260 {
261 	int err;
262 
263 	/* Set ACTIVE to SLEEP SEQ address in T2 memory*/
264 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_A2S);
265 
266 	if (err)
267 		pr_err("TWL4030 sleep sequence config error\n");
268 
269 	return err;
270 }
271 
272 static int twl4030_config_warmreset_sequence(u8 address)
273 {
274 	int err;
275 	u8 rd_data;
276 
277 	/* Set WARM RESET SEQ address for P1 */
278 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, address, R_SEQ_ADD_WARM);
279 	if (err)
280 		goto out;
281 
282 	/* P1/P2/P3 enable WARMRESET */
283 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P1_SW_EVENTS);
284 	if (err)
285 		goto out;
286 
287 	rd_data |= PWR_ENABLE_WARMRESET;
288 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P1_SW_EVENTS);
289 	if (err)
290 		goto out;
291 
292 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P2_SW_EVENTS);
293 	if (err)
294 		goto out;
295 
296 	rd_data |= PWR_ENABLE_WARMRESET;
297 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P2_SW_EVENTS);
298 	if (err)
299 		goto out;
300 
301 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &rd_data, R_P3_SW_EVENTS);
302 	if (err)
303 		goto out;
304 
305 	rd_data |= PWR_ENABLE_WARMRESET;
306 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, rd_data, R_P3_SW_EVENTS);
307 out:
308 	if (err)
309 		pr_err("TWL4030 warmreset seq config error\n");
310 	return err;
311 }
312 
313 static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
314 {
315 	int rconfig_addr;
316 	int err;
317 	u8 type;
318 	u8 grp;
319 	u8 remap;
320 
321 	if (rconfig->resource > TOTAL_RESOURCES) {
322 		pr_err("TWL4030 Resource %d does not exist\n",
323 			rconfig->resource);
324 		return -EINVAL;
325 	}
326 
327 	rconfig_addr = res_config_addrs[rconfig->resource];
328 
329 	/* Set resource group */
330 	err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &grp,
331 			      rconfig_addr + DEV_GRP_OFFSET);
332 	if (err) {
333 		pr_err("TWL4030 Resource %d group could not be read\n",
334 			rconfig->resource);
335 		return err;
336 	}
337 
338 	if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) {
339 		grp &= ~DEV_GRP_MASK;
340 		grp |= rconfig->devgroup << DEV_GRP_SHIFT;
341 		err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
342 				       grp, rconfig_addr + DEV_GRP_OFFSET);
343 		if (err < 0) {
344 			pr_err("TWL4030 failed to program devgroup\n");
345 			return err;
346 		}
347 	}
348 
349 	/* Set resource types */
350 	err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &type,
351 				rconfig_addr + TYPE_OFFSET);
352 	if (err < 0) {
353 		pr_err("TWL4030 Resource %d type could not be read\n",
354 			rconfig->resource);
355 		return err;
356 	}
357 
358 	if (rconfig->type != TWL4030_RESCONFIG_UNDEF) {
359 		type &= ~TYPE_MASK;
360 		type |= rconfig->type << TYPE_SHIFT;
361 	}
362 
363 	if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) {
364 		type &= ~TYPE2_MASK;
365 		type |= rconfig->type2 << TYPE2_SHIFT;
366 	}
367 
368 	err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
369 				type, rconfig_addr + TYPE_OFFSET);
370 	if (err < 0) {
371 		pr_err("TWL4030 failed to program resource type\n");
372 		return err;
373 	}
374 
375 	/* Set remap states */
376 	err = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &remap,
377 			      rconfig_addr + REMAP_OFFSET);
378 	if (err < 0) {
379 		pr_err("TWL4030 Resource %d remap could not be read\n",
380 			rconfig->resource);
381 		return err;
382 	}
383 
384 	if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) {
385 		remap &= ~OFF_STATE_MASK;
386 		remap |= rconfig->remap_off << OFF_STATE_SHIFT;
387 	}
388 
389 	if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) {
390 		remap &= ~SLEEP_STATE_MASK;
391 		remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT;
392 	}
393 
394 	err = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
395 			       remap,
396 			       rconfig_addr + REMAP_OFFSET);
397 	if (err < 0) {
398 		pr_err("TWL4030 failed to program remap\n");
399 		return err;
400 	}
401 
402 	return 0;
403 }
404 
405 static int load_twl4030_script(struct twl4030_script *tscript,
406 	       u8 address)
407 {
408 	int err;
409 	static int order;
410 
411 	/* Make sure the script isn't going beyond last valid address (0x3f) */
412 	if ((address + tscript->size) > END_OF_SCRIPT) {
413 		pr_err("TWL4030 scripts too big error\n");
414 		return -EINVAL;
415 	}
416 
417 	err = twl4030_write_script(address, tscript->script, tscript->size);
418 	if (err)
419 		goto out;
420 
421 	if (tscript->flags & TWL4030_WRST_SCRIPT) {
422 		err = twl4030_config_warmreset_sequence(address);
423 		if (err)
424 			goto out;
425 	}
426 	if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) {
427 		/* Reset any existing sleep script to avoid hangs on reboot */
428 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
429 				       R_SEQ_ADD_A2S);
430 		if (err)
431 			goto out;
432 
433 		err = twl4030_config_wakeup12_sequence(address);
434 		if (err)
435 			goto out;
436 		order = 1;
437 	}
438 	if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) {
439 		err = twl4030_config_wakeup3_sequence(address);
440 		if (err)
441 			goto out;
442 	}
443 	if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
444 		if (!order)
445 			pr_warning("TWL4030: Bad order of scripts (sleep "\
446 					"script before wakeup) Leads to boot"\
447 					"failure on some boards\n");
448 		err = twl4030_config_sleep_sequence(address);
449 	}
450 out:
451 	return err;
452 }
453 
454 int twl4030_remove_script(u8 flags)
455 {
456 	int err = 0;
457 
458 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
459 			       TWL4030_PM_MASTER_PROTECT_KEY);
460 	if (err) {
461 		pr_err("twl4030: unable to unlock PROTECT_KEY\n");
462 		return err;
463 	}
464 
465 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2,
466 			       TWL4030_PM_MASTER_PROTECT_KEY);
467 	if (err) {
468 		pr_err("twl4030: unable to unlock PROTECT_KEY\n");
469 		return err;
470 	}
471 
472 	if (flags & TWL4030_WRST_SCRIPT) {
473 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
474 				       R_SEQ_ADD_WARM);
475 		if (err)
476 			return err;
477 	}
478 	if (flags & TWL4030_WAKEUP12_SCRIPT) {
479 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
480 				       R_SEQ_ADD_S2A12);
481 		if (err)
482 			return err;
483 	}
484 	if (flags & TWL4030_WAKEUP3_SCRIPT) {
485 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
486 				       R_SEQ_ADD_S2A3);
487 		if (err)
488 			return err;
489 	}
490 	if (flags & TWL4030_SLEEP_SCRIPT) {
491 		err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, END_OF_SCRIPT,
492 				       R_SEQ_ADD_A2S);
493 		if (err)
494 			return err;
495 	}
496 
497 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
498 			       TWL4030_PM_MASTER_PROTECT_KEY);
499 	if (err)
500 		pr_err("TWL4030 Unable to relock registers\n");
501 
502 	return err;
503 }
504 
505 static int twl4030_power_configure_scripts(struct twl4030_power_data *pdata)
506 {
507 	int err;
508 	int i;
509 	u8 address = twl4030_start_script_address;
510 
511 	for (i = 0; i < pdata->num; i++) {
512 		err = load_twl4030_script(pdata->scripts[i], address);
513 		if (err)
514 			return err;
515 		address += pdata->scripts[i]->size;
516 	}
517 
518 	return 0;
519 }
520 
521 static int twl4030_power_configure_resources(struct twl4030_power_data *pdata)
522 {
523 	struct twl4030_resconfig *resconfig = pdata->resource_config;
524 	int err;
525 
526 	if (resconfig) {
527 		while (resconfig->resource) {
528 			err = twl4030_configure_resource(resconfig);
529 			if (err)
530 				return err;
531 			resconfig++;
532 		}
533 	}
534 
535 	return 0;
536 }
537 
538 /*
539  * In master mode, start the power off sequence.
540  * After a successful execution, TWL shuts down the power to the SoC
541  * and all peripherals connected to it.
542  */
543 void twl4030_power_off(void)
544 {
545 	int err;
546 
547 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, PWR_DEVOFF,
548 			       TWL4030_PM_MASTER_P1_SW_EVENTS);
549 	if (err)
550 		pr_err("TWL4030 Unable to power off\n");
551 }
552 
553 static bool twl4030_power_use_poweroff(struct twl4030_power_data *pdata,
554 					struct device_node *node)
555 {
556 	if (pdata && pdata->use_poweroff)
557 		return true;
558 
559 	if (of_property_read_bool(node, "ti,use_poweroff"))
560 		return true;
561 
562 	return false;
563 }
564 
565 static int twl4030_power_probe(struct platform_device *pdev)
566 {
567 	struct twl4030_power_data *pdata = dev_get_platdata(&pdev->dev);
568 	struct device_node *node = pdev->dev.of_node;
569 	int err = 0;
570 	int err2 = 0;
571 	u8 val;
572 
573 	if (!pdata && !node) {
574 		dev_err(&pdev->dev, "Platform data is missing\n");
575 		return -EINVAL;
576 	}
577 
578 	err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1,
579 			       TWL4030_PM_MASTER_PROTECT_KEY);
580 	err |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
581 			       TWL4030_PM_MASTER_KEY_CFG2,
582 			       TWL4030_PM_MASTER_PROTECT_KEY);
583 
584 	if (err) {
585 		pr_err("TWL4030 Unable to unlock registers\n");
586 		return err;
587 	}
588 
589 	if (pdata) {
590 		/* TODO: convert to device tree */
591 		err = twl4030_power_configure_scripts(pdata);
592 		if (err) {
593 			pr_err("TWL4030 failed to load scripts\n");
594 			goto relock;
595 		}
596 		err = twl4030_power_configure_resources(pdata);
597 		if (err) {
598 			pr_err("TWL4030 failed to configure resource\n");
599 			goto relock;
600 		}
601 	}
602 
603 	/* Board has to be wired properly to use this feature */
604 	if (twl4030_power_use_poweroff(pdata, node) && !pm_power_off) {
605 		/* Default for SEQ_OFFSYNC is set, lets ensure this */
606 		err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &val,
607 				      TWL4030_PM_MASTER_CFG_P123_TRANSITION);
608 		if (err) {
609 			pr_warning("TWL4030 Unable to read registers\n");
610 
611 		} else if (!(val & SEQ_OFFSYNC)) {
612 			val |= SEQ_OFFSYNC;
613 			err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, val,
614 					TWL4030_PM_MASTER_CFG_P123_TRANSITION);
615 			if (err) {
616 				pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
617 				goto relock;
618 			}
619 		}
620 
621 		pm_power_off = twl4030_power_off;
622 	}
623 
624 relock:
625 	err2 = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0,
626 			       TWL4030_PM_MASTER_PROTECT_KEY);
627 	if (err2) {
628 		pr_err("TWL4030 Unable to relock registers\n");
629 		return err2;
630 	}
631 
632 	return err;
633 }
634 
635 static int twl4030_power_remove(struct platform_device *pdev)
636 {
637 	return 0;
638 }
639 
640 #ifdef CONFIG_OF
641 static const struct of_device_id twl4030_power_of_match[] = {
642 	{.compatible = "ti,twl4030-power", },
643 	{ },
644 };
645 MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
646 #endif
647 
648 static struct platform_driver twl4030_power_driver = {
649 	.driver = {
650 		.name	= "twl4030_power",
651 		.owner	= THIS_MODULE,
652 		.of_match_table = of_match_ptr(twl4030_power_of_match),
653 	},
654 	.probe		= twl4030_power_probe,
655 	.remove		= twl4030_power_remove,
656 };
657 
658 module_platform_driver(twl4030_power_driver);
659 
660 MODULE_AUTHOR("Nokia Corporation");
661 MODULE_AUTHOR("Texas Instruments, Inc.");
662 MODULE_DESCRIPTION("Power management for TWL4030");
663 MODULE_LICENSE("GPL");
664 MODULE_ALIAS("platform:twl4030_power");
665