2017-11-03 13:28:30 +03:00
// SPDX-License-Identifier: GPL-2.0
2005-05-26 16:55:55 +04:00
/*
* PCMCIA driver for SL811HS ( as found in REX - CFU1U )
* Filename : sl811_cs . c
* Author : Yukio Yamamoto
*
* Port to sl811 - hcd and 2.6 . x by
* Botond Botyanszki < boti @ rocketmail . com >
* Simon Pickering
*
* Last update : 2005 - 05 - 12
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/ptrace.h>
# include <linux/slab.h>
# include <linux/string.h>
# include <linux/timer.h>
# include <linux/ioport.h>
2005-10-29 22:07:23 +04:00
# include <linux/platform_device.h>
2005-05-26 16:55:55 +04:00
# include <pcmcia/cistpl.h>
# include <pcmcia/cisreg.h>
# include <pcmcia/ds.h>
2006-06-13 20:59:32 +04:00
# include <linux/usb/sl811.h>
2005-05-26 16:55:55 +04:00
MODULE_AUTHOR ( " Botond Botyanszki " ) ;
MODULE_DESCRIPTION ( " REX-CFU1U PCMCIA driver for 2.6 " ) ;
MODULE_LICENSE ( " GPL " ) ;
/*====================================================================*/
/* MACROS */
/*====================================================================*/
# define INFO(args...) printk(KERN_INFO "sl811_cs: " args)
/*====================================================================*/
/* VARIABLES */
/*====================================================================*/
typedef struct local_info_t {
2006-03-05 12:45:09 +03:00
struct pcmcia_device * p_dev ;
2005-05-26 16:55:55 +04:00
} local_info_t ;
2006-03-31 19:21:06 +04:00
static void sl811_cs_release ( struct pcmcia_device * link ) ;
2005-11-14 23:23:14 +03:00
2005-05-26 16:55:55 +04:00
/*====================================================================*/
static void release_platform_dev ( struct device * dev )
{
2009-10-24 17:55:39 +04:00
dev_dbg ( dev , " sl811_cs platform_dev release \n " ) ;
2005-05-26 16:55:55 +04:00
dev - > parent = NULL ;
}
static struct sl811_platform_data platform_data = {
. potpg = 100 ,
. power = 50 , /* == 100mA */
// .reset = ... FIXME: invoke CF reset on the card
} ;
static struct resource resources [ ] = {
[ 0 ] = {
. flags = IORESOURCE_IRQ ,
} ,
[ 1 ] = {
// .name = "address",
. flags = IORESOURCE_IO ,
} ,
[ 2 ] = {
// .name = "data",
. flags = IORESOURCE_IO ,
} ,
} ;
2006-02-06 23:15:15 +03:00
extern struct platform_driver sl811h_driver ;
2005-05-26 16:55:55 +04:00
static struct platform_device platform_dev = {
. id = - 1 ,
. dev = {
. platform_data = & platform_data ,
. release = release_platform_dev ,
} ,
. resource = resources ,
. num_resources = ARRAY_SIZE ( resources ) ,
} ;
2008-08-28 03:05:34 +04:00
static int sl811_hc_init ( struct device * parent , resource_size_t base_addr ,
int irq )
2005-05-26 16:55:55 +04:00
{
if ( platform_dev . dev . parent )
return - EBUSY ;
platform_dev . dev . parent = parent ;
/* finish seting up the platform device */
resources [ 0 ] . start = irq ;
resources [ 1 ] . start = base_addr ;
resources [ 1 ] . end = base_addr ;
resources [ 2 ] . start = base_addr + 1 ;
resources [ 2 ] . end = base_addr + 1 ;
/* The driver core will probe for us. We know sl811-hcd has been
2005-11-08 07:45:20 +03:00
* initialized already because of the link order dependency created
* by referencing " sl811h_driver " .
2005-05-26 16:55:55 +04:00
*/
2006-02-06 23:15:15 +03:00
platform_dev . name = sl811h_driver . driver . name ;
2005-05-26 16:55:55 +04:00
return platform_device_register ( & platform_dev ) ;
}
/*====================================================================*/
2006-03-31 19:21:06 +04:00
static void sl811_cs_detach ( struct pcmcia_device * link )
2005-05-26 16:55:55 +04:00
{
2009-10-24 17:55:39 +04:00
dev_dbg ( & link - > dev , " sl811_cs_detach \n " ) ;
2005-05-26 16:55:55 +04:00
2006-03-02 02:09:29 +03:00
sl811_cs_release ( link ) ;
2005-05-26 16:55:55 +04:00
/* This points to the parent local_info_t struct */
kfree ( link - > priv ) ;
}
2006-03-31 19:21:06 +04:00
static void sl811_cs_release ( struct pcmcia_device * link )
2005-05-26 16:55:55 +04:00
{
2009-10-24 17:55:39 +04:00
dev_dbg ( & link - > dev , " sl811_cs_release \n " ) ;
2005-05-26 16:55:55 +04:00
2006-03-31 19:21:06 +04:00
pcmcia_disable_device ( link ) ;
2005-05-26 16:55:55 +04:00
platform_device_unregister ( & platform_dev ) ;
}
2010-07-30 15:13:46 +04:00
static int sl811_cs_config_check ( struct pcmcia_device * p_dev , void * priv_data )
2008-07-29 10:38:55 +04:00
{
2010-07-30 15:13:46 +04:00
if ( p_dev - > config_index = = 0 )
return - EINVAL ;
return pcmcia_request_io ( p_dev ) ;
2008-07-29 10:38:55 +04:00
}
2006-03-31 19:26:06 +04:00
static int sl811_cs_config ( struct pcmcia_device * link )
2005-05-26 16:55:55 +04:00
{
2009-11-03 12:27:34 +03:00
struct device * parent = & link - > dev ;
2009-10-24 17:55:39 +04:00
int ret ;
2005-05-26 16:55:55 +04:00
2009-10-24 17:55:39 +04:00
dev_dbg ( & link - > dev , " sl811_cs_config \n " ) ;
2005-05-26 16:55:55 +04:00
2010-07-30 11:51:52 +04:00
link - > config_flags | = CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
2010-07-30 15:13:46 +04:00
CONF_AUTO_CHECK_VCC | CONF_AUTO_SET_IO ;
2010-07-30 11:51:52 +04:00
2008-08-02 18:12:00 +04:00
if ( pcmcia_loop_config ( link , sl811_cs_config_check , NULL ) )
goto failed ;
2005-05-26 16:55:55 +04:00
/* require an IRQ and two registers */
2010-07-24 17:58:54 +04:00
if ( resource_size ( link - > resource [ 0 ] ) < 2 )
2008-08-02 18:12:00 +04:00
goto failed ;
2010-03-07 14:21:16 +03:00
if ( ! link - > irq )
2008-08-02 18:12:00 +04:00
goto failed ;
2005-05-26 16:55:55 +04:00
2010-07-29 21:27:09 +04:00
ret = pcmcia_enable_device ( link ) ;
2009-10-24 17:55:39 +04:00
if ( ret )
goto failed ;
2005-05-26 16:55:55 +04:00
2010-07-24 17:58:54 +04:00
if ( sl811_hc_init ( parent , link - > resource [ 0 ] - > start , link - > irq )
2005-05-26 16:55:55 +04:00
< 0 ) {
2008-08-02 18:12:00 +04:00
failed :
printk ( KERN_WARNING " sl811_cs_config failed \n " ) ;
2005-05-26 16:55:55 +04:00
sl811_cs_release ( link ) ;
2006-03-31 19:26:06 +04:00
return - ENODEV ;
2005-05-26 16:55:55 +04:00
}
2006-03-31 19:26:06 +04:00
return 0 ;
2005-05-26 16:55:55 +04:00
}
2006-03-31 19:26:06 +04:00
static int sl811_cs_probe ( struct pcmcia_device * link )
2005-05-26 16:55:55 +04:00
{
local_info_t * local ;
some kmalloc/memset ->kzalloc (tree wide)
Transform some calls to kmalloc/memset to a single kzalloc (or kcalloc).
Here is a short excerpt of the semantic patch performing
this transformation:
@@
type T2;
expression x;
identifier f,fld;
expression E;
expression E1,E2;
expression e1,e2,e3,y;
statement S;
@@
x =
- kmalloc
+ kzalloc
(E1,E2)
... when != \(x->fld=E;\|y=f(...,x,...);\|f(...,x,...);\|x=E;\|while(...) S\|for(e1;e2;e3) S\)
- memset((T2)x,0,E1);
@@
expression E1,E2,E3;
@@
- kzalloc(E1 * E2,E3)
+ kcalloc(E1,E2,E3)
[akpm@linux-foundation.org: get kcalloc args the right way around]
Signed-off-by: Yoann Padioleau <padator@wanadoo.fr>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Acked-by: Russell King <rmk@arm.linux.org.uk>
Cc: Bryan Wu <bryan.wu@analog.com>
Acked-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Dave Airlie <airlied@linux.ie>
Acked-by: Roland Dreier <rolandd@cisco.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Acked-by: Pierre Ossman <drzeus-list@drzeus.cx>
Cc: Jeff Garzik <jeff@garzik.org>
Cc: "David S. Miller" <davem@davemloft.net>
Acked-by: Greg KH <greg@kroah.com>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-19 12:49:03 +04:00
local = kzalloc ( sizeof ( local_info_t ) , GFP_KERNEL ) ;
2005-05-26 16:55:55 +04:00
if ( ! local )
2005-11-14 23:25:51 +03:00
return - ENOMEM ;
2006-03-31 19:21:06 +04:00
local - > p_dev = link ;
2005-05-26 16:55:55 +04:00
link - > priv = local ;
2006-03-31 19:26:06 +04:00
return sl811_cs_config ( link ) ;
2005-05-26 16:55:55 +04:00
}
2011-05-04 06:29:01 +04:00
static const struct pcmcia_device_id sl811_ids [ ] = {
2005-06-28 03:28:43 +04:00
PCMCIA_DEVICE_MANF_CARD ( 0xc015 , 0x0001 ) , /* RATOC USB HOST CF+ Card */
PCMCIA_DEVICE_NULL ,
} ;
MODULE_DEVICE_TABLE ( pcmcia , sl811_ids ) ;
2005-05-26 16:55:55 +04:00
static struct pcmcia_driver sl811_cs_driver = {
. owner = THIS_MODULE ,
2010-08-08 13:36:26 +04:00
. name = " sl811_cs " ,
2006-03-31 19:26:06 +04:00
. probe = sl811_cs_probe ,
2005-11-14 23:23:14 +03:00
. remove = sl811_cs_detach ,
2005-06-28 03:28:43 +04:00
. id_table = sl811_ids ,
2005-05-26 16:55:55 +04:00
} ;
2013-03-06 22:29:17 +04:00
module_pcmcia_driver ( sl811_cs_driver ) ;