.. | .. |
---|
17 | 17 | #include <asm/tce.h> |
---|
18 | 18 | #include "pci.h" |
---|
19 | 19 | |
---|
| 20 | +unsigned long pnv_ioda_parse_tce_sizes(struct pnv_phb *phb) |
---|
| 21 | +{ |
---|
| 22 | + struct pci_controller *hose = phb->hose; |
---|
| 23 | + struct device_node *dn = hose->dn; |
---|
| 24 | + unsigned long mask = 0; |
---|
| 25 | + int i, rc, count; |
---|
| 26 | + u32 val; |
---|
| 27 | + |
---|
| 28 | + count = of_property_count_u32_elems(dn, "ibm,supported-tce-sizes"); |
---|
| 29 | + if (count <= 0) { |
---|
| 30 | + mask = SZ_4K | SZ_64K; |
---|
| 31 | + /* Add 16M for POWER8 by default */ |
---|
| 32 | + if (cpu_has_feature(CPU_FTR_ARCH_207S) && |
---|
| 33 | + !cpu_has_feature(CPU_FTR_ARCH_300)) |
---|
| 34 | + mask |= SZ_16M | SZ_256M; |
---|
| 35 | + return mask; |
---|
| 36 | + } |
---|
| 37 | + |
---|
| 38 | + for (i = 0; i < count; i++) { |
---|
| 39 | + rc = of_property_read_u32_index(dn, "ibm,supported-tce-sizes", |
---|
| 40 | + i, &val); |
---|
| 41 | + if (rc == 0) |
---|
| 42 | + mask |= 1ULL << val; |
---|
| 43 | + } |
---|
| 44 | + |
---|
| 45 | + return mask; |
---|
| 46 | +} |
---|
| 47 | + |
---|
20 | 48 | void pnv_pci_setup_iommu_table(struct iommu_table *tbl, |
---|
21 | 49 | void *tce_mem, u64 tce_size, |
---|
22 | 50 | u64 dma_offset, unsigned int page_shift) |
---|
.. | .. |
---|
138 | 166 | if (!ptce) { |
---|
139 | 167 | ptce = pnv_tce(tbl, false, idx, alloc); |
---|
140 | 168 | if (!ptce) |
---|
141 | | - return alloc ? H_HARDWARE : H_TOO_HARD; |
---|
| 169 | + return -ENOMEM; |
---|
142 | 170 | } |
---|
143 | 171 | |
---|
144 | 172 | if (newtce & TCE_PCI_WRITE) |
---|
.. | .. |
---|
340 | 368 | return -ENOMEM; |
---|
341 | 369 | } |
---|
342 | 370 | |
---|
343 | | -static void pnv_iommu_table_group_link_free(struct rcu_head *head) |
---|
344 | | -{ |
---|
345 | | - struct iommu_table_group_link *tgl = container_of(head, |
---|
346 | | - struct iommu_table_group_link, rcu); |
---|
347 | | - |
---|
348 | | - kfree(tgl); |
---|
349 | | -} |
---|
350 | | - |
---|
351 | 371 | void pnv_pci_unlink_table_and_group(struct iommu_table *tbl, |
---|
352 | 372 | struct iommu_table_group *table_group) |
---|
353 | 373 | { |
---|
.. | .. |
---|
363 | 383 | list_for_each_entry_rcu(tgl, &tbl->it_group_list, next) { |
---|
364 | 384 | if (tgl->table_group == table_group) { |
---|
365 | 385 | list_del_rcu(&tgl->next); |
---|
366 | | - call_rcu(&tgl->rcu, pnv_iommu_table_group_link_free); |
---|
| 386 | + kfree_rcu(tgl, rcu); |
---|
367 | 387 | found = true; |
---|
368 | 388 | break; |
---|
369 | 389 | } |
---|
.. | .. |
---|
375 | 395 | found = false; |
---|
376 | 396 | for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { |
---|
377 | 397 | if (table_group->tables[i] == tbl) { |
---|
| 398 | + iommu_tce_table_put(tbl); |
---|
378 | 399 | table_group->tables[i] = NULL; |
---|
379 | 400 | found = true; |
---|
380 | 401 | break; |
---|
.. | .. |
---|
400 | 421 | tgl->table_group = table_group; |
---|
401 | 422 | list_add_rcu(&tgl->next, &tbl->it_group_list); |
---|
402 | 423 | |
---|
403 | | - table_group->tables[num] = tbl; |
---|
| 424 | + table_group->tables[num] = iommu_tce_table_get(tbl); |
---|
404 | 425 | |
---|
405 | 426 | return 0; |
---|
406 | 427 | } |
---|