Commit 3ad0b02e4c1d5feba44b8ff48dccd1ba61a826b0

Authored by Venki Pallipadi
Committed by Len Brown
1 parent 27471fdb32

i7300_idle: Disable ioat channel only on platforms where ile driver can load

Based on input from Andi Kleen:
share the platform detection code with ioat_dma and disable the channel in
dma engine only for specific platforms.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

Showing 3 changed files with 89 additions and 71 deletions Side-by-side Diff

drivers/dma/ioat_dma.c
... ... @@ -33,6 +33,7 @@
33 33 #include <linux/delay.h>
34 34 #include <linux/dma-mapping.h>
35 35 #include <linux/workqueue.h>
  36 +#include <linux/i7300_idle.h>
36 37 #include "ioatdma.h"
37 38 #include "ioatdma_registers.h"
38 39 #include "ioatdma_hw.h"
... ... @@ -172,7 +173,9 @@
172 173 xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
173 174  
174 175 #if CONFIG_I7300_IDLE_IOAT_CHANNEL
175   - device->common.chancnt--;
  176 + if (i7300_idle_platform_probe(NULL, NULL) == 0) {
  177 + device->common.chancnt--;
  178 + }
176 179 #endif
177 180 for (i = 0; i < device->common.chancnt; i++) {
178 181 ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
drivers/idle/i7300_idle.c
... ... @@ -25,6 +25,7 @@
25 25 #include <linux/delay.h>
26 26 #include <linux/debugfs.h>
27 27 #include <linux/stop_machine.h>
  28 +#include <linux/i7300_idle.h>
28 29  
29 30 #include <asm/idle.h>
30 31  
31 32  
... ... @@ -505,77 +506,8 @@
505 506 .notifier_call = i7300_idle_notifier,
506 507 };
507 508  
508   -/*
509   - * I/O AT controls (PCI bus 0 device 8 function 0)
510   - * DIMM controls (PCI bus 0 device 16 function 1)
511   - */
512   -#define IOAT_BUS 0
513   -#define IOAT_DEVFN PCI_DEVFN(8, 0)
514   -#define MEMCTL_BUS 0
515   -#define MEMCTL_DEVFN PCI_DEVFN(16, 1)
516   -
517   -struct fbd_ioat {
518   - unsigned int vendor;
519   - unsigned int ioat_dev;
520   -};
521   -
522   -/*
523   - * The i5000 chip-set has the same hooks as the i7300
524   - * but support is disabled by default because this driver
525   - * has not been validated on that platform.
526   - */
527   -#define SUPPORT_I5000 0
528   -
529   -static const struct fbd_ioat fbd_ioat_list[] = {
530   - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB},
531   -#if SUPPORT_I5000
532   - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT},
533   -#endif
534   - {0, 0}
535   -};
536   -
537   -/* table of devices that work with this driver */
538   -static const struct pci_device_id pci_tbl[] = {
539   - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) },
540   -#if SUPPORT_I5000
541   - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
542   -#endif
543   - { } /* Terminating entry */
544   -};
545   -
546 509 MODULE_DEVICE_TABLE(pci, pci_tbl);
547 510  
548   -/* Check for known platforms with I/O-AT */
549   -static int __init i7300_idle_platform_probe(void)
550   -{
551   - int i;
552   -
553   - fbd_dev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN);
554   - if (!fbd_dev)
555   - return -ENODEV;
556   -
557   - for (i = 0; pci_tbl[i].vendor != 0; i++) {
558   - if (fbd_dev->vendor == pci_tbl[i].vendor &&
559   - fbd_dev->device == pci_tbl[i].device) {
560   - break;
561   - }
562   - }
563   - if (pci_tbl[i].vendor == 0)
564   - return -ENODEV;
565   -
566   - ioat_dev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN);
567   - if (!ioat_dev)
568   - return -ENODEV;
569   -
570   - for (i = 0; fbd_ioat_list[i].vendor != 0; i++) {
571   - if (ioat_dev->vendor == fbd_ioat_list[i].vendor &&
572   - ioat_dev->device == fbd_ioat_list[i].ioat_dev) {
573   - return 0;
574   - }
575   - }
576   - return -ENODEV;
577   -}
578   -
579 511 int stats_open_generic(struct inode *inode, struct file *fp)
580 512 {
581 513 fp->private_data = inode->i_private;
... ... @@ -617,7 +549,7 @@
617 549 cpus_clear(idle_cpumask);
618 550 total_us = 0;
619 551  
620   - if (i7300_idle_platform_probe())
  552 + if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev))
621 553 return -ENODEV;
622 554  
623 555 if (i7300_idle_thrt_save())
include/linux/i7300_idle.h
  1 +
  2 +#ifndef I7300_IDLE_H
  3 +#define I7300_IDLE_H
  4 +
  5 +#include <linux/pci.h>
  6 +
  7 +/*
  8 + * I/O AT controls (PCI bus 0 device 8 function 0)
  9 + * DIMM controls (PCI bus 0 device 16 function 1)
  10 + */
  11 +#define IOAT_BUS 0
  12 +#define IOAT_DEVFN PCI_DEVFN(8, 0)
  13 +#define MEMCTL_BUS 0
  14 +#define MEMCTL_DEVFN PCI_DEVFN(16, 1)
  15 +
  16 +struct fbd_ioat {
  17 + unsigned int vendor;
  18 + unsigned int ioat_dev;
  19 +};
  20 +
  21 +/*
  22 + * The i5000 chip-set has the same hooks as the i7300
  23 + * but support is disabled by default because this driver
  24 + * has not been validated on that platform.
  25 + */
  26 +#define SUPPORT_I5000 0
  27 +
  28 +static const struct fbd_ioat fbd_ioat_list[] = {
  29 + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB},
  30 +#if SUPPORT_I5000
  31 + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT},
  32 +#endif
  33 + {0, 0}
  34 +};
  35 +
  36 +/* table of devices that work with this driver */
  37 +static const struct pci_device_id pci_tbl[] = {
  38 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) },
  39 +#if SUPPORT_I5000
  40 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
  41 +#endif
  42 + { } /* Terminating entry */
  43 +};
  44 +
  45 +/* Check for known platforms with I/O-AT */
  46 +static inline int i7300_idle_platform_probe(struct pci_dev **fbd_dev,
  47 + struct pci_dev **ioat_dev)
  48 +{
  49 + int i;
  50 + struct pci_dev *memdev, *dmadev;
  51 +
  52 + memdev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN);
  53 + if (!memdev)
  54 + return -ENODEV;
  55 +
  56 + for (i = 0; pci_tbl[i].vendor != 0; i++) {
  57 + if (memdev->vendor == pci_tbl[i].vendor &&
  58 + memdev->device == pci_tbl[i].device) {
  59 + break;
  60 + }
  61 + }
  62 + if (pci_tbl[i].vendor == 0)
  63 + return -ENODEV;
  64 +
  65 + dmadev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN);
  66 + if (!dmadev)
  67 + return -ENODEV;
  68 +
  69 + for (i = 0; fbd_ioat_list[i].vendor != 0; i++) {
  70 + if (dmadev->vendor == fbd_ioat_list[i].vendor &&
  71 + dmadev->device == fbd_ioat_list[i].ioat_dev) {
  72 + if (fbd_dev)
  73 + *fbd_dev = memdev;
  74 + if (ioat_dev)
  75 + *ioat_dev = dmadev;
  76 +
  77 + return 0;
  78 + }
  79 + }
  80 + return -ENODEV;
  81 +}
  82 +
  83 +#endif