1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2007 PA Semi, Inc
5 * Maintained by: Olof Johansson <olof@lixom.net>
7 * Based on drivers/pcmcia/omap_cf.c
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>
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>
25 #include <pcmcia/ss.h>
27 static const char driver_name
[] = "electra-cf";
29 struct electra_cf_socket
{
30 struct pcmcia_socket socket
;
32 struct timer_list timer
;
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
;
44 struct resource iomem
;
45 void __iomem
*gpio_base
;
52 #define POLL_INTERVAL (2 * HZ)
55 static int electra_cf_present(struct electra_cf_socket
*cf
)
59 gpio
= in_le32(cf
->gpio_base
+0x40);
60 return !(gpio
& (1 << cf
->gpio_detect
));
63 static int electra_cf_ss_init(struct pcmcia_socket
*s
)
68 /* the timer is primarily to kick this socket's pccardd */
69 static void electra_cf_timer(struct timer_list
*t
)
71 struct electra_cf_socket
*cf
= from_timer(cf
, t
, timer
);
72 int present
= electra_cf_present(cf
);
74 if (present
!= cf
->present
) {
75 cf
->present
= present
;
76 pcmcia_parse_events(&cf
->socket
, SS_DETECT
);
80 mod_timer(&cf
->timer
, jiffies
+ POLL_INTERVAL
);
83 static irqreturn_t
electra_cf_irq(int irq
, void *_cf
)
85 struct electra_cf_socket
*cf
= _cf
;
87 electra_cf_timer(&cf
->timer
);
91 static int electra_cf_get_status(struct pcmcia_socket
*s
, u_int
*sp
)
93 struct electra_cf_socket
*cf
;
98 cf
= container_of(s
, struct electra_cf_socket
, socket
);
100 /* NOTE CF is always 3VCARD */
101 if (electra_cf_present(cf
)) {
102 *sp
= SS_READY
| SS_DETECT
| SS_POWERON
| SS_3VCARD
;
104 s
->pci_irq
= cf
->irq
;
110 static int electra_cf_set_socket(struct pcmcia_socket
*sock
,
111 struct socket_state_t
*s
)
115 struct electra_cf_socket
*cf
;
117 cf
= container_of(sock
, struct electra_cf_socket
, socket
);
119 /* "reset" means no power in our case */
120 vcc
= (s
->flags
& SS_RESET
) ? 0 : s
->Vcc
;
127 gpio
= (1 << cf
->gpio_3v
);
130 gpio
= (1 << cf
->gpio_5v
);
136 gpio
|= 1 << (cf
->gpio_3v
+ 16); /* enwr */
137 gpio
|= 1 << (cf
->gpio_5v
+ 16); /* enwr */
138 out_le32(cf
->gpio_base
+0x90, gpio
);
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
);
146 static int electra_cf_set_io_map(struct pcmcia_socket
*s
,
147 struct pccard_io_map
*io
)
152 static int electra_cf_set_mem_map(struct pcmcia_socket
*s
,
153 struct pccard_mem_map
*map
)
155 struct electra_cf_socket
*cf
;
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;
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
,
175 static int electra_cf_probe(struct platform_device
*ofdev
)
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
= -ENOMEM
;
182 const unsigned int *prop
;
185 err
= of_address_to_resource(np
, 0, &mem
);
189 err
= of_address_to_resource(np
, 1, &io
);
193 cf
= kzalloc(sizeof(*cf
), GFP_KERNEL
);
197 timer_setup(&cf
->timer
, electra_cf_timer
, 0);
201 cf
->mem_phys
= mem
.start
;
202 cf
->mem_size
= PAGE_ALIGN(resource_size(&mem
));
203 cf
->mem_base
= ioremap(cf
->mem_phys
, cf
->mem_size
);
206 cf
->io_size
= PAGE_ALIGN(resource_size(&io
));
207 cf
->io_virt
= ioremap_phb(io
.start
, cf
->io_size
);
211 cf
->gpio_base
= ioremap(0xfc103000, 0x1000);
214 dev_set_drvdata(device
, cf
);
216 cf
->io_base
= (unsigned long)cf
->io_virt
- VMALLOC_END
;
217 cf
->iomem
.start
= (unsigned long)cf
->mem_base
;
218 cf
->iomem
.end
= (unsigned long)cf
->mem_base
+ (mem
.end
- mem
.start
);
219 cf
->iomem
.flags
= IORESOURCE_MEM
;
221 cf
->irq
= irq_of_parse_and_map(np
, 0);
223 status
= request_irq(cf
->irq
, electra_cf_irq
, IRQF_SHARED
,
226 dev_err(device
, "request_irq failed\n");
230 cf
->socket
.pci_irq
= cf
->irq
;
234 prop
= of_get_property(np
, "card-detect-gpio", NULL
);
237 cf
->gpio_detect
= *prop
;
239 prop
= of_get_property(np
, "card-vsense-gpio", NULL
);
242 cf
->gpio_vsense
= *prop
;
244 prop
= of_get_property(np
, "card-3v-gpio", NULL
);
249 prop
= of_get_property(np
, "card-5v-gpio", NULL
);
254 cf
->socket
.io_offset
= cf
->io_base
;
256 /* reserve chip-select regions */
257 if (!request_mem_region(cf
->mem_phys
, cf
->mem_size
, driver_name
)) {
259 dev_err(device
, "Can't claim memory region\n");
263 if (!request_region(cf
->io_base
, cf
->io_size
, driver_name
)) {
265 dev_err(device
, "Can't claim I/O region\n");
269 cf
->socket
.owner
= THIS_MODULE
;
270 cf
->socket
.dev
.parent
= &ofdev
->dev
;
271 cf
->socket
.ops
= &electra_cf_ops
;
272 cf
->socket
.resource_ops
= &pccard_static_ops
;
273 cf
->socket
.features
= SS_CAP_PCCARD
| SS_CAP_STATIC_MAP
|
275 cf
->socket
.map_size
= 0x800;
277 status
= pcmcia_register_socket(&cf
->socket
);
279 dev_err(device
, "pcmcia_register_socket failed\n");
283 dev_info(device
, "at mem 0x%lx io 0x%llx irq %d\n",
284 cf
->mem_phys
, io
.start
, cf
->irq
);
287 electra_cf_timer(&cf
->timer
);
291 release_region(cf
->io_base
, cf
->io_size
);
293 release_mem_region(cf
->mem_phys
, cf
->mem_size
);
296 free_irq(cf
->irq
, cf
);
298 iounmap(cf
->gpio_base
);
300 device_init_wakeup(&ofdev
->dev
, 0);
301 iounmap(cf
->io_virt
);
303 iounmap(cf
->mem_base
);
310 static void electra_cf_remove(struct platform_device
*ofdev
)
312 struct device
*device
= &ofdev
->dev
;
313 struct electra_cf_socket
*cf
;
315 cf
= dev_get_drvdata(device
);
318 pcmcia_unregister_socket(&cf
->socket
);
319 free_irq(cf
->irq
, cf
);
320 timer_shutdown_sync(&cf
->timer
);
322 iounmap(cf
->io_virt
);
323 iounmap(cf
->mem_base
);
324 iounmap(cf
->gpio_base
);
325 release_mem_region(cf
->mem_phys
, cf
->mem_size
);
326 release_region(cf
->io_base
, cf
->io_size
);
331 static const struct of_device_id electra_cf_match
[] = {
333 .compatible
= "electra-cf",
337 MODULE_DEVICE_TABLE(of
, electra_cf_match
);
339 static struct platform_driver electra_cf_driver
= {
342 .of_match_table
= electra_cf_match
,
344 .probe
= electra_cf_probe
,
345 .remove_new
= electra_cf_remove
,
348 module_platform_driver(electra_cf_driver
);
350 MODULE_LICENSE("GPL");
351 MODULE_AUTHOR("Olof Johansson <olof@lixom.net>");
352 MODULE_DESCRIPTION("PA Semi Electra CF driver");