2019-05-28 19:57:05 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2010-11-26 13:52:35 +03:00
/*
* cs5535 - mfd . c - core MFD driver for CS5535 / CS5536 southbridges
*
* The CS5535 and CS5536 has an ISA bridge on the PCI bus that is
* used for accessing GPIOs , MFGPTs , ACPI , etc . Each subdevice has
* an IO range that ' s specified in a single BAR . The BAR order is
* hardcoded in the CS553x specifications .
*
* Copyright ( c ) 2010 Andres Salomon < dilinger @ queued . net >
*/
# include <linux/kernel.h>
# include <linux/mfd/core.h>
# include <linux/module.h>
# include <linux/pci.h>
2011-03-22 05:19:35 +03:00
# include <asm/olpc.h>
2010-11-26 13:52:35 +03:00
# define DRV_NAME "cs5535-mfd"
enum cs5535_mfd_bars {
SMB_BAR = 0 ,
GPIO_BAR = 1 ,
MFGPT_BAR = 2 ,
PMS_BAR = 4 ,
ACPI_BAR = 5 ,
NR_BARS ,
} ;
2012-11-19 22:24:21 +04:00
static struct resource cs5535_mfd_resources [ NR_BARS ] ;
2010-11-26 13:52:35 +03:00
2012-11-19 22:24:21 +04:00
static struct mfd_cell cs5535_mfd_cells [ ] = {
2010-11-26 13:52:35 +03:00
{
. name = " cs5535-smb " ,
. num_resources = 1 ,
. resources = & cs5535_mfd_resources [ SMB_BAR ] ,
} ,
{
. name = " cs5535-gpio " ,
. num_resources = 1 ,
. resources = & cs5535_mfd_resources [ GPIO_BAR ] ,
} ,
{
. name = " cs5535-mfgpt " ,
. num_resources = 1 ,
. resources = & cs5535_mfd_resources [ MFGPT_BAR ] ,
} ,
{
. name = " cs5535-pms " ,
. num_resources = 1 ,
. resources = & cs5535_mfd_resources [ PMS_BAR ] ,
} ,
2019-10-18 13:36:44 +03:00
} ;
static struct mfd_cell cs5535_olpc_mfd_cells [ ] = {
2010-11-26 13:52:35 +03:00
{
2019-10-18 13:36:44 +03:00
. name = " olpc-xo1-pm-acpi " ,
. num_resources = 1 ,
. resources = & cs5535_mfd_resources [ ACPI_BAR ] ,
} ,
{
. name = " olpc-xo1-sci-acpi " ,
2010-11-26 13:52:35 +03:00
. num_resources = 1 ,
. resources = & cs5535_mfd_resources [ ACPI_BAR ] ,
} ,
2019-06-20 14:19:57 +03:00
} ;
2011-03-22 05:19:35 +03:00
2012-11-19 22:23:04 +04:00
static int cs5535_mfd_probe ( struct pci_dev * pdev ,
2010-11-26 13:52:35 +03:00
const struct pci_device_id * id )
{
2019-10-18 12:23:49 +03:00
int err , bar ;
2010-11-26 13:52:35 +03:00
err = pci_enable_device ( pdev ) ;
if ( err )
return err ;
2019-10-18 12:23:49 +03:00
for ( bar = 0 ; bar < NR_BARS ; bar + + ) {
2010-11-26 13:52:35 +03:00
struct resource * r = & cs5535_mfd_resources [ bar ] ;
r - > flags = IORESOURCE_IO ;
r - > start = pci_resource_start ( pdev , bar ) ;
r - > end = pci_resource_end ( pdev , bar ) ;
}
2019-10-21 10:49:49 +03:00
err = pci_request_region ( pdev , PMS_BAR , DRV_NAME ) ;
if ( err ) {
dev_err ( & pdev - > dev , " Failed to request PMS_BAR's IO region \n " ) ;
goto err_disable ;
}
2019-10-18 12:09:24 +03:00
err = mfd_add_devices ( & pdev - > dev , PLATFORM_DEVID_NONE , cs5535_mfd_cells ,
2012-09-11 11:16:36 +04:00
ARRAY_SIZE ( cs5535_mfd_cells ) , NULL , 0 , NULL ) ;
2010-11-26 13:52:35 +03:00
if ( err ) {
2019-10-18 12:09:24 +03:00
dev_err ( & pdev - > dev ,
" Failed to add CS5535 sub-devices: %d \n " , err ) ;
2019-10-21 10:49:49 +03:00
goto err_release_pms ;
2010-11-26 13:52:35 +03:00
}
2019-06-20 14:19:57 +03:00
2019-10-21 10:49:49 +03:00
if ( machine_is_olpc ( ) ) {
err = pci_request_region ( pdev , ACPI_BAR , DRV_NAME ) ;
if ( err ) {
dev_err ( & pdev - > dev ,
" Failed to request ACPI_BAR's IO region \n " ) ;
goto err_remove_devices ;
}
2019-10-18 13:36:44 +03:00
err = mfd_add_devices ( & pdev - > dev , PLATFORM_DEVID_NONE ,
cs5535_olpc_mfd_cells ,
ARRAY_SIZE ( cs5535_olpc_mfd_cells ) ,
NULL , 0 , NULL ) ;
2019-10-21 10:49:49 +03:00
if ( err ) {
2019-10-18 13:36:44 +03:00
dev_err ( & pdev - > dev ,
" Failed to add CS5535 OLPC sub-devices: %d \n " ,
err ) ;
2019-10-21 10:49:49 +03:00
goto err_release_acpi ;
}
}
2010-11-26 13:52:35 +03:00
2010-12-01 00:54:39 +03:00
dev_info ( & pdev - > dev , " %zu devices registered. \n " ,
2010-11-26 13:52:35 +03:00
ARRAY_SIZE ( cs5535_mfd_cells ) ) ;
return 0 ;
2019-10-21 10:49:49 +03:00
err_release_acpi :
pci_release_region ( pdev , ACPI_BAR ) ;
err_remove_devices :
mfd_remove_devices ( & pdev - > dev ) ;
err_release_pms :
pci_release_region ( pdev , PMS_BAR ) ;
2010-11-26 13:52:35 +03:00
err_disable :
pci_disable_device ( pdev ) ;
return err ;
}
2012-11-19 22:26:01 +04:00
static void cs5535_mfd_remove ( struct pci_dev * pdev )
2010-11-26 13:52:35 +03:00
{
mfd_remove_devices ( & pdev - > dev ) ;
2019-10-21 10:49:49 +03:00
if ( machine_is_olpc ( ) )
pci_release_region ( pdev , ACPI_BAR ) ;
pci_release_region ( pdev , PMS_BAR ) ;
2010-11-26 13:52:35 +03:00
pci_disable_device ( pdev ) ;
}
2013-12-03 03:15:39 +04:00
static const struct pci_device_id cs5535_mfd_pci_tbl [ ] = {
2010-11-26 13:52:35 +03:00
{ PCI_DEVICE ( PCI_VENDOR_ID_NS , PCI_DEVICE_ID_NS_CS5535_ISA ) } ,
{ PCI_DEVICE ( PCI_VENDOR_ID_AMD , PCI_DEVICE_ID_AMD_CS5536_ISA ) } ,
{ 0 , }
} ;
MODULE_DEVICE_TABLE ( pci , cs5535_mfd_pci_tbl ) ;
mfd: Fix cs5535 section mismatch
Silence following warnings:
WARNING: drivers/mfd/cs5535-mfd.o(.data+0x20): Section mismatch in
reference from the variable cs5535_mfd_drv to the function
.devinit.text:cs5535_mfd_probe()
The variable cs5535_mfd_drv references
the function __devinit cs5535_mfd_probe()
If the reference is valid then annotate the
variable with __init* or __refdata (see linux/init.h) or name the variable:
*driver, *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console
WARNING: drivers/mfd/cs5535-mfd.o(.data+0x28): Section mismatch in
reference from the variable cs5535_mfd_drv to the function
.devexit.text:cs5535_mfd_remove()
The variable cs5535_mfd_drv references
the function __devexit cs5535_mfd_remove()
If the reference is valid then annotate the
variable with __exit* (see linux/init.h) or name the variable:
*driver, *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console
Rename the variable from *_drv to *_driver so
modpost ignore the OK references to __devinit/__devexit
functions.
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Acked-by: Andres Salomon <dilinger@queued.net>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2011-12-14 00:30:04 +04:00
static struct pci_driver cs5535_mfd_driver = {
2010-11-26 13:52:35 +03:00
. name = DRV_NAME ,
. id_table = cs5535_mfd_pci_tbl ,
. probe = cs5535_mfd_probe ,
2012-11-19 22:20:24 +04:00
. remove = cs5535_mfd_remove ,
2010-11-26 13:52:35 +03:00
} ;
2012-04-03 05:09:19 +04:00
module_pci_driver ( cs5535_mfd_driver ) ;
2010-11-26 13:52:35 +03:00
MODULE_AUTHOR ( " Andres Salomon <dilinger@queued.net> " ) ;
MODULE_DESCRIPTION ( " MFD driver for CS5535/CS5536 southbridge's ISA PCI device " ) ;
MODULE_LICENSE ( " GPL " ) ;