PageRenderTime 32ms CodeModel.GetById 16ms app.highlight 10ms RepoModel.GetById 2ms app.codeStats 0ms

/arch/arm/mach-mxs/ocotp.c

https://github.com/AICP/kernel_asus_grouper
C | 92 lines | 46 code | 23 blank | 23 comment | 8 complexity | 085767517d288ad24937160746f7589c MD5 | raw file
 1/*
 2 * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
 3 *
 4 * This program is free software; you can redistribute it and/or modify
 5 * it under the terms of the GNU General Public License as published by
 6 * the Free Software Foundation; either version 2 of the License, or
 7 * (at your option) any later version.
 8 *
 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 */
14
15#include <linux/delay.h>
16#include <linux/err.h>
17#include <linux/mutex.h>
18
19#include <asm/processor.h>	/* for cpu_relax() */
20
21#include <mach/mxs.h>
22
23#define OCOTP_WORD_OFFSET		0x20
24#define OCOTP_WORD_COUNT		0x20
25
26#define BM_OCOTP_CTRL_BUSY		(1 << 8)
27#define BM_OCOTP_CTRL_ERROR		(1 << 9)
28#define BM_OCOTP_CTRL_RD_BANK_OPEN	(1 << 12)
29
30static DEFINE_MUTEX(ocotp_mutex);
31static u32 ocotp_words[OCOTP_WORD_COUNT];
32
33const u32 *mxs_get_ocotp(void)
34{
35	void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
36	int timeout = 0x400;
37	size_t i;
38	static int once = 0;
39
40	if (once)
41		return ocotp_words;
42
43	mutex_lock(&ocotp_mutex);
44
45	/*
46	 * clk_enable(hbus_clk) for ocotp can be skipped
47	 * as it must be on when system is running.
48	 */
49
50	/* try to clear ERROR bit */
51	__mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
52
53	/* check both BUSY and ERROR cleared */
54	while ((__raw_readl(ocotp_base) &
55		(BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
56		cpu_relax();
57
58	if (unlikely(!timeout))
59		goto error_unlock;
60
61	/* open OCOTP banks for read */
62	__mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
63
64	/* approximately wait 32 hclk cycles */
65	udelay(1);
66
67	/* poll BUSY bit becoming cleared */
68	timeout = 0x400;
69	while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
70		cpu_relax();
71
72	if (unlikely(!timeout))
73		goto error_unlock;
74
75	for (i = 0; i < OCOTP_WORD_COUNT; i++)
76		ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
77						i * 0x10);
78
79	/* close banks for power saving */
80	__mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
81
82	once = 1;
83
84	mutex_unlock(&ocotp_mutex);
85
86	return ocotp_words;
87
88error_unlock:
89	mutex_unlock(&ocotp_mutex);
90	pr_err("%s: timeout in reading OCOTP\n", __func__);
91	return NULL;
92}