diff options
author | Ohad Ben-Cohen <ohad@wizery.com> | 2011-09-05 10:30:34 -0400 |
---|---|---|
committer | Ohad Ben-Cohen <ohad@wizery.com> | 2011-09-21 12:45:32 -0400 |
commit | c97f6dd0fe21dfd658c59c144a1b7fd5d8db04ac (patch) | |
tree | 6cc0cb7fa7072aa62375a558a732b837703829a6 /drivers/hwspinlock | |
parent | e467b6421435f467e274d4f25d62900e1e0e4286 (diff) |
hwspinlock/omap: simplify allocation scheme
Instead of allocating every hwspinlock separately, allocate
them all in one shot.
This both simplifies the driver and helps achieving better
slab utilization.
Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Diffstat (limited to 'drivers/hwspinlock')
-rw-r--r-- | drivers/hwspinlock/omap_hwspinlock.c | 51 |
1 files changed, 17 insertions, 34 deletions
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c index 1d19fe9324a4..d0583480fe33 100644 --- a/drivers/hwspinlock/omap_hwspinlock.c +++ b/drivers/hwspinlock/omap_hwspinlock.c | |||
@@ -52,6 +52,7 @@ struct omap_hwspinlock { | |||
52 | struct omap_hwspinlock_state { | 52 | struct omap_hwspinlock_state { |
53 | int num_locks; /* Total number of locks in system */ | 53 | int num_locks; /* Total number of locks in system */ |
54 | void __iomem *io_base; /* Mapped base address */ | 54 | void __iomem *io_base; /* Mapped base address */ |
55 | struct omap_hwspinlock lock[0]; /* Array of 'num_locks' locks */ | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | static int omap_hwspinlock_trylock(struct hwspinlock *lock) | 58 | static int omap_hwspinlock_trylock(struct hwspinlock *lock) |
@@ -95,7 +96,6 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev) | |||
95 | { | 96 | { |
96 | struct omap_hwspinlock *omap_lock; | 97 | struct omap_hwspinlock *omap_lock; |
97 | struct omap_hwspinlock_state *state; | 98 | struct omap_hwspinlock_state *state; |
98 | struct hwspinlock *lock; | ||
99 | struct resource *res; | 99 | struct resource *res; |
100 | void __iomem *io_base; | 100 | void __iomem *io_base; |
101 | int i, ret; | 101 | int i, ret; |
@@ -104,15 +104,9 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev) | |||
104 | if (!res) | 104 | if (!res) |
105 | return -ENODEV; | 105 | return -ENODEV; |
106 | 106 | ||
107 | state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
108 | if (!state) | ||
109 | return -ENOMEM; | ||
110 | |||
111 | io_base = ioremap(res->start, resource_size(res)); | 107 | io_base = ioremap(res->start, resource_size(res)); |
112 | if (!io_base) { | 108 | if (!io_base) |
113 | ret = -ENOMEM; | 109 | return -ENOMEM; |
114 | goto free_state; | ||
115 | } | ||
116 | 110 | ||
117 | /* Determine number of locks */ | 111 | /* Determine number of locks */ |
118 | i = readl(io_base + SYSSTATUS_OFFSET); | 112 | i = readl(io_base + SYSSTATUS_OFFSET); |
@@ -124,7 +118,15 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev) | |||
124 | goto iounmap_base; | 118 | goto iounmap_base; |
125 | } | 119 | } |
126 | 120 | ||
127 | state->num_locks = i * 32; | 121 | i *= 32; /* actual number of locks in this device */ |
122 | |||
123 | state = kzalloc(sizeof(*state) + i * sizeof(*omap_lock), GFP_KERNEL); | ||
124 | if (!state) { | ||
125 | ret = -ENOMEM; | ||
126 | goto iounmap_base; | ||
127 | } | ||
128 | |||
129 | state->num_locks = i; | ||
128 | state->io_base = io_base; | 130 | state->io_base = io_base; |
129 | 131 | ||
130 | platform_set_drvdata(pdev, state); | 132 | platform_set_drvdata(pdev, state); |
@@ -136,11 +138,7 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev) | |||
136 | pm_runtime_enable(&pdev->dev); | 138 | pm_runtime_enable(&pdev->dev); |
137 | 139 | ||
138 | for (i = 0; i < state->num_locks; i++) { | 140 | for (i = 0; i < state->num_locks; i++) { |
139 | omap_lock = kzalloc(sizeof(*omap_lock), GFP_KERNEL); | 141 | omap_lock = &state->lock[i]; |
140 | if (!omap_lock) { | ||
141 | ret = -ENOMEM; | ||
142 | goto free_locks; | ||
143 | } | ||
144 | 142 | ||
145 | omap_lock->lock.dev = &pdev->dev; | 143 | omap_lock->lock.dev = &pdev->dev; |
146 | omap_lock->lock.id = i; | 144 | omap_lock->lock.id = i; |
@@ -148,30 +146,19 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev) | |||
148 | omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i; | 146 | omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i; |
149 | 147 | ||
150 | ret = hwspin_lock_register(&omap_lock->lock); | 148 | ret = hwspin_lock_register(&omap_lock->lock); |
151 | if (ret) { | 149 | if (ret) |
152 | kfree(omap_lock); | ||
153 | goto free_locks; | 150 | goto free_locks; |
154 | } | ||
155 | } | 151 | } |
156 | 152 | ||
157 | return 0; | 153 | return 0; |
158 | 154 | ||
159 | free_locks: | 155 | free_locks: |
160 | while (--i >= 0) { | 156 | while (--i >= 0) |
161 | lock = hwspin_lock_unregister(i); | 157 | hwspin_lock_unregister(i); |
162 | /* this should't happen, but let's give our best effort */ | ||
163 | if (!lock) { | ||
164 | dev_err(&pdev->dev, "%s: cleanups failed\n", __func__); | ||
165 | continue; | ||
166 | } | ||
167 | omap_lock = to_omap_hwspinlock(lock); | ||
168 | kfree(omap_lock); | ||
169 | } | ||
170 | pm_runtime_disable(&pdev->dev); | 158 | pm_runtime_disable(&pdev->dev); |
159 | kfree(state); | ||
171 | iounmap_base: | 160 | iounmap_base: |
172 | iounmap(io_base); | 161 | iounmap(io_base); |
173 | free_state: | ||
174 | kfree(state); | ||
175 | return ret; | 162 | return ret; |
176 | } | 163 | } |
177 | 164 | ||
@@ -179,7 +166,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev) | |||
179 | { | 166 | { |
180 | struct omap_hwspinlock_state *state = platform_get_drvdata(pdev); | 167 | struct omap_hwspinlock_state *state = platform_get_drvdata(pdev); |
181 | struct hwspinlock *lock; | 168 | struct hwspinlock *lock; |
182 | struct omap_hwspinlock *omap_lock; | ||
183 | int i; | 169 | int i; |
184 | 170 | ||
185 | for (i = 0; i < state->num_locks; i++) { | 171 | for (i = 0; i < state->num_locks; i++) { |
@@ -190,9 +176,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev) | |||
190 | dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i); | 176 | dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i); |
191 | return -EBUSY; | 177 | return -EBUSY; |
192 | } | 178 | } |
193 | |||
194 | omap_lock = to_omap_hwspinlock(lock); | ||
195 | kfree(omap_lock); | ||
196 | } | 179 | } |
197 | 180 | ||
198 | pm_runtime_disable(&pdev->dev); | 181 | pm_runtime_disable(&pdev->dev); |