Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ef057fa authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[SERIAL] serial_cs: Convert Oxford 950 / Possio GCC wakeup quirk



Move the Oxford Semi OX950 / Possio GCC wakeup handling to a quirk
wakeup handler.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent eee3a883
Loading
Loading
Loading
Loading
+63 −37
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ struct serial_quirk {
	unsigned int manfid;
	unsigned int prodid;
	int multi;		/* 1 = multifunction, > 1 = # ports */
	void (*wakeup)(struct pcmcia_device *);
	int (*post)(struct pcmcia_device *);
};

@@ -130,16 +131,67 @@ static int quirk_post_ibm(struct pcmcia_device *link)
	return -ENODEV;
}

static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
{
	struct serial_info *info = link->priv;

	outb(12, info->c950ctrl + 1);
}

/* request_region? oxsemi branch does no request_region too... */
/*
 * This sequence is needed to properly initialize MC45 attached to OXCF950.
 * I tried decreasing these msleep()s, but it worked properly (survived
 * 1000 stop/start operations) with these timeouts (or bigger).
 */
static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
{
	struct serial_info *info = link->priv;
	unsigned int ctrl = info->c950ctrl;

	outb(0xA, ctrl + 1);
	msleep(100);
	outb(0xE, ctrl + 1);
	msleep(300);
	outb(0xC, ctrl + 1);
	msleep(100);
	outb(0xE, ctrl + 1);
	msleep(200);
	outb(0xF, ctrl + 1);
	msleep(100);
	outb(0xE, ctrl + 1);
	msleep(100);
	outb(0xC, ctrl + 1);
}

static const struct serial_quirk quirks[] = {
	{
		.manfid	= MANFID_IBM,
		.prodid	= ~0,
		.multi	= -1,
		.post	= quirk_post_ibm,
	}, {
		.manfid	= MANFID_INTEL,
		.prodid	= PRODID_INTEL_DUAL_RS232,
		.multi	= 2,
	}, {
		.manfid	= MANFID_NATINST,
		.prodid	= PRODID_NATINST_QUAD_RS232,
		.multi	= 4,
	}, {
		.manfid	= MANFID_OMEGA,
		.prodid	= PRODID_OMEGA_QSP_100,
		.multi	= 4,
	}, {
		.manfid	= MANFID_OXSEMI,
		.prodid	= ~0,
		.multi	= -1,
		.wakeup	= quirk_wakeup_oxsemi,
	}, {
		.manfid	= MANFID_POSSIO,
		.prodid	= PRODID_POSSIO_GCC,
		.multi	= -1,
		.wakeup	= quirk_wakeup_possio_gcc,
	}, {
		.manfid	= MANFID_QUATECH,
		.prodid	= PRODID_QUATECH_DUAL_RS232,
@@ -156,14 +208,6 @@ static const struct serial_quirk quirks[] = {
		.manfid	= MANFID_SOCKET,
		.prodid	= PRODID_SOCKET_DUAL_RS232,
		.multi	= 2,
	}, {
		.manfid	= MANFID_INTEL,
		.prodid	= PRODID_INTEL_DUAL_RS232,
		.multi	= 2,
	}, {
		.manfid	= MANFID_NATINST,
		.prodid	= PRODID_NATINST_QUAD_RS232,
		.multi	= 4,
	}
};

@@ -171,33 +215,6 @@ static const struct serial_quirk quirks[] = {
static int serial_config(struct pcmcia_device * link);


static void wakeup_card(struct serial_info *info)
{
	int ctrl = info->c950ctrl;

	if (info->manfid == MANFID_OXSEMI) {
		outb(12, ctrl + 1);
	} else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) {
		/* request_region? oxsemi branch does no request_region too... */
		/* This sequence is needed to properly initialize MC45 attached to OXCF950.
		 * I tried decreasing these msleep()s, but it worked properly (survived
		 * 1000 stop/start operations) with these timeouts (or bigger). */
		outb(0xA, ctrl + 1);
		msleep(100);
		outb(0xE, ctrl + 1);
		msleep(300);
		outb(0xC, ctrl + 1);
		msleep(100);
		outb(0xE, ctrl + 1);
		msleep(200);
		outb(0xF, ctrl + 1);
		msleep(100);
		outb(0xE, ctrl + 1);
		msleep(100);
		outb(0xC, ctrl + 1);
	}
}

/*======================================================================

    After a card is removed, serial_remove() will unregister
@@ -243,7 +260,9 @@ static int serial_resume(struct pcmcia_device *link)

		for (i = 0; i < info->ndev; i++)
			serial8250_resume_port(info->line[i]);
		wakeup_card(info);

		if (info->quirk && info->quirk->wakeup)
			info->quirk->wakeup(link);
	}

	return 0;
@@ -602,7 +621,14 @@ static int multi_config(struct pcmcia_device * link)
					link->irq.AssignedIRQ);
		}
		info->c950ctrl = base2;
		wakeup_card(info);

		/*
		 * FIXME: We really should wake up the port prior to
		 * handing it over to the serial layer.
		 */
		if (info->quirk && info->quirk->wakeup)
			info->quirk->wakeup(link);

		rc = 0;
		goto free_cfg_mem;
	}