static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71805f_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); int nr = attr->index; u8 reg; unsigned long val; int err; err = kstrtoul(buf, 10, &val); if (err) return err; if (val < 1 || val > 3) return -EINVAL; if (val > 1) { /* Automatic mode, user can't set PWM value */ if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr], S_IRUGO)) dev_dbg(dev, "chmod -w pwm%d failed\n", nr + 1); } mutex_lock(&data->update_lock); reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(nr)) & ~FAN_CTRL_MODE_MASK; switch (val) { case 1: reg |= FAN_CTRL_MODE_MANUAL; break; case 2: reg |= FAN_CTRL_MODE_TEMPERATURE; break; case 3: reg |= FAN_CTRL_MODE_SPEED; break; } data->fan_ctrl[nr] = reg; f71805f_write8(data, F71805F_REG_FAN_CTRL(nr), reg); mutex_unlock(&data->update_lock); if (val == 1) { /* Manual mode, user can set PWM value */ if (sysfs_chmod_file(&dev->kobj, f71805f_attr_pwm[nr], S_IRUGO | S_IWUSR)) dev_dbg(dev, "chmod +w pwm%d failed\n", nr + 1); } return count; }
static int __init sysfsfuse_init(void) { nvfuse_kobj = kobject_create_and_add("fuse", firmware_kobj); PRINT_FUSE(("\n Fuse Init")); if (! nvfuse_kobj) { PRINT_FUSE(("Fuse Init failed!")); return -ENOMEM; } CHK_ERR(NvDdkFuseOpen(s_hRmGlobal)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_OdmProduction_attr.attr)); // change fuse file permissions, if ODM production fuse is not blown if (OdmProductionFuseVal() == 0) { nvfuse_DeviceKey_attr.attr.mode = 0640; nvfuse_JtagDisable_attr.attr.mode = 0640; nvfuse_OdmProduction_attr.attr.mode = 0640; nvfuse_SecBootDeviceConfig_attr.attr.mode = 0640; nvfuse_SecBootDeviceSelect_attr.attr.mode = 0640; nvfuse_SecureBootKey_attr.attr.mode = 0640; nvfuse_SwReserved_attr.attr.mode = 0640; nvfuse_SkipDevSelStraps_attr.attr.mode = 0640; nvfuse_SecBootDeviceSelectRaw_attr.attr.mode = 0640; nvfuse_ReservedOdm_attr.attr.mode = 0640; sysfs_chmod_file(nvfuse_kobj, &nvfuse_OdmProduction_attr.attr, 0640); } CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_DeviceKey_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_JtagDisable_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_KeyProgrammed_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_SecBootDeviceConfig_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_SecBootDeviceSelect_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_SecureBootKey_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_sku_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_SpareBits_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_SwReserved_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_SkipDevSelStraps_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_SecBootDeviceSelectRaw_attr.attr)); CHK_ERR(sysfs_create_file(nvfuse_kobj, &nvfuse_ReservedOdm_attr.attr)); PRINT_FUSE(("\n Fuse Init Exiting")); return 0; }
static int __devinit f71805f_probe(struct platform_device *pdev) { struct f71805f_sio_data *sio_data = pdev->dev.platform_data; struct f71805f_data *data; struct resource *res; int i, err; static const char *names[] = { "f71805f", "f71872f", }; if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { err = -ENOMEM; printk(KERN_ERR DRVNAME ": Out of memory\n"); goto exit; } res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!request_region(res->start + ADDR_REG_OFFSET, 2, DRVNAME)) { err = -EBUSY; dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)(res->start + ADDR_REG_OFFSET), (unsigned long)(res->start + ADDR_REG_OFFSET + 1)); goto exit_free; } data->addr = res->start; data->name = names[sio_data->kind]; mutex_init(&data->update_lock); platform_set_drvdata(pdev, data); /* Some voltage inputs depend on chip model and configuration */ switch (sio_data->kind) { case f71805f: data->has_in = 0x1ff; break; case f71872f: data->has_in = 0x6ef; if (sio_data->fnsel1 & 0x01) data->has_in |= (1 << 4); /* in4 */ if (sio_data->fnsel1 & 0x02) data->has_in |= (1 << 8); /* in8 */ break; } /* Initialize the F71805F chip */ f71805f_init_device(data); /* Register sysfs interface files */ if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group))) goto exit_release_region; if (data->has_in & (1 << 4)) { /* in4 */ if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[0]))) goto exit_remove_files; } if (data->has_in & (1 << 8)) { /* in8 */ if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[1]))) goto exit_remove_files; } if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */ if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[2]))) goto exit_remove_files; } if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */ if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[3]))) goto exit_remove_files; } for (i = 0; i < 3; i++) { /* If control mode is PWM, create pwm_freq file */ if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) { if ((err = sysfs_create_file(&pdev->dev.kobj, f71805f_attributes_pwm_freq[i]))) goto exit_remove_files; } /* If PWM is in manual mode, add write permission */ if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) { if ((err = sysfs_chmod_file(&pdev->dev.kobj, f71805f_attr_pwm[i], S_IRUGO | S_IWUSR))) { dev_err(&pdev->dev, "chmod +w pwm%d failed\n", i + 1); goto exit_remove_files; } } } data->hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); dev_err(&pdev->dev, "Class registration failed (%d)\n", err); goto exit_remove_files; } return 0; exit_remove_files: sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); for (i = 0; i < 4; i++) sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); exit_release_region: release_region(res->start + ADDR_REG_OFFSET, 2); exit_free: platform_set_drvdata(pdev, NULL); kfree(data); exit: return err; }
static ssize_t sysfsfuse_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { unsigned int size = 0; NvDdkFuseDataType FuseType; NvError Err; char WriteFuseBuf[BUF_SIZE]; #if SYSFS_FUSE_DEBUG_PRINTS unsigned char i = 0; #endif unsigned char OdmProdFuseVal = 0; OdmProdFuseVal = OdmProductionFuseVal(); if(OdmProdFuseVal == 1) { PRINT_FUSE(("\r\n ODM production fuse is already blown\n")); return -EINVAL; } FuseType = GetFuseType(attr->attr.name, &size); // As count includes data bytes followed by 0xA (line feed character) // and two chars can be stored in a fuse byte if ((count - 1) > (2 * size)) { PRINT_FUSE(("\r\n Requested data size[%d] > fuse size [%d]\n",count/2,size)); return -EINVAL; } if (buf != NULL) { StrToInt(buf, WriteFuseBuf, (count - 1), size); } else printk("\r\n buf is NULL"); PRINT_FUSE(("\r\n Input string: %s", buf)); PRINT_FUSE(("\n Fuse data of size [%d] to write\n", size)); #if SYSFS_FUSE_DEBUG_PRINTS for (i = 0; i < size; i++) PRINT_FUSE(("0x%x\n",WriteFuseBuf[i])); #endif NvDdkFuseClear(); Err = NvDdkFuseSet(FuseType, WriteFuseBuf, &size); if (Err == NvSuccess) { NvDdkFuseProgram(); NvDdkFuseSense(); NvDdkFuseVerify(); } else { PRINT_FUSE(("\r\n Fuse programming failed with error 0x%x",Err)); } if (Err == NvSuccess) { // if ODM production fuse is blown, change file permissions to 0440 if (FuseType == NvDdkFuseDataType_OdmProduction) { sysfs_chmod_file(kobj, &attr->attr, 0440); sysfs_chmod_file(kobj, &nvfuse_DeviceKey_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_JtagDisable_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_OdmProduction_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_SecBootDeviceConfig_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_SecBootDeviceSelect_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_SecureBootKey_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_SwReserved_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_SkipDevSelStraps_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_SecBootDeviceSelectRaw_attr.attr, 0440); sysfs_chmod_file(kobj, &nvfuse_ReservedOdm_attr.attr, 0440); } PRINT_FUSE(("\r\n fuse set success \n")); } else { PRINT_FUSE(("\r\n fuse set failed Err: 0x%x\n", Err)); return -EFAULT; } return count; }