2005-04-16 15:20:36 -07:00
/* auxio.c: Probing for the Sparc AUXIO register at boot time.
*
* Copyright ( C ) 1996 David S . Miller ( davem @ caip . rutgers . edu )
*
* Refactoring for unified NCR / PCIO support 2002 Eric Brower ( ebrower @ usa . net )
*/
2006-06-25 02:08:47 -07:00
# include <linux/module.h>
2005-04-16 15:20:36 -07:00
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/ioport.h>
2008-08-07 15:33:36 -07:00
# include <linux/of_device.h>
2005-04-16 15:20:36 -07:00
2006-06-29 15:22:22 -07:00
# include <asm/prom.h>
2005-04-16 15:20:36 -07:00
# include <asm/io.h>
# include <asm/auxio.h>
void __iomem * auxio_register = NULL ;
2006-06-25 02:08:47 -07:00
EXPORT_SYMBOL ( auxio_register ) ;
2005-04-16 15:20:36 -07:00
enum auxio_type {
AUXIO_TYPE_NODEV ,
AUXIO_TYPE_SBUS ,
AUXIO_TYPE_EBUS
} ;
static enum auxio_type auxio_devtype = AUXIO_TYPE_NODEV ;
static DEFINE_SPINLOCK ( auxio_lock ) ;
2008-10-29 23:18:41 -07:00
static void __auxio_rmw ( u8 bits_on , u8 bits_off , int ebus )
2005-04-16 15:20:36 -07:00
{
if ( auxio_register ) {
unsigned long flags ;
2008-10-29 23:18:41 -07:00
u8 regval , newval ;
2005-04-16 15:20:36 -07:00
spin_lock_irqsave ( & auxio_lock , flags ) ;
2008-10-29 23:18:41 -07:00
regval = ( ebus ?
( u8 ) readl ( auxio_register ) :
sbus_readb ( auxio_register ) ) ;
2005-04-16 15:20:36 -07:00
newval = regval | bits_on ;
newval & = ~ bits_off ;
2008-10-29 23:18:41 -07:00
if ( ! ebus )
newval & = ~ AUXIO_AUX1_MASK ;
if ( ebus )
writel ( ( u32 ) newval , auxio_register ) ;
else
sbus_writeb ( newval , auxio_register ) ;
2005-04-16 15:20:36 -07:00
spin_unlock_irqrestore ( & auxio_lock , flags ) ;
}
}
2008-10-29 23:18:41 -07:00
static void __auxio_set_bit ( u8 bit , int on , int ebus )
2005-04-16 15:20:36 -07:00
{
2008-10-29 23:18:41 -07:00
u8 bits_on = ( ebus ? AUXIO_PCIO_LED : AUXIO_AUX1_LED ) ;
u8 bits_off = 0 ;
2005-04-16 15:20:36 -07:00
2008-10-29 23:18:41 -07:00
if ( ! on ) {
u8 tmp = bits_off ;
bits_off = bits_on ;
bits_on = tmp ;
2005-04-16 15:20:36 -07:00
}
2008-10-29 23:18:41 -07:00
__auxio_rmw ( bits_on , bits_off , ebus ) ;
2005-04-16 15:20:36 -07:00
}
void auxio_set_led ( int on )
{
2008-10-29 23:18:41 -07:00
int ebus = auxio_devtype = = AUXIO_TYPE_EBUS ;
u8 bit ;
bit = ( ebus ? AUXIO_PCIO_LED : AUXIO_AUX1_LED ) ;
__auxio_set_bit ( bit , on , ebus ) ;
2005-04-16 15:20:36 -07:00
}
2009-01-08 16:58:20 -08:00
EXPORT_SYMBOL ( auxio_set_led ) ;
2005-04-16 15:20:36 -07:00
2008-10-29 23:18:41 -07:00
static void __auxio_sbus_set_lte ( int on )
2005-04-16 15:20:36 -07:00
{
2008-10-29 23:18:41 -07:00
__auxio_set_bit ( AUXIO_AUX1_LTE , on , 0 ) ;
2005-04-16 15:20:36 -07:00
}
void auxio_set_lte ( int on )
{
switch ( auxio_devtype ) {
case AUXIO_TYPE_SBUS :
__auxio_sbus_set_lte ( on ) ;
break ;
case AUXIO_TYPE_EBUS :
/* FALL-THROUGH */
default :
break ;
}
}
2009-01-08 16:58:20 -08:00
EXPORT_SYMBOL ( auxio_set_lte ) ;
2005-04-16 15:20:36 -07:00
2011-03-30 17:37:56 -07:00
static const struct of_device_id auxio_match [ ] = {
2006-06-23 22:46:49 -07:00
{
. name = " auxio " ,
} ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , auxio_match ) ;
2011-02-22 20:01:33 -07:00
static int __devinit auxio_probe ( struct platform_device * dev )
2006-06-23 22:46:49 -07:00
{
2010-04-13 16:12:29 -07:00
struct device_node * dp = dev - > dev . of_node ;
2006-06-29 14:36:35 -07:00
unsigned long size ;
if ( ! strcmp ( dp - > parent - > name , " ebus " ) ) {
auxio_devtype = AUXIO_TYPE_EBUS ;
size = sizeof ( u32 ) ;
} else if ( ! strcmp ( dp - > parent - > name , " sbus " ) ) {
auxio_devtype = AUXIO_TYPE_SBUS ;
size = 1 ;
} else {
printk ( " auxio: Unknown parent bus type [%s] \n " ,
dp - > parent - > name ) ;
2006-06-23 22:46:49 -07:00
return - ENODEV ;
2006-06-29 14:36:35 -07:00
}
auxio_register = of_ioremap ( & dev - > resource [ 0 ] , 0 , size , " auxio " ) ;
2006-06-23 22:46:49 -07:00
if ( ! auxio_register )
return - ENODEV ;
2006-06-29 14:36:35 -07:00
printk ( KERN_INFO " AUXIO: Found device at %s \n " ,
dp - > full_name ) ;
2006-06-23 22:46:49 -07:00
2006-06-29 14:36:35 -07:00
if ( auxio_devtype = = AUXIO_TYPE_EBUS )
auxio_set_led ( AUXIO_LED_ON ) ;
2006-06-23 22:46:49 -07:00
return 0 ;
}
2011-02-22 20:01:33 -07:00
static struct platform_driver auxio_driver = {
2006-06-29 14:36:35 -07:00
. probe = auxio_probe ,
2010-04-13 16:13:02 -07:00
. driver = {
. name = " auxio " ,
. owner = THIS_MODULE ,
. of_match_table = auxio_match ,
2007-10-10 23:27:34 -07:00
} ,
2006-06-23 22:46:49 -07:00
} ;
2006-06-29 14:36:35 -07:00
static int __init auxio_init ( void )
2006-06-23 22:46:49 -07:00
{
2011-02-22 20:01:33 -07:00
return platform_driver_register ( & auxio_driver ) ;
2005-04-16 15:20:36 -07:00
}
2006-06-23 22:46:49 -07:00
/* Must be after subsys_initcall() so that busses are probed. Must
* be before device_initcall ( ) because things like the floppy driver
* need to use the AUXIO register .
*/
2006-06-29 14:36:35 -07:00
fs_initcall ( auxio_init ) ;