History

Merge tag 'platform-drivers-x86-v6.7-6' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver fixes from Ilpo Järvinen: - Intel PMC GBE LTR regression - P2SB / PCI deadlock fix * tag 'platform-drivers-x86-v6.7-6' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: platform/x86/intel/pmc: Move GBE LTR ignore to suspend callback platform/x86/intel/pmc: Allow reenabling LTRs platform/x86/intel/pmc: Add suspend callback platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe

Linus Torvalds committed 2 years ago

Commit e543d0b2 parents 09c57a7 70681aa7 files · +176 −68Browse files

Unified · Split

7 files
  1. drivers/platform/x86/intel/pmc/adl.c +3 −6
  2. drivers/platform/x86/intel/pmc/cnp.c +20 −6
  3. drivers/platform/x86/intel/pmc/core.c +9 −3
  4. drivers/platform/x86/intel/pmc/core.h +6 −1
  5. drivers/platform/x86/intel/pmc/mtl.c +3 −6
  6. drivers/platform/x86/intel/pmc/tgl.c +4 −5
  7. drivers/platform/x86/p2sb.c +131 −41
drivers/platform/x86/intel/pmc/adl.c+3−6
@@ -314,16 +314,13 @@ int adl_core_init(struct pmc_dev *pmcdev) · 313 unmodified lines
314 struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];314 struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
315 int ret;315 int ret;
316 316
317 pmcdev->suspend = cnl_suspend;
318 pmcdev->resume = cnl_resume;
319
317 pmc->map = &adl_reg_map;320 pmc->map = &adl_reg_map;
318 ret = get_primary_reg_base(pmc);321 ret = get_primary_reg_base(pmc);
319 if (ret)322 if (ret)
320 return ret;323 return ret;
321 324
322 /* Due to a hardware limitation, the GBE LTR blocks PC10
323 * when a cable is attached. Tell the PMC to ignore it.
324 */
325 dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n");
326 pmc_core_send_ltr_ignore(pmcdev, 3);
327
328 return 0;325 return 0;
329}326}
drivers/platform/x86/intel/pmc/cnp.c+20−6
@@ -204,21 +204,35 @@ const struct pmc_reg_map cnp_reg_map = { · 203 unmodified lines
204 .etr3_offset = ETR3_OFFSET,204 .etr3_offset = ETR3_OFFSET,
205};205};
206 206
207void cnl_suspend(struct pmc_dev *pmcdev)
208{
209 /*
210 * Due to a hardware limitation, the GBE LTR blocks PC10
211 * when a cable is attached. To unblock PC10 during suspend,
212 * tell the PMC to ignore it.
213 */
214 pmc_core_send_ltr_ignore(pmcdev, 3, 1);
215}
216
217int cnl_resume(struct pmc_dev *pmcdev)
218{
219 pmc_core_send_ltr_ignore(pmcdev, 3, 0);
220
221 return pmc_core_resume_common(pmcdev);
222}
223
207int cnp_core_init(struct pmc_dev *pmcdev)224int cnp_core_init(struct pmc_dev *pmcdev)
208{225{
209 struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];226 struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
210 int ret;227 int ret;
211 228
229 pmcdev->suspend = cnl_suspend;
230 pmcdev->resume = cnl_resume;
231
212 pmc->map = &cnp_reg_map;232 pmc->map = &cnp_reg_map;
213 ret = get_primary_reg_base(pmc);233 ret = get_primary_reg_base(pmc);
214 if (ret)234 if (ret)
215 return ret;235 return ret;
216 236
217 /* Due to a hardware limitation, the GBE LTR blocks PC10
218 * when a cable is attached. Tell the PMC to ignore it.
219 */
220 dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n");
221 pmc_core_send_ltr_ignore(pmcdev, 3);
222
223 return 0;237 return 0;
224}238}
drivers/platform/x86/intel/pmc/core.c+9−3
@@ -460,7 +460,7 @@ out_unlock: · 459 unmodified lines
460}460}
461DEFINE_SHOW_ATTRIBUTE(pmc_core_pll);461DEFINE_SHOW_ATTRIBUTE(pmc_core_pll);
462 462
463int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value)463int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore)
464{464{
465 struct pmc *pmc;465 struct pmc *pmc;
466 const struct pmc_reg_map *map;466 const struct pmc_reg_map *map;
@@ -498,7 +498,10 @@ int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value) · 31 unmodified lines
498 mutex_lock(&pmcdev->lock);498 mutex_lock(&pmcdev->lock);
499 499
500 reg = pmc_core_reg_read(pmc, map->ltr_ignore_offset);500 reg = pmc_core_reg_read(pmc, map->ltr_ignore_offset);
501 reg |= BIT(ltr_index);501 if (ignore)
502 reg |= BIT(ltr_index);
503 else
504 reg &= ~BIT(ltr_index);
502 pmc_core_reg_write(pmc, map->ltr_ignore_offset, reg);505 pmc_core_reg_write(pmc, map->ltr_ignore_offset, reg);
503 506
504 mutex_unlock(&pmcdev->lock);507 mutex_unlock(&pmcdev->lock);
@@ -521,7 +524,7 @@ static ssize_t pmc_core_ltr_ignore_write(struct file *file, · 16 unmodified lines
521 if (err)524 if (err)
522 return err;525 return err;
523 526
524 err = pmc_core_send_ltr_ignore(pmcdev, value);527 err = pmc_core_send_ltr_ignore(pmcdev, value, 1);
525 528
526 return err == 0 ? count : err;529 return err == 0 ? count : err;
527}530}
@@ -1279,6 +1282,9 @@ static __maybe_unused int pmc_core_suspend(struct device *dev) · 751 unmodified lines
1279 struct pmc_dev *pmcdev = dev_get_drvdata(dev);1282 struct pmc_dev *pmcdev = dev_get_drvdata(dev);
1280 struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];1283 struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
1281 1284
1285 if (pmcdev->suspend)
1286 pmcdev->suspend(pmcdev);
1287
1282 /* Check if the syspend will actually use S0ix */1288 /* Check if the syspend will actually use S0ix */
1283 if (pm_suspend_via_firmware())1289 if (pm_suspend_via_firmware())
1284 return 0;1290 return 0;
drivers/platform/x86/intel/pmc/core.h+6−1
@@ -363,6 +363,7 @@ struct pmc { · 362 unmodified lines
363 * @s0ix_counter: S0ix residency (step adjusted)363 * @s0ix_counter: S0ix residency (step adjusted)
364 * @num_lpm_modes: Count of enabled modes364 * @num_lpm_modes: Count of enabled modes
365 * @lpm_en_modes: Array of enabled modes from lowest to highest priority365 * @lpm_en_modes: Array of enabled modes from lowest to highest priority
366 * @suspend: Function to perform platform specific suspend
366 * @resume: Function to perform platform specific resume367 * @resume: Function to perform platform specific resume
367 *368 *
368 * pmc_dev contains info about power management controller device.369 * pmc_dev contains info about power management controller device.
@@ -379,6 +380,7 @@ struct pmc_dev { · 10 unmodified lines
379 u64 s0ix_counter;380 u64 s0ix_counter;
380 int num_lpm_modes;381 int num_lpm_modes;
381 int lpm_en_modes[LPM_MAX_NUM_MODES];382 int lpm_en_modes[LPM_MAX_NUM_MODES];
383 void (*suspend)(struct pmc_dev *pmcdev);
382 int (*resume)(struct pmc_dev *pmcdev);384 int (*resume)(struct pmc_dev *pmcdev);
383 385
384 bool has_die_c6;386 bool has_die_c6;
@@ -486,7 +488,7 @@ extern const struct pmc_bit_map *mtl_ioem_lpm_maps[]; · 101 unmodified lines
486extern const struct pmc_reg_map mtl_ioem_reg_map;488extern const struct pmc_reg_map mtl_ioem_reg_map;
487 489
488extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);490extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);
489extern int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value);491int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore);
490 492
491int pmc_core_resume_common(struct pmc_dev *pmcdev);493int pmc_core_resume_common(struct pmc_dev *pmcdev);
492int get_primary_reg_base(struct pmc *pmc);494int get_primary_reg_base(struct pmc *pmc);
@@ -500,6 +502,9 @@ int tgl_core_init(struct pmc_dev *pmcdev); · 7 unmodified lines
500int adl_core_init(struct pmc_dev *pmcdev);502int adl_core_init(struct pmc_dev *pmcdev);
501int mtl_core_init(struct pmc_dev *pmcdev);503int mtl_core_init(struct pmc_dev *pmcdev);
502 504
505void cnl_suspend(struct pmc_dev *pmcdev);
506int cnl_resume(struct pmc_dev *pmcdev);
507
503#define pmc_for_each_mode(i, mode, pmcdev) \508#define pmc_for_each_mode(i, mode, pmcdev) \
504 for (i = 0, mode = pmcdev->lpm_en_modes[i]; \509 for (i = 0, mode = pmcdev->lpm_en_modes[i]; \
505 i < pmcdev->num_lpm_modes; \510 i < pmcdev->num_lpm_modes; \
drivers/platform/x86/intel/pmc/mtl.c+3−6
@@ -979,6 +979,8 @@ static void mtl_d3_fixup(void) · 978 unmodified lines
979static int mtl_resume(struct pmc_dev *pmcdev)979static int mtl_resume(struct pmc_dev *pmcdev)
980{980{
981 mtl_d3_fixup();981 mtl_d3_fixup();
982 pmc_core_send_ltr_ignore(pmcdev, 3, 0);
983
982 return pmc_core_resume_common(pmcdev);984 return pmc_core_resume_common(pmcdev);
983}985}
984 986
@@ -989,6 +991,7 @@ int mtl_core_init(struct pmc_dev *pmcdev) · 4 unmodified lines
989 991
990 mtl_d3_fixup();992 mtl_d3_fixup();
991 993
994 pmcdev->suspend = cnl_suspend;
992 pmcdev->resume = mtl_resume;995 pmcdev->resume = mtl_resume;
993 996
994 pmcdev->regmap_list = mtl_pmc_info_list;997 pmcdev->regmap_list = mtl_pmc_info_list;
@@ -1002,11 +1005,5 @@ int mtl_core_init(struct pmc_dev *pmcdev) · 7 unmodified lines
1002 return ret;1005 return ret;
1003 }1006 }
1004 1007
1005 /* Due to a hardware limitation, the GBE LTR blocks PC10
1006 * when a cable is attached. Tell the PMC to ignore it.
1007 */
1008 dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n");
1009 pmc_core_send_ltr_ignore(pmcdev, 3);
1010
1011 return 0;1008 return 0;
1012}1009}
drivers/platform/x86/intel/pmc/tgl.c+4−5
@@ -259,16 +259,15 @@ int tgl_core_init(struct pmc_dev *pmcdev) · 258 unmodified lines
259 int ret;259 int ret;
260 260
261 pmc->map = &tgl_reg_map;261 pmc->map = &tgl_reg_map;
262
263 pmcdev->suspend = cnl_suspend;
264 pmcdev->resume = cnl_resume;
265
262 ret = get_primary_reg_base(pmc);266 ret = get_primary_reg_base(pmc);
263 if (ret)267 if (ret)
264 return ret;268 return ret;
265 269
266 pmc_core_get_tgl_lpm_reqs(pmcdev->pdev);270 pmc_core_get_tgl_lpm_reqs(pmcdev->pdev);
267 /* Due to a hardware limitation, the GBE LTR blocks PC10
268 * when a cable is attached. Tell the PMC to ignore it.
269 */
270 dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n");
271 pmc_core_send_ltr_ignore(pmcdev, 3);
272 271
273 return 0;272 return 0;
274}273}
drivers/platform/x86/p2sb.c+131−41
@@ -26,6 +26,21 @@ static const struct x86_cpu_id p2sb_cpu_ids[] = { · 25 unmodified lines
26 {}26 {}
27};27};
28 28
29/*
30 * Cache BAR0 of P2SB device functions 0 to 7.
31 * TODO: The constant 8 is the number of functions that PCI specification
32 * defines. Same definitions exist tree-wide. Unify this definition and
33 * the other definitions then move to include/uapi/linux/pci.h.
34 */
35#define NR_P2SB_RES_CACHE 8
36
37struct p2sb_res_cache {
38 u32 bus_dev_id;
39 struct resource res;
40};
41
42static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE];
43
29static int p2sb_get_devfn(unsigned int *devfn)44static int p2sb_get_devfn(unsigned int *devfn)
30{45{
31 unsigned int fn = P2SB_DEVFN_DEFAULT;46 unsigned int fn = P2SB_DEVFN_DEFAULT;
@@ -39,8 +54,16 @@ static int p2sb_get_devfn(unsigned int *devfn) · 7 unmodified lines
39 return 0;54 return 0;
40}55}
41 56
57static bool p2sb_valid_resource(struct resource *res)
58{
59 if (res->flags)
60 return true;
61
62 return false;
63}
64
42/* Copy resource from the first BAR of the device in question */65/* Copy resource from the first BAR of the device in question */
43static int p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem)66static void p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem)
44{67{
45 struct resource *bar0 = &pdev->resource[0];68 struct resource *bar0 = &pdev->resource[0];
46 69
@@ -56,47 +79,64 @@ static int p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) · 9 unmodified lines
56 mem->end = bar0->end;79 mem->end = bar0->end;
57 mem->flags = bar0->flags;80 mem->flags = bar0->flags;
58 mem->desc = bar0->desc;81 mem->desc = bar0->desc;
59
60 return 0;
61}82}
62 83
63static int p2sb_scan_and_read(struct pci_bus *bus, unsigned int devfn, struct resource *mem)84static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn)
64{85{
86 struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC(devfn)];
65 struct pci_dev *pdev;87 struct pci_dev *pdev;
66 int ret;
67 88
68 pdev = pci_scan_single_device(bus, devfn);89 pdev = pci_scan_single_device(bus, devfn);
69 if (!pdev)90 if (!pdev)
70 return -ENODEV;91 return;
71 92
72 ret = p2sb_read_bar0(pdev, mem);93 p2sb_read_bar0(pdev, &cache->res);
94 cache->bus_dev_id = bus->dev.id;
73 95
74 pci_stop_and_remove_bus_device(pdev);96 pci_stop_and_remove_bus_device(pdev);
75 return ret;97 return;
76}98}
77 99
78/**100static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn)
79 * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR101{
80 * @bus: PCI bus to communicate with102 unsigned int slot, fn;
81 * @devfn: PCI slot and function to communicate with103
82 * @mem: memory resource to be filled in104 if (PCI_FUNC(devfn) == 0) {
83 *105 /*
84 * The BIOS prevents the P2SB device from being enumerated by the PCI106 * When function number of the P2SB device is zero, scan it and
85 * subsystem, so we need to unhide and hide it back to lookup the BAR.107 * other function numbers, and if devices are available, cache
86 *108 * their BAR0s.
87 * if @bus is NULL, the bus 0 in domain 0 will be used.109 */
88 * If @devfn is 0, it will be replaced by devfn of the P2SB device.110 slot = PCI_SLOT(devfn);
89 *111 for (fn = 0; fn < NR_P2SB_RES_CACHE; fn++)
90 * Caller must provide a valid pointer to @mem.112 p2sb_scan_and_cache_devfn(bus, PCI_DEVFN(slot, fn));
91 *113 } else {
92 * Locking is handled by pci_rescan_remove_lock mutex.114 /* Scan the P2SB device and cache its BAR0 */
93 *115 p2sb_scan_and_cache_devfn(bus, devfn);
94 * Return:116 }
95 * 0 on success or appropriate errno value on error.117
96 */118 if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res))
97int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)119 return -ENOENT;
120
121 return 0;
122}
123
124static struct pci_bus *p2sb_get_bus(struct pci_bus *bus)
125{
126 static struct pci_bus *p2sb_bus;
127
128 bus = bus ?: p2sb_bus;
129 if (bus)
130 return bus;
131
132 /* Assume P2SB is on the bus 0 in domain 0 */
133 p2sb_bus = pci_find_bus(0, 0);
134 return p2sb_bus;
135}
136
137static int p2sb_cache_resources(void)
98{138{
99 struct pci_dev *pdev_p2sb;139 struct pci_bus *bus;
100 unsigned int devfn_p2sb;140 unsigned int devfn_p2sb;
101 u32 value = P2SBC_HIDE;141 u32 value = P2SBC_HIDE;
102 int ret;142 int ret;
@@ -106,8 +146,9 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) · 3 unmodified lines
106 if (ret)146 if (ret)
107 return ret;147 return ret;
108 148
109 /* if @bus is NULL, use bus 0 in domain 0 */149 bus = p2sb_get_bus(NULL);
110 bus = bus ?: pci_find_bus(0, 0);150 if (!bus)
151 return -ENODEV;
111 152
112 /*153 /*
113 * Prevent concurrent PCI bus scan from seeing the P2SB device and154 * Prevent concurrent PCI bus scan from seeing the P2SB device and
@@ -115,17 +156,16 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) · 1 unmodified line
115 */156 */
116 pci_lock_rescan_remove();157 pci_lock_rescan_remove();
117 158
118 /* Unhide the P2SB device, if needed */159 /*
160 * The BIOS prevents the P2SB device from being enumerated by the PCI
161 * subsystem, so we need to unhide and hide it back to lookup the BAR.
162 * Unhide the P2SB device here, if needed.
163 */
119 pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value);164 pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value);
120 if (value & P2SBC_HIDE)165 if (value & P2SBC_HIDE)
121 pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0);166 pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0);
122 167
123 pdev_p2sb = pci_scan_single_device(bus, devfn_p2sb);168 ret = p2sb_scan_and_cache(bus, devfn_p2sb);
124 if (devfn)
125 ret = p2sb_scan_and_read(bus, devfn, mem);
126 else
127 ret = p2sb_read_bar0(pdev_p2sb, mem);
128 pci_stop_and_remove_bus_device(pdev_p2sb);
129 169
130 /* Hide the P2SB device, if it was hidden */170 /* Hide the P2SB device, if it was hidden */
131 if (value & P2SBC_HIDE)171 if (value & P2SBC_HIDE)
@@ -133,12 +173,62 @@ int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) · 1 unmodified line
133 173
134 pci_unlock_rescan_remove();174 pci_unlock_rescan_remove();
135 175
136 if (ret)176 return ret;
137 return ret;177}
178
179/**
180 * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR
181 * @bus: PCI bus to communicate with
182 * @devfn: PCI slot and function to communicate with
183 * @mem: memory resource to be filled in
184 *
185 * If @bus is NULL, the bus 0 in domain 0 will be used.
186 * If @devfn is 0, it will be replaced by devfn of the P2SB device.
187 *
188 * Caller must provide a valid pointer to @mem.
189 *
190 * Return:
191 * 0 on success or appropriate errno value on error.
192 */
193int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem)
194{
195 struct p2sb_res_cache *cache;
196 int ret;
138 197
139 if (mem->flags == 0)198 bus = p2sb_get_bus(bus);
199 if (!bus)
140 return -ENODEV;200 return -ENODEV;
141 201
202 if (!devfn) {
203 ret = p2sb_get_devfn(&devfn);
204 if (ret)
205 return ret;
206 }
207
208 cache = &p2sb_resources[PCI_FUNC(devfn)];
209 if (cache->bus_dev_id != bus->dev.id)
210 return -ENODEV;
211
212 if (!p2sb_valid_resource(&cache->res))
213 return -ENOENT;
214
215 memcpy(mem, &cache->res, sizeof(*mem));
142 return 0;216 return 0;
143}217}
144EXPORT_SYMBOL_GPL(p2sb_bar);218EXPORT_SYMBOL_GPL(p2sb_bar);
219
220static int __init p2sb_fs_init(void)
221{
222 p2sb_cache_resources();
223 return 0;
224}
225
226/*
227 * pci_rescan_remove_lock to avoid access to unhidden P2SB devices can
228 * not be locked in sysfs pci bus rescan path because of deadlock. To
229 * avoid the deadlock, access to P2SB devices with the lock at an early
230 * step in kernel initialization and cache required resources. This
231 * should happen after subsys_initcall which initializes PCI subsystem
232 * and before device_initcall which requires P2SB resources.
233 */
234fs_initcall(p2sb_fs_init);