2005-04-17 02:20:36 +04:00
/*
2005-05-20 22:33:25 +04:00
* matrox_w1 . c
2005-04-17 02:20:36 +04:00
*
* Copyright ( c ) 2004 Evgeniy Polyakov < johnpol @ 2 ka . mipt . ru >
2005-05-20 22:33:25 +04:00
*
2005-04-17 02:20:36 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <asm/types.h>
2005-12-06 13:38:28 +03:00
# include <asm/atomic.h>
2005-04-17 02:20:36 +04:00
# include <asm/io.h>
# include <linux/delay.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/list.h>
# include <linux/interrupt.h>
# include <linux/spinlock.h>
# include <linux/timer.h>
# include <linux/slab.h>
# include <linux/pci_ids.h>
# include <linux/pci.h>
2005-12-06 13:38:28 +03:00
# include "../w1.h"
# include "../w1_int.h"
# include "../w1_log.h"
2005-04-17 02:20:36 +04:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Evgeniy Polyakov <johnpol@2ka.mipt.ru> " ) ;
MODULE_DESCRIPTION ( " Driver for transport(Dallas 1-wire prtocol) over VGA DDC(matrox gpio). " ) ;
static struct pci_device_id matrox_w1_tbl [ ] = {
{ PCI_DEVICE ( PCI_VENDOR_ID_MATROX , PCI_DEVICE_ID_MATROX_G400 ) } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( pci , matrox_w1_tbl ) ;
static int __devinit matrox_w1_probe ( struct pci_dev * , const struct pci_device_id * ) ;
static void __devexit matrox_w1_remove ( struct pci_dev * ) ;
static struct pci_driver matrox_w1_pci_driver = {
. name = " matrox_w1 " ,
. id_table = matrox_w1_tbl ,
. probe = matrox_w1_probe ,
. remove = __devexit_p ( matrox_w1_remove ) ,
} ;
2005-05-20 22:33:25 +04:00
/*
2005-04-17 02:20:36 +04:00
* Matrox G400 DDC registers .
*/
# define MATROX_G400_DDC_CLK (1<<4)
# define MATROX_G400_DDC_DATA (1<<1)
# define MATROX_BASE 0x3C00
# define MATROX_STATUS 0x1e14
# define MATROX_PORT_INDEX_OFFSET 0x00
# define MATROX_PORT_DATA_OFFSET 0x0A
# define MATROX_GET_CONTROL 0x2A
# define MATROX_GET_DATA 0x2B
# define MATROX_CURSOR_CTL 0x06
struct matrox_device
{
void __iomem * base_addr ;
void __iomem * port_index ;
void __iomem * port_data ;
u8 data_mask ;
unsigned long phys_addr ;
void __iomem * virt_addr ;
unsigned long found ;
struct w1_bus_master * bus_master ;
} ;
2005-12-06 13:38:27 +03:00
static u8 matrox_w1_read_ddc_bit ( void * ) ;
static void matrox_w1_write_ddc_bit ( void * , u8 ) ;
2005-04-17 02:20:36 +04:00
/*
* These functions read and write DDC Data bit .
*
* Using tristate pins , since i can ' t find any open - drain pin in whole motherboard .
* Unfortunately we can ' t connect to Intel ' s 82801 xx IO controller
2006-03-24 20:23:14 +03:00
* since we don ' t know motherboard schema , which has pretty unused ( may be not ) GPIO .
2005-04-17 02:20:36 +04:00
*
* I ' ve heard that PIIX also has open drain pin .
*
* Port mapping .
*/
static __inline__ u8 matrox_w1_read_reg ( struct matrox_device * dev , u8 reg )
{
u8 ret ;
writeb ( reg , dev - > port_index ) ;
ret = readb ( dev - > port_data ) ;
barrier ( ) ;
return ret ;
}
static __inline__ void matrox_w1_write_reg ( struct matrox_device * dev , u8 reg , u8 val )
{
writeb ( reg , dev - > port_index ) ;
writeb ( val , dev - > port_data ) ;
wmb ( ) ;
}
2005-12-06 13:38:27 +03:00
static void matrox_w1_write_ddc_bit ( void * data , u8 bit )
2005-04-17 02:20:36 +04:00
{
u8 ret ;
2005-12-06 13:38:27 +03:00
struct matrox_device * dev = data ;
2005-04-17 02:20:36 +04:00
if ( bit )
bit = 0 ;
else
bit = dev - > data_mask ;
ret = matrox_w1_read_reg ( dev , MATROX_GET_CONTROL ) ;
matrox_w1_write_reg ( dev , MATROX_GET_CONTROL , ( ( ret & ~ dev - > data_mask ) | bit ) ) ;
matrox_w1_write_reg ( dev , MATROX_GET_DATA , 0x00 ) ;
}
2005-12-06 13:38:27 +03:00
static u8 matrox_w1_read_ddc_bit ( void * data )
2005-04-17 02:20:36 +04:00
{
u8 ret ;
2005-12-06 13:38:27 +03:00
struct matrox_device * dev = data ;
2005-04-17 02:20:36 +04:00
ret = matrox_w1_read_reg ( dev , MATROX_GET_DATA ) ;
return ret ;
}
static void matrox_w1_hw_init ( struct matrox_device * dev )
{
matrox_w1_write_reg ( dev , MATROX_GET_DATA , 0xFF ) ;
matrox_w1_write_reg ( dev , MATROX_GET_CONTROL , 0x00 ) ;
}
static int __devinit matrox_w1_probe ( struct pci_dev * pdev , const struct pci_device_id * ent )
{
struct matrox_device * dev ;
int err ;
assert ( pdev ! = NULL ) ;
assert ( ent ! = NULL ) ;
if ( pdev - > vendor ! = PCI_VENDOR_ID_MATROX | | pdev - > device ! = PCI_DEVICE_ID_MATROX_G400 )
return - ENODEV ;
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
dev = kzalloc ( sizeof ( struct matrox_device ) +
2005-04-17 02:20:36 +04:00
sizeof ( struct w1_bus_master ) , GFP_KERNEL ) ;
if ( ! dev ) {
dev_err ( & pdev - > dev ,
" %s: Failed to create new matrox_device object. \n " ,
__func__ ) ;
return - ENOMEM ;
}
dev - > bus_master = ( struct w1_bus_master * ) ( dev + 1 ) ;
2005-05-20 22:33:25 +04:00
/*
* True for G400 , for some other we need resource 0 , see drivers / video / matrox / matroxfb_base . c
2005-04-17 02:20:36 +04:00
*/
dev - > phys_addr = pci_resource_start ( pdev , 1 ) ;
dev - > virt_addr = ioremap_nocache ( dev - > phys_addr , 16384 ) ;
if ( ! dev - > virt_addr ) {
dev_err ( & pdev - > dev , " %s: failed to ioremap(0x%lx, %d). \n " ,
__func__ , dev - > phys_addr , 16384 ) ;
err = - EIO ;
goto err_out_free_device ;
}
dev - > base_addr = dev - > virt_addr + MATROX_BASE ;
dev - > port_index = dev - > base_addr + MATROX_PORT_INDEX_OFFSET ;
dev - > port_data = dev - > base_addr + MATROX_PORT_DATA_OFFSET ;
dev - > data_mask = ( MATROX_G400_DDC_DATA ) ;
matrox_w1_hw_init ( dev ) ;
2005-12-06 13:38:27 +03:00
dev - > bus_master - > data = dev ;
2005-04-17 02:20:36 +04:00
dev - > bus_master - > read_bit = & matrox_w1_read_ddc_bit ;
dev - > bus_master - > write_bit = & matrox_w1_write_ddc_bit ;
err = w1_add_master_device ( dev - > bus_master ) ;
if ( err )
goto err_out_free_device ;
pci_set_drvdata ( pdev , dev ) ;
dev - > found = 1 ;
dev_info ( & pdev - > dev , " Matrox G400 GPIO transport layer for 1-wire. \n " ) ;
return 0 ;
err_out_free_device :
2006-10-05 14:26:02 +04:00
if ( dev - > virt_addr )
iounmap ( dev - > virt_addr ) ;
2005-04-17 02:20:36 +04:00
kfree ( dev ) ;
return err ;
}
static void __devexit matrox_w1_remove ( struct pci_dev * pdev )
{
struct matrox_device * dev = pci_get_drvdata ( pdev ) ;
assert ( dev ! = NULL ) ;
if ( dev - > found ) {
w1_remove_master_device ( dev - > bus_master ) ;
iounmap ( dev - > virt_addr ) ;
}
kfree ( dev ) ;
}
static int __init matrox_w1_init ( void )
{
return pci_register_driver ( & matrox_w1_pci_driver ) ;
}
static void __exit matrox_w1_fini ( void )
{
pci_unregister_driver ( & matrox_w1_pci_driver ) ;
}
module_init ( matrox_w1_init ) ;
module_exit ( matrox_w1_fini ) ;