Beispiel #1
0
int acpi_check_region(resource_size_t start, resource_size_t n,
		      const char *name)
{
	struct resource res = {
		.start = start,
		.end   = start + n - 1,
		.name  = name,
		.flags = IORESOURCE_IO,
	};

	return acpi_check_resource_conflict(&res);
}
EXPORT_SYMBOL(acpi_check_region);

/*
 * Let drivers know whether the resource checks are effective
 */
int acpi_resources_are_enforced(void)
{
	return acpi_enforce_resources == ENFORCE_RESOURCES_STRICT;
}
EXPORT_SYMBOL(acpi_resources_are_enforced);

/*
 * Deallocate the memory for a spinlock.
 */
void acpi_os_delete_lock(acpi_spinlock handle)
{
	ACPI_FREE(handle);
}
Beispiel #2
0
int acpi_check_region(resource_size_t start, resource_size_t n,
		      const char *name)
{
	struct resource res = {
		.start = start,
		.end   = start + n - 1,
		.name  = name,
		.flags = IORESOURCE_IO,
	};

	return acpi_check_resource_conflict(&res);
}
EXPORT_SYMBOL(acpi_check_region);

int acpi_resources_are_enforced(void)
{
	return acpi_enforce_resources == ENFORCE_RESOURCES_STRICT;
}
EXPORT_SYMBOL(acpi_resources_are_enforced);

void acpi_os_delete_lock(acpi_spinlock handle)
{
	ACPI_FREE(handle);
}
Beispiel #3
0
static int mfd_add_device(struct device *parent, int id,
			  const struct mfd_cell *cell,
			  struct resource *mem_base,
			  int irq_base)
{
	struct resource *res;
	struct platform_device *pdev;
	int ret = -ENOMEM;
	int r;

	pdev = platform_device_alloc(cell->name, id + cell->id);
	if (!pdev)
		goto fail_alloc;

	res = kzalloc(sizeof(*res) * cell->num_resources, GFP_KERNEL);
	if (!res)
		goto fail_device;

	pdev->dev.parent = parent;
        pdev->dev.type = &mfd_dev_type;
        
	if (cell->pdata_size) {
		ret = platform_device_add_data(pdev,
					cell->platform_data, cell->pdata_size);
		if (ret)
			goto fail_res;
	}

	ret = mfd_platform_add_cell(pdev, cell);
	if (ret)
		goto fail_res;

	for (r = 0; r < cell->num_resources; r++) {
		res[r].name = cell->resources[r].name;
		res[r].flags = cell->resources[r].flags;

		/* Find out base to use */
		if ((cell->resources[r].flags & IORESOURCE_MEM) && mem_base) {
			res[r].parent = mem_base;
			res[r].start = mem_base->start +
				cell->resources[r].start;
			res[r].end = mem_base->start +
				cell->resources[r].end;
		} else if (cell->resources[r].flags & IORESOURCE_IRQ) {
			res[r].start = irq_base +
				cell->resources[r].start;
			res[r].end   = irq_base +
				cell->resources[r].end;
		} else {
			res[r].parent = cell->resources[r].parent;
			res[r].start = cell->resources[r].start;
			res[r].end   = cell->resources[r].end;
		}

		if (!cell->ignore_resource_conflicts) {
			ret = acpi_check_resource_conflict(&res[r]);
			if (ret)
				goto fail_res;
		}
	}

	ret = platform_device_add_resources(pdev, res, cell->num_resources);
	if (ret)
		goto fail_res;

	ret = platform_device_add(pdev);
	if (ret)
		goto fail_res;

	if (cell->pm_runtime_no_callbacks)
		pm_runtime_no_callbacks(&pdev->dev);

	kfree(res);

	return 0;

fail_res:
	kfree(res);
fail_device:
	platform_device_put(pdev);
fail_alloc:
	return ret;
}
Beispiel #4
0
static int __init pc87427_device_add(unsigned short address)
{
	struct resource res = {
		.start	= address,
		.end	= address + REGION_LENGTH - 1,
		.name	= logdev_str[0],
		.flags	= IORESOURCE_IO,
	};
	int err;

	err = acpi_check_resource_conflict(&res);
	if (err)
		goto exit;

	pdev = platform_device_alloc(DRVNAME, address);
	if (!pdev) {
		err = -ENOMEM;
		printk(KERN_ERR DRVNAME ": Device allocation failed\n");
		goto exit;
	}

	err = platform_device_add_resources(pdev, &res, 1);
	if (err) {
		printk(KERN_ERR DRVNAME ": Device resource addition failed "
		       "(%d)\n", err);
		goto exit_device_put;
	}

	err = platform_device_add(pdev);
	if (err) {
		printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
		       err);
		goto exit_device_put;
	}

	return 0;

exit_device_put:
	platform_device_put(pdev);
exit:
	return err;
}

static int __init pc87427_find(int sioaddr, unsigned short *address)
{
	u16 val;
	int i, err = 0;

	/* Identify device */
	val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
	if (val != 0xf2) {	/* PC87427 */
		err = -ENODEV;
		goto exit;
	}

	for (i = 0; i < 2; i++) {
		address[i] = 0;
		/* Select logical device */
		superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]);

		val = superio_inb(sioaddr, SIOREG_ACT);
		if (!(val & 0x01)) {
			printk(KERN_INFO DRVNAME ": Logical device 0x%02x "
			       "not activated\n", logdev[i]);
			continue;
		}

		val = superio_inb(sioaddr, SIOREG_MAP);
		if (val & 0x01) {
			printk(KERN_WARNING DRVNAME ": Logical device 0x%02x "
			       "is memory-mapped, can't use\n", logdev[i]);
			continue;
		}

		val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
		    | superio_inb(sioaddr, SIOREG_IOBASE + 1);
		if (!val) {
			printk(KERN_INFO DRVNAME ": I/O base address not set "
			       "for logical device 0x%02x\n", logdev[i]);
			continue;
		}
		address[i] = val;
	}

exit:
	superio_exit(sioaddr);
	return err;
}
Beispiel #5
0
static int __init f71805f_device_add(unsigned short address,
				     const struct f71805f_sio_data *sio_data)
{
	struct resource res = {
		.start	= address,
		.end	= address + REGION_LENGTH - 1,
		.flags	= IORESOURCE_IO,
	};
	int err;

	pdev = platform_device_alloc(DRVNAME, address);
	if (!pdev) {
		err = -ENOMEM;
		printk(KERN_ERR DRVNAME ": Device allocation failed\n");
		goto exit;
	}

	res.name = pdev->name;
	err = acpi_check_resource_conflict(&res);
	if (err)
		goto exit_device_put;

	err = platform_device_add_resources(pdev, &res, 1);
	if (err) {
		printk(KERN_ERR DRVNAME ": Device resource addition failed "
		       "(%d)\n", err);
		goto exit_device_put;
	}

	err = platform_device_add_data(pdev, sio_data,
				       sizeof(struct f71805f_sio_data));
	if (err) {
		printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
		goto exit_device_put;
	}

	err = platform_device_add(pdev);
	if (err) {
		printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
		       err);
		goto exit_device_put;
	}

	return 0;

exit_device_put:
	platform_device_put(pdev);
exit:
	return err;
}

static int __init f71805f_find(int sioaddr, unsigned short *address,
			       struct f71805f_sio_data *sio_data)
{
	int err = -ENODEV;
	u16 devid;

	static const char *names[] = {
		"F71805F/FG",
		"F71872F/FG or F71806F/FG",
	};

	superio_enter(sioaddr);

	devid = superio_inw(sioaddr, SIO_REG_MANID);
	if (devid != SIO_FINTEK_ID)
		goto exit;

	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
	switch (devid) {
	case SIO_F71805F_ID:
		sio_data->kind = f71805f;
		break;
	case SIO_F71872F_ID:
		sio_data->kind = f71872f;
		sio_data->fnsel1 = superio_inb(sioaddr, SIO_REG_FNSEL1);
		break;
	default:
		printk(KERN_INFO DRVNAME ": Unsupported Fintek device, "
		       "skipping\n");
		goto exit;
	}

	superio_select(sioaddr, F71805F_LD_HWM);
	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
		printk(KERN_WARNING DRVNAME ": Device not activated, "
		       "skipping\n");
		goto exit;
	}

	*address = superio_inw(sioaddr, SIO_REG_ADDR);
	if (*address == 0) {
		printk(KERN_WARNING DRVNAME ": Base address not set, "
		       "skipping\n");
		goto exit;
	}
	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */

	err = 0;
	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %u\n",
	       names[sio_data->kind], *address,
	       superio_inb(sioaddr, SIO_REG_DEVREV));

exit:
	superio_exit(sioaddr);
	return err;
}
static int __init smsc47b397_device_add(unsigned short address)
{
	struct resource res = {
		.start	= address,
		.end	= address + SMSC_EXTENT - 1,
		.name	= DRVNAME,
		.flags	= IORESOURCE_IO,
	};
	int err;

	err = acpi_check_resource_conflict(&res);
	if (err)
		goto exit;

	pdev = platform_device_alloc(DRVNAME, address);
	if (!pdev) {
		err = -ENOMEM;
		pr_err("Device allocation failed\n");
		goto exit;
	}

	err = platform_device_add_resources(pdev, &res, 1);
	if (err) {
		pr_err("Device resource addition failed (%d)\n", err);
		goto exit_device_put;
	}

	err = platform_device_add(pdev);
	if (err) {
		pr_err("Device addition failed (%d)\n", err);
		goto exit_device_put;
	}

	return 0;

exit_device_put:
	platform_device_put(pdev);
exit:
	return err;
}

static int __init smsc47b397_find(void)
{
	u8 id, rev;
	char *name;
	unsigned short addr;

	superio_enter();
	id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);

	switch (id) {
	case 0x81:
		name = "SCH5307-NS";
		break;
	case 0x6f:
		name = "LPC47B397-NC";
		break;
	case 0x85:
	case 0x8c:
		name = "SCH5317";
		break;
	default:
		superio_exit();
		return -ENODEV;
	}

	rev = superio_inb(SUPERIO_REG_DEVREV);

	superio_select(SUPERIO_REG_LD8);
	addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
		 |  superio_inb(SUPERIO_REG_BASE_LSB);

	pr_info("found SMSC %s (base address 0x%04x, revision %u)\n",
		name, addr, rev);

	superio_exit();
	return addr;
}
Beispiel #7
0
static int __init sensors_nct6683_init(void)
{
	struct nct6683_sio_data sio_data;
	int sioaddr[2] = { 0x2e, 0x4e };
	struct resource res;
	bool found = false;
	int address;
	int i, err;

	err = platform_driver_register(&nct6683_driver);
	if (err)
		return err;

	/*
	 * initialize sio_data->kind and sio_data->sioreg.
	 *
	 * when Super-I/O functions move to a separate file, the Super-I/O
	 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
	 * nct6683 hardware monitor, and call probe()
	 */
	for (i = 0; i < ARRAY_SIZE(pdev); i++) {
		address = nct6683_find(sioaddr[i], &sio_data);
		if (address <= 0)
			continue;

		found = true;

		pdev[i] = platform_device_alloc(DRVNAME, address);
		if (!pdev[i]) {
			err = -ENOMEM;
			goto exit_device_unregister;
		}

		err = platform_device_add_data(pdev[i], &sio_data,
					       sizeof(struct nct6683_sio_data));
		if (err)
			goto exit_device_put;

		memset(&res, 0, sizeof(res));
		res.name = DRVNAME;
		res.start = address + IOREGION_OFFSET;
		res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
		res.flags = IORESOURCE_IO;

		err = acpi_check_resource_conflict(&res);
		if (err) {
			platform_device_put(pdev[i]);
			pdev[i] = NULL;
			continue;
		}

		err = platform_device_add_resources(pdev[i], &res, 1);
		if (err)
			goto exit_device_put;

		/* platform_device_add calls probe() */
		err = platform_device_add(pdev[i]);
		if (err)
			goto exit_device_put;
	}
	if (!found) {
		err = -ENODEV;
		goto exit_unregister;
	}

	return 0;

exit_device_put:
	platform_device_put(pdev[i]);
exit_device_unregister:
	while (--i >= 0) {
		if (pdev[i])
			platform_device_unregister(pdev[i]);
	}
exit_unregister:
	platform_driver_unregister(&nct6683_driver);
	return err;
}