12dca0b997f0659a7064eeb594ebdcd2678a74ac
[openwrt/staging/yousong.git] / target / linux / rdc / patches-2.6.30 / 001-rdc321x_mfd_southbridge.patch
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.
5
6 Signed-off-by: Florian Fainelli <florian@openwrt.org>
7 ---
8 Changes from v2:
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
13
14 --- a/drivers/mfd/Kconfig
15 +++ b/drivers/mfd/Kconfig
16 @@ -241,6 +241,15 @@ config PCF50633_GPIO
17 Say yes here if you want to include support GPIO for pins on
18 the PCF50633 chip.
19
20 +config MFD_RDC321X
21 + tristate "Support for RDC-R321x southbridge"
22 + select MFD_CORE
23 + depends on PCI
24 + help
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.
28 +
29 endmenu
30
31 menu "Multimedia Capabilities Port drivers"
32 --- a/drivers/mfd/Makefile
33 +++ b/drivers/mfd/Makefile
34 @@ -40,4 +40,6 @@ obj-$(CONFIG_PMIC_DA903X) += da903x.o
35
36 obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o
37 obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
38 -obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
39 \ No newline at end of file
40 +obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
41 +
42 +obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
43 --- /dev/null
44 +++ b/drivers/mfd/rdc321x-southbridge.c
45 @@ -0,0 +1,123 @@
46 +/*
47 + * RDC321x MFD southbrige driver
48 + *
49 + * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
50 + * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
51 + *
52 + * This program is free software; you can redistribute it and/or modify
53 + * it under the terms of the GNU General Public License as published by
54 + * the Free Software Foundation; either version 2 of the License, or
55 + * (at your option) any later version.
56 + *
57 + * This program is distributed in the hope that it will be useful,
58 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
59 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60 + * GNU General Public License for more details.
61 + *
62 + * You should have received a copy of the GNU General Public License
63 + * along with this program; if not, write to the Free Software
64 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
65 + *
66 + */
67 +#include <linux/init.h>
68 +#include <linux/module.h>
69 +#include <linux/kernel.h>
70 +#include <linux/platform_device.h>
71 +#include <linux/pci.h>
72 +#include <linux/mfd/core.h>
73 +#include <linux/mfd/rdc321x.h>
74 +
75 +static struct rdc321x_wdt_pdata rdc321x_wdt_pdata;
76 +
77 +static struct resource rdc321x_wdt_resource[] = {
78 + {
79 + .name = "wdt-reg",
80 + .start = RDC321X_WDT_CTRL,
81 + .end = RDC321X_WDT_CTRL + 0x3,
82 + .flags = IORESOURCE_MEM,
83 + }
84 +};
85 +
86 +static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = {
87 + .max_gpios = RDC321X_MAX_GPIO,
88 +};
89 +
90 +static struct resource rdc321x_gpio_resources[] = {
91 + {
92 + .name = "gpio-reg1",
93 + .start = RDC321X_GPIO_CTRL_REG1,
94 + .end = RDC321X_GPIO_CTRL_REG1 + 0x7,
95 + .flags = IORESOURCE_MEM,
96 + }, {
97 + .name = "gpio-reg2",
98 + .start = RDC321X_GPIO_CTRL_REG2,
99 + .end = RDC321X_GPIO_CTRL_REG2 + 0x7,
100 + .flags = IORESOURCE_MEM,
101 + }
102 +};
103 +
104 +static struct mfd_cell rdc321x_sb_cells[] = {
105 + {
106 + .name = "rdc321x-wdt",
107 + .resources = rdc321x_wdt_resource,
108 + .num_resources = ARRAY_SIZE(rdc321x_wdt_resource),
109 + .driver_data = &rdc321x_wdt_pdata,
110 + }, {
111 + .name = "rdc321x-gpio",
112 + .resources = rdc321x_gpio_resources,
113 + .num_resources = ARRAY_SIZE(rdc321x_gpio_resources),
114 + .driver_data = &rdc321x_gpio_pdata,
115 + },
116 +};
117 +
118 +static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,
119 + const struct pci_device_id *ent)
120 +{
121 + int err;
122 +
123 + err = pci_enable_device(pdev);
124 + if (err) {
125 + dev_err(&pdev->dev, "failed to enable device\n");
126 + return err;
127 + }
128 +
129 + rdc321x_gpio_pdata.sb_pdev = pdev;
130 + rdc321x_wdt_pdata.sb_pdev = pdev;
131 +
132 + return mfd_add_devices(&pdev->dev, -1,
133 + rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0);
134 +}
135 +
136 +static void __devexit rdc321x_sb_remove(struct pci_dev *pdev)
137 +{
138 + mfd_remove_devices(&pdev->dev);
139 +}
140 +
141 +static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = {
142 + { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) },
143 + {}
144 +};
145 +
146 +static struct pci_driver rdc321x_sb_driver = {
147 + .name = "RDC321x Southbridge",
148 + .id_table = rdc321x_sb_table,
149 + .probe = rdc321x_sb_probe,
150 + .remove = __devexit_p(rdc321x_sb_remove),
151 +};
152 +
153 +static int __init rdc321x_sb_init(void)
154 +{
155 + return pci_register_driver(&rdc321x_sb_driver);
156 +}
157 +
158 +static void __exit rdc321x_sb_exit(void)
159 +{
160 + pci_unregister_driver(&rdc321x_sb_driver);
161 +}
162 +
163 +module_init(rdc321x_sb_init);
164 +module_exit(rdc321x_sb_exit);
165 +
166 +MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
167 +MODULE_LICENSE("GPL");
168 +MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver");
169 --- /dev/null
170 +++ b/include/linux/mfd/rdc321x.h
171 @@ -0,0 +1,26 @@
172 +#ifndef __RDC321X_MFD_H
173 +#define __RDC321X_MFD_H
174 +
175 +#include <linux/types.h>
176 +#include <linux/pci.h>
177 +
178 +/* Offsets to be accessed in the southbridge PCI
179 + * device configuration register */
180 +#define RDC321X_WDT_CTRL 0x44
181 +#define RDC321X_GPIO_CTRL_REG1 0x48
182 +#define RDC321X_GPIO_DATA_REG1 0x4c
183 +#define RDC321X_GPIO_CTRL_REG2 0x84
184 +#define RDC321X_GPIO_DATA_REG2 0x88
185 +
186 +#define RDC321X_MAX_GPIO 58
187 +
188 +struct rdc321x_gpio_pdata {
189 + struct pci_dev *sb_pdev;
190 + unsigned max_gpios;
191 +};
192 +
193 +struct rdc321x_wdt_pdata {
194 + struct pci_dev *sb_pdev;
195 +};
196 +
197 +#endif /* __RDC321X_MFD_H */