bq2415x_charger.patch: Make sure that hook function can be called for init reported...
[kernel-power] / kernel-power-2.6.28 / debian / patches / support-non-page-aligned-buffers-in-iommu_vmap.diff
1 --- a/arch/arm/plat-omap/iovmm.c        2011-11-15 06:09:03.909034496 -0500
2 +++ b/arch/arm/plat-omap/iovmm.c        2011-12-21 14:03:23.673780000 -0500
3 @@ -59,6 +59,15 @@
4  
5  static struct kmem_cache *iovm_area_cachep;
6  
7 +/* return the offset of the first scatterlist entry in a sg table */
8 +static unsigned int sgtable_offset(const struct sg_table *sgt)
9 +{
10 +       if (!sgt || !sgt->nents)
11 +               return 0;
12 +
13 +       return sgt->sgl->offset;
14 +}
15 +
16  /* return total bytes of sg buffers */
17  static size_t sgtable_len(const struct sg_table *sgt)
18  {
19 @@ -71,11 +80,17 @@
20         for_each_sg(sgt->sgl, sg, sgt->nents, i) {
21                 size_t bytes;
22  
23 -               bytes = sg_dma_len(sg);
24 +               bytes = sg_dma_len(sg) + sg->offset;
25  
26                 if (!iopgsz_ok(bytes)) {
27 -                       pr_err("%s: sg[%d] not iommu pagesize(%x)\n",
28 -                              __func__, i, bytes);
29 +                       pr_err("%s: sg[%d] not iommu pagesize(%u %u)\n",
30 +                              __func__, i, bytes, sg->offset);
31 +                       return 0;
32 +               }
33 +
34 +               if (i && sg->offset) {
35 +                       pr_err("%s: sg[%d] offset not allowed in internal "
36 +                              "entries\n", __func__, i);
37                         return 0;
38                 }
39  
40 @@ -112,6 +127,16 @@
41  
42         return nr_entries;
43  }
44 +static struct scatterlist *sg_alloc(unsigned int nents, gfp_t gfp_mask)
45 +{
46 +       return kmalloc(nents * sizeof(struct scatterlist), gfp_mask);
47 +}
48 +
49 +static void sg_free(struct scatterlist *sg, unsigned int nents)
50 +{
51 +       kfree(sg);
52 +}
53 +
54  
55  /* allocate and initialize sg_table header(a kind of 'superblock') */
56  static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags)
57 @@ -138,7 +163,7 @@
58         if (!sgt)
59                 return ERR_PTR(-ENOMEM);
60  
61 -       err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL);
62 +       err = __sg_alloc_table(sgt, nr_entries, -1, GFP_KERNEL, sg_alloc);
63         if (err)
64                 return ERR_PTR(err);
65  
66 @@ -153,7 +178,7 @@
67         if (!sgt)
68                 return;
69  
70 -       sg_free_table(sgt);
71 +       __sg_free_table(sgt, -1, sg_free);      
72         kfree(sgt);
73  
74         pr_debug("%s: sgt:%p\n", __func__, sgt);
75 @@ -182,8 +207,8 @@
76                 u32 pa;
77                 int err;
78  
79 -               pa = sg_phys(sg);
80 -               bytes = sg_dma_len(sg);
81 +               pa = sg_phys(sg) - sg->offset;
82 +               bytes = sg_dma_len(sg) + sg->offset;
83  
84                 BUG_ON(bytes != PAGE_SIZE);
85  
86 @@ -450,8 +475,8 @@
87                 size_t bytes;
88                 struct iotlb_entry e;
89  
90 -               pa = sg_phys(sg);
91 -               bytes = sg_dma_len(sg);
92 +               pa = sg_phys(sg) - sg->offset;
93 +               bytes = sg_dma_len(sg) + sg->offset;
94  
95                 flags &= ~IOVMF_PGSZ_MASK;
96                 pgsz = bytes_to_iopgsz(bytes);
97 @@ -632,7 +657,7 @@
98         if (IS_ERR_VALUE(da))
99                 vunmap_sg(va);
100  
101 -       return da;
102 +       return da + sgtable_offset(sgt);
103  }
104  EXPORT_SYMBOL_GPL(iommu_vmap);
105  
106 @@ -651,6 +676,7 @@
107          * 'sgt' is allocated before 'iommu_vmalloc()' is called.
108          * Just returns 'sgt' to the caller to free
109          */
110 +       da &= PAGE_MASK;
111         sgt = unmap_vm_area(obj, da, vunmap_sg, IOVMF_DISCONT | IOVMF_MMIO);
112         if (!sgt)
113                 dev_dbg(obj->dev, "%s: No sgt\n", __func__);