kernel: update linux 3.0 to 3.0.17
[openwrt.git] / target / linux / rdc / patches-2.6.32 / 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 @@ -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..
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 @@ -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
38 +
39 +obj-$(CONFIG_MFD_RDC321X)      += rdc321x-southbridge.o
40 --- /dev/null
41 +++ b/drivers/mfd/rdc321x-southbridge.c
42 @@ -0,0 +1,123 @@
43 +/*
44 + * RDC321x MFD southbrige driver
45 + *
46 + * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
47 + * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com>
48 + *
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.
53 + *
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.
58 + *
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.
62 + *
63 + */
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>
71 +
72 +static struct rdc321x_wdt_pdata rdc321x_wdt_pdata;
73 +
74 +static struct resource rdc321x_wdt_resource[] = {
75 +       {
76 +               .name   = "wdt-reg",
77 +               .start  = RDC321X_WDT_CTRL,
78 +               .end    = RDC321X_WDT_CTRL + 0x3,
79 +               .flags  = IORESOURCE_IO,
80 +       }
81 +};
82 +
83 +static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = {
84 +       .max_gpios      = RDC321X_MAX_GPIO,
85 +};
86 +
87 +static struct resource rdc321x_gpio_resources[] = {
88 +       {
89 +               .name   = "gpio-reg1",
90 +               .start  = RDC321X_GPIO_CTRL_REG1,
91 +               .end    = RDC321X_GPIO_CTRL_REG1 + 0x7,
92 +               .flags  = IORESOURCE_IO,
93 +       }, {
94 +               .name   = "gpio-reg2",
95 +               .start  = RDC321X_GPIO_CTRL_REG2,
96 +               .end    = RDC321X_GPIO_CTRL_REG2 + 0x7,
97 +               .flags  = IORESOURCE_IO,
98 +       }
99 +};
100 +
101 +static struct mfd_cell rdc321x_sb_cells[] = {
102 +       {
103 +               .name           = "rdc321x-wdt",
104 +               .resources      = rdc321x_wdt_resource,
105 +               .num_resources  = ARRAY_SIZE(rdc321x_wdt_resource),
106 +               .driver_data    = &rdc321x_wdt_pdata,
107 +       }, {
108 +               .name           = "rdc321x-gpio",
109 +               .resources      = rdc321x_gpio_resources,
110 +               .num_resources  = ARRAY_SIZE(rdc321x_gpio_resources),
111 +               .driver_data    = &rdc321x_gpio_pdata,
112 +       },
113 +};
114 +
115 +static int __devinit rdc321x_sb_probe(struct pci_dev *pdev,
116 +                                       const struct pci_device_id *ent)
117 +{
118 +       int err;
119 +
120 +       err = pci_enable_device(pdev);
121 +       if (err) {
122 +               dev_err(&pdev->dev, "failed to enable device\n");
123 +               return err;
124 +       }
125 +
126 +       rdc321x_gpio_pdata.sb_pdev = pdev;
127 +       rdc321x_wdt_pdata.sb_pdev = pdev;
128 +
129 +       return mfd_add_devices(&pdev->dev, -1,
130 +               rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0);
131 +}
132 +
133 +static void __devexit rdc321x_sb_remove(struct pci_dev *pdev)
134 +{
135 +       mfd_remove_devices(&pdev->dev);
136 +}
137 +
138 +static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = {
139 +       { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) },
140 +       {}
141 +};
142 +
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),
148 +};
149 +
150 +static int __init rdc321x_sb_init(void)
151 +{
152 +       return pci_register_driver(&rdc321x_sb_driver);
153 +}
154 +
155 +static void __exit rdc321x_sb_exit(void)
156 +{
157 +       pci_unregister_driver(&rdc321x_sb_driver);
158 +}
159 +
160 +module_init(rdc321x_sb_init);
161 +module_exit(rdc321x_sb_exit);
162 +
163 +MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
164 +MODULE_LICENSE("GPL");
165 +MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver");
166 --- /dev/null
167 +++ b/include/linux/mfd/rdc321x.h
168 @@ -0,0 +1,26 @@
169 +#ifndef __RDC321X_MFD_H
170 +#define __RDC321X_MFD_H
171 +
172 +#include <linux/types.h>
173 +#include <linux/pci.h>
174 +
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
182 +
183 +#define RDC321X_MAX_GPIO       58
184 +
185 +struct rdc321x_gpio_pdata {
186 +       struct pci_dev *sb_pdev;
187 +       unsigned max_gpios;
188 +};
189 +
190 +struct rdc321x_wdt_pdata {
191 +       struct pci_dev *sb_pdev;
192 +};
193 +
194 +#endif /* __RDC321X_MFD_H */