panic on unrecovered NMI, thanks rtz2
[openwrt/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_MEM,
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_MEM,
93 + }, {
94 + .name = "gpio-reg2",
95 + .start = RDC321X_GPIO_CTRL_REG2,
96 + .end = RDC321X_GPIO_CTRL_REG2 + 0x7,
97 + .flags = IORESOURCE_MEM,
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 */