123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- /*
- * drivers/misc/sec_param.c
- *
- * Copyright (c) 2011 Samsung Electronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
- #include <linux/module.h>
- #include <linux/device.h>
- #include <linux/slab.h>
- #include <linux/fs.h>
- #include <linux/uaccess.h>
- #include <linux/sec_param.h>
- #include <linux/file.h>
- #include <linux/syscalls.h>
- #define PARAM_RD 0
- #define PARAM_WR 1
- #define SEC_PARAM_FILE_NAME "/dev/block/platform/msm_sdcc.1/by-name/param" /* parameter block */
- #if defined(CONFIG_PARAM_SIZE_983000)
- #define SEC_PARAM_FILE_SIZE 0x983000 /* 9.5MB */
- #else
- #define SEC_PARAM_FILE_SIZE 0xA00000 /* 10MB */
- #endif
- #define SEC_PARAM_FILE_OFFSET (SEC_PARAM_FILE_SIZE - 0x100000)
- /* single global instance */
- struct sec_param_data *param_data;
- static bool param_sec_operation(void *value, int offset,
- int size, int direction)
- {
- /* Read from PARAM(parameter) partition */
- struct file *filp;
- mm_segment_t fs;
- int ret = true;
- int flag = (direction == PARAM_WR) ? (O_RDWR | O_SYNC) : O_RDONLY;
- pr_debug("%s %p %x %d %d\n", __func__, value, offset, size, direction);
- filp = filp_open(SEC_PARAM_FILE_NAME, flag, 0);
- if (IS_ERR(filp)) {
- pr_err("%s: filp_open failed. (%ld)\n",
- __func__, PTR_ERR(filp));
- return false;
- }
- fs = get_fs();
- set_fs(get_ds());
- ret = filp->f_op->llseek(filp, offset, SEEK_SET);
- if (ret < 0) {
- pr_err("%s FAIL LLSEEK\n", __func__);
- ret = false;
- goto param_sec_debug_out;
- }
- if (direction == PARAM_RD)
- ret = filp->f_op->read(filp, (char __user *)value,
- size, &filp->f_pos);
- else if (direction == PARAM_WR)
- ret = filp->f_op->write(filp, (char __user *)value,
- size, &filp->f_pos);
- param_sec_debug_out:
- set_fs(fs);
- filp_close(filp, NULL);
- return ret;
- }
- bool sec_open_param(void)
- {
- int ret = true;
- int offset = SEC_PARAM_FILE_OFFSET;
- if (param_data != NULL)
- return true;
- param_data = kmalloc(sizeof(struct sec_param_data), GFP_KERNEL);
- ret = param_sec_operation(param_data, offset,
- sizeof(struct sec_param_data), PARAM_RD);
- if (!ret) {
- kfree(param_data);
- param_data = NULL;
- pr_err("%s PARAM OPEN FAIL\n", __func__);
- return false;
- }
- return ret;
- }
- EXPORT_SYMBOL(sec_open_param);
- bool sec_get_param(enum sec_param_index index, void *value)
- {
- int ret = true;
- ret = sec_open_param();
- if (!ret)
- return ret;
- switch (index) {
- case param_index_debuglevel:
- memcpy(value, &(param_data->debuglevel), sizeof(unsigned int));
- break;
- case param_index_uartsel:
- memcpy(value, &(param_data->uartsel), sizeof(unsigned int));
- break;
- case param_rory_control:
- memcpy(value, &(param_data->rory_control),
- sizeof(unsigned int));
- break;
- case param_index_movinand_checksum_done:
- memcpy(value, &(param_data->movinand_checksum_done),
- sizeof(unsigned int));
- break;
- case param_index_movinand_checksum_pass:
- memcpy(value, &(param_data->movinand_checksum_pass),
- sizeof(unsigned int));
- break;
- #if defined(CONFIG_MACH_APEXQ) || defined(CONFIG_MACH_AEGIS2)
- case param_slideCount:
- memcpy(value, &(param_data->slideCount),
- sizeof(unsigned int));
- break;
- #endif
- #if defined(CONFIG_GSM_MODEM_SPRD6500) || defined(CONFIG_SGLTE_QSC_MODEM)
- case param_update_cp_bin:
- memcpy(value, &(param_data->update_cp_bin),
- sizeof(unsigned int));
- printk(KERN_INFO "param_data.update_cp_bin :[%d]!!", param_data->update_cp_bin);
- break;
- #endif
- #ifdef CONFIG_RTC_AUTO_PWRON_PARAM
- case param_index_boot_alarm_set:
- memcpy(value, &(param_data->boot_alarm_set), sizeof(unsigned int));
- break;
- case param_index_boot_alarm_value_l:
- memcpy(value, &(param_data->boot_alarm_value_l), sizeof(unsigned int));
- break;
- case param_index_boot_alarm_value_h:
- memcpy(value, &(param_data->boot_alarm_value_h), sizeof(unsigned int));
- break;
- #endif
- #ifdef CONFIG_SEC_MONITOR_BATTERY_REMOVAL
- case param_index_normal_poweroff:
- memcpy(&(param_data->normal_poweroff), value, sizeof(unsigned int));
- break;
- #endif
- #ifdef CONFIG_RESTART_REASON_SEC_PARAM
- case param_index_restart_reason:
- memcpy(value, &(param_data->param_restart_reason), sizeof(unsigned int));
- break;
- #endif
- default:
- return false;
- }
- return true;
- }
- EXPORT_SYMBOL(sec_get_param);
- bool sec_set_param(enum sec_param_index index, void *value)
- {
- int ret = true;
- int offset = SEC_PARAM_FILE_OFFSET;
- ret = sec_open_param();
- if (!ret)
- return ret;
- switch (index) {
- case param_index_debuglevel:
- memcpy(&(param_data->debuglevel),
- value, sizeof(unsigned int));
- break;
- case param_index_uartsel:
- memcpy(&(param_data->uartsel),
- value, sizeof(unsigned int));
- break;
- case param_rory_control:
- memcpy(&(param_data->rory_control),
- value, sizeof(unsigned int));
- break;
- case param_index_movinand_checksum_done:
- memcpy(&(param_data->movinand_checksum_done),
- value, sizeof(unsigned int));
- break;
- case param_index_movinand_checksum_pass:
- memcpy(&(param_data->movinand_checksum_pass),
- value, sizeof(unsigned int));
- break;
- #if defined(CONFIG_MACH_APEXQ) || defined(CONFIG_MACH_AEGIS2)
- case param_slideCount:
- memcpy(&(param_data->slideCount),
- value, sizeof(unsigned int));
- break;
- #endif
- #if defined(CONFIG_GSM_MODEM_SPRD6500) || defined(CONFIG_SGLTE_QSC_MODEM)
- case param_update_cp_bin:
- memcpy(&(param_data->update_cp_bin),
- value, sizeof(unsigned int));
- break;
- #endif
- #ifdef CONFIG_RTC_AUTO_PWRON_PARAM
- case param_index_boot_alarm_set:
- memcpy(&(param_data->boot_alarm_set), value, sizeof(unsigned int));
- break;
- case param_index_boot_alarm_value_l:
- memcpy(&(param_data->boot_alarm_value_l), value, sizeof(unsigned int));
- break;
- case param_index_boot_alarm_value_h:
- memcpy(&(param_data->boot_alarm_value_h), value, sizeof(unsigned int));
- break;
- #endif
- #ifdef CONFIG_SEC_MONITOR_BATTERY_REMOVAL
- case param_index_normal_poweroff:
- memcpy(&(param_data->normal_poweroff), value, sizeof(unsigned int));
- break;
- #endif
- #ifdef CONFIG_RESTART_REASON_SEC_PARAM
- case param_index_restart_reason:
- memcpy(&(param_data->param_restart_reason),
- value, sizeof(unsigned int));
- break;
- #endif
- default:
- return false;
- }
- return param_sec_operation(param_data, offset,
- sizeof(struct sec_param_data), PARAM_WR);
- }
- EXPORT_SYMBOL(sec_set_param);
- /* ##########################################################
- * #
- * # SEC PARAM Driver sysfs file
- * # 1. movinand_checksum_done_show
- * # 2. movinand_checksum_pass_show
- * ##########################################################
- * */
- static struct class *sec_param_class;
- struct device *sec_param_dev;
- static ssize_t movinand_checksum_done_show
- (struct device *dev, struct device_attribute *attr, char *buf)
- {
- int ret = 0;
- sec_get_param(param_index_movinand_checksum_done, &ret);
- if (ret == 1 || ret == 0) {
- pr_err("checksum is not in valuable range.\n");
- ret = 1;
- }
- return snprintf(buf, PAGE_SIZE, "%u\n", ret);
- }
- static DEVICE_ATTR(movinand_checksum_done,
- 0664, movinand_checksum_done_show, NULL);
- static ssize_t movinand_checksum_pass_show
- (struct device *dev, struct device_attribute *attr, char *buf)
- {
- int ret = 0;
- sec_get_param(param_index_movinand_checksum_pass, &ret);
- if (ret == 1 || ret == 0) {
- pr_err("checksum is not in valuable range.\n");
- ret = 1;
- }
- return snprintf(buf, PAGE_SIZE, "%u\n", ret);
- }
- static DEVICE_ATTR(movinand_checksum_pass,
- 0664, movinand_checksum_pass_show, NULL);
- int sec_param_sysfs_init(void)
- {
- int ret = 0;
- sec_param_class = class_create(THIS_MODULE, "sec_param");
- if (IS_ERR(sec_param_class)) {
- pr_err("Failed to create class(mdnie_class)!!\n");
- ret = -1;
- goto failed_create_class;
- }
- sec_param_dev = device_create(sec_param_class,
- NULL, 0, NULL, "sec_param");
- if (IS_ERR(sec_param_dev)) {
- printk(KERN_ERR "Failed to create device(sec_param_dev)!!");
- ret = -1;
- goto failed_create_dev;
- }
- if (device_create_file(sec_param_dev,
- &dev_attr_movinand_checksum_done) < 0) {
- pr_err("Failed to create device file!(%s)!\n",
- dev_attr_movinand_checksum_done.attr.name);
- ret = -1;
- }
- if (device_create_file(sec_param_dev,
- &dev_attr_movinand_checksum_pass) < 0) {
- pr_err("Failed to create device file!(%s)!\n",
- dev_attr_movinand_checksum_pass.attr.name);
- ret = -1;
- }
- failed_create_class:
- return ret;
- failed_create_dev:
- class_destroy(sec_param_class);
- return ret;
- }
- module_init(sec_param_sysfs_init);
|