Convert the driver to standard spilt model arch-specific code registers
platform device to which driver code can bind later.
Also request IRQ immediately upon binding to the device instead of doing
this when serio port is being opened.
Signed-off-by: Dmitry Torokhov <redacted>
---
Not tested as I don't have the hardware...
arch/m68k/q40/config.c | 12 ++++
drivers/input/serio/q40kbd.c | 134 ++++++++++++++++++++++++------------------
2 files changed, 87 insertions(+), 59 deletions(-)
@@ -92,12 +103,9 @@ static void q40kbd_flush(void)staticintq40kbd_open(structserio*port){-q40kbd_flush();+structq40kbd*q40kbd=port->port_data;-if(request_irq(Q40_IRQ_KEYBOARD,q40kbd_interrupt,0,"q40kbd",NULL)){-printk(KERN_ERR"q40kbd.c: Can't get irq %d.\n",Q40_IRQ_KEYBOARD);-return-EBUSY;-}+q40kbd_flush(q40kbd);/* off we go */master_outb(-1,KEYBOARD_UNLOCK_REG);
@@ -108,35 +116,68 @@ static int q40kbd_open(struct serio *port)staticvoidq40kbd_close(structserio*port){-master_outb(0,KEY_IRQ_ENABLE_REG);-master_outb(-1,KEYBOARD_UNLOCK_REG);-free_irq(Q40_IRQ_KEYBOARD,NULL);+structq40kbd*q40kbd=port->port_data;-q40kbd_flush();+q40kbd_stop(q40kbd);+q40kbd_flush(q40kbd);}-staticint__devinitq40kbd_probe(structplatform_device*dev)+staticint__devinitq40kbd_probe(structplatform_device*pdev){-q40kbd_port=kzalloc(sizeof(structserio),GFP_KERNEL);-if(!q40kbd_port)-return-ENOMEM;--q40kbd_port->id.type=SERIO_8042;-q40kbd_port->open=q40kbd_open;-q40kbd_port->close=q40kbd_close;-q40kbd_port->dev.parent=&dev->dev;-strlcpy(q40kbd_port->name,"Q40 Kbd Port",sizeof(q40kbd_port->name));-strlcpy(q40kbd_port->phys,"Q40",sizeof(q40kbd_port->phys));--serio_register_port(q40kbd_port);+structq40kbd*q40kbd;+structserio*port;+interror;++q40kbd=kzalloc(sizeof(structq40kbd),GFP_KERNEL);+port=kzalloc(sizeof(structserio),GFP_KERNEL);+if(!q40kbd||!port){+error=-ENOMEM;+gotoerr_free_mem;+}++q40kbd->port=port;+spin_lock_init(&q40kbd->lock);++port->id.type=SERIO_8042;+port->open=q40kbd_open;+port->close=q40kbd_close;+port->port_data=q40kbd;+port->dev.parent=&pdev->dev;+strlcpy(port->name,"Q40 Kbd Port",sizeof(port->name));+strlcpy(port->phys,"Q40",sizeof(port->phys));++q40kbd_stop(q40kbd);++error=request_irq(Q40_IRQ_KEYBOARD,q40kbd_interrupt,0,+DRV_NAME,q40kbd);+if(error){+dev_err(&pdev->dev,"Can't get irq %d.\n",Q40_IRQ_KEYBOARD);+gotoerr_free_mem;+}++serio_register_port(q40kbd->port);++platform_set_drvdata(pdev,q40kbd);printk(KERN_INFO"serio: Q40 kbd registered\n");return0;++err_free_mem:+kfree(port);+kfree(q40kbd);+returnerror;}-staticint__devexitq40kbd_remove(structplatform_device*dev)+staticint__devexitq40kbd_remove(structplatform_device*pdev){-serio_unregister_port(q40kbd_port);+structq40kbd*q40kbd=platform_get_drvdata(pdev);++free_irq(Q40_IRQ_KEYBOARD,q40kbd);++serio_unregister_port(q40kbd->port);+kfree(q40kbd);++platform_set_drvdata(pdev,NULL);return0;}
On Fri, Dec 30, 2011 at 05:11:11PM -0800, Dmitry Torokhov wrote:
Convert the driver to standard spilt model arch-specific code registers
platform device to which driver code can bind later.
Also request IRQ immediately upon binding to the device instead of doing
this when serio port is being opened.
Signed-off-by: Dmitry Torokhov <redacted>
---
Not tested as I don't have the hardware...
If anyone could give this patch a spin it would be most appreciated.
Thanks!
@@ -92,12 +103,9 @@ static void q40kbd_flush(void)staticintq40kbd_open(structserio*port){-q40kbd_flush();+structq40kbd*q40kbd=port->port_data;-if(request_irq(Q40_IRQ_KEYBOARD,q40kbd_interrupt,0,"q40kbd",NULL)){-printk(KERN_ERR"q40kbd.c: Can't get irq %d.\n",Q40_IRQ_KEYBOARD);-return-EBUSY;-}+q40kbd_flush(q40kbd);/* off we go */master_outb(-1,KEYBOARD_UNLOCK_REG);
@@ -108,35 +116,68 @@ static int q40kbd_open(struct serio *port)staticvoidq40kbd_close(structserio*port){-master_outb(0,KEY_IRQ_ENABLE_REG);-master_outb(-1,KEYBOARD_UNLOCK_REG);-free_irq(Q40_IRQ_KEYBOARD,NULL);+structq40kbd*q40kbd=port->port_data;-q40kbd_flush();+q40kbd_stop(q40kbd);+q40kbd_flush(q40kbd);}-staticint__devinitq40kbd_probe(structplatform_device*dev)+staticint__devinitq40kbd_probe(structplatform_device*pdev){-q40kbd_port=kzalloc(sizeof(structserio),GFP_KERNEL);-if(!q40kbd_port)-return-ENOMEM;--q40kbd_port->id.type=SERIO_8042;-q40kbd_port->open=q40kbd_open;-q40kbd_port->close=q40kbd_close;-q40kbd_port->dev.parent=&dev->dev;-strlcpy(q40kbd_port->name,"Q40 Kbd Port",sizeof(q40kbd_port->name));-strlcpy(q40kbd_port->phys,"Q40",sizeof(q40kbd_port->phys));--serio_register_port(q40kbd_port);+structq40kbd*q40kbd;+structserio*port;+interror;++q40kbd=kzalloc(sizeof(structq40kbd),GFP_KERNEL);+port=kzalloc(sizeof(structserio),GFP_KERNEL);+if(!q40kbd||!port){+error=-ENOMEM;+gotoerr_free_mem;+}++q40kbd->port=port;+spin_lock_init(&q40kbd->lock);++port->id.type=SERIO_8042;+port->open=q40kbd_open;+port->close=q40kbd_close;+port->port_data=q40kbd;+port->dev.parent=&pdev->dev;+strlcpy(port->name,"Q40 Kbd Port",sizeof(port->name));+strlcpy(port->phys,"Q40",sizeof(port->phys));++q40kbd_stop(q40kbd);++error=request_irq(Q40_IRQ_KEYBOARD,q40kbd_interrupt,0,+DRV_NAME,q40kbd);+if(error){+dev_err(&pdev->dev,"Can't get irq %d.\n",Q40_IRQ_KEYBOARD);+gotoerr_free_mem;+}++serio_register_port(q40kbd->port);++platform_set_drvdata(pdev,q40kbd);printk(KERN_INFO"serio: Q40 kbd registered\n");return0;++err_free_mem:+kfree(port);+kfree(q40kbd);+returnerror;}-staticint__devexitq40kbd_remove(structplatform_device*dev)+staticint__devexitq40kbd_remove(structplatform_device*pdev){-serio_unregister_port(q40kbd_port);+structq40kbd*q40kbd=platform_get_drvdata(pdev);++free_irq(Q40_IRQ_KEYBOARD,q40kbd);++serio_unregister_port(q40kbd->port);+kfree(q40kbd);++platform_set_drvdata(pdev,NULL);return0;}
Hi Dmitry,
On Sat, Dec 31, 2011 at 02:11, Dmitry Torokhov
[off-list ref] wrote:
Convert the driver to standard spilt model arch-specific code registers
platform device to which driver code can bind later.
Also request IRQ immediately upon binding to the device instead of doing
this when serio port is being opened.
Signed-off-by: Dmitry Torokhov <redacted>
---
Not tested as I don't have the hardware...
Unfortunately I also don't have the hardware.
But it compiles. A few comments below.
Thanks, it's a nice cleanup!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Jan 11, 2012 at 08:55:54AM +0100, Geert Uytterhoeven wrote:
Hi Dmitry,
On Sat, Dec 31, 2011 at 02:11, Dmitry Torokhov
[off-list ref] wrote:
quoted
Convert the driver to standard spilt model arch-specific code registers
platform device to which driver code can bind later.
Also request IRQ immediately upon binding to the device instead of doing
this when serio port is being opened.
Signed-off-by: Dmitry Torokhov <redacted>
---
Not tested as I don't have the hardware...
Unfortunately I also don't have the hardware.
But it compiles. A few comments below.
If you would use platform_device_register_simple(), you don't need the
q40_kbd_pdev above, reducing memory consumption on non-Q40 platforms.
Isn't this file only compiled on q40 platforms?
quoted
+}
+arch_initcall(q40_add_kbd_device);
For the Amiga platform drivers, I used device_initcall().
Won't it potentially race with initialization of q40kbd? It looks like
module_initcall is the same as device_initcall() when module is compiled
in. Given that q40kbd uses platform_dveice_probe() losing race might be
fatal.
Thanks for lookign this over.
--
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
If you would use platform_device_register_simple(), you don't need the
q40_kbd_pdev above, reducing memory consumption on non-Q40 platforms.
Isn't this file only compiled on q40 platforms?
No, m68k does support multi-platform kernels.
quoted
quoted
+}
+arch_initcall(q40_add_kbd_device);
For the Amiga platform drivers, I used device_initcall().
Won't it potentially race with initialization of q40kbd? It looks like
module_initcall is the same as device_initcall() when module is compiled
in. Given that q40kbd uses platform_dveice_probe() losing race might be
fatal.
So far I haven't encountered any problems on Amiga.
I'll look into this.
Should the unregister be done before freeing the IRQ, i.e. reverse
order compared to probe?
Unregister will most likely cause memory being freed; you don't want to
chance IRQ firing here.
And in the probe case that can't happen when request_irq() is called?
Can a call to q40kbd_stop() first fix that?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
If you would use platform_device_register_simple(), you don't need the
q40_kbd_pdev above, reducing memory consumption on non-Q40 platforms.
Isn't this file only compiled on q40 platforms?
No, m68k does support multi-platform kernels.
OK, I'll do dynamic platform device allocation.
quoted
quoted
quoted
+}
+arch_initcall(q40_add_kbd_device);
For the Amiga platform drivers, I used device_initcall().
Won't it potentially race with initialization of q40kbd? It looks like
module_initcall is the same as device_initcall() when module is compiled
in. Given that q40kbd uses platform_dveice_probe() losing race might be
fatal.
So far I haven't encountered any problems on Amiga.
I'll look into this.
I guess link order (arch before drivers) saves you here but it is not
very clean.
Should the unregister be done before freeing the IRQ, i.e. reverse
order compared to probe?
Unregister will most likely cause memory being freed; you don't want to
chance IRQ firing here.
And in the probe case that can't happen when request_irq() is called?
We explicitly do q40kbd_stop() before requesting IRQ. Frankly serio
will be stopped by the serio core (via serio->stop() which is
q40kbd_stop()) so freeing IRQ fisrt should be fine, it just was looking
scary. I'll revert the order and add a comment.
Thanks.
--
Dmitry
If you would use platform_device_register_simple(), you don't need the
q40_kbd_pdev above, reducing memory consumption on non-Q40 platforms.
Isn't this file only compiled on q40 platforms?
No, m68k does support multi-platform kernels.
OK, I'll do dynamic platform device allocation.
quoted
quoted
quoted
quoted
+}
+arch_initcall(q40_add_kbd_device);
For the Amiga platform drivers, I used device_initcall().
Won't it potentially race with initialization of q40kbd? It looks like
module_initcall is the same as device_initcall() when module is compiled
in. Given that q40kbd uses platform_dveice_probe() losing race might be
fatal.
So far I haven't encountered any problems on Amiga.
I'll look into this.
I guess link order (arch before drivers) saves you here but it is not
very clean.
Should the unregister be done before freeing the IRQ, i.e. reverse
order compared to probe?
Unregister will most likely cause memory being freed; you don't want to
chance IRQ firing here.
And in the probe case that can't happen when request_irq() is called?
We explicitly do q40kbd_stop() before requesting IRQ. Frankly serio
will be stopped by the serio core (via serio->stop() which is
q40kbd_stop()) so freeing IRQ fisrt should be fine, it just was looking
scary. I'll revert the order and add a comment.
OK, so here it is.
--
Dmitry
Input: q40kbd - convert driver to the split model
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Convert the driver to standard spilt model arch-specific code registers
platform device to which driver code can bind later.
Also request IRQ immediately upon binding to the device instead of doing
this when serio port is being opened.
Signed-off-by: Dmitry Torokhov <redacted>
---
arch/m68k/q40/config.c | 7 ++
drivers/input/serio/q40kbd.c | 139 ++++++++++++++++++++++++------------------
2 files changed, 86 insertions(+), 60 deletions(-)
@@ -92,12 +103,9 @@ static void q40kbd_flush(void)staticintq40kbd_open(structserio*port){-q40kbd_flush();+structq40kbd*q40kbd=port->port_data;-if(request_irq(Q40_IRQ_KEYBOARD,q40kbd_interrupt,0,"q40kbd",NULL)){-printk(KERN_ERR"q40kbd.c: Can't get irq %d.\n",Q40_IRQ_KEYBOARD);-return-EBUSY;-}+q40kbd_flush(q40kbd);/* off we go */master_outb(-1,KEYBOARD_UNLOCK_REG);
@@ -108,36 +116,72 @@ static int q40kbd_open(struct serio *port)staticvoidq40kbd_close(structserio*port){-master_outb(0,KEY_IRQ_ENABLE_REG);-master_outb(-1,KEYBOARD_UNLOCK_REG);-free_irq(Q40_IRQ_KEYBOARD,NULL);+structq40kbd*q40kbd=port->port_data;-q40kbd_flush();+q40kbd_stop();+q40kbd_flush(q40kbd);}-staticint__devinitq40kbd_probe(structplatform_device*dev)+staticint__devinitq40kbd_probe(structplatform_device*pdev){-q40kbd_port=kzalloc(sizeof(structserio),GFP_KERNEL);-if(!q40kbd_port)-return-ENOMEM;--q40kbd_port->id.type=SERIO_8042;-q40kbd_port->open=q40kbd_open;-q40kbd_port->close=q40kbd_close;-q40kbd_port->dev.parent=&dev->dev;-strlcpy(q40kbd_port->name,"Q40 Kbd Port",sizeof(q40kbd_port->name));-strlcpy(q40kbd_port->phys,"Q40",sizeof(q40kbd_port->phys));--serio_register_port(q40kbd_port);+structq40kbd*q40kbd;+structserio*port;+interror;++q40kbd=kzalloc(sizeof(structq40kbd),GFP_KERNEL);+port=kzalloc(sizeof(structserio),GFP_KERNEL);+if(!q40kbd||!port){+error=-ENOMEM;+gotoerr_free_mem;+}++q40kbd->port=port;+spin_lock_init(&q40kbd->lock);++port->id.type=SERIO_8042;+port->open=q40kbd_open;+port->close=q40kbd_close;+port->port_data=q40kbd;+port->dev.parent=&pdev->dev;+strlcpy(port->name,"Q40 Kbd Port",sizeof(port->name));+strlcpy(port->phys,"Q40",sizeof(port->phys));++q40kbd_stop();++error=request_irq(Q40_IRQ_KEYBOARD,q40kbd_interrupt,0,+DRV_NAME,q40kbd);+if(error){+dev_err(&pdev->dev,"Can't get irq %d.\n",Q40_IRQ_KEYBOARD);+gotoerr_free_mem;+}++serio_register_port(q40kbd->port);++platform_set_drvdata(pdev,q40kbd);printk(KERN_INFO"serio: Q40 kbd registered\n");return0;++err_free_mem:+kfree(port);+kfree(q40kbd);+returnerror;}-staticint__devexitq40kbd_remove(structplatform_device*dev)+staticint__devexitq40kbd_remove(structplatform_device*pdev){-serio_unregister_port(q40kbd_port);-+structq40kbd*q40kbd=platform_get_drvdata(pdev);++/*+*q40kbd_close()willbecalledaspartofunregistering+*andwillensurethatIRQisturnedoff,soitissafe+*tounregisterportfirstandfreeIRQlater.+*/+serio_unregister_port(q40kbd->port);+free_irq(Q40_IRQ_KEYBOARD,q40kbd);+kfree(q40kbd);++platform_set_drvdata(pdev,NULL);return0;}
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Input: q40kbd - convert driver to the split model
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Convert the driver to standard spilt model arch-specific code registers
platform device to which driver code can bind later.
Also request IRQ immediately upon binding to the device instead of doing
this when serio port is being opened.
Signed-off-by: Dmitry Torokhov <redacted>
---
arch/m68k/q40/config.c | 7 ++
drivers/input/serio/q40kbd.c | 139 ++++++++++++++++++++++++------------------
2 files changed, 86 insertions(+), 60 deletions(-)
@@ -329,3 +330,9 @@ static int q40_set_rtc_pll(struct rtc_pll_info *pll)}elsereturn-EINVAL;}++static__initintq40_add_kbd_device(void)+{+returnplatform_device_register_simple("q40kbd",-1,NULL,0);
arch/m68k/q40/config.c: In function ‘q40_add_kbd_device’:
arch/m68k/q40/config.c:336: warning: return makes integer from pointer without a cast
Either ignore the error and always return 0, or:
@@ -333,6 +333,12 @@ static int q40_set_rtc_pll(struct rtc_pll_info *pll)static__initintq40_add_kbd_device(void){-returnplatform_device_register_simple("q40kbd",-1,NULL,0);+structplatform_device*pdev;++pdev=platform_device_register_simple("q40kbd",-1,NULL,0);+if(IS_ERR(pdev))+returnPTR_ERR(pdev);++return0;}arch_initcall(q40_add_kbd_device);
The rest is
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds