int rtc_ioctl(unsigned int cmd, unsigned long arg) { struct timeval power_ic_time; struct timeval * usr_spc_time_val = (struct timeval *)arg; int err = 0; /* Handle the request. */ switch(cmd) { case POWER_IC_IOCTL_GET_TIME: /* Read the TOD and DAY registers and set the data in the timeval structure to the format the Linux uses.*/ err = power_ic_rtc_get_time(&power_ic_time); if(copy_to_user(usr_spc_time_val, &power_ic_time, sizeof(power_ic_time))) { err = -EFAULT; } break; case POWER_IC_IOCTL_GET_ALARM_TIME: /* Read the TODA and DAYA registers and set the data in the timeval structure to the format the Linux uses.*/ err = power_ic_rtc_get_time_alarm(&power_ic_time); if(copy_to_user(usr_spc_time_val, &power_ic_time, sizeof(power_ic_time))) { err = -EFAULT; } break; case POWER_IC_IOCTL_SET_TIME: /* Write to the TOD and DAY registers based on the data in the timeval struct */ if(copy_from_user(&power_ic_time,usr_spc_time_val, sizeof(power_ic_time))) { err = -EFAULT; } err = power_ic_rtc_set_time(&power_ic_time); break; case POWER_IC_IOCTL_SET_ALARM_TIME: /* Write to the TODA and DAYA registers based on the data in the timeval struct */ if (copy_from_user(&power_ic_time,usr_spc_time_val,sizeof(power_ic_time))) { err = -EFAULT; } err = power_ic_rtc_set_time_alarm(&power_ic_time); break; default: /* This shouldn't be able to happen, but just in case... */ tracemsg(_k_d("0x%X unsupported ioctl command"), (int) cmd); err = -ENOTTY; break; } return err; }
/* * This function resets the system. It is called by machine_restart(). * * @param mode indicates different kinds of resets */ void arch_reset(char mode) { #if defined(CONFIG_MOT_FEAT_SYSREBOOT_ATLAS) int retval, mema, step = 0; struct timeval tv; #elif defined(CONFIG_MOT_FEAT_SYSREBOOT_CRM) unsigned long amcr; unsigned long crm_ap_amcr = IO_ADDRESS(CRM_AP_BASE_ADDR + CRM_AP_AMCR); #endif /* CONFIG_MOT_FEAT_SYSREBOOT_CRM */ if (system_rev == CHIP_REV_2_0) { /* Workaround reset problem on PASS2 by manually reset WEIM */ __raw_writel(0x00001E00, IO_ADDRESS(WEIM_CTRL_CS0 + CSCRU)); __raw_writel(0x20000D01, IO_ADDRESS(WEIM_CTRL_CS0 + CSCRL)); __raw_writel(0x0, IO_ADDRESS(WEIM_CTRL_CS0 + CSCRA)); } #if defined(CONFIG_MOT_FEAT_SYSREBOOT_ATLAS) /* * Set bit 4 of the Atlas MEMA register. This bit indicates to the * MBM that the phone is to be reset. */ retval = power_ic_backup_memory_read(POWER_IC_BACKUP_MEMORY_ID_ATLAS_BACKUP_SOFT_RESET, &mema); if(retval != 0) { step = 1; goto die; } mema |= 1; retval = power_ic_backup_memory_write(POWER_IC_BACKUP_MEMORY_ID_ATLAS_BACKUP_SOFT_RESET, mema); if(retval != 0) { step = 2; goto die; } /* * Set the Atlas RTC alarm to go off in 2 seconds. Experience indicates * that values less than 2 may not work reliably. */ retval = power_ic_rtc_get_time(&tv); if(retval != 0) { step = 3; goto die; } tv.tv_sec += 2; retval = power_ic_rtc_set_time_alarm(&tv); if(retval != 0) { step = 4; goto die; } /* power down the system */ __mxc_power_off(); die: printk("recieved error %d from power_ic driver at step %d in reboot", retval, step); /* fall through to existing reset code */ #elif defined(CONFIG_MOT_FEAT_SYSREBOOT_CRM) /* * Need to Reboot via Clock Reset Module with Software reset */ amcr = readl( crm_ap_amcr ); amcr &= ~CRM_AP_AMCR_SW_AP; writel( amcr, crm_ap_amcr ); while(1) { /* stay here, software reset */ arch_idle(); } #endif /* CONFIG_MOT_FEAT_SYSREBOOT_CRM */ if ((__raw_readw(IO_ADDRESS(WDOG1_BASE_ADDR)) & 0x4) != 0) { asm("cpsid iaf"); while (1) { } } else { __raw_writew(__raw_readw(IO_ADDRESS(WDOG1_BASE_ADDR)) | 0x4, IO_ADDRESS(WDOG1_BASE_ADDR)); } }