blob: 284118a888b73365e03f63a6a98239d9bddf7ee7 [file] [log] [blame]
Borjan Tchakaloff37ad1d32018-02-16 18:27:16 +01001/* linux/arch/arm/mach-msm/msm_ddr_sysctl.c
2 *
3 * Copyright 2017-2018 Fairphone B.V.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
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
16#include <linux/module.h>
17#include <linux/sysctl.h>
18#include <mach/msm_smem.h>
19#include "smem_private.h"
20
21
22/* DDR vendor identifiers (64-bits unsigned integer) */
23enum {
24 DDR_VENDOR_ID_INVALID = -1,
25 DDR_VENDOR_ID_SAMSUNG = 1,
26 DDR_VENDOR_ID_MICRON = 255,
27};
28
29/* Maximum DDR vendor name length */
30#define DDR_VENDOR_NAME_MAX_LEN 32
31
32/* DDR vendor names (shorter than DDR_VENDOR_NAME_MAX_LEN) */
33char *DDR_VENDOR_NAME_MICRON = "Micron";
34char *DDR_VENDOR_NAME_SAMSUNG = "Samsung";
35char *DDR_VENDOR_NAME_UNKNOWN = "Unknown";
36
37static char ddr_vendor[DDR_VENDOR_NAME_MAX_LEN] = "";
38
39static struct ctl_table_header *ddr_table_header;
40
41static ctl_table ddr_vendor_table[] = {
42 {
43 .procname = "vendor",
44 .data = ddr_vendor,
45 .maxlen = DDR_VENDOR_NAME_MAX_LEN,
46 .mode = 0444,
47 .proc_handler = proc_dostring,
48 },
49 {}
50};
51
52static ctl_table ddr_dir_table[] = {
53 {
54 .procname = "ddr",
55 .mode = 0555,
56 .child = ddr_vendor_table,
57 },
58 {}
59};
60
61static ctl_table dev_root_table[] = {
62 {
63 .procname = "dev",
64 .mode = 0555,
65 .child = ddr_dir_table,
66 },
67 {}
68};
69
70
71static int get_ddr_vendor_id_from_smem(void) {
72 unsigned int smem_size;
73 unsigned int *smem_ddr_vendor_id;
74
75 smem_ddr_vendor_id = smem_get_entry(SMEM_DDR_VENDOR_ID, &smem_size);
76 if (smem_ddr_vendor_id == NULL) {
77 printk("Could not get the DDR vendor identifier from SMEM\n");
78 return DDR_VENDOR_ID_INVALID;
79 }
80
81 return (int) *smem_ddr_vendor_id;
82}
83
84static int __init msm_ddr_init(void) {
85 switch (get_ddr_vendor_id_from_smem()) {
86 case DDR_VENDOR_ID_MICRON:
87 strncpy(ddr_vendor, DDR_VENDOR_NAME_MICRON, DDR_VENDOR_NAME_MAX_LEN);
88 break;
89 case DDR_VENDOR_ID_SAMSUNG:
90 strncpy(ddr_vendor, DDR_VENDOR_NAME_SAMSUNG, DDR_VENDOR_NAME_MAX_LEN);
91 break;
92 case DDR_VENDOR_ID_INVALID:
93 default:
94 strncpy(ddr_vendor, DDR_VENDOR_NAME_UNKNOWN, DDR_VENDOR_NAME_MAX_LEN);
95 break;
96 }
97 ddr_vendor[DDR_VENDOR_NAME_MAX_LEN-1] = '\0';
98
99 ddr_table_header = register_sysctl_table(dev_root_table);
100 if (!ddr_table_header)
101 return -ENOMEM;
102
103 return 0;
104}
105
106static void __exit msm_ddr_exit(void) {
107 unregister_sysctl_table(ddr_table_header);
108}
109
110module_init(msm_ddr_init);
111module_exit(msm_ddr_exit);
112MODULE_LICENSE("GPL");
113MODULE_DESCRIPTION("DDR information");