diff options
-rw-r--r-- | drivers/mfd/Kconfig | 9 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 3 | ||||
-rw-r--r-- | drivers/mfd/rdc321x-southbridge.c | 123 | ||||
-rw-r--r-- | include/linux/mfd/rdc321x.h | 26 |
4 files changed, 160 insertions, 1 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 3c6a9860dd9c..93d0e31c0438 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -409,6 +409,15 @@ config LPC_SCH | |||
409 | LPC bridge function of the Intel SCH provides support for | 409 | LPC bridge function of the Intel SCH provides support for |
410 | System Management Bus and General Purpose I/O. | 410 | System Management Bus and General Purpose I/O. |
411 | 411 | ||
412 | config MFD_RDC321X | ||
413 | tristate "Support for RDC-R321x southbridge" | ||
414 | select MFD_CORE | ||
415 | depends on PCI | ||
416 | help | ||
417 | Say yes here if you want to have support for the RDC R-321x SoC | ||
418 | southbridge which provides access to GPIOs and Watchdog using the | ||
419 | southbridge PCI device configuration space. | ||
420 | |||
412 | endmenu | 421 | endmenu |
413 | 422 | ||
414 | menu "Multimedia Capabilities Port drivers" | 423 | menu "Multimedia Capabilities Port drivers" |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 87935f967aa0..f177e064b31b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -63,4 +63,5 @@ obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o | |||
63 | obj-$(CONFIG_AB4500_CORE) += ab4500-core.o | 63 | obj-$(CONFIG_AB4500_CORE) += ab4500-core.o |
64 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o | 64 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o |
65 | obj-$(CONFIG_PMIC_ADP5520) += adp5520.o | 65 | obj-$(CONFIG_PMIC_ADP5520) += adp5520.o |
66 | obj-$(CONFIG_LPC_SCH) += lpc_sch.o \ No newline at end of file | 66 | obj-$(CONFIG_LPC_SCH) += lpc_sch.o |
67 | obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o | ||
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c new file mode 100644 index 000000000000..256dd560bd48 --- /dev/null +++ b/drivers/mfd/rdc321x-southbridge.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * RDC321x MFD southbrige driver | ||
3 | * | ||
4 | * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org> | ||
5 | * Copyright (C) 2010 Bernhard Loos <bernhardloos@googlemail.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | */ | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/pci.h> | ||
27 | #include <linux/mfd/core.h> | ||
28 | #include <linux/mfd/rdc321x.h> | ||
29 | |||
30 | static struct rdc321x_wdt_pdata rdc321x_wdt_pdata; | ||
31 | |||
32 | static struct resource rdc321x_wdt_resource[] = { | ||
33 | { | ||
34 | .name = "wdt-reg", | ||
35 | .start = RDC321X_WDT_CTRL, | ||
36 | .end = RDC321X_WDT_CTRL + 0x3, | ||
37 | .flags = IORESOURCE_MEM, | ||
38 | } | ||
39 | }; | ||
40 | |||
41 | static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = { | ||
42 | .max_gpios = RDC321X_MAX_GPIO, | ||
43 | }; | ||
44 | |||
45 | static struct resource rdc321x_gpio_resources[] = { | ||
46 | { | ||
47 | .name = "gpio-reg1", | ||
48 | .start = RDC321X_GPIO_CTRL_REG1, | ||
49 | .end = RDC321X_GPIO_CTRL_REG1 + 0x7, | ||
50 | .flags = IORESOURCE_MEM, | ||
51 | }, { | ||
52 | .name = "gpio-reg2", | ||
53 | .start = RDC321X_GPIO_CTRL_REG2, | ||
54 | .end = RDC321X_GPIO_CTRL_REG2 + 0x7, | ||
55 | .flags = IORESOURCE_MEM, | ||
56 | } | ||
57 | }; | ||
58 | |||
59 | static struct mfd_cell rdc321x_sb_cells[] = { | ||
60 | { | ||
61 | .name = "rdc321x-wdt", | ||
62 | .resources = rdc321x_wdt_resource, | ||
63 | .num_resources = ARRAY_SIZE(rdc321x_wdt_resource), | ||
64 | .driver_data = &rdc321x_wdt_pdata, | ||
65 | }, { | ||
66 | .name = "rdc321x-gpio", | ||
67 | .resources = rdc321x_gpio_resources, | ||
68 | .num_resources = ARRAY_SIZE(rdc321x_gpio_resources), | ||
69 | .driver_data = &rdc321x_gpio_pdata, | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | static int __devinit rdc321x_sb_probe(struct pci_dev *pdev, | ||
74 | const struct pci_device_id *ent) | ||
75 | { | ||
76 | int err; | ||
77 | |||
78 | err = pci_enable_device(pdev); | ||
79 | if (err) { | ||
80 | dev_err(&pdev->dev, "failed to enable device\n"); | ||
81 | return err; | ||
82 | } | ||
83 | |||
84 | rdc321x_gpio_pdata.sb_pdev = pdev; | ||
85 | rdc321x_wdt_pdata.sb_pdev = pdev; | ||
86 | |||
87 | return mfd_add_devices(&pdev->dev, -1, | ||
88 | rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); | ||
89 | } | ||
90 | |||
91 | static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) | ||
92 | { | ||
93 | mfd_remove_devices(&pdev->dev); | ||
94 | } | ||
95 | |||
96 | static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = { | ||
97 | { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) }, | ||
98 | {} | ||
99 | }; | ||
100 | |||
101 | static struct pci_driver rdc321x_sb_driver = { | ||
102 | .name = "RDC321x Southbridge", | ||
103 | .id_table = rdc321x_sb_table, | ||
104 | .probe = rdc321x_sb_probe, | ||
105 | .remove = __devexit_p(rdc321x_sb_remove), | ||
106 | }; | ||
107 | |||
108 | static int __init rdc321x_sb_init(void) | ||
109 | { | ||
110 | return pci_register_driver(&rdc321x_sb_driver); | ||
111 | } | ||
112 | |||
113 | static void __exit rdc321x_sb_exit(void) | ||
114 | { | ||
115 | pci_unregister_driver(&rdc321x_sb_driver); | ||
116 | } | ||
117 | |||
118 | module_init(rdc321x_sb_init); | ||
119 | module_exit(rdc321x_sb_exit); | ||
120 | |||
121 | MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); | ||
122 | MODULE_LICENSE("GPL"); | ||
123 | MODULE_DESCRIPTION("RDC R-321x MFD southbridge driver"); | ||
diff --git a/include/linux/mfd/rdc321x.h b/include/linux/mfd/rdc321x.h new file mode 100644 index 000000000000..4bdf19c8eedf --- /dev/null +++ b/include/linux/mfd/rdc321x.h | |||
@@ -0,0 +1,26 @@ | |||
1 | #ifndef __RDC321X_MFD_H | ||
2 | #define __RDC321X_MFD_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | #include <linux/pci.h> | ||
6 | |||
7 | /* Offsets to be accessed in the southbridge PCI | ||
8 | * device configuration register */ | ||
9 | #define RDC321X_WDT_CTRL 0x44 | ||
10 | #define RDC321X_GPIO_CTRL_REG1 0x48 | ||
11 | #define RDC321X_GPIO_DATA_REG1 0x4c | ||
12 | #define RDC321X_GPIO_CTRL_REG2 0x84 | ||
13 | #define RDC321X_GPIO_DATA_REG2 0x88 | ||
14 | |||
15 | #define RDC321X_MAX_GPIO 58 | ||
16 | |||
17 | struct rdc321x_gpio_pdata { | ||
18 | struct pci_dev *sb_pdev; | ||
19 | unsigned max_gpios; | ||
20 | }; | ||
21 | |||
22 | struct rdc321x_wdt_pdata { | ||
23 | struct pci_dev *sb_pdev; | ||
24 | }; | ||
25 | |||
26 | #endif /* __RDC321X_MFD_H */ | ||