Char/Misc driver fixes for 3.19-rc5

Here are 3 small driver fixes for reported issues for 3.19-rc5.  All of
 these have been in linux-next for a while with no reported problems.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iEYEABECAAYFAlS5VzYACgkQMUfUDdst+ylv5gCfT8krEtuWXM1NMZwIuftf4Whb
 z8cAn23whaxGED7AyBRVXxMohYF8Vxq9
 =yMIV
 -----END PGP SIGNATURE-----

Merge tag 'char-misc-3.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc driver fixes from Greg KH:
 "Here are three small driver fixes for reported issues for 3.19-rc5.

  All of these have been in linux-next for a while with no reported
  problems"

* tag 'char-misc-3.19-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  mcb: mcb-pci: Only remap the 1st 0x200 bytes of BAR 0
  mei: add ABI documentation for fw_status exported through sysfs
  mei: clean reset bit before reset
This commit is contained in:
Linus Torvalds 2015-01-17 08:18:08 +13:00
commit 7ad4b4ae57
4 changed files with 46 additions and 9 deletions

View File

@ -14,3 +14,18 @@ Description:
The /sys/class/mei/meiN directory is created for
each probed mei device
What: /sys/class/mei/meiN/fw_status
Date: Nov 2014
KernelVersion: 3.19
Contact: Tomas Winkler <tomas.winkler@intel.com>
Description: Display fw status registers content
The ME FW writes its status information into fw status
registers for BIOS and OS to monitor fw health.
The register contains running state, power management
state, error codes, and others. The way the registers
are decoded depends on PCH or SoC generation.
Also number of registers varies between 1 and 6
depending on generation.

View File

@ -7,6 +7,7 @@
#define PCI_DEVICE_ID_MEN_CHAMELEON 0x4d45
#define CHAMELEON_FILENAME_LEN 12
#define CHAMELEONV2_MAGIC 0xabce
#define CHAM_HEADER_SIZE 0x200
enum chameleon_descriptor_type {
CHAMELEON_DTYPE_GENERAL = 0x0,

View File

@ -17,6 +17,7 @@
struct priv {
struct mcb_bus *bus;
phys_addr_t mapbase;
void __iomem *base;
};
@ -31,8 +32,8 @@ static int mcb_pci_get_irq(struct mcb_device *mdev)
static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct resource *res;
struct priv *priv;
phys_addr_t mapbase;
int ret;
int num_cells;
unsigned long flags;
@ -47,19 +48,21 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENODEV;
}
mapbase = pci_resource_start(pdev, 0);
if (!mapbase) {
priv->mapbase = pci_resource_start(pdev, 0);
if (!priv->mapbase) {
dev_err(&pdev->dev, "No PCI resource\n");
goto err_start;
}
ret = pci_request_region(pdev, 0, KBUILD_MODNAME);
if (ret) {
dev_err(&pdev->dev, "Failed to request PCI BARs\n");
res = request_mem_region(priv->mapbase, CHAM_HEADER_SIZE,
KBUILD_MODNAME);
if (IS_ERR(res)) {
dev_err(&pdev->dev, "Failed to request PCI memory\n");
ret = PTR_ERR(res);
goto err_start;
}
priv->base = pci_iomap(pdev, 0, 0);
priv->base = ioremap(priv->mapbase, CHAM_HEADER_SIZE);
if (!priv->base) {
dev_err(&pdev->dev, "Cannot ioremap\n");
ret = -ENOMEM;
@ -84,7 +87,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
priv->bus->get_irq = mcb_pci_get_irq;
ret = chameleon_parse_cells(priv->bus, mapbase, priv->base);
ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base);
if (ret < 0)
goto err_drvdata;
num_cells = ret;
@ -93,8 +96,10 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
mcb_bus_add_devices(priv->bus);
return 0;
err_drvdata:
pci_iounmap(pdev, priv->base);
iounmap(priv->base);
err_ioremap:
pci_release_region(pdev, 0);
err_start:
@ -107,6 +112,10 @@ static void mcb_pci_remove(struct pci_dev *pdev)
struct priv *priv = pci_get_drvdata(pdev);
mcb_release_bus(priv->bus);
iounmap(priv->base);
release_region(priv->mapbase, CHAM_HEADER_SIZE);
pci_disable_device(pdev);
}
static const struct pci_device_id mcb_pci_tbl[] = {

View File

@ -234,6 +234,18 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
struct mei_me_hw *hw = to_me_hw(dev);
u32 hcsr = mei_hcsr_read(hw);
/* H_RST may be found lit before reset is started,
* for example if preceding reset flow hasn't completed.
* In that case asserting H_RST will be ignored, therefore
* we need to clean H_RST bit to start a successful reset sequence.
*/
if ((hcsr & H_RST) == H_RST) {
dev_warn(dev->dev, "H_RST is set = 0x%08X", hcsr);
hcsr &= ~H_RST;
mei_me_reg_write(hw, H_CSR, hcsr);
hcsr = mei_hcsr_read(hw);
}
hcsr |= H_RST | H_IG | H_IS;
if (intr_enable)