pcmcia: CompactFlash driver for PA Semi Electra boards
PATCH 1/1 pcmcia: CompactFlash driver for PA Semi Electra boards
Driver for the CompactFlash slot on the PA Semi Electra eval board. It's a simple device sitting on localbus, with interrupts and detect/voltage control over GPIO.
The driver is implemented as an of_platform driver, and adds localbus as a bus being probed by the of_platform framework.
---
Fixed the comments from Russell on last post, this should be good to merge now.
drivers/pcmcia/Kconfig +7 -0
@@ -270,6 +270,13 @@ config AT91_CF Say Y here to support the CompactFlash controller on AT91 chips. Or choose M to compile the driver as a module named "at91_cf". +config ELECTRA_CF + bool "Electra CompactFlash Controller" + depends on PCMCIA=y && PPC_PASEMI + help + Say Y here to support the CompactFlash controller on the + PA Semi Electra eval board. + config PCCARD_NONSTATIC tristate
drivers/pcmcia/Makefile +1 -0
@@ -37,6 +37,7 @@ obj-$(CONFIG_PCMCIA_VRC4171) += vrc417 obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o obj-$(CONFIG_OMAP_CF) += omap_cf.o obj-$(CONFIG_AT91_CF) += at91_cf.o +obj-$(CONFIG_ELECTRA_CF) += electra_cf.o sa11xx_core-y += soc_common.o sa11xx_base.o pxa2xx_core-y += soc_common.o pxa2xx_base.o
drivers/pcmcia/electra_cf.c new file +382 -0
382 lines not on this page · raw message
arch/powerpc/platforms/pasemi/setup.c +1 -0
@@ -205,6 +205,7 @@ static void __init pas_init_early(void) }static struct of_device_id pasemi_bus_ids[] = { + { .type ="localbus" , }, { .type ="sdc" , }, {}, };
Quoted 6 lines
drivers/pcmcia/electra_cf.c new file +6
-0+static int bus_notify (struct notifier_block *nb,unsigned long action, +void *data) +{ +struct device *dev = data; + +printk ("bus notify called\n" );
drivers/pcmcia/electra_cf.c line 343
Quoted 10 lines
drivers/pcmcia/electra_cf.c new file +10
-0+ +/* We are only intereted in device addition */ +if (action !=BUS_NOTIFY_ADD_DEVICE ) +return 0 ; + +/* We use the direct ops for localbus */ + dev->archdata.dma_ops = &dma_direct_ops; + +return 0 ; +}
Sorry for not coming back to you after the last posting of the patch, but I still really this bit of the code. We don't set dma ops from a driver anywhere else in the tree, so I'd really prefer if you could handle this in architecture code somewhere. Especially as dma_direct_ops and the pcmcia_bug_type shouldn't really be something exported to users.
Also this code is unlogic if not buggy. Just because you have one electra bridge it doesn't mean all pcmcia is driven by it. In fact I'm pretty sure there are cardbus/pcmcia bridges that can be plugged into plain pci slots.
Quoted 23 lines · Christoph Hellwig
Quoted 6 lines
drivers/pcmcia/electra_cf.c new file +6
-0+static int bus_notify (struct notifier_block *nb,unsigned long action, +void *data) +{ +struct device *dev = data; + +printk ("bus notify called\n" );drivers/pcmcia/electra_cf.c line 343
Quoted 10 lines
drivers/pcmcia/electra_cf.c new file +10
-0+ +/* We are only intereted in device addition */ +if (action !=BUS_NOTIFY_ADD_DEVICE ) +return 0 ; + +/* We use the direct ops for localbus */ + dev->archdata.dma_ops = &dma_direct_ops; + +return 0 ; +}Sorry for not coming back to you after the last posting of the patch, but I still really this bit of the code. We don't set dma ops from a driver anywhere else in the tree, so I'd really prefer if you could handle this in architecture code somewhere. Especially as
dma_direct_opsand thepcmcia_bug_typeshouldn't really be something exported to users.
Quoted 4 lines
Also this code is unlogic if not buggy. Just because you have one electra bridge it doesn't mean all pcmcia is driven by it. In fact I'm pretty sure there are cardbus/pcmcia bridges that can be plugged into plain pci slots.
Yeah, all good points. Also, I obviously missed to take out the debug printk. I'll post an updated patch separately.
Thanks!
-Olof
PATCH v2 1/1 pcmcia: CompactFlash driver for PA Semi Electra boards
In reply to Olof JohanssonDriver for the CompactFlash slot on the PA Semi Electra eval board. It's a simple device sitting on localbus, with interrupts and detect/voltage control over GPIO.
The driver is implemented as an of_platform driver, and adds localbus as a bus being probed by the of_platform framework.
---
Chances since last post:
* Comments from Christoph:
- Moved bus notifier to arch code
- Checking for bus (socket driver) type before changing dma ops
drivers/pcmcia/Kconfig +7 -0
@@ -270,6 +270,13 @@ config AT91_CF Say Y here to support the CompactFlash controller on AT91 chips. Or choose M to compile the driver as a module named "at91_cf". +config ELECTRA_CF + bool "Electra CompactFlash Controller" + depends on PCMCIA=y && PPC_PASEMI + help + Say Y here to support the CompactFlash controller on the + PA Semi Electra eval board. + config PCCARD_NONSTATIC tristate
drivers/pcmcia/Makefile +1 -0
@@ -37,6 +37,7 @@ obj-$(CONFIG_PCMCIA_VRC4171) += vrc417 obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o obj-$(CONFIG_OMAP_CF) += omap_cf.o obj-$(CONFIG_AT91_CF) += at91_cf.o +obj-$(CONFIG_ELECTRA_CF) += electra_cf.o sa11xx_core-y += soc_common.o sa11xx_base.o pxa2xx_core-y += soc_common.o pxa2xx_base.o
drivers/pcmcia/electra_cf.c new file +359 -0
359 lines not on this page · raw message
arch/powerpc/platforms/pasemi/setup.c +42 -0
61 lines not on this page · raw message
Quoted 6 lines · Olof Johansson
Driver for the CompactFlash slot on the PA Semi Electra eval board. It's a simple device sitting on localbus, with interrupts and detect/voltage control over GPIO.
The driver is implemented as an
of_platformdriver, and adds localbus as a bus being probed by theof_platformframework.
Looks good to me. The only odd thing is the inconsistant use of #ifdef CONFIG_PCMCIA in setup.c.
Quoted 10 lines · Christoph Hellwig
Quoted 6 lines · Olof Johansson
Driver for the CompactFlash slot on the PA Semi Electra eval board. It's a simple device sitting on localbus, with interrupts and detect/voltage control over GPIO.
The driver is implemented as an
of_platformdriver, and adds localbus as a bus being probed by theof_platformframework.Looks good to me. The only odd thing is the inconsistant use of #ifdef
CONFIG_PCMCIAinsetup.c.
Thanks, and thanks for the review.
The ifdef is needed since for CONFIG_PCMCIA=n builds, the bus notifier isn't available. I wanted to do the bus notifier registration explicitly before the of_platform bus probe to avoid later surprises due to reordered initcalls in case it was split up in it's own initcall.
I could add the code under ifdef as well, but it didn't seem too critical. Once the second major board comes along I'll probably move it out to a per-board file, there's no real need for it just yet.
-Olof
PATCH v3 1/1 pcmcia: CompactFlash driver for PA Semi Electra boards
Driver for the CompactFlash slot on the PA Semi Electra eval board. It's a simple device sitting on localbus, with interrupts and detect/voltage control over GPIO.
The driver is implemented as an of_platform driver, and adds localbus as a bus being probed by the of_platform framework.
---
Quoted 8 lines · olof
The ifdef is needed since for
CONFIG_PCMCIA=nbuilds, the bus notifier isn't available. I wanted to do the bus notifier registration explicitly before theof_platformbus probe to avoid later surprises due to reordered initcalls in case it was split up in it's own initcall.I could add the code under ifdef as well, but it didn't seem too critical. Once the second major board comes along I'll probably move it out to a per-board file, there's no real need for it just yet.
Alright, turns out I still need to declare the extern bus type, which would mean two #ifdefs in one function. Moving it out instead.
I've addressed Milton's comments as well.
Who's maintaining PCMCIA? MAINTAINERS only lists a mailing list, no person. Seems weird for a component that's marked as maintained.
drivers/pcmcia/Kconfig +7 -0
@@ -270,6 +270,13 @@ config AT91_CF Say Y here to support the CompactFlash controller on AT91 chips. Or choose M to compile the driver as a module named "at91_cf". +config ELECTRA_CF + bool "Electra CompactFlash Controller" + depends on PCMCIA=y && PPC_PASEMI + help + Say Y here to support the CompactFlash controller on the + PA Semi Electra eval board. + config PCCARD_NONSTATIC tristate
drivers/pcmcia/Makefile +1 -0
@@ -37,6 +37,7 @@ obj-$(CONFIG_PCMCIA_VRC4171) += vrc417 obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o obj-$(CONFIG_OMAP_CF) += omap_cf.o obj-$(CONFIG_AT91_CF) += at91_cf.o +obj-$(CONFIG_ELECTRA_CF) += electra_cf.o sa11xx_core-y += soc_common.o sa11xx_base.o pxa2xx_core-y += soc_common.o pxa2xx_base.o
drivers/pcmcia/electra_cf.c new file +374 -0
374 lines not on this page · raw message
arch/powerpc/platforms/pasemi/setup.c +56 -0
75 lines not on this page · raw message
Quoted 23 lines · On Thu, 5 Jul 2007 09:49:14 -0500 [email protected] (Olof Johansson) wrote:
Driver for the CompactFlash slot on the PA Semi Electra eval board. It's a simple device sitting on localbus, with interrupts and detect/voltage control over GPIO.
The driver is implemented as an
of_platformdriver, and adds localbus as a bus being probed by theof_platformframework.Signed-off-by Olof Johansson <[email protected]>---
Quoted 8 lines · olof
The ifdef is needed since for
CONFIG_PCMCIA=nbuilds, the bus notifier isn't available. I wanted to do the bus notifier registration explicitly before theof_platformbus probe to avoid later surprises due to reordered initcalls in case it was split up in it's own initcall.I could add the code under ifdef as well, but it didn't seem too critical. Once the second major board comes along I'll probably move it out to a per-board file, there's no real need for it just yet.
Quoted 7 lines
Alright, turns out I still need to declare the extern bus type, which would mean two #ifdefs in one function. Moving it out instead.
I've addressed Milton's comments as well.
Who's maintaining PCMCIA?
MAINTAINERSonly lists a mailing list, no person. Seems weird for a component that's marked as maintained.
Dominik Brodowski. He's having a bit of downtime at present (exams, I think). He expects to return. Meanwhile, cc'ing me usually has some effect.
Quoted 4 lines
...
(quoted diff) +1
-0+static const char driver_name[] = "electra-cf";
Review
Quoted 10 lines
(quoted diff) +7
-0+static struct of_device_id electra_cf_match[] = +{ + { + .compatible = "electra-cf", + }, + {}, +};
Could have reused driver_name[] here, if that was appropriate.
Review
Quoted 3 lines
(quoted diff) +3
-0+static struct of_platform_driver electra_cf_driver = +{ + .name = (char *)driver_name,
ug. But it's not your fault - we should have always made it const.
arch/powerpc/platforms/pasemi/setup.c
Quoted 2 lines
arch/powerpc/platforms/pasemi/setup.c +0
-0
I never know who maintains random-scruffy-ppc code like this. From a peek in the git-whatchanged output, it appears to be yourself.
Have a few little fixies:
drivers/pcmcia/electra_cf.c renamed from drivers/pcmcia/electra_cf.c~pcmcia-compactflash-driver-for-pa-semi-electra-boards-fix +3 -8
@@ -201,9 +201,7 @@ static int __devinit electra_cf_probe(stif (!cf)return -ENOMEM ; -init_timer (&cf->timer); - cf->timer.function = electra_cf_timer; - cf->timer.data = (unsigned long ) cf; +setup_timer (&cf->timer, electra_cf_timer, (unsigned long )cf); cf->irq =NO_IRQ ; cf->ofdev = ofdev;
@@ -340,16 +338,14 @@ static int __devexit electra_cf_remove(sreturn 0 ; } -static struct of_device_id electra_cf_match[] = -{ +static struct of_device_id electra_cf_match[] = { { .compatible ="electra-cf" , }, {}, }; -static struct of_platform_driver electra_cf_driver = -{ +static struct of_platform_driver electra_cf_driver = { .name = (char *)driver_name, .match_table = electra_cf_match, .probe = electra_cf_probe,
@@ -371,4 +367,3 @@ module_exit(electra_cf_exit);MODULE_LICENSE ("GPL" );MODULE_AUTHOR ("Olof Johansson <[email protected]>" );MODULE_DESCRIPTION ("PA Semi Electra CF driver" ); -
_
Olof Johansson
Acked-byQuoted 6 lines · Andrew Morton
Quoted 2 lines
Who's maintaining PCMCIA?
MAINTAINERSonly lists a mailing list, no person. Seems weird for a component that's marked as maintained.Dominik Brodowski. He's having a bit of downtime at present (exams, I think). He expects to return. Meanwhile, cc'ing me usually has some effect.
Thanks!
Quoted 4 lines
Quoted 4 lines
+static const char driver_name[] = "electra-cf";
...
Quoted 9 lines
Review
Quoted 7 lines
(quoted diff) +7
-0+static struct of_device_id electra_cf_match[] = +{ + { + .compatible = "electra-cf", + }, + {}, +};Could have reused driver_name[] here, if that was appropriate.
Driver name and device tree compatible field is not neccessarily the same, even though they do coincide here.
Quoted 5 lines
arch/powerpc/platforms/pasemi/setup.c
Quoted 2 lines
arch/powerpc/platforms/pasemi/setup.c +0
-0I never know who maintains random-scruffy-ppc code like this. From a peek in the git-whatchanged output, it appears to be yourself.
Check the top of the file. :) (Kumar started doing that, I kept it up, seems useful). And yes, we do tend to have per-platform maintainers on ppc.
Quoted 1 line
Have a few little fixies:
Thanks!
Quoted 2 lines
drivers/pcmcia/electra_cf.c renamed from drivers/pcmcia/electra_cf.c~pcmcia-compactflash-driver-for-pa-semi-electra-boards-fix +0
-0
[...]
PATCH 1/1 pcmcia: Updates to electra_cf driver
In reply to Olof JohanssonFix build of electra_cf, since the IO space setup interfaces were changed when BenH rewrote it.
Also clean it up a bit, add 5V support, make it unloadable, remove some dead variables, etc.
---
Andrew,
I did this as an incremental patch that you can just merge into the base one that's already in -mm, but I could merge and resubmit the base patch instead if you prefer.
(The base patch is pcmcia-compactflash-driver-for-pa-semi-electra-boards.patch)
-Olof
drivers/pcmcia/electra_cf.c +23 -15
@@ -28,6 +28,7 @@#include <linux/init.h> #include <linux/delay.h> #include <linux/interrupt.h> +#include <linux/vmalloc.h> #include <pcmcia/ss.h> #include <asm/of_platform.h>
@@ -105,10 +106,8 @@ static int electra_cf_get_status(struct/* NOTE CF is always 3VCARD */ if (electra_cf_present (cf)) { -struct electra_cf_socket *cf; - *sp =SS_READY |SS_DETECT |SS_POWERON |SS_3VCARD ; - cf = container_of(s, struct electra_cf_socket, socket); + s->pci_irq = cf->irq; }else *sp =0 ;
@@ -134,8 +133,10 @@ static int electra_cf_set_socket(structcase 33 : gpio = (1 << cf->gpio_3v);break ; +case 5 : + gpio = (1 << cf->gpio_5v); +break ;default : -/* CF is 3.3V only */ return -EINVAL ; }
@@ -188,6 +189,7 @@ static int __devinit electra_cf_probe(stint status;const unsigned int *prop;int err; +struct vm_struct *area; err =of_address_to_resource (np,0 , &mem);if (err)
@@ -206,22 +208,27 @@ static int __devinit electra_cf_probe(st cf->ofdev = ofdev; cf->mem_phys = mem.start; - cf->mem_base =ioremap (mem.start, mem.end - mem.start); + cf->mem_size =PAGE_ALIGN (mem.end - mem.start); + cf->mem_base =ioremap (cf->mem_phys, cf->mem_size); cf->io_size =PAGE_ALIGN (io.end - io.start); - cf->io_virt =reserve_phb_iospace (cf->io_size); + area =__get_vm_area (cf->io_size,0 ,PHB_IO_BASE ,PHB_IO_END ); +if (area ==NULL ) +return -ENOMEM ; + + cf->io_virt = (void __iomem *)(area->addr); cf->gpio_base =ioremap (0xfc103000 ,0x1000 );dev_set_drvdata (device, cf); -if (!cf->mem_base || !cf->io_virt || !cf->gpio_base) { +if (!cf->mem_base || !cf->io_virt || !cf->gpio_base || + (__ioremap_at (io.start, cf->io_virt, cf->io_size, + _PAGE_NO_CACHE | _PAGE_GUARDED) ==NULL )) {dev_err (device,"can't ioremap ranges\n" ); status = -ENOMEM ; goto fail1; } -__ioremap_explicit (io.start, (unsigned long )cf->io_virt, cf->io_size, - _PAGE_NO_CACHE | _PAGE_GUARDED); cf->io_base = (unsigned long )cf->io_virt -VMALLOC_END ;
@@ -263,8 +270,7 @@ static int __devinit electra_cf_probe(st cf->socket.io_offset = cf->io_base;/* reserve chip-select regions */ -if (!request_mem_region (mem.start, mem.end +1 - mem.start, - driver_name)) { +if (!request_mem_region (cf->mem_phys, cf->mem_size, driver_name)) { status = -ENXIO ;dev_err (device,"Can't claim memory region\n" ); goto fail1;
@@ -291,21 +297,22 @@ static int __devinit electra_cf_probe(st }dev_info (device,"at mem 0x%lx io 0x%lx irq %d\n" , - mem.start, io.start, cf->irq); + cf->mem_phys, io.start, cf->irq); cf->active =1 ;electra_cf_timer ((unsigned long )cf);return 0 ; fail3: -release_mem_region (io.start, io.end +1 - io.start); +release_region (cf->io_base, cf->io_size); fail2: -release_mem_region (mem.start, mem.end +1 - mem.start); +release_mem_region (cf->mem_phys, cf->mem_size); fail1:if (cf->irq !=NO_IRQ )free_irq (cf->irq, cf); -/* XXX No way to undo the ioremap_explicit at this time */ +if (cf->io_virt) +__iounmap_at (cf->io_virt, cf->io_size);if (cf->mem_base)iounmap (cf->mem_base);if (cf->gpio_base)
@@ -328,6 +335,7 @@ static int __devexit electra_cf_remove(sfree_irq (cf->irq, cf);del_timer_sync (&cf->timer); +__iounmap_at (cf->io_virt, cf->io_size);iounmap (cf->mem_base);iounmap (cf->gpio_base);release_mem_region (cf->mem_phys, cf->mem_size);
drivers/pcmcia/Kconfig +2 -2
@@ -272,8 +272,8 @@ config AT91_CF Or choose M to compile the driver as a module named "at91_cf". config ELECTRA_CF - bool "Electra CompactFlash Controller" - depends on PCMCIA=y && PPC_PASEMI + tristate "Electra CompactFlash Controller" + depends on PCMCIA && PPC_PASEMI help Say Y here to support the CompactFlash controller on the PA Semi Electra eval board.
Quoted 9 lines · Christoph Hellwig
Quoted 8 lines · Olof Johansson
Quoted 6 lines
Driver for the CompactFlash slot on the PA Semi Electra eval board. It's a simple device sitting on localbus, with interrupts and detect/voltage control over GPIO.
The driver is implemented as an
of_platformdriver, and adds localbus as a bus being probed by theof_platformframework.
Quoted 7 lines
Quoted 2 lines
Looks good to me. The only odd thing is the inconsistant use of #ifdef
CONFIG_PCMCIAinsetup.c.The ifdef is needed since for
CONFIG_PCMCIA=nbuilds, the bus notifier isn't available. I wanted to do the bus notifier registration explicitly before theof_platformbus probe to avoid later surprises due to reordered initcalls in case it was split up in it's own initcall.
If CONFIG_PCMCIA=m then your notifier is not registered. The modprobe of your of_driver loads ds.ko, registers the bus, then registers your driver. When the socket driver tries to dma, the BUG in dma_64 for no archdata.dma_ops triggers.
It seems like we need
(1) a notifier that a bus is registered, run before allowing any devices, so that platforms can register bus notifiers by bus name before the devices and drivers are registered.
(2) a powerpc64 generic pcmcia bus notifier that copys the dma ops from the parent socket.
(3) something to set the dma_ops to direct_dma_ops on the of device.
If we don't want (3) to be in the driver (as Christoph previosly mentioned), then it needs to be a seperate bus that reuses the of matching. This would be similar to how ibmebus is setup. If I remember the discussion, ibmebus is to provide the alternate dma ops and steals match etc code from the of_platform bus type.
Oh, is this why you have depends on PCMCIA=y ?
Quoted 3 lines
I could add the code under ifdef as well, but it didn't seem too critical. Once the second major board comes along I'll probably move it out to a per-board file, there's no real need for it just yet.
milton
Quoted 16 lines · Milton Miller
If
CONFIG_PCMCIA=mthen your notifier is not registered. The modprobe of yourof_driverloads ds.ko, registers the bus, then registers your driver. When the socket driver tries to dma, the BUG indma_64for no archdata.dma_ops triggers.It seems like we need
(1) a notifier that a bus is registered, run before allowing any devices, so that platforms can register bus notifiers by bus name before the devices and drivers are registered.
(2) a powerpc64 generic pcmcia bus notifier that copys the dma ops from the parent socket.
(3) something to set the
dma_opstodirect_dma_opson the of device.
Quoted 8 lines
If we don't want (3) to be in the driver (as Christoph previosly mentioned), then it needs to be a seperate bus that reuses the of
matching. This would be similar to how ibmebus is setup. If I
remember the discussion, ibmebus is to provide the alternate dma ops and steals match etc code from theof_platformbus type.Oh, is this why you have depends on PCMCIA=y ?
Yes.
-Olof
Hi Olof.
Quoted 6 lines · Olof Johansson
Driver for the CompactFlash slot on the PA Semi Electra eval board. It's a simple device sitting on localbus, with interrupts and detect/voltage control over GPIO.
The driver is implemented as an
of_platformdriver, and adds localbus as a bus being probed by theof_platformframework.
...
Quoted 65 lines
drivers/pcmcia/electra_cf.c new file +45
-0+ +static int __devinit electra_cf_probe (struct of_device *ofdev, +const struct of_device_id *match) +{ +struct device *device = &ofdev->dev; +struct device_node *np = ofdev->node; +struct electra_cf_socket *cf; +struct resource mem, io; +int status; +const unsigned int *prop; +int err; + + err =of_address_to_resource (np,0 , &mem); +if (err) +return -EINVAL ; + + err =of_address_to_resource (np,1 , &io); +if (err) +return -EINVAL ; + + cf =kzalloc (sizeof *cf,GFP_KERNEL ); +if (!cf) +return -ENOMEM ; + +init_timer (&cf->timer); + cf->timer.function = electra_cf_timer; + cf->timer.data = (unsigned long ) cf; + + cf->ofdev = ofdev; + cf->mem_phys = mem.start; + cf->mem_base =ioremap (mem.start, mem.end - mem.start); + cf->io_size =PAGE_ALIGN (io.end - io.start); + + cf->io_virt =reserve_phb_iospace (cf->io_size); + + cf->gpio_base =ioremap (0xfc103000 ,0x1000 ); +dev_set_drvdata (device, cf); + +if (!cf->mem_base || !cf->io_virt || !cf->gpio_base) { +dev_err (device,"can't ioremap ranges\n" ); + status = -ENOMEM ; + goto fail1; + } + + __ioremap_explicit(io.start, (unsigned long)cf->io_virt,
cf->io_size,drivers/pcmcia/electra_cf.c new file +6
-0+ _PAGE_NO_CACHE | _PAGE_GUARDED); + + cf->io_base = (unsigned long )cf->io_virt -VMALLOC_END ; + + cf->iomem.start = (unsigned long )cf->mem_base; + cf->iomem.end = (unsigned long)cf->mem_base + (mem.end -mem.start);
drivers/pcmcia/electra_cf.c new file +12
-0+ cf->iomem.flags =IORESOURCE_MEM ; + + cf->irq =irq_of_parse_and_map (np,0 ); + + status =request_irq (cf->irq, electra_cf_irq,IRQF_SHARED , + driver_name, cf); +if (status <0 ) { +dev_err (device,"request_irq failed\n" ); + goto fail1; + } + + cf->socket.pci_irq = cf->irq;
drivers/pcmcia/electra_cf.c line 252
Quoted 10 lines
drivers/pcmcia/electra_cf.c new file +10
-0+ + prop =get_property (np,"card-detect-gpio" ,NULL ); + cf->gpio_detect = *prop; + prop =get_property (np,"card-vsense-gpio" ,NULL ); + cf->gpio_vsense = *prop; + prop =get_property (np,"card-3v-gpio" ,NULL ); + cf->gpio_3v = *prop; + prop =get_property (np,"card-5v-gpio" ,NULL ); + cf->gpio_5v = *prop; +
get_property is now a #define for of_get_property. I think the use of get_property is being deprecated.
If of_get_property fails to find the property, then you will dereference a NULL pointer in a probe function and will leave the bus_type locked.
Quoted 33 lines
drivers/pcmcia/electra_cf.c new file +33
-0+ cf->socket.io_offset = cf->io_base; + +/* reserve chip-select regions */ +if (!request_mem_region (mem.start, mem.end +1 - mem.start, + driver_name)) { + status = -ENXIO ; +dev_err (device,"Can't claim memory region\n" ); + goto fail1; + } + +if (!request_region (cf->io_base, cf->io_size, driver_name)) { + status = -ENXIO ; +dev_err (device,"Can't claim I/O region\n" ); + goto fail2; + } + + cf->socket.owner =THIS_MODULE ; + cf->socket.dev.parent = &ofdev->dev; + cf->socket.ops = &electra_cf_ops; + cf->socket.resource_ops = &pccard_static_ops; + cf->socket.features =SS_CAP_PCCARD |SS_CAP_STATIC_MAP | +SS_CAP_MEM_ALIGN ; + cf->socket.map_size =0x800 ; + + status =pcmcia_register_socket (&cf->socket); +if (status <0 ) { +dev_err (device,"pcmcia_register_socket failed\n" ); + goto fail3; + } + +dev_info (device,"at mem 0x%lx io 0x%lx irq %d\n" , + mem.start, io.start, cf->irq); +
drivers/pcmcia/electra_cf.c line 295
Quoted 10 lines
drivers/pcmcia/electra_cf.c new file +10
-0+ cf->active =1 ; +electra_cf_timer ((unsigned long )cf); +return 0 ; + +fail3: +release_mem_region (io.start, io.end +1 - io.start); +fail2: +release_mem_region (mem.start, mem.end +1 - mem.start); +fail1: +/* XXX No way to undo the io reservation at this time */
What io reservation is this comment referring to?
Where is the request_irq undone?
Quoted 18 lines
drivers/pcmcia/electra_cf.c new file +17
-0+if (cf->mem_base) +iounmap (cf->mem_base); +if (cf->gpio_base) +iounmap (cf->gpio_base); +device_init_wakeup (&ofdev->dev,0 ); +kfree (cf); +return status; + +} + +static int __devexit electra_cf_remove(struct of_device *ofdev) +{ +struct device *device = &ofdev->dev; +struct electra_cf_socket *cf; + + cf =dev_get_drvdata (device); +
drivers/pcmcia/electra_cf.c line 322
Quoted 10 lines
drivers/pcmcia/electra_cf.c new file +10
-0+ cf->active =0 ; +pcmcia_unregister_socket (&cf->socket); +free_irq (cf->irq, cf); +del_timer_sync (&cf->timer); + +iounmap (cf->mem_base); +iounmap (cf->gpio_base); +release_mem_region (cf->mem_phys, cf->mem_size); +release_region (cf->io_base, cf->io_size); +
irq_request?
Quoted 9 lines
drivers/pcmcia/electra_cf.c new file +9
-0+kfree (cf); + +return 0 ; +} + +static int bus_notify (struct notifier_block *nb,unsigned long action, +void *data) +{ +struct device *dev = data;
drivers/pcmcia/electra_cf.c line 341
Quoted 10 lines
drivers/pcmcia/electra_cf.c new file +10
-0+ +printk ("bus notify called\n" ); + +/* We are only intereted in device addition */ +if (action !=BUS_NOTIFY_ADD_DEVICE ) +return 0 ; + +/* We use the direct ops for localbus */ + dev->archdata.dma_ops = &dma_direct_ops; +
I'm also replying to your reply to hch's reply. Is that enough of a reply? :-)
Quoted 24 lines
drivers/pcmcia/electra_cf.c new file +24
-0+return 0 ; +} + +static struct notifier_block bus_notifier = { + .notifier_call = bus_notify, +}; + +static struct of_device_id electra_cf_match[] = +{ + { + .compatible ="electra-cf" , + }, + {}, +}; + +static struct of_platform_driver electra_cf_driver = +{ + .name = (char *)driver_name, + .match_table = electra_cf_match, + .probe = electra_cf_probe, + .remove = electra_cf_remove, +}; + +static int __init electra_cf_init (void )
drivers/pcmcia/electra_cf.c line 375
Quoted 10 lines
drivers/pcmcia/electra_cf.c new file +10
-0+{ +bus_register_notifier (&pcmcia_bus_type, &bus_notifier); +return of_register_platform_driver (&electra_cf_driver); +} +module_init (electra_cf_init); + +static void __exit electra_cf_exit(void) +{ +bus_unregister_notifier (&pcmcia_bus_type, &bus_notifier); +of_unregister_platform_driver (&electra_cf_driver);
Should these be reversed? (if we keep it here)
drivers/pcmcia/electra_cf.c line 382
Quoted 7 lines
drivers/pcmcia/electra_cf.c new file +7
-0+} +module_exit (electra_cf_exit); + +MODULE_LICENSE ("GPL" ); +MODULE_AUTHOR ("Olof Johansson <olof at lixom.net>" ); +MODULE_DESCRIPTION ("PA Semi Electra CF driver" ); +
cheers,
milton
Quoted 2 lines · Milton Miller
get_propertyis now a #define forof_get_property. I think the use ofget_propertyis being deprecated.
Yeah, it's a pita. I've moved these over now.
Quoted 3 lines
If
of_get_propertyfails to find the property, then you will dereference a NULL pointer in a probe function and will leave thebus_typelocked.
Fixed.
Quoted 3 lines
Quoted 1 line
+ /* XXX No way to undo the io reservation at this time */
What io reservation is this comment referring to?
ioremap_explicit. I've updated the comment.
Quoted 1 line
Where is the
request_irqundone?
Fixed.
Quoted 12 lines
Quoted 12 lines
drivers/pcmcia/electra_cf.c new file +12
-0+static int __devexit electra_cf_remove(struct of_device *ofdev) +{ +struct device *device = &ofdev->dev; +struct electra_cf_socket *cf; + + cf =dev_get_drvdata (device); + + cf->active =0 ; +pcmcia_unregister_socket (&cf->socket); +free_irq (cf->irq, cf); +del_timer_sync (&cf->timer); +
Quoted 8 lines
drivers/pcmcia/electra_cf.c line 322
Quoted 6 lines
drivers/pcmcia/electra_cf.c new file +5
-0+iounmap (cf->mem_base); +iounmap (cf->gpio_base); +release_mem_region (cf->mem_phys, cf->mem_size); +release_region (cf->io_base, cf->io_size); +
irq_request?
Huh?
-Olof