1 This patch adds a new MFD driver for the RDC321x southbridge. This southbridge
2 is always present in the RDC321x System-on-a-Chip and provides access to some
3 GPIOs as well as a watchdog. Access to these two functions is done using the
4 southbridge PCI device configuration space.
6 Signed-off-by: Florian Fainelli <florian@openwrt.org>
9 - pass the pci_dev pointer to MFD cell drivers as platform_data
10 - remove the printk(KERN_ERR and use dev_err instead
11 - removed pci_dev accessors
12 - use DEFINE_PCI_DEVICE_TABLE
14 --- a/drivers/mfd/Kconfig
15 +++ b/drivers/mfd/Kconfig
16 @@ -305,6 +305,15 @@ config EZX_PCAP
17 This enables the PCAP ASIC present on EZX Phones. This is
18 needed for MMC, TouchScreen, Sound, USB, etc..
21 + tristate "Support for RDC-R321x southbridge"
25 + Say yes here if you want to have support for the RDC R-321x SoC
26 + southbridge which provides access to GPIOs and Watchdog using the
27 + southbridge PCI device configuration space.
31 menu "Multimedia Capabilities Port drivers"
32 --- a/drivers/mfd/Makefile
33 +++ b/drivers/mfd/Makefile
34 @@ -50,3 +50,5 @@ obj-$(CONFIG_PCF50633_ADC) += pcf50633-a
35 obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
36 obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
37 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
39 +obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
41 +++ b/drivers/mfd/rdc321x-southbridge.c
44 + * RDC321x MFD southbrige driver
46 + * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
47 + * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
49 + * This program is free software; you can redistribute it and/or modify
50 + * it under the terms of the GNU General Public License as published by
51 + * the Free Software Foundation; either version 2 of the License, or
52 + * (at your option) any later version.
54 + * This program is distributed in the hope that it will be useful,
55 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
56 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57 + * GNU General Public License for more details.
59 + * You should have received a copy of the GNU General Public License
60 + * along with this program; if not, write to the Free Software
61 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
64 +#include <linux/init.h>
65 +#include <linux/module.h>
66 +#include <linux/kernel.h>
67 +#include <linux/platform_device.h>
68 +#include <linux/pci.h>
69 +#include <linux/mfd/core.h>
70 +#include <linux/mfd/rdc321x.h>
72 +static struct rdc321x_wdt_pdata rdc321x_wdt_pdata;
74 +static struct resource rdc321x_wdt_resource[] = {
77 + .start = RDC321X_WDT_CTRL,
78 + .end = RDC321X_WDT_CTRL + 0x3,
79 + .flags = IORESOURCE_IO,
83 +static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = {
84 + .max_gpios = RDC321X_MAX_GPIO,
87 +static struct resource rdc321x_gpio_resources[] = {
89 + .name = "gpio-reg1",
90 + .start = RDC321X_GPIO_CTRL_REG1,
91 + .end = RDC321X_GPIO_CTRL_REG1 + 0x7,
92 + .flags = IORESOURCE_IO,
94 + .name = "gpio-reg2",
95 + .start = RDC321X_GPIO_CTRL_REG2,
96 + .end = RDC321X_GPIO_CTRL_REG2 + 0x7,
97 + .flags = IORESOURCE_IO,
101 +static struct mfd_cell rdc321x_sb_cells[] = {
103 + .name = "rdc321x-wdt",
104 + .resources = rdc321x_wdt_resource,
105 + .num_resources = ARRAY_SIZE(rdc321x_wdt_resource),
106 + .driver_data = &rdc321x_wdt_pdata,
108 + .name = "rdc321x-gpio",
109 + .resources = rdc321x_gpio_resources,
110 + .num_resources = ARRAY_SIZE(rdc321x_gpio_resources),
111 + .driver_data = &rdc321x_gpio_pdata,
115 +static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,
116 + const struct pci_device_id *ent)
120 + err = pci_enable_device(pdev);
122 + dev_err(&pdev->dev, "failed to enable device\n");
126 + rdc321x_gpio_pdata.sb_pdev = pdev;
127 + rdc321x_wdt_pdata.sb_pdev = pdev;
129 + return mfd_add_devices(&pdev->dev, -1,
130 + rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0);
133 +static void __devexit rdc321x_sb_remove(struct pci_dev *pdev)
135 + mfd_remove_devices(&pdev->dev);
138 +static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = {
139 + { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) },
143 +static struct pci_driver rdc321x_sb_driver = {
144 + .name = "RDC321x Southbridge",
145 + .id_table = rdc321x_sb_table,
146 + .probe = rdc321x_sb_probe,
147 + .remove = __devexit_p(rdc321x_sb_remove),
150 +static int __init rdc321x_sb_init(void)
152 + return pci_register_driver(&rdc321x_sb_driver);
155 +static void __exit rdc321x_sb_exit(void)
157 + pci_unregister_driver(&rdc321x_sb_driver);
160 +module_init(rdc321x_sb_init);
161 +module_exit(rdc321x_sb_exit);
163 +MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
164 +MODULE_LICENSE("GPL");
165 +MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver");
167 +++ b/include/linux/mfd/rdc321x.h
169 +#ifndef __RDC321X_MFD_H
170 +#define __RDC321X_MFD_H
172 +#include <linux/types.h>
173 +#include <linux/pci.h>
175 +/* Offsets to be accessed in the southbridge PCI
176 + * device configuration register */
177 +#define RDC321X_WDT_CTRL 0x44
178 +#define RDC321X_GPIO_CTRL_REG1 0x48
179 +#define RDC321X_GPIO_DATA_REG1 0x4c
180 +#define RDC321X_GPIO_CTRL_REG2 0x84
181 +#define RDC321X_GPIO_DATA_REG2 0x88
183 +#define RDC321X_MAX_GPIO 58
185 +struct rdc321x_gpio_pdata {
186 + struct pci_dev *sb_pdev;
187 + unsigned max_gpios;
190 +struct rdc321x_wdt_pdata {
191 + struct pci_dev *sb_pdev;
194 +#endif /* __RDC321X_MFD_H */