All of lore.kernel.org
 help / color / mirror / Atom feed
From: "David E. Box" <david.e.box@linux.intel.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: mjg59@srcf.ucam.org, linux-kernel@vger.kernel.org,
	platform-driver-x86@vger.kernel.org
Subject: Re: [PATCH v5][RESEND] X86 platform: New BayTrail IOSF-SB MBI driver
Date: Thu, 19 Dec 2013 23:01:44 -0800	[thread overview]
Message-ID: <20131220070144.GA17342@linux.intel.com> (raw)
In-Reply-To: <2414298.1sYXWhUkOA@vostro.rjw.lan>

On Fri, Dec 20, 2013 at 02:59:29AM +0100, Rafael J. Wysocki wrote:
> On Thursday, December 19, 2013 02:37:46 PM David E. Box wrote:
> > From: "David E. Box" <david.e.box@linux.intel.com>
> > 
> > Current Intel SOC cores use a MailBox Interface (MBI) to provide access to unit
> > devices connected to the system fabric. This driver implements access to this
> > interface on BayTrail platforms. This is a requirement for drivers that need
> > access to unit registers on the platform (e.g. accessing the PUNIT for power
> > management features such as RAPL). Serialized access is handled by all exported
> > routines with spinlocks.
> > 
> > The API includes 3 functions for access to unit registers:
> > 
> > int bt_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr)
> > int bt_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr)
> > int bt_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask)
> > 
> > port:	indicating the unit being accessed
> > opcode:	the read or write port specific opcode
> > offset:	the register offset within the port
> > mdr:	the register data to be read, written, or modified
> > mask:	bit locations in mdr to change
> > 
> > Returns nonzero on error
> > 
> > Note: GPU code handles access to the GFX unit. Therefore access to that unit
> > with this driver is disallowed to avoid conflicts.
> > 
> > Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> > ---
> > v5: Converted from pnpacpi/mmio driver to pci/config_space driver as
> >     necessitated by firmware change.
> > 
> > v4: Define driver as platform specific to BayTrail as some platforms cannot
> >     enumerate the MBI using ACPI as noted by Bin Gao <bin.gao@linux.intel.com>
> >     Renamed register macros and API funcitons to platform specific names.
> >     Changed dependency to PNPACPI as sugessted by Rafael Wysocki <rjw@rjwysocki.net>
> > 
> > v3: Converted to PNP ACPI driver as sugessted by Rafael Wysocki <rjw@rjwysocki.net>
> >     Removed config visibility to user as suggested by Andi Kleen <andi@firstfloor.org>
> > 
> > v2: Made modular since there was no longer a reason not to
> >     Moved to x86 platform as suggested by Mathhew Garrett <mjg59@srcf.ucam.org>
> >     Added probe to init to cause driver load to fail if device not detected.
> > 
> >  drivers/platform/x86/Kconfig          |    8 ++
> >  drivers/platform/x86/Makefile         |    1 +
> >  drivers/platform/x86/intel_baytrail.c |  224 +++++++++++++++++++++++++++++++++
> >  drivers/platform/x86/intel_baytrail.h |   90 +++++++++++++
> >  4 files changed, 323 insertions(+)
> >  create mode 100644 drivers/platform/x86/intel_baytrail.c
> >  create mode 100644 drivers/platform/x86/intel_baytrail.h
> > 
> > diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> > index b51a746..b482e22 100644
> > --- a/drivers/platform/x86/Kconfig
> > +++ b/drivers/platform/x86/Kconfig
> > @@ -819,4 +819,12 @@ config PVPANIC
> >  	  a paravirtualized device provided by QEMU; it lets a virtual machine
> >  	  (guest) communicate panic events to the host.
> >  
> > +config INTEL_BAYTRAIL_MBI
> > +	tristate
> > +	depends on PCI
> > +	---help---
> > +	  Needed on Baytrail platforms for access to the IOSF Sideband Mailbox
> > +	  Interface. This is a requirement for systems that need to configure
> > +	  the PUNIT for power management features such as RAPL.
> > +
> >  endif # X86_PLATFORM_DEVICES
> > diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> > index 5dbe193..b3d4cfd 100644
> > --- a/drivers/platform/x86/Makefile
> > +++ b/drivers/platform/x86/Makefile
> > @@ -55,3 +55,4 @@ obj-$(CONFIG_INTEL_RST)		+= intel-rst.o
> >  obj-$(CONFIG_INTEL_SMARTCONNECT)	+= intel-smartconnect.o
> >  
> >  obj-$(CONFIG_PVPANIC)           += pvpanic.o
> > +obj-$(CONFIG_INTEL_BAYTRAIL_MBI)	+= intel_baytrail.o
> > diff --git a/drivers/platform/x86/intel_baytrail.c b/drivers/platform/x86/intel_baytrail.c
> > new file mode 100644
> > index 0000000..f96626b
> > --- /dev/null
> > +++ b/drivers/platform/x86/intel_baytrail.c
> > @@ -0,0 +1,224 @@
> > +/*
> > + * Baytrail IOSF-SB MailBox Interface Driver
> > + * Copyright (c) 2013, Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> > + * more details.
> > + *
> > + *
> > + * The IOSF-SB is a fabric bus available on Atom based SOC's that uses a
> > + * mailbox interface (MBI) to communicate with mutiple devices. This
> > + * driver implements BayTrail-specific access to this interface.
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/init.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/pci.h>
> > +
> > +#include "intel_baytrail.h"
> > +
> > +static DEFINE_SPINLOCK(iosf_mbi_lock);
> > +
> > +static inline u32 iosf_mbi_form_mcr(u8 op, u8 port, u8 offset)
> > +{
> > +	return (op << 24) | (port << 16) | (offset << 8) | BT_MBI_ENABLE;
> > +}
> > +
> > +static struct pci_dev *mbi_pdev;	/* one mbi device */
> > +
> > +/* Hold lock before calling */
> 
> Which lock?
>
> > +static int iosf_mbi_pci_read_mdr(u32 mcrx, u32 mcr, u32 *mdr)
> > +{
> > +	int result;
> > +
> > +	if (!mbi_pdev)
> > +		return -ENODEV;
> > +
> > +	if (mcrx) {
> > +		result = pci_write_config_dword(mbi_pdev,
> > +						BT_MBI_MCRX_OFFSET, mcrx);
> > +		if (result < 0)
> > +			goto iosf_mbi_read_err;
> 
> Why not to call the label just err?
> 

I like the clarity since there are multiple goto labels

> > +	}
> > +
> > +	result = pci_write_config_dword(mbi_pdev,
> > +					BT_MBI_MCR_OFFSET, mcr);
> 
> Doesn't that fit into 80 chars?
> 

ok

> > +	if (result < 0)
> > +		goto iosf_mbi_read_err;
> > +
> > +	result = pci_read_config_dword(mbi_pdev,
> > +				       BT_MBI_MDR_OFFSET, mdr);
> > +	if (result < 0)
> > +		goto iosf_mbi_read_err;
> > +
> > +	return 0;
> > +
> > +iosf_mbi_read_err:
> > +	dev_err(&mbi_pdev->dev, "error: PCI config operation returned %d\n",
> > +		result);
> 
> If you said "PCI config access failed with %d\n", you wouldn't need the "error:" thing.
> 

ok

> > +	return result;
> > +}
> > +
> > +/* Hold lock before calling */
> > +static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr)
> > +{
> > +	int result;
> > +
> > +	if (!mbi_pdev)
> > +		return -ENODEV;
> > +
> > +	result = pci_write_config_dword(mbi_pdev,
> > +					BT_MBI_MDR_OFFSET, mdr);
> > +	if (result < 0)
> > +		goto iosf_mbi_write_err;
> > +
> > +	if (mcrx) {
> > +		result = pci_write_config_dword(mbi_pdev,
> > +			 BT_MBI_MCRX_OFFSET, mcrx);
> > +		if (result < 0)
> > +			goto iosf_mbi_write_err;
> > +	}
> > +
> > +	result = pci_write_config_dword(mbi_pdev,
> > +					BT_MBI_MCR_OFFSET, mcr);
> > +	if (result < 0)
> > +		goto iosf_mbi_write_err;
> > +
> > +	return 0;
> > +
> > +iosf_mbi_write_err:
> > +	dev_err(&mbi_pdev->dev, "error: PCI config operation returned %d\n",
> > +		result);
> > +	return result;
> > +}
> > +
> > +int bt_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr)
> > +{
> > +	u32 mcr, mcrx;
> > +	unsigned long flags;
> > +	int ret;
> > +
> > +	/*Access to the GFX unit is handled by GPU code */
> > +	BUG_ON(port == BT_MBI_UNIT_GFX);
> 
> Is that a good enough reason to crash the kernel?  Maybe WARN_ON() + return error
> would be sufficient?
> 

Ok.

> > +
> > +	mcr = iosf_mbi_form_mcr(opcode, port, offset & BT_MBI_MASK_LO);
> > +	mcrx = offset & BT_MBI_MASK_HI;
> > +
> > +	spin_lock_irqsave(&iosf_mbi_lock, flags);
> > +	ret = iosf_mbi_pci_read_mdr(mcrx, mcr, mdr);
> > +	spin_unlock_irqrestore(&iosf_mbi_lock, flags);
> > +
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(bt_mbi_read);
> > +
> > +int bt_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr)
> > +{
> > +	u32 mcr, mcrx;
> > +	unsigned long flags;
> > +	int ret;
> > +
> > +	/*Access to the GFX unit is handled by GPU code */
> > +	BUG_ON(port == BT_MBI_UNIT_GFX);
> 
> Same comment here.
> 
> > +
> > +	mcr = iosf_mbi_form_mcr(opcode, port, offset & BT_MBI_MASK_LO);
> > +	mcrx = offset & BT_MBI_MASK_HI;
> > +
> > +	spin_lock_irqsave(&iosf_mbi_lock, flags);
> > +	ret = iosf_mbi_pci_write_mdr(mcrx, mcr, mdr);
> > +	spin_unlock_irqrestore(&iosf_mbi_lock, flags);
> > +
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(bt_mbi_write);
> > +
> > +int bt_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask)
> > +{
> > +	u32 mcr, mcrx;
> > +	u32 value;
> > +	unsigned long flags;
> > +	int ret;
> > +
> > +	/*Access to the GFX unit is handled by GPU code */
> > +	BUG_ON(port == BT_MBI_UNIT_GFX);
> 
> And here.
> 
> > +
> > +	mcr = iosf_mbi_form_mcr(opcode, port, offset & BT_MBI_MASK_LO);
> > +	mcrx = offset & BT_MBI_MASK_HI;
> > +
> > +	spin_lock_irqsave(&iosf_mbi_lock, flags);
> > +
> > +	/* Read current mdr value */
> > +	ret = iosf_mbi_pci_read_mdr(mcrx, mcr & BT_MBI_RD_MASK, &value);
> > +	if (ret < 0) {
> > +		spin_unlock_irqrestore(&iosf_mbi_lock, flags);
> > +		return ret;
> > +	}
> > +
> > +	/* Apply mask */
> > +	value &= ~mask;
> > +	mdr &= mask;
> > +	value |= mdr;
> > +
> > +	/* Write back */
> > +	ret = iosf_mbi_pci_write_mdr(mcrx, mcr | BT_MBI_WR_MASK, value);
> > +
> > +	spin_unlock_irqrestore(&iosf_mbi_lock, flags);
> > +
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(bt_mbi_modify);
> > +
> > +static int iosf_mbi_probe(struct pci_dev *pdev,
> > +			  const struct pci_device_id *unused)
> > +{
> > +	int ret;
> > +
> > +	ret = pci_enable_device(pdev);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "error: could not enable device\n");
> > +		return ret;
> > +	}
> > +
> > +	mbi_pdev = pci_dev_get(pdev);
> > +	return 0;
> > +}
> > +
> > +static DEFINE_PCI_DEVICE_TABLE(iosf_mbi_pci_ids) = {
> > +	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0F00) },
> > +	{ 0, },
> > +};
> > +MODULE_DEVICE_TABLE(pci, iosf_mbi_pci_ids);
> > +
> > +static struct pci_driver iosf_mbi_pci_driver = {
> > +	.name		= "iosf_mbi_pci",
> > +	.probe		= iosf_mbi_probe,
> > +	.id_table	= iosf_mbi_pci_ids,
> > +};
> > +
> > +static int __init bt_mbi_init(void)
> > +{
> > +	return pci_register_driver(&iosf_mbi_pci_driver);
> > +}
> > +
> > +static void __exit bt_mbi_exit(void)
> > +{
> > +	pci_unregister_driver(&iosf_mbi_pci_driver);
> > +	if (mbi_pdev) {
> > +		pci_dev_put(mbi_pdev);
> > +		mbi_pdev = NULL;
> > +	}
> > +}
> > +
> > +module_init(bt_mbi_init);
> > +module_exit(bt_mbi_exit);
> > +
> > +MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
> > +MODULE_DESCRIPTION("BayTrail Mailbox Interface accessor");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/drivers/platform/x86/intel_baytrail.h b/drivers/platform/x86/intel_baytrail.h
> > new file mode 100644
> > index 0000000..8bcc311
> > --- /dev/null
> > +++ b/drivers/platform/x86/intel_baytrail.h
> > @@ -0,0 +1,90 @@
> > +/*
> > + * intel_baytrail.h: MailBox access support for Intel BayTrail platforms
> > + */
> > +
> > +#ifndef INTEL_BAYTRAIL_MBI_SYMS_H
> > +#define INTEL_BAYTRAIL_MBI_SYMS_H
> > +
> > +#define BT_MBI_MCR_OFFSET	0xD0
> > +#define BT_MBI_MDR_OFFSET	0xD4
> > +#define BT_MBI_MCRX_OFFSET	0xD8
> > +
> > +#define BT_MBI_RD_MASK		0xFEFFFFFF
> > +#define BT_MBI_WR_MASK		0X01000000
> > +
> > +#define BT_MBI_MASK_HI		0xFFFFFF00
> > +#define BT_MBI_MASK_LO		0x000000FF
> > +#define BT_MBI_ENABLE		0xF0
> > +
> > +/* BT-SB unit access methods */
> > +#define BT_MBI_UNIT_AUNIT	0x00
> > +#define BT_MBI_UNIT_SMC		0x01
> > +#define BT_MBI_UNIT_CPU		0x02
> > +#define BT_MBI_UNIT_BUNIT	0x03
> > +#define BT_MBI_UNIT_PMC		0x04
> > +#define BT_MBI_UNIT_GFX		0x06
> > +#define BT_MBI_UNIT_SMI		0x0C
> > +#define BT_MBI_UNIT_USB		0x43
> > +#define BT_MBI_UNIT_SATA	0xA3
> > +#define BT_MBI_UNIT_PCIE	0xA6
> > +
> > +/* Read/write opcodes */
> > +#define BT_MBI_AUNIT_READ	0x10
> > +#define BT_MBI_AUNIT_WRITE	0x11
> > +#define BT_MBI_SMC_READ		0x10
> > +#define BT_MBI_SMC_WRITE	0x11
> > +#define BT_MBI_CPU_READ		0x10
> > +#define BT_MBI_CPU_WRITE	0x11
> > +#define BT_MBI_BUNIT_READ	0x10
> > +#define BT_MBI_BUNIT_WRITE	0x11
> > +#define BT_MBI_PMC_READ		0x06
> > +#define BT_MBI_PMC_WRITE	0x07
> > +#define BT_MBI_GFX_READ		0x00
> > +#define BT_MBI_GFX_WRITE	0x01
> > +#define BT_MBI_SMIO_READ	0x06
> > +#define BT_MBI_SMIO_WRITE	0x07
> > +#define BT_MBI_USB_READ		0x06
> > +#define BT_MBI_USB_WRITE	0x07
> > +#define BT_MBI_SATA_READ	0x00
> > +#define BT_MBI_SATA_WRITE	0x01
> > +#define BT_MBI_PCIE_READ	0x00
> > +#define BT_MBI_PCIE_WRITE	0x01
> > +
> > +/**
> > + * bt_mbi_read() - MailBox Interface read command
> > + * @port:	port indicating subunit being accessed
> > + * @opcode:	port specific read or write opcode
> > + * @offset:	register address offset
> > + * @mdr:	register data to be read
> > + *
> > + * Locking is handled by spinlock - cannot sleep.
> > + * Return: Nonzero on error
> > + */
> > +int bt_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr);
> > +
> > +/**
> > + * bt_mbi_write() - MailBox unmasked write command
> > + * @port:	port indicating subunit being accessed
> > + * @opcode:	port specific read or write opcode
> > + * @offset:	register address offset
> > + * @mdr:	register data to be written
> > + *
> > + * Locking is handled by spinlock - cannot sleep.
> > + * Return: Nonzero on error
> > + */
> > +int bt_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr);
> > +
> > +/**
> > + * bt_mbi_modify() - MailBox masked write command
> > + * @port:	port indicating subunit being accessed
> > + * @opcode:	port specific read or write opcode
> > + * @offset:	register address offset
> > + * @mdr:	register data being modified
> > + * @mask:	mask indicating bits in mdr to be modified
> > + *
> > + * Locking is handled by spinlock - cannot sleep.
> > + * Return: Nonzero on error
> > + */
> > +int bt_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask);
> > +
> > +#endif /* INTEL_BAYTRAIL_MBI_SYMS_H */
> 
> Are the users of the interface supposed to include this file?
>

Only for the macro definitions.

> Rafael

- Dave

  reply	other threads:[~2013-12-20  7:03 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-22  6:05 [PATCH 1/2] New Driver for IOSF-SB MBI access on Intel SOCs David E. Box
2013-11-22  6:05 ` [PATCH 2/2] ACPI / platform: Add ACPI ID for Intel IOSF-SB David E. Box
2013-11-22 18:18 ` [PATCH 1/2] New Driver for IOSF-SB MBI access on Intel SOCs Matthew Garrett
2013-11-24  0:41 ` One Thousand Gnomes
2013-12-03 23:59 ` [PATCHv2 0/2] New driver for Intel IOSF MBI access David E. Box
2013-12-03 23:59   ` [PATCHv2 1/2] New Driver for IOSF-SB MBI access on Intel SOCs David E. Box
2013-12-04  6:44     ` Andi Kleen
2013-12-03 23:59   ` [PATCHv2 2/2] ACPI/platform: Add ACPI ID for Intel MBI device David E. Box
2013-12-04  1:30     ` Matthew Garrett
2013-12-04  2:17       ` David E. Box
2013-12-04  2:21         ` Matthew Garrett
2013-12-04  2:44           ` David E. Box
2013-12-04  2:54             ` Matthew Garrett
2013-12-04 21:34               ` Rafael J. Wysocki
2013-12-05 20:01   ` [PATCH] X86 platform: New IOSF-SB MBI driver for Intel SOCs David E. Box
2013-12-05 22:32     ` Rafael J. Wysocki
2013-12-06 20:59   ` [PATCH] X86 platform: New BayTrail IOSF-SB MBI driver David E. Box
2013-12-07  1:29     ` Rafael J. Wysocki
2013-12-10  1:11       ` David E. Box
2013-12-19 22:37     ` [PATCH v5][RESEND] " David E. Box
2013-12-20  1:59       ` Rafael J. Wysocki
2013-12-20  7:01         ` David E. Box [this message]
2013-12-30 18:12       ` [PATCH v6] " David E. Box
2014-01-07 18:03         ` [PATCH v6][RESEND] platform: x86: " David E. Box
2014-01-07 18:15           ` Randy Dunlap
2014-01-07 18:48             ` David E. Box
2014-01-07 19:30               ` Randy Dunlap
2014-01-07 20:46               ` Rafael J. Wysocki
2014-01-07 21:43                 ` David E. Box
2014-01-08  0:11                   ` Rafael J. Wysocki
2014-01-08  0:00                     ` H. Peter Anvin
2014-01-08  5:27                     ` David E. Box
2014-01-08 13:47                       ` Rafael J. Wysocki
2014-01-08 21:27       ` [PATCH v7] arch: x86: New MailBox support driver for Intel SOC's David E. Box
2014-01-10 22:10         ` [tip:x86/platform] " tip-bot for David E. Box

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20131220070144.GA17342@linux.intel.com \
    --to=david.e.box@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.