···11+===============================================================================22+Freescale Interlaken Look-Aside Controller Device Bindings33+Copyright 2012 Freescale Semiconductor Inc.44+55+CONTENTS66+ - Interlaken Look-Aside Controller (LAC) Node77+ - Example LAC Node88+ - Interlaken Look-Aside Controller (LAC) Software Portal Node99+ - Interlaken Look-Aside Controller (LAC) Software Portal Child Nodes1010+ - Example LAC SWP Node with Child Nodes1111+1212+==============================================================================1313+Interlaken Look-Aside Controller (LAC) Node1414+1515+DESCRIPTION1616+1717+The Interlaken is a narrow, high speed channelized chip-to-chip interface. To1818+facilitate interoperability between a data path device and a look-aside1919+co-processor, the Interlaken Look-Aside protocol is defined for short2020+transaction-related transfers. Although based on the Interlaken protocol,2121+Interlaken Look-Aside is not directly compatible with Interlaken and can be2222+considered a different operation mode.2323+2424+The Interlaken LA controller connects internal platform to Interlaken serial2525+interface. It accepts LA command through software portals, which are system2626+memory mapped 4KB spaces. The LA commands are then translated into the2727+Interlaken control words and data words, which are sent on TX side to TCAM2828+through SerDes lanes.2929+3030+There are two 4KiB spaces defined within the LAC global register memory map.3131+There is a full register set at 0x0000-0x0FFF (also known as the "hypervisor"3232+version), and a subset at 0x1000-0x1FFF. The former is a superset of the3333+latter, and includes certain registers that should not be accessible to3434+partitioned software. Separate nodes are used for each region, with a phandle3535+linking the hypervisor node to the normal operating node.3636+3737+PROPERTIES3838+3939+ - compatible4040+ Usage: required4141+ Value type: <string>4242+ Definition: Must include "fsl,interlaken-lac". This represents only4343+ those LAC CCSR registers not protected in partitioned4444+ software. The version of the device is determined by the LAC4545+ IP Block Revision Register (IPBRR0) at offset 0x0BF8.4646+4747+ Table of correspondences between IPBRR0 values and example4848+ chips:4949+ Value Device5050+ ----------- -------5151+ 0x02000100 T42405252+5353+ The Hypervisor node has a different compatible. It must include5454+ "fsl,interlaken-lac-hv". This node represents the protected5555+ LAC register space and is required except inside a partition5656+ where access to the hypervisor node is to be denied.5757+5858+ - fsl,non-hv-node5959+ Usage: required in "fsl,interlaken-lac-hv"6060+ Value type: <phandle>6161+ Definition: Points to the non-protected LAC CCSR mapped register space6262+ node.6363+6464+ - reg6565+ Usage: required6666+ Value type: <prop-encoded-array>6767+ Definition: A standard property. The first resource represents the6868+ Interlaken LAC configuration registers.6969+7070+ - interrupts:7171+ Usage: required in non-hv node only7272+ Value type: <prop-encoded-array>7373+ Definition: Interrupt mapping for Interlaken LAC error IRQ.7474+7575+EXAMPLE7676+ lac: lac@229000 {7777+ compatible = "fsl,interlaken-lac"7878+ reg = <0x229000 0x1000>;7979+ interrupts = <16 2 1 18>;8080+ };8181+8282+ lac-hv@228000 {8383+ compatible = "fsl,interlaken-lac-hv"8484+ reg = <0x228000 0x1000>;8585+ fsl,non-hv-node = <&lac>;8686+ };8787+8888+===============================================================================8989+Interlaken Look-Aside Controller (LAC) Software Portal Container Node9090+9191+DESCRIPTION9292+The Interlaken Look-Aside Controller (LAC) utilizes Software Portals to accept9393+Interlaken Look-Aside (ILA) commands. The Interlaken LAC software portal9494+memory map occupies 128KB of memory space. The software portal memory space is9595+intended to be cache-enabled. WIMG for each software space is required to be9696+0010 if stashing is enabled; otherwise, WIMG can be 0000 or 0010.9797+9898+PROPERTIES9999+100100+ - #address-cells101101+ Usage: required102102+ Value type: <u32>103103+ Definition: A standard property. Must have a value of 1.104104+105105+ - #size-cells106106+ Usage: required107107+ Value type: <u32>108108+ Definition: A standard property. Must have a value of 1.109109+110110+ - compatible111111+ Usage: required112112+ Value type: <string>113113+ Definition: Must include "fsl,interlaken-lac-portals"114114+115115+ - ranges116116+ Usage: required117117+ Value type: <prop-encoded-array>118118+ Definition: A standard property. Specifies the address and length119119+ of the LAC portal memory space.120120+121121+===============================================================================122122+Interlaken Look-Aside Controller (LAC) Software Portals Child Nodes123123+124124+DESCRIPTION125125+There are up to 24 available software portals with each software portal126126+requiring 4KB of consecutive memory within the software portal memory mapped127127+space.128128+129129+PROPERTIES130130+131131+ - compatible132132+ Usage: required133133+ Value type: <string>134134+ Definition: Must include "fsl,interlaken-lac-portal-vX.Y" where X is135135+ the Major version (IP_MJ) found in the LAC IP Block Revision136136+ Register (IPBRR0), at offset 0x0BF8, and Y is the Minor version137137+ (IP_MN).138138+139139+ Table of correspondences between version values and example chips:140140+ Value Device141141+ ------ -------142142+ 1.0 T4240143143+144144+ - reg145145+ Usage: required146146+ Value type: <prop-encoded-array>147147+ Definition: A standard property. The first resource represents the148148+ Interlaken LAC software portal registers.149149+150150+ - fsl,liodn151151+ Value type: <u32>152152+ Definition: The logical I/O device number (LIODN) for this device. The153153+ LIODN is a number expressed by this device and used to perform154154+ look-ups in the IOMMU (PAMU) address table when performing155155+ DMAs. This property is automatically added by u-boot.156156+157157+===============================================================================158158+EXAMPLE159159+160160+lac-portals {161161+ #address-cells = <0x1>;162162+ #size-cells = <0x1>;163163+ compatible = "fsl,interlaken-lac-portals";164164+ ranges = <0x0 0xf 0xf4400000 0x20000>;165165+166166+ lportal0: lac-portal@0 {167167+ compatible = "fsl,interlaken-lac-portal-v1.0";168168+ fsl,liodn = <0x204>;169169+ reg = <0x0 0x1000>;170170+ };171171+172172+ lportal1: lac-portal@1000 {173173+ compatible = "fsl,interlaken-lac-portal-v1.0";174174+ fsl,liodn = <0x205>;175175+ reg = <0x1000 0x1000>;176176+ };177177+178178+ lportal2: lac-portal@2000 {179179+ compatible = "fsl,interlaken-lac-portal-v1.0";180180+ fsl,liodn = <0x206>;181181+ reg = <0x2000 0x1000>;182182+ };183183+184184+ lportal3: lac-portal@3000 {185185+ compatible = "fsl,interlaken-lac-portal-v1.0";186186+ fsl,liodn = <0x207>;187187+ reg = <0x3000 0x1000>;188188+ };189189+190190+ lportal4: lac-portal@4000 {191191+ compatible = "fsl,interlaken-lac-portal-v1.0";192192+ fsl,liodn = <0x208>;193193+ reg = <0x4000 0x1000>;194194+ };195195+196196+ lportal5: lac-portal@5000 {197197+ compatible = "fsl,interlaken-lac-portal-v1.0";198198+ fsl,liodn = <0x209>;199199+ reg = <0x5000 0x1000>;200200+ };201201+202202+ lportal6: lac-portal@6000 {203203+ compatible = "fsl,interlaken-lac-portal-v1.0";204204+ fsl,liodn = <0x20A>;205205+ reg = <0x6000 0x1000>;206206+ };207207+208208+ lportal7: lac-portal@7000 {209209+ compatible = "fsl,interlaken-lac-portal-v1.0";210210+ fsl,liodn = <0x20B>;211211+ reg = <0x7000 0x1000>;212212+ };213213+214214+ lportal8: lac-portal@8000 {215215+ compatible = "fsl,interlaken-lac-portal-v1.0";216216+ fsl,liodn = <0x20C>;217217+ reg = <0x8000 0x1000>;218218+ };219219+220220+ lportal9: lac-portal@9000 {221221+ compatible = "fsl,interlaken-lac-portal-v1.0";222222+ fsl,liodn = <0x20D>;223223+ reg = <0x9000 0x1000>;224224+ };225225+226226+ lportal10: lac-portal@A000 {227227+ compatible = "fsl,interlaken-lac-portal-v1.0";228228+ fsl,liodn = <0x20E>;229229+ reg = <0xA000 0x1000>;230230+ };231231+232232+ lportal11: lac-portal@B000 {233233+ compatible = "fsl,interlaken-lac-portal-v1.0";234234+ fsl,liodn = <0x20F>;235235+ reg = <0xB000 0x1000>;236236+ };237237+238238+ lportal12: lac-portal@C000 {239239+ compatible = "fsl,interlaken-lac-portal-v1.0";240240+ fsl,liodn = <0x210>;241241+ reg = <0xC000 0x1000>;242242+ };243243+244244+ lportal13: lac-portal@D000 {245245+ compatible = "fsl,interlaken-lac-portal-v1.0";246246+ fsl,liodn = <0x211>;247247+ reg = <0xD000 0x1000>;248248+ };249249+250250+ lportal14: lac-portal@E000 {251251+ compatible = "fsl,interlaken-lac-portal-v1.0";252252+ fsl,liodn = <0x212>;253253+ reg = <0xE000 0x1000>;254254+ };255255+256256+ lportal15: lac-portal@F000 {257257+ compatible = "fsl,interlaken-lac-portal-v1.0";258258+ fsl,liodn = <0x213>;259259+ reg = <0xF000 0x1000>;260260+ };261261+262262+ lportal16: lac-portal@10000 {263263+ compatible = "fsl,interlaken-lac-portal-v1.0";264264+ fsl,liodn = <0x214>;265265+ reg = <0x10000 0x1000>;266266+ };267267+268268+ lportal17: lac-portal@11000 {269269+ compatible = "fsl,interlaken-lac-portal-v1.0";270270+ fsl,liodn = <0x215>;271271+ reg = <0x11000 0x1000>;272272+ };273273+274274+ lportal8: lac-portal@1200 {275275+ compatible = "fsl,interlaken-lac-portal-v1.0";276276+ fsl,liodn = <0x216>;277277+ reg = <0x12000 0x1000>;278278+ };279279+280280+ lportal19: lac-portal@13000 {281281+ compatible = "fsl,interlaken-lac-portal-v1.0";282282+ fsl,liodn = <0x217>;283283+ reg = <0x13000 0x1000>;284284+ };285285+286286+ lportal20: lac-portal@14000 {287287+ compatible = "fsl,interlaken-lac-portal-v1.0";288288+ fsl,liodn = <0x218>;289289+ reg = <0x14000 0x1000>;290290+ };291291+292292+ lportal21: lac-portal@15000 {293293+ compatible = "fsl,interlaken-lac-portal-v1.0";294294+ fsl,liodn = <0x219>;295295+ reg = <0x15000 0x1000>;296296+ };297297+298298+ lportal22: lac-portal@16000 {299299+ compatible = "fsl,interlaken-lac-portal-v1.0";300300+ fsl,liodn = <0x21A>;301301+ reg = <0x16000 0x1000>;302302+ };303303+304304+ lportal23: lac-portal@17000 {305305+ compatible = "fsl,interlaken-lac-portal-v1.0";306306+ fsl,liodn = <0x21B>;307307+ reg = <0x17000 0x1000>;308308+ };309309+};
···11+/* T4240 Interlaken LAC Portal device tree stub with 24 portals.22+ *33+ * Copyright 2012 Freescale Semiconductor Inc.44+ *55+ * Redistribution and use in source and binary forms, with or without66+ * modification, are permitted provided that the following conditions are met:77+ * * Redistributions of source code must retain the above copyright88+ * notice, this list of conditions and the following disclaimer.99+ * * Redistributions in binary form must reproduce the above copyright1010+ * notice, this list of conditions and the following disclaimer in the1111+ * documentation and/or other materials provided with the distribution.1212+ * * Neither the name of Freescale Semiconductor nor the1313+ * names of its contributors may be used to endorse or promote products1414+ * derived from this software without specific prior written permission.1515+ *1616+ *1717+ * ALTERNATIVELY, this software may be distributed under the terms of the1818+ * GNU General Public License ("GPL") as published by the Free Software1919+ * Foundation, either version 2 of that License or (at your option) any2020+ * later version.2121+ *2222+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY2323+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED2424+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE2525+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY2626+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES2727+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;2828+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND2929+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT3030+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3131+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3232+ */3333+3434+#address-cells = <0x1>;3535+#size-cells = <0x1>;3636+compatible = "fsl,interlaken-lac-portals";3737+3838+lportal0: lac-portal@0 {3939+ compatible = "fsl,interlaken-lac-portal-v1.0";4040+ reg = <0x0 0x1000>;4141+};4242+4343+lportal1: lac-portal@1000 {4444+ compatible = "fsl,interlaken-lac-portal-v1.0";4545+ reg = <0x1000 0x1000>;4646+};4747+4848+lportal2: lac-portal@2000 {4949+ compatible = "fsl,interlaken-lac-portal-v1.0";5050+ reg = <0x2000 0x1000>;5151+};5252+5353+lportal3: lac-portal@3000 {5454+ compatible = "fsl,interlaken-lac-portal-v1.0";5555+ reg = <0x3000 0x1000>;5656+};5757+5858+lportal4: lac-portal@4000 {5959+ compatible = "fsl,interlaken-lac-portal-v1.0";6060+ reg = <0x4000 0x1000>;6161+};6262+6363+lportal5: lac-portal@5000 {6464+ compatible = "fsl,interlaken-lac-portal-v1.0";6565+ reg = <0x5000 0x1000>;6666+};6767+6868+lportal6: lac-portal@6000 {6969+ compatible = "fsl,interlaken-lac-portal-v1.0";7070+ reg = <0x6000 0x1000>;7171+};7272+7373+lportal7: lac-portal@7000 {7474+ compatible = "fsl,interlaken-lac-portal-v1.0";7575+ reg = <0x7000 0x1000>;7676+};7777+7878+lportal8: lac-portal@8000 {7979+ compatible = "fsl,interlaken-lac-portal-v1.0";8080+ reg = <0x8000 0x1000>;8181+};8282+8383+lportal9: lac-portal@9000 {8484+ compatible = "fsl,interlaken-lac-portal-v1.0";8585+ reg = <0x9000 0x1000>;8686+};8787+8888+lportal10: lac-portal@A000 {8989+ compatible = "fsl,interlaken-lac-portal-v1.0";9090+ reg = <0xA000 0x1000>;9191+};9292+9393+lportal11: lac-portal@B000 {9494+ compatible = "fsl,interlaken-lac-portal-v1.0";9595+ reg = <0xB000 0x1000>;9696+};9797+9898+lportal12: lac-portal@C000 {9999+ compatible = "fsl,interlaken-lac-portal-v1.0";100100+ reg = <0xC000 0x1000>;101101+};102102+103103+lportal13: lac-portal@D000 {104104+ compatible = "fsl,interlaken-lac-portal-v1.0";105105+ reg = <0xD000 0x1000>;106106+};107107+108108+lportal14: lac-portal@E000 {109109+ compatible = "fsl,interlaken-lac-portal-v1.0";110110+ reg = <0xE000 0x1000>;111111+};112112+113113+lportal15: lac-portal@F000 {114114+ compatible = "fsl,interlaken-lac-portal-v1.0";115115+ reg = <0xF000 0x1000>;116116+};117117+118118+lportal16: lac-portal@10000 {119119+ compatible = "fsl,interlaken-lac-portal-v1.0";120120+ reg = <0x10000 0x1000>;121121+};122122+123123+lportal17: lac-portal@11000 {124124+ compatible = "fsl,interlaken-lac-portal-v1.0";125125+ reg = <0x11000 0x1000>;126126+};127127+128128+lportal18: lac-portal@1200 {129129+ compatible = "fsl,interlaken-lac-portal-v1.0";130130+ reg = <0x12000 0x1000>;131131+};132132+133133+lportal19: lac-portal@13000 {134134+ compatible = "fsl,interlaken-lac-portal-v1.0";135135+ reg = <0x13000 0x1000>;136136+};137137+138138+lportal20: lac-portal@14000 {139139+ compatible = "fsl,interlaken-lac-portal-v1.0";140140+ reg = <0x14000 0x1000>;141141+};142142+143143+lportal21: lac-portal@15000 {144144+ compatible = "fsl,interlaken-lac-portal-v1.0";145145+ reg = <0x15000 0x1000>;146146+};147147+148148+lportal22: lac-portal@16000 {149149+ compatible = "fsl,interlaken-lac-portal-v1.0";150150+ reg = <0x16000 0x1000>;151151+};152152+153153+lportal23: lac-portal@17000 {154154+ compatible = "fsl,interlaken-lac-portal-v1.0";155155+ reg = <0x17000 0x1000>;156156+};
+45
arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi
···11+/*22+ * T4 Interlaken Look-aside Controller (LAC) device tree stub33+ *44+ * Copyright 2012 Freescale Semiconductor Inc.55+ *66+ * Redistribution and use in source and binary forms, with or without77+ * modification, are permitted provided that the following conditions are met:88+ * * Redistributions of source code must retain the above copyright99+ * notice, this list of conditions and the following disclaimer.1010+ * * Redistributions in binary form must reproduce the above copyright1111+ * notice, this list of conditions and the following disclaimer in the1212+ * documentation and/or other materials provided with the distribution.1313+ * * Neither the name of Freescale Semiconductor nor the1414+ * names of its contributors may be used to endorse or promote products1515+ * derived from this software without specific prior written permission.1616+ *1717+ *1818+ * ALTERNATIVELY, this software may be distributed under the terms of the1919+ * GNU General Public License ("GPL") as published by the Free Software2020+ * Foundation, either version 2 of that License or (at your option) any2121+ * later version.2222+ *2323+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY2424+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED2525+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE2626+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY2727+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES2828+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;2929+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND3030+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT3131+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS3232+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.3333+ */3434+3535+lac: lac@229000 {3636+ compatible = "fsl,interlaken-lac";3737+ reg = <0x229000 0x1000>;3838+ interrupts = <16 2 1 18>;3939+};4040+4141+lac-hv@228000 {4242+ compatible = "fsl,interlaken-lac-hv";4343+ reg = <0x228000 0x1000>;4444+ fsl,non-hv-node = <&lac>;4545+};
···339339#endif340340};341341342342+extern struct bus_type mpic_subsys;343343+342344/*343345 * MPIC flags (passed to mpic_alloc)344346 *···394392395393#define MPIC_REGSET_STANDARD MPIC_REGSET(0) /* Original MPIC */396394#define MPIC_REGSET_TSI108 MPIC_REGSET(1) /* Tsi108/109 PIC */395395+396396+/* Get the version of primary MPIC */397397+extern u32 fsl_mpic_primary_get_version(void);397398398399/* Allocate the controller structure and setup the linux irq descs399400 * for the range if interrupts passed in. No HW initialization is
+46
arch/powerpc/include/asm/mpic_timer.h
···11+/*22+ * arch/powerpc/include/asm/mpic_timer.h33+ *44+ * Header file for Mpic Global Timer55+ *66+ * Copyright 2013 Freescale Semiconductor, Inc.77+ *88+ * Author: Wang Dongsheng <Dongsheng.Wang@freescale.com>99+ * Li Yang <leoli@freescale.com>1010+ *1111+ * This program is free software; you can redistribute it and/or modify it1212+ * under the terms of the GNU General Public License as published by the1313+ * Free Software Foundation; either version 2 of the License, or (at your1414+ * option) any later version.1515+ */1616+1717+#ifndef __MPIC_TIMER__1818+#define __MPIC_TIMER__1919+2020+#include <linux/interrupt.h>2121+#include <linux/time.h>2222+2323+struct mpic_timer {2424+ void *dev;2525+ struct cascade_priv *cascade_handle;2626+ unsigned int num;2727+ unsigned int irq;2828+};2929+3030+#ifdef CONFIG_MPIC_TIMER3131+struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev,3232+ const struct timeval *time);3333+void mpic_start_timer(struct mpic_timer *handle);3434+void mpic_stop_timer(struct mpic_timer *handle);3535+void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time);3636+void mpic_free_timer(struct mpic_timer *handle);3737+#else3838+struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev,3939+ const struct timeval *time) { return NULL; }4040+void mpic_start_timer(struct mpic_timer *handle) { }4141+void mpic_stop_timer(struct mpic_timer *handle) { }4242+void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time) { }4343+void mpic_free_timer(struct mpic_timer *handle) { }4444+#endif4545+4646+#endif
+1-11
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
···231231 .id_table = mcu_ids,232232};233233234234-static int __init mcu_init(void)235235-{236236- return i2c_add_driver(&mcu_driver);237237-}238238-module_init(mcu_init);239239-240240-static void __exit mcu_exit(void)241241-{242242- i2c_del_driver(&mcu_driver);243243-}244244-module_exit(mcu_exit);234234+module_i2c_driver(mcu_driver);245235246236MODULE_DESCRIPTION("Power Management and GPIO expander driver for "247237 "MPC8349E-mITX-compatible MCU");
-5
arch/powerpc/platforms/85xx/p5020_ds.c
···7575#ifdef CONFIG_PCI7676 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,7777#endif7878-/* coreint doesn't play nice with lazy EE, use legacy mpic for now */7979-#ifdef CONFIG_PPC648080- .get_irq = mpic_get_irq,8181-#else8278 .get_irq = mpic_get_coreint_irq,8383-#endif8479 .restart = fsl_rstcr_restart,8580 .calibrate_decr = generic_calibrate_decr,8681 .progress = udbg_progress,
-5
arch/powerpc/platforms/85xx/p5040_ds.c
···6666#ifdef CONFIG_PCI6767 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,6868#endif6969-/* coreint doesn't play nice with lazy EE, use legacy mpic for now */7070-#ifdef CONFIG_PPC647171- .get_irq = mpic_get_irq,7272-#else7369 .get_irq = mpic_get_coreint_irq,7474-#endif7570 .restart = fsl_rstcr_restart,7671 .calibrate_decr = generic_calibrate_decr,7772 .progress = udbg_progress,
-5
arch/powerpc/platforms/85xx/t4240_qds.c
···7575#ifdef CONFIG_PCI7676 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,7777#endif7878-/* coreint doesn't play nice with lazy EE, use legacy mpic for now */7979-#ifdef CONFIG_PPC648080- .get_irq = mpic_get_irq,8181-#else8278 .get_irq = mpic_get_coreint_irq,8383-#endif8479 .restart = fsl_rstcr_restart,8580 .calibrate_decr = generic_calibrate_decr,8681 .progress = udbg_progress,
+3-10
arch/powerpc/platforms/8xx/m8xx_setup.c
···219219220220static void cpm_cascade(unsigned int irq, struct irq_desc *desc)221221{222222- struct irq_chip *chip;223223- int cascade_irq;222222+ struct irq_chip *chip = irq_desc_get_chip(desc);223223+ int cascade_irq = cpm_get_irq();224224225225- if ((cascade_irq = cpm_get_irq()) >= 0) {226226- struct irq_desc *cdesc = irq_to_desc(cascade_irq);227227-225225+ if (cascade_irq >= 0)228226 generic_handle_irq(cascade_irq);229227230230- chip = irq_desc_get_chip(cdesc);231231- chip->irq_eoi(&cdesc->irq_data);232232- }233233-234234- chip = irq_desc_get_chip(desc);235228 chip->irq_eoi(&desc->irq_data);236229}237230
+21
arch/powerpc/platforms/Kconfig
···8686 bool8787 default n88888989+config MPIC_TIMER9090+ bool "MPIC Global Timer"9191+ depends on MPIC && FSL_SOC9292+ default n9393+ help9494+ The MPIC global timer is a hardware timer inside the9595+ Freescale PIC complying with OpenPIC standard. When the9696+ specified interval times out, the hardware timer generates9797+ an interrupt. The driver currently is only tested on fsl9898+ chip, but it can potentially support other global timers9999+ complying with the OpenPIC standard.100100+101101+config FSL_MPIC_TIMER_WAKEUP102102+ tristate "Freescale MPIC global timer wakeup driver"103103+ depends on FSL_SOC && MPIC_TIMER && PM104104+ default n105105+ help106106+ The driver provides a way to wake up the system by MPIC107107+ timer.108108+ e.g. "echo 5 > /sys/devices/system/mpic/timer_wakeup"109109+89110config PPC_EPAPR_HV_PIC90111 bool91112 default n
···11+/*22+ * MPIC timer driver33+ *44+ * Copyright 2013 Freescale Semiconductor, Inc.55+ * Author: Dongsheng Wang <Dongsheng.Wang@freescale.com>66+ * Li Yang <leoli@freescale.com>77+ *88+ * This program is free software; you can redistribute it and/or modify it99+ * under the terms of the GNU General Public License as published by the1010+ * Free Software Foundation; either version 2 of the License, or (at your1111+ * option) any later version.1212+ */1313+1414+#include <linux/kernel.h>1515+#include <linux/init.h>1616+#include <linux/module.h>1717+#include <linux/errno.h>1818+#include <linux/mm.h>1919+#include <linux/interrupt.h>2020+#include <linux/slab.h>2121+#include <linux/of.h>2222+#include <linux/of_device.h>2323+#include <linux/syscore_ops.h>2424+#include <sysdev/fsl_soc.h>2525+#include <asm/io.h>2626+2727+#include <asm/mpic_timer.h>2828+2929+#define FSL_GLOBAL_TIMER 0x13030+3131+/* Clock Ratio3232+ * Divide by 64 0x000003003333+ * Divide by 32 0x000002003434+ * Divide by 16 0x000001003535+ * Divide by 8 0x00000000 (Hardware default div)3636+ */3737+#define MPIC_TIMER_TCR_CLKDIV 0x000003003838+3939+#define MPIC_TIMER_TCR_ROVR_OFFSET 244040+4141+#define TIMER_STOP 0x800000004242+#define TIMERS_PER_GROUP 44343+#define MAX_TICKS (~0U >> 1)4444+#define MAX_TICKS_CASCADE (~0U)4545+#define TIMER_OFFSET(num) (1 << (TIMERS_PER_GROUP - 1 - num))4646+4747+/* tv_usec should be less than ONE_SECOND, otherwise use tv_sec */4848+#define ONE_SECOND 10000004949+5050+struct timer_regs {5151+ u32 gtccr;5252+ u32 res0[3];5353+ u32 gtbcr;5454+ u32 res1[3];5555+ u32 gtvpr;5656+ u32 res2[3];5757+ u32 gtdr;5858+ u32 res3[3];5959+};6060+6161+struct cascade_priv {6262+ u32 tcr_value; /* TCR register: CASC & ROVR value */6363+ unsigned int cascade_map; /* cascade map */6464+ unsigned int timer_num; /* cascade control timer */6565+};6666+6767+struct timer_group_priv {6868+ struct timer_regs __iomem *regs;6969+ struct mpic_timer timer[TIMERS_PER_GROUP];7070+ struct list_head node;7171+ unsigned int timerfreq;7272+ unsigned int idle;7373+ unsigned int flags;7474+ spinlock_t lock;7575+ void __iomem *group_tcr;7676+};7777+7878+static struct cascade_priv cascade_timer[] = {7979+ /* cascade timer 0 and 1 */8080+ {0x1, 0xc, 0x1},8181+ /* cascade timer 1 and 2 */8282+ {0x2, 0x6, 0x2},8383+ /* cascade timer 2 and 3 */8484+ {0x4, 0x3, 0x3}8585+};8686+8787+static LIST_HEAD(timer_group_list);8888+8989+static void convert_ticks_to_time(struct timer_group_priv *priv,9090+ const u64 ticks, struct timeval *time)9191+{9292+ u64 tmp_sec;9393+9494+ time->tv_sec = (__kernel_time_t)div_u64(ticks, priv->timerfreq);9595+ tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq;9696+9797+ time->tv_usec = (__kernel_suseconds_t)9898+ div_u64((ticks - tmp_sec) * 1000000, priv->timerfreq);9999+100100+ return;101101+}102102+103103+/* the time set by the user is converted to "ticks" */104104+static int convert_time_to_ticks(struct timer_group_priv *priv,105105+ const struct timeval *time, u64 *ticks)106106+{107107+ u64 max_value; /* prevent u64 overflow */108108+ u64 tmp = 0;109109+110110+ u64 tmp_sec;111111+ u64 tmp_ms;112112+ u64 tmp_us;113113+114114+ max_value = div_u64(ULLONG_MAX, priv->timerfreq);115115+116116+ if (time->tv_sec > max_value ||117117+ (time->tv_sec == max_value && time->tv_usec > 0))118118+ return -EINVAL;119119+120120+ tmp_sec = (u64)time->tv_sec * (u64)priv->timerfreq;121121+ tmp += tmp_sec;122122+123123+ tmp_ms = time->tv_usec / 1000;124124+ tmp_ms = div_u64((u64)tmp_ms * (u64)priv->timerfreq, 1000);125125+ tmp += tmp_ms;126126+127127+ tmp_us = time->tv_usec % 1000;128128+ tmp_us = div_u64((u64)tmp_us * (u64)priv->timerfreq, 1000000);129129+ tmp += tmp_us;130130+131131+ *ticks = tmp;132132+133133+ return 0;134134+}135135+136136+/* detect whether there is a cascade timer available */137137+static struct mpic_timer *detect_idle_cascade_timer(138138+ struct timer_group_priv *priv)139139+{140140+ struct cascade_priv *casc_priv;141141+ unsigned int map;142142+ unsigned int array_size = ARRAY_SIZE(cascade_timer);143143+ unsigned int num;144144+ unsigned int i;145145+ unsigned long flags;146146+147147+ casc_priv = cascade_timer;148148+ for (i = 0; i < array_size; i++) {149149+ spin_lock_irqsave(&priv->lock, flags);150150+ map = casc_priv->cascade_map & priv->idle;151151+ if (map == casc_priv->cascade_map) {152152+ num = casc_priv->timer_num;153153+ priv->timer[num].cascade_handle = casc_priv;154154+155155+ /* set timer busy */156156+ priv->idle &= ~casc_priv->cascade_map;157157+ spin_unlock_irqrestore(&priv->lock, flags);158158+ return &priv->timer[num];159159+ }160160+ spin_unlock_irqrestore(&priv->lock, flags);161161+ casc_priv++;162162+ }163163+164164+ return NULL;165165+}166166+167167+static int set_cascade_timer(struct timer_group_priv *priv, u64 ticks,168168+ unsigned int num)169169+{170170+ struct cascade_priv *casc_priv;171171+ u32 tcr;172172+ u32 tmp_ticks;173173+ u32 rem_ticks;174174+175175+ /* set group tcr reg for cascade */176176+ casc_priv = priv->timer[num].cascade_handle;177177+ if (!casc_priv)178178+ return -EINVAL;179179+180180+ tcr = casc_priv->tcr_value |181181+ (casc_priv->tcr_value << MPIC_TIMER_TCR_ROVR_OFFSET);182182+ setbits32(priv->group_tcr, tcr);183183+184184+ tmp_ticks = div_u64_rem(ticks, MAX_TICKS_CASCADE, &rem_ticks);185185+186186+ out_be32(&priv->regs[num].gtccr, 0);187187+ out_be32(&priv->regs[num].gtbcr, tmp_ticks | TIMER_STOP);188188+189189+ out_be32(&priv->regs[num - 1].gtccr, 0);190190+ out_be32(&priv->regs[num - 1].gtbcr, rem_ticks);191191+192192+ return 0;193193+}194194+195195+static struct mpic_timer *get_cascade_timer(struct timer_group_priv *priv,196196+ u64 ticks)197197+{198198+ struct mpic_timer *allocated_timer;199199+200200+ /* Two cascade timers: Support the maximum time */201201+ const u64 max_ticks = (u64)MAX_TICKS * (u64)MAX_TICKS_CASCADE;202202+ int ret;203203+204204+ if (ticks > max_ticks)205205+ return NULL;206206+207207+ /* detect idle timer */208208+ allocated_timer = detect_idle_cascade_timer(priv);209209+ if (!allocated_timer)210210+ return NULL;211211+212212+ /* set ticks to timer */213213+ ret = set_cascade_timer(priv, ticks, allocated_timer->num);214214+ if (ret < 0)215215+ return NULL;216216+217217+ return allocated_timer;218218+}219219+220220+static struct mpic_timer *get_timer(const struct timeval *time)221221+{222222+ struct timer_group_priv *priv;223223+ struct mpic_timer *timer;224224+225225+ u64 ticks;226226+ unsigned int num;227227+ unsigned int i;228228+ unsigned long flags;229229+ int ret;230230+231231+ list_for_each_entry(priv, &timer_group_list, node) {232232+ ret = convert_time_to_ticks(priv, time, &ticks);233233+ if (ret < 0)234234+ return NULL;235235+236236+ if (ticks > MAX_TICKS) {237237+ if (!(priv->flags & FSL_GLOBAL_TIMER))238238+ return NULL;239239+240240+ timer = get_cascade_timer(priv, ticks);241241+ if (!timer)242242+ continue;243243+244244+ return timer;245245+ }246246+247247+ for (i = 0; i < TIMERS_PER_GROUP; i++) {248248+ /* one timer: Reverse allocation */249249+ num = TIMERS_PER_GROUP - 1 - i;250250+ spin_lock_irqsave(&priv->lock, flags);251251+ if (priv->idle & (1 << i)) {252252+ /* set timer busy */253253+ priv->idle &= ~(1 << i);254254+ /* set ticks & stop timer */255255+ out_be32(&priv->regs[num].gtbcr,256256+ ticks | TIMER_STOP);257257+ out_be32(&priv->regs[num].gtccr, 0);258258+ priv->timer[num].cascade_handle = NULL;259259+ spin_unlock_irqrestore(&priv->lock, flags);260260+ return &priv->timer[num];261261+ }262262+ spin_unlock_irqrestore(&priv->lock, flags);263263+ }264264+ }265265+266266+ return NULL;267267+}268268+269269+/**270270+ * mpic_start_timer - start hardware timer271271+ * @handle: the timer to be started.272272+ *273273+ * It will do ->fn(->dev) callback from the hardware interrupt at274274+ * the ->timeval point in the future.275275+ */276276+void mpic_start_timer(struct mpic_timer *handle)277277+{278278+ struct timer_group_priv *priv = container_of(handle,279279+ struct timer_group_priv, timer[handle->num]);280280+281281+ clrbits32(&priv->regs[handle->num].gtbcr, TIMER_STOP);282282+}283283+EXPORT_SYMBOL(mpic_start_timer);284284+285285+/**286286+ * mpic_stop_timer - stop hardware timer287287+ * @handle: the timer to be stoped288288+ *289289+ * The timer periodically generates an interrupt. Unless user stops the timer.290290+ */291291+void mpic_stop_timer(struct mpic_timer *handle)292292+{293293+ struct timer_group_priv *priv = container_of(handle,294294+ struct timer_group_priv, timer[handle->num]);295295+ struct cascade_priv *casc_priv;296296+297297+ setbits32(&priv->regs[handle->num].gtbcr, TIMER_STOP);298298+299299+ casc_priv = priv->timer[handle->num].cascade_handle;300300+ if (casc_priv) {301301+ out_be32(&priv->regs[handle->num].gtccr, 0);302302+ out_be32(&priv->regs[handle->num - 1].gtccr, 0);303303+ } else {304304+ out_be32(&priv->regs[handle->num].gtccr, 0);305305+ }306306+}307307+EXPORT_SYMBOL(mpic_stop_timer);308308+309309+/**310310+ * mpic_get_remain_time - get timer time311311+ * @handle: the timer to be selected.312312+ * @time: time for timer313313+ *314314+ * Query timer remaining time.315315+ */316316+void mpic_get_remain_time(struct mpic_timer *handle, struct timeval *time)317317+{318318+ struct timer_group_priv *priv = container_of(handle,319319+ struct timer_group_priv, timer[handle->num]);320320+ struct cascade_priv *casc_priv;321321+322322+ u64 ticks;323323+ u32 tmp_ticks;324324+325325+ casc_priv = priv->timer[handle->num].cascade_handle;326326+ if (casc_priv) {327327+ tmp_ticks = in_be32(&priv->regs[handle->num].gtccr);328328+ ticks = ((u64)tmp_ticks & UINT_MAX) * (u64)MAX_TICKS_CASCADE;329329+ tmp_ticks = in_be32(&priv->regs[handle->num - 1].gtccr);330330+ ticks += tmp_ticks;331331+ } else {332332+ ticks = in_be32(&priv->regs[handle->num].gtccr);333333+ }334334+335335+ convert_ticks_to_time(priv, ticks, time);336336+}337337+EXPORT_SYMBOL(mpic_get_remain_time);338338+339339+/**340340+ * mpic_free_timer - free hardware timer341341+ * @handle: the timer to be removed.342342+ *343343+ * Free the timer.344344+ *345345+ * Note: can not be used in interrupt context.346346+ */347347+void mpic_free_timer(struct mpic_timer *handle)348348+{349349+ struct timer_group_priv *priv = container_of(handle,350350+ struct timer_group_priv, timer[handle->num]);351351+352352+ struct cascade_priv *casc_priv;353353+ unsigned long flags;354354+355355+ mpic_stop_timer(handle);356356+357357+ casc_priv = priv->timer[handle->num].cascade_handle;358358+359359+ free_irq(priv->timer[handle->num].irq, priv->timer[handle->num].dev);360360+361361+ spin_lock_irqsave(&priv->lock, flags);362362+ if (casc_priv) {363363+ u32 tcr;364364+ tcr = casc_priv->tcr_value | (casc_priv->tcr_value <<365365+ MPIC_TIMER_TCR_ROVR_OFFSET);366366+ clrbits32(priv->group_tcr, tcr);367367+ priv->idle |= casc_priv->cascade_map;368368+ priv->timer[handle->num].cascade_handle = NULL;369369+ } else {370370+ priv->idle |= TIMER_OFFSET(handle->num);371371+ }372372+ spin_unlock_irqrestore(&priv->lock, flags);373373+}374374+EXPORT_SYMBOL(mpic_free_timer);375375+376376+/**377377+ * mpic_request_timer - get a hardware timer378378+ * @fn: interrupt handler function379379+ * @dev: callback function of the data380380+ * @time: time for timer381381+ *382382+ * This executes the "request_irq", returning NULL383383+ * else "handle" on success.384384+ */385385+struct mpic_timer *mpic_request_timer(irq_handler_t fn, void *dev,386386+ const struct timeval *time)387387+{388388+ struct mpic_timer *allocated_timer;389389+ int ret;390390+391391+ if (list_empty(&timer_group_list))392392+ return NULL;393393+394394+ if (!(time->tv_sec + time->tv_usec) ||395395+ time->tv_sec < 0 || time->tv_usec < 0)396396+ return NULL;397397+398398+ if (time->tv_usec > ONE_SECOND)399399+ return NULL;400400+401401+ allocated_timer = get_timer(time);402402+ if (!allocated_timer)403403+ return NULL;404404+405405+ ret = request_irq(allocated_timer->irq, fn,406406+ IRQF_TRIGGER_LOW, "global-timer", dev);407407+ if (ret) {408408+ mpic_free_timer(allocated_timer);409409+ return NULL;410410+ }411411+412412+ allocated_timer->dev = dev;413413+414414+ return allocated_timer;415415+}416416+EXPORT_SYMBOL(mpic_request_timer);417417+418418+static int timer_group_get_freq(struct device_node *np,419419+ struct timer_group_priv *priv)420420+{421421+ u32 div;422422+423423+ if (priv->flags & FSL_GLOBAL_TIMER) {424424+ struct device_node *dn;425425+426426+ dn = of_find_compatible_node(NULL, NULL, "fsl,mpic");427427+ if (dn) {428428+ of_property_read_u32(dn, "clock-frequency",429429+ &priv->timerfreq);430430+ of_node_put(dn);431431+ }432432+ }433433+434434+ if (priv->timerfreq <= 0)435435+ return -EINVAL;436436+437437+ if (priv->flags & FSL_GLOBAL_TIMER) {438438+ div = (1 << (MPIC_TIMER_TCR_CLKDIV >> 8)) * 8;439439+ priv->timerfreq /= div;440440+ }441441+442442+ return 0;443443+}444444+445445+static int timer_group_get_irq(struct device_node *np,446446+ struct timer_group_priv *priv)447447+{448448+ const u32 all_timer[] = { 0, TIMERS_PER_GROUP };449449+ const u32 *p;450450+ u32 offset;451451+ u32 count;452452+453453+ unsigned int i;454454+ unsigned int j;455455+ unsigned int irq_index = 0;456456+ unsigned int irq;457457+ int len;458458+459459+ p = of_get_property(np, "fsl,available-ranges", &len);460460+ if (p && len % (2 * sizeof(u32)) != 0) {461461+ pr_err("%s: malformed available-ranges property.\n",462462+ np->full_name);463463+ return -EINVAL;464464+ }465465+466466+ if (!p) {467467+ p = all_timer;468468+ len = sizeof(all_timer);469469+ }470470+471471+ len /= 2 * sizeof(u32);472472+473473+ for (i = 0; i < len; i++) {474474+ offset = p[i * 2];475475+ count = p[i * 2 + 1];476476+ for (j = 0; j < count; j++) {477477+ irq = irq_of_parse_and_map(np, irq_index);478478+ if (!irq) {479479+ pr_err("%s: irq parse and map failed.\n",480480+ np->full_name);481481+ return -EINVAL;482482+ }483483+484484+ /* Set timer idle */485485+ priv->idle |= TIMER_OFFSET((offset + j));486486+ priv->timer[offset + j].irq = irq;487487+ priv->timer[offset + j].num = offset + j;488488+ irq_index++;489489+ }490490+ }491491+492492+ return 0;493493+}494494+495495+static void timer_group_init(struct device_node *np)496496+{497497+ struct timer_group_priv *priv;498498+ unsigned int i = 0;499499+ int ret;500500+501501+ priv = kzalloc(sizeof(struct timer_group_priv), GFP_KERNEL);502502+ if (!priv) {503503+ pr_err("%s: cannot allocate memory for group.\n",504504+ np->full_name);505505+ return;506506+ }507507+508508+ if (of_device_is_compatible(np, "fsl,mpic-global-timer"))509509+ priv->flags |= FSL_GLOBAL_TIMER;510510+511511+ priv->regs = of_iomap(np, i++);512512+ if (!priv->regs) {513513+ pr_err("%s: cannot ioremap timer register address.\n",514514+ np->full_name);515515+ goto out;516516+ }517517+518518+ if (priv->flags & FSL_GLOBAL_TIMER) {519519+ priv->group_tcr = of_iomap(np, i++);520520+ if (!priv->group_tcr) {521521+ pr_err("%s: cannot ioremap tcr address.\n",522522+ np->full_name);523523+ goto out;524524+ }525525+ }526526+527527+ ret = timer_group_get_freq(np, priv);528528+ if (ret < 0) {529529+ pr_err("%s: cannot get timer frequency.\n", np->full_name);530530+ goto out;531531+ }532532+533533+ ret = timer_group_get_irq(np, priv);534534+ if (ret < 0) {535535+ pr_err("%s: cannot get timer irqs.\n", np->full_name);536536+ goto out;537537+ }538538+539539+ spin_lock_init(&priv->lock);540540+541541+ /* Init FSL timer hardware */542542+ if (priv->flags & FSL_GLOBAL_TIMER)543543+ setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);544544+545545+ list_add_tail(&priv->node, &timer_group_list);546546+547547+ return;548548+549549+out:550550+ if (priv->regs)551551+ iounmap(priv->regs);552552+553553+ if (priv->group_tcr)554554+ iounmap(priv->group_tcr);555555+556556+ kfree(priv);557557+}558558+559559+static void mpic_timer_resume(void)560560+{561561+ struct timer_group_priv *priv;562562+563563+ list_for_each_entry(priv, &timer_group_list, node) {564564+ /* Init FSL timer hardware */565565+ if (priv->flags & FSL_GLOBAL_TIMER)566566+ setbits32(priv->group_tcr, MPIC_TIMER_TCR_CLKDIV);567567+ }568568+}569569+570570+static const struct of_device_id mpic_timer_ids[] = {571571+ { .compatible = "fsl,mpic-global-timer", },572572+ {},573573+};574574+575575+static struct syscore_ops mpic_timer_syscore_ops = {576576+ .resume = mpic_timer_resume,577577+};578578+579579+static int __init mpic_timer_init(void)580580+{581581+ struct device_node *np = NULL;582582+583583+ for_each_matching_node(np, mpic_timer_ids)584584+ timer_group_init(np);585585+586586+ register_syscore_ops(&mpic_timer_syscore_ops);587587+588588+ if (list_empty(&timer_group_list))589589+ return -ENODEV;590590+591591+ return 0;592592+}593593+subsys_initcall(mpic_timer_init);
+8
drivers/i2c/busses/i2c-cpm.c
···338338 tptr = 0;339339 rptr = 0;340340341341+ /*342342+ * If there was a collision in the last i2c transaction,343343+ * Set I2COM_MASTER as it was cleared during collision.344344+ */345345+ if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) {346346+ out_8(&cpm->i2c_reg->i2com, I2COM_MASTER);347347+ }348348+341349 while (tptr < num) {342350 pmsg = &msgs[tptr];343351 dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr);
+8
drivers/watchdog/booke_wdt.c
···138138 val &= ~WDTP_MASK;139139 val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));140140141141+#ifdef CONFIG_PPC_BOOK3E_64142142+ /*143143+ * Crit ints are currently broken on PPC64 Book-E, so144144+ * just disable them for now.145145+ */146146+ val &= ~TCR_WIE;147147+#endif148148+141149 mtspr(SPRN_TCR, val);142150}143151