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); |
