void mvg_emmc_nanodelay(u32 delay_ns) { //struct timespec t_start,t_end1; get_monotonic_boottime(&t_hr_start); do { get_monotonic_boottime(&t_hr_end1); if ( t_hr_end1.tv_nsec< t_hr_start.tv_nsec ) { t_hr_end1.tv_nsec=1000000000+t_hr_end1.tv_nsec-t_hr_start.tv_nsec; } else { t_hr_end1.tv_nsec=t_hr_end1.tv_nsec-t_hr_start.tv_nsec; } if ( t_hr_end1.tv_nsec>delay_ns ) break; } while(1); }
static long kfd_ioctl_get_clock_counters(struct file *filep, struct kfd_process *p, void __user *arg) { struct kfd_ioctl_get_clock_counters_args args; struct kfd_dev *dev; struct timespec time; if (copy_from_user(&args, arg, sizeof(args))) return -EFAULT; dev = kfd_device_by_id(args.gpu_id); if (dev == NULL) return -EINVAL; /* Reading GPU clock counter from KGD */ args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); /* No access to rdtsc. Using raw monotonic time */ getrawmonotonic(&time); args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time); get_monotonic_boottime(&time); args.system_clock_counter = (uint64_t)timespec_to_ns(&time); /* Since the counter is in nano-seconds we use 1GHz frequency */ args.system_clock_freq = 1000000000; if (copy_to_user(arg, &args, sizeof(args))) return -EFAULT; return 0; }
static int alarm_get_time(enum android_alarm_type alarm_type, struct timespec *ts) { int rv = 0; switch (alarm_type) { #ifdef CONFIG_BCM_RTC_ALARM_BOOT case ANDROID_ALARM_RTC_POWERON: #endif case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: getnstimeofday(ts); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: get_monotonic_boottime(ts); break; case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(ts); break; default: rv = -EINVAL; } return rv; }
irqreturn_t stml0xx_isr(int irq, void *dev) { static struct timespec ts; static struct stml0xx_work_struct *stm_ws; struct stml0xx_data *ps_stml0xx = dev; get_monotonic_boottime(&ts); if (stml0xx_irq_disable) return IRQ_HANDLED; stm_ws = kmalloc( sizeof(struct stml0xx_work_struct), GFP_ATOMIC); if (!stm_ws) { dev_err(&ps_stml0xx->spi->dev, "stml0xx_isr: unable to allocate work struct"); return IRQ_HANDLED; } INIT_WORK((struct work_struct *)stm_ws, stml0xx_irq_work_func); stm_ws->ts_ns = ts_to_ns(ts); queue_work(ps_stml0xx->irq_work_queue, (struct work_struct *)stm_ws); return IRQ_HANDLED; }
void addTimeAndBusyWait(struct timespec* time, long nanoseconds) { addTime(time, nanoseconds); struct timespec actualTime; do { get_monotonic_boottime(&actualTime); } while (timespec_compare(time, &actualTime) > 0); }
static int64_t getCurNS(void) { int64_t ns; struct timespec time; time.tv_sec = time.tv_nsec = 0; get_monotonic_boottime(&time); ns = time.tv_sec * 1000000000LL + time.tv_nsec; return ns; }
static irqreturn_t sensordata_irq_thread_fn(int iIrq, void *dev_id) { struct ssp_data *data = dev_id; struct timespec ts; get_monotonic_boottime(&ts); data->timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec; select_irq_msg(data); data->uIrqCnt++; return IRQ_HANDLED; }
static void android_bat_set_charge_time(struct android_bat_data *battery, bool enable) { if (enable && !battery->charging_start_time) { struct timespec cur_time; get_monotonic_boottime(&cur_time); /* record start time for charge timeout timer */ battery->charging_start_time = cur_time.tv_sec; } else if (!enable) { /* clear charge timeout timer */ battery->charging_start_time = 0; } }
static bool android_bat_charge_timeout(struct android_bat_data *battery, unsigned long timeout) { struct timespec cur_time; if (!battery->charging_start_time) return 0; get_monotonic_boottime(&cur_time); pr_debug("%s: Start time: %ld, End time: %ld, current time: %ld\n", __func__, battery->charging_start_time, battery->charging_start_time + timeout, cur_time.tv_sec); return cur_time.tv_sec >= battery->charging_start_time + timeout; }
static void cw_update_time_member_capacity_change(struct cw_battery *cw_bat) { struct timespec ts; int new_run_time; int new_sleep_time; ktime_get_ts(&ts); new_run_time = ts.tv_sec; get_monotonic_boottime(&ts); new_sleep_time = ts.tv_sec - new_run_time; cw_bat->run_time_capacity_change = new_run_time; cw_bat->sleep_time_capacity_change = new_sleep_time; }
static int uptime_show(struct seq_file *m, void *v) { NsRule *ptr = find_sandbox(current->nsproxy); if (ptr) { unsigned long long delta; struct timespec uptime; #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)) do_posix_clock_monotonic_gettime(&uptime); monotonic_to_bootbased(&uptime); #else get_monotonic_boottime(&uptime); #endif delta = (unsigned long long) uptime.tv_sec - (unsigned long long) ptr->real_start_time.tv_sec; seq_printf(m, "%llu 0\n", delta); } else seq_printf(m, "0 0\n"); return 0; }
static int android_power_debug_dump(struct seq_file *s, void *unused) { struct android_bat_data *battery = s->private; struct timespec cur_time; android_bat_update_data(battery); get_monotonic_boottime(&cur_time); mutex_lock(&android_bat_state_lock); seq_printf(s, "l=%d v=%d c=%d temp=%s%ld.%ld h=%d st=%d%s ct=%lu type=%s\n", battery->batt_soc, battery->batt_vcell/1000, battery->batt_current, battery->batt_temp < 0 ? "-" : "", abs(battery->batt_temp / 10), abs(battery->batt_temp % 10), battery->batt_health, battery->charging_status, battery->recharging ? "r" : "", battery->charging_start_time ? cur_time.tv_sec - battery->charging_start_time : 0, charge_source_str(battery->charge_source)); mutex_unlock(&android_bat_state_lock); return 0; }
static int get_usb_charge_state(struct cw_battery *cw_bat) { int charge_time; int time_from_boot; struct timespec ts; int gadget_status = get_gadget_connect_flag(); int usb_status = dwc_vbus_status(); get_monotonic_boottime(&ts); time_from_boot = ts.tv_sec; if (cw_bat->charger_init_mode) { if (usb_status == 1 || usb_status == 2) { cw_bat->charger_init_mode = 0; } else if (time_from_boot < 8) { usb_status = cw_bat->charger_init_mode; } else if (strstr(saved_command_line,"charger")) { cw_bat->charger_init_mode = dwc_otg_check_dpdm(); usb_status = cw_bat->charger_init_mode; } } #ifdef NO_STANDARD_AC_BIG_CHARGE_MODE if (cw_bat->usb_online == 1) { charge_time = time_from_boot - cw_bat->sleep_time_charge_start - cw_bat->run_time_charge_start; if (charge_time > 3) { if (gadget_status == 0 && dwc_vbus_status() == 1) { usb_status = 2; } } } #endif return usb_status; dev_dbg(&cw_bat->client->dev, "%s usb_status=[%d],cw_bat->charger_mode=[%d],cw_bat->gadget_status=[%d], cw_bat->charger_init_mode = [%d]\n",__func__,usb_status,cw_bat->charger_mode,gadget_status, cw_bat->charger_init_mode); }
int stml0xx_ms_data_buffer_write(struct stml0xx_data *ps_stml0xx, unsigned char type, unsigned char *data, int size) { int new_head; struct stml0xx_moto_sensor_data *buffer; struct timespec ts; static bool error_reported; new_head = (ps_stml0xx->stml0xx_ms_data_buffer_head + 1) & STML0XX_MS_DATA_QUEUE_MASK; if (new_head == ps_stml0xx->stml0xx_ms_data_buffer_tail) { if (!error_reported) { dev_err(&stml0xx_misc_data->spi->dev, "ms data buffer full"); error_reported = true; } wake_up(&ps_stml0xx->stml0xx_ms_data_wq); return 0; } buffer = &(ps_stml0xx->stml0xx_ms_data_buffer[new_head]); buffer->type = type; if (data != NULL && size > 0) { if (size > sizeof(buffer->data)) { dev_err(&stml0xx_misc_data->spi->dev, "size %d exceeds ms buffer", size); return 0; } memcpy(buffer->data, data, size); } buffer->size = size; get_monotonic_boottime(&ts); buffer->timestamp = ts.tv_sec * 1000000000LL + ts.tv_nsec; ps_stml0xx->stml0xx_ms_data_buffer_head = new_head; wake_up(&ps_stml0xx->stml0xx_ms_data_wq); error_reported = false; return 1; }
/* Send a single command to the chip. * * If the SR (suppress response bit) is NOT set, will read the * response and cache it the driver object retrieve with escore_resp(). * * Returns: * 0 - on success. * EITIMEDOUT - if the chip did not respond in within the expected time. * E* - any value that can be returned by the underlying HAL. */ int escore_cmd(struct escore_priv *escore, u32 cmd) { int sr; int err; u32 resp; BUG_ON(!escore); sr = cmd & BIT(28); err = escore->cmd(escore, cmd, sr, &resp); if (err || sr) return err; if (resp == 0) { err = -ETIMEDOUT; dev_err(escore->dev, "no response to command 0x%08x\n", cmd); } else { escore->last_response = resp; get_monotonic_boottime(&escore->last_resp_time); } return err; }
static int stml0xx_resume(struct device *dev) { static struct timespec ts; static struct stml0xx_delayed_work_struct *stm_ws; struct stml0xx_data *ps_stml0xx = spi_get_drvdata(to_spi_device(dev)); get_monotonic_boottime(&ts); dev_dbg(&stml0xx_misc_data->spi->dev, "%s", __func__); mutex_lock(&ps_stml0xx->lock); ps_stml0xx->is_suspended = false; enable_irq(ps_stml0xx->irq); if (ps_stml0xx->pending_wake_work) { stm_ws = kmalloc( sizeof(struct stml0xx_delayed_work_struct), GFP_ATOMIC); if (!stm_ws) { dev_err(dev, "stml0xx_resume: unable to allocate work struct"); return 0; } INIT_DELAYED_WORK((struct delayed_work *)stm_ws, stml0xx_irq_wake_work_func); stm_ws->ts_ns = ts_to_ns(ts); queue_delayed_work(ps_stml0xx->irq_work_queue, (struct delayed_work *)stm_ws, 0); ps_stml0xx->pending_wake_work = false; } if (stml0xx_irq_disable == 0) queue_work(ps_stml0xx->irq_work_queue, &ps_stml0xx->clear_interrupt_status_work); mutex_unlock(&ps_stml0xx->lock); return 0; }
static void android_bat_monitor_work(struct work_struct *work) { struct android_bat_data *battery = container_of(work, struct android_bat_data, monitor_work); struct timespec cur_time; wake_lock(&battery->monitor_wake_lock); android_bat_update_data(battery); mutex_lock(&android_bat_state_lock); switch (battery->charging_status) { case POWER_SUPPLY_STATUS_FULL: if (battery->batt_vcell < battery->pdata->recharging_voltage && !battery->recharging) { battery->recharging = true; android_bat_enable_charging(battery, true); pr_info("battery: start recharging, v=%d\n", battery->batt_vcell/1000); } break; case POWER_SUPPLY_STATUS_DISCHARGING: break; case POWER_SUPPLY_STATUS_CHARGING: switch (battery->batt_health) { case POWER_SUPPLY_HEALTH_OVERHEAT: case POWER_SUPPLY_HEALTH_COLD: case POWER_SUPPLY_HEALTH_OVERVOLTAGE: case POWER_SUPPLY_HEALTH_DEAD: case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE: battery->charging_status = POWER_SUPPLY_STATUS_NOT_CHARGING; android_bat_enable_charging(battery, false); pr_info("battery: Not charging, health=%d\n", battery->batt_health); break; default: break; } break; case POWER_SUPPLY_STATUS_NOT_CHARGING: if (battery->batt_health == POWER_SUPPLY_HEALTH_GOOD) { pr_info("battery: battery health recovered\n"); if (battery->charge_source != CHARGE_SOURCE_NONE) { android_bat_enable_charging(battery, true); battery->charging_status = POWER_SUPPLY_STATUS_CHARGING; } else { battery->charging_status = POWER_SUPPLY_STATUS_DISCHARGING; } } break; default: pr_err("%s: Undefined battery status: %d\n", __func__, battery->charging_status); break; } android_bat_charging_timer(battery); get_monotonic_boottime(&cur_time); pr_info("battery: l=%d v=%d c=%d temp=%s%ld.%ld h=%d st=%d%s ct=%lu type=%s\n", battery->batt_soc, battery->batt_vcell/1000, battery->batt_current, battery->batt_temp < 0 ? "-" : "", abs(battery->batt_temp / 10), abs(battery->batt_temp % 10), battery->batt_health, battery->charging_status, battery->recharging ? "r" : "", battery->charging_start_time ? cur_time.tv_sec - battery->charging_start_time : 0, charge_source_str(battery->charge_source)); mutex_unlock(&android_bat_state_lock); power_supply_changed(&battery->psy_bat); battery->last_poll = ktime_get_boottime(); android_bat_monitor_set_alarm(battery, FAST_POLL); wake_unlock(&battery->monitor_wake_lock); return; }
static int posix_get_boottime(const clockid_t which_clock, struct timespec *tp) { get_monotonic_boottime(tp); return 0; }
void txSender(unsigned long argument) { GpioUart* uart = (GpioUart*)argument; spinlock_t locker; spin_lock_init(&locker); struct timespec lastBitTime; get_monotonic_boottime(&lastBitTime); // What is the delay for a bit in nanoseconds? long bitDelay = 1000000000L / uart->baudRate; // We can send multiple bytes at once, if it will not take too long. // Let us take up to half a millisecond if our first byte will take less than that // (so we will go as long as necessary to get one byte out) int bitsFrame = 10 + (uart->secondStopBit ? 1 : 0) + (uart->parityBit ? 1 : 0); int bytesToDo = 500000 / bitDelay / bitsFrame; // But at least one byte... bytesToDo = (bytesToDo == 0) ? 1 : bytesToDo; for (int i = 0;i < bytesToDo; i++) { // Have we a byte to send? int byteToSend = removeTxByte(uart); if (byteToSend != -1) { // We use the spinlock to disable interrupts so that we can busy-wait exact timing // TESTING //spin_lock_irqsave(&locker, savedFlags); spin_lock_bh(&locker); // Make sure we have at least the required stop bits before our start bit long stopBitNanoseconds = bitDelay + (uart->secondStopBit ? bitDelay : 0); // Start bit holdAndSetTx(uart, false, &lastBitTime, stopBitNanoseconds); int bits = byteToSend; int parity = 0; // UART is Least Significant Bit first for (int i = 0;i < 8; i++) { // Keep track of parity parity ^= (bits & 1); // Send the value of the lowest bit holdAndSetTx(uart, bits & 1, &lastBitTime, bitDelay); // Shift out the just-transmitted bit bits >>= 1; } // Parity bit if (uart->parityBit) { holdAndSetTx(uart, parity, &lastBitTime, bitDelay); } // Stop bit(s), though we don't wait for them... holdAndSetTx(uart, true, &lastBitTime, bitDelay); // The byte is done! //TESTING //spin_unlock_irqrestore(&locker, savedFlags); spin_unlock_bh(&locker); } }
static int cw_get_capacity(struct cw_battery *cw_bat) { int ret; u8 reg_val[2]; struct timespec ts; long new_run_time; long new_sleep_time; long capacity_or_aconline_time; int allow_change; int allow_capacity; static int if_quickstart; static int jump_flag; static int jump_flag2; static int reset_loop; int charge_time; u8 reset_val; ret = cw_i2c_read(cw_bat->client, REG_SOC, reg_val, 2); if (ret < 0) return ret; cw_capacity = reg_val[0]; if ((cw_capacity < 0) || (cw_capacity > 100)) { dev_err(&cw_bat->client->dev, "get cw_capacity error; cw_capacity = %d\n", cw_capacity); reset_loop++; if (reset_loop > 5) { reset_val = MODE_SLEEP; ret = cw_i2c_write(cw_bat->client, REG_MODE, &reset_val, 1); if (ret < 0) return ret; reset_val = MODE_NORMAL; msleep(10); ret = cw_i2c_write(cw_bat->client, REG_MODE, &reset_val, 1); if (ret < 0) return ret; dev_dbg(&cw_bat->client->dev, "report battery capacity error"); ret = cw_update_config_info(cw_bat); if (ret) return ret; reset_loop = 0; } return cw_capacity; } else { reset_loop = 0; } if (cw_capacity == 0) dev_dbg(&cw_bat->client->dev, "the cw201x capacity is 0 !!!!!!!, funciton: %s, line: %d\n", __func__, __LINE__); else dev_dbg(&cw_bat->client->dev, "the cw201x capacity is %d, funciton: %s\n", cw_capacity, __func__); ktime_get_ts(&ts); new_run_time = ts.tv_sec; get_monotonic_boottime(&ts); new_sleep_time = ts.tv_sec - new_run_time; if (((cw_bat->charger_mode > 0) && (cw_capacity <= (cw_bat->capacity - 1)) && (cw_capacity > (cw_bat->capacity - 30/*9*/))) || ((cw_bat->charger_mode == 0) && (cw_capacity == (cw_bat->capacity + 1)))) { if (!(cw_capacity == 0 && cw_bat->capacity <= 2)) { cw_capacity = cw_bat->capacity; } } if ((cw_bat->charger_mode > 0) && (cw_capacity >= 95) && (cw_capacity <= cw_bat->capacity)) { capacity_or_aconline_time = (cw_bat->sleep_time_capacity_change > cw_bat->sleep_time_charge_start) ? cw_bat->sleep_time_capacity_change : cw_bat->sleep_time_charge_start; capacity_or_aconline_time += (cw_bat->run_time_capacity_change > cw_bat->run_time_charge_start) ? cw_bat->run_time_capacity_change : cw_bat->run_time_charge_start; allow_change = (new_sleep_time + new_run_time - capacity_or_aconline_time) / BATTERY_UP_MAX_CHANGE; if (allow_change > 0) { allow_capacity = cw_bat->capacity + allow_change; cw_capacity = (allow_capacity <= 100) ? allow_capacity : 100; jump_flag = 1; } else if (cw_capacity <= cw_bat->capacity) { cw_capacity = cw_bat->capacity; } } else if ((cw_bat->charger_mode == 0) && cw_bat->capacity == 100 && cw_capacity < cw_bat->capacity && jump_flag2 == 0) { cw_capacity = cw_bat->capacity; jump_flag2 = 1; } else if ((cw_bat->charger_mode == 0) && (cw_capacity <= cw_bat->capacity) && (cw_capacity >= 90) && ((jump_flag == 1) || (jump_flag2 == 1))) { capacity_or_aconline_time = (cw_bat->sleep_time_capacity_change > cw_bat->sleep_time_charge_start) ? cw_bat->sleep_time_capacity_change : cw_bat->sleep_time_charge_start; capacity_or_aconline_time += (cw_bat->run_time_capacity_change > cw_bat->run_time_charge_start) ? cw_bat->run_time_capacity_change : cw_bat->run_time_charge_start; allow_change = (new_sleep_time + new_run_time - capacity_or_aconline_time) / BATTERY_DOWN_CHANGE; if (allow_change > 0) { allow_capacity = cw_bat->capacity - allow_change; if (cw_capacity >= allow_capacity) { jump_flag = 0; jump_flag2 = 0; } else { cw_capacity = (allow_capacity <= 100) ? allow_capacity : 100; } } else if (cw_capacity <= cw_bat->capacity) { cw_capacity = cw_bat->capacity; } } if ((cw_capacity == 0) && (cw_bat->capacity > 1)) { allow_change = ((new_run_time - cw_bat->run_time_capacity_change) / BATTERY_DOWN_MIN_CHANGE_RUN); allow_change += ((new_sleep_time - cw_bat->sleep_time_capacity_change) / BATTERY_DOWN_MIN_CHANGE_SLEEP); allow_capacity = cw_bat->capacity - allow_change; cw_capacity = (allow_capacity >= cw_capacity) ? allow_capacity : cw_capacity; dev_dbg(&cw_bat->client->dev, "report GGIC POR happened"); reg_val[0] = MODE_NORMAL; ret = cw_i2c_write(cw_bat->client, REG_MODE, reg_val, 1); if (ret < 0) return ret; dev_dbg(&cw_bat->client->dev, "report battery capacity jump 0 "); } #if 1 if ((cw_bat->charger_mode > 0) && (cw_capacity == 0)) { charge_time = new_sleep_time + new_run_time - cw_bat->sleep_time_charge_start - cw_bat->run_time_charge_start; if ((charge_time > BATTERY_DOWN_MAX_CHANGE_RUN_AC_ONLINE) && (if_quickstart == 0)) { cw_quickstart(cw_bat); reset_val = MODE_SLEEP; ret = cw_i2c_write(cw_bat->client, REG_MODE, &reset_val, 1); if (ret < 0) return ret; reset_val = MODE_NORMAL; msleep(10); ret = cw_i2c_write(cw_bat->client, REG_MODE, &reset_val, 1); if (ret < 0) return ret; dev_dbg(&cw_bat->client->dev, "report battery capacity error"); ret = cw_update_config_info(cw_bat); if (ret) return ret; dev_dbg(&cw_bat->client->dev, "report battery capacity still 0 if in changing"); if_quickstart = 1; } } else if ((if_quickstart == 1) && (cw_bat->charger_mode == 0)) { if_quickstart = 0; } #endif #ifdef SYSTEM_SHUTDOWN_VOLTAGE if ((cw_bat->charger_mode == 0) && (cw_capacity <= 20) && (cw_bat->voltage <= SYSTEM_SHUTDOWN_VOLTAGE)) { if (if_quickstart == 10) { allow_change = ((new_run_time - cw_bat->run_time_capacity_change) / BATTERY_DOWN_MIN_CHANGE_RUN); allow_change += ((new_sleep_time - cw_bat->sleep_time_capacity_change) / BATTERY_DOWN_MIN_CHANGE_SLEEP); allow_capacity = cw_bat->capacity - allow_change; cw_capacity = (allow_capacity >= 0) ? allow_capacity : 0; if (cw_capacity < 1) { cw_quickstart(cw_bat); if_quickstart = 12; cw_capacity = 0; } } else if (if_quickstart <= 10) if_quickstart = if_quickstart+2; dev_dbg(&cw_bat->client->dev, "the cw201x voltage is less than SYSTEM_SHUTDOWN_VOLTAGE !!!!!!!, funciton: %s, line: %d\n", __func__, __LINE__); } else if ((cw_bat->charger_mode > 0) && (if_quickstart <= 12)) { if_quickstart = 0; } #endif return cw_capacity; }
/** * write_ipc_from_queue() - try to write ipc msg from Tx queue to device * @dev: ishtp device pointer * * Check if DRBL is cleared. if it is - write the first IPC msg, then call * the callback function (unless it's NULL) * * Return: 0 for success else failure code */ static int write_ipc_from_queue(struct ishtp_device *dev) { struct wr_msg_ctl_info *ipc_link; unsigned long length; unsigned long rem; unsigned long flags; uint32_t doorbell_val; uint32_t *r_buf; uint32_t reg_addr; int i; void (*ipc_send_compl)(void *); void *ipc_send_compl_prm; static int out_ipc_locked; unsigned long out_ipc_flags; if (dev->dev_state == ISHTP_DEV_DISABLED) return -EINVAL; spin_lock_irqsave(&dev->out_ipc_spinlock, out_ipc_flags); if (out_ipc_locked) { spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags); return -EBUSY; } out_ipc_locked = 1; if (!ish_is_input_ready(dev)) { out_ipc_locked = 0; spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags); return -EBUSY; } spin_unlock_irqrestore(&dev->out_ipc_spinlock, out_ipc_flags); spin_lock_irqsave(&dev->wr_processing_spinlock, flags); /* * if tx send list is empty - return 0; * may happen, as RX_COMPLETE handler doesn't check list emptiness. */ if (list_empty(&dev->wr_processing_list_head.link)) { spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); out_ipc_locked = 0; return 0; } ipc_link = list_entry(dev->wr_processing_list_head.link.next, struct wr_msg_ctl_info, link); /* first 4 bytes of the data is the doorbell value (IPC header) */ length = ipc_link->length - sizeof(uint32_t); doorbell_val = *(uint32_t *)ipc_link->inline_data; r_buf = (uint32_t *)(ipc_link->inline_data + sizeof(uint32_t)); /* If sending MNG_SYNC_FW_CLOCK, update clock again */ if (IPC_HEADER_GET_PROTOCOL(doorbell_val) == IPC_PROTOCOL_MNG && IPC_HEADER_GET_MNG_CMD(doorbell_val) == MNG_SYNC_FW_CLOCK) { struct timespec ts_system; struct timeval tv_utc; uint64_t usec_system, usec_utc; struct ipc_time_update_msg time_update; struct time_sync_format ts_format; get_monotonic_boottime(&ts_system); do_gettimeofday(&tv_utc); usec_system = (timespec_to_ns(&ts_system)) / NSEC_PER_USEC; usec_utc = (uint64_t)tv_utc.tv_sec * 1000000 + ((uint32_t)tv_utc.tv_usec); ts_format.ts1_source = HOST_SYSTEM_TIME_USEC; ts_format.ts2_source = HOST_UTC_TIME_USEC; ts_format.reserved = 0; time_update.primary_host_time = usec_system; time_update.secondary_host_time = usec_utc; time_update.sync_info = ts_format; memcpy(r_buf, &time_update, sizeof(struct ipc_time_update_msg)); } for (i = 0, reg_addr = IPC_REG_HOST2ISH_MSG; i < length >> 2; i++, reg_addr += 4) ish_reg_write(dev, reg_addr, r_buf[i]); rem = length & 0x3; if (rem > 0) { uint32_t reg = 0; memcpy(®, &r_buf[length >> 2], rem); ish_reg_write(dev, reg_addr, reg); }
static int cw_get_capacity(struct cw_battery *cw_bat) { int cw_capacity; int ret; u8 reg_val[2]; struct timespec ts; long new_run_time; long new_sleep_time; long capacity_or_aconline_time; int allow_change; int allow_capacity; static int if_quickstart = 0; static int jump_flag =0; int charge_time; // ret = cw_read(cw_bat->client, REG_SOC, ®_val); ret = cw_read_word(cw_bat->client, REG_SOC, reg_val); if (ret < 0) return ret; cw_capacity = reg_val[0]; if ((cw_capacity < 0) || (cw_capacity > 100)) { dev_err(&cw_bat->client->dev, "get cw_capacity error; cw_capacity = %d\n", cw_capacity); return cw_capacity; } if (cw_capacity == 0) dev_dbg(&cw_bat->client->dev, "the cw201x capacity is 0 !!!!!!!, funciton: %s, line: %d\n", __func__, __LINE__); else dev_dbg(&cw_bat->client->dev, "the cw201x capacity is %d, funciton: %s\n", cw_capacity, __func__); // ret = cw_read(cw_bat->client, REG_SOC + 1, ®_val); ktime_get_ts(&ts); new_run_time = ts.tv_sec; get_monotonic_boottime(&ts); new_sleep_time = ts.tv_sec - new_run_time; if ((cw_bat->charger_mode > 0) && (cw_capacity >= 95) && (cw_capacity <= cw_bat->capacity)) { // avoid no charge full capacity_or_aconline_time = (cw_bat->sleep_time_capacity_change > cw_bat->sleep_time_charge_start) ? cw_bat->sleep_time_capacity_change : cw_bat->sleep_time_charge_start; capacity_or_aconline_time += (cw_bat->run_time_capacity_change > cw_bat->run_time_charge_start) ? cw_bat->run_time_capacity_change : cw_bat->run_time_charge_start; allow_change = (new_sleep_time + new_run_time - capacity_or_aconline_time) / BATTERY_UP_MAX_CHANGE; if (allow_change > 0) { allow_capacity = cw_bat->capacity + allow_change; cw_capacity = (allow_capacity <= 100) ? allow_capacity : 100; jump_flag =1; } else if (cw_capacity <= cw_bat->capacity) { cw_capacity = cw_bat->capacity; } } else if (((cw_bat->charger_mode > 0) && (cw_capacity == (cw_bat->capacity - 1))) || ((cw_bat->charger_mode == 0) && (cw_capacity == (cw_bat->capacity + 1)))) { // modify battery level swing if (!(cw_capacity == 0 && cw_bat->capacity == 1)) { cw_capacity = cw_bat->capacity; } } else if ((cw_capacity == 0) && (cw_bat->capacity > 1)) { // avoid battery level jump to 0% at a moment from more than 2% allow_change = ((new_run_time - cw_bat->run_time_capacity_change) / BATTERY_DOWN_MIN_CHANGE_RUN); allow_change += ((new_sleep_time - cw_bat->sleep_time_capacity_change) / BATTERY_DOWN_MIN_CHANGE_SLEEP); allow_capacity = cw_bat->capacity - allow_change; cw_capacity = (allow_capacity >= cw_capacity) ? allow_capacity: cw_capacity; reg_val[0] = MODE_NORMAL; ret = cw_write(cw_bat->client, REG_MODE, reg_val); if (ret < 0) return ret; } else if ((cw_bat->charger_mode == 0) && (cw_capacity <= cw_bat->capacity ) && (cw_capacity >= 90) && (jump_flag == 1)) { // avoid battery level jump to CW_BAT capacity_or_aconline_time = (cw_bat->sleep_time_capacity_change > cw_bat->sleep_time_charge_start) ? cw_bat->sleep_time_capacity_change : cw_bat->sleep_time_charge_start; capacity_or_aconline_time += (cw_bat->run_time_capacity_change > cw_bat->run_time_charge_start) ? cw_bat->run_time_capacity_change : cw_bat->run_time_charge_start; allow_change = (new_sleep_time + new_run_time - capacity_or_aconline_time) / BATTERY_DOWN_CHANGE; if (allow_change > 0) { allow_capacity = cw_bat->capacity - allow_change; if (cw_capacity >= allow_capacity){ jump_flag =0; } else{ cw_capacity = (allow_capacity <= 100) ? allow_capacity : 100; } } else if (cw_capacity <= cw_bat->capacity) { cw_capacity = cw_bat->capacity; } } #if 1 if((cw_bat->charger_mode > 0) &&(cw_capacity == 0)) { charge_time = new_sleep_time + new_run_time - cw_bat->sleep_time_charge_start - cw_bat->run_time_charge_start; if ((charge_time > BATTERY_DOWN_MAX_CHANGE_RUN_AC_ONLINE) && (if_quickstart == 0)) { cw_quickstart(cw_bat); // if the cw_capacity = 0 the cw2015 will qstrt if_quickstart = 1; } } else if ((if_quickstart == 1)&&(cw_bat->charger_mode == 0)) { if_quickstart = 0; } #endif #if 0 if (cw_bat->plat_data->chg_ok_pin != INVALID_GPIO) { if(gpio_get_value(cw_bat->plat_data->chg_ok_pin) != cw_bat->plat_data->chg_ok_level) { if (cw_capacity == 100) { cw_capacity = 99; } } else { if (cw_bat->charger_mode > 0) { cw_capacity = 100; } } } #endif #ifdef SYSTEM_SHUTDOWN_VOLTAGE if ((cw_bat->charger_mode == 0) && (cw_capacity <= 10) && (cw_bat->voltage <= SYSTEM_SHUTDOWN_VOLTAGE)){ if (if_quickstart == 10){ cw_quickstart(cw_bat); if_quickstart = 12; cw_capacity = 0; } else if (if_quickstart <= 10) if_quickstart =if_quickstart+2; dev_info(&cw_bat->client->dev, "the cw201x voltage is less than SYSTEM_SHUTDOWN_VOLTAGE !!!!!!!, funciton: %s, line: %d\n", __func__, __LINE__); } else if ((cw_bat->charger_mode > 0)&& (if_quickstart <= 12)) { if_quickstart = 0; } #endif return cw_capacity; }
//For non-timer-based busy check void mvg_emmc_check_busy_and_reset(int delay_ms, int delay_us, u64 addr, u32 len) { struct msdc_host *host=mtk_msdc_host[0]; volatile unsigned int *reg1=(unsigned int *)(host->base+OFFSET_SDC_STS); //volatile unsigned int *reg2 = (unsigned int *)(host->base+OFFSET_MSDC_INT); static struct timespec t_start,t_end1; //Note: From msdc_response to here: 6571 consume 120us get_monotonic_boottime(&t_start); if ( delay_ms ) mdelay(delay_ms); if ( delay_us ) udelay(delay_us); get_monotonic_boottime(&t_end1); if ( (*reg1&SDC_STS_SDCBUSY) || (len==0) ) { //len=0 for erase //printk(KERN_ERR TAG " emmc_reset_mode %d\n", mvg_spoh_emmc_priv.emmc_reset_mode); if ( (mvg_spoh_emmc_priv.emmc_reset_mode==MVG_EMMC_RESET_W_POWEROFF) || (mvg_spoh_emmc_priv.emmc_reset_mode==MVG_EMMC_RESET_WO_POWEROFF) ) { if ( t_end1.tv_nsec< t_start.tv_nsec ) { t_end1.tv_nsec=1000000000+t_end1.tv_nsec-t_start.tv_nsec; } else { t_end1.tv_nsec=t_end1.tv_nsec-t_start.tv_nsec; } if ( mvg_spoh_emmc_priv.emmc_reset_mode==MVG_EMMC_RESET_W_POWEROFF ) { hwPowerDown(MT6325_POWER_LDO_VEMC33, "msdc"); //hwPowerDown(MT6323_POWER_LDO_VIO18, "msdc"); //VIO18 shall not be turned off since system will hang #if 0 if ( mvg_spoh_emmc_priv.emmc_reset_mode==MVG_EMMC_RESET_W_POWEROFF ) { while (upmu_get_qi_vemc_3v3_en()); } #else mdelay(12); //wait LDO drop to about 0 --> Consult PMIC designer for time to wait. #endif } //Since print itself will add delay to perform wdt_arch_reset(), // only enable the next log only for measure planned timing and actual timing. if ( mvg_spoh_emmc_priv.emmc_reset_mode==MVG_EMMC_RESET_W_POWEROFF ) { //printk(KERN_ERR TAG " %d us reset with poweroff, test len %d, addr %x, plan %u us\n", t_end1.tv_nsec/1000, len, (unsigned int)addr, delay_ms*1000+delay_us); } else { //printk(KERN_ERR TAG " %d us reset without poweroff, test len %d, addr %x, plan %u us\n", t_end1.tv_nsec/1000, len, (unsigned int)addr, delay_ms*1000+delay_us); } mvg_wdt_reset(); } else if ( mvg_spoh_emmc_priv.emmc_reset_mode==MVG_EMMC_NO_RESET ) { //printk(KERN_ERR TAG " mvg_emmc_check_busy_and_reset wait %u\n", delay); if ( t_end1.tv_nsec< t_start.tv_nsec ) { t_end1.tv_nsec=1000000000+t_end1.tv_nsec-t_start.tv_nsec; } else { t_end1.tv_nsec=t_end1.tv_nsec-t_start.tv_nsec; } printk(KERN_ERR TAG " not reset after %d us, test len %d , addr %x, plan %u us\n", ((int)t_end1.tv_nsec)/1000, len, (unsigned int)addr, delay_ms*1000+delay_us); //Not really reset --> for UT/simulation mode mvg_spoh_emmc_priv.reset_time_divisor=1; return; } } else { printk(KERN_ERR TAG " busy end before %d us, test len %u\n", delay_ms*1000+delay_us, mvg_spoh_emmc_priv.match_len); #if 0 mvg_emmc_reset_planned=0; #else mvg_emmc_reset_timeout=1; mvg_emmc_reset_planned--; #endif mvg_spoh_emmc_priv.reset_delay_result=1; //Fail to reset/poweroff before program finish. Double time divisor to shorten time before reset/poweroff mvg_spoh_emmc_priv.reset_time_divisor=mvg_spoh_emmc_priv.reset_time_divisor<<1; } }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; struct rtc_time new_rtc_tm; struct rtc_device *rtc_dev; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) return -EINVAL; if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): switch (alarm_type) { case ANDROID_ALARM_POWER_UP: /* disable power up alarm interrupt */ rv = alarm_irq_enable(0); break; case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: case ANDROID_ALARM_SYSTEMTIME: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); devalarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; default: break; } break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; #if defined(CONFIG_RTC_CHN_ALARM_BOOT) case ANDROID_ALARM_SET_ALARM: { char bootalarm_data[14]; if (copy_from_user(bootalarm_data, (void __user *)arg, 14)) { rv = -EFAULT; goto err1; } alarm_set_bootalarm(bootalarm_data); break; } #endif case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; devalarm_start(&alarms[alarm_type], timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (alarm_type == ANDROID_ALARM_POWER_UP) alarm_set_rtc_ring(new_alarm_time); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rtc_time_to_tm(new_rtc_time.tv_sec, &new_rtc_tm); rtc_dev = alarmtimer_get_rtcdev(); rv = do_settimeofday(&new_rtc_time); if (rv < 0) goto err1; if (rtc_dev) rv = rtc_set_time(rtc_dev, &new_rtc_tm); if (pwr_rtc_dev) rv = rtc_set_time(pwr_rtc_dev, &new_rtc_tm); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_POWER_UP: case ANDROID_ALARM_RTC: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: get_monotonic_boottime(&tmp_time); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }
static void baro_work_func(struct work_struct *work) { struct baro_context *cxt = NULL; /* hwm_sensor_data sensor_data; */ int value, status; int64_t pre_ns, cur_ns; int64_t delay_ms; struct timespec time; int err; cxt = baro_context_obj; delay_ms = atomic_read(&cxt->delay); if (NULL == cxt->baro_data.get_data) BARO_LOG("baro driver not register data path\n"); time.tv_sec = time.tv_nsec = 0; get_monotonic_boottime(&time); cur_ns = time.tv_sec*1000000000LL+time.tv_nsec; /* add wake lock to make sure data can be read before system suspend */ err = cxt->baro_data.get_data(&value, &status); if (err) { BARO_ERR("get baro data fails!!\n"); goto baro_loop; } else { { cxt->drv_data.baro_data.values[0] = value; cxt->drv_data.baro_data.status = status; pre_ns = cxt->drv_data.baro_data.time; cxt->drv_data.baro_data.time = cur_ns; } } if (true == cxt->is_first_data_after_enable) { pre_ns = cur_ns; cxt->is_first_data_after_enable = false; /* filter -1 value */ if (BARO_INVALID_VALUE == cxt->drv_data.baro_data.values[0]) { BARO_LOG(" read invalid data\n"); goto baro_loop; } } /* report data to input device */ /*BARO_LOG("new baro work run....\n"); */ /*BARO_LOG("baro data[%d].\n", cxt->drv_data.baro_data.values[0]); */ while ((cur_ns - pre_ns) >= delay_ms*1800000LL) { pre_ns += delay_ms*1000000LL; baro_data_report(cxt->idev, cxt->drv_data.baro_data.values[0], cxt->drv_data.baro_data.status, pre_ns); } baro_data_report(cxt->idev, cxt->drv_data.baro_data.values[0], cxt->drv_data.baro_data.status, cxt->drv_data.baro_data.time); baro_loop: if (true == cxt->is_polling_run) { { startTimer(&cxt->hrTimer, atomic_read(&cxt->delay), false); } } }
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rv = 0; unsigned long flags; struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; struct rtc_time new_rtc_tm; struct rtc_device *rtc_dev; struct rtc_wkalrm pwron_alm; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; if (alarm_type >= ANDROID_ALARM_TYPE_COUNT && alarm_type != ANDROID_ALARM_POWER_ON && alarm_type != ANDROID_ALARM_POWER_ON_LOGO) { return -EINVAL; } if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) return -EPERM; if (file->private_data == NULL && cmd != ANDROID_ALARM_SET_RTC) { spin_lock_irqsave(&alarm_slock, flags); if (alarm_opened) { spin_unlock_irqrestore(&alarm_slock, flags); return -EBUSY; } alarm_opened = 1; file->private_data = (void *)1; spin_unlock_irqrestore(&alarm_slock, flags); } } switch (ANDROID_ALARM_BASE_CMD(cmd)) { case ANDROID_ALARM_CLEAR(0): pr_alarm(IO, "alarm %d clear\n", alarm_type); if (alarm_type == ANDROID_ALARM_POWER_ON || alarm_type == ANDROID_ALARM_POWER_ON_LOGO) { new_alarm_time.tv_sec = 0; alarm_set_power_on(new_alarm_time, false); break; } spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); devalarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) wake_unlock(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_OLD: case ANDROID_ALARM_SET_AND_WAIT_OLD: if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { rv = -EFAULT; goto err1; } new_alarm_time.tv_nsec = 0; goto from_old_alarm_set; case ANDROID_ALARM_SET_AND_WAIT(0): case ANDROID_ALARM_SET(0): if (copy_from_user(&new_alarm_time, (void __user *)arg, sizeof(new_alarm_time))) { rv = -EFAULT; goto err1; } from_old_alarm_set: pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); if (alarm_type == ANDROID_ALARM_POWER_ON) { alarm_set_power_on(new_alarm_time, false); break; } if (alarm_type == ANDROID_ALARM_POWER_ON_LOGO) { alarm_set_power_on(new_alarm_time, true); break; } spin_lock_irqsave(&alarm_slock, flags); alarm_enabled |= alarm_type_mask; devalarm_start(&alarms[alarm_type], timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) break; /* fall though */ case ANDROID_ALARM_WAIT: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { wake_unlock(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); if (rv) goto err1; spin_lock_irqsave(&alarm_slock, flags); rv = alarm_pending; wait_pending = 1; alarm_pending = 0; spin_unlock_irqrestore(&alarm_slock, flags); break; case ANDROID_ALARM_SET_RTC: if (copy_from_user(&new_rtc_time, (void __user *)arg, sizeof(new_rtc_time))) { rv = -EFAULT; goto err1; } rtc_time_to_tm(new_rtc_time.tv_sec, &new_rtc_tm); pr_alarm(IO, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", new_rtc_time.tv_sec, new_rtc_time.tv_nsec, new_rtc_tm.tm_hour, new_rtc_tm.tm_min, new_rtc_tm.tm_sec, new_rtc_tm.tm_mon + 1, new_rtc_tm.tm_mday, new_rtc_tm.tm_year + 1900); rtc_dev = alarmtimer_get_rtcdev(); rv = do_settimeofday(&new_rtc_time); if (rv < 0) { goto err1; } if (rtc_dev) { rv = rtc_set_time(rtc_dev, &new_rtc_tm); } spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); spin_unlock_irqrestore(&alarm_slock, flags); if (rv < 0) goto err1; break; case ANDROID_ALARM_GET_TIME(0): switch (alarm_type) { case ANDROID_ALARM_RTC_WAKEUP: case ANDROID_ALARM_RTC: getnstimeofday(&tmp_time); break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: get_monotonic_boottime(&tmp_time); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: ktime_get_ts(&tmp_time); break; case ANDROID_ALARM_POWER_ON: case ANDROID_ALARM_POWER_ON_LOGO: break; } if (copy_to_user((void __user *)arg, &tmp_time, sizeof(tmp_time))) { rv = -EFAULT; goto err1; } break; case ANDROID_ALARM_GET_POWER_ON: alarm_get_power_on(&pwron_alm); if (copy_to_user((void __user *)arg, &pwron_alm, sizeof(struct rtc_wkalrm))) { rv = -EFAULT; goto err1; } break; default: rv = -EINVAL; goto err1; } err1: return rv; }