aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2013-03-26 18:42:47 -0400
committerVinod Koul <vinod.koul@intel.com>2013-04-15 00:21:20 -0400
commit8a52b9ff1154a68b6a2a8da9a31a87e52f5f6418 (patch)
tree54fcb19bbcd64cf50a86efe4feeac899b32fd40b /drivers/dma
parentd92a8d7cbb6941d5d985ccb3453a2ac5c92f60e4 (diff)
ioatdma: channel reset scheme fixup on Intel Atom S1200 platforms
The Intel Atom S1200 family ioatdma changed the channel reset behavior. It does a reset similar to PCI FLR by resetting all the MSIX registers. We have to re-init msix interrupts because of this. This workaround is only specific to this platform and is not expected to carry over to the later generations. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Acked-by: Dan Williams <djbw@fb.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/ioat/dma.c8
-rw-r--r--drivers/dma/ioat/dma.h10
-rw-r--r--drivers/dma/ioat/dma_v3.c236
3 files changed, 171 insertions, 83 deletions
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
index 1879a5942bfc..17a2393b3e25 100644
--- a/drivers/dma/ioat/dma.c
+++ b/drivers/dma/ioat/dma.c
@@ -892,7 +892,7 @@ MODULE_PARM_DESC(ioat_interrupt_style,
892 * ioat_dma_setup_interrupts - setup interrupt handler 892 * ioat_dma_setup_interrupts - setup interrupt handler
893 * @device: ioat device 893 * @device: ioat device
894 */ 894 */
895static int ioat_dma_setup_interrupts(struct ioatdma_device *device) 895int ioat_dma_setup_interrupts(struct ioatdma_device *device)
896{ 896{
897 struct ioat_chan_common *chan; 897 struct ioat_chan_common *chan;
898 struct pci_dev *pdev = device->pdev; 898 struct pci_dev *pdev = device->pdev;
@@ -941,6 +941,7 @@ msix:
941 } 941 }
942 } 942 }
943 intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL; 943 intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL;
944 device->irq_mode = IOAT_MSIX;
944 goto done; 945 goto done;
945 946
946msix_single_vector: 947msix_single_vector:
@@ -956,6 +957,7 @@ msix_single_vector:
956 pci_disable_msix(pdev); 957 pci_disable_msix(pdev);
957 goto msi; 958 goto msi;
958 } 959 }
960 device->irq_mode = IOAT_MSIX_SINGLE;
959 goto done; 961 goto done;
960 962
961msi: 963msi:
@@ -969,6 +971,7 @@ msi:
969 pci_disable_msi(pdev); 971 pci_disable_msi(pdev);
970 goto intx; 972 goto intx;
971 } 973 }
974 device->irq_mode = IOAT_MSIX;
972 goto done; 975 goto done;
973 976
974intx: 977intx:
@@ -977,6 +980,7 @@ intx:
977 if (err) 980 if (err)
978 goto err_no_irq; 981 goto err_no_irq;
979 982
983 device->irq_mode = IOAT_INTX;
980done: 984done:
981 if (device->intr_quirk) 985 if (device->intr_quirk)
982 device->intr_quirk(device); 986 device->intr_quirk(device);
@@ -987,9 +991,11 @@ done:
987err_no_irq: 991err_no_irq:
988 /* Disable all interrupt generation */ 992 /* Disable all interrupt generation */
989 writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET); 993 writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET);
994 device->irq_mode = IOAT_NOIRQ;
990 dev_err(dev, "no usable interrupts\n"); 995 dev_err(dev, "no usable interrupts\n");
991 return err; 996 return err;
992} 997}
998EXPORT_SYMBOL(ioat_dma_setup_interrupts);
993 999
994static void ioat_disable_interrupts(struct ioatdma_device *device) 1000static void ioat_disable_interrupts(struct ioatdma_device *device)
995{ 1001{
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h
index 9285caadf825..b16902cd2684 100644
--- a/drivers/dma/ioat/dma.h
+++ b/drivers/dma/ioat/dma.h
@@ -48,6 +48,14 @@
48 */ 48 */
49#define NULL_DESC_BUFFER_SIZE 1 49#define NULL_DESC_BUFFER_SIZE 1
50 50
51enum ioat_irq_mode {
52 IOAT_NOIRQ = 0,
53 IOAT_MSIX,
54 IOAT_MSIX_SINGLE,
55 IOAT_MSI,
56 IOAT_INTX
57};
58
51/** 59/**
52 * struct ioatdma_device - internal representation of a IOAT device 60 * struct ioatdma_device - internal representation of a IOAT device
53 * @pdev: PCI-Express device 61 * @pdev: PCI-Express device
@@ -77,6 +85,7 @@ struct ioatdma_device {
77 struct msix_entry msix_entries[4]; 85 struct msix_entry msix_entries[4];
78 struct ioat_chan_common *idx[4]; 86 struct ioat_chan_common *idx[4];
79 struct dca_provider *dca; 87 struct dca_provider *dca;
88 enum ioat_irq_mode irq_mode;
80 void (*intr_quirk)(struct ioatdma_device *device); 89 void (*intr_quirk)(struct ioatdma_device *device);
81 int (*enumerate_channels)(struct ioatdma_device *device); 90 int (*enumerate_channels)(struct ioatdma_device *device);
82 int (*reset_hw)(struct ioat_chan_common *chan); 91 int (*reset_hw)(struct ioat_chan_common *chan);
@@ -341,6 +350,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
341 dma_addr_t *phys_complete); 350 dma_addr_t *phys_complete);
342void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); 351void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type);
343void ioat_kobject_del(struct ioatdma_device *device); 352void ioat_kobject_del(struct ioatdma_device *device);
353int ioat_dma_setup_interrupts(struct ioatdma_device *device);
344extern const struct sysfs_ops ioat_sysfs_ops; 354extern const struct sysfs_ops ioat_sysfs_ops;
345extern struct ioat_sysfs_entry ioat_version_attr; 355extern struct ioat_sysfs_entry ioat_version_attr;
346extern struct ioat_sysfs_entry ioat_cap_attr; 356extern struct ioat_sysfs_entry ioat_cap_attr;
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c
index ab5655eb0602..65b912aa1012 100644
--- a/drivers/dma/ioat/dma_v3.c
+++ b/drivers/dma/ioat/dma_v3.c
@@ -111,6 +111,103 @@ static void pq_set_src(struct ioat_raw_descriptor *descs[2],
111 pq->coef[idx] = coef; 111 pq->coef[idx] = coef;
112} 112}
113 113
114static bool is_jf_ioat(struct pci_dev *pdev)
115{
116 switch (pdev->device) {
117 case PCI_DEVICE_ID_INTEL_IOAT_JSF0:
118 case PCI_DEVICE_ID_INTEL_IOAT_JSF1:
119 case PCI_DEVICE_ID_INTEL_IOAT_JSF2:
120 case PCI_DEVICE_ID_INTEL_IOAT_JSF3:
121 case PCI_DEVICE_ID_INTEL_IOAT_JSF4:
122 case PCI_DEVICE_ID_INTEL_IOAT_JSF5:
123 case PCI_DEVICE_ID_INTEL_IOAT_JSF6:
124 case PCI_DEVICE_ID_INTEL_IOAT_JSF7:
125 case PCI_DEVICE_ID_INTEL_IOAT_JSF8:
126 case PCI_DEVICE_ID_INTEL_IOAT_JSF9:
127 return true;
128 default:
129 return false;
130 }
131}
132
133static bool is_snb_ioat(struct pci_dev *pdev)
134{
135 switch (pdev->device) {
136 case PCI_DEVICE_ID_INTEL_IOAT_SNB0:
137 case PCI_DEVICE_ID_INTEL_IOAT_SNB1:
138 case PCI_DEVICE_ID_INTEL_IOAT_SNB2:
139 case PCI_DEVICE_ID_INTEL_IOAT_SNB3:
140 case PCI_DEVICE_ID_INTEL_IOAT_SNB4:
141 case PCI_DEVICE_ID_INTEL_IOAT_SNB5:
142 case PCI_DEVICE_ID_INTEL_IOAT_SNB6:
143 case PCI_DEVICE_ID_INTEL_IOAT_SNB7:
144 case PCI_DEVICE_ID_INTEL_IOAT_SNB8:
145 case PCI_DEVICE_ID_INTEL_IOAT_SNB9:
146 return true;
147 default:
148 return false;
149 }
150}
151
152static bool is_ivb_ioat(struct pci_dev *pdev)
153{
154 switch (pdev->device) {
155 case PCI_DEVICE_ID_INTEL_IOAT_IVB0:
156 case PCI_DEVICE_ID_INTEL_IOAT_IVB1:
157 case PCI_DEVICE_ID_INTEL_IOAT_IVB2:
158 case PCI_DEVICE_ID_INTEL_IOAT_IVB3:
159 case PCI_DEVICE_ID_INTEL_IOAT_IVB4:
160 case PCI_DEVICE_ID_INTEL_IOAT_IVB5:
161 case PCI_DEVICE_ID_INTEL_IOAT_IVB6:
162 case PCI_DEVICE_ID_INTEL_IOAT_IVB7:
163 case PCI_DEVICE_ID_INTEL_IOAT_IVB8:
164 case PCI_DEVICE_ID_INTEL_IOAT_IVB9:
165 return true;
166 default:
167 return false;
168 }
169
170}
171
172static bool is_hsw_ioat(struct pci_dev *pdev)
173{
174 switch (pdev->device) {
175 case PCI_DEVICE_ID_INTEL_IOAT_HSW0:
176 case PCI_DEVICE_ID_INTEL_IOAT_HSW1:
177 case PCI_DEVICE_ID_INTEL_IOAT_HSW2:
178 case PCI_DEVICE_ID_INTEL_IOAT_HSW3:
179 case PCI_DEVICE_ID_INTEL_IOAT_HSW4:
180 case PCI_DEVICE_ID_INTEL_IOAT_HSW5:
181 case PCI_DEVICE_ID_INTEL_IOAT_HSW6:
182 case PCI_DEVICE_ID_INTEL_IOAT_HSW7:
183 case PCI_DEVICE_ID_INTEL_IOAT_HSW8:
184 case PCI_DEVICE_ID_INTEL_IOAT_HSW9:
185 return true;
186 default:
187 return false;
188 }
189
190}
191
192static bool is_xeon_cb32(struct pci_dev *pdev)
193{
194 return is_jf_ioat(pdev) || is_snb_ioat(pdev) || is_ivb_ioat(pdev) ||
195 is_hsw_ioat(pdev);
196}
197
198static bool is_bwd_ioat(struct pci_dev *pdev)
199{
200 switch (pdev->device) {
201 case PCI_DEVICE_ID_INTEL_IOAT_BWD0:
202 case PCI_DEVICE_ID_INTEL_IOAT_BWD1:
203 case PCI_DEVICE_ID_INTEL_IOAT_BWD2:
204 case PCI_DEVICE_ID_INTEL_IOAT_BWD3:
205 return true;
206 default:
207 return false;
208 }
209}
210
114static void ioat3_dma_unmap(struct ioat2_dma_chan *ioat, 211static void ioat3_dma_unmap(struct ioat2_dma_chan *ioat,
115 struct ioat_ring_ent *desc, int idx) 212 struct ioat_ring_ent *desc, int idx)
116{ 213{
@@ -1168,6 +1265,56 @@ static int ioat3_dma_self_test(struct ioatdma_device *device)
1168 return 0; 1265 return 0;
1169} 1266}
1170 1267
1268static int ioat3_irq_reinit(struct ioatdma_device *device)
1269{
1270 int msixcnt = device->common.chancnt;
1271 struct pci_dev *pdev = device->pdev;
1272 int i;
1273 struct msix_entry *msix;
1274 struct ioat_chan_common *chan;
1275 int err = 0;
1276
1277 switch (device->irq_mode) {
1278 case IOAT_MSIX:
1279
1280 for (i = 0; i < msixcnt; i++) {
1281 msix = &device->msix_entries[i];
1282 chan = ioat_chan_by_index(device, i);
1283 devm_free_irq(&pdev->dev, msix->vector, chan);
1284 }
1285
1286 pci_disable_msix(pdev);
1287 break;
1288
1289 case IOAT_MSIX_SINGLE:
1290 msix = &device->msix_entries[0];
1291 chan = ioat_chan_by_index(device, 0);
1292 devm_free_irq(&pdev->dev, msix->vector, chan);
1293 pci_disable_msix(pdev);
1294 break;
1295
1296 case IOAT_MSI:
1297 chan = ioat_chan_by_index(device, 0);
1298 devm_free_irq(&pdev->dev, pdev->irq, chan);
1299 pci_disable_msi(pdev);
1300 break;
1301
1302 case IOAT_INTX:
1303 chan = ioat_chan_by_index(device, 0);
1304 devm_free_irq(&pdev->dev, pdev->irq, chan);
1305 break;
1306
1307 default:
1308 return 0;
1309 }
1310
1311 device->irq_mode = IOAT_NOIRQ;
1312
1313 err = ioat_dma_setup_interrupts(device);
1314
1315 return err;
1316}
1317
1171static int ioat3_reset_hw(struct ioat_chan_common *chan) 1318static int ioat3_reset_hw(struct ioat_chan_common *chan)
1172{ 1319{
1173 /* throw away whatever the channel was doing and get it 1320 /* throw away whatever the channel was doing and get it
@@ -1199,91 +1346,16 @@ static int ioat3_reset_hw(struct ioat_chan_common *chan)
1199 if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0) 1346 if (dev_id == PCI_DEVICE_ID_INTEL_IOAT_TBG0)
1200 pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10); 1347 pci_write_config_dword(pdev, IOAT_PCI_DMAUNCERRSTS_OFFSET, 0x10);
1201 1348
1202 return ioat2_reset_sync(chan, msecs_to_jiffies(200)); 1349 err = ioat2_reset_sync(chan, msecs_to_jiffies(200));
1203} 1350 if (err) {
1204 1351 dev_err(&pdev->dev, "Failed to reset!\n");
1205static bool is_jf_ioat(struct pci_dev *pdev) 1352 return err;
1206{
1207 switch (pdev->device) {
1208 case PCI_DEVICE_ID_INTEL_IOAT_JSF0:
1209 case PCI_DEVICE_ID_INTEL_IOAT_JSF1:
1210 case PCI_DEVICE_ID_INTEL_IOAT_JSF2:
1211 case PCI_DEVICE_ID_INTEL_IOAT_JSF3:
1212 case PCI_DEVICE_ID_INTEL_IOAT_JSF4:
1213 case PCI_DEVICE_ID_INTEL_IOAT_JSF5:
1214 case PCI_DEVICE_ID_INTEL_IOAT_JSF6:
1215 case PCI_DEVICE_ID_INTEL_IOAT_JSF7:
1216 case PCI_DEVICE_ID_INTEL_IOAT_JSF8:
1217 case PCI_DEVICE_ID_INTEL_IOAT_JSF9:
1218 return true;
1219 default:
1220 return false;
1221 }
1222}
1223
1224static bool is_snb_ioat(struct pci_dev *pdev)
1225{
1226 switch (pdev->device) {
1227 case PCI_DEVICE_ID_INTEL_IOAT_SNB0:
1228 case PCI_DEVICE_ID_INTEL_IOAT_SNB1:
1229 case PCI_DEVICE_ID_INTEL_IOAT_SNB2:
1230 case PCI_DEVICE_ID_INTEL_IOAT_SNB3:
1231 case PCI_DEVICE_ID_INTEL_IOAT_SNB4:
1232 case PCI_DEVICE_ID_INTEL_IOAT_SNB5:
1233 case PCI_DEVICE_ID_INTEL_IOAT_SNB6:
1234 case PCI_DEVICE_ID_INTEL_IOAT_SNB7:
1235 case PCI_DEVICE_ID_INTEL_IOAT_SNB8:
1236 case PCI_DEVICE_ID_INTEL_IOAT_SNB9:
1237 return true;
1238 default:
1239 return false;
1240 }
1241}
1242
1243static bool is_ivb_ioat(struct pci_dev *pdev)
1244{
1245 switch (pdev->device) {
1246 case PCI_DEVICE_ID_INTEL_IOAT_IVB0:
1247 case PCI_DEVICE_ID_INTEL_IOAT_IVB1:
1248 case PCI_DEVICE_ID_INTEL_IOAT_IVB2:
1249 case PCI_DEVICE_ID_INTEL_IOAT_IVB3:
1250 case PCI_DEVICE_ID_INTEL_IOAT_IVB4:
1251 case PCI_DEVICE_ID_INTEL_IOAT_IVB5:
1252 case PCI_DEVICE_ID_INTEL_IOAT_IVB6:
1253 case PCI_DEVICE_ID_INTEL_IOAT_IVB7:
1254 case PCI_DEVICE_ID_INTEL_IOAT_IVB8:
1255 case PCI_DEVICE_ID_INTEL_IOAT_IVB9:
1256 return true;
1257 default:
1258 return false;
1259 }
1260
1261}
1262
1263static bool is_hsw_ioat(struct pci_dev *pdev)
1264{
1265 switch (pdev->device) {
1266 case PCI_DEVICE_ID_INTEL_IOAT_HSW0:
1267 case PCI_DEVICE_ID_INTEL_IOAT_HSW1:
1268 case PCI_DEVICE_ID_INTEL_IOAT_HSW2:
1269 case PCI_DEVICE_ID_INTEL_IOAT_HSW3:
1270 case PCI_DEVICE_ID_INTEL_IOAT_HSW4:
1271 case PCI_DEVICE_ID_INTEL_IOAT_HSW5:
1272 case PCI_DEVICE_ID_INTEL_IOAT_HSW6:
1273 case PCI_DEVICE_ID_INTEL_IOAT_HSW7:
1274 case PCI_DEVICE_ID_INTEL_IOAT_HSW8:
1275 case PCI_DEVICE_ID_INTEL_IOAT_HSW9:
1276 return true;
1277 default:
1278 return false;
1279 } 1353 }
1280 1354
1281} 1355 if (device->irq_mode != IOAT_NOIRQ && is_bwd_ioat(pdev))
1356 err = ioat3_irq_reinit(device);
1282 1357
1283static bool is_xeon_cb32(struct pci_dev *pdev) 1358 return err;
1284{
1285 return is_jf_ioat(pdev) || is_snb_ioat(pdev) || is_ivb_ioat(pdev) ||
1286 is_hsw_ioat(pdev);
1287} 1359}
1288 1360
1289int ioat3_dma_probe(struct ioatdma_device *device, int dca) 1361int ioat3_dma_probe(struct ioatdma_device *device, int dca)