📄 feature.c
字号:
}#endif}static struct feature_controller*feature_add_controller(struct device_node *controller_device, fbit* bits){ struct feature_controller* controller; if (controller_count >= MAX_FEATURE_CONTROLLERS) { printk(KERN_INFO "Feature controller %s skipped(MAX:%d)\n", controller_device->full_name, MAX_FEATURE_CONTROLLERS); return NULL; } controller = &controllers[controller_count]; controller->bits = bits; controller->device = controller_device; if (controller_device->n_addrs == 0) { printk(KERN_ERR "No addresses for %s\n", controller_device->full_name); return NULL; } controller->reg = (volatile u32 *)ioremap( controller_device->addrs[0].address, MAX_FEATURE_OFFSET); if (bits == NULL) { printk(KERN_INFO "Twiddling the magic ohare bits\n"); out_le32(FREG(controller,OHARE_FEATURE_REG), STARMAX_FEATURES); return NULL; } spin_lock_init(&controller->lock); controller_count++; return controller;}static struct feature_controller*feature_lookup_controller(struct device_node *device){ int i; if (device == NULL) return NULL; while(device) { for (i=0; i<controller_count; i++) if (device == controllers[i].device) return &controllers[i]; device = device->parent; }#ifdef DEBUG_FEATURE printk("feature: <%s> not found on any controller\n", device->name);#endif return NULL;}intfeature_set(struct device_node* device, enum system_feature f){ struct feature_controller* controller; unsigned long flags; unsigned long value; fbit* bit; if (f >= FEATURE_last) return -EINVAL; controller = feature_lookup_controller(device); if (!controller) return -ENODEV; bit = &controller->bits[f]; if (!bit->mask) return -EINVAL; #ifdef DEBUG_FEATURE printk("feature: <%s> setting feature %d in controller @0x%x\n", device->name, (int)f, (unsigned int)controller->reg);#endif spin_lock_irqsave(&controller->lock, flags); value = in_le32(FREG(controller, bit->reg)); value = bit->polarity ? (value & ~bit->mask) : (value | bit->mask); out_le32(FREG(controller, bit->reg), value); (void)in_le32(FREG(controller, bit->reg)); spin_unlock_irqrestore(&controller->lock, flags); return 0;}intfeature_clear(struct device_node* device, enum system_feature f){ struct feature_controller* controller; unsigned long flags; unsigned long value; fbit* bit; if (f >= FEATURE_last) return -EINVAL; controller = feature_lookup_controller(device); if (!controller) return -ENODEV; bit = &controller->bits[f]; if (!bit->mask) return -EINVAL; #ifdef DEBUG_FEATURE printk("feature: <%s> clearing feature %d in controller @0x%x\n", device->name, (int)f, (unsigned int)controller->reg);#endif spin_lock_irqsave(&controller->lock, flags); value = in_le32(FREG(controller, bit->reg)); value = bit->polarity ? (value | bit->mask) : (value & ~bit->mask); out_le32(FREG(controller, bit->reg), value); (void)in_le32(FREG(controller, bit->reg)); spin_unlock_irqrestore(&controller->lock, flags); return 0;}intfeature_test(struct device_node* device, enum system_feature f){ struct feature_controller* controller; unsigned long value; fbit* bit; if (f >= FEATURE_last) return -EINVAL; controller = feature_lookup_controller(device); if (!controller) return -ENODEV; bit = &controller->bits[f]; if (!bit->mask) return -EINVAL; #ifdef DEBUG_FEATURE printk("feature: <%s> clearing feature %d in controller @0x%x\n", device->name, (int)f, (unsigned int)controller->reg);#endif /* If one feature contains several bits, all of them must be set * for value to be true, or all of them must be 0 if polarity is * inverse */ value = (in_le32(FREG(controller, bit->reg)) & bit->mask); return bit->polarity ? (value == 0) : (value == bit->mask);}/* * Core99 functions * * Note: We currently assume there is _one_ UniN chip and _one_ KeyLargo * chip, which is the case on all Core99 machines so far *//* Only one GMAC is assumed */voidfeature_set_gmac_power(struct device_node* device, int power){ if (!uninorth_base) return; if (power) UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); else UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); udelay(20);}voidfeature_set_gmac_phy_reset(struct device_node* device, int reset){ if (!keylargo_base) return; out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET), reset); (void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET));}/* Pass the node of the correct controller, please */voidfeature_set_usb_power(struct device_node* device, int power){}/* Not yet implemented */void feature_set_firewire_power(struct device_node* device, int power){}/* Initialize the Core99 UniNorth host bridge and memory controller */static voiduninorth_init(void){ struct device_node* gmac; unsigned long actrl; /* Set the arbitrer QAck delay according to what Apple does */ actrl = in_be32(UN_REG(UNI_N_ARB_CTRL)) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; UN_OUT(UNI_N_ARB_CTRL, actrl); /* * Turns OFF the gmac clock. The gmac driver will turn * it back ON when the interface is enabled. This save * power on portables. * * Note: We could also try to turn OFF the PHY. Since this * has to be done by both the gmac driver and this code, * I'll probably end-up moving some of this out of the * modular gmac driver into a non-modular stub containing * some basic PHY management and power management stuffs */ gmac = find_devices("ethernet"); while(gmac) { if (device_is_compatible(gmac, "gmac")) break; gmac = gmac->next; } if (gmac) feature_set_gmac_power(gmac, 0);}/* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure * OpenPIC is enabled */static voidkeylargo_init(void){ KL_BIS(KEYLARGO_FCR2, KL2_MPIC_ENABLE);}#ifdef CONFIG_PMAC_PBOOKvoidfeature_prepare_for_sleep(void){ /* We assume gatwick is second */ struct feature_controller* ctrler = &controllers[0]; if (!ctrler) return; if (controller_count > 1 && device_is_compatible(ctrler->device, "gatwick")) ctrler = &controllers[1]; if (ctrler->bits == feature_bits_heathrow || ctrler->bits == feature_bits_paddington) { heathrow_prepare_for_sleep(ctrler); return; } if (ctrler->bits == feature_bits_keylargo) { core99_prepare_for_sleep(ctrler); return; }}voidfeature_wake_up(void){ struct feature_controller* ctrler = &controllers[0]; if (!ctrler) return; if (controller_count > 1 && device_is_compatible(ctrler->device, "gatwick")) ctrler = &controllers[1]; if (ctrler->bits == feature_bits_heathrow || ctrler->bits == feature_bits_paddington) { heathrow_wakeup(ctrler); return; } if (ctrler->bits == feature_bits_keylargo) { core99_wake_up(ctrler); return; }}static u32 save_fcr[5];static u32 save_mbcr;static voidheathrow_prepare_for_sleep(struct feature_controller* ctrler){ save_mbcr = in_le32(FREG(ctrler, 0x34)); save_fcr[0] = in_le32(FREG(ctrler, 0x38)); save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE);}static voidheathrow_wakeup(struct feature_controller* ctrler){ out_le32(FREG(ctrler, 0x38), save_fcr[0]); out_le32(FREG(ctrler, 0x3c), save_fcr[1]); out_le32(FREG(ctrler, 0x34), save_mbcr); mdelay(1); out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); mdelay(1);}static voidcore99_prepare_for_sleep(struct feature_controller* ctrler){ /* Not yet implemented */}static voidcore99_wake_up(struct feature_controller* ctrler){ /* Not yet implemented */}#endif /* CONFIG_PMAC_PBOOK */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -