static void __init __pm_init_errata_flg(void)
{
	u32 chip_id = get_chip_id();

#ifdef CONFIG_MM_V3D_TIMEOUT_ERRATUM
	if (chip_id <= KONA_CHIP_ID_JAVA_A1)
		pm_erratum_flg |= ERRATUM_MM_V3D_TIMEOUT;
#endif

#ifdef CONFIG_PLL1_8PHASE_OFF_ERRATUM
	if (chip_id <= KONA_CHIP_ID_JAVA_A1)
		pm_erratum_flg |= ERRATUM_PLL1_8PHASE_OFF;
#endif

#ifdef CONFIG_MM_POWER_OK_ERRATUM
	if (chip_id <= KONA_CHIP_ID_JAVA_A1)
		pm_erratum_flg |= ERRATUM_MM_POWER_OK;
#endif

#ifdef CONFIG_MM_FREEZE_VAR500M_ERRATUM
	if (chip_id <= KONA_CHIP_ID_JAVA_A1)
		pm_erratum_flg |= ERRATUM_MM_FREEZE_VAR500M;
#endif

#ifdef CONFIG_A7_PLL_PWRDWN_ERRATUM
	if (chip_id <= KONA_CHIP_ID_JAVA_A0)
		pm_erratum_flg |= ERRATUM_A7_PLL_PWRDWN;
#endif
	if (chip_id <= KONA_CHIP_ID_JAVA_A0)
		pm_erratum_flg |= ERRATUM_VDDFIX_LEAKAGE;
}
static void __init __pm_init_errata_flg(void)
{
	u32 chip_id = get_chip_id();

#ifdef CONFIG_MM_V3D_TIMEOUT_ERRATUM
	if (chip_id <= KONA_CHIP_ID_HAWAII_A0)
		pm_erratum_flg |= ERRATUM_MM_V3D_TIMEOUT;
#endif

#ifdef CONFIG_PLL1_8PHASE_OFF_ERRATUM
	if (chip_id <= KONA_CHIP_ID_HAWAII_A0)
		pm_erratum_flg |= ERRATUM_PLL1_8PHASE_OFF;
#endif

#ifdef CONFIG_MM_POWER_OK_ERRATUM
	if (chip_id <= KONA_CHIP_ID_HAWAII_A0)
		pm_erratum_flg |= ERRATUM_MM_POWER_OK;
#endif

#ifdef CONFIG_MM_FREEZE_VAR500M_ERRATUM
	if (chip_id <= KONA_CHIP_ID_HAWAII_A0)
		pm_erratum_flg |= ERRATUM_MM_FREEZE_VAR500M;
#endif

}
Example #3
0
int cpu_is_sama5d2(void)
{
	unsigned int chip_id = get_chip_id();

	return ((chip_id == ARCH_ID_SAMA5D2) ||
		(chip_id == ARCH_ID_SAMA5D2_SIP)) ? 1 : 0;
}
Example #4
0
static void export_kernel_boot_props(void)
{
    char tmp[PROP_VALUE_MAX];
    const char *pval;
    unsigned i;
    struct {
        const char *src_prop;
        const char *dest_prop;
        const char *def_val;
    } prop_map[] = {
        { "ro.boot.serialno", "ro.serialno", "", },
        { "ro.boot.mode", "ro.bootmode", "unknown", },
        { "ro.boot.baseband", "ro.baseband", "unknown", },
        { "ro.boot.bootloader", "ro.bootloader", "unknown", },
    };
    char buf[32] = {0};

    if (get_chip_id(buf, sizeof(buf)) < 0) {
        ERROR("get chip id failed\n");
    } else {
        property_set("ro.boot.serialno", buf);
    }

    for (i = 0; i < ARRAY_SIZE(prop_map); i++) {
        pval = property_get(prop_map[i].src_prop);
        property_set(prop_map[i].dest_prop, pval ?: prop_map[i].def_val);
    }

    pval = property_get("ro.boot.console");
    if (pval)
        strlcpy(console, pval, sizeof(console));

    /* save a copy for init's usage during boot */
    strlcpy(bootmode, property_get("ro.bootmode"), sizeof(bootmode));

    /* if this was given on kernel command line, override what we read
     * before (e.g. from /proc/cpuinfo), if anything */
    pval = property_get("ro.boot.hardware");
    if (pval)
        strlcpy(hardware, pval, sizeof(hardware));
    property_set("ro.hardware", hardware);

    snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
    property_set("ro.revision", tmp);

    /* TODO: these are obsolete. We should delete them */
    if (!strcmp(bootmode,"factory"))
        property_set("ro.factorytest", "1");
    else if (!strcmp(bootmode,"factory2"))
        property_set("ro.factorytest", "2");
    else
        property_set("ro.factorytest", "0");
}
Example #5
0
char *get_cpu_name(void)
{
	unsigned int chip_id = get_chip_id();
	unsigned int extension_id = get_extension_chip_id();

	if (chip_id == ARCH_ID_SAMA5D2) {
		switch (extension_id) {
		case ARCH_EXID_SAMA5D21CU:
			return "SAMA5D21";
		case ARCH_EXID_SAMA5D22CU:
			return "SAMA5D22-CU";
		case ARCH_EXID_SAMA5D22CN:
			return "SAMA5D22-CN";
		case ARCH_EXID_SAMA5D23CU:
			return "SAMA5D23-CU";
		case ARCH_EXID_SAMA5D24CX:
			return "SAMA5D24-CX";
		case ARCH_EXID_SAMA5D24CU:
			return "SAMA5D24-CU";
		case ARCH_EXID_SAMA5D26CU:
			return "SAMA5D26-CU";
		case ARCH_EXID_SAMA5D27CU:
			return "SAMA5D27-CU";
		case ARCH_EXID_SAMA5D27CN:
			return "SAMA5D27-CN";
		case ARCH_EXID_SAMA5D28CU:
			return "SAMA5D28-CU";
		case ARCH_EXID_SAMA5D28CN:
			return "SAMA5D28-CN";
		}
	}

	if ((chip_id == ARCH_ID_SAMA5D2) || (chip_id == ARCH_ID_SAMA5D2_SIP)) {
		switch (extension_id) {
		case ARCH_EXID_SAMA5D225C_D1M:
			return "SAMA5D225 128M bits DDR2 SDRAM";
		case ARCH_EXID_SAMA5D27C_D5M:
			return "SAMA5D27 512M bits DDR2 SDRAM";
		case ARCH_EXID_SAMA5D27C_D1G:
			return "SAMA5D27 1G bits DDR2 SDRAM";
		case ARCH_EXID_SAMA5D28C_D1G:
			return "SAMA5D28 1G bits DDR2 SDRAM";
		}
	}

	return "Unknown CPU type";
}
Example #6
0
static int sigar_cpu_list_get(sigar_t *sigar, sigar_cpu_list_t *cpulist)
{
    kstat_ctl_t *kc = sigar->kc;
    kstat_t *ksp;
    uint_t cpuinfo[CPU_STATES];
    unsigned int i;
    int is_debug = SIGAR_LOG_IS_DEBUG(sigar);
    sigar_cache_t *chips;

    if (sigar_kstat_update(sigar) == -1) {
        return errno;
    }

    if (cpulist == &sigar->cpulist) {
        if (sigar->cpulist.size == 0) {
            /* create once */
            sigar_cpu_list_create(cpulist);
        }
        else {
            /* reset, re-using cpulist.data */
            sigar->cpulist.number = 0;
        }
    }
    else {
        sigar_cpu_list_create(cpulist);
    }

    if (is_debug) {
        sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
                         "[cpu_list] OS reports %d CPUs",
                         sigar->ncpu);
    }

    chips = sigar_cache_new(16);
    chips->free_value = free_chip_id;

    for (i=0; i<sigar->ncpu; i++) {
        sigar_cpu_t *cpu;
        char *buf;
        int chip_id;
        sigar_cache_entry_t *ent;

        if (!CPU_ONLINE(sigar->ks.cpuid[i])) {
            sigar_log_printf(sigar, SIGAR_LOG_INFO,
                             "cpu %d (id=%d) is offline",
                             i, sigar->ks.cpuid[i]);
            continue;
        }

        if (!(ksp = sigar->ks.cpu[i])) {
            sigar_log_printf(sigar, SIGAR_LOG_ERROR,
                             "NULL ksp for cpu %d (id=%d)",
                             i, sigar->ks.cpuid[i]);
            continue; /* shouldnot happen */
        }

        if (kstat_read(kc, ksp, NULL) < 0) {
            sigar_log_printf(sigar, SIGAR_LOG_ERROR,
                             "kstat_read failed for cpu %d (id=%d): %s",
                             i, sigar->ks.cpuid[i],
                             sigar_strerror(sigar, errno));
            continue; /* shouldnot happen */
        }

        /*
         * cpu_stat_t is not binary compatible between solaris versions.
         * since cpu_stat is a 'raw' kstat and not 'named' we cannot
         * use name based lookups as we do for others.
         * the start of the cpu_stat_t structure is binary compatible,
         * which looks like so:
         * typedef struct cpu_stat {
         *    kmutex_t        cpu_stat_lock;
         *    cpu_sysinfo_t   cpu_sysinfo;
         *    ...
         *    typedef struct cpu_sysinfo {
         *       ulong cpu[CPU_STATES];
         *       ...
         * we just copy the piece we need below:
         */
        buf = ksp->ks_data;
        buf += sizeof(kmutex_t);
        memcpy(&cpuinfo[0], buf, sizeof(cpuinfo));
        chip_id = sigar->cpu_list_cores ? -1 : get_chip_id(sigar, i);

        if (chip_id == -1) {
            SIGAR_CPU_LIST_GROW(cpulist);
            cpu = &cpulist->data[cpulist->number++];
            SIGAR_ZERO(cpu);
        }
        else {
            /* merge times of logical processors */
            ent = sigar_cache_get(chips, chip_id);
            if (ent->value) {
                cpu = &cpulist->data[(long)ent->value-1];
            }
            else {
                SIGAR_CPU_LIST_GROW(cpulist);
                cpu = &cpulist->data[cpulist->number++];
                ent->value = (void *)(long)cpulist->number;
                SIGAR_ZERO(cpu);

                if (is_debug) {
                    sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
                                     "[cpu_list] Merging times of"
                                     " logical processors for chip_id=%d",
                                     chip_id);
                }
            }
        }

        cpu->user += SIGAR_TICK2MSEC(cpuinfo[CPU_USER]);
        cpu->sys  += SIGAR_TICK2MSEC(cpuinfo[CPU_KERNEL]);
        cpu->idle += SIGAR_TICK2MSEC(cpuinfo[CPU_IDLE]);
        cpu->wait += SIGAR_TICK2MSEC(cpuinfo[CPU_WAIT]);
        cpu->nice += 0; /* no cpu->nice */
        cpu->total = cpu->user + cpu->sys + cpu->idle + cpu->wait;
    }

    sigar_cache_destroy(chips);

    return SIGAR_OK;
}
Example #7
0
static int dk_ioctl
(
 	struct inode *inode, 
	struct file *file,
	unsigned int cmd,
	unsigned long arg
)
{
		INT32 ret=-1;
		INT32 data;
		struct cfg_op co;
		INT32 cli_id;
		INT32 i;
		struct client_info ci;
		struct event_op eo;
		event_handle evt_hnd;
		p_event_struct p_event;
		p_atheros_dev p_client;

		
#ifdef DK_DEBUG
		printk("DK::dk_ioctl \n");
#endif

		cli_id = (int) ((unsigned long)file->private_data);
		p_client = get_client(cli_id);
		if (p_client == NULL) {
				printk("DK:: Invalid client \n");
				return -1;
		}
		switch (cmd) {
			case DK_IOCTL_GET_VERSION:
#ifdef DK_DEBUG
				printk("DK:: DK_IOCTL_GET_VERISION \n");
#endif
				data = (DRV_MAJOR_VERSION << 16) | (DRV_MINOR_VERSION);
				ret = put_user(data, (INT32 *)arg);
				break;
			case DK_IOCTL_GET_CLIENT_INFO:
#ifdef DK_DEBUG
				printk("DK:: DK_IOCTL_GET_CLIENT_INFO \n");
#endif
				if (get_cli_info(cli_id,&ci) < 0) {
					printk("DK:: get_cli_info failed, cli_id : %d \n", cli_id);
					ret = -1;
				} else {
					ret = copy_to_user((void *)arg,(void *)&ci,sizeof(ci));
				}
				ret = 0;
				break;
			case DK_IOCTL_CFG_READ:
#if !defined(P1020)
				if (copy_from_user((void *)&co,(void *)arg,sizeof(co))) {
						return -EFAULT;
				}
#ifdef DK_DEBUG
				printk("DK::Cfg read @ offset %x \n",co.offset);
#endif
#if defined(OWL_PB42) || defined(PYTHON_EMU)
#ifdef WASP_OSPREY
   if(cli_id!=0){ // For DBDC operation, Wasp radio's client ID is zero; 
#endif
				if (cli_cfg_read(cli_id,co.offset,co.size,&co.value) < 0) {
					ret = -1;
				} else {
					ret = copy_to_user((void *)arg,(void *)&co,sizeof(co));
				}
#ifdef WASP_OSPREY
  }
#endif
#endif
#else
                ret = -1;
#endif
				break;
                        case DK_IOCTL_RTC_REG_READ:
                                if (copy_from_user((void *)&co,(void *)arg,sizeof(co))) {
                                                return -EFAULT;
                                }
#ifdef DK_DEBUG
                                printk("DK::Rtc reg read @ offset %x \n",co.offset);
#endif
#ifndef OCTEON
                                if (rtc_reg_read(cli_id,co.offset,&co.value) < 0) {
                                        ret = -1;
                                } else {
                                        ret = copy_to_user((void *)arg,(void *)&co,sizeof(co));
                                }
#endif
                                break;

			case DK_IOCTL_GET_CHIP_ID:
				if (copy_from_user((void *)&co,(void *)arg,sizeof(co))) {
						return -EFAULT;
				}
#ifdef DK_DEBUG
				printk("DK::Reading Chio ID @ offset %x \n",co.offset);
#endif
#ifndef OCTEON
				if (get_chip_id(cli_id,co.offset,co.size,&co.value) < 0) {
					ret = -1;
				} else {
					ret = copy_to_user((void *)arg,(void *)&co,sizeof(co));
				}
				break;
#endif
			case DK_IOCTL_CFG_WRITE:
				if (copy_from_user((void *)&co,(void *)arg,sizeof(co))) {
						return -EFAULT;
				}
#ifdef DK_DEBUG
				printk("DK::Cfg write @ offset %x : %x \n",co.offset,co.value);
#endif
#if defined(OWL_PB42) || defined(PYTHON_EMU)
#ifdef WASP_OSPREY
   if(cli_id!=0){ // For DBDC operation, Wasp radio's client ID is zero; 
#endif
				if (cli_cfg_write(cli_id,co.offset,co.size,co.value) < 0) {
					ret = -1;
				} else {
					ret = 0;
				}
#ifdef WASP_OSPREY
  }
#endif
#endif
				break;
                        case DK_IOCTL_SYS_REG_WRITE_32:
                        case DK_IOCTL_FULL_ADDR_WRITE:
                                if (copy_from_user((void *)&co,(void *)arg,sizeof(co))) {
                                                return -EFAULT;
                                }
#ifdef DK_DEBUG
                                printk("DK::full addr write @ address %x : %x \n",co.offset,co.value);
#endif
#ifdef AP83
                                if (full_addr_write(cli_id,co.offset,co.value) < 0) {
                                        ret = -1;
                                } else {
                                        ret = 0;
                                }
#endif
                                break;
						case DK_IOCTL_SYS_REG_READ_32:
                        case DK_IOCTL_FULL_ADDR_READ:
                                if (copy_from_user((void *)&co,(void *)arg,sizeof(co))) {
                                                return -EFAULT;
                                }
#ifdef DK_DEBUG
                                printk("DK::Full add read @ address %x \n",co.offset);
#endif
#ifdef AP83
                                if (full_addr_read(cli_id,co.offset,&co.value) < 0) {
                                        ret = -1;
                                } else {
                                        ret = copy_to_user((void *)arg,(void *)&co,sizeof(co));
                                }
#endif
                                break;
                        case DK_IOCTL_RTC_REG_WRITE:
                                if (copy_from_user((void *)&co,(void *)arg,sizeof(co))) {
                                                return -EFAULT;
                                }
#ifdef DK_DEBUG
                                printk("DK::rtc write @ offset %x : %x \n",co.offset,co.value);
#endif
#ifdef AP83
#ifndef WASP
                                if (rtc_reg_write(cli_id,co.offset,co.value) < 0) {
                                        ret = -1;
                                } else {
                                        ret = 0;
                                }
#endif
#endif
                                break;

			case DK_IOCTL_CREATE_EVENT:
#ifdef DK_DEBUG
				printk("DK::Create event \n");
#endif
				if (copy_from_user((void *)&eo,(void *)arg,sizeof(eo))) {
						return -EFAULT;
				}
				ret = -1;
				if (eo.valid) {
			 		evt_hnd.eventID = eo.param[5] & 0xffff;
					evt_hnd.f2Handle = (eo.param[5] >> 16) & 0xffff;
					p_event = createEvent (eo.param[0], // type
					                       eo.param[1], // persistent
					                       eo.param[2], // param1
					                       eo.param[3], // param2
					                       eo.param[4], // param3
					                       evt_hnd);
					if (p_event != NULL) {
						// need to look at the event type to see which queue
						switch (p_event->type ) {
							case ISR_INTERRUPT:
								//if param1 is zero, we, by default
								// set the "ISR IMR" to pass everything
								if ( 0 == p_event->param1 ) {
									p_event->param1 = 0xffffffff;
								}
								if (pushEvent(p_event, &p_client->isr_event_q,
								               TRUE) ) {
										ret = 0;
								} else {
									printk("DK::Push Event Failed \n");
									kfree(p_event);
								} 
								break;
							default:
								printk("DK::Event Type %d not supported \n",p_event->type);
								kfree(p_event);
								break;
						}
					} 
				}
				break;
			case DK_IOCTL_GET_NEXT_EVENT:
#ifdef DK_DEBUG
				printk("DK::Get next event \n");
#endif
				ret = 0;
				eo.valid = 0;
				if (p_client->trigered_event_q.queueSize) {
					if (checkForEvents(&p_client->trigered_event_q,TRUE)){ 
						p_event = popEvent(&p_client->trigered_event_q,TRUE);
						eo.valid = 1;
						eo.param[0] = p_event->type;
						eo.param[1] = p_event->persistent;
						eo.param[2] = p_event->param1; 
						eo.param[3] = p_event->param2;
						eo.param[4] = p_event->param3;
						eo.param[5] = (p_event->eventHandle.f2Handle << 16) | 
						               p_event->eventHandle.eventID; 
						for (i=0;i<6;i++) { 
							eo.param[6+i] = p_event->result[i]; 
						} 
					#ifdef DK_DEBUG 
						printk("DK:: Pop event %x \n",(UINT32)p_event);
					#endif 
						kfree(p_event);
					} 
				}
				ret = copy_to_user((void *)arg,(void *)&eo,sizeof(eo));
				break;
            case DK_IOCTL_FLASH_READ:
                printk("DK:: Flash read is not supported any more from art driver\n");
                break;
            case DK_IOCTL_FLASH_WRITE:
                printk("DK:: Flash read is not supported any more from art driver\n");
                break; 
/*
#ifdef OWL_PB42
            case DK_IOCTL_MAC_WRITE:
#ifdef DK_DEBUG
                 printk("DK::Get DK_IOCTL_MAC_WRITE\n ");
#endif
                 if (copy_from_user((void *)&flashMac,(void *)arg,sizeof(flashMac))) {
                      printk("DK:: Copy_from_user failed 1\n");
                      return -EFAULT;
                 }
                 if (copy_from_user((void *)mac0Addr,(void *)flashMac.pAddr0, 6)){
                     printk("DK:: Copy_from_user failedi 2\n");
                     return -EFAULT;
                 }
                 if (copy_from_user((void *)mac1Addr,(void *)flashMac.pAddr1, 6)){
                     printk("DK:: Copy_from_user failed 3\n");
                     return -EFAULT;
                 }

#ifdef DK_DEBUG
                 printk("DK:: MAC Addr\n");
				 for(i=0; i<6; i++)
					printk("%x  ", mac0Addr[i]);
				 printk("\n");
				 for(i=0; i<6; i++)
					printk("%x  ", mac1Addr[i]);
				 printk("\n");
#endif

				memcpy(&hw_mac_cfg, 0xbf7f0000, 16);
				ar7100_spi_sector_erase(0x7f0000);
				// Copy mac address to ath_hw_cfg structure
				for(i=0; i<6; i++)
			        hw_mac_cfg.macAddr0[i] = mac0Addr[i];

				for(i=0; i<6; i++)
			        hw_mac_cfg.macAddr1[i] = mac1Addr[i];

				ar7100_spi_write_page(0x7f0000, &hw_mac_cfg, 256);				
				ret = 1;
                break; 
#endif
*/
			default:
				printk("DK::Unreconginzed ioctl command %d \n",cmd);
				break;
		}
Example #8
0
static INT32 __init dk_module_init(void) 
{
		INT32 error;

#if  defined(PYTHON_EMU)
        	UINT32 *addr;
#endif		
#ifndef OCTEON 
        INT32 ap83_81=0;
#endif		
		
#ifdef DK_DEBUG
		printk("DK::Module init \n");
#endif // DK_DEBUG
                
#ifndef OWL_PB42 
        get_chip_id(0,CHIP_ID_LOCATION,4,&ap83_81); // for getting the chip rev_id; to differentiate between PB and AP
        printk("CHIP REV ID: %x\n",ap83_81);
#endif
#if  defined(PYTHON_EMU)
        addr = (UINT32 *)(MERLIN_PCI_COMMAND_REG_ADDRESS);
        printk("Writing value 0x6 to Merlin PCI command register\n");
        writel(0x6,addr); // enabling ddr and dma of Merlin
	if((ap83_81==0x100)||(ap83_81==0x1100)||(ap83_81==0x101)||(ap83_81==0x1101)
	||(ap83_81==0x2120)||(ap83_81==0x1120)||(ap83_81==0x0120) // Wasp 1.0 package C, B and A 
	||(ap83_81==0x2121)||(ap83_81==0x1121)||(ap83_81==0x0121) // Wasp 1.1 package C, B and A 
	||(ap83_81==0x2122)||(ap83_81==0x1122)||(ap83_81==0x0122) // Wasp 1.2 package C, B and A 
	||(ap83_81==0x2123)||(ap83_81==0x1123)||(ap83_81==0x0123)){ // Wasp 1.3 package C, B and A 
	        addr = (UINT32 *)(VIRIAN_BASE_ADDRESS);
        	writel(readl(addr)& 0xfffeffff,addr);
	        printk("Resetting bit 16 of VIRIAN register 0xb80f0000\n");
	}else{
                addr = (UINT32 *)(0xb80f001c );
                writel(readl(addr)& 0xfffeffff,addr);
                printk("Resetting bit 16 of Python  register 0xb80f001c \n");

	}

#endif

		error = dk_dev_init();
		if (error < 0) {
			printk("DK::Cannot register device \n");
			return error;
		}
		init_client();
#ifdef AP83
                if (init_wmac_device()){ // enabling the wmac ; setting the handle for applications
                         printk("Error in initializing wmac \n");
                         return error;
                }
			printk("IRSHAD!!!!!! \n");

#ifndef WASP_OSPREY
			printk("IRSHAD2 returning!!!!!! \n");
		return 0;
#endif

#endif
               #if defined(OWL_PB42) || defined(PYTHON_EMU)
			printk("IRSHAD2!!!!!! \n");
		     error = bus_module_init();
                #endif
                 
#if !defined(OWL_PB42) && !defined(PYTHON_EMU)
		if (error < 0) {
			cleanup_client();
			dk_dev_exit();
			printk("DK::Cannot locate device. Reset the machine \n");
			return error;
		}
#endif
		return 0;
}
Example #9
0
File: main.c Project: vladsor/chaos
/*
 * ---===--- MAIN ---===---
 */
int main(int argc, char *argv[])
{
  int iofd;
  int ch;
  unsigned long fan1_info = 0;
  unsigned long fan2_info = 0;
  unsigned long fan3_info = 0;
  signed int system_temp = 0;
  double cpu1_temp = 0;
  double cpu2_temp = 0;
  char io_dev[FILENAME_MAX];

  strcpy(io_dev, "/dev/io");		// FreeBSD default

  /*
   * 'h' and '?' are not listed, to give an error message when used.
   */
  while ( (ch = getopt(argc, argv, "Adf:qt")) != -1 )
  {
    switch (ch)
    {
      case 'A':
        show_all_fans = 1;
        break;
      case 'd':
        debug = 1;
        break;
      case 'f':
        strcpy(io_dev, optarg);
        break;
      case 'q':
        quiet = 1;
        break;
      case 't':
        swap_cpu_temps = 1;
        break;
      case 'h':
      case '?':
      default:
        usage();
    }
  }
  argc -= optind;
  argv += optind;

  /*
   * Open /dev/io for inb() and outb() permissions.
   */
  if ( (iofd = open(io_dev, O_RDWR)) == -1 )
  {
    perror("open() failed");
    exit(1);
  }

  /*
   * Check to see if the vendor ID code returned from the chip matches
   * 0x5CA3 (Winbond chipset).
   */
  if ( (vendor_id = get_vendor_id()) != 0x5CA3 )
  {
    printf("You do not have a Winbond hardware monitoring chipset.\n");
    printf("Your vendor ID code is: 0x%4.4X\n", vendor_id);
    close(iofd);
    exit(1);
  }
  switch ( chip_id = get_chip_id() )
  {
    case 0x10:		strcpy(chip, "W83781D <untested>");	break;
    case 0x20:		strcpy(chip, "W83627HF <untested>");	break;
    case 0x30:		strcpy(chip, "W83782D");		break;
    case 0x40:		strcpy(chip, "W83783S <untested>");	break;
    default:		strcpy(chip, "(unknown)");		break;
  }

  if (!quiet)
  {
    printf("Winbond %s detected (vendor=0x%4.4X, chip=0x%2.2X)\n\n",
      chip, vendor_id, chip_id);
  }

  if (swap_cpu_temps)
  {
    /*
     * Swap CPU1 and CPU2 temperatures; the Abit BP6 has thermistors 1
     * and 2 reversed (hardware bug).
     */
    get_cpu_temperatures(&cpu2_temp, &cpu1_temp);
  }
  else
  {
    get_cpu_temperatures(&cpu1_temp, &cpu2_temp);
  }
  get_fan_statistics(&fan1_info, &fan2_info, &fan3_info);
  get_system_temperature(&system_temp);

  printf("System Temperature\t%3dF (%d.0C)\n",
	 C2F(system_temp), system_temp);
  printf("CPU1 Temperature\t%3dF (%3.01fC)\n",
	 C2F(cpu1_temp), cpu1_temp);
  printf("CPU2 Temperature\t%3dF (%3.01fC)\n",
	 C2F(cpu2_temp), cpu2_temp);
  if (show_all_fans == 1)
  {
    display_fan("FAN1", fan1_info);
    display_fan("FAN2", fan2_info);
    display_fan("FAN3", fan3_info);
  }
  else
  {
    if (fan1_info != 0)		display_fan("FAN1", fan1_info);
    if (fan2_info != 0)		display_fan("FAN2", fan2_info);
    if (fan3_info != 0)		display_fan("FAN3", fan3_info);
  }

  close(iofd);
  exit(0);
}