| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2007 PA Semi, Inc |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Maintained by: Olof Johansson <olof@lixom.net> |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Based on drivers/pcmcia/omap_cf.c |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 16 | | - * GNU General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | | - * You should have received a copy of the GNU General Public License |
|---|
| 19 | | - * along with this program; if not, write to the Free Software |
|---|
| 20 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 21 | 8 | */ |
|---|
| 22 | 9 | |
|---|
| 23 | 10 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 191 | 178 | struct device_node *np = ofdev->dev.of_node; |
|---|
| 192 | 179 | struct electra_cf_socket *cf; |
|---|
| 193 | 180 | struct resource mem, io; |
|---|
| 194 | | - int status; |
|---|
| 181 | + int status = -ENOMEM; |
|---|
| 195 | 182 | const unsigned int *prop; |
|---|
| 196 | 183 | int err; |
|---|
| 197 | | - struct vm_struct *area; |
|---|
| 198 | 184 | |
|---|
| 199 | 185 | err = of_address_to_resource(np, 0, &mem); |
|---|
| 200 | 186 | if (err) |
|---|
| .. | .. |
|---|
| 215 | 201 | cf->mem_phys = mem.start; |
|---|
| 216 | 202 | cf->mem_size = PAGE_ALIGN(resource_size(&mem)); |
|---|
| 217 | 203 | cf->mem_base = ioremap(cf->mem_phys, cf->mem_size); |
|---|
| 204 | + if (!cf->mem_base) |
|---|
| 205 | + goto out_free_cf; |
|---|
| 218 | 206 | cf->io_size = PAGE_ALIGN(resource_size(&io)); |
|---|
| 219 | | - |
|---|
| 220 | | - area = __get_vm_area(cf->io_size, 0, PHB_IO_BASE, PHB_IO_END); |
|---|
| 221 | | - if (area == NULL) { |
|---|
| 222 | | - status = -ENOMEM; |
|---|
| 223 | | - goto fail1; |
|---|
| 224 | | - } |
|---|
| 225 | | - |
|---|
| 226 | | - cf->io_virt = (void __iomem *)(area->addr); |
|---|
| 207 | + cf->io_virt = ioremap_phb(io.start, cf->io_size); |
|---|
| 208 | + if (!cf->io_virt) |
|---|
| 209 | + goto out_unmap_mem; |
|---|
| 227 | 210 | |
|---|
| 228 | 211 | cf->gpio_base = ioremap(0xfc103000, 0x1000); |
|---|
| 212 | + if (!cf->gpio_base) |
|---|
| 213 | + goto out_unmap_virt; |
|---|
| 229 | 214 | dev_set_drvdata(device, cf); |
|---|
| 230 | 215 | |
|---|
| 231 | | - if (!cf->mem_base || !cf->io_virt || !cf->gpio_base || |
|---|
| 232 | | - (__ioremap_at(io.start, cf->io_virt, cf->io_size, |
|---|
| 233 | | - pgprot_val(pgprot_noncached(__pgprot(0)))) == NULL)) { |
|---|
| 234 | | - dev_err(device, "can't ioremap ranges\n"); |
|---|
| 235 | | - status = -ENOMEM; |
|---|
| 236 | | - goto fail1; |
|---|
| 237 | | - } |
|---|
| 238 | | - |
|---|
| 239 | | - |
|---|
| 240 | 216 | cf->io_base = (unsigned long)cf->io_virt - VMALLOC_END; |
|---|
| 241 | | - |
|---|
| 242 | 217 | cf->iomem.start = (unsigned long)cf->mem_base; |
|---|
| 243 | 218 | cf->iomem.end = (unsigned long)cf->mem_base + (mem.end - mem.start); |
|---|
| 244 | 219 | cf->iomem.flags = IORESOURCE_MEM; |
|---|
| .. | .. |
|---|
| 318 | 293 | if (cf->irq) |
|---|
| 319 | 294 | free_irq(cf->irq, cf); |
|---|
| 320 | 295 | |
|---|
| 321 | | - if (cf->io_virt) |
|---|
| 322 | | - __iounmap_at(cf->io_virt, cf->io_size); |
|---|
| 323 | | - if (cf->mem_base) |
|---|
| 324 | | - iounmap(cf->mem_base); |
|---|
| 325 | | - if (cf->gpio_base) |
|---|
| 326 | | - iounmap(cf->gpio_base); |
|---|
| 327 | | - if (area) |
|---|
| 328 | | - device_init_wakeup(&ofdev->dev, 0); |
|---|
| 296 | + iounmap(cf->gpio_base); |
|---|
| 297 | +out_unmap_virt: |
|---|
| 298 | + device_init_wakeup(&ofdev->dev, 0); |
|---|
| 299 | + iounmap(cf->io_virt); |
|---|
| 300 | +out_unmap_mem: |
|---|
| 301 | + iounmap(cf->mem_base); |
|---|
| 302 | +out_free_cf: |
|---|
| 329 | 303 | kfree(cf); |
|---|
| 330 | 304 | return status; |
|---|
| 331 | 305 | |
|---|
| .. | .. |
|---|
| 343 | 317 | free_irq(cf->irq, cf); |
|---|
| 344 | 318 | del_timer_sync(&cf->timer); |
|---|
| 345 | 319 | |
|---|
| 346 | | - __iounmap_at(cf->io_virt, cf->io_size); |
|---|
| 320 | + iounmap(cf->io_virt); |
|---|
| 347 | 321 | iounmap(cf->mem_base); |
|---|
| 348 | 322 | iounmap(cf->gpio_base); |
|---|
| 349 | 323 | release_mem_region(cf->mem_phys, cf->mem_size); |
|---|