blob: 7f773afeb340a8cfb1b22a5774c099d051ee52e1 [file] [log] [blame]
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -07001/*
2 * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 */
17#include <linux/kernel.h>
18#include <linux/pci.h>
19#include <linux/gpio.h>
20
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -070021struct pch_regs {
22 u32 ien;
23 u32 istatus;
24 u32 idisp;
25 u32 iclr;
26 u32 imask;
27 u32 imaskclr;
28 u32 po;
29 u32 pi;
30 u32 pm;
31 u32 im0;
32 u32 im1;
Tomoya MORINAGAe98bed72011-07-21 09:19:58 +090033 u32 reserved[3];
34 u32 gpio_use_sel;
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -070035 u32 reset;
36};
37
Tomoya MORINAGAd4260e62011-07-21 09:19:57 +090038enum pch_type_t {
39 INTEL_EG20T_PCH,
40 OKISEMI_ML7223m_IOH, /* OKISEMI ML7223 IOH PCIe Bus-m */
41 OKISEMI_ML7223n_IOH /* OKISEMI ML7223 IOH PCIe Bus-n */
42};
43
44/* Specifies number of GPIO PINS */
45static int gpio_pins[] = {
46 [INTEL_EG20T_PCH] = 12,
47 [OKISEMI_ML7223m_IOH] = 8,
48 [OKISEMI_ML7223n_IOH] = 8,
49};
50
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -070051/**
52 * struct pch_gpio_reg_data - The register store data.
53 * @po_reg: To store contents of PO register.
54 * @pm_reg: To store contents of PM register.
Tomoya MORINAGAe98bed72011-07-21 09:19:58 +090055 * @im0_reg: To store contents of IM0 register.
56 * @im1_reg: To store contents of IM1 register.
57 * @gpio_use_sel_reg : To store contents of GPIO_USE_SEL register.
58 * (Only ML7223 Bus-n)
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -070059 */
60struct pch_gpio_reg_data {
61 u32 po_reg;
62 u32 pm_reg;
Tomoya MORINAGAe98bed72011-07-21 09:19:58 +090063 u32 im0_reg;
64 u32 im1_reg;
65 u32 gpio_use_sel_reg;
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -070066};
67
68/**
69 * struct pch_gpio - GPIO private data structure.
70 * @base: PCI base address of Memory mapped I/O register.
71 * @reg: Memory mapped PCH GPIO register list.
72 * @dev: Pointer to device structure.
73 * @gpio: Data for GPIO infrastructure.
74 * @pch_gpio_reg: Memory mapped Register data is saved here
75 * when suspend.
Tomoya MORINAGAd4260e62011-07-21 09:19:57 +090076 * @ioh: IOH ID
Tomoya MORINAGAd568a682011-07-21 09:19:55 +090077 * @spinlock: Used for register access protection in
78 * interrupt context pch_irq_mask,
79 * pch_irq_unmask and pch_irq_type;
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -070080 */
81struct pch_gpio {
82 void __iomem *base;
83 struct pch_regs __iomem *reg;
84 struct device *dev;
85 struct gpio_chip gpio;
86 struct pch_gpio_reg_data pch_gpio_reg;
87 struct mutex lock;
Tomoya MORINAGAd4260e62011-07-21 09:19:57 +090088 enum pch_type_t ioh;
Tomoya MORINAGAd568a682011-07-21 09:19:55 +090089 spinlock_t spinlock;
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -070090};
91
92static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val)
93{
94 u32 reg_val;
95 struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
96
97 mutex_lock(&chip->lock);
98 reg_val = ioread32(&chip->reg->po);
99 if (val)
100 reg_val |= (1 << nr);
101 else
102 reg_val &= ~(1 << nr);
103
104 iowrite32(reg_val, &chip->reg->po);
105 mutex_unlock(&chip->lock);
106}
107
108static int pch_gpio_get(struct gpio_chip *gpio, unsigned nr)
109{
110 struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
111
112 return ioread32(&chip->reg->pi) & (1 << nr);
113}
114
115static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
116 int val)
117{
118 struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
119 u32 pm;
120 u32 reg_val;
121
122 mutex_lock(&chip->lock);
Tomoya MORINAGAd4260e62011-07-21 09:19:57 +0900123 pm = ioread32(&chip->reg->pm) & ((1 << gpio_pins[chip->ioh]) - 1);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700124 pm |= (1 << nr);
125 iowrite32(pm, &chip->reg->pm);
126
127 reg_val = ioread32(&chip->reg->po);
128 if (val)
129 reg_val |= (1 << nr);
130 else
131 reg_val &= ~(1 << nr);
Peter Tyser88aab932011-03-25 10:04:00 -0500132 iowrite32(reg_val, &chip->reg->po);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700133
134 mutex_unlock(&chip->lock);
135
136 return 0;
137}
138
139static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
140{
141 struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio);
142 u32 pm;
143
144 mutex_lock(&chip->lock);
Tomoya MORINAGAd4260e62011-07-21 09:19:57 +0900145 pm = ioread32(&chip->reg->pm) & ((1 << gpio_pins[chip->ioh]) - 1);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700146 pm &= ~(1 << nr);
147 iowrite32(pm, &chip->reg->pm);
148 mutex_unlock(&chip->lock);
149
150 return 0;
151}
152
153/*
154 * Save register configuration and disable interrupts.
155 */
156static void pch_gpio_save_reg_conf(struct pch_gpio *chip)
157{
158 chip->pch_gpio_reg.po_reg = ioread32(&chip->reg->po);
159 chip->pch_gpio_reg.pm_reg = ioread32(&chip->reg->pm);
Tomoya MORINAGAe98bed72011-07-21 09:19:58 +0900160 chip->pch_gpio_reg.im0_reg = ioread32(&chip->reg->im0);
161 if (chip->ioh == INTEL_EG20T_PCH)
162 chip->pch_gpio_reg.im1_reg = ioread32(&chip->reg->im1);
163 if (chip->ioh == OKISEMI_ML7223n_IOH)
164 chip->pch_gpio_reg.gpio_use_sel_reg =\
165 ioread32(&chip->reg->gpio_use_sel);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700166}
167
168/*
169 * This function restores the register configuration of the GPIO device.
170 */
171static void pch_gpio_restore_reg_conf(struct pch_gpio *chip)
172{
173 /* to store contents of PO register */
174 iowrite32(chip->pch_gpio_reg.po_reg, &chip->reg->po);
175 /* to store contents of PM register */
176 iowrite32(chip->pch_gpio_reg.pm_reg, &chip->reg->pm);
Tomoya MORINAGAe98bed72011-07-21 09:19:58 +0900177 iowrite32(chip->pch_gpio_reg.im0_reg, &chip->reg->im0);
178 if (chip->ioh == INTEL_EG20T_PCH)
179 iowrite32(chip->pch_gpio_reg.im1_reg, &chip->reg->im1);
180 if (chip->ioh == OKISEMI_ML7223n_IOH)
181 iowrite32(chip->pch_gpio_reg.gpio_use_sel_reg,
182 &chip->reg->gpio_use_sel);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700183}
184
185static void pch_gpio_setup(struct pch_gpio *chip)
186{
187 struct gpio_chip *gpio = &chip->gpio;
188
189 gpio->label = dev_name(chip->dev);
190 gpio->owner = THIS_MODULE;
191 gpio->direction_input = pch_gpio_direction_input;
192 gpio->get = pch_gpio_get;
193 gpio->direction_output = pch_gpio_direction_output;
194 gpio->set = pch_gpio_set;
195 gpio->dbg_show = NULL;
196 gpio->base = -1;
Tomoya MORINAGAd4260e62011-07-21 09:19:57 +0900197 gpio->ngpio = gpio_pins[chip->ioh];
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700198 gpio->can_sleep = 0;
199}
200
201static int __devinit pch_gpio_probe(struct pci_dev *pdev,
202 const struct pci_device_id *id)
203{
204 s32 ret;
205 struct pch_gpio *chip;
206
207 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
208 if (chip == NULL)
209 return -ENOMEM;
210
211 chip->dev = &pdev->dev;
212 ret = pci_enable_device(pdev);
213 if (ret) {
214 dev_err(&pdev->dev, "%s : pci_enable_device FAILED", __func__);
215 goto err_pci_enable;
216 }
217
218 ret = pci_request_regions(pdev, KBUILD_MODNAME);
219 if (ret) {
220 dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret);
221 goto err_request_regions;
222 }
223
224 chip->base = pci_iomap(pdev, 1, 0);
225 if (chip->base == 0) {
226 dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
227 ret = -ENOMEM;
228 goto err_iomap;
229 }
230
Tomoya MORINAGAd4260e62011-07-21 09:19:57 +0900231 if (pdev->device == 0x8803)
232 chip->ioh = INTEL_EG20T_PCH;
233 else if (pdev->device == 0x8014)
234 chip->ioh = OKISEMI_ML7223m_IOH;
235 else if (pdev->device == 0x8043)
236 chip->ioh = OKISEMI_ML7223n_IOH;
237
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700238 chip->reg = chip->base;
239 pci_set_drvdata(pdev, chip);
240 mutex_init(&chip->lock);
241 pch_gpio_setup(chip);
242 ret = gpiochip_add(&chip->gpio);
243 if (ret) {
244 dev_err(&pdev->dev, "PCH gpio: Failed to register GPIO\n");
245 goto err_gpiochip_add;
246 }
247
248 return 0;
249
250err_gpiochip_add:
251 pci_iounmap(pdev, chip->base);
252
253err_iomap:
254 pci_release_regions(pdev);
255
256err_request_regions:
257 pci_disable_device(pdev);
258
259err_pci_enable:
260 kfree(chip);
261 dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret);
262 return ret;
263}
264
265static void __devexit pch_gpio_remove(struct pci_dev *pdev)
266{
267 int err;
268 struct pch_gpio *chip = pci_get_drvdata(pdev);
269
270 err = gpiochip_remove(&chip->gpio);
271 if (err)
272 dev_err(&pdev->dev, "Failed gpiochip_remove\n");
273
274 pci_iounmap(pdev, chip->base);
275 pci_release_regions(pdev);
276 pci_disable_device(pdev);
277 kfree(chip);
278}
279
280#ifdef CONFIG_PM
281static int pch_gpio_suspend(struct pci_dev *pdev, pm_message_t state)
282{
283 s32 ret;
284 struct pch_gpio *chip = pci_get_drvdata(pdev);
Tomoya MORINAGAd568a682011-07-21 09:19:55 +0900285 unsigned long flags;
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700286
Tomoya MORINAGAd568a682011-07-21 09:19:55 +0900287 spin_lock_irqsave(&chip->spinlock, flags);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700288 pch_gpio_save_reg_conf(chip);
Tomoya MORINAGAd568a682011-07-21 09:19:55 +0900289 spin_unlock_irqrestore(&chip->spinlock, flags);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700290
291 ret = pci_save_state(pdev);
292 if (ret) {
293 dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret);
294 return ret;
295 }
296 pci_disable_device(pdev);
297 pci_set_power_state(pdev, PCI_D0);
298 ret = pci_enable_wake(pdev, PCI_D0, 1);
299 if (ret)
300 dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret);
301
302 return 0;
303}
304
305static int pch_gpio_resume(struct pci_dev *pdev)
306{
307 s32 ret;
308 struct pch_gpio *chip = pci_get_drvdata(pdev);
Tomoya MORINAGAd568a682011-07-21 09:19:55 +0900309 unsigned long flags;
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700310
311 ret = pci_enable_wake(pdev, PCI_D0, 0);
312
313 pci_set_power_state(pdev, PCI_D0);
314 ret = pci_enable_device(pdev);
315 if (ret) {
316 dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret);
317 return ret;
318 }
319 pci_restore_state(pdev);
320
Tomoya MORINAGAd568a682011-07-21 09:19:55 +0900321 spin_lock_irqsave(&chip->spinlock, flags);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700322 iowrite32(0x01, &chip->reg->reset);
323 iowrite32(0x00, &chip->reg->reset);
324 pch_gpio_restore_reg_conf(chip);
Tomoya MORINAGAd568a682011-07-21 09:19:55 +0900325 spin_unlock_irqrestore(&chip->spinlock, flags);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700326
327 return 0;
328}
329#else
330#define pch_gpio_suspend NULL
331#define pch_gpio_resume NULL
332#endif
333
Tomoya MORINAGAbc786cc2011-05-09 19:58:49 +0900334#define PCI_VENDOR_ID_ROHM 0x10DB
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700335static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = {
336 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) },
Tomoya MORINAGAbc786cc2011-05-09 19:58:49 +0900337 { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) },
Tomoya MORINAGAc3520a12011-07-21 09:19:56 +0900338 { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8043) },
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700339 { 0, }
340};
Axel Lin19234cd2011-03-11 14:58:30 -0800341MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id);
Tomoya MORINAGA04c17aa82010-10-27 15:33:21 -0700342
343static struct pci_driver pch_gpio_driver = {
344 .name = "pch_gpio",
345 .id_table = pch_gpio_pcidev_id,
346 .probe = pch_gpio_probe,
347 .remove = __devexit_p(pch_gpio_remove),
348 .suspend = pch_gpio_suspend,
349 .resume = pch_gpio_resume
350};
351
352static int __init pch_gpio_pci_init(void)
353{
354 return pci_register_driver(&pch_gpio_driver);
355}
356module_init(pch_gpio_pci_init);
357
358static void __exit pch_gpio_pci_exit(void)
359{
360 pci_unregister_driver(&pch_gpio_driver);
361}
362module_exit(pch_gpio_pci_exit);
363
364MODULE_DESCRIPTION("PCH GPIO PCI Driver");
365MODULE_LICENSE("GPL");