Commit 7ad4b4ae5757b89637f5767ae5d9e1436a6413e0
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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
Showing 4 changed files Side-by-side Diff
Documentation/ABI/testing/sysfs-class-mei
... | ... | @@ -13,4 +13,19 @@ |
13 | 13 | Description: |
14 | 14 | The /sys/class/mei/meiN directory is created for |
15 | 15 | each probed mei device |
16 | + | |
17 | +What: /sys/class/mei/meiN/fw_status | |
18 | +Date: Nov 2014 | |
19 | +KernelVersion: 3.19 | |
20 | +Contact: Tomas Winkler <tomas.winkler@intel.com> | |
21 | +Description: Display fw status registers content | |
22 | + | |
23 | + The ME FW writes its status information into fw status | |
24 | + registers for BIOS and OS to monitor fw health. | |
25 | + | |
26 | + The register contains running state, power management | |
27 | + state, error codes, and others. The way the registers | |
28 | + are decoded depends on PCH or SoC generation. | |
29 | + Also number of registers varies between 1 and 6 | |
30 | + depending on generation. |
drivers/mcb/mcb-internal.h
drivers/mcb/mcb-pci.c
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | |
18 | 18 | struct priv { |
19 | 19 | struct mcb_bus *bus; |
20 | + phys_addr_t mapbase; | |
20 | 21 | void __iomem *base; |
21 | 22 | }; |
22 | 23 | |
23 | 24 | |
... | ... | @@ -31,8 +32,8 @@ |
31 | 32 | |
32 | 33 | static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
33 | 34 | { |
35 | + struct resource *res; | |
34 | 36 | struct priv *priv; |
35 | - phys_addr_t mapbase; | |
36 | 37 | int ret; |
37 | 38 | int num_cells; |
38 | 39 | unsigned long flags; |
39 | 40 | |
40 | 41 | |
... | ... | @@ -47,19 +48,21 @@ |
47 | 48 | return -ENODEV; |
48 | 49 | } |
49 | 50 | |
50 | - mapbase = pci_resource_start(pdev, 0); | |
51 | - if (!mapbase) { | |
51 | + priv->mapbase = pci_resource_start(pdev, 0); | |
52 | + if (!priv->mapbase) { | |
52 | 53 | dev_err(&pdev->dev, "No PCI resource\n"); |
53 | 54 | goto err_start; |
54 | 55 | } |
55 | 56 | |
56 | - ret = pci_request_region(pdev, 0, KBUILD_MODNAME); | |
57 | - if (ret) { | |
58 | - dev_err(&pdev->dev, "Failed to request PCI BARs\n"); | |
57 | + res = request_mem_region(priv->mapbase, CHAM_HEADER_SIZE, | |
58 | + KBUILD_MODNAME); | |
59 | + if (IS_ERR(res)) { | |
60 | + dev_err(&pdev->dev, "Failed to request PCI memory\n"); | |
61 | + ret = PTR_ERR(res); | |
59 | 62 | goto err_start; |
60 | 63 | } |
61 | 64 | |
62 | - priv->base = pci_iomap(pdev, 0, 0); | |
65 | + priv->base = ioremap(priv->mapbase, CHAM_HEADER_SIZE); | |
63 | 66 | if (!priv->base) { |
64 | 67 | dev_err(&pdev->dev, "Cannot ioremap\n"); |
65 | 68 | ret = -ENOMEM; |
... | ... | @@ -84,7 +87,7 @@ |
84 | 87 | |
85 | 88 | priv->bus->get_irq = mcb_pci_get_irq; |
86 | 89 | |
87 | - ret = chameleon_parse_cells(priv->bus, mapbase, priv->base); | |
90 | + ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base); | |
88 | 91 | if (ret < 0) |
89 | 92 | goto err_drvdata; |
90 | 93 | num_cells = ret; |
91 | 94 | |
... | ... | @@ -93,8 +96,10 @@ |
93 | 96 | |
94 | 97 | mcb_bus_add_devices(priv->bus); |
95 | 98 | |
99 | + return 0; | |
100 | + | |
96 | 101 | err_drvdata: |
97 | - pci_iounmap(pdev, priv->base); | |
102 | + iounmap(priv->base); | |
98 | 103 | err_ioremap: |
99 | 104 | pci_release_region(pdev, 0); |
100 | 105 | err_start: |
... | ... | @@ -107,6 +112,10 @@ |
107 | 112 | struct priv *priv = pci_get_drvdata(pdev); |
108 | 113 | |
109 | 114 | mcb_release_bus(priv->bus); |
115 | + | |
116 | + iounmap(priv->base); | |
117 | + release_region(priv->mapbase, CHAM_HEADER_SIZE); | |
118 | + pci_disable_device(pdev); | |
110 | 119 | } |
111 | 120 | |
112 | 121 | static const struct pci_device_id mcb_pci_tbl[] = { |
drivers/misc/mei/hw-me.c
... | ... | @@ -234,6 +234,18 @@ |
234 | 234 | struct mei_me_hw *hw = to_me_hw(dev); |
235 | 235 | u32 hcsr = mei_hcsr_read(hw); |
236 | 236 | |
237 | + /* H_RST may be found lit before reset is started, | |
238 | + * for example if preceding reset flow hasn't completed. | |
239 | + * In that case asserting H_RST will be ignored, therefore | |
240 | + * we need to clean H_RST bit to start a successful reset sequence. | |
241 | + */ | |
242 | + if ((hcsr & H_RST) == H_RST) { | |
243 | + dev_warn(dev->dev, "H_RST is set = 0x%08X", hcsr); | |
244 | + hcsr &= ~H_RST; | |
245 | + mei_me_reg_write(hw, H_CSR, hcsr); | |
246 | + hcsr = mei_hcsr_read(hw); | |
247 | + } | |
248 | + | |
237 | 249 | hcsr |= H_RST | H_IG | H_IS; |
238 | 250 | |
239 | 251 | if (intr_enable) |