Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: Add support for the RDC321x southbridge

This patch adds a new MFD driver for the RDC321x southbridge. This southbridge
is always present in the RDC321x System-on-a-Chip and provides access to some
GPIOs as well as a watchdog. Access to these two functions is done using the
southbridge PCI device configuration space.

Signed-off-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Florian Fainelli and committed by
Samuel Ortiz
e090d506 f322d5f0

+159
+9
drivers/mfd/Kconfig
··· 409 409 LPC bridge function of the Intel SCH provides support for 410 410 System Management Bus and General Purpose I/O. 411 411 412 + config MFD_RDC321X 413 + tristate "Support for RDC-R321x southbridge" 414 + select MFD_CORE 415 + depends on PCI 416 + help 417 + Say yes here if you want to have support for the RDC R-321x SoC 418 + southbridge which provides access to GPIOs and Watchdog using the 419 + southbridge PCI device configuration space. 420 + 412 421 endmenu 413 422 414 423 menu "Multimedia Capabilities Port drivers"
+1
drivers/mfd/Makefile
··· 64 64 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 65 65 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 66 66 obj-$(CONFIG_LPC_SCH) += lpc_sch.o 67 + obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
+123
drivers/mfd/rdc321x-southbridge.c
··· 1 + /* 2 + * RDC321x MFD southbrige driver 3 + * 4 + * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org> 5 + * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 + * 21 + */ 22 + #include <linux/init.h> 23 + #include <linux/module.h> 24 + #include <linux/kernel.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/pci.h> 27 + #include <linux/mfd/core.h> 28 + #include <linux/mfd/rdc321x.h> 29 + 30 + static struct rdc321x_wdt_pdata rdc321x_wdt_pdata; 31 + 32 + static struct resource rdc321x_wdt_resource[] = { 33 + { 34 + .name = "wdt-reg", 35 + .start = RDC321X_WDT_CTRL, 36 + .end = RDC321X_WDT_CTRL + 0x3, 37 + .flags = IORESOURCE_MEM, 38 + } 39 + }; 40 + 41 + static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = { 42 + .max_gpios = RDC321X_MAX_GPIO, 43 + }; 44 + 45 + static struct resource rdc321x_gpio_resources[] = { 46 + { 47 + .name = "gpio-reg1", 48 + .start = RDC321X_GPIO_CTRL_REG1, 49 + .end = RDC321X_GPIO_CTRL_REG1 + 0x7, 50 + .flags = IORESOURCE_MEM, 51 + }, { 52 + .name = "gpio-reg2", 53 + .start = RDC321X_GPIO_CTRL_REG2, 54 + .end = RDC321X_GPIO_CTRL_REG2 + 0x7, 55 + .flags = IORESOURCE_MEM, 56 + } 57 + }; 58 + 59 + static struct mfd_cell rdc321x_sb_cells[] = { 60 + { 61 + .name = "rdc321x-wdt", 62 + .resources = rdc321x_wdt_resource, 63 + .num_resources = ARRAY_SIZE(rdc321x_wdt_resource), 64 + .driver_data = &rdc321x_wdt_pdata, 65 + }, { 66 + .name = "rdc321x-gpio", 67 + .resources = rdc321x_gpio_resources, 68 + .num_resources = ARRAY_SIZE(rdc321x_gpio_resources), 69 + .driver_data = &rdc321x_gpio_pdata, 70 + }, 71 + }; 72 + 73 + static int __devinit rdc321x_sb_probe(struct pci_dev *pdev, 74 + const struct pci_device_id *ent) 75 + { 76 + int err; 77 + 78 + err = pci_enable_device(pdev); 79 + if (err) { 80 + dev_err(&pdev->dev, "failed to enable device\n"); 81 + return err; 82 + } 83 + 84 + rdc321x_gpio_pdata.sb_pdev = pdev; 85 + rdc321x_wdt_pdata.sb_pdev = pdev; 86 + 87 + return mfd_add_devices(&pdev->dev, -1, 88 + rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); 89 + } 90 + 91 + static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) 92 + { 93 + mfd_remove_devices(&pdev->dev); 94 + } 95 + 96 + static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = { 97 + { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) }, 98 + {} 99 + }; 100 + 101 + static struct pci_driver rdc321x_sb_driver = { 102 + .name = "RDC321x Southbridge", 103 + .id_table = rdc321x_sb_table, 104 + .probe = rdc321x_sb_probe, 105 + .remove = __devexit_p(rdc321x_sb_remove), 106 + }; 107 + 108 + static int __init rdc321x_sb_init(void) 109 + { 110 + return pci_register_driver(&rdc321x_sb_driver); 111 + } 112 + 113 + static void __exit rdc321x_sb_exit(void) 114 + { 115 + pci_unregister_driver(&rdc321x_sb_driver); 116 + } 117 + 118 + module_init(rdc321x_sb_init); 119 + module_exit(rdc321x_sb_exit); 120 + 121 + MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); 122 + MODULE_LICENSE("GPL"); 123 + MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver");
+26
include/linux/mfd/rdc321x.h
··· 1 + #ifndef __RDC321X_MFD_H 2 + #define __RDC321X_MFD_H 3 + 4 + #include <linux/types.h> 5 + #include <linux/pci.h> 6 + 7 + /* Offsets to be accessed in the southbridge PCI 8 + * device configuration register */ 9 + #define RDC321X_WDT_CTRL 0x44 10 + #define RDC321X_GPIO_CTRL_REG1 0x48 11 + #define RDC321X_GPIO_DATA_REG1 0x4c 12 + #define RDC321X_GPIO_CTRL_REG2 0x84 13 + #define RDC321X_GPIO_DATA_REG2 0x88 14 + 15 + #define RDC321X_MAX_GPIO 58 16 + 17 + struct rdc321x_gpio_pdata { 18 + struct pci_dev *sb_pdev; 19 + unsigned max_gpios; 20 + }; 21 + 22 + struct rdc321x_wdt_pdata { 23 + struct pci_dev *sb_pdev; 24 + }; 25 + 26 + #endif /* __RDC321X_MFD_H */