static int cros_ec_lpc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct cros_ec_device *ec_dev; int ret; if (!devm_request_region(dev, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE, dev_name(dev))) { dev_err(dev, "couldn't reserve memmap region\n"); return -EBUSY; } if ((inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) != 'E') || (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1) != 'C')) { dev_err(dev, "EC ID not detected\n"); return -ENODEV; } if (!devm_request_region(dev, EC_HOST_CMD_REGION0, EC_HOST_CMD_REGION_SIZE, dev_name(dev))) { dev_err(dev, "couldn't reserve region0\n"); return -EBUSY; } if (!devm_request_region(dev, EC_HOST_CMD_REGION1, EC_HOST_CMD_REGION_SIZE, dev_name(dev))) { dev_err(dev, "couldn't reserve region1\n"); return -EBUSY; } ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL); if (!ec_dev) return -ENOMEM; platform_set_drvdata(pdev, ec_dev); ec_dev->dev = dev; ec_dev->ec_name = pdev->name; ec_dev->phys_name = dev_name(dev); ec_dev->parent = dev; ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc; ec_dev->cmd_readmem = cros_ec_lpc_readmem; ret = cros_ec_register(ec_dev); if (ret) { dev_err(dev, "couldn't register ec_dev (%d)\n", ret); return ret; } return 0; }
static int stx104_probe(struct device *dev, unsigned int id) { struct iio_dev *indio_dev; struct stx104_iio *priv; indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); if (!indio_dev) return -ENOMEM; if (!devm_request_region(dev, base[id], STX104_EXTENT, dev_name(dev))) { dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", base[id], base[id] + STX104_EXTENT); return -EBUSY; } indio_dev->info = &stx104_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = stx104_channels; indio_dev->num_channels = STX104_NUM_CHAN; indio_dev->name = dev_name(dev); priv = iio_priv(indio_dev); priv->base = base[id]; /* initialize DAC output to 0V */ outw(0, base[id] + 4); outw(0, base[id] + 6); return devm_iio_device_register(dev, indio_dev); }
/* This platform device is ordinarily registered by the vx855 mfd driver */ static int vx855gpio_probe(struct platform_device *pdev) { struct resource *res_gpi; struct resource *res_gpo; struct vx855_gpio *vg; res_gpi = platform_get_resource(pdev, IORESOURCE_IO, 0); res_gpo = platform_get_resource(pdev, IORESOURCE_IO, 1); if (!res_gpi || !res_gpo) return -EBUSY; vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL); if (!vg) return -ENOMEM; platform_set_drvdata(pdev, vg); dev_info(&pdev->dev, "found VX855 GPIO controller\n"); vg->io_gpi = res_gpi->start; vg->io_gpo = res_gpo->start; spin_lock_init(&vg->lock); /* * A single byte is used to control various GPIO ports on the VX855, * and in the case of the OLPC XO-1.5, some of those ports are used * for switches that are interpreted and exposed through ACPI. ACPI * will have reserved the region, so our own reservation will not * succeed. Ignore and continue. */ if (!devm_request_region(&pdev->dev, res_gpi->start, resource_size(res_gpi), MODULE_NAME "_gpi")) dev_warn(&pdev->dev, "GPI I/O resource busy, probably claimed by ACPI\n"); if (!devm_request_region(&pdev->dev, res_gpo->start, resource_size(res_gpo), MODULE_NAME "_gpo")) dev_warn(&pdev->dev, "GPO I/O resource busy, probably claimed by ACPI\n"); vx855gpio_gpio_setup(vg); return gpiochip_add(&vg->gpio); }
static int __init mod_init(void) { int err = -ENODEV; struct pci_dev *pdev = NULL; const struct pci_device_id *ent; u32 pmbase; struct amd768_priv *priv; for_each_pci_dev(pdev) { ent = pci_match_id(pci_tbl, pdev); if (ent) goto found; } /* Device not found. */ return -ENODEV; found: err = pci_read_config_dword(pdev, 0x58, &pmbase); if (err) return err; pmbase &= 0x0000FF00; if (pmbase == 0) return -EIO; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; if (!devm_request_region(&pdev->dev, pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) { dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n", pmbase + 0xF0); return -EBUSY; } priv->iobase = devm_ioport_map(&pdev->dev, pmbase + PMBASE_OFFSET, PMBASE_SIZE); if (!priv->iobase) { pr_err(DRV_NAME "Cannot map ioport\n"); return -ENOMEM; } amd_rng.priv = (unsigned long)priv; priv->pcidev = pdev; pr_info(DRV_NAME " detected\n"); return devm_hwrng_register(&pdev->dev, &amd_rng); }
/* SECTION: Initialisation */ static int sir_ir_probe(struct platform_device *dev) { int retval; rcdev = devm_rc_allocate_device(&sir_ir_dev->dev, RC_DRIVER_IR_RAW); if (!rcdev) return -ENOMEM; rcdev->input_name = "SIR IrDA port"; rcdev->input_phys = KBUILD_MODNAME "/input0"; rcdev->input_id.bustype = BUS_HOST; rcdev->input_id.vendor = 0x0001; rcdev->input_id.product = 0x0001; rcdev->input_id.version = 0x0100; rcdev->tx_ir = sir_tx_ir; rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; rcdev->driver_name = KBUILD_MODNAME; rcdev->map_name = RC_MAP_RC6_MCE; rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->dev.parent = &sir_ir_dev->dev; setup_timer(&timerlist, sir_timeout, 0); /* get I/O port access and IRQ line */ if (!devm_request_region(&sir_ir_dev->dev, io, 8, KBUILD_MODNAME)) { pr_err("i/o port 0x%.4x already in use.\n", io); return -EBUSY; } retval = devm_request_irq(&sir_ir_dev->dev, irq, sir_interrupt, 0, KBUILD_MODNAME, NULL); if (retval < 0) { pr_err("IRQ %d already in use.\n", irq); return retval; } pr_info("I/O port 0x%.4x, IRQ %d.\n", io, irq); retval = devm_rc_register_device(&sir_ir_dev->dev, rcdev); if (retval < 0) return retval; init_hardware(); return 0; }
static int pc87427_request_regions(struct platform_device *pdev, int count) { struct resource *res; int i; for (i = 0; i < count; i++) { res = platform_get_resource(pdev, IORESOURCE_IO, i); if (!res) { dev_err(&pdev->dev, "Missing resource #%d\n", i); return -ENOENT; } if (!devm_request_region(&pdev->dev, res->start, resource_size(res), DRVNAME)) { dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)res->start, (unsigned long)res->end); return -EBUSY; } } return 0; }
static int sch_gpio_probe(struct platform_device *pdev) { struct sch_gpio *sch; struct resource *res; sch = devm_kzalloc(&pdev->dev, sizeof(*sch), GFP_KERNEL); if (!sch) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!res) return -EBUSY; if (!devm_request_region(&pdev->dev, res->start, resource_size(res), pdev->name)) return -EBUSY; spin_lock_init(&sch->lock); sch->iobase = res->start; sch->chip = sch_gpio_chip; sch->chip.label = dev_name(&pdev->dev); sch->chip.parent = &pdev->dev; switch (pdev->id) { case PCI_DEVICE_ID_INTEL_SCH_LPC: sch->core_base = 0; sch->resume_base = 10; sch->chip.ngpio = 14; /* * GPIO[6:0] enabled by default * GPIO7 is configured by the CMC as SLPIOVR * Enable GPIO[9:8] core powered gpios explicitly */ sch_gpio_reg_set(&sch->chip, 8, GEN, 1); sch_gpio_reg_set(&sch->chip, 9, GEN, 1); /* * SUS_GPIO[2:0] enabled by default * Enable SUS_GPIO3 resume powered gpio explicitly */ sch_gpio_reg_set(&sch->chip, 13, GEN, 1); break; case PCI_DEVICE_ID_INTEL_ITC_LPC: sch->core_base = 0; sch->resume_base = 5; sch->chip.ngpio = 14; break; case PCI_DEVICE_ID_INTEL_CENTERTON_ILB: sch->core_base = 0; sch->resume_base = 21; sch->chip.ngpio = 30; break; case PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB: sch->core_base = 0; sch->resume_base = 2; sch->chip.ngpio = 8; break; default: return -ENODEV; } platform_set_drvdata(pdev, sch); return gpiochip_add(&sch->chip); }
static int dio48e_probe(struct device *dev, unsigned int id) { struct dio48e_gpio *dio48egpio; const char *const name = dev_name(dev); int err; dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL); if (!dio48egpio) return -ENOMEM; if (!devm_request_region(dev, base[id], DIO48E_EXTENT, name)) { dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", base[id], base[id] + DIO48E_EXTENT); return -EBUSY; } dio48egpio->chip.label = name; dio48egpio->chip.parent = dev; dio48egpio->chip.owner = THIS_MODULE; dio48egpio->chip.base = -1; dio48egpio->chip.ngpio = DIO48E_NGPIO; dio48egpio->chip.names = dio48e_names; dio48egpio->chip.get_direction = dio48e_gpio_get_direction; dio48egpio->chip.direction_input = dio48e_gpio_direction_input; dio48egpio->chip.direction_output = dio48e_gpio_direction_output; dio48egpio->chip.get = dio48e_gpio_get; dio48egpio->chip.set = dio48e_gpio_set; dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple; dio48egpio->base = base[id]; raw_spin_lock_init(&dio48egpio->lock); err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio); if (err) { dev_err(dev, "GPIO registering failed (%d)\n", err); return err; } /* initialize all GPIO as output */ outb(0x80, base[id] + 3); outb(0x00, base[id]); outb(0x00, base[id] + 1); outb(0x00, base[id] + 2); outb(0x00, base[id] + 3); outb(0x80, base[id] + 7); outb(0x00, base[id] + 4); outb(0x00, base[id] + 5); outb(0x00, base[id] + 6); outb(0x00, base[id] + 7); /* disable IRQ by default */ inb(base[id] + 0xB); err = gpiochip_irqchip_add(&dio48egpio->chip, &dio48e_irqchip, 0, handle_edge_irq, IRQ_TYPE_NONE); if (err) { dev_err(dev, "Could not add irqchip (%d)\n", err); return err; } err = devm_request_irq(dev, irq[id], dio48e_irq_handler, 0, name, dio48egpio); if (err) { dev_err(dev, "IRQ handler registering failed (%d)\n", err); return err; } return 0; }
static int serial_ir_probe(struct platform_device *dev) { struct rc_dev *rcdev; int i, nlow, nhigh, result; rcdev = devm_rc_allocate_device(&dev->dev, RC_DRIVER_IR_RAW); if (!rcdev) return -ENOMEM; if (hardware[type].send_pulse && hardware[type].send_space) rcdev->tx_ir = serial_ir_tx; if (hardware[type].set_send_carrier) rcdev->s_tx_carrier = serial_ir_tx_carrier; if (hardware[type].set_duty_cycle) rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle; switch (type) { case IR_HOMEBREW: rcdev->input_name = "Serial IR type home-brew"; break; case IR_IRDEO: rcdev->input_name = "Serial IR type IRdeo"; break; case IR_IRDEO_REMOTE: rcdev->input_name = "Serial IR type IRdeo remote"; break; case IR_ANIMAX: rcdev->input_name = "Serial IR type AnimaX"; break; case IR_IGOR: rcdev->input_name = "Serial IR type IgorPlug"; break; } rcdev->input_phys = KBUILD_MODNAME "/input0"; rcdev->input_id.bustype = BUS_HOST; rcdev->input_id.vendor = 0x0001; rcdev->input_id.product = 0x0001; rcdev->input_id.version = 0x0100; rcdev->open = serial_ir_open; rcdev->close = serial_ir_close; rcdev->dev.parent = &serial_ir.pdev->dev; rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; rcdev->driver_name = KBUILD_MODNAME; rcdev->map_name = RC_MAP_RC6_MCE; rcdev->min_timeout = 1; rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; rcdev->rx_resolution = 250000; serial_ir.rcdev = rcdev; setup_timer(&serial_ir.timeout_timer, serial_ir_timeout, (unsigned long)&serial_ir); result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler, share_irq ? IRQF_SHARED : 0, KBUILD_MODNAME, &hardware); if (result < 0) { if (result == -EBUSY) dev_err(&dev->dev, "IRQ %d busy\n", irq); else if (result == -EINVAL) dev_err(&dev->dev, "Bad irq number or handler\n"); return result; } /* Reserve io region. */ if ((iommap && (devm_request_mem_region(&dev->dev, iommap, 8 << ioshift, KBUILD_MODNAME) == NULL)) || (!iommap && (devm_request_region(&dev->dev, io, 8, KBUILD_MODNAME) == NULL))) { dev_err(&dev->dev, "port %04x already in use\n", io); dev_warn(&dev->dev, "use 'setserial /dev/ttySX uart none'\n"); dev_warn(&dev->dev, "or compile the serial port driver as module and\n"); dev_warn(&dev->dev, "make sure this module is loaded first\n"); return -EBUSY; } result = hardware_init_port(); if (result < 0) return result; /* Initialize pulse/space widths */ init_timing_params(50, 38000); /* If pin is high, then this must be an active low receiver. */ if (sense == -1) { /* wait 1/2 sec for the power supply */ msleep(500); /* * probe 9 times every 0.04s, collect "votes" for * active high/low */ nlow = 0; nhigh = 0; for (i = 0; i < 9; i++) { if (sinp(UART_MSR) & hardware[type].signal_pin) nlow++; else nhigh++; msleep(40); } sense = nlow >= nhigh ? 1 : 0; dev_info(&dev->dev, "auto-detected active %s receiver\n", sense ? "low" : "high"); } else dev_info(&dev->dev, "Manually using active %s receiver\n", sense ? "low" : "high"); dev_dbg(&dev->dev, "Interrupt %d, port %04x obtained\n", irq, io); return devm_rc_register_device(&dev->dev, rcdev); }
static int f71805f_probe(struct platform_device *pdev) { struct f71805f_sio_data *sio_data = dev_get_platdata(&pdev->dev); struct f71805f_data *data; struct resource *res; int i, err; static const char * const names[] = { "f71805f", "f71872f", }; data = devm_kzalloc(&pdev->dev, sizeof(struct f71805f_data), GFP_KERNEL); if (!data) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!devm_request_region(&pdev->dev, res->start + ADDR_REG_OFFSET, 2, DRVNAME)) { 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)); return -EBUSY; } 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 */ err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group); if (err) return err; if (data->has_in & (1 << 4)) { /* in4 */ err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[0]); if (err) goto exit_remove_files; } if (data->has_in & (1 << 8)) { /* in8 */ err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[1]); if (err) goto exit_remove_files; } if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */ err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[2]); if (err) goto exit_remove_files; } if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */ err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[3]); if (err) 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)) { err = sysfs_create_file(&pdev->dev.kobj, f71805f_attributes_pwm_freq[i]); if (err) goto exit_remove_files; } /* If PWM is in manual mode, add write permission */ if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) { err = sysfs_chmod_file(&pdev->dev.kobj, f71805f_attr_pwm[i], S_IRUGO | S_IWUSR); if (err) { 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); return err; }
static int stx104_probe(struct device *dev, unsigned int id) { struct iio_dev *indio_dev; struct stx104_iio *priv; struct stx104_gpio *stx104gpio; int err; indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); if (!indio_dev) return -ENOMEM; stx104gpio = devm_kzalloc(dev, sizeof(*stx104gpio), GFP_KERNEL); if (!stx104gpio) return -ENOMEM; if (!devm_request_region(dev, base[id], STX104_EXTENT, dev_name(dev))) { dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", base[id], base[id] + STX104_EXTENT); return -EBUSY; } indio_dev->info = &stx104_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = stx104_channels; indio_dev->num_channels = STX104_NUM_CHAN; indio_dev->name = dev_name(dev); priv = iio_priv(indio_dev); priv->base = base[id]; /* initialize DAC output to 0V */ outw(0, base[id] + 4); outw(0, base[id] + 6); err = devm_iio_device_register(dev, indio_dev); if (err) { dev_err(dev, "IIO device registering failed (%d)\n", err); return err; } stx104gpio->chip.label = dev_name(dev); stx104gpio->chip.parent = dev; stx104gpio->chip.owner = THIS_MODULE; stx104gpio->chip.base = -1; stx104gpio->chip.ngpio = 8; stx104gpio->chip.get_direction = stx104_gpio_get_direction; stx104gpio->chip.direction_input = stx104_gpio_direction_input; stx104gpio->chip.direction_output = stx104_gpio_direction_output; stx104gpio->chip.get = stx104_gpio_get; stx104gpio->chip.set = stx104_gpio_set; stx104gpio->base = base[id] + 3; stx104gpio->out_state = 0x0; spin_lock_init(&stx104gpio->lock); dev_set_drvdata(dev, stx104gpio); err = gpiochip_add_data(&stx104gpio->chip, stx104gpio); if (err) { dev_err(dev, "GPIO registering failed (%d)\n", err); return err; } return 0; }
static int cros_ec_lpc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct acpi_device *adev; acpi_status status; struct cros_ec_device *ec_dev; u8 buf[2]; int ret; if (!devm_request_region(dev, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE, dev_name(dev))) { dev_err(dev, "couldn't reserve memmap region\n"); return -EBUSY; } cros_ec_lpc_read_bytes(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID, 2, buf); if (buf[0] != 'E' || buf[1] != 'C') { dev_err(dev, "EC ID not detected\n"); return -ENODEV; } if (!devm_request_region(dev, EC_HOST_CMD_REGION0, EC_HOST_CMD_REGION_SIZE, dev_name(dev))) { dev_err(dev, "couldn't reserve region0\n"); return -EBUSY; } if (!devm_request_region(dev, EC_HOST_CMD_REGION1, EC_HOST_CMD_REGION_SIZE, dev_name(dev))) { dev_err(dev, "couldn't reserve region1\n"); return -EBUSY; } ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL); if (!ec_dev) return -ENOMEM; platform_set_drvdata(pdev, ec_dev); ec_dev->dev = dev; ec_dev->phys_name = dev_name(dev); ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc; ec_dev->pkt_xfer = cros_ec_pkt_xfer_lpc; ec_dev->cmd_readmem = cros_ec_lpc_readmem; ec_dev->din_size = sizeof(struct ec_host_response) + sizeof(struct ec_response_get_protocol_info); ec_dev->dout_size = sizeof(struct ec_host_request); ret = cros_ec_register(ec_dev); if (ret) { dev_err(dev, "couldn't register ec_dev (%d)\n", ret); return ret; } /* * Connect a notify handler to process MKBP messages if we have a * companion ACPI device. */ adev = ACPI_COMPANION(dev); if (adev) { status = acpi_install_notify_handler(adev->handle, ACPI_ALL_NOTIFY, cros_ec_lpc_acpi_notify, ec_dev); if (ACPI_FAILURE(status)) dev_warn(dev, "Failed to register notifier %08x\n", status); } return 0; }
static int nct6683_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct nct6683_sio_data *sio_data = dev->platform_data; struct attribute_group *group; struct nct6683_data *data; struct device *hwmon_dev; struct resource *res; int groups = 0; char build[16]; res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!devm_request_region(dev, res->start, IOREGION_LENGTH, DRVNAME)) return -EBUSY; data = devm_kzalloc(dev, sizeof(struct nct6683_data), GFP_KERNEL); if (!data) return -ENOMEM; data->kind = sio_data->kind; data->sioreg = sio_data->sioreg; data->addr = res->start; mutex_init(&data->update_lock); platform_set_drvdata(pdev, data); data->customer_id = nct6683_read16(data, NCT6683_REG_CUSTOMER_ID); /* By default only instantiate driver if the customer ID is known */ switch (data->customer_id) { case NCT6683_CUSTOMER_ID_INTEL: break; case NCT6683_CUSTOMER_ID_MITAC: break; default: if (!force) return -ENODEV; } nct6683_init_device(data); nct6683_setup_fans(data); nct6683_setup_sensors(data); /* Register sysfs hooks */ if (data->have_pwm) { group = nct6683_create_attr_group(dev, &nct6683_pwm_template_group, fls(data->have_pwm)); if (IS_ERR(group)) return PTR_ERR(group); data->groups[groups++] = group; } if (data->in_num) { group = nct6683_create_attr_group(dev, &nct6683_in_template_group, data->in_num); if (IS_ERR(group)) return PTR_ERR(group); data->groups[groups++] = group; } if (data->have_fan) { group = nct6683_create_attr_group(dev, &nct6683_fan_template_group, fls(data->have_fan)); if (IS_ERR(group)) return PTR_ERR(group); data->groups[groups++] = group; } if (data->temp_num) { group = nct6683_create_attr_group(dev, &nct6683_temp_template_group, data->temp_num); if (IS_ERR(group)) return PTR_ERR(group); data->groups[groups++] = group; } data->groups[groups++] = &nct6683_group_other; if (data->customer_id == NCT6683_CUSTOMER_ID_INTEL) scnprintf(build, sizeof(build), "%02x/%02x/%02x", nct6683_read(data, NCT6683_REG_BUILD_MONTH), nct6683_read(data, NCT6683_REG_BUILD_DAY), nct6683_read(data, NCT6683_REG_BUILD_YEAR)); else scnprintf(build, sizeof(build), "%02d/%02d/%02d", nct6683_read(data, NCT6683_REG_BUILD_MONTH), nct6683_read(data, NCT6683_REG_BUILD_DAY), nct6683_read(data, NCT6683_REG_BUILD_YEAR)); dev_info(dev, "%s EC firmware version %d.%d build %s\n", nct6683_chip_names[data->kind], nct6683_read(data, NCT6683_REG_VERSION_HI), nct6683_read(data, NCT6683_REG_VERSION_LO), build); hwmon_dev = devm_hwmon_device_register_with_groups(dev, nct6683_device_names[data->kind], data, data->groups); return PTR_ERR_OR_ZERO(hwmon_dev); }
/** * Does the PCI detection and init of the device. * * Return: 0 on success, negated errno on failure. */ static int vbg_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) { struct device *dev = &pci->dev; resource_size_t io, io_len, mmio, mmio_len; struct vmmdev_memory *vmmdev; struct vbg_dev *gdev; int ret; gdev = devm_kzalloc(dev, sizeof(*gdev), GFP_KERNEL); if (!gdev) return -ENOMEM; ret = pci_enable_device(pci); if (ret != 0) { vbg_err("vboxguest: Error enabling device: %d\n", ret); return ret; } ret = -ENODEV; io = pci_resource_start(pci, 0); io_len = pci_resource_len(pci, 0); if (!io || !io_len) { vbg_err("vboxguest: Error IO-port resource (0) is missing\n"); goto err_disable_pcidev; } if (devm_request_region(dev, io, io_len, DEVICE_NAME) == NULL) { vbg_err("vboxguest: Error could not claim IO resource\n"); ret = -EBUSY; goto err_disable_pcidev; } mmio = pci_resource_start(pci, 1); mmio_len = pci_resource_len(pci, 1); if (!mmio || !mmio_len) { vbg_err("vboxguest: Error MMIO resource (1) is missing\n"); goto err_disable_pcidev; } if (devm_request_mem_region(dev, mmio, mmio_len, DEVICE_NAME) == NULL) { vbg_err("vboxguest: Error could not claim MMIO resource\n"); ret = -EBUSY; goto err_disable_pcidev; } vmmdev = devm_ioremap(dev, mmio, mmio_len); if (!vmmdev) { vbg_err("vboxguest: Error ioremap failed; MMIO addr=%pap size=%pap\n", &mmio, &mmio_len); goto err_disable_pcidev; } /* Validate MMIO region version and size. */ if (vmmdev->version != VMMDEV_MEMORY_VERSION || vmmdev->size < 32 || vmmdev->size > mmio_len) { vbg_err("vboxguest: Bogus VMMDev memory; version=%08x (expected %08x) size=%d (expected <= %d)\n", vmmdev->version, VMMDEV_MEMORY_VERSION, vmmdev->size, (int)mmio_len); goto err_disable_pcidev; } gdev->io_port = io; gdev->mmio = vmmdev; gdev->dev = dev; gdev->misc_device.minor = MISC_DYNAMIC_MINOR; gdev->misc_device.name = DEVICE_NAME; gdev->misc_device.fops = &vbg_misc_device_fops; gdev->misc_device_user.minor = MISC_DYNAMIC_MINOR; gdev->misc_device_user.name = DEVICE_NAME_USER; gdev->misc_device_user.fops = &vbg_misc_device_user_fops; ret = vbg_core_init(gdev, VMMDEV_EVENT_MOUSE_POSITION_CHANGED); if (ret) goto err_disable_pcidev; ret = vbg_create_input_device(gdev); if (ret) { vbg_err("vboxguest: Error creating input device: %d\n", ret); goto err_vbg_core_exit; } ret = devm_request_irq(dev, pci->irq, vbg_core_isr, IRQF_SHARED, DEVICE_NAME, gdev); if (ret) { vbg_err("vboxguest: Error requesting irq: %d\n", ret); goto err_vbg_core_exit; } ret = misc_register(&gdev->misc_device); if (ret) { vbg_err("vboxguest: Error misc_register %s failed: %d\n", DEVICE_NAME, ret); goto err_vbg_core_exit; } ret = misc_register(&gdev->misc_device_user); if (ret) { vbg_err("vboxguest: Error misc_register %s failed: %d\n", DEVICE_NAME_USER, ret); goto err_unregister_misc_device; } mutex_lock(&vbg_gdev_mutex); if (!vbg_gdev) vbg_gdev = gdev; else ret = -EBUSY; mutex_unlock(&vbg_gdev_mutex); if (ret) { vbg_err("vboxguest: Error more then 1 vbox guest pci device\n"); goto err_unregister_misc_device_user; } pci_set_drvdata(pci, gdev); device_create_file(dev, &dev_attr_host_version); device_create_file(dev, &dev_attr_host_features); vbg_info("vboxguest: misc device minor %d, IRQ %d, I/O port %x, MMIO at %pap (size %pap)\n", gdev->misc_device.minor, pci->irq, gdev->io_port, &mmio, &mmio_len); return 0; err_unregister_misc_device_user: misc_deregister(&gdev->misc_device_user); err_unregister_misc_device: misc_deregister(&gdev->misc_device); err_vbg_core_exit: vbg_core_exit(gdev); err_disable_pcidev: pci_disable_device(pci); return ret; }