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

Commit a6c16c28 authored by Corey Minyard's avatar Corey Minyard Committed by Linus Torvalds
Browse files

IPMI: Detect register spacing on PCI interfaces



The IPMI spec defines a way to detect register spacing for PCI interfaces,
so implement it.

Signed-off-by: default avatarSteven Hsieh <sshsieh@broadcom.com>
Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9ebca93b
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -2424,6 +2424,38 @@ static void ipmi_pci_cleanup(struct smi_info *info)
	pci_disable_device(pdev);
}

static int __devinit ipmi_pci_probe_regspacing(struct smi_info *info)
{
	if (info->si_type == SI_KCS) {
		unsigned char	status;
		int		regspacing;

		info->io.regsize = DEFAULT_REGSIZE;
		info->io.regshift = 0;
		info->io_size = 2;
		info->handlers = &kcs_smi_handlers;

		/* detect 1, 4, 16byte spacing */
		for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) {
			info->io.regspacing = regspacing;
			if (info->io_setup(info)) {
				dev_err(info->dev,
					"Could not setup I/O space\n");
				return DEFAULT_REGSPACING;
			}
			/* write invalid cmd */
			info->io.outputb(&info->io, 1, 0x10);
			/* read status back */
			status = info->io.inputb(&info->io, 1);
			info->io_cleanup(info);
			if (status)
				return regspacing;
			regspacing *= 4;
		}
	}
	return DEFAULT_REGSPACING;
}

static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
				    const struct pci_device_id *ent)
{
@@ -2476,8 +2508,8 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
	}
	info->io.addr_data = pci_resource_start(pdev, 0);

	info->io.regspacing = DEFAULT_REGSPACING;
	info->io.regsize = DEFAULT_REGSPACING;
	info->io.regspacing = ipmi_pci_probe_regspacing(info);
	info->io.regsize = DEFAULT_REGSIZE;
	info->io.regshift = 0;

	info->irq = pdev->irq;