135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini/* 235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * Copyright (c) 2009-2011 Wind River Systems, Inc. 3b73df6986bdf0186deeb30b272a9b890065ca223Davide Ciminaghi * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini, Davide Ciminaghi) 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]; 49e885ba298098959d03c58d946c6fad8f8ed4a1c7Davide Ciminaghi spinlock_t lock[sta2x11_n_mfd_plat_devs]; 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 79f791be492f76dea7b0641ed227a60eeb2fa7e255Bill Pembertonstatic int sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags) 8035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 81e885ba298098959d03c58d946c6fad8f8ed4a1c7Davide Ciminaghi int i; 8235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); 8335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_instance *instance; 8435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 8535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (mfd) 8635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -EBUSY; 8735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini instance = sta2x11_get_instance(pdev); 8835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!instance) 8935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -EINVAL; 9035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini mfd = kzalloc(sizeof(*mfd), flags); 9135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!mfd) 9235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENOMEM; 9335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini INIT_LIST_HEAD(&mfd->list); 94e885ba298098959d03c58d946c6fad8f8ed4a1c7Davide Ciminaghi for (i = 0; i < ARRAY_SIZE(mfd->lock); i++) 95e885ba298098959d03c58d946c6fad8f8ed4a1c7Davide Ciminaghi spin_lock_init(&mfd->lock[i]); 9635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini mfd->instance = instance; 9735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini list_add(&mfd->list, &sta2x11_mfd_list); 9835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 9935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 10035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 1011950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* This function is exported and is not expected to fail */ 1021950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghiu32 __sta2x11_mfd_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val, 1031950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi enum sta2x11_mfd_plat_dev index) 10435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 10535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); 10635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini u32 r; 10735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini unsigned long flags; 108709edecd4eaaa210ea9296c6d8ec5e9cedf1abe3Wei Yongjun void __iomem *regs; 10935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 11035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!mfd) { 11135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_warn(&pdev->dev, ": can't access sctl regs\n"); 11235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 11335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 114709edecd4eaaa210ea9296c6d8ec5e9cedf1abe3Wei Yongjun 115709edecd4eaaa210ea9296c6d8ec5e9cedf1abe3Wei Yongjun regs = mfd->regs[index]; 1161950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi if (!regs) { 11735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_warn(&pdev->dev, ": system ctl not initialized\n"); 11835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 11935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 120e885ba298098959d03c58d946c6fad8f8ed4a1c7Davide Ciminaghi spin_lock_irqsave(&mfd->lock[index], flags); 1211950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi r = readl(regs + reg); 12235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini r &= ~mask; 12335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini r |= val; 12435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (mask) 1251950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi writel(r, regs + reg); 126e885ba298098959d03c58d946c6fad8f8ed4a1c7Davide Ciminaghi spin_unlock_irqrestore(&mfd->lock[index], flags); 12735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return r; 12835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 1291950c7164646bfeeb82c34bc299d82119706afb5Davide CiminaghiEXPORT_SYMBOL(__sta2x11_mfd_mask); 13035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 13129f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghiint sta2x11_mfd_get_regs_data(struct platform_device *dev, 13229f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi enum sta2x11_mfd_plat_dev index, 13329f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi void __iomem **regs, 13429f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi spinlock_t **lock) 13535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 136334a41ce9b753ec615e8c6c50ee07d6197190610Jingoo Han struct pci_dev *pdev = *(struct pci_dev **)dev_get_platdata(&dev->dev); 13729f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi struct sta2x11_mfd *mfd; 13835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 13929f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi if (!pdev) 14029f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi return -ENODEV; 14129f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi mfd = sta2x11_mfd_find(pdev); 14229f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi if (!mfd) 14329f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi return -ENODEV; 14429f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi if (index >= sta2x11_n_mfd_plat_devs) 14529f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi return -ENODEV; 14629f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi *regs = mfd->regs[index]; 14729f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi *lock = &mfd->lock[index]; 14829f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi pr_debug("%s %d *regs = %p\n", __func__, __LINE__, *regs); 14929f5b5a326b44c55e81b15308255ba695fecb323Davide Ciminaghi return *regs ? 0 : -ENODEV; 15035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 15129f5b5a326b44c55e81b15308255ba695fecb323Davide CiminaghiEXPORT_SYMBOL(sta2x11_mfd_get_regs_data); 15235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 153d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi/* 154d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi * Special sta2x11-mfd regmap lock/unlock functions 155d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi */ 15635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 157d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic void sta2x11_regmap_lock(void *__lock) 158d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 159d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi spinlock_t *lock = __lock; 160d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi spin_lock(lock); 161d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 16235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 163d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic void sta2x11_regmap_unlock(void *__lock) 164d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 165d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi spinlock_t *lock = __lock; 166d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi spin_unlock(lock); 167d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 16835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 169dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi/* OTP (one time programmable registers do not require locking */ 170dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghistatic void sta2x11_regmap_nolock(void *__lock) 171dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi{ 172dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi} 173dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi 174d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic const char *sta2x11_mfd_names[sta2x11_n_mfd_plat_devs] = { 175b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi [sta2x11_sctl] = STA2X11_MFD_SCTL_NAME, 176b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi [sta2x11_apbreg] = STA2X11_MFD_APBREG_NAME, 177b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi [sta2x11_apb_soc_regs] = STA2X11_MFD_APB_SOC_REGS_NAME, 178dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi [sta2x11_scr] = STA2X11_MFD_SCR_NAME, 17935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 18035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 181d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_sctl_writeable_reg(struct device *dev, unsigned int reg) 182d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 183d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return !__reg_within_range(reg, SCTL_SCPCIECSBRST, SCTL_SCRSTSTA); 184d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 185d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi 186d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic struct regmap_config sta2x11_sctl_regmap_config = { 187d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_bits = 32, 188d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_stride = 4, 189d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .val_bits = 32, 190d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .lock = sta2x11_regmap_lock, 191d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .unlock = sta2x11_regmap_unlock, 192d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .max_register = SCTL_SCRSTSTA, 193d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .writeable_reg = sta2x11_sctl_writeable_reg, 19435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 19535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 196dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghistatic bool sta2x11_scr_readable_reg(struct device *dev, unsigned int reg) 197dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi{ 198dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi return (reg == STA2X11_SECR_CR) || 199dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi __reg_within_range(reg, STA2X11_SECR_FVR0, STA2X11_SECR_FVR1); 200dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi} 20135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 202dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghistatic bool sta2x11_scr_writeable_reg(struct device *dev, unsigned int reg) 20335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 204dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi return false; 205dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi} 20635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 207dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghistatic struct regmap_config sta2x11_scr_regmap_config = { 208dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .reg_bits = 32, 209dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .reg_stride = 4, 210dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .val_bits = 32, 211dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .lock = sta2x11_regmap_nolock, 212dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .unlock = sta2x11_regmap_nolock, 213dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .max_register = STA2X11_SECR_FVR1, 214dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .readable_reg = sta2x11_scr_readable_reg, 215dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .writeable_reg = sta2x11_scr_writeable_reg, 216dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi}; 21735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 218d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_apbreg_readable_reg(struct device *dev, unsigned int reg) 219d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 220d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi /* Two blocks (CAN and MLB, SARAC) 0x100 bytes apart */ 221d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (reg >= APBREG_BSR_SARAC) 222d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi reg -= APBREG_BSR_SARAC; 223d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi switch (reg) { 224d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_BSR: 225d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PAER: 226d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PWAC: 227d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PRAC: 228d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PCG: 229d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_PUR: 230d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case APBREG_EMU_PCG: 231d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return true; 232d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi default: 233d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return false; 234d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi } 235d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 23635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 237d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_apbreg_writeable_reg(struct device *dev, unsigned int reg) 238d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 239d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (reg >= APBREG_BSR_SARAC) 240d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi reg -= APBREG_BSR_SARAC; 241d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (!sta2x11_apbreg_readable_reg(dev, reg)) 242d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return false; 243d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return reg != APBREG_PAER; 244d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 24535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 246d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic struct regmap_config sta2x11_apbreg_regmap_config = { 247d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_bits = 32, 248d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_stride = 4, 249d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .val_bits = 32, 250d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .lock = sta2x11_regmap_lock, 251d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .unlock = sta2x11_regmap_unlock, 252d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .max_register = APBREG_EMU_PCG_SARAC, 253d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .readable_reg = sta2x11_apbreg_readable_reg, 254d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .writeable_reg = sta2x11_apbreg_writeable_reg, 2551950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 25635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 257d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_apb_soc_regs_readable_reg(struct device *dev, 258d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi unsigned int reg) 259d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 260d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return reg <= PCIE_SoC_INT_ROUTER_STATUS3_REG || 261d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi __reg_within_range(reg, DMA_IP_CTRL_REG, SPARE3_RESERVED) || 262d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi __reg_within_range(reg, MASTER_LOCK_REG, 263d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi SYSTEM_CONFIG_STATUS_REG) || 264d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi reg == MSP_CLK_CTRL_REG || 265d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi __reg_within_range(reg, COMPENSATION_REG1, TEST_CTL_REG); 266d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi} 26735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 268d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic bool sta2x11_apb_soc_regs_writeable_reg(struct device *dev, 269d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi unsigned int reg) 270d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi{ 271d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (!sta2x11_apb_soc_regs_readable_reg(dev, reg)) 272d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return false; 273d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi switch (reg) { 274d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case PCIE_COMMON_CLOCK_CONFIG_0_4_0: 275d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case SYSTEM_CONFIG_STATUS_REG: 276d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case COMPENSATION_REG1: 277d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case PCIE_SoC_INT_ROUTER_STATUS0_REG...PCIE_SoC_INT_ROUTER_STATUS3_REG: 278d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi case PCIE_PM_STATUS_0_PORT_0_4...PCIE_PM_STATUS_7_0_EP4: 279d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return false; 280d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi default: 281d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return true; 28235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 28335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 28435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 285d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic struct regmap_config sta2x11_apb_soc_regs_regmap_config = { 286d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_bits = 32, 287d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .reg_stride = 4, 288d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .val_bits = 32, 289d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .lock = sta2x11_regmap_lock, 290d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .unlock = sta2x11_regmap_unlock, 291d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .max_register = TEST_CTL_REG, 292d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .readable_reg = sta2x11_apb_soc_regs_readable_reg, 293d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi .writeable_reg = sta2x11_apb_soc_regs_writeable_reg, 2941950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 29535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 296d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghistatic struct regmap_config * 297d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghista2x11_mfd_regmap_configs[sta2x11_n_mfd_plat_devs] = { 298d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi [sta2x11_sctl] = &sta2x11_sctl_regmap_config, 299d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi [sta2x11_apbreg] = &sta2x11_apbreg_regmap_config, 300d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi [sta2x11_apb_soc_regs] = &sta2x11_apb_soc_regs_regmap_config, 301dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi [sta2x11_scr] = &sta2x11_scr_regmap_config, 3021950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 30335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 304dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi/* Probe for the four platform devices */ 3051950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 3061950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int sta2x11_mfd_platform_probe(struct platform_device *dev, 3071950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi enum sta2x11_mfd_plat_dev index) 30835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 30935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct pci_dev **pdev; 31035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct sta2x11_mfd *mfd; 31135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini struct resource *res; 3121950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi const char *name = sta2x11_mfd_names[index]; 313d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi struct regmap_config *regmap_config = sta2x11_mfd_regmap_configs[index]; 31435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 315334a41ce9b753ec615e8c6c50ee07d6197190610Jingoo Han pdev = dev_get_platdata(&dev->dev); 31635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini mfd = sta2x11_mfd_find(*pdev); 31735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!mfd) 31835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENODEV; 319d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi if (!regmap_config) 320d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi return -ENODEV; 32135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 32235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini res = platform_get_resource(dev, IORESOURCE_MEM, 0); 32335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (!res) 32435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENOMEM; 32535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3261950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi if (!request_mem_region(res->start, resource_size(res), name)) 32735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -EBUSY; 32835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3291950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi mfd->regs[index] = ioremap(res->start, resource_size(res)); 3301950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi if (!mfd->regs[index]) { 33135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini release_mem_region(res->start, resource_size(res)); 33235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return -ENOMEM; 33335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 334d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi regmap_config->lock_arg = &mfd->lock; 335d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi /* 336d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi No caching, registers could be reached both via regmap and via 337d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi void __iomem * 338d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi */ 339d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi regmap_config->cache_type = REGCACHE_NONE; 340d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi mfd->regmap[index] = devm_regmap_init_mmio(&dev->dev, mfd->regs[index], 341d94e25535a7979a6c81922496f475a5dd0e006b4Davide Ciminaghi regmap_config); 342ec9e4ba67e3782d5a9ec12754223a3f611810a93Wei Yongjun WARN_ON(IS_ERR(mfd->regmap[index])); 34335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 34435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 34535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 34635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3471950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int sta2x11_sctl_probe(struct platform_device *dev) 3481950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 3491950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi return sta2x11_mfd_platform_probe(dev, sta2x11_sctl); 3501950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 3511950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 3521950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int sta2x11_apbreg_probe(struct platform_device *dev) 3531950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 3541950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi return sta2x11_mfd_platform_probe(dev, sta2x11_apbreg); 3551950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 3561950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 3571950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int sta2x11_apb_soc_regs_probe(struct platform_device *dev) 3581950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 3591950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi return sta2x11_mfd_platform_probe(dev, sta2x11_apb_soc_regs); 3601950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 3611950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 362dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghistatic int sta2x11_scr_probe(struct platform_device *dev) 363dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi{ 364dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi return sta2x11_mfd_platform_probe(dev, sta2x11_scr); 365dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi} 366dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi 3671950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* The three platform drivers */ 36835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic struct platform_driver sta2x11_sctl_platform_driver = { 36935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .driver = { 370b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi .name = STA2X11_MFD_SCTL_NAME, 37135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .owner = THIS_MODULE, 37235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini }, 37335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .probe = sta2x11_sctl_probe, 37435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 37535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 37635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __init sta2x11_sctl_init(void) 37735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 37835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pr_info("%s\n", __func__); 37935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return platform_driver_register(&sta2x11_sctl_platform_driver); 38035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 38135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 38235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic struct platform_driver sta2x11_platform_driver = { 38335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .driver = { 384b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi .name = STA2X11_MFD_APBREG_NAME, 38535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .owner = THIS_MODULE, 38635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini }, 38735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .probe = sta2x11_apbreg_probe, 38835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 38935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 39035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __init sta2x11_apbreg_init(void) 39135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 39235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pr_info("%s\n", __func__); 39335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return platform_driver_register(&sta2x11_platform_driver); 39435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 39535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 3961950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic struct platform_driver sta2x11_apb_soc_regs_platform_driver = { 3971950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .driver = { 398b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi .name = STA2X11_MFD_APB_SOC_REGS_NAME, 3991950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .owner = THIS_MODULE, 4001950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 4011950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .probe = sta2x11_apb_soc_regs_probe, 4021950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 4031950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4041950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic int __init sta2x11_apb_soc_regs_init(void) 4051950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 4061950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi pr_info("%s\n", __func__); 4071950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi return platform_driver_register(&sta2x11_apb_soc_regs_platform_driver); 4081950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 4091950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 410dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghistatic struct platform_driver sta2x11_scr_platform_driver = { 411dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .driver = { 412dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .name = STA2X11_MFD_SCR_NAME, 413dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .owner = THIS_MODULE, 414dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi }, 415dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi .probe = sta2x11_scr_probe, 416dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi}; 417dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi 418dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghistatic int __init sta2x11_scr_init(void) 419dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi{ 420dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi pr_info("%s\n", __func__); 421dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi return platform_driver_register(&sta2x11_scr_platform_driver); 422dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi} 423dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi 424dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghi 42535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini/* 4261950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi * What follows are the PCI devices that host the above pdevs. 42735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * Each logic block is 4kB and they are all consecutive: we use this info. 42835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini */ 42935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 4301950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 0 device */ 4311950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4321950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 0, Bar 0 */ 4331950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghienum mfd0_bar0_cells { 43435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_GPIO_0 = 0, 43535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_GPIO_1, 43635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_GPIO_2, 43735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_GPIO_3, 43835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_SCTL, 43935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_SCR, 44035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_TIME, 44135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 4421950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 0 , Bar 1 */ 4431950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghienum mfd0_bar1_cells { 44435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini STA2X11_APBREG = 0, 44535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 44635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#define CELL_4K(_name, _cell) { \ 44735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .name = _name, \ 44835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .start = _cell * 4096, .end = _cell * 4096 + 4095, \ 44935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .flags = IORESOURCE_MEM, \ 45035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 45135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 452a73e5df16b52a12f5210b20484e74c45ae25d04cBill Pembertonstatic const struct resource gpio_resources[] = { 45335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini { 454b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi /* 4 consecutive cells, 1 driver */ 455b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi .name = STA2X11_MFD_GPIO_NAME, 45635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .start = 0, 45735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .end = (4 * 4096) - 1, 45835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .flags = IORESOURCE_MEM, 45935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 46035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 461a73e5df16b52a12f5210b20484e74c45ae25d04cBill Pembertonstatic const struct resource sctl_resources[] = { 462b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_SCTL_NAME, STA2X11_SCTL), 46335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 464a73e5df16b52a12f5210b20484e74c45ae25d04cBill Pembertonstatic const struct resource scr_resources[] = { 465b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_SCR_NAME, STA2X11_SCR), 46635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 467a73e5df16b52a12f5210b20484e74c45ae25d04cBill Pembertonstatic const struct resource time_resources[] = { 468b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_TIME_NAME, STA2X11_TIME), 46935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 47035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 471a73e5df16b52a12f5210b20484e74c45ae25d04cBill Pembertonstatic const struct resource apbreg_resources[] = { 472b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_APBREG_NAME, STA2X11_APBREG), 47335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 47435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 47535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini#define DEV(_name, _r) \ 47635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini { .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, } 47735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 4782dfea3803dcf70983d14ce1dcbb3e97a7459a28bLinus Torvaldsstatic struct mfd_cell sta2x11_mfd0_bar0[] = { 479b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi /* offset 0: we add pdata later */ 480b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_GPIO_NAME, gpio_resources), 481b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_SCTL_NAME, sctl_resources), 482b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_SCR_NAME, scr_resources), 483b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_TIME_NAME, time_resources), 48435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 48535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 4862dfea3803dcf70983d14ce1dcbb3e97a7459a28bLinus Torvaldsstatic struct mfd_cell sta2x11_mfd0_bar1[] = { 487b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_APBREG_NAME, apbreg_resources), 48835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 48935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 4901950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 1 devices */ 4911950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4921950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 1, Bar 0 */ 4931950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghienum mfd1_bar0_cells { 4941950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi STA2X11_VIC = 0, 4951950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 4961950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 4971950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi/* Mfd 1, Bar 1 */ 4981950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghienum mfd1_bar1_cells { 4991950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi STA2X11_APB_SOC_REGS = 0, 5001950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5011950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 502612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartmanstatic const struct resource vic_resources[] = { 503b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_VIC_NAME, STA2X11_VIC), 5041950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5051950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 506612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartmanstatic const struct resource apb_soc_regs_resources[] = { 507b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi CELL_4K(STA2X11_MFD_APB_SOC_REGS_NAME, STA2X11_APB_SOC_REGS), 5081950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5091950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 510612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartmanstatic struct mfd_cell sta2x11_mfd1_bar0[] = { 511b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_VIC_NAME, vic_resources), 5121950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5131950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 514612b95cd7926d1a583e68f12e10b44b7ac80ca17Greg Kroah-Hartmanstatic struct mfd_cell sta2x11_mfd1_bar1[] = { 515b18adafccd497245a6bc5b867bf9cba7e01f8729Davide Ciminaghi DEV(STA2X11_MFD_APB_SOC_REGS_NAME, apb_soc_regs_resources), 5161950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5171950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5181950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 51935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int sta2x11_mfd_suspend(struct pci_dev *pdev, pm_message_t state) 52035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 52135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_save_state(pdev); 52235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_disable_device(pdev); 52335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_set_power_state(pdev, pci_choose_state(pdev, state)); 52435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 52535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 52635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 52735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 52835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int sta2x11_mfd_resume(struct pci_dev *pdev) 52935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 53035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini int err; 53135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 5324d1d99807ae6a291faf3ac0732257a56d93598edJulia Lawall pci_set_power_state(pdev, PCI_D0); 53335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini err = pci_enable_device(pdev); 53435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (err) 53535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return err; 53635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_restore_state(pdev); 53735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 53835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 53935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 54035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 5411950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistruct sta2x11_mfd_bar_setup_data { 5421950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi struct mfd_cell *cells; 5431950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi int ncells; 5441950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5451950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5461950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistruct sta2x11_mfd_setup_data { 5471950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi struct sta2x11_mfd_bar_setup_data bars[2]; 5481950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5491950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5501950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi#define STA2X11_MFD0 0 5511950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi#define STA2X11_MFD1 1 5521950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5531950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghistatic struct sta2x11_mfd_setup_data mfd_setup_data[] = { 5541950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi /* Mfd 0: gpio, sctl, scr, timers / apbregs */ 5551950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [STA2X11_MFD0] = { 5561950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .bars = { 5571950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [0] = { 5581950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .cells = sta2x11_mfd0_bar0, 5591950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .ncells = ARRAY_SIZE(sta2x11_mfd0_bar0), 5601950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5611950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [1] = { 5621950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .cells = sta2x11_mfd0_bar1, 5631950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .ncells = ARRAY_SIZE(sta2x11_mfd0_bar1), 5641950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5651950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5661950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5671950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi /* Mfd 1: vic / apb-soc-regs */ 5681950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [STA2X11_MFD1] = { 5691950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .bars = { 5701950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [0] = { 5711950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .cells = sta2x11_mfd1_bar0, 5721950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .ncells = ARRAY_SIZE(sta2x11_mfd1_bar0), 5731950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5741950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi [1] = { 5751950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .cells = sta2x11_mfd1_bar1, 5761950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi .ncells = ARRAY_SIZE(sta2x11_mfd1_bar1), 5771950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5781950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5791950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi }, 5801950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi}; 5811950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 5822dfea3803dcf70983d14ce1dcbb3e97a7459a28bLinus Torvaldsstatic void sta2x11_mfd_setup(struct pci_dev *pdev, 5832dfea3803dcf70983d14ce1dcbb3e97a7459a28bLinus Torvalds struct sta2x11_mfd_setup_data *sd) 5841950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi{ 5851950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi int i, j; 5861950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi for (i = 0; i < ARRAY_SIZE(sd->bars); i++) 5871950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi for (j = 0; j < sd->bars[i].ncells; j++) { 5881950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi sd->bars[i].cells[j].pdata_size = sizeof(pdev); 5891950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi sd->bars[i].cells[j].platform_data = &pdev; 5901950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi } 5911950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi} 5921950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 593f791be492f76dea7b0641ed227a60eeb2fa7e255Bill Pembertonstatic int sta2x11_mfd_probe(struct pci_dev *pdev, 5942dfea3803dcf70983d14ce1dcbb3e97a7459a28bLinus Torvalds const struct pci_device_id *pci_id) 59535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 59635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini int err, i; 5971950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi struct sta2x11_mfd_setup_data *setup_data; 59835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 59935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_info(&pdev->dev, "%s\n", __func__); 60035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 60135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini err = pci_enable_device(pdev); 60235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (err) { 60335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_err(&pdev->dev, "Can't enable device.\n"); 60435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return err; 60535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 60635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 60735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini err = pci_enable_msi(pdev); 60835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini if (err) 60935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini dev_info(&pdev->dev, "Enable msi failed\n"); 61035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 6111950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi setup_data = pci_id->device == PCI_DEVICE_ID_STMICRO_GPIO ? 6121950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi &mfd_setup_data[STA2X11_MFD0] : 6131950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi &mfd_setup_data[STA2X11_MFD1]; 61435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 61535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini /* platform data is the pci device for all of them */ 6161950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi sta2x11_mfd_setup(pdev, setup_data); 61735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 61835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini /* Record this pdev before mfd_add_devices: their probe looks for it */ 6198ec86a302a190bc4864928dd69f3f22066137b68Davide Ciminaghi if (!sta2x11_mfd_find(pdev)) 6208ec86a302a190bc4864928dd69f3f22066137b68Davide Ciminaghi sta2x11_mfd_add(pdev, GFP_ATOMIC); 62135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 6221950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi /* Just 2 bars for all mfd's at present */ 6231950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi for (i = 0; i < 2; i++) { 6241950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi err = mfd_add_devices(&pdev->dev, -1, 6251950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi setup_data->bars[i].cells, 6261950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi setup_data->bars[i].ncells, 6271950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi &pdev->resource[i], 6281950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi 0, NULL); 6291950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi if (err) { 6301950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi dev_err(&pdev->dev, 6311950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi "mfd_add_devices[%d] failed: %d\n", i, err); 6321950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi goto err_disable; 6331950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi } 63435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini } 63535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 63635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return 0; 63735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 63835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinierr_disable: 63935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini mfd_remove_devices(&pdev->dev); 64035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_disable_device(pdev); 64135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pci_disable_msi(pdev); 64235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return err; 64335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 64435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 64536fcd06c4638acacee7135906cab60f11ea1ffacJingoo Hanstatic const struct pci_device_id sta2x11_mfd_tbl[] = { 64635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)}, 6471950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghi {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_VIC)}, 64835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini {0,}, 64935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 65035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 65135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic struct pci_driver sta2x11_mfd_driver = { 65235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .name = "sta2x11-mfd", 65335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .id_table = sta2x11_mfd_tbl, 65435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .probe = sta2x11_mfd_probe, 65535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .suspend = sta2x11_mfd_suspend, 65635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini .resume = sta2x11_mfd_resume, 65735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini}; 65835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 65935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinistatic int __init sta2x11_mfd_init(void) 66035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini{ 66135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini pr_info("%s\n", __func__); 66235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini return pci_register_driver(&sta2x11_mfd_driver); 66335bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini} 66435bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 66535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini/* 66635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * All of this must be ready before "normal" devices like MMCI appear. 66735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * But MFD (the pci device) can't be too early. The following choice 66835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * prepares platform drivers very early and probe the PCI device later, 66935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini * but before other PCI devices. 67035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini */ 67135bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinisubsys_initcall(sta2x11_apbreg_init); 67235bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinisubsys_initcall(sta2x11_sctl_init); 6731950c7164646bfeeb82c34bc299d82119706afb5Davide Ciminaghisubsys_initcall(sta2x11_apb_soc_regs_init); 674dba6c1aeea4dd0e251e41c3f585abf4a06a4f057Davide Ciminaghisubsys_initcall(sta2x11_scr_init); 67535bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubinirootfs_initcall(sta2x11_mfd_init); 67635bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro Rubini 67735bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro RubiniMODULE_LICENSE("GPL v2"); 67835bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro RubiniMODULE_AUTHOR("Wind River"); 67935bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro RubiniMODULE_DESCRIPTION("STA2x11 mfd for GPIO, SCTL and APBREG"); 68035bdd29095ad614c5fb4a934bfd4f57a94dfd395Alessandro RubiniMODULE_DEVICE_TABLE(pci, sta2x11_mfd_tbl); 681