2008-01-09 22:10:41 +03:00
/*
* OF - platform PATA driver
*
* Copyright ( c ) 2007 MontaVista Software , Inc .
* Anton Vorontsov < avorontsov @ ru . mvista . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License ( Version 2 ) as
* published by the Free Software Foundation .
*/
# include <linux/kernel.h>
# include <linux/module.h>
2011-09-07 16:36:26 +04:00
# include <linux/of_address.h>
2011-12-23 00:07:00 +04:00
# include <linux/platform_device.h>
2008-02-02 02:02:30 +03:00
# include <linux/ata_platform.h>
2012-12-03 22:34:42 +04:00
# include <linux/libata.h>
2008-01-09 22:10:41 +03:00
2012-12-22 01:19:58 +04:00
static int pata_of_platform_probe ( struct platform_device * ofdev )
2008-01-09 22:10:41 +03:00
{
int ret ;
2010-04-14 03:12:29 +04:00
struct device_node * dn = ofdev - > dev . of_node ;
2008-01-09 22:10:41 +03:00
struct resource io_res ;
struct resource ctl_res ;
2011-12-23 00:07:00 +04:00
struct resource * irq_res ;
2008-01-09 22:10:41 +03:00
unsigned int reg_shift = 0 ;
int pio_mode = 0 ;
int pio_mask ;
const u32 * prop ;
ret = of_address_to_resource ( dn , 0 , & io_res ) ;
if ( ret ) {
dev_err ( & ofdev - > dev , " can't get IO address from "
" device tree \n " ) ;
return - EINVAL ;
}
2007-12-04 23:44:32 +03:00
if ( of_device_is_compatible ( dn , " electra-ide " ) ) {
/* Altstatus is really at offset 0x3f6 from the primary window
* on electra - ide . Adjust ctl_res and io_res accordingly .
*/
ctl_res = io_res ;
ctl_res . start = ctl_res . start + 0x3f6 ;
io_res . end = ctl_res . start - 1 ;
} else {
ret = of_address_to_resource ( dn , 1 , & ctl_res ) ;
if ( ret ) {
dev_err ( & ofdev - > dev , " can't get CTL address from "
" device tree \n " ) ;
return - EINVAL ;
}
2008-01-09 22:10:41 +03:00
}
2011-12-23 00:07:00 +04:00
irq_res = platform_get_resource ( ofdev , IORESOURCE_IRQ , 0 ) ;
if ( irq_res )
irq_res - > flags = 0 ;
2008-01-09 22:10:41 +03:00
prop = of_get_property ( dn , " reg-shift " , NULL ) ;
if ( prop )
2011-09-07 16:36:26 +04:00
reg_shift = be32_to_cpup ( prop ) ;
2008-01-09 22:10:41 +03:00
prop = of_get_property ( dn , " pio-mode " , NULL ) ;
if ( prop ) {
2011-09-07 16:36:26 +04:00
pio_mode = be32_to_cpup ( prop ) ;
2008-01-09 22:10:41 +03:00
if ( pio_mode > 6 ) {
dev_err ( & ofdev - > dev , " invalid pio-mode \n " ) ;
return - EINVAL ;
}
} else {
dev_info ( & ofdev - > dev , " pio-mode unspecified, assuming PIO0 \n " ) ;
}
pio_mask = 1 < < pio_mode ;
pio_mask | = ( 1 < < pio_mode ) - 1 ;
2011-12-23 00:07:00 +04:00
return __pata_platform_probe ( & ofdev - > dev , & io_res , & ctl_res , irq_res ,
2008-01-09 22:10:41 +03:00
reg_shift , pio_mask ) ;
}
static struct of_device_id pata_of_platform_match [ ] = {
{ . compatible = " ata-generic " , } ,
2007-12-04 23:44:32 +03:00
{ . compatible = " electra-ide " , } ,
2008-01-09 22:10:41 +03:00
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , pata_of_platform_match ) ;
2011-02-17 12:43:24 +03:00
static struct platform_driver pata_of_platform_driver = {
2010-04-14 03:13:02 +04:00
. driver = {
. name = " pata_of_platform " ,
. owner = THIS_MODULE ,
. of_match_table = pata_of_platform_match ,
} ,
2008-01-09 22:10:41 +03:00
. probe = pata_of_platform_probe ,
2012-11-02 11:46:22 +04:00
. remove = ata_platform_remove_one ,
2008-01-09 22:10:41 +03:00
} ;
2011-11-27 10:44:26 +04:00
module_platform_driver ( pata_of_platform_driver ) ;
2008-01-09 22:10:41 +03:00
MODULE_DESCRIPTION ( " OF-platform PATA driver " ) ;
MODULE_AUTHOR ( " Anton Vorontsov <avorontsov@ru.mvista.com> " ) ;
MODULE_LICENSE ( " GPL " ) ;