sta2x11-mfd.c revision b18adafccd497245a6bc5b867bf9cba7e01f8729
135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini/* 235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * Copyright (c) 2009-2011 Wind River Systems, Inc. 335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini) 435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * 535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * This program is free software; you can redistribute it and/or modify 635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * it under the terms of the GNU General Public License version 2 as 735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * published by the Free Software Foundation. 835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * 935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * This program is distributed in the hope that it will be useful, 1035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * but WITHOUT ANY WARRANTY; without even the implied warranty of 1135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 1235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * See the GNU General Public License for more details. 1335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * 1435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * You should have received a copy of the GNU General Public License 1535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * along with this program; if not, write to the Free Software 1635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * 1835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini */ 1935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 2035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/kernel.h> 2135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/module.h> 2235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/spinlock.h> 2335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/errno.h> 2435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/device.h> 2535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/slab.h> 2635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/list.h> 2735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/io.h> 2835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/ioport.h> 2935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/pci.h> 3035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/seq_file.h> 3135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/platform_device.h> 3235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/mfd/core.h> 3335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <linux/mfd/sta2x11-mfd.h> 34d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi#include <linux/regmap.h> 3535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#include <asm/sta2x11.h> 3735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 38d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic inline int __reg_within_range(unsigned int r, 39d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi unsigned int start, 40d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi unsigned int end) 41d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 42d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return ((r >= start) && (r <= end)); 43d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 44d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi 4535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini/* This describes STA2X11 MFD chip for us, we may have several */ 4635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistruct sta2x11_mfd { 4735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_instance *instance; 48d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi struct regmap *regmap[sta2x11_n_mfd_plat_devs]; 4935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini spinlock_t lock; 5035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct list_head list; 511950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi void __iomem *regs[sta2x11_n_mfd_plat_devs]; 5235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 5335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 5435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic LIST_HEAD(sta2x11_mfd_list); 5535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 5635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini/* Three functions to act on the list */ 5735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic struct sta2x11_mfd *sta2x11_mfd_find(struct pci_dev *pdev) 5835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 5935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_instance *instance; 6035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd *mfd; 6135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 6235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!pdev && !list_empty(&sta2x11_mfd_list)) { 6335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pr_warning("%s: Unspecified device, " 6435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini "using first instance\n", __func__); 6535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return list_entry(sta2x11_mfd_list.next, 6635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd, list); 6735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 6835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 6935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini instance = sta2x11_get_instance(pdev); 7035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!instance) 7135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return NULL; 7235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini list_for_each_entry(mfd, &sta2x11_mfd_list, list) { 7335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (mfd->instance == instance) 7435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return mfd; 7535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 7635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return NULL; 7735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 7835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 7935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags) 8035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 8135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); 8235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_instance *instance; 8335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 8435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (mfd) 8535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -EBUSY; 8635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini instance = sta2x11_get_instance(pdev); 8735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!instance) 8835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -EINVAL; 8935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini mfd = kzalloc(sizeof(*mfd), flags); 9035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!mfd) 9135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENOMEM; 9235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini INIT_LIST_HEAD(&mfd->list); 9335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini spin_lock_init(&mfd->lock); 9435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini mfd->instance = instance; 9535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini list_add(&mfd->list, &sta2x11_mfd_list); 9635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 9735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 9835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 9935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __devexit mfd_remove(struct pci_dev *pdev) 10035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 10135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); 10235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 10335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!mfd) 10435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENODEV; 10535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini list_del(&mfd->list); 10635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini kfree(mfd); 10735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 10835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 10935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 1101950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* This function is exported and is not expected to fail */ 1111950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghiu32 __sta2x11_mfd_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val, 1121950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi enum sta2x11_mfd_plat_dev index) 11335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 11435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); 11535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini u32 r; 11635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini unsigned long flags; 1171950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi void __iomem *regs = mfd->regs[index]; 11835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 11935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!mfd) { 12035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_warn(&pdev->dev, ": can't access sctl regs\n"); 12135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 12235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 1231950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi if (!regs) { 12435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_warn(&pdev->dev, ": system ctl not initialized\n"); 12535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 12635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 12735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini spin_lock_irqsave(&mfd->lock, flags); 1281950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi r = readl(regs + reg); 12935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini r &= ~mask; 13035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini r |= val; 13135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (mask) 1321950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi writel(r, regs + reg); 13335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini spin_unlock_irqrestore(&mfd->lock, flags); 13435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return r; 13535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 1361950c7164646bfeeb82c34bc299d82119706afb5Davide CiminaghiEXPORT_SYMBOL(__sta2x11_mfd_mask); 13735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 13829f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghiint sta2x11_mfd_get_regs_data(struct platform_device *dev, 13929f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi enum sta2x11_mfd_plat_dev index, 14029f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi void __iomem **regs, 14129f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi spinlock_t **lock) 14229f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi{ 14329f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi struct pci_dev *pdev = *(struct pci_dev **)(dev->dev.platform_data); 14429f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi struct sta2x11_mfd *mfd; 14529f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi 14629f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi if (!pdev) 14729f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi return -ENODEV; 14829f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi mfd = sta2x11_mfd_find(pdev); 14929f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi if (!mfd) 15029f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi return -ENODEV; 15129f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi if (index >= sta2x11_n_mfd_plat_devs) 15229f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi return -ENODEV; 15329f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi *regs = mfd->regs[index]; 15429f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi *lock = &mfd->lock[index]; 15529f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi pr_debug("%s %d *regs = %p\n", __func__, __LINE__, *regs); 15629f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi return *regs ? 0 : -ENODEV; 15729f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi} 15829f5b5a326b44c55e81b15308255ba695fecb323Davide CiminaghiEXPORT_SYMBOL(sta2x11_mfd_get_regs_data); 15929f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi 160d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi/* 161d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi * Special sta2x11-mfd regmap lock/unlock functions 162d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi */ 16335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 164d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic void sta2x11_regmap_lock(void *__lock) 165d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 166d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi spinlock_t *lock = __lock; 167d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi spin_lock(lock); 168d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 16935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 170d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic void sta2x11_regmap_unlock(void *__lock) 171d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 172d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi spinlock_t *lock = __lock; 173d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi spin_unlock(lock); 174d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 17535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 176d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic const char *sta2x11_mfd_names[sta2x11_n_mfd_plat_devs] = { 177b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi [sta2x11_sctl] = STA2X11_MFD_SCTL_NAME, 178b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi [sta2x11_apbreg] = STA2X11_MFD_APBREG_NAME, 179b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi [sta2x11_apb_soc_regs] = STA2X11_MFD_APB_SOC_REGS_NAME, 18035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 18135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 182d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_sctl_writeable_reg(struct device *dev, unsigned int reg) 183d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 184d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return !__reg_within_range(reg, SCTL_SCPCIECSBRST, SCTL_SCRSTSTA); 185d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 186d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi 187d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic struct regmap_config sta2x11_sctl_regmap_config = { 188d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_bits = 32, 189d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_stride = 4, 190d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .val_bits = 32, 191d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .lock = sta2x11_regmap_lock, 192d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .unlock = sta2x11_regmap_unlock, 193d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .max_register = SCTL_SCRSTSTA, 194d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .writeable_reg = sta2x11_sctl_writeable_reg, 1951950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 19635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 197d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_apbreg_readable_reg(struct device *dev, unsigned int reg) 198d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 199d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi /* Two blocks (CAN and MLB, SARAC) 0x100 bytes apart */ 200d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (reg >= APBREG_BSR_SARAC) 201d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi reg -= APBREG_BSR_SARAC; 202d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi switch (reg) { 203d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_BSR: 204d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PAER: 205d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PWAC: 206d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PRAC: 207d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PCG: 208d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PUR: 209d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_EMU_PCG: 210d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return true; 211d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi default: 212d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return false; 213d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi } 214d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 215d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi 216d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_apbreg_writeable_reg(struct device *dev, unsigned int reg) 217d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 218d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (reg >= APBREG_BSR_SARAC) 219d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi reg -= APBREG_BSR_SARAC; 220d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (!sta2x11_apbreg_readable_reg(dev, reg)) 221d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return false; 222d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return reg != APBREG_PAER; 223d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 224d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi 225d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic struct regmap_config sta2x11_apbreg_regmap_config = { 226d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_bits = 32, 227d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_stride = 4, 228d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .val_bits = 32, 229d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .lock = sta2x11_regmap_lock, 230d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .unlock = sta2x11_regmap_unlock, 231d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .max_register = APBREG_EMU_PCG_SARAC, 232d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .readable_reg = sta2x11_apbreg_readable_reg, 233d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .writeable_reg = sta2x11_apbreg_writeable_reg, 2341950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 23535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 236d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_apb_soc_regs_readable_reg(struct device *dev, 237d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi unsigned int reg) 238d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 239d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return reg <= PCIE_SoC_INT_ROUTER_STATUS3_REG || 240d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi __reg_within_range(reg, DMA_IP_CTRL_REG, SPARE3_RESERVED) || 241d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi __reg_within_range(reg, MASTER_LOCK_REG, 242d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi SYSTEM_CONFIG_STATUS_REG) || 243d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi reg == MSP_CLK_CTRL_REG || 244d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi __reg_within_range(reg, COMPENSATION_REG1, TEST_CTL_REG); 245d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 24635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 247d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_apb_soc_regs_writeable_reg(struct device *dev, 248d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi unsigned int reg) 249d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 250d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (!sta2x11_apb_soc_regs_readable_reg(dev, reg)) 251d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return false; 252d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi switch (reg) { 253d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case PCIE_COMMON_CLOCK_CONFIG_0_4_0: 254d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case SYSTEM_CONFIG_STATUS_REG: 255d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case COMPENSATION_REG1: 256d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case PCIE_SoC_INT_ROUTER_STATUS0_REG...PCIE_SoC_INT_ROUTER_STATUS3_REG: 257d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case PCIE_PM_STATUS_0_PORT_0_4...PCIE_PM_STATUS_7_0_EP4: 258d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return false; 259d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi default: 260d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return true; 261d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi } 262d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 26335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 264d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic struct regmap_config sta2x11_apb_soc_regs_regmap_config = { 265d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_bits = 32, 266d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_stride = 4, 267d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .val_bits = 32, 268d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .lock = sta2x11_regmap_lock, 269d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .unlock = sta2x11_regmap_unlock, 270d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .max_register = TEST_CTL_REG, 271d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .readable_reg = sta2x11_apb_soc_regs_readable_reg, 272d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .writeable_reg = sta2x11_apb_soc_regs_writeable_reg, 2731950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 27435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 275d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic struct regmap_config * 276d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghista2x11_mfd_regmap_configs[sta2x11_n_mfd_plat_devs] = { 277d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi [sta2x11_sctl] = &sta2x11_sctl_regmap_config, 278d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi [sta2x11_apbreg] = &sta2x11_apbreg_regmap_config, 279d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi [sta2x11_apb_soc_regs] = &sta2x11_apb_soc_regs_regmap_config, 2801950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 28135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 2821950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Probe for the three platform devices */ 2831950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 2841950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int sta2x11_mfd_platform_probe(struct platform_device *dev, 2851950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi enum sta2x11_mfd_plat_dev index) 28635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 28735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct pci_dev **pdev; 28835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd *mfd; 28935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct resource *res; 2901950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi const char *name = sta2x11_mfd_names[index]; 291d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi struct regmap_config *regmap_config = sta2x11_mfd_regmap_configs[index]; 29235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 29335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pdev = dev->dev.platform_data; 29435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini mfd = sta2x11_mfd_find(*pdev); 29535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!mfd) 29635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENODEV; 297d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (!regmap_config) 298d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return -ENODEV; 29935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 30035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini res = platform_get_resource(dev, IORESOURCE_MEM, 0); 30135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!res) 30235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENOMEM; 30335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3041950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi if (!request_mem_region(res->start, resource_size(res), name)) 30535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -EBUSY; 30635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3071950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi mfd->regs[index] = ioremap(res->start, resource_size(res)); 3081950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi if (!mfd->regs[index]) { 30935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini release_mem_region(res->start, resource_size(res)); 31035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENOMEM; 31135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 312d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi regmap_config->lock_arg = &mfd->lock; 313d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi /* 314d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi No caching, registers could be reached both via regmap and via 315d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi void __iomem * 316d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi */ 317d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi regmap_config->cache_type = REGCACHE_NONE; 318d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi mfd->regmap[index] = devm_regmap_init_mmio(&dev->dev, mfd->regs[index], 319d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi regmap_config); 320d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi WARN_ON(!mfd->regmap[index]); 321d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi 32235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 32335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 32435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3251950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int sta2x11_sctl_probe(struct platform_device *dev) 3261950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 3271950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi return sta2x11_mfd_platform_probe(dev, sta2x11_sctl); 3281950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 3291950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 3301950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int sta2x11_apbreg_probe(struct platform_device *dev) 3311950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 3321950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi return sta2x11_mfd_platform_probe(dev, sta2x11_apbreg); 3331950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 3341950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 3351950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int sta2x11_apb_soc_regs_probe(struct platform_device *dev) 3361950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 3371950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi return sta2x11_mfd_platform_probe(dev, sta2x11_apb_soc_regs); 3381950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 3391950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 3401950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* The three platform drivers */ 34135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic struct platform_driver sta2x11_sctl_platform_driver = { 34235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .driver = { 343b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi .name = STA2X11_MFD_SCTL_NAME, 34435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .owner = THIS_MODULE, 34535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini }, 34635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .probe = sta2x11_sctl_probe, 34735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 34835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 34935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __init sta2x11_sctl_init(void) 35035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 35135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pr_info("%s\n", __func__); 35235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return platform_driver_register(&sta2x11_sctl_platform_driver); 35335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 35435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 35535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic struct platform_driver sta2x11_platform_driver = { 35635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .driver = { 357b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi .name = STA2X11_MFD_APBREG_NAME, 35835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .owner = THIS_MODULE, 35935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini }, 36035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .probe = sta2x11_apbreg_probe, 36135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 36235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 36335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __init sta2x11_apbreg_init(void) 36435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 36535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pr_info("%s\n", __func__); 36635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return platform_driver_register(&sta2x11_platform_driver); 36735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 36835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3691950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic struct platform_driver sta2x11_apb_soc_regs_platform_driver = { 3701950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .driver = { 371b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi .name = STA2X11_MFD_APB_SOC_REGS_NAME, 3721950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .owner = THIS_MODULE, 3731950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 3741950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .probe = sta2x11_apb_soc_regs_probe, 3751950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 3761950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 3771950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int __init sta2x11_apb_soc_regs_init(void) 3781950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 3791950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi pr_info("%s\n", __func__); 3801950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi return platform_driver_register(&sta2x11_apb_soc_regs_platform_driver); 3811950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 3821950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 38335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini/* 3841950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi * What follows are the PCI devices that host the above pdevs. 38535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * Each logic block is 4kB and they are all consecutive: we use this info. 38635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini */ 38735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3881950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 0 device */ 3891950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 3901950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 0, Bar 0 */ 3911950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghienum mfd0_bar0_cells { 39235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_GPIO_0 = 0, 39335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_GPIO_1, 39435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_GPIO_2, 39535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_GPIO_3, 39635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_SCTL, 39735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_SCR, 39835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_TIME, 39935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 4001950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 0 , Bar 1 */ 4011950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghienum mfd0_bar1_cells { 40235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_APBREG = 0, 40335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 40435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#define CELL_4K(_name, _cell) { \ 40535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .name = _name, \ 40635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .start = _cell * 4096, .end = _cell * 4096 + 4095, \ 40735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .flags = IORESOURCE_MEM, \ 40835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 40935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 41035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic const __devinitconst struct resource gpio_resources[] = { 41135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini { 412b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi /* 4 consecutive cells, 1 driver */ 413b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi .name = STA2X11_MFD_GPIO_NAME, 41435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .start = 0, 41535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .end = (4 * 4096) - 1, 41635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .flags = IORESOURCE_MEM, 41735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 41835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 41935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic const __devinitconst struct resource sctl_resources[] = { 420b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_SCTL_NAME, STA2X11_SCTL), 42135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 42235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic const __devinitconst struct resource scr_resources[] = { 423b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_SCR_NAME, STA2X11_SCR), 42435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 42535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic const __devinitconst struct resource time_resources[] = { 426b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_TIME_NAME, STA2X11_TIME), 42735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 42835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 42935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic const __devinitconst struct resource apbreg_resources[] = { 430b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_APBREG_NAME, STA2X11_APBREG), 43135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 43235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 43335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#define DEV(_name, _r) \ 43435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini { .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, } 43535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 4361950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic __devinitdata struct mfd_cell sta2x11_mfd0_bar0[] = { 437b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi /* offset 0: we add pdata later */ 438b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_GPIO_NAME, gpio_resources), 439b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_SCTL_NAME, sctl_resources), 440b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_SCR_NAME, scr_resources), 441b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_TIME_NAME, time_resources), 44235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 44335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 4441950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic __devinitdata struct mfd_cell sta2x11_mfd0_bar1[] = { 445b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_APBREG_NAME, apbreg_resources), 44635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 44735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 4481950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 1 devices */ 4491950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4501950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 1, Bar 0 */ 4511950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghienum mfd1_bar0_cells { 4521950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi STA2X11_VIC = 0, 4531950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 4541950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4551950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 1, Bar 1 */ 4561950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghienum mfd1_bar1_cells { 4571950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi STA2X11_APB_SOC_REGS = 0, 4581950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 4591950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4601950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic const __devinitconst struct resource vic_resources[] = { 461b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_VIC_NAME, STA2X11_VIC), 4621950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 4631950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4641950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic const __devinitconst struct resource apb_soc_regs_resources[] = { 465b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_APB_SOC_REGS_NAME, STA2X11_APB_SOC_REGS), 4661950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 4671950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4681950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic __devinitdata struct mfd_cell sta2x11_mfd1_bar0[] = { 469b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_VIC_NAME, vic_resources), 4701950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 4711950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4721950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic __devinitdata struct mfd_cell sta2x11_mfd1_bar1[] = { 473b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_APB_SOC_REGS_NAME, apb_soc_regs_resources), 4741950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 4751950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4761950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 47735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int sta2x11_mfd_suspend(struct pci_dev *pdev, pm_message_t state) 47835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 47935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_save_state(pdev); 48035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_disable_device(pdev); 48135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_set_power_state(pdev, pci_choose_state(pdev, state)); 48235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 48335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 48435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 48535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 48635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int sta2x11_mfd_resume(struct pci_dev *pdev) 48735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 48835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini int err; 48935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 49035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_set_power_state(pdev, 0); 49135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini err = pci_enable_device(pdev); 49235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (err) 49335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return err; 49435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_restore_state(pdev); 49535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 49635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 49735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 49835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 4991950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistruct sta2x11_mfd_bar_setup_data { 5001950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi struct mfd_cell *cells; 5011950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi int ncells; 5021950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5031950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5041950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistruct sta2x11_mfd_setup_data { 5051950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi struct sta2x11_mfd_bar_setup_data bars[2]; 5061950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5071950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5081950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi#define STA2X11_MFD0 0 5091950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi#define STA2X11_MFD1 1 5101950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5111950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic struct sta2x11_mfd_setup_data mfd_setup_data[] = { 5121950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi /* Mfd 0: gpio, sctl, scr, timers / apbregs */ 5131950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [STA2X11_MFD0] = { 5141950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .bars = { 5151950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [0] = { 5161950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .cells = sta2x11_mfd0_bar0, 5171950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .ncells = ARRAY_SIZE(sta2x11_mfd0_bar0), 5181950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5191950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [1] = { 5201950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .cells = sta2x11_mfd0_bar1, 5211950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .ncells = ARRAY_SIZE(sta2x11_mfd0_bar1), 5221950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5231950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5241950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5251950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi /* Mfd 1: vic / apb-soc-regs */ 5261950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [STA2X11_MFD1] = { 5271950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .bars = { 5281950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [0] = { 5291950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .cells = sta2x11_mfd1_bar0, 5301950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .ncells = ARRAY_SIZE(sta2x11_mfd1_bar0), 5311950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5321950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [1] = { 5331950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .cells = sta2x11_mfd1_bar1, 5341950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .ncells = ARRAY_SIZE(sta2x11_mfd1_bar1), 5351950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5361950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5371950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5381950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5391950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5401950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic void __devinit sta2x11_mfd_setup(struct pci_dev *pdev, 5411950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi struct sta2x11_mfd_setup_data *sd) 5421950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 5431950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi int i, j; 5441950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi for (i = 0; i < ARRAY_SIZE(sd->bars); i++) 5451950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi for (j = 0; j < sd->bars[i].ncells; j++) { 5461950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi sd->bars[i].cells[j].pdata_size = sizeof(pdev); 5471950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi sd->bars[i].cells[j].platform_data = &pdev; 5481950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi } 5491950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 5501950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 55135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __devinit sta2x11_mfd_probe(struct pci_dev *pdev, 55235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini const struct pci_device_id *pci_id) 55335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 55435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini int err, i; 5551950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi struct sta2x11_mfd_setup_data *setup_data; 55635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_gpio_pdata *gpio_data; 55735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 55835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_info(&pdev->dev, "%s\n", __func__); 55935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 56035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini err = pci_enable_device(pdev); 56135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (err) { 56235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_err(&pdev->dev, "Can't enable device.\n"); 56335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return err; 56435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 56535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 56635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini err = pci_enable_msi(pdev); 56735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (err) 56835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_info(&pdev->dev, "Enable msi failed\n"); 56935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 5701950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi setup_data = pci_id->device == PCI_DEVICE_ID_STMICRO_GPIO ? 5711950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi &mfd_setup_data[STA2X11_MFD0] : 5721950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi &mfd_setup_data[STA2X11_MFD1]; 5731950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 57435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini /* Read gpio config data as pci device's platform data */ 57535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini gpio_data = dev_get_platdata(&pdev->dev); 57635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!gpio_data) 57735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_warn(&pdev->dev, "no gpio configuration\n"); 57835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 57935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_dbg(&pdev->dev, "%s, gpio_data = %p (%p)\n", __func__, 58035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini gpio_data, &gpio_data); 58135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_dbg(&pdev->dev, "%s, pdev = %p (%p)\n", __func__, 58235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pdev, &pdev); 58335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 58435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini /* platform data is the pci device for all of them */ 5851950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi sta2x11_mfd_setup(pdev, setup_data); 58635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 58735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini /* Record this pdev before mfd_add_devices: their probe looks for it */ 58835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini sta2x11_mfd_add(pdev, GFP_ATOMIC); 58935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 5901950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi /* Just 2 bars for all mfd's at present */ 5911950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi for (i = 0; i < 2; i++) { 5921950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi err = mfd_add_devices(&pdev->dev, -1, 5931950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi setup_data->bars[i].cells, 5941950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi setup_data->bars[i].ncells, 5951950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi &pdev->resource[i], 5961950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 0, NULL); 5971950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi if (err) { 5981950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi dev_err(&pdev->dev, 5991950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi "mfd_add_devices[%d] failed: %d\n", i, err); 6001950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi goto err_disable; 6011950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi } 60235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 60335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 60435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 60535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 60635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinierr_disable: 60735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini mfd_remove_devices(&pdev->dev); 60835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_disable_device(pdev); 60935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_disable_msi(pdev); 61035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return err; 61135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 61235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 61335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic DEFINE_PCI_DEVICE_TABLE(sta2x11_mfd_tbl) = { 61435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)}, 6151950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIC)}, 61635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini {0,}, 61735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 61835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 61935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic struct pci_driver sta2x11_mfd_driver = { 62035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .name = "sta2x11-mfd", 62135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .id_table = sta2x11_mfd_tbl, 62235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .probe = sta2x11_mfd_probe, 62335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .suspend = sta2x11_mfd_suspend, 62435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .resume = sta2x11_mfd_resume, 62535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 62635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 62735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __init sta2x11_mfd_init(void) 62835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 62935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pr_info("%s\n", __func__); 63035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return pci_register_driver(&sta2x11_mfd_driver); 63135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 63235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 63335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini/* 63435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * All of this must be ready before "normal" devices like MMCI appear. 63535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * But MFD (the pci device) can't be too early. The following choice 63635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * prepares platform drivers very early and probe the PCI device later, 63735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * but before other PCI devices. 63835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini */ 63935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinisubsys_initcall(sta2x11_apbreg_init); 64035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinisubsys_initcall(sta2x11_sctl_init); 6411950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghisubsys_initcall(sta2x11_apb_soc_regs_init); 64235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinirootfs_initcall(sta2x11_mfd_init); 64335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 64435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro RubiniMODULE_LICENSE("GPL v2"); 64535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro RubiniMODULE_AUTHOR("Wind River"); 64635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro RubiniMODULE_DESCRIPTION("STA2x11 mfd for GPIO, SCTL and APBREG"); 64735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro RubiniMODULE_DEVICE_TABLE(pci, sta2x11_mfd_tbl); 648