1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2007 PA Semi, Inc 4 * 5 * Maintained by: Olof Johansson <olof@lixom.net> 6 * 7 * Based on drivers/pcmcia/omap_cf.c 8 */ 9 10 #include <linux/module.h> 11 #include <linux/kernel.h> 12 #include <linux/sched.h> 13 #include <linux/platform_device.h> 14 #include <linux/errno.h> 15 #include <linux/init.h> 16 #include <linux/delay.h> 17 #include <linux/interrupt.h> 18 #include <linux/mm.h> 19 #include <linux/vmalloc.h> 20 #include <linux/of_address.h> 21 #include <linux/of_irq.h> 22 #include <linux/of_platform.h> 23 #include <linux/slab.h> 24 25 #include <pcmcia/ss.h> 26 27 static const char driver_name[] = "electra-cf"; 28 29 struct electra_cf_socket { 30 struct pcmcia_socket socket; 31 32 struct timer_list timer; 33 unsigned present:1; 34 unsigned active:1; 35 36 struct platform_device *ofdev; 37 unsigned long mem_phys; 38 void __iomem *mem_base; 39 unsigned long mem_size; 40 void __iomem *io_virt; 41 unsigned int io_base; 42 unsigned int io_size; 43 u_int irq; 44 struct resource iomem; 45 void __iomem *gpio_base; 46 int gpio_detect; 47 int gpio_vsense; 48 int gpio_3v; 49 int gpio_5v; 50 }; 51 52 #define POLL_INTERVAL (2 * HZ) 53 54 55 static int electra_cf_present(struct electra_cf_socket *cf) 56 { 57 unsigned int gpio; 58 59 gpio = in_le32(cf->gpio_base+0x40); 60 return !(gpio & (1 << cf->gpio_detect)); 61 } 62 63 static int electra_cf_ss_init(struct pcmcia_socket *s) 64 { 65 return 0; 66 } 67 68 /* the timer is primarily to kick this socket's pccardd */ 69 static void electra_cf_timer(struct timer_list *t) 70 { 71 struct electra_cf_socket *cf = from_timer(cf, t, timer); 72 int present = electra_cf_present(cf); 73 74 if (present != cf->present) { 75 cf->present = present; 76 pcmcia_parse_events(&cf->socket, SS_DETECT); 77 } 78 79 if (cf->active) 80 mod_timer(&cf->timer, jiffies + POLL_INTERVAL); 81 } 82 83 static irqreturn_t electra_cf_irq(int irq, void *_cf) 84 { 85 struct electra_cf_socket *cf = _cf; 86 87 electra_cf_timer(&cf->timer); 88 return IRQ_HANDLED; 89 } 90 91 static int electra_cf_get_status(struct pcmcia_socket *s, u_int *sp) 92 { 93 struct electra_cf_socket *cf; 94 95 if (!sp) 96 return -EINVAL; 97 98 cf = container_of(s, struct electra_cf_socket, socket); 99 100 /* NOTE CF is always 3VCARD */ 101 if (electra_cf_present(cf)) { 102 *sp = SS_READY | SS_DETECT | SS_POWERON | SS_3VCARD; 103 104 s->pci_irq = cf->irq; 105 } else 106 *sp = 0; 107 return 0; 108 } 109 110 static int electra_cf_set_socket(struct pcmcia_socket *sock, 111 struct socket_state_t *s) 112 { 113 unsigned int gpio; 114 unsigned int vcc; 115 struct electra_cf_socket *cf; 116 117 cf = container_of(sock, struct electra_cf_socket, socket); 118 119 /* "reset" means no power in our case */ 120 vcc = (s->flags & SS_RESET) ? 0 : s->Vcc; 121 122 switch (vcc) { 123 case 0: 124 gpio = 0; 125 break; 126 case 33: 127 gpio = (1 << cf->gpio_3v); 128 break; 129 case 5: 130 gpio = (1 << cf->gpio_5v); 131 break; 132 default: 133 return -EINVAL; 134 } 135 136 gpio |= 1 << (cf->gpio_3v + 16); /* enwr */ 137 gpio |= 1 << (cf->gpio_5v + 16); /* enwr */ 138 out_le32(cf->gpio_base+0x90, gpio); 139 140 pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n", 141 driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask); 142 143 return 0; 144 } 145 146 static int electra_cf_set_io_map(struct pcmcia_socket *s, 147 struct pccard_io_map *io) 148 { 149 return 0; 150 } 151 152 static int electra_cf_set_mem_map(struct pcmcia_socket *s, 153 struct pccard_mem_map *map) 154 { 155 struct electra_cf_socket *cf; 156 157 if (map->card_start) 158 return -EINVAL; 159 cf = container_of(s, struct electra_cf_socket, socket); 160 map->static_start = cf->mem_phys; 161 map->flags &= MAP_ACTIVE|MAP_ATTRIB; 162 if (!(map->flags & MAP_ATTRIB)) 163 map->static_start += 0x800; 164 return 0; 165 } 166 167 static struct pccard_operations electra_cf_ops = { 168 .init = electra_cf_ss_init, 169 .get_status = electra_cf_get_status, 170 .set_socket = electra_cf_set_socket, 171 .set_io_map = electra_cf_set_io_map, 172 .set_mem_map = electra_cf_set_mem_map, 173 }; 174 175 static int electra_cf_probe(struct platform_device *ofdev) 176 { 177 struct device *device = &ofdev->dev; 178 struct device_node *np = ofdev->dev.of_node; 179 struct electra_cf_socket *cf; 180 struct resource mem, io; 181 int status; 182 const unsigned int *prop; 183 int err; 184 struct vm_struct *area; 185 186 err = of_address_to_resource(np, 0, &mem); 187 if (err) 188 return -EINVAL; 189 190 err = of_address_to_resource(np, 1, &io); 191 if (err) 192 return -EINVAL; 193 194 cf = kzalloc(sizeof(*cf), GFP_KERNEL); 195 if (!cf) 196 return -ENOMEM; 197 198 timer_setup(&cf->timer, electra_cf_timer, 0); 199 cf->irq = 0; 200 201 cf->ofdev = ofdev; 202 cf->mem_phys = mem.start; 203 cf->mem_size = PAGE_ALIGN(resource_size(&mem)); 204 cf->mem_base = ioremap(cf->mem_phys, cf->mem_size); 205 cf->io_size = PAGE_ALIGN(resource_size(&io)); 206 207 area = __get_vm_area(cf->io_size, 0, PHB_IO_BASE, PHB_IO_END); 208 if (area == NULL) { 209 status = -ENOMEM; 210 goto fail1; 211 } 212 213 cf->io_virt = (void __iomem *)(area->addr); 214 215 cf->gpio_base = ioremap(0xfc103000, 0x1000); 216 dev_set_drvdata(device, cf); 217 218 if (!cf->mem_base || !cf->io_virt || !cf->gpio_base || 219 (__ioremap_at(io.start, cf->io_virt, cf->io_size, 220 pgprot_noncached(PAGE_KERNEL)) == NULL)) { 221 dev_err(device, "can't ioremap ranges\n"); 222 status = -ENOMEM; 223 goto fail1; 224 } 225 226 227 cf->io_base = (unsigned long)cf->io_virt - VMALLOC_END; 228 229 cf->iomem.start = (unsigned long)cf->mem_base; 230 cf->iomem.end = (unsigned long)cf->mem_base + (mem.end - mem.start); 231 cf->iomem.flags = IORESOURCE_MEM; 232 233 cf->irq = irq_of_parse_and_map(np, 0); 234 235 status = request_irq(cf->irq, electra_cf_irq, IRQF_SHARED, 236 driver_name, cf); 237 if (status < 0) { 238 dev_err(device, "request_irq failed\n"); 239 goto fail1; 240 } 241 242 cf->socket.pci_irq = cf->irq; 243 244 prop = of_get_property(np, "card-detect-gpio", NULL); 245 if (!prop) 246 goto fail1; 247 cf->gpio_detect = *prop; 248 249 prop = of_get_property(np, "card-vsense-gpio", NULL); 250 if (!prop) 251 goto fail1; 252 cf->gpio_vsense = *prop; 253 254 prop = of_get_property(np, "card-3v-gpio", NULL); 255 if (!prop) 256 goto fail1; 257 cf->gpio_3v = *prop; 258 259 prop = of_get_property(np, "card-5v-gpio", NULL); 260 if (!prop) 261 goto fail1; 262 cf->gpio_5v = *prop; 263 264 cf->socket.io_offset = cf->io_base; 265 266 /* reserve chip-select regions */ 267 if (!request_mem_region(cf->mem_phys, cf->mem_size, driver_name)) { 268 status = -ENXIO; 269 dev_err(device, "Can't claim memory region\n"); 270 goto fail1; 271 } 272 273 if (!request_region(cf->io_base, cf->io_size, driver_name)) { 274 status = -ENXIO; 275 dev_err(device, "Can't claim I/O region\n"); 276 goto fail2; 277 } 278 279 cf->socket.owner = THIS_MODULE; 280 cf->socket.dev.parent = &ofdev->dev; 281 cf->socket.ops = &electra_cf_ops; 282 cf->socket.resource_ops = &pccard_static_ops; 283 cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP | 284 SS_CAP_MEM_ALIGN; 285 cf->socket.map_size = 0x800; 286 287 status = pcmcia_register_socket(&cf->socket); 288 if (status < 0) { 289 dev_err(device, "pcmcia_register_socket failed\n"); 290 goto fail3; 291 } 292 293 dev_info(device, "at mem 0x%lx io 0x%llx irq %d\n", 294 cf->mem_phys, io.start, cf->irq); 295 296 cf->active = 1; 297 electra_cf_timer(&cf->timer); 298 return 0; 299 300 fail3: 301 release_region(cf->io_base, cf->io_size); 302 fail2: 303 release_mem_region(cf->mem_phys, cf->mem_size); 304 fail1: 305 if (cf->irq) 306 free_irq(cf->irq, cf); 307 308 if (cf->io_virt) 309 __iounmap_at(cf->io_virt, cf->io_size); 310 if (cf->mem_base) 311 iounmap(cf->mem_base); 312 if (cf->gpio_base) 313 iounmap(cf->gpio_base); 314 if (area) 315 device_init_wakeup(&ofdev->dev, 0); 316 kfree(cf); 317 return status; 318 319 } 320 321 static int electra_cf_remove(struct platform_device *ofdev) 322 { 323 struct device *device = &ofdev->dev; 324 struct electra_cf_socket *cf; 325 326 cf = dev_get_drvdata(device); 327 328 cf->active = 0; 329 pcmcia_unregister_socket(&cf->socket); 330 free_irq(cf->irq, cf); 331 del_timer_sync(&cf->timer); 332 333 __iounmap_at(cf->io_virt, cf->io_size); 334 iounmap(cf->mem_base); 335 iounmap(cf->gpio_base); 336 release_mem_region(cf->mem_phys, cf->mem_size); 337 release_region(cf->io_base, cf->io_size); 338 339 kfree(cf); 340 341 return 0; 342 } 343 344 static const struct of_device_id electra_cf_match[] = { 345 { 346 .compatible = "electra-cf", 347 }, 348 {}, 349 }; 350 MODULE_DEVICE_TABLE(of, electra_cf_match); 351 352 static struct platform_driver electra_cf_driver = { 353 .driver = { 354 .name = driver_name, 355 .of_match_table = electra_cf_match, 356 }, 357 .probe = electra_cf_probe, 358 .remove = electra_cf_remove, 359 }; 360 361 module_platform_driver(electra_cf_driver); 362 363 MODULE_LICENSE("GPL"); 364 MODULE_AUTHOR("Olof Johansson <olof@lixom.net>"); 365 MODULE_DESCRIPTION("PA Semi Electra CF driver"); 366