Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.37-rc1 312 lines 7.4 kB view raw
1/* 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 21#define PCH_GPIO_ALL_PINS 0xfff /* Mask for GPIO pins 0 to 11 */ 22#define GPIO_NUM_PINS 12 /* Specifies number of GPIO PINS GPIO0-GPIO11 */ 23 24struct pch_regs { 25 u32 ien; 26 u32 istatus; 27 u32 idisp; 28 u32 iclr; 29 u32 imask; 30 u32 imaskclr; 31 u32 po; 32 u32 pi; 33 u32 pm; 34 u32 im0; 35 u32 im1; 36 u32 reserved[4]; 37 u32 reset; 38}; 39 40/** 41 * struct pch_gpio_reg_data - The register store data. 42 * @po_reg: To store contents of PO register. 43 * @pm_reg: To store contents of PM register. 44 */ 45struct pch_gpio_reg_data { 46 u32 po_reg; 47 u32 pm_reg; 48}; 49 50/** 51 * struct pch_gpio - GPIO private data structure. 52 * @base: PCI base address of Memory mapped I/O register. 53 * @reg: Memory mapped PCH GPIO register list. 54 * @dev: Pointer to device structure. 55 * @gpio: Data for GPIO infrastructure. 56 * @pch_gpio_reg: Memory mapped Register data is saved here 57 * when suspend. 58 */ 59struct pch_gpio { 60 void __iomem *base; 61 struct pch_regs __iomem *reg; 62 struct device *dev; 63 struct gpio_chip gpio; 64 struct pch_gpio_reg_data pch_gpio_reg; 65 struct mutex lock; 66}; 67 68static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) 69{ 70 u32 reg_val; 71 struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); 72 73 mutex_lock(&chip->lock); 74 reg_val = ioread32(&chip->reg->po); 75 if (val) 76 reg_val |= (1 << nr); 77 else 78 reg_val &= ~(1 << nr); 79 80 iowrite32(reg_val, &chip->reg->po); 81 mutex_unlock(&chip->lock); 82} 83 84static int pch_gpio_get(struct gpio_chip *gpio, unsigned nr) 85{ 86 struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); 87 88 return ioread32(&chip->reg->pi) & (1 << nr); 89} 90 91static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, 92 int val) 93{ 94 struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); 95 u32 pm; 96 u32 reg_val; 97 98 mutex_lock(&chip->lock); 99 pm = ioread32(&chip->reg->pm) & PCH_GPIO_ALL_PINS; 100 pm |= (1 << nr); 101 iowrite32(pm, &chip->reg->pm); 102 103 reg_val = ioread32(&chip->reg->po); 104 if (val) 105 reg_val |= (1 << nr); 106 else 107 reg_val &= ~(1 << nr); 108 109 mutex_unlock(&chip->lock); 110 111 return 0; 112} 113 114static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) 115{ 116 struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); 117 u32 pm; 118 119 mutex_lock(&chip->lock); 120 pm = ioread32(&chip->reg->pm) & PCH_GPIO_ALL_PINS; /*bits 0-11*/ 121 pm &= ~(1 << nr); 122 iowrite32(pm, &chip->reg->pm); 123 mutex_unlock(&chip->lock); 124 125 return 0; 126} 127 128/* 129 * Save register configuration and disable interrupts. 130 */ 131static void pch_gpio_save_reg_conf(struct pch_gpio *chip) 132{ 133 chip->pch_gpio_reg.po_reg = ioread32(&chip->reg->po); 134 chip->pch_gpio_reg.pm_reg = ioread32(&chip->reg->pm); 135} 136 137/* 138 * This function restores the register configuration of the GPIO device. 139 */ 140static void pch_gpio_restore_reg_conf(struct pch_gpio *chip) 141{ 142 /* to store contents of PO register */ 143 iowrite32(chip->pch_gpio_reg.po_reg, &chip->reg->po); 144 /* to store contents of PM register */ 145 iowrite32(chip->pch_gpio_reg.pm_reg, &chip->reg->pm); 146} 147 148static void pch_gpio_setup(struct pch_gpio *chip) 149{ 150 struct gpio_chip *gpio = &chip->gpio; 151 152 gpio->label = dev_name(chip->dev); 153 gpio->owner = THIS_MODULE; 154 gpio->direction_input = pch_gpio_direction_input; 155 gpio->get = pch_gpio_get; 156 gpio->direction_output = pch_gpio_direction_output; 157 gpio->set = pch_gpio_set; 158 gpio->dbg_show = NULL; 159 gpio->base = -1; 160 gpio->ngpio = GPIO_NUM_PINS; 161 gpio->can_sleep = 0; 162} 163 164static int __devinit pch_gpio_probe(struct pci_dev *pdev, 165 const struct pci_device_id *id) 166{ 167 s32 ret; 168 struct pch_gpio *chip; 169 170 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 171 if (chip == NULL) 172 return -ENOMEM; 173 174 chip->dev = &pdev->dev; 175 ret = pci_enable_device(pdev); 176 if (ret) { 177 dev_err(&pdev->dev, "%s : pci_enable_device FAILED", __func__); 178 goto err_pci_enable; 179 } 180 181 ret = pci_request_regions(pdev, KBUILD_MODNAME); 182 if (ret) { 183 dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret); 184 goto err_request_regions; 185 } 186 187 chip->base = pci_iomap(pdev, 1, 0); 188 if (chip->base == 0) { 189 dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__); 190 ret = -ENOMEM; 191 goto err_iomap; 192 } 193 194 chip->reg = chip->base; 195 pci_set_drvdata(pdev, chip); 196 mutex_init(&chip->lock); 197 pch_gpio_setup(chip); 198 ret = gpiochip_add(&chip->gpio); 199 if (ret) { 200 dev_err(&pdev->dev, "PCH gpio: Failed to register GPIO\n"); 201 goto err_gpiochip_add; 202 } 203 204 return 0; 205 206err_gpiochip_add: 207 pci_iounmap(pdev, chip->base); 208 209err_iomap: 210 pci_release_regions(pdev); 211 212err_request_regions: 213 pci_disable_device(pdev); 214 215err_pci_enable: 216 kfree(chip); 217 dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); 218 return ret; 219} 220 221static void __devexit pch_gpio_remove(struct pci_dev *pdev) 222{ 223 int err; 224 struct pch_gpio *chip = pci_get_drvdata(pdev); 225 226 err = gpiochip_remove(&chip->gpio); 227 if (err) 228 dev_err(&pdev->dev, "Failed gpiochip_remove\n"); 229 230 pci_iounmap(pdev, chip->base); 231 pci_release_regions(pdev); 232 pci_disable_device(pdev); 233 kfree(chip); 234} 235 236#ifdef CONFIG_PM 237static int pch_gpio_suspend(struct pci_dev *pdev, pm_message_t state) 238{ 239 s32 ret; 240 struct pch_gpio *chip = pci_get_drvdata(pdev); 241 242 pch_gpio_save_reg_conf(chip); 243 pch_gpio_restore_reg_conf(chip); 244 245 ret = pci_save_state(pdev); 246 if (ret) { 247 dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret); 248 return ret; 249 } 250 pci_disable_device(pdev); 251 pci_set_power_state(pdev, PCI_D0); 252 ret = pci_enable_wake(pdev, PCI_D0, 1); 253 if (ret) 254 dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret); 255 256 return 0; 257} 258 259static int pch_gpio_resume(struct pci_dev *pdev) 260{ 261 s32 ret; 262 struct pch_gpio *chip = pci_get_drvdata(pdev); 263 264 ret = pci_enable_wake(pdev, PCI_D0, 0); 265 266 pci_set_power_state(pdev, PCI_D0); 267 ret = pci_enable_device(pdev); 268 if (ret) { 269 dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret); 270 return ret; 271 } 272 pci_restore_state(pdev); 273 274 iowrite32(0x01, &chip->reg->reset); 275 iowrite32(0x00, &chip->reg->reset); 276 pch_gpio_restore_reg_conf(chip); 277 278 return 0; 279} 280#else 281#define pch_gpio_suspend NULL 282#define pch_gpio_resume NULL 283#endif 284 285static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = { 286 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, 287 { 0, } 288}; 289 290static struct pci_driver pch_gpio_driver = { 291 .name = "pch_gpio", 292 .id_table = pch_gpio_pcidev_id, 293 .probe = pch_gpio_probe, 294 .remove = __devexit_p(pch_gpio_remove), 295 .suspend = pch_gpio_suspend, 296 .resume = pch_gpio_resume 297}; 298 299static int __init pch_gpio_pci_init(void) 300{ 301 return pci_register_driver(&pch_gpio_driver); 302} 303module_init(pch_gpio_pci_init); 304 305static void __exit pch_gpio_pci_exit(void) 306{ 307 pci_unregister_driver(&pch_gpio_driver); 308} 309module_exit(pch_gpio_pci_exit); 310 311MODULE_DESCRIPTION("PCH GPIO PCI Driver"); 312MODULE_LICENSE("GPL");