Commit 36d46a59 authored by Johannes Berg's avatar Johannes Berg Committed by Richard Weinberger
Browse files

um: Support dynamic IRQ allocation



It's cumbersome and error-prone to keep adding fixed IRQ numbers,
and for proper device wakeup support for the virtio/vhost-user
support we need to have different IRQs for each device. Even if
in theory two IRQs (with and without wake) might be sufficient,
it's much easier to reason about it when we have dynamic number
assignment. It also makes it easier to add new devices that may
dynamically exist or depending on the configuration, etc.

Add support for this, up to 64 IRQs (the same limit as epoll FDs
we have right now). Since it's not easy to port all the existing
places to dynamic allocation (some data is statically initialized)
keep the low numbers are reserved for the existing hard-coded IRQ
numbers.

Acked-By: default avatarAnton Ivanov <anton.ivanov@cambridgegreys.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Acked-By: default avatarAnton Ivanov <anton.ivanov@cambridgegreys.com>
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent d66c9183
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -262,21 +262,27 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
{
	const struct line_driver *driver = line->driver;
	int err = 0;
	int err;

	if (input)
	if (input) {
		err = um_request_irq(driver->read_irq, fd, IRQ_READ,
				     line_interrupt, IRQF_SHARED,
				     driver->read_irq_name, data);
	if (err)
		if (err < 0)
			return err;
	if (output)
	}

	if (output) {
		err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
				     line_write_interrupt, IRQF_SHARED,
				     driver->write_irq_name, data);
		if (err < 0)
			return err;
	}

	return 0;
}

static int line_activate(struct tty_port *port, struct tty_struct *tty)
{
	int ret;
+1 −1
Original line number Diff line number Diff line
@@ -738,7 +738,7 @@ static int __init mconsole_init(void)

	err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
			     IRQF_SHARED, "mconsole", (void *)sock);
	if (err) {
	if (err < 0) {
		printk(KERN_ERR "Failed to get IRQ for management console\n");
		goto out;
	}
+1 −1
Original line number Diff line number Diff line
@@ -160,7 +160,7 @@ static int uml_net_open(struct net_device *dev)

	err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
			     IRQF_SHARED, dev->name, dev);
	if (err != 0) {
	if (err < 0) {
		printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
		err = -ENETUNREACH;
		goto out_close;
+2 −2
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ static int port_accept(struct port_list *port)
		  .port 	= port });

	if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
			  IRQF_SHARED, "telnetd", conn)) {
			  IRQF_SHARED, "telnetd", conn) < 0) {
		printk(KERN_ERR "port_accept : failed to get IRQ for "
		       "telnetd\n");
		goto out_free;
@@ -182,7 +182,7 @@ void *port_data(int port_num)
	}

	if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
			  IRQF_SHARED, "port", port)) {
			  IRQF_SHARED, "port", port) < 0) {
		printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
		goto out_close;
	}
+1 −1
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ static int __init rng_init (void)
	random_fd = err;
	err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
			     0, "random", NULL);
	if (err)
	if (err < 0)
		goto err_out_cleanup_hw;

	sigio_broken(random_fd, 1);
Loading