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