diff options
685 files changed, 21747 insertions, 5907 deletions
@@ -3554,12 +3554,12 @@ E: cvance@nai.com D: portions of the Linux Security Module (LSM) framework and security modules N: Petr Vandrovec -E: vandrove@vc.cvut.cz +E: petr@vandrovec.name D: Small contributions to ncpfs D: Matrox framebuffer driver -S: Chudenicka 8 -S: 10200 Prague 10, Hostivar -S: Czech Republic +S: 21513 Conradia Ct +S: Cupertino, CA 95014 +S: USA N: Thibaut Varene E: T-Bone@parisc-linux.org diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX index 7f5fc3ba9c91..ecf7d04bca26 100644 --- a/Documentation/arm/00-INDEX +++ b/Documentation/arm/00-INDEX @@ -6,6 +6,8 @@ Interrupts - ARM Interrupt subsystem documentation IXP2000 - Release Notes for Linux on Intel's IXP2000 Network Processor +msm + - MSM specific documentation Netwinder - Netwinder specific documentation Porting diff --git a/Documentation/arm/msm/gpiomux.txt b/Documentation/arm/msm/gpiomux.txt new file mode 100644 index 000000000000..67a81620adf6 --- /dev/null +++ b/Documentation/arm/msm/gpiomux.txt @@ -0,0 +1,176 @@ +This document provides an overview of the msm_gpiomux interface, which +is used to provide gpio pin multiplexing and configuration on mach-msm +targets. + +History +======= + +The first-generation API for gpio configuration & multiplexing on msm +is the function gpio_tlmm_config(). This function has a few notable +shortcomings, which led to its deprecation and replacement by gpiomux: + +The 'disable' parameter: Setting the second parameter to +gpio_tlmm_config to GPIO_CFG_DISABLE tells the peripheral +processor in charge of the subsystem to perform a look-up into a +low-power table and apply the low-power/sleep setting for the pin. +As the msm family evolved this became problematic. Not all pins +have sleep settings, not all peripheral processors will accept requests +to apply said sleep settings, and not all msm targets have their gpio +subsystems managed by a peripheral processor. In order to get consistent +behavior on all targets, drivers are forced to ignore this parameter, +rendering it useless. + +The 'direction' flag: for all mux-settings other than raw-gpio (0), +the output-enable bit of a gpio is hard-wired to a known +input (usually VDD or ground). For those settings, the direction flag +is meaningless at best, and deceptive at worst. In addition, using the +direction flag to change output-enable (OE) directly can cause trouble in +gpiolib, which has no visibility into gpio direction changes made +in this way. Direction control in gpio mode should be made through gpiolib. + +Key Features of gpiomux +======================= + +- A consistent interface across all generations of msm. Drivers can expect +the same results on every target. +- gpiomux plays nicely with gpiolib. Functions that should belong to gpiolib +are left to gpiolib and not duplicated here. gpiomux is written with the +intent that gpio_chips will call gpiomux reference-counting methods +from their request() and free() hooks, providing full integration. +- Tabular configuration. Instead of having to call gpio_tlmm_config +hundreds of times, gpio configuration is placed in a single table. +- Per-gpio sleep. Each gpio is individually reference counted, allowing only +those lines which are in use to be put in high-power states. +- 0 means 'do nothing': all flags are designed so that the default memset-zero +equates to a sensible default of 'no configuration', preventing users +from having to provide hundreds of 'no-op' configs for unused or +unwanted lines. + +Usage +===== + +To use gpiomux, provide configuration information for relevant gpio lines +in the msm_gpiomux_configs table. Since a 0 equates to "unconfigured", +only those lines to be managed by gpiomux need to be specified. Here +is a completely fictional example: + +struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = { + [12] = { + .active = GPIOMUX_VALID | GPIOMUX_DRV_8MA | GPIOMUX_FUNC_1, + .suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN, + }, + [34] = { + .suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN, + }, +}; + +To indicate that a gpio is in use, call msm_gpiomux_get() to increase +its reference count. To decrease the reference count, call msm_gpiomux_put(). + +The effect of this configuration is as follows: + +When the system boots, gpios 12 and 34 will be initialized with their +'suspended' configurations. All other gpios, which were left unconfigured, +will not be touched. + +When msm_gpiomux_get() is called on gpio 12 to raise its reference count +above 0, its active configuration will be applied. Since no other gpio +line has a valid active configuration, msm_gpiomux_get() will have no +effect on any other line. + +When msm_gpiomux_put() is called on gpio 12 or 34 to drop their reference +count to 0, their suspended configurations will be applied. +Since no other gpio line has a valid suspended configuration, no other +gpio line will be effected by msm_gpiomux_put(). Since gpio 34 has no valid +active configuration, this is effectively a no-op for gpio 34 as well, +with one small caveat, see the section "About Output-Enable Settings". + +All of the GPIOMUX_VALID flags may seem like unnecessary overhead, but +they address some important issues. As unused entries (all those +except 12 and 34) are zero-filled, gpiomux needs a way to distinguish +the used fields from the unused. In addition, the all-zero pattern +is a valid configuration! Therefore, gpiomux defines an additional bit +which is used to indicate when a field is used. This has the pleasant +side-effect of allowing calls to msm_gpiomux_write to use '0' to indicate +that a value should not be changed: + + msm_gpiomux_write(0, GPIOMUX_VALID, 0); + +replaces the active configuration of gpio 0 with an all-zero configuration, +but leaves the suspended configuration as it was. + +Static Configurations +===================== + +To install a static configuration, which is applied at boot and does +not change after that, install a configuration with a suspended component +but no active component, as in the previous example: + + [34] = { + .suspended = GPIOMUX_VALID | GPIOMUX_PULL_DOWN, + }, + +The suspended setting is applied during boot, and the lack of any valid +active setting prevents any other setting from being applied at runtime. +If other subsystems attempting to access the line is a concern, one could +*really* anchor the configuration down by calling msm_gpiomux_get on the +line at initialization to move the line into active mode. With the line +held, it will never be re-suspended, and with no valid active configuration, +no new configurations will be applied. + +But then, if having other subsystems grabbing for the line is truly a concern, +it should be reserved with gpio_request instead, which carries an implicit +msm_gpiomux_get. + +gpiomux and gpiolib +=================== + +It is expected that msm gpio_chips will call msm_gpiomux_get() and +msm_gpiomux_put() from their request and free hooks, like this fictional +example: + +static int request(struct gpio_chip *chip, unsigned offset) +{ + return msm_gpiomux_get(chip->base + offset); +} + +static void free(struct gpio_chip *chip, unsigned offset) +{ + msm_gpiomux_put(chip->base + offset); +} + + ...somewhere in a gpio_chip declaration... + .request = request, + .free = free, + +This provides important functionality: +- It guarantees that a gpio line will have its 'active' config applied + when the line is requested, and will not be suspended while the line + remains requested; and +- It guarantees that gpio-direction settings from gpiolib behave sensibly. + See "About Output-Enable Settings." + +This mechanism allows for "auto-request" of gpiomux lines via gpiolib +when it is suitable. Drivers wishing more exact control are, of course, +free to also use msm_gpiomux_set and msm_gpiomux_get. + +About Output-Enable Settings +============================ + +Some msm targets do not have the ability to query the current gpio +configuration setting. This means that changes made to the output-enable +(OE) bit by gpiolib cannot be consistently detected and preserved by gpiomux. +Therefore, when gpiomux applies a configuration setting, any direction +settings which may have been applied by gpiolib are lost and the default +input settings are re-applied. + +For this reason, drivers should not assume that gpio direction settings +continue to hold if they free and then re-request a gpio. This seems like +common sense - after all, anybody could have obtained the line in the +meantime - but it needs saying. + +This also means that calls to msm_gpiomux_write will reset the OE bit, +which means that if the gpio line is held by a client of gpiolib and +msm_gpiomux_write is called, the direction setting has been lost and +gpiolib's internal state has been broken. +Release gpio lines before reconfiguring them. diff --git a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt index 2df71861e578..d9271e74e488 100644 --- a/Documentation/networking/e1000.txt +++ b/Documentation/networking/e1000.txt @@ -1,82 +1,35 @@ Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters =============================================================== -September 26, 2006 - +Intel Gigabit Linux driver. +Copyright(c) 1999 - 2010 Intel Corporation. Contents ======== -- In This Release - Identifying Your Adapter -- Building and Installation - Command Line Parameters - Speed and Duplex Configuration - Additional Configurations -- Known Issues - Support - -In This Release -=============== - -This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family -of Adapters. This driver includes support for Itanium(R)2-based systems. - -For questions related to hardware requirements, refer to the documentation -supplied with your Intel PRO/1000 adapter. All hardware requirements listed -apply to use with Linux. - -The following features are now available in supported kernels: - - Native VLANs - - Channel Bonding (teaming) - - SNMP - -Channel Bonding documentation can be found in the Linux kernel source: -/Documentation/networking/bonding.txt - -The driver information previously displayed in the /proc filesystem is not -supported in this release. Alternatively, you can use ethtool (version 1.6 -or later), lspci, and ifconfig to obtain the same information. - -Instructions on updating ethtool can be found in the section "Additional -Configurations" later in this document. - -NOTE: The Intel(R) 82562v 10/100 Network Connection only provides 10/100 -support. - - Identifying Your Adapter ======================== For more information on how to identify your adapter, go to the Adapter & Driver ID Guide at: - http://support.intel.com/support/network/adapter/pro100/21397.htm + http://support.intel.com/support/go/network/adapter/idguide.htm For the latest Intel network drivers for Linux, refer to the following website. In the search field, enter your adapter name or type, or use the networking link on the left to search for your adapter: - http://downloadfinder.intel.com/scripts-df/support_intel.asp - + http://support.intel.com/support/go/network/adapter/home.htm Command Line Parameters ======================= -If the driver is built as a module, the following optional parameters -are used by entering them on the command line with the modprobe command -using this syntax: - - modprobe e1000 [<option>=<VAL1>,<VAL2>,...] - -For example, with two PRO/1000 PCI adapters, entering: - - modprobe e1000 TxDescriptors=80,128 - -loads the e1000 driver with 80 TX descriptors for the first adapter and -128 TX descriptors for the second adapter. - The default value for each parameter is generally the recommended setting, unless otherwise noted. @@ -89,10 +42,6 @@ NOTES: For more information about the AutoNeg, Duplex, and Speed parameters, see the application note at: http://www.intel.com/design/network/applnots/ap450.htm - A descriptor describes a data buffer and attributes related to - the data buffer. This information is accessed by the hardware. - - AutoNeg ------- (Supported only on adapters with copper connections) @@ -106,7 +55,6 @@ Duplex parameters must not be specified. NOTE: Refer to the Speed and Duplex section of this readme for more information on the AutoNeg parameter. - Duplex ------ (Supported only on adapters with copper connections) @@ -119,7 +67,6 @@ set to auto-negotiate, the board auto-detects the correct duplex. If the link partner is forced (either full or half), Duplex defaults to half- duplex. - FlowControl ----------- Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx) @@ -128,16 +75,16 @@ Default Value: Reads flow control settings from the EEPROM This parameter controls the automatic generation(Tx) and response(Rx) to Ethernet PAUSE frames. - InterruptThrottleRate --------------------- (not supported on Intel(R) 82542, 82543 or 82544-based adapters) -Valid Range: 0,1,3,100-100000 (0=off, 1=dynamic, 3=dynamic conservative) +Valid Range: 0,1,3,4,100-100000 (0=off, 1=dynamic, 3=dynamic conservative, + 4=simplified balancing) Default Value: 3 The driver can limit the amount of interrupts per second that the adapter -will generate for incoming packets. It does this by writing a value to the -adapter that is based on the maximum amount of interrupts that the adapter +will generate for incoming packets. It does this by writing a value to the +adapter that is based on the maximum amount of interrupts that the adapter will generate per second. Setting InterruptThrottleRate to a value greater or equal to 100 @@ -146,37 +93,43 @@ per second, even if more packets have come in. This reduces interrupt load on the system and can lower CPU utilization under heavy load, but will increase latency as packets are not processed as quickly. -The default behaviour of the driver previously assumed a static -InterruptThrottleRate value of 8000, providing a good fallback value for -all traffic types,but lacking in small packet performance and latency. -The hardware can handle many more small packets per second however, and +The default behaviour of the driver previously assumed a static +InterruptThrottleRate value of 8000, providing a good fallback value for +all traffic types,but lacking in small packet performance and latency. +The hardware can handle many more small packets per second however, and for this reason an adaptive interrupt moderation algorithm was implemented. Since 7.3.x, the driver has two adaptive modes (setting 1 or 3) in which -it dynamically adjusts the InterruptThrottleRate value based on the traffic +it dynamically adjusts the InterruptThrottleRate value based on the traffic that it receives. After determining the type of incoming traffic in the last -timeframe, it will adjust the InterruptThrottleRate to an appropriate value +timeframe, it will adjust the InterruptThrottleRate to an appropriate value for that traffic. The algorithm classifies the incoming traffic every interval into -classes. Once the class is determined, the InterruptThrottleRate value is -adjusted to suit that traffic type the best. There are three classes defined: +classes. Once the class is determined, the InterruptThrottleRate value is +adjusted to suit that traffic type the best. There are three classes defined: "Bulk traffic", for large amounts of packets of normal size; "Low latency", for small amounts of traffic and/or a significant percentage of small -packets; and "Lowest latency", for almost completely small packets or +packets; and "Lowest latency", for almost completely small packets or minimal traffic. -In dynamic conservative mode, the InterruptThrottleRate value is set to 4000 -for traffic that falls in class "Bulk traffic". If traffic falls in the "Low -latency" or "Lowest latency" class, the InterruptThrottleRate is increased +In dynamic conservative mode, the InterruptThrottleRate value is set to 4000 +for traffic that falls in class "Bulk traffic". If traffic falls in the "Low +latency" or "Lowest latency" class, the InterruptThrottleRate is increased stepwise to 20000. This default mode is suitable for most applications. For situations where low latency is vital such as cluster or grid computing, the algorithm can reduce latency even more when InterruptThrottleRate is set to mode 1. In this mode, which operates -the same as mode 3, the InterruptThrottleRate will be increased stepwise to +the same as mode 3, the InterruptThrottleRate will be increased stepwise to 70000 for traffic in class "Lowest latency". +In simplified mode the interrupt rate is based on the ratio of Tx and +Rx traffic. If the bytes per second rate is approximately equal, the +interrupt rate will drop as low as 2000 interrupts per second. If the +traffic is mostly transmit or mostly receive, the interrupt rate could +be as high as 8000. + Setting InterruptThrottleRate to 0 turns off any interrupt moderation and may improve small packet latency, but is generally not suitable for bulk throughput traffic. @@ -212,8 +165,6 @@ NOTE: When e1000 is loaded with default settings and multiple adapters be platform-specific. If CPU utilization is not a concern, use RX_POLLING (NAPI) and default driver settings. - - RxDescriptors ------------- Valid Range: 80-256 for 82542 and 82543-based adapters @@ -225,15 +176,14 @@ by the driver. Increasing this value allows the driver to buffer more incoming packets, at the expense of increased system memory utilization. Each descriptor is 16 bytes. A receive buffer is also allocated for each -descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending +descriptor and can be either 2048, 4096, 8192, or 16384 bytes, depending on the MTU setting. The maximum MTU size is 16110. -NOTE: MTU designates the frame size. It only needs to be set for Jumbo - Frames. Depending on the available system resources, the request - for a higher number of receive descriptors may be denied. In this +NOTE: MTU designates the frame size. It only needs to be set for Jumbo + Frames. Depending on the available system resources, the request + for a higher number of receive descriptors may be denied. In this case, use a lower number. - RxIntDelay ---------- Valid Range: 0-65535 (0=off) @@ -254,7 +204,6 @@ CAUTION: When setting RxIntDelay to a value other than 0, adapters may restoring the network connection. To eliminate the potential for the hang ensure that RxIntDelay is set to 0. - RxAbsIntDelay ------------- (This parameter is supported only on 82540, 82545 and later adapters.) @@ -268,7 +217,6 @@ packet is received within the set amount of time. Proper tuning, along with RxIntDelay, may improve traffic throughput in specific network conditions. - Speed ----- (This parameter is supported only on adapters with copper connections.) @@ -280,7 +228,6 @@ Speed forces the line speed to the specified value in megabits per second partner is set to auto-negotiate, the board will auto-detect the correct speed. Duplex should also be set when Speed is set to either 10 or 100. - TxDescriptors ------------- Valid Range: 80-256 for 82542 and 82543-based adapters @@ -295,6 +242,36 @@ NOTE: Depending on the available system resources, the request for a higher number of transmit descriptors may be denied. In this case, use a lower number. +TxDescriptorStep +---------------- +Valid Range: 1 (use every Tx Descriptor) + 4 (use every 4th Tx Descriptor) + +Default Value: 1 (use every Tx Descriptor) + +On certain non-Intel architectures, it has been observed that intense TX +traffic bursts of short packets may result in an improper descriptor +writeback. If this occurs, the driver will report a "TX Timeout" and reset +the adapter, after which the transmit flow will restart, though data may +have stalled for as much as 10 seconds before it resumes. + +The improper writeback does not occur on the first descriptor in a system +memory cache-line, which is typically 32 bytes, or 4 descriptors long. + +Setting TxDescriptorStep to a value of 4 will ensure that all TX descriptors +are aligned to the start of a system memory cache line, and so this problem +will not occur. + +NOTES: Setting TxDescriptorStep to 4 effectively reduces the number of + TxDescriptors available for transmits to 1/4 of the normal allocation. + This has a possible negative performance impact, which may be + compensated for by allocating more descriptors using the TxDescriptors + module parameter. + + There are other conditions which may result in "TX Timeout", which will + not be resolved by the use of the TxDescriptorStep parameter. As the + issue addressed by this parameter has never been observed on Intel + Architecture platforms, it should not be used on Intel platforms. TxIntDelay ---------- @@ -307,7 +284,6 @@ efficiency if properly tuned for specific network traffic. If the system is reporting dropped transmits, this value may be set too high causing the driver to run out of available transmit descriptors. - TxAbsIntDelay ------------- (This parameter is supported only on 82540, 82545 and later adapters.) @@ -330,6 +306,35 @@ Default Value: 1 A value of '1' indicates that the driver should enable IP checksum offload for received packets (both UDP and TCP) to the adapter hardware. +Copybreak +--------- +Valid Range: 0-xxxxxxx (0=off) +Default Value: 256 +Usage: insmod e1000.ko copybreak=128 + +Driver copies all packets below or equaling this size to a fresh Rx +buffer before handing it up the stack. + +This parameter is different than other parameters, in that it is a +single (not 1,1,1 etc.) parameter applied to all driver instances and +it is also available during runtime at +/sys/module/e1000/parameters/copybreak + +SmartPowerDownEnable +-------------------- +Valid Range: 0-1 +Default Value: 0 (disabled) + +Allows PHY to turn off in lower power states. The user can turn off +this parameter in supported chipsets. + +KumeranLockLoss +--------------- +Valid Range: 0-1 +Default Value: 1 (enabled) + +This workaround skips resetting the PHY at shutdown for the initial +silicon releases of ICH8 systems. Speed and Duplex Configuration ============================== @@ -385,40 +390,9 @@ If the link partner is forced to a specific speed and duplex, then this parameter should not be used. Instead, use the Speed and Duplex parameters previously mentioned to force the adapter to the same speed and duplex. - Additional Configurations ========================= - Configuring the Driver on Different Distributions - ------------------------------------------------- - Configuring a network driver to load properly when the system is started - is distribution dependent. Typically, the configuration process involves - adding an alias line to /etc/modules.conf or /etc/modprobe.conf as well - as editing other system startup scripts and/or configuration files. Many - popular Linux distributions ship with tools to make these changes for you. - To learn the proper way to configure a network device for your system, - refer to your distribution documentation. If during this process you are - asked for the driver or module name, the name for the Linux Base Driver - for the Intel(R) PRO/1000 Family of Adapters is e1000. - - As an example, if you install the e1000 driver for two PRO/1000 adapters - (eth0 and eth1) and set the speed and duplex to 10full and 100half, add - the following to modules.conf or or modprobe.conf: - - alias eth0 e1000 - alias eth1 e1000 - options e1000 Speed=10,100 Duplex=2,1 - - Viewing Link Messages - --------------------- - Link messages will not be displayed to the console if the distribution is - restricting system messages. In order to see network driver link messages - on your console, set dmesg to eight by entering the following: - - dmesg -n 8 - - NOTE: This setting is not saved across reboots. - Jumbo Frames ------------ Jumbo Frames support is enabled by changing the MTU to a value larger than @@ -437,9 +411,11 @@ Additional Configurations setting in a different location. Notes: - - - To enable Jumbo Frames, increase the MTU size on the interface beyond - 1500. + Degradation in throughput performance may be observed in some Jumbo frames + environments. If this is observed, increasing the application's socket buffer + size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values may help. + See the specific application manual and /usr/src/linux*/Documentation/ + networking/ip-sysctl.txt for more details. - The maximum MTU setting for Jumbo Frames is 16110. This value coincides with the maximum Jumbo Frames size of 16128. @@ -447,40 +423,11 @@ Additional Configurations - Using Jumbo Frames at 10 or 100 Mbps may result in poor performance or loss of link. - - Some Intel gigabit adapters that support Jumbo Frames have a frame size - limit of 9238 bytes, with a corresponding MTU size limit of 9216 bytes. - The adapters with this limitation are based on the Intel(R) 82571EB, - 82572EI, 82573L and 80003ES2LAN controller. These correspond to the - following product names: - Intel(R) PRO/1000 PT Server Adapter - Intel(R) PRO/1000 PT Desktop Adapter - Intel(R) PRO/1000 PT Network Connection - Intel(R) PRO/1000 PT Dual Port Server Adapter - Intel(R) PRO/1000 PT Dual Port Network Connection - Intel(R) PRO/1000 PF Server Adapter - Intel(R) PRO/1000 PF Network Connection - Intel(R) PRO/1000 PF Dual Port Server Adapter - Intel(R) PRO/1000 PB Server Connection - Intel(R) PRO/1000 PL Network Connection - Intel(R) PRO/1000 EB Network Connection with I/O Acceleration - Intel(R) PRO/1000 EB Backplane Connection with I/O Acceleration - Intel(R) PRO/1000 PT Quad Port Server Adapter - - Adapters based on the Intel(R) 82542 and 82573V/E controller do not support Jumbo Frames. These correspond to the following product names: Intel(R) PRO/1000 Gigabit Server Adapter Intel(R) PRO/1000 PM Network Connection - - The following adapters do not support Jumbo Frames: - Intel(R) 82562V 10/100 Network Connection - Intel(R) 82566DM Gigabit Network Connection - Intel(R) 82566DC Gigabit Network Connection - Intel(R) 82566MM Gigabit Network Connection - Intel(R) 82566MC Gigabit Network Connection - Intel(R) 82562GT 10/100 Network Connection - Intel(R) 82562G 10/100 Network Connection - - Ethtool ------- The driver utilizes the ethtool interface for driver configuration and @@ -490,142 +437,14 @@ Additional Configurations The latest release of ethtool can be found from http://sourceforge.net/projects/gkernel. - NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support - for a more complete ethtool feature set can be enabled by upgrading - ethtool to ethtool-1.8.1. - Enabling Wake on LAN* (WoL) --------------------------- - WoL is configured through the Ethtool* utility. Ethtool is included with - all versions of Red Hat after Red Hat 7.2. For other Linux distributions, - download and install Ethtool from the following website: - http://sourceforge.net/projects/gkernel. - - For instructions on enabling WoL with Ethtool, refer to the website listed - above. + WoL is configured through the Ethtool* utility. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the e1000 driver must be loaded when shutting down or rebooting the system. - Wake On LAN is only supported on port A for the following devices: - Intel(R) PRO/1000 PT Dual Port Network Connection - Intel(R) PRO/1000 PT Dual Port Server Connection - Intel(R) PRO/1000 PT Dual Port Server Adapter - Intel(R) PRO/1000 PF Dual Port Server Adapter - Intel(R) PRO/1000 PT Quad Port Server Adapter - - NAPI - ---- - NAPI (Rx polling mode) is enabled in the e1000 driver. - - See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI. - - -Known Issues -============ - -Dropped Receive Packets on Half-duplex 10/100 Networks ------------------------------------------------------- -If you have an Intel PCI Express adapter running at 10mbps or 100mbps, half- -duplex, you may observe occasional dropped receive packets. There are no -workarounds for this problem in this network configuration. The network must -be updated to operate in full-duplex, and/or 1000mbps only. - -Jumbo Frames System Requirement -------------------------------- -Memory allocation failures have been observed on Linux systems with 64 MB -of RAM or less that are running Jumbo Frames. If you are using Jumbo -Frames, your system may require more than the advertised minimum -requirement of 64 MB of system memory. - -Performance Degradation with Jumbo Frames ------------------------------------------ -Degradation in throughput performance may be observed in some Jumbo frames -environments. If this is observed, increasing the application's socket -buffer size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values -may help. See the specific application manual and -/usr/src/linux*/Documentation/ -networking/ip-sysctl.txt for more details. - -Jumbo Frames on Foundry BigIron 8000 switch -------------------------------------------- -There is a known issue using Jumbo frames when connected to a Foundry -BigIron 8000 switch. This is a 3rd party limitation. If you experience -loss of packets, lower the MTU size. - -Allocating Rx Buffers when Using Jumbo Frames ---------------------------------------------- -Allocating Rx buffers when using Jumbo Frames on 2.6.x kernels may fail if -the available memory is heavily fragmented. This issue may be seen with PCI-X -adapters or with packet split disabled. This can be reduced or eliminated -by changing the amount of available memory for receive buffer allocation, by -increasing /proc/sys/vm/min_free_kbytes. - -Multiple Interfaces on Same Ethernet Broadcast Network ------------------------------------------------------- -Due to the default ARP behavior on Linux, it is not possible to have -one system on two IP networks in the same Ethernet broadcast domain -(non-partitioned switch) behave as expected. All Ethernet interfaces -will respond to IP traffic for any IP address assigned to the system. -This results in unbalanced receive traffic. - -If you have multiple interfaces in a server, either turn on ARP -filtering by entering: - - echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter -(this only works if your kernel's version is higher than 2.4.5), - -NOTE: This setting is not saved across reboots. The configuration -change can be made permanent by adding the line: - net.ipv4.conf.all.arp_filter = 1 -to the file /etc/sysctl.conf - - or, - -install the interfaces in separate broadcast domains (either in -different switches or in a switch partitioned to VLANs). - -82541/82547 can't link or are slow to link with some link partners ------------------------------------------------------------------ -There is a known compatibility issue with 82541/82547 and some -low-end switches where the link will not be established, or will -be slow to establish. In particular, these switches are known to -be incompatible with 82541/82547: - - Planex FXG-08TE - I-O Data ETG-SH8 - -To workaround this issue, the driver can be compiled with an override -of the PHY's master/slave setting. Forcing master or forcing slave -mode will improve time-to-link. - - # make CFLAGS_EXTRA=-DE1000_MASTER_SLAVE=<n> - -Where <n> is: - - 0 = Hardware default - 1 = Master mode - 2 = Slave mode - 3 = Auto master/slave - -Disable rx flow control with ethtool ------------------------------------- -In order to disable receive flow control using ethtool, you must turn -off auto-negotiation on the same command line. - -For example: - - ethtool -A eth? autoneg off rx off - -Unplugging network cable while ethtool -p is running ----------------------------------------------------- -In kernel versions 2.5.50 and later (including 2.6 kernel), unplugging -the network cable while ethtool -p is running will cause the system to -become unresponsive to keyboard commands, except for control-alt-delete. -Restarting the system appears to be the only remedy. - - Support ======= diff --git a/Documentation/networking/e1000e.txt b/Documentation/networking/e1000e.txt new file mode 100644 index 000000000000..6aa048badf32 --- /dev/null +++ b/Documentation/networking/e1000e.txt @@ -0,0 +1,302 @@ +Linux* Driver for Intel(R) Network Connection +=============================================================== + +Intel Gigabit Linux driver. +Copyright(c) 1999 - 2010 Intel Corporation. + +Contents +======== + +- Identifying Your Adapter +- Command Line Parameters +- Additional Configurations +- Support + +Identifying Your Adapter +======================== + +The e1000e driver supports all PCI Express Intel(R) Gigabit Network +Connections, except those that are 82575, 82576 and 82580-based*. + +* NOTE: The Intel(R) PRO/1000 P Dual Port Server Adapter is supported by + the e1000 driver, not the e1000e driver due to the 82546 part being used + behind a PCI Express bridge. + +For more information on how to identify your adapter, go to the Adapter & +Driver ID Guide at: + + http://support.intel.com/support/go/network/adapter/idguide.htm + +For the latest Intel network drivers for Linux, refer to the following +website. In the search field, enter your adapter name or type, or use the +networking link on the left to search for your adapter: + + http://support.intel.com/support/go/network/adapter/home.htm + +Command Line Parameters +======================= + +The default value for each parameter is generally the recommended setting, +unless otherwise noted. + +NOTES: For more information about the InterruptThrottleRate, + RxIntDelay, TxIntDelay, RxAbsIntDelay, and TxAbsIntDelay + parameters, see the application note at: + http://www.intel.com/design/network/applnots/ap450.htm + +InterruptThrottleRate +--------------------- +Valid Range: 0,1,3,4,100-100000 (0=off, 1=dynamic, 3=dynamic conservative, + 4=simplified balancing) +Default Value: 3 + +The driver can limit the amount of interrupts per second that the adapter +will generate for incoming packets. It does this by writing a value to the +adapter that is based on the maximum amount of interrupts that the adapter +will generate per second. + +Setting InterruptThrottleRate to a value greater or equal to 100 +will program the adapter to send out a maximum of that many interrupts +per second, even if more packets have come in. This reduces interrupt +load on the system and can lower CPU utilization under heavy load, +but will increase latency as packets are not processed as quickly. + +The driver has two adaptive modes (setting 1 or 3) in which +it dynamically adjusts the InterruptThrottleRate value based on the traffic +that it receives. After determining the type of incoming traffic in the last +timeframe, it will adjust the InterruptThrottleRate to an appropriate value +for that traffic. + +The algorithm classifies the incoming traffic every interval into +classes. Once the class is determined, the InterruptThrottleRate value is +adjusted to suit that traffic type the best. There are three classes defined: +"Bulk traffic", for large amounts of packets of normal size; "Low latency", +for small amounts of traffic and/or a significant percentage of small +packets; and "Lowest latency", for almost completely small packets or +minimal traffic. + +In dynamic conservative mode, the InterruptThrottleRate value is set to 4000 +for traffic that falls in class "Bulk traffic". If traffic falls in the "Low +latency" or "Lowest latency" class, the InterruptThrottleRate is increased +stepwise to 20000. This default mode is suitable for most applications. + +For situations where low latency is vital such as cluster or +grid computing, the algorithm can reduce latency even more when +InterruptThrottleRate is set to mode 1. In this mode, which operates +the same as mode 3, the InterruptThrottleRate will be increased stepwise to +70000 for traffic in class "Lowest latency". + +In simplified mode the interrupt rate is based on the ratio of Tx and +Rx traffic. If the bytes per second rate is approximately equal the +interrupt rate will drop as low as 2000 interrupts per second. If the +traffic is mostly transmit or mostly receive, the interrupt rate could +be as high as 8000. + +Setting InterruptThrottleRate to 0 turns off any interrupt moderation +and may improve small packet latency, but is generally not suitable +for bulk throughput traffic. + +NOTE: InterruptThrottleRate takes precedence over the TxAbsIntDelay and + RxAbsIntDelay parameters. In other words, minimizing the receive + and/or transmit absolute delays does not force the controller to + generate more interrupts than what the Interrupt Throttle Rate + allows. + +NOTE: When e1000e is loaded with default settings and multiple adapters + are in use simultaneously, the CPU utilization may increase non- + linearly. In order to limit the CPU utilization without impacting + the overall throughput, we recommend that you load the driver as + follows: + + modprobe e1000e InterruptThrottleRate=3000,3000,3000 + + This sets the InterruptThrottleRate to 3000 interrupts/sec for + the first, second, and third instances of the driver. The range + of 2000 to 3000 interrupts per second works on a majority of + systems and is a good starting point, but the optimal value will + be platform-specific. If CPU utilization is not a concern, use + RX_POLLING (NAPI) and default driver settings. + +RxIntDelay +---------- +Valid Range: 0-65535 (0=off) +Default Value: 0 + +This value delays the generation of receive interrupts in units of 1.024 +microseconds. Receive interrupt reduction can improve CPU efficiency if +properly tuned for specific network traffic. Increasing this value adds +extra latency to frame reception and can end up decreasing the throughput +of TCP traffic. If the system is reporting dropped receives, this value +may be set too high, causing the driver to run out of available receive +descriptors. + +CAUTION: When setting RxIntDelay to a value other than 0, adapters may + hang (stop transmitting) under certain network conditions. If + this occurs a NETDEV WATCHDOG message is logged in the system + event log. In addition, the controller is automatically reset, + restoring the network connection. To eliminate the potential + for the hang ensure that RxIntDelay is set to 0. + +RxAbsIntDelay +------------- +Valid Range: 0-65535 (0=off) +Default Value: 8 + +This value, in units of 1.024 microseconds, limits the delay in which a +receive interrupt is generated. Useful only if RxIntDelay is non-zero, +this value ensures that an interrupt is generated after the initial +packet is received within the set amount of time. Proper tuning, +along with RxIntDelay, may improve traffic throughput in specific network +conditions. + +TxIntDelay +---------- +Valid Range: 0-65535 (0=off) +Default Value: 8 + +This value delays the generation of transmit interrupts in units of +1.024 microseconds. Transmit interrupt reduction can improve CPU +efficiency if properly tuned for specific network traffic. If the +system is reporting dropped transmits, this value may be set too high +causing the driver to run out of available transmit descriptors. + +TxAbsIntDelay +------------- +Valid Range: 0-65535 (0=off) +Default Value: 32 + +This value, in units of 1.024 microseconds, limits the delay in which a +transmit interrupt is generated. Useful only if TxIntDelay is non-zero, +this value ensures that an interrupt is generated after the initial +packet is sent on the wire within the set amount of time. Proper tuning, +along with TxIntDelay, may improve traffic throughput in specific +network conditions. + +Copybreak +--------- +Valid Range: 0-xxxxxxx (0=off) +Default Value: 256 + +Driver copies all packets below or equaling this size to a fresh Rx +buffer before handing it up the stack. + +This parameter is different than other parameters, in that it is a +single (not 1,1,1 etc.) parameter applied to all driver instances and +it is also available during runtime at +/sys/module/e1000e/parameters/copybreak + +SmartPowerDownEnable +-------------------- +Valid Range: 0-1 +Default Value: 0 (disabled) + +Allows PHY to turn off in lower power states. The user can set this parameter +in supported chipsets. + +KumeranLockLoss +--------------- +Valid Range: 0-1 +Default Value: 1 (enabled) + +This workaround skips resetting the PHY at shutdown for the initial +silicon releases of ICH8 systems. + +IntMode +------- +Valid Range: 0-2 (0=legacy, 1=MSI, 2=MSI-X) +Default Value: 2 + +Allows changing the interrupt mode at module load time, without requiring a +recompile. If the driver load fails to enable a specific interrupt mode, the +driver will try other interrupt modes, from least to most compatible. The +interrupt order is MSI-X, MSI, Legacy. If specifying MSI (IntMode=1) +interrupts, only MSI and Legacy will be attempted. + +CrcStripping +------------ +Valid Range: 0-1 +Default Value: 1 (enabled) + +Strip the CRC from received packets before sending up the network stack. If +you have a machine with a BMC enabled but cannot receive IPMI traffic after +loading or enabling the driver, try disabling this feature. + +WriteProtectNVM +--------------- +Valid Range: 0-1 +Default Value: 1 (enabled) + +Set the hardware to ignore all write/erase cycles to the GbE region in the +ICHx NVM (non-volatile memory). This feature can be disabled by the +WriteProtectNVM module parameter (enabled by default) only after a hardware +reset, but the machine must be power cycled before trying to enable writes. + +Note: the kernel boot option iomem=relaxed may need to be set if the kernel +config option CONFIG_STRICT_DEVMEM=y, if the root user wants to write the +NVM from user space via ethtool. + +Additional Configurations +========================= + + Jumbo Frames + ------------ + Jumbo Frames support is enabled by changing the MTU to a value larger than + the default of 1500. Use the ifconfig command to increase the MTU size. + For example: + + ifconfig eth<x> mtu 9000 up + + This setting is not saved across reboots. + + Notes: + + - The maximum MTU setting for Jumbo Frames is 9216. This value coincides + with the maximum Jumbo Frames size of 9234 bytes. + + - Using Jumbo Frames at 10 or 100 Mbps is not supported and may result in + poor performance or loss of link. + + - Some adapters limit Jumbo Frames sized packets to a maximum of + 4096 bytes and some adapters do not support Jumbo Frames. + + + Ethtool + ------- + The driver utilizes the ethtool interface for driver configuration and + diagnostics, as well as displaying statistical information. We + strongly recommend downloading the latest version of Ethtool at: + + http://sourceforge.net/projects/gkernel. + + Speed and Duplex + ---------------- + Speed and Duplex are configured through the Ethtool* utility. For + instructions, refer to the Ethtool man page. + + Enabling Wake on LAN* (WoL) + --------------------------- + WoL is configured through the Ethtool* utility. For instructions on + enabling WoL with Ethtool, refer to the Ethtool man page. + + WoL will be enabled on the system during the next shut down or reboot. + For this driver version, in order to enable WoL, the e1000e driver must be + loaded when shutting down or rebooting the system. + + In most cases Wake On LAN is only supported on port A for multiple port + adapters. To verify if a port supports Wake on LAN run ethtool eth<X>. + + +Support +======= + +For general information, go to the Intel support website at: + + www.intel.com/support/ + +or the Intel Wired Networking project hosted by Sourceforge at: + + http://sourceforge.net/projects/e1000 + +If an issue is identified with the released source code on the supported +kernel with a supported adapter, email the specific information related +to the issue to e1000-devel@lists.sf.net diff --git a/Documentation/networking/ixgbevf.txt b/Documentation/networking/ixgbevf.txt index 19015de6725f..21dd5d15b6b4 100755..100644 --- a/Documentation/networking/ixgbevf.txt +++ b/Documentation/networking/ixgbevf.txt @@ -1,19 +1,16 @@ Linux* Base Driver for Intel(R) Network Connection ================================================== -November 24, 2009 +Intel Gigabit Linux driver. +Copyright(c) 1999 - 2010 Intel Corporation. Contents ======== -- In This Release - Identifying Your Adapter - Known Issues/Troubleshooting - Support -In This Release -=============== - This file describes the ixgbevf Linux* Base Driver for Intel Network Connection. @@ -33,7 +30,7 @@ Identifying Your Adapter For more information on how to identify your adapter, go to the Adapter & Driver ID Guide at: - http://support.intel.com/support/network/sb/CS-008441.htm + http://support.intel.com/support/go/network/adapter/idguide.htm Known Issues/Troubleshooting ============================ @@ -57,34 +54,3 @@ or the Intel Wired Networking project hosted by Sourceforge at: If an issue is identified with the released source code on the supported kernel with a supported adapter, email the specific information related to the issue to e1000-devel@lists.sf.net - -License -======= - -Intel 10 Gigabit Linux driver. -Copyright(c) 1999 - 2009 Intel Corporation. - -This program is free software; you can redistribute it and/or modify it -under the terms and conditions of the GNU General Public License, -version 2, as published by the Free Software Foundation. - -This program is distributed in the hope it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - -The full GNU General Public License is included in this distribution in -the file called "COPYING". - -Trademarks -========== - -Intel, Itanium, and Pentium are trademarks or registered trademarks of -Intel Corporation or its subsidiaries in the United States and other -countries. - -* Other names and brands may be claimed as the property of others. diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c index ccd951fa94ee..cc96ee2666f2 100644 --- a/Documentation/vm/page-types.c +++ b/Documentation/vm/page-types.c @@ -478,7 +478,7 @@ static void prepare_hwpoison_fd(void) } if (opt_unpoison && !hwpoison_forget_fd) { - sprintf(buf, "%s/renew-pfn", hwpoison_debug_fs); + sprintf(buf, "%s/unpoison-pfn", hwpoison_debug_fs); hwpoison_forget_fd = checked_open(buf, O_WRONLY); } } diff --git a/MAINTAINERS b/MAINTAINERS index 668682d1f5fa..8395f2eeb782 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -962,6 +962,23 @@ W: http://www.fluff.org/ben/linux/ S: Maintained F: arch/arm/mach-s3c6410/ +ARM/S5P ARM ARCHITECTURES +M: Kukjin Kim <kgene.kim@samsung.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-s5p*/ + +ARM/SAMSUNG S5P SERIES FIMC SUPPORT +M: Kyungmin Park <kyungmin.park@samsung.com> +M: Sylwester Nawrocki <s.nawrocki@samsung.com> +L: linux-arm-kernel@lists.infradead.org +L: linux-media@vger.kernel.org +S: Maintained +F: arch/arm/plat-s5p/dev-fimc* +F: arch/arm/plat-samsung/include/plat/*fimc* +F: drivers/media/video/s5p-fimc/ + ARM/SHMOBILE ARM ARCHITECTURE M: Paul Mundt <lethal@linux-sh.org> M: Magnus Damm <magnus.damm@gmail.com> @@ -973,11 +990,23 @@ S: Supported F: arch/arm/mach-shmobile/ F: drivers/sh/ +ARM/TELECHIPS ARM ARCHITECTURE +M: "Hans J. Koch" <hjk@linutronix.de> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/plat-tcc/ +F: arch/arm/mach-tcc8k/ + ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT M: Lennert Buytenhek <kernel@wantstofly.org> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +ARM/TETON BGA MACHINE SUPPORT +M: Mark F. Brown <mark.brown314@gmail.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained + ARM/THECUS N2100 MACHINE SUPPORT M: Lennert Buytenhek <kernel@wantstofly.org> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -2528,7 +2557,7 @@ S: Supported F: drivers/scsi/gdt* GENERIC GPIO I2C DRIVER -M: Haavard Skinnemoen <hskinnemoen@atmel.com> +M: Haavard Skinnemoen <hskinnemoen@gmail.com> S: Supported F: drivers/i2c/busses/i2c-gpio.c F: include/linux/i2c-gpio.h @@ -3056,16 +3085,27 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/ixp2000/ -INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe) +INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf) M: Jeff Kirsher <jeffrey.t.kirsher@intel.com> M: Jesse Brandeburg <jesse.brandeburg@intel.com> M: Bruce Allan <bruce.w.allan@intel.com> -M: Alex Duyck <alexander.h.duyck@intel.com> +M: Carolyn Wyborny <carolyn.wyborny@intel.com> +M: Don Skidmore <donald.c.skidmore@intel.com> +M: Greg Rose <gregory.v.rose@intel.com> M: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com> +M: Alex Duyck <alexander.h.duyck@intel.com> M: John Ronciak <john.ronciak@intel.com> L: e1000-devel@lists.sourceforge.net W: http://e1000.sourceforge.net/ S: Supported +F: Documentation/networking/e100.txt +F: Documentation/networking/e1000.txt +F: Documentation/networking/e1000e.txt +F: Documentation/networking/igb.txt +F: Documentation/networking/igbvf.txt +F: Documentation/networking/ixgb.txt +F: Documentation/networking/ixgbe.txt +F: Documentation/networking/ixgbevf.txt F: drivers/net/e100.c F: drivers/net/e1000/ F: drivers/net/e1000e/ @@ -3073,6 +3113,7 @@ F: drivers/net/igb/ F: drivers/net/igbvf/ F: drivers/net/ixgb/ F: drivers/net/ixgbe/ +F: drivers/net/ixgbevf/ INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT L: linux-wireless@vger.kernel.org @@ -3781,9 +3822,8 @@ W: http://www.syskonnect.com S: Supported MATROX FRAMEBUFFER DRIVER -M: Petr Vandrovec <vandrove@vc.cvut.cz> L: linux-fbdev@vger.kernel.org -S: Maintained +S: Orphan F: drivers/video/matrox/matroxfb_* F: include/linux/matroxfb.h @@ -3970,8 +4010,8 @@ S: Maintained F: drivers/net/natsemi.c NCP FILESYSTEM -M: Petr Vandrovec <vandrove@vc.cvut.cz> -S: Maintained +M: Petr Vandrovec <petr@vandrovec.name> +S: Odd Fixes F: fs/ncpfs/ NCR DUAL 700 SCSI DRIVER (MICROCHANNEL) @@ -5002,6 +5042,12 @@ F: drivers/media/common/saa7146* F: drivers/media/video/*7146* F: include/media/*7146* +SAMSUNG AUDIO (ASoC) DRIVERS +M: Jassi Brar <jassi.brar@samsung.com> +L: alsa-devel@alsa-project.org (moderated for non-subscribers) +S: Supported +F: sound/soc/s3c24xx + TLG2300 VIDEO4LINUX-2 DRIVER M: Huang Shijie <shijie8@gmail.com> M: Kang Yong <kangyong@telegent.com> @@ -6444,8 +6490,10 @@ F: include/linux/wm97xx.h WOLFSON MICROELECTRONICS DRIVERS M: Mark Brown <broonie@opensource.wolfsonmicro.com> M: Ian Lartey <ian@opensource.wolfsonmicro.com> +M: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> +T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus -W: http://opensource.wolfsonmicro.com/node/8 +W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices S: Supported F: Documentation/hwmon/wm83?? F: drivers/leds/leds-wm83*.c @@ -1,8 +1,8 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 36 -EXTRAVERSION = -rc6 -NAME = Sheep on Meth +EXTRAVERSION = -rc8 +NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index d290845aef59..6f7feb5db271 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -48,7 +48,7 @@ SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask) sigset_t mask; unsigned long res; - siginitset(&mask, newmask & ~_BLOCKABLE); + siginitset(&mask, newmask & _BLOCKABLE); res = sigprocmask(how, &mask, &oldmask); if (!res) { force_successful_syscall_return(); diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b404e5eec0c1..19792a9192b7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -516,6 +516,7 @@ config ARCH_MMP select GENERIC_CLOCKEVENTS select TICK_ONESHOT select PLAT_PXA + select SPARSE_IRQ help Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line. @@ -593,6 +594,7 @@ config ARCH_PXA select GENERIC_CLOCKEVENTS select TICK_ONESHOT select PLAT_PXA + select SPARSE_IRQ help Support for Intel/Marvell's PXA2xx/PXA3xx processor line. @@ -684,8 +686,8 @@ config ARCH_S3C64XX help Samsung S3C64XX series based systems -config ARCH_S5P6440 - bool "Samsung S5P6440" +config ARCH_S5P64X0 + bool "Samsung S5P6440 S5P6450" select CPU_V6 select GENERIC_GPIO select HAVE_CLK @@ -694,7 +696,8 @@ config ARCH_S5P6440 select HAVE_S3C2410_I2C select HAVE_S3C_RTC help - Samsung S5P6440 CPU based systems + Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, + SMDK6450. config ARCH_S5P6442 bool "Samsung S5P6442" @@ -753,6 +756,15 @@ config ARCH_SHARK Support for the StrongARM based Digital DNARD machine, also known as "Shark" (<http://www.shark-linux.de/shark.html>). +config ARCH_TCC_926 + bool "Telechips TCC ARM926-based systems" + select CPU_ARM926T + select HAVE_CLK + select COMMON_CLKDEV + select GENERIC_CLOCKEVENTS + help + Support for Telechips TCC ARM926-based systems. + config ARCH_LH7A40X bool "Sharp LH7A40X" select CPU_ARM922T @@ -921,6 +933,8 @@ source "arch/arm/plat-s5p/Kconfig" source "arch/arm/plat-spear/Kconfig" +source "arch/arm/plat-tcc/Kconfig" + if ARCH_S3C2410 source "arch/arm/mach-s3c2400/Kconfig" source "arch/arm/mach-s3c2410/Kconfig" @@ -934,7 +948,7 @@ if ARCH_S3C64XX source "arch/arm/mach-s3c64xx/Kconfig" endif -source "arch/arm/mach-s5p6440/Kconfig" +source "arch/arm/mach-s5p64x0/Kconfig" source "arch/arm/mach-s5p6442/Kconfig" @@ -1107,6 +1121,20 @@ config ARM_ERRATA_720789 invalidated are not, resulting in an incoherency in the system page tables. The workaround changes the TLB flushing routines to invalidate entries regardless of the ASID. + +config ARM_ERRATA_743622 + bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption" + depends on CPU_V7 + help + This option enables the workaround for the 743622 Cortex-A9 + (r2p0..r2p2) erratum. Under very rare conditions, a faulty + optimisation in the Cortex-A9 Store Buffer may lead to data + corruption. This workaround sets a specific bit in the diagnostic + register of the Cortex-A9 which disables the Store Buffer + optimisation, preventing the defect from occurring. This has no + visible impact on the overall performance or power consumption of the + processor. + endmenu source "arch/arm/common/Kconfig" @@ -1273,7 +1301,7 @@ source kernel/Kconfig.preempt config HZ int - default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || \ + default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \ ARCH_S5P6442 || ARCH_S5PV210 || ARCH_S5PV310 default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER default AT91_TIMER_HZ if ARCH_AT91 @@ -1479,6 +1507,20 @@ config UACCESS_WITH_MEMCPY However, if the CPU data cache is using a write-allocate mode, this option is unlikely to provide any performance gain. +config SECCOMP + bool + prompt "Enable seccomp to safely compute untrusted bytecode" + ---help--- + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via prctl(PR_SET_SECCOMP), it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" help diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 4dbce538fec4..2fd0b99afc4b 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -2,6 +2,20 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +config STRICT_DEVMEM + bool "Filter access to /dev/mem" + depends on MMU + ---help--- + If this option is disabled, you allow userspace (root) access to all + of memory, including kernel and userspace memory. Accidental + access to this is obviously disastrous, but specific access can + be used by people debugging the kernel. + + If this option is switched on, the /dev/mem file only allows + userspace access to memory mapped peripherals. + + If in doubt, say Y. + # RMK wants arm kernels compiled with frame pointers or stack unwinding. # If you know what you are doing and are willing to live without stack # traces, you can get a slightly smaller kernel by setting this option to diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 59c1ce858fc8..b87aed028eef 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -173,7 +173,7 @@ machine-$(CONFIG_ARCH_RPC) := rpc machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443 machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx -machine-$(CONFIG_ARCH_S5P6440) := s5p6440 +machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0 machine-$(CONFIG_ARCH_S5P6442) := s5p6442 machine-$(CONFIG_ARCH_S5PC100) := s5pc100 machine-$(CONFIG_ARCH_S5PV210) := s5pv210 @@ -183,6 +183,7 @@ machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_SHMOBILE) := shmobile machine-$(CONFIG_ARCH_STMP378X) := stmp378x machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx +machine-$(CONFIG_ARCH_TCC8K) := tcc8k machine-$(CONFIG_ARCH_TEGRA) := tegra machine-$(CONFIG_ARCH_U300) := u300 machine-$(CONFIG_ARCH_U8500) := ux500 @@ -202,6 +203,7 @@ plat-$(CONFIG_ARCH_MXC) := mxc plat-$(CONFIG_ARCH_OMAP) := omap plat-$(CONFIG_ARCH_S3C64XX) := samsung plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx +plat-$(CONFIG_ARCH_TCC_926) := tcc plat-$(CONFIG_PLAT_IOP) := iop plat-$(CONFIG_PLAT_NOMADIK) := nomadik plat-$(CONFIG_PLAT_ORION) := orion @@ -245,13 +247,14 @@ ifeq ($(FASTFPE),$(wildcard $(FASTFPE))) FASTFPE_OBJ :=$(FASTFPE)/ endif -# If we have a machine-specific directory, then include it in the build. -core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ -core-y += $(machdirs) $(platdirs) core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) core-$(CONFIG_VFP) += arch/arm/vfp/ +# If we have a machine-specific directory, then include it in the build. +core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ +core-y += $(machdirs) $(platdirs) + drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ libs-y := arch/arm/lib/ $(libs-y) diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 7dfa9a85bc0c..ada6359160eb 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -67,25 +67,11 @@ static inline unsigned int gic_irq(unsigned int irq) /* * Routines to acknowledge, disable and enable interrupts - * - * Linux assumes that when we're done with an interrupt we need to - * unmask it, in the same way we need to unmask an interrupt when - * we first enable it. - * - * The GIC has a separate notion of "end of interrupt" to re-enable - * an interrupt after handling, in order to support hardware - * prioritisation. - * - * We can make the GIC behave in the way that Linux expects by making - * our "acknowledge" routine disable the interrupt, then mark it as - * complete. */ static void gic_ack_irq(unsigned int irq) { - u32 mask = 1 << (irq % 32); spin_lock(&irq_controller_lock); - writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4); writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI); spin_unlock(&irq_controller_lock); } diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig index f1bac70d6ce9..9e90e6d79297 100644 --- a/arch/arm/configs/at91sam9g20ek_defconfig +++ b/arch/arm/configs/at91sam9g20ek_defconfig @@ -13,6 +13,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_ARCH_AT91=y CONFIG_ARCH_AT91SAM9G20=y CONFIG_MACH_AT91SAM9G20EK=y +CONFIG_MACH_AT91SAM9G20EK_2MMC=y CONFIG_AT91_PROGRAMMABLE_CLOCKS=y # CONFIG_ARM_THUMB is not set CONFIG_AEABI=y diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig index ccc9c9959b82..2f7042813765 100644 --- a/arch/arm/configs/kirkwood_defconfig +++ b/arch/arm/configs/kirkwood_defconfig @@ -15,6 +15,7 @@ CONFIG_MACH_MV88F6281GTW_GE=y CONFIG_MACH_SHEEVAPLUG=y CONFIG_MACH_ESATA_SHEEVAPLUG=y CONFIG_MACH_GURUPLUG=y +CONFIG_MACH_DOCKSTAR=y CONFIG_MACH_TS219=y CONFIG_MACH_TS41X=y CONFIG_MACH_OPENRD_BASE=y diff --git a/arch/arm/configs/mx27_defconfig b/arch/arm/configs/mx27_defconfig index b2038b0e266f..813cfb366c18 100644 --- a/arch/arm/configs/mx27_defconfig +++ b/arch/arm/configs/mx27_defconfig @@ -21,8 +21,14 @@ CONFIG_ARCH_MX2=y CONFIG_MACH_MX27=y CONFIG_MACH_MX27ADS=y CONFIG_MACH_PCM038=y +CONFIG_MACH_CPUIMX27=y +CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2=y +CONFIG_MACH_EUKREA_CPUIMX27_USEUART4=y CONFIG_MACH_MX27_3DS=y +CONFIG_MACH_IMX27_VISSTRIM_M10=y CONFIG_MACH_IMX27LITE=y +CONFIG_MACH_PCA100=y +CONFIG_MACH_MXT_TD60=y CONFIG_MXC_IRQ_PRIOR=y CONFIG_MXC_PWM=y CONFIG_NO_HZ=y @@ -76,7 +82,9 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ADS7846=m # CONFIG_SERIO is not set +CONFIG_SERIAL_8250=m CONFIG_SERIAL_IMX=y CONFIG_SERIAL_IMX_CONSOLE=y # CONFIG_LEGACY_PTYS is not set @@ -85,19 +93,20 @@ CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_IMX=y CONFIG_SPI=y -CONFIG_SPI_BITBANG=y +CONFIG_SPI_IMX=y CONFIG_W1=y CONFIG_W1_MASTER_MXC=y CONFIG_W1_SLAVE_THERM=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_IMX=y -# CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FONTS=y CONFIG_FONT_8x8=y # CONFIG_HID_SUPPORT is not set -# CONFIG_USB_SUPPORT is not set +CONFIG_USB=m +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_ULPI=y CONFIG_MMC=y CONFIG_MMC_MXC=y CONFIG_RTC_CLASS=y diff --git a/arch/arm/configs/mx31pdk_defconfig b/arch/arm/configs/mx31pdk_defconfig deleted file mode 100644 index 2d29329749e4..000000000000 --- a/arch/arm/configs/mx31pdk_defconfig +++ /dev/null @@ -1,44 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_COMPAT_BRK is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_MXC=y -# CONFIG_MACH_MX31ADS is not set -CONFIG_MACH_MX31_3DS=y -CONFIG_AEABI=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FIRMWARE_IN_KERNEL is not set -# CONFIG_BLK_DEV is not set -# CONFIG_MISC_DEVICES is not set -CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_IMX=y -CONFIG_SERIAL_IMX_CONSOLE=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_HWMON is not set -# CONFIG_VGA_CONSOLE is not set -# CONFIG_HID_SUPPORT is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_DNOTIFY is not set -# CONFIG_ENABLE_WARN_DEPRECATED is not set -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRC32 is not set diff --git a/arch/arm/configs/mx3_defconfig b/arch/arm/configs/mx3_defconfig index 161f907b611f..f0c339fd5d21 100644 --- a/arch/arm/configs/mx3_defconfig +++ b/arch/arm/configs/mx3_defconfig @@ -24,6 +24,7 @@ CONFIG_MACH_PCM043=y CONFIG_MACH_ARMADILLO5X0=y CONFIG_MACH_MX35_3DS=y CONFIG_MACH_KZM_ARM11_01=y +CONFIG_MACH_EUKREA_CPUIMX35=y CONFIG_MXC_IRQ_PRIOR=y CONFIG_MXC_PWM=y CONFIG_NO_HZ=y @@ -108,7 +109,6 @@ CONFIG_MMC=y CONFIG_MMC_MXC=y CONFIG_DMADEVICES=y # CONFIG_DNOTIFY is not set -CONFIG_INOTIFY=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_UBIFS_FS=y diff --git a/arch/arm/configs/mx51_defconfig b/arch/arm/configs/mx51_defconfig index a665ecbbe2bc..163cfee7644c 100644 --- a/arch/arm/configs/mx51_defconfig +++ b/arch/arm/configs/mx51_defconfig @@ -15,6 +15,8 @@ CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_ARCH_MXC=y CONFIG_ARCH_MX5=y CONFIG_MACH_MX51_BABBAGE=y +CONFIG_MACH_MX51_3DS=y +CONFIG_MACH_EUKREA_CPUIMX51=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT_VOLUNTARY=y @@ -69,7 +71,6 @@ CONFIG_REALTEK_PHY=y CONFIG_NATIONAL_PHY=y CONFIG_STE10XP=y CONFIG_LSI_ET1011C_PHY=y -CONFIG_FIXED_PHY=y CONFIG_MDIO_BITBANG=y CONFIG_MDIO_GPIO=y CONFIG_NET_ETHERNET=y @@ -100,7 +101,6 @@ CONFIG_I2C_ALGOPCF=m CONFIG_I2C_ALGOPCA=m CONFIG_GPIO_SYSFS=y # CONFIG_HWMON is not set -# CONFIG_VGA_CONSOLE is not set # CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_EHCI_HCD=y @@ -117,13 +117,11 @@ CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y -CONFIG_EXT3_DEFAULTS_TO_ORDERED=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_INOTIFY=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -136,6 +134,7 @@ CONFIG_ZISOFS=y CONFIG_UDF_FS=m CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=y +CONFIG_TMPFS=y CONFIG_CONFIGFS_FS=m CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -151,7 +150,6 @@ CONFIG_NLS_UTF8=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y -# CONFIG_DETECT_SOFTLOCKUP is not set # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_RCU_CPU_STALL_DETECTOR is not set @@ -159,7 +157,6 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_ARM_UNWIND is not set CONFIG_DEBUG_LL=y CONFIG_EARLY_PRINTK=y -CONFIG_KEYS=y CONFIG_SECURITYFS=y CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_LZO=y diff --git a/arch/arm/configs/s5p6440_defconfig b/arch/arm/configs/s5p64x0_defconfig index 0b0266c6d326..2993ecd35145 100644 --- a/arch/arm/configs/s5p6440_defconfig +++ b/arch/arm/configs/s5p64x0_defconfig @@ -5,10 +5,11 @@ CONFIG_KALLSYMS_ALL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set -CONFIG_ARCH_S5P6440=y +CONFIG_ARCH_S5P64X0=y CONFIG_S3C_BOOT_ERROR_RESET=y CONFIG_S3C_LOWLEVEL_UART_PORT=1 CONFIG_MACH_SMDK6440=y +CONFIG_MACH_SMDK6450=y CONFIG_CPU_32v6K=y CONFIG_AEABI=y CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc" diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 5747a8baa413..8bb66bca2e3e 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -127,4 +127,8 @@ struct mm_struct; extern unsigned long arch_randomize_brk(struct mm_struct *mm); #define arch_randomize_brk arch_randomize_brk +extern int vectors_user_mapping(void); +#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping() +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES + #endif diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 1261b1f928d9..815efa2d4e07 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -294,6 +294,7 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); #define ARCH_HAS_VALID_PHYS_ADDR_RANGE extern int valid_phys_addr_range(unsigned long addr, size_t size); extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); +extern int devmem_is_allowed(unsigned long pfn); #endif /* diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index a0b3cac0547c..71605d9f8e42 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h @@ -18,7 +18,6 @@ #include <asm/cacheflush.h> #include <asm/cachetype.h> #include <asm/proc-fns.h> -#include <asm-generic/mm_hooks.h> void __check_kvm_seq(struct mm_struct *mm); @@ -134,4 +133,32 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, #define deactivate_mm(tsk,mm) do { } while (0) #define activate_mm(prev,next) switch_mm(prev, next, NULL) +/* + * We are inserting a "fake" vma for the user-accessible vector page so + * gdb and friends can get to it through ptrace and /proc/<pid>/mem. + * But we also want to remove it before the generic code gets to see it + * during process exit or the unmapping of it would cause total havoc. + * (the macro is used as remove_vma() is static to mm/mmap.c) + */ +#define arch_exit_mmap(mm) \ +do { \ + struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \ + if (high_vma) { \ + BUG_ON(high_vma->vm_next); /* it should be last */ \ + if (high_vma->vm_prev) \ + high_vma->vm_prev->vm_next = NULL; \ + else \ + mm->mmap = NULL; \ + rb_erase(&high_vma->vm_rb, &mm->mm_rb); \ + mm->mmap_cache = NULL; \ + mm->map_count--; \ + remove_vma(high_vma); \ + } \ +} while (0) + +static inline void arch_dup_mmap(struct mm_struct *oldmm, + struct mm_struct *mm) +{ +} + #endif diff --git a/arch/arm/include/asm/seccomp.h b/arch/arm/include/asm/seccomp.h new file mode 100644 index 000000000000..52b156b341f5 --- /dev/null +++ b/arch/arm/include/asm/seccomp.h @@ -0,0 +1,11 @@ +#ifndef _ASM_ARM_SECCOMP_H +#define _ASM_ARM_SECCOMP_H + +#include <linux/unistd.h> + +#define __NR_seccomp_read __NR_read +#define __NR_seccomp_write __NR_write +#define __NR_seccomp_exit __NR_exit +#define __NR_seccomp_sigreturn __NR_rt_sigreturn + +#endif /* _ASM_ARM_SECCOMP_H */ diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 763e29fa8530..7b5cc8dae06e 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -144,6 +144,7 @@ extern void vfp_flush_hwstate(struct thread_info *); #define TIF_MEMDIE 18 /* is terminating due to OOM killer */ #define TIF_FREEZE 19 #define TIF_RESTORE_SIGMASK 20 +#define TIF_SECCOMP 21 #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -153,6 +154,7 @@ extern void vfp_flush_hwstate(struct thread_info *); #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) #define _TIF_FREEZE (1 << TIF_FREEZE) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) +#define _TIF_SECCOMP (1 << TIF_SECCOMP) /* * Change these and you break ASM code in entry-common.S diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 2d23ad985180..8bfa98757cd2 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -334,7 +334,6 @@ ENTRY(vector_swi) get_thread_info tsk adr tbl, sys_call_table @ load syscall table pointer - ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing #if defined(CONFIG_OABI_COMPAT) /* @@ -351,8 +350,20 @@ ENTRY(vector_swi) eor scno, scno, #__NR_SYSCALL_BASE @ check OS number #endif + ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing stmdb sp!, {r4, r5} @ push fifth and sixth args - tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? + +#ifdef CONFIG_SECCOMP + tst r10, #_TIF_SECCOMP + beq 1f + mov r0, scno + bl __secure_computing + add r0, sp, #S_R0 + S_OFF @ pointer to regs + ldmia r0, {r0 - r3} @ have to reload r0 - r3 +1: +#endif + + tst r10, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? bne __sys_trace cmp scno, #NR_syscalls @ check upper syscall limit diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c index 8bccbfa693ff..2c1f0050c9c4 100644 --- a/arch/arm/kernel/kprobes-decode.c +++ b/arch/arm/kernel/kprobes-decode.c @@ -1162,11 +1162,12 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) { /* * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx - * Undef : cccc 0011 0x00 xxxx xxxx xxxx xxxx xxxx + * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx * ALU op with S bit and Rd == 15 : * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx */ - if ((insn & 0x0f900000) == 0x03200000 || /* MSR & Undef */ + if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */ + (insn & 0x0ff00000) == 0x03400000 || /* Undef */ (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ return INSN_REJECTED; @@ -1177,7 +1178,7 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) * *S (bit 20) updates condition codes * ADC/SBC/RSC reads the C flag */ - insn &= 0xfff00fff; /* Rn = r0, Rd = r0 */ + insn &= 0xffff0fff; /* Rd = r0 */ asi->insn[0] = insn; asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ emulate_alu_imm_rwflags : emulate_alu_imm_rflags; diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 3af34bf4f4df..e76fcaadce03 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -482,3 +482,24 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) unsigned long range_end = mm->brk + 0x02000000; return randomize_range(mm->brk, range_end, 0) ? : mm->brk; } + +/* + * The vectors page is always readable from user space for the + * atomic helpers and the signal restart code. Let's declare a mapping + * for it so it is visible through ptrace and /proc/<pid>/mem. + */ + +int vectors_user_mapping(void) +{ + struct mm_struct *mm = current->mm; + return install_special_mapping(mm, 0xffff0000, PAGE_SIZE, + VM_READ | VM_EXEC | + VM_MAYREAD | VM_MAYEXEC | + VM_ALWAYSDUMP | VM_RESERVED, + NULL); +} + +const char *arch_vma_name(struct vm_area_struct *vma) +{ + return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL; +} diff --git a/arch/arm/mach-aaec2000/include/mach/vmalloc.h b/arch/arm/mach-aaec2000/include/mach/vmalloc.h index 551f68f666bf..cff4e0a996ce 100644 --- a/arch/arm/mach-aaec2000/include/mach/vmalloc.h +++ b/arch/arm/mach-aaec2000/include/mach/vmalloc.h @@ -11,6 +11,6 @@ #ifndef __ASM_ARCH_VMALLOC_H #define __ASM_ARCH_VMALLOC_H -#define VMALLOC_END (PAGE_OFFSET + 0x10000000) +#define VMALLOC_END 0xd0000000 #endif /* __ASM_ARCH_VMALLOC_H */ diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index ca33862b4bf4..851e8139ef9d 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -33,6 +33,7 @@ config ARCH_AT91SAM9260 select HAVE_AT91_USART3 select HAVE_AT91_USART4 select HAVE_AT91_USART5 + select HAVE_NET_MACB config ARCH_AT91SAM9261 bool "AT91SAM9261" @@ -51,6 +52,7 @@ config ARCH_AT91SAM9263 select CPU_ARM926T select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL + select HAVE_NET_MACB config ARCH_AT91SAM9RL bool "AT91SAM9RL" @@ -66,6 +68,7 @@ config ARCH_AT91SAM9G20 select HAVE_AT91_USART3 select HAVE_AT91_USART4 select HAVE_AT91_USART5 + select HAVE_NET_MACB config ARCH_AT91SAM9G45 bool "AT91SAM9G45" @@ -73,6 +76,7 @@ config ARCH_AT91SAM9G45 select GENERIC_CLOCKEVENTS select HAVE_AT91_USART3 select HAVE_FB_ATMEL + select HAVE_NET_MACB config ARCH_AT91CAP9 bool "AT91CAP9" @@ -344,6 +348,7 @@ config MACH_AT91SAM9G20EK that embeds only one SD/MMC slot. config MACH_AT91SAM9G20EK_2MMC + depends on MACH_AT91SAM9G20EK bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots" select HAVE_NAND_ATMEL_BUSWIDTH_16 help @@ -389,8 +394,8 @@ if ARCH_AT91SAM9G45 comment "AT91SAM9G45 Board Type" -config MACH_AT91SAM9G45EKES - bool "Atmel AT91SAM9G45-EKES Evaluation Kit" +config MACH_AT91SAM9M10G45EK + bool "Atmel AT91SAM9M10G45-EK Evaluation Kits" select HAVE_NAND_ATMEL_BUSWIDTH_16 help Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit. diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 7cbe06d7cee9..412b3a471a4b 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -62,7 +62,6 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o # AT91SAM9G20 board-specific support obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o -obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o @@ -71,7 +70,7 @@ obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o # AT91SAM9G45 board-specific support -obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o +obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o # AT91CAP9 board-specific support obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o diff --git a/arch/arm/mach-at91/board-at572d940hf_ek.c b/arch/arm/mach-at91/board-at572d940hf_ek.c index 5daff277f53e..46651623f208 100644 --- a/arch/arm/mach-at91/board-at572d940hf_ek.c +++ b/arch/arm/mach-at91/board-at572d940hf_ek.c @@ -216,7 +216,7 @@ static struct atmel_nand_data __initdata eb_nand_data = { /* .rdy_pin = AT91_PIN_PC16, */ .enable_pin = AT91_PIN_PA15, .partition_info = nand_partitions, -#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) +#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) .bus_width_16 = 1, #else .bus_width_16 = 0, diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c deleted file mode 100644 index c49f5c003ee1..000000000000 --- a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (C) 2005 SAN People - * Copyright (C) 2008 Atmel - * Copyright (C) 2009 Rob Emanuele - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spi/spi.h> -#include <linux/spi/at73c213.h> -#include <linux/clk.h> -#include <linux/regulator/machine.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/consumer.h> - -#include <mach/hardware.h> -#include <asm/setup.h> -#include <asm/mach-types.h> -#include <asm/irq.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <mach/board.h> -#include <mach/gpio.h> -#include <mach/at91sam9_smc.h> - -#include "sam9_smc.h" -#include "generic.h" - - -static void __init ek_map_io(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91sam9260_initialize(18432000); - - /* DGBU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* set serial console to ttyS0 (ie, DBGU) */ - at91_set_serial_console(0); -} - -static void __init ek_init_irq(void) -{ - at91sam9260_init_interrupts(NULL); -} - - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata ek_udc_data = { - .vbus_pin = AT91_PIN_PC5, - .pullup_pin = 0, /* pull-up driven by UDC */ -}; - - -/* - * SPI devices. - */ -static struct spi_board_info ek_spi_devices[] = { -#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91)) - { /* DataFlash chip */ - .modalias = "mtd_dataflash", - .chip_select = 1, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) - { /* DataFlash card */ - .modalias = "mtd_dataflash", - .chip_select = 0, - .max_speed_hz = 15 * 1000 * 1000, - .bus_num = 0, - }, -#endif -#endif -}; - - -/* - * MACB Ethernet device - */ -static struct at91_eth_data __initdata ek_macb_data = { - .phy_irq_pin = AT91_PIN_PB0, - .is_rmii = 1, -}; - - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Bootstrap", - .offset = 0, - .size = 4 * SZ_1M, - }, - { - .name = "Partition 1", - .offset = MTDPART_OFS_NXTBLK, - .size = 60 * SZ_1M, - }, - { - .name = "Partition 2", - .offset = MTDPART_OFS_NXTBLK, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) -{ - *num_partitions = ARRAY_SIZE(ek_nand_partition); - return ek_nand_partition; -} - -/* det_pin is not connected */ -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .rdy_pin = AT91_PIN_PC13, - .enable_pin = AT91_PIN_PC14, - .partition_info = nand_partitions, -#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) - .bus_width_16 = 1, -#else - .bus_width_16 = 0, -#endif -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 2, - .ncs_write_setup = 0, - .nwe_setup = 2, - - .ncs_read_pulse = 4, - .nrd_pulse = 4, - .ncs_write_pulse = 4, - .nwe_pulse = 4, - - .read_cycle = 7, - .write_cycle = 7, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, - .tdf_cycles = 3, -}; - -static void __init ek_add_device_nand(void) -{ - /* setup bus-width (8 or 16) */ - if (ek_nand_data.bus_width_16) - ek_nand_smc_config.mode |= AT91_SMC_DBW_16; - else - ek_nand_smc_config.mode |= AT91_SMC_DBW_8; - - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - - -/* - * MCI (SD/MMC) - * wp_pin is not connected - */ -#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) -static struct mci_platform_data __initdata ek_mmc_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PC2, - .wp_pin = -ENODEV, - }, - .slot[1] = { - .bus_width = 4, - .detect_pin = AT91_PIN_PC9, - .wp_pin = -ENODEV, - }, - -}; -#else -static struct at91_mmc_data __initdata ek_mmc_data = { - .slot_b = 1, /* Only one slot so use slot B */ - .wire4 = 1, - .det_pin = AT91_PIN_PC9, -}; -#endif - -/* - * LEDs - */ -static struct gpio_led ek_leds[] = { - { /* "bottom" led, green, userled1 to be defined */ - .name = "ds5", - .gpio = AT91_PIN_PB8, - .active_low = 1, - .default_trigger = "none", - }, - { /* "power" led, yellow */ - .name = "ds1", - .gpio = AT91_PIN_PB9, - .default_trigger = "heartbeat", - } -}; - -#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE) -static struct regulator_consumer_supply ek_audio_consumer_supplies[] = { - REGULATOR_SUPPLY("AVDD", "0-001b"), - REGULATOR_SUPPLY("HPVDD", "0-001b"), - REGULATOR_SUPPLY("DBVDD", "0-001b"), - REGULATOR_SUPPLY("DCVDD", "0-001b"), -}; - -static struct regulator_init_data ek_avdd_reg_init_data = { - .constraints = { - .name = "3V3", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = ek_audio_consumer_supplies, - .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies), -}; - -static struct fixed_voltage_config ek_vdd_pdata = { - .supply_name = "board-3V3", - .microvolts = 3300000, - .gpio = -EINVAL, - .enabled_at_boot = 0, - .init_data = &ek_avdd_reg_init_data, -}; -static struct platform_device ek_voltage_regulator = { - .name = "reg-fixed-voltage", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_vdd_pdata, - }, -}; -static void __init ek_add_regulators(void) -{ - platform_device_register(&ek_voltage_regulator); -} -#else -static void __init ek_add_regulators(void) {} -#endif - -static struct i2c_board_info __initdata ek_i2c_devices[] = { - { - I2C_BOARD_INFO("24c512", 0x50), - }, -}; - - -static void __init ek_board_init(void) -{ - /* Serial */ - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&ek_usbh_data); - /* USB Device */ - at91_add_device_udc(&ek_udc_data); - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* NAND */ - ek_add_device_nand(); - /* Ethernet */ - at91_add_device_eth(&ek_macb_data); - /* Regulators */ - ek_add_regulators(); - /* MMC */ -#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) - at91_add_device_mci(0, &ek_mmc_data); -#else - at91_add_device_mmc(0, &ek_mmc_data); -#endif - /* I2C */ - at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - /* PCK0 provides MCLK to the WM8731 */ - at91_set_B_periph(AT91_PIN_PC1, 0); - /* SSC (for WM8731) */ - at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); -} - -MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") - /* Maintainer: Rob Emanuele */ - .phys_io = AT91_BASE_SYS, - .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, - .boot_params = AT91_SDRAM_BASE + 0x100, - .timer = &at91sam926x_timer, - .map_io = ek_map_io, - .init_irq = ek_init_irq, - .init_machine = ek_board_init, -MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index 6ea9808b8868..b463e340c4a0 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c @@ -47,6 +47,18 @@ #include "sam9_smc.h" #include "generic.h" +/* + * board revision encoding + * bit 0: + * 0 => 1 sd/mmc slot + * 1 => 2 sd/mmc slots connectors (board from revision C) + */ +#define HAVE_2MMC (1 << 0) +static int inline ek_have_2mmc(void) +{ + return machine_is_at91sam9g20ek_2mmc() || (system_rev & HAVE_2MMC); +} + static void __init ek_map_io(void) { @@ -94,7 +106,7 @@ static struct at91_udc_data __initdata ek_udc_data = { * SPI devices. */ static struct spi_board_info ek_spi_devices[] = { -#if !defined(CONFIG_MMC_AT91) +#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91)) { /* DataFlash chip */ .modalias = "mtd_dataflash", .chip_select = 1, @@ -121,6 +133,13 @@ static struct at91_eth_data __initdata ek_macb_data = { .is_rmii = 1, }; +static void __init ek_add_device_macb(void) +{ + if (ek_have_2mmc()) + ek_macb_data.phy_irq_pin = AT91_PIN_PB0; + + at91_add_device_eth(&ek_macb_data); +} /* * NAND flash @@ -198,13 +217,36 @@ static void __init ek_add_device_nand(void) /* * MCI (SD/MMC) - * det_pin, wp_pin and vcc_pin are not connected + * wp_pin and vcc_pin are not connected */ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) +static struct mci_platform_data __initdata ek_mmc_data = { + .slot[1] = { + .bus_width = 4, + .detect_pin = AT91_PIN_PC9, + }, + +}; +#else static struct at91_mmc_data __initdata ek_mmc_data = { - .slot_b = 1, + .slot_b = 1, /* Only one slot so use slot B */ .wire4 = 1, + .det_pin = AT91_PIN_PC9, }; +#endif +static void __init ek_add_device_mmc(void) +{ +#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) + if (ek_have_2mmc()) { + ek_mmc_data.slot[0].bus_width = 4; + ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2; + } + at91_add_device_mci(0, &ek_mmc_data); +#else + at91_add_device_mmc(0, &ek_mmc_data); +#endif +} /* * LEDs @@ -223,6 +265,15 @@ static struct gpio_led ek_leds[] = { } }; +static void __init ek_add_device_gpio_leds(void) +{ + if (ek_have_2mmc()) { + ek_leds[0].gpio = AT91_PIN_PB8; + ek_leds[1].gpio = AT91_PIN_PB9; + } + + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); +} /* * GPIO Buttons @@ -336,15 +387,15 @@ static void __init ek_board_init(void) /* NAND */ ek_add_device_nand(); /* Ethernet */ - at91_add_device_eth(&ek_macb_data); + ek_add_device_macb(); /* Regulators */ ek_add_regulators(); /* MMC */ - at91_add_device_mmc(0, &ek_mmc_data); + ek_add_device_mmc(); /* I2C */ at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices)); /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + ek_add_device_gpio_leds(); /* Push Buttons */ ek_add_device_buttons(); /* PCK0 provides MCLK to the WM8731 */ @@ -363,3 +414,14 @@ MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK") .init_irq = ek_init_irq, .init_machine = ek_board_init, MACHINE_END + +MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod") + /* Maintainer: Atmel */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index ee800595594d..ae0e0843e5f5 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -135,7 +135,7 @@ static struct atmel_nand_data __initdata ek_nand_data = { .rdy_pin = AT91_PIN_PC8, .enable_pin = AT91_PIN_PC14, .partition_info = nand_partitions, -#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) +#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16) .bus_width_16 = 1, #else .bus_width_16 = 0, @@ -399,7 +399,7 @@ static void __init ek_board_init(void) at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); } -MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES") +MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK") /* Maintainer: Atmel */ .phys_io = AT91_BASE_SYS, .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h index d34cdb8abdca..063ac44a0204 100644 --- a/arch/arm/mach-at91/include/mach/at91x40.h +++ b/arch/arm/mach-at91/include/mach/at91x40.h @@ -52,4 +52,10 @@ #define AT91_DBGU_CIDR (AT91_SF + 0) /* CIDR in PS segment */ #define AT91_DBGU_EXID (AT91_SF + 4) /* EXID in PS segment */ +/* + * Support defines for the simple Power Controller module. + */ +#define AT91_PS_CR (AT91_PS + 0) /* PS Control register */ +#define AT91_PS_CR_CPU (1 << 0) /* CPU clock disable bit */ + #endif /* AT91X40_H */ diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h index c80e090b3670..36af14bc13bb 100644 --- a/arch/arm/mach-at91/include/mach/system.h +++ b/arch/arm/mach-at91/include/mach/system.h @@ -28,17 +28,20 @@ static inline void arch_idle(void) { -#ifndef CONFIG_DEBUG_KERNEL /* * Disable the processor clock. The processor will be automatically * re-enabled by an interrupt or by a reset. */ - at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); +#ifdef AT91_PS + at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU); #else + at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); +#endif +#ifndef CONFIG_CPU_ARM920T /* * Set the processor (CP15) into 'Wait for Interrupt' mode. - * Unlike disabling the processor clock via the PMC (above) - * this allows the processor to be woken via JTAG. + * Post-RM9200 processors need this in conjunction with the above + * to save power when idle. */ cpu_do_idle(); #endif diff --git a/arch/arm/mach-bcmring/include/mach/vmalloc.h b/arch/arm/mach-bcmring/include/mach/vmalloc.h index 35e2ead8395c..3db3a09fd398 100644 --- a/arch/arm/mach-bcmring/include/mach/vmalloc.h +++ b/arch/arm/mach-bcmring/include/mach/vmalloc.h @@ -22,4 +22,4 @@ * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles * larger physical memory designs better. */ -#define VMALLOC_END (PAGE_OFFSET + 0x30000000) +#define VMALLOC_END 0xf0000000 diff --git a/arch/arm/mach-clps711x/include/mach/vmalloc.h b/arch/arm/mach-clps711x/include/mach/vmalloc.h index ea6cc7beff28..30b3a287ed88 100644 --- a/arch/arm/mach-clps711x/include/mach/vmalloc.h +++ b/arch/arm/mach-clps711x/include/mach/vmalloc.h @@ -17,4 +17,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define VMALLOC_END (PAGE_OFFSET + 0x10000000) +#define VMALLOC_END 0xd0000000 diff --git a/arch/arm/mach-ebsa110/include/mach/vmalloc.h b/arch/arm/mach-ebsa110/include/mach/vmalloc.h index 9b44c19e95ec..60bde56fba4c 100644 --- a/arch/arm/mach-ebsa110/include/mach/vmalloc.h +++ b/arch/arm/mach-ebsa110/include/mach/vmalloc.h @@ -7,4 +7,4 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define VMALLOC_END (PAGE_OFFSET + 0x1f000000) +#define VMALLOC_END 0xdf000000 diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c index 8904ca4e2e24..a696d354b1f8 100644 --- a/arch/arm/mach-ep93xx/dma-m2p.c +++ b/arch/arm/mach-ep93xx/dma-m2p.c @@ -276,7 +276,7 @@ static void channel_disable(struct m2p_channel *ch) v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN); m2p_set_control(ch, v); - while (m2p_channel_state(ch) == STATE_ON) + while (m2p_channel_state(ch) >= STATE_ON) cpu_relax(); m2p_set_control(ch, 0x0); diff --git a/arch/arm/mach-footbridge/include/mach/vmalloc.h b/arch/arm/mach-footbridge/include/mach/vmalloc.h index d0958d860a3c..0ffbb7c85e59 100644 --- a/arch/arm/mach-footbridge/include/mach/vmalloc.h +++ b/arch/arm/mach-footbridge/include/mach/vmalloc.h @@ -7,4 +7,4 @@ */ -#define VMALLOC_END (PAGE_OFFSET + 0x30000000) +#define VMALLOC_END 0xf0000000 diff --git a/arch/arm/mach-h720x/include/mach/vmalloc.h b/arch/arm/mach-h720x/include/mach/vmalloc.h index ff1460d6841b..a45915b88756 100644 --- a/arch/arm/mach-h720x/include/mach/vmalloc.h +++ b/arch/arm/mach-h720x/include/mach/vmalloc.h @@ -5,6 +5,6 @@ #ifndef __ARCH_ARM_VMALLOC_H #define __ARCH_ARM_VMALLOC_H -#define VMALLOC_END (PAGE_OFFSET + 0x10000000) +#define VMALLOC_END 0xd0000000 #endif diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index c5c0369bb481..197f9e241cff 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -122,6 +122,7 @@ config MACH_CPUIMX27 select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_MXC_NAND + select MXC_ULPI if USB_ULPI help Include support for Eukrea CPUIMX27 platform. This includes specific configurations for the module and its peripherals. @@ -146,8 +147,8 @@ choice default MACH_EUKREA_MBIMX27_BASEBOARD config MACH_EUKREA_MBIMX27_BASEBOARD - prompt "Eukrea MBIMX27 development board" - bool + bool "Eukrea MBIMX27 development board" + select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_SPI_IMX help @@ -163,6 +164,15 @@ config MACH_MX27_3DS Include support for MX27PDK platform. This includes specific configurations for the board and its peripherals. +config MACH_IMX27_VISSTRIM_M10 + bool "Vista Silicon i.MX27 Visstrim_m10" + select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_UART + help + Include support for Visstrim_m10 platform and its different variants. + This includes specific configurations for the board and its + peripherals. + config MACH_IMX27LITE bool "LogicPD MX27 LITEKIT platform" select IMX_HAVE_PLATFORM_IMX_UART @@ -173,6 +183,7 @@ config MACH_IMX27LITE config MACH_PCA100 bool "Phytec phyCARD-s (pca100)" select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_MXC_NAND select IMX_HAVE_PLATFORM_SPI_IMX diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 46a9fdfbbd15..5582692bb176 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o obj-$(CONFIG_MACH_IMX27LITE) += mach-imx27lite.o +obj-$(CONFIG_MACH_IMX27_VISSTRIM_M10) += mach-imx27_visstrim_m10.o obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o obj-$(CONFIG_MACH_PCA100) += mach-pca100.o diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c index c05096c38301..daca30b2d5b1 100644 --- a/arch/arm/mach-imx/clock-imx1.c +++ b/arch/arm/mach-imx/clock-imx1.c @@ -592,7 +592,7 @@ static struct clk_lookup lookups[] __initdata = { _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk) _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk) _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) - _REGISTER_CLOCK("spi_imx.0", NULL, spi_clk) + _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk) _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk) _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) _REGISTER_CLOCK(NULL, "mshc", mshc_clk) diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c index bb419ef4d133..cf15ea516a72 100644 --- a/arch/arm/mach-imx/clock-imx21.c +++ b/arch/arm/mach-imx/clock-imx21.c @@ -1172,9 +1172,9 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0]) _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0]) _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1]) - _REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0]) - _REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1]) - _REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2]) + _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0]) + _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1]) + _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2]) _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0]) _REGISTER_CLOCK(NULL, "csi", csi_clk[0]) _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0]) diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c index 5a1aa15c8a16..98a25bada783 100644 --- a/arch/arm/mach-imx/clock-imx27.c +++ b/arch/arm/mach-imx/clock-imx27.c @@ -594,27 +594,27 @@ DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk); DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk); /* Clocks we cannot directly gate, but drivers need their rates */ -DEFINE_CLOCK(cspi1_clk, 0, 0, 0, NULL, &cspi1_clk1, &per2_clk); -DEFINE_CLOCK(cspi2_clk, 1, 0, 0, NULL, &cspi2_clk1, &per2_clk); -DEFINE_CLOCK(cspi3_clk, 2, 0, 0, NULL, &cspi13_clk1, &per2_clk); -DEFINE_CLOCK(sdhc1_clk, 0, 0, 0, NULL, &sdhc1_clk1, &per2_clk); -DEFINE_CLOCK(sdhc2_clk, 1, 0, 0, NULL, &sdhc2_clk1, &per2_clk); -DEFINE_CLOCK(sdhc3_clk, 2, 0, 0, NULL, &sdhc3_clk1, &per2_clk); -DEFINE_CLOCK(pwm_clk, 0, 0, 0, NULL, &pwm_clk1, &per1_clk); -DEFINE_CLOCK(gpt1_clk, 0, 0, 0, NULL, &gpt1_clk1, &per1_clk); -DEFINE_CLOCK(gpt2_clk, 1, 0, 0, NULL, &gpt2_clk1, &per1_clk); -DEFINE_CLOCK(gpt3_clk, 2, 0, 0, NULL, &gpt3_clk1, &per1_clk); -DEFINE_CLOCK(gpt4_clk, 3, 0, 0, NULL, &gpt4_clk1, &per1_clk); -DEFINE_CLOCK(gpt5_clk, 4, 0, 0, NULL, &gpt5_clk1, &per1_clk); -DEFINE_CLOCK(gpt6_clk, 5, 0, 0, NULL, &gpt6_clk1, &per1_clk); -DEFINE_CLOCK(uart1_clk, 0, 0, 0, NULL, &uart1_clk1, &per1_clk); -DEFINE_CLOCK(uart2_clk, 1, 0, 0, NULL, &uart2_clk1, &per1_clk); -DEFINE_CLOCK(uart3_clk, 2, 0, 0, NULL, &uart3_clk1, &per1_clk); -DEFINE_CLOCK(uart4_clk, 3, 0, 0, NULL, &uart4_clk1, &per1_clk); -DEFINE_CLOCK(uart5_clk, 4, 0, 0, NULL, &uart5_clk1, &per1_clk); -DEFINE_CLOCK(uart6_clk, 5, 0, 0, NULL, &uart6_clk1, &per1_clk); -DEFINE_CLOCK1(lcdc_clk, 0, 0, 0, parent, &lcdc_clk1, &per3_clk); -DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk); +DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk); +DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk); +DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk); +DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk); +DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk); +DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk); +DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk); +DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk); +DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk); +DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk); +DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk); +DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk); +DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk); +DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk); +DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk); +DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk); +DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk); +DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk); +DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk); +DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk); +DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk); #define _REGISTER_CLOCK(d, n, c) \ { \ @@ -640,9 +640,9 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk) - _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) - _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk) - _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk) + _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk) + _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk) + _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk) _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk) diff --git a/arch/arm/mach-imx/devices-imx1.h b/arch/arm/mach-imx/devices-imx1.h index a8d94f078196..81979486218e 100644 --- a/arch/arm/mach-imx/devices-imx1.h +++ b/arch/arm/mach-imx/devices-imx1.h @@ -9,10 +9,12 @@ #include <mach/mx1.h> #include <mach/devices-common.h> -#define imx1_add_i2c_imx(pdata) \ - imx_add_imx_i2c(0, MX1_I2C_BASE_ADDR, SZ_4K, MX1_INT_I2C, pdata) +extern const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst; +#define imx1_add_imx_i2c(pdata) \ + imx_add_imx_i2c(&imx1_imx_i2c_data, pdata) -#define imx1_add_imx_uart0(pdata) \ - imx_add_imx_uart_3irq(0, MX1_UART1_BASE_ADDR, 0xd0, MX1_INT_UART1RX, MX1_INT_UART1TX, MX1_INT_UART1RTS, pdata) -#define imx1_add_imx_uart1(pdata) \ - imx_add_imx_uart_3irq(0, MX1_UART2_BASE_ADDR, 0xd0, MX1_INT_UART2RX, MX1_INT_UART2TX, MX1_INT_UART2RTS, pdata) +extern const struct imx_imx_uart_3irq_data imx1_imx_uart_data[] __initconst; +#define imx1_add_imx_uart(id, pdata) \ + imx_add_imx_uart_3irq(&imx1_imx_uart_data[id], pdata) +#define imx1_add_imx_uart0(pdata) imx1_add_imx_uart(0, pdata) +#define imx1_add_imx_uart1(pdata) imx1_add_imx_uart(1, pdata) diff --git a/arch/arm/mach-imx/devices-imx21.h b/arch/arm/mach-imx/devices-imx21.h index 42788e99d127..d189039749b0 100644 --- a/arch/arm/mach-imx/devices-imx21.h +++ b/arch/arm/mach-imx/devices-imx21.h @@ -9,22 +9,28 @@ #include <mach/mx21.h> #include <mach/devices-common.h> -#define imx21_add_i2c_imx(pdata) \ - imx_add_imx_i2c(0, MX2x_I2C_BASE_ADDR, SZ_4K, MX2x_INT_I2C, pdata) +extern const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst; +#define imx21_add_imx_i2c(pdata) \ + imx_add_imx_i2c(&imx21_imx_i2c_data, pdata) -#define imx21_add_imx_uart0(pdata) \ - imx_add_imx_uart_1irq(0, MX21_UART1_BASE_ADDR, SZ_4K, MX21_INT_UART1, pdata) -#define imx21_add_imx_uart1(pdata) \ - imx_add_imx_uart_1irq(1, MX21_UART2_BASE_ADDR, SZ_4K, MX21_INT_UART2, pdata) -#define imx21_add_imx_uart2(pdata) \ - imx_add_imx_uart_1irq(2, MX21_UART3_BASE_ADDR, SZ_4K, MX21_INT_UART3, pdata) -#define imx21_add_imx_uart3(pdata) \ - imx_add_imx_uart_1irq(3, MX21_UART4_BASE_ADDR, SZ_4K, MX21_INT_UART4, pdata) +extern const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst; +#define imx21_add_imx_ssi(id, pdata) \ + imx_add_imx_ssi(&imx21_imx_ssi_data[id], pdata) +extern const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst; +#define imx21_add_imx_uart(id, pdata) \ + imx_add_imx_uart_1irq(&imx21_imx_uart_data[id], pdata) +#define imx21_add_imx_uart0(pdata) imx21_add_imx_uart(0, pdata) +#define imx21_add_imx_uart1(pdata) imx21_add_imx_uart(1, pdata) +#define imx21_add_imx_uart2(pdata) imx21_add_imx_uart(2, pdata) +#define imx21_add_imx_uart3(pdata) imx21_add_imx_uart(3, pdata) + +extern const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst; #define imx21_add_mxc_nand(pdata) \ - imx_add_mxc_nand_v1(MX21_NFC_BASE_ADDR, MX21_INT_NANDFC, pdata) + imx_add_mxc_nand(&imx21_mxc_nand_data, pdata) -#define imx21_add_spi_imx0(pdata) \ - imx_add_spi_imx(0, MX21_CSPI1_BASE_ADDR, SZ_4K, MX21_INT_CSPI1, pdata) -#define imx21_add_spi_imx1(pdata) \ - imx_add_spi_imx(1, MX21_CSPI2_BASE_ADDR, SZ_4K, MX21_INT_CSPI2, pdata) +extern const struct imx_spi_imx_data imx21_cspi_data[] __initconst; +#define imx21_add_cspi(id, pdata) \ + imx_add_spi_imx(&imx21_cspi_data[id], pdata) +#define imx21_add_spi_imx0(pdata) imx21_add_cspi(0, pdata) +#define imx21_add_spi_imx1(pdata) imx21_add_cspi(1, pdata) diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h index 65e7bb7ec2e8..7011690364f2 100644 --- a/arch/arm/mach-imx/devices-imx27.h +++ b/arch/arm/mach-imx/devices-imx27.h @@ -9,30 +9,35 @@ #include <mach/mx27.h> #include <mach/devices-common.h> -#define imx27_add_i2c_imx0(pdata) \ - imx_add_imx_i2c(0, MX27_I2C1_BASE_ADDR, SZ_4K, MX27_INT_I2C1, pdata) -#define imx27_add_i2c_imx1(pdata) \ - imx_add_imx_i2c(1, MX27_I2C2_BASE_ADDR, SZ_4K, MX27_INT_I2C2, pdata) +extern const struct imx_fec_data imx27_fec_data __initconst; +#define imx27_add_fec(pdata) \ + imx_add_fec(&imx27_fec_data, pdata) -#define imx27_add_imx_uart0(pdata) \ - imx_add_imx_uart_1irq(0, MX27_UART1_BASE_ADDR, SZ_4K, MX27_INT_UART1, pdata) -#define imx27_add_imx_uart1(pdata) \ - imx_add_imx_uart_1irq(1, MX27_UART2_BASE_ADDR, SZ_4K, MX27_INT_UART2, pdata) -#define imx27_add_imx_uart2(pdata) \ - imx_add_imx_uart_1irq(2, MX27_UART3_BASE_ADDR, SZ_4K, MX27_INT_UART3, pdata) -#define imx27_add_imx_uart3(pdata) \ - imx_add_imx_uart_1irq(3, MX27_UART4_BASE_ADDR, SZ_4K, MX27_INT_UART4, pdata) -#define imx27_add_imx_uart4(pdata) \ - imx_add_imx_uart_1irq(4, MX27_UART5_BASE_ADDR, SZ_4K, MX27_INT_UART5, pdata) -#define imx27_add_imx_uart5(pdata) \ - imx_add_imx_uart_1irq(5, MX27_UART6_BASE_ADDR, SZ_4K, MX27_INT_UART6, pdata) +extern const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst; +#define imx27_add_imx_i2c(id, pdata) \ + imx_add_imx_i2c(&imx27_imx_i2c_data[id], pdata) +extern const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst; +#define imx27_add_imx_ssi(id, pdata) \ + imx_add_imx_ssi(&imx27_imx_ssi_data[id], pdata) + +extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst; +#define imx27_add_imx_uart(id, pdata) \ + imx_add_imx_uart_1irq(&imx27_imx_uart_data[id], pdata) +#define imx27_add_imx_uart0(pdata) imx27_add_imx_uart(0, pdata) +#define imx27_add_imx_uart1(pdata) imx27_add_imx_uart(1, pdata) +#define imx27_add_imx_uart2(pdata) imx27_add_imx_uart(2, pdata) +#define imx27_add_imx_uart3(pdata) imx27_add_imx_uart(3, pdata) +#define imx27_add_imx_uart4(pdata) imx27_add_imx_uart(4, pdata) +#define imx27_add_imx_uart5(pdata) imx27_add_imx_uart(5, pdata) + +extern const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst; #define imx27_add_mxc_nand(pdata) \ - imx_add_mxc_nand_v1(MX27_NFC_BASE_ADDR, MX27_INT_NANDFC, pdata) + imx_add_mxc_nand(&imx27_mxc_nand_data, pdata) -#define imx27_add_spi_imx0(pdata) \ - imx_add_spi_imx(0, MX27_CSPI1_BASE_ADDR, SZ_4K, MX27_INT_CSPI1, pdata) -#define imx27_add_spi_imx1(pdata) \ - imx_add_spi_imx(1, MX27_CSPI2_BASE_ADDR, SZ_4K, MX27_INT_CSPI2, pdata) -#define imx27_add_spi_imx2(pdata) \ - imx_add_spi_imx(2, MX27_CSPI3_BASE_ADDR, SZ_4K, MX27_INT_CSPI3, pdata) +extern const struct imx_spi_imx_data imx27_cspi_data[] __initconst; +#define imx27_add_cspi(id, pdata) \ + imx_add_spi_imx(&imx27_cspi_data[id], pdata) +#define imx27_add_spi_imx0(pdata) imx27_add_cspi(0, pdata) +#define imx27_add_spi_imx1(pdata) imx27_add_cspi(1, pdata) +#define imx27_add_spi_imx2(pdata) imx27_add_cspi(2, pdata) diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c index 9c271a752b84..fba5047de8b1 100644 --- a/arch/arm/mach-imx/devices.c +++ b/arch/arm/mach-imx/devices.c @@ -314,27 +314,6 @@ struct platform_device mxc_fb_device = { }, }; -#ifdef CONFIG_MACH_MX27 -static struct resource mxc_fec_resources[] = { - { - .start = MX27_FEC_BASE_ADDR, - .end = MX27_FEC_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = MX27_INT_FEC, - .end = MX27_INT_FEC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_fec_device = { - .name = "fec", - .id = 0, - .num_resources = ARRAY_SIZE(mxc_fec_resources), - .resource = mxc_fec_resources, -}; -#endif - static struct resource mxc_pwm_resources[] = { { .start = MX2x_PWM_BASE_ADDR, @@ -480,41 +459,6 @@ struct platform_device mxc_usbh2 = { }; #endif -#define DEFINE_IMX_SSI_DMARES(_name, ssin, suffix) \ - { \ - .name = _name, \ - .start = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \ - .end = MX2x_DMA_REQ_SSI ## ssin ## _ ## suffix, \ - .flags = IORESOURCE_DMA, \ - } - -#define DEFINE_IMX_SSI_DEVICE(n, ssin, baseaddr, irq) \ - static struct resource imx_ssi_resources ## n[] = { \ - { \ - .start = MX2x_SSI ## ssin ## _BASE_ADDR, \ - .end = MX2x_SSI ## ssin ## _BASE_ADDR + 0x6f, \ - .flags = IORESOURCE_MEM, \ - }, { \ - .start = MX2x_INT_SSI1, \ - .end = MX2x_INT_SSI1, \ - .flags = IORESOURCE_IRQ, \ - }, \ - DEFINE_IMX_SSI_DMARES("tx0", ssin, TX0), \ - DEFINE_IMX_SSI_DMARES("rx0", ssin, RX0), \ - DEFINE_IMX_SSI_DMARES("tx1", ssin, TX1), \ - DEFINE_IMX_SSI_DMARES("rx1", ssin, RX1), \ - }; \ - \ - struct platform_device imx_ssi_device ## n = { \ - .name = "imx-ssi", \ - .id = n, \ - .num_resources = ARRAY_SIZE(imx_ssi_resources ## n), \ - .resource = imx_ssi_resources ## n, \ - } - -DEFINE_IMX_SSI_DEVICE(0, 1, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1); -DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1); - /* GPIO port description */ #define DEFINE_MXC_GPIO_PORT_IRQ(SOC, n, _irq) \ { \ diff --git a/arch/arm/mach-imx/devices.h b/arch/arm/mach-imx/devices.h index efd4527506a5..807f02a031c9 100644 --- a/arch/arm/mach-imx/devices.h +++ b/arch/arm/mach-imx/devices.h @@ -16,7 +16,6 @@ extern struct platform_device mxc_gpt5; extern struct platform_device mxc_wdt; extern struct platform_device mxc_w1_master_device; extern struct platform_device mxc_fb_device; -extern struct platform_device mxc_fec_device; extern struct platform_device mxc_pwm_device; extern struct platform_device mxc_sdhc_device0; extern struct platform_device mxc_sdhc_device1; @@ -26,7 +25,5 @@ extern struct platform_device mxc_otg_host; extern struct platform_device mxc_usbh1; extern struct platform_device mxc_usbh2; extern struct platform_device mx21_usbhc_device; -extern struct platform_device imx_ssi_device0; -extern struct platform_device imx_ssi_device1; extern struct platform_device imx_kpp_device; #endif diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c index 4edc5f439201..026263c665ca 100644 --- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c +++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c @@ -36,13 +36,12 @@ #include <mach/hardware.h> #include <mach/mmc.h> #include <mach/spi.h> -#include <mach/ssi.h> #include <mach/audmux.h> #include "devices-imx27.h" #include "devices.h" -static int eukrea_mbimx27_pins[] = { +static const int eukrea_mbimx27_pins[] __initconst = { /* UART2 */ PE3_PF_UART2_CTS, PE4_PF_UART2_RTS, @@ -311,7 +310,8 @@ static struct imxmmc_platform_data sdhc_pdata = { .dat3_card_detect = 1, }; -struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata = { +static const +struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata __initconst = { .flags = IMX_SSI_DMA | IMX_SSI_USE_I2S_SLAVE, }; @@ -357,7 +357,7 @@ void __init eukrea_mbimx27_baseboard_init(void) i2c_register_board_info(0, eukrea_mbimx27_i2c_devices, ARRAY_SIZE(eukrea_mbimx27_i2c_devices)); - mxc_register_device(&imx_ssi_device0, &eukrea_mbimx27_ssi_pdata); + imx27_add_imx_ssi(0, &eukrea_mbimx27_ssi_pdata); #if defined(CONFIG_TOUCHSCREEN_ADS7846) \ || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index 339150ab0ea5..a1681fc9d9b0 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c @@ -46,7 +46,7 @@ #include "devices-imx27.h" #include "devices.h" -static int eukrea_cpuimx27_pins[] = { +static const int eukrea_cpuimx27_pins[] __initconst = { /* UART1 */ PE12_PF_UART1_TXD, PE13_PF_UART1_RXD, @@ -157,7 +157,6 @@ cpuimx27_nand_board_info __initconst = { static struct platform_device *platform_devices[] __initdata = { &eukrea_cpuimx27_nor_mtd_device, - &mxc_fec_device, &mxc_wdt, &mxc_w1_master_device, }; @@ -259,8 +258,9 @@ static void __init eukrea_cpuimx27_init(void) i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices, ARRAY_SIZE(eukrea_cpuimx27_i2c_devices)); - imx27_add_i2c_imx1(&cpuimx27_i2c1_data); + imx27_add_imx_i2c(0, &cpuimx27_i2c1_data); + imx27_add_fec(NULL); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); #if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2) diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c new file mode 100644 index 000000000000..a0d78faa08e8 --- /dev/null +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -0,0 +1,263 @@ +/* + * mach-imx27_visstrim_m10.c + * + * Copyright 2010 Javier Martin <javier.martin@vista-silicon.com> + * + * Based on mach-pcm038.c, mach-pca100.c, mach-mx27ads.c and others. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/platform_device.h> +#include <linux/mtd/physmap.h> +#include <linux/i2c.h> +#include <linux/i2c/pca953x.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/gpio.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <mach/common.h> +#include <mach/mmc.h> +#include <mach/iomux.h> +#include <mach/mxc_ehci.h> + +#include "devices-imx27.h" +#include "devices.h" + +#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17) +#define SDHC1_IRQ IRQ_GPIOB(25) + +static const int visstrim_m10_pins[] __initconst = { + /* UART1 (console) */ + PE12_PF_UART1_TXD, + PE13_PF_UART1_RXD, + PE14_PF_UART1_CTS, + PE15_PF_UART1_RTS, + /* FEC */ + PD0_AIN_FEC_TXD0, + PD1_AIN_FEC_TXD1, + PD2_AIN_FEC_TXD2, + PD3_AIN_FEC_TXD3, + PD4_AOUT_FEC_RX_ER, + PD5_AOUT_FEC_RXD1, + PD6_AOUT_FEC_RXD2, + PD7_AOUT_FEC_RXD3, + PD8_AF_FEC_MDIO, + PD9_AIN_FEC_MDC, + PD10_AOUT_FEC_CRS, + PD11_AOUT_FEC_TX_CLK, + PD12_AOUT_FEC_RXD0, + PD13_AOUT_FEC_RX_DV, + PD14_AOUT_FEC_RX_CLK, + PD15_AOUT_FEC_COL, + PD16_AIN_FEC_TX_ER, + PF23_AIN_FEC_TX_EN, + /* SDHC1 */ + PE18_PF_SD1_D0, + PE19_PF_SD1_D1, + PE20_PF_SD1_D2, + PE21_PF_SD1_D3, + PE22_PF_SD1_CMD, + PE23_PF_SD1_CLK, + /* Both I2Cs */ + PD17_PF_I2C_DATA, + PD18_PF_I2C_CLK, + PC5_PF_I2C2_SDA, + PC6_PF_I2C2_SCL, + /* USB OTG */ + OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT, + PC9_PF_USBOTG_DATA0, + PC11_PF_USBOTG_DATA1, + PC10_PF_USBOTG_DATA2, + PC13_PF_USBOTG_DATA3, + PC12_PF_USBOTG_DATA4, + PC7_PF_USBOTG_DATA5, + PC8_PF_USBOTG_DATA6, + PE25_PF_USBOTG_DATA7, + PE24_PF_USBOTG_CLK, + PE2_PF_USBOTG_DIR, + PE0_PF_USBOTG_NXT, + PE1_PF_USBOTG_STP, + PB23_PF_USB_PWR, + PB24_PF_USB_OC, +}; + +/* GPIOs used as events for applications */ +static struct gpio_keys_button visstrim_gpio_keys[] = { + { + .type = EV_KEY, + .code = KEY_RESTART, + .gpio = (GPIO_PORTC + 15), + .desc = "Default config", + .active_low = 0, + .wakeup = 1, + }, + { + .type = EV_KEY, + .code = KEY_RECORD, + .gpio = (GPIO_PORTF + 14), + .desc = "Record", + .active_low = 0, + .wakeup = 1, + }, + { + .type = EV_KEY, + .code = KEY_STOP, + .gpio = (GPIO_PORTF + 13), + .desc = "Stop", + .active_low = 0, + .wakeup = 1, + } +}; + +static struct gpio_keys_platform_data visstrim_gpio_keys_platform_data = { + .buttons = visstrim_gpio_keys, + .nbuttons = ARRAY_SIZE(visstrim_gpio_keys), +}; + +static struct platform_device visstrim_gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &visstrim_gpio_keys_platform_data, + }, +}; + +/* Visstrim_SM10 has a microSD slot connected to sdhc1 */ +static int visstrim_m10_sdhc1_init(struct device *dev, + irq_handler_t detect_irq, void *data) +{ + int ret; + + ret = request_irq(SDHC1_IRQ, detect_irq, IRQF_TRIGGER_FALLING, + "mmc-detect", data); + return ret; +} + +static void visstrim_m10_sdhc1_exit(struct device *dev, void *data) +{ + free_irq(SDHC1_IRQ, data); +} + +static struct imxmmc_platform_data visstrim_m10_sdhc_pdata = { + .init = visstrim_m10_sdhc1_init, + .exit = visstrim_m10_sdhc1_exit, +}; + +/* Visstrim_SM10 NOR flash */ +static struct physmap_flash_data visstrim_m10_flash_data = { + .width = 2, +}; + +static struct resource visstrim_m10_flash_resource = { + .start = 0xc0000000, + .end = 0xc0000000 + SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device visstrim_m10_nor_mtd_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &visstrim_m10_flash_data, + }, + .num_resources = 1, + .resource = &visstrim_m10_flash_resource, +}; + +static struct platform_device *platform_devices[] __initdata = { + &visstrim_gpio_keys_device, + &visstrim_m10_nor_mtd_device, +}; + +/* Visstrim_M10 uses UART0 as console */ +static const struct imxuart_platform_data uart_pdata __initconst = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +/* I2C */ +static const struct imxi2c_platform_data visstrim_m10_i2c_data __initconst = { + .bitrate = 100000, +}; + +static struct pca953x_platform_data visstrim_m10_pca9555_pdata = { + .gpio_base = 240, /* After MX27 internal GPIOs */ + .invert = 0, +}; + +static struct i2c_board_info visstrim_m10_i2c_devices[] = { + { + I2C_BOARD_INFO("pca9555", 0x20), + .platform_data = &visstrim_m10_pca9555_pdata, + }, +}; + +/* USB OTG */ +static int otg_phy_init(struct platform_device *pdev) +{ + gpio_set_value(OTG_PHY_CS_GPIO, 0); + return 0; +} + +static struct mxc_usbh_platform_data visstrim_m10_usbotg_pdata = { + .init = otg_phy_init, + .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, + .flags = MXC_EHCI_POWER_PINS_ENABLED, +}; + +static void __init visstrim_m10_board_init(void) +{ + int ret; + + ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins, + ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10"); + if (ret) + pr_err("Failed to setup pins (%d)\n", ret); + + imx27_add_imx_uart0(&uart_pdata); + + i2c_register_board_info(0, visstrim_m10_i2c_devices, + ARRAY_SIZE(visstrim_m10_i2c_devices)); + imx27_add_imx_i2c(0, &visstrim_m10_i2c_data); + imx27_add_imx_i2c(1, &visstrim_m10_i2c_data); + mxc_register_device(&mxc_sdhc_device0, &visstrim_m10_sdhc_pdata); + mxc_register_device(&mxc_otg_host, &visstrim_m10_usbotg_pdata); + imx27_add_fec(NULL); + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} + +static void __init visstrim_m10_timer_init(void) +{ + mx27_clocks_init((unsigned long)25000000); +} + +static struct sys_timer visstrim_m10_timer = { + .init = visstrim_m10_timer_init, +}; + +MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10") + .phys_io = MX27_AIPI_BASE_ADDR, + .io_pg_offst = ((MX27_AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = MX27_PHYS_OFFSET + 0x100, + .map_io = mx27_map_io, + .init_irq = mx27_init_irq, + .init_machine = visstrim_m10_board_init, + .timer = &visstrim_m10_timer, +MACHINE_END diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c index 22a2b5d91213..60d4d0ac4939 100644 --- a/arch/arm/mach-imx/mach-imx27lite.c +++ b/arch/arm/mach-imx/mach-imx27lite.c @@ -27,7 +27,7 @@ #include "devices-imx27.h" #include "devices.h" -static unsigned int mx27lite_pins[] = { +static const int mx27lite_pins[] __initconst = { /* UART1 */ PE12_PF_UART1_TXD, PE13_PF_UART1_RXD, @@ -58,16 +58,12 @@ static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; -static struct platform_device *platform_devices[] __initdata = { - &mxc_fec_device, -}; - static void __init mx27lite_init(void) { mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins), "imx27lite"); imx27_add_imx_uart0(&uart_pdata); - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + imx27_add_fec(NULL); } static void __init mx27lite_timer_init(void) diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c index 77a760cfadc0..85e2877572b5 100644 --- a/arch/arm/mach-imx/mach-mx1ads.c +++ b/arch/arm/mach-imx/mach-mx1ads.c @@ -32,7 +32,7 @@ #include "devices-imx1.h" #include "devices.h" -static int mx1ads_pins[] = { +static const int mx1ads_pins[] __initconst = { /* UART1 */ PC9_PF_UART1_CTS, PC10_PF_UART1_RTS, @@ -131,7 +131,7 @@ static void __init mx1ads_init(void) i2c_register_board_info(0, mx1ads_i2c_devices, ARRAY_SIZE(mx1ads_i2c_devices)); - imx1_add_i2c_imx(&mx1ads_i2c_data); + imx1_add_imx_i2c(&mx1ads_i2c_data); } static void __init mx1ads_timer_init(void) diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c index 96d7f8189f32..7f021e6f6acd 100644 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ b/arch/arm/mach-imx/mach-mx21ads.c @@ -67,7 +67,7 @@ #define MX21ADS_IO_LED4_ON 0x4000 #define MX21ADS_IO_LED3_ON 0x8000 -static unsigned int mx21ads_pins[] = { +static const int mx21ads_pins[] __initconst = { /* CS8900A */ (GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11), diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index e66ffaa1c26c..a69dba252658 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -33,7 +33,7 @@ #include "devices-imx27.h" #include "devices.h" -static unsigned int mx27pdk_pins[] = { +static const int mx27pdk_pins[] __initconst = { /* UART1 */ PE12_PF_UART1_TXD, PE13_PF_UART1_RXD, @@ -64,10 +64,6 @@ static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; -static struct platform_device *platform_devices[] __initdata = { - &mxc_fec_device, -}; - /* * Matrix keyboard */ @@ -94,7 +90,7 @@ static void __init mx27pdk_init(void) mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), "mx27pdk"); imx27_add_imx_uart0(&uart_pdata); - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + imx27_add_fec(NULL); mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data); } diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c index 9c77da98a10e..ffb39a42f240 100644 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ b/arch/arm/mach-imx/mach-mx27ads.c @@ -66,7 +66,7 @@ /* to determine the correct external crystal reference */ #define CKIH_27MHZ_BIT_SET (1 << 3) -static unsigned int mx27ads_pins[] = { +static const int mx27ads_pins[] __initconst = { /* UART0 */ PE12_PF_UART1_TXD, PE13_PF_UART1_RXD, @@ -284,7 +284,6 @@ static struct imxmmc_platform_data sdhc2_pdata = { static struct platform_device *platform_devices[] __initdata = { &mx27ads_nor_mtd_device, - &mxc_fec_device, &mxc_w1_master_device, }; @@ -308,11 +307,12 @@ static void __init mx27ads_board_init(void) /* only the i2c master 1 is used on this CPU card */ i2c_register_board_info(1, mx27ads_i2c_devices, ARRAY_SIZE(mx27ads_i2c_devices)); - imx27_add_i2c_imx1(&mx27ads_i2c1_data); + imx27_add_imx_i2c(1, &mx27ads_i2c1_data); mxc_register_device(&mxc_fb_device, &mx27ads_fb_data); mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata); mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata); + imx27_add_fec(NULL); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); } diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c index a3a1e452d4c5..f4c397dec794 100644 --- a/arch/arm/mach-imx/mach-mxt_td60.c +++ b/arch/arm/mach-imx/mach-mxt_td60.c @@ -37,7 +37,7 @@ #include "devices-imx27.h" #include "devices.h" -static unsigned int mxt_td60_pins[] __initdata = { +static const int mxt_td60_pins[] __initconst = { /* UART0 */ PE12_PF_UART1_TXD, PE13_PF_UART1_RXD, @@ -231,10 +231,6 @@ static struct imxmmc_platform_data sdhc1_pdata = { .exit = mxt_td60_sdhc1_exit, }; -static struct platform_device *platform_devices[] __initdata = { - &mxc_fec_device, -}; - static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -255,12 +251,11 @@ static void __init mxt_td60_board_init(void) i2c_register_board_info(1, mxt_td60_i2c2_devices, ARRAY_SIZE(mxt_td60_i2c2_devices)); - imx27_add_i2c_imx0(&mxt_td60_i2c0_data); - imx27_add_i2c_imx1(&mxt_td60_i2c1_data); + imx27_add_imx_i2c(0, &mxt_td60_i2c0_data); + imx27_add_imx_i2c(1, &mxt_td60_i2c1_data); mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data); mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata); - - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + imx27_add_fec(NULL); } static void __init mxt_td60_timer_init(void) diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index 23c9e1f37b9c..223c31c48db6 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c @@ -38,7 +38,6 @@ #include <mach/iomux-mx27.h> #include <asm/mach/time.h> #include <mach/audmux.h> -#include <mach/ssi.h> #include <mach/mxc_nand.h> #include <mach/irqs.h> #include <mach/mmc.h> @@ -55,7 +54,7 @@ #define SPI1_SS1 (GPIO_PORTD + 27) #define SD2_CD (GPIO_PORTC + 29) -static int pca100_pins[] = { +static const int pca100_pins[] __initconst = { /* UART1 */ PE12_PF_UART1_TXD, PE13_PF_UART1_RXD, @@ -174,7 +173,6 @@ pca100_nand_board_info __initconst = { static struct platform_device *platform_devices[] __initdata = { &mxc_w1_master_device, - &mxc_fec_device, &mxc_wdt, }; @@ -193,11 +191,9 @@ static struct i2c_board_info pca100_i2c_devices[] = { I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ .platform_data = &board_eeprom, }, { - I2C_BOARD_INFO("rtc-pcf8563", 0x51), - .type = "pcf8563" + I2C_BOARD_INFO("pcf8563", 0x51), }, { I2C_BOARD_INFO("lm75", 0x4a), - .type = "lm75" } }; @@ -252,7 +248,7 @@ static void pca100_ac97_cold_reset(struct snd_ac97 *ac97) msleep(2); } -static struct imx_ssi_platform_data pca100_ssi_pdata = { +static const struct imx_ssi_platform_data pca100_ssi_pdata __initconst = { .ac97_reset = pca100_ac97_cold_reset, .ac97_warm_reset = pca100_ac97_warm_reset, .flags = IMX_SSI_USE_AC97, @@ -389,7 +385,7 @@ static void __init pca100_init(void) if (ret) printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret); - mxc_register_device(&imx_ssi_device0, &pca100_ssi_pdata); + imx27_add_imx_ssi(0, &pca100_ssi_pdata); imx27_add_imx_uart0(&uart_pdata); @@ -401,7 +397,7 @@ static void __init pca100_init(void) i2c_register_board_info(1, pca100_i2c_devices, ARRAY_SIZE(pca100_i2c_devices)); - imx27_add_i2c_imx1(&pca100_i2c1_data); + imx27_add_imx_i2c(1, &pca100_i2c1_data); #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_IN); @@ -436,6 +432,7 @@ static void __init pca100_init(void) mxc_register_device(&mxc_fb_device, &pca100_fb_data); + imx27_add_fec(NULL); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); } diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c index 9212e8f37001..b9888a8defc1 100644 --- a/arch/arm/mach-imx/mach-pcm038.c +++ b/arch/arm/mach-imx/mach-pcm038.c @@ -43,7 +43,7 @@ #include "devices-imx27.h" #include "devices.h" -static int pcm038_pins[] = { +static const int pcm038_pins[] __initconst = { /* UART1 */ PE12_PF_UART1_TXD, PE13_PF_UART1_RXD, @@ -173,7 +173,6 @@ pcm038_nand_board_info __initconst = { static struct platform_device *platform_devices[] __initdata = { &pcm038_nor_mtd_device, &mxc_w1_master_device, - &mxc_fec_device, &pcm038_sram_mtd_device, &mxc_wdt, }; @@ -257,7 +256,7 @@ static struct regulator_init_data cam_data = { .consumer_supplies = cam_consumers, }; -struct mc13783_regulator_init_data pcm038_regulators[] = { +static struct mc13783_regulator_init_data pcm038_regulators[] = { { .id = MC13783_REGU_VCAM, .init_data = &cam_data, @@ -309,7 +308,7 @@ static void __init pcm038_init(void) i2c_register_board_info(1, pcm038_i2c_devices, ARRAY_SIZE(pcm038_i2c_devices)); - imx27_add_i2c_imx1(&pcm038_i2c1_data); + imx27_add_imx_i2c(1, &pcm038_i2c1_data); /* PE18 for user-LED D40 */ mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT); @@ -325,6 +324,7 @@ static void __init pcm038_init(void) mxc_register_device(&mxc_usbh2, &usbh2_pdata); + imx27_add_fec(NULL); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); #ifdef CONFIG_MACH_PCM970_BASEBOARD diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c index 88bf0d1e26e6..fb2e5f3d37f6 100644 --- a/arch/arm/mach-imx/mach-scb9328.c +++ b/arch/arm/mach-imx/mach-scb9328.c @@ -95,7 +95,7 @@ static struct platform_device dm9000x_device = { } }; -static int mxc_uart1_pins[] = { +static const int mxc_uart1_pins[] = { PC9_PF_UART1_CTS, PC10_PF_UART1_RTS, PC11_PF_UART1_TXD, diff --git a/arch/arm/mach-imx/pcm970-baseboard.c b/arch/arm/mach-imx/pcm970-baseboard.c index f490a406d57e..9110d9cca7a2 100644 --- a/arch/arm/mach-imx/pcm970-baseboard.c +++ b/arch/arm/mach-imx/pcm970-baseboard.c @@ -31,7 +31,7 @@ #include "devices.h" -static int pcm970_pins[] = { +static const int pcm970_pins[] __initconst = { /* SDHC */ PB4_PF_SD2_D0, PB5_PF_SD2_D1, @@ -200,7 +200,7 @@ static struct resource pcm970_sja1000_resources[] = { }, }; -struct sja1000_platform_data pcm970_sja1000_platform_data = { +static struct sja1000_platform_data pcm970_sja1000_platform_data = { .osc_freq = 16000000, .ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL, .cdr = CDR_CBP, diff --git a/arch/arm/mach-integrator/include/mach/vmalloc.h b/arch/arm/mach-integrator/include/mach/vmalloc.h index e87ab0b37bdd..e056e7cf5645 100644 --- a/arch/arm/mach-integrator/include/mach/vmalloc.h +++ b/arch/arm/mach-integrator/include/mach/vmalloc.h @@ -17,4 +17,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define VMALLOC_END (PAGE_OFFSET + 0x10000000) +#define VMALLOC_END 0xd0000000 diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index cc25501b57fa..34106335c728 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -58,6 +58,12 @@ config MACH_TS41X QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS devices. +config MACH_DOCKSTAR + bool "Seagate FreeAgent DockStar" + help + Say 'Y' here if you want your kernel to support the + Seagate FreeAgent DockStar. + config MACH_OPENRD bool @@ -100,6 +106,12 @@ config MACH_NETSPACE_MAX_V2 Say 'Y' here if you want your kernel to support the LaCie Network Space Max v2 NAS. +config MACH_D2NET_V2 + bool "LaCie d2 Network v2 NAS Board" + help + Say 'Y' here if you want your kernel to support the + LaCie d2 Network v2 NAS. + config MACH_NET2BIG_V2 bool "LaCie 2Big Network v2 NAS Board" help diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 295d7baa6ae1..5dcaa81a2ec3 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -7,14 +7,16 @@ obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o +obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o -obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o -obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o -obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o -obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o -obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o +obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_T5325) += t5325-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c new file mode 100644 index 000000000000..cd62d0f82a73 --- /dev/null +++ b/arch/arm/mach-kirkwood/d2net_v2-setup.c @@ -0,0 +1,231 @@ +/* + * arch/arm/mach-kirkwood/d2net_v2-setup.c + * + * LaCie d2 Network Space v2 Board Setup + * + * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/mv643xx_eth.h> +#include <linux/input.h> +#include <linux/gpio.h> +#include <linux/gpio_keys.h> +#include <linux/leds.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/kirkwood.h> +#include <mach/leds-ns2.h> +#include "common.h" +#include "mpp.h" +#include "lacie_v2-common.h" + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data d2net_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data d2net_v2_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define D2NET_V2_GPIO_PUSH_BUTTON 34 +#define D2NET_V2_GPIO_POWER_SWITCH_ON 13 +#define D2NET_V2_GPIO_POWER_SWITCH_OFF 15 + +#define D2NET_V2_SWITCH_POWER_ON 0x1 +#define D2NET_V2_SWITCH_POWER_OFF 0x2 + +static struct gpio_keys_button d2net_v2_buttons[] = { + [0] = { + .type = EV_SW, + .code = D2NET_V2_SWITCH_POWER_ON, + .gpio = D2NET_V2_GPIO_POWER_SWITCH_ON, + .desc = "Back power switch (on|auto)", + .active_low = 0, + }, + [1] = { + .type = EV_SW, + .code = D2NET_V2_SWITCH_POWER_OFF, + .gpio = D2NET_V2_GPIO_POWER_SWITCH_OFF, + .desc = "Back power switch (auto|off)", + .active_low = 0, + }, + [2] = { + .code = KEY_POWER, + .gpio = D2NET_V2_GPIO_PUSH_BUTTON, + .desc = "Front Push Button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data d2net_v2_button_data = { + .buttons = d2net_v2_buttons, + .nbuttons = ARRAY_SIZE(d2net_v2_buttons), +}; + +static struct platform_device d2net_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &d2net_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +#define D2NET_V2_GPIO_RED_LED 12 + +static struct gpio_led d2net_v2_gpio_led_pins[] = { + { + .name = "d2net_v2:red:fail", + .gpio = D2NET_V2_GPIO_RED_LED, + }, +}; + +static struct gpio_led_platform_data d2net_v2_gpio_leds_data = { + .num_leds = ARRAY_SIZE(d2net_v2_gpio_led_pins), + .leds = d2net_v2_gpio_led_pins, +}; + +static struct platform_device d2net_v2_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &d2net_v2_gpio_leds_data, + }, +}; + +/***************************************************************************** + * Dual-GPIO CPLD LEDs + ****************************************************************************/ + +#define D2NET_V2_GPIO_BLUE_LED_SLOW 29 +#define D2NET_V2_GPIO_BLUE_LED_CMD 30 + +static struct ns2_led d2net_v2_led_pins[] = { + { + .name = "d2net_v2:blue:sata", + .cmd = D2NET_V2_GPIO_BLUE_LED_CMD, + .slow = D2NET_V2_GPIO_BLUE_LED_SLOW, + }, +}; + +static struct ns2_led_platform_data d2net_v2_leds_data = { + .num_leds = ARRAY_SIZE(d2net_v2_led_pins), + .leds = d2net_v2_led_pins, +}; + +static struct platform_device d2net_v2_leds = { + .name = "leds-ns2", + .id = -1, + .dev = { + .platform_data = &d2net_v2_leds_data, + }, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int d2net_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, /* Red led */ + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA 0 power */ + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* Blue led (slow register) */ + MPP30_GPIO, /* Blue led (command register) */ + MPP34_GPIO, /* Power button (1 = Released, 0 = Pushed) */ + MPP35_GPIO, /* Inhibit power-off */ + 0 +}; + +#define D2NET_V2_GPIO_POWER_OFF 7 + +static void d2net_v2_power_off(void) +{ + gpio_set_value(D2NET_V2_GPIO_POWER_OFF, 1); +} + +static void __init d2net_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(d2net_v2_mpp_config); + + lacie_v2_hdd_power_init(1); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&d2net_v2_ge00_data); + kirkwood_sata_init(&d2net_v2_sata_data); + kirkwood_uart0_init(); + lacie_v2_register_flash(); + lacie_v2_register_i2c_devices(); + + platform_device_register(&d2net_v2_leds); + platform_device_register(&d2net_v2_gpio_leds); + platform_device_register(&d2net_v2_gpio_buttons); + + if (gpio_request(D2NET_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(D2NET_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = d2net_v2_power_off; + else + pr_err("d2net_v2: failed to configure power-off GPIO\n"); +} + +MACHINE_START(D2NET_V2, "LaCie d2 Network v2") + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = d2net_v2_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &lacie_v2_timer, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/dockstar-setup.c b/arch/arm/mach-kirkwood/dockstar-setup.c new file mode 100644 index 000000000000..a90475d5059c --- /dev/null +++ b/arch/arm/mach-kirkwood/dockstar-setup.c @@ -0,0 +1,112 @@ +/* + * arch/arm/mach-kirkwood/dockstar-setup.c + * + * Seagate FreeAgent DockStar Setup + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/ata_platform.h> +#include <linux/mtd/partitions.h> +#include <linux/mv643xx_eth.h> +#include <linux/gpio.h> +#include <linux/leds.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/kirkwood.h> +#include <plat/mvsdio.h> +#include "common.h" +#include "mpp.h" + +static struct mtd_partition dockstar_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data dockstar_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct gpio_led dockstar_led_pins[] = { + { + .name = "dockstar:green:health", + .default_trigger = "default-on", + .gpio = 46, + .active_low = 1, + }, + { + .name = "dockstar:orange:misc", + .default_trigger = "none", + .gpio = 47, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data dockstar_led_data = { + .leds = dockstar_led_pins, + .num_leds = ARRAY_SIZE(dockstar_led_pins), +}; + +static struct platform_device dockstar_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &dockstar_led_data, + } +}; + +static unsigned int dockstar_mpp_config[] __initdata = { + MPP29_GPIO, /* USB Power Enable */ + MPP46_GPIO, /* LED green */ + MPP47_GPIO, /* LED orange */ + 0 +}; + +static void __init dockstar_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + /* setup gpio pin select */ + kirkwood_mpp_conf(dockstar_mpp_config); + + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(dockstar_nand_parts), 25); + + if (gpio_request(29, "USB Power Enable") != 0 || + gpio_direction_output(29, 1) != 0) + printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n"); + kirkwood_ehci_init(); + + kirkwood_ge00_init(&dockstar_ge00_data); + + platform_device_register(&dockstar_leds); +} + +MACHINE_START(DOCKSTAR, "Seagate FreeAgent DockStar") + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = dockstar_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &kirkwood_timer, +MACHINE_END diff --git a/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h b/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h new file mode 100644 index 000000000000..24b536ebdf13 --- /dev/null +++ b/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h @@ -0,0 +1,55 @@ +/* + * arch/arm/mach-kirkwood/include/mach/leds-netxbig.h + * + * Platform data structure for netxbig LED driver + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __MACH_LEDS_NETXBIG_H +#define __MACH_LEDS_NETXBIG_H + +struct netxbig_gpio_ext { + unsigned *addr; + int num_addr; + unsigned *data; + int num_data; + unsigned enable; +}; + +enum netxbig_led_mode { + NETXBIG_LED_OFF, + NETXBIG_LED_ON, + NETXBIG_LED_SATA, + NETXBIG_LED_TIMER1, + NETXBIG_LED_TIMER2, + NETXBIG_LED_MODE_NUM, +}; + +#define NETXBIG_LED_INVALID_MODE NETXBIG_LED_MODE_NUM + +struct netxbig_led_timer { + unsigned long delay_on; + unsigned long delay_off; + enum netxbig_led_mode mode; +}; + +struct netxbig_led { + const char *name; + const char *default_trigger; + int mode_addr; + int *mode_val; + int bright_addr; +}; + +struct netxbig_led_platform_data { + struct netxbig_gpio_ext *gpio_ext; + struct netxbig_led_timer *timer; + int num_timer; + struct netxbig_led *leds; + int num_leds; +}; + +#endif /* __MACH_LEDS_NETXBIG_H */ diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c new file mode 100644 index 000000000000..d3ea1b6c8a02 --- /dev/null +++ b/arch/arm/mach-kirkwood/lacie_v2-common.c @@ -0,0 +1,127 @@ +/* + * arch/arm/mach-kirkwood/lacie_v2-common.c + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mtd/physmap.h> +#include <linux/spi/flash.h> +#include <linux/spi/spi.h> +#include <linux/i2c.h> +#include <linux/i2c/at24.h> +#include <linux/gpio.h> +#include <asm/mach/time.h> +#include <mach/kirkwood.h> +#include <mach/irqs.h> +#include <plat/time.h> +#include "common.h" + +/***************************************************************************** + * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) + ****************************************************************************/ + +static struct mtd_partition lacie_v2_flash_parts[] = { + { + .name = "u-boot", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static const struct flash_platform_data lacie_v2_flash = { + .type = "mx25l4005a", + .name = "spi_flash", + .parts = lacie_v2_flash_parts, + .nr_parts = ARRAY_SIZE(lacie_v2_flash_parts), +}; + +static struct spi_board_info __initdata lacie_v2_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &lacie_v2_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +void __init lacie_v2_register_flash(void) +{ + spi_register_board_info(lacie_v2_spi_slave_info, + ARRAY_SIZE(lacie_v2_spi_slave_info)); + kirkwood_spi_init(); +} + +/***************************************************************************** + * I2C devices + ****************************************************************************/ + +static struct at24_platform_data at24c04 = { + .byte_len = SZ_4K / 8, + .page_size = 16, +}; + +/* + * i2c addr | chip | description + * 0x50 | HT24LC04 | eeprom (512B) + */ + +static struct i2c_board_info __initdata lacie_v2_i2c_info[] = { + { + I2C_BOARD_INFO("24c04", 0x50), + .platform_data = &at24c04, + } +}; + +void __init lacie_v2_register_i2c_devices(void) +{ + kirkwood_i2c_init(); + i2c_register_board_info(0, lacie_v2_i2c_info, + ARRAY_SIZE(lacie_v2_i2c_info)); +} + +/***************************************************************************** + * Hard Disk power + ****************************************************************************/ + +static int __initdata lacie_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 }; + +void __init lacie_v2_hdd_power_init(int hdd_num) +{ + int i; + int err; + + /* Power up all hard disks. */ + for (i = 0; i < hdd_num; i++) { + err = gpio_request(lacie_v2_gpio_hdd_power[i], NULL); + if (err == 0) { + err = gpio_direction_output( + lacie_v2_gpio_hdd_power[i], 1); + /* Free the HDD power GPIOs. This allow user-space to + * configure them via the gpiolib sysfs interface. */ + gpio_free(lacie_v2_gpio_hdd_power[i]); + } + if (err) + pr_err("Failed to power up HDD%d\n", i + 1); + } +} + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static void lacie_v2_timer_init(void) +{ + kirkwood_tclk = 166666667; + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +struct sys_timer lacie_v2_timer = { + .init = lacie_v2_timer_init, +}; diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.h b/arch/arm/mach-kirkwood/lacie_v2-common.h new file mode 100644 index 000000000000..af521315b87b --- /dev/null +++ b/arch/arm/mach-kirkwood/lacie_v2-common.h @@ -0,0 +1,18 @@ +/* + * arch/arm/mach-kirkwood/lacie_v2-common.h + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ARCH_KIRKWOOD_LACIE_V2_COMMON_H +#define __ARCH_KIRKWOOD_LACIE_V2_COMMON_H + +void lacie_v2_register_flash(void); +void lacie_v2_register_i2c_devices(void); +void lacie_v2_hdd_power_init(int hdd_num); + +extern struct sys_timer lacie_v2_timer; + +#endif diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c index d26bf324738b..fed264d28f4a 100644 --- a/arch/arm/mach-kirkwood/netspace_v2-setup.c +++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c @@ -24,56 +24,19 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/spi/flash.h> -#include <linux/spi/spi.h> #include <linux/ata_platform.h> #include <linux/mv643xx_eth.h> -#include <linux/i2c.h> -#include <linux/i2c/at24.h> #include <linux/input.h> #include <linux/gpio.h> #include <linux/gpio_keys.h> #include <linux/leds.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/time.h> #include <mach/kirkwood.h> #include <mach/leds-ns2.h> -#include <plat/time.h> #include "common.h" #include "mpp.h" - -/***************************************************************************** - * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) - ****************************************************************************/ - -static struct mtd_partition netspace_v2_flash_parts[] = { - { - .name = "u-boot", - .size = MTDPART_SIZ_FULL, - .offset = 0, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, -}; - -static const struct flash_platform_data netspace_v2_flash = { - .type = "mx25l4005a", - .name = "spi_flash", - .parts = netspace_v2_flash_parts, - .nr_parts = ARRAY_SIZE(netspace_v2_flash_parts), -}; - -static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = { - { - .modalias = "m25p80", - .platform_data = &netspace_v2_flash, - .irq = -1, - .max_speed_hz = 20000000, - .bus_num = 0, - .chip_select = 0, - }, -}; +#include "lacie_v2-common.h" /***************************************************************************** * Ethernet @@ -84,27 +47,6 @@ static struct mv643xx_eth_platform_data netspace_v2_ge00_data = { }; /***************************************************************************** - * I2C devices - ****************************************************************************/ - -static struct at24_platform_data at24c04 = { - .byte_len = SZ_4K / 8, - .page_size = 16, -}; - -/* - * i2c addr | chip | description - * 0x50 | HT24LC04 | eeprom (512B) - */ - -static struct i2c_board_info __initdata netspace_v2_i2c_info[] = { - { - I2C_BOARD_INFO("24c04", 0x50), - .platform_data = &at24c04, - } -}; - -/***************************************************************************** * SATA ****************************************************************************/ @@ -112,35 +54,6 @@ static struct mv_sata_platform_data netspace_v2_sata_data = { .n_ports = 2, }; -#define NETSPACE_V2_GPIO_SATA0_POWER 16 -#define NETSPACE_V2_GPIO_SATA1_POWER 17 - -static void __init netspace_v2_sata_power_init(void) -{ - int err; - - err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power"); - if (err == 0) { - err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1); - if (err) - gpio_free(NETSPACE_V2_GPIO_SATA0_POWER); - } - if (err) - pr_err("netspace_v2: failed to setup SATA0 power\n"); - - if (machine_is_netspace_max_v2()) { - err = gpio_request(NETSPACE_V2_GPIO_SATA1_POWER, "SATA1 power"); - if (err == 0) { - err = gpio_direction_output( - NETSPACE_V2_GPIO_SATA1_POWER, 1); - if (err) - gpio_free(NETSPACE_V2_GPIO_SATA1_POWER); - } - if (err) - pr_err("netspace_v2: failed to setup SATA1 power\n"); - } -} - /***************************************************************************** * GPIO keys ****************************************************************************/ @@ -224,20 +137,6 @@ static struct platform_device netspace_v2_leds = { }; /***************************************************************************** - * Timer - ****************************************************************************/ - -static void netspace_v2_timer_init(void) -{ - kirkwood_tclk = 166666667; - orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); -} - -struct sys_timer netspace_v2_timer = { - .init = netspace_v2_timer_init, -}; - -/***************************************************************************** * General Setup ****************************************************************************/ @@ -291,18 +190,17 @@ static void __init netspace_v2_init(void) kirkwood_init(); kirkwood_mpp_conf(netspace_v2_mpp_config); - netspace_v2_sata_power_init(); + if (machine_is_netspace_max_v2()) + lacie_v2_hdd_power_init(2); + else + lacie_v2_hdd_power_init(1); kirkwood_ehci_init(); kirkwood_ge00_init(&netspace_v2_ge00_data); kirkwood_sata_init(&netspace_v2_sata_data); kirkwood_uart0_init(); - spi_register_board_info(netspace_v2_spi_slave_info, - ARRAY_SIZE(netspace_v2_spi_slave_info)); - kirkwood_spi_init(); - kirkwood_i2c_init(); - i2c_register_board_info(0, netspace_v2_i2c_info, - ARRAY_SIZE(netspace_v2_i2c_info)); + lacie_v2_register_flash(); + lacie_v2_register_i2c_devices(); platform_device_register(&netspace_v2_leds); platform_device_register(&netspace_v2_gpio_leds); @@ -323,7 +221,7 @@ MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &netspace_v2_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -335,7 +233,7 @@ MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &netspace_v2_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -347,6 +245,6 @@ MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2") .init_machine = netspace_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &netspace_v2_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c index 2bd14c5079de..d970e1eee37d 100644 --- a/arch/arm/mach-kirkwood/netxbig_v2-setup.c +++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c @@ -23,55 +23,19 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/mtd/physmap.h> -#include <linux/spi/flash.h> -#include <linux/spi/spi.h> #include <linux/ata_platform.h> #include <linux/mv643xx_eth.h> -#include <linux/i2c.h> -#include <linux/i2c/at24.h> #include <linux/input.h> #include <linux/gpio.h> #include <linux/gpio_keys.h> #include <linux/leds.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <asm/mach/time.h> #include <mach/kirkwood.h> -#include <plat/time.h> +#include <mach/leds-netxbig.h> #include "common.h" #include "mpp.h" - -/***************************************************************************** - * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) - ****************************************************************************/ - -static struct mtd_partition netxbig_v2_flash_parts[] = { - { - .name = "u-boot", - .size = MTDPART_SIZ_FULL, - .offset = 0, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, -}; - -static const struct flash_platform_data netxbig_v2_flash = { - .type = "mx25l4005a", - .name = "spi_flash", - .parts = netxbig_v2_flash_parts, - .nr_parts = ARRAY_SIZE(netxbig_v2_flash_parts), -}; - -static struct spi_board_info __initdata netxbig_v2_spi_slave_info[] = { - { - .modalias = "m25p80", - .platform_data = &netxbig_v2_flash, - .irq = -1, - .max_speed_hz = 20000000, - .bus_num = 0, - .chip_select = 0, - }, -}; +#include "lacie_v2-common.h" /***************************************************************************** * Ethernet @@ -86,27 +50,6 @@ static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = { }; /***************************************************************************** - * I2C devices - ****************************************************************************/ - -static struct at24_platform_data at24c04 = { - .byte_len = SZ_4K / 8, - .page_size = 16, -}; - -/* - * i2c addr | chip | description - * 0x50 | HT24LC04 | eeprom (512B) - */ - -static struct i2c_board_info __initdata netxbig_v2_i2c_info[] = { - { - I2C_BOARD_INFO("24c04", 0x50), - .platform_data = &at24c04, - } -}; - -/***************************************************************************** * SATA ****************************************************************************/ @@ -114,34 +57,6 @@ static struct mv_sata_platform_data netxbig_v2_sata_data = { .n_ports = 2, }; -static int __initdata netxbig_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 }; - -static void __init netxbig_v2_sata_power_init(void) -{ - int i; - int err; - int hdd_nb; - - if (machine_is_net2big_v2()) - hdd_nb = 2; - else - hdd_nb = 5; - - /* Power up all hard disks. */ - for (i = 0; i < hdd_nb; i++) { - err = gpio_request(netxbig_v2_gpio_hdd_power[i], NULL); - if (err == 0) { - err = gpio_direction_output( - netxbig_v2_gpio_hdd_power[i], 1); - /* Free the HDD power GPIOs. This allow user-space to - * configure them via the gpiolib sysfs interface. */ - gpio_free(netxbig_v2_gpio_hdd_power[i]); - } - if (err) - pr_err("netxbig_v2: failed to power up HDD%d\n", i + 1); - } -} - /***************************************************************************** * GPIO keys ****************************************************************************/ @@ -190,7 +105,7 @@ static struct platform_device netxbig_v2_gpio_buttons = { }; /***************************************************************************** - * GPIO LEDs + * GPIO extension LEDs ****************************************************************************/ /* @@ -200,19 +115,32 @@ static struct platform_device netxbig_v2_gpio_buttons = { * - address register : bit [0-2] -> GPIO [47-49] * - data register : bit [0-2] -> GPIO [44-46] * - enable register : GPIO 29 - * + */ + +static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 }; +static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 }; + +static struct netxbig_gpio_ext netxbig_v2_gpio_ext = { + .addr = netxbig_v2_gpio_ext_addr, + .num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr), + .data = netxbig_v2_gpio_ext_data, + .num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data), + .enable = 29, +}; + +/* * Address register selection: * * addr | register * ---------------------------- * 0 | front LED * 1 | front LED brightness - * 2 | HDD LED brightness - * 3 | HDD1 LED - * 4 | HDD2 LED - * 5 | HDD3 LED - * 6 | HDD4 LED - * 7 | HDD5 LED + * 2 | SATA LED brightness + * 3 | SATA0 LED + * 4 | SATA1 LED + * 5 | SATA2 LED + * 6 | SATA3 LED + * 7 | SATA4 LED * * Data register configuration: * @@ -233,30 +161,107 @@ static struct platform_device netxbig_v2_gpio_buttons = { * 6 | blink blue on=1 sec and red on=1 sec * 7 | blink blue on=0.5 sec and blue off=2.5 sec * - * data | HDD LED mode + * data | SATA LED mode * ------------------------------------------------- - * 0 | fix blue on + * 0 | fix off * 1 | SATA activity blink * 2 | fix red on * 3 | blink blue on=1 sec and blue off=1 sec * 4 | blink red on=1 sec and red off=1 sec * 5 | blink blue on=2.5 sec and red on=0.5 sec * 6 | blink blue on=1 sec and red on=1 sec - * 7 | blink blue on=0.5 sec and blue off=2.5 sec + * 7 | fix blue on */ -/***************************************************************************** - * Timer - ****************************************************************************/ +static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 2, + [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE, + [NETXBIG_LED_TIMER1] = 4, + [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE, +}; -static void netxbig_v2_timer_init(void) -{ - kirkwood_tclk = 166666667; - orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); -} +static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 1, + [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE, + [NETXBIG_LED_TIMER1] = 3, + [NETXBIG_LED_TIMER2] = 7, +}; + +static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 7, + [NETXBIG_LED_SATA] = 1, + [NETXBIG_LED_TIMER1] = 3, + [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE, +}; + +static struct netxbig_led_timer netxbig_v2_led_timer[] = { + [0] = { + .delay_on = 500, + .delay_off = 500, + .mode = NETXBIG_LED_TIMER1, + }, + [1] = { + .delay_on = 500, + .delay_off = 1000, + .mode = NETXBIG_LED_TIMER2, + }, +}; + +#define NETXBIG_LED(_name, maddr, mval, baddr) \ + { .name = _name, \ + .mode_addr = maddr, \ + .mode_val = mval, \ + .bright_addr = baddr } + +static struct netxbig_led net2big_v2_leds_ctrl[] = { + NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1), + NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1), + NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2), + NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2), +}; + +static struct netxbig_led_platform_data net2big_v2_leds_data = { + .gpio_ext = &netxbig_v2_gpio_ext, + .timer = netxbig_v2_led_timer, + .num_timer = ARRAY_SIZE(netxbig_v2_led_timer), + .leds = net2big_v2_leds_ctrl, + .num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl), +}; + +static struct netxbig_led net5big_v2_leds_ctrl[] = { + NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1), + NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1), + NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata5", 7, netxbig_v2_red_mled, 2), +}; -struct sys_timer netxbig_v2_timer = { - .init = netxbig_v2_timer_init, +static struct netxbig_led_platform_data net5big_v2_leds_data = { + .gpio_ext = &netxbig_v2_gpio_ext, + .timer = netxbig_v2_led_timer, + .num_timer = ARRAY_SIZE(netxbig_v2_led_timer), + .leds = net5big_v2_leds_ctrl, + .num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl), +}; + +static struct platform_device netxbig_v2_leds = { + .name = "leds-netxbig", + .id = -1, + .dev = { + .platform_data = &net2big_v2_leds_data, + }, }; /***************************************************************************** @@ -284,18 +289,18 @@ static unsigned int net2big_v2_mpp_config[] __initdata = { MPP24_GPIO, /* USB mode select */ MPP26_GPIO, /* USB device vbus */ MPP28_GPIO, /* USB enable host vbus */ - MPP29_GPIO, /* CPLD extension ALE */ + MPP29_GPIO, /* GPIO extension ALE */ MPP34_GPIO, /* Rear Push button */ MPP35_GPIO, /* Inhibit switch power-off */ MPP36_GPIO, /* SATA HDD1 presence */ MPP37_GPIO, /* SATA HDD2 presence */ MPP40_GPIO, /* eSATA presence */ - MPP44_GPIO, /* CPLD extension (data 0) */ - MPP45_GPIO, /* CPLD extension (data 1) */ - MPP46_GPIO, /* CPLD extension (data 2) */ - MPP47_GPIO, /* CPLD extension (addr 0) */ - MPP48_GPIO, /* CPLD extension (addr 1) */ - MPP49_GPIO, /* CPLD extension (addr 2) */ + MPP44_GPIO, /* GPIO extension (data 0) */ + MPP45_GPIO, /* GPIO extension (data 1) */ + MPP46_GPIO, /* GPIO extension (data 2) */ + MPP47_GPIO, /* GPIO extension (addr 0) */ + MPP48_GPIO, /* GPIO extension (addr 1) */ + MPP49_GPIO, /* GPIO extension (addr 2) */ 0 }; @@ -324,7 +329,7 @@ static unsigned int net5big_v2_mpp_config[] __initdata = { MPP26_GE1_RXD2, MPP27_GE1_RXD3, MPP28_GPIO, /* USB enable host vbus */ - MPP29_GPIO, /* CPLD extension ALE */ + MPP29_GPIO, /* GPIO extension ALE */ MPP30_GE1_RXCTL, MPP31_GE1_RXCLK, MPP32_GE1_TCLKOUT, @@ -339,12 +344,12 @@ static unsigned int net5big_v2_mpp_config[] __initdata = { MPP41_GPIO, /* SATA HDD3 power */ MPP42_GPIO, /* SATA HDD4 power */ MPP43_GPIO, /* SATA HDD5 power */ - MPP44_GPIO, /* CPLD extension (data 0) */ - MPP45_GPIO, /* CPLD extension (data 1) */ - MPP46_GPIO, /* CPLD extension (data 2) */ - MPP47_GPIO, /* CPLD extension (addr 0) */ - MPP48_GPIO, /* CPLD extension (addr 1) */ - MPP49_GPIO, /* CPLD extension (addr 2) */ + MPP44_GPIO, /* GPIO extension (data 0) */ + MPP45_GPIO, /* GPIO extension (data 1) */ + MPP46_GPIO, /* GPIO extension (data 2) */ + MPP47_GPIO, /* GPIO extension (addr 0) */ + MPP48_GPIO, /* GPIO extension (addr 1) */ + MPP49_GPIO, /* GPIO extension (addr 2) */ 0 }; @@ -366,7 +371,10 @@ static void __init netxbig_v2_init(void) else kirkwood_mpp_conf(net5big_v2_mpp_config); - netxbig_v2_sata_power_init(); + if (machine_is_net2big_v2()) + lacie_v2_hdd_power_init(2); + else + lacie_v2_hdd_power_init(5); kirkwood_ehci_init(); kirkwood_ge00_init(&netxbig_v2_ge00_data); @@ -374,13 +382,12 @@ static void __init netxbig_v2_init(void) kirkwood_ge01_init(&netxbig_v2_ge01_data); kirkwood_sata_init(&netxbig_v2_sata_data); kirkwood_uart0_init(); - spi_register_board_info(netxbig_v2_spi_slave_info, - ARRAY_SIZE(netxbig_v2_spi_slave_info)); - kirkwood_spi_init(); - kirkwood_i2c_init(); - i2c_register_board_info(0, netxbig_v2_i2c_info, - ARRAY_SIZE(netxbig_v2_i2c_info)); + lacie_v2_register_flash(); + lacie_v2_register_i2c_devices(); + if (machine_is_net5big_v2()) + netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data; + platform_device_register(&netxbig_v2_leds); platform_device_register(&netxbig_v2_gpio_buttons); if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 && @@ -398,7 +405,7 @@ MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") .init_machine = netxbig_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &netxbig_v2_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif @@ -410,6 +417,6 @@ MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") .init_machine = netxbig_v2_init, .map_io = kirkwood_map_io, .init_irq = kirkwood_init_irq, - .timer = &netxbig_v2_timer, + .timer = &lacie_v2_timer, MACHINE_END #endif diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c index fd06be618815..38017c8ac43f 100644 --- a/arch/arm/mach-kirkwood/openrd-setup.c +++ b/arch/arm/mach-kirkwood/openrd-setup.c @@ -16,6 +16,7 @@ #include <linux/ata_platform.h> #include <linux/mv643xx_eth.h> #include <linux/i2c.h> +#include <linux/gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/kirkwood.h> @@ -57,7 +58,22 @@ static struct mvsdio_platform_data openrd_mvsdio_data = { }; static unsigned int openrd_mpp_config[] __initdata = { + MPP12_SD_CLK, + MPP13_SD_CMD, + MPP14_SD_D0, + MPP15_SD_D1, + MPP16_SD_D2, + MPP17_SD_D3, + MPP28_GPIO, MPP29_GPIO, + MPP34_GPIO, + 0 +}; + +/* Configure MPP for UART1 */ +static unsigned int openrd_uart1_mpp_config[] __initdata = { + MPP13_UART1_TXD, + MPP14_UART1_RXD, 0 }; @@ -67,6 +83,68 @@ static struct i2c_board_info i2c_board_info[] __initdata = { }, }; +static int __initdata uart1; + +static int __init sd_uart_selection(char *str) +{ + uart1 = -EINVAL; + + /* Default is SD. Change if required, for UART */ + if (!str) + return 0; + + if (!strncmp(str, "232", 3)) { + uart1 = 232; + } else if (!strncmp(str, "485", 3)) { + /* OpenRD-Base doesn't have RS485. Treat is as an + * unknown argument & just have default setting - + * which is SD */ + if (machine_is_openrd_base()) { + uart1 = -ENODEV; + return 1; + } + + uart1 = 485; + } + return 1; +} +/* Parse boot_command_line string kw_openrd_init_uart1=232/485 */ +__setup("kw_openrd_init_uart1=", sd_uart_selection); + +static int __init uart1_mpp_config(void) +{ + kirkwood_mpp_conf(openrd_uart1_mpp_config); + + if (gpio_request(34, "SD_UART1_SEL")) { + printk(KERN_ERR "GPIO request failed for SD/UART1 selection" + ", gpio: 34\n"); + return -EIO; + } + + if (gpio_request(28, "RS232_RS485_SEL")) { + printk(KERN_ERR "GPIO request failed for RS232/RS485 selection" + ", gpio# 28\n"); + gpio_free(34); + return -EIO; + } + + /* Select UART1 + * Pin # 34: 0 => UART1, 1 => SD */ + gpio_direction_output(34, 0); + + /* Select RS232 OR RS485 + * Pin # 28: 0 => RS232, 1 => RS485 */ + if (uart1 == 232) + gpio_direction_output(28, 0); + else + gpio_direction_output(28, 1); + + gpio_free(34); + gpio_free(28); + + return 0; +} + static void __init openrd_init(void) { /* @@ -90,7 +168,6 @@ static void __init openrd_init(void) kirkwood_ge01_init(&openrd_ge01_data); kirkwood_sata_init(&openrd_sata_data); - kirkwood_sdio_init(&openrd_mvsdio_data); kirkwood_i2c_init(); @@ -99,6 +176,28 @@ static void __init openrd_init(void) ARRAY_SIZE(i2c_board_info)); kirkwood_audio_init(); } + + if (uart1 <= 0) { + if (uart1 < 0) + printk(KERN_ERR "Invalid kernel parameter to select " + "UART1. Defaulting to SD. ERROR CODE: %d\n", + uart1); + + /* Select SD + * Pin # 34: 0 => UART1, 1 => SD */ + if (gpio_request(34, "SD_UART1_SEL")) { + printk(KERN_ERR "GPIO request failed for SD/UART1 " + "selection, gpio: 34\n"); + } else { + + gpio_direction_output(34, 1); + gpio_free(34); + kirkwood_sdio_init(&openrd_mvsdio_data); + } + } else { + if (!uart1_mpp_config()) + kirkwood_uart1_init(); + } } static int __init openrd_pci_init(void) diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 6ab843eaa35b..0711d3b620ad 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -57,6 +57,13 @@ config MACH_MARVELL_JASPER PXA910-based development board. Since MMP2 is compatible to ARMv6 architecture. +config MACH_TETON_BGA + bool "Marvell's PXA168 Teton BGA Development Board" + select CPU_PXA168 + help + Say 'Y' here if you want to support the Marvell PXA168-based + Teton BGA Development Board. + endmenu config CPU_PXA168 diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 8b66d06739c4..751cdbf733c8 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o obj-$(CONFIG_MACH_FLINT) += flint.o obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o +obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index 0629394a5fb9..4681bedbe788 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -16,6 +16,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/nand.h> +#include <linux/interrupt.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -23,6 +24,9 @@ #include <mach/mfp-pxa168.h> #include <mach/pxa168.h> #include <mach/gpio.h> +#include <video/pxa168fb.h> +#include <linux/input.h> +#include <plat/pxa27x_keypad.h> #include "common.h" @@ -66,6 +70,43 @@ static unsigned long common_pin_config[] __initdata = { GPIO115_I2S_BCLK, GPIO116_I2S_RXD, GPIO117_I2S_TXD, + + /* LCD */ + GPIO56_LCD_FCLK_RD, + GPIO57_LCD_LCLK_A0, + GPIO58_LCD_PCLK_WR, + GPIO59_LCD_DENA_BIAS, + GPIO60_LCD_DD0, + GPIO61_LCD_DD1, + GPIO62_LCD_DD2, + GPIO63_LCD_DD3, + GPIO64_LCD_DD4, + GPIO65_LCD_DD5, + GPIO66_LCD_DD6, + GPIO67_LCD_DD7, + GPIO68_LCD_DD8, + GPIO69_LCD_DD9, + GPIO70_LCD_DD10, + GPIO71_LCD_DD11, + GPIO72_LCD_DD12, + GPIO73_LCD_DD13, + GPIO74_LCD_DD14, + GPIO75_LCD_DD15, + GPIO76_LCD_DD16, + GPIO77_LCD_DD17, + GPIO78_LCD_DD18, + GPIO79_LCD_DD19, + GPIO80_LCD_DD20, + GPIO81_LCD_DD21, + GPIO82_LCD_DD22, + GPIO83_LCD_DD23, + + /* Keypad */ + GPIO109_KP_MKIN1, + GPIO110_KP_MKIN0, + GPIO111_KP_MKOUT7, + GPIO112_KP_MKOUT6, + GPIO121_KP_MKIN4, }; static struct smc91x_platdata smc91x_info = { @@ -134,6 +175,51 @@ static struct i2c_board_info aspenite_i2c_info[] __initdata = { { I2C_BOARD_INFO("wm8753", 0x1b), }, }; +static struct fb_videomode video_modes[] = { + [0] = { + .pixclock = 30120, + .refresh = 60, + .xres = 800, + .yres = 480, + .hsync_len = 1, + .left_margin = 215, + .right_margin = 40, + .vsync_len = 1, + .upper_margin = 34, + .lower_margin = 10, + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, + }, +}; + +struct pxa168fb_mach_info aspenite_lcd_info = { + .id = "Graphic Frame", + .modes = video_modes, + .num_modes = ARRAY_SIZE(video_modes), + .pix_fmt = PIX_FMT_RGB565, + .io_pin_allocation_mode = PIN_MODE_DUMB_24, + .dumb_mode = DUMB_MODE_RGB888, + .active = 1, + .panel_rbswap = 0, + .invert_pixclock = 0, +}; + +static unsigned int aspenite_matrix_key_map[] = { + KEY(0, 6, KEY_UP), /* SW 4 */ + KEY(0, 7, KEY_DOWN), /* SW 5 */ + KEY(1, 6, KEY_LEFT), /* SW 6 */ + KEY(1, 7, KEY_RIGHT), /* SW 7 */ + KEY(4, 6, KEY_ENTER), /* SW 8 */ + KEY(4, 7, KEY_ESC), /* SW 9 */ +}; + +static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = { + .matrix_key_rows = 5, + .matrix_key_cols = 8, + .matrix_key_map = aspenite_matrix_key_map, + .matrix_key_map_size = ARRAY_SIZE(aspenite_matrix_key_map), + .debounce_interval = 30, +}; + static void __init common_init(void) { mfp_config(ARRAY_AND_SIZE(common_pin_config)); @@ -143,6 +229,8 @@ static void __init common_init(void) pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info)); pxa168_add_ssp(1); pxa168_add_nand(&aspenite_nand_info); + pxa168_add_fb(&aspenite_lcd_info); + pxa168_add_keypad(&aspenite_keypad_info); /* off-chip devices */ platform_device_register(&smc91x_device); @@ -152,6 +240,7 @@ MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform") .phys_io = APB_PHYS_BASE, .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, .map_io = mmp_map_io, + .nr_irqs = IRQ_BOARD_START, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = common_init, @@ -161,6 +250,7 @@ MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform") .phys_io = APB_PHYS_BASE, .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, .map_io = mmp_map_io, + .nr_irqs = IRQ_BOARD_START, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = common_init, diff --git a/arch/arm/mach-mmp/common.c b/arch/arm/mach-mmp/common.c index 3b29fa7e9b08..0ec0ca80bb3e 100644 --- a/arch/arm/mach-mmp/common.c +++ b/arch/arm/mach-mmp/common.c @@ -10,13 +10,20 @@ #include <linux/init.h> #include <linux/kernel.h> +#include <linux/module.h> #include <asm/page.h> #include <asm/mach/map.h> #include <mach/addr-map.h> +#include <mach/cputype.h> #include "common.h" +#define MMP_CHIPID (AXI_VIRT_BASE + 0x82c00) + +unsigned int mmp_chip_id; +EXPORT_SYMBOL(mmp_chip_id); + static struct map_desc standard_io_desc[] __initdata = { { .pfn = __phys_to_pfn(APB_PHYS_BASE), @@ -34,4 +41,7 @@ static struct map_desc standard_io_desc[] __initdata = { void __init mmp_map_io(void) { iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); + + /* this is early, initialize mmp_chip_id here */ + mmp_chip_id = __raw_readl(MMP_CHIPID); } diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c index e4312d238eae..c558425c3613 100644 --- a/arch/arm/mach-mmp/flint.c +++ b/arch/arm/mach-mmp/flint.c @@ -16,6 +16,7 @@ #include <linux/smc91x.h> #include <linux/io.h> #include <linux/gpio.h> +#include <linux/interrupt.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -25,6 +26,8 @@ #include "common.h" +#define FLINT_NR_IRQS (IRQ_BOARD_START + 48) + static unsigned long flint_pin_config[] __initdata = { /* UART1 */ GPIO45_UART1_RXD, @@ -116,6 +119,7 @@ MACHINE_START(FLINT, "Flint Development Platform") .phys_io = APB_PHYS_BASE, .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, .map_io = mmp_map_io, + .nr_irqs = FLINT_NR_IRQS, .init_irq = mmp2_init_irq, .timer = &mmp2_timer, .init_machine = flint_init, diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h index 83b18721d933..f43a68b213f1 100644 --- a/arch/arm/mach-mmp/include/mach/cputype.h +++ b/arch/arm/mach-mmp/include/mach/cputype.h @@ -4,36 +4,51 @@ #include <asm/cputype.h> /* - * CPU Stepping OLD_ID CPU_ID CHIP_ID + * CPU Stepping CPU_ID CHIP_ID * - * PXA168 A0 0x41159263 0x56158400 0x00A0A333 - * PXA910 Y0 0x41159262 0x56158000 0x00F0C910 - * MMP2 Z0 0x560f5811 + * PXA168 S0 0x56158400 0x0000C910 + * PXA168 A0 0x56158400 0x00A0A168 + * PXA910 Y1 0x56158400 0x00F2C920 + * PXA910 A0 0x56158400 0x00F2C910 + * PXA910 A1 0x56158400 0x00A0C910 + * PXA920 Y0 0x56158400 0x00F2C920 + * PXA920 A0 0x56158400 0x00A0C920 + * PXA920 A1 0x56158400 0x00A1C920 + * MMP2 Z0 0x560f5811 0x00F00410 + * MMP2 Z1 0x560f5811 0x00E00410 + * MMP2 A0 0x560f5811 0x00A0A610 */ +extern unsigned int mmp_chip_id; + #ifdef CONFIG_CPU_PXA168 -# define __cpu_is_pxa168(id) \ - ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x84; }) +static inline int cpu_is_pxa168(void) +{ + return (((read_cpuid_id() >> 8) & 0xff) == 0x84) && + ((mmp_chip_id & 0xfff) == 0x168); +} #else -# define __cpu_is_pxa168(id) (0) +#define cpu_is_pxa168() (0) #endif +/* cpu_is_pxa910() is shared on both pxa910 and pxa920 */ #ifdef CONFIG_CPU_PXA910 -# define __cpu_is_pxa910(id) \ - ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x80; }) +static inline int cpu_is_pxa910(void) +{ + return (((read_cpuid_id() >> 8) & 0xff) == 0x84) && + (((mmp_chip_id & 0xfff) == 0x910) || + ((mmp_chip_id & 0xfff) == 0x920)); +} #else -# define __cpu_is_pxa910(id) (0) +#define cpu_is_pxa910() (0) #endif #ifdef CONFIG_CPU_MMP2 -# define __cpu_is_mmp2(id) \ - ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x58; }) +static inline int cpu_is_mmp2(void) +{ + return (((cpu_readid_id() >> 8) & 0xff) == 0x58); #else -# define __cpu_is_mmp2(id) (0) +#define cpu_is_mmp2() (0) #endif -#define cpu_is_pxa168() ({ __cpu_is_pxa168(read_cpuid_id()); }) -#define cpu_is_pxa910() ({ __cpu_is_pxa910(read_cpuid_id()); }) -#define cpu_is_mmp2() ({ __cpu_is_mmp2(read_cpuid_id()); }) - #endif /* __ASM_MACH_CPUTYPE_H */ diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index b379cdec4d38..a09d328e2ddd 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -222,10 +222,8 @@ #define IRQ_GPIO_NUM 192 #define IRQ_GPIO(x) (IRQ_GPIO_START + (x)) -/* Board IRQ - 64 by default, increase if not enough */ #define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM) -#define IRQ_BOARD_END (IRQ_BOARD_START + 64) -#define NR_IRQS (IRQ_BOARD_END) +#define NR_IRQS (IRQ_BOARD_START) #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h index ded43c455ec3..4621067c7720 100644 --- a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h +++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h @@ -289,4 +289,11 @@ #define GPIO86_PWM1_OUT MFP_CFG(GPIO86, AF2) #define GPIO86_PWM2_OUT MFP_CFG(GPIO86, AF3) +/* Keypad */ +#define GPIO109_KP_MKIN1 MFP_CFG(GPIO109, AF7) +#define GPIO110_KP_MKIN0 MFP_CFG(GPIO110, AF7) +#define GPIO111_KP_MKOUT7 MFP_CFG(GPIO111, AF7) +#define GPIO112_KP_MKOUT6 MFP_CFG(GPIO112, AF7) +#define GPIO121_KP_MKIN4 MFP_CFG(GPIO121, AF7) + #endif /* __ASM_MACH_MFP_PXA168_H */ diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h index 27e1bc758623..1801e4206232 100644 --- a/arch/arm/mach-mmp/include/mach/pxa168.h +++ b/arch/arm/mach-mmp/include/mach/pxa168.h @@ -5,11 +5,15 @@ struct sys_timer; extern struct sys_timer pxa168_timer; extern void __init pxa168_init_irq(void); +extern void pxa168_clear_keypad_wakeup(void); #include <linux/i2c.h> #include <mach/devices.h> #include <plat/i2c.h> #include <plat/pxa3xx_nand.h> +#include <video/pxa168fb.h> +#include <plat/pxa27x_keypad.h> +#include <mach/cputype.h> extern struct pxa_device_desc pxa168_device_uart1; extern struct pxa_device_desc pxa168_device_uart2; @@ -25,6 +29,8 @@ extern struct pxa_device_desc pxa168_device_ssp3; extern struct pxa_device_desc pxa168_device_ssp4; extern struct pxa_device_desc pxa168_device_ssp5; extern struct pxa_device_desc pxa168_device_nand; +extern struct pxa_device_desc pxa168_device_fb; +extern struct pxa_device_desc pxa168_device_keypad; static inline int pxa168_add_uart(int id) { @@ -97,4 +103,18 @@ static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info) { return pxa_register_device(&pxa168_device_nand, info, sizeof(*info)); } + +static inline int pxa168_add_fb(struct pxa168fb_mach_info *mi) +{ + return pxa_register_device(&pxa168_device_fb, mi, sizeof(*mi)); +} + +static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data) +{ + if (cpu_is_pxa168()) + data->clear_wakeup_event = pxa168_clear_keypad_wakeup; + + return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data)); +} + #endif /* __ASM_MACH_PXA168_H */ diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h index 919030514120..ac4702357a6e 100644 --- a/arch/arm/mach-mmp/include/mach/regs-apmu.h +++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h @@ -33,4 +33,16 @@ #define APMU_FNRST_DIS (1 << 1) #define APMU_AXIRST_DIS (1 << 0) +/* Wake Clear Register */ +#define APMU_WAKE_CLR APMU_REG(0x07c) + +#define APMU_PXA168_KP_WAKE_CLR (1 << 7) +#define APMU_PXA168_CFI_WAKE_CLR (1 << 6) +#define APMU_PXA168_XD_WAKE_CLR (1 << 5) +#define APMU_PXA168_MSP_WAKE_CLR (1 << 4) +#define APMU_PXA168_SD4_WAKE_CLR (1 << 3) +#define APMU_PXA168_SD3_WAKE_CLR (1 << 2) +#define APMU_PXA168_SD2_WAKE_CLR (1 << 1) +#define APMU_PXA168_SD1_WAKE_CLR (1 << 0) + #endif /* __ASM_MACH_REGS_APMU_H */ diff --git a/arch/arm/mach-mmp/include/mach/teton_bga.h b/arch/arm/mach-mmp/include/mach/teton_bga.h new file mode 100644 index 000000000000..61a539b2cc98 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/teton_bga.h @@ -0,0 +1,27 @@ +/* + * linux/arch/arm/mach-mmp/include/mach/teton_bga.h + * + * Support for the Marvell PXA168 Teton BGA Development Platform. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ +#ifndef __ASM_MACH_TETON_BGA_H +#define __ASM_MACH_TETON_BGA_H + +/* GPIOs */ +#define MMC_PWENA_GPIO 27 +#define USBHPENB_GPIO 55 +#define RTC_INT_GPIO 78 +#define LCD_VBLK_EN_GPIO 79 +#define LCD_DVDD_EN_GPIO 80 +#define RST_WIFI_GPIO 81 +#define CF_PWEN_GPIO 82 +#define USB_OC_GPIO 83 +#define PWM_GPIO 84 +#define USBHPENA_GPIO 85 +#define TS_INT_GPIO 86 +#define CIR_GPIO 108 + +#endif /* __ASM_MACH_TETON_BGA_H */ diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c index 80c3e7ab1e17..940ee03e3682 100644 --- a/arch/arm/mach-mmp/jasper.c +++ b/arch/arm/mach-mmp/jasper.c @@ -18,16 +18,18 @@ #include <linux/regulator/machine.h> #include <linux/regulator/max8649.h> #include <linux/mfd/max8925.h> +#include <linux/interrupt.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/addr-map.h> #include <mach/mfp-mmp2.h> #include <mach/mmp2.h> -#include <mach/irqs.h> #include "common.h" +#define JASPER_NR_IRQS (IRQ_BOARD_START + 48) + static unsigned long jasper_pin_config[] __initdata = { /* UART1 */ GPIO29_UART1_RXD, @@ -137,6 +139,7 @@ MACHINE_START(MARVELL_JASPER, "Jasper Development Platform") .phys_io = APB_PHYS_BASE, .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, .map_io = mmp_map_io, + .nr_irqs = JASPER_NR_IRQS, .init_irq = mmp2_init_irq, .timer = &mmp2_timer, .init_machine = jasper_init, diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index 652ae660634c..72b4e7631583 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c @@ -77,8 +77,10 @@ static APBC_CLK(ssp2, PXA168_SSP2, 4, 0); static APBC_CLK(ssp3, PXA168_SSP3, 4, 0); static APBC_CLK(ssp4, PXA168_SSP4, 4, 0); static APBC_CLK(ssp5, PXA168_SSP5, 4, 0); +static APBC_CLK(keypad, PXA168_KPC, 0, 32000); static APMU_CLK(nand, NAND, 0x01db, 208000000); +static APMU_CLK(lcd, LCD, 0x7f, 312000000); /* device and clock bindings */ static struct clk_lookup pxa168_clkregs[] = { @@ -96,6 +98,8 @@ static struct clk_lookup pxa168_clkregs[] = { INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL), INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL), INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), + INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL), + INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL), }; static int __init pxa168_init(void) @@ -132,6 +136,16 @@ struct sys_timer pxa168_timer = { .init = pxa168_timer_init, }; +void pxa168_clear_keypad_wakeup(void) +{ + uint32_t val; + uint32_t mask = APMU_PXA168_KP_WAKE_CLR; + + /* wake event clear is needed in order to clear keypad interrupt */ + val = __raw_readl(APMU_WAKE_CLR); + __raw_writel(val | mask, APMU_WAKE_CLR); +} + /* on-chip devices */ PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22); PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24); @@ -147,3 +161,5 @@ PXA168_DEVICE(ssp2, "pxa168-ssp", 1, SSP2, 0xd401c000, 0x40, 54, 55); PXA168_DEVICE(ssp3, "pxa168-ssp", 2, SSP3, 0xd401f000, 0x40, 56, 57); PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59); PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61); +PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8); +PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c); diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c new file mode 100644 index 000000000000..a4a375c58e0c --- /dev/null +++ b/arch/arm/mach-mmp/teton_bga.c @@ -0,0 +1,91 @@ +/* + * linux/arch/arm/mach-mmp/teton_bga.c + * + * Support for the Marvell PXA168 Teton BGA Development Platform. + * + * Author: Mark F. Brown <mark.brown314@gmail.com> + * + * This code is based on aspenite.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/input.h> +#include <plat/pxa27x_keypad.h> +#include <linux/i2c.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/addr-map.h> +#include <mach/mfp-pxa168.h> +#include <mach/pxa168.h> +#include <mach/teton_bga.h> + +#include "common.h" + +static unsigned long teton_bga_pin_config[] __initdata = { + /* UART1 */ + GPIO107_UART1_TXD, + GPIO108_UART1_RXD, + + /* Keypad */ + GPIO109_KP_MKIN1, + GPIO110_KP_MKIN0, + GPIO111_KP_MKOUT7, + GPIO112_KP_MKOUT6, + + /* I2C Bus */ + GPIO105_CI2C_SDA, + GPIO106_CI2C_SCL, + + /* RTC */ + GPIO78_GPIO, +}; + +static unsigned int teton_bga_matrix_key_map[] = { + KEY(0, 6, KEY_ESC), + KEY(0, 7, KEY_ENTER), + KEY(1, 6, KEY_LEFT), + KEY(1, 7, KEY_RIGHT), +}; + +static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = { + .matrix_key_rows = 2, + .matrix_key_cols = 8, + .matrix_key_map = teton_bga_matrix_key_map, + .matrix_key_map_size = ARRAY_SIZE(teton_bga_matrix_key_map), + .debounce_interval = 30, +}; + +static struct i2c_board_info teton_bga_i2c_info[] __initdata = { + { + I2C_BOARD_INFO("ds1337", 0x68), + .irq = gpio_to_irq(RTC_INT_GPIO) + }, +}; + +static void __init teton_bga_init(void) +{ + mfp_config(ARRAY_AND_SIZE(teton_bga_pin_config)); + + /* on-chip devices */ + pxa168_add_uart(1); + pxa168_add_keypad(&teton_bga_keypad_info); + pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info)); +} + +MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform") + .phys_io = APB_PHYS_BASE, + .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, + .map_io = mmp_map_io, + .nr_irqs = IRQ_BOARD_START, + .init_irq = pxa168_init_irq, + .timer = &pxa168_timer, + .init_machine = teton_bga_init, +MACHINE_END diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index ee65e05f0cf1..54571139dc4b 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -14,6 +14,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/mtd/onenand.h> +#include <linux/interrupt.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -24,6 +25,8 @@ #include "common.h" +#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 24) + static unsigned long ttc_dkb_pin_config[] __initdata = { /* UART2 */ GPIO47_UART2_RXD, @@ -125,6 +128,7 @@ MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform") .phys_io = APB_PHYS_BASE, .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc, .map_io = mmp_map_io, + .nr_irqs = TTCDKB_NR_IRQS, .init_irq = pxa910_init_irq, .timer = &pxa910_timer, .init_machine = ttc_dkb_init, diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 47264a76eeb3..3115a29dec4e 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -10,6 +10,8 @@ config ARCH_MSM7X00A select MSM_SMD select MSM_SMD_PKG3 select CPU_V6 + select MSM_PROC_COMM + select HAS_MSM_DEBUG_UART_PHYS config ARCH_MSM7X30 bool "MSM7x30" @@ -18,6 +20,9 @@ config ARCH_MSM7X30 select MSM_VIC select CPU_V7 select MSM_REMOTE_SPINLOCK_DEKKERS + select MSM_GPIOMUX + select MSM_PROC_COMM + select HAS_MSM_DEBUG_UART_PHYS config ARCH_QSD8X50 bool "QSD8X50" @@ -26,6 +31,19 @@ config ARCH_QSD8X50 select MSM_VIC select CPU_V7 select MSM_REMOTE_SPINLOCK_LDREX + select MSM_GPIOMUX + select MSM_PROC_COMM + select HAS_MSM_DEBUG_UART_PHYS + +config ARCH_MSM8X60 + bool "MSM8X60" + select ARM_GIC + select CPU_V7 + select MSM_V2_TLMM + select MSM_GPIOMUX + select MACH_MSM8X60_SURF if (!MACH_MSM8X60_RUMI3 && !MACH_MSM8X60_SIM \ + && !MACH_MSM8X60_FFA) + endchoice config MSM_SOC_REV_A @@ -36,6 +54,9 @@ config ARCH_MSM_ARM11 config ARCH_MSM_SCORPION bool +config HAS_MSM_DEBUG_UART_PHYS + bool + config MSM_VIC bool @@ -74,6 +95,30 @@ config MACH_QSD8X50A_ST1_5 help Support for the Qualcomm ST1.5. +config MACH_MSM8X60_RUMI3 + depends on ARCH_MSM8X60 + bool "MSM8x60 RUMI3" + help + Support for the Qualcomm MSM8x60 RUMI3 emulator. + +config MACH_MSM8X60_SURF + depends on ARCH_MSM8X60 + bool "MSM8x60 SURF" + help + Support for the Qualcomm MSM8x60 SURF eval board. + +config MACH_MSM8X60_SIM + depends on ARCH_MSM8X60 + bool "MSM8x60 Simulator" + help + Support for the Qualcomm MSM8x60 simulator. + +config MACH_MSM8X60_FFA + depends on ARCH_MSM8X60 + bool "MSM8x60 FFA" + help + Support for the Qualcomm MSM8x60 FFA eval board. + endmenu config MSM_DEBUG_UART @@ -82,6 +127,7 @@ config MSM_DEBUG_UART default 2 if MSM_DEBUG_UART2 default 3 if MSM_DEBUG_UART3 +if HAS_MSM_DEBUG_UART_PHYS choice prompt "Debug UART" @@ -99,11 +145,20 @@ choice config MSM_DEBUG_UART3 bool "UART3" endchoice +endif config MSM_SMD_PKG3 bool +config MSM_PROC_COMM + bool + config MSM_SMD bool +config MSM_GPIOMUX + bool + +config MSM_V2_TLMM + bool endif diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 704610648a25..b5a7b07a44f5 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,16 +1,20 @@ -obj-y += proc_comm.o -obj-y += io.o idle.o timer.o dma.o -obj-y += vreg.o +obj-y += io.o idle.o timer.o +ifndef CONFIG_ARCH_MSM8X60 obj-y += acpuclock-arm11.o -obj-y += clock.o clock-pcom.o -obj-y += gpio.o +obj-y += dma.o +endif ifdef CONFIG_MSM_VIC obj-y += irq-vic.o else +ifndef CONFIG_ARCH_MSM8X60 obj-y += irq.o endif +endif +obj-$(CONFIG_ARCH_MSM8X60) += clock-dummy.o iommu.o iommu_dev.o devices-msm8x60-iommu.o +obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o +obj-$(CONFIG_MSM_PROC_COMM) += clock.o obj-$(CONFIG_ARCH_QSD8X50) += sirc.o obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MSM_SMD) += last_radio_log.o @@ -19,4 +23,11 @@ obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o d obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o +obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o +obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o +obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o +obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o +ifndef CONFIG_MSM_V2_TLMM +obj-y += gpio.o +endif diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index e32981928c77..76d5a22a6984 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -39,27 +39,11 @@ extern struct sys_timer msm_timer; -#ifdef CONFIG_SERIAL_MSM_CONSOLE -static struct msm_gpio uart2_config_data[] = { - { GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_RFR"}, - { GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_CTS"}, - { GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"}, - { GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"}, -}; - -static void msm7x30_init_uart2(void) -{ - msm_gpios_request_enable(uart2_config_data, - ARRAY_SIZE(uart2_config_data)); - -} -#endif - static struct platform_device *devices[] __initdata = { #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) &msm_device_uart2, #endif - + &msm_device_smd, }; static void __init msm7x30_init_irq(void) @@ -70,10 +54,6 @@ static void __init msm7x30_init_irq(void) static void __init msm7x30_init(void) { platform_add_devices(devices, ARRAY_SIZE(devices)); -#ifdef CONFIG_SERIAL_MSM_CONSOLE - msm7x30_init_uart2(); -#endif - } static void __init msm7x30_map_io(void) diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c new file mode 100644 index 000000000000..7486a681cc71 --- /dev/null +++ b/arch/arm/mach-msm/board-msm8x60.c @@ -0,0 +1,100 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/irq.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/hardware/gic.h> + +#include <mach/board.h> +#include <mach/msm_iomap.h> + +void __iomem *gic_cpu_base_addr; + +unsigned long clk_get_max_axi_khz(void) +{ + return 0; +} + +static void __init msm8x60_map_io(void) +{ + msm_map_msm8x60_io(); +} + +static void __init msm8x60_init_irq(void) +{ + unsigned int i; + + gic_dist_init(0, MSM_QGIC_DIST_BASE, GIC_PPI_START); + gic_cpu_base_addr = (void *)MSM_QGIC_CPU_BASE; + gic_cpu_init(0, MSM_QGIC_CPU_BASE); + + /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */ + writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4); + + /* RUMI does not adhere to GIC spec by enabling STIs by default. + * Enable/clear is supposed to be RO for STIs, but is RW on RUMI. + */ + if (!machine_is_msm8x60_sim()) + writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET); + + /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet + * as they are configured as level, which does not play nice with + * handle_percpu_irq. + */ + for (i = GIC_PPI_START; i < GIC_SPI_START; i++) { + if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE) + set_irq_handler(i, handle_percpu_irq); + } +} + +static void __init msm8x60_init(void) +{ +} + +MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3") + .map_io = msm8x60_map_io, + .init_irq = msm8x60_init_irq, + .init_machine = msm8x60_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF") + .map_io = msm8x60_map_io, + .init_irq = msm8x60_init_irq, + .init_machine = msm8x60_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR") + .map_io = msm8x60_map_io, + .init_irq = msm8x60_init_irq, + .init_machine = msm8x60_init, + .timer = &msm_timer, +MACHINE_END + +MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA") + .map_io = msm8x60_map_io, + .init_irq = msm8x60_init_irq, + .init_machine = msm8x60_init, + .timer = &msm_timer, +MACHINE_END diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index e3cc80792d6c..d5d5e441a52d 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -35,20 +35,49 @@ extern struct sys_timer msm_timer; -static struct msm_gpio uart3_config_data[] = { - { GPIO_CFG(86, 1, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"}, - { GPIO_CFG(87, 1, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"}, +static const resource_size_t qsd8x50_surf_smc91x_base __initdata = 0x70000300; +static const unsigned qsd8x50_surf_smc91x_gpio __initdata = 156; + +/* Leave smc91x resources empty here, as we'll fill them in + * at run-time: they vary from board to board, and the true + * configuration won't be known until boot. + */ +static struct resource smc91x_resources[] __initdata = { + [0] = { + .flags = IORESOURCE_MEM, + }, + [1] = { + .flags = IORESOURCE_IRQ, + }, }; -static struct platform_device *devices[] __initdata = { - &msm_device_uart3, +static struct platform_device smc91x_device __initdata = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, }; -static void msm8x50_init_uart3(void) +static int __init msm_init_smc91x(void) { - msm_gpios_request_enable(uart3_config_data, - ARRAY_SIZE(uart3_config_data)); + if (machine_is_qsd8x50_surf()) { + smc91x_resources[0].start = qsd8x50_surf_smc91x_base; + smc91x_resources[0].end = qsd8x50_surf_smc91x_base + 0xff; + smc91x_resources[1].start = + gpio_to_irq(qsd8x50_surf_smc91x_gpio); + smc91x_resources[1].end = + gpio_to_irq(qsd8x50_surf_smc91x_gpio); + platform_device_register(&smc91x_device); + } + + return 0; } +module_init(msm_init_smc91x); + +static struct platform_device *devices[] __initdata = { + &msm_device_uart3, + &msm_device_smd, +}; static void __init qsd8x50_map_io(void) { @@ -64,7 +93,6 @@ static void __init qsd8x50_init_irq(void) static void __init qsd8x50_init(void) { - msm8x50_init_uart3(); platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c new file mode 100644 index 000000000000..1250d22082ee --- /dev/null +++ b/arch/arm/mach-msm/clock-dummy.c @@ -0,0 +1,54 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + */ +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/module.h> + +struct clk *clk_get(struct device *dev, const char *id) +{ + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return -ENOENT; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_get_rate); + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + return -ENOENT; +} +EXPORT_SYMBOL(clk_set_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c index b449e8ad2904..7fcf2e3b7698 100644 --- a/arch/arm/mach-msm/devices-msm7x30.c +++ b/arch/arm/mach-msm/devices-msm7x30.c @@ -51,6 +51,11 @@ struct platform_device msm_device_uart2 = { .resource = resources_uart2, }; +struct platform_device msm_device_smd = { + .name = "msm_smd", + .id = -1, +}; + struct clk msm_clocks_7x30[] = { CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), diff --git a/arch/arm/mach-msm/devices-msm8x60-iommu.c b/arch/arm/mach-msm/devices-msm8x60-iommu.c new file mode 100644 index 000000000000..89b9d4437e92 --- /dev/null +++ b/arch/arm/mach-msm/devices-msm8x60-iommu.c @@ -0,0 +1,883 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/bootmem.h> + +#include <mach/msm_iomap-8x60.h> +#include <mach/irqs-8x60.h> +#include <mach/iommu.h> + +static struct resource msm_iommu_jpegd_resources[] = { + { + .start = MSM_IOMMU_JPEGD_PHYS, + .end = MSM_IOMMU_JPEGD_PHYS + MSM_IOMMU_JPEGD_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ, + .end = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_JPEGD_CB_SC_SECURE_IRQ, + .end = SMMU_JPEGD_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_vpe_resources[] = { + { + .start = MSM_IOMMU_VPE_PHYS, + .end = MSM_IOMMU_VPE_PHYS + MSM_IOMMU_VPE_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_VPE_CB_SC_NON_SECURE_IRQ, + .end = SMMU_VPE_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_VPE_CB_SC_SECURE_IRQ, + .end = SMMU_VPE_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_mdp0_resources[] = { + { + .start = MSM_IOMMU_MDP0_PHYS, + .end = MSM_IOMMU_MDP0_PHYS + MSM_IOMMU_MDP0_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_MDP0_CB_SC_NON_SECURE_IRQ, + .end = SMMU_MDP0_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_MDP0_CB_SC_SECURE_IRQ, + .end = SMMU_MDP0_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_mdp1_resources[] = { + { + .start = MSM_IOMMU_MDP1_PHYS, + .end = MSM_IOMMU_MDP1_PHYS + MSM_IOMMU_MDP1_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_MDP1_CB_SC_NON_SECURE_IRQ, + .end = SMMU_MDP1_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_MDP1_CB_SC_SECURE_IRQ, + .end = SMMU_MDP1_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_rot_resources[] = { + { + .start = MSM_IOMMU_ROT_PHYS, + .end = MSM_IOMMU_ROT_PHYS + MSM_IOMMU_ROT_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_ROT_CB_SC_NON_SECURE_IRQ, + .end = SMMU_ROT_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_ROT_CB_SC_SECURE_IRQ, + .end = SMMU_ROT_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_ijpeg_resources[] = { + { + .start = MSM_IOMMU_IJPEG_PHYS, + .end = MSM_IOMMU_IJPEG_PHYS + MSM_IOMMU_IJPEG_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ, + .end = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_IJPEG_CB_SC_SECURE_IRQ, + .end = SMMU_IJPEG_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_vfe_resources[] = { + { + .start = MSM_IOMMU_VFE_PHYS, + .end = MSM_IOMMU_VFE_PHYS + MSM_IOMMU_VFE_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_VFE_CB_SC_NON_SECURE_IRQ, + .end = SMMU_VFE_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_VFE_CB_SC_SECURE_IRQ, + .end = SMMU_VFE_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_vcodec_a_resources[] = { + { + .start = MSM_IOMMU_VCODEC_A_PHYS, + .end = MSM_IOMMU_VCODEC_A_PHYS + MSM_IOMMU_VCODEC_A_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ, + .end = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_VCODEC_A_CB_SC_SECURE_IRQ, + .end = SMMU_VCODEC_A_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_vcodec_b_resources[] = { + { + .start = MSM_IOMMU_VCODEC_B_PHYS, + .end = MSM_IOMMU_VCODEC_B_PHYS + MSM_IOMMU_VCODEC_B_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ, + .end = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_VCODEC_B_CB_SC_SECURE_IRQ, + .end = SMMU_VCODEC_B_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_gfx3d_resources[] = { + { + .start = MSM_IOMMU_GFX3D_PHYS, + .end = MSM_IOMMU_GFX3D_PHYS + MSM_IOMMU_GFX3D_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ, + .end = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_GFX3D_CB_SC_SECURE_IRQ, + .end = SMMU_GFX3D_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource msm_iommu_gfx2d0_resources[] = { + { + .start = MSM_IOMMU_GFX2D0_PHYS, + .end = MSM_IOMMU_GFX2D0_PHYS + MSM_IOMMU_GFX2D0_SIZE - 1, + .name = "physbase", + .flags = IORESOURCE_MEM, + }, + { + .name = "nonsecure_irq", + .start = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ, + .end = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, + { + .name = "secure_irq", + .start = SMMU_GFX2D0_CB_SC_SECURE_IRQ, + .end = SMMU_GFX2D0_CB_SC_SECURE_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device msm_root_iommu_dev = { + .name = "msm_iommu", + .id = -1, +}; + +static struct msm_iommu_dev jpegd_smmu = { + .name = "jpegd", + .clk_rate = -1 +}; + +static struct msm_iommu_dev vpe_smmu = { + .name = "vpe" +}; + +static struct msm_iommu_dev mdp0_smmu = { + .name = "mdp0" +}; + +static struct msm_iommu_dev mdp1_smmu = { + .name = "mdp1" +}; + +static struct msm_iommu_dev rot_smmu = { + .name = "rot" +}; + +static struct msm_iommu_dev ijpeg_smmu = { + .name = "ijpeg" +}; + +static struct msm_iommu_dev vfe_smmu = { + .name = "vfe", + .clk_rate = -1 +}; + +static struct msm_iommu_dev vcodec_a_smmu = { + .name = "vcodec_a" +}; + +static struct msm_iommu_dev vcodec_b_smmu = { + .name = "vcodec_b" +}; + +static struct msm_iommu_dev gfx3d_smmu = { + .name = "gfx3d", + .clk_rate = 27000000 +}; + +static struct msm_iommu_dev gfx2d0_smmu = { + .name = "gfx2d0", + .clk_rate = 27000000 +}; + +static struct platform_device msm_device_smmu_jpegd = { + .name = "msm_iommu", + .id = 0, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_jpegd_resources), + .resource = msm_iommu_jpegd_resources, +}; + +static struct platform_device msm_device_smmu_vpe = { + .name = "msm_iommu", + .id = 1, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_vpe_resources), + .resource = msm_iommu_vpe_resources, +}; + +static struct platform_device msm_device_smmu_mdp0 = { + .name = "msm_iommu", + .id = 2, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_mdp0_resources), + .resource = msm_iommu_mdp0_resources, +}; + +static struct platform_device msm_device_smmu_mdp1 = { + .name = "msm_iommu", + .id = 3, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_mdp1_resources), + .resource = msm_iommu_mdp1_resources, +}; + +static struct platform_device msm_device_smmu_rot = { + .name = "msm_iommu", + .id = 4, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_rot_resources), + .resource = msm_iommu_rot_resources, +}; + +static struct platform_device msm_device_smmu_ijpeg = { + .name = "msm_iommu", + .id = 5, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_ijpeg_resources), + .resource = msm_iommu_ijpeg_resources, +}; + +static struct platform_device msm_device_smmu_vfe = { + .name = "msm_iommu", + .id = 6, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_vfe_resources), + .resource = msm_iommu_vfe_resources, +}; + +static struct platform_device msm_device_smmu_vcodec_a = { + .name = "msm_iommu", + .id = 7, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_vcodec_a_resources), + .resource = msm_iommu_vcodec_a_resources, +}; + +static struct platform_device msm_device_smmu_vcodec_b = { + .name = "msm_iommu", + .id = 8, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_vcodec_b_resources), + .resource = msm_iommu_vcodec_b_resources, +}; + +static struct platform_device msm_device_smmu_gfx3d = { + .name = "msm_iommu", + .id = 9, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_gfx3d_resources), + .resource = msm_iommu_gfx3d_resources, +}; + +static struct platform_device msm_device_smmu_gfx2d0 = { + .name = "msm_iommu", + .id = 10, + .dev = { + .parent = &msm_root_iommu_dev.dev, + }, + .num_resources = ARRAY_SIZE(msm_iommu_gfx2d0_resources), + .resource = msm_iommu_gfx2d0_resources, +}; + +static struct msm_iommu_ctx_dev jpegd_src_ctx = { + .name = "jpegd_src", + .num = 0, + .mids = {0, -1} +}; + +static struct msm_iommu_ctx_dev jpegd_dst_ctx = { + .name = "jpegd_dst", + .num = 1, + .mids = {1, -1} +}; + +static struct msm_iommu_ctx_dev vpe_src_ctx = { + .name = "vpe_src", + .num = 0, + .mids = {0, -1} +}; + +static struct msm_iommu_ctx_dev vpe_dst_ctx = { + .name = "vpe_dst", + .num = 1, + .mids = {1, -1} +}; + +static struct msm_iommu_ctx_dev mdp_vg1_ctx = { + .name = "mdp_vg1", + .num = 0, + .mids = {0, 2, -1} +}; + +static struct msm_iommu_ctx_dev mdp_rgb1_ctx = { + .name = "mdp_rgb1", + .num = 1, + .mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1} +}; + +static struct msm_iommu_ctx_dev mdp_vg2_ctx = { + .name = "mdp_vg2", + .num = 0, + .mids = {0, 2, -1} +}; + +static struct msm_iommu_ctx_dev mdp_rgb2_ctx = { + .name = "mdp_rgb2", + .num = 1, + .mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1} +}; + +static struct msm_iommu_ctx_dev rot_src_ctx = { + .name = "rot_src", + .num = 0, + .mids = {0, -1} +}; + +static struct msm_iommu_ctx_dev rot_dst_ctx = { + .name = "rot_dst", + .num = 1, + .mids = {1, -1} +}; + +static struct msm_iommu_ctx_dev ijpeg_src_ctx = { + .name = "ijpeg_src", + .num = 0, + .mids = {0, -1} +}; + +static struct msm_iommu_ctx_dev ijpeg_dst_ctx = { + .name = "ijpeg_dst", + .num = 1, + .mids = {1, -1} +}; + +static struct msm_iommu_ctx_dev vfe_imgwr_ctx = { + .name = "vfe_imgwr", + .num = 0, + .mids = {2, 3, 4, 5, 6, 7, 8, -1} +}; + +static struct msm_iommu_ctx_dev vfe_misc_ctx = { + .name = "vfe_misc", + .num = 1, + .mids = {0, 1, 9, -1} +}; + +static struct msm_iommu_ctx_dev vcodec_a_stream_ctx = { + .name = "vcodec_a_stream", + .num = 0, + .mids = {2, 5, -1} +}; + +static struct msm_iommu_ctx_dev vcodec_a_mm1_ctx = { + .name = "vcodec_a_mm1", + .num = 1, + .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1} +}; + +static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = { + .name = "vcodec_b_mm2", + .num = 0, + .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1} +}; + +static struct msm_iommu_ctx_dev gfx3d_rbpa_ctx = { + .name = "gfx3d_rbpa", + .num = 0, + .mids = {-1} +}; + +static struct msm_iommu_ctx_dev gfx3d_cpvgttc_ctx = { + .name = "gfx3d_cpvgttc", + .num = 1, + .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1} +}; + +static struct msm_iommu_ctx_dev gfx3d_smmu_ctx = { + .name = "gfx3d_smmu", + .num = 2, + .mids = {8, 9, 10, 11, 12, -1} +}; + +static struct msm_iommu_ctx_dev gfx2d0_pixv1_ctx = { + .name = "gfx2d0_pixv1_smmu", + .num = 0, + .mids = {0, 3, 4, -1} +}; + +static struct msm_iommu_ctx_dev gfx2d0_texv3_ctx = { + .name = "gfx2d0_texv3_smmu", + .num = 1, + .mids = {1, 6, 7, -1} +}; + +static struct platform_device msm_device_jpegd_src_ctx = { + .name = "msm_iommu_ctx", + .id = 0, + .dev = { + .parent = &msm_device_smmu_jpegd.dev, + }, +}; + +static struct platform_device msm_device_jpegd_dst_ctx = { + .name = "msm_iommu_ctx", + .id = 1, + .dev = { + .parent = &msm_device_smmu_jpegd.dev, + }, +}; + +static struct platform_device msm_device_vpe_src_ctx = { + .name = "msm_iommu_ctx", + .id = 2, + .dev = { + .parent = &msm_device_smmu_vpe.dev, + }, +}; + +static struct platform_device msm_device_vpe_dst_ctx = { + .name = "msm_iommu_ctx", + .id = 3, + .dev = { + .parent = &msm_device_smmu_vpe.dev, + }, +}; + +static struct platform_device msm_device_mdp_vg1_ctx = { + .name = "msm_iommu_ctx", + .id = 4, + .dev = { + .parent = &msm_device_smmu_mdp0.dev, + }, +}; + +static struct platform_device msm_device_mdp_rgb1_ctx = { + .name = "msm_iommu_ctx", + .id = 5, + .dev = { + .parent = &msm_device_smmu_mdp0.dev, + }, +}; + +static struct platform_device msm_device_mdp_vg2_ctx = { + .name = "msm_iommu_ctx", + .id = 6, + .dev = { + .parent = &msm_device_smmu_mdp1.dev, + }, +}; + +static struct platform_device msm_device_mdp_rgb2_ctx = { + .name = "msm_iommu_ctx", + .id = 7, + .dev = { + .parent = &msm_device_smmu_mdp1.dev, + }, +}; + +static struct platform_device msm_device_rot_src_ctx = { + .name = "msm_iommu_ctx", + .id = 8, + .dev = { + .parent = &msm_device_smmu_rot.dev, + }, +}; + +static struct platform_device msm_device_rot_dst_ctx = { + .name = "msm_iommu_ctx", + .id = 9, + .dev = { + .parent = &msm_device_smmu_rot.dev, + }, +}; + +static struct platform_device msm_device_ijpeg_src_ctx = { + .name = "msm_iommu_ctx", + .id = 10, + .dev = { + .parent = &msm_device_smmu_ijpeg.dev, + }, +}; + +static struct platform_device msm_device_ijpeg_dst_ctx = { + .name = "msm_iommu_ctx", + .id = 11, + .dev = { + .parent = &msm_device_smmu_ijpeg.dev, + }, +}; + +static struct platform_device msm_device_vfe_imgwr_ctx = { + .name = "msm_iommu_ctx", + .id = 12, + .dev = { + .parent = &msm_device_smmu_vfe.dev, + }, +}; + +static struct platform_device msm_device_vfe_misc_ctx = { + .name = "msm_iommu_ctx", + .id = 13, + .dev = { + .parent = &msm_device_smmu_vfe.dev, + }, +}; + +static struct platform_device msm_device_vcodec_a_stream_ctx = { + .name = "msm_iommu_ctx", + .id = 14, + .dev = { + .parent = &msm_device_smmu_vcodec_a.dev, + }, +}; + +static struct platform_device msm_device_vcodec_a_mm1_ctx = { + .name = "msm_iommu_ctx", + .id = 15, + .dev = { + .parent = &msm_device_smmu_vcodec_a.dev, + }, +}; + +static struct platform_device msm_device_vcodec_b_mm2_ctx = { + .name = "msm_iommu_ctx", + .id = 16, + .dev = { + .parent = &msm_device_smmu_vcodec_b.dev, + }, +}; + +static struct platform_device msm_device_gfx3d_rbpa_ctx = { + .name = "msm_iommu_ctx", + .id = 17, + .dev = { + .parent = &msm_device_smmu_gfx3d.dev, + }, +}; + +static struct platform_device msm_device_gfx3d_cpvgttc_ctx = { + .name = "msm_iommu_ctx", + .id = 18, + .dev = { + .parent = &msm_device_smmu_gfx3d.dev, + }, +}; + +static struct platform_device msm_device_gfx3d_smmu_ctx = { + .name = "msm_iommu_ctx", + .id = 19, + .dev = { + .parent = &msm_device_smmu_gfx3d.dev, + }, +}; + +static struct platform_device msm_device_gfx2d0_pixv1_ctx = { + .name = "msm_iommu_ctx", + .id = 20, + .dev = { + .parent = &msm_device_smmu_gfx2d0.dev, + }, +}; + +static struct platform_device msm_device_gfx2d0_texv3_ctx = { + .name = "msm_iommu_ctx", + .id = 21, + .dev = { + .parent = &msm_device_smmu_gfx2d0.dev, + }, +}; + +static struct platform_device *msm_iommu_devs[] = { + &msm_device_smmu_jpegd, + &msm_device_smmu_vpe, + &msm_device_smmu_mdp0, + &msm_device_smmu_mdp1, + &msm_device_smmu_rot, + &msm_device_smmu_ijpeg, + &msm_device_smmu_vfe, + &msm_device_smmu_vcodec_a, + &msm_device_smmu_vcodec_b, + &msm_device_smmu_gfx3d, + &msm_device_smmu_gfx2d0, +}; + +static struct msm_iommu_dev *msm_iommu_data[] = { + &jpegd_smmu, + &vpe_smmu, + &mdp0_smmu, + &mdp1_smmu, + &rot_smmu, + &ijpeg_smmu, + &vfe_smmu, + &vcodec_a_smmu, + &vcodec_b_smmu, + &gfx3d_smmu, + &gfx2d0_smmu, +}; + +static struct platform_device *msm_iommu_ctx_devs[] = { + &msm_device_jpegd_src_ctx, + &msm_device_jpegd_dst_ctx, + &msm_device_vpe_src_ctx, + &msm_device_vpe_dst_ctx, + &msm_device_mdp_vg1_ctx, + &msm_device_mdp_rgb1_ctx, + &msm_device_mdp_vg2_ctx, + &msm_device_mdp_rgb2_ctx, + &msm_device_rot_src_ctx, + &msm_device_rot_dst_ctx, + &msm_device_ijpeg_src_ctx, + &msm_device_ijpeg_dst_ctx, + &msm_device_vfe_imgwr_ctx, + &msm_device_vfe_misc_ctx, + &msm_device_vcodec_a_stream_ctx, + &msm_device_vcodec_a_mm1_ctx, + &msm_device_vcodec_b_mm2_ctx, + &msm_device_gfx3d_rbpa_ctx, + &msm_device_gfx3d_cpvgttc_ctx, + &msm_device_gfx3d_smmu_ctx, + &msm_device_gfx2d0_pixv1_ctx, + &msm_device_gfx2d0_texv3_ctx, +}; + +static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = { + &jpegd_src_ctx, + &jpegd_dst_ctx, + &vpe_src_ctx, + &vpe_dst_ctx, + &mdp_vg1_ctx, + &mdp_rgb1_ctx, + &mdp_vg2_ctx, + &mdp_rgb2_ctx, + &rot_src_ctx, + &rot_dst_ctx, + &ijpeg_src_ctx, + &ijpeg_dst_ctx, + &vfe_imgwr_ctx, + &vfe_misc_ctx, + &vcodec_a_stream_ctx, + &vcodec_a_mm1_ctx, + &vcodec_b_mm2_ctx, + &gfx3d_rbpa_ctx, + &gfx3d_cpvgttc_ctx, + &gfx3d_smmu_ctx, + &gfx2d0_pixv1_ctx, + &gfx2d0_texv3_ctx, +}; + +static int msm8x60_iommu_init(void) +{ + int ret, i; + + ret = platform_device_register(&msm_root_iommu_dev); + if (ret != 0) { + pr_err("Failed to register root IOMMU device!\n"); + goto failure; + } + + for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); i++) { + ret = platform_device_add_data(msm_iommu_devs[i], + msm_iommu_data[i], + sizeof(struct msm_iommu_dev)); + if (ret != 0) { + pr_err("platform_device_add_data failed, " + "i = %d\n", i); + goto failure_unwind; + } + + ret = platform_device_register(msm_iommu_devs[i]); + + if (ret != 0) { + pr_err("platform_device_register smmu failed, " + "i = %d\n", i); + goto failure_unwind; + } + } + + for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++) { + ret = platform_device_add_data(msm_iommu_ctx_devs[i], + msm_iommu_ctx_data[i], + sizeof(*msm_iommu_ctx_devs[i])); + if (ret != 0) { + pr_err("platform_device_add_data smmu failed, " + "i = %d\n", i); + goto failure_unwind2; + } + + ret = platform_device_register(msm_iommu_ctx_devs[i]); + if (ret != 0) { + pr_err("platform_device_register ctx failed, " + "i = %d\n", i); + goto failure_unwind2; + } + } + return 0; + +failure_unwind2: + while (--i >= 0) + platform_device_unregister(msm_iommu_ctx_devs[i]); +failure_unwind: + while (--i >= 0) + platform_device_unregister(msm_iommu_devs[i]); + + platform_device_unregister(&msm_root_iommu_dev); +failure: + return ret; +} + +static void msm8x60_iommu_exit(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++) + platform_device_unregister(msm_iommu_ctx_devs[i]); + + for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); ++i) + platform_device_unregister(msm_iommu_devs[i]); + + platform_device_unregister(&msm_root_iommu_dev); +} + +subsys_initcall(msm8x60_iommu_init); +module_exit(msm8x60_iommu_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>"); diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c index 4d4a50785e34..6fe67c5d1ae0 100644 --- a/arch/arm/mach-msm/devices-qsd8x50.c +++ b/arch/arm/mach-msm/devices-qsd8x50.c @@ -48,6 +48,11 @@ struct platform_device msm_device_uart3 = { .resource = resources_uart3, }; +struct platform_device msm_device_smd = { + .name = "msm_smd", + .id = -1, +}; + struct clk msm_clocks_8x50[] = { CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN), diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c index bc32c845c7b0..33051b509e88 100644 --- a/arch/arm/mach-msm/gpio.c +++ b/arch/arm/mach-msm/gpio.c @@ -1,7 +1,7 @@ /* linux/arch/arm/mach-msm/gpio.c * * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -14,72 +14,363 @@ * */ +#include <linux/bitops.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> #include <linux/module.h> -#include <mach/gpio.h> -#include "proc_comm.h" - -int gpio_tlmm_config(unsigned config, unsigned disable) -{ - return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable); -} -EXPORT_SYMBOL(gpio_tlmm_config); - -int msm_gpios_enable(const struct msm_gpio *table, int size) -{ - int rc; - int i; - const struct msm_gpio *g; - for (i = 0; i < size; i++) { - g = table + i; - rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE); - if (rc) { - pr_err("gpio_tlmm_config(0x%08x, GPIO_ENABLE)" - " <%s> failed: %d\n", - g->gpio_cfg, g->label ?: "?", rc); - pr_err("pin %d func %d dir %d pull %d drvstr %d\n", - GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg), - GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg), - GPIO_DRVSTR(g->gpio_cfg)); - goto err; - } +#include "gpio_hw.h" +#include "gpiomux.h" + +#define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0) + +#define MSM_GPIO_BANK(bank, first, last) \ + { \ + .regs = { \ + .out = MSM_GPIO_OUT_##bank, \ + .in = MSM_GPIO_IN_##bank, \ + .int_status = MSM_GPIO_INT_STATUS_##bank, \ + .int_clear = MSM_GPIO_INT_CLEAR_##bank, \ + .int_en = MSM_GPIO_INT_EN_##bank, \ + .int_edge = MSM_GPIO_INT_EDGE_##bank, \ + .int_pos = MSM_GPIO_INT_POS_##bank, \ + .oe = MSM_GPIO_OE_##bank, \ + }, \ + .chip = { \ + .base = (first), \ + .ngpio = (last) - (first) + 1, \ + .get = msm_gpio_get, \ + .set = msm_gpio_set, \ + .direction_input = msm_gpio_direction_input, \ + .direction_output = msm_gpio_direction_output, \ + .to_irq = msm_gpio_to_irq, \ + .request = msm_gpio_request, \ + .free = msm_gpio_free, \ + } \ } + +#define MSM_GPIO_BROKEN_INT_CLEAR 1 + +struct msm_gpio_regs { + void __iomem *out; + void __iomem *in; + void __iomem *int_status; + void __iomem *int_clear; + void __iomem *int_en; + void __iomem *int_edge; + void __iomem *int_pos; + void __iomem *oe; +}; + +struct msm_gpio_chip { + spinlock_t lock; + struct gpio_chip chip; + struct msm_gpio_regs regs; +#if MSM_GPIO_BROKEN_INT_CLEAR + unsigned int_status_copy; +#endif + unsigned int both_edge_detect; + unsigned int int_enable[2]; /* 0: awake, 1: sleep */ +}; + +static int msm_gpio_write(struct msm_gpio_chip *msm_chip, + unsigned offset, unsigned on) +{ + unsigned mask = BIT(offset); + unsigned val; + + val = readl(msm_chip->regs.out); + if (on) + writel(val | mask, msm_chip->regs.out); + else + writel(val & ~mask, msm_chip->regs.out); return 0; -err: - msm_gpios_disable(table, i); - return rc; -} -EXPORT_SYMBOL(msm_gpios_enable); - -void msm_gpios_disable(const struct msm_gpio *table, int size) -{ - int rc; - int i; - const struct msm_gpio *g; - for (i = size-1; i >= 0; i--) { - g = table + i; - rc = gpio_tlmm_config(g->gpio_cfg, GPIO_DISABLE); - if (rc) { - pr_err("gpio_tlmm_config(0x%08x, GPIO_DISABLE)" - " <%s> failed: %d\n", - g->gpio_cfg, g->label ?: "?", rc); - pr_err("pin %d func %d dir %d pull %d drvstr %d\n", - GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg), - GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg), - GPIO_DRVSTR(g->gpio_cfg)); - } +} + +static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip) +{ + int loop_limit = 100; + unsigned pol, val, val2, intstat; + do { + val = readl(msm_chip->regs.in); + pol = readl(msm_chip->regs.int_pos); + pol = (pol & ~msm_chip->both_edge_detect) | + (~val & msm_chip->both_edge_detect); + writel(pol, msm_chip->regs.int_pos); + intstat = readl(msm_chip->regs.int_status); + val2 = readl(msm_chip->regs.in); + if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0) + return; + } while (loop_limit-- > 0); + printk(KERN_ERR "msm_gpio_update_both_edge_detect, " + "failed to reach stable state %x != %x\n", val, val2); +} + +static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip, + unsigned offset) +{ + unsigned bit = BIT(offset); + +#if MSM_GPIO_BROKEN_INT_CLEAR + /* Save interrupts that already triggered before we loose them. */ + /* Any interrupt that triggers between the read of int_status */ + /* and the write to int_clear will still be lost though. */ + msm_chip->int_status_copy |= readl(msm_chip->regs.int_status); + msm_chip->int_status_copy &= ~bit; +#endif + writel(bit, msm_chip->regs.int_clear); + msm_gpio_update_both_edge_detect(msm_chip); + return 0; +} + +static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + struct msm_gpio_chip *msm_chip; + unsigned long irq_flags; + + msm_chip = container_of(chip, struct msm_gpio_chip, chip); + spin_lock_irqsave(&msm_chip->lock, irq_flags); + writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe); + spin_unlock_irqrestore(&msm_chip->lock, irq_flags); + return 0; +} + +static int +msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) +{ + struct msm_gpio_chip *msm_chip; + unsigned long irq_flags; + + msm_chip = container_of(chip, struct msm_gpio_chip, chip); + spin_lock_irqsave(&msm_chip->lock, irq_flags); + msm_gpio_write(msm_chip, offset, value); + writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe); + spin_unlock_irqrestore(&msm_chip->lock, irq_flags); + return 0; +} + +static int msm_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct msm_gpio_chip *msm_chip; + + msm_chip = container_of(chip, struct msm_gpio_chip, chip); + return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0; +} + +static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct msm_gpio_chip *msm_chip; + unsigned long irq_flags; + + msm_chip = container_of(chip, struct msm_gpio_chip, chip); + spin_lock_irqsave(&msm_chip->lock, irq_flags); + msm_gpio_write(msm_chip, offset, value); + spin_unlock_irqrestore(&msm_chip->lock, irq_flags); +} + +static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + return MSM_GPIO_TO_INT(chip->base + offset); +} + +#ifdef CONFIG_MSM_GPIOMUX +static int msm_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + return msm_gpiomux_get(chip->base + offset); +} + +static void msm_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + msm_gpiomux_put(chip->base + offset); +} +#else +#define msm_gpio_request NULL +#define msm_gpio_free NULL +#endif + +struct msm_gpio_chip msm_gpio_chips[] = { +#if defined(CONFIG_ARCH_MSM7X00A) + MSM_GPIO_BANK(0, 0, 15), + MSM_GPIO_BANK(1, 16, 42), + MSM_GPIO_BANK(2, 43, 67), + MSM_GPIO_BANK(3, 68, 94), + MSM_GPIO_BANK(4, 95, 106), + MSM_GPIO_BANK(5, 107, 121), +#elif defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X27) + MSM_GPIO_BANK(0, 0, 15), + MSM_GPIO_BANK(1, 16, 42), + MSM_GPIO_BANK(2, 43, 67), + MSM_GPIO_BANK(3, 68, 94), + MSM_GPIO_BANK(4, 95, 106), + MSM_GPIO_BANK(5, 107, 132), +#elif defined(CONFIG_ARCH_MSM7X30) + MSM_GPIO_BANK(0, 0, 15), + MSM_GPIO_BANK(1, 16, 43), + MSM_GPIO_BANK(2, 44, 67), + MSM_GPIO_BANK(3, 68, 94), + MSM_GPIO_BANK(4, 95, 106), + MSM_GPIO_BANK(5, 107, 133), + MSM_GPIO_BANK(6, 134, 150), + MSM_GPIO_BANK(7, 151, 181), +#elif defined(CONFIG_ARCH_QSD8X50) + MSM_GPIO_BANK(0, 0, 15), + MSM_GPIO_BANK(1, 16, 42), + MSM_GPIO_BANK(2, 43, 67), + MSM_GPIO_BANK(3, 68, 94), + MSM_GPIO_BANK(4, 95, 103), + MSM_GPIO_BANK(5, 104, 121), + MSM_GPIO_BANK(6, 122, 152), + MSM_GPIO_BANK(7, 153, 164), +#endif +}; + +static void msm_gpio_irq_ack(unsigned int irq) +{ + unsigned long irq_flags; + struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq); + spin_lock_irqsave(&msm_chip->lock, irq_flags); + msm_gpio_clear_detect_status(msm_chip, + irq - gpio_to_irq(msm_chip->chip.base)); + spin_unlock_irqrestore(&msm_chip->lock, irq_flags); +} + +static void msm_gpio_irq_mask(unsigned int irq) +{ + unsigned long irq_flags; + struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq); + unsigned offset = irq - gpio_to_irq(msm_chip->chip.base); + + spin_lock_irqsave(&msm_chip->lock, irq_flags); + /* level triggered interrupts are also latched */ + if (!(readl(msm_chip->regs.int_edge) & BIT(offset))) + msm_gpio_clear_detect_status(msm_chip, offset); + msm_chip->int_enable[0] &= ~BIT(offset); + writel(msm_chip->int_enable[0], msm_chip->regs.int_en); + spin_unlock_irqrestore(&msm_chip->lock, irq_flags); +} + +static void msm_gpio_irq_unmask(unsigned int irq) +{ + unsigned long irq_flags; + struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq); + unsigned offset = irq - gpio_to_irq(msm_chip->chip.base); + + spin_lock_irqsave(&msm_chip->lock, irq_flags); + /* level triggered interrupts are also latched */ + if (!(readl(msm_chip->regs.int_edge) & BIT(offset))) + msm_gpio_clear_detect_status(msm_chip, offset); + msm_chip->int_enable[0] |= BIT(offset); + writel(msm_chip->int_enable[0], msm_chip->regs.int_en); + spin_unlock_irqrestore(&msm_chip->lock, irq_flags); +} + +static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on) +{ + unsigned long irq_flags; + struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq); + unsigned offset = irq - gpio_to_irq(msm_chip->chip.base); + + spin_lock_irqsave(&msm_chip->lock, irq_flags); + + if (on) + msm_chip->int_enable[1] |= BIT(offset); + else + msm_chip->int_enable[1] &= ~BIT(offset); + + spin_unlock_irqrestore(&msm_chip->lock, irq_flags); + return 0; +} + +static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) +{ + unsigned long irq_flags; + struct msm_gpio_chip *msm_chip = get_irq_chip_data(irq); + unsigned offset = irq - gpio_to_irq(msm_chip->chip.base); + unsigned val, mask = BIT(offset); + + spin_lock_irqsave(&msm_chip->lock, irq_flags); + val = readl(msm_chip->regs.int_edge); + if (flow_type & IRQ_TYPE_EDGE_BOTH) { + writel(val | mask, msm_chip->regs.int_edge); + irq_desc[irq].handle_irq = handle_edge_irq; + } else { + writel(val & ~mask, msm_chip->regs.int_edge); + irq_desc[irq].handle_irq = handle_level_irq; + } + if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { + msm_chip->both_edge_detect |= mask; + msm_gpio_update_both_edge_detect(msm_chip); + } else { + msm_chip->both_edge_detect &= ~mask; + val = readl(msm_chip->regs.int_pos); + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) + writel(val | mask, msm_chip->regs.int_pos); + else + writel(val & ~mask, msm_chip->regs.int_pos); } + spin_unlock_irqrestore(&msm_chip->lock, irq_flags); + return 0; } -EXPORT_SYMBOL(msm_gpios_disable); -int msm_gpios_request_enable(const struct msm_gpio *table, int size) +static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { - int rc = msm_gpios_enable(table, size); - return rc; + int i, j, mask; + unsigned val; + + for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) { + struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i]; + val = readl(msm_chip->regs.int_status); + val &= msm_chip->int_enable[0]; + while (val) { + mask = val & -val; + j = fls(mask) - 1; + /* printk("%s %08x %08x bit %d gpio %d irq %d\n", + __func__, v, m, j, msm_chip->chip.start + j, + FIRST_GPIO_IRQ + msm_chip->chip.start + j); */ + val &= ~mask; + generic_handle_irq(FIRST_GPIO_IRQ + + msm_chip->chip.base + j); + } + } + desc->chip->ack(irq); } -EXPORT_SYMBOL(msm_gpios_request_enable); -void msm_gpios_disable_free(const struct msm_gpio *table, int size) +static struct irq_chip msm_gpio_irq_chip = { + .name = "msmgpio", + .ack = msm_gpio_irq_ack, + .mask = msm_gpio_irq_mask, + .unmask = msm_gpio_irq_unmask, + .set_wake = msm_gpio_irq_set_wake, + .set_type = msm_gpio_irq_set_type, +}; + +static int __init msm_init_gpio(void) { - msm_gpios_disable(table, size); + int i, j = 0; + + for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) { + if (i - FIRST_GPIO_IRQ >= + msm_gpio_chips[j].chip.base + + msm_gpio_chips[j].chip.ngpio) + j++; + set_irq_chip_data(i, &msm_gpio_chips[j]); + set_irq_chip(i, &msm_gpio_irq_chip); + set_irq_handler(i, handle_edge_irq); + set_irq_flags(i, IRQF_VALID); + } + + for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) { + spin_lock_init(&msm_gpio_chips[i].lock); + writel(0, msm_gpio_chips[i].regs.int_en); + gpiochip_add(&msm_gpio_chips[i].chip); + } + + set_irq_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler); + set_irq_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler); + set_irq_wake(INT_GPIO_GROUP1, 1); + set_irq_wake(INT_GPIO_GROUP2, 2); + return 0; } -EXPORT_SYMBOL(msm_gpios_disable_free); + +postcore_initcall(msm_init_gpio); diff --git a/arch/arm/mach-msm/gpio_hw.h b/arch/arm/mach-msm/gpio_hw.h new file mode 100644 index 000000000000..6b5066038baa --- /dev/null +++ b/arch/arm/mach-msm/gpio_hw.h @@ -0,0 +1,278 @@ +/* arch/arm/mach-msm/gpio_hw.h + * + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland <swetland@google.com> + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_H +#define __ARCH_ARM_MACH_MSM_GPIO_HW_H + +#include <mach/msm_iomap.h> + +/* see 80-VA736-2 Rev C pp 695-751 +** +** These are actually the *shadow* gpio registers, since the +** real ones (which allow full access) are only available to the +** ARM9 side of the world. +** +** Since the _BASE need to be page-aligned when we're mapping them +** to virtual addresses, adjust for the additional offset in these +** macros. +*/ + +#if defined(CONFIG_ARCH_MSM7X30) +#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + (off)) +#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off)) +#else +#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) +#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) +#endif + +#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X25) ||\ + defined(CONFIG_ARCH_MSM7X27) + +/* output value */ +#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */ +#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 42-16 */ +#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-43 */ +#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */ +#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */ +#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 107-121 */ + +/* same pin map as above, output enable */ +#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x10) +#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08) +#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x14) +#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x18) +#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x1C) +#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x54) + +/* same pin map as above, input read */ +#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x34) +#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20) +#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x38) +#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x3C) +#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x40) +#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x44) + +/* same pin map as above, 1=edge 0=level interrup */ +#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60) +#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50) +#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64) +#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68) +#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C) +#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0) + +/* same pin map as above, 1=positive 0=negative */ +#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70) +#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58) +#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74) +#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78) +#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C) +#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC) + +/* same pin map as above, interrupt enable */ +#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80) +#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60) +#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84) +#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88) +#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C) +#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8) + +/* same pin map as above, write 1 to clear interrupt */ +#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90) +#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68) +#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94) +#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98) +#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C) +#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4) + +/* same pin map as above, 1=interrupt pending */ +#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0) +#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70) +#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4) +#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8) +#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC) +#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0) + +#endif + +#if defined(CONFIG_ARCH_QSD8X50) +/* output value */ +#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */ +#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 42-16 */ +#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-43 */ +#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */ +#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 103-95 */ +#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x10) /* gpio 121-104 */ +#define MSM_GPIO_OUT_6 MSM_GPIO1_REG(0x14) /* gpio 152-122 */ +#define MSM_GPIO_OUT_7 MSM_GPIO1_REG(0x18) /* gpio 164-153 */ + +/* same pin map as above, output enable */ +#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x20) +#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08) +#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x24) +#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x28) +#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x2C) +#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x30) +#define MSM_GPIO_OE_6 MSM_GPIO1_REG(0x34) +#define MSM_GPIO_OE_7 MSM_GPIO1_REG(0x38) + +/* same pin map as above, input read */ +#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x50) +#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20) +#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x54) +#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x58) +#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x5C) +#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x60) +#define MSM_GPIO_IN_6 MSM_GPIO1_REG(0x64) +#define MSM_GPIO_IN_7 MSM_GPIO1_REG(0x68) + +/* same pin map as above, 1=edge 0=level interrup */ +#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x70) +#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50) +#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x74) +#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x78) +#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x7C) +#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0x80) +#define MSM_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0x84) +#define MSM_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x88) + +/* same pin map as above, 1=positive 0=negative */ +#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x90) +#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58) +#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x94) +#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x98) +#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x9C) +#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xA0) +#define MSM_GPIO_INT_POS_6 MSM_GPIO1_REG(0xA4) +#define MSM_GPIO_INT_POS_7 MSM_GPIO1_REG(0xA8) + +/* same pin map as above, interrupt enable */ +#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0xB0) +#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60) +#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0xB4) +#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0xB8) +#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0xBC) +#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xC0) +#define MSM_GPIO_INT_EN_6 MSM_GPIO1_REG(0xC4) +#define MSM_GPIO_INT_EN_7 MSM_GPIO1_REG(0xC8) + +/* same pin map as above, write 1 to clear interrupt */ +#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0xD0) +#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68) +#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0xD4) +#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0xD8) +#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0xDC) +#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xE0) +#define MSM_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xE4) +#define MSM_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0xE8) + +/* same pin map as above, 1=interrupt pending */ +#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xF0) +#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70) +#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xF4) +#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xF8) +#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xFC) +#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0x100) +#define MSM_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0x104) +#define MSM_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x108) + +#endif + +#if defined(CONFIG_ARCH_MSM7X30) + +/* output value */ +#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */ +#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 43-16 */ +#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-44 */ +#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */ +#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */ +#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 133-107 */ +#define MSM_GPIO_OUT_6 MSM_GPIO1_REG(0xC4) /* gpio 150-134 */ +#define MSM_GPIO_OUT_7 MSM_GPIO1_REG(0x214) /* gpio 181-151 */ + +/* same pin map as above, output enable */ +#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x10) +#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08) +#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x14) +#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x18) +#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x1C) +#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x54) +#define MSM_GPIO_OE_6 MSM_GPIO1_REG(0xC8) +#define MSM_GPIO_OE_7 MSM_GPIO1_REG(0x218) + +/* same pin map as above, input read */ +#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x34) +#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20) +#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x38) +#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x3C) +#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x40) +#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x44) +#define MSM_GPIO_IN_6 MSM_GPIO1_REG(0xCC) +#define MSM_GPIO_IN_7 MSM_GPIO1_REG(0x21C) + +/* same pin map as above, 1=edge 0=level interrup */ +#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60) +#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50) +#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64) +#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68) +#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C) +#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0) +#define MSM_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0xD0) +#define MSM_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x240) + +/* same pin map as above, 1=positive 0=negative */ +#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70) +#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58) +#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74) +#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78) +#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C) +#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC) +#define MSM_GPIO_INT_POS_6 MSM_GPIO1_REG(0xD4) +#define MSM_GPIO_INT_POS_7 MSM_GPIO1_REG(0x228) + +/* same pin map as above, interrupt enable */ +#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80) +#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60) +#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84) +#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88) +#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C) +#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8) +#define MSM_GPIO_INT_EN_6 MSM_GPIO1_REG(0xD8) +#define MSM_GPIO_INT_EN_7 MSM_GPIO1_REG(0x22C) + +/* same pin map as above, write 1 to clear interrupt */ +#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90) +#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68) +#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94) +#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98) +#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C) +#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4) +#define MSM_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xDC) +#define MSM_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0x230) + +/* same pin map as above, 1=interrupt pending */ +#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0) +#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70) +#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4) +#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8) +#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC) +#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0) +#define MSM_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0xE0) +#define MSM_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x234) + +#endif + +#endif diff --git a/arch/arm/mach-msm/gpiomux-7x30.c b/arch/arm/mach-msm/gpiomux-7x30.c new file mode 100644 index 000000000000..6ce41c5241a5 --- /dev/null +++ b/arch/arm/mach-msm/gpiomux-7x30.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include "gpiomux.h" + +struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = { +#ifdef CONFIG_SERIAL_MSM_CONSOLE + [49] = { /* UART2 RFR */ + .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | + GPIOMUX_FUNC_2 | GPIOMUX_VALID, + }, + [50] = { /* UART2 CTS */ + .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | + GPIOMUX_FUNC_2 | GPIOMUX_VALID, + }, + [51] = { /* UART2 RX */ + .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | + GPIOMUX_FUNC_2 | GPIOMUX_VALID, + }, + [52] = { /* UART2 TX */ + .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | + GPIOMUX_FUNC_2 | GPIOMUX_VALID, + }, +#endif +}; diff --git a/arch/arm/mach-msm/gpiomux-8x50.c b/arch/arm/mach-msm/gpiomux-8x50.c new file mode 100644 index 000000000000..4406e0f4ae95 --- /dev/null +++ b/arch/arm/mach-msm/gpiomux-8x50.c @@ -0,0 +1,28 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include "gpiomux.h" + +struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = { + [86] = { /* UART3 RX */ + .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | + GPIOMUX_FUNC_1 | GPIOMUX_VALID, + }, + [87] = { /* UART3 TX */ + .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN | + GPIOMUX_FUNC_1 | GPIOMUX_VALID, + }, +}; diff --git a/arch/arm/mach-msm/gpiomux-8x60.c b/arch/arm/mach-msm/gpiomux-8x60.c new file mode 100644 index 000000000000..7b380b31bd0e --- /dev/null +++ b/arch/arm/mach-msm/gpiomux-8x60.c @@ -0,0 +1,19 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include "gpiomux.h" + +struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {}; diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c new file mode 100644 index 000000000000..27de2abd7144 --- /dev/null +++ b/arch/arm/mach-msm/gpiomux-v1.c @@ -0,0 +1,33 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include <linux/kernel.h> +#include "gpiomux.h" +#include "proc_comm.h" + +void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val) +{ + unsigned tlmm_config = (val & ~GPIOMUX_CTL_MASK) | + ((gpio & 0x3ff) << 4); + unsigned tlmm_disable = 0; + int rc; + + rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, + &tlmm_config, &tlmm_disable); + if (rc) + pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n", + __func__, rc, tlmm_config, tlmm_disable); +} diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h new file mode 100644 index 000000000000..71d86feba450 --- /dev/null +++ b/arch/arm/mach-msm/gpiomux-v1.h @@ -0,0 +1,67 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H +#define __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H + +#if defined(CONFIG_ARCH_MSM7X30) +#define GPIOMUX_NGPIOS 182 +#elif defined(CONFIG_ARCH_QSD8X50) +#define GPIOMUX_NGPIOS 165 +#else +#define GPIOMUX_NGPIOS 133 +#endif + +typedef u32 gpiomux_config_t; + +enum { + GPIOMUX_DRV_2MA = 0UL << 17, + GPIOMUX_DRV_4MA = 1UL << 17, + GPIOMUX_DRV_6MA = 2UL << 17, + GPIOMUX_DRV_8MA = 3UL << 17, + GPIOMUX_DRV_10MA = 4UL << 17, + GPIOMUX_DRV_12MA = 5UL << 17, + GPIOMUX_DRV_14MA = 6UL << 17, + GPIOMUX_DRV_16MA = 7UL << 17, +}; + +enum { + GPIOMUX_FUNC_GPIO = 0UL, + GPIOMUX_FUNC_1 = 1UL, + GPIOMUX_FUNC_2 = 2UL, + GPIOMUX_FUNC_3 = 3UL, + GPIOMUX_FUNC_4 = 4UL, + GPIOMUX_FUNC_5 = 5UL, + GPIOMUX_FUNC_6 = 6UL, + GPIOMUX_FUNC_7 = 7UL, + GPIOMUX_FUNC_8 = 8UL, + GPIOMUX_FUNC_9 = 9UL, + GPIOMUX_FUNC_A = 10UL, + GPIOMUX_FUNC_B = 11UL, + GPIOMUX_FUNC_C = 12UL, + GPIOMUX_FUNC_D = 13UL, + GPIOMUX_FUNC_E = 14UL, + GPIOMUX_FUNC_F = 15UL, +}; + +enum { + GPIOMUX_PULL_NONE = 0UL << 15, + GPIOMUX_PULL_DOWN = 1UL << 15, + GPIOMUX_PULL_KEEPER = 2UL << 15, + GPIOMUX_PULL_UP = 3UL << 15, +}; + +#endif diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c new file mode 100644 index 000000000000..273396d2b127 --- /dev/null +++ b/arch/arm/mach-msm/gpiomux-v2.c @@ -0,0 +1,25 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include <linux/io.h> +#include <mach/msm_iomap.h> +#include "gpiomux.h" + +void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val) +{ + writel(val & ~GPIOMUX_CTL_MASK, + MSM_TLMM_BASE + 0x1000 + (0x10 * gpio)); +} diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h new file mode 100644 index 000000000000..3bf10e7f0381 --- /dev/null +++ b/arch/arm/mach-msm/gpiomux-v2.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H +#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H + +#define GPIOMUX_NGPIOS 173 + +typedef u16 gpiomux_config_t; + +enum { + GPIOMUX_DRV_2MA = 0UL << 6, + GPIOMUX_DRV_4MA = 1UL << 6, + GPIOMUX_DRV_6MA = 2UL << 6, + GPIOMUX_DRV_8MA = 3UL << 6, + GPIOMUX_DRV_10MA = 4UL << 6, + GPIOMUX_DRV_12MA = 5UL << 6, + GPIOMUX_DRV_14MA = 6UL << 6, + GPIOMUX_DRV_16MA = 7UL << 6, +}; + +enum { + GPIOMUX_FUNC_GPIO = 0UL << 2, + GPIOMUX_FUNC_1 = 1UL << 2, + GPIOMUX_FUNC_2 = 2UL << 2, + GPIOMUX_FUNC_3 = 3UL << 2, + GPIOMUX_FUNC_4 = 4UL << 2, + GPIOMUX_FUNC_5 = 5UL << 2, + GPIOMUX_FUNC_6 = 6UL << 2, + GPIOMUX_FUNC_7 = 7UL << 2, + GPIOMUX_FUNC_8 = 8UL << 2, + GPIOMUX_FUNC_9 = 9UL << 2, + GPIOMUX_FUNC_A = 10UL << 2, + GPIOMUX_FUNC_B = 11UL << 2, + GPIOMUX_FUNC_C = 12UL << 2, + GPIOMUX_FUNC_D = 13UL << 2, + GPIOMUX_FUNC_E = 14UL << 2, + GPIOMUX_FUNC_F = 15UL << 2, +}; + +enum { + GPIOMUX_PULL_NONE = 0UL, + GPIOMUX_PULL_DOWN = 1UL, + GPIOMUX_PULL_KEEPER = 2UL, + GPIOMUX_PULL_UP = 3UL, +}; + +#endif diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c new file mode 100644 index 000000000000..53af21abd155 --- /dev/null +++ b/arch/arm/mach-msm/gpiomux.c @@ -0,0 +1,96 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#include <linux/module.h> +#include <linux/spinlock.h> +#include "gpiomux.h" + +static DEFINE_SPINLOCK(gpiomux_lock); + +int msm_gpiomux_write(unsigned gpio, + gpiomux_config_t active, + gpiomux_config_t suspended) +{ + struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio; + unsigned long irq_flags; + gpiomux_config_t setting; + + if (gpio >= GPIOMUX_NGPIOS) + return -EINVAL; + + spin_lock_irqsave(&gpiomux_lock, irq_flags); + + if (active & GPIOMUX_VALID) + cfg->active = active; + + if (suspended & GPIOMUX_VALID) + cfg->suspended = suspended; + + setting = cfg->ref ? active : suspended; + if (setting & GPIOMUX_VALID) + __msm_gpiomux_write(gpio, setting); + + spin_unlock_irqrestore(&gpiomux_lock, irq_flags); + return 0; +} +EXPORT_SYMBOL(msm_gpiomux_write); + +int msm_gpiomux_get(unsigned gpio) +{ + struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio; + unsigned long irq_flags; + + if (gpio >= GPIOMUX_NGPIOS) + return -EINVAL; + + spin_lock_irqsave(&gpiomux_lock, irq_flags); + if (cfg->ref++ == 0 && cfg->active & GPIOMUX_VALID) + __msm_gpiomux_write(gpio, cfg->active); + spin_unlock_irqrestore(&gpiomux_lock, irq_flags); + return 0; +} +EXPORT_SYMBOL(msm_gpiomux_get); + +int msm_gpiomux_put(unsigned gpio) +{ + struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio; + unsigned long irq_flags; + + if (gpio >= GPIOMUX_NGPIOS) + return -EINVAL; + + spin_lock_irqsave(&gpiomux_lock, irq_flags); + BUG_ON(cfg->ref == 0); + if (--cfg->ref == 0 && cfg->suspended & GPIOMUX_VALID) + __msm_gpiomux_write(gpio, cfg->suspended); + spin_unlock_irqrestore(&gpiomux_lock, irq_flags); + return 0; +} +EXPORT_SYMBOL(msm_gpiomux_put); + +static int __init gpiomux_init(void) +{ + unsigned n; + + for (n = 0; n < GPIOMUX_NGPIOS; ++n) { + msm_gpiomux_configs[n].ref = 0; + if (!(msm_gpiomux_configs[n].suspended & GPIOMUX_VALID)) + continue; + __msm_gpiomux_write(n, msm_gpiomux_configs[n].suspended); + } + return 0; +} +postcore_initcall(gpiomux_init); diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h new file mode 100644 index 000000000000..b178d9cb742f --- /dev/null +++ b/arch/arm/mach-msm/gpiomux.h @@ -0,0 +1,114 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_H +#define __ARCH_ARM_MACH_MSM_GPIOMUX_H + +#include <linux/bitops.h> +#include <linux/errno.h> + +#if defined(CONFIG_MSM_V2_TLMM) +#include "gpiomux-v2.h" +#else +#include "gpiomux-v1.h" +#endif + +/** + * struct msm_gpiomux_config: gpiomux settings for one gpio line. + * + * A complete gpiomux config is the bitwise-or of a drive-strength, + * function, and pull. For functions other than GPIO, the OE + * is hard-wired according to the function. For GPIO mode, + * OE is controlled by gpiolib. + * + * Available settings differ by target; see the gpiomux header + * specific to your target arch for available configurations. + * + * @active: The configuration to be installed when the line is + * active, or its reference count is > 0. + * @suspended: The configuration to be installed when the line + * is suspended, or its reference count is 0. + * @ref: The reference count of the line. For internal use of + * the gpiomux framework only. + */ +struct msm_gpiomux_config { + gpiomux_config_t active; + gpiomux_config_t suspended; + unsigned ref; +}; + +/** + * @GPIOMUX_VALID: If set, the config field contains 'good data'. + * The absence of this bit will prevent the gpiomux + * system from applying the configuration under all + * circumstances. + */ +enum { + GPIOMUX_VALID = BIT(sizeof(gpiomux_config_t) * BITS_PER_BYTE - 1), + GPIOMUX_CTL_MASK = GPIOMUX_VALID, +}; + +#ifdef CONFIG_MSM_GPIOMUX + +/* Each architecture must provide its own instance of this table. + * To avoid having gpiomux manage any given gpio, one or both of + * the entries can avoid setting GPIOMUX_VALID - the absence + * of that flag will prevent the configuration from being applied + * during state transitions. + */ +extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS]; + +/* Increment a gpio's reference count, possibly activating the line. */ +int __must_check msm_gpiomux_get(unsigned gpio); + +/* Decrement a gpio's reference count, possibly suspending the line. */ +int msm_gpiomux_put(unsigned gpio); + +/* Install a new configuration to the gpio line. To avoid overwriting + * a configuration, leave the VALID bit out. + */ +int msm_gpiomux_write(unsigned gpio, + gpiomux_config_t active, + gpiomux_config_t suspended); + +/* Architecture-internal function for use by the framework only. + * This function can assume the following: + * - the gpio value has passed a bounds-check + * - the gpiomux spinlock has been obtained + * + * This function is not for public consumption. External users + * should use msm_gpiomux_write. + */ +void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val); +#else +static inline int __must_check msm_gpiomux_get(unsigned gpio) +{ + return -ENOSYS; +} + +static inline int msm_gpiomux_put(unsigned gpio) +{ + return -ENOSYS; +} + +static inline int msm_gpiomux_write(unsigned gpio, + gpiomux_config_t active, + gpiomux_config_t suspended) +{ + return -ENOSYS; +} +#endif +#endif diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h index 5a79bcf50413..6abf4a6eadc1 100644 --- a/arch/arm/mach-msm/include/mach/board.h +++ b/arch/arm/mach-msm/include/mach/board.h @@ -33,6 +33,8 @@ struct msm_acpu_clock_platform_data struct clk; +extern struct sys_timer msm_timer; + /* common init routines for use by arch/arm/mach-msm/board-*.c */ void __init msm_add_devices(void); diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S index 528750f307e9..238c4f132cdb 100644 --- a/arch/arm/mach-msm/include/mach/debug-macro.S +++ b/arch/arm/mach-msm/include/mach/debug-macro.S @@ -19,7 +19,7 @@ #include <mach/hardware.h> #include <mach/msm_iomap.h> -#ifdef CONFIG_MSM_DEBUG_UART +#ifdef CONFIG_HAS_MSM_DEBUG_UART_PHYS .macro addruart, rx, tmp @ see if the MMU is enabled and select appropriate base address mrc p15, 0, \rx, c1, c0 diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h index 00f9bbfadbe6..05583f569524 100644 --- a/arch/arm/mach-msm/include/mach/dma.h +++ b/arch/arm/mach-msm/include/mach/dma.h @@ -32,10 +32,18 @@ struct msm_dmov_cmd { void *data; }; +#ifndef CONFIG_ARCH_MSM8X60 void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd); void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful); int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr); - +#else +static inline +void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { } +static inline +void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { } +static inline +int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; } +#endif #define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2)) diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S new file mode 100644 index 000000000000..4dc99aa65d07 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S @@ -0,0 +1,88 @@ +/* + * Low-level IRQ helper macros + * + * Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <mach/hardware.h> +#include <asm/hardware/gic.h> + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =gic_cpu_base_addr + ldr \base, [\base] + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + /* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Migrated the code from ARM MP port to be more consistant + * with interrupt processing , the following still holds true + * however, all interrupts are treated the same regardless of + * if they are local IPI or PPI + * + * Interrupts 0-15 are IPI + * 16-31 are PPI + * (16-18 are the timers) + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * A simple read from the controller will tell us the number of the + * highest priority enabled interrupt. We then just need to check + * whether it is in the valid range for an IRQ (0-1020 inclusive). + * + * Base ARM code assumes that the local (private) peripheral interrupts + * are not valid, we treat them differently, in that the privates are + * handled like normal shared interrupts with the exception that only + * one processor can register the interrupt and the handler must be + * the same for all processors. + */ + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 =srcCPU, + 9-0 =int # */ + + bic \irqnr, \irqstat, #0x1c00 @mask src + cmp \irqnr, #15 + ldr \tmp, =1021 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + + .endm + + /* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt on the + * controller, since this requires the original irqstat value which + * we won't easily be able to recreate later. + */ + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + strcc \irqstat, [\base, #GIC_CPU_EOI] + cmpcs \irqnr, \irqnr + .endm + + /* As above, this assumes that irqstat and base are preserved.. */ + + .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #16 + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 + .endm diff --git a/arch/arm/mach-msm/include/mach/entry-macro-vic.S b/arch/arm/mach-msm/include/mach/entry-macro-vic.S new file mode 100644 index 000000000000..70563ed11b36 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/entry-macro-vic.S @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Author: Brian Swetland <swetland@google.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <mach/msm_iomap.h> + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + @ enable imprecise aborts + cpsie a + mov \base, #MSM_VIC_BASE + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + @ 0xD0 has irq# or old irq# if the irq has been handled + @ 0xD4 has irq# or -1 if none pending *but* if you just + @ read 0xD4 you never get the first irq for some reason + ldr \irqnr, [\base, #0xD0] + ldr \irqnr, [\base, #0xD4] + cmp \irqnr, #0xffffffff + .endm diff --git a/arch/arm/mach-msm/include/mach/entry-macro.S b/arch/arm/mach-msm/include/mach/entry-macro.S index d2259486bcb1..b16f082eeb6f 100644 --- a/arch/arm/mach-msm/include/mach/entry-macro.S +++ b/arch/arm/mach-msm/include/mach/entry-macro.S @@ -1,38 +1,23 @@ -/* arch/arm/mach-msm7200/include/mach/entry-macro.S +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. * - * Copyright (C) 2007 Google, Inc. - * Author: Brian Swetland <swetland@google.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * */ -#include <mach/msm_iomap.h> - - .macro disable_fiq - .endm - - .macro get_irqnr_preamble, base, tmp - @ enable imprecise aborts - cpsie a - mov \base, #MSM_VIC_BASE - .endm - - .macro arch_ret_to_user, tmp1, tmp2 - .endm - - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - @ 0xD0 has irq# or old irq# if the irq has been handled - @ 0xD4 has irq# or -1 if none pending *but* if you just - @ read 0xD4 you never get the first irq for some reason - ldr \irqnr, [\base, #0xD0] - ldr \irqnr, [\base, #0xD4] - cmp \irqnr, #0xffffffff - .endm +#if defined(CONFIG_ARM_GIC) +#include <mach/entry-macro-qgic.S> +#else +#include <mach/entry-macro-vic.S> +#endif diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h index 83e47c0d5c2e..36ad50d3bfaa 100644 --- a/arch/arm/mach-msm/include/mach/gpio.h +++ b/arch/arm/mach-msm/include/mach/gpio.h @@ -23,127 +23,4 @@ #define gpio_cansleep __gpio_cansleep #define gpio_to_irq __gpio_to_irq -/** - * struct msm_gpio - GPIO pin description - * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config() - * @label - textual label - * - * Usually, GPIO's are operated by sets. - * This struct accumulate all GPIO information in single source - * and facilitete group operations provided by msm_gpios_xxx() - */ -struct msm_gpio { - u32 gpio_cfg; - const char *label; -}; - -/** - * msm_gpios_request_enable() - request and enable set of GPIOs - * - * Request and configure set of GPIO's - * In case of error, all operations rolled back. - * Return error code. - * - * @table: GPIO table - * @size: number of entries in @table - */ -int msm_gpios_request_enable(const struct msm_gpio *table, int size); - -/** - * msm_gpios_disable_free() - disable and free set of GPIOs - * - * @table: GPIO table - * @size: number of entries in @table - */ -void msm_gpios_disable_free(const struct msm_gpio *table, int size); - -/** - * msm_gpios_request() - request set of GPIOs - * In case of error, all operations rolled back. - * Return error code. - * - * @table: GPIO table - * @size: number of entries in @table - */ -int msm_gpios_request(const struct msm_gpio *table, int size); - -/** - * msm_gpios_free() - free set of GPIOs - * - * @table: GPIO table - * @size: number of entries in @table - */ -void msm_gpios_free(const struct msm_gpio *table, int size); - -/** - * msm_gpios_enable() - enable set of GPIOs - * In case of error, all operations rolled back. - * Return error code. - * - * @table: GPIO table - * @size: number of entries in @table - */ -int msm_gpios_enable(const struct msm_gpio *table, int size); - -/** - * msm_gpios_disable() - disable set of GPIOs - * - * @table: GPIO table - * @size: number of entries in @table - */ -void msm_gpios_disable(const struct msm_gpio *table, int size); - -/* GPIO TLMM (Top Level Multiplexing) Definitions */ - -/* GPIO TLMM: Function -- GPIO specific */ - -/* GPIO TLMM: Direction */ -enum { - GPIO_INPUT, - GPIO_OUTPUT, -}; - -/* GPIO TLMM: Pullup/Pulldown */ -enum { - GPIO_NO_PULL, - GPIO_PULL_DOWN, - GPIO_KEEPER, - GPIO_PULL_UP, -}; - -/* GPIO TLMM: Drive Strength */ -enum { - GPIO_2MA, - GPIO_4MA, - GPIO_6MA, - GPIO_8MA, - GPIO_10MA, - GPIO_12MA, - GPIO_14MA, - GPIO_16MA, -}; - -enum { - GPIO_ENABLE, - GPIO_DISABLE, -}; - -#define GPIO_CFG(gpio, func, dir, pull, drvstr) \ - ((((gpio) & 0x3FF) << 4) | \ - ((func) & 0xf) | \ - (((dir) & 0x1) << 14) | \ - (((pull) & 0x3) << 15) | \ - (((drvstr) & 0xF) << 17)) - -/** - * extract GPIO pin from bit-field used for gpio_tlmm_config - */ -#define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff) -#define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf) -#define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1) -#define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3) -#define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf) - -int gpio_tlmm_config(unsigned config, unsigned disable); - #endif /* __ASM_ARCH_MSM_GPIO_H */ diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h index c35b29f9ac0f..7386e732baad 100644 --- a/arch/arm/mach-msm/include/mach/io.h +++ b/arch/arm/mach-msm/include/mach/io.h @@ -28,6 +28,7 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m void msm_map_qsd8x50_io(void); void msm_map_msm7x30_io(void); +void msm_map_msm8x60_io(void); extern unsigned int msm_shared_ram_phys; diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h new file mode 100644 index 000000000000..218ef5732a24 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/iommu.h @@ -0,0 +1,103 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef MSM_IOMMU_H +#define MSM_IOMMU_H + +#include <linux/interrupt.h> + +/* Maximum number of Machine IDs that we are allowing to be mapped to the same + * context bank. The number of MIDs mapped to the same CB does not affect + * performance, but there is a practical limit on how many distinct MIDs may + * be present. These mappings are typically determined at design time and are + * not expected to change at run time. + */ +#define MAX_NUM_MIDS 16 + +/** + * struct msm_iommu_dev - a single IOMMU hardware instance + * name Human-readable name given to this IOMMU HW instance + * clk_rate Rate to set for this IOMMU's clock, if applicable to this + * particular IOMMU. 0 means don't set a rate. + * -1 means it is an AXI clock with no valid rate + * + */ +struct msm_iommu_dev { + const char *name; + int clk_rate; +}; + +/** + * struct msm_iommu_ctx_dev - an IOMMU context bank instance + * name Human-readable name given to this context bank + * num Index of this context bank within the hardware + * mids List of Machine IDs that are to be mapped into this context + * bank, terminated by -1. The MID is a set of signals on the + * AXI bus that identifies the function associated with a specific + * memory request. (See ARM spec). + */ +struct msm_iommu_ctx_dev { + const char *name; + int num; + int mids[MAX_NUM_MIDS]; +}; + + +/** + * struct msm_iommu_drvdata - A single IOMMU hardware instance + * @base: IOMMU config port base address (VA) + * @irq: Interrupt number + * + * A msm_iommu_drvdata holds the global driver data about a single piece + * of an IOMMU hardware instance. + */ +struct msm_iommu_drvdata { + void __iomem *base; + int irq; +}; + +/** + * struct msm_iommu_ctx_drvdata - an IOMMU context bank instance + * @num: Hardware context number of this context + * @pdev: Platform device associated wit this HW instance + * @attached_elm: List element for domains to track which devices are + * attached to them + * + * A msm_iommu_ctx_drvdata holds the driver data for a single context bank + * within each IOMMU hardware instance + */ +struct msm_iommu_ctx_drvdata { + int num; + struct platform_device *pdev; + struct list_head attached_elm; +}; + +/* + * Look up an IOMMU context device by its context name. NULL if none found. + * Useful for testing and drivers that do not yet fully have IOMMU stuff in + * their platform devices. + */ +struct device *msm_iommu_get_ctx(const char *ctx_name); + +/* + * Interrupt handler for the IOMMU context fault interrupt. Hooking the + * interrupt is not supported in the API yet, but this will print an error + * message and dump useful IOMMU registers. + */ +irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id); + +#endif diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h new file mode 100644 index 000000000000..f9386d3a2f77 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h @@ -0,0 +1,1871 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H +#define __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H + +#define CTX_SHIFT 12 + +#define GET_GLOBAL_REG(reg, base) (readl((base) + (reg))) +#define GET_CTX_REG(reg, base, ctx) \ + (readl((base) + (reg) + ((ctx) << CTX_SHIFT))) + +#define SET_GLOBAL_REG(reg, base, val) writel((val), ((base) + (reg))) + +#define SET_CTX_REG(reg, base, ctx, val) \ + writel((val), ((base) + (reg) + ((ctx) << CTX_SHIFT))) + +/* Wrappers for numbered registers */ +#define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG(b, ((r) + (n << 2)), (v)) +#define GET_GLOBAL_REG_N(b, n, r) GET_GLOBAL_REG(b, ((r) + (n << 2))) + +/* Field wrappers */ +#define GET_GLOBAL_FIELD(b, r, F) GET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT) +#define GET_CONTEXT_FIELD(b, c, r, F) \ + GET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT) + +#define SET_GLOBAL_FIELD(b, r, F, v) \ + SET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT, (v)) +#define SET_CONTEXT_FIELD(b, c, r, F, v) \ + SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT, (v)) + +#define GET_FIELD(addr, mask, shift) ((readl(addr) >> (shift)) & (mask)) + +#define SET_FIELD(addr, mask, shift, v) \ +do { \ + int t = readl(addr); \ + writel((t & ~((mask) << (shift))) + (((v) & (mask)) << (shift)), addr);\ +} while (0) + + +#define NUM_FL_PTE 4096 +#define NUM_SL_PTE 256 + +/* First-level page table bits */ +#define FL_BASE_MASK 0xFFFFFC00 +#define FL_TYPE_TABLE (1 << 0) +#define FL_TYPE_SECT (2 << 0) +#define FL_SUPERSECTION (1 << 18) +#define FL_AP_WRITE (1 << 10) +#define FL_AP_READ (1 << 11) +#define FL_SHARED (1 << 16) +#define FL_OFFSET(va) (((va) & 0xFFF00000) >> 20) + +/* Second-level page table bits */ +#define SL_BASE_MASK_LARGE 0xFFFF0000 +#define SL_BASE_MASK_SMALL 0xFFFFF000 +#define SL_TYPE_LARGE (1 << 0) +#define SL_TYPE_SMALL (2 << 0) +#define SL_AP0 (1 << 4) +#define SL_AP1 (2 << 4) +#define SL_SHARED (1 << 10) +#define SL_OFFSET(va) (((va) & 0xFF000) >> 12) + +/* Global register setters / getters */ +#define SET_M2VCBR_N(b, N, v) SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v)) +#define SET_CBACR_N(b, N, v) SET_GLOBAL_REG_N(CBACR_N, N, (b), (v)) +#define SET_TLBRSW(b, v) SET_GLOBAL_REG(TLBRSW, (b), (v)) +#define SET_TLBTR0(b, v) SET_GLOBAL_REG(TLBTR0, (b), (v)) +#define SET_TLBTR1(b, v) SET_GLOBAL_REG(TLBTR1, (b), (v)) +#define SET_TLBTR2(b, v) SET_GLOBAL_REG(TLBTR2, (b), (v)) +#define SET_TESTBUSCR(b, v) SET_GLOBAL_REG(TESTBUSCR, (b), (v)) +#define SET_GLOBAL_TLBIALL(b, v) SET_GLOBAL_REG(GLOBAL_TLBIALL, (b), (v)) +#define SET_TLBIVMID(b, v) SET_GLOBAL_REG(TLBIVMID, (b), (v)) +#define SET_CR(b, v) SET_GLOBAL_REG(CR, (b), (v)) +#define SET_EAR(b, v) SET_GLOBAL_REG(EAR, (b), (v)) +#define SET_ESR(b, v) SET_GLOBAL_REG(ESR, (b), (v)) +#define SET_ESRRESTORE(b, v) SET_GLOBAL_REG(ESRRESTORE, (b), (v)) +#define SET_ESYNR0(b, v) SET_GLOBAL_REG(ESYNR0, (b), (v)) +#define SET_ESYNR1(b, v) SET_GLOBAL_REG(ESYNR1, (b), (v)) +#define SET_RPU_ACR(b, v) SET_GLOBAL_REG(RPU_ACR, (b), (v)) + +#define GET_M2VCBR_N(b, N) GET_GLOBAL_REG_N(M2VCBR_N, N, (b)) +#define GET_CBACR_N(b, N) GET_GLOBAL_REG_N(CBACR_N, N, (b)) +#define GET_TLBTR0(b) GET_GLOBAL_REG(TLBTR0, (b)) +#define GET_TLBTR1(b) GET_GLOBAL_REG(TLBTR1, (b)) +#define GET_TLBTR2(b) GET_GLOBAL_REG(TLBTR2, (b)) +#define GET_TESTBUSCR(b) GET_GLOBAL_REG(TESTBUSCR, (b)) +#define GET_GLOBAL_TLBIALL(b) GET_GLOBAL_REG(GLOBAL_TLBIALL, (b)) +#define GET_TLBIVMID(b) GET_GLOBAL_REG(TLBIVMID, (b)) +#define GET_CR(b) GET_GLOBAL_REG(CR, (b)) +#define GET_EAR(b) GET_GLOBAL_REG(EAR, (b)) +#define GET_ESR(b) GET_GLOBAL_REG(ESR, (b)) +#define GET_ESRRESTORE(b) GET_GLOBAL_REG(ESRRESTORE, (b)) +#define GET_ESYNR0(b) GET_GLOBAL_REG(ESYNR0, (b)) +#define GET_ESYNR1(b) GET_GLOBAL_REG(ESYNR1, (b)) +#define GET_REV(b) GET_GLOBAL_REG(REV, (b)) +#define GET_IDR(b) GET_GLOBAL_REG(IDR, (b)) +#define GET_RPU_ACR(b) GET_GLOBAL_REG(RPU_ACR, (b)) + + +/* Context register setters/getters */ +#define SET_SCTLR(b, c, v) SET_CTX_REG(SCTLR, (b), (c), (v)) +#define SET_ACTLR(b, c, v) SET_CTX_REG(ACTLR, (b), (c), (v)) +#define SET_CONTEXTIDR(b, c, v) SET_CTX_REG(CONTEXTIDR, (b), (c), (v)) +#define SET_TTBR0(b, c, v) SET_CTX_REG(TTBR0, (b), (c), (v)) +#define SET_TTBR1(b, c, v) SET_CTX_REG(TTBR1, (b), (c), (v)) +#define SET_TTBCR(b, c, v) SET_CTX_REG(TTBCR, (b), (c), (v)) +#define SET_PAR(b, c, v) SET_CTX_REG(PAR, (b), (c), (v)) +#define SET_FSR(b, c, v) SET_CTX_REG(FSR, (b), (c), (v)) +#define SET_FSRRESTORE(b, c, v) SET_CTX_REG(FSRRESTORE, (b), (c), (v)) +#define SET_FAR(b, c, v) SET_CTX_REG(FAR, (b), (c), (v)) +#define SET_FSYNR0(b, c, v) SET_CTX_REG(FSYNR0, (b), (c), (v)) +#define SET_FSYNR1(b, c, v) SET_CTX_REG(FSYNR1, (b), (c), (v)) +#define SET_PRRR(b, c, v) SET_CTX_REG(PRRR, (b), (c), (v)) +#define SET_NMRR(b, c, v) SET_CTX_REG(NMRR, (b), (c), (v)) +#define SET_TLBLKCR(b, c, v) SET_CTX_REG(TLBLCKR, (b), (c), (v)) +#define SET_V2PSR(b, c, v) SET_CTX_REG(V2PSR, (b), (c), (v)) +#define SET_TLBFLPTER(b, c, v) SET_CTX_REG(TLBFLPTER, (b), (c), (v)) +#define SET_TLBSLPTER(b, c, v) SET_CTX_REG(TLBSLPTER, (b), (c), (v)) +#define SET_BFBCR(b, c, v) SET_CTX_REG(BFBCR, (b), (c), (v)) +#define SET_CTX_TLBIALL(b, c, v) SET_CTX_REG(CTX_TLBIALL, (b), (c), (v)) +#define SET_TLBIASID(b, c, v) SET_CTX_REG(TLBIASID, (b), (c), (v)) +#define SET_TLBIVA(b, c, v) SET_CTX_REG(TLBIVA, (b), (c), (v)) +#define SET_TLBIVAA(b, c, v) SET_CTX_REG(TLBIVAA, (b), (c), (v)) +#define SET_V2PPR(b, c, v) SET_CTX_REG(V2PPR, (b), (c), (v)) +#define SET_V2PPW(b, c, v) SET_CTX_REG(V2PPW, (b), (c), (v)) +#define SET_V2PUR(b, c, v) SET_CTX_REG(V2PUR, (b), (c), (v)) +#define SET_V2PUW(b, c, v) SET_CTX_REG(V2PUW, (b), (c), (v)) +#define SET_RESUME(b, c, v) SET_CTX_REG(RESUME, (b), (c), (v)) + +#define GET_SCTLR(b, c) GET_CTX_REG(SCTLR, (b), (c)) +#define GET_ACTLR(b, c) GET_CTX_REG(ACTLR, (b), (c)) +#define GET_CONTEXTIDR(b, c) GET_CTX_REG(CONTEXTIDR, (b), (c)) +#define GET_TTBR0(b, c) GET_CTX_REG(TTBR0, (b), (c)) +#define GET_TTBR1(b, c) GET_CTX_REG(TTBR1, (b), (c)) +#define GET_TTBCR(b, c) GET_CTX_REG(TTBCR, (b), (c)) +#define GET_PAR(b, c) GET_CTX_REG(PAR, (b), (c)) +#define GET_FSR(b, c) GET_CTX_REG(FSR, (b), (c)) +#define GET_FSRRESTORE(b, c) GET_CTX_REG(FSRRESTORE, (b), (c)) +#define GET_FAR(b, c) GET_CTX_REG(FAR, (b), (c)) +#define GET_FSYNR0(b, c) GET_CTX_REG(FSYNR0, (b), (c)) +#define GET_FSYNR1(b, c) GET_CTX_REG(FSYNR1, (b), (c)) +#define GET_PRRR(b, c) GET_CTX_REG(PRRR, (b), (c)) +#define GET_NMRR(b, c) GET_CTX_REG(NMRR, (b), (c)) +#define GET_TLBLCKR(b, c) GET_CTX_REG(TLBLCKR, (b), (c)) +#define GET_V2PSR(b, c) GET_CTX_REG(V2PSR, (b), (c)) +#define GET_TLBFLPTER(b, c) GET_CTX_REG(TLBFLPTER, (b), (c)) +#define GET_TLBSLPTER(b, c) GET_CTX_REG(TLBSLPTER, (b), (c)) +#define GET_BFBCR(b, c) GET_CTX_REG(BFBCR, (b), (c)) +#define GET_CTX_TLBIALL(b, c) GET_CTX_REG(CTX_TLBIALL, (b), (c)) +#define GET_TLBIASID(b, c) GET_CTX_REG(TLBIASID, (b), (c)) +#define GET_TLBIVA(b, c) GET_CTX_REG(TLBIVA, (b), (c)) +#define GET_TLBIVAA(b, c) GET_CTX_REG(TLBIVAA, (b), (c)) +#define GET_V2PPR(b, c) GET_CTX_REG(V2PPR, (b), (c)) +#define GET_V2PPW(b, c) GET_CTX_REG(V2PPW, (b), (c)) +#define GET_V2PUR(b, c) GET_CTX_REG(V2PUR, (b), (c)) +#define GET_V2PUW(b, c) GET_CTX_REG(V2PUW, (b), (c)) +#define GET_RESUME(b, c) GET_CTX_REG(RESUME, (b), (c)) + + +/* Global field setters / getters */ +/* Global Field Setters: */ +/* CBACR_N */ +#define SET_RWVMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID, v) +#define SET_RWE(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE, v) +#define SET_RWGE(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE, v) +#define SET_CBVMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID, v) +#define SET_IRPTNDX(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX, v) + + +/* M2VCBR_N */ +#define SET_VMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID, v) +#define SET_CBNDX(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX, v) +#define SET_BYPASSD(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD, v) +#define SET_BPRCOSH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH, v) +#define SET_BPRCISH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH, v) +#define SET_BPRCNSH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH, v) +#define SET_BPSHCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG, v) +#define SET_NSCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG, v) +#define SET_BPMTCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG, v) +#define SET_BPMEMTYPE(b, n, v) \ + SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE, v) + + +/* CR */ +#define SET_RPUE(b, v) SET_GLOBAL_FIELD(b, CR, RPUE, v) +#define SET_RPUERE(b, v) SET_GLOBAL_FIELD(b, CR, RPUERE, v) +#define SET_RPUEIE(b, v) SET_GLOBAL_FIELD(b, CR, RPUEIE, v) +#define SET_DCDEE(b, v) SET_GLOBAL_FIELD(b, CR, DCDEE, v) +#define SET_CLIENTPD(b, v) SET_GLOBAL_FIELD(b, CR, CLIENTPD, v) +#define SET_STALLD(b, v) SET_GLOBAL_FIELD(b, CR, STALLD, v) +#define SET_TLBLKCRWE(b, v) SET_GLOBAL_FIELD(b, CR, TLBLKCRWE, v) +#define SET_CR_TLBIALLCFG(b, v) SET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG, v) +#define SET_TLBIVMIDCFG(b, v) SET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG, v) +#define SET_CR_HUME(b, v) SET_GLOBAL_FIELD(b, CR, CR_HUME, v) + + +/* ESR */ +#define SET_CFG(b, v) SET_GLOBAL_FIELD(b, ESR, CFG, v) +#define SET_BYPASS(b, v) SET_GLOBAL_FIELD(b, ESR, BYPASS, v) +#define SET_ESR_MULTI(b, v) SET_GLOBAL_FIELD(b, ESR, ESR_MULTI, v) + + +/* ESYNR0 */ +#define SET_ESYNR0_AMID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID, v) +#define SET_ESYNR0_APID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID, v) +#define SET_ESYNR0_ABID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID, v) +#define SET_ESYNR0_AVMID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID, v) +#define SET_ESYNR0_ATID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID, v) + + +/* ESYNR1 */ +#define SET_ESYNR1_AMEMTYPE(b, v) \ + SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE, v) +#define SET_ESYNR1_ASHARED(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED, v) +#define SET_ESYNR1_AINNERSHARED(b, v) \ + SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED, v) +#define SET_ESYNR1_APRIV(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV, v) +#define SET_ESYNR1_APROTNS(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS, v) +#define SET_ESYNR1_AINST(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST, v) +#define SET_ESYNR1_AWRITE(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE, v) +#define SET_ESYNR1_ABURST(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST, v) +#define SET_ESYNR1_ALEN(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN, v) +#define SET_ESYNR1_ASIZE(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE, v) +#define SET_ESYNR1_ALOCK(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK, v) +#define SET_ESYNR1_AOOO(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO, v) +#define SET_ESYNR1_AFULL(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL, v) +#define SET_ESYNR1_AC(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC, v) +#define SET_ESYNR1_DCD(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD, v) + + +/* TESTBUSCR */ +#define SET_TBE(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBE, v) +#define SET_SPDMBE(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE, v) +#define SET_WGSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL, v) +#define SET_TBLSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL, v) +#define SET_TBHSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL, v) +#define SET_SPDM0SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL, v) +#define SET_SPDM1SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL, v) +#define SET_SPDM2SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL, v) +#define SET_SPDM3SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL, v) + + +/* TLBIVMID */ +#define SET_TLBIVMID_VMID(b, v) SET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID, v) + + +/* TLBRSW */ +#define SET_TLBRSW_INDEX(b, v) SET_GLOBAL_FIELD(b, TLBRSW, TLBRSW_INDEX, v) +#define SET_TLBBFBS(b, v) SET_GLOBAL_FIELD(b, TLBRSW, TLBBFBS, v) + + +/* TLBTR0 */ +#define SET_PR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, PR, v) +#define SET_PW(b, v) SET_GLOBAL_FIELD(b, TLBTR0, PW, v) +#define SET_UR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, UR, v) +#define SET_UW(b, v) SET_GLOBAL_FIELD(b, TLBTR0, UW, v) +#define SET_XN(b, v) SET_GLOBAL_FIELD(b, TLBTR0, XN, v) +#define SET_NSDESC(b, v) SET_GLOBAL_FIELD(b, TLBTR0, NSDESC, v) +#define SET_ISH(b, v) SET_GLOBAL_FIELD(b, TLBTR0, ISH, v) +#define SET_SH(b, v) SET_GLOBAL_FIELD(b, TLBTR0, SH, v) +#define SET_MT(b, v) SET_GLOBAL_FIELD(b, TLBTR0, MT, v) +#define SET_DPSIZR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, DPSIZR, v) +#define SET_DPSIZC(b, v) SET_GLOBAL_FIELD(b, TLBTR0, DPSIZC, v) + + +/* TLBTR1 */ +#define SET_TLBTR1_VMID(b, v) SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID, v) +#define SET_TLBTR1_PA(b, v) SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA, v) + + +/* TLBTR2 */ +#define SET_TLBTR2_ASID(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID, v) +#define SET_TLBTR2_V(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V, v) +#define SET_TLBTR2_NSTID(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID, v) +#define SET_TLBTR2_NV(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV, v) +#define SET_TLBTR2_VA(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA, v) + + +/* Global Field Getters */ +/* CBACR_N */ +#define GET_RWVMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID) +#define GET_RWE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE) +#define GET_RWGE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE) +#define GET_CBVMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID) +#define GET_IRPTNDX(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX) + + +/* M2VCBR_N */ +#define GET_VMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID) +#define GET_CBNDX(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX) +#define GET_BYPASSD(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD) +#define GET_BPRCOSH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH) +#define GET_BPRCISH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH) +#define GET_BPRCNSH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH) +#define GET_BPSHCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG) +#define GET_NSCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG) +#define GET_BPMTCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG) +#define GET_BPMEMTYPE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE) + + +/* CR */ +#define GET_RPUE(b) GET_GLOBAL_FIELD(b, CR, RPUE) +#define GET_RPUERE(b) GET_GLOBAL_FIELD(b, CR, RPUERE) +#define GET_RPUEIE(b) GET_GLOBAL_FIELD(b, CR, RPUEIE) +#define GET_DCDEE(b) GET_GLOBAL_FIELD(b, CR, DCDEE) +#define GET_CLIENTPD(b) GET_GLOBAL_FIELD(b, CR, CLIENTPD) +#define GET_STALLD(b) GET_GLOBAL_FIELD(b, CR, STALLD) +#define GET_TLBLKCRWE(b) GET_GLOBAL_FIELD(b, CR, TLBLKCRWE) +#define GET_CR_TLBIALLCFG(b) GET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG) +#define GET_TLBIVMIDCFG(b) GET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG) +#define GET_CR_HUME(b) GET_GLOBAL_FIELD(b, CR, CR_HUME) + + +/* ESR */ +#define GET_CFG(b) GET_GLOBAL_FIELD(b, ESR, CFG) +#define GET_BYPASS(b) GET_GLOBAL_FIELD(b, ESR, BYPASS) +#define GET_ESR_MULTI(b) GET_GLOBAL_FIELD(b, ESR, ESR_MULTI) + + +/* ESYNR0 */ +#define GET_ESYNR0_AMID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID) +#define GET_ESYNR0_APID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID) +#define GET_ESYNR0_ABID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID) +#define GET_ESYNR0_AVMID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID) +#define GET_ESYNR0_ATID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID) + + +/* ESYNR1 */ +#define GET_ESYNR1_AMEMTYPE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE) +#define GET_ESYNR1_ASHARED(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED) +#define GET_ESYNR1_AINNERSHARED(b) \ + GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED) +#define GET_ESYNR1_APRIV(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV) +#define GET_ESYNR1_APROTNS(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS) +#define GET_ESYNR1_AINST(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST) +#define GET_ESYNR1_AWRITE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE) +#define GET_ESYNR1_ABURST(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST) +#define GET_ESYNR1_ALEN(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN) +#define GET_ESYNR1_ASIZE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE) +#define GET_ESYNR1_ALOCK(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK) +#define GET_ESYNR1_AOOO(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO) +#define GET_ESYNR1_AFULL(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL) +#define GET_ESYNR1_AC(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC) +#define GET_ESYNR1_DCD(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD) + + +/* IDR */ +#define GET_NM2VCBMT(b) GET_GLOBAL_FIELD(b, IDR, NM2VCBMT) +#define GET_HTW(b) GET_GLOBAL_FIELD(b, IDR, HTW) +#define GET_HUM(b) GET_GLOBAL_FIELD(b, IDR, HUM) +#define GET_TLBSIZE(b) GET_GLOBAL_FIELD(b, IDR, TLBSIZE) +#define GET_NCB(b) GET_GLOBAL_FIELD(b, IDR, NCB) +#define GET_NIRPT(b) GET_GLOBAL_FIELD(b, IDR, NIRPT) + + +/* REV */ +#define GET_MAJOR(b) GET_GLOBAL_FIELD(b, REV, MAJOR) +#define GET_MINOR(b) GET_GLOBAL_FIELD(b, REV, MINOR) + + +/* TESTBUSCR */ +#define GET_TBE(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBE) +#define GET_SPDMBE(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE) +#define GET_WGSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL) +#define GET_TBLSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL) +#define GET_TBHSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL) +#define GET_SPDM0SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL) +#define GET_SPDM1SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL) +#define GET_SPDM2SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL) +#define GET_SPDM3SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL) + + +/* TLBIVMID */ +#define GET_TLBIVMID_VMID(b) GET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID) + + +/* TLBTR0 */ +#define GET_PR(b) GET_GLOBAL_FIELD(b, TLBTR0, PR) +#define GET_PW(b) GET_GLOBAL_FIELD(b, TLBTR0, PW) +#define GET_UR(b) GET_GLOBAL_FIELD(b, TLBTR0, UR) +#define GET_UW(b) GET_GLOBAL_FIELD(b, TLBTR0, UW) +#define GET_XN(b) GET_GLOBAL_FIELD(b, TLBTR0, XN) +#define GET_NSDESC(b) GET_GLOBAL_FIELD(b, TLBTR0, NSDESC) +#define GET_ISH(b) GET_GLOBAL_FIELD(b, TLBTR0, ISH) +#define GET_SH(b) GET_GLOBAL_FIELD(b, TLBTR0, SH) +#define GET_MT(b) GET_GLOBAL_FIELD(b, TLBTR0, MT) +#define GET_DPSIZR(b) GET_GLOBAL_FIELD(b, TLBTR0, DPSIZR) +#define GET_DPSIZC(b) GET_GLOBAL_FIELD(b, TLBTR0, DPSIZC) + + +/* TLBTR1 */ +#define GET_TLBTR1_VMID(b) GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID) +#define GET_TLBTR1_PA(b) GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA) + + +/* TLBTR2 */ +#define GET_TLBTR2_ASID(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID) +#define GET_TLBTR2_V(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V) +#define GET_TLBTR2_NSTID(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID) +#define GET_TLBTR2_NV(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV) +#define GET_TLBTR2_VA(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA) + + +/* Context Register setters / getters */ +/* Context Register setters */ +/* ACTLR */ +#define SET_CFERE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFERE, v) +#define SET_CFEIE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFEIE, v) +#define SET_PTSHCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG, v) +#define SET_RCOSH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCOSH, v) +#define SET_RCISH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCISH, v) +#define SET_RCNSH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCNSH, v) +#define SET_PRIVCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG, v) +#define SET_DNA(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, DNA, v) +#define SET_DNLV2PA(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA, v) +#define SET_TLBMCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG, v) +#define SET_CFCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFCFG, v) +#define SET_TIPCF(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, TIPCF, v) +#define SET_V2PCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG, v) +#define SET_HUME(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, HUME, v) +#define SET_PTMTCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG, v) +#define SET_PTMEMTYPE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE, v) + + +/* BFBCR */ +#define SET_BFBDFE(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE, v) +#define SET_BFBSFE(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE, v) +#define SET_SFVS(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, SFVS, v) +#define SET_FLVIC(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, FLVIC, v) +#define SET_SLVIC(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, SLVIC, v) + + +/* CONTEXTIDR */ +#define SET_CONTEXTIDR_ASID(b, c, v) \ + SET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID, v) +#define SET_CONTEXTIDR_PROCID(b, c, v) \ + SET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID, v) + + +/* FSR */ +#define SET_TF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, TF, v) +#define SET_AFF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, AFF, v) +#define SET_APF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, APF, v) +#define SET_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, TLBMF, v) +#define SET_HTWDEEF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, HTWDEEF, v) +#define SET_HTWSEEF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, HTWSEEF, v) +#define SET_MHF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, MHF, v) +#define SET_SL(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, SL, v) +#define SET_SS(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, SS, v) +#define SET_MULTI(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, MULTI, v) + + +/* FSYNR0 */ +#define SET_AMID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, AMID, v) +#define SET_APID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, APID, v) +#define SET_ABID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, ABID, v) +#define SET_ATID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, ATID, v) + + +/* FSYNR1 */ +#define SET_AMEMTYPE(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE, v) +#define SET_ASHARED(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED, v) +#define SET_AINNERSHARED(b, c, v) \ + SET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED, v) +#define SET_APRIV(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, APRIV, v) +#define SET_APROTNS(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS, v) +#define SET_AINST(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AINST, v) +#define SET_AWRITE(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE, v) +#define SET_ABURST(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ABURST, v) +#define SET_ALEN(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ALEN, v) +#define SET_FSYNR1_ASIZE(b, c, v) \ + SET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE, v) +#define SET_ALOCK(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK, v) +#define SET_AFULL(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AFULL, v) + + +/* NMRR */ +#define SET_ICPC0(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC0, v) +#define SET_ICPC1(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC1, v) +#define SET_ICPC2(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC2, v) +#define SET_ICPC3(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC3, v) +#define SET_ICPC4(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC4, v) +#define SET_ICPC5(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC5, v) +#define SET_ICPC6(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC6, v) +#define SET_ICPC7(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC7, v) +#define SET_OCPC0(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC0, v) +#define SET_OCPC1(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC1, v) +#define SET_OCPC2(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC2, v) +#define SET_OCPC3(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC3, v) +#define SET_OCPC4(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC4, v) +#define SET_OCPC5(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC5, v) +#define SET_OCPC6(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC6, v) +#define SET_OCPC7(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC7, v) + + +/* PAR */ +#define SET_FAULT(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT, v) + +#define SET_FAULT_TF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TF, v) +#define SET_FAULT_AFF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF, v) +#define SET_FAULT_APF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_APF, v) +#define SET_FAULT_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF, v) +#define SET_FAULT_HTWDEEF(b, c, v) \ + SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF, v) +#define SET_FAULT_HTWSEEF(b, c, v) \ + SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF, v) +#define SET_FAULT_MHF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF, v) +#define SET_FAULT_SL(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_SL, v) +#define SET_FAULT_SS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_SS, v) + +#define SET_NOFAULT_SS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SS, v) +#define SET_NOFAULT_MT(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_MT, v) +#define SET_NOFAULT_SH(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SH, v) +#define SET_NOFAULT_NS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NS, v) +#define SET_NOFAULT_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NOS, v) +#define SET_NPFAULT_PA(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NPFAULT_PA, v) + + +/* PRRR */ +#define SET_MTC0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC0, v) +#define SET_MTC1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC1, v) +#define SET_MTC2(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC2, v) +#define SET_MTC3(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC3, v) +#define SET_MTC4(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC4, v) +#define SET_MTC5(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC5, v) +#define SET_MTC6(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC6, v) +#define SET_MTC7(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC7, v) +#define SET_SHDSH0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHDSH0, v) +#define SET_SHDSH1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHDSH1, v) +#define SET_SHNMSH0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0, v) +#define SET_SHNMSH1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1, v) +#define SET_NOS0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS0, v) +#define SET_NOS1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS1, v) +#define SET_NOS2(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS2, v) +#define SET_NOS3(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS3, v) +#define SET_NOS4(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS4, v) +#define SET_NOS5(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS5, v) +#define SET_NOS6(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS6, v) +#define SET_NOS7(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS7, v) + + +/* RESUME */ +#define SET_TNR(b, c, v) SET_CONTEXT_FIELD(b, c, RESUME, TNR, v) + + +/* SCTLR */ +#define SET_M(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, M, v) +#define SET_TRE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, TRE, v) +#define SET_AFE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, AFE, v) +#define SET_HAF(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, HAF, v) +#define SET_BE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, BE, v) +#define SET_AFFD(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, AFFD, v) + + +/* TLBLKCR */ +#define SET_LKE(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, LKE, v) +#define SET_TLBLKCR_TLBIALLCFG(b, c, v) \ + SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG, v) +#define SET_TLBIASIDCFG(b, c, v) \ + SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG, v) +#define SET_TLBIVAACFG(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG, v) +#define SET_FLOOR(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR, v) +#define SET_VICTIM(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM, v) + + +/* TTBCR */ +#define SET_N(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, N, v) +#define SET_PD0(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, PD0, v) +#define SET_PD1(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, PD1, v) + + +/* TTBR0 */ +#define SET_TTBR0_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH, v) +#define SET_TTBR0_SH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH, v) +#define SET_TTBR0_ORGN(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN, v) +#define SET_TTBR0_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS, v) +#define SET_TTBR0_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL, v) +#define SET_TTBR0_PA(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA, v) + + +/* TTBR1 */ +#define SET_TTBR1_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH, v) +#define SET_TTBR1_SH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH, v) +#define SET_TTBR1_ORGN(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN, v) +#define SET_TTBR1_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS, v) +#define SET_TTBR1_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL, v) +#define SET_TTBR1_PA(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA, v) + + +/* V2PSR */ +#define SET_HIT(b, c, v) SET_CONTEXT_FIELD(b, c, V2PSR, HIT, v) +#define SET_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PSR, INDEX, v) + + +/* V2Pxx UW UR PW PR */ +#define SET_V2PUW_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_INDEX, v) +#define SET_V2PUW_VA(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_VA, v) + +#define SET_V2PUR_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_INDEX, v) +#define SET_V2PUR_VA(b, c, v) SET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_VA, v) + +#define SET_V2PPW_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_INDEX, v) +#define SET_V2PPW_VA(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_VA, v) + +#define SET_V2PPR_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_INDEX, v) +#define SET_V2PPR_VA(b, c, v) SET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_VA, v) + + +/* Context Register getters */ +/* ACTLR */ +#define GET_CFERE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFERE) +#define GET_CFEIE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFEIE) +#define GET_PTSHCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG) +#define GET_RCOSH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCOSH) +#define GET_RCISH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCISH) +#define GET_RCNSH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCNSH) +#define GET_PRIVCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG) +#define GET_DNA(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, DNA) +#define GET_DNLV2PA(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA) +#define GET_TLBMCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG) +#define GET_CFCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFCFG) +#define GET_TIPCF(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, TIPCF) +#define GET_V2PCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG) +#define GET_HUME(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, HUME) +#define GET_PTMTCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG) +#define GET_PTMEMTYPE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE) + +/* BFBCR */ +#define GET_BFBDFE(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE) +#define GET_BFBSFE(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE) +#define GET_SFVS(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, SFVS) +#define GET_FLVIC(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, FLVIC) +#define GET_SLVIC(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, SLVIC) + + +/* CONTEXTIDR */ +#define GET_CONTEXTIDR_ASID(b, c) \ + GET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID) +#define GET_CONTEXTIDR_PROCID(b, c) GET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID) + + +/* FSR */ +#define GET_TF(b, c) GET_CONTEXT_FIELD(b, c, FSR, TF) +#define GET_AFF(b, c) GET_CONTEXT_FIELD(b, c, FSR, AFF) +#define GET_APF(b, c) GET_CONTEXT_FIELD(b, c, FSR, APF) +#define GET_TLBMF(b, c) GET_CONTEXT_FIELD(b, c, FSR, TLBMF) +#define GET_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, FSR, HTWDEEF) +#define GET_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, FSR, HTWSEEF) +#define GET_MHF(b, c) GET_CONTEXT_FIELD(b, c, FSR, MHF) +#define GET_SL(b, c) GET_CONTEXT_FIELD(b, c, FSR, SL) +#define GET_SS(b, c) GET_CONTEXT_FIELD(b, c, FSR, SS) +#define GET_MULTI(b, c) GET_CONTEXT_FIELD(b, c, FSR, MULTI) + + +/* FSYNR0 */ +#define GET_AMID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, AMID) +#define GET_APID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, APID) +#define GET_ABID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, ABID) +#define GET_ATID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, ATID) + + +/* FSYNR1 */ +#define GET_AMEMTYPE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE) +#define GET_ASHARED(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED) +#define GET_AINNERSHARED(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED) +#define GET_APRIV(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, APRIV) +#define GET_APROTNS(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS) +#define GET_AINST(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AINST) +#define GET_AWRITE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE) +#define GET_ABURST(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ABURST) +#define GET_ALEN(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ALEN) +#define GET_FSYNR1_ASIZE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE) +#define GET_ALOCK(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK) +#define GET_AFULL(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AFULL) + + +/* NMRR */ +#define GET_ICPC0(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC0) +#define GET_ICPC1(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC1) +#define GET_ICPC2(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC2) +#define GET_ICPC3(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC3) +#define GET_ICPC4(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC4) +#define GET_ICPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC5) +#define GET_ICPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC6) +#define GET_ICPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC7) +#define GET_OCPC0(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC0) +#define GET_OCPC1(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC1) +#define GET_OCPC2(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC2) +#define GET_OCPC3(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC3) +#define GET_OCPC4(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC4) +#define GET_OCPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC5) +#define GET_OCPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC6) +#define GET_OCPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC7) + + +/* PAR */ +#define GET_FAULT(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT) + +#define GET_FAULT_TF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_TF) +#define GET_FAULT_AFF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF) +#define GET_FAULT_APF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_APF) +#define GET_FAULT_TLBMF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF) +#define GET_FAULT_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF) +#define GET_FAULT_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF) +#define GET_FAULT_MHF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF) +#define GET_FAULT_SL(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_SL) +#define GET_FAULT_SS(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_SS) + +#define GET_NOFAULT_SS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SS) +#define GET_NOFAULT_MT(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_MT) +#define GET_NOFAULT_SH(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SH) +#define GET_NOFAULT_NS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NS) +#define GET_NOFAULT_NOS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NOS) +#define GET_NPFAULT_PA(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NPFAULT_PA) + + +/* PRRR */ +#define GET_MTC0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC0) +#define GET_MTC1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC1) +#define GET_MTC2(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC2) +#define GET_MTC3(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC3) +#define GET_MTC4(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC4) +#define GET_MTC5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC5) +#define GET_MTC6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC6) +#define GET_MTC7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC7) +#define GET_SHDSH0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHDSH0) +#define GET_SHDSH1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHDSH1) +#define GET_SHNMSH0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0) +#define GET_SHNMSH1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1) +#define GET_NOS0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS0) +#define GET_NOS1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS1) +#define GET_NOS2(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS2) +#define GET_NOS3(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS3) +#define GET_NOS4(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS4) +#define GET_NOS5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS5) +#define GET_NOS6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS6) +#define GET_NOS7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS7) + + +/* RESUME */ +#define GET_TNR(b, c) GET_CONTEXT_FIELD(b, c, RESUME, TNR) + + +/* SCTLR */ +#define GET_M(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, M) +#define GET_TRE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, TRE) +#define GET_AFE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, AFE) +#define GET_HAF(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, HAF) +#define GET_BE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, BE) +#define GET_AFFD(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, AFFD) + + +/* TLBLKCR */ +#define GET_LKE(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, LKE) +#define GET_TLBLCKR_TLBIALLCFG(b, c) \ + GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG) +#define GET_TLBIASIDCFG(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG) +#define GET_TLBIVAACFG(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG) +#define GET_FLOOR(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR) +#define GET_VICTIM(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM) + + +/* TTBCR */ +#define GET_N(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, N) +#define GET_PD0(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, PD0) +#define GET_PD1(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, PD1) + + +/* TTBR0 */ +#define GET_TTBR0_IRGNH(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH) +#define GET_TTBR0_SH(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH) +#define GET_TTBR0_ORGN(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN) +#define GET_TTBR0_NOS(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS) +#define GET_TTBR0_IRGNL(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL) +#define GET_TTBR0_PA(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA) + + +/* TTBR1 */ +#define GET_TTBR1_IRGNH(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH) +#define GET_TTBR1_SH(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH) +#define GET_TTBR1_ORGN(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN) +#define GET_TTBR1_NOS(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS) +#define GET_TTBR1_IRGNL(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL) +#define GET_TTBR1_PA(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA) + + +/* V2PSR */ +#define GET_HIT(b, c) GET_CONTEXT_FIELD(b, c, V2PSR, HIT) +#define GET_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PSR, INDEX) + + +/* V2Pxx UW UR PW PR */ +#define GET_V2PUW_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_INDEX) +#define GET_V2PUW_VA(b, c) GET_CONTEXT_FIELD(b, c, V2PUW, V2Pxx_VA) + +#define GET_V2PUR_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_INDEX) +#define GET_V2PUR_VA(b, c) GET_CONTEXT_FIELD(b, c, V2PUR, V2Pxx_VA) + +#define GET_V2PPW_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_INDEX) +#define GET_V2PPW_VA(b, c) GET_CONTEXT_FIELD(b, c, V2PPW, V2Pxx_VA) + +#define GET_V2PPR_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_INDEX) +#define GET_V2PPR_VA(b, c) GET_CONTEXT_FIELD(b, c, V2PPR, V2Pxx_VA) + + +/* Global Registers */ +#define M2VCBR_N (0xFF000) +#define CBACR_N (0xFF800) +#define TLBRSW (0xFFE00) +#define TLBTR0 (0xFFE80) +#define TLBTR1 (0xFFE84) +#define TLBTR2 (0xFFE88) +#define TESTBUSCR (0xFFE8C) +#define GLOBAL_TLBIALL (0xFFF00) +#define TLBIVMID (0xFFF04) +#define CR (0xFFF80) +#define EAR (0xFFF84) +#define ESR (0xFFF88) +#define ESRRESTORE (0xFFF8C) +#define ESYNR0 (0xFFF90) +#define ESYNR1 (0xFFF94) +#define REV (0xFFFF4) +#define IDR (0xFFFF8) +#define RPU_ACR (0xFFFFC) + + +/* Context Bank Registers */ +#define SCTLR (0x000) +#define ACTLR (0x004) +#define CONTEXTIDR (0x008) +#define TTBR0 (0x010) +#define TTBR1 (0x014) +#define TTBCR (0x018) +#define PAR (0x01C) +#define FSR (0x020) +#define FSRRESTORE (0x024) +#define FAR (0x028) +#define FSYNR0 (0x02C) +#define FSYNR1 (0x030) +#define PRRR (0x034) +#define NMRR (0x038) +#define TLBLCKR (0x03C) +#define V2PSR (0x040) +#define TLBFLPTER (0x044) +#define TLBSLPTER (0x048) +#define BFBCR (0x04C) +#define CTX_TLBIALL (0x800) +#define TLBIASID (0x804) +#define TLBIVA (0x808) +#define TLBIVAA (0x80C) +#define V2PPR (0x810) +#define V2PPW (0x814) +#define V2PUR (0x818) +#define V2PUW (0x81C) +#define RESUME (0x820) + + +/* Global Register Fields */ +/* CBACRn */ +#define RWVMID (RWVMID_MASK << RWVMID_SHIFT) +#define RWE (RWE_MASK << RWE_SHIFT) +#define RWGE (RWGE_MASK << RWGE_SHIFT) +#define CBVMID (CBVMID_MASK << CBVMID_SHIFT) +#define IRPTNDX (IRPTNDX_MASK << IRPTNDX_SHIFT) + + +/* CR */ +#define RPUE (RPUE_MASK << RPUE_SHIFT) +#define RPUERE (RPUERE_MASK << RPUERE_SHIFT) +#define RPUEIE (RPUEIE_MASK << RPUEIE_SHIFT) +#define DCDEE (DCDEE_MASK << DCDEE_SHIFT) +#define CLIENTPD (CLIENTPD_MASK << CLIENTPD_SHIFT) +#define STALLD (STALLD_MASK << STALLD_SHIFT) +#define TLBLKCRWE (TLBLKCRWE_MASK << TLBLKCRWE_SHIFT) +#define CR_TLBIALLCFG (CR_TLBIALLCFG_MASK << CR_TLBIALLCFG_SHIFT) +#define TLBIVMIDCFG (TLBIVMIDCFG_MASK << TLBIVMIDCFG_SHIFT) +#define CR_HUME (CR_HUME_MASK << CR_HUME_SHIFT) + + +/* ESR */ +#define CFG (CFG_MASK << CFG_SHIFT) +#define BYPASS (BYPASS_MASK << BYPASS_SHIFT) +#define ESR_MULTI (ESR_MULTI_MASK << ESR_MULTI_SHIFT) + + +/* ESYNR0 */ +#define ESYNR0_AMID (ESYNR0_AMID_MASK << ESYNR0_AMID_SHIFT) +#define ESYNR0_APID (ESYNR0_APID_MASK << ESYNR0_APID_SHIFT) +#define ESYNR0_ABID (ESYNR0_ABID_MASK << ESYNR0_ABID_SHIFT) +#define ESYNR0_AVMID (ESYNR0_AVMID_MASK << ESYNR0_AVMID_SHIFT) +#define ESYNR0_ATID (ESYNR0_ATID_MASK << ESYNR0_ATID_SHIFT) + + +/* ESYNR1 */ +#define ESYNR1_AMEMTYPE (ESYNR1_AMEMTYPE_MASK << ESYNR1_AMEMTYPE_SHIFT) +#define ESYNR1_ASHARED (ESYNR1_ASHARED_MASK << ESYNR1_ASHARED_SHIFT) +#define ESYNR1_AINNERSHARED (ESYNR1_AINNERSHARED_MASK<< \ + ESYNR1_AINNERSHARED_SHIFT) +#define ESYNR1_APRIV (ESYNR1_APRIV_MASK << ESYNR1_APRIV_SHIFT) +#define ESYNR1_APROTNS (ESYNR1_APROTNS_MASK << ESYNR1_APROTNS_SHIFT) +#define ESYNR1_AINST (ESYNR1_AINST_MASK << ESYNR1_AINST_SHIFT) +#define ESYNR1_AWRITE (ESYNR1_AWRITE_MASK << ESYNR1_AWRITE_SHIFT) +#define ESYNR1_ABURST (ESYNR1_ABURST_MASK << ESYNR1_ABURST_SHIFT) +#define ESYNR1_ALEN (ESYNR1_ALEN_MASK << ESYNR1_ALEN_SHIFT) +#define ESYNR1_ASIZE (ESYNR1_ASIZE_MASK << ESYNR1_ASIZE_SHIFT) +#define ESYNR1_ALOCK (ESYNR1_ALOCK_MASK << ESYNR1_ALOCK_SHIFT) +#define ESYNR1_AOOO (ESYNR1_AOOO_MASK << ESYNR1_AOOO_SHIFT) +#define ESYNR1_AFULL (ESYNR1_AFULL_MASK << ESYNR1_AFULL_SHIFT) +#define ESYNR1_AC (ESYNR1_AC_MASK << ESYNR1_AC_SHIFT) +#define ESYNR1_DCD (ESYNR1_DCD_MASK << ESYNR1_DCD_SHIFT) + + +/* IDR */ +#define NM2VCBMT (NM2VCBMT_MASK << NM2VCBMT_SHIFT) +#define HTW (HTW_MASK << HTW_SHIFT) +#define HUM (HUM_MASK << HUM_SHIFT) +#define TLBSIZE (TLBSIZE_MASK << TLBSIZE_SHIFT) +#define NCB (NCB_MASK << NCB_SHIFT) +#define NIRPT (NIRPT_MASK << NIRPT_SHIFT) + + +/* M2VCBRn */ +#define VMID (VMID_MASK << VMID_SHIFT) +#define CBNDX (CBNDX_MASK << CBNDX_SHIFT) +#define BYPASSD (BYPASSD_MASK << BYPASSD_SHIFT) +#define BPRCOSH (BPRCOSH_MASK << BPRCOSH_SHIFT) +#define BPRCISH (BPRCISH_MASK << BPRCISH_SHIFT) +#define BPRCNSH (BPRCNSH_MASK << BPRCNSH_SHIFT) +#define BPSHCFG (BPSHCFG_MASK << BPSHCFG_SHIFT) +#define NSCFG (NSCFG_MASK << NSCFG_SHIFT) +#define BPMTCFG (BPMTCFG_MASK << BPMTCFG_SHIFT) +#define BPMEMTYPE (BPMEMTYPE_MASK << BPMEMTYPE_SHIFT) + + +/* REV */ +#define IDR_MINOR (MINOR_MASK << MINOR_SHIFT) +#define IDR_MAJOR (MAJOR_MASK << MAJOR_SHIFT) + + +/* TESTBUSCR */ +#define TBE (TBE_MASK << TBE_SHIFT) +#define SPDMBE (SPDMBE_MASK << SPDMBE_SHIFT) +#define WGSEL (WGSEL_MASK << WGSEL_SHIFT) +#define TBLSEL (TBLSEL_MASK << TBLSEL_SHIFT) +#define TBHSEL (TBHSEL_MASK << TBHSEL_SHIFT) +#define SPDM0SEL (SPDM0SEL_MASK << SPDM0SEL_SHIFT) +#define SPDM1SEL (SPDM1SEL_MASK << SPDM1SEL_SHIFT) +#define SPDM2SEL (SPDM2SEL_MASK << SPDM2SEL_SHIFT) +#define SPDM3SEL (SPDM3SEL_MASK << SPDM3SEL_SHIFT) + + +/* TLBIVMID */ +#define TLBIVMID_VMID (TLBIVMID_VMID_MASK << TLBIVMID_VMID_SHIFT) + + +/* TLBRSW */ +#define TLBRSW_INDEX (TLBRSW_INDEX_MASK << TLBRSW_INDEX_SHIFT) +#define TLBBFBS (TLBBFBS_MASK << TLBBFBS_SHIFT) + + +/* TLBTR0 */ +#define PR (PR_MASK << PR_SHIFT) +#define PW (PW_MASK << PW_SHIFT) +#define UR (UR_MASK << UR_SHIFT) +#define UW (UW_MASK << UW_SHIFT) +#define XN (XN_MASK << XN_SHIFT) +#define NSDESC (NSDESC_MASK << NSDESC_SHIFT) +#define ISH (ISH_MASK << ISH_SHIFT) +#define SH (SH_MASK << SH_SHIFT) +#define MT (MT_MASK << MT_SHIFT) +#define DPSIZR (DPSIZR_MASK << DPSIZR_SHIFT) +#define DPSIZC (DPSIZC_MASK << DPSIZC_SHIFT) + + +/* TLBTR1 */ +#define TLBTR1_VMID (TLBTR1_VMID_MASK << TLBTR1_VMID_SHIFT) +#define TLBTR1_PA (TLBTR1_PA_MASK << TLBTR1_PA_SHIFT) + + +/* TLBTR2 */ +#define TLBTR2_ASID (TLBTR2_ASID_MASK << TLBTR2_ASID_SHIFT) +#define TLBTR2_V (TLBTR2_V_MASK << TLBTR2_V_SHIFT) +#define TLBTR2_NSTID (TLBTR2_NSTID_MASK << TLBTR2_NSTID_SHIFT) +#define TLBTR2_NV (TLBTR2_NV_MASK << TLBTR2_NV_SHIFT) +#define TLBTR2_VA (TLBTR2_VA_MASK << TLBTR2_VA_SHIFT) + + +/* Context Register Fields */ +/* ACTLR */ +#define CFERE (CFERE_MASK << CFERE_SHIFT) +#define CFEIE (CFEIE_MASK << CFEIE_SHIFT) +#define PTSHCFG (PTSHCFG_MASK << PTSHCFG_SHIFT) +#define RCOSH (RCOSH_MASK << RCOSH_SHIFT) +#define RCISH (RCISH_MASK << RCISH_SHIFT) +#define RCNSH (RCNSH_MASK << RCNSH_SHIFT) +#define PRIVCFG (PRIVCFG_MASK << PRIVCFG_SHIFT) +#define DNA (DNA_MASK << DNA_SHIFT) +#define DNLV2PA (DNLV2PA_MASK << DNLV2PA_SHIFT) +#define TLBMCFG (TLBMCFG_MASK << TLBMCFG_SHIFT) +#define CFCFG (CFCFG_MASK << CFCFG_SHIFT) +#define TIPCF (TIPCF_MASK << TIPCF_SHIFT) +#define V2PCFG (V2PCFG_MASK << V2PCFG_SHIFT) +#define HUME (HUME_MASK << HUME_SHIFT) +#define PTMTCFG (PTMTCFG_MASK << PTMTCFG_SHIFT) +#define PTMEMTYPE (PTMEMTYPE_MASK << PTMEMTYPE_SHIFT) + + +/* BFBCR */ +#define BFBDFE (BFBDFE_MASK << BFBDFE_SHIFT) +#define BFBSFE (BFBSFE_MASK << BFBSFE_SHIFT) +#define SFVS (SFVS_MASK << SFVS_SHIFT) +#define FLVIC (FLVIC_MASK << FLVIC_SHIFT) +#define SLVIC (SLVIC_MASK << SLVIC_SHIFT) + + +/* CONTEXTIDR */ +#define CONTEXTIDR_ASID (CONTEXTIDR_ASID_MASK << CONTEXTIDR_ASID_SHIFT) +#define PROCID (PROCID_MASK << PROCID_SHIFT) + + +/* FSR */ +#define TF (TF_MASK << TF_SHIFT) +#define AFF (AFF_MASK << AFF_SHIFT) +#define APF (APF_MASK << APF_SHIFT) +#define TLBMF (TLBMF_MASK << TLBMF_SHIFT) +#define HTWDEEF (HTWDEEF_MASK << HTWDEEF_SHIFT) +#define HTWSEEF (HTWSEEF_MASK << HTWSEEF_SHIFT) +#define MHF (MHF_MASK << MHF_SHIFT) +#define SL (SL_MASK << SL_SHIFT) +#define SS (SS_MASK << SS_SHIFT) +#define MULTI (MULTI_MASK << MULTI_SHIFT) + + +/* FSYNR0 */ +#define AMID (AMID_MASK << AMID_SHIFT) +#define APID (APID_MASK << APID_SHIFT) +#define ABID (ABID_MASK << ABID_SHIFT) +#define ATID (ATID_MASK << ATID_SHIFT) + + +/* FSYNR1 */ +#define AMEMTYPE (AMEMTYPE_MASK << AMEMTYPE_SHIFT) +#define ASHARED (ASHARED_MASK << ASHARED_SHIFT) +#define AINNERSHARED (AINNERSHARED_MASK << AINNERSHARED_SHIFT) +#define APRIV (APRIV_MASK << APRIV_SHIFT) +#define APROTNS (APROTNS_MASK << APROTNS_SHIFT) +#define AINST (AINST_MASK << AINST_SHIFT) +#define AWRITE (AWRITE_MASK << AWRITE_SHIFT) +#define ABURST (ABURST_MASK << ABURST_SHIFT) +#define ALEN (ALEN_MASK << ALEN_SHIFT) +#define FSYNR1_ASIZE (FSYNR1_ASIZE_MASK << FSYNR1_ASIZE_SHIFT) +#define ALOCK (ALOCK_MASK << ALOCK_SHIFT) +#define AFULL (AFULL_MASK << AFULL_SHIFT) + + +/* NMRR */ +#define ICPC0 (ICPC0_MASK << ICPC0_SHIFT) +#define ICPC1 (ICPC1_MASK << ICPC1_SHIFT) +#define ICPC2 (ICPC2_MASK << ICPC2_SHIFT) +#define ICPC3 (ICPC3_MASK << ICPC3_SHIFT) +#define ICPC4 (ICPC4_MASK << ICPC4_SHIFT) +#define ICPC5 (ICPC5_MASK << ICPC5_SHIFT) +#define ICPC6 (ICPC6_MASK << ICPC6_SHIFT) +#define ICPC7 (ICPC7_MASK << ICPC7_SHIFT) +#define OCPC0 (OCPC0_MASK << OCPC0_SHIFT) +#define OCPC1 (OCPC1_MASK << OCPC1_SHIFT) +#define OCPC2 (OCPC2_MASK << OCPC2_SHIFT) +#define OCPC3 (OCPC3_MASK << OCPC3_SHIFT) +#define OCPC4 (OCPC4_MASK << OCPC4_SHIFT) +#define OCPC5 (OCPC5_MASK << OCPC5_SHIFT) +#define OCPC6 (OCPC6_MASK << OCPC6_SHIFT) +#define OCPC7 (OCPC7_MASK << OCPC7_SHIFT) + + +/* PAR */ +#define FAULT (FAULT_MASK << FAULT_SHIFT) +/* If a fault is present, these are the +same as the fault fields in the FAR */ +#define FAULT_TF (FAULT_TF_MASK << FAULT_TF_SHIFT) +#define FAULT_AFF (FAULT_AFF_MASK << FAULT_AFF_SHIFT) +#define FAULT_APF (FAULT_APF_MASK << FAULT_APF_SHIFT) +#define FAULT_TLBMF (FAULT_TLBMF_MASK << FAULT_TLBMF_SHIFT) +#define FAULT_HTWDEEF (FAULT_HTWDEEF_MASK << FAULT_HTWDEEF_SHIFT) +#define FAULT_HTWSEEF (FAULT_HTWSEEF_MASK << FAULT_HTWSEEF_SHIFT) +#define FAULT_MHF (FAULT_MHF_MASK << FAULT_MHF_SHIFT) +#define FAULT_SL (FAULT_SL_MASK << FAULT_SL_SHIFT) +#define FAULT_SS (FAULT_SS_MASK << FAULT_SS_SHIFT) + +/* If NO fault is present, the following fields are in effect */ +/* (FAULT remains as before) */ +#define PAR_NOFAULT_SS (PAR_NOFAULT_SS_MASK << PAR_NOFAULT_SS_SHIFT) +#define PAR_NOFAULT_MT (PAR_NOFAULT_MT_MASK << PAR_NOFAULT_MT_SHIFT) +#define PAR_NOFAULT_SH (PAR_NOFAULT_SH_MASK << PAR_NOFAULT_SH_SHIFT) +#define PAR_NOFAULT_NS (PAR_NOFAULT_NS_MASK << PAR_NOFAULT_NS_SHIFT) +#define PAR_NOFAULT_NOS (PAR_NOFAULT_NOS_MASK << PAR_NOFAULT_NOS_SHIFT) +#define PAR_NPFAULT_PA (PAR_NPFAULT_PA_MASK << PAR_NPFAULT_PA_SHIFT) + + +/* PRRR */ +#define MTC0 (MTC0_MASK << MTC0_SHIFT) +#define MTC1 (MTC1_MASK << MTC1_SHIFT) +#define MTC2 (MTC2_MASK << MTC2_SHIFT) +#define MTC3 (MTC3_MASK << MTC3_SHIFT) +#define MTC4 (MTC4_MASK << MTC4_SHIFT) +#define MTC5 (MTC5_MASK << MTC5_SHIFT) +#define MTC6 (MTC6_MASK << MTC6_SHIFT) +#define MTC7 (MTC7_MASK << MTC7_SHIFT) +#define SHDSH0 (SHDSH0_MASK << SHDSH0_SHIFT) +#define SHDSH1 (SHDSH1_MASK << SHDSH1_SHIFT) +#define SHNMSH0 (SHNMSH0_MASK << SHNMSH0_SHIFT) +#define SHNMSH1 (SHNMSH1_MASK << SHNMSH1_SHIFT) +#define NOS0 (NOS0_MASK << NOS0_SHIFT) +#define NOS1 (NOS1_MASK << NOS1_SHIFT) +#define NOS2 (NOS2_MASK << NOS2_SHIFT) +#define NOS3 (NOS3_MASK << NOS3_SHIFT) +#define NOS4 (NOS4_MASK << NOS4_SHIFT) +#define NOS5 (NOS5_MASK << NOS5_SHIFT) +#define NOS6 (NOS6_MASK << NOS6_SHIFT) +#define NOS7 (NOS7_MASK << NOS7_SHIFT) + + +/* RESUME */ +#define TNR (TNR_MASK << TNR_SHIFT) + + +/* SCTLR */ +#define M (M_MASK << M_SHIFT) +#define TRE (TRE_MASK << TRE_SHIFT) +#define AFE (AFE_MASK << AFE_SHIFT) +#define HAF (HAF_MASK << HAF_SHIFT) +#define BE (BE_MASK << BE_SHIFT) +#define AFFD (AFFD_MASK << AFFD_SHIFT) + + +/* TLBIASID */ +#define TLBIASID_ASID (TLBIASID_ASID_MASK << TLBIASID_ASID_SHIFT) + + +/* TLBIVA */ +#define TLBIVA_ASID (TLBIVA_ASID_MASK << TLBIVA_ASID_SHIFT) +#define TLBIVA_VA (TLBIVA_VA_MASK << TLBIVA_VA_SHIFT) + + +/* TLBIVAA */ +#define TLBIVAA_VA (TLBIVAA_VA_MASK << TLBIVAA_VA_SHIFT) + + +/* TLBLCKR */ +#define LKE (LKE_MASK << LKE_SHIFT) +#define TLBLCKR_TLBIALLCFG (TLBLCKR_TLBIALLCFG_MASK<<TLBLCKR_TLBIALLCFG_SHIFT) +#define TLBIASIDCFG (TLBIASIDCFG_MASK << TLBIASIDCFG_SHIFT) +#define TLBIVAACFG (TLBIVAACFG_MASK << TLBIVAACFG_SHIFT) +#define FLOOR (FLOOR_MASK << FLOOR_SHIFT) +#define VICTIM (VICTIM_MASK << VICTIM_SHIFT) + + +/* TTBCR */ +#define N (N_MASK << N_SHIFT) +#define PD0 (PD0_MASK << PD0_SHIFT) +#define PD1 (PD1_MASK << PD1_SHIFT) + + +/* TTBR0 */ +#define TTBR0_IRGNH (TTBR0_IRGNH_MASK << TTBR0_IRGNH_SHIFT) +#define TTBR0_SH (TTBR0_SH_MASK << TTBR0_SH_SHIFT) +#define TTBR0_ORGN (TTBR0_ORGN_MASK << TTBR0_ORGN_SHIFT) +#define TTBR0_NOS (TTBR0_NOS_MASK << TTBR0_NOS_SHIFT) +#define TTBR0_IRGNL (TTBR0_IRGNL_MASK << TTBR0_IRGNL_SHIFT) +#define TTBR0_PA (TTBR0_PA_MASK << TTBR0_PA_SHIFT) + + +/* TTBR1 */ +#define TTBR1_IRGNH (TTBR1_IRGNH_MASK << TTBR1_IRGNH_SHIFT) +#define TTBR1_SH (TTBR1_SH_MASK << TTBR1_SH_SHIFT) +#define TTBR1_ORGN (TTBR1_ORGN_MASK << TTBR1_ORGN_SHIFT) +#define TTBR1_NOS (TTBR1_NOS_MASK << TTBR1_NOS_SHIFT) +#define TTBR1_IRGNL (TTBR1_IRGNL_MASK << TTBR1_IRGNL_SHIFT) +#define TTBR1_PA (TTBR1_PA_MASK << TTBR1_PA_SHIFT) + + +/* V2PSR */ +#define HIT (HIT_MASK << HIT_SHIFT) +#define INDEX (INDEX_MASK << INDEX_SHIFT) + + +/* V2Pxx */ +#define V2Pxx_INDEX (V2Pxx_INDEX_MASK << V2Pxx_INDEX_SHIFT) +#define V2Pxx_VA (V2Pxx_VA_MASK << V2Pxx_VA_SHIFT) + + +/* Global Register Masks */ +/* CBACRn */ +#define RWVMID_MASK 0x1F +#define RWE_MASK 0x01 +#define RWGE_MASK 0x01 +#define CBVMID_MASK 0x1F +#define IRPTNDX_MASK 0xFF + + +/* CR */ +#define RPUE_MASK 0x01 +#define RPUERE_MASK 0x01 +#define RPUEIE_MASK 0x01 +#define DCDEE_MASK 0x01 +#define CLIENTPD_MASK 0x01 +#define STALLD_MASK 0x01 +#define TLBLKCRWE_MASK 0x01 +#define CR_TLBIALLCFG_MASK 0x01 +#define TLBIVMIDCFG_MASK 0x01 +#define CR_HUME_MASK 0x01 + + +/* ESR */ +#define CFG_MASK 0x01 +#define BYPASS_MASK 0x01 +#define ESR_MULTI_MASK 0x01 + + +/* ESYNR0 */ +#define ESYNR0_AMID_MASK 0xFF +#define ESYNR0_APID_MASK 0x1F +#define ESYNR0_ABID_MASK 0x07 +#define ESYNR0_AVMID_MASK 0x1F +#define ESYNR0_ATID_MASK 0xFF + + +/* ESYNR1 */ +#define ESYNR1_AMEMTYPE_MASK 0x07 +#define ESYNR1_ASHARED_MASK 0x01 +#define ESYNR1_AINNERSHARED_MASK 0x01 +#define ESYNR1_APRIV_MASK 0x01 +#define ESYNR1_APROTNS_MASK 0x01 +#define ESYNR1_AINST_MASK 0x01 +#define ESYNR1_AWRITE_MASK 0x01 +#define ESYNR1_ABURST_MASK 0x01 +#define ESYNR1_ALEN_MASK 0x0F +#define ESYNR1_ASIZE_MASK 0x01 +#define ESYNR1_ALOCK_MASK 0x03 +#define ESYNR1_AOOO_MASK 0x01 +#define ESYNR1_AFULL_MASK 0x01 +#define ESYNR1_AC_MASK 0x01 +#define ESYNR1_DCD_MASK 0x01 + + +/* IDR */ +#define NM2VCBMT_MASK 0x1FF +#define HTW_MASK 0x01 +#define HUM_MASK 0x01 +#define TLBSIZE_MASK 0x0F +#define NCB_MASK 0xFF +#define NIRPT_MASK 0xFF + + +/* M2VCBRn */ +#define VMID_MASK 0x1F +#define CBNDX_MASK 0xFF +#define BYPASSD_MASK 0x01 +#define BPRCOSH_MASK 0x01 +#define BPRCISH_MASK 0x01 +#define BPRCNSH_MASK 0x01 +#define BPSHCFG_MASK 0x03 +#define NSCFG_MASK 0x03 +#define BPMTCFG_MASK 0x01 +#define BPMEMTYPE_MASK 0x07 + + +/* REV */ +#define MINOR_MASK 0x0F +#define MAJOR_MASK 0x0F + + +/* TESTBUSCR */ +#define TBE_MASK 0x01 +#define SPDMBE_MASK 0x01 +#define WGSEL_MASK 0x03 +#define TBLSEL_MASK 0x03 +#define TBHSEL_MASK 0x03 +#define SPDM0SEL_MASK 0x0F +#define SPDM1SEL_MASK 0x0F +#define SPDM2SEL_MASK 0x0F +#define SPDM3SEL_MASK 0x0F + + +/* TLBIMID */ +#define TLBIVMID_VMID_MASK 0x1F + + +/* TLBRSW */ +#define TLBRSW_INDEX_MASK 0xFF +#define TLBBFBS_MASK 0x03 + + +/* TLBTR0 */ +#define PR_MASK 0x01 +#define PW_MASK 0x01 +#define UR_MASK 0x01 +#define UW_MASK 0x01 +#define XN_MASK 0x01 +#define NSDESC_MASK 0x01 +#define ISH_MASK 0x01 +#define SH_MASK 0x01 +#define MT_MASK 0x07 +#define DPSIZR_MASK 0x07 +#define DPSIZC_MASK 0x07 + + +/* TLBTR1 */ +#define TLBTR1_VMID_MASK 0x1F +#define TLBTR1_PA_MASK 0x000FFFFF + + +/* TLBTR2 */ +#define TLBTR2_ASID_MASK 0xFF +#define TLBTR2_V_MASK 0x01 +#define TLBTR2_NSTID_MASK 0x01 +#define TLBTR2_NV_MASK 0x01 +#define TLBTR2_VA_MASK 0x000FFFFF + + +/* Global Register Shifts */ +/* CBACRn */ +#define RWVMID_SHIFT 0 +#define RWE_SHIFT 8 +#define RWGE_SHIFT 9 +#define CBVMID_SHIFT 16 +#define IRPTNDX_SHIFT 24 + + +/* CR */ +#define RPUE_SHIFT 0 +#define RPUERE_SHIFT 1 +#define RPUEIE_SHIFT 2 +#define DCDEE_SHIFT 3 +#define CLIENTPD_SHIFT 4 +#define STALLD_SHIFT 5 +#define TLBLKCRWE_SHIFT 6 +#define CR_TLBIALLCFG_SHIFT 7 +#define TLBIVMIDCFG_SHIFT 8 +#define CR_HUME_SHIFT 9 + + +/* ESR */ +#define CFG_SHIFT 0 +#define BYPASS_SHIFT 1 +#define ESR_MULTI_SHIFT 31 + + +/* ESYNR0 */ +#define ESYNR0_AMID_SHIFT 0 +#define ESYNR0_APID_SHIFT 8 +#define ESYNR0_ABID_SHIFT 13 +#define ESYNR0_AVMID_SHIFT 16 +#define ESYNR0_ATID_SHIFT 24 + + +/* ESYNR1 */ +#define ESYNR1_AMEMTYPE_SHIFT 0 +#define ESYNR1_ASHARED_SHIFT 3 +#define ESYNR1_AINNERSHARED_SHIFT 4 +#define ESYNR1_APRIV_SHIFT 5 +#define ESYNR1_APROTNS_SHIFT 6 +#define ESYNR1_AINST_SHIFT 7 +#define ESYNR1_AWRITE_SHIFT 8 +#define ESYNR1_ABURST_SHIFT 10 +#define ESYNR1_ALEN_SHIFT 12 +#define ESYNR1_ASIZE_SHIFT 16 +#define ESYNR1_ALOCK_SHIFT 20 +#define ESYNR1_AOOO_SHIFT 22 +#define ESYNR1_AFULL_SHIFT 24 +#define ESYNR1_AC_SHIFT 30 +#define ESYNR1_DCD_SHIFT 31 + + +/* IDR */ +#define NM2VCBMT_SHIFT 0 +#define HTW_SHIFT 9 +#define HUM_SHIFT 10 +#define TLBSIZE_SHIFT 12 +#define NCB_SHIFT 16 +#define NIRPT_SHIFT 24 + + +/* M2VCBRn */ +#define VMID_SHIFT 0 +#define CBNDX_SHIFT 8 +#define BYPASSD_SHIFT 16 +#define BPRCOSH_SHIFT 17 +#define BPRCISH_SHIFT 18 +#define BPRCNSH_SHIFT 19 +#define BPSHCFG_SHIFT 20 +#define NSCFG_SHIFT 22 +#define BPMTCFG_SHIFT 24 +#define BPMEMTYPE_SHIFT 25 + + +/* REV */ +#define MINOR_SHIFT 0 +#define MAJOR_SHIFT 4 + + +/* TESTBUSCR */ +#define TBE_SHIFT 0 +#define SPDMBE_SHIFT 1 +#define WGSEL_SHIFT 8 +#define TBLSEL_SHIFT 12 +#define TBHSEL_SHIFT 14 +#define SPDM0SEL_SHIFT 16 +#define SPDM1SEL_SHIFT 20 +#define SPDM2SEL_SHIFT 24 +#define SPDM3SEL_SHIFT 28 + + +/* TLBIMID */ +#define TLBIVMID_VMID_SHIFT 0 + + +/* TLBRSW */ +#define TLBRSW_INDEX_SHIFT 0 +#define TLBBFBS_SHIFT 8 + + +/* TLBTR0 */ +#define PR_SHIFT 0 +#define PW_SHIFT 1 +#define UR_SHIFT 2 +#define UW_SHIFT 3 +#define XN_SHIFT 4 +#define NSDESC_SHIFT 6 +#define ISH_SHIFT 7 +#define SH_SHIFT 8 +#define MT_SHIFT 9 +#define DPSIZR_SHIFT 16 +#define DPSIZC_SHIFT 20 + + +/* TLBTR1 */ +#define TLBTR1_VMID_SHIFT 0 +#define TLBTR1_PA_SHIFT 12 + + +/* TLBTR2 */ +#define TLBTR2_ASID_SHIFT 0 +#define TLBTR2_V_SHIFT 8 +#define TLBTR2_NSTID_SHIFT 9 +#define TLBTR2_NV_SHIFT 10 +#define TLBTR2_VA_SHIFT 12 + + +/* Context Register Masks */ +/* ACTLR */ +#define CFERE_MASK 0x01 +#define CFEIE_MASK 0x01 +#define PTSHCFG_MASK 0x03 +#define RCOSH_MASK 0x01 +#define RCISH_MASK 0x01 +#define RCNSH_MASK 0x01 +#define PRIVCFG_MASK 0x03 +#define DNA_MASK 0x01 +#define DNLV2PA_MASK 0x01 +#define TLBMCFG_MASK 0x03 +#define CFCFG_MASK 0x01 +#define TIPCF_MASK 0x01 +#define V2PCFG_MASK 0x03 +#define HUME_MASK 0x01 +#define PTMTCFG_MASK 0x01 +#define PTMEMTYPE_MASK 0x07 + + +/* BFBCR */ +#define BFBDFE_MASK 0x01 +#define BFBSFE_MASK 0x01 +#define SFVS_MASK 0x01 +#define FLVIC_MASK 0x0F +#define SLVIC_MASK 0x0F + + +/* CONTEXTIDR */ +#define CONTEXTIDR_ASID_MASK 0xFF +#define PROCID_MASK 0x00FFFFFF + + +/* FSR */ +#define TF_MASK 0x01 +#define AFF_MASK 0x01 +#define APF_MASK 0x01 +#define TLBMF_MASK 0x01 +#define HTWDEEF_MASK 0x01 +#define HTWSEEF_MASK 0x01 +#define MHF_MASK 0x01 +#define SL_MASK 0x01 +#define SS_MASK 0x01 +#define MULTI_MASK 0x01 + + +/* FSYNR0 */ +#define AMID_MASK 0xFF +#define APID_MASK 0x1F +#define ABID_MASK 0x07 +#define ATID_MASK 0xFF + + +/* FSYNR1 */ +#define AMEMTYPE_MASK 0x07 +#define ASHARED_MASK 0x01 +#define AINNERSHARED_MASK 0x01 +#define APRIV_MASK 0x01 +#define APROTNS_MASK 0x01 +#define AINST_MASK 0x01 +#define AWRITE_MASK 0x01 +#define ABURST_MASK 0x01 +#define ALEN_MASK 0x0F +#define FSYNR1_ASIZE_MASK 0x07 +#define ALOCK_MASK 0x03 +#define AFULL_MASK 0x01 + + +/* NMRR */ +#define ICPC0_MASK 0x03 +#define ICPC1_MASK 0x03 +#define ICPC2_MASK 0x03 +#define ICPC3_MASK 0x03 +#define ICPC4_MASK 0x03 +#define ICPC5_MASK 0x03 +#define ICPC6_MASK 0x03 +#define ICPC7_MASK 0x03 +#define OCPC0_MASK 0x03 +#define OCPC1_MASK 0x03 +#define OCPC2_MASK 0x03 +#define OCPC3_MASK 0x03 +#define OCPC4_MASK 0x03 +#define OCPC5_MASK 0x03 +#define OCPC6_MASK 0x03 +#define OCPC7_MASK 0x03 + + +/* PAR */ +#define FAULT_MASK 0x01 +/* If a fault is present, these are the +same as the fault fields in the FAR */ +#define FAULT_TF_MASK 0x01 +#define FAULT_AFF_MASK 0x01 +#define FAULT_APF_MASK 0x01 +#define FAULT_TLBMF_MASK 0x01 +#define FAULT_HTWDEEF_MASK 0x01 +#define FAULT_HTWSEEF_MASK 0x01 +#define FAULT_MHF_MASK 0x01 +#define FAULT_SL_MASK 0x01 +#define FAULT_SS_MASK 0x01 + +/* If NO fault is present, the following + * fields are in effect + * (FAULT remains as before) */ +#define PAR_NOFAULT_SS_MASK 0x01 +#define PAR_NOFAULT_MT_MASK 0x07 +#define PAR_NOFAULT_SH_MASK 0x01 +#define PAR_NOFAULT_NS_MASK 0x01 +#define PAR_NOFAULT_NOS_MASK 0x01 +#define PAR_NPFAULT_PA_MASK 0x000FFFFF + + +/* PRRR */ +#define MTC0_MASK 0x03 +#define MTC1_MASK 0x03 +#define MTC2_MASK 0x03 +#define MTC3_MASK 0x03 +#define MTC4_MASK 0x03 +#define MTC5_MASK 0x03 +#define MTC6_MASK 0x03 +#define MTC7_MASK 0x03 +#define SHDSH0_MASK 0x01 +#define SHDSH1_MASK 0x01 +#define SHNMSH0_MASK 0x01 +#define SHNMSH1_MASK 0x01 +#define NOS0_MASK 0x01 +#define NOS1_MASK 0x01 +#define NOS2_MASK 0x01 +#define NOS3_MASK 0x01 +#define NOS4_MASK 0x01 +#define NOS5_MASK 0x01 +#define NOS6_MASK 0x01 +#define NOS7_MASK 0x01 + + +/* RESUME */ +#define TNR_MASK 0x01 + + +/* SCTLR */ +#define M_MASK 0x01 +#define TRE_MASK 0x01 +#define AFE_MASK 0x01 +#define HAF_MASK 0x01 +#define BE_MASK 0x01 +#define AFFD_MASK 0x01 + + +/* TLBIASID */ +#define TLBIASID_ASID_MASK 0xFF + + +/* TLBIVA */ +#define TLBIVA_ASID_MASK 0xFF +#define TLBIVA_VA_MASK 0x000FFFFF + + +/* TLBIVAA */ +#define TLBIVAA_VA_MASK 0x000FFFFF + + +/* TLBLCKR */ +#define LKE_MASK 0x01 +#define TLBLCKR_TLBIALLCFG_MASK 0x01 +#define TLBIASIDCFG_MASK 0x01 +#define TLBIVAACFG_MASK 0x01 +#define FLOOR_MASK 0xFF +#define VICTIM_MASK 0xFF + + +/* TTBCR */ +#define N_MASK 0x07 +#define PD0_MASK 0x01 +#define PD1_MASK 0x01 + + +/* TTBR0 */ +#define TTBR0_IRGNH_MASK 0x01 +#define TTBR0_SH_MASK 0x01 +#define TTBR0_ORGN_MASK 0x03 +#define TTBR0_NOS_MASK 0x01 +#define TTBR0_IRGNL_MASK 0x01 +#define TTBR0_PA_MASK 0x0003FFFF + + +/* TTBR1 */ +#define TTBR1_IRGNH_MASK 0x01 +#define TTBR1_SH_MASK 0x01 +#define TTBR1_ORGN_MASK 0x03 +#define TTBR1_NOS_MASK 0x01 +#define TTBR1_IRGNL_MASK 0x01 +#define TTBR1_PA_MASK 0x0003FFFF + + +/* V2PSR */ +#define HIT_MASK 0x01 +#define INDEX_MASK 0xFF + + +/* V2Pxx */ +#define V2Pxx_INDEX_MASK 0xFF +#define V2Pxx_VA_MASK 0x000FFFFF + + +/* Context Register Shifts */ +/* ACTLR */ +#define CFERE_SHIFT 0 +#define CFEIE_SHIFT 1 +#define PTSHCFG_SHIFT 2 +#define RCOSH_SHIFT 4 +#define RCISH_SHIFT 5 +#define RCNSH_SHIFT 6 +#define PRIVCFG_SHIFT 8 +#define DNA_SHIFT 10 +#define DNLV2PA_SHIFT 11 +#define TLBMCFG_SHIFT 12 +#define CFCFG_SHIFT 14 +#define TIPCF_SHIFT 15 +#define V2PCFG_SHIFT 16 +#define HUME_SHIFT 18 +#define PTMTCFG_SHIFT 20 +#define PTMEMTYPE_SHIFT 21 + + +/* BFBCR */ +#define BFBDFE_SHIFT 0 +#define BFBSFE_SHIFT 1 +#define SFVS_SHIFT 2 +#define FLVIC_SHIFT 4 +#define SLVIC_SHIFT 8 + + +/* CONTEXTIDR */ +#define CONTEXTIDR_ASID_SHIFT 0 +#define PROCID_SHIFT 8 + + +/* FSR */ +#define TF_SHIFT 1 +#define AFF_SHIFT 2 +#define APF_SHIFT 3 +#define TLBMF_SHIFT 4 +#define HTWDEEF_SHIFT 5 +#define HTWSEEF_SHIFT 6 +#define MHF_SHIFT 7 +#define SL_SHIFT 16 +#define SS_SHIFT 30 +#define MULTI_SHIFT 31 + + +/* FSYNR0 */ +#define AMID_SHIFT 0 +#define APID_SHIFT 8 +#define ABID_SHIFT 13 +#define ATID_SHIFT 24 + + +/* FSYNR1 */ +#define AMEMTYPE_SHIFT 0 +#define ASHARED_SHIFT 3 +#define AINNERSHARED_SHIFT 4 +#define APRIV_SHIFT 5 +#define APROTNS_SHIFT 6 +#define AINST_SHIFT 7 +#define AWRITE_SHIFT 8 +#define ABURST_SHIFT 10 +#define ALEN_SHIFT 12 +#define FSYNR1_ASIZE_SHIFT 16 +#define ALOCK_SHIFT 20 +#define AFULL_SHIFT 24 + + +/* NMRR */ +#define ICPC0_SHIFT 0 +#define ICPC1_SHIFT 2 +#define ICPC2_SHIFT 4 +#define ICPC3_SHIFT 6 +#define ICPC4_SHIFT 8 +#define ICPC5_SHIFT 10 +#define ICPC6_SHIFT 12 +#define ICPC7_SHIFT 14 +#define OCPC0_SHIFT 16 +#define OCPC1_SHIFT 18 +#define OCPC2_SHIFT 20 +#define OCPC3_SHIFT 22 +#define OCPC4_SHIFT 24 +#define OCPC5_SHIFT 26 +#define OCPC6_SHIFT 28 +#define OCPC7_SHIFT 30 + + +/* PAR */ +#define FAULT_SHIFT 0 +/* If a fault is present, these are the +same as the fault fields in the FAR */ +#define FAULT_TF_SHIFT 1 +#define FAULT_AFF_SHIFT 2 +#define FAULT_APF_SHIFT 3 +#define FAULT_TLBMF_SHIFT 4 +#define FAULT_HTWDEEF_SHIFT 5 +#define FAULT_HTWSEEF_SHIFT 6 +#define FAULT_MHF_SHIFT 7 +#define FAULT_SL_SHIFT 16 +#define FAULT_SS_SHIFT 30 + +/* If NO fault is present, the following + * fields are in effect + * (FAULT remains as before) */ +#define PAR_NOFAULT_SS_SHIFT 1 +#define PAR_NOFAULT_MT_SHIFT 4 +#define PAR_NOFAULT_SH_SHIFT 7 +#define PAR_NOFAULT_NS_SHIFT 9 +#define PAR_NOFAULT_NOS_SHIFT 10 +#define PAR_NPFAULT_PA_SHIFT 12 + + +/* PRRR */ +#define MTC0_SHIFT 0 +#define MTC1_SHIFT 2 +#define MTC2_SHIFT 4 +#define MTC3_SHIFT 6 +#define MTC4_SHIFT 8 +#define MTC5_SHIFT 10 +#define MTC6_SHIFT 12 +#define MTC7_SHIFT 14 +#define SHDSH0_SHIFT 16 +#define SHDSH1_SHIFT 17 +#define SHNMSH0_SHIFT 18 +#define SHNMSH1_SHIFT 19 +#define NOS0_SHIFT 24 +#define NOS1_SHIFT 25 +#define NOS2_SHIFT 26 +#define NOS3_SHIFT 27 +#define NOS4_SHIFT 28 +#define NOS5_SHIFT 29 +#define NOS6_SHIFT 30 +#define NOS7_SHIFT 31 + + +/* RESUME */ +#define TNR_SHIFT 0 + + +/* SCTLR */ +#define M_SHIFT 0 +#define TRE_SHIFT 1 +#define AFE_SHIFT 2 +#define HAF_SHIFT 3 +#define BE_SHIFT 4 +#define AFFD_SHIFT 5 + + +/* TLBIASID */ +#define TLBIASID_ASID_SHIFT 0 + + +/* TLBIVA */ +#define TLBIVA_ASID_SHIFT 0 +#define TLBIVA_VA_SHIFT 12 + + +/* TLBIVAA */ +#define TLBIVAA_VA_SHIFT 12 + + +/* TLBLCKR */ +#define LKE_SHIFT 0 +#define TLBLCKR_TLBIALLCFG_SHIFT 1 +#define TLBIASIDCFG_SHIFT 2 +#define TLBIVAACFG_SHIFT 3 +#define FLOOR_SHIFT 8 +#define VICTIM_SHIFT 8 + + +/* TTBCR */ +#define N_SHIFT 3 +#define PD0_SHIFT 4 +#define PD1_SHIFT 5 + + +/* TTBR0 */ +#define TTBR0_IRGNH_SHIFT 0 +#define TTBR0_SH_SHIFT 1 +#define TTBR0_ORGN_SHIFT 3 +#define TTBR0_NOS_SHIFT 5 +#define TTBR0_IRGNL_SHIFT 6 +#define TTBR0_PA_SHIFT 14 + + +/* TTBR1 */ +#define TTBR1_IRGNH_SHIFT 0 +#define TTBR1_SH_SHIFT 1 +#define TTBR1_ORGN_SHIFT 3 +#define TTBR1_NOS_SHIFT 5 +#define TTBR1_IRGNL_SHIFT 6 +#define TTBR1_PA_SHIFT 14 + + +/* V2PSR */ +#define HIT_SHIFT 0 +#define INDEX_SHIFT 8 + + +/* V2Pxx */ +#define V2Pxx_INDEX_SHIFT 0 +#define V2Pxx_VA_SHIFT 12 + +#endif diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h new file mode 100644 index 000000000000..36074cfc9ad2 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/irqs-8x60.h @@ -0,0 +1,253 @@ +/* Copyright (c) 2010 Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __ASM_ARCH_MSM_IRQS_8X60_H +#define __ASM_ARCH_MSM_IRQS_8X60_H + +/* MSM ACPU Interrupt Numbers */ + +/* 0-15: STI/SGI (software triggered/generated interrupts) + * 16-31: PPI (private peripheral interrupts) + * 32+: SPI (shared peripheral interrupts) + */ + +#define GIC_PPI_START 16 +#define GIC_SPI_START 32 + +#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 0) +#define INT_GP_TIMER_EXP (GIC_PPI_START + 1) +#define INT_GP_TIMER2_EXP (GIC_PPI_START + 2) +#define WDT0_ACCSCSSNBARK_INT (GIC_PPI_START + 3) +#define WDT1_ACCSCSSNBARK_INT (GIC_PPI_START + 4) +#define AVS_SVICINT (GIC_PPI_START + 5) +#define AVS_SVICINTSWDONE (GIC_PPI_START + 6) +#define CPU_DBGCPUXCOMMRXFULL (GIC_PPI_START + 7) +#define CPU_DBGCPUXCOMMTXEMPTY (GIC_PPI_START + 8) +#define CPU_SICCPUXPERFMONIRPTREQ (GIC_PPI_START + 9) +#define SC_AVSCPUXDOWN (GIC_PPI_START + 10) +#define SC_AVSCPUXUP (GIC_PPI_START + 11) +#define SC_SICCPUXACGIRPTREQ (GIC_PPI_START + 12) +/* PPI 13 to 15 are unused */ + + +#define SC_SICMPUIRPTREQ (GIC_SPI_START + 0) +#define SC_SICL2IRPTREQ (GIC_SPI_START + 1) +#define SC_SICL2ACGIRPTREQ (GIC_SPI_START + 2) +#define NC (GIC_SPI_START + 3) +#define TLMM_SCSS_DIR_CONN_IRQ_0 (GIC_SPI_START + 4) +#define TLMM_SCSS_DIR_CONN_IRQ_1 (GIC_SPI_START + 5) +#define TLMM_SCSS_DIR_CONN_IRQ_2 (GIC_SPI_START + 6) +#define TLMM_SCSS_DIR_CONN_IRQ_3 (GIC_SPI_START + 7) +#define TLMM_SCSS_DIR_CONN_IRQ_4 (GIC_SPI_START + 8) +#define TLMM_SCSS_DIR_CONN_IRQ_5 (GIC_SPI_START + 9) +#define TLMM_SCSS_DIR_CONN_IRQ_6 (GIC_SPI_START + 10) +#define TLMM_SCSS_DIR_CONN_IRQ_7 (GIC_SPI_START + 11) +#define TLMM_SCSS_DIR_CONN_IRQ_8 (GIC_SPI_START + 12) +#define TLMM_SCSS_DIR_CONN_IRQ_9 (GIC_SPI_START + 13) +#define PM8058_SEC_IRQ_N (GIC_SPI_START + 14) +#define PM8901_SEC_IRQ_N (GIC_SPI_START + 15) +#define TLMM_SCSS_SUMMARY_IRQ (GIC_SPI_START + 16) +#define SPDM_RT_1_IRQ (GIC_SPI_START + 17) +#define SPDM_DIAG_IRQ (GIC_SPI_START + 18) +#define RPM_SCSS_CPU0_GP_HIGH_IRQ (GIC_SPI_START + 19) +#define RPM_SCSS_CPU0_GP_MEDIUM_IRQ (GIC_SPI_START + 20) +#define RPM_SCSS_CPU0_GP_LOW_IRQ (GIC_SPI_START + 21) +#define RPM_SCSS_CPU0_WAKE_UP_IRQ (GIC_SPI_START + 22) +#define RPM_SCSS_CPU1_GP_HIGH_IRQ (GIC_SPI_START + 23) +#define RPM_SCSS_CPU1_GP_MEDIUM_IRQ (GIC_SPI_START + 24) +#define RPM_SCSS_CPU1_GP_LOW_IRQ (GIC_SPI_START + 25) +#define RPM_SCSS_CPU1_WAKE_UP_IRQ (GIC_SPI_START + 26) +#define SSBI2_2_SC_CPU0_SECURE_INT (GIC_SPI_START + 27) +#define SSBI2_2_SC_CPU0_NON_SECURE_INT (GIC_SPI_START + 28) +#define SSBI2_1_SC_CPU0_SECURE_INT (GIC_SPI_START + 29) +#define SSBI2_1_SC_CPU0_NON_SECURE_INT (GIC_SPI_START + 30) +#define MSMC_SC_SEC_CE_IRQ (GIC_SPI_START + 31) +#define MSMC_SC_PRI_CE_IRQ (GIC_SPI_START + 32) +#define MARM_FIQ (GIC_SPI_START + 33) +#define MARM_IRQ (GIC_SPI_START + 34) +#define MARM_L2CC_IRQ (GIC_SPI_START + 35) +#define MARM_WDOG_EXPIRED (GIC_SPI_START + 36) +#define MARM_SCSS_GP_IRQ_0 (GIC_SPI_START + 37) +#define MARM_SCSS_GP_IRQ_1 (GIC_SPI_START + 38) +#define MARM_SCSS_GP_IRQ_2 (GIC_SPI_START + 39) +#define MARM_SCSS_GP_IRQ_3 (GIC_SPI_START + 40) +#define MARM_SCSS_GP_IRQ_4 (GIC_SPI_START + 41) +#define MARM_SCSS_GP_IRQ_5 (GIC_SPI_START + 42) +#define MARM_SCSS_GP_IRQ_6 (GIC_SPI_START + 43) +#define MARM_SCSS_GP_IRQ_7 (GIC_SPI_START + 44) +#define MARM_SCSS_GP_IRQ_8 (GIC_SPI_START + 45) +#define MARM_SCSS_GP_IRQ_9 (GIC_SPI_START + 46) +#define VPE_IRQ (GIC_SPI_START + 47) +#define VFE_IRQ (GIC_SPI_START + 48) +#define VCODEC_IRQ (GIC_SPI_START + 49) +#define TV_ENC_IRQ (GIC_SPI_START + 50) +#define SMMU_VPE_CB_SC_SECURE_IRQ (GIC_SPI_START + 51) +#define SMMU_VPE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 52) +#define SMMU_VFE_CB_SC_SECURE_IRQ (GIC_SPI_START + 53) +#define SMMU_VFE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 54) +#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ (GIC_SPI_START + 55) +#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 56) +#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ (GIC_SPI_START + 57) +#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 58) +#define SMMU_ROT_CB_SC_SECURE_IRQ (GIC_SPI_START + 59) +#define SMMU_ROT_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 60) +#define SMMU_MDP1_CB_SC_SECURE_IRQ (GIC_SPI_START + 61) +#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 62) +#define SMMU_MDP0_CB_SC_SECURE_IRQ (GIC_SPI_START + 63) +#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 64) +#define SMMU_JPEGD_CB_SC_SECURE_IRQ (GIC_SPI_START + 65) +#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 66) +#define SMMU_IJPEG_CB_SC_SECURE_IRQ (GIC_SPI_START + 67) +#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 68) +#define SMMU_GFX3D_CB_SC_SECURE_IRQ (GIC_SPI_START + 69) +#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 70) +#define SMMU_GFX2D0_CB_SC_SECURE_IRQ (GIC_SPI_START + 71) +#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 72) +#define ROT_IRQ (GIC_SPI_START + 73) +#define MMSS_FABRIC_IRQ (GIC_SPI_START + 74) +#define MDP_IRQ (GIC_SPI_START + 75) +#define JPEGD_IRQ (GIC_SPI_START + 76) +#define JPEG_IRQ (GIC_SPI_START + 77) +#define MMSS_IMEM_IRQ (GIC_SPI_START + 78) +#define HDMI_IRQ (GIC_SPI_START + 79) +#define GFX3D_IRQ (GIC_SPI_START + 80) +#define GFX2D0_IRQ (GIC_SPI_START + 81) +#define DSI_IRQ (GIC_SPI_START + 82) +#define CSI_1_IRQ (GIC_SPI_START + 83) +#define CSI_0_IRQ (GIC_SPI_START + 84) +#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ (GIC_SPI_START + 85) +#define LPASS_SCSS_MIDI_IRQ (GIC_SPI_START + 86) +#define LPASS_Q6SS_WDOG_EXPIRED (GIC_SPI_START + 87) +#define LPASS_SCSS_GP_LOW_IRQ (GIC_SPI_START + 88) +#define LPASS_SCSS_GP_MEDIUM_IRQ (GIC_SPI_START + 89) +#define LPASS_SCSS_GP_HIGH_IRQ (GIC_SPI_START + 90) +#define TOP_IMEM_IRQ (GIC_SPI_START + 91) +#define FABRIC_SYS_IRQ (GIC_SPI_START + 92) +#define FABRIC_APPS_IRQ (GIC_SPI_START + 93) +#define USB1_HS_BAM_IRQ (GIC_SPI_START + 94) +#define SDC4_BAM_IRQ (GIC_SPI_START + 95) +#define SDC3_BAM_IRQ (GIC_SPI_START + 96) +#define SDC2_BAM_IRQ (GIC_SPI_START + 97) +#define SDC1_BAM_IRQ (GIC_SPI_START + 98) +#define FABRIC_SPS_IRQ (GIC_SPI_START + 99) +#define USB1_HS_IRQ (GIC_SPI_START + 100) +#define SDC4_IRQ_0 (GIC_SPI_START + 101) +#define SDC3_IRQ_0 (GIC_SPI_START + 102) +#define SDC2_IRQ_0 (GIC_SPI_START + 103) +#define SDC1_IRQ_0 (GIC_SPI_START + 104) +#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105) +#define SPS_SEC_VIOL_IRQ (GIC_SPI_START + 106) +#define SPS_MTI_0 (GIC_SPI_START + 107) +#define SPS_MTI_1 (GIC_SPI_START + 108) +#define SPS_MTI_2 (GIC_SPI_START + 109) +#define SPS_MTI_3 (GIC_SPI_START + 110) +#define SPS_MTI_4 (GIC_SPI_START + 111) +#define SPS_MTI_5 (GIC_SPI_START + 112) +#define SPS_MTI_6 (GIC_SPI_START + 113) +#define SPS_MTI_7 (GIC_SPI_START + 114) +#define SPS_MTI_8 (GIC_SPI_START + 115) +#define SPS_MTI_9 (GIC_SPI_START + 116) +#define SPS_MTI_10 (GIC_SPI_START + 117) +#define SPS_MTI_11 (GIC_SPI_START + 118) +#define SPS_MTI_12 (GIC_SPI_START + 119) +#define SPS_MTI_13 (GIC_SPI_START + 120) +#define SPS_MTI_14 (GIC_SPI_START + 121) +#define SPS_MTI_15 (GIC_SPI_START + 122) +#define SPS_MTI_16 (GIC_SPI_START + 123) +#define SPS_MTI_17 (GIC_SPI_START + 124) +#define SPS_MTI_18 (GIC_SPI_START + 125) +#define SPS_MTI_19 (GIC_SPI_START + 126) +#define SPS_MTI_20 (GIC_SPI_START + 127) +#define SPS_MTI_21 (GIC_SPI_START + 128) +#define SPS_MTI_22 (GIC_SPI_START + 129) +#define SPS_MTI_23 (GIC_SPI_START + 130) +#define SPS_MTI_24 (GIC_SPI_START + 131) +#define SPS_MTI_25 (GIC_SPI_START + 132) +#define SPS_MTI_26 (GIC_SPI_START + 133) +#define SPS_MTI_27 (GIC_SPI_START + 134) +#define SPS_MTI_28 (GIC_SPI_START + 135) +#define SPS_MTI_29 (GIC_SPI_START + 136) +#define SPS_MTI_30 (GIC_SPI_START + 137) +#define SPS_MTI_31 (GIC_SPI_START + 138) +#define UXMC_EBI2_WR_ER_DONE_IRQ (GIC_SPI_START + 139) +#define UXMC_EBI2_OP_DONE_IRQ (GIC_SPI_START + 140) +#define USB2_IRQ (GIC_SPI_START + 141) +#define USB1_IRQ (GIC_SPI_START + 142) +#define TSSC_SSBI_IRQ (GIC_SPI_START + 143) +#define TSSC_SAMPLE_IRQ (GIC_SPI_START + 144) +#define TSSC_PENUP_IRQ (GIC_SPI_START + 145) +#define INT_UART1DM_IRQ (GIC_SPI_START + 146) +#define GSBI1_QUP_IRQ (GIC_SPI_START + 147) +#define INT_UART2DM_IRQ (GIC_SPI_START + 148) +#define GSBI2_QUP_IRQ (GIC_SPI_START + 149) +#define INT_UART3DM_IRQ (GIC_SPI_START + 150) +#define GSBI3_QUP_IRQ (GIC_SPI_START + 151) +#define INT_UART4DM_IRQ (GIC_SPI_START + 152) +#define GSBI4_QUP_IRQ (GIC_SPI_START + 153) +#define INT_UART5DM_IRQ (GIC_SPI_START + 154) +#define GSBI5_QUP_IRQ (GIC_SPI_START + 155) +#define INT_UART6DM_IRQ (GIC_SPI_START + 156) +#define GSBI6_QUP_IRQ (GIC_SPI_START + 157) +#define INT_UART7DM_IRQ (GIC_SPI_START + 158) +#define GSBI7_QUP_IRQ (GIC_SPI_START + 159) +#define INT_UART8DM_IRQ (GIC_SPI_START + 160) +#define GSBI8_QUP_IRQ (GIC_SPI_START + 161) +#define TSIF_TSPP_IRQ (GIC_SPI_START + 162) +#define TSIF_BAM_IRQ (GIC_SPI_START + 163) +#define TSIF2_IRQ (GIC_SPI_START + 164) +#define TSIF1_IRQ (GIC_SPI_START + 165) +#define INT_ADM1_MASTER (GIC_SPI_START + 166) +#define INT_ADM1_AARM (GIC_SPI_START + 167) +#define INT_ADM1_SD2 (GIC_SPI_START + 168) +#define INT_ADM1_SD3 (GIC_SPI_START + 169) +#define INT_ADM0_MASTER (GIC_SPI_START + 170) +#define INT_ADM0_AARM (GIC_SPI_START + 171) +#define INT_ADM0_SD2 (GIC_SPI_START + 172) +#define INT_ADM0_SD3 (GIC_SPI_START + 173) +#define CC_SCSS_WDT1CPU1BITEEXPIRED (GIC_SPI_START + 174) +#define CC_SCSS_WDT1CPU0BITEEXPIRED (GIC_SPI_START + 175) +#define CC_SCSS_WDT0CPU1BITEEXPIRED (GIC_SPI_START + 176) +#define CC_SCSS_WDT0CPU0BITEEXPIRED (GIC_SPI_START + 177) +#define TSENS_UPPER_LOWER_INT (GIC_SPI_START + 178) +#define SSBI2_2_SC_CPU1_SECURE_INT (GIC_SPI_START + 179) +#define SSBI2_2_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 180) +#define SSBI2_1_SC_CPU1_SECURE_INT (GIC_SPI_START + 181) +#define SSBI2_1_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 182) +#define XPU_SUMMARY_IRQ (GIC_SPI_START + 183) +#define BUS_EXCEPTION_SUMMARY_IRQ (GIC_SPI_START + 184) +#define HSDDRX_SMICH0_IRQ (GIC_SPI_START + 185) +#define HSDDRX_EBI1_IRQ (GIC_SPI_START + 186) +#define SDC5_BAM_IRQ (GIC_SPI_START + 187) +#define SDC5_IRQ_0 (GIC_SPI_START + 188) +#define INT_UART9DM_IRQ (GIC_SPI_START + 189) +#define GSBI9_QUP_IRQ (GIC_SPI_START + 190) +#define INT_UART10DM_IRQ (GIC_SPI_START + 191) +#define GSBI10_QUP_IRQ (GIC_SPI_START + 192) +#define INT_UART11DM_IRQ (GIC_SPI_START + 193) +#define GSBI11_QUP_IRQ (GIC_SPI_START + 194) +#define INT_UART12DM_IRQ (GIC_SPI_START + 195) +#define GSBI12_QUP_IRQ (GIC_SPI_START + 196) +/*SPI 197 to 216 arent used in 8x60*/ +#define SMPSS_SPARE_1 (GIC_SPI_START + 217) +#define SMPSS_SPARE_2 (GIC_SPI_START + 218) +#define SMPSS_SPARE_3 (GIC_SPI_START + 219) +#define SMPSS_SPARE_4 (GIC_SPI_START + 220) +#define SMPSS_SPARE_5 (GIC_SPI_START + 221) +#define SMPSS_SPARE_6 (GIC_SPI_START + 222) +#define SMPSS_SPARE_7 (GIC_SPI_START + 223) + +#define NR_GPIO_IRQS 173 +#define NR_MSM_IRQS 256 +#define NR_BOARD_IRQS 0 + +#endif diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h index 164d355c96ea..8679a4564744 100644 --- a/arch/arm/mach-msm/include/mach/irqs.h +++ b/arch/arm/mach-msm/include/mach/irqs.h @@ -24,6 +24,8 @@ #elif defined(CONFIG_ARCH_QSD8X50) #include "irqs-8x50.h" #include "sirc.h" +#elif defined(CONFIG_ARCH_MSM8X60) +#include "irqs-8x60.h" #elif defined(CONFIG_ARCH_MSM_ARM11) #include "irqs-7x00.h" #else diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h index 50c7847e6002..070e17d237f1 100644 --- a/arch/arm/mach-msm/include/mach/memory.h +++ b/arch/arm/mach-msm/include/mach/memory.h @@ -23,6 +23,8 @@ #define PHYS_OFFSET UL(0x20000000) #elif defined(CONFIG_ARCH_MSM7X30) #define PHYS_OFFSET UL(0x00200000) +#elif defined(CONFIG_ARCH_MSM8X60) +#define PHYS_OFFSET UL(0x40200000) #else #define PHYS_OFFSET UL(0x10000000) #endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h new file mode 100644 index 000000000000..45bab50e3ee6 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. + * Author: Brian Swetland <swetland@google.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * The MSM peripherals are spread all over across 768MB of physical + * space, which makes just having a simple IO_ADDRESS macro to slide + * them into the right virtual location rough. Instead, we will + * provide a master phys->virt mapping for peripherals here. + * + */ + +#ifndef __ASM_ARCH_MSM_IOMAP_8X60_H +#define __ASM_ARCH_MSM_IOMAP_8X60_H + +/* Physical base address and size of peripherals. + * Ordered by the virtual base addresses they will be mapped at. + * + * MSM_VIC_BASE must be an value that can be loaded via a "mov" + * instruction, otherwise entry-macro.S will not compile. + * + * If you add or remove entries here, you'll want to edit the + * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your + * changes. + * + */ + +#define MSM_QGIC_DIST_BASE IOMEM(0xF0000000) +#define MSM_QGIC_DIST_PHYS 0x02080000 +#define MSM_QGIC_DIST_SIZE SZ_4K + +#define MSM_QGIC_CPU_BASE IOMEM(0xF0001000) +#define MSM_QGIC_CPU_PHYS 0x02081000 +#define MSM_QGIC_CPU_SIZE SZ_4K + +#define MSM_ACC_BASE IOMEM(0xF0002000) +#define MSM_ACC_PHYS 0x02001000 +#define MSM_ACC_SIZE SZ_4K + +#define MSM_GCC_BASE IOMEM(0xF0003000) +#define MSM_GCC_PHYS 0x02082000 +#define MSM_GCC_SIZE SZ_4K + +#define MSM_TLMM_BASE IOMEM(0xF0004000) +#define MSM_TLMM_PHYS 0x00800000 +#define MSM_TLMM_SIZE SZ_16K + +#define MSM_SHARED_RAM_BASE IOMEM(0xF0100000) +#define MSM_SHARED_RAM_SIZE SZ_1M + +#define MSM_TMR_BASE IOMEM(0xF0200000) +#define MSM_TMR_PHYS 0x02000000 +#define MSM_TMR_SIZE (SZ_1M) + +#define MSM_GPT_BASE (MSM_TMR_BASE + 0x4) +#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24) + +#define MSM_IOMMU_JPEGD_PHYS 0x07300000 +#define MSM_IOMMU_JPEGD_SIZE SZ_1M + +#define MSM_IOMMU_VPE_PHYS 0x07400000 +#define MSM_IOMMU_VPE_SIZE SZ_1M + +#define MSM_IOMMU_MDP0_PHYS 0x07500000 +#define MSM_IOMMU_MDP0_SIZE SZ_1M + +#define MSM_IOMMU_MDP1_PHYS 0x07600000 +#define MSM_IOMMU_MDP1_SIZE SZ_1M + +#define MSM_IOMMU_ROT_PHYS 0x07700000 +#define MSM_IOMMU_ROT_SIZE SZ_1M + +#define MSM_IOMMU_IJPEG_PHYS 0x07800000 +#define MSM_IOMMU_IJPEG_SIZE SZ_1M + +#define MSM_IOMMU_VFE_PHYS 0x07900000 +#define MSM_IOMMU_VFE_SIZE SZ_1M + +#define MSM_IOMMU_VCODEC_A_PHYS 0x07A00000 +#define MSM_IOMMU_VCODEC_A_SIZE SZ_1M + +#define MSM_IOMMU_VCODEC_B_PHYS 0x07B00000 +#define MSM_IOMMU_VCODEC_B_SIZE SZ_1M + +#define MSM_IOMMU_GFX3D_PHYS 0x07C00000 +#define MSM_IOMMU_GFX3D_SIZE SZ_1M + +#define MSM_IOMMU_GFX2D0_PHYS 0x07D00000 +#define MSM_IOMMU_GFX2D0_SIZE SZ_1M + +#endif diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index e6b1821cc4ea..8e24dd812139 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h @@ -47,8 +47,12 @@ #include "msm_iomap-7x30.h" #elif defined(CONFIG_ARCH_QSD8X50) #include "msm_iomap-8x50.h" +#elif defined(CONFIG_ARCH_MSM8X60) +#include "msm_iomap-8x60.h" #else #include "msm_iomap-7x00.h" #endif + + #endif diff --git a/arch/arm/mach-msm/include/mach/smp.h b/arch/arm/mach-msm/include/mach/smp.h new file mode 100644 index 000000000000..3ff7bf5e679e --- /dev/null +++ b/arch/arm/mach-msm/include/mach/smp.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Code Aurora nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __ASM_ARCH_MSM_SMP_H +#define __ASM_ARCH_MSM_SMP_H + +#include <asm/hardware/gic.h> + +static inline void smp_cross_call(const struct cpumask *mask) +{ + gic_raise_softirq(mask, 1); +} + +#endif diff --git a/arch/arm/mach-msm/include/mach/vmalloc.h b/arch/arm/mach-msm/include/mach/vmalloc.h index 05f81fd8623c..31a32ad062dc 100644 --- a/arch/arm/mach-msm/include/mach/vmalloc.h +++ b/arch/arm/mach-msm/include/mach/vmalloc.h @@ -16,7 +16,7 @@ #ifndef __ASM_ARCH_MSM_VMALLOC_H #define __ASM_ARCH_MSM_VMALLOC_H -#define VMALLOC_END (PAGE_OFFSET + 0x10000000) +#define VMALLOC_END 0xd0000000 #endif diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 1c05060b5f3b..d36b61074146 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -100,6 +100,21 @@ void __init msm_map_qsd8x50_io(void) } #endif /* CONFIG_ARCH_QSD8X50 */ +#ifdef CONFIG_ARCH_MSM8X60 +static struct map_desc msm8x60_io_desc[] __initdata = { + MSM_DEVICE(QGIC_DIST), + MSM_DEVICE(QGIC_CPU), + MSM_DEVICE(TMR), + MSM_DEVICE(ACC), + MSM_DEVICE(GCC), +}; + +void __init msm_map_msm8x60_io(void) +{ + iotable_init(msm8x60_io_desc, ARRAY_SIZE(msm8x60_io_desc)); +} +#endif /* CONFIG_ARCH_MSM8X60 */ + #ifdef CONFIG_ARCH_MSM7X30 static struct map_desc msm7x30_io_desc[] __initdata = { MSM_DEVICE(VIC), diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c new file mode 100644 index 000000000000..f71747db3bee --- /dev/null +++ b/arch/arm/mach-msm/iommu.c @@ -0,0 +1,597 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/errno.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <linux/iommu.h> + +#include <asm/cacheflush.h> +#include <asm/sizes.h> + +#include <mach/iommu_hw-8xxx.h> +#include <mach/iommu.h> + +DEFINE_SPINLOCK(msm_iommu_lock); + +struct msm_priv { + unsigned long *pgtable; + struct list_head list_attached; +}; + +static void __flush_iotlb(struct iommu_domain *domain) +{ + struct msm_priv *priv = domain->priv; + struct msm_iommu_drvdata *iommu_drvdata; + struct msm_iommu_ctx_drvdata *ctx_drvdata; + +#ifndef CONFIG_IOMMU_PGTABLES_L2 + unsigned long *fl_table = priv->pgtable; + int i; + + dmac_flush_range(fl_table, fl_table + SZ_16K); + + for (i = 0; i < NUM_FL_PTE; i++) + if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) { + void *sl_table = __va(fl_table[i] & FL_BASE_MASK); + dmac_flush_range(sl_table, sl_table + SZ_4K); + } +#endif + + list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) { + if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent) + BUG(); + + iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent); + SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0); + } +} + +static void __reset_context(void __iomem *base, int ctx) +{ + SET_BPRCOSH(base, ctx, 0); + SET_BPRCISH(base, ctx, 0); + SET_BPRCNSH(base, ctx, 0); + SET_BPSHCFG(base, ctx, 0); + SET_BPMTCFG(base, ctx, 0); + SET_ACTLR(base, ctx, 0); + SET_SCTLR(base, ctx, 0); + SET_FSRRESTORE(base, ctx, 0); + SET_TTBR0(base, ctx, 0); + SET_TTBR1(base, ctx, 0); + SET_TTBCR(base, ctx, 0); + SET_BFBCR(base, ctx, 0); + SET_PAR(base, ctx, 0); + SET_FAR(base, ctx, 0); + SET_CTX_TLBIALL(base, ctx, 0); + SET_TLBFLPTER(base, ctx, 0); + SET_TLBSLPTER(base, ctx, 0); + SET_TLBLKCR(base, ctx, 0); + SET_PRRR(base, ctx, 0); + SET_NMRR(base, ctx, 0); + SET_CONTEXTIDR(base, ctx, 0); +} + +static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable) +{ + __reset_context(base, ctx); + + /* Set up HTW mode */ + /* TLB miss configuration: perform HTW on miss */ + SET_TLBMCFG(base, ctx, 0x3); + + /* V2P configuration: HTW for access */ + SET_V2PCFG(base, ctx, 0x3); + + SET_TTBCR(base, ctx, 0); + SET_TTBR0_PA(base, ctx, (pgtable >> 14)); + + /* Invalidate the TLB for this context */ + SET_CTX_TLBIALL(base, ctx, 0); + + /* Set interrupt number to "secure" interrupt */ + SET_IRPTNDX(base, ctx, 0); + + /* Enable context fault interrupt */ + SET_CFEIE(base, ctx, 1); + + /* Stall access on a context fault and let the handler deal with it */ + SET_CFCFG(base, ctx, 1); + + /* Redirect all cacheable requests to L2 slave port. */ + SET_RCISH(base, ctx, 1); + SET_RCOSH(base, ctx, 1); + SET_RCNSH(base, ctx, 1); + + /* Turn on TEX Remap */ + SET_TRE(base, ctx, 1); + + /* Do not configure PRRR / NMRR on the IOMMU for now. We will assume + * TEX class 0 for everything until attributes are properly worked out + */ + SET_PRRR(base, ctx, 0); + SET_NMRR(base, ctx, 0); + + /* Turn on BFB prefetch */ + SET_BFBDFE(base, ctx, 1); + +#ifdef CONFIG_IOMMU_PGTABLES_L2 + /* Configure page tables as inner-cacheable and shareable to reduce + * the TLB miss penalty. + */ + SET_TTBR0_SH(base, ctx, 1); + SET_TTBR1_SH(base, ctx, 1); + + SET_TTBR0_NOS(base, ctx, 1); + SET_TTBR1_NOS(base, ctx, 1); + + SET_TTBR0_IRGNH(base, ctx, 0); /* WB, WA */ + SET_TTBR0_IRGNL(base, ctx, 1); + + SET_TTBR1_IRGNH(base, ctx, 0); /* WB, WA */ + SET_TTBR1_IRGNL(base, ctx, 1); + + SET_TTBR0_ORGN(base, ctx, 1); /* WB, WA */ + SET_TTBR1_ORGN(base, ctx, 1); /* WB, WA */ +#endif + + /* Enable the MMU */ + SET_M(base, ctx, 1); +} + +static int msm_iommu_domain_init(struct iommu_domain *domain) +{ + struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL); + + if (!priv) + goto fail_nomem; + + INIT_LIST_HEAD(&priv->list_attached); + priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL, + get_order(SZ_16K)); + + if (!priv->pgtable) + goto fail_nomem; + + memset(priv->pgtable, 0, SZ_16K); + domain->priv = priv; + return 0; + +fail_nomem: + kfree(priv); + return -ENOMEM; +} + +static void msm_iommu_domain_destroy(struct iommu_domain *domain) +{ + struct msm_priv *priv; + unsigned long flags; + unsigned long *fl_table; + int i; + + spin_lock_irqsave(&msm_iommu_lock, flags); + priv = domain->priv; + domain->priv = NULL; + + if (priv) { + fl_table = priv->pgtable; + + for (i = 0; i < NUM_FL_PTE; i++) + if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) + free_page((unsigned long) __va(((fl_table[i]) & + FL_BASE_MASK))); + + free_pages((unsigned long)priv->pgtable, get_order(SZ_16K)); + priv->pgtable = NULL; + } + + kfree(priv); + spin_unlock_irqrestore(&msm_iommu_lock, flags); +} + +static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) +{ + struct msm_priv *priv; + struct msm_iommu_ctx_dev *ctx_dev; + struct msm_iommu_drvdata *iommu_drvdata; + struct msm_iommu_ctx_drvdata *ctx_drvdata; + struct msm_iommu_ctx_drvdata *tmp_drvdata; + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&msm_iommu_lock, flags); + + priv = domain->priv; + + if (!priv || !dev) { + ret = -EINVAL; + goto fail; + } + + iommu_drvdata = dev_get_drvdata(dev->parent); + ctx_drvdata = dev_get_drvdata(dev); + ctx_dev = dev->platform_data; + + if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) { + ret = -EINVAL; + goto fail; + } + + list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm) + if (tmp_drvdata == ctx_drvdata) { + ret = -EBUSY; + goto fail; + } + + __program_context(iommu_drvdata->base, ctx_dev->num, + __pa(priv->pgtable)); + + list_add(&(ctx_drvdata->attached_elm), &priv->list_attached); + __flush_iotlb(domain); + +fail: + spin_unlock_irqrestore(&msm_iommu_lock, flags); + return ret; +} + +static void msm_iommu_detach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct msm_priv *priv; + struct msm_iommu_ctx_dev *ctx_dev; + struct msm_iommu_drvdata *iommu_drvdata; + struct msm_iommu_ctx_drvdata *ctx_drvdata; + unsigned long flags; + + spin_lock_irqsave(&msm_iommu_lock, flags); + priv = domain->priv; + + if (!priv || !dev) + goto fail; + + iommu_drvdata = dev_get_drvdata(dev->parent); + ctx_drvdata = dev_get_drvdata(dev); + ctx_dev = dev->platform_data; + + if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) + goto fail; + + __flush_iotlb(domain); + __reset_context(iommu_drvdata->base, ctx_dev->num); + list_del_init(&ctx_drvdata->attached_elm); + +fail: + spin_unlock_irqrestore(&msm_iommu_lock, flags); +} + +static int msm_iommu_map(struct iommu_domain *domain, unsigned long va, + phys_addr_t pa, int order, int prot) +{ + struct msm_priv *priv; + unsigned long flags; + unsigned long *fl_table; + unsigned long *fl_pte; + unsigned long fl_offset; + unsigned long *sl_table; + unsigned long *sl_pte; + unsigned long sl_offset; + size_t len = 0x1000UL << order; + int ret = 0; + + spin_lock_irqsave(&msm_iommu_lock, flags); + priv = domain->priv; + + if (!priv) { + ret = -EINVAL; + goto fail; + } + + fl_table = priv->pgtable; + + if (len != SZ_16M && len != SZ_1M && + len != SZ_64K && len != SZ_4K) { + pr_debug("Bad size: %d\n", len); + ret = -EINVAL; + goto fail; + } + + if (!fl_table) { + pr_debug("Null page table\n"); + ret = -EINVAL; + goto fail; + } + + fl_offset = FL_OFFSET(va); /* Upper 12 bits */ + fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */ + + if (len == SZ_16M) { + int i = 0; + for (i = 0; i < 16; i++) + *(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION | + FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT | + FL_SHARED; + } + + if (len == SZ_1M) + *fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE | + FL_TYPE_SECT | FL_SHARED; + + /* Need a 2nd level table */ + if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) { + unsigned long *sl; + sl = (unsigned long *) __get_free_pages(GFP_KERNEL, + get_order(SZ_4K)); + + if (!sl) { + pr_debug("Could not allocate second level table\n"); + ret = -ENOMEM; + goto fail; + } + + memset(sl, 0, SZ_4K); + *fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | FL_TYPE_TABLE); + } + + sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK)); + sl_offset = SL_OFFSET(va); + sl_pte = sl_table + sl_offset; + + + if (len == SZ_4K) + *sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 | + SL_SHARED | SL_TYPE_SMALL; + + if (len == SZ_64K) { + int i; + + for (i = 0; i < 16; i++) + *(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 | + SL_AP1 | SL_SHARED | SL_TYPE_LARGE; + } + + __flush_iotlb(domain); +fail: + spin_unlock_irqrestore(&msm_iommu_lock, flags); + return ret; +} + +static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va, + int order) +{ + struct msm_priv *priv; + unsigned long flags; + unsigned long *fl_table; + unsigned long *fl_pte; + unsigned long fl_offset; + unsigned long *sl_table; + unsigned long *sl_pte; + unsigned long sl_offset; + size_t len = 0x1000UL << order; + int i, ret = 0; + + spin_lock_irqsave(&msm_iommu_lock, flags); + + priv = domain->priv; + + if (!priv) { + ret = -ENODEV; + goto fail; + } + + fl_table = priv->pgtable; + + if (len != SZ_16M && len != SZ_1M && + len != SZ_64K && len != SZ_4K) { + pr_debug("Bad length: %d\n", len); + ret = -EINVAL; + goto fail; + } + + if (!fl_table) { + pr_debug("Null page table\n"); + ret = -EINVAL; + goto fail; + } + + fl_offset = FL_OFFSET(va); /* Upper 12 bits */ + fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */ + + if (*fl_pte == 0) { + pr_debug("First level PTE is 0\n"); + ret = -ENODEV; + goto fail; + } + + /* Unmap supersection */ + if (len == SZ_16M) + for (i = 0; i < 16; i++) + *(fl_pte+i) = 0; + + if (len == SZ_1M) + *fl_pte = 0; + + sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK)); + sl_offset = SL_OFFSET(va); + sl_pte = sl_table + sl_offset; + + if (len == SZ_64K) { + for (i = 0; i < 16; i++) + *(sl_pte+i) = 0; + } + + if (len == SZ_4K) + *sl_pte = 0; + + if (len == SZ_4K || len == SZ_64K) { + int used = 0; + + for (i = 0; i < NUM_SL_PTE; i++) + if (sl_table[i]) + used = 1; + if (!used) { + free_page((unsigned long)sl_table); + *fl_pte = 0; + } + } + + __flush_iotlb(domain); +fail: + spin_unlock_irqrestore(&msm_iommu_lock, flags); + return ret; +} + +static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain, + unsigned long va) +{ + struct msm_priv *priv; + struct msm_iommu_drvdata *iommu_drvdata; + struct msm_iommu_ctx_drvdata *ctx_drvdata; + unsigned int par; + unsigned long flags; + void __iomem *base; + phys_addr_t ret = 0; + int ctx; + + spin_lock_irqsave(&msm_iommu_lock, flags); + + priv = domain->priv; + if (list_empty(&priv->list_attached)) + goto fail; + + ctx_drvdata = list_entry(priv->list_attached.next, + struct msm_iommu_ctx_drvdata, attached_elm); + iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent); + + base = iommu_drvdata->base; + ctx = ctx_drvdata->num; + + /* Invalidate context TLB */ + SET_CTX_TLBIALL(base, ctx, 0); + SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT); + + if (GET_FAULT(base, ctx)) + goto fail; + + par = GET_PAR(base, ctx); + + /* We are dealing with a supersection */ + if (GET_NOFAULT_SS(base, ctx)) + ret = (par & 0xFF000000) | (va & 0x00FFFFFF); + else /* Upper 20 bits from PAR, lower 12 from VA */ + ret = (par & 0xFFFFF000) | (va & 0x00000FFF); + +fail: + spin_unlock_irqrestore(&msm_iommu_lock, flags); + return ret; +} + +static int msm_iommu_domain_has_cap(struct iommu_domain *domain, + unsigned long cap) +{ + return 0; +} + +static void print_ctx_regs(void __iomem *base, int ctx) +{ + unsigned int fsr = GET_FSR(base, ctx); + pr_err("FAR = %08x PAR = %08x\n", + GET_FAR(base, ctx), GET_PAR(base, ctx)); + pr_err("FSR = %08x [%s%s%s%s%s%s%s%s%s%s]\n", fsr, + (fsr & 0x02) ? "TF " : "", + (fsr & 0x04) ? "AFF " : "", + (fsr & 0x08) ? "APF " : "", + (fsr & 0x10) ? "TLBMF " : "", + (fsr & 0x20) ? "HTWDEEF " : "", + (fsr & 0x40) ? "HTWSEEF " : "", + (fsr & 0x80) ? "MHF " : "", + (fsr & 0x10000) ? "SL " : "", + (fsr & 0x40000000) ? "SS " : "", + (fsr & 0x80000000) ? "MULTI " : ""); + + pr_err("FSYNR0 = %08x FSYNR1 = %08x\n", + GET_FSYNR0(base, ctx), GET_FSYNR1(base, ctx)); + pr_err("TTBR0 = %08x TTBR1 = %08x\n", + GET_TTBR0(base, ctx), GET_TTBR1(base, ctx)); + pr_err("SCTLR = %08x ACTLR = %08x\n", + GET_SCTLR(base, ctx), GET_ACTLR(base, ctx)); + pr_err("PRRR = %08x NMRR = %08x\n", + GET_PRRR(base, ctx), GET_NMRR(base, ctx)); +} + +irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id) +{ + struct msm_iommu_drvdata *drvdata = dev_id; + void __iomem *base; + unsigned int fsr = 0; + int ncb = 0, i = 0; + + spin_lock(&msm_iommu_lock); + + if (!drvdata) { + pr_err("Invalid device ID in context interrupt handler\n"); + goto fail; + } + + base = drvdata->base; + + pr_err("===== WOAH! =====\n"); + pr_err("Unexpected IOMMU page fault!\n"); + pr_err("base = %08x\n", (unsigned int) base); + + ncb = GET_NCB(base)+1; + for (i = 0; i < ncb; i++) { + fsr = GET_FSR(base, i); + if (fsr) { + pr_err("Fault occurred in context %d.\n", i); + pr_err("Interesting registers:\n"); + print_ctx_regs(base, i); + SET_FSR(base, i, 0x4000000F); + } + } +fail: + spin_unlock(&msm_iommu_lock); + return 0; +} + +static struct iommu_ops msm_iommu_ops = { + .domain_init = msm_iommu_domain_init, + .domain_destroy = msm_iommu_domain_destroy, + .attach_dev = msm_iommu_attach_dev, + .detach_dev = msm_iommu_detach_dev, + .map = msm_iommu_map, + .unmap = msm_iommu_unmap, + .iova_to_phys = msm_iommu_iova_to_phys, + .domain_has_cap = msm_iommu_domain_has_cap +}; + +static int msm_iommu_init(void) +{ + register_iommu(&msm_iommu_ops); + return 0; +} + +subsys_initcall(msm_iommu_init); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>"); diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c new file mode 100644 index 000000000000..c33ae786c41f --- /dev/null +++ b/arch/arm/mach-msm/iommu_dev.c @@ -0,0 +1,374 @@ +/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/iommu.h> +#include <linux/interrupt.h> +#include <linux/err.h> +#include <linux/slab.h> + +#include <mach/iommu_hw-8xxx.h> +#include <mach/iommu.h> + +struct iommu_ctx_iter_data { + /* input */ + const char *name; + + /* output */ + struct device *dev; +}; + +static struct platform_device *msm_iommu_root_dev; + +static int each_iommu_ctx(struct device *dev, void *data) +{ + struct iommu_ctx_iter_data *res = data; + struct msm_iommu_ctx_dev *c = dev->platform_data; + + if (!res || !c || !c->name || !res->name) + return -EINVAL; + + if (!strcmp(res->name, c->name)) { + res->dev = dev; + return 1; + } + return 0; +} + +static int each_iommu(struct device *dev, void *data) +{ + return device_for_each_child(dev, data, each_iommu_ctx); +} + +struct device *msm_iommu_get_ctx(const char *ctx_name) +{ + struct iommu_ctx_iter_data r; + int found; + + if (!msm_iommu_root_dev) { + pr_err("No root IOMMU device.\n"); + goto fail; + } + + r.name = ctx_name; + found = device_for_each_child(&msm_iommu_root_dev->dev, &r, each_iommu); + + if (!found) { + pr_err("Could not find context <%s>\n", ctx_name); + goto fail; + } + + return r.dev; +fail: + return NULL; +} +EXPORT_SYMBOL(msm_iommu_get_ctx); + +static void msm_iommu_reset(void __iomem *base) +{ + int ctx, ncb; + + SET_RPUE(base, 0); + SET_RPUEIE(base, 0); + SET_ESRRESTORE(base, 0); + SET_TBE(base, 0); + SET_CR(base, 0); + SET_SPDMBE(base, 0); + SET_TESTBUSCR(base, 0); + SET_TLBRSW(base, 0); + SET_GLOBAL_TLBIALL(base, 0); + SET_RPU_ACR(base, 0); + SET_TLBLKCRWE(base, 1); + ncb = GET_NCB(base)+1; + + for (ctx = 0; ctx < ncb; ctx++) { + SET_BPRCOSH(base, ctx, 0); + SET_BPRCISH(base, ctx, 0); + SET_BPRCNSH(base, ctx, 0); + SET_BPSHCFG(base, ctx, 0); + SET_BPMTCFG(base, ctx, 0); + SET_ACTLR(base, ctx, 0); + SET_SCTLR(base, ctx, 0); + SET_FSRRESTORE(base, ctx, 0); + SET_TTBR0(base, ctx, 0); + SET_TTBR1(base, ctx, 0); + SET_TTBCR(base, ctx, 0); + SET_BFBCR(base, ctx, 0); + SET_PAR(base, ctx, 0); + SET_FAR(base, ctx, 0); + SET_CTX_TLBIALL(base, ctx, 0); + SET_TLBFLPTER(base, ctx, 0); + SET_TLBSLPTER(base, ctx, 0); + SET_TLBLKCR(base, ctx, 0); + SET_PRRR(base, ctx, 0); + SET_NMRR(base, ctx, 0); + SET_CONTEXTIDR(base, ctx, 0); + } +} + +static int msm_iommu_probe(struct platform_device *pdev) +{ + struct resource *r; + struct clk *iommu_clk; + struct msm_iommu_drvdata *drvdata; + struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data; + void __iomem *regs_base; + resource_size_t len; + int ret = 0, ncb, nm2v, irq; + + if (pdev->id != -1) { + drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); + + if (!drvdata) { + ret = -ENOMEM; + goto fail; + } + + if (!iommu_dev) { + ret = -ENODEV; + goto fail; + } + + if (iommu_dev->clk_rate != 0) { + iommu_clk = clk_get(&pdev->dev, "iommu_clk"); + + if (IS_ERR(iommu_clk)) { + ret = -ENODEV; + goto fail; + } + + if (iommu_dev->clk_rate > 0) { + ret = clk_set_rate(iommu_clk, + iommu_dev->clk_rate); + if (ret) { + clk_put(iommu_clk); + goto fail; + } + } + + ret = clk_enable(iommu_clk); + if (ret) { + clk_put(iommu_clk); + goto fail; + } + clk_put(iommu_clk); + } + + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "physbase"); + if (!r) { + ret = -ENODEV; + goto fail; + } + + len = r->end - r->start + 1; + + r = request_mem_region(r->start, len, r->name); + if (!r) { + pr_err("Could not request memory region: " + "start=%p, len=%d\n", (void *) r->start, len); + ret = -EBUSY; + goto fail; + } + + regs_base = ioremap(r->start, len); + + if (!regs_base) { + pr_err("Could not ioremap: start=%p, len=%d\n", + (void *) r->start, len); + ret = -EBUSY; + goto fail; + } + + irq = platform_get_irq_byname(pdev, "secure_irq"); + if (irq < 0) { + ret = -ENODEV; + goto fail; + } + + mb(); + + if (GET_IDR(regs_base) == 0) { + pr_err("Invalid IDR value detected\n"); + ret = -ENODEV; + goto fail; + } + + ret = request_irq(irq, msm_iommu_fault_handler, 0, + "msm_iommu_secure_irpt_handler", drvdata); + if (ret) { + pr_err("Request IRQ %d failed with ret=%d\n", irq, ret); + goto fail; + } + + msm_iommu_reset(regs_base); + drvdata->base = regs_base; + drvdata->irq = irq; + + nm2v = GET_NM2VCBMT((unsigned long) regs_base); + ncb = GET_NCB((unsigned long) regs_base); + + pr_info("device %s mapped at %p, irq %d with %d ctx banks\n", + iommu_dev->name, regs_base, irq, ncb+1); + + platform_set_drvdata(pdev, drvdata); + } else + msm_iommu_root_dev = pdev; + + return 0; + +fail: + kfree(drvdata); + return ret; +} + +static int msm_iommu_remove(struct platform_device *pdev) +{ + struct msm_iommu_drvdata *drv = NULL; + + drv = platform_get_drvdata(pdev); + if (drv) { + memset(drv, 0, sizeof(struct msm_iommu_drvdata)); + kfree(drv); + platform_set_drvdata(pdev, NULL); + } + return 0; +} + +static int msm_iommu_ctx_probe(struct platform_device *pdev) +{ + struct msm_iommu_ctx_dev *c = pdev->dev.platform_data; + struct msm_iommu_drvdata *drvdata; + struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL; + int i, ret = 0; + if (!c || !pdev->dev.parent) { + ret = -EINVAL; + goto fail; + } + + drvdata = dev_get_drvdata(pdev->dev.parent); + + if (!drvdata) { + ret = -ENODEV; + goto fail; + } + + ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL); + if (!ctx_drvdata) { + ret = -ENOMEM; + goto fail; + } + ctx_drvdata->num = c->num; + ctx_drvdata->pdev = pdev; + + INIT_LIST_HEAD(&ctx_drvdata->attached_elm); + platform_set_drvdata(pdev, ctx_drvdata); + + /* Program the M2V tables for this context */ + for (i = 0; i < MAX_NUM_MIDS; i++) { + int mid = c->mids[i]; + if (mid == -1) + break; + + SET_M2VCBR_N(drvdata->base, mid, 0); + SET_CBACR_N(drvdata->base, c->num, 0); + + /* Set VMID = MID */ + SET_VMID(drvdata->base, mid, mid); + + /* Set the context number for that MID to this context */ + SET_CBNDX(drvdata->base, mid, c->num); + + /* Set MID associated with this context bank */ + SET_CBVMID(drvdata->base, c->num, mid); + + /* Set security bit override to be Non-secure */ + SET_NSCFG(drvdata->base, mid, 3); + } + + pr_info("context device %s with bank index %d\n", c->name, c->num); + + return 0; +fail: + kfree(ctx_drvdata); + return ret; +} + +static int msm_iommu_ctx_remove(struct platform_device *pdev) +{ + struct msm_iommu_ctx_drvdata *drv = NULL; + drv = platform_get_drvdata(pdev); + if (drv) { + memset(drv, 0, sizeof(struct msm_iommu_ctx_drvdata)); + kfree(drv); + platform_set_drvdata(pdev, NULL); + } + return 0; +} + +static struct platform_driver msm_iommu_driver = { + .driver = { + .name = "msm_iommu", + }, + .probe = msm_iommu_probe, + .remove = msm_iommu_remove, +}; + +static struct platform_driver msm_iommu_ctx_driver = { + .driver = { + .name = "msm_iommu_ctx", + }, + .probe = msm_iommu_ctx_probe, + .remove = msm_iommu_ctx_remove, +}; + +static int msm_iommu_driver_init(void) +{ + int ret; + ret = platform_driver_register(&msm_iommu_driver); + if (ret != 0) { + pr_err("Failed to register IOMMU driver\n"); + goto error; + } + + ret = platform_driver_register(&msm_iommu_ctx_driver); + if (ret != 0) { + pr_err("Failed to register IOMMU context driver\n"); + goto error; + } + +error: + return ret; +} + +static void msm_iommu_driver_exit(void) +{ + platform_driver_unregister(&msm_iommu_ctx_driver); + platform_driver_unregister(&msm_iommu_driver); +} + +subsys_initcall(msm_iommu_driver_init); +module_exit(msm_iommu_driver_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>"); diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index dec5ca622d7d..7689848ec680 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -28,7 +28,6 @@ #ifndef MSM_DGT_BASE #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10) #endif -#define MSM_DGT_SHIFT (5) #define TIMER_MATCH_VAL 0x0000 #define TIMER_COUNT_VAL 0x0004 @@ -36,12 +35,28 @@ #define TIMER_ENABLE_CLR_ON_MATCH_EN 2 #define TIMER_ENABLE_EN 1 #define TIMER_CLEAR 0x000C - +#define DGT_CLK_CTL 0x0034 +enum { + DGT_CLK_CTL_DIV_1 = 0, + DGT_CLK_CTL_DIV_2 = 1, + DGT_CLK_CTL_DIV_3 = 2, + DGT_CLK_CTL_DIV_4 = 3, +}; #define CSR_PROTECTION 0x0020 #define CSR_PROTECTION_EN 1 #define GPT_HZ 32768 + +#if defined(CONFIG_ARCH_QSD8X50) +#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */ +#define MSM_DGT_SHIFT (0) +#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) +#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */ +#define MSM_DGT_SHIFT (0) +#else #define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */ +#define MSM_DGT_SHIFT (5) +#endif struct msm_clock { struct clock_event_device clockevent; @@ -170,6 +185,10 @@ static void __init msm_timer_init(void) int i; int res; +#ifdef CONFIG_ARCH_MSM8X60 + writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); +#endif + for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) { struct msm_clock *clock = &msm_clocks[i]; struct clock_event_device *ce = &clock->clockevent; diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig index c71a7bc19284..aa57e35ce3cd 100644 --- a/arch/arm/mach-mx25/Kconfig +++ b/arch/arm/mach-mx25/Kconfig @@ -12,6 +12,8 @@ config MACH_EUKREA_CPUIMX25 select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_MXC_NAND + select IMX_HAVE_PLATFORM_FLEXCAN + select IMX_HAVE_PLATFORM_ESDHC select MXC_ULPI if USB_ULPI choice @@ -20,8 +22,8 @@ choice default MACH_EUKREA_MBIMXSD25_BASEBOARD config MACH_EUKREA_MBIMXSD25_BASEBOARD - prompt "Eukrea MBIMXSD development board" - bool + bool "Eukrea MBIMXSD development board" + select IMX_HAVE_PLATFORM_IMX_SSI help This adds board specific devices that can be found on Eukrea's MBIMXSD evaluation board. diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c index 40c7cc41cee3..9e4a5578c2fb 100644 --- a/arch/arm/mach-mx25/clock.c +++ b/arch/arm/mach-mx25/clock.c @@ -72,7 +72,7 @@ unsigned long get_rate_arm(struct clk *clk) unsigned long rate = get_rate_mpll(); if (cctl & (1 << 14)) - rate = (rate * 3) >> 1; + rate = (rate * 3) >> 2; return rate / ((cctl >> 30) + 1); } @@ -99,7 +99,7 @@ static unsigned long get_rate_per(int per) if (readl(CRM_BASE + 0x64) & (1 << per)) fref = get_rate_upll(); else - fref = get_rate_ipg(NULL); + fref = get_rate_ahb(NULL); return fref / (val + 1); } @@ -139,6 +139,16 @@ static unsigned long get_rate_lcdc(struct clk *clk) return get_rate_per(7); } +static unsigned long get_rate_esdhc1(struct clk *clk) +{ + return get_rate_per(3); +} + +static unsigned long get_rate_esdhc2(struct clk *clk) +{ + return get_rate_per(4); +} + static unsigned long get_rate_csi(struct clk *clk) { return get_rate_per(0); @@ -213,6 +223,12 @@ DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL); DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL); DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL); DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL); +DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL); +DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL, + &esdhc1_ahb_clk); +DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL); +DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL, + &esdhc2_ahb_clk); DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL); DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL); DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk); @@ -238,10 +254,14 @@ DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk); DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL); DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk); DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk); +DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL, + &esdhc1_per_clk); +DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL, + &esdhc2_per_clk); DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL); DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk); DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL); -DEFINE_CLOCK(can2_clk, 0, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL); +DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL); #define _REGISTER_CLOCK(d, n, c) \ { \ @@ -261,9 +281,9 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) - _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) - _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk) - _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk) + _REGISTER_CLOCK("imx25-cspi.0", NULL, cspi1_clk) + _REGISTER_CLOCK("imx25-cspi.1", NULL, cspi2_clk) + _REGISTER_CLOCK("imx25-cspi.2", NULL, cspi3_clk) _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk) _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk) _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk) @@ -279,6 +299,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx-wdt.0", NULL, wdt_clk) _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk) _REGISTER_CLOCK(NULL, "audmux", audmux_clk) _REGISTER_CLOCK("flexcan.0", NULL, can1_clk) diff --git a/arch/arm/mach-mx25/devices-imx25.h b/arch/arm/mach-mx25/devices-imx25.h index d86a7c3ca8b0..93afa10b13cf 100644 --- a/arch/arm/mach-mx25/devices-imx25.h +++ b/arch/arm/mach-mx25/devices-imx25.h @@ -9,35 +9,46 @@ #include <mach/mx25.h> #include <mach/devices-common.h> +extern const struct imx_fec_data imx25_fec_data __initconst; +#define imx25_add_fec(pdata) \ + imx_add_fec(&imx25_fec_data, pdata) + #define imx25_add_flexcan0(pdata) \ imx_add_flexcan(0, MX25_CAN1_BASE_ADDR, SZ_16K, MX25_INT_CAN1, pdata) #define imx25_add_flexcan1(pdata) \ imx_add_flexcan(1, MX25_CAN2_BASE_ADDR, SZ_16K, MX25_INT_CAN2, pdata) -#define imx25_add_imx_i2c0(pdata) \ - imx_add_imx_i2c(0, MX25_I2C1_BASE_ADDR, SZ_16K, MX25_INT_I2C1, pdata) -#define imx25_add_imx_i2c1(pdata) \ - imx_add_imx_i2c(1, MX25_I2C2_BASE_ADDR, SZ_16K, MX25_INT_I2C2, pdata) -#define imx25_add_imx_i2c2(pdata) \ - imx_add_imx_i2c(2, MX25_I2C3_BASE_ADDR, SZ_16K, MX25_INT_I2C3, pdata) - -#define imx25_add_imx_uart0(pdata) \ - imx_add_imx_uart_1irq(0, MX25_UART1_BASE_ADDR, SZ_16K, MX25_INT_UART1, pdata) -#define imx25_add_imx_uart1(pdata) \ - imx_add_imx_uart_1irq(1, MX25_UART2_BASE_ADDR, SZ_16K, MX25_INT_UART2, pdata) -#define imx25_add_imx_uart2(pdata) \ - imx_add_imx_uart_1irq(2, MX25_UART3_BASE_ADDR, SZ_16K, MX25_INT_UART3, pdata) -#define imx25_add_imx_uart3(pdata) \ - imx_add_imx_uart_1irq(3, MX25_UART4_BASE_ADDR, SZ_16K, MX25_INT_UART4, pdata) -#define imx25_add_imx_uart4(pdata) \ - imx_add_imx_uart_1irq(4, MX25_UART5_BASE_ADDR, SZ_16K, MX25_INT_UART5, pdata) +extern const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst; +#define imx25_add_imx_i2c(id, pdata) \ + imx_add_imx_i2c(&imx25_imx_i2c_data[id], pdata) +#define imx25_add_imx_i2c0(pdata) imx25_add_imx_i2c(0, pdata) +#define imx25_add_imx_i2c1(pdata) imx25_add_imx_i2c(1, pdata) +#define imx25_add_imx_i2c2(pdata) imx25_add_imx_i2c(2, pdata) + +extern const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst; +#define imx25_add_imx_ssi(id, pdata) \ + imx_add_imx_ssi(&imx25_imx_ssi_data[id], pdata) + +extern const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst; +#define imx25_add_imx_uart(id, pdata) \ + imx_add_imx_uart_1irq(&imx25_imx_uart_data[id], pdata) +#define imx25_add_imx_uart0(pdata) imx25_add_imx_uart(0, pdata) +#define imx25_add_imx_uart1(pdata) imx25_add_imx_uart(1, pdata) +#define imx25_add_imx_uart2(pdata) imx25_add_imx_uart(2, pdata) +#define imx25_add_imx_uart3(pdata) imx25_add_imx_uart(3, pdata) +#define imx25_add_imx_uart4(pdata) imx25_add_imx_uart(4, pdata) +extern const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst; #define imx25_add_mxc_nand(pdata) \ - imx_add_mxc_nand_v21(MX25_NFC_BASE_ADDR, MX25_INT_NANDFC, pdata) - -#define imx25_add_spi_imx0(pdata) \ - imx_add_spi_imx(0, MX25_CSPI1_BASE_ADDR, SZ_16K, MX25_INT_CSPI1, pdata) -#define imx25_add_spi_imx1(pdata) \ - imx_add_spi_imx(1, MX25_CSPI2_BASE_ADDR, SZ_16K, MX25_INT_CSPI2, pdata) -#define imx25_add_spi_imx2(pdata) \ - imx_add_spi_imx(2, MX25_CSPI3_BASE_ADDR, SZ_16K, MX25_INT_CSPI3, pdata) + imx_add_mxc_nand(&imx25_mxc_nand_data, pdata) + +extern const struct imx_spi_imx_data imx25_spi_imx_data[] __initconst; +#define imx25_add_spi_imx(id, pdata) \ + imx_add_spi_imx(&imx25_spi_imx_data[id], pdata) +#define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata) +#define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata) +#define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata) + +extern const struct imx_esdhc_imx_data imx25_esdhc_data[] __initconst; +#define imx25_add_esdhc(id, pdata) \ + imx_add_esdhc(&imx25_esdhc_data[id], pdata) diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c index 3468eb15b236..1d0eb3e85941 100644 --- a/arch/arm/mach-mx25/devices.c +++ b/arch/arm/mach-mx25/devices.c @@ -208,26 +208,6 @@ int __init imx25_register_gpios(void) return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); } -static struct resource mx25_fec_resources[] = { - { - .start = MX25_FEC_BASE_ADDR, - .end = MX25_FEC_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, - { - .start = MX25_INT_FEC, - .end = MX25_INT_FEC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mx25_fec_device = { - .name = "fec", - .id = 0, - .num_resources = ARRAY_SIZE(mx25_fec_resources), - .resource = mx25_fec_resources, -}; - static struct resource mx25_rtc_resources[] = { { .start = MX25_DRYICE_BASE_ADDR, @@ -305,44 +285,6 @@ struct platform_device mx25_kpp_device = { .resource = mx25_kpp_resources, }; -static struct resource imx_ssi_resources0[] = { - { - .start = MX25_SSI1_BASE_ADDR, - .end = MX25_SSI1_BASE_ADDR + 0x3fff, - .flags = IORESOURCE_MEM, - }, { - .start = MX25_INT_SSI1, - .end = MX25_INT_SSI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource imx_ssi_resources1[] = { - { - .start = MX25_SSI2_BASE_ADDR, - .end = MX25_SSI2_BASE_ADDR + 0x3fff, - .flags = IORESOURCE_MEM - }, { - .start = MX25_INT_SSI2, - .end = MX25_INT_SSI2, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device imx_ssi_device0 = { - .name = "imx-ssi", - .id = 0, - .num_resources = ARRAY_SIZE(imx_ssi_resources0), - .resource = imx_ssi_resources0, -}; - -struct platform_device imx_ssi_device1 = { - .name = "imx-ssi", - .id = 1, - .num_resources = ARRAY_SIZE(imx_ssi_resources1), - .resource = imx_ssi_resources1, -}; - static struct resource mx25_csi_resources[] = { { .start = MX25_CSI_BASE_ADDR, diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h index 4aceb68e35a7..7b70a43c3a4b 100644 --- a/arch/arm/mach-mx25/devices.h +++ b/arch/arm/mach-mx25/devices.h @@ -6,11 +6,8 @@ extern struct platform_device mxc_pwm_device1; extern struct platform_device mxc_pwm_device2; extern struct platform_device mxc_pwm_device3; extern struct platform_device mxc_keypad_device; -extern struct platform_device mx25_fec_device; extern struct platform_device mx25_rtc_device; extern struct platform_device mx25_fb_device; extern struct platform_device mxc_wdt; extern struct platform_device mx25_kpp_device; -extern struct platform_device imx_ssi_device0; -extern struct platform_device imx_ssi_device1; extern struct platform_device mx25_csi_device; diff --git a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c index 4aaadc753d3e..e765ac5d9a08 100644 --- a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c @@ -34,7 +34,6 @@ #include <mach/mx25.h> #include <mach/imx-uart.h> #include <mach/imxfb.h> -#include <mach/ssi.h> #include <mach/audmux.h> #include "devices-imx25.h" @@ -90,6 +89,9 @@ static struct pad_desc eukrea_mbimxsd_pads[] = { MX25_PAD_KPP_COL2__AUD5_TXC, MX25_PAD_KPP_COL1__AUD5_RXD, MX25_PAD_KPP_COL0__AUD5_TXD, + /* CAN */ + MX25_PAD_GPIO_D__CAN2_RX, + MX25_PAD_GPIO_C__CAN2_TX, }; #define GPIO_LED1 83 @@ -114,6 +116,38 @@ static struct imx_fb_videomode eukrea_mximxsd_modes[] = { }, .bpp = 16, .pcr = 0xCAD08B80, + }, { + .mode = { + .name = "DVI-VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 32000, + .hsync_len = 7, + .left_margin = 100, + .right_margin = 100, + .vsync_len = 7, + .upper_margin = 7, + .lower_margin = 100, + }, + .pcr = 0xFA208B80, + .bpp = 16, + }, { + .mode = { + .name = "DVI-SVGA", + .refresh = 60, + .xres = 800, + .yres = 600, + .pixclock = 25000, + .hsync_len = 7, + .left_margin = 75, + .right_margin = 75, + .vsync_len = 7, + .upper_margin = 7, + .lower_margin = 75, + }, + .pcr = 0xFA208B80, + .bpp = 16, }, }; @@ -205,7 +239,8 @@ static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = { }, }; -struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = { +static const +struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = { .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE, }; @@ -239,7 +274,10 @@ void __init eukrea_mbimxsd25_baseboard_init(void) imx25_add_imx_uart1(&uart_pdata); mxc_register_device(&mx25_fb_device, &eukrea_mximxsd_fb_pdata); - mxc_register_device(&imx_ssi_device0, &eukrea_mbimxsd_ssi_pdata); + imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata); + + imx25_add_flexcan1(NULL); + imx25_add_esdhc(0, NULL); gpio_request(GPIO_LED1, "LED1"); gpio_direction_output(GPIO_LED1, 1); diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c index e064bb3d6919..3b28a75007ad 100644 --- a/arch/arm/mach-mx25/mach-cpuimx25.c +++ b/arch/arm/mach-mx25/mach-cpuimx25.c @@ -23,7 +23,6 @@ #include <linux/clk.h> #include <linux/irq.h> #include <linux/gpio.h> -#include <linux/fec.h> #include <linux/platform_device.h> #include <linux/usb/otg.h> #include <linux/usb/ulpi.h> @@ -41,7 +40,6 @@ #include <mach/mxc_nand.h> #include <mach/imxfb.h> #include <mach/mxc_ehci.h> -#include <mach/ulpi.h> #include <mach/iomux-mx25.h> #include "devices-imx25.h" @@ -67,7 +65,7 @@ static struct pad_desc eukrea_cpuimx25_pads[] = { MX25_PAD_I2C1_DAT__I2C1_DAT, }; -static struct fec_platform_data mx25_fec_pdata = { +static const struct fec_platform_data mx25_fec_pdata __initconst = { .phy = PHY_INTERFACE_MODE_RMII, }; @@ -129,24 +127,19 @@ static void __init eukrea_cpuimx25_init(void) imx25_add_imx_uart0(&uart_pdata); imx25_add_mxc_nand(&eukrea_cpuimx25_nand_board_info); mxc_register_device(&mx25_rtc_device, NULL); - mxc_register_device(&mx25_fec_device, &mx25_fec_pdata); + imx25_add_fec(&mx25_fec_pdata); i2c_register_board_info(0, eukrea_cpuimx25_i2c_devices, ARRAY_SIZE(eukrea_cpuimx25_i2c_devices)); imx25_add_imx_i2c0(&eukrea_cpuimx25_i2c0_data); -#if defined(CONFIG_USB_ULPI) - if (otg_mode_host) { - otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, - ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); - + if (otg_mode_host) mxc_register_device(&mxc_otg, &otg_pdata); - } - mxc_register_device(&mxc_usbh2, &usbh2_pdata); -#endif - if (!otg_mode_host) + else mxc_register_device(&otg_udc_device, &otg_device_pdata); + mxc_register_device(&mxc_usbh2, &usbh2_pdata); + #ifdef CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD eukrea_mbimxsd25_baseboard_init(); #endif diff --git a/arch/arm/mach-mx25/mach-mx25_3ds.c b/arch/arm/mach-mx25/mach-mx25_3ds.c index 62bc21f11a71..bd1805698631 100644 --- a/arch/arm/mach-mx25/mach-mx25_3ds.c +++ b/arch/arm/mach-mx25/mach-mx25_3ds.c @@ -28,7 +28,6 @@ #include <linux/clk.h> #include <linux/irq.h> #include <linux/gpio.h> -#include <linux/fec.h> #include <linux/platform_device.h> #include <linux/input/matrix_keypad.h> @@ -99,7 +98,7 @@ static struct pad_desc mx25pdk_pads[] = { MX25_PAD_KPP_COL3__KPP_COL3, }; -static struct fec_platform_data mx25_fec_pdata = { +static const struct fec_platform_data mx25_fec_pdata __initconst = { .phy = PHY_INTERFACE_MODE_RMII, }; @@ -192,7 +191,7 @@ static void __init mx25pdk_init(void) mxc_register_device(&mxc_wdt, NULL); mx25pdk_fec_reset(); - mxc_register_device(&mx25_fec_device, &mx25_fec_pdata); + imx25_add_fec(&mx25_fec_pdata); mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data); } diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 85beece802aa..096fd33f8ab9 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -9,6 +9,7 @@ config ARCH_MX35 bool select ARCH_MXC_IOMUX_V3 select ARCH_MXC_AUDMUX_V2 + select HAVE_EPIT comment "MX3 platforms:" @@ -16,6 +17,7 @@ config MACH_MX31ADS bool "Support MX31ADS platforms" select ARCH_MX31 select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART default y help @@ -117,9 +119,11 @@ config MACH_PCM043 bool "Support Phytec pcm043 (i.MX35) platforms" select ARCH_MX35 select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_MXC_NAND select IMX_HAVE_PLATFORM_FLEXCAN + select IMX_HAVE_PLATFORM_ESDHC select MXC_ULPI if USB_ULPI help Include support for Phytec pcm043 platform. This includes @@ -140,6 +144,7 @@ config MACH_MX35_3DS bool "Support MX35PDK platform" select ARCH_MX35 select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_MXC_NAND default n help Include support for MX35PDK platform. This includes specific @@ -159,6 +164,8 @@ config MACH_EUKREA_CPUIMX35 select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_MXC_NAND + select IMX_HAVE_PLATFORM_FLEXCAN + select IMX_HAVE_PLATFORM_ESDHC select MXC_ULPI if USB_ULPI help Include support for Eukrea CPUIMX35 platform. This includes @@ -170,8 +177,8 @@ choice default MACH_EUKREA_MBIMXSD35_BASEBOARD config MACH_EUKREA_MBIMXSD35_BASEBOARD - prompt "Eukrea MBIMXSD development board" - bool + bool "Eukrea MBIMXSD development board" + select IMX_HAVE_PLATFORM_IMX_SSI help This adds board specific devices that can be found on Eukrea's MBIMXSD evaluation board. diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 2bd7beceb991..8a182d0a3fcf 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -7,7 +7,6 @@ obj-y := mm.o devices.o cpu.o CFLAGS_mm.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS CFLAGS_devices.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS -CFLAGS_cpu.o = -DIMX_NEEDS_DEPRECATED_SYMBOLS obj-$(CONFIG_ARCH_MX31) += clock-imx31.o iomux-imx31.o obj-$(CONFIG_ARCH_MX35) += clock-imx35.o obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c index 9a9eb6de6127..109e98f323e0 100644 --- a/arch/arm/mach-mx3/clock-imx31.c +++ b/arch/arm/mach-mx3/clock-imx31.c @@ -477,7 +477,7 @@ DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk); DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk); DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk); DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk); -DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk); +DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk); DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk); DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk); DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk); @@ -525,9 +525,9 @@ DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "emi", emi_clk) - _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) - _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk) - _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk) + _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk) + _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk) + _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk) _REGISTER_CLOCK(NULL, "pwm", pwm_clk) _REGISTER_CLOCK("imx-wdt.0", NULL, wdog_clk) @@ -564,7 +564,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "ata", ata_clk) _REGISTER_CLOCK(NULL, "rtic", rtic_clk) _REGISTER_CLOCK(NULL, "rng", rng_clk) - _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1) + _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk1) _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2) _REGISTER_CLOCK(NULL, "mstick", mstick1_clk) _REGISTER_CLOCK(NULL, "mstick", mstick2_clk) diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c index 7a62e744a8b0..61e4a318980a 100644 --- a/arch/arm/mach-mx3/clock-imx35.c +++ b/arch/arm/mach-mx3/clock-imx35.c @@ -364,8 +364,8 @@ DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL); DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL); DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL); DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL); -DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg_per, NULL); -DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg_per, NULL); +DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg, NULL); +DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg, NULL); DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL); DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL); DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL); @@ -451,17 +451,17 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "ata", ata_clk) _REGISTER_CLOCK("flexcan.0", NULL, can1_clk) _REGISTER_CLOCK("flexcan.1", NULL, can2_clk) - _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) - _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk) + _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk) + _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk) _REGISTER_CLOCK(NULL, "ect", ect_clk) _REGISTER_CLOCK(NULL, "edio", edio_clk) _REGISTER_CLOCK(NULL, "emi", emi_clk) - _REGISTER_CLOCK(NULL, "epit", epit1_clk) - _REGISTER_CLOCK(NULL, "epit", epit2_clk) + _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk) + _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk) _REGISTER_CLOCK(NULL, "esai", esai_clk) - _REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk) - _REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk) - _REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk) _REGISTER_CLOCK("fec.0", NULL, fec_clk) _REGISTER_CLOCK(NULL, "gpio", gpio1_clk) _REGISTER_CLOCK(NULL, "gpio", gpio2_clk) @@ -482,7 +482,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "rtc", rtc_clk) _REGISTER_CLOCK(NULL, "rtic", rtic_clk) _REGISTER_CLOCK(NULL, "scc", scc_clk) - _REGISTER_CLOCK(NULL, "sdma", sdma_clk) + _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk) _REGISTER_CLOCK(NULL, "spba", spba_clk) _REGISTER_CLOCK(NULL, "spdif", spdif_clk) _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) @@ -535,8 +535,16 @@ int __init mx35_clocks_init() __raw_writel(cgr2, CCM_BASE + CCM_CGR2); __raw_writel(cgr3, CCM_BASE + CCM_CGR3); + clk_enable(&iim_clk); + mx35_read_cpu_rev(); + +#ifdef CONFIG_MXC_USE_EPIT + epit_timer_init(&epit1_clk, + MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); +#else mxc_timer_init(&gpt_clk, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); +#endif return 0; } diff --git a/arch/arm/mach-mx3/cpu.c b/arch/arm/mach-mx3/cpu.c index 861afe0fe3ad..d00a75457812 100644 --- a/arch/arm/mach-mx3/cpu.c +++ b/arch/arm/mach-mx3/cpu.c @@ -25,15 +25,15 @@ struct mx3_cpu_type { }; static struct mx3_cpu_type mx31_cpu_type[] __initdata = { - { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = CHIP_REV_1_0 }, - { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = CHIP_REV_1_1 }, - { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = CHIP_REV_1_1 }, - { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = CHIP_REV_1_1 }, - { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = CHIP_REV_1_1 }, - { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = CHIP_REV_1_2 }, - { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = CHIP_REV_1_2 }, - { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = CHIP_REV_2_0 }, - { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = CHIP_REV_2_0 }, + { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = MX3x_CHIP_REV_1_0 }, + { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = MX3x_CHIP_REV_1_1 }, + { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = MX3x_CHIP_REV_1_1 }, + { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = MX3x_CHIP_REV_1_1 }, + { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = MX3x_CHIP_REV_1_1 }, + { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = MX3x_CHIP_REV_1_2 }, + { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = MX3x_CHIP_REV_1_2 }, + { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = MX3x_CHIP_REV_2_0 }, + { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = MX3x_CHIP_REV_2_0 }, }; void __init mx31_read_cpu_rev(void) @@ -41,7 +41,7 @@ void __init mx31_read_cpu_rev(void) u32 i, srev; /* read SREV register from IIM module */ - srev = __raw_readl(IO_ADDRESS(IIM_BASE_ADDR + MXC_IIMSREV)); + srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) if (srev == mx31_cpu_type[i].srev) { @@ -55,3 +55,30 @@ void __init mx31_read_cpu_rev(void) printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev); } + +unsigned int mx35_cpu_rev; +EXPORT_SYMBOL(mx35_cpu_rev); + +void __init mx35_read_cpu_rev(void) +{ + u32 rev; + char *srev = "unknown"; + + rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); + switch (rev) { + case 0x00: + mx35_cpu_rev = MX3x_CHIP_REV_1_0; + srev = "1.0"; + break; + case 0x10: + mx35_cpu_rev = MX3x_CHIP_REV_2_0; + srev = "2.0"; + break; + case 0x11: + mx35_cpu_rev = MX3x_CHIP_REV_2_1; + srev = "2.1"; + break; + } + + printk(KERN_INFO "CPU identified as i.MX35, silicon rev %s\n", srev); +} diff --git a/arch/arm/mach-mx3/devices-imx31.h b/arch/arm/mach-mx3/devices-imx31.h index 3b1a44a20585..de9598590eba 100644 --- a/arch/arm/mach-mx3/devices-imx31.h +++ b/arch/arm/mach-mx3/devices-imx31.h @@ -9,30 +9,33 @@ #include <mach/mx31.h> #include <mach/devices-common.h> -#define imx31_add_imx_i2c0(pdata) \ - imx_add_imx_i2c(0, MX31_I2C1_BASE_ADDR, SZ_4K, MX31_INT_I2C1, pdata) -#define imx31_add_imx_i2c1(pdata) \ - imx_add_imx_i2c(1, MX31_I2C2_BASE_ADDR, SZ_4K, MX31_INT_I2C2, pdata) -#define imx31_add_imx_i2c2(pdata) \ - imx_add_imx_i2c(2, MX31_I2C3_BASE_ADDR, SZ_4K, MX31_INT_I2C3, pdata) +extern const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst; +#define imx31_add_imx_i2c(id, pdata) \ + imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata) +#define imx31_add_imx_i2c0(pdata) imx31_add_imx_i2c(0, pdata) +#define imx31_add_imx_i2c1(pdata) imx31_add_imx_i2c(1, pdata) +#define imx31_add_imx_i2c2(pdata) imx31_add_imx_i2c(2, pdata) -#define imx31_add_imx_uart0(pdata) \ - imx_add_imx_uart_1irq(0, MX31_UART1_BASE_ADDR, SZ_16K, MX31_INT_UART1, pdata) -#define imx31_add_imx_uart1(pdata) \ - imx_add_imx_uart_1irq(1, MX31_UART2_BASE_ADDR, SZ_16K, MX31_INT_UART2, pdata) -#define imx31_add_imx_uart2(pdata) \ - imx_add_imx_uart_1irq(2, MX31_UART3_BASE_ADDR, SZ_16K, MX31_INT_UART3, pdata) -#define imx31_add_imx_uart3(pdata) \ - imx_add_imx_uart_1irq(3, MX31_UART4_BASE_ADDR, SZ_16K, MX31_INT_UART4, pdata) -#define imx31_add_imx_uart4(pdata) \ - imx_add_imx_uart_1irq(4, MX31_UART5_BASE_ADDR, SZ_16K, MX31_INT_UART5, pdata) +extern const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst; +#define imx31_add_imx_ssi(id, pdata) \ + imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata) +extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst; +#define imx31_add_imx_uart(id, pdata) \ + imx_add_imx_uart_1irq(&imx31_imx_uart_data[id], pdata) +#define imx31_add_imx_uart0(pdata) imx31_add_imx_uart(0, pdata) +#define imx31_add_imx_uart1(pdata) imx31_add_imx_uart(1, pdata) +#define imx31_add_imx_uart2(pdata) imx31_add_imx_uart(2, pdata) +#define imx31_add_imx_uart3(pdata) imx31_add_imx_uart(3, pdata) +#define imx31_add_imx_uart4(pdata) imx31_add_imx_uart(4, pdata) + +extern const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst; #define imx31_add_mxc_nand(pdata) \ - imx_add_mxc_nand_v1(MX31_NFC_BASE_ADDR, MX31_INT_NANDFC, pdata) + imx_add_mxc_nand(&imx31_mxc_nand_data, pdata) -#define imx31_add_spi_imx0(pdata) \ - imx_add_spi_imx(0, MX31_CSPI1_BASE_ADDR, SZ_4K, MX31_INT_CSPI1, pdata) -#define imx31_add_spi_imx1(pdata) \ - imx_add_spi_imx(1, MX31_CSPI2_BASE_ADDR, SZ_4K, MX31_INT_CSPI2, pdata) -#define imx31_add_spi_imx2(pdata) \ - imx_add_spi_imx(2, MX31_CSPI3_BASE_ADDR, SZ_4K, MX31_INT_CSPI3, pdata) +extern const struct imx_spi_imx_data imx31_cspi_data[] __initconst; +#define imx31_add_cspi(id, pdata) \ + imx_add_spi_imx(&imx31_cspi_data[id], pdata) +#define imx31_add_spi_imx0(pdata) imx31_add_cspi(0, pdata) +#define imx31_add_spi_imx1(pdata) imx31_add_cspi(1, pdata) +#define imx31_add_spi_imx2(pdata) imx31_add_cspi(2, pdata) diff --git a/arch/arm/mach-mx3/devices-imx35.h b/arch/arm/mach-mx3/devices-imx35.h index f6a431a4c3d2..5eb917b638d0 100644 --- a/arch/arm/mach-mx3/devices-imx35.h +++ b/arch/arm/mach-mx3/devices-imx35.h @@ -9,29 +9,43 @@ #include <mach/mx35.h> #include <mach/devices-common.h> +extern const struct imx_fec_data imx35_fec_data __initconst; +#define imx35_add_fec(pdata) \ + imx_add_fec(&imx35_fec_data, pdata) + #define imx35_add_flexcan0(pdata) \ imx_add_flexcan(0, MX35_CAN1_BASE_ADDR, SZ_16K, MX35_INT_CAN1, pdata) #define imx35_add_flexcan1(pdata) \ imx_add_flexcan(1, MX35_CAN2_BASE_ADDR, SZ_16K, MX35_INT_CAN2, pdata) -#define imx35_add_imx_i2c0(pdata) \ - imx_add_imx_i2c(0, MX35_I2C1_BASE_ADDR, SZ_4K, MX35_INT_I2C1, pdata) -#define imx35_add_imx_i2c1(pdata) \ - imx_add_imx_i2c(1, MX35_I2C2_BASE_ADDR, SZ_4K, MX35_INT_I2C2, pdata) -#define imx35_add_imx_i2c2(pdata) \ - imx_add_imx_i2c(2, MX35_I2C3_BASE_ADDR, SZ_4K, MX35_INT_I2C3, pdata) +extern const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst; +#define imx35_add_imx_i2c(id, pdata) \ + imx_add_imx_i2c(&imx35_imx_i2c_data[id], pdata) +#define imx35_add_imx_i2c0(pdata) imx35_add_imx_i2c(0, pdata) +#define imx35_add_imx_i2c1(pdata) imx35_add_imx_i2c(1, pdata) +#define imx35_add_imx_i2c2(pdata) imx35_add_imx_i2c(2, pdata) + +extern const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst; +#define imx35_add_imx_ssi(id, pdata) \ + imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata) -#define imx35_add_imx_uart0(pdata) \ - imx_add_imx_uart_1irq(0, MX35_UART1_BASE_ADDR, SZ_16K, MX35_INT_UART1, pdata) -#define imx35_add_imx_uart1(pdata) \ - imx_add_imx_uart_1irq(1, MX35_UART2_BASE_ADDR, SZ_16K, MX35_INT_UART2, pdata) -#define imx35_add_imx_uart2(pdata) \ - imx_add_imx_uart_1irq(2, MX35_UART3_BASE_ADDR, SZ_16K, MX35_INT_UART3, pdata) +extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst; +#define imx35_add_imx_uart(id, pdata) \ + imx_add_imx_uart_1irq(&imx35_imx_uart_data[id], pdata) +#define imx35_add_imx_uart0(pdata) imx35_add_imx_uart(0, pdata) +#define imx35_add_imx_uart1(pdata) imx35_add_imx_uart(1, pdata) +#define imx35_add_imx_uart2(pdata) imx35_add_imx_uart(2, pdata) +extern const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst; #define imx35_add_mxc_nand(pdata) \ - imx_add_mxc_nand_v21(MX35_NFC_BASE_ADDR, MX35_INT_NANDFC, pdata) + imx_add_mxc_nand(&imx35_mxc_nand_data, pdata) + +extern const struct imx_spi_imx_data imx35_cspi_data[] __initconst; +#define imx35_add_cspi(id, pdata) \ + imx_add_spi_imx(&imx35_cspi_data[id], pdata) +#define imx35_add_spi_imx0(pdata) imx35_add_cspi(0, pdata) +#define imx35_add_spi_imx1(pdata) imx35_add_cspi(1, pdata) -#define imx35_add_spi_imx0(pdata) \ - imx_add_spi_imx(0, MX35_CSPI1_BASE_ADDR, SZ_4K, MX35_INT_CSPI1, pdata) -#define imx35_add_spi_imx1(pdata) \ - imx_add_spi_imx(1, MX35_CSPI2_BASE_ADDR, SZ_4K, MX35_INT_CSPI2, pdata) +extern const struct imx_esdhc_imx_data imx35_esdhc_data[] __initconst; +#define imx35_add_esdhc(id, pdata) \ + imx_add_esdhc(&imx35_esdhc_data[id], pdata) diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index a4fd1a26fc91..f4dff11aaee7 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -281,65 +281,6 @@ struct platform_device mxc_usbh2 = { .num_resources = ARRAY_SIZE(mxc_usbh2_resources), }; -#if defined(CONFIG_ARCH_MX35) -static struct resource mxc_fec_resources[] = { - { - .start = MXC_FEC_BASE_ADDR, - .end = MXC_FEC_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, { - .start = MXC_INT_FEC, - .end = MXC_INT_FEC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_fec_device = { - .name = "fec", - .id = 0, - .num_resources = ARRAY_SIZE(mxc_fec_resources), - .resource = mxc_fec_resources, -}; -#endif - -static struct resource imx_ssi_resources0[] = { - { - .start = SSI1_BASE_ADDR, - .end = SSI1_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, { - .start = MX31_INT_SSI1, - .end = MX31_INT_SSI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource imx_ssi_resources1[] = { - { - .start = SSI2_BASE_ADDR, - .end = SSI2_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM - }, { - .start = MX31_INT_SSI2, - .end = MX31_INT_SSI2, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device imx_ssi_device0 = { - .name = "imx-ssi", - .id = 0, - .num_resources = ARRAY_SIZE(imx_ssi_resources0), - .resource = imx_ssi_resources0, -}; - -struct platform_device imx_ssi_device1 = { - .name = "imx-ssi", - .id = 1, - .num_resources = ARRAY_SIZE(imx_ssi_resources1), - .resource = imx_ssi_resources1, -}; - static struct resource imx_wdt_resources[] = { { .flags = IORESOURCE_MEM, @@ -410,10 +351,6 @@ static int __init mx3_devices_init(void) mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff; mxc_usbh1_resources[1].start = MXC_INT_USBHS; mxc_usbh1_resources[1].end = MXC_INT_USBHS; - imx_ssi_resources0[1].start = MX35_INT_SSI1; - imx_ssi_resources0[1].end = MX35_INT_SSI1; - imx_ssi_resources1[1].start = MX35_INT_SSI2; - imx_ssi_resources1[1].end = MX35_INT_SSI2; imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR; imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff; } diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index e5535234839f..585f814473d5 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h @@ -2,7 +2,6 @@ extern struct platform_device mxc_w1_master_device; extern struct platform_device mx3_ipu; extern struct platform_device mx3_fb; extern struct platform_device mx3_camera; -extern struct platform_device mxc_fec_device; extern struct platform_device mxcsdhc_device0; extern struct platform_device mxcsdhc_device1; extern struct platform_device mxc_otg_udc_device; @@ -10,9 +9,6 @@ extern struct platform_device mxc_otg_host; extern struct platform_device mxc_usbh1; extern struct platform_device mxc_usbh2; extern struct platform_device mxc_rnga_device; -extern struct platform_device imx_ssi_device0; -extern struct platform_device imx_ssi_device1; -extern struct platform_device imx_ssi_device1; extern struct platform_device imx_wdt_device0; extern struct platform_device imx_rtc_device0; extern struct platform_device imx_kpp_device; diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c index f8f15e3ac7a0..1abc10d52922 100644 --- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c @@ -43,14 +43,13 @@ #include <mach/ipu.h> #include <mach/mx3fb.h> #include <mach/audmux.h> -#include <mach/ssi.h> #include "devices-imx35.h" #include "devices.h" static const struct fb_videomode fb_modedb[] = { { - .name = "CMO_QVGA", + .name = "CMO-QVGA", .refresh = 60, .xres = 320, .yres = 240, @@ -65,6 +64,40 @@ static const struct fb_videomode fb_modedb[] = { .vmode = FB_VMODE_NONINTERLACED, .flag = 0, }, + { + .name = "DVI-VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 32000, + .left_margin = 100, + .right_margin = 100, + .upper_margin = 7, + .lower_margin = 100, + .hsync_len = 7, + .vsync_len = 7, + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, + { + .name = "DVI-SVGA", + .refresh = 60, + .xres = 800, + .yres = 600, + .pixclock = 25000, + .left_margin = 75, + .right_margin = 75, + .upper_margin = 7, + .lower_margin = 75, + .hsync_len = 7, + .vsync_len = 7, + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT | + FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, }; static struct ipu_platform_data mx3_ipu_data = { @@ -73,7 +106,7 @@ static struct ipu_platform_data mx3_ipu_data = { static struct mx3fb_platform_data mx3fb_pdata = { .dma_dev = &mx3_ipu.dev, - .name = "CMO_QVGA", + .name = "CMO-QVGA", .mode = fb_modedb, .num_modes = ARRAY_SIZE(fb_modedb), }; @@ -120,6 +153,16 @@ static struct pad_desc eukrea_mbimxsd_pads[] = { MX35_PAD_STXD4__AUDMUX_AUD4_TXD, MX35_PAD_SRXD4__AUDMUX_AUD4_RXD, MX35_PAD_SCK4__AUDMUX_AUD4_TXC, + /* CAN2 */ + MX35_PAD_TX5_RX0__CAN2_TXCAN, + MX35_PAD_TX4_RX1__CAN2_RXCAN, + /* SDCARD */ + MX35_PAD_SD1_CMD__ESDHC1_CMD, + MX35_PAD_SD1_CLK__ESDHC1_CLK, + MX35_PAD_SD1_DATA0__ESDHC1_DAT0, + MX35_PAD_SD1_DATA1__ESDHC1_DAT1, + MX35_PAD_SD1_DATA2__ESDHC1_DAT2, + MX35_PAD_SD1_DATA3__ESDHC1_DAT3, }; #define GPIO_LED1 (2 * 32 + 29) @@ -206,7 +249,8 @@ static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = { }, }; -struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = { +static const +struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = { .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE, }; @@ -242,7 +286,10 @@ void __init eukrea_mbimxsd35_baseboard_init(void) mxc_register_device(&mx3_ipu, &mx3_ipu_data); mxc_register_device(&mx3_fb, &mx3fb_pdata); - mxc_register_device(&imx_ssi_device0, &eukrea_mbimxsd_ssi_pdata); + imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata); + + imx35_add_flexcan1(NULL); + imx35_add_esdhc(0, NULL); gpio_request(GPIO_LED1, "LED1"); gpio_direction_output(GPIO_LED1, 1); @@ -254,7 +301,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void) gpio_request(GPIO_LCDPWR, "LCDPWR"); gpio_direction_output(GPIO_LCDPWR, 1); - gpio_free(GPIO_SWITCH1); + gpio_free(GPIO_LCDPWR); i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices, ARRAY_SIZE(eukrea_mbimxsd_i2c_devices)); diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c index 2a4f8b781ba4..bf2d6e2ec0d6 100644 --- a/arch/arm/mach-mx3/mach-cpuimx35.c +++ b/arch/arm/mach-mx3/mach-cpuimx35.c @@ -31,6 +31,7 @@ #include <linux/usb/otg.h> #include <linux/usb/ulpi.h> #include <linux/fsl_devices.h> +#include <linux/i2c-gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -43,7 +44,6 @@ #include <mach/iomux-mx35.h> #include <mach/mxc_nand.h> #include <mach/mxc_ehci.h> -#include <mach/ulpi.h> #include "devices-imx35.h" #include "devices.h" @@ -53,39 +53,16 @@ static const struct imxuart_platform_data uart_pdata __initconst = { }; static const struct imxi2c_platform_data -eukrea_cpuimx35_i2c0_data __initconst = { - .bitrate = 50000, + eukrea_cpuimx35_i2c0_data __initconst = { + .bitrate = 100000, }; -#define TSC2007_IRQGPIO (2 * 32 + 2) -static int ts_get_pendown_state(void) -{ - int val = 0; - gpio_free(TSC2007_IRQGPIO); - gpio_request(TSC2007_IRQGPIO, NULL); - gpio_direction_input(TSC2007_IRQGPIO); - - val = gpio_get_value(TSC2007_IRQGPIO); - - gpio_free(TSC2007_IRQGPIO); - gpio_request(TSC2007_IRQGPIO, NULL); - - return val ? 0 : 1; -} - -static int ts_init(void) -{ - gpio_request(TSC2007_IRQGPIO, NULL); - return 0; -} - static struct tsc2007_platform_data tsc2007_info = { .model = 2007, .x_plate_ohms = 180, - .get_pendown_state = ts_get_pendown_state, - .init_platform_hw = ts_init, }; +#define TSC2007_IRQGPIO (2 * 32 + 2) static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { { I2C_BOARD_INFO("pcf8563", 0x51), @@ -98,7 +75,6 @@ static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = { }; static struct platform_device *devices[] __initdata = { - &mxc_fec_device, &imx_wdt_device0, }; @@ -135,18 +111,18 @@ static struct pad_desc eukrea_cpuimx35_pads[] = { }; static const struct mxc_nand_platform_data -eukrea_cpuimx35_nand_board_info __initconst = { + eukrea_cpuimx35_nand_board_info __initconst = { .width = 1, .hw_ecc = 1, .flash_bbt = 1, }; -static struct mxc_usbh_platform_data otg_pdata = { +static struct mxc_usbh_platform_data __maybe_unused otg_pdata = { .portsc = MXC_EHCI_MODE_UTMI, .flags = MXC_EHCI_INTERFACE_DIFF_UNI, }; -static struct mxc_usbh_platform_data usbh1_pdata = { +static struct mxc_usbh_platform_data __maybe_unused usbh1_pdata = { .portsc = MXC_EHCI_MODE_SERIAL, .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN, @@ -180,6 +156,7 @@ static void __init mxc_board_init(void) mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads, ARRAY_SIZE(eukrea_cpuimx35_pads)); + imx35_add_fec(NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); imx35_add_imx_uart0(&uart_pdata); @@ -189,18 +166,13 @@ static void __init mxc_board_init(void) ARRAY_SIZE(eukrea_cpuimx35_i2c_devices)); imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data); -#if defined(CONFIG_USB_ULPI) - if (otg_mode_host) { - otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops, - ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT); - + if (otg_mode_host) mxc_register_device(&mxc_otg_host, &otg_pdata); - } - mxc_register_device(&mxc_usbh1, &usbh1_pdata); -#endif - if (!otg_mode_host) + else mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata); + mxc_register_device(&mxc_usbh1, &usbh1_pdata); + #ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD eukrea_mbimxsd35_baseboard_init(); #endif diff --git a/arch/arm/mach-mx3/mach-mx31ads.c b/arch/arm/mach-mx3/mach-mx31ads.c index 94b3e7c42404..5f670ba7f0c2 100644 --- a/arch/arm/mach-mx3/mach-mx31ads.c +++ b/arch/arm/mach-mx3/mach-mx31ads.c @@ -22,13 +22,13 @@ #include <linux/i2c.h> #include <linux/irq.h> -#include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> #include <asm/memory.h> #include <asm/mach/map.h> #include <mach/common.h> +#include <mach/board-mx31ads.h> #include <mach/iomux-mx3.h> #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 @@ -40,10 +40,6 @@ #include "devices-imx31.h" #include "devices.h" -/* Base address of PBC controller */ -#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT -/* Offsets for the PBC Controller register */ - /* PBC Board interrupt status register */ #define PBC_INTSTATUS 0x000016 @@ -67,7 +63,6 @@ #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) #define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4) -#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) #define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) #define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) @@ -517,7 +512,7 @@ static unsigned int ssi_pins[] = { static void mxc_init_audio(void) { - mxc_register_device(&imx_ssi_device0, NULL); + imx31_add_imx_ssi(0, NULL); mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi"); } diff --git a/arch/arm/mach-mx3/mach-mx35_3ds.c b/arch/arm/mach-mx3/mach-mx35_3ds.c index 1c30d7212f17..91bb06552af1 100644 --- a/arch/arm/mach-mx3/mach-mx35_3ds.c +++ b/arch/arm/mach-mx3/mach-mx35_3ds.c @@ -1,5 +1,6 @@ /* * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix * * Author: Fabio Estevam <fabio.estevam@freescale.com> * @@ -27,6 +28,8 @@ #include <linux/gpio.h> #include <linux/fsl_devices.h> +#include <linux/mtd/physmap.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> @@ -35,6 +38,7 @@ #include <mach/hardware.h> #include <mach/common.h> #include <mach/iomux-mx35.h> +#include <mach/mxc_ehci.h> #include "devices-imx35.h" #include "devices.h" @@ -43,8 +47,34 @@ static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; +static struct physmap_flash_data mx35pdk_flash_data = { + .width = 2, +}; + +static struct resource mx35pdk_flash_resource = { + .start = MX35_CS0_BASE_ADDR, + .end = MX35_CS0_BASE_ADDR + SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device mx35pdk_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &mx35pdk_flash_data, + }, + .resource = &mx35pdk_flash_resource, + .num_resources = 1, +}; + +static const struct mxc_nand_platform_data mx35pdk_nand_board_info __initconst = { + .width = 1, + .hw_ecc = 1, + .flash_bbt = 1, +}; + static struct platform_device *devices[] __initdata = { - &mxc_fec_device, + &mx35pdk_flash, }; static struct pad_desc mx35pdk_pads[] = { @@ -75,14 +105,24 @@ static struct pad_desc mx35pdk_pads[] = { /* USBOTG */ MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR, MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC, + /* USBH1 */ + MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR, + MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC, }; /* OTG config */ -static struct fsl_usb2_platform_data usb_pdata = { +static struct fsl_usb2_platform_data usb_otg_pdata = { .operating_mode = FSL_USB2_DR_DEVICE, .phy_mode = FSL_USB2_PHY_UTMI_WIDE, }; +/* USB HOST config */ +static struct mxc_usbh_platform_data usb_host_pdata = { + .portsc = MXC_EHCI_MODE_SERIAL, + .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | + MXC_EHCI_INTERNAL_PHY, +}; + /* * Board specific initialization. */ @@ -90,11 +130,16 @@ static void __init mxc_board_init(void) { mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads)); + imx35_add_fec(NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); imx35_add_imx_uart0(&uart_pdata); - mxc_register_device(&mxc_otg_udc_device, &usb_pdata); + mxc_register_device(&mxc_otg_udc_device, &usb_otg_pdata); + + mxc_register_device(&mxc_usbh1, &usb_host_pdata); + + imx35_add_mxc_nand(&mx35pdk_nand_board_info); } static void __init mx35pdk_timer_init(void) diff --git a/arch/arm/mach-mx3/mach-pcm037_eet.c b/arch/arm/mach-mx3/mach-pcm037_eet.c index c8b98218efee..99e0894e07db 100644 --- a/arch/arm/mach-mx3/mach-pcm037_eet.c +++ b/arch/arm/mach-mx3/mach-pcm037_eet.c @@ -19,6 +19,7 @@ #include "pcm037.h" #include "devices.h" +#include "devices-imx31.h" static unsigned int pcm037_eet_pins[] = { /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */ @@ -181,7 +182,7 @@ static int eet_init_devices(void) /* SPI */ spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev)); #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) - imx35_add_spi_imx0(&pcm037_spi1_pdata); + imx31_add_spi_imx0(&pcm037_spi1_pdata); #endif platform_device_register(&pcm037_gpio_keys_device); diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c index 28886f0e62f9..a9397a4151e3 100644 --- a/arch/arm/mach-mx3/mach-pcm043.c +++ b/arch/arm/mach-mx3/mach-pcm043.c @@ -42,7 +42,6 @@ #include <mach/mxc_ehci.h> #include <mach/ulpi.h> #include <mach/audmux.h> -#include <mach/ssi.h> #include "devices-imx35.h" #include "devices.h" @@ -141,7 +140,6 @@ static struct i2c_board_info pcm043_i2c_devices[] = { static struct platform_device *devices[] __initdata = { &pcm043_flash, - &mxc_fec_device, &imx_wdt_device0, }; @@ -217,6 +215,13 @@ static struct pad_desc pcm043_pads[] = { /* CAN2 */ MX35_PAD_TX5_RX0__CAN2_TXCAN, MX35_PAD_TX4_RX1__CAN2_RXCAN, + /* esdhc */ + MX35_PAD_SD1_CMD__ESDHC1_CMD, + MX35_PAD_SD1_CLK__ESDHC1_CLK, + MX35_PAD_SD1_DATA0__ESDHC1_DAT0, + MX35_PAD_SD1_DATA1__ESDHC1_DAT1, + MX35_PAD_SD1_DATA2__ESDHC1_DAT2, + MX35_PAD_SD1_DATA3__ESDHC1_DAT3, }; #define AC97_GPIO_TXFS (1 * 32 + 31) @@ -293,7 +298,7 @@ err1: mdelay(1); } -static struct imx_ssi_platform_data pcm043_ssi_pdata = { +static const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = { .ac97_reset = pcm043_ac97_cold_reset, .ac97_warm_reset = pcm043_ac97_warm_reset, .flags = IMX_SSI_USE_AC97, @@ -357,11 +362,12 @@ static void __init mxc_board_init(void) MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */ MXC_AUDMUX_V2_PDCR_RXDSEL(3)); + imx35_add_fec(NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); imx35_add_imx_uart0(&uart_pdata); imx35_add_mxc_nand(&pcm037_nand_board_info); - mxc_register_device(&imx_ssi_device0, &pcm043_ssi_pdata); + imx35_add_imx_ssi(0, &pcm043_ssi_pdata); imx35_add_imx_uart1(&uart_pdata); @@ -389,6 +395,7 @@ static void __init mxc_board_init(void) mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata); imx35_add_flexcan1(NULL); + imx35_add_esdhc(0, NULL); } static void __init pcm043_timer_init(void) diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c index 20e48c0195c4..b4ffc531a82c 100644 --- a/arch/arm/mach-mx3/mm.c +++ b/arch/arm/mach-mx3/mm.c @@ -110,6 +110,24 @@ void __init mx35_init_irq(void) static int mxc_init_l2x0(void) { void __iomem *l2x0_base; + void __iomem *clkctl_base; +/* + * First of all, we must repair broken chip settings. There are some + * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These + * misconfigured CPUs will run amok immediately when the L2 cache gets enabled. + * Workaraound is to setup the correct register setting prior enabling the + * L2 cache. This should not hurt already working CPUs, as they are using the + * same value + */ +#define L2_MEM_VAL 0x10 + + clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096); + if (clkctl_base != NULL) { + writel(0x00000515, clkctl_base + L2_MEM_VAL); + iounmap(clkctl_base); + } else { + pr_err("L2 cache: Cannot fix timing. Trying to continue without\n"); + } l2x0_base = ioremap(L2CC_BASE_ADDR, 4096); if (IS_ERR(l2x0_base)) { diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index 0848db5dd364..a2df9ac37996 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -5,11 +5,14 @@ config ARCH_MX51 default y select MXC_TZIC select ARCH_MXC_IOMUX_V3 + select ARCH_MXC_AUDMUX_V2 comment "MX5 platforms:" config MACH_MX51_BABBAGE bool "Support MX51 BABBAGE platforms" + select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_UART help Include support for MX51 Babbage platform, also known as MX51EVK in u-boot. This includes specific configurations for the board and its @@ -17,6 +20,8 @@ config MACH_MX51_BABBAGE config MACH_MX51_3DS bool "Support MX51PDK (3DS)" + select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_SPI_IMX select MXC_DEBUG_BOARD help Include support for MX51PDK (3DS) platform. This includes specific @@ -24,6 +29,10 @@ config MACH_MX51_3DS config MACH_EUKREA_CPUIMX51 bool "Support Eukrea CPUIMX51 module" + select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_MXC_NAND + select IMX_HAVE_PLATFORM_SPI_IMX help Include support for Eukrea CPUIMX51 platform. This includes specific configurations for the module and its peripherals. @@ -36,10 +45,43 @@ choice config MACH_EUKREA_MBIMX51_BASEBOARD prompt "Eukrea MBIMX51 development board" bool + select IMX_HAVE_PLATFORM_ESDHC help This adds board specific devices that can be found on Eukrea's MBIMX51 evaluation board. endchoice +config MACH_EUKREA_CPUIMX51SD + bool "Support Eukrea CPUIMX51SD module" + select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_SPI_IMX + select IMX_HAVE_PLATFORM_IMX_UART + select IMX_HAVE_PLATFORM_MXC_NAND + help + Include support for Eukrea CPUIMX51SD platform. This includes + specific configurations for the module and its peripherals. + +choice + prompt "Baseboard" + depends on MACH_EUKREA_CPUIMX51SD + default MACH_EUKREA_MBIMXSD51_BASEBOARD + +config MACH_EUKREA_MBIMXSD51_BASEBOARD + prompt "Eukrea MBIMXSD development board" + bool + select IMX_HAVE_PLATFORM_ESDHC + help + This adds board specific devices that can be found on Eukrea's + MBIMXSD evaluation board. + +endchoice + +config MACH_MX51_EFIKAMX + bool "Support MX51 Genesi Efika MX nettop" + select IMX_HAVE_PLATFORM_IMX_UART + help + Include support for Genesi Efika MX nettop. This includes specific + configurations for the board and its peripherals. + endif diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index 86c66e7f52f3..1769c161a60d 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -9,3 +9,6 @@ obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o +obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += board-cpuimx51sd.o +obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd-baseboard.o +obj-$(CONFIG_MACH_MX51_EFIKAMX) += board-mx51_efikamx.o diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c index 623607a20f57..378f5327ae77 100644 --- a/arch/arm/mach-mx5/board-cpuimx51.c +++ b/arch/arm/mach-mx5/board-cpuimx51.c @@ -28,9 +28,7 @@ #include <mach/eukrea-baseboards.h> #include <mach/common.h> #include <mach/hardware.h> -#include <mach/imx-uart.h> #include <mach/iomux-mx51.h> -#include <mach/i2c.h> #include <mach/mxc_ehci.h> #include <asm/irq.h> @@ -39,6 +37,7 @@ #include <asm/mach/arch.h> #include <asm/mach/time.h> +#include "devices-imx51.h" #include "devices.h" #define CPUIMX51_USBH1_STP (0*32 + 27) @@ -109,7 +108,6 @@ static struct platform_device serial_device = { #endif static struct platform_device *devices[] __initdata = { - &mxc_fec_device, #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) &serial_device, #endif @@ -148,11 +146,19 @@ static struct pad_desc eukrea_cpuimx51_pads[] = { MX51_PAD_USBH1_STP__USBH1_STP, }; -static struct imxuart_platform_data uart_pdata = { +static const struct mxc_nand_platform_data + eukrea_cpuimx51_nand_board_info __initconst = { + .width = 1, + .hw_ecc = 1, + .flash_bbt = 1, +}; + +static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; -static struct imxi2c_platform_data eukrea_cpuimx51_i2c_data = { +static const +struct imxi2c_platform_data eukrea_cpuimx51_i2c_data __initconst = { .bitrate = 100000, }; @@ -239,7 +245,9 @@ static void __init eukrea_cpuimx51_init(void) mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads, ARRAY_SIZE(eukrea_cpuimx51_pads)); - mxc_register_device(&mxc_uart_device0, &uart_pdata); + imx51_add_imx_uart(0, &uart_pdata); + imx51_add_mxc_nand(&eukrea_cpuimx51_nand_board_info); + gpio_request(CPUIMX51_QUARTA_GPIO, "quarta_irq"); gpio_direction_input(CPUIMX51_QUARTA_GPIO); gpio_free(CPUIMX51_QUARTA_GPIO); @@ -253,9 +261,10 @@ static void __init eukrea_cpuimx51_init(void) gpio_direction_input(CPUIMX51_QUARTD_GPIO); gpio_free(CPUIMX51_QUARTD_GPIO); + imx51_add_fec(NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); - mxc_register_device(&mxc_i2c_device1, &eukrea_cpuimx51_i2c_data); + imx51_add_imx_i2c(1, &eukrea_cpuimx51_i2c_data); i2c_register_board_info(1, eukrea_cpuimx51_i2c_devices, ARRAY_SIZE(eukrea_cpuimx51_i2c_devices)); diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c new file mode 100644 index 000000000000..bd5eb61a7eba --- /dev/null +++ b/arch/arm/mach-mx5/board-cpuimx51sd.c @@ -0,0 +1,333 @@ +/* + * + * Copyright (C) 2010 Eric Bénard <eric@eukrea.com> + * + * based on board-mx51_babbage.c which is + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com> + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/i2c/tsc2007.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/fsl_devices.h> +#include <linux/i2c-gpio.h> +#include <linux/spi/spi.h> +#include <linux/can/platform/mcp251x.h> + +#include <mach/eukrea-baseboards.h> +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/iomux-mx51.h> +#include <mach/mxc_ehci.h> + +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include "devices-imx51.h" +#include "devices.h" + +#define USBH1_RST (1*32 + 28) +#define ETH_RST (1*32 + 31) +#define TSC2007_IRQGPIO (2*32 + 12) +#define CAN_IRQGPIO (0*32 + 1) +#define CAN_RST (3*32 + 15) +#define CAN_NCS (3*32 + 24) +#define CAN_RXOBF (0*32 + 4) +#define CAN_RX1BF (0*32 + 6) +#define CAN_TXORTS (0*32 + 7) +#define CAN_TX1RTS (0*32 + 8) +#define CAN_TX2RTS (0*32 + 9) +#define I2C_SCL (3*32 + 16) +#define I2C_SDA (3*32 + 17) + +/* USB_CTRL_1 */ +#define MX51_USB_CTRL_1_OFFSET 0x10 +#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25) + +#define MX51_USB_PLLDIV_12_MHZ 0x00 +#define MX51_USB_PLL_DIV_19_2_MHZ 0x01 +#define MX51_USB_PLL_DIV_24_MHZ 0x02 + +#define CPUIMX51SD_GPIO_3_12 IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, \ + MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP) + +static struct pad_desc eukrea_cpuimx51sd_pads[] = { + /* UART1 */ + MX51_PAD_UART1_RXD__UART1_RXD, + MX51_PAD_UART1_TXD__UART1_TXD, + MX51_PAD_UART1_RTS__UART1_RTS, + MX51_PAD_UART1_CTS__UART1_CTS, + + /* USB HOST1 */ + MX51_PAD_USBH1_CLK__USBH1_CLK, + MX51_PAD_USBH1_DIR__USBH1_DIR, + MX51_PAD_USBH1_NXT__USBH1_NXT, + MX51_PAD_USBH1_DATA0__USBH1_DATA0, + MX51_PAD_USBH1_DATA1__USBH1_DATA1, + MX51_PAD_USBH1_DATA2__USBH1_DATA2, + MX51_PAD_USBH1_DATA3__USBH1_DATA3, + MX51_PAD_USBH1_DATA4__USBH1_DATA4, + MX51_PAD_USBH1_DATA5__USBH1_DATA5, + MX51_PAD_USBH1_DATA6__USBH1_DATA6, + MX51_PAD_USBH1_DATA7__USBH1_DATA7, + MX51_PAD_USBH1_STP__USBH1_STP, + MX51_PAD_EIM_CS3__GPIO_2_28, /* PHY nRESET */ + + /* FEC */ + MX51_PAD_EIM_DTACK__GPIO_2_31, /* PHY nRESET */ + + /* HSI2C */ + MX51_PAD_I2C1_CLK__GPIO_4_16, + MX51_PAD_I2C1_DAT__GPIO_4_17, + + /* CAN */ + MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI, + MX51_PAD_CSPI1_MISO__ECSPI1_MISO, + MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK, + MX51_PAD_CSPI1_SS0__GPIO_4_24, /* nCS */ + MX51_PAD_CSI2_PIXCLK__GPIO_4_15, /* nReset */ + MX51_PAD_GPIO_1_1__GPIO_1_1, /* IRQ */ + MX51_PAD_GPIO_1_4__GPIO_1_4, /* Control signals */ + MX51_PAD_GPIO_1_6__GPIO_1_6, + MX51_PAD_GPIO_1_7__GPIO_1_7, + MX51_PAD_GPIO_1_8__GPIO_1_8, + MX51_PAD_GPIO_1_9__GPIO_1_9, + + /* Touchscreen */ + CPUIMX51SD_GPIO_3_12, /* IRQ */ +}; + +static const struct imxuart_platform_data uart_pdata __initconst = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static int ts_get_pendown_state(void) +{ + return gpio_get_value(TSC2007_IRQGPIO) ? 0 : 1; +} + +static struct tsc2007_platform_data tsc2007_info = { + .model = 2007, + .x_plate_ohms = 180, + .get_pendown_state = ts_get_pendown_state, +}; + +static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = { + { + I2C_BOARD_INFO("pcf8563", 0x51), + }, { + I2C_BOARD_INFO("tsc2007", 0x49), + .type = "tsc2007", + .platform_data = &tsc2007_info, + .irq = gpio_to_irq(TSC2007_IRQGPIO), + }, +}; + +static const struct mxc_nand_platform_data + eukrea_cpuimx51sd_nand_board_info __initconst = { + .width = 1, + .hw_ecc = 1, + .flash_bbt = 1, +}; + +/* This function is board specific as the bit mask for the plldiv will also +be different for other Freescale SoCs, thus a common bitmask is not +possible and cannot get place in /plat-mxc/ehci.c.*/ +static int initialize_otg_port(struct platform_device *pdev) +{ + u32 v; + void __iomem *usb_base; + void __iomem *usbother_base; + + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; + + /* Set the PHY clock to 19.2MHz */ + v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET); + v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK; + v |= MX51_USB_PLL_DIV_19_2_MHZ; + __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET); + iounmap(usb_base); + return 0; +} + +static int initialize_usbh1_port(struct platform_device *pdev) +{ + u32 v; + void __iomem *usb_base; + void __iomem *usbother_base; + + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; + + /* The clock for the USBH1 ULPI port will come from the PHY. */ + v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET); + __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN, + usbother_base + MX51_USB_CTRL_1_OFFSET); + iounmap(usb_base); + return 0; +} + +static struct mxc_usbh_platform_data dr_utmi_config = { + .init = initialize_otg_port, + .portsc = MXC_EHCI_UTMI_16BIT, + .flags = MXC_EHCI_INTERNAL_PHY, +}; + +static struct fsl_usb2_platform_data usb_pdata = { + .operating_mode = FSL_USB2_DR_DEVICE, + .phy_mode = FSL_USB2_PHY_UTMI_WIDE, +}; + +static struct mxc_usbh_platform_data usbh1_config = { + .init = initialize_usbh1_port, + .portsc = MXC_EHCI_MODE_ULPI, + .flags = (MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_ITC_NO_THRESHOLD), +}; + +static int otg_mode_host; + +static int __init eukrea_cpuimx51sd_otg_mode(char *options) +{ + if (!strcmp(options, "host")) + otg_mode_host = 1; + else if (!strcmp(options, "device")) + otg_mode_host = 0; + else + pr_info("otg_mode neither \"host\" nor \"device\". " + "Defaulting to device\n"); + return 0; +} +__setup("otg_mode=", eukrea_cpuimx51sd_otg_mode); + +static struct i2c_gpio_platform_data pdata = { + .sda_pin = I2C_SDA, + .sda_is_open_drain = 0, + .scl_pin = I2C_SCL, + .scl_is_open_drain = 0, + .udelay = 2, +}; + +static struct platform_device hsi2c_gpio_device = { + .name = "i2c-gpio", + .id = 0, + .dev.platform_data = &pdata, +}; + +static struct mcp251x_platform_data mcp251x_info = { + .oscillator_frequency = 24E6, +}; + +static struct spi_board_info cpuimx51sd_spi_device[] = { + { + .modalias = "mcp2515", + .max_speed_hz = 6500000, + .bus_num = 0, + .mode = SPI_MODE_0, + .chip_select = 0, + .platform_data = &mcp251x_info, + .irq = gpio_to_irq(0 * 32 + 1) + }, +}; + +static int cpuimx51sd_spi1_cs[] = { + CAN_NCS, +}; + +static const struct spi_imx_master cpuimx51sd_ecspi1_pdata __initconst = { + .chipselect = cpuimx51sd_spi1_cs, + .num_chipselect = ARRAY_SIZE(cpuimx51sd_spi1_cs), +}; + +static struct platform_device *platform_devices[] __initdata = { + &hsi2c_gpio_device, +}; + +static void __init eukrea_cpuimx51sd_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads, + ARRAY_SIZE(eukrea_cpuimx51sd_pads)); + + imx51_add_imx_uart(0, &uart_pdata); + imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info); + + gpio_request(ETH_RST, "eth_rst"); + gpio_set_value(ETH_RST, 1); + imx51_add_fec(NULL); + + gpio_request(CAN_IRQGPIO, "can_irq"); + gpio_direction_input(CAN_IRQGPIO); + gpio_free(CAN_IRQGPIO); + gpio_request(CAN_NCS, "can_ncs"); + gpio_direction_output(CAN_NCS, 1); + gpio_free(CAN_NCS); + gpio_request(CAN_RST, "can_rst"); + gpio_direction_output(CAN_RST, 0); + msleep(20); + gpio_set_value(CAN_RST, 1); + imx51_add_ecspi(0, &cpuimx51sd_ecspi1_pdata); + spi_register_board_info(cpuimx51sd_spi_device, + ARRAY_SIZE(cpuimx51sd_spi_device)); + + gpio_request(TSC2007_IRQGPIO, "tsc2007_irq"); + gpio_direction_input(TSC2007_IRQGPIO); + gpio_free(TSC2007_IRQGPIO); + + i2c_register_board_info(0, eukrea_cpuimx51sd_i2c_devices, + ARRAY_SIZE(eukrea_cpuimx51sd_i2c_devices)); + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + + if (otg_mode_host) + mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); + else { + initialize_otg_port(NULL); + mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata); + } + + gpio_request(USBH1_RST, "usb_rst"); + gpio_direction_output(USBH1_RST, 0); + msleep(20); + gpio_set_value(USBH1_RST, 1); + mxc_register_device(&mxc_usbh1_device, &usbh1_config); + +#ifdef CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD + eukrea_mbimxsd51_baseboard_init(); +#endif +} + +static void __init eukrea_cpuimx51sd_timer_init(void) +{ + mx51_clocks_init(32768, 24000000, 22579200, 0); +} + +static struct sys_timer mxc_timer = { + .init = eukrea_cpuimx51sd_timer_init, +}; + +MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD") + /* Maintainer: Eric Bénard <eric@eukrea.com> */ + .phys_io = MX51_AIPS1_BASE_ADDR, + .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = mx51_map_io, + .init_irq = mx51_init_irq, + .init_machine = eukrea_cpuimx51sd_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c index f95c2fd94667..ed08a2352a1a 100644 --- a/arch/arm/mach-mx5/board-mx51_3ds.c +++ b/arch/arm/mach-mx5/board-mx51_3ds.c @@ -13,6 +13,7 @@ #include <linux/irq.h> #include <linux/platform_device.h> #include <linux/input/matrix_keypad.h> +#include <linux/spi/spi.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -21,12 +22,13 @@ #include <mach/hardware.h> #include <mach/common.h> #include <mach/iomux-mx51.h> -#include <mach/imx-uart.h> #include <mach/3ds_debugboard.h> +#include "devices-imx51.h" #include "devices.h" #define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 6) +#define MX51_3DS_ECSPI2_CS (GPIO_PORTC + 28) static struct pad_desc mx51_3ds_pads[] = { /* UART1 */ @@ -61,19 +63,25 @@ static struct pad_desc mx51_3ds_pads[] = { MX51_PAD_KEY_COL3__KEY_COL3, MX51_PAD_KEY_COL4__KEY_COL4, MX51_PAD_KEY_COL5__KEY_COL5, + + /* eCSPI2 */ + MX51_PAD_NANDF_RB2__ECSPI2_SCLK, + MX51_PAD_NANDF_RB3__ECSPI2_MISO, + MX51_PAD_NANDF_D15__ECSPI2_MOSI, + MX51_PAD_NANDF_D12__GPIO_3_28, }; /* Serial ports */ #if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) -static struct imxuart_platform_data uart_pdata = { +static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; static inline void mxc_init_imx_uart(void) { - mxc_register_device(&mxc_uart_device0, &uart_pdata); - mxc_register_device(&mxc_uart_device1, &uart_pdata); - mxc_register_device(&mxc_uart_device2, &uart_pdata); + imx51_add_imx_uart(0, &uart_pdata); + imx51_add_imx_uart(1, &uart_pdata); + imx51_add_imx_uart(2, &uart_pdata); } #else /* !SERIAL_IMX */ static inline void mxc_init_imx_uart(void) @@ -127,6 +135,26 @@ static inline void mxc_init_keypad(void) } #endif +static int mx51_3ds_spi2_cs[] = { + MXC_SPI_CS(0), + MX51_3DS_ECSPI2_CS, +}; + +static const struct spi_imx_master mx51_3ds_ecspi2_pdata __initconst = { + .chipselect = mx51_3ds_spi2_cs, + .num_chipselect = ARRAY_SIZE(mx51_3ds_spi2_cs), +}; + +static struct spi_board_info mx51_3ds_spi_nor_device[] = { + { + .modalias = "m25p80", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .mode = SPI_MODE_0, + .platform_data = NULL,}, +}; + /* * Board specific initialization. */ @@ -136,6 +164,10 @@ static void __init mxc_board_init(void) ARRAY_SIZE(mx51_3ds_pads)); mxc_init_imx_uart(); + imx51_add_ecspi(1, &mx51_3ds_ecspi2_pdata); + spi_register_board_info(mx51_3ds_spi_nor_device, + ARRAY_SIZE(mx51_3ds_spi_nor_device)); + if (mxc_expio_init(MX51_CS5_BASE_ADDR, EXPIO_PARENT_INT)) printk(KERN_WARNING "Init of the debugboard failed, all " "devices on the board are unusable.\n"); diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index 6e384d92e625..23ee4a447406 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -17,12 +17,11 @@ #include <linux/delay.h> #include <linux/io.h> #include <linux/fsl_devices.h> +#include <linux/fec.h> #include <mach/common.h> #include <mach/hardware.h> -#include <mach/imx-uart.h> #include <mach/iomux-mx51.h> -#include <mach/i2c.h> #include <mach/mxc_ehci.h> #include <asm/irq.h> @@ -31,11 +30,13 @@ #include <asm/mach/arch.h> #include <asm/mach/time.h> +#include "devices-imx51.h" #include "devices.h" #define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */ #define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */ -#define BABBAGE_PHY_RESET (1*32 +5) /* GPIO_2_5 */ +#define BABBAGE_PHY_RESET (1*32 + 5) /* GPIO_2_5 */ +#define BABBAGE_FEC_PHY_RESET (1*32 + 14) /* GPIO_2_14 */ /* USB_CTRL_1 */ #define MX51_USB_CTRL_1_OFFSET 0x10 @@ -45,10 +46,6 @@ #define MX51_USB_PLL_DIV_19_2_MHZ 0x01 #define MX51_USB_PLL_DIV_24_MHZ 0x02 -static struct platform_device *devices[] __initdata = { - &mxc_fec_device, -}; - static struct pad_desc mx51babbage_pads[] = { /* UART1 */ MX51_PAD_UART1_RXD__UART1_RXD, @@ -93,19 +90,41 @@ static struct pad_desc mx51babbage_pads[] = { /* USB HUB reset line*/ MX51_PAD_GPIO_1_7__GPIO_1_7, + + /* FEC */ + MX51_PAD_EIM_EB2__FEC_MDIO, + MX51_PAD_EIM_EB3__FEC_RDAT1, + MX51_PAD_EIM_CS2__FEC_RDAT2, + MX51_PAD_EIM_CS3__FEC_RDAT3, + MX51_PAD_EIM_CS4__FEC_RX_ER, + MX51_PAD_EIM_CS5__FEC_CRS, + MX51_PAD_NANDF_RB2__FEC_COL, + MX51_PAD_NANDF_RB3__FEC_RXCLK, + MX51_PAD_NANDF_RB6__FEC_RDAT0, + MX51_PAD_NANDF_RB7__FEC_TDAT0, + MX51_PAD_NANDF_CS2__FEC_TX_ER, + MX51_PAD_NANDF_CS3__FEC_MDC, + MX51_PAD_NANDF_CS4__FEC_TDAT1, + MX51_PAD_NANDF_CS5__FEC_TDAT2, + MX51_PAD_NANDF_CS6__FEC_TDAT3, + MX51_PAD_NANDF_CS7__FEC_TX_EN, + MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK, + + /* FEC PHY reset line */ + MX51_PAD_EIM_A20__GPIO_2_14, }; /* Serial ports */ #if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) -static struct imxuart_platform_data uart_pdata = { +static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; static inline void mxc_init_imx_uart(void) { - mxc_register_device(&mxc_uart_device0, &uart_pdata); - mxc_register_device(&mxc_uart_device1, &uart_pdata); - mxc_register_device(&mxc_uart_device2, &uart_pdata); + imx51_add_imx_uart(0, &uart_pdata); + imx51_add_imx_uart(1, &uart_pdata); + imx51_add_imx_uart(2, &uart_pdata); } #else /* !SERIAL_IMX */ static inline void mxc_init_imx_uart(void) @@ -113,7 +132,7 @@ static inline void mxc_init_imx_uart(void) } #endif /* SERIAL_IMX */ -static struct imxi2c_platform_data babbage_i2c_data = { +static const struct imxi2c_platform_data babbage_i2c_data __initconst = { .bitrate = 100000, }; @@ -171,6 +190,22 @@ static inline void babbage_usbhub_reset(void) gpio_set_value(BABBAGE_USB_HUB_RESET, 1); } +static inline void babbage_fec_reset(void) +{ + int ret; + + /* reset FEC PHY */ + ret = gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset"); + if (ret) { + printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret); + return; + } + gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0); + gpio_set_value(BABBAGE_FEC_PHY_RESET, 0); + msleep(1); + gpio_set_value(BABBAGE_FEC_PHY_RESET, 1); +} + /* This function is board specific as the bit mask for the plldiv will also be different for other Freescale SoCs, thus a common bitmask is not possible and cannot get place in /plat-mxc/ehci.c.*/ @@ -178,7 +213,7 @@ static int initialize_otg_port(struct platform_device *pdev) { u32 v; void __iomem *usb_base; - u32 usbother_base; + void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; @@ -196,7 +231,7 @@ static int initialize_usbh1_port(struct platform_device *pdev) { u32 v; void __iomem *usb_base; - u32 usbother_base; + void __iomem *usbother_base; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; @@ -250,10 +285,11 @@ static void __init mxc_board_init(void) mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads, ARRAY_SIZE(mx51babbage_pads)); mxc_init_imx_uart(); - platform_add_devices(devices, ARRAY_SIZE(devices)); + babbage_fec_reset(); + imx51_add_fec(NULL); - mxc_register_device(&mxc_i2c_device0, &babbage_i2c_data); - mxc_register_device(&mxc_i2c_device1, &babbage_i2c_data); + imx51_add_imx_i2c(0, &babbage_i2c_data); + imx51_add_imx_i2c(1, &babbage_i2c_data); mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data); if (otg_mode_host) @@ -283,7 +319,7 @@ MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board") /* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */ .phys_io = MX51_AIPS1_BASE_ADDR, .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = MX51_PHYS_OFFSET + 0x100, .map_io = mx51_map_io, .init_irq = mx51_init_irq, .init_machine = mxc_board_init, diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c new file mode 100644 index 000000000000..b00502acdc15 --- /dev/null +++ b/arch/arm/mach-mx5/board-mx51_efikamx.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2010 Linaro Limited + * + * based on code from the following + * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved. + * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/fsl_devices.h> + +#include <mach/common.h> +#include <mach/hardware.h> +#include <mach/iomux-mx51.h> +#include <mach/i2c.h> +#include <mach/mxc_ehci.h> + +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> + +#include "devices-imx51.h" +#include "devices.h" + +#define MX51_USB_PLL_DIV_24_MHZ 0x01 + +static struct pad_desc mx51efikamx_pads[] = { + /* UART1 */ + MX51_PAD_UART1_RXD__UART1_RXD, + MX51_PAD_UART1_TXD__UART1_TXD, + MX51_PAD_UART1_RTS__UART1_RTS, + MX51_PAD_UART1_CTS__UART1_CTS, +}; + +/* Serial ports */ +#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE) +static const struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static inline void mxc_init_imx_uart(void) +{ + imx51_add_imx_uart(0, &uart_pdata); + imx51_add_imx_uart(1, &uart_pdata); + imx51_add_imx_uart(2, &uart_pdata); +} +#else /* !SERIAL_IMX */ +static inline void mxc_init_imx_uart(void) +{ +} +#endif /* SERIAL_IMX */ + +/* This function is board specific as the bit mask for the plldiv will also + * be different for other Freescale SoCs, thus a common bitmask is not + * possible and cannot get place in /plat-mxc/ehci.c. + */ +static int initialize_otg_port(struct platform_device *pdev) +{ + u32 v; + void __iomem *usb_base; + void __iomem *usbother_base; + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); + usbother_base = (void __iomem *)(usb_base + MX5_USBOTHER_REGS_OFFSET); + + /* Set the PHY clock to 19.2MHz */ + v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET); + v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK; + v |= MX51_USB_PLL_DIV_24_MHZ; + __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET); + iounmap(usb_base); + return 0; +} + +static struct mxc_usbh_platform_data dr_utmi_config = { + .init = initialize_otg_port, + .portsc = MXC_EHCI_UTMI_16BIT, + .flags = MXC_EHCI_INTERNAL_PHY, +}; + +static void __init mxc_board_init(void) +{ + mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads, + ARRAY_SIZE(mx51efikamx_pads)); + mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); + mxc_init_imx_uart(); +} + +static void __init mx51_efikamx_timer_init(void) +{ + mx51_clocks_init(32768, 24000000, 22579200, 24576000); +} + +static struct sys_timer mxc_timer = { + .init = mx51_efikamx_timer_init, +}; + +MACHINE_START(MX51_EFIKAMX, "Genesi EfikaMX nettop") + /* Maintainer: Amit Kucheria <amit.kucheria@linaro.org> */ + .phys_io = MX51_AIPS1_BASE_ADDR, + .io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = MX51_PHYS_OFFSET + 0x100, + .map_io = mx51_map_io, + .init_irq = mx51_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 57c10a9926cc..f2aae92cf0e2 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -41,34 +41,66 @@ static struct clk usboh3_clk; #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ -static int _clk_ccgr_enable(struct clk *clk) +/* calculate best pre and post dividers to get the required divider */ +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post, + u32 max_pre, u32 max_post) { - u32 reg; + if (div >= max_pre * max_post) { + *pre = max_pre; + *post = max_post; + } else if (div >= max_pre) { + u32 min_pre, temp_pre, old_err, err; + min_pre = DIV_ROUND_UP(div, max_post); + old_err = max_pre; + for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) { + err = div % temp_pre; + if (err == 0) { + *pre = temp_pre; + break; + } + err = temp_pre - err; + if (err < old_err) { + old_err = err; + *pre = temp_pre; + } + } + *post = DIV_ROUND_UP(div, *pre); + } else { + *pre = div; + *post = 1; + } +} + +static void _clk_ccgr_setclk(struct clk *clk, unsigned mode) +{ + u32 reg = __raw_readl(clk->enable_reg); + + reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift); + reg |= mode << clk->enable_shift; - reg = __raw_readl(clk->enable_reg); - reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift; __raw_writel(reg, clk->enable_reg); +} +static int _clk_ccgr_enable(struct clk *clk) +{ + _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON); return 0; } static void _clk_ccgr_disable(struct clk *clk) { - u32 reg; - reg = __raw_readl(clk->enable_reg); - reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift); - __raw_writel(reg, clk->enable_reg); + _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF); +} +static int _clk_ccgr_enable_inrun(struct clk *clk) +{ + _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE); + return 0; } static void _clk_ccgr_disable_inwait(struct clk *clk) { - u32 reg; - - reg = __raw_readl(clk->enable_reg); - reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift); - reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift; - __raw_writel(reg, clk->enable_reg); + _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE); } /* @@ -542,60 +574,60 @@ static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent) return 0; } -static unsigned long clk_uart_get_rate(struct clk *clk) -{ - u32 reg, prediv, podf; - unsigned long parent_rate; +#define clk_nfc_set_parent NULL - parent_rate = clk_get_rate(clk->parent); - - reg = __raw_readl(MXC_CCM_CSCDR1); - prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1; - podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1; +static unsigned long clk_nfc_get_rate(struct clk *clk) +{ + unsigned long rate; + u32 reg, div; - return parent_rate / (prediv * podf); + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >> + MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1; + rate = clk_get_rate(clk->parent) / div; + WARN_ON(rate == 0); + return rate; } -static int _clk_uart_set_parent(struct clk *clk, struct clk *parent) +static unsigned long clk_nfc_round_rate(struct clk *clk, + unsigned long rate) { - u32 reg, mux; + u32 div; + unsigned long parent_rate = clk_get_rate(clk->parent); - mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, - &lp_apm_clk); - reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK; - reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET; - __raw_writel(reg, MXC_CCM_CSCMR1); + if (!rate) + return -EINVAL; - return 0; -} + div = parent_rate / rate; -static unsigned long clk_usboh3_get_rate(struct clk *clk) -{ - u32 reg, prediv, podf; - unsigned long parent_rate; + if (parent_rate % rate) + div++; - parent_rate = clk_get_rate(clk->parent); + if (div > 8) + return -EINVAL; - reg = __raw_readl(MXC_CCM_CSCDR1); - prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >> - MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1; - podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >> - MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1; + return parent_rate / div; - return parent_rate / (prediv * podf); } -static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent) +static int clk_nfc_set_rate(struct clk *clk, unsigned long rate) { - u32 reg, mux; + u32 reg, div; + + div = clk_get_rate(clk->parent) / rate; + if (div == 0) + div++; + if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8)) + return -EINVAL; + + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK; + reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_CBCDR); - mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, - &lp_apm_clk); - reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK; - reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET; - __raw_writel(reg, MXC_CCM_CSCMR1); + while (__raw_readl(MXC_CCM_CDHIPR) & + MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){ + } return 0; } @@ -620,6 +652,17 @@ static unsigned long get_ckih2_reference_clock_rate(struct clk *clk) return ckih2_reference; } +static unsigned long clk_emi_slow_get_rate(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >> + MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1; + + return clk_get_rate(clk->parent) / div; +} + /* External high frequency clock */ static struct clk ckih_clk = { .get_rate = get_high_reference_clock_rate, @@ -715,18 +758,6 @@ static struct clk ipg_perclk = { .set_parent = _clk_ipg_per_set_parent, }; -static struct clk uart_root_clk = { - .parent = &pll2_sw_clk, - .get_rate = clk_uart_get_rate, - .set_parent = _clk_uart_set_parent, -}; - -static struct clk usboh3_clk = { - .parent = &pll2_sw_clk, - .get_rate = clk_usboh3_get_rate, - .set_parent = _clk_usboh3_set_parent, -}; - static struct clk ahb_max_clk = { .parent = &ahb_clk, .enable_reg = MXC_CCM_CCGR0, @@ -762,45 +793,183 @@ static struct clk kpp_clk = { .id = 0, }; -#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \ +static struct clk emi_slow_clk = { + .parent = &pll2_sw_clk, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, + .enable = _clk_ccgr_enable, + .disable = _clk_ccgr_disable_inwait, + .get_rate = clk_emi_slow_get_rate, +}; + +#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ static struct clk name = { \ .id = i, \ .enable_reg = er, \ .enable_shift = es, \ - .get_rate = gr, \ - .set_rate = sr, \ + .get_rate = pfx##_get_rate, \ + .set_rate = pfx##_set_rate, \ + .round_rate = pfx##_round_rate, \ + .set_parent = pfx##_set_parent, \ .enable = _clk_ccgr_enable, \ .disable = _clk_ccgr_disable, \ .parent = p, \ .secondary = s, \ } -/* DEFINE_CLOCK(name, id, enable_reg, enable_shift, - get_rate, set_rate, parent, secondary); */ +#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \ + static struct clk name = { \ + .id = i, \ + .enable_reg = er, \ + .enable_shift = es, \ + .get_rate = pfx##_get_rate, \ + .set_rate = pfx##_set_rate, \ + .set_parent = pfx##_set_parent, \ + .enable = _clk_max_enable, \ + .disable = _clk_max_disable, \ + .parent = p, \ + .secondary = s, \ + } + +#define CLK_GET_RATE(name, nr, bitsname) \ +static unsigned long clk_##name##_get_rate(struct clk *clk) \ +{ \ + u32 reg, pred, podf; \ + \ + reg = __raw_readl(MXC_CCM_CSCDR##nr); \ + pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \ + >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \ + podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \ + >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \ + \ + return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \ + (pred + 1) * (podf + 1)); \ +} + +#define CLK_SET_PARENT(name, nr, bitsname) \ +static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \ +{ \ + u32 reg, mux; \ + \ + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \ + &pll3_sw_clk, &lp_apm_clk); \ + reg = __raw_readl(MXC_CCM_CSCMR##nr) & \ + ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \ + reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \ + __raw_writel(reg, MXC_CCM_CSCMR##nr); \ + \ + return 0; \ +} + +#define CLK_SET_RATE(name, nr, bitsname) \ +static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \ +{ \ + u32 reg, div, parent_rate; \ + u32 pre = 0, post = 0; \ + \ + parent_rate = clk_get_rate(clk->parent); \ + div = parent_rate / rate; \ + \ + if ((parent_rate / div) != rate) \ + return -EINVAL; \ + \ + __calc_pre_post_dividers(div, &pre, &post, \ + (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \ + MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \ + (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \ + MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\ + \ + /* Set sdhc1 clock divider */ \ + reg = __raw_readl(MXC_CCM_CSCDR##nr) & \ + ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \ + | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \ + reg |= (post - 1) << \ + MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \ + reg |= (pre - 1) << \ + MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \ + __raw_writel(reg, MXC_CCM_CSCDR##nr); \ + \ + return 0; \ +} + +/* UART */ +CLK_GET_RATE(uart, 1, UART) +CLK_SET_PARENT(uart, 1, UART) + +static struct clk uart_root_clk = { + .parent = &pll2_sw_clk, + .get_rate = clk_uart_get_rate, + .set_parent = clk_uart_set_parent, +}; + +/* USBOH3 */ +CLK_GET_RATE(usboh3, 1, USBOH3) +CLK_SET_PARENT(usboh3, 1, USBOH3) + +static struct clk usboh3_clk = { + .parent = &pll2_sw_clk, + .get_rate = clk_usboh3_get_rate, + .set_parent = clk_usboh3_set_parent, +}; + +/* eCSPI */ +CLK_GET_RATE(ecspi, 2, CSPI) +CLK_SET_PARENT(ecspi, 1, CSPI) + +static struct clk ecspi_main_clk = { + .parent = &pll3_sw_clk, + .get_rate = clk_ecspi_get_rate, + .set_parent = clk_ecspi_set_parent, +}; + +/* eSDHC */ +CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1) +CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1) +CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1) + +CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2) +CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2) +CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2) + +#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \ + static struct clk name = { \ + .id = i, \ + .enable_reg = er, \ + .enable_shift = es, \ + .get_rate = gr, \ + .set_rate = sr, \ + .enable = e, \ + .disable = d, \ + .parent = p, \ + .secondary = s, \ + } + +#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \ + DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s) /* Shared peripheral bus arbiter */ DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET, NULL, NULL, &ipg_clk, NULL); /* UART */ -DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET, - NULL, NULL, &uart_root_clk, NULL); -DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET, - NULL, NULL, &uart_root_clk, NULL); -DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET, - NULL, NULL, &uart_root_clk, NULL); DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &ipg_clk, &aips_tz1_clk); DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, &ipg_clk, &aips_tz1_clk); DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET, NULL, NULL, &ipg_clk, &spba_clk); +DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET, + NULL, NULL, &uart_root_clk, &uart1_ipg_clk); +DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET, + NULL, NULL, &uart_root_clk, &uart2_ipg_clk); +DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET, + NULL, NULL, &uart_root_clk, &uart3_ipg_clk); /* GPT */ -DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, - NULL, NULL, &ipg_clk, NULL); DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, + NULL, NULL, &ipg_clk, &gpt_ipg_clk); /* I2C */ DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET, @@ -814,6 +983,52 @@ DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, NULL, NULL, &ipg_clk, NULL); +/* NFC */ +DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, + clk_nfc, &emi_slow_clk, NULL); + +/* SSI */ +DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET, + NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET, + NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk); +DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET, + NULL, NULL, &ipg_clk, NULL); +DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET, + NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk); + +/* eCSPI */ +DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, + NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable, + &ipg_clk, &spba_clk); +DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET, + NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk); +DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET, + NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable, + &ipg_clk, &aips_tz2_clk); +DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET, + NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk); + +/* CSPI */ +DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, + NULL, NULL, &ipg_clk, &aips_tz2_clk); +DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET, + NULL, NULL, &ipg_clk, &cspi_ipg_clk); + +/* SDMA */ +DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET, + NULL, NULL, &ahb_clk, NULL); + +/* eSDHC */ +DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET, + NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); +DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET, + clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk); +DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET, + NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); +DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET, + clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk); + #define _REGISTER_CLOCK(d, n, c) \ { \ .dev_id = d, \ @@ -837,6 +1052,18 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk) _REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk) + _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk) + _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) + _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) + _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk) + _REGISTER_CLOCK(NULL, "ckih", ckih_clk) + _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk) + _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk) + _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) + _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) + _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) + _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) }; static void clk_tree_init(void) @@ -880,6 +1107,14 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, /* set the usboh3_clk parent to pll2_sw_clk */ clk_set_parent(&usboh3_clk, &pll2_sw_clk); + /* Set SDHC parents to be PLL2 */ + clk_set_parent(&esdhc1_clk, &pll2_sw_clk); + clk_set_parent(&esdhc2_clk, &pll2_sw_clk); + + /* set SDHC root clock as 166.25MHZ*/ + clk_set_rate(&esdhc1_clk, 166250000); + clk_set_rate(&esdhc2_clk, 166250000); + /* System timer */ mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_MXC_INT_GPT); diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c index 2d37785e3857..eaacb6e9b5d0 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c @@ -70,6 +70,25 @@ int mx51_revision(void) } EXPORT_SYMBOL(mx51_revision); +#ifdef CONFIG_NEON + +/* + * All versions of the silicon before Rev. 3 have broken NEON implementations. + * Dependent on link order - so the assumption is that vfp_init is called + * before us. + */ +static int __init mx51_neon_fixup(void) +{ + if (mx51_revision() < MX51_CHIP_REV_3_0 && (elf_hwcap & HWCAP_NEON)) { + elf_hwcap &= ~HWCAP_NEON; + pr_info("Turning off NEON support, detected broken NEON implementation\n"); + } + return 0; +} + +late_initcall(mx51_neon_fixup); +#endif + static int __init post_cpu_init(void) { unsigned int reg; diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h new file mode 100644 index 000000000000..5cc910e60538 --- /dev/null +++ b/arch/arm/mach-mx5/devices-imx51.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 Pengutronix + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include <mach/mx51.h> +#include <mach/devices-common.h> + +extern const struct imx_fec_data imx51_fec_data __initconst; +#define imx51_add_fec(pdata) \ + imx_add_fec(&imx51_fec_data, pdata) + +extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst; +#define imx51_add_imx_i2c(id, pdata) \ + imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata) + +extern const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst; +#define imx51_add_imx_ssi(id, pdata) \ + imx_add_imx_ssi(&imx51_imx_ssi_data[id], pdata) + +extern const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst; +#define imx51_add_imx_uart(id, pdata) \ + imx_add_imx_uart_1irq(&imx51_imx_uart_data[id], pdata) + +extern const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst; +#define imx51_add_mxc_nand(pdata) \ + imx_add_mxc_nand(&imx51_mxc_nand_data, pdata) + +extern const struct imx_spi_imx_data imx51_cspi_data __initconst; +#define imx51_add_cspi(pdata) \ + imx_add_spi_imx(&imx51_cspi_data, pdata) + +extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst; +#define imx51_add_ecspi(id, pdata) \ + imx_add_spi_imx(&imx51_ecspi_data[id], pdata) + +extern const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst; +#define imx51_add_esdhc(id, pdata) \ + imx_add_esdhc(&imx51_esdhc_data[id], pdata) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 1920ff4963b2..4c7be87a7c9d 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -17,120 +17,6 @@ #include <mach/imx-uart.h> #include <mach/irqs.h> -static struct resource uart0[] = { - { - .start = MX51_UART1_BASE_ADDR, - .end = MX51_UART1_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, { - .start = MX51_MXC_INT_UART1, - .end = MX51_MXC_INT_UART1, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_uart_device0 = { - .name = "imx-uart", - .id = 0, - .resource = uart0, - .num_resources = ARRAY_SIZE(uart0), -}; - -static struct resource uart1[] = { - { - .start = MX51_UART2_BASE_ADDR, - .end = MX51_UART2_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, { - .start = MX51_MXC_INT_UART2, - .end = MX51_MXC_INT_UART2, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_uart_device1 = { - .name = "imx-uart", - .id = 1, - .resource = uart1, - .num_resources = ARRAY_SIZE(uart1), -}; - -static struct resource uart2[] = { - { - .start = MX51_UART3_BASE_ADDR, - .end = MX51_UART3_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, { - .start = MX51_MXC_INT_UART3, - .end = MX51_MXC_INT_UART3, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_uart_device2 = { - .name = "imx-uart", - .id = 2, - .resource = uart2, - .num_resources = ARRAY_SIZE(uart2), -}; - -static struct resource mxc_fec_resources[] = { - { - .start = MX51_MXC_FEC_BASE_ADDR, - .end = MX51_MXC_FEC_BASE_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, { - .start = MX51_MXC_INT_FEC, - .end = MX51_MXC_INT_FEC, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_fec_device = { - .name = "fec", - .id = 0, - .num_resources = ARRAY_SIZE(mxc_fec_resources), - .resource = mxc_fec_resources, -}; - -static struct resource mxc_i2c0_resources[] = { - { - .start = MX51_I2C1_BASE_ADDR, - .end = MX51_I2C1_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = MX51_MXC_INT_I2C1, - .end = MX51_MXC_INT_I2C1, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_i2c_device0 = { - .name = "imx-i2c", - .id = 0, - .num_resources = ARRAY_SIZE(mxc_i2c0_resources), - .resource = mxc_i2c0_resources, -}; - -static struct resource mxc_i2c1_resources[] = { - { - .start = MX51_I2C2_BASE_ADDR, - .end = MX51_I2C2_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = MX51_MXC_INT_I2C2, - .end = MX51_MXC_INT_I2C2, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device mxc_i2c_device1 = { - .name = "imx-i2c", - .id = 1, - .num_resources = ARRAY_SIZE(mxc_i2c1_resources), - .resource = mxc_i2c1_resources, -}; - static struct resource mxc_hsi2c_resources[] = { { .start = MX51_HSI2C_DMA_BASE_ADDR, diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index e509cfaad1d4..af1d07c0bbc1 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -1,12 +1,6 @@ -extern struct platform_device mxc_uart_device0; -extern struct platform_device mxc_uart_device1; -extern struct platform_device mxc_uart_device2; -extern struct platform_device mxc_fec_device; extern struct platform_device mxc_usbdr_host_device; extern struct platform_device mxc_usbh1_device; extern struct platform_device mxc_usbdr_udc_device; extern struct platform_device mxc_wdt; -extern struct platform_device mxc_i2c_device0; -extern struct platform_device mxc_i2c_device1; extern struct platform_device mxc_hsi2c_device; extern struct platform_device mxc_keypad_device; diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c index ffa93d1d6ef8..a2e6e8c39d25 100644 --- a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c +++ b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c @@ -30,6 +30,7 @@ #include <asm/mach/arch.h> +#include "devices-imx51.h" #include "devices.h" #define MBIMX51_TSC2007_GPIO (2*32 + 30) @@ -112,9 +113,25 @@ static struct pad_desc mbimx51_pads[] = { MX51_PAD_KEY_COL1__KEY_COL1, MX51_PAD_KEY_COL2__KEY_COL2, MX51_PAD_KEY_COL3__KEY_COL3, + + /* SD 1 */ + MX51_PAD_SD1_CMD__SD1_CMD, + MX51_PAD_SD1_CLK__SD1_CLK, + MX51_PAD_SD1_DATA0__SD1_DATA0, + MX51_PAD_SD1_DATA1__SD1_DATA1, + MX51_PAD_SD1_DATA2__SD1_DATA2, + MX51_PAD_SD1_DATA3__SD1_DATA3, + + /* SD 2 */ + MX51_PAD_SD2_CMD__SD2_CMD, + MX51_PAD_SD2_CLK__SD2_CLK, + MX51_PAD_SD2_DATA0__SD2_DATA0, + MX51_PAD_SD2_DATA1__SD2_DATA1, + MX51_PAD_SD2_DATA2__SD2_DATA2, + MX51_PAD_SD2_DATA3__SD2_DATA3, }; -static struct imxuart_platform_data uart_pdata = { +static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -158,9 +175,11 @@ struct tsc2007_platform_data tsc2007_data = { static struct i2c_board_info mbimx51_i2c_devices[] = { { - I2C_BOARD_INFO("tsc2007", 0x48), + I2C_BOARD_INFO("tsc2007", 0x49), .irq = MBIMX51_TSC2007_IRQ, .platform_data = &tsc2007_data, + }, { + I2C_BOARD_INFO("tlv320aic23", 0x1a), }, }; @@ -172,8 +191,8 @@ void __init eukrea_mbimx51_baseboard_init(void) mxc_iomux_v3_setup_multiple_pads(mbimx51_pads, ARRAY_SIZE(mbimx51_pads)); - mxc_register_device(&mxc_uart_device1, NULL); - mxc_register_device(&mxc_uart_device2, &uart_pdata); + imx51_add_imx_uart(1, NULL); + imx51_add_imx_uart(2, &uart_pdata); gpio_request(MBIMX51_LED0, "LED0"); gpio_direction_output(MBIMX51_LED0, 1); @@ -197,4 +216,7 @@ void __init eukrea_mbimx51_baseboard_init(void) set_irq_type(MBIMX51_TSC2007_IRQ, IRQF_TRIGGER_FALLING); i2c_register_board_info(1, mbimx51_i2c_devices, ARRAY_SIZE(mbimx51_i2c_devices)); + + imx51_add_esdhc(0, NULL); + imx51_add_esdhc(1, NULL); } diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c new file mode 100644 index 000000000000..2b48f5190830 --- /dev/null +++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2010 Eric Benard - eric@eukrea.com + * + * Based on pcm970-baseboard.c which is : + * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include <linux/types.h> +#include <linux/init.h> + +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/leds.h> +#include <linux/platform_device.h> +#include <linux/gpio_keys.h> +#include <linux/input.h> +#include <linux/i2c.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <asm/mach/map.h> + +#include <mach/hardware.h> +#include <mach/common.h> +#include <mach/imx-uart.h> +#include <mach/iomux-mx51.h> +#include <mach/audmux.h> + +#include "devices-imx51.h" +#include "devices.h" + +#define MBIMXSD_GPIO_3_31 IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, \ + MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP) + +static struct pad_desc eukrea_mbimxsd_pads[] = { + /* LED */ + MX51_PAD_NANDF_D10__GPIO_3_30, + /* SWITCH */ + MBIMXSD_GPIO_3_31, + /* UART2 */ + MX51_PAD_UART2_RXD__UART2_RXD, + MX51_PAD_UART2_TXD__UART2_TXD, + /* UART 3 */ + MX51_PAD_UART3_RXD__UART3_RXD, + MX51_PAD_UART3_TXD__UART3_TXD, + MX51_PAD_KEY_COL4__UART3_RTS, + MX51_PAD_KEY_COL5__UART3_CTS, + /* SD */ + MX51_PAD_SD1_CMD__SD1_CMD, + MX51_PAD_SD1_CLK__SD1_CLK, + MX51_PAD_SD1_DATA0__SD1_DATA0, + MX51_PAD_SD1_DATA1__SD1_DATA1, + MX51_PAD_SD1_DATA2__SD1_DATA2, + MX51_PAD_SD1_DATA3__SD1_DATA3, +}; + +#define GPIO_LED1 (2 * 32 + 30) +#define GPIO_SWITCH1 (2 * 32 + 31) + +static struct gpio_led eukrea_mbimxsd_leds[] = { + { + .name = "led1", + .default_trigger = "heartbeat", + .active_low = 1, + .gpio = GPIO_LED1, + }, +}; + +static struct gpio_led_platform_data eukrea_mbimxsd_led_info = { + .leds = eukrea_mbimxsd_leds, + .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds), +}; + +static struct platform_device eukrea_mbimxsd_leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &eukrea_mbimxsd_led_info, + }, +}; + +static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = { + { + .gpio = GPIO_SWITCH1, + .code = BTN_0, + .desc = "BP1", + .active_low = 1, + .wakeup = 1, + }, +}; + +static struct gpio_keys_platform_data eukrea_mbimxsd_button_data = { + .buttons = eukrea_mbimxsd_gpio_buttons, + .nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons), +}; + +static struct platform_device eukrea_mbimxsd_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &eukrea_mbimxsd_button_data, + } +}; + +static struct platform_device *platform_devices[] __initdata = { + &eukrea_mbimxsd_leds_gpio, + &eukrea_mbimxsd_button_device, +}; + +static const struct imxuart_platform_data uart_pdata __initconst = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic23", 0x1a), + }, +}; + +/* + * system init for baseboard usage. Will be called by cpuimx51sd init. + * + * Add platform devices present on this baseboard and init + * them from CPU side as far as required to use them later on + */ +void __init eukrea_mbimxsd51_baseboard_init(void) +{ + if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads, + ARRAY_SIZE(eukrea_mbimxsd_pads))) + printk(KERN_ERR "error setting mbimxsd pads !\n"); + + imx51_add_imx_uart(1, NULL); + imx51_add_imx_uart(2, &uart_pdata); + + imx51_add_esdhc(0, NULL); + + gpio_request(GPIO_LED1, "LED1"); + gpio_direction_output(GPIO_LED1, 1); + gpio_free(GPIO_LED1); + + gpio_request(GPIO_SWITCH1, "SWITCH1"); + gpio_direction_input(GPIO_SWITCH1); + gpio_free(GPIO_SWITCH1); + + i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices, + ARRAY_SIZE(eukrea_mbimxsd_i2c_devices)); + + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); +} diff --git a/arch/arm/mach-netx/include/mach/vmalloc.h b/arch/arm/mach-netx/include/mach/vmalloc.h index 25d5cc676e0f..7cca3574308f 100644 --- a/arch/arm/mach-netx/include/mach/vmalloc.h +++ b/arch/arm/mach-netx/include/mach/vmalloc.h @@ -16,4 +16,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define VMALLOC_END (PAGE_OFFSET + 0x10000000) +#define VMALLOC_END 0xd0000000 diff --git a/arch/arm/mach-omap1/include/mach/vmalloc.h b/arch/arm/mach-omap1/include/mach/vmalloc.h index 1b2af14df151..b001f67d695b 100644 --- a/arch/arm/mach-omap1/include/mach/vmalloc.h +++ b/arch/arm/mach-omap1/include/mach/vmalloc.h @@ -17,4 +17,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define VMALLOC_END (PAGE_OFFSET + 0x18000000) +#define VMALLOC_END 0xd8000000 diff --git a/arch/arm/mach-omap2/include/mach/vmalloc.h b/arch/arm/mach-omap2/include/mach/vmalloc.h index 9ce9b6e8ad23..4da31e997efe 100644 --- a/arch/arm/mach-omap2/include/mach/vmalloc.h +++ b/arch/arm/mach-omap2/include/mach/vmalloc.h @@ -17,4 +17,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define VMALLOC_END (PAGE_OFFSET + 0x38000000) +#define VMALLOC_END 0xf8000000 diff --git a/arch/arm/mach-pnx4008/include/mach/vmalloc.h b/arch/arm/mach-pnx4008/include/mach/vmalloc.h index 2ad398378aed..31b65ee07b0b 100644 --- a/arch/arm/mach-pnx4008/include/mach/vmalloc.h +++ b/arch/arm/mach-pnx4008/include/mach/vmalloc.h @@ -17,4 +17,4 @@ * The vmalloc() routines leaves a hole of 4kB between each vmalloced * area for the same reason. ;) */ -#define VMALLOC_END (PAGE_OFFSET + 0x10000000) +#define VMALLOC_END 0xd0000000 diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 7aefb9074852..dd235ecc9d6c 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -8,19 +8,16 @@ config ARCH_LUBBOCK bool "Intel DBPXA250 Development Platform (aka Lubbock)" select PXA25x select SA1111 - select PXA_HAVE_BOARD_IRQS config MACH_MAINSTONE bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)" select PXA27x select HAVE_PWM - select PXA_HAVE_BOARD_IRQS config MACH_ZYLONITE bool select PXA3xx select HAVE_PWM - select PXA_HAVE_BOARD_IRQS config MACH_ZYLONITE300 bool "PXA3xx Development Platform (aka Zylonite) PXA300/310" @@ -44,6 +41,10 @@ config MACH_TAVOREVB select PXA3xx select CPU_PXA930 +config MACH_TAVOREVB3 + bool "PXA95x Development Platform (aka TavorEVB III)" + select CPU_PXA950 + config MACH_SAAR bool "PXA930 Handheld Platform (aka SAAR)" select PXA3xx @@ -61,7 +62,6 @@ config ARCH_VIPER select ISA select I2C_GPIO select HAVE_PWM - select PXA_HAVE_BOARD_IRQS select PXA_HAVE_ISA_IRQS select ARCOM_PCMCIA @@ -69,7 +69,6 @@ config MACH_ARCOM_ZEUS bool "Arcom/Eurotech ZEUS SBC" select PXA27x select ISA - select PXA_HAVE_BOARD_IRQS select PXA_HAVE_ISA_IRQS select ARCOM_PCMCIA @@ -77,7 +76,6 @@ config MACH_BALLOON3 bool "Balloon 3 board" select PXA27x select IWMMXT - select PXA_HAVE_BOARD_IRQS config MACH_CSB726 bool "Enable Cogent CSB726 System On a Module" @@ -140,13 +138,11 @@ config MACH_INTELMOTE2 bool "Intel Mote 2 Platform" select PXA27x select IWMMXT - select PXA_HAVE_BOARD_IRQS config MACH_STARGATE2 bool "Intel Stargate 2 Platform" select PXA27x select IWMMXT - select PXA_HAVE_BOARD_IRQS config MACH_XCEP bool "Iskratel Electronics XCEP" @@ -206,13 +202,11 @@ config MACH_LOGICPD_PXA270 bool "LogicPD PXA270 Card Engine Development Platform" select PXA27x select HAVE_PWM - select PXA_HAVE_BOARD_IRQS config MACH_PCM027 bool "Phytec phyCORE-PXA270 CPU module (PCM-027)" select PXA27x select IWMMXT - select PXA_HAVE_BOARD_IRQS config MACH_PCM990_BASEBOARD bool "PHYTEC PCM-990 development board" @@ -247,7 +241,6 @@ config MACH_COLIBRI_PXA270_INCOME depends on MACH_COLIBRI select PXA27x select HAVE_PWM - select PXA_HAVE_BOARD_IRQS config MACH_COLIBRI300 bool "Toradex Colibri PXA300/310" @@ -274,7 +267,6 @@ config MACH_H4700 select PXA27x select IWMMXT select HAVE_PWM - select PXA_HAVE_BOARD_IRQS config MACH_H5000 bool "HP iPAQ h5000" @@ -289,7 +281,6 @@ config MACH_MAGICIAN select PXA27x select IWMMXT select HAVE_PWM - select PXA_HAVE_BOARD_IRQS config MACH_MIOA701 bool "Mitac Mio A701 Support" @@ -307,7 +298,6 @@ config PXA_EZX select PXA27x select IWMMXT select HAVE_PWM - select PXA_HAVE_BOARD_IRQS config MACH_EZX_A780 bool "Motorola EZX A780" @@ -478,7 +468,6 @@ config MACH_POODLE depends on PXA_SHARPSL select PXA25x select SHARP_LOCOMO - select PXA_HAVE_BOARD_IRQS config MACH_CORGI bool "Enable Sharp SL-C700 (Corgi) Support" @@ -523,7 +512,6 @@ config MACH_TOSA bool "Enable Sharp SL-6000x (Tosa) Support" depends on PXA_SHARPSL select PXA25x - select PXA_HAVE_BOARD_IRQS config TOSA_BT tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" @@ -552,7 +540,6 @@ config MACH_ICONTROL config ARCH_PXA_ESERIES bool "PXA based Toshiba e-series PDAs" select PXA25x - select PXA_HAVE_BOARD_IRQS config MACH_E330 bool "Toshiba e330" @@ -606,7 +593,6 @@ config MACH_ZIPIT2 bool "Zipit Z2 Handheld" select PXA27x select HAVE_PWM - select PXA_HAVE_BOARD_IRQS endmenu @@ -643,6 +629,7 @@ config CPU_PXA300 config CPU_PXA310 bool select CPU_PXA300 + select PXA310_ULPI if USB_ULPI help PXA310 (codename Monahans-LV) @@ -692,10 +679,10 @@ config SHARPSL_PM_MAX1111 select HWMON select SENSORS_MAX1111 -config PXA_HAVE_BOARD_IRQS +config PXA_HAVE_ISA_IRQS bool -config PXA_HAVE_ISA_IRQS +config PXA310_ULPI bool endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 85c7fb324dbb..e2f89c2c6f49 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -18,7 +18,7 @@ endif # SoC-specific code obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa2xx.o pxa25x.o obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o pxa2xx.o pxa27x.o -obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o +obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o obj-$(CONFIG_CPU_PXA300) += pxa300.o obj-$(CONFIG_CPU_PXA320) += pxa320.o obj-$(CONFIG_CPU_PXA930) += pxa930.o @@ -32,6 +32,7 @@ obj-$(CONFIG_MACH_ZYLONITE300) += zylonite.o zylonite_pxa300.o obj-$(CONFIG_MACH_ZYLONITE320) += zylonite.o zylonite_pxa320.o obj-$(CONFIG_MACH_LITTLETON) += littleton.o obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o +obj-$(CONFIG_MACH_TAVOREVB3) += tavorevb3.o obj-$(CONFIG_MACH_SAAR) += saar.o # 3rd Party Dev Platforms diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 9041340fee1d..79d0f6cf53d7 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -68,42 +68,6 @@ static unsigned long balloon3_pin_config[] __initdata = { /* Reset, configured as GPIO wakeup source */ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, - - /* LEDs */ - GPIO9_GPIO, /* NAND activity LED */ - GPIO10_GPIO, /* Heartbeat LED */ - - /* AC97 */ - GPIO28_AC97_BITCLK, - GPIO29_AC97_SDATA_IN_0, - GPIO30_AC97_SDATA_OUT, - GPIO31_AC97_SYNC, - GPIO113_AC97_nRESET, - GPIO95_GPIO, - - /* MMC */ - GPIO32_MMC_CLK, - GPIO92_MMC_DAT_0, - GPIO109_MMC_DAT_1, - GPIO110_MMC_DAT_2, - GPIO111_MMC_DAT_3, - GPIO112_MMC_CMD, - - /* USB Host */ - GPIO88_USBH1_PWR, - GPIO89_USBH1_PEN, - - /* PC Card */ - GPIO48_nPOE, - GPIO49_nPWE, - GPIO50_nPIOR, - GPIO51_nPIOW, - GPIO85_nPCE_1, - GPIO54_nPCE_2, - GPIO79_PSKTSEL, - GPIO55_nPREG, - GPIO56_nPWAIT, - GPIO57_nIOIS16, }; /****************************************************************************** @@ -132,6 +96,34 @@ int __init parse_balloon3_features(char *arg) early_param("balloon3_features", parse_balloon3_features); /****************************************************************************** + * Compact Flash slot + ******************************************************************************/ +#if defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE) +static unsigned long balloon3_cf_pin_config[] __initdata = { + GPIO48_nPOE, + GPIO49_nPWE, + GPIO50_nPIOR, + GPIO51_nPIOW, + GPIO85_nPCE_1, + GPIO54_nPCE_2, + GPIO79_PSKTSEL, + GPIO55_nPREG, + GPIO56_nPWAIT, + GPIO57_nIOIS16, +}; + +static void __init balloon3_cf_init(void) +{ + if (!balloon3_has(BALLOON3_FEATURE_CF)) + return; + + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_cf_pin_config)); +} +#else +static inline void balloon3_cf_init(void) {} +#endif + +/****************************************************************************** * NOR Flash ******************************************************************************/ #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) @@ -179,6 +171,15 @@ static inline void balloon3_nor_init(void) {} ******************************************************************************/ #if defined(CONFIG_TOUCHSCREEN_UCB1400) || \ defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE) +static unsigned long balloon3_ac97_pin_config[] __initdata = { + GPIO28_AC97_BITCLK, + GPIO29_AC97_SDATA_IN_0, + GPIO30_AC97_SDATA_OUT, + GPIO31_AC97_SYNC, + GPIO113_AC97_nRESET, + GPIO95_GPIO, +}; + static struct ucb1400_pdata vpac270_ucb1400_pdata = { .irq = IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ), }; @@ -197,6 +198,7 @@ static void __init balloon3_ts_init(void) if (!balloon3_has(BALLOON3_FEATURE_AUDIO)) return; + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config)); pxa_set_ac97_info(NULL); platform_device_register(&balloon3_ucb1400_device); } @@ -208,6 +210,11 @@ static inline void balloon3_ts_init(void) {} * Framebuffer ******************************************************************************/ #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static unsigned long balloon3_lcd_pin_config[] __initdata = { + GPIOxx_LCD_TFT_16BPP, + GPIO99_GPIO, +}; + static struct pxafb_mode_info balloon3_lcd_modes[] = { { .pixclock = 38000, @@ -242,6 +249,8 @@ static void __init balloon3_lcd_init(void) if (!balloon3_has(BALLOON3_FEATURE_TOPPOLY)) return; + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config)); + ret = gpio_request(BALLOON3_GPIO_RUN_BACKLIGHT, "BKL-ON"); if (ret) { pr_err("Requesting BKL-ON GPIO failed!\n"); @@ -271,6 +280,15 @@ static inline void balloon3_lcd_init(void) {} * SD/MMC card controller ******************************************************************************/ #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) +static unsigned long balloon3_mmc_pin_config[] __initdata = { + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, +}; + static struct pxamci_platform_data balloon3_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .gpio_card_detect = -1, @@ -281,6 +299,7 @@ static struct pxamci_platform_data balloon3_mci_platform_data = { static void __init balloon3_mmc_init(void) { + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_mmc_pin_config)); pxa_set_mci_info(&balloon3_mci_platform_data); } #else @@ -339,6 +358,11 @@ static inline void balloon3_irda_init(void) {} * USB Host ******************************************************************************/ #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static unsigned long balloon3_uhc_pin_config[] __initdata = { + GPIO88_USBH1_PWR, + GPIO89_USBH1_PEN, +}; + static struct pxaohci_platform_data balloon3_ohci_info = { .port_mode = PMM_PERPORT_MODE, .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW, @@ -348,6 +372,7 @@ static void __init balloon3_uhc_init(void) { if (!balloon3_has(BALLOON3_FEATURE_OHCI)) return; + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_uhc_pin_config)); pxa_set_ohci_info(&balloon3_ohci_info); } #else @@ -358,6 +383,11 @@ static inline void balloon3_uhc_init(void) {} * LEDs ******************************************************************************/ #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +static unsigned long balloon3_led_pin_config[] __initdata = { + GPIO9_GPIO, /* NAND activity LED */ + GPIO10_GPIO, /* Heartbeat LED */ +}; + struct gpio_led balloon3_gpio_leds[] = { { .name = "balloon3:green:idle", @@ -436,6 +466,7 @@ static struct platform_device balloon3_pcf_leds = { static void __init balloon3_leds_init(void) { + pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_led_pin_config)); platform_device_register(&balloon3_leds); platform_device_register(&balloon3_pcf_leds); } @@ -757,6 +788,7 @@ static void __init balloon3_init(void) balloon3_ts_init(); balloon3_udc_init(); balloon3_uhc_init(); + balloon3_cf_init(); } static struct map_desc balloon3_io_desc[] __initdata = { @@ -779,6 +811,7 @@ MACHINE_START(BALLOON3, "Balloon3") .phys_io = 0x40000000, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = balloon3_map_io, + .nr_irqs = BALLOON3_NR_IRQS, .init_irq = balloon3_init_irq, .timer = &pxa_timer, .init_machine = balloon3_init, diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index bff6e78f033d..ad40e7b141e0 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -33,6 +33,9 @@ extern void cmx255_init(void); extern void cmx270_init(void); +/* reserve IRQs for IT8152 */ +#define CMX2XX_NR_IRQS (IRQ_BOARD_START + 40) + /* virtual addresses for statically mapped regions */ #define CMX2XX_VIRT_BASE (0xe8000000) #define CMX2XX_IT8152_VIRT (CMX2XX_VIRT_BASE) @@ -514,6 +517,7 @@ MACHINE_START(ARMCORE, "Compulab CM-X2XX") .phys_io = 0x40000000, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = cmx2xx_map_io, + .nr_irqs = CMX2XX_NR_IRQS, .init_irq = cmx2xx_init_irq, .timer = &pxa_timer, .init_machine = cmx2xx_init, diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index c70e6c2f4e7c..8e0b5622b277 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -19,6 +19,7 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/platform_device.h> +#include <linux/clk.h> #include <linux/gpio.h> #include <linux/dm9000.h> @@ -50,6 +51,7 @@ #include <plat/i2c.h> #include <plat/pxa3xx_nand.h> #include <mach/audio.h> +#include <mach/pxa3xx-u2d.h> #include <asm/mach/map.h> @@ -68,6 +70,8 @@ #define GPIO97_RTC_RD (97) #define GPIO98_RTC_IO (98) +#define GPIO_ULPI_PHY_RST (127) + static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = { /* LCD */ GPIO54_LCD_LDD_0, @@ -472,6 +476,78 @@ static void __init cm_x300_init_mmc(void) static inline void cm_x300_init_mmc(void) {} #endif +#if defined(CONFIG_PXA310_ULPI) +static struct clk *pout_clk; + +static int cm_x300_ulpi_phy_reset(void) +{ + int err; + + /* reset the PHY */ + err = gpio_request(GPIO_ULPI_PHY_RST, "ulpi reset"); + if (err) { + pr_err("%s: failed to request ULPI reset GPIO: %d\n", + __func__, err); + return err; + } + + gpio_direction_output(GPIO_ULPI_PHY_RST, 0); + msleep(10); + gpio_set_value(GPIO_ULPI_PHY_RST, 1); + msleep(10); + + gpio_free(GPIO_ULPI_PHY_RST); + + return 0; +} + +static inline int cm_x300_u2d_init(struct device *dev) +{ + int err = 0; + + if (cpu_is_pxa310()) { + /* CLK_POUT is connected to the ULPI PHY */ + pout_clk = clk_get(NULL, "CLK_POUT"); + if (IS_ERR(pout_clk)) { + err = PTR_ERR(pout_clk); + pr_err("%s: failed to get CLK_POUT: %d\n", + __func__, err); + return err; + } + clk_enable(pout_clk); + + err = cm_x300_ulpi_phy_reset(); + if (err) { + clk_disable(pout_clk); + clk_put(pout_clk); + } + } + + return err; +} + +static void cm_x300_u2d_exit(struct device *dev) +{ + if (cpu_is_pxa310()) { + clk_disable(pout_clk); + clk_put(pout_clk); + } +} + +static struct pxa3xx_u2d_platform_data cm_x300_u2d_platform_data = { + .ulpi_mode = ULPI_SER_6PIN, + .init = cm_x300_u2d_init, + .exit = cm_x300_u2d_exit, +}; + +static void cm_x300_init_u2d(void) +{ + pxa3xx_set_u2d_info(&cm_x300_u2d_platform_data); +} +#else +static inline void cm_x300_init_u2d(void) {} +#endif + #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) static int cm_x300_ohci_init(struct device *dev) { @@ -754,6 +830,7 @@ static void __init cm_x300_init(void) cm_x300_init_da9030(); cm_x300_init_dm9000(); cm_x300_init_lcd(); + cm_x300_init_u2d(); cm_x300_init_ohci(); cm_x300_init_mmc(); cm_x300_init_nand(); diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c index 0a0d0fe99220..88fbec05ec50 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c @@ -159,7 +159,7 @@ static int pxa3xx_cpufreq_verify(struct cpufreq_policy *policy) static unsigned int pxa3xx_cpufreq_get(unsigned int cpu) { - return get_clk_frequency_khz(0); + return pxa3xx_get_clk_frequency_khz(0); } static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, @@ -212,7 +212,8 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) policy->cpuinfo.min_freq = 104000; policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000; policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ - policy->cur = policy->min = policy->max = get_clk_frequency_khz(0); + policy->max = pxa3xx_get_clk_frequency_khz(0); + policy->cur = policy->min = policy->max; if (cpu_is_pxa300() || cpu_is_pxa310()) ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs)); diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 65447dc736c2..08b410343870 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -6,11 +6,12 @@ #include <asm/pmu.h> #include <mach/udc.h> +#include <mach/pxa3xx-u2d.h> #include <mach/pxafb.h> #include <mach/mmc.h> #include <mach/irda.h> #include <mach/ohci.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/pxa2xx_spi.h> #include <mach/camera.h> #include <mach/audio.h> @@ -134,6 +135,33 @@ struct platform_device pxa27x_device_udc = { } }; +#ifdef CONFIG_PXA3xx +static struct resource pxa3xx_u2d_resources[] = { + [0] = { + .start = 0x54100000, + .end = 0x54100fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_USB2, + .end = IRQ_USB2, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device pxa3xx_device_u2d = { + .name = "pxa3xx-u2d", + .id = -1, + .resource = pxa3xx_u2d_resources, + .num_resources = ARRAY_SIZE(pxa3xx_u2d_resources), +}; + +void __init pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info) +{ + pxa_register_device(&pxa3xx_device_u2d, info); +} +#endif /* CONFIG_PXA3xx */ + static struct resource pxafb_resources[] = { [0] = { .start = 0x44000000, diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index 50353ea49ba4..715e8bd02e24 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -4,6 +4,7 @@ extern struct platform_device pxa3xx_device_mci2; extern struct platform_device pxa3xx_device_mci3; extern struct platform_device pxa25x_device_udc; extern struct platform_device pxa27x_device_udc; +extern struct platform_device pxa3xx_device_u2d; extern struct platform_device pxa_device_fb; extern struct platform_device pxa_device_ffuart; extern struct platform_device pxa_device_btuart; diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 0517c17978f3..51286a738a3b 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -43,7 +43,7 @@ #include <mach/pxafb.h> #include <mach/ohci.h> #include <mach/mmc.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <plat/i2c.h> #include <mach/camera.h> #include <mach/pxa2xx_spi.h> diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index 349212a1cbd3..4971ce119501 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -29,6 +29,7 @@ #include <mach/pxa25x.h> #include <mach/eseries-gpio.h> +#include <mach/eseries-irq.h> #include <mach/audio.h> #include <mach/pxafb.h> #include <mach/udc.h> @@ -183,6 +184,7 @@ MACHINE_START(E330, "Toshiba e330") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, .fixup = eseries_fixup, .init_machine = e330_init, @@ -233,6 +235,7 @@ MACHINE_START(E350, "Toshiba e350") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, .fixup = eseries_fixup, .init_machine = e350_init, @@ -356,6 +359,7 @@ MACHINE_START(E400, "Toshiba e400") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, .fixup = eseries_fixup, .init_machine = e400_init, @@ -545,6 +549,7 @@ MACHINE_START(E740, "Toshiba e740") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, .fixup = eseries_fixup, .init_machine = e740_init, @@ -737,6 +742,7 @@ MACHINE_START(E750, "Toshiba e750") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, .fixup = eseries_fixup, .init_machine = e750_init, @@ -933,6 +939,7 @@ MACHINE_START(E800, "Toshiba e800") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = ESERIES_NR_IRQS, .init_irq = pxa25x_init_irq, .fixup = eseries_fixup, .init_machine = e800_init, diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index 626c82b13970..f997e8455557 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -32,12 +32,14 @@ #include <mach/ohci.h> #include <plat/i2c.h> #include <mach/hardware.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/camera.h> #include "devices.h" #include "generic.h" +#define EZX_NR_IRQS (IRQ_BOARD_START + 24) + #define GPIO12_A780_FLIP_LID 12 #define GPIO15_A1200_FLIP_LID 15 #define GPIO15_A910_FLIP_LID 15 @@ -800,6 +802,7 @@ MACHINE_START(EZX_A780, "Motorola EZX A780") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = a780_init, @@ -866,6 +869,7 @@ MACHINE_START(EZX_E680, "Motorola EZX E680") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = e680_init, @@ -932,6 +936,7 @@ MACHINE_START(EZX_A1200, "Motorola EZX A1200") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = a1200_init, @@ -1124,6 +1129,7 @@ MACHINE_START(EZX_A910, "Motorola EZX A910") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = a910_init, @@ -1190,6 +1196,7 @@ MACHINE_START(EZX_E6, "Motorola EZX E6") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = e6_init, @@ -1230,6 +1237,7 @@ MACHINE_START(EZX_E2, "Motorola EZX E2") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = EZX_NR_IRQS, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = e2_init, diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index baabb3ce088e..6451e9c3a93f 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -66,8 +66,7 @@ unsigned int get_clk_frequency_khz(int info) return pxa25x_get_clk_frequency_khz(info); else if (cpu_is_pxa27x()) return pxa27x_get_clk_frequency_khz(info); - else - return pxa3xx_get_clk_frequency_khz(info); + return 0; } EXPORT_SYMBOL(get_clk_frequency_khz); @@ -80,8 +79,7 @@ unsigned int get_memclk_frequency_10khz(void) return pxa25x_get_memclk_frequency_10khz(); else if (cpu_is_pxa27x()) return pxa27x_get_memclk_frequency_10khz(); - else - return pxa3xx_get_memclk_frequency_10khz(); + return 0; } EXPORT_SYMBOL(get_memclk_frequency_10khz); diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index c6305c5b8a72..4b1ad2769ed7 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -54,11 +54,9 @@ static inline void pxa2xx_clear_reset_status(unsigned int mask) {} #ifdef CONFIG_PXA3xx extern unsigned pxa3xx_get_clk_frequency_khz(int); -extern unsigned pxa3xx_get_memclk_frequency_10khz(void); extern void pxa3xx_clear_reset_status(unsigned int); #else #define pxa3xx_get_clk_frequency_khz(x) (0) -#define pxa3xx_get_memclk_frequency_10khz() (0) static inline void pxa3xx_clear_reset_status(unsigned int mask) {} #endif diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 848c861dd23f..10104f16e6e4 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -874,6 +874,7 @@ MACHINE_START(H4700, "HP iPAQ HX4700") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = HX4700_NR_IRQS, .init_irq = pxa27x_init_irq, .init_machine = hx4700_init, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h index eec92e6fd7cf..561562b4360b 100644 --- a/arch/arm/mach-pxa/include/mach/balloon3.h +++ b/arch/arm/mach-pxa/include/mach/balloon3.h @@ -174,6 +174,8 @@ enum balloon3_features { #define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ) #define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD) +#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 4) + extern int balloon3_has(enum balloon3_features feature); #endif diff --git a/arch/arm/mach-pxa/include/mach/eseries-irq.h b/arch/arm/mach-pxa/include/mach/eseries-irq.h index f2a93d5e31d3..de292b269c63 100644 --- a/arch/arm/mach-pxa/include/mach/eseries-irq.h +++ b/arch/arm/mach-pxa/include/mach/eseries-irq.h @@ -25,3 +25,4 @@ #define TMIO_SD_IRQ IRQ_TMIO(1) #define TMIO_USB_IRQ IRQ_TMIO(2) +#define ESERIES_NR_IRQS (IRQ_BOARD_START + 16) diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h b/arch/arm/mach-pxa/include/mach/hx4700.h index 9eaeed1f87f1..37408449ec25 100644 --- a/arch/arm/mach-pxa/include/mach/hx4700.h +++ b/arch/arm/mach-pxa/include/mach/hx4700.h @@ -17,6 +17,7 @@ #define HX4700_ASIC3_GPIO_BASE NR_BUILTIN_GPIO #define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS) +#define HX4700_NR_IRQS (IRQ_BOARD_START + 70) /* * PXA GPIOs diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index ffc8314520f2..d372caa75dc7 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -117,48 +117,12 @@ /* * The following interrupts are for board specific purposes. Since * the kernel can only run on one machine at a time, we can re-use - * these. There will be 16 IRQs by default. If it is not enough, - * IRQ_BOARD_END is allowed be customized for each board, but keep - * the numbers within sensible limits and in descending order, so - * when multiple config options are selected, the maximum will be - * used. + * these. + * By default, no board IRQ is reserved. It should be finished in + * custom board since sparse IRQ is already enabled. */ #define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM) -#if defined(CONFIG_MACH_H4700) -#define IRQ_BOARD_END (IRQ_BOARD_START + 70) -#elif defined(CONFIG_MACH_ZYLONITE) -#define IRQ_BOARD_END (IRQ_BOARD_START + 32) -#elif defined(CONFIG_PXA_EZX) -#define IRQ_BOARD_END (IRQ_BOARD_START + 23) -#else -#define IRQ_BOARD_END (IRQ_BOARD_START + 16) -#endif - -/* - * Figure out the MAX IRQ number. - * - * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1. - * If we have an LoCoMo, the max IRQ is IRQ_LOCOMO_SPI_TEND+1 - * Otherwise, we have the standard IRQs only. - */ -#ifdef CONFIG_SA1111 -#define NR_IRQS (IRQ_BOARD_END + 55) -#elif defined(CONFIG_PXA_HAVE_BOARD_IRQS) -#define NR_IRQS (IRQ_BOARD_END) -#else #define NR_IRQS (IRQ_BOARD_START) -#endif - -/* add IT8152 IRQs beyond BOARD_END */ -#ifdef CONFIG_PCI_HOST_ITE8152 -#define IT8152_LAST_IRQ (IRQ_BOARD_END + 40) - -#if NR_IRQS < (IT8152_LAST_IRQ+1) -#undef NR_IRQS -#define NR_IRQS (IT8152_LAST_IRQ+1) -#endif - -#endif /* CONFIG_PCI_HOST_ITE8152 */ #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h index 6c9b21c51322..2a5726c15e0e 100644 --- a/arch/arm/mach-pxa/include/mach/littleton.h +++ b/arch/arm/mach-pxa/include/mach/littleton.h @@ -10,4 +10,6 @@ #define EXT0_GPIO_BASE (NR_BUILTIN_GPIO) #define EXT0_GPIO(x) (EXT0_GPIO_BASE + (x)) +#define LITTLETON_NR_IRQS (IRQ_BOARD_START + 8) + #endif /* __ASM_ARCH_LITTLETON_H */ diff --git a/arch/arm/mach-pxa/include/mach/lpd270.h b/arch/arm/mach-pxa/include/mach/lpd270.h index 0e6440c81683..cd070092b6eb 100644 --- a/arch/arm/mach-pxa/include/mach/lpd270.h +++ b/arch/arm/mach-pxa/include/mach/lpd270.h @@ -38,5 +38,6 @@ #define LPD270_USBC_IRQ LPD270_IRQ(2) #define LPD270_ETHERNET_IRQ LPD270_IRQ(3) #define LPD270_AC97_IRQ LPD270_IRQ(4) +#define LPD270_NR_IRQS (IRQ_BOARD_START + 5) #endif diff --git a/arch/arm/mach-pxa/include/mach/lubbock.h b/arch/arm/mach-pxa/include/mach/lubbock.h index a0d4247f08fc..2a086e8373eb 100644 --- a/arch/arm/mach-pxa/include/mach/lubbock.h +++ b/arch/arm/mach-pxa/include/mach/lubbock.h @@ -45,6 +45,9 @@ #define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */ #define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6) +#define LUBBOCK_SA1111_IRQ_BASE (IRQ_BOARD_START + 16) +#define LUBBOCK_NR_IRQS (IRQ_BOARD_START + 16 + 55) + #ifndef __ASSEMBLY__ extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set); #endif diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h index 20ef37d4a9a7..0a2efcf7947c 100644 --- a/arch/arm/mach-pxa/include/mach/magician.h +++ b/arch/arm/mach-pxa/include/mach/magician.h @@ -71,6 +71,8 @@ #define IRQ_MAGICIAN_BT (IRQ_BOARD_START + 2) #define IRQ_MAGICIAN_VBUS (IRQ_BOARD_START + 3) +#define MAGICIAN_NR_IRQS (IRQ_BOARD_START + 8) + /* * CPLD EGPIOs */ diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h index 86e623abd64d..4c2d11cd824d 100644 --- a/arch/arm/mach-pxa/include/mach/mainstone.h +++ b/arch/arm/mach-pxa/include/mach/mainstone.h @@ -134,4 +134,6 @@ #define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14) #define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15) +#define MAINSTONE_NR_IRQS (IRQ_BOARD_START + 16) + #endif diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h index 0d119d3b9221..04f7c97044f3 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h @@ -69,6 +69,7 @@ #define nBE0_GPIO_60 MFP_CFG(nBE0, AF0) #define nBE1_GPIO_61 MFP_CFG(nBE1, AF0) #define RDY_GPIO_62 MFP_CFG(RDY, AF0) +#define PMIC_INT_GPIO83 MFP_CFG_LPM(PMIC_INT, AF0, PULL_HIGH) /* Chip Select */ #define DF_nCS0_nCS2 MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH) @@ -92,6 +93,9 @@ #define GPIO63_CI2C_SCL MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH) #define GPIO64_CI2C_SDA MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH) +#define GPIO73_CI2C_SCL MFP_CFG_LPM(GPIO73, AF1, PULL_HIGH) +#define GPIO74_CI2C_SDA MFP_CFG_LPM(GPIO74, AF1, PULL_HIGH) + #define GPIO77_CI2C_SCL MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH) #define GPIO78_CI2C_SDA MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH) @@ -345,6 +349,9 @@ #define GPIO69_UART1_CTS MFP_CFG(GPIO69, AF2) #define GPIO70_UART1_RTS MFP_CFG(GPIO70, AF2) +#define GPIO53_UART1_TXD MFP_CFG(GPIO53, AF2) +#define GPIO54_UART1_RXD MFP_CFG(GPIO54, AF2) + /* UART2 - BTUART */ #define GPIO91_UART2_RXD MFP_CFG(GPIO91, AF1) #define GPIO92_UART2_TXD MFP_CFG(GPIO92, AF1) diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h index 04083263167e..4bac588478a8 100644 --- a/arch/arm/mach-pxa/include/mach/pcm027.h +++ b/arch/arm/mach-pxa/include/mach/pcm027.h @@ -30,6 +30,8 @@ #define PCM027_MMCDET_IRQ PCM027_IRQ(2) #define PCM027_PM_5V_IRQ PCM027_IRQ(3) +#define PCM027_NR_IRQS (IRQ_BOARD_START + 32) + /* I2C RTC */ #define PCM027_RTC_IRQ_GPIO 0 #define PCM027_RTC_IRQ IRQ_GPIO(PCM027_RTC_IRQ_GPIO) diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h index 0b3e6d051c64..83d1cfd00fc9 100644 --- a/arch/arm/mach-pxa/include/mach/poodle.h +++ b/arch/arm/mach-pxa/include/mach/poodle.h @@ -85,6 +85,8 @@ #define POODLE_LOCOMO_GPIO_232VCC_ON LOCOMO_GPIO(12) #define POODLE_LOCOMO_GPIO_JK_B LOCOMO_GPIO(13) +#define POODLE_NR_IRQS (IRQ_BOARD_START + 4) /* 4 for LoCoMo */ + extern struct platform_device poodle_locomo_device; #endif /* __ASM_ARCH_POODLE_H */ diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h new file mode 100644 index 000000000000..9d82cb65ea56 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h @@ -0,0 +1,35 @@ +/* + * PXA3xx U2D header + * + * Copyright (C) 2010 CompuLab Ltd. + * + * Igor Grinberg <grinberg@compulab.co.il> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __PXA310_U2D__ +#define __PXA310_U2D__ + +#include <linux/usb/ulpi.h> + +struct pxa3xx_u2d_platform_data { + +#define ULPI_SER_6PIN (1 << 0) +#define ULPI_SER_3PIN (1 << 1) + unsigned int ulpi_mode; + + int (*init)(struct device *); + void (*exit)(struct device *); +}; + + +/* Start PXA3xx U2D host */ +int pxa3xx_u2d_start_hc(struct usb_bus *host); +/* Stop PXA3xx U2D host */ +void pxa3xx_u2d_stop_hc(struct usb_bus *host); + +extern void pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info); + +#endif /* __PXA310_U2D__ */ diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h index 1bbd1f2e4beb..1272c4b56ceb 100644 --- a/arch/arm/mach-pxa/include/mach/tosa.h +++ b/arch/arm/mach-pxa/include/mach/tosa.h @@ -20,6 +20,7 @@ /* Jacket Scoop */ #define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000) +#define TOSA_NR_IRQS (IRQ_BOARD_START + TC6393XB_NR_IRQS) /* * SCOOP2 internal GPIOs */ diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/include/mach/zeus.h index 6e119976003e..faa408ab7ad7 100644 --- a/arch/arm/mach-pxa/include/mach/zeus.h +++ b/arch/arm/mach-pxa/include/mach/zeus.h @@ -15,6 +15,8 @@ #ifndef _MACH_ZEUS_H #define _MACH_ZEUS_H +#define ZEUS_NR_IRQS (IRQ_BOARD_START + 48) + /* Physical addresses */ #define ZEUS_FLASH_PHYS PXA_CS0_PHYS #define ZEUS_ETH0_PHYS PXA_CS1_PHYS diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h index 9edf645368d6..ea24998b923c 100644 --- a/arch/arm/mach-pxa/include/mach/zylonite.h +++ b/arch/arm/mach-pxa/include/mach/zylonite.h @@ -5,6 +5,8 @@ #define EXT_GPIO(x) (128 + (x)) +#define ZYLONITE_NR_IRQS (IRQ_BOARD_START + 32) + /* the following variables are processor specific and initialized * by the corresponding zylonite_pxa3xx_init() */ diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 9b9046185b00..eb5850624c1d 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -43,7 +43,7 @@ #include <mach/pxafb.h> #include <mach/mmc.h> #include <mach/pxa2xx_spi.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/littleton.h> #include <plat/i2c.h> #include <plat/pxa3xx_nand.h> @@ -441,6 +441,7 @@ MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleto .boot_params = 0xa0000100, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = pxa_map_io, + .nr_irqs = LITTLETON_NR_IRQS, .init_irq = pxa3xx_init_irq, .timer = &pxa_timer, .init_machine = littleton_init, diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index d279507fc748..fc9502ef4024 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -509,6 +509,7 @@ MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = lpd270_map_io, + .nr_irqs = LPD270_NR_IRQS, .init_irq = lpd270_init_irq, .timer = &pxa_timer, .init_machine = lpd270_init, diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 330c3282856e..1956c23093d1 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -229,7 +229,7 @@ static struct resource sa1111_resources[] = { }; static struct sa1111_platform_data sa1111_info = { - .irq_base = IRQ_BOARD_END, + .irq_base = LUBBOCK_SA1111_IRQ_BASE, }; static struct platform_device sa1111_device = { @@ -560,6 +560,7 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") .phys_io = 0x40000000, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = lubbock_map_io, + .nr_irqs = LUBBOCK_NR_IRQS, .init_irq = lubbock_init_irq, .timer = &pxa_timer, .init_machine = lubbock_init, diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index e81dd0c8e40d..42a0c2b41281 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -768,6 +768,7 @@ MACHINE_START(MAGICIAN, "HTC Magician") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, .map_io = pxa_map_io, + .nr_irqs = MAGICIAN_NR_IRQS, .init_irq = pxa27x_init_irq, .init_machine = magician_init, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 5543c64da9ef..8b710024601c 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -50,7 +50,7 @@ #include <mach/mmc.h> #include <mach/irda.h> #include <mach/ohci.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include "generic.h" #include "devices.h" @@ -628,6 +628,7 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") .boot_params = 0xa0000100, /* BLOB boot parameter setting */ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = mainstone_map_io, + .nr_irqs = MAINSTONE_NR_IRQS, .init_irq = mainstone_init_irq, .timer = &pxa_timer, .init_machine = mainstone_init, diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index dc66942ef9ab..ffb3f5a8a086 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -45,7 +45,7 @@ #include <mach/pxa27x.h> #include <mach/regs-rtc.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/pxafb.h> #include <mach/mmc.h> #include <mach/udc.h> diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 91038eeafe44..3ff0c4a1ca4c 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -39,7 +39,7 @@ #include <mach/mmc.h> #include <mach/pxafb.h> #include <mach/irda.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/palmasoc.h> #include <mach/palm27x.h> diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 1c281995f658..5b9f766d1468 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -39,7 +39,7 @@ #include <mach/mmc.h> #include <mach/pxafb.h> #include <mach/irda.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/udc.h> #include <mach/palmasoc.h> #include <mach/palm27x.h> diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index 52defd5e42e5..f685a600a181 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -39,7 +39,7 @@ #include <mach/mmc.h> #include <mach/pxafb.h> #include <mach/irda.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/udc.h> #include <mach/ohci.h> #include <mach/pxa2xx-regs.h> diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 144dc2b6911f..89a37922b9d3 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -43,7 +43,7 @@ #include <mach/mmc.h> #include <mach/pxafb.h> #include <mach/irda.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/udc.h> #include <mach/palmasoc.h> #include <mach/palm27x.h> diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index 87e4b1044e0b..38f4425bfc95 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -41,7 +41,7 @@ #include <mach/mmc.h> #include <mach/pxafb.h> #include <mach/irda.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/udc.h> #include <mach/palmasoc.h> #include <mach/palm27x.h> diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index 2190af066470..90b08ba8ad1a 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c @@ -262,6 +262,7 @@ MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270") .phys_io = 0x40000000, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = pcm027_map_io, + .nr_irqs = PCM027_NR_IRQS, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = pcm027_init, diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 55e8fcde0141..c04e025cd790 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -469,6 +469,7 @@ MACHINE_START(POODLE, "SHARP Poodle") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_poodle, .map_io = pxa_map_io, + .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */ .init_irq = pxa25x_init_irq, .timer = &pxa_timer, .init_machine = poodle_init, diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c new file mode 100644 index 000000000000..ce7168b233e2 --- /dev/null +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c @@ -0,0 +1,400 @@ +/* + * linux/arch/arm/mach-pxa/pxa3xx-ulpi.c + * + * code specific to pxa3xx aka Monahans + * + * Copyright (C) 2010 CompuLab Ltd. + * + * 2010-13-07: Igor Grinberg <grinberg@compulab.co.il> + * initial version: pxa310 USB Host mode support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/usb.h> +#include <linux/usb/otg.h> + +#include <mach/hardware.h> +#include <mach/regs-u2d.h> +#include <mach/pxa3xx-u2d.h> + +struct pxa3xx_u2d_ulpi { + struct clk *clk; + void __iomem *mmio_base; + + struct otg_transceiver *otg; + unsigned int ulpi_mode; +}; + +static struct pxa3xx_u2d_ulpi *u2d; + +static inline u32 u2d_readl(u32 reg) +{ + return __raw_readl(u2d->mmio_base + reg); +} + +static inline void u2d_writel(u32 reg, u32 val) +{ + __raw_writel(val, u2d->mmio_base + reg); +} + +#if defined(CONFIG_PXA310_ULPI) +enum u2d_ulpi_phy_mode { + SYNCH = 0, + CARKIT = (1 << 0), + SER_3PIN = (1 << 1), + SER_6PIN = (1 << 2), + LOWPOWER = (1 << 3), +}; + +static inline enum u2d_ulpi_phy_mode pxa310_ulpi_get_phymode(void) +{ + return (u2d_readl(U2DOTGUSR) >> 28) & 0xF; +} + +static int pxa310_ulpi_poll(void) +{ + int timeout = 50000; + + while (timeout--) { + if (!(u2d_readl(U2DOTGUCR) & U2DOTGUCR_RUN)) + return 0; + + cpu_relax(); + } + + pr_warning("%s: ULPI access timed out!\n", __func__); + + return -ETIMEDOUT; +} + +static int pxa310_ulpi_read(struct otg_transceiver *otg, u32 reg) +{ + int err; + + if (pxa310_ulpi_get_phymode() != SYNCH) { + pr_warning("%s: PHY is not in SYNCH mode!\n", __func__); + return -EBUSY; + } + + u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | U2DOTGUCR_RNW | (reg << 16)); + msleep(5); + + err = pxa310_ulpi_poll(); + if (err) + return err; + + return u2d_readl(U2DOTGUCR) & U2DOTGUCR_RDATA; +} + +static int pxa310_ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg) +{ + if (pxa310_ulpi_get_phymode() != SYNCH) { + pr_warning("%s: PHY is not in SYNCH mode!\n", __func__); + return -EBUSY; + } + + u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | (reg << 16) | (val << 8)); + msleep(5); + + return pxa310_ulpi_poll(); +} + +struct otg_io_access_ops pxa310_ulpi_access_ops = { + .read = pxa310_ulpi_read, + .write = pxa310_ulpi_write, +}; + +static void pxa310_otg_transceiver_rtsm(void) +{ + u32 u2dotgcr; + + /* put PHY to sync mode */ + u2dotgcr = u2d_readl(U2DOTGCR); + u2dotgcr |= U2DOTGCR_RTSM | U2DOTGCR_UTMID; + u2d_writel(U2DOTGCR, u2dotgcr); + msleep(10); + + /* setup OTG sync mode */ + u2dotgcr = u2d_readl(U2DOTGCR); + u2dotgcr |= U2DOTGCR_ULAF; + u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF); + u2d_writel(U2DOTGCR, u2dotgcr); +} + +static int pxa310_start_otg_host_transcvr(struct usb_bus *host) +{ + int err; + + pxa310_otg_transceiver_rtsm(); + + err = otg_init(u2d->otg); + if (err) { + pr_err("OTG transceiver init failed"); + return err; + } + + err = otg_set_vbus(u2d->otg, 1); + if (err) { + pr_err("OTG transceiver VBUS set failed"); + return err; + } + + err = otg_set_host(u2d->otg, host); + if (err) + pr_err("OTG transceiver Host mode set failed"); + + return err; +} + +static int pxa310_start_otg_hc(struct usb_bus *host) +{ + u32 u2dotgcr; + int err; + + /* disable USB device controller */ + u2d_writel(U2DCR, u2d_readl(U2DCR) & ~U2DCR_UDE); + u2d_writel(U2DOTGCR, u2d_readl(U2DOTGCR) | U2DOTGCR_UTMID); + u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F); + + err = pxa310_start_otg_host_transcvr(host); + if (err) + return err; + + /* set xceiver mode */ + if (u2d->ulpi_mode & ULPI_IC_6PIN_SERIAL) + u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) & ~U2DP3CR_P2SS); + else if (u2d->ulpi_mode & ULPI_IC_3PIN_SERIAL) + u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) | U2DP3CR_P2SS); + + /* start OTG host controller */ + u2dotgcr = u2d_readl(U2DOTGCR) | U2DOTGCR_SMAF; + u2d_writel(U2DOTGCR, u2dotgcr & ~(U2DOTGCR_ULAF | U2DOTGCR_CKAF)); + + return 0; +} + +static void pxa310_stop_otg_hc(void) +{ + pxa310_otg_transceiver_rtsm(); + + otg_set_host(u2d->otg, NULL); + otg_set_vbus(u2d->otg, 0); + otg_shutdown(u2d->otg); +} + +static void pxa310_u2d_setup_otg_hc(void) +{ + u32 u2dotgcr; + + u2dotgcr = u2d_readl(U2DOTGCR); + u2dotgcr |= U2DOTGCR_ULAF | U2DOTGCR_UTMID; + u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF); + u2d_writel(U2DOTGCR, u2dotgcr); + msleep(5); + u2d_writel(U2DOTGCR, u2dotgcr | U2DOTGCR_ULE); + msleep(5); + u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F); +} + +static int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata) +{ + unsigned int ulpi_mode = ULPI_OTG_DRVVBUS; + + if (pdata) { + if (pdata->ulpi_mode & ULPI_SER_6PIN) + ulpi_mode |= ULPI_IC_6PIN_SERIAL; + else if (pdata->ulpi_mode & ULPI_SER_3PIN) + ulpi_mode |= ULPI_IC_3PIN_SERIAL; + } + + u2d->ulpi_mode = ulpi_mode; + + u2d->otg = otg_ulpi_create(&pxa310_ulpi_access_ops, ulpi_mode); + if (!u2d->otg) + return -ENOMEM; + + u2d->otg->io_priv = u2d->mmio_base; + + return 0; +} + +static void pxa310_otg_exit(void) +{ + kfree(u2d->otg); +} +#else +static inline void pxa310_u2d_setup_otg_hc(void) {} +static inline int pxa310_start_otg_hc(struct usb_bus *host) +{ + return 0; +} +static inline void pxa310_stop_otg_hc(void) {} +static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata) +{ + return 0; +} +static inline void pxa310_otg_exit(void) {} +#endif /* CONFIG_PXA310_ULPI */ + +int pxa3xx_u2d_start_hc(struct usb_bus *host) +{ + int err = 0; + + /* In case the PXA3xx ULPI isn't used, do nothing. */ + if (!u2d) + return 0; + + clk_enable(u2d->clk); + + if (cpu_is_pxa310()) { + pxa310_u2d_setup_otg_hc(); + err = pxa310_start_otg_hc(host); + } + + return err; +} + +void pxa3xx_u2d_stop_hc(struct usb_bus *host) +{ + /* In case the PXA3xx ULPI isn't used, do nothing. */ + if (!u2d) + return; + + if (cpu_is_pxa310()) + pxa310_stop_otg_hc(); + + clk_disable(u2d->clk); +} + +static int pxa3xx_u2d_probe(struct platform_device *pdev) +{ + struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data; + struct resource *r; + int err; + + u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL); + if (!u2d) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + u2d->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(u2d->clk)) { + dev_err(&pdev->dev, "failed to get u2d clock\n"); + err = PTR_ERR(u2d->clk); + goto err_free_mem; + } + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "no IO memory resource defined\n"); + err = -ENODEV; + goto err_put_clk; + } + + r = request_mem_region(r->start, resource_size(r), pdev->name); + if (!r) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + err = -EBUSY; + goto err_put_clk; + } + + u2d->mmio_base = ioremap(r->start, resource_size(r)); + if (!u2d->mmio_base) { + dev_err(&pdev->dev, "ioremap() failed\n"); + err = -ENODEV; + goto err_free_res; + } + + if (pdata->init) { + err = pdata->init(&pdev->dev); + if (err) + goto err_free_io; + } + + /* Only PXA310 U2D has OTG functionality */ + if (cpu_is_pxa310()) { + err = pxa310_otg_init(pdata); + if (err) + goto err_free_plat; + } + + platform_set_drvdata(pdev, &u2d); + + return 0; + +err_free_plat: + if (pdata->exit) + pdata->exit(&pdev->dev); +err_free_io: + iounmap(u2d->mmio_base); +err_free_res: + release_mem_region(r->start, resource_size(r)); +err_put_clk: + clk_put(u2d->clk); +err_free_mem: + kfree(u2d); + return err; +} + +static int pxa3xx_u2d_remove(struct platform_device *pdev) +{ + struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data; + struct resource *r; + + if (cpu_is_pxa310()) { + pxa310_stop_otg_hc(); + pxa310_otg_exit(); + } + + if (pdata->exit) + pdata->exit(&pdev->dev); + + platform_set_drvdata(pdev, NULL); + iounmap(u2d->mmio_base); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(r->start, resource_size(r)); + + clk_put(u2d->clk); + + kfree(u2d); + + return 0; +} + +static struct platform_driver pxa3xx_u2d_ulpi_driver = { + .driver = { + .name = "pxa3xx-u2d", + .owner = THIS_MODULE, + }, + .probe = pxa3xx_u2d_probe, + .remove = pxa3xx_u2d_remove, +}; + +static int pxa3xx_u2d_ulpi_init(void) +{ + return platform_driver_register(&pxa3xx_u2d_ulpi_driver); +} +module_init(pxa3xx_u2d_ulpi_init); + +static void __exit pxa3xx_u2d_ulpi_exit(void) +{ + platform_driver_unregister(&pxa3xx_u2d_ulpi_driver); +} +module_exit(pxa3xx_u2d_ulpi_exit); + +MODULE_DESCRIPTION("PXA3xx U2D ULPI driver"); +MODULE_AUTHOR("Igor Grinberg"); +MODULE_LICENSE("GPL v2"); diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index fa0014847c71..c85c3a7abd31 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -98,23 +98,6 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info) return CLK / 1000; } -/* - * Return the current static memory controller clock frequency - * in units of 10kHz - */ -unsigned int pxa3xx_get_memclk_frequency_10khz(void) -{ - unsigned long acsr; - unsigned int smcfs, clk = 0; - - acsr = ACSR; - - smcfs = (acsr >> 23) & 0x7; - clk = (acsr & ACCR_D0CS) ? RO_CLK : smcfs_mult[smcfs] * BASE_CLK; - - return (clk / 10000); -} - void pxa3xx_clear_reset_status(unsigned int mask) { /* RESET_STATUS_* has a 1:1 mapping with ARSR */ @@ -265,7 +248,7 @@ static struct clk_lookup pxa3xx_clkregs[] = { INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL), INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL), INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL), - INIT_CLKREG(&clk_pxa3xx_u2d, NULL, "U2DCLK"), + INIT_CLKREG(&clk_pxa3xx_u2d, "pxa3xx-u2d", NULL), INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL), INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa27x-ssp.0", NULL), INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa27x-ssp.1", NULL), diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c index 064292008288..7d29dd3af79d 100644 --- a/arch/arm/mach-pxa/pxa930.c +++ b/arch/arm/mach-pxa/pxa930.c @@ -192,7 +192,7 @@ static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = { static int __init pxa930_init(void) { - if (cpu_is_pxa930() || cpu_is_pxa935()) { + if (cpu_is_pxa930() || cpu_is_pxa935() || cpu_is_pxa950()) { mfp_init_base(io_p2v(MFPR_BASE)); mfp_init_addr(pxa930_mfp_addr_map); } diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index a654d1e6b38a..62de07341cc6 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -56,6 +56,8 @@ #include "devices.h" #include "generic.h" +#define STARGATE_NR_IRQS (IRQ_BOARD_START + 8) + /* Bluetooth */ #define SG2_BT_RESET 81 @@ -1011,6 +1013,7 @@ MACHINE_START(STARGATE2, "Stargate 2") .phys_io = 0x40000000, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = pxa_map_io, + .nr_irqs = STARGATE_NR_IRQS, .init_irq = pxa27x_init_irq, .timer = &pxa_timer, .init_machine = stargate2_init, diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index f02dcb5b4e97..0f440c9d7cbd 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -25,7 +25,7 @@ #include <mach/pxa930.h> #include <mach/pxafb.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include "devices.h" #include "generic.h" diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c new file mode 100644 index 000000000000..5eeba64515e4 --- /dev/null +++ b/arch/arm/mach-pxa/tavorevb3.c @@ -0,0 +1,136 @@ +/* + * linux/arch/arm/mach-pxa/tavorevb3.c + * + * Support for the Marvell EVB3 Development Platform. + * + * Copyright: (C) Copyright 2008-2010 Marvell International Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/mfd/88pm860x.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#include <mach/pxa930.h> + +#include <plat/i2c.h> + +#include "devices.h" +#include "generic.h" + +#define TAVOREVB3_NR_IRQS (IRQ_BOARD_START + 24) + +static mfp_cfg_t evb3_mfp_cfg[] __initdata = { + /* UART */ + GPIO53_UART1_TXD, + GPIO54_UART1_RXD, + + /* PMIC */ + PMIC_INT_GPIO83, +}; + +#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) +static struct pm860x_touch_pdata evb3_touch = { + .gpadc_prebias = 1, + .slot_cycle = 1, + .tsi_prebias = 6, + .pen_prebias = 16, + .pen_prechg = 2, + .res_x = 300, +}; + +static struct pm860x_backlight_pdata evb3_backlight[] = { + { + .id = PM8606_ID_BACKLIGHT, + .iset = PM8606_WLED_CURRENT(24), + .flags = PM8606_BACKLIGHT1, + }, + {}, +}; + +static struct pm860x_led_pdata evb3_led[] = { + { + .id = PM8606_ID_LED, + .iset = PM8606_LED_CURRENT(12), + .flags = PM8606_LED1_RED, + }, { + .id = PM8606_ID_LED, + .iset = PM8606_LED_CURRENT(12), + .flags = PM8606_LED1_GREEN, + }, { + .id = PM8606_ID_LED, + .iset = PM8606_LED_CURRENT(12), + .flags = PM8606_LED1_BLUE, + }, { + .id = PM8606_ID_LED, + .iset = PM8606_LED_CURRENT(12), + .flags = PM8606_LED2_RED, + }, { + .id = PM8606_ID_LED, + .iset = PM8606_LED_CURRENT(12), + .flags = PM8606_LED2_GREEN, + }, { + .id = PM8606_ID_LED, + .iset = PM8606_LED_CURRENT(12), + .flags = PM8606_LED2_BLUE, + }, +}; + +static struct pm860x_platform_data evb3_pm8607_info = { + .touch = &evb3_touch, + .backlight = &evb3_backlight[0], + .led = &evb3_led[0], + .companion_addr = 0x10, + .irq_mode = 0, + .irq_base = IRQ_BOARD_START, + + .i2c_port = GI2C_PORT, +}; + +static struct i2c_board_info evb3_i2c_info[] = { + { + .type = "88PM860x", + .addr = 0x34, + .platform_data = &evb3_pm8607_info, + .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), + }, +}; + +static void __init evb3_init_i2c(void) +{ + pxa_set_i2c_info(NULL); + i2c_register_board_info(0, ARRAY_AND_SIZE(evb3_i2c_info)); +} +#else +static inline void evb3_init_i2c(void) {} +#endif + +static void __init evb3_init(void) +{ + /* initialize MFP configurations */ + pxa3xx_mfp_config(ARRAY_AND_SIZE(evb3_mfp_cfg)); + + pxa_set_ffuart_info(NULL); + + evb3_init_i2c(); +} + +MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)") + .phys_io = 0x40000000, + .boot_params = 0xa0000100, + .map_io = pxa_map_io, + .nr_irqs = TAVOREVB3_NR_IRQS, + .init_irq = pxa3xx_init_irq, + .timer = &pxa_timer, + .init_machine = evb3_init, +MACHINE_END diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 83cc3a18c2e9..3a06e98b4920 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -956,6 +956,7 @@ MACHINE_START(TOSA, "SHARP Tosa") .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_tosa, .map_io = pxa_map_io, + .nr_irqs = TOSA_NR_IRQS, .init_irq = pxa25x_init_irq, .init_machine = tosa_init, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index f0d02288b4ca..8c44bc4381ba 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -37,7 +37,7 @@ #include <mach/z2.h> #include <mach/pxafb.h> #include <mach/mmc.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <mach/pxa2xx_spi.h> #include <plat/i2c.h> diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 03b9cb910e08..9da2b624ba20 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -904,6 +904,7 @@ MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS") .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc), .boot_params = 0xa0000100, .map_io = zeus_map_io, + .nr_irqs = ZEUS_NR_IRQS, .init_irq = zeus_init_irq, .timer = &pxa_timer, .init_machine = zeus_init, diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index c479cbecf784..69df3edcdd98 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -30,7 +30,7 @@ #include <mach/zylonite.h> #include <mach/mmc.h> #include <mach/ohci.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> #include <plat/pxa3xx_nand.h> #include "devices.h" @@ -415,6 +415,7 @@ MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") .boot_params = 0xa0000100, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = pxa_map_io, + .nr_irqs = ZYLONITE_NR_IRQS, .init_irq = pxa3xx_init_irq, .timer = &pxa_timer, .init_machine = zylonite_init, diff --git a/arch/arm/mach-rpc/include/mach/vmalloc.h b/arch/arm/mach-rpc/include/mach/vmalloc.h index 9a96fd69e705..3bcd86fadb81 100644 --- a/arch/arm/mach-rpc/include/mach/vmalloc.h +++ b/arch/arm/mach-rpc/include/mach/vmalloc.h @@ -7,4 +7,4 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define VMALLOC_END (PAGE_OFFSET + 0x1c000000) +#define VMALLOC_END 0xdc000000 diff --git a/arch/arm/mach-s5p6440/Kconfig b/arch/arm/mach-s5p6440/Kconfig deleted file mode 100644 index 6a4af7f57584..000000000000 --- a/arch/arm/mach-s5p6440/Kconfig +++ /dev/null @@ -1,33 +0,0 @@ -# arch/arm/mach-s5p6440/Kconfig -# -# Copyright (c) 2009 Samsung Electronics Co., Ltd. -# http://www.samsung.com/ -# -# Licensed under GPLv2 - -if ARCH_S5P6440 - -config CPU_S5P6440 - bool - select S3C_PL330_DMA - help - Enable S5P6440 CPU support - -config S5P6440_SETUP_I2C1 - bool - help - Common setup code for i2c bus 1. - -config MACH_SMDK6440 - bool "SMDK6440" - select CPU_S5P6440 - select S3C_DEV_I2C1 - select S3C_DEV_RTC - select S3C_DEV_WDT - select SAMSUNG_DEV_ADC - select SAMSUNG_DEV_TS - select S5P6440_SETUP_I2C1 - help - Machine support for the Samsung SMDK6440 - -endif diff --git a/arch/arm/mach-s5p6440/Makefile b/arch/arm/mach-s5p6440/Makefile deleted file mode 100644 index c3fe4d3662a9..000000000000 --- a/arch/arm/mach-s5p6440/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# arch/arm/mach-s5p6440/Makefile -# -# Copyright (c) 2009 Samsung Electronics Co., Ltd. -# http://www.samsung.com/ -# -# Licensed under GPLv2 - -obj-y := -obj-m := -obj-n := -obj- := - -# Core support for S5P6440 system - -obj-$(CONFIG_CPU_S5P6440) += cpu.o init.o clock.o gpio.o dma.o -obj-$(CONFIG_CPU_S5P6440) += setup-i2c0.o - -# machine support - -obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o - -# device support -obj-y += dev-audio.o -obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o -obj-$(CONFIG_S5P6440_SETUP_I2C1) += setup-i2c1.o diff --git a/arch/arm/mach-s5p6440/clock.c b/arch/arm/mach-s5p6440/clock.c deleted file mode 100644 index ca6e48dce777..000000000000 --- a/arch/arm/mach-s5p6440/clock.c +++ /dev/null @@ -1,846 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/clock.c - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Clock support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/errno.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/sysdev.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <mach/map.h> - -#include <plat/cpu-freq.h> -#include <mach/regs-clock.h> -#include <plat/clock.h> -#include <plat/cpu.h> -#include <plat/clock-clksrc.h> -#include <plat/s5p-clock.h> -#include <plat/pll.h> -#include <plat/s5p6440.h> - -/* APLL Mux output clock */ -static struct clksrc_clk clk_mout_apll = { - .clk = { - .name = "mout_apll", - .id = -1, - }, - .sources = &clk_src_apll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 }, -}; - -static int s5p6440_epll_enable(struct clk *clk, int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; - - if (enable) - __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); - else - __raw_writel(epll_con, S5P_EPLL_CON); - - return 0; -} - -static unsigned long s5p6440_epll_get_rate(struct clk *clk) -{ - return clk->rate; -} - -static u32 epll_div[][5] = { - { 36000000, 0, 48, 1, 4 }, - { 48000000, 0, 32, 1, 3 }, - { 60000000, 0, 40, 1, 3 }, - { 72000000, 0, 48, 1, 3 }, - { 84000000, 0, 28, 1, 2 }, - { 96000000, 0, 32, 1, 2 }, - { 32768000, 45264, 43, 1, 4 }, - { 45158000, 6903, 30, 1, 3 }, - { 49152000, 50332, 32, 1, 3 }, - { 67738000, 10398, 45, 1, 3 }, - { 73728000, 9961, 49, 1, 3 } -}; - -static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned int epll_con, epll_con_k; - unsigned int i; - - if (clk->rate == rate) /* Return if nothing changed */ - return 0; - - epll_con = __raw_readl(S5P_EPLL_CON); - epll_con_k = __raw_readl(S5P_EPLL_CON_K); - - epll_con_k &= ~(PLL90XX_KDIV_MASK); - epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK); - - for (i = 0; i < ARRAY_SIZE(epll_div); i++) { - if (epll_div[i][0] == rate) { - epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT); - epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) | - (epll_div[i][3] << PLL90XX_PDIV_SHIFT) | - (epll_div[i][4] << PLL90XX_SDIV_SHIFT); - break; - } - } - - if (i == ARRAY_SIZE(epll_div)) { - printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); - return -EINVAL; - } - - __raw_writel(epll_con, S5P_EPLL_CON); - __raw_writel(epll_con_k, S5P_EPLL_CON_K); - - clk->rate = rate; - - return 0; -} - -static struct clk_ops s5p6440_epll_ops = { - .get_rate = s5p6440_epll_get_rate, - .set_rate = s5p6440_epll_set_rate, -}; - -static struct clksrc_clk clk_mout_epll = { - .clk = { - .name = "mout_epll", - .id = -1, - }, - .sources = &clk_src_epll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 2, .size = 1 }, -}; - -static struct clksrc_clk clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - .id = -1, - }, - .sources = &clk_src_mpll, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 }, -}; - -enum perf_level { - L0 = 532*1000, - L1 = 266*1000, - L2 = 133*1000, -}; - -static const u32 clock_table[][3] = { - /*{ARM_CLK, DIVarm, DIVhclk}*/ - {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P_CLKDIV0_HCLK_SHIFT)}, - {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P_CLKDIV0_HCLK_SHIFT)}, - {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P_CLKDIV0_HCLK_SHIFT)}, -}; - -static unsigned long s5p6440_armclk_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - u32 clkdiv; - - /* divisor mask starts at bit0, so no need to shift */ - clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK; - - return rate / (clkdiv + 1); -} - -static unsigned long s5p6440_armclk_round_rate(struct clk *clk, - unsigned long rate) -{ - u32 iter; - - for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) { - if (rate > clock_table[iter][0]) - return clock_table[iter-1][0]; - } - - return clock_table[ARRAY_SIZE(clock_table) - 1][0]; -} - -static int s5p6440_armclk_set_rate(struct clk *clk, unsigned long rate) -{ - u32 round_tmp; - u32 iter; - u32 clk_div0_tmp; - u32 cur_rate = clk->ops->get_rate(clk); - unsigned long flags; - - round_tmp = clk->ops->round_rate(clk, rate); - if (round_tmp == cur_rate) - return 0; - - - for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) { - if (round_tmp == clock_table[iter][0]) - break; - } - - if (iter >= ARRAY_SIZE(clock_table)) - iter = ARRAY_SIZE(clock_table) - 1; - - local_irq_save(flags); - if (cur_rate > round_tmp) { - /* Frequency Down */ - clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); - clk_div0_tmp |= clock_table[iter][1]; - __raw_writel(clk_div0_tmp, ARM_CLK_DIV); - - clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & - ~(S5P_CLKDIV0_HCLK_MASK); - clk_div0_tmp |= clock_table[iter][2]; - __raw_writel(clk_div0_tmp, ARM_CLK_DIV); - - - } else { - /* Frequency Up */ - clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & - ~(S5P_CLKDIV0_HCLK_MASK); - clk_div0_tmp |= clock_table[iter][2]; - __raw_writel(clk_div0_tmp, ARM_CLK_DIV); - - clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); - clk_div0_tmp |= clock_table[iter][1]; - __raw_writel(clk_div0_tmp, ARM_CLK_DIV); - } - local_irq_restore(flags); - - clk->rate = clock_table[iter][0]; - - return 0; -} - -static struct clk_ops s5p6440_clkarm_ops = { - .get_rate = s5p6440_armclk_get_rate, - .set_rate = s5p6440_armclk_set_rate, - .round_rate = s5p6440_armclk_round_rate, -}; - -static struct clksrc_clk clk_armclk = { - .clk = { - .name = "armclk", - .id = 1, - .parent = &clk_mout_apll.clk, - .ops = &s5p6440_clkarm_ops, - }, - .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 4 }, -}; - -static struct clksrc_clk clk_dout_mpll = { - .clk = { - .name = "dout_mpll", - .id = -1, - .parent = &clk_mout_mpll.clk, - }, - .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 1 }, -}; - -static struct clksrc_clk clk_hclk = { - .clk = { - .name = "clk_hclk", - .id = -1, - .parent = &clk_armclk.clk, - }, - .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 4 }, -}; - -static struct clksrc_clk clk_pclk = { - .clk = { - .name = "clk_pclk", - .id = -1, - .parent = &clk_hclk.clk, - }, - .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 4 }, -}; - -static struct clk *clkset_hclklow_list[] = { - &clk_mout_apll.clk, - &clk_mout_mpll.clk, -}; - -static struct clksrc_sources clkset_hclklow = { - .sources = clkset_hclklow_list, - .nr_sources = ARRAY_SIZE(clkset_hclklow_list), -}; - -static struct clksrc_clk clk_hclk_low = { - .clk = { - .name = "hclk_low", - .id = -1, - }, - .sources = &clkset_hclklow, - .reg_src = { .reg = S5P_SYS_OTHERS, .shift = 6, .size = 1 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 }, -}; - -static struct clksrc_clk clk_pclk_low = { - .clk = { - .name = "pclk_low", - .id = -1, - .parent = &clk_hclk_low.clk, - }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 }, -}; - -int s5p6440_clk48m_ctrl(struct clk *clk, int enable) -{ - unsigned long flags; - u32 val; - - /* can't rely on clock lock, this register has other usages */ - local_irq_save(flags); - - val = __raw_readl(S5P_OTHERS); - if (enable) - val |= S5P_OTHERS_USB_SIG_MASK; - else - val &= ~S5P_OTHERS_USB_SIG_MASK; - - __raw_writel(val, S5P_OTHERS); - - local_irq_restore(flags); - - return 0; -} - -static int s5p6440_pclk_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_PCLK, clk, enable); -} - -static int s5p6440_hclk0_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_HCLK0, clk, enable); -} - -static int s5p6440_hclk1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_HCLK1, clk, enable); -} - -static int s5p6440_sclk_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_SCLK0, clk, enable); -} - -static int s5p6440_sclk1_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_SCLK1, clk, enable); -} - -static int s5p6440_mem_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLK_GATE_MEM0, clk, enable); -} - -/* - * The following clocks will be disabled during clock initialization. It is - * recommended to keep the following clocks disabled until the driver requests - * for enabling the clock. - */ -static struct clk init_clocks_disable[] = { - { - .name = "nand", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_mem_ctrl, - .ctrlbit = S5P_CLKCON_MEM0_HCLK_NFCON, - }, { - .name = "adc", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_TSADC, - }, { - .name = "i2c", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_IIC0, - }, { - .name = "i2s_v40", - .id = 0, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_IIS2, - }, { - .name = "spi", - .id = 0, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_SPI0, - }, { - .name = "spi", - .id = 1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_SPI1, - }, { - .name = "sclk_spi_48", - .id = 0, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_SPI0_48, - }, { - .name = "sclk_spi_48", - .id = 1, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_SPI1_48, - }, { - .name = "mmc_48m", - .id = 0, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_MMC0_48, - }, { - .name = "mmc_48m", - .id = 1, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_MMC1_48, - }, { - .name = "mmc_48m", - .id = 2, - .parent = &clk_48m, - .enable = s5p6440_sclk_ctrl, - .ctrlbit = S5P_CLKCON_SCLK0_MMC2_48, - }, { - .name = "otg", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_USB - }, { - .name = "post", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_POST0 - }, { - .name = "lcd", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk1_ctrl, - .ctrlbit = S5P_CLKCON_HCLK1_DISPCON, - }, { - .name = "hsmmc", - .id = 0, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_HSMMC0, - }, { - .name = "hsmmc", - .id = 1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_HSMMC1, - }, { - .name = "hsmmc", - .id = 2, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = S5P_CLKCON_HCLK0_HSMMC2, - }, { - .name = "rtc", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_RTC, - }, { - .name = "watchdog", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_WDT, - }, { - .name = "timers", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_PWM, - }, { - .name = "hclk_fimgvg", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk1_ctrl, - .ctrlbit = (1 << 2), - }, { - .name = "tsi", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk1_ctrl, - .ctrlbit = (1 << 0), - }, { - .name = "pclk_fimgvg", - .id = -1, - .parent = &clk_pclk.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 31), - }, { - .name = "dmc0", - .id = -1, - .parent = &clk_pclk.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 30), - }, { - .name = "etm", - .id = -1, - .parent = &clk_pclk.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 29), - }, { - .name = "dsim", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 28), - }, { - .name = "gps", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 25), - }, { - .name = "pcm", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = (1 << 8), - }, { - .name = "irom", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 25), - }, { - .name = "dma", - .id = -1, - .parent = &clk_hclk_low.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 12), - }, { - .name = "2d", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 8), - }, -}; - -/* - * The following clocks will be enabled during clock initialization. - */ -static struct clk init_clocks[] = { - { - .name = "gpio", - .id = -1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_GPIO, - }, { - .name = "uart", - .id = 0, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_UART0, - }, { - .name = "uart", - .id = 1, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_UART1, - }, { - .name = "uart", - .id = 2, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_UART2, - }, { - .name = "uart", - .id = 3, - .parent = &clk_pclk_low.clk, - .enable = s5p6440_pclk_ctrl, - .ctrlbit = S5P_CLKCON_PCLK_UART3, - }, { - .name = "mem", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 21), - }, { - .name = "intc", - .id = -1, - .parent = &clk_hclk.clk, - .enable = s5p6440_hclk0_ctrl, - .ctrlbit = (1 << 1), - }, -}; - -static struct clk clk_iis_cd_v40 = { - .name = "iis_cdclk_v40", - .id = -1, -}; - -static struct clk clk_pcm_cd = { - .name = "pcm_cdclk", - .id = -1, -}; - -static struct clk *clkset_group1_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll.clk, - &clk_fin_epll, -}; - -static struct clksrc_sources clkset_group1 = { - .sources = clkset_group1_list, - .nr_sources = ARRAY_SIZE(clkset_group1_list), -}; - -static struct clk *clkset_uart_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll.clk, -}; - -static struct clksrc_sources clkset_uart = { - .sources = clkset_uart_list, - .nr_sources = ARRAY_SIZE(clkset_uart_list), -}; - -static struct clk *clkset_audio_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll.clk, - &clk_fin_epll, - &clk_iis_cd_v40, - &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio = { - .sources = clkset_audio_list, - .nr_sources = ARRAY_SIZE(clkset_audio_list), -}; - -static struct clksrc_clk clksrcs[] = { - { - .clk = { - .name = "mmc_bus", - .id = 0, - .ctrlbit = S5P_CLKCON_SCLK0_MMC0, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "mmc_bus", - .id = 1, - .ctrlbit = S5P_CLKCON_SCLK0_MMC1, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "mmc_bus", - .id = 2, - .ctrlbit = S5P_CLKCON_SCLK0_MMC2, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 }, - }, { - .clk = { - .name = "uclk1", - .id = -1, - .ctrlbit = S5P_CLKCON_SCLK0_UART, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_uart, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 13, .size = 1 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 }, - }, { - .clk = { - .name = "spi_epll", - .id = 0, - .ctrlbit = S5P_CLKCON_SCLK0_SPI0, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "spi_epll", - .id = 1, - .ctrlbit = S5P_CLKCON_SCLK0_SPI1, - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_post", - .id = -1, - .ctrlbit = (1 << 10), - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC0, .shift = 26, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 }, - }, { - .clk = { - .name = "sclk_dispcon", - .id = -1, - .ctrlbit = (1 << 1), - .enable = s5p6440_sclk1_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 }, - }, { - .clk = { - .name = "sclk_fimgvg", - .id = -1, - .ctrlbit = (1 << 2), - .enable = s5p6440_sclk1_ctrl, - }, - .sources = &clkset_group1, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 }, - .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 }, - }, { - .clk = { - .name = "sclk_audio2", - .id = -1, - .ctrlbit = (1 << 11), - .enable = s5p6440_sclk_ctrl, - }, - .sources = &clkset_audio, - .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 3 }, - .reg_div = { .reg = S5P_CLK_DIV2, .shift = 24, .size = 4 }, - }, -}; - -/* Clock initialisation code */ -static struct clksrc_clk *sysclks[] = { - &clk_mout_apll, - &clk_mout_epll, - &clk_mout_mpll, - &clk_dout_mpll, - &clk_armclk, - &clk_hclk, - &clk_pclk, - &clk_hclk_low, - &clk_pclk_low, -}; - -void __init_or_cpufreq s5p6440_setup_clocks(void) -{ - struct clk *xtal_clk; - unsigned long xtal; - unsigned long fclk; - unsigned long hclk; - unsigned long hclk_low; - unsigned long pclk; - unsigned long pclk_low; - unsigned long epll; - unsigned long apll; - unsigned long mpll; - unsigned int ptr; - - /* Set S5P6440 functions for clk_fout_epll */ - clk_fout_epll.enable = s5p6440_epll_enable; - clk_fout_epll.ops = &s5p6440_epll_ops; - - clk_48m.enable = s5p6440_clk48m_ctrl; - - xtal_clk = clk_get(NULL, "ext_xtal"); - BUG_ON(IS_ERR(xtal_clk)); - - xtal = clk_get_rate(xtal_clk); - clk_put(xtal_clk); - - epll = s5p_get_pll90xx(xtal, __raw_readl(S5P_EPLL_CON), - __raw_readl(S5P_EPLL_CON_K)); - mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); - apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4502); - - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_fout_apll.rate = apll; - - printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ - " E=%ld.%ldMHz\n", - print_mhz(apll), print_mhz(mpll), print_mhz(epll)); - - fclk = clk_get_rate(&clk_armclk.clk); - hclk = clk_get_rate(&clk_hclk.clk); - pclk = clk_get_rate(&clk_pclk.clk); - hclk_low = clk_get_rate(&clk_hclk_low.clk); - pclk_low = clk_get_rate(&clk_pclk_low.clk); - - printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ - " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", - print_mhz(hclk), print_mhz(hclk_low), - print_mhz(pclk), print_mhz(pclk_low)); - - clk_f.rate = fclk; - clk_h.rate = hclk; - clk_p.rate = pclk; - - for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) - s3c_set_clksrc(&clksrcs[ptr], true); -} - -static struct clk *clks[] __initdata = { - &clk_ext, - &clk_iis_cd_v40, - &clk_pcm_cd, -}; - -void __init s5p6440_register_clocks(void) -{ - struct clk *clkp; - int ret; - int ptr; - - ret = s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - if (ret > 0) - printk(KERN_ERR "Failed to register %u clocks\n", ret); - - for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) - s3c_register_clksrc(sysclks[ptr], 1); - - s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); - s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - - clkp = init_clocks_disable; - for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { - - ret = s3c24xx_register_clock(clkp); - if (ret < 0) { - printk(KERN_ERR "Failed to register clock %s (%d)\n", - clkp->name, ret); - } - (clkp->enable)(clkp, 0); - } - - s3c_pwmclk_init(); -} diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c deleted file mode 100644 index 526f33adb31d..000000000000 --- a/arch/arm/mach-s5p6440/cpu.c +++ /dev/null @@ -1,116 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/cpu.c - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/list.h> -#include <linux/timer.h> -#include <linux/init.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/sysdev.h> -#include <linux/serial_core.h> -#include <linux/platform_device.h> - -#include <asm/mach/arch.h> -#include <asm/mach/map.h> -#include <asm/mach/irq.h> - -#include <asm/proc-fns.h> - -#include <mach/hardware.h> -#include <mach/map.h> -#include <asm/irq.h> - -#include <plat/regs-serial.h> -#include <mach/regs-clock.h> - -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/clock.h> -#include <plat/s5p6440.h> -#include <plat/adc-core.h> - -static void s5p6440_idle(void) -{ - unsigned long val; - - if (!need_resched()) { - val = __raw_readl(S5P_PWR_CFG); - val &= ~(0x3<<5); - val |= (0x1<<5); - __raw_writel(val, S5P_PWR_CFG); - - cpu_do_idle(); - } - local_irq_enable(); -} - -/* s5p6440_map_io - * - * register the standard cpu IO areas -*/ - -void __init s5p6440_map_io(void) -{ - /* initialize any device information early */ - s3c_adc_setname("s3c64xx-adc"); -} - -void __init s5p6440_init_clocks(int xtal) -{ - printk(KERN_DEBUG "%s: initializing clocks\n", __func__); - - s3c24xx_register_baseclocks(xtal); - s5p_register_clocks(xtal); - s5p6440_register_clocks(); - s5p6440_setup_clocks(); -} - -void __init s5p6440_init_irq(void) -{ - /* S5P6440 supports only 2 VIC */ - u32 vic[2]; - - /* - * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)] - * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22] - */ - vic[0] = 0xff800ae7; - vic[1] = 0xffbf23e5; - - s5p_init_irq(vic, ARRAY_SIZE(vic)); -} - -struct sysdev_class s5p6440_sysclass = { - .name = "s5p6440-core", -}; - -static struct sys_device s5p6440_sysdev = { - .cls = &s5p6440_sysclass, -}; - -static int __init s5p6440_core_init(void) -{ - return sysdev_class_register(&s5p6440_sysclass); -} - -core_initcall(s5p6440_core_init); - -int __init s5p6440_init(void) -{ - printk(KERN_INFO "S5P6440: Initializing architecture\n"); - - /* set idle function */ - pm_idle = s5p6440_idle; - - return sysdev_register(&s5p6440_sysdev); -} diff --git a/arch/arm/mach-s5p6440/dev-audio.c b/arch/arm/mach-s5p6440/dev-audio.c deleted file mode 100644 index 3ca0d2b8275d..000000000000 --- a/arch/arm/mach-s5p6440/dev-audio.c +++ /dev/null @@ -1,127 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/dev-audio.c - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Jaswinder Singh <jassi.brar@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/platform_device.h> -#include <linux/dma-mapping.h> -#include <linux/gpio.h> - -#include <plat/gpio-cfg.h> -#include <plat/audio.h> - -#include <mach/map.h> -#include <mach/dma.h> -#include <mach/irqs.h> - -static int s5p6440_cfg_i2s(struct platform_device *pdev) -{ - /* configure GPIO for i2s port */ - switch (pdev->id) { - case -1: - s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5)); - break; - - default: - printk(KERN_ERR "Invalid Device %d\n", pdev->id); - return -EINVAL; - } - - return 0; -} - -static struct s3c_audio_pdata s3c_i2s_pdata = { - .cfg_gpio = s5p6440_cfg_i2s, -}; - -static struct resource s5p6440_iis0_resource[] = { - [0] = { - .start = S5P6440_PA_I2S, - .end = S5P6440_PA_I2S + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_I2S0_TX, - .end = DMACH_I2S0_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_I2S0_RX, - .end = DMACH_I2S0_RX, - .flags = IORESOURCE_DMA, - }, -}; - -struct platform_device s5p6440_device_iis = { - .name = "s3c64xx-iis-v4", - .id = -1, - .num_resources = ARRAY_SIZE(s5p6440_iis0_resource), - .resource = s5p6440_iis0_resource, - .dev = { - .platform_data = &s3c_i2s_pdata, - }, -}; - -/* PCM Controller platform_devices */ - -static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev) -{ - switch (pdev->id) { - case 0: - s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2)); - break; - - default: - printk(KERN_DEBUG "Invalid PCM Controller number!"); - return -EINVAL; - } - - return 0; -} - -static struct s3c_audio_pdata s3c_pcm_pdata = { - .cfg_gpio = s5p6440_pcm_cfg_gpio, -}; - -static struct resource s5p6440_pcm0_resource[] = { - [0] = { - .start = S5P6440_PA_PCM, - .end = S5P6440_PA_PCM + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_PCM0_TX, - .end = DMACH_PCM0_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_PCM0_RX, - .end = DMACH_PCM0_RX, - .flags = IORESOURCE_DMA, - }, -}; - -struct platform_device s5p6440_device_pcm = { - .name = "samsung-pcm", - .id = 0, - .num_resources = ARRAY_SIZE(s5p6440_pcm0_resource), - .resource = s5p6440_pcm0_resource, - .dev = { - .platform_data = &s3c_pcm_pdata, - }, -}; diff --git a/arch/arm/mach-s5p6440/dev-spi.c b/arch/arm/mach-s5p6440/dev-spi.c deleted file mode 100644 index 510af44d180c..000000000000 --- a/arch/arm/mach-s5p6440/dev-spi.c +++ /dev/null @@ -1,176 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/dev-spi.c - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh <jassi.brar@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/platform_device.h> -#include <linux/dma-mapping.h> -#include <linux/gpio.h> - -#include <mach/dma.h> -#include <mach/map.h> -#include <mach/irqs.h> -#include <mach/spi-clocks.h> - -#include <plat/s3c64xx-spi.h> -#include <plat/gpio-cfg.h> - -static char *spi_src_clks[] = { - [S5P6440_SPI_SRCCLK_PCLK] = "pclk", - [S5P6440_SPI_SRCCLK_SCLK] = "spi_epll", -}; - -/* SPI Controller platform_devices */ - -/* Since we emulate multi-cs capability, we do not touch the CS. - * The emulated CS is toggled by board specific mechanism, as it can - * be either some immediate GPIO or some signal out of some other - * chip in between ... or some yet another way. - * We simply do not assume anything about CS. - */ -static int s5p6440_spi_cfg_gpio(struct platform_device *pdev) -{ - switch (pdev->id) { - case 0: - s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2)); - s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP); - s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP); - s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP); - break; - - case 1: - s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2)); - s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2)); - s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP); - s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP); - s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP); - break; - - default: - dev_err(&pdev->dev, "Invalid SPI Controller number!"); - return -EINVAL; - } - - return 0; -} - -static struct resource s5p6440_spi0_resource[] = { - [0] = { - .start = S5P6440_PA_SPI0, - .end = S5P6440_PA_SPI0 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI0_TX, - .end = DMACH_SPI0_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI0_RX, - .end = DMACH_SPI0_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI0, - .end = IRQ_SPI0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5p6440_spi0_pdata = { - .cfg_gpio = s5p6440_spi_cfg_gpio, - .fifo_lvl_mask = 0x1ff, - .rx_lvl_offset = 15, -}; - -static u64 spi_dmamask = DMA_BIT_MASK(32); - -struct platform_device s5p6440_device_spi0 = { - .name = "s3c64xx-spi", - .id = 0, - .num_resources = ARRAY_SIZE(s5p6440_spi0_resource), - .resource = s5p6440_spi0_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5p6440_spi0_pdata, - }, -}; - -static struct resource s5p6440_spi1_resource[] = { - [0] = { - .start = S5P6440_PA_SPI1, - .end = S5P6440_PA_SPI1 + 0x100 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = DMACH_SPI1_TX, - .end = DMACH_SPI1_TX, - .flags = IORESOURCE_DMA, - }, - [2] = { - .start = DMACH_SPI1_RX, - .end = DMACH_SPI1_RX, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = IRQ_SPI1, - .end = IRQ_SPI1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct s3c64xx_spi_info s5p6440_spi1_pdata = { - .cfg_gpio = s5p6440_spi_cfg_gpio, - .fifo_lvl_mask = 0x7f, - .rx_lvl_offset = 15, -}; - -struct platform_device s5p6440_device_spi1 = { - .name = "s3c64xx-spi", - .id = 1, - .num_resources = ARRAY_SIZE(s5p6440_spi1_resource), - .resource = s5p6440_spi1_resource, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5p6440_spi1_pdata, - }, -}; - -void __init s5p6440_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) -{ - struct s3c64xx_spi_info *pd; - - /* Reject invalid configuration */ - if (!num_cs || src_clk_nr < 0 - || src_clk_nr > S5P6440_SPI_SRCCLK_SCLK) { - printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__); - return; - } - - switch (cntrlr) { - case 0: - pd = &s5p6440_spi0_pdata; - break; - case 1: - pd = &s5p6440_spi1_pdata; - break; - default: - printk(KERN_ERR "%s: Invalid SPI controller(%d)\n", - __func__, cntrlr); - return; - } - - pd->num_cs = num_cs; - pd->src_clk_nr = src_clk_nr; - pd->src_clk_name = spi_src_clks[src_clk_nr]; -} diff --git a/arch/arm/mach-s5p6440/include/mach/debug-macro.S b/arch/arm/mach-s5p6440/include/mach/debug-macro.S deleted file mode 100644 index 1347d7f99079..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/debug-macro.S +++ /dev/null @@ -1,37 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/debug-macro.S - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -/* pull in the relevant register and map files. */ - -#include <mach/map.h> -#include <plat/regs-serial.h> - - /* note, for the boot process to work we have to keep the UART - * virtual address aligned to an 1MiB boundary for the L1 - * mapping the head code makes. We keep the UART virtual address - * aligned and add in the offset when we load the value here. - */ - - .macro addruart, rx, rtmp - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 - ldreq \rx, = S3C_PA_UART - ldrne \rx, = S3C_VA_UART -#if CONFIG_DEBUG_S3C_UART != 0 - add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART) -#endif - .endm - -/* include the reset of the code which will do the work, we're only - * compiling for a single cpu processor type so the default of s3c2440 - * will be fine with us. - */ - -#include <plat/debug-macro.S> diff --git a/arch/arm/mach-s5p6440/include/mach/gpio.h b/arch/arm/mach-s5p6440/include/mach/gpio.h deleted file mode 100644 index 21783834f2a2..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/gpio.h +++ /dev/null @@ -1,80 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/gpio.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - GPIO lib support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_GPIO_H -#define __ASM_ARCH_GPIO_H __FILE__ - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value -#define gpio_cansleep __gpio_cansleep -#define gpio_to_irq __gpio_to_irq - -/* GPIO bank sizes */ -#define S5P6440_GPIO_A_NR (6) -#define S5P6440_GPIO_B_NR (7) -#define S5P6440_GPIO_C_NR (8) -#define S5P6440_GPIO_F_NR (2) -#define S5P6440_GPIO_G_NR (7) -#define S5P6440_GPIO_H_NR (10) -#define S5P6440_GPIO_I_NR (16) -#define S5P6440_GPIO_J_NR (12) -#define S5P6440_GPIO_N_NR (16) -#define S5P6440_GPIO_P_NR (8) -#define S5P6440_GPIO_R_NR (15) - -/* GPIO bank numbers */ - -/* CONFIG_S3C_GPIO_SPACE allows the user to select extra - * space for debugging purposes so that any accidental - * change from one gpio bank to another can be caught. -*/ -#define S5P6440_GPIO_NEXT(__gpio) \ - ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) - -enum s5p_gpio_number { - S5P6440_GPIO_A_START = 0, - S5P6440_GPIO_B_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_A), - S5P6440_GPIO_C_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_B), - S5P6440_GPIO_F_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_C), - S5P6440_GPIO_G_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_F), - S5P6440_GPIO_H_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_G), - S5P6440_GPIO_I_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_H), - S5P6440_GPIO_J_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_I), - S5P6440_GPIO_N_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_J), - S5P6440_GPIO_P_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_N), - S5P6440_GPIO_R_START = S5P6440_GPIO_NEXT(S5P6440_GPIO_P), -}; - -/* S5P6440 GPIO number definitions. */ -#define S5P6440_GPA(_nr) (S5P6440_GPIO_A_START + (_nr)) -#define S5P6440_GPB(_nr) (S5P6440_GPIO_B_START + (_nr)) -#define S5P6440_GPC(_nr) (S5P6440_GPIO_C_START + (_nr)) -#define S5P6440_GPF(_nr) (S5P6440_GPIO_F_START + (_nr)) -#define S5P6440_GPG(_nr) (S5P6440_GPIO_G_START + (_nr)) -#define S5P6440_GPH(_nr) (S5P6440_GPIO_H_START + (_nr)) -#define S5P6440_GPI(_nr) (S5P6440_GPIO_I_START + (_nr)) -#define S5P6440_GPJ(_nr) (S5P6440_GPIO_J_START + (_nr)) -#define S5P6440_GPN(_nr) (S5P6440_GPIO_N_START + (_nr)) -#define S5P6440_GPP(_nr) (S5P6440_GPIO_P_START + (_nr)) -#define S5P6440_GPR(_nr) (S5P6440_GPIO_R_START + (_nr)) - -/* the end of the S5P6440 specific gpios */ -#define S5P6440_GPIO_END (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1) -#define S3C_GPIO_END S5P6440_GPIO_END - -/* define the number of gpios we need to the one after the GPR() range */ -#define ARCH_NR_GPIOS (S5P6440_GPR(S5P6440_GPIO_R_NR) + \ - CONFIG_SAMSUNG_GPIO_EXTRA + 1) - -#include <asm-generic/gpio.h> - -#endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/io.h b/arch/arm/mach-s5p6440/include/mach/io.h deleted file mode 100644 index fa2d69cb1ad7..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/io.h +++ /dev/null @@ -1,18 +0,0 @@ -/* arch/arm/mach-s5p6440/include/mach/io.h - * - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben-linux@fluff.org> - * - * Default IO routines for S3C64XX based - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* No current ISA/PCI bus support. */ -#define __io(a) __typesafe_io(a) -#define __mem_pci(a) (a) - -#define IO_SPACE_LIMIT (0xFFFFFFFF) - -#endif diff --git a/arch/arm/mach-s5p6440/include/mach/map.h b/arch/arm/mach-s5p6440/include/mach/map.h deleted file mode 100644 index 6cc5cbc88ffb..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/map.h +++ /dev/null @@ -1,86 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/map.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Memory map definitions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_MAP_H -#define __ASM_ARCH_MAP_H __FILE__ - -#include <plat/map-base.h> -#include <plat/map-s5p.h> - -#define S5P6440_PA_CHIPID (0xE0000000) -#define S5P_PA_CHIPID S5P6440_PA_CHIPID - -#define S5P6440_PA_SYSCON (0xE0100000) -#define S5P6440_PA_CLK (S5P6440_PA_SYSCON + 0x0) -#define S5P_PA_SYSCON S5P6440_PA_SYSCON - -#define S5P6440_PA_GPIO (0xE0308000) -#define S5P_PA_GPIO S5P6440_PA_GPIO - -#define S5P6440_PA_VIC0 (0xE4000000) -#define S5P_PA_VIC0 S5P6440_PA_VIC0 - -#define S5P6440_PA_PDMA 0xE9000000 - -#define S5P6440_PA_VIC1 (0xE4100000) -#define S5P_PA_VIC1 S5P6440_PA_VIC1 - -#define S5P6440_PA_TIMER (0xEA000000) -#define S5P_PA_TIMER S5P6440_PA_TIMER - -#define S5P6440_PA_RTC (0xEA100000) - -#define S5P6440_PA_WDT (0xEA200000) -#define S5P_PA_WDT S5P6440_PA_WDT - -#define S5P6440_PA_UART (0xEC000000) - -#define S5P_PA_UART0 (S5P6440_PA_UART + 0x0) -#define S5P_PA_UART1 (S5P6440_PA_UART + 0x400) -#define S5P_PA_UART2 (S5P6440_PA_UART + 0x800) -#define S5P_PA_UART3 (S5P6440_PA_UART + 0xC00) - -#define S5P_SZ_UART SZ_256 - -#define S5P6440_PA_IIC0 (0xEC104000) -#define S5P6440_PA_IIC1 (0xEC20F000) - -#define S5P6440_PA_SPI0 0xEC400000 -#define S5P6440_PA_SPI1 0xEC500000 - -#define S5P6440_PA_HSOTG (0xED100000) - -#define S5P6440_PA_HSMMC0 (0xED800000) -#define S5P6440_PA_HSMMC1 (0xED900000) -#define S5P6440_PA_HSMMC2 (0xEDA00000) - -#define S5P6440_PA_SDRAM (0x20000000) -#define S5P_PA_SDRAM S5P6440_PA_SDRAM - -/* I2S */ -#define S5P6440_PA_I2S 0xF2000000 - -/* PCM */ -#define S5P6440_PA_PCM 0xF2100000 - -#define S5P6440_PA_ADC (0xF3000000) - -/* compatibiltiy defines. */ -#define S3C_PA_UART S5P6440_PA_UART -#define S3C_PA_IIC S5P6440_PA_IIC0 -#define S3C_PA_RTC S5P6440_PA_RTC -#define S3C_PA_IIC1 S5P6440_PA_IIC1 -#define S3C_PA_WDT S5P6440_PA_WDT - -#define SAMSUNG_PA_ADC S5P6440_PA_ADC - -#endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/regs-clock.h b/arch/arm/mach-s5p6440/include/mach/regs-clock.h deleted file mode 100644 index c783ecc9f193..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/regs-clock.h +++ /dev/null @@ -1,130 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/regs-clock.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Clock register definitions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_REGS_CLOCK_H -#define __ASM_ARCH_REGS_CLOCK_H __FILE__ - -#include <mach/map.h> - -#define S5P_CLKREG(x) (S3C_VA_SYS + (x)) - -#define S5P_APLL_LOCK S5P_CLKREG(0x00) -#define S5P_MPLL_LOCK S5P_CLKREG(0x04) -#define S5P_EPLL_LOCK S5P_CLKREG(0x08) -#define S5P_APLL_CON S5P_CLKREG(0x0C) -#define S5P_MPLL_CON S5P_CLKREG(0x10) -#define S5P_EPLL_CON S5P_CLKREG(0x14) -#define S5P_EPLL_CON_K S5P_CLKREG(0x18) -#define S5P_CLK_SRC0 S5P_CLKREG(0x1C) -#define S5P_CLK_DIV0 S5P_CLKREG(0x20) -#define S5P_CLK_DIV1 S5P_CLKREG(0x24) -#define S5P_CLK_DIV2 S5P_CLKREG(0x28) -#define S5P_CLK_OUT S5P_CLKREG(0x2C) -#define S5P_CLK_GATE_HCLK0 S5P_CLKREG(0x30) -#define S5P_CLK_GATE_PCLK S5P_CLKREG(0x34) -#define S5P_CLK_GATE_SCLK0 S5P_CLKREG(0x38) -#define S5P_CLK_GATE_MEM0 S5P_CLKREG(0x3C) -#define S5P_CLK_DIV3 S5P_CLKREG(0x40) -#define S5P_CLK_GATE_HCLK1 S5P_CLKREG(0x44) -#define S5P_CLK_GATE_SCLK1 S5P_CLKREG(0x48) -#define S5P_AHB_CON0 S5P_CLKREG(0x100) -#define S5P_CLK_SRC1 S5P_CLKREG(0x10C) -#define S5P_SWRESET S5P_CLKREG(0x114) -#define S5P_SYS_ID S5P_CLKREG(0x118) -#define S5P_SYS_OTHERS S5P_CLKREG(0x11C) -#define S5P_MEM_CFG_STAT S5P_CLKREG(0x12C) -#define S5P_PWR_CFG S5P_CLKREG(0x804) -#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0x808) -#define S5P_NORMAL_CFG S5P_CLKREG(0x810) -#define S5P_STOP_CFG S5P_CLKREG(0x814) -#define S5P_SLEEP_CFG S5P_CLKREG(0x818) -#define S5P_OSC_FREQ S5P_CLKREG(0x820) -#define S5P_OSC_STABLE S5P_CLKREG(0x824) -#define S5P_PWR_STABLE S5P_CLKREG(0x828) -#define S5P_MTC_STABLE S5P_CLKREG(0x830) -#define S5P_OTHERS S5P_CLKREG(0x900) -#define S5P_RST_STAT S5P_CLKREG(0x904) -#define S5P_WAKEUP_STAT S5P_CLKREG(0x908) -#define S5P_SLPEN S5P_CLKREG(0x930) -#define S5P_INFORM0 S5P_CLKREG(0xA00) -#define S5P_INFORM1 S5P_CLKREG(0xA04) -#define S5P_INFORM2 S5P_CLKREG(0xA08) -#define S5P_INFORM3 S5P_CLKREG(0xA0C) - -/* CLKDIV0 */ -#define S5P_CLKDIV0_PCLK_MASK (0xf << 12) -#define S5P_CLKDIV0_PCLK_SHIFT (12) -#define S5P_CLKDIV0_HCLK_MASK (0xf << 8) -#define S5P_CLKDIV0_HCLK_SHIFT (8) -#define S5P_CLKDIV0_MPLL_MASK (0x1 << 4) -#define S5P_CLKDIV0_ARM_MASK (0xf << 0) -#define S5P_CLKDIV0_ARM_SHIFT (0) - -/* CLKDIV3 */ -#define S5P_CLKDIV3_PCLK_LOW_MASK (0xf << 12) -#define S5P_CLKDIV3_PCLK_LOW_SHIFT (12) -#define S5P_CLKDIV3_HCLK_LOW_MASK (0xf << 8) -#define S5P_CLKDIV3_HCLK_LOW_SHIFT (8) - -/* HCLK0 GATE Registers */ -#define S5P_CLKCON_HCLK0_USB (1<<20) -#define S5P_CLKCON_HCLK0_HSMMC2 (1<<19) -#define S5P_CLKCON_HCLK0_HSMMC1 (1<<18) -#define S5P_CLKCON_HCLK0_HSMMC0 (1<<17) -#define S5P_CLKCON_HCLK0_POST0 (1<<5) - -/* HCLK1 GATE Registers */ -#define S5P_CLKCON_HCLK1_DISPCON (1<<1) - -/* PCLK GATE Registers */ -#define S5P_CLKCON_PCLK_IIS2 (1<<26) -#define S5P_CLKCON_PCLK_SPI1 (1<<22) -#define S5P_CLKCON_PCLK_SPI0 (1<<21) -#define S5P_CLKCON_PCLK_GPIO (1<<18) -#define S5P_CLKCON_PCLK_IIC0 (1<<17) -#define S5P_CLKCON_PCLK_TSADC (1<<12) -#define S5P_CLKCON_PCLK_PWM (1<<7) -#define S5P_CLKCON_PCLK_RTC (1<<6) -#define S5P_CLKCON_PCLK_WDT (1<<5) -#define S5P_CLKCON_PCLK_UART3 (1<<4) -#define S5P_CLKCON_PCLK_UART2 (1<<3) -#define S5P_CLKCON_PCLK_UART1 (1<<2) -#define S5P_CLKCON_PCLK_UART0 (1<<1) - -/* SCLK0 GATE Registers */ -#define S5P_CLKCON_SCLK0_MMC2_48 (1<<29) -#define S5P_CLKCON_SCLK0_MMC1_48 (1<<28) -#define S5P_CLKCON_SCLK0_MMC0_48 (1<<27) -#define S5P_CLKCON_SCLK0_MMC2 (1<<26) -#define S5P_CLKCON_SCLK0_MMC1 (1<<25) -#define S5P_CLKCON_SCLK0_MMC0 (1<<24) -#define S5P_CLKCON_SCLK0_SPI1_48 (1<<23) -#define S5P_CLKCON_SCLK0_SPI0_48 (1<<22) -#define S5P_CLKCON_SCLK0_SPI1 (1<<21) -#define S5P_CLKCON_SCLK0_SPI0 (1<<20) -#define S5P_CLKCON_SCLK0_UART (1<<5) - -/* SCLK1 GATE Registers */ - -/* MEM0 GATE Registers */ -#define S5P_CLKCON_MEM0_HCLK_NFCON (1<<2) - -/*OTHERS Resgister */ -#define S5P_OTHERS_USB_SIG_MASK (1<<16) -#define S5P_OTHERS_HCLK_LOW_SEL_MPLL (1<<6) - -/* Compatibility defines */ -#define ARM_CLK_DIV S5P_CLK_DIV0 -#define ARM_DIV_RATIO_SHIFT 0 -#define ARM_DIV_MASK (0xf << ARM_DIV_RATIO_SHIFT) - -#endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/spi-clocks.h b/arch/arm/mach-s5p6440/include/mach/spi-clocks.h deleted file mode 100644 index 5fbca50d1cfb..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/spi-clocks.h +++ /dev/null @@ -1,17 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/spi-clocks.h - * - * Copyright (C) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh <jassi.brar@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __S5P6440_PLAT_SPI_CLKS_H -#define __S5P6440_PLAT_SPI_CLKS_H __FILE__ - -#define S5P6440_SPI_SRCCLK_PCLK 0 -#define S5P6440_SPI_SRCCLK_SCLK 1 - -#endif /* __S5P6440_PLAT_SPI_CLKS_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/uncompress.h b/arch/arm/mach-s5p6440/include/mach/uncompress.h deleted file mode 100644 index 7c1f600d65c0..000000000000 --- a/arch/arm/mach-s5p6440/include/mach/uncompress.h +++ /dev/null @@ -1,24 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/uncompress.h - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - uncompress code - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_UNCOMPRESS_H -#define __ASM_ARCH_UNCOMPRESS_H - -#include <mach/map.h> -#include <plat/uncompress.h> - -static void arch_detect_cpu(void) -{ - /* we do not need to do any cpu detection here at the moment. */ -} - -#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-s5p6440/init.c b/arch/arm/mach-s5p6440/init.c deleted file mode 100644 index a1f3727e4021..000000000000 --- a/arch/arm/mach-s5p6440/init.c +++ /dev/null @@ -1,52 +0,0 @@ -/* linux/arch/arm/mach-s5p6440/init.c - * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * S5P6440 - Init support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/serial_core.h> - -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/s5p6440.h> -#include <plat/regs-serial.h> - -static struct s3c24xx_uart_clksrc s5p6440_serial_clocks[] = { - [0] = { - .name = "pclk_low", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, - [1] = { - .name = "uclk1", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, -}; - -/* uart registration process */ -void __init s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) -{ - struct s3c2410_uartcfg *tcfg = cfg; - u32 ucnt; - - for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { - if (!tcfg->clocks) { - tcfg->clocks = s5p6440_serial_clocks; - tcfg->clocks_size = ARRAY_SIZE(s5p6440_serial_clocks); - } - } - - s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); -} diff --git a/arch/arm/mach-s5p6442/cpu.c b/arch/arm/mach-s5p6442/cpu.c index a48fb553fd01..842af86bda6d 100644 --- a/arch/arm/mach-s5p6442/cpu.c +++ b/arch/arm/mach-s5p6442/cpu.c @@ -1,7 +1,7 @@ /* linux/arch/arm/mach-s5p6442/cpu.c * * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * http://www.samsung.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -19,6 +19,7 @@ #include <linux/sysdev.h> #include <linux/serial_core.h> #include <linux/platform_device.h> +#include <linux/sched.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -47,10 +48,30 @@ static struct map_desc s5p6442_iodesc[] __initdata = { .length = SZ_16K, .type = MT_DEVICE, }, { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5P6442_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5P6442_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5P6442_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, { .virtual = (unsigned long)VA_VIC2, .pfn = __phys_to_pfn(S5P6442_PA_VIC2), .length = SZ_16K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, } }; @@ -62,10 +83,11 @@ static void s5p6442_idle(void) local_irq_enable(); } -/* s5p6442_map_io +/* + * s5p6442_map_io * * register the standard cpu IO areas -*/ + */ void __init s5p6442_map_io(void) { diff --git a/arch/arm/mach-s5p6442/include/mach/map.h b/arch/arm/mach-s5p6442/include/mach/map.h index 281d256faafb..31fb2e68d527 100644 --- a/arch/arm/mach-s5p6442/include/mach/map.h +++ b/arch/arm/mach-s5p6442/include/mach/map.h @@ -23,16 +23,10 @@ #define S5P_PA_SYSCON S5P6442_PA_SYSCON #define S5P6442_PA_GPIO (0xE0200000) -#define S5P_PA_GPIO S5P6442_PA_GPIO #define S5P6442_PA_VIC0 (0xE4000000) -#define S5P_PA_VIC0 S5P6442_PA_VIC0 - #define S5P6442_PA_VIC1 (0xE4100000) -#define S5P_PA_VIC1 S5P6442_PA_VIC1 - #define S5P6442_PA_VIC2 (0xE4200000) -#define S5P_PA_VIC2 S5P6442_PA_VIC2 #define S5P6442_PA_MDMA 0xE8000000 #define S5P6442_PA_PDMA 0xE9000000 diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig new file mode 100644 index 000000000000..fbcae9352022 --- /dev/null +++ b/arch/arm/mach-s5p64x0/Kconfig @@ -0,0 +1,57 @@ +# arch/arm/mach-s5p64x0/Kconfig +# +# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. +# http://www.samsung.com/ +# +# Licensed under GPLv2 + +if ARCH_S5P64X0 + +config CPU_S5P6440 + bool + select PLAT_S5P + select S3C_PL330_DMA + help + Enable S5P6440 CPU support + +config CPU_S5P6450 + bool + select PLAT_S5P + select S3C_PL330_DMA + help + Enable S5P6450 CPU support + +config S5P64X0_SETUP_I2C1 + bool + help + Common setup code for i2c bus 1. + +# machine support + +config MACH_SMDK6440 + bool "SMDK6440" + select CPU_S5P6440 + select S3C_DEV_I2C1 + select S3C_DEV_RTC + select S3C_DEV_WDT + select S3C64XX_DEV_SPI + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_TS + select S5P64X0_SETUP_I2C1 + help + Machine support for the Samsung SMDK6440 + +config MACH_SMDK6450 + bool "SMDK6450" + select CPU_S5P6450 + select S3C_DEV_I2C1 + select S3C_DEV_RTC + select S3C_DEV_WDT + select S3C64XX_DEV_SPI + select SAMSUNG_DEV_ADC + select SAMSUNG_DEV_TS + select S5P64X0_SETUP_I2C1 + help + Machine support for the Samsung SMDK6450 + +endif diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile new file mode 100644 index 000000000000..2655829e6bf8 --- /dev/null +++ b/arch/arm/mach-s5p64x0/Makefile @@ -0,0 +1,30 @@ +# arch/arm/mach-s5p64x0/Makefile +# +# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. +# http://www.samsung.com +# +# Licensed under GPLv2 + +obj-y := +obj-m := +obj-n := +obj- := + +# Core support for S5P64X0 system + +obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o +obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o +obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o gpio.o +obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o + +# machine support + +obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o +obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o + +# device support + +obj-y += dev-audio.o +obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o + +obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o diff --git a/arch/arm/mach-s5p6440/Makefile.boot b/arch/arm/mach-s5p64x0/Makefile.boot index ff90aa13bd67..ff90aa13bd67 100644 --- a/arch/arm/mach-s5p6440/Makefile.boot +++ b/arch/arm/mach-s5p64x0/Makefile.boot diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c new file mode 100644 index 000000000000..f93dcd8b4d6a --- /dev/null +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -0,0 +1,626 @@ +/* linux/arch/arm/mach-s5p64x0/clock-s5p6440.c + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P6440 - Clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/sysdev.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/map.h> +#include <mach/regs-clock.h> +#include <mach/s5p64x0-clock.h> + +#include <plat/cpu-freq.h> +#include <plat/clock.h> +#include <plat/cpu.h> +#include <plat/pll.h> +#include <plat/s5p-clock.h> +#include <plat/clock-clksrc.h> +#include <plat/s5p6440.h> + +static u32 epll_div[][5] = { + { 36000000, 0, 48, 1, 4 }, + { 48000000, 0, 32, 1, 3 }, + { 60000000, 0, 40, 1, 3 }, + { 72000000, 0, 48, 1, 3 }, + { 84000000, 0, 28, 1, 2 }, + { 96000000, 0, 32, 1, 2 }, + { 32768000, 45264, 43, 1, 4 }, + { 45158000, 6903, 30, 1, 3 }, + { 49152000, 50332, 32, 1, 3 }, + { 67738000, 10398, 45, 1, 3 }, + { 73728000, 9961, 49, 1, 3 } +}; + +static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int epll_con, epll_con_k; + unsigned int i; + + if (clk->rate == rate) /* Return if nothing changed */ + return 0; + + epll_con = __raw_readl(S5P64X0_EPLL_CON); + epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K); + + epll_con_k &= ~(PLL90XX_KDIV_MASK); + epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK); + + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { + if (epll_div[i][0] == rate) { + epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT); + epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) | + (epll_div[i][3] << PLL90XX_PDIV_SHIFT) | + (epll_div[i][4] << PLL90XX_SDIV_SHIFT); + break; + } + } + + if (i == ARRAY_SIZE(epll_div)) { + printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); + return -EINVAL; + } + + __raw_writel(epll_con, S5P64X0_EPLL_CON); + __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); + + clk->rate = rate; + + return 0; +} + +static struct clk_ops s5p6440_epll_ops = { + .get_rate = s5p64x0_epll_get_rate, + .set_rate = s5p6440_epll_set_rate, +}; + +static struct clksrc_clk clk_hclk = { + .clk = { + .name = "clk_hclk", + .id = -1, + .parent = &clk_armclk.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk = { + .clk = { + .name = "clk_pclk", + .id = -1, + .parent = &clk_hclk.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 }, +}; +static struct clksrc_clk clk_hclk_low = { + .clk = { + .name = "clk_hclk_low", + .id = -1, + }, + .sources = &clkset_hclk_low, + .reg_src = { .reg = S5P64X0_SYS_OTHERS, .shift = 6, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk_low = { + .clk = { + .name = "clk_pclk_low", + .id = -1, + .parent = &clk_hclk_low.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 }, +}; + +/* + * The following clocks will be disabled during clock initialization. It is + * recommended to keep the following clocks disabled until the driver requests + * for enabling the clock. + */ +static struct clk init_clocks_disable[] = { + { + .name = "nand", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_mem_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "post", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 5) + }, { + .name = "2d", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "hsmmc", + .id = 0, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "hsmmc", + .id = 1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 18), + }, { + .name = "hsmmc", + .id = 2, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 19), + }, { + .name = "otg", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 20) + }, { + .name = "irom", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 25), + }, { + .name = "lcd", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk1_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "hclk_fimgvg", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk1_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "tsi", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk1_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "watchdog", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "rtc", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 6), + }, { + .name = "timers", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "pcm", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 8), + }, { + .name = "adc", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "i2c", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "spi", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "spi", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 22), + }, { + .name = "gps", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 25), + }, { + .name = "i2s_v40", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 26), + }, { + .name = "dsim", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 28), + }, { + .name = "etm", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 29), + }, { + .name = "dmc0", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 30), + }, { + .name = "pclk_fimgvg", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 31), + }, { + .name = "sclk_spi_48", + .id = 0, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 22), + }, { + .name = "sclk_spi_48", + .id = 1, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 23), + }, { + .name = "mmc_48m", + .id = 0, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 27), + }, { + .name = "mmc_48m", + .id = 1, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 28), + }, { + .name = "mmc_48m", + .id = 2, + .parent = &clk_48m, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 29), + }, +}; + +/* + * The following clocks will be enabled during clock initialization. + */ +static struct clk init_clocks[] = { + { + .name = "intc", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "mem", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "dma", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "uart", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "uart", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "uart", + .id = 2, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "uart", + .id = 3, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "gpio", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 18), + }, +}; + +static struct clk clk_iis_cd_v40 = { + .name = "iis_cdclk_v40", + .id = -1, +}; + +static struct clk clk_pcm_cd = { + .name = "pcm_cdclk", + .id = -1, +}; + +static struct clk *clkset_group1_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll.clk, + &clk_fin_epll, +}; + +static struct clksrc_sources clkset_group1 = { + .sources = clkset_group1_list, + .nr_sources = ARRAY_SIZE(clkset_group1_list), +}; + +static struct clk *clkset_uart_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll.clk, +}; + +static struct clksrc_sources clkset_uart = { + .sources = clkset_uart_list, + .nr_sources = ARRAY_SIZE(clkset_uart_list), +}; + +static struct clk *clkset_audio_list[] = { + &clk_mout_epll.clk, + &clk_dout_mpll.clk, + &clk_fin_epll, + &clk_iis_cd_v40, + &clk_pcm_cd, +}; + +static struct clksrc_sources clkset_audio = { + .sources = clkset_audio_list, + .nr_sources = ARRAY_SIZE(clkset_audio_list), +}; + +static struct clksrc_clk clksrcs[] = { + { + .clk = { + .name = "mmc_bus", + .id = 0, + .ctrlbit = (1 << 24), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 1, + .ctrlbit = (1 << 25), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "mmc_bus", + .id = 2, + .ctrlbit = (1 << 26), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = -1, + .ctrlbit = (1 << 5), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 0, + .ctrlbit = (1 << 20), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 1, + .ctrlbit = (1 << 21), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_post", + .id = -1, + .ctrlbit = (1 << 10), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "sclk_dispcon", + .id = -1, + .ctrlbit = (1 << 1), + .enable = s5p64x0_sclk1_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimgvg", + .id = -1, + .ctrlbit = (1 << 2), + .enable = s5p64x0_sclk1_ctrl, + }, + .sources = &clkset_group1, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_audio2", + .id = -1, + .ctrlbit = (1 << 11), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_audio, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 0, .size = 3 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 24, .size = 4 }, + }, +}; + +/* Clock initialization code */ +static struct clksrc_clk *sysclks[] = { + &clk_mout_apll, + &clk_mout_epll, + &clk_mout_mpll, + &clk_dout_mpll, + &clk_armclk, + &clk_hclk, + &clk_pclk, + &clk_hclk_low, + &clk_pclk_low, +}; + +void __init_or_cpufreq s5p6440_setup_clocks(void) +{ + struct clk *xtal_clk; + + unsigned long xtal; + unsigned long fclk; + unsigned long hclk; + unsigned long hclk_low; + unsigned long pclk; + unsigned long pclk_low; + + unsigned long apll; + unsigned long mpll; + unsigned long epll; + unsigned int ptr; + + /* Set S5P6440 functions for clk_fout_epll */ + + clk_fout_epll.enable = s5p64x0_epll_enable; + clk_fout_epll.ops = &s5p6440_epll_ops; + + clk_48m.enable = s5p64x0_clk48m_ctrl; + + xtal_clk = clk_get(NULL, "ext_xtal"); + BUG_ON(IS_ERR(xtal_clk)); + + xtal = clk_get_rate(xtal_clk); + clk_put(xtal_clk); + + apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502); + mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502); + epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON), + __raw_readl(S5P64X0_EPLL_CON_K)); + + clk_fout_apll.rate = apll; + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + + printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ + " E=%ld.%ldMHz\n", + print_mhz(apll), print_mhz(mpll), print_mhz(epll)); + + fclk = clk_get_rate(&clk_armclk.clk); + hclk = clk_get_rate(&clk_hclk.clk); + pclk = clk_get_rate(&clk_pclk.clk); + hclk_low = clk_get_rate(&clk_hclk_low.clk); + pclk_low = clk_get_rate(&clk_pclk_low.clk); + + printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ + " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", + print_mhz(hclk), print_mhz(hclk_low), + print_mhz(pclk), print_mhz(pclk_low)); + + clk_f.rate = fclk; + clk_h.rate = hclk; + clk_p.rate = pclk; + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_set_clksrc(&clksrcs[ptr], true); +} + +static struct clk *clks[] __initdata = { + &clk_ext, + &clk_iis_cd_v40, + &clk_pcm_cd, +}; + +void __init s5p6440_register_clocks(void) +{ + struct clk *clkp; + int ret; + int ptr; + + s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); + + for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) + s3c_register_clksrc(sysclks[ptr], 1); + + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + + clkp = init_clocks_disable; + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + (clkp->enable)(clkp, 0); + } + + s3c_pwmclk_init(); +} diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c new file mode 100644 index 000000000000..f9afb05b217c --- /dev/null +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -0,0 +1,655 @@ +/* linux/arch/arm/mach-s5p64x0/clock-s5p6450.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P6450 - Clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/sysdev.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/map.h> +#include <mach/regs-clock.h> +#include <mach/s5p64x0-clock.h> + +#include <plat/cpu-freq.h> +#include <plat/clock.h> +#include <plat/cpu.h> +#include <plat/pll.h> +#include <plat/s5p-clock.h> +#include <plat/clock-clksrc.h> +#include <plat/s5p6450.h> + +static struct clksrc_clk clk_mout_dpll = { + .clk = { + .name = "mout_dpll", + .id = -1, + }, + .sources = &clk_src_dpll, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 }, +}; + +static u32 epll_div[][5] = { + { 133000000, 27307, 55, 2, 2 }, + { 100000000, 43691, 41, 2, 2 }, + { 480000000, 0, 80, 2, 0 }, +}; + +static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int epll_con, epll_con_k; + unsigned int i; + + if (clk->rate == rate) /* Return if nothing changed */ + return 0; + + epll_con = __raw_readl(S5P64X0_EPLL_CON); + epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K); + + epll_con_k &= ~(PLL90XX_KDIV_MASK); + epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK); + + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { + if (epll_div[i][0] == rate) { + epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT); + epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) | + (epll_div[i][3] << PLL90XX_PDIV_SHIFT) | + (epll_div[i][4] << PLL90XX_SDIV_SHIFT); + break; + } + } + + if (i == ARRAY_SIZE(epll_div)) { + printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__); + return -EINVAL; + } + + __raw_writel(epll_con, S5P64X0_EPLL_CON); + __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); + + clk->rate = rate; + + return 0; +} + +static struct clk_ops s5p6450_epll_ops = { + .get_rate = s5p64x0_epll_get_rate, + .set_rate = s5p6450_epll_set_rate, +}; + +static struct clksrc_clk clk_dout_epll = { + .clk = { + .name = "dout_epll", + .id = -1, + .parent = &clk_mout_epll.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 24, .size = 4 }, +}; + +static struct clksrc_clk clk_mout_hclk_sel = { + .clk = { + .name = "mout_hclk_sel", + .id = -1, + }, + .sources = &clkset_hclk_low, + .reg_src = { .reg = S5P64X0_OTHERS, .shift = 15, .size = 1 }, +}; + +static struct clk *clkset_hclk_list[] = { + &clk_mout_hclk_sel.clk, + &clk_armclk.clk, +}; + +static struct clksrc_sources clkset_hclk = { + .sources = clkset_hclk_list, + .nr_sources = ARRAY_SIZE(clkset_hclk_list), +}; + +static struct clksrc_clk clk_hclk = { + .clk = { + .name = "clk_hclk", + .id = -1, + }, + .sources = &clkset_hclk, + .reg_src = { .reg = S5P64X0_OTHERS, .shift = 14, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk = { + .clk = { + .name = "clk_pclk", + .id = -1, + .parent = &clk_hclk.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 }, +}; +static struct clksrc_clk clk_dout_pwm_ratio0 = { + .clk = { + .name = "clk_dout_pwm_ratio0", + .id = -1, + .parent = &clk_mout_hclk_sel.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 16, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk_to_wdt_pwm = { + .clk = { + .name = "clk_pclk_to_wdt_pwm", + .id = -1, + .parent = &clk_dout_pwm_ratio0.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 20, .size = 4 }, +}; + +static struct clksrc_clk clk_hclk_low = { + .clk = { + .name = "clk_hclk_low", + .id = -1, + }, + .sources = &clkset_hclk_low, + .reg_src = { .reg = S5P64X0_OTHERS, .shift = 6, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clk_pclk_low = { + .clk = { + .name = "clk_pclk_low", + .id = -1, + .parent = &clk_hclk_low.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 }, +}; + +/* + * The following clocks will be disabled during clock initialization. It is + * recommended to keep the following clocks disabled until the driver requests + * for enabling the clock. + */ +static struct clk init_clocks_disable[] = { + { + .name = "usbhost", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "hsmmc", + .id = 0, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "hsmmc", + .id = 1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 18), + }, { + .name = "hsmmc", + .id = 2, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 19), + }, { + .name = "usbotg", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 20), + }, { + .name = "lcd", + .id = -1, + .parent = &clk_h, + .enable = s5p64x0_hclk1_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "watchdog", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 5), + }, { + .name = "adc", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "i2c", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 17), + }, { + .name = "spi", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "spi", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 22), + }, { + .name = "iis", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 26), + }, { + .name = "i2c", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 27), + }, { + .name = "dmc0", + .id = -1, + .parent = &clk_pclk.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 30), + } +}; + +/* + * The following clocks will be enabled during clock initialization. + */ +static struct clk init_clocks[] = { + { + .name = "intc", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "mem", + .id = -1, + .parent = &clk_hclk.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 21), + }, { + .name = "dma", + .id = -1, + .parent = &clk_hclk_low.clk, + .enable = s5p64x0_hclk0_ctrl, + .ctrlbit = (1 << 12), + }, { + .name = "uart", + .id = 0, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 1), + }, { + .name = "uart", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 2), + }, { + .name = "uart", + .id = 2, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 3), + }, { + .name = "uart", + .id = 3, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 4), + }, { + .name = "timers", + .id = -1, + .parent = &clk_pclk_to_wdt_pwm.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 7), + }, { + .name = "gpio", + .id = -1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 18), + }, +}; + +static struct clk *clkset_uart_list[] = { + &clk_dout_epll.clk, + &clk_dout_mpll.clk, +}; + +static struct clksrc_sources clkset_uart = { + .sources = clkset_uart_list, + .nr_sources = ARRAY_SIZE(clkset_uart_list), +}; + +static struct clk *clkset_mali_list[] = { + &clk_mout_epll.clk, + &clk_mout_apll.clk, + &clk_mout_mpll.clk, +}; + +static struct clksrc_sources clkset_mali = { + .sources = clkset_mali_list, + .nr_sources = ARRAY_SIZE(clkset_mali_list), +}; + +static struct clk *clkset_group2_list[] = { + &clk_dout_epll.clk, + &clk_dout_mpll.clk, + &clk_ext_xtal_mux, +}; + +static struct clksrc_sources clkset_group2 = { + .sources = clkset_group2_list, + .nr_sources = ARRAY_SIZE(clkset_group2_list), +}; + +static struct clk *clkset_dispcon_list[] = { + &clk_dout_epll.clk, + &clk_dout_mpll.clk, + &clk_ext_xtal_mux, + &clk_mout_dpll.clk, +}; + +static struct clksrc_sources clkset_dispcon = { + .sources = clkset_dispcon_list, + .nr_sources = ARRAY_SIZE(clkset_dispcon_list), +}; + +static struct clk *clkset_hsmmc44_list[] = { + &clk_dout_epll.clk, + &clk_dout_mpll.clk, + &clk_ext_xtal_mux, + &s5p_clk_27m, + &clk_48m, +}; + +static struct clksrc_sources clkset_hsmmc44 = { + .sources = clkset_hsmmc44_list, + .nr_sources = ARRAY_SIZE(clkset_hsmmc44_list), +}; + +static struct clk *clkset_sclk_audio0_list[] = { + [0] = &clk_dout_epll.clk, + [1] = &clk_dout_mpll.clk, + [2] = &clk_ext_xtal_mux, + [3] = NULL, + [4] = NULL, +}; + +static struct clksrc_sources clkset_sclk_audio0 = { + .sources = clkset_sclk_audio0_list, + .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list), +}; + +static struct clksrc_clk clk_sclk_audio0 = { + .clk = { + .name = "audio-bus", + .id = -1, + .enable = s5p64x0_sclk_ctrl, + .ctrlbit = (1 << 8), + .parent = &clk_dout_epll.clk, + }, + .sources = &clkset_sclk_audio0, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 10, .size = 3 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 8, .size = 4 }, +}; + +static struct clksrc_clk clksrcs[] = { + { + .clk = { + .name = "sclk_mmc", + .id = 0, + .ctrlbit = (1 << 24), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_mmc", + .id = 1, + .ctrlbit = (1 << 25), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_mmc", + .id = 2, + .ctrlbit = (1 << 26), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, + }, { + .clk = { + .name = "uclk1", + .id = -1, + .ctrlbit = (1 << 5), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_uart, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 0, + .ctrlbit = (1 << 20), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_spi", + .id = 1, + .ctrlbit = (1 << 21), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_fimc", + .id = -1, + .ctrlbit = (1 << 10), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 }, + }, { + .clk = { + .name = "aclk_mali", + .id = -1, + .ctrlbit = (1 << 2), + .enable = s5p64x0_sclk1_ctrl, + }, + .sources = &clkset_mali, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 }, + }, { + .clk = { + .name = "sclk_2d", + .id = -1, + .ctrlbit = (1 << 12), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_mali, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 30, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_usi", + .id = -1, + .ctrlbit = (1 << 7), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 10, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 16, .size = 4 }, + }, { + .clk = { + .name = "sclk_camif", + .id = -1, + .ctrlbit = (1 << 6), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_group2, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 28, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 20, .size = 4 }, + }, { + .clk = { + .name = "sclk_dispcon", + .id = -1, + .ctrlbit = (1 << 1), + .enable = s5p64x0_sclk1_ctrl, + }, + .sources = &clkset_dispcon, + .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 }, + .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 }, + }, { + .clk = { + .name = "sclk_hsmmc44", + .id = -1, + .ctrlbit = (1 << 30), + .enable = s5p64x0_sclk_ctrl, + }, + .sources = &clkset_hsmmc44, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 6, .size = 3 }, + .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 28, .size = 4 }, + }, +}; + +/* Clock initialization code */ +static struct clksrc_clk *sysclks[] = { + &clk_mout_apll, + &clk_mout_epll, + &clk_dout_epll, + &clk_mout_mpll, + &clk_dout_mpll, + &clk_armclk, + &clk_mout_hclk_sel, + &clk_dout_pwm_ratio0, + &clk_pclk_to_wdt_pwm, + &clk_hclk, + &clk_pclk, + &clk_hclk_low, + &clk_pclk_low, + &clk_sclk_audio0, +}; + +void __init_or_cpufreq s5p6450_setup_clocks(void) +{ + struct clk *xtal_clk; + + unsigned long xtal; + unsigned long fclk; + unsigned long hclk; + unsigned long hclk_low; + unsigned long pclk; + unsigned long pclk_low; + + unsigned long apll; + unsigned long mpll; + unsigned long epll; + unsigned long dpll; + unsigned int ptr; + + /* Set S5P6450 functions for clk_fout_epll */ + + clk_fout_epll.enable = s5p64x0_epll_enable; + clk_fout_epll.ops = &s5p6450_epll_ops; + + clk_48m.enable = s5p64x0_clk48m_ctrl; + + xtal_clk = clk_get(NULL, "ext_xtal"); + BUG_ON(IS_ERR(xtal_clk)); + + xtal = clk_get_rate(xtal_clk); + clk_put(xtal_clk); + + apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502); + mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502); + epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON), + __raw_readl(S5P64X0_EPLL_CON_K)); + dpll = s5p_get_pll46xx(xtal, __raw_readl(S5P6450_DPLL_CON), + __raw_readl(S5P6450_DPLL_CON_K), pll_4650c); + + clk_fout_apll.rate = apll; + clk_fout_mpll.rate = mpll; + clk_fout_epll.rate = epll; + clk_fout_dpll.rate = dpll; + + printk(KERN_INFO "S5P6450: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \ + " E=%ld.%ldMHz, D=%ld.%ldMHz\n", + print_mhz(apll), print_mhz(mpll), print_mhz(epll), + print_mhz(dpll)); + + fclk = clk_get_rate(&clk_armclk.clk); + hclk = clk_get_rate(&clk_hclk.clk); + pclk = clk_get_rate(&clk_pclk.clk); + hclk_low = clk_get_rate(&clk_hclk_low.clk); + pclk_low = clk_get_rate(&clk_pclk_low.clk); + + printk(KERN_INFO "S5P6450: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \ + " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n", + print_mhz(hclk), print_mhz(hclk_low), + print_mhz(pclk), print_mhz(pclk_low)); + + clk_f.rate = fclk; + clk_h.rate = hclk; + clk_p.rate = pclk; + + for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) + s3c_set_clksrc(&clksrcs[ptr], true); +} + +void __init s5p6450_register_clocks(void) +{ + struct clk *clkp; + int ret; + int ptr; + + for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) + s3c_register_clksrc(sysclks[ptr], 1); + + s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); + s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); + + clkp = init_clocks_disable; + for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { + + ret = s3c24xx_register_clock(clkp); + if (ret < 0) { + printk(KERN_ERR "Failed to register clock %s (%d)\n", + clkp->name, ret); + } + (clkp->enable)(clkp, 0); + } + + s3c_pwmclk_init(); +} diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c new file mode 100644 index 000000000000..523ba8039ac2 --- /dev/null +++ b/arch/arm/mach-s5p64x0/clock.c @@ -0,0 +1,253 @@ +/* linux/arch/arm/mach-s5p64x0/clock.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/sysdev.h> +#include <linux/io.h> + +#include <mach/hardware.h> +#include <mach/map.h> +#include <mach/regs-clock.h> + +#include <plat/cpu-freq.h> +#include <plat/clock.h> +#include <plat/cpu.h> +#include <plat/pll.h> +#include <plat/s5p-clock.h> +#include <plat/clock-clksrc.h> +#include <plat/s5p6440.h> +#include <plat/s5p6450.h> + +struct clksrc_clk clk_mout_apll = { + .clk = { + .name = "mout_apll", + .id = -1, + }, + .sources = &clk_src_apll, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 0, .size = 1 }, +}; + +struct clksrc_clk clk_mout_mpll = { + .clk = { + .name = "mout_mpll", + .id = -1, + }, + .sources = &clk_src_mpll, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 1, .size = 1 }, +}; + +struct clksrc_clk clk_mout_epll = { + .clk = { + .name = "mout_epll", + .id = -1, + }, + .sources = &clk_src_epll, + .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 2, .size = 1 }, +}; + +enum perf_level { + L0 = 532*1000, + L1 = 266*1000, + L2 = 133*1000, +}; + +static const u32 clock_table[][3] = { + /*{ARM_CLK, DIVarm, DIVhclk}*/ + {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, + {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, + {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, +}; + +int s5p64x0_epll_enable(struct clk *clk, int enable) +{ + unsigned int ctrlbit = clk->ctrlbit; + unsigned int epll_con = __raw_readl(S5P64X0_EPLL_CON) & ~ctrlbit; + + if (enable) + __raw_writel(epll_con | ctrlbit, S5P64X0_EPLL_CON); + else + __raw_writel(epll_con, S5P64X0_EPLL_CON); + + return 0; +} + +unsigned long s5p64x0_epll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +unsigned long s5p64x0_armclk_get_rate(struct clk *clk) +{ + unsigned long rate = clk_get_rate(clk->parent); + u32 clkdiv; + + /* divisor mask starts at bit0, so no need to shift */ + clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK; + + return rate / (clkdiv + 1); +} + +unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate) +{ + u32 iter; + + for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) { + if (rate > clock_table[iter][0]) + return clock_table[iter-1][0]; + } + + return clock_table[ARRAY_SIZE(clock_table) - 1][0]; +} + +int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate) +{ + u32 round_tmp; + u32 iter; + u32 clk_div0_tmp; + u32 cur_rate = clk->ops->get_rate(clk); + unsigned long flags; + + round_tmp = clk->ops->round_rate(clk, rate); + if (round_tmp == cur_rate) + return 0; + + + for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) { + if (round_tmp == clock_table[iter][0]) + break; + } + + if (iter >= ARRAY_SIZE(clock_table)) + iter = ARRAY_SIZE(clock_table) - 1; + + local_irq_save(flags); + if (cur_rate > round_tmp) { + /* Frequency Down */ + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); + clk_div0_tmp |= clock_table[iter][1]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & + ~(S5P64X0_CLKDIV0_HCLK_MASK); + clk_div0_tmp |= clock_table[iter][2]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + + } else { + /* Frequency Up */ + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & + ~(S5P64X0_CLKDIV0_HCLK_MASK); + clk_div0_tmp |= clock_table[iter][2]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + + clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK); + clk_div0_tmp |= clock_table[iter][1]; + __raw_writel(clk_div0_tmp, ARM_CLK_DIV); + } + local_irq_restore(flags); + + clk->rate = clock_table[iter][0]; + + return 0; +} + +struct clk_ops s5p64x0_clkarm_ops = { + .get_rate = s5p64x0_armclk_get_rate, + .set_rate = s5p64x0_armclk_set_rate, + .round_rate = s5p64x0_armclk_round_rate, +}; + +struct clksrc_clk clk_armclk = { + .clk = { + .name = "armclk", + .id = 1, + .parent = &clk_mout_apll.clk, + .ops = &s5p64x0_clkarm_ops, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 0, .size = 4 }, +}; + +struct clksrc_clk clk_dout_mpll = { + .clk = { + .name = "dout_mpll", + .id = -1, + .parent = &clk_mout_mpll.clk, + }, + .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 4, .size = 1 }, +}; + +struct clk *clkset_hclk_low_list[] = { + &clk_mout_apll.clk, + &clk_mout_mpll.clk, +}; + +struct clksrc_sources clkset_hclk_low = { + .sources = clkset_hclk_low_list, + .nr_sources = ARRAY_SIZE(clkset_hclk_low_list), +}; + +int s5p64x0_pclk_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_PCLK, clk, enable); +} + +int s5p64x0_hclk0_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK0, clk, enable); +} + +int s5p64x0_hclk1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK1, clk, enable); +} + +int s5p64x0_sclk_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK0, clk, enable); +} + +int s5p64x0_sclk1_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK1, clk, enable); +} + +int s5p64x0_mem_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(S5P64X0_CLK_GATE_MEM0, clk, enable); +} + +int s5p64x0_clk48m_ctrl(struct clk *clk, int enable) +{ + unsigned long flags; + u32 val; + + /* can't rely on clock lock, this register has other usages */ + local_irq_save(flags); + + val = __raw_readl(S5P64X0_OTHERS); + if (enable) + val |= S5P64X0_OTHERS_USB_SIG_MASK; + else + val &= ~S5P64X0_OTHERS_USB_SIG_MASK; + + __raw_writel(val, S5P64X0_OTHERS); + + local_irq_restore(flags); + + return 0; +} diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c new file mode 100644 index 000000000000..b8d02eb4cf30 --- /dev/null +++ b/arch/arm/mach-s5p64x0/cpu.c @@ -0,0 +1,209 @@ +/* linux/arch/arm/mach-s5p64x0/cpu.c + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/sysdev.h> +#include <linux/serial_core.h> +#include <linux/platform_device.h> +#include <linux/sched.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/proc-fns.h> +#include <asm/irq.h> + +#include <mach/hardware.h> +#include <mach/map.h> +#include <mach/regs-clock.h> + +#include <plat/regs-serial.h> +#include <plat/cpu.h> +#include <plat/devs.h> +#include <plat/clock.h> +#include <plat/s5p6440.h> +#include <plat/s5p6450.h> +#include <plat/adc-core.h> + +/* Initial IO mappings */ + +static struct map_desc s5p64x0_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5P64X0_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5P64X0_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5P64X0_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc s5p6440_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S5P6440_PA_UART(0)), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc s5p6450_iodesc[] __initdata = { + { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S5P6450_PA_UART(0)), + .length = SZ_512K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART + SZ_512K, + .pfn = __phys_to_pfn(S5P6450_PA_UART(5)), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static void s5p64x0_idle(void) +{ + unsigned long val; + + if (!need_resched()) { + val = __raw_readl(S5P64X0_PWR_CFG); + val &= ~(0x3 << 5); + val |= (0x1 << 5); + __raw_writel(val, S5P64X0_PWR_CFG); + + cpu_do_idle(); + } + local_irq_enable(); +} + +/* + * s5p64x0_map_io + * + * register the standard CPU IO areas + */ + +void __init s5p6440_map_io(void) +{ + /* initialize any device information early */ + s3c_adc_setname("s3c64xx-adc"); + + iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc)); + iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc)); +} + +void __init s5p6450_map_io(void) +{ + /* initialize any device information early */ + s3c_adc_setname("s3c64xx-adc"); + + iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc)); + iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6440_iodesc)); +} + +/* + * s5p64x0_init_clocks + * + * register and setup the CPU clocks + */ + +void __init s5p6440_init_clocks(int xtal) +{ + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + s5p6440_register_clocks(); + s5p6440_setup_clocks(); +} + +void __init s5p6450_init_clocks(int xtal) +{ + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + s5p6450_register_clocks(); + s5p6450_setup_clocks(); +} + +/* + * s5p64x0_init_irq + * + * register the CPU interrupts + */ + +void __init s5p6440_init_irq(void) +{ + /* S5P6440 supports 2 VIC */ + u32 vic[2]; + + /* + * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)] + * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22] + */ + vic[0] = 0xff800ae7; + vic[1] = 0xffbf23e5; + + s5p_init_irq(vic, ARRAY_SIZE(vic)); +} + +void __init s5p6450_init_irq(void) +{ + /* S5P6450 supports only 2 VIC */ + u32 vic[2]; + + /* + * VIC0 is missing IRQ_VIC0[(13-15), (21-22)] + * VIC1 is missing IRQ VIC1[12, 14, 23] + */ + vic[0] = 0xff9f1fff; + vic[1] = 0xff7fafff; + + s5p_init_irq(vic, ARRAY_SIZE(vic)); +} + +struct sysdev_class s5p64x0_sysclass = { + .name = "s5p64x0-core", +}; + +static struct sys_device s5p64x0_sysdev = { + .cls = &s5p64x0_sysclass, +}; + +static int __init s5p64x0_core_init(void) +{ + return sysdev_class_register(&s5p64x0_sysclass); +} +core_initcall(s5p64x0_core_init); + +int __init s5p64x0_init(void) +{ + printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n"); + + /* set idle function */ + pm_idle = s5p64x0_idle; + + return sysdev_register(&s5p64x0_sysdev); +} diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c new file mode 100644 index 000000000000..fa097bd68ca4 --- /dev/null +++ b/arch/arm/mach-s5p64x0/dev-audio.c @@ -0,0 +1,164 @@ +/* linux/arch/arm/mach-s5p64x0/dev-audio.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/gpio.h> + +#include <plat/gpio-cfg.h> +#include <plat/audio.h> + +#include <mach/map.h> +#include <mach/dma.h> +#include <mach/irqs.h> + +static int s5p6440_cfg_i2s(struct platform_device *pdev) +{ + /* configure GPIO for i2s port */ + switch (pdev->id) { + case -1: + s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5)); + break; + + default: + printk(KERN_ERR "Invalid Device %d\n", pdev->id); + return -EINVAL; + } + + return 0; +} + +static int s5p6450_cfg_i2s(struct platform_device *pdev) +{ + /* configure GPIO for i2s port */ + switch (pdev->id) { + case -1: + s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6450_GPR(5), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6450_GPR(6), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6450_GPR(7), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6450_GPR(8), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6450_GPR(13), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6450_GPR(14), S3C_GPIO_SFN(5)); + break; + + default: + printk(KERN_ERR "Invalid Device %d\n", pdev->id); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s5p6440_i2s_pdata = { + .cfg_gpio = s5p6440_cfg_i2s, +}; + +static struct s3c_audio_pdata s5p6450_i2s_pdata = { + .cfg_gpio = s5p6450_cfg_i2s, +}; + +static struct resource s5p64x0_iis0_resource[] = { + [0] = { + .start = S5P64X0_PA_I2S, + .end = S5P64X0_PA_I2S + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S0_TX, + .end = DMACH_I2S0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S0_RX, + .end = DMACH_I2S0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6440_device_iis = { + .name = "s3c64xx-iis-v4", + .id = -1, + .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), + .resource = s5p64x0_iis0_resource, + .dev = { + .platform_data = &s5p6440_i2s_pdata, + }, +}; + +struct platform_device s5p6450_device_iis0 = { + .name = "s3c64xx-iis-v4", + .id = -1, + .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), + .resource = s5p64x0_iis0_resource, + .dev = { + .platform_data = &s5p6450_i2s_pdata, + }, +}; + +/* PCM Controller platform_devices */ + +static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2)); + break; + + default: + printk(KERN_DEBUG "Invalid PCM Controller number!"); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s5p6440_pcm_pdata = { + .cfg_gpio = s5p6440_pcm_cfg_gpio, +}; + +static struct resource s5p6440_pcm0_resource[] = { + [0] = { + .start = S5P64X0_PA_PCM, + .end = S5P64X0_PA_PCM + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM0_TX, + .end = DMACH_PCM0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM0_RX, + .end = DMACH_PCM0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6440_device_pcm = { + .name = "samsung-pcm", + .id = 0, + .num_resources = ARRAY_SIZE(s5p6440_pcm0_resource), + .resource = s5p6440_pcm0_resource, + .dev = { + .platform_data = &s5p6440_pcm_pdata, + }, +}; diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c new file mode 100644 index 000000000000..5b69ec4c8af3 --- /dev/null +++ b/arch/arm/mach-s5p64x0/dev-spi.c @@ -0,0 +1,232 @@ +/* linux/arch/arm/mach-s5p64x0/dev-spi.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/gpio.h> + +#include <mach/dma.h> +#include <mach/map.h> +#include <mach/irqs.h> +#include <mach/regs-clock.h> +#include <mach/spi-clocks.h> + +#include <plat/s3c64xx-spi.h> +#include <plat/gpio-cfg.h> + +static char *s5p64x0_spi_src_clks[] = { + [S5P64X0_SPI_SRCCLK_PCLK] = "pclk", + [S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi", +}; + +/* SPI Controller platform_devices */ + +/* Since we emulate multi-cs capability, we do not touch the CS. + * The emulated CS is toggled by board specific mechanism, as it can + * be either some immediate GPIO or some signal out of some other + * chip in between ... or some yet another way. + * We simply do not assume anything about CS. + */ +static int s5p6440_spi_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP); + break; + + case 1: + s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP); + break; + + default: + dev_err(&pdev->dev, "Invalid SPI Controller number!"); + return -EINVAL; + } + + return 0; +} + +static int s5p6450_spi_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin(S5P6450_GPC(0), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6450_GPC(1), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6450_GPC(2), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5P6450_GPC(0), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S5P6450_GPC(1), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S5P6450_GPC(2), S3C_GPIO_PULL_UP); + break; + + case 1: + s3c_gpio_cfgpin(S5P6450_GPC(4), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6450_GPC(5), S3C_GPIO_SFN(2)); + s3c_gpio_cfgpin(S5P6450_GPC(6), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5P6450_GPC(4), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S5P6450_GPC(5), S3C_GPIO_PULL_UP); + s3c_gpio_setpull(S5P6450_GPC(6), S3C_GPIO_PULL_UP); + break; + + default: + dev_err(&pdev->dev, "Invalid SPI Controller number!"); + return -EINVAL; + } + + return 0; +} + +static struct resource s5p64x0_spi0_resource[] = { + [0] = { + .start = S5P64X0_PA_SPI0, + .end = S5P64X0_PA_SPI0 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_SPI0_TX, + .end = DMACH_SPI0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_SPI0_RX, + .end = DMACH_SPI0_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = IRQ_SPI0, + .end = IRQ_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c64xx_spi_info s5p6440_spi0_pdata = { + .cfg_gpio = s5p6440_spi_cfg_gpio, + .fifo_lvl_mask = 0x1ff, + .rx_lvl_offset = 15, +}; + +static struct s3c64xx_spi_info s5p6450_spi0_pdata = { + .cfg_gpio = s5p6450_spi_cfg_gpio, + .fifo_lvl_mask = 0x1ff, + .rx_lvl_offset = 15, +}; + +static u64 spi_dmamask = DMA_BIT_MASK(32); + +struct platform_device s5p64x0_device_spi0 = { + .name = "s3c64xx-spi", + .id = 0, + .num_resources = ARRAY_SIZE(s5p64x0_spi0_resource), + .resource = s5p64x0_spi0_resource, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct resource s5p64x0_spi1_resource[] = { + [0] = { + .start = S5P64X0_PA_SPI1, + .end = S5P64X0_PA_SPI1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_SPI1_TX, + .end = DMACH_SPI1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_SPI1_RX, + .end = DMACH_SPI1_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = IRQ_SPI1, + .end = IRQ_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c64xx_spi_info s5p6440_spi1_pdata = { + .cfg_gpio = s5p6440_spi_cfg_gpio, + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 15, +}; + +static struct s3c64xx_spi_info s5p6450_spi1_pdata = { + .cfg_gpio = s5p6450_spi_cfg_gpio, + .fifo_lvl_mask = 0x7f, + .rx_lvl_offset = 15, +}; + +struct platform_device s5p64x0_device_spi1 = { + .name = "s3c64xx-spi", + .id = 1, + .num_resources = ARRAY_SIZE(s5p64x0_spi1_resource), + .resource = s5p64x0_spi1_resource, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs) +{ + unsigned int id; + struct s3c64xx_spi_info *pd; + + id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000; + + /* Reject invalid configuration */ + if (!num_cs || src_clk_nr < 0 + || src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) { + printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__); + return; + } + + switch (cntrlr) { + case 0: + if (id == 0x50000) + pd = &s5p6450_spi0_pdata; + else + pd = &s5p6440_spi0_pdata; + + s5p64x0_device_spi0.dev.platform_data = pd; + break; + case 1: + if (id == 0x50000) + pd = &s5p6450_spi1_pdata; + else + pd = &s5p6440_spi1_pdata; + + s5p64x0_device_spi1.dev.platform_data = pd; + break; + default: + printk(KERN_ERR "%s: Invalid SPI controller(%d)\n", + __func__, cntrlr); + return; + } + + pd->num_cs = num_cs; + pd->src_clk_nr = src_clk_nr; + pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr]; +} diff --git a/arch/arm/mach-s5p6440/dma.c b/arch/arm/mach-s5p64x0/dma.c index 07606ad57519..29a8c2410049 100644 --- a/arch/arm/mach-s5p6440/dma.c +++ b/arch/arm/mach-s5p64x0/dma.c @@ -1,4 +1,8 @@ -/* +/* linux/arch/arm/mach-s5p64x0/dma.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright (C) 2010 Samsung Electronics Co. Ltd. * Jaswinder Singh <jassi.brar@samsung.com> * @@ -15,26 +19,25 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ +*/ #include <linux/platform_device.h> #include <linux/dma-mapping.h> -#include <plat/devs.h> -#include <plat/irqs.h> - #include <mach/map.h> #include <mach/irqs.h> +#include <mach/regs-clock.h> +#include <plat/devs.h> #include <plat/s3c-pl330-pdata.h> static u64 dma_dmamask = DMA_BIT_MASK(32); -static struct resource s5p6440_pdma_resource[] = { +static struct resource s5p64x0_pdma_resource[] = { [0] = { - .start = S5P6440_PA_PDMA, - .end = S5P6440_PA_PDMA + SZ_4K, - .flags = IORESOURCE_MEM, + .start = S5P64X0_PA_PDMA, + .end = S5P64X0_PA_PDMA + SZ_4K, + .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_DMA0, @@ -80,26 +83,67 @@ static struct s3c_pl330_platdata s5p6440_pdma_pdata = { }, }; -static struct platform_device s5p6440_device_pdma = { +static struct s3c_pl330_platdata s5p6450_pdma_pdata = { + .peri = { + [0] = DMACH_UART0_RX, + [1] = DMACH_UART0_TX, + [2] = DMACH_UART1_RX, + [3] = DMACH_UART1_TX, + [4] = DMACH_UART2_RX, + [5] = DMACH_UART2_TX, + [6] = DMACH_UART3_RX, + [7] = DMACH_UART3_TX, + [8] = DMACH_UART4_RX, + [9] = DMACH_UART4_TX, + [10] = DMACH_PCM0_TX, + [11] = DMACH_PCM0_RX, + [12] = DMACH_I2S0_TX, + [13] = DMACH_I2S0_RX, + [14] = DMACH_SPI0_TX, + [15] = DMACH_SPI0_RX, + [16] = DMACH_PCM1_TX, + [17] = DMACH_PCM1_RX, + [18] = DMACH_PCM2_TX, + [19] = DMACH_PCM2_RX, + [20] = DMACH_SPI1_TX, + [21] = DMACH_SPI1_RX, + [22] = DMACH_USI_TX, + [23] = DMACH_USI_RX, + [24] = DMACH_MAX, + [25] = DMACH_I2S1_TX, + [26] = DMACH_I2S1_RX, + [27] = DMACH_I2S2_TX, + [28] = DMACH_I2S2_RX, + [29] = DMACH_PWM, + [30] = DMACH_UART5_RX, + [31] = DMACH_UART5_TX, + }, +}; + +static struct platform_device s5p64x0_device_pdma = { .name = "s3c-pl330", - .id = 1, - .num_resources = ARRAY_SIZE(s5p6440_pdma_resource), - .resource = s5p6440_pdma_resource, + .id = 0, + .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource), + .resource = s5p64x0_pdma_resource, .dev = { .dma_mask = &dma_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &s5p6440_pdma_pdata, }, }; -static struct platform_device *s5p6440_dmacs[] __initdata = { - &s5p6440_device_pdma, -}; - -static int __init s5p6440_dma_init(void) +static int __init s5p64x0_dma_init(void) { - platform_add_devices(s5p6440_dmacs, ARRAY_SIZE(s5p6440_dmacs)); + unsigned int id; + + id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000; + + if (id == 0x50000) + s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata; + else + s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; + + platform_device_register(&s5p64x0_device_pdma); return 0; } -arch_initcall(s5p6440_dma_init); +arch_initcall(s5p64x0_dma_init); diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p64x0/gpio.c index 8bf6e0ce51c9..39159dd5a29a 100644 --- a/arch/arm/mach-s5p6440/gpio.c +++ b/arch/arm/mach-s5p64x0/gpio.c @@ -1,14 +1,14 @@ -/* arch/arm/mach-s5p6440/gpio.c +/* linux/arch/arm/mach-s5p64x0/gpio.c * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * S5P6440 - GPIOlib support + * S5P64X0 - GPIOlib support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - */ +*/ #include <linux/kernel.h> #include <linux/irq.h> @@ -22,26 +22,29 @@ #include <plat/gpio-cfg.h> #include <plat/gpio-cfg-helpers.h> -/* GPIO bank summary: -* -* Bank GPIOs Style SlpCon ExtInt Group -* A 6 4Bit Yes 1 -* B 7 4Bit Yes 1 -* C 8 4Bit Yes 2 -* F 2 2Bit Yes 4 [1] -* G 7 4Bit Yes 5 -* H 10 4Bit[2] Yes 6 -* I 16 2Bit Yes None -* J 12 2Bit Yes None -* N 16 2Bit No IRQ_EINT -* P 8 2Bit Yes 8 -* R 15 4Bit[2] Yes 8 -* -* [1] BANKF pins 14,15 do not form part of the external interrupt sources -* [2] BANK has two control registers, GPxCON0 and GPxCON1 -*/ +/* To be implemented S5P6450 GPIO */ + +/* + * S5P6440 GPIO bank summary: + * + * Bank GPIOs Style SlpCon ExtInt Group + * A 6 4Bit Yes 1 + * B 7 4Bit Yes 1 + * C 8 4Bit Yes 2 + * F 2 2Bit Yes 4 [1] + * G 7 4Bit Yes 5 + * H 10 4Bit[2] Yes 6 + * I 16 2Bit Yes None + * J 12 2Bit Yes None + * N 16 2Bit No IRQ_EINT + * P 8 2Bit Yes 8 + * R 15 4Bit[2] Yes 8 + * + * [1] BANKF pins 14,15 do not form part of the external interrupt sources + * [2] BANK has two control registers, GPxCON0 and GPxCON1 + */ -static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip, +static int s5p64x0_gpiolib_rbank_4bit2_input(struct gpio_chip *chip, unsigned int offset) { struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); @@ -77,7 +80,7 @@ static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip, return 0; } -static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip, +static int s5p64x0_gpiolib_rbank_4bit2_output(struct gpio_chip *chip, unsigned int offset, int value) { struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); @@ -124,12 +127,11 @@ static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip, return 0; } -int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip, +int s5p64x0_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip, unsigned int off, unsigned int cfg) { void __iomem *reg = chip->base; unsigned int shift; - unsigned long flags; u32 con; switch (off) { @@ -155,26 +157,22 @@ int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip, cfg <<= shift; } - s3c_gpio_lock(chip, flags); - con = __raw_readl(reg); con &= ~(0xf << shift); con |= cfg; __raw_writel(con, reg); - s3c_gpio_unlock(chip, flags); - return 0; } -static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = { +static struct s3c_gpio_cfg s5p64x0_gpio_cfgs[] = { { .cfg_eint = 0, }, { .cfg_eint = 7, }, { .cfg_eint = 3, - .set_config = s5p6440_gpio_setcfg_4bit_rbank, + .set_config = s5p64x0_gpio_setcfg_4bit_rbank, }, { .cfg_eint = 0, .set_config = s3c_gpio_setcfg_s3c24xx, @@ -193,7 +191,7 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = { static struct s3c_gpio_chip s5p6440_gpio_4bit[] = { { .base = S5P6440_GPA_BASE, - .config = &s5p6440_gpio_cfgs[1], + .config = &s5p64x0_gpio_cfgs[1], .chip = { .base = S5P6440_GPA(0), .ngpio = S5P6440_GPIO_A_NR, @@ -201,7 +199,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = { }, }, { .base = S5P6440_GPB_BASE, - .config = &s5p6440_gpio_cfgs[1], + .config = &s5p64x0_gpio_cfgs[1], .chip = { .base = S5P6440_GPB(0), .ngpio = S5P6440_GPIO_B_NR, @@ -209,7 +207,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = { }, }, { .base = S5P6440_GPC_BASE, - .config = &s5p6440_gpio_cfgs[1], + .config = &s5p64x0_gpio_cfgs[1], .chip = { .base = S5P6440_GPC(0), .ngpio = S5P6440_GPIO_C_NR, @@ -217,7 +215,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = { }, }, { .base = S5P6440_GPG_BASE, - .config = &s5p6440_gpio_cfgs[1], + .config = &s5p64x0_gpio_cfgs[1], .chip = { .base = S5P6440_GPG(0), .ngpio = S5P6440_GPIO_G_NR, @@ -229,7 +227,7 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit[] = { static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = { { .base = S5P6440_GPH_BASE + 0x4, - .config = &s5p6440_gpio_cfgs[1], + .config = &s5p64x0_gpio_cfgs[1], .chip = { .base = S5P6440_GPH(0), .ngpio = S5P6440_GPIO_H_NR, @@ -238,10 +236,10 @@ static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = { }, }; -static struct s3c_gpio_chip gpio_rbank_4bit2[] = { +static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = { { .base = S5P6440_GPR_BASE + 0x4, - .config = &s5p6440_gpio_cfgs[2], + .config = &s5p64x0_gpio_cfgs[2], .chip = { .base = S5P6440_GPR(0), .ngpio = S5P6440_GPIO_R_NR, @@ -253,7 +251,7 @@ static struct s3c_gpio_chip gpio_rbank_4bit2[] = { static struct s3c_gpio_chip s5p6440_gpio_2bit[] = { { .base = S5P6440_GPF_BASE, - .config = &s5p6440_gpio_cfgs[5], + .config = &s5p64x0_gpio_cfgs[5], .chip = { .base = S5P6440_GPF(0), .ngpio = S5P6440_GPIO_F_NR, @@ -261,7 +259,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = { }, }, { .base = S5P6440_GPI_BASE, - .config = &s5p6440_gpio_cfgs[3], + .config = &s5p64x0_gpio_cfgs[3], .chip = { .base = S5P6440_GPI(0), .ngpio = S5P6440_GPIO_I_NR, @@ -269,7 +267,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = { }, }, { .base = S5P6440_GPJ_BASE, - .config = &s5p6440_gpio_cfgs[3], + .config = &s5p64x0_gpio_cfgs[3], .chip = { .base = S5P6440_GPJ(0), .ngpio = S5P6440_GPIO_J_NR, @@ -277,7 +275,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = { }, }, { .base = S5P6440_GPN_BASE, - .config = &s5p6440_gpio_cfgs[4], + .config = &s5p64x0_gpio_cfgs[4], .chip = { .base = S5P6440_GPN(0), .ngpio = S5P6440_GPIO_N_NR, @@ -285,7 +283,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = { }, }, { .base = S5P6440_GPP_BASE, - .config = &s5p6440_gpio_cfgs[5], + .config = &s5p64x0_gpio_cfgs[5], .chip = { .base = S5P6440_GPP(0), .ngpio = S5P6440_GPIO_P_NR, @@ -294,7 +292,7 @@ static struct s3c_gpio_chip s5p6440_gpio_2bit[] = { }, }; -void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips) +void __init s5p64x0_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips) { for (; nr_chips > 0; nr_chips--, chipcfg++) { if (!chipcfg->set_config) @@ -308,13 +306,13 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips) } } -static void __init s5p6440_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip, +static void __init s5p64x0_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip, int nr_chips) { for (; nr_chips > 0; nr_chips--, chip++) { - chip->chip.direction_input = s5p6440_gpiolib_rbank_4bit2_input; + chip->chip.direction_input = s5p64x0_gpiolib_rbank_4bit2_input; chip->chip.direction_output = - s5p6440_gpiolib_rbank_4bit2_output; + s5p64x0_gpiolib_rbank_4bit2_output; s3c_gpiolib_add(chip); } } @@ -324,8 +322,8 @@ static int __init s5p6440_gpiolib_init(void) struct s3c_gpio_chip *chips = s5p6440_gpio_2bit; int nr_chips = ARRAY_SIZE(s5p6440_gpio_2bit); - s5p6440_gpiolib_set_cfg(s5p6440_gpio_cfgs, - ARRAY_SIZE(s5p6440_gpio_cfgs)); + s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs, + ARRAY_SIZE(s5p64x0_gpio_cfgs)); for (; nr_chips > 0; nr_chips--, chips++) s3c_gpiolib_add(chips); @@ -336,8 +334,8 @@ static int __init s5p6440_gpiolib_init(void) samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2, ARRAY_SIZE(s5p6440_gpio_4bit2)); - s5p6440_gpio_add_rbank_4bit2(gpio_rbank_4bit2, - ARRAY_SIZE(gpio_rbank_4bit2)); + s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2, + ARRAY_SIZE(s5p6440_gpio_rbank_4bit2)); return 0; } diff --git a/arch/arm/mach-s5p64x0/include/mach/debug-macro.S b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S new file mode 100644 index 000000000000..79b04e6a6f8e --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S @@ -0,0 +1,33 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/debug-macro.S + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/* pull in the relevant register and map files. */ + +#include <plat/map-base.h> +#include <plat/map-s5p.h> + +#include <plat/regs-serial.h> + + .macro addruart, rp, rv + mov \rp, #0xE0000000 + orr \rp, \rp, #0x00100000 + ldr \rp, [\rp, #0x118 ] + and \rp, \rp, #0xff000 + teq \rp, #0x50000 @@ S5P6450 + ldreq \rp, =0xEC800000 + movne \rp, #0xEC000000 @@ S5P6440 + ldrne \rv, = S3C_VA_UART +#if CONFIG_DEBUG_S3C_UART != 0 + add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART) + add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART) +#endif + .endm + +#include <plat/debug-macro.S> diff --git a/arch/arm/mach-s5p6440/include/mach/dma.h b/arch/arm/mach-s5p64x0/include/mach/dma.h index 81209eb1409b..81209eb1409b 100644 --- a/arch/arm/mach-s5p6440/include/mach/dma.h +++ b/arch/arm/mach-s5p64x0/include/mach/dma.h diff --git a/arch/arm/mach-s5p6440/include/mach/entry-macro.S b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S index e65f1b967262..10b62b4f8211 100644 --- a/arch/arm/mach-s5p6440/include/mach/entry-macro.S +++ b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S @@ -1,9 +1,9 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/entry-macro.S +/* linux/arch/arm/mach-s5p64x0/include/mach/entry-macro.S * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * Low-level IRQ helper macros for the Samsung S5P6440 + * Low-level IRQ helper macros for the Samsung S5P64X0 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/arch/arm/mach-s5p64x0/include/mach/gpio.h b/arch/arm/mach-s5p64x0/include/mach/gpio.h new file mode 100644 index 000000000000..5486c8f01f1d --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/gpio.h @@ -0,0 +1,139 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/gpio.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - GPIO lib support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H __FILE__ + +#define gpio_get_value __gpio_get_value +#define gpio_set_value __gpio_set_value +#define gpio_cansleep __gpio_cansleep +#define gpio_to_irq __gpio_to_irq + +/* GPIO bank sizes */ + +#define S5P6440_GPIO_A_NR (6) +#define S5P6440_GPIO_B_NR (7) +#define S5P6440_GPIO_C_NR (8) +#define S5P6440_GPIO_F_NR (2) +#define S5P6440_GPIO_G_NR (7) +#define S5P6440_GPIO_H_NR (10) +#define S5P6440_GPIO_I_NR (16) +#define S5P6440_GPIO_J_NR (12) +#define S5P6440_GPIO_N_NR (16) +#define S5P6440_GPIO_P_NR (8) +#define S5P6440_GPIO_R_NR (15) + +#define S5P6450_GPIO_A_NR (6) +#define S5P6450_GPIO_B_NR (7) +#define S5P6450_GPIO_C_NR (8) +#define S5P6450_GPIO_D_NR (8) +#define S5P6450_GPIO_F_NR (2) +#define S5P6450_GPIO_G_NR (14) +#define S5P6450_GPIO_H_NR (10) +#define S5P6450_GPIO_I_NR (16) +#define S5P6450_GPIO_J_NR (12) +#define S5P6450_GPIO_K_NR (5) +#define S5P6450_GPIO_N_NR (16) +#define S5P6450_GPIO_P_NR (11) +#define S5P6450_GPIO_Q_NR (14) +#define S5P6450_GPIO_R_NR (15) +#define S5P6450_GPIO_S_NR (8) + +/* GPIO bank numbers */ + +/* CONFIG_S3C_GPIO_SPACE allows the user to select extra + * space for debugging purposes so that any accidental + * change from one gpio bank to another can be caught. +*/ + +#define S5P64X0_GPIO_NEXT(__gpio) \ + ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) + +enum s5p6440_gpio_number { + S5P6440_GPIO_A_START = 0, + S5P6440_GPIO_B_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_A), + S5P6440_GPIO_C_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_B), + S5P6440_GPIO_F_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_C), + S5P6440_GPIO_G_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_F), + S5P6440_GPIO_H_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_G), + S5P6440_GPIO_I_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_H), + S5P6440_GPIO_J_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_I), + S5P6440_GPIO_N_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_J), + S5P6440_GPIO_P_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_N), + S5P6440_GPIO_R_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_P), +}; + +enum s5p6450_gpio_number { + S5P6450_GPIO_A_START = 0, + S5P6450_GPIO_B_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_A), + S5P6450_GPIO_C_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_B), + S5P6450_GPIO_D_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_C), + S5P6450_GPIO_F_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_D), + S5P6450_GPIO_G_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_F), + S5P6450_GPIO_H_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_G), + S5P6450_GPIO_I_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_H), + S5P6450_GPIO_J_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_I), + S5P6450_GPIO_K_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_J), + S5P6450_GPIO_N_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_K), + S5P6450_GPIO_P_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_N), + S5P6450_GPIO_Q_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_P), + S5P6450_GPIO_R_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_Q), + S5P6450_GPIO_S_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_R), +}; + +/* GPIO number definitions */ + +#define S5P6440_GPA(_nr) (S5P6440_GPIO_A_START + (_nr)) +#define S5P6440_GPB(_nr) (S5P6440_GPIO_B_START + (_nr)) +#define S5P6440_GPC(_nr) (S5P6440_GPIO_C_START + (_nr)) +#define S5P6440_GPF(_nr) (S5P6440_GPIO_F_START + (_nr)) +#define S5P6440_GPG(_nr) (S5P6440_GPIO_G_START + (_nr)) +#define S5P6440_GPH(_nr) (S5P6440_GPIO_H_START + (_nr)) +#define S5P6440_GPI(_nr) (S5P6440_GPIO_I_START + (_nr)) +#define S5P6440_GPJ(_nr) (S5P6440_GPIO_J_START + (_nr)) +#define S5P6440_GPN(_nr) (S5P6440_GPIO_N_START + (_nr)) +#define S5P6440_GPP(_nr) (S5P6440_GPIO_P_START + (_nr)) +#define S5P6440_GPR(_nr) (S5P6440_GPIO_R_START + (_nr)) + +#define S5P6450_GPA(_nr) (S5P6450_GPIO_A_START + (_nr)) +#define S5P6450_GPB(_nr) (S5P6450_GPIO_B_START + (_nr)) +#define S5P6450_GPC(_nr) (S5P6450_GPIO_C_START + (_nr)) +#define S5P6450_GPD(_nr) (S5P6450_GPIO_D_START + (_nr)) +#define S5P6450_GPF(_nr) (S5P6450_GPIO_F_START + (_nr)) +#define S5P6450_GPG(_nr) (S5P6450_GPIO_G_START + (_nr)) +#define S5P6450_GPH(_nr) (S5P6450_GPIO_H_START + (_nr)) +#define S5P6450_GPI(_nr) (S5P6450_GPIO_I_START + (_nr)) +#define S5P6450_GPJ(_nr) (S5P6450_GPIO_J_START + (_nr)) +#define S5P6450_GPK(_nr) (S5P6450_GPIO_K_START + (_nr)) +#define S5P6450_GPN(_nr) (S5P6450_GPIO_N_START + (_nr)) +#define S5P6450_GPP(_nr) (S5P6450_GPIO_P_START + (_nr)) +#define S5P6450_GPQ(_nr) (S5P6450_GPIO_Q_START + (_nr)) +#define S5P6450_GPR(_nr) (S5P6450_GPIO_R_START + (_nr)) +#define S5P6450_GPS(_nr) (S5P6450_GPIO_S_START + (_nr)) + +/* the end of the S5P64X0 specific gpios */ + +#define S5P6440_GPIO_END (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1) +#define S5P6450_GPIO_END (S5P6450_GPS(S5P6450_GPIO_S_NR) + 1) + +#define S5P64X0_GPIO_END (S5P6440_GPIO_END > S5P6450_GPIO_END ? \ + S5P6440_GPIO_END : S5P6450_GPIO_END) + +#define S3C_GPIO_END S5P64X0_GPIO_END + +/* define the number of gpios we need to the one after the last GPIO range */ + +#define ARCH_NR_GPIOS (S5P64X0_GPIO_END + CONFIG_SAMSUNG_GPIO_EXTRA) + +#include <asm-generic/gpio.h> + +#endif /* __ASM_ARCH_GPIO_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/hardware.h b/arch/arm/mach-s5p64x0/include/mach/hardware.h index be8b26e875db..d3e87996dd9a 100644 --- a/arch/arm/mach-s5p6440/include/mach/hardware.h +++ b/arch/arm/mach-s5p64x0/include/mach/hardware.h @@ -1,9 +1,9 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/hardware.h +/* linux/arch/arm/mach-s5p64x0/include/mach/hardware.h * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * S5P6440 - Hardware support + * S5P64X0 - Hardware support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/arch/arm/mach-s5p64x0/include/mach/i2c.h b/arch/arm/mach-s5p64x0/include/mach/i2c.h new file mode 100644 index 000000000000..887d25209e8e --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/i2c.h @@ -0,0 +1,17 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/i2c.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 I2C configuration + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +extern void s5p6440_i2c0_cfg_gpio(struct platform_device *dev); +extern void s5p6440_i2c1_cfg_gpio(struct platform_device *dev); + +extern void s5p6450_i2c0_cfg_gpio(struct platform_device *dev); +extern void s5p6450_i2c1_cfg_gpio(struct platform_device *dev); diff --git a/arch/arm/mach-s5p64x0/include/mach/io.h b/arch/arm/mach-s5p64x0/include/mach/io.h new file mode 100644 index 000000000000..a3e095c02fb5 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/io.h @@ -0,0 +1,25 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/io.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright 2008 Simtec Electronics + * Ben Dooks <ben-linux@fluff.org> + * + * Default IO routines for S5P64X0 based + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +/* No current ISA/PCI bus support. */ +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#define IO_SPACE_LIMIT (0xFFFFFFFF) + +#endif diff --git a/arch/arm/mach-s5p6440/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h index 16a761270de1..513abffc7604 100644 --- a/arch/arm/mach-s5p6440/include/mach/irqs.h +++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h @@ -1,17 +1,17 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/irqs.h +/* linux/arch/arm/mach-s5p64x0/include/mach/irqs.h * - * Copyright 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * S5P6440 - IRQ definitions + * S5P64X0 - IRQ definitions * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifndef __ASM_ARCH_S5P_IRQS_H -#define __ASM_ARCH_S5P_IRQS_H __FILE__ +#ifndef __ASM_ARCH_IRQS_H +#define __ASM_ARCH_IRQS_H __FILE__ #include <plat/irqs.h> @@ -20,10 +20,12 @@ #define IRQ_EINT0_3 S5P_IRQ_VIC0(0) #define IRQ_EINT4_11 S5P_IRQ_VIC0(1) #define IRQ_RTC_TIC S5P_IRQ_VIC0(2) +#define IRQ_IIS1 S5P_IRQ_VIC0(3) /* for only S5P6450 */ +#define IRQ_IIS2 S5P_IRQ_VIC0(4) /* for only S5P6450 */ #define IRQ_IIC1 S5P_IRQ_VIC0(5) #define IRQ_I2SV40 S5P_IRQ_VIC0(6) -#define IRQ_GPS S5P_IRQ_VIC0(7) -#define IRQ_POST0 S5P_IRQ_VIC0(9) +#define IRQ_GPS S5P_IRQ_VIC0(7) /* for only S5P6450 */ + #define IRQ_2D S5P_IRQ_VIC0(11) #define IRQ_TIMER0_VIC S5P_IRQ_VIC0(23) #define IRQ_TIMER1_VIC S5P_IRQ_VIC0(24) @@ -39,22 +41,26 @@ #define IRQ_EINT12_15 S5P_IRQ_VIC1(0) #define IRQ_PCM0 S5P_IRQ_VIC1(2) +#define IRQ_PCM1 S5P_IRQ_VIC1(3) /* for only S5P6450 */ +#define IRQ_PCM2 S5P_IRQ_VIC1(4) /* for only S5P6450 */ #define IRQ_UART0 S5P_IRQ_VIC1(5) #define IRQ_UART1 S5P_IRQ_VIC1(6) #define IRQ_UART2 S5P_IRQ_VIC1(7) #define IRQ_UART3 S5P_IRQ_VIC1(8) #define IRQ_DMA0 S5P_IRQ_VIC1(9) +#define IRQ_UART4 S5P_IRQ_VIC1(10) /* S5P6450 */ +#define IRQ_UART5 S5P_IRQ_VIC1(11) /* S5P6450 */ #define IRQ_NFC S5P_IRQ_VIC1(13) +#define IRQ_USI S5P_IRQ_VIC1(15) /* S5P6450 */ #define IRQ_SPI0 S5P_IRQ_VIC1(16) #define IRQ_SPI1 S5P_IRQ_VIC1(17) +#define IRQ_HSMMC2 S5P_IRQ_VIC1(17) /* Shared */ #define IRQ_IIC S5P_IRQ_VIC1(18) #define IRQ_DISPCON3 S5P_IRQ_VIC1(19) -#define IRQ_FIMGVG S5P_IRQ_VIC1(20) #define IRQ_EINT_GROUPS S5P_IRQ_VIC1(21) -#define IRQ_PMU S5P_IRQ_VIC1(23) +#define IRQ_PMU S5P_IRQ_VIC1(23) /* S5P6440 */ #define IRQ_HSMMC0 S5P_IRQ_VIC1(24) #define IRQ_HSMMC1 S5P_IRQ_VIC1(25) -#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */ #define IRQ_OTG S5P_IRQ_VIC1(26) #define IRQ_DSI S5P_IRQ_VIC1(27) #define IRQ_RTC_ALARM S5P_IRQ_VIC1(28) @@ -63,6 +69,24 @@ #define IRQ_TC IRQ_PENDN #define IRQ_ADC S5P_IRQ_VIC1(31) +/* UART interrupts, S5P6450 has 5 UARTs */ +#define IRQ_S5P_UART_BASE4 (96) +#define IRQ_S5P_UART_BASE5 (100) + +#define IRQ_S5P_UART_RX4 (IRQ_S5P_UART_BASE4 + UART_IRQ_RXD) +#define IRQ_S5P_UART_TX4 (IRQ_S5P_UART_BASE4 + UART_IRQ_TXD) +#define IRQ_S5P_UART_ERR4 (IRQ_S5P_UART_BASE4 + UART_IRQ_ERR) + +#define IRQ_S5P_UART_RX5 (IRQ_S5P_UART_BASE5 + UART_IRQ_RXD) +#define IRQ_S5P_UART_TX5 (IRQ_S5P_UART_BASE5 + UART_IRQ_TXD) +#define IRQ_S5P_UART_ERR5 (IRQ_S5P_UART_BASE5 + UART_IRQ_ERR) + +/* S3C compatibilty defines */ +#define IRQ_S3CUART_RX4 IRQ_S5P_UART_RX4 +#define IRQ_S3CUART_RX5 IRQ_S5P_UART_RX5 + +/* S5P6450 EINT feature will be added */ + /* * Since the IRQ_EINT(x) are a linear mapping on s5p6440 we just defined * them as an IRQ_EINT(x) macro from S5P_IRQ_EINT_BASE which we place @@ -115,4 +139,4 @@ #define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1) -#endif /* __ASM_ARCH_S5P_IRQS_H */ +#endif /* __ASM_ARCH_IRQS_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h new file mode 100644 index 000000000000..31e534156e06 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/map.h @@ -0,0 +1,83 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/map.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Memory map definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_MAP_H +#define __ASM_ARCH_MAP_H __FILE__ + +#include <plat/map-base.h> +#include <plat/map-s5p.h> + +#define S5P64X0_PA_SDRAM (0x20000000) + +#define S5P64X0_PA_CHIPID (0xE0000000) +#define S5P_PA_CHIPID S5P64X0_PA_CHIPID + +#define S5P64X0_PA_SYSCON (0xE0100000) +#define S5P_PA_SYSCON S5P64X0_PA_SYSCON + +#define S5P64X0_PA_GPIO (0xE0308000) + +#define S5P64X0_PA_VIC0 (0xE4000000) +#define S5P64X0_PA_VIC1 (0xE4100000) + +#define S5P64X0_PA_PDMA (0xE9000000) + +#define S5P64X0_PA_TIMER (0xEA000000) +#define S5P_PA_TIMER S5P64X0_PA_TIMER + +#define S5P64X0_PA_RTC (0xEA100000) + +#define S5P64X0_PA_WDT (0xEA200000) + +#define S5P6440_PA_UART(x) (0xEC000000 + ((x) * S3C_UART_OFFSET)) +#define S5P6450_PA_UART(x) ((x < 5) ? (0xEC800000 + ((x) * S3C_UART_OFFSET)) : (0xEC000000)) + +#define S5P_PA_UART0 S5P6450_PA_UART(0) +#define S5P_PA_UART1 S5P6450_PA_UART(1) +#define S5P_PA_UART2 S5P6450_PA_UART(2) +#define S5P_PA_UART3 S5P6450_PA_UART(3) +#define S5P_PA_UART4 S5P6450_PA_UART(4) +#define S5P_PA_UART5 S5P6450_PA_UART(5) + +#define S5P_SZ_UART SZ_256 + +#define S5P6440_PA_IIC0 (0xEC104000) +#define S5P6440_PA_IIC1 (0xEC20F000) +#define S5P6450_PA_IIC0 (0xEC100000) +#define S5P6450_PA_IIC1 (0xEC200000) + +#define S5P64X0_PA_SPI0 (0xEC400000) +#define S5P64X0_PA_SPI1 (0xEC500000) + +#define S5P64X0_PA_HSOTG (0xED100000) + +#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000)) + +#define S5P64X0_PA_I2S (0xF2000000) + +#define S5P64X0_PA_PCM (0xF2100000) + +#define S5P64X0_PA_ADC (0xF3000000) + +/* compatibiltiy defines. */ + +#define S3C_PA_HSMMC0 S5P64X0_PA_HSMMC(0) +#define S3C_PA_HSMMC1 S5P64X0_PA_HSMMC(1) +#define S3C_PA_HSMMC2 S5P64X0_PA_HSMMC(2) +#define S3C_PA_IIC S5P6440_PA_IIC0 +#define S3C_PA_IIC1 S5P6440_PA_IIC1 +#define S3C_PA_RTC S5P64X0_PA_RTC +#define S3C_PA_WDT S5P64X0_PA_WDT + +#define SAMSUNG_PA_ADC S5P64X0_PA_ADC + +#endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/memory.h b/arch/arm/mach-s5p64x0/include/mach/memory.h index d62910c71b56..1b036b0a24ce 100644 --- a/arch/arm/mach-s5p6440/include/mach/memory.h +++ b/arch/arm/mach-s5p64x0/include/mach/memory.h @@ -1,9 +1,9 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/memory.h +/* linux/arch/arm/mach-s5p64x0/include/mach/memory.h * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * S5P6440 - Memory definitions + * S5P64X0 - Memory definitions * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -11,9 +11,9 @@ */ #ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H __FILE__ -#define PHYS_OFFSET UL(0x20000000) +#define PHYS_OFFSET UL(0x20000000) #define CONSISTENT_DMA_SIZE SZ_8M #endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h b/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h index 6a2a02fdf12a..19fff8b701c0 100644 --- a/arch/arm/mach-s5p6440/include/mach/pwm-clock.h +++ b/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h @@ -1,16 +1,14 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h +/* linux/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * http://armlinux.simtec.co.uk/ * - * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h - * - * S5P6440 - pwm clock and timer support + * S5P64X0 - pwm clock and timer support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h new file mode 100644 index 000000000000..58e1bc813804 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h @@ -0,0 +1,63 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/regs-clock.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Clock register definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_REGS_CLOCK_H +#define __ASM_ARCH_REGS_CLOCK_H __FILE__ + +#include <mach/map.h> + +#define S5P_CLKREG(x) (S3C_VA_SYS + (x)) + +#define S5P64X0_APLL_CON S5P_CLKREG(0x0C) +#define S5P64X0_MPLL_CON S5P_CLKREG(0x10) +#define S5P64X0_EPLL_CON S5P_CLKREG(0x14) +#define S5P64X0_EPLL_CON_K S5P_CLKREG(0x18) + +#define S5P64X0_CLK_SRC0 S5P_CLKREG(0x1C) + +#define S5P64X0_CLK_DIV0 S5P_CLKREG(0x20) +#define S5P64X0_CLK_DIV1 S5P_CLKREG(0x24) +#define S5P64X0_CLK_DIV2 S5P_CLKREG(0x28) + +#define S5P64X0_CLK_GATE_HCLK0 S5P_CLKREG(0x30) +#define S5P64X0_CLK_GATE_PCLK S5P_CLKREG(0x34) +#define S5P64X0_CLK_GATE_SCLK0 S5P_CLKREG(0x38) +#define S5P64X0_CLK_GATE_MEM0 S5P_CLKREG(0x3C) + +#define S5P64X0_CLK_DIV3 S5P_CLKREG(0x40) + +#define S5P64X0_CLK_GATE_HCLK1 S5P_CLKREG(0x44) +#define S5P64X0_CLK_GATE_SCLK1 S5P_CLKREG(0x48) + +#define S5P6450_DPLL_CON S5P_CLKREG(0x50) +#define S5P6450_DPLL_CON_K S5P_CLKREG(0x54) + +#define S5P64X0_CLK_SRC1 S5P_CLKREG(0x10C) + +#define S5P64X0_SYS_ID S5P_CLKREG(0x118) +#define S5P64X0_SYS_OTHERS S5P_CLKREG(0x11C) + +#define S5P64X0_PWR_CFG S5P_CLKREG(0x804) +#define S5P64X0_OTHERS S5P_CLKREG(0x900) + +#define S5P64X0_CLKDIV0_HCLK_SHIFT (8) +#define S5P64X0_CLKDIV0_HCLK_MASK (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT) + +#define S5P64X0_OTHERS_USB_SIG_MASK (1 << 16) + +/* Compatibility defines */ + +#define ARM_CLK_DIV S5P64X0_CLK_DIV0 +#define ARM_DIV_RATIO_SHIFT 0 +#define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT) + +#endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h index 82ff753913da..85f448e20a8b 100644 --- a/arch/arm/mach-s5p6440/include/mach/regs-gpio.h +++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h @@ -1,21 +1,24 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/regs-gpio.h +/* linux/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * S5P6440 - GPIO register definitions + * S5P64X0 - GPIO register definitions * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - */ +*/ #ifndef __ASM_ARCH_REGS_GPIO_H #define __ASM_ARCH_REGS_GPIO_H __FILE__ #include <mach/map.h> +/* Will be implemented S5P6442 GPIOlib */ + /* Base addresses for each of the banks */ + #define S5P6440_GPA_BASE (S5P_VA_GPIO + 0x0000) #define S5P6440_GPB_BASE (S5P_VA_GPIO + 0x0020) #define S5P6440_GPC_BASE (S5P_VA_GPIO + 0x0040) @@ -27,6 +30,7 @@ #define S5P6440_GPN_BASE (S5P_VA_GPIO + 0x0830) #define S5P6440_GPP_BASE (S5P_VA_GPIO + 0x0160) #define S5P6440_GPR_BASE (S5P_VA_GPIO + 0x0290) + #define S5P6440_EINT0CON0 (S5P_VA_GPIO + 0x900) #define S5P6440_EINT0FLTCON0 (S5P_VA_GPIO + 0x910) #define S5P6440_EINT0FLTCON1 (S5P_VA_GPIO + 0x914) @@ -34,19 +38,23 @@ #define S5P6440_EINT0PEND (S5P_VA_GPIO + 0x924) /* for LCD */ + #define S5P6440_SPCON_LCD_SEL_RGB (1 << 0) #define S5P6440_SPCON_LCD_SEL_MASK (3 << 0) -/* These set of macros are not really useful for the - * GPF/GPI/GPJ/GPN/GPP, - * useful for others set of GPIO's (4 bit) +/* + * These set of macros are not really useful for the + * GPF/GPI/GPJ/GPN/GPP, useful for others set of GPIO's (4 bit) */ + #define S5P6440_GPIO_CONMASK(__gpio) (0xf << ((__gpio) * 4)) #define S5P6440_GPIO_INPUT(__gpio) (0x0 << ((__gpio) * 4)) #define S5P6440_GPIO_OUTPUT(__gpio) (0x1 << ((__gpio) * 4)) -/* Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit) - * */ +/* + * Use these macros for GPF/GPI/GPJ/GPN/GPP set of GPIO (2 bit) + */ + #define S5P6440_GPIO2_CONMASK(__gpio) (0x3 << ((__gpio) * 2)) #define S5P6440_GPIO2_INPUT(__gpio) (0x0 << ((__gpio) * 2)) #define S5P6440_GPIO2_OUTPUT(__gpio) (0x1 << ((__gpio) * 2)) diff --git a/arch/arm/mach-s5p6440/include/mach/regs-irq.h b/arch/arm/mach-s5p64x0/include/mach/regs-irq.h index a961f4beeb0c..4aaebdace55f 100644 --- a/arch/arm/mach-s5p6440/include/mach/regs-irq.h +++ b/arch/arm/mach-s5p64x0/include/mach/regs-irq.h @@ -1,9 +1,9 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/regs-irq.h +/* linux/arch/arm/mach-s5p64x0/include/mach/regs-irq.h * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * S5P6440 - IRQ register definitions + * S5P64X0 - IRQ register definitions * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h new file mode 100644 index 000000000000..ff85b4b6e8d9 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h @@ -0,0 +1,46 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Header file for s5p64x0 clock support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_CLOCK_H +#define __ASM_ARCH_CLOCK_H __FILE__ + +#include <linux/clk.h> + +extern struct clksrc_clk clk_mout_apll; +extern struct clksrc_clk clk_mout_mpll; +extern struct clksrc_clk clk_mout_epll; + +extern int s5p64x0_epll_enable(struct clk *clk, int enable); +extern unsigned long s5p64x0_epll_get_rate(struct clk *clk); + +extern unsigned long s5p64x0_armclk_get_rate(struct clk *clk); +extern unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate); +extern int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate); + +extern struct clk_ops s5p64x0_clkarm_ops; + +extern struct clksrc_clk clk_armclk; +extern struct clksrc_clk clk_dout_mpll; + +extern struct clk *clkset_hclk_low_list[]; +extern struct clksrc_sources clkset_hclk_low; + +extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable); +extern int s5p64x0_hclk0_ctrl(struct clk *clk, int enable); +extern int s5p64x0_hclk1_ctrl(struct clk *clk, int enable); +extern int s5p64x0_sclk_ctrl(struct clk *clk, int enable); +extern int s5p64x0_sclk1_ctrl(struct clk *clk, int enable); +extern int s5p64x0_mem_ctrl(struct clk *clk, int enable); + +extern int s5p64x0_clk48m_ctrl(struct clk *clk, int enable); + +#endif /* __ASM_ARCH_CLOCK_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h b/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h new file mode 100644 index 000000000000..170a20a9643a --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h @@ -0,0 +1,20 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_SPI_CLKS_H +#define __ASM_ARCH_SPI_CLKS_H __FILE__ + +#define S5P64X0_SPI_SRCCLK_PCLK 0 +#define S5P64X0_SPI_SRCCLK_SCLK 1 + +#endif /* __ASM_ARCH_SPI_CLKS_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h index a359ee3fa510..60f57532c970 100644 --- a/arch/arm/mach-s5p6440/include/mach/system.h +++ b/arch/arm/mach-s5p64x0/include/mach/system.h @@ -1,9 +1,9 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/system.h +/* linux/arch/arm/mach-s5p64x0/include/mach/system.h * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * S5P6440 - system support header + * S5P64X0 - system support header * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/arch/arm/mach-s5p6440/include/mach/tick.h b/arch/arm/mach-s5p64x0/include/mach/tick.h index 2f25c7f07970..00aa7f1d8e51 100644 --- a/arch/arm/mach-s5p6440/include/mach/tick.h +++ b/arch/arm/mach-s5p64x0/include/mach/tick.h @@ -1,9 +1,14 @@ -/* linux/arch/arm/mach-s5p6440/include/mach/tick.h +/* linux/arch/arm/mach-s5p64x0/include/mach/tick.h * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * - * S5P6440 - Timer tick support definitions + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * S5P64X0 - Timer tick support definitions * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/arch/arm/mach-s5p6440/include/mach/timex.h b/arch/arm/mach-s5p64x0/include/mach/timex.h index fb2e8cd40829..4b91faa195a8 100644 --- a/arch/arm/mach-s5p6440/include/mach/timex.h +++ b/arch/arm/mach-s5p64x0/include/mach/timex.h @@ -1,9 +1,12 @@ -/* arch/arm/mach-s3c64xx/include/mach/timex.h +/* linux/arch/arm/mach-s5p64x0/include/mach/timex.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * Copyright (c) 2003-2005 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * - * S3C6400 - time parameters + * S5P64X0 - time parameters * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/arch/arm/mach-s5p64x0/include/mach/uncompress.h b/arch/arm/mach-s5p64x0/include/mach/uncompress.h new file mode 100644 index 000000000000..c65b229aab23 --- /dev/null +++ b/arch/arm/mach-s5p64x0/include/mach/uncompress.h @@ -0,0 +1,212 @@ +/* linux/arch/arm/mach-s5p64x0/include/mach/uncompress.h + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - uncompress code + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __ASM_ARCH_UNCOMPRESS_H +#define __ASM_ARCH_UNCOMPRESS_H + +#include <mach/map.h> + +/* + * cannot use commonly <plat/uncompress.h> + * because uart base of S5P6440 and S5P6450 is different + */ + +typedef unsigned int upf_t; /* cannot include linux/serial_core.h */ + +/* uart setup */ + +static unsigned int fifo_mask; +static unsigned int fifo_max; + +/* forward declerations */ + +static void arch_detect_cpu(void); + +/* defines for UART registers */ + +#include <plat/regs-serial.h> +#include <plat/regs-watchdog.h> + +/* working in physical space... */ +#undef S3C2410_WDOGREG +#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x))) + +/* how many bytes we allow into the FIFO at a time in FIFO mode */ +#define FIFO_MAX (14) + +static unsigned long uart_base; + +static __inline__ void get_uart_base(void) +{ + unsigned int chipid; + + chipid = *(const volatile unsigned int __force *) 0xE0100118; + + uart_base = S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT; + + if ((chipid & 0xff000) == 0x50000) + uart_base += 0xEC800000; + else + uart_base += 0xEC000000; +} + +static __inline__ void uart_wr(unsigned int reg, unsigned int val) +{ + volatile unsigned int *ptr; + + get_uart_base(); + ptr = (volatile unsigned int *)(reg + uart_base); + *ptr = val; +} + +static __inline__ unsigned int uart_rd(unsigned int reg) +{ + volatile unsigned int *ptr; + + get_uart_base(); + ptr = (volatile unsigned int *)(reg + uart_base); + return *ptr; +} + +/* + * we can deal with the case the UARTs are being run + * in FIFO mode, so that we don't hold up our execution + * waiting for tx to happen... + */ + +static void putc(int ch) +{ + if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) { + int level; + + while (1) { + level = uart_rd(S3C2410_UFSTAT); + level &= fifo_mask; + + if (level < fifo_max) + break; + } + + } else { + /* not using fifos */ + + while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE) + barrier(); + } + + /* write byte to transmission register */ + uart_wr(S3C2410_UTXH, ch); +} + +static inline void flush(void) +{ +} + +#define __raw_writel(d, ad) \ + do { \ + *((volatile unsigned int __force *)(ad)) = (d); \ + } while (0) + +/* + * CONFIG_S3C_BOOT_WATCHDOG + * + * Simple boot-time watchdog setup, to reboot the system if there is + * any problem with the boot process + */ + +#ifdef CONFIG_S3C_BOOT_WATCHDOG + +#define WDOG_COUNT (0xff00) + +static inline void arch_decomp_wdog(void) +{ + __raw_writel(WDOG_COUNT, S3C2410_WTCNT); +} + +static void arch_decomp_wdog_start(void) +{ + __raw_writel(WDOG_COUNT, S3C2410_WTDAT); + __raw_writel(WDOG_COUNT, S3C2410_WTCNT); + __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON); +} + +#else +#define arch_decomp_wdog_start() +#define arch_decomp_wdog() +#endif + +#ifdef CONFIG_S3C_BOOT_ERROR_RESET + +static void arch_decomp_error(const char *x) +{ + putstr("\n\n"); + putstr(x); + putstr("\n\n -- System resetting\n"); + + __raw_writel(0x4000, S3C2410_WTDAT); + __raw_writel(0x4000, S3C2410_WTCNT); + __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON); + + while(1); +} + +#define arch_error arch_decomp_error +#endif + +#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO +static inline void arch_enable_uart_fifo(void) +{ + u32 fifocon = uart_rd(S3C2410_UFCON); + + if (!(fifocon & S3C2410_UFCON_FIFOMODE)) { + fifocon |= S3C2410_UFCON_RESETBOTH; + uart_wr(S3C2410_UFCON, fifocon); + + /* wait for fifo reset to complete */ + while (1) { + fifocon = uart_rd(S3C2410_UFCON); + if (!(fifocon & S3C2410_UFCON_RESETBOTH)) + break; + } + } +} +#else +#define arch_enable_uart_fifo() do { } while(0) +#endif + +static void arch_decomp_setup(void) +{ + /* + * we may need to setup the uart(s) here if we are not running + * on an BAST... the BAST will have left the uarts configured + * after calling linux. + */ + + arch_detect_cpu(); + arch_decomp_wdog_start(); + + /* + * Enable the UART FIFOs if they where not enabled and our + * configuration says we should turn them on. + */ + + arch_enable_uart_fifo(); +} + + + +static void arch_detect_cpu(void) +{ + /* we do not need to do any cpu detection here at the moment. */ +} + +#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-s5p6440/include/mach/vmalloc.h b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h index e3f0eebf5205..97a9df38f1cf 100644 --- a/arch/arm/mach-s5p6440/include/mach/vmalloc.h +++ b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h @@ -1,4 +1,7 @@ -/* arch/arm/mach-s5p6440/include/mach/vmalloc.h +/* linux/arch/arm/mach-s5p64x0/include/mach/vmalloc.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * Copyright 2010 Ben Dooks <ben-linux@fluff.org> * diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c new file mode 100644 index 000000000000..79833caf8165 --- /dev/null +++ b/arch/arm/mach-s5p64x0/init.c @@ -0,0 +1,73 @@ +/* linux/arch/arm/mach-s5p64x0/init.c + * + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5P64X0 - Init support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/serial_core.h> + +#include <mach/map.h> + +#include <plat/cpu.h> +#include <plat/devs.h> +#include <plat/s5p6440.h> +#include <plat/s5p6450.h> +#include <plat/regs-serial.h> + +static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = { + [0] = { + .name = "pclk_low", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, + [1] = { + .name = "uclk1", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, +}; + +/* uart registration process */ + +void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + struct s3c2410_uartcfg *tcfg = cfg; + u32 ucnt; + + for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { + if (!tcfg->clocks) { + tcfg->clocks = s5p64x0_serial_clocks; + tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks); + } + } +} + +void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + int uart; + + for (uart = 0; uart < no; uart++) { + s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart); + s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART; + } + + s5p64x0_common_init_uarts(cfg, no); + s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); +} + +void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + s5p64x0_common_init_uarts(cfg, no); + s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); +} diff --git a/arch/arm/mach-s5p6440/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c index 9202aaac3b56..28de0a57208c 100644 --- a/arch/arm/mach-s5p6440/mach-smdk6440.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c @@ -1,7 +1,7 @@ -/* linux/arch/arm/mach-s5p6440/mach-smdk6440.c +/* linux/arch/arm/mach-s5p64x0/mach-smdk6440.c * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -21,21 +21,22 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/clk.h> +#include <linux/gpio.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/irq.h> +#include <asm/mach-types.h> #include <mach/hardware.h> #include <mach/map.h> - -#include <asm/irq.h> -#include <asm/mach-types.h> +#include <mach/regs-clock.h> +#include <mach/i2c.h> #include <plat/regs-serial.h> - +#include <plat/gpio-cfg.h> #include <plat/s5p6440.h> #include <plat/clock.h> -#include <mach/regs-clock.h> #include <plat/devs.h> #include <plat/cpu.h> #include <plat/iic.h> @@ -58,43 +59,60 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = { [0] = { - .hwport = 0, - .flags = 0, - .ucon = SMDK6440_UCON_DEFAULT, - .ulcon = SMDK6440_ULCON_DEFAULT, - .ufcon = SMDK6440_UFCON_DEFAULT, + .hwport = 0, + .flags = 0, + .ucon = SMDK6440_UCON_DEFAULT, + .ulcon = SMDK6440_ULCON_DEFAULT, + .ufcon = SMDK6440_UFCON_DEFAULT, }, [1] = { - .hwport = 1, - .flags = 0, - .ucon = SMDK6440_UCON_DEFAULT, - .ulcon = SMDK6440_ULCON_DEFAULT, - .ufcon = SMDK6440_UFCON_DEFAULT, + .hwport = 1, + .flags = 0, + .ucon = SMDK6440_UCON_DEFAULT, + .ulcon = SMDK6440_ULCON_DEFAULT, + .ufcon = SMDK6440_UFCON_DEFAULT, }, [2] = { - .hwport = 2, - .flags = 0, - .ucon = SMDK6440_UCON_DEFAULT, - .ulcon = SMDK6440_ULCON_DEFAULT, - .ufcon = SMDK6440_UFCON_DEFAULT, + .hwport = 2, + .flags = 0, + .ucon = SMDK6440_UCON_DEFAULT, + .ulcon = SMDK6440_ULCON_DEFAULT, + .ufcon = SMDK6440_UFCON_DEFAULT, }, [3] = { - .hwport = 3, - .flags = 0, - .ucon = SMDK6440_UCON_DEFAULT, - .ulcon = SMDK6440_ULCON_DEFAULT, - .ufcon = SMDK6440_UFCON_DEFAULT, + .hwport = 3, + .flags = 0, + .ucon = SMDK6440_UCON_DEFAULT, + .ulcon = SMDK6440_ULCON_DEFAULT, + .ufcon = SMDK6440_UFCON_DEFAULT, }, }; static struct platform_device *smdk6440_devices[] __initdata = { - &s5p6440_device_iis, &s3c_device_adc, &s3c_device_rtc, &s3c_device_i2c0, &s3c_device_i2c1, &s3c_device_ts, &s3c_device_wdt, + &s5p6440_device_iis, +}; + +static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = { + .flags = 0, + .slave_addr = 0x10, + .frequency = 100*1000, + .sda_delay = 100, + .cfg_gpio = s5p6440_i2c0_cfg_gpio, +}; + +static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = { + .flags = 0, + .bus_num = 1, + .slave_addr = 0x10, + .frequency = 100*1000, + .sda_delay = 100, + .cfg_gpio = s5p6440_i2c1_cfg_gpio, }; static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = { @@ -113,7 +131,7 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { static void __init smdk6440_map_io(void) { - s5p_init_io(NULL, 0, S5P_SYS_ID); + s5p_init_io(NULL, 0, S5P64X0_SYS_ID); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs)); } @@ -122,9 +140,8 @@ static void __init smdk6440_machine_init(void) { s3c24xx_ts_set_platdata(&s3c_ts_platform); - /* I2C */ - s3c_i2c0_set_platdata(NULL); - s3c_i2c1_set_platdata(NULL); + s3c_i2c0_set_platdata(&s5p6440_i2c0_data); + s3c_i2c1_set_platdata(&s5p6440_i2c1_data); i2c_register_board_info(0, smdk6440_i2c_devs0, ARRAY_SIZE(smdk6440_i2c_devs0)); i2c_register_board_info(1, smdk6440_i2c_devs1, @@ -135,9 +152,9 @@ static void __init smdk6440_machine_init(void) MACHINE_START(SMDK6440, "SMDK6440") /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ - .phys_io = S3C_PA_UART & 0xfff00000, + .phys_io = S5P6440_PA_UART(0) & 0xfff00000, .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc, - .boot_params = S5P_PA_SDRAM + 0x100, + .boot_params = S5P64X0_PA_SDRAM + 0x100, .init_irq = s5p6440_init_irq, .map_io = smdk6440_map_io, diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c new file mode 100644 index 000000000000..8e982171418b --- /dev/null +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c @@ -0,0 +1,182 @@ +/* linux/arch/arm/mach-s5p64x0/mach-smdk6450.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/i2c.h> +#include <linux/serial_core.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/gpio.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <mach/hardware.h> +#include <mach/map.h> +#include <mach/regs-clock.h> +#include <mach/i2c.h> + +#include <plat/regs-serial.h> +#include <plat/gpio-cfg.h> +#include <plat/s5p6450.h> +#include <plat/clock.h> +#include <plat/devs.h> +#include <plat/cpu.h> +#include <plat/iic.h> +#include <plat/pll.h> +#include <plat/adc.h> +#include <plat/ts.h> + +#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ + S3C2410_UCON_RXILEVEL | \ + S3C2410_UCON_TXIRQMODE | \ + S3C2410_UCON_RXIRQMODE | \ + S3C2410_UCON_RXFIFO_TOI | \ + S3C2443_UCON_RXERR_IRQEN) + +#define SMDK6450_ULCON_DEFAULT S3C2410_LCON_CS8 + +#define SMDK6450_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ + S3C2440_UFCON_TXTRIG16 | \ + S3C2410_UFCON_RXTRIG8) + +static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = SMDK6450_UCON_DEFAULT, + .ulcon = SMDK6450_ULCON_DEFAULT, + .ufcon = SMDK6450_UFCON_DEFAULT, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = SMDK6450_UCON_DEFAULT, + .ulcon = SMDK6450_ULCON_DEFAULT, + .ufcon = SMDK6450_UFCON_DEFAULT, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = SMDK6450_UCON_DEFAULT, + .ulcon = SMDK6450_ULCON_DEFAULT, + .ufcon = SMDK6450_UFCON_DEFAULT, + }, + [3] = { + .hwport = 3, + .flags = 0, + .ucon = SMDK6450_UCON_DEFAULT, + .ulcon = SMDK6450_ULCON_DEFAULT, + .ufcon = SMDK6450_UFCON_DEFAULT, + }, +#if CONFIG_SERIAL_SAMSUNG_UARTS > 4 + [4] = { + .hwport = 4, + .flags = 0, + .ucon = SMDK6450_UCON_DEFAULT, + .ulcon = SMDK6450_ULCON_DEFAULT, + .ufcon = SMDK6450_UFCON_DEFAULT, + }, +#endif +#if CONFIG_SERIAL_SAMSUNG_UARTS > 5 + [5] = { + .hwport = 5, + .flags = 0, + .ucon = SMDK6450_UCON_DEFAULT, + .ulcon = SMDK6450_ULCON_DEFAULT, + .ufcon = SMDK6450_UFCON_DEFAULT, + }, +#endif +}; + +static struct platform_device *smdk6450_devices[] __initdata = { + &s3c_device_adc, + &s3c_device_rtc, + &s3c_device_i2c0, + &s3c_device_i2c1, + &s3c_device_ts, + &s3c_device_wdt, + &s5p6450_device_iis0, + /* s5p6450_device_spi0 will be added */ +}; + +static struct s3c2410_platform_i2c s5p6450_i2c0_data __initdata = { + .flags = 0, + .slave_addr = 0x10, + .frequency = 100*1000, + .sda_delay = 100, + .cfg_gpio = s5p6450_i2c0_cfg_gpio, +}; + +static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = { + .flags = 0, + .bus_num = 1, + .slave_addr = 0x10, + .frequency = 100*1000, + .sda_delay = 100, + .cfg_gpio = s5p6450_i2c1_cfg_gpio, +}; + +static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = { + { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */ +}; + +static struct i2c_board_info smdk6450_i2c_devs1[] __initdata = { + { I2C_BOARD_INFO("24c128", 0x57), },/* Samsung S524AD0XD1 EEPROM */ +}; + +static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { + .delay = 10000, + .presc = 49, + .oversampling_shift = 2, +}; + +static void __init smdk6450_map_io(void) +{ + s5p_init_io(NULL, 0, S5P64X0_SYS_ID); + s3c24xx_init_clocks(19200000); + s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs)); +} + +static void __init smdk6450_machine_init(void) +{ + s3c24xx_ts_set_platdata(&s3c_ts_platform); + + s3c_i2c0_set_platdata(&s5p6450_i2c0_data); + s3c_i2c1_set_platdata(&s5p6450_i2c1_data); + i2c_register_board_info(0, smdk6450_i2c_devs0, + ARRAY_SIZE(smdk6450_i2c_devs0)); + i2c_register_board_info(1, smdk6450_i2c_devs1, + ARRAY_SIZE(smdk6450_i2c_devs1)); + + platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices)); +} + +MACHINE_START(SMDK6450, "SMDK6450") + /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ + .phys_io = S5P6450_PA_UART(0) & 0xfff00000, + .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc, + .boot_params = S5P64X0_PA_SDRAM + 0x100, + + .init_irq = s5p6450_init_irq, + .map_io = smdk6450_map_io, + .init_machine = smdk6450_machine_init, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s5p6440/setup-i2c0.c b/arch/arm/mach-s5p64x0/setup-i2c0.c index 2c99d14f7ac7..dc4cc65a5019 100644 --- a/arch/arm/mach-s5p6440/setup-i2c0.c +++ b/arch/arm/mach-s5p64x0/setup-i2c0.c @@ -1,11 +1,11 @@ -/* linux/arch/arm/mach-s5p6440/setup-i2c0.c +/* linux/arch/arm/mach-s5p64x0/setup-i2c0.c * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * I2C0 GPIO configuration. * - * Based on plat-s3c64xx/setup-i2c0.c + * Based on plat-s3c64x0/setup-i2c0.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,17 +14,29 @@ #include <linux/kernel.h> #include <linux/types.h> +#include <linux/gpio.h> struct platform_device; /* don't need the contents */ -#include <linux/gpio.h> #include <plat/gpio-cfg.h> #include <plat/iic.h> -void s3c_i2c0_cfg_gpio(struct platform_device *dev) +#include <mach/i2c.h> + +void s5p6440_i2c0_cfg_gpio(struct platform_device *dev) { s3c_gpio_cfgpin(S5P6440_GPB(5), S3C_GPIO_SFN(2)); s3c_gpio_setpull(S5P6440_GPB(5), S3C_GPIO_PULL_UP); s3c_gpio_cfgpin(S5P6440_GPB(6), S3C_GPIO_SFN(2)); s3c_gpio_setpull(S5P6440_GPB(6), S3C_GPIO_PULL_UP); } + +void s5p6450_i2c0_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgpin(S5P6450_GPB(5), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5P6450_GPB(5), S3C_GPIO_PULL_UP); + s3c_gpio_cfgpin(S5P6450_GPB(6), S3C_GPIO_SFN(2)); + s3c_gpio_setpull(S5P6450_GPB(6), S3C_GPIO_PULL_UP); +} + +void s3c_i2c0_cfg_gpio(struct platform_device *dev) { } diff --git a/arch/arm/mach-s5p6440/setup-i2c1.c b/arch/arm/mach-s5p64x0/setup-i2c1.c index 9a1537f786e0..2edd7912f8e4 100644 --- a/arch/arm/mach-s5p6440/setup-i2c1.c +++ b/arch/arm/mach-s5p64x0/setup-i2c1.c @@ -1,7 +1,7 @@ -/* linux/arch/arm/mach-s5p6440/setup-i2c1.c +/* linux/arch/arm/mach-s5p64xx/setup-i2c1.c * - * Copyright (c) 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * I2C1 GPIO configuration. * @@ -21,10 +21,22 @@ struct platform_device; /* don't need the contents */ #include <plat/gpio-cfg.h> #include <plat/iic.h> -void s3c_i2c1_cfg_gpio(struct platform_device *dev) +#include <mach/i2c.h> + +void s5p6440_i2c1_cfg_gpio(struct platform_device *dev) { s3c_gpio_cfgpin(S5P6440_GPR(9), S3C_GPIO_SFN(6)); s3c_gpio_setpull(S5P6440_GPR(9), S3C_GPIO_PULL_UP); s3c_gpio_cfgpin(S5P6440_GPR(10), S3C_GPIO_SFN(6)); s3c_gpio_setpull(S5P6440_GPR(10), S3C_GPIO_PULL_UP); } + +void s5p6450_i2c1_cfg_gpio(struct platform_device *dev) +{ + s3c_gpio_cfgpin(S5P6450_GPR(9), S3C_GPIO_SFN(6)); + s3c_gpio_setpull(S5P6450_GPR(9), S3C_GPIO_PULL_UP); + s3c_gpio_cfgpin(S5P6450_GPR(10), S3C_GPIO_SFN(6)); + s3c_gpio_setpull(S5P6450_GPR(10), S3C_GPIO_PULL_UP); +} + +void s3c_i2c1_cfg_gpio(struct platform_device *dev) { } diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c index 251c92ac5b22..fd2708e7d8a9 100644 --- a/arch/arm/mach-s5pc100/cpu.c +++ b/arch/arm/mach-s5pc100/cpu.c @@ -1,5 +1,8 @@ /* linux/arch/arm/mach-s5pc100/cpu.c * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * * Copyright 2009 Samsung Electronics Co. * Byungho Min <bhmin@samsung.com> * @@ -21,6 +24,7 @@ #include <linux/sysdev.h> #include <linux/serial_core.h> #include <linux/platform_device.h> +#include <linux/sched.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -56,11 +60,31 @@ static struct map_desc s5pc100_iodesc[] __initdata = { .length = SZ_16K, .type = MT_DEVICE, }, { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5PC100_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5PC100_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5PC100_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, { .virtual = (unsigned long)VA_VIC2, - .pfn = __phys_to_pfn(S5P_PA_VIC2), + .pfn = __phys_to_pfn(S5PC100_PA_VIC2), .length = SZ_16K, .type = MT_DEVICE, }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, + }, { .virtual = (unsigned long)S5PC100_VA_OTHERS, .pfn = __phys_to_pfn(S5PC100_PA_OTHERS), .length = SZ_4K, diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h index 01b9134feff0..8751ef4a6804 100644 --- a/arch/arm/mach-s5pc100/include/mach/map.h +++ b/arch/arm/mach-s5pc100/include/mach/map.h @@ -44,19 +44,16 @@ #define S5PC100_PA_OTHERS (0xE0200000) #define S5PC100_VA_OTHERS (S3C_VA_SYS + 0x10000) -#define S5P_PA_GPIO (0xE0300000) +#define S5PC100_PA_GPIO (0xE0300000) #define S5PC1XX_VA_GPIO S3C_ADDR(0x00500000) /* Interrupt */ -#define S5PC100_PA_VIC (0xE4000000) +#define S5PC100_PA_VIC0 (0xE4000000) +#define S5PC100_PA_VIC1 (0xE4100000) +#define S5PC100_PA_VIC2 (0xE4200000) #define S5PC100_VA_VIC S3C_VA_IRQ -#define S5PC100_PA_VIC_OFFSET 0x100000 #define S5PC100_VA_VIC_OFFSET 0x10000 -#define S5PC1XX_PA_VIC(x) (S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET)) #define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET)) -#define S5P_PA_VIC0 S5PC1XX_PA_VIC(0) -#define S5P_PA_VIC1 S5PC1XX_PA_VIC(1) -#define S5P_PA_VIC2 S5PC1XX_PA_VIC(2) #define S5PC100_PA_ONENAND (0xE7100000) diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index d3a38955c741..5315fec3db86 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -53,11 +53,6 @@ config S5PV210_SETUP_SDHCI_GPIO help Common setup code for SDHCI gpio. -config S5PC110_DEV_ONENAND - bool - help - Compile in platform device definition for OneNAND1 controller - menu "S5PC110 Machines" config MACH_AQUILA @@ -71,7 +66,7 @@ config MACH_AQUILA select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 - select S5PC110_DEV_ONENAND + select S5P_DEV_ONENAND select S5PV210_SETUP_FB_24BPP select S5PV210_SETUP_SDHCI help @@ -88,7 +83,7 @@ config MACH_GONI select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 - select S5PC110_DEV_ONENAND + select S5P_DEV_ONENAND select S5PV210_SETUP_FB_24BPP select S5PV210_SETUP_SDHCI help diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 05048c5aa4c6..704548912408 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_MACH_GONI) += mach-goni.o obj-y += dev-audio.o obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o -obj-$(CONFIG_S5PC110_DEV_ONENAND) += dev-onenand.o obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o obj-$(CONFIG_S5PV210_SETUP_I2C1) += setup-i2c1.o diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index cfecd70657cb..d562670e1b0b 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -173,11 +173,6 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable) return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); } -static int s5pv210_clk_ip4_ctrl(struct clk *clk, int enable) -{ - return s5p_gatectrl(S5P_CLKGATE_IP4, clk, enable); -} - static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable); diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index 77f456c91ad3..2f16bfc0a116 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c @@ -1,7 +1,7 @@ /* linux/arch/arm/mach-s5pv210/cpu.c * * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * http://www.samsung.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -19,6 +19,7 @@ #include <linux/io.h> #include <linux/sysdev.h> #include <linux/platform_device.h> +#include <linux/sched.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -50,6 +51,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE, }, { + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5PV210_PA_GPIO), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC0, + .pfn = __phys_to_pfn(S5PV210_PA_VIC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)VA_VIC1, + .pfn = __phys_to_pfn(S5PV210_PA_VIC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, { .virtual = (unsigned long)VA_VIC2, .pfn = __phys_to_pfn(S5PV210_PA_VIC2), .length = SZ_16K, @@ -60,6 +76,11 @@ static struct map_desc s5pv210_iodesc[] __initdata = { .length = SZ_16K, .type = MT_DEVICE, }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, + }, { .virtual = (unsigned long)S5P_VA_SROMC, .pfn = __phys_to_pfn(S5PV210_PA_SROMC), .length = SZ_4K, diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h index dd4fb6bf14b5..bd9afd52466a 100644 --- a/arch/arm/mach-s5pv210/include/mach/map.h +++ b/arch/arm/mach-s5pv210/include/mach/map.h @@ -17,7 +17,10 @@ #include <plat/map-s5p.h> #define S5PC110_PA_ONENAND (0xB0000000) +#define S5P_PA_ONENAND S5PC110_PA_ONENAND + #define S5PC110_PA_ONENAND_DMA (0xB0600000) +#define S5P_PA_ONENAND_DMA S5PC110_PA_ONENAND_DMA #define S5PV210_PA_CHIPID (0xE0000000) #define S5P_PA_CHIPID S5PV210_PA_CHIPID @@ -26,7 +29,6 @@ #define S5P_PA_SYSCON S5PV210_PA_SYSCON #define S5PV210_PA_GPIO (0xE0200000) -#define S5P_PA_GPIO S5PV210_PA_GPIO /* SPI */ #define S5PV210_PA_SPI0 0xE1300000 @@ -72,16 +74,9 @@ #define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) #define S5PV210_PA_VIC0 (0xF2000000) -#define S5P_PA_VIC0 S5PV210_PA_VIC0 - #define S5PV210_PA_VIC1 (0xF2100000) -#define S5P_PA_VIC1 S5PV210_PA_VIC1 - #define S5PV210_PA_VIC2 (0xF2200000) -#define S5P_PA_VIC2 S5PV210_PA_VIC2 - #define S5PV210_PA_VIC3 (0xF2300000) -#define S5P_PA_VIC3 S5PV210_PA_VIC3 #define S5PV210_PA_SDRAM (0x20000000) #define S5P_PA_SDRAM S5PV210_PA_SDRAM diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c index 0dda8012d6b2..bf772de6b0c3 100644 --- a/arch/arm/mach-s5pv210/mach-aquila.c +++ b/arch/arm/mach-s5pv210/mach-aquila.c @@ -477,7 +477,7 @@ static struct platform_device *aquila_devices[] __initdata = { &aquila_i2c_gpio_pmic, &aquila_device_gpiokeys, &s3c_device_fb, - &s5pc110_device_onenand, + &s5p_device_onenand, &s3c_device_hsmmc0, &s3c_device_hsmmc1, &s3c_device_hsmmc2, diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index 53754d7d364e..fdc5cca4eb41 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c @@ -456,7 +456,7 @@ static void goni_setup_sdhci(void) static struct platform_device *goni_devices[] __initdata = { &s3c_device_fb, - &s5pc110_device_onenand, + &s5p_device_onenand, &goni_i2c_gpio_pmic, &goni_device_gpiokeys, &s5p_device_fimc0, diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index e5b261a99ab2..4add39853ff9 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -31,9 +31,14 @@ extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); /* Initial IO mappings */ static struct map_desc s5pv310_iodesc[] __initdata = { { - .virtual = (unsigned long)S5P_VA_COREPERI_BASE, - .pfn = __phys_to_pfn(S5PV310_PA_COREPERI), - .length = SZ_8K, + .virtual = (unsigned long)S5P_VA_SYSRAM, + .pfn = __phys_to_pfn(S5PV310_PA_SYSRAM), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_CMU, + .pfn = __phys_to_pfn(S5PV310_PA_CMU), + .length = SZ_128K, .type = MT_DEVICE, }, { .virtual = (unsigned long)S5P_VA_COMBINER_BASE, @@ -41,19 +46,24 @@ static struct map_desc s5pv310_iodesc[] __initdata = { .length = SZ_4K, .type = MT_DEVICE, }, { + .virtual = (unsigned long)S5P_VA_COREPERI_BASE, + .pfn = __phys_to_pfn(S5PV310_PA_COREPERI), + .length = SZ_8K, + .type = MT_DEVICE, + }, { .virtual = (unsigned long)S5P_VA_L2CC, .pfn = __phys_to_pfn(S5PV310_PA_L2CC), .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S5P_VA_SYSRAM, - .pfn = __phys_to_pfn(S5PV310_PA_SYSRAM), + .virtual = (unsigned long)S5P_VA_GPIO, + .pfn = __phys_to_pfn(S5PV310_PA_GPIO1), .length = SZ_4K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S5P_VA_CMU, - .pfn = __phys_to_pfn(S5PV310_PA_CMU), - .length = SZ_128K, + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, .type = MT_DEVICE, }, }; diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h index 4cdedda6e652..471fc3bb199a 100644 --- a/arch/arm/mach-s5pv310/include/mach/irqs.h +++ b/arch/arm/mach-s5pv310/include/mach/irqs.h @@ -68,6 +68,8 @@ #define IRQ_IIC COMBINER_IRQ(27, 0) +#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0) + /* Set the default NR_IRQS */ #define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0) diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 213e1101a3b3..aff6d23624bb 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h @@ -25,6 +25,12 @@ #define S5PV310_PA_SYSRAM (0x02025000) +#define S5PC210_PA_ONENAND (0x0C000000) +#define S5P_PA_ONENAND S5PC210_PA_ONENAND + +#define S5PC210_PA_ONENAND_DMA (0x0C600000) +#define S5P_PA_ONENAND_DMA S5PC210_PA_ONENAND_DMA + #define S5PV310_PA_CHIPID (0x10000000) #define S5P_PA_CHIPID S5PV310_PA_CHIPID @@ -46,7 +52,6 @@ #define S5PV310_PA_GPIO1 (0x11400000) #define S5PV310_PA_GPIO2 (0x11000000) #define S5PV310_PA_GPIO3 (0x03860000) -#define S5P_PA_GPIO S5PV310_PA_GPIO1 #define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) diff --git a/arch/arm/mach-shark/include/mach/vmalloc.h b/arch/arm/mach-shark/include/mach/vmalloc.h index f6c6837c5451..8e845b6a7cb5 100644 --- a/arch/arm/mach-shark/include/mach/vmalloc.h +++ b/arch/arm/mach-shark/include/mach/vmalloc.h @@ -1,4 +1,4 @@ /* * arch/arm/mach-shark/include/mach/vmalloc.h */ -#define VMALLOC_END (PAGE_OFFSET + 0x10000000) +#define VMALLOC_END 0xd0000000 diff --git a/arch/arm/mach-tcc8k/Kconfig b/arch/arm/mach-tcc8k/Kconfig new file mode 100644 index 000000000000..ad86415d1577 --- /dev/null +++ b/arch/arm/mach-tcc8k/Kconfig @@ -0,0 +1,11 @@ +if ARCH_TCC8K + +comment "TCC8000 systems:" + +config MACH_TCC8000_SDK + bool "Telechips TCC8000-SDK development kit" + default y + help + Support for the Telechips TCC8000-SDK board. + +endif diff --git a/arch/arm/mach-tcc8k/Makefile b/arch/arm/mach-tcc8k/Makefile new file mode 100644 index 000000000000..9bacf31e49ba --- /dev/null +++ b/arch/arm/mach-tcc8k/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for TCC8K boards and common files. +# + +# Common support +obj-y += clock.o irq.o time.o io.o devices.o + +# Board specific support +obj-$(CONFIG_MACH_TCC8000_SDK) += board-tcc8000-sdk.o diff --git a/arch/arm/mach-tcc8k/Makefile.boot b/arch/arm/mach-tcc8k/Makefile.boot new file mode 100644 index 000000000000..f135c9deae10 --- /dev/null +++ b/arch/arm/mach-tcc8k/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x20008000 +params_phys-y := 0x20000100 +initrd_phys-y := 0x20800000 diff --git a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c new file mode 100644 index 000000000000..4e42555b2009 --- /dev/null +++ b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> + +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/time.h> + +#include <mach/clock.h> + +#include "common.h" + +#define XI_FREQUENCY 12000000 +#define XTI_FREQUENCY 32768 + +#ifdef CONFIG_MTD_NAND_TCC +/* NAND */ +static struct tcc_nand_platform_data tcc8k_sdk_nand_data = { + .width = 1, + .hw_ecc = 0, +}; +#endif + +static void __init tcc8k_init(void) +{ +#ifdef CONFIG_MTD_NAND_TCC + tcc_nand_device.dev.platform_data = &tcc8k_sdk_nand_data; + platform_device_register(&tcc_nand_device); +#endif +} + +static void __init tcc8k_init_timer(void) +{ + tcc_clocks_init(XI_FREQUENCY, XTI_FREQUENCY); +} + +static struct sys_timer tcc8k_timer = { + .init = tcc8k_init_timer, +}; + +static void __init tcc8k_map_io(void) +{ + tcc8k_map_common_io(); +} + +MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board") + .phys_io = 0x90000000, + .io_pg_offst = ((0xf1000000) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x00000100, + .map_io = tcc8k_map_io, + .init_irq = tcc8k_init_irq, + .init_machine = tcc8k_init, + .timer = &tcc8k_timer, +MACHINE_END diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c new file mode 100644 index 000000000000..ba32a15127ab --- /dev/null +++ b/arch/arm/mach-tcc8k/clock.c @@ -0,0 +1,567 @@ +/* + * Lowlevel clock handling for Telechips TCC8xxx SoCs + * + * Copyright (C) 2010 by Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GPL v2 + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/spinlock.h> + +#include <asm/clkdev.h> + +#include <mach/clock.h> +#include <mach/irqs.h> +#include <mach/tcc8k-regs.h> + +#include "common.h" + +#define BCLKCTR0 (CKC_BASE + BCLKCTR0_OFFS) +#define BCLKCTR1 (CKC_BASE + BCLKCTR1_OFFS) + +#define ACLKREF (CKC_BASE + ACLKREF_OFFS) +#define ACLKUART0 (CKC_BASE + ACLKUART0_OFFS) +#define ACLKUART1 (CKC_BASE + ACLKUART1_OFFS) +#define ACLKUART2 (CKC_BASE + ACLKUART2_OFFS) +#define ACLKUART3 (CKC_BASE + ACLKUART3_OFFS) +#define ACLKUART4 (CKC_BASE + ACLKUART4_OFFS) +#define ACLKI2C (CKC_BASE + ACLKI2C_OFFS) +#define ACLKADC (CKC_BASE + ACLKADC_OFFS) +#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS) +#define ACLKLCD (CKC_BASE + ACLKLCD_OFFS) +#define ACLKSDH0 (CKC_BASE + ACLKSDH0_OFFS) +#define ACLKSDH1 (CKC_BASE + ACLKSDH1_OFFS) +#define ACLKSPI0 (CKC_BASE + ACLKSPI0_OFFS) +#define ACLKSPI1 (CKC_BASE + ACLKSPI1_OFFS) +#define ACLKSPDIF (CKC_BASE + ACLKSPDIF_OFFS) +#define ACLKC3DEC (CKC_BASE + ACLKC3DEC_OFFS) +#define ACLKCAN0 (CKC_BASE + ACLKCAN0_OFFS) +#define ACLKCAN1 (CKC_BASE + ACLKCAN1_OFFS) +#define ACLKGSB0 (CKC_BASE + ACLKGSB0_OFFS) +#define ACLKGSB1 (CKC_BASE + ACLKGSB1_OFFS) +#define ACLKGSB2 (CKC_BASE + ACLKGSB2_OFFS) +#define ACLKGSB3 (CKC_BASE + ACLKGSB3_OFFS) +#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS) +#define ACLKTCT (CKC_BASE + ACLKTCT_OFFS) +#define ACLKTCX (CKC_BASE + ACLKTCX_OFFS) +#define ACLKTCZ (CKC_BASE + ACLKTCZ_OFFS) + +/* Crystal frequencies */ +static unsigned long xi_rate, xti_rate; + +static void __iomem *pll_cfg_addr(int pll) +{ + switch (pll) { + case 0: return (CKC_BASE + PLL0CFG_OFFS); + case 1: return (CKC_BASE + PLL1CFG_OFFS); + case 2: return (CKC_BASE + PLL2CFG_OFFS); + default: + BUG(); + } +} + +static int pll_enable(int pll, int enable) +{ + u32 reg; + void __iomem *addr = pll_cfg_addr(pll); + + reg = __raw_readl(addr); + if (enable) + reg &= ~PLLxCFG_PD; + else + reg |= PLLxCFG_PD; + + __raw_writel(reg, addr); + return 0; +} + +static int xi_enable(int enable) +{ + u32 reg; + + reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS); + if (enable) + reg |= CLKCTRL_XE; + else + reg &= ~CLKCTRL_XE; + + __raw_writel(reg, CKC_BASE + CLKCTRL_OFFS); + return 0; +} + +static int root_clk_enable(enum root_clks src) +{ + switch (src) { + case CLK_SRC_PLL0: return pll_enable(0, 1); + case CLK_SRC_PLL1: return pll_enable(1, 1); + case CLK_SRC_PLL2: return pll_enable(2, 1); + case CLK_SRC_XI: return xi_enable(1); + default: + BUG(); + } + return 0; +} + +static int root_clk_disable(enum root_clks root_src) +{ + switch (root_src) { + case CLK_SRC_PLL0: return pll_enable(0, 0); + case CLK_SRC_PLL1: return pll_enable(1, 0); + case CLK_SRC_PLL2: return pll_enable(2, 0); + case CLK_SRC_XI: return xi_enable(0); + default: + BUG(); + } + return 0; +} + +static int enable_clk(struct clk *clk) +{ + u32 reg; + + if (clk->root_id != CLK_SRC_NOROOT) + return root_clk_enable(clk->root_id); + + if (clk->aclkreg) { + reg = __raw_readl(clk->aclkreg); + reg |= ACLK_EN; + __raw_writel(reg, clk->aclkreg); + } + if (clk->bclkctr) { + reg = __raw_readl(clk->bclkctr); + reg |= 1 << clk->bclk_shift; + __raw_writel(reg, clk->bclkctr); + } + return 0; +} + +static void disable_clk(struct clk *clk) +{ + u32 reg; + + if (clk->root_id != CLK_SRC_NOROOT) { + root_clk_disable(clk->root_id); + return; + } + + if (clk->bclkctr) { + reg = __raw_readl(clk->bclkctr); + reg &= ~(1 << clk->bclk_shift); + __raw_writel(reg, clk->bclkctr); + } + if (clk->aclkreg) { + reg = __raw_readl(clk->aclkreg); + reg &= ~ACLK_EN; + __raw_writel(reg, clk->aclkreg); + } +} + +static unsigned long get_rate_pll(int pll) +{ + u32 reg; + unsigned long s, m, p; + void __iomem *addr = pll_cfg_addr(pll); + + reg = __raw_readl(addr); + s = (reg >> 16) & 0x07; + m = (reg >> 8) & 0xff; + p = reg & 0x3f; + + return (m * xi_rate) / (p * (1 << s)); +} + +static unsigned long get_rate_pll_div(int pll) +{ + u32 reg; + unsigned long div = 0; + void __iomem *addr; + + switch (pll) { + case 0: + addr = CKC_BASE + CLKDIVC0_OFFS; + reg = __raw_readl(addr); + if (reg & CLKDIVC0_P0E) + div = (reg >> 24) & 0x3f; + break; + case 1: + addr = CKC_BASE + CLKDIVC0_OFFS; + reg = __raw_readl(addr); + if (reg & CLKDIVC0_P1E) + div = (reg >> 16) & 0x3f; + break; + case 2: + addr = CKC_BASE + CLKDIVC1_OFFS; + reg = __raw_readl(addr); + if (reg & CLKDIVC1_P2E) + div = __raw_readl(addr) & 0x3f; + break; + } + return get_rate_pll(pll) / (div + 1); +} + +static unsigned long get_rate_xi_div(void) +{ + unsigned long div = 0; + u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS); + + if (reg & CLKDIVC0_XE) + div = (reg >> 8) & 0x3f; + + return xi_rate / (div + 1); +} + +static unsigned long get_rate_xti_div(void) +{ + unsigned long div = 0; + u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS); + + if (reg & CLKDIVC0_XTE) + div = reg & 0x3f; + + return xti_rate / (div + 1); +} + +static unsigned long root_clk_get_rate(enum root_clks src) +{ + switch (src) { + case CLK_SRC_PLL0: return get_rate_pll(0); + case CLK_SRC_PLL1: return get_rate_pll(1); + case CLK_SRC_PLL2: return get_rate_pll(2); + case CLK_SRC_PLL0DIV: return get_rate_pll_div(0); + case CLK_SRC_PLL1DIV: return get_rate_pll_div(1); + case CLK_SRC_PLL2DIV: return get_rate_pll_div(2); + case CLK_SRC_XI: return xi_rate; + case CLK_SRC_XTI: return xti_rate; + case CLK_SRC_XIDIV: return get_rate_xi_div(); + case CLK_SRC_XTIDIV: return get_rate_xti_div(); + default: return 0; + } +} + +static unsigned long aclk_get_rate(struct clk *clk) +{ + u32 reg; + unsigned long div; + unsigned int src; + + reg = __raw_readl(clk->aclkreg); + div = reg & 0x0fff; + src = (reg >> ACLK_SEL_SHIFT) & CLK_SRC_MASK; + return root_clk_get_rate(src) / (div + 1); +} + +static unsigned long aclk_best_div(struct clk *clk, unsigned long rate) +{ + unsigned long div, src, freq, r1, r2; + + src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT; + src &= CLK_SRC_MASK; + freq = root_clk_get_rate(src); + div = freq / rate + 1; + r1 = freq / div; + r2 = freq / (div + 1); + if (r2 >= rate) + return div + 1; + if ((rate - r2) < (r1 - rate)) + return div + 1; + + return div; +} + +static unsigned long aclk_round_rate(struct clk *clk, unsigned long rate) +{ + unsigned int src; + + src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT; + src &= CLK_SRC_MASK; + + return root_clk_get_rate(src) / aclk_best_div(clk, rate); +} + +static int aclk_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + + reg = __raw_readl(clk->aclkreg) & ~ACLK_DIV_MASK; + reg |= aclk_best_div(clk, rate); + return 0; +} + +static unsigned long get_rate_sys(struct clk *clk) +{ + unsigned int src; + + src = __raw_readl(CKC_BASE + CLKCTRL_OFFS) & CLK_SRC_MASK; + return root_clk_get_rate(src); +} + +static unsigned long get_rate_bus(struct clk *clk) +{ + unsigned int div; + + div = (__raw_readl(CKC_BASE + CLKCTRL_OFFS) >> 4) & 0xff; + return get_rate_sys(clk) / (div + 1); +} + +static unsigned long get_rate_cpu(struct clk *clk) +{ + unsigned int reg, div, fsys, fbus; + + fbus = get_rate_bus(clk); + reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS); + if (reg & (1 << 29)) + return fbus; + fsys = get_rate_sys(clk); + div = (reg >> 16) & 0x0f; + return fbus + ((fsys - fbus) * (div + 1)) / 16; +} + +static unsigned long get_rate_root(struct clk *clk) +{ + return root_clk_get_rate(clk->root_id); +} + +static int aclk_set_parent(struct clk *clock, struct clk *parent) +{ + u32 reg; + + if (clock->parent == parent) + return 0; + + clock->parent = parent; + + if (!parent) + return 0; + + if (parent->root_id == CLK_SRC_NOROOT) + return 0; + reg = __raw_readl(clock->aclkreg); + reg &= ~ACLK_SEL_MASK; + reg |= (parent->root_id << ACLK_SEL_SHIFT) & ACLK_SEL_MASK; + __raw_writel(reg, clock->aclkreg); + + return 0; +} + +#define DEFINE_ROOT_CLOCK(name, ri, p) \ + static struct clk name = { \ + .root_id = ri, \ + .get_rate = get_rate_root, \ + .enable = enable_clk, \ + .disable = disable_clk, \ + .parent = p, \ + }; + +#define DEFINE_SPECIAL_CLOCK(name, gr, p) \ + static struct clk name = { \ + .root_id = CLK_SRC_NOROOT, \ + .get_rate = gr, \ + .parent = p, \ + }; + +#define DEFINE_ACLOCK(name, bc, bs, ar) \ + static struct clk name = { \ + .root_id = CLK_SRC_NOROOT, \ + .bclkctr = bc, \ + .bclk_shift = bs, \ + .aclkreg = ar, \ + .get_rate = aclk_get_rate, \ + .set_rate = aclk_set_rate, \ + .round_rate = aclk_round_rate, \ + .enable = enable_clk, \ + .disable = disable_clk, \ + .set_parent = aclk_set_parent, \ + }; + +#define DEFINE_BCLOCK(name, bc, bs, gr, p) \ + static struct clk name = { \ + .root_id = CLK_SRC_NOROOT, \ + .bclkctr = bc, \ + .bclk_shift = bs, \ + .get_rate = gr, \ + .enable = enable_clk, \ + .disable = disable_clk, \ + .parent = p, \ + }; + +DEFINE_ROOT_CLOCK(xi, CLK_SRC_XI, NULL) +DEFINE_ROOT_CLOCK(xti, CLK_SRC_XTI, NULL) +DEFINE_ROOT_CLOCK(xidiv, CLK_SRC_XIDIV, &xi) +DEFINE_ROOT_CLOCK(xtidiv, CLK_SRC_XTIDIV, &xti) +DEFINE_ROOT_CLOCK(pll0, CLK_SRC_PLL0, &xi) +DEFINE_ROOT_CLOCK(pll1, CLK_SRC_PLL1, &xi) +DEFINE_ROOT_CLOCK(pll2, CLK_SRC_PLL2, &xi) +DEFINE_ROOT_CLOCK(pll0div, CLK_SRC_PLL0DIV, &pll0) +DEFINE_ROOT_CLOCK(pll1div, CLK_SRC_PLL1DIV, &pll1) +DEFINE_ROOT_CLOCK(pll2div, CLK_SRC_PLL2DIV, &pll2) + +/* The following 3 clocks are special and are initialized explicitly later */ +DEFINE_SPECIAL_CLOCK(sys, get_rate_sys, NULL) +DEFINE_SPECIAL_CLOCK(bus, get_rate_bus, &sys) +DEFINE_SPECIAL_CLOCK(cpu, get_rate_cpu, &sys) + +DEFINE_ACLOCK(tct, NULL, 0, ACLKTCT) +DEFINE_ACLOCK(tcx, NULL, 0, ACLKTCX) +DEFINE_ACLOCK(tcz, NULL, 0, ACLKTCZ) +DEFINE_ACLOCK(ref, NULL, 0, ACLKREF) +DEFINE_ACLOCK(uart0, BCLKCTR0, 5, ACLKUART0) +DEFINE_ACLOCK(uart1, BCLKCTR0, 23, ACLKUART1) +DEFINE_ACLOCK(uart2, BCLKCTR0, 6, ACLKUART2) +DEFINE_ACLOCK(uart3, BCLKCTR0, 8, ACLKUART3) +DEFINE_ACLOCK(uart4, BCLKCTR1, 6, ACLKUART4) +DEFINE_ACLOCK(i2c, BCLKCTR0, 7, ACLKI2C) +DEFINE_ACLOCK(adc, BCLKCTR0, 10, ACLKADC) +DEFINE_ACLOCK(usbh0, BCLKCTR0, 11, ACLKUSBH) +DEFINE_ACLOCK(lcd, BCLKCTR0, 13, ACLKLCD) +DEFINE_ACLOCK(sd0, BCLKCTR0, 17, ACLKSDH0) +DEFINE_ACLOCK(sd1, BCLKCTR1, 5, ACLKSDH1) +DEFINE_ACLOCK(spi0, BCLKCTR0, 24, ACLKSPI0) +DEFINE_ACLOCK(spi1, BCLKCTR0, 30, ACLKSPI1) +DEFINE_ACLOCK(spdif, BCLKCTR1, 2, ACLKSPDIF) +DEFINE_ACLOCK(c3dec, BCLKCTR1, 9, ACLKC3DEC) +DEFINE_ACLOCK(can0, BCLKCTR1, 10, ACLKCAN0) +DEFINE_ACLOCK(can1, BCLKCTR1, 11, ACLKCAN1) +DEFINE_ACLOCK(gsb0, BCLKCTR1, 13, ACLKGSB0) +DEFINE_ACLOCK(gsb1, BCLKCTR1, 14, ACLKGSB1) +DEFINE_ACLOCK(gsb2, BCLKCTR1, 15, ACLKGSB2) +DEFINE_ACLOCK(gsb3, BCLKCTR1, 16, ACLKGSB3) +DEFINE_ACLOCK(usbh1, BCLKCTR1, 20, ACLKUSBH) + +DEFINE_BCLOCK(dai0, BCLKCTR0, 0, NULL, NULL) +DEFINE_BCLOCK(pic, BCLKCTR0, 1, NULL, NULL) +DEFINE_BCLOCK(tc, BCLKCTR0, 2, NULL, NULL) +DEFINE_BCLOCK(gpio, BCLKCTR0, 3, NULL, NULL) +DEFINE_BCLOCK(usbd, BCLKCTR0, 4, NULL, NULL) +DEFINE_BCLOCK(ecc, BCLKCTR0, 9, NULL, NULL) +DEFINE_BCLOCK(gdma0, BCLKCTR0, 12, NULL, NULL) +DEFINE_BCLOCK(rtc, BCLKCTR0, 15, NULL, NULL) +DEFINE_BCLOCK(nfc, BCLKCTR0, 16, NULL, NULL) +DEFINE_BCLOCK(g2d, BCLKCTR0, 18, NULL, NULL) +DEFINE_BCLOCK(gdma1, BCLKCTR0, 22, NULL, NULL) +DEFINE_BCLOCK(mscl, BCLKCTR0, 25, NULL, NULL) +DEFINE_BCLOCK(bdma, BCLKCTR1, 0, NULL, NULL) +DEFINE_BCLOCK(adma0, BCLKCTR1, 1, NULL, NULL) +DEFINE_BCLOCK(scfg, BCLKCTR1, 3, NULL, NULL) +DEFINE_BCLOCK(cid, BCLKCTR1, 4, NULL, NULL) +DEFINE_BCLOCK(dai1, BCLKCTR1, 7, NULL, NULL) +DEFINE_BCLOCK(adma1, BCLKCTR1, 8, NULL, NULL) +DEFINE_BCLOCK(gps, BCLKCTR1, 12, NULL, NULL) +DEFINE_BCLOCK(gdma2, BCLKCTR1, 17, NULL, NULL) +DEFINE_BCLOCK(gdma3, BCLKCTR1, 18, NULL, NULL) +DEFINE_BCLOCK(ddrc, BCLKCTR1, 19, NULL, NULL) + +#define _REGISTER_CLOCK(d, n, c) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk = &c, \ + }, + +static struct clk_lookup lookups[] = { + _REGISTER_CLOCK(NULL, "bus", bus) + _REGISTER_CLOCK(NULL, "cpu", cpu) + _REGISTER_CLOCK(NULL, "tct", tct) + _REGISTER_CLOCK(NULL, "tcx", tcx) + _REGISTER_CLOCK(NULL, "tcz", tcz) + _REGISTER_CLOCK(NULL, "ref", ref) + _REGISTER_CLOCK(NULL, "dai0", dai0) + _REGISTER_CLOCK(NULL, "pic", pic) + _REGISTER_CLOCK(NULL, "tc", tc) + _REGISTER_CLOCK(NULL, "gpio", gpio) + _REGISTER_CLOCK(NULL, "usbd", usbd) + _REGISTER_CLOCK("tcc-uart.0", NULL, uart0) + _REGISTER_CLOCK("tcc-uart.2", NULL, uart2) + _REGISTER_CLOCK("tcc-i2c", NULL, i2c) + _REGISTER_CLOCK("tcc-uart.3", NULL, uart3) + _REGISTER_CLOCK(NULL, "ecc", ecc) + _REGISTER_CLOCK(NULL, "adc", adc) + _REGISTER_CLOCK("tcc-usbh.0", "usb", usbh0) + _REGISTER_CLOCK(NULL, "gdma0", gdma0) + _REGISTER_CLOCK(NULL, "lcd", lcd) + _REGISTER_CLOCK(NULL, "rtc", rtc) + _REGISTER_CLOCK(NULL, "nfc", nfc) + _REGISTER_CLOCK("tcc-mmc.0", NULL, sd0) + _REGISTER_CLOCK(NULL, "g2d", g2d) + _REGISTER_CLOCK(NULL, "gdma1", gdma1) + _REGISTER_CLOCK("tcc-uart.1", NULL, uart1) + _REGISTER_CLOCK("tcc-spi.0", NULL, spi0) + _REGISTER_CLOCK(NULL, "mscl", mscl) + _REGISTER_CLOCK("tcc-spi.1", NULL, spi1) + _REGISTER_CLOCK(NULL, "bdma", bdma) + _REGISTER_CLOCK(NULL, "adma0", adma0) + _REGISTER_CLOCK(NULL, "spdif", spdif) + _REGISTER_CLOCK(NULL, "scfg", scfg) + _REGISTER_CLOCK(NULL, "cid", cid) + _REGISTER_CLOCK("tcc-mmc.1", NULL, sd1) + _REGISTER_CLOCK("tcc-uart.4", NULL, uart4) + _REGISTER_CLOCK(NULL, "dai1", dai1) + _REGISTER_CLOCK(NULL, "adma1", adma1) + _REGISTER_CLOCK(NULL, "c3dec", c3dec) + _REGISTER_CLOCK("tcc-can.0", NULL, can0) + _REGISTER_CLOCK("tcc-can.1", NULL, can1) + _REGISTER_CLOCK(NULL, "gps", gps) + _REGISTER_CLOCK("tcc-gsb.0", NULL, gsb0) + _REGISTER_CLOCK("tcc-gsb.1", NULL, gsb1) + _REGISTER_CLOCK("tcc-gsb.2", NULL, gsb2) + _REGISTER_CLOCK("tcc-gsb.3", NULL, gsb3) + _REGISTER_CLOCK(NULL, "gdma2", gdma2) + _REGISTER_CLOCK(NULL, "gdma3", gdma3) + _REGISTER_CLOCK(NULL, "ddrc", ddrc) + _REGISTER_CLOCK("tcc-usbh.1", "usb", usbh1) +}; + +static struct clk *root_clk_by_index(enum root_clks src) +{ + switch (src) { + case CLK_SRC_PLL0: return &pll0; + case CLK_SRC_PLL1: return &pll1; + case CLK_SRC_PLL2: return &pll2; + case CLK_SRC_PLL0DIV: return &pll0div; + case CLK_SRC_PLL1DIV: return &pll1div; + case CLK_SRC_PLL2DIV: return &pll2div; + case CLK_SRC_XI: return ξ + case CLK_SRC_XTI: return &xti; + case CLK_SRC_XIDIV: return &xidiv; + case CLK_SRC_XTIDIV: return &xtidiv; + default: return NULL; + } +} + +static void find_aclk_parent(struct clk *clk) +{ + unsigned int src; + struct clk *clock; + + if (!clk->aclkreg) + return; + + src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT; + src &= CLK_SRC_MASK; + + clock = root_clk_by_index(src); + if (!clock) + return; + + clk->parent = clock; + clk->set_parent = aclk_set_parent; +} + +void __init tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq) +{ + int i; + + xi_rate = xi_freq; + xti_rate = xti_freq; + + /* fixup parents and add the clock */ + for (i = 0; i < ARRAY_SIZE(lookups); i++) { + find_aclk_parent(lookups[i].clk); + clkdev_add(&lookups[i]); + } + tcc8k_timer_init(&tcz, (void __iomem *)TIMER_BASE, INT_TC32); +} diff --git a/arch/arm/mach-tcc8k/common.h b/arch/arm/mach-tcc8k/common.h new file mode 100644 index 000000000000..705690add395 --- /dev/null +++ b/arch/arm/mach-tcc8k/common.h @@ -0,0 +1,15 @@ +#ifndef MACH_TCC8K_COMMON_H +#define MACH_TCC8K_COMMON_H + +#include <linux/platform_device.h> + +extern struct platform_device tcc_nand_device; + +struct clk; + +extern void tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq); +extern void tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq); +extern void tcc8k_init_irq(void); +extern void tcc8k_map_common_io(void); + +#endif diff --git a/arch/arm/mach-tcc8k/devices.c b/arch/arm/mach-tcc8k/devices.c new file mode 100644 index 000000000000..6722ad7c2836 --- /dev/null +++ b/arch/arm/mach-tcc8k/devices.c @@ -0,0 +1,239 @@ +/* + * linux/arch/arm/mach-tcc8k/devices.c + * + * Copyright (C) Telechips, Inc. + * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of GPL v2. + * + */ + +#include <linux/dma-mapping.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> + +#include <asm/mach/map.h> + +#include <mach/tcc8k-regs.h> +#include <mach/irqs.h> + +#include "common.h" + +static u64 tcc8k_dmamask = DMA_BIT_MASK(32); + +#ifdef CONFIG_MTD_NAND_TCC +/* NAND controller */ +static struct resource tcc_nand_resources[] = { + { + .start = (resource_size_t)NFC_BASE, + .end = (resource_size_t)NFC_BASE + 0x7f, + .flags = IORESOURCE_MEM, + }, { + .start = INT_NFC, + .end = INT_NFC, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device tcc_nand_device = { + .name = "tcc_nand", + .id = 0, + .num_resources = ARRAY_SIZE(tcc_nand_resources), + .resource = tcc_nand_resources, +}; +#endif + +#ifdef CONFIG_MMC_TCC8K +/* MMC controller */ +static struct resource tcc8k_mmc0_resource[] = { + { + .start = INT_SD0, + .end = INT_SD0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource tcc8k_mmc1_resource[] = { + { + .start = INT_SD1, + .end = INT_SD1, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device tcc8k_mmc0_device = { + .name = "tcc-mmc", + .id = 0, + .num_resources = ARRAY_SIZE(tcc8k_mmc0_resource), + .resource = tcc8k_mmc0_resource, + .dev = { + .dma_mask = &tcc8k_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; + +struct platform_device tcc8k_mmc1_device = { + .name = "tcc-mmc", + .id = 1, + .num_resources = ARRAY_SIZE(tcc8k_mmc1_resource), + .resource = tcc8k_mmc1_resource, + .dev = { + .dma_mask = &tcc8k_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; + +static inline void tcc8k_init_mmc(void) +{ + u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS); + + reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS; + __raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS); + + platform_device_register(&tcc8k_mmc0_device); + platform_device_register(&tcc8k_mmc1_device); +} +#else +static inline void tcc8k_init_mmc(void) { } +#endif + +#ifdef CONFIG_USB_OHCI_HCD +static int tcc8k_ohci_init(struct device *dev) +{ + u32 reg; + + /* Use GPIO PK19 as VBUS control output */ + reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS); + reg &= ~(1 << 19); + __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS); + reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS); + reg &= ~(1 << 19); + __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS); + + reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS); + reg |= (1 << 19); + __raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS); + /* Turn on VBUS */ + reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS); + reg |= (1 << 19); + __raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS); + + return 0; +} + +static struct resource tcc8k_ohci0_resources[] = { + [0] = { + .start = (resource_size_t)USBH0_BASE, + .end = (resource_size_t)USBH0_BASE + 0x5c, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_USBH0, + .end = INT_USBH0, + .flags = IORESOURCE_IRQ, + } +}; + +static struct resource tcc8k_ohci1_resources[] = { + [0] = { + .start = (resource_size_t)USBH1_BASE, + .end = (resource_size_t)USBH1_BASE + 0x5c, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_USBH1, + .end = INT_USBH1, + .flags = IORESOURCE_IRQ, + } +}; + +static struct tccohci_platform_data tcc8k_ohci0_platform_data = { + .controller = 0, + .port_mode = PMM_PERPORT_MODE, + .init = tcc8k_ohci_init, +}; + +static struct tccohci_platform_data tcc8k_ohci1_platform_data = { + .controller = 1, + .port_mode = PMM_PERPORT_MODE, + .init = tcc8k_ohci_init, +}; + +static struct platform_device ohci0_device = { + .name = "tcc-ohci", + .id = 0, + .dev = { + .dma_mask = &tcc8k_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &tcc8k_ohci0_platform_data, + }, + .num_resources = ARRAY_SIZE(tcc8k_ohci0_resources), + .resource = tcc8k_ohci0_resources, +}; + +static struct platform_device ohci1_device = { + .name = "tcc-ohci", + .id = 1, + .dev = { + .dma_mask = &tcc8k_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &tcc8k_ohci1_platform_data, + }, + .num_resources = ARRAY_SIZE(tcc8k_ohci1_resources), + .resource = tcc8k_ohci1_resources, +}; + +static void __init tcc8k_init_usbhost(void) +{ + platform_device_register(&ohci0_device); + platform_device_register(&ohci1_device); +} +#else +static void __init tcc8k_init_usbhost(void) { } +#endif + +/* USB device controller*/ +#ifdef CONFIG_USB_GADGET_TCC8K +static struct resource udc_resources[] = { + [0] = { + .start = INT_USBD, + .end = INT_USBD, + .flags = IORESOURCE_IRQ, + }, + [1] = { + .start = INT_UDMA, + .end = INT_UDMA, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device tcc8k_udc_device = { + .name = "tcc-udc", + .id = 0, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), + .dev = { + .dma_mask = &tcc8k_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static void __init tcc8k_init_usb_gadget(void) +{ + platform_device_register(&tcc8k_udc_device); +} +#else +static void __init tcc8k_init_usb_gadget(void) { } +#endif /* CONFIG_USB_GADGET_TCC83X */ + +static int __init tcc8k_init_devices(void) +{ + tcc8k_init_mmc(); + tcc8k_init_usbhost(); + tcc8k_init_usb_gadget(); + return 0; +} + +arch_initcall(tcc8k_init_devices); diff --git a/arch/arm/mach-tcc8k/io.c b/arch/arm/mach-tcc8k/io.c new file mode 100644 index 000000000000..9b39d7fa658f --- /dev/null +++ b/arch/arm/mach-tcc8k/io.c @@ -0,0 +1,62 @@ +/* + * linux/arch/arm/mach-tcc8k/io.c + * + * (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * derived from TCC83xx io.c + * Copyright (C) Telechips, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> + +#include <asm/mach/map.h> + +#include <mach/tcc8k-regs.h> + +/* + * The machine specific code may provide the extra mapping besides the + * default mapping provided here. + */ +static struct map_desc tcc8k_io_desc[] __initdata = { + { + .virtual = (unsigned long)CS1_BASE_VIRT, + .pfn = __phys_to_pfn(CS1_BASE), + .length = CS1_SIZE, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)AHB_PERI_BASE_VIRT, + .pfn = __phys_to_pfn(AHB_PERI_BASE), + .length = AHB_PERI_SIZE, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)APB0_PERI_BASE_VIRT, + .pfn = __phys_to_pfn(APB0_PERI_BASE), + .length = APB0_PERI_SIZE, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)APB1_PERI_BASE_VIRT, + .pfn = __phys_to_pfn(APB1_PERI_BASE), + .length = APB1_PERI_SIZE, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)EXT_MEM_CTRL_BASE_VIRT, + .pfn = __phys_to_pfn(EXT_MEM_CTRL_BASE), + .length = EXT_MEM_CTRL_SIZE, + .type = MT_DEVICE, + }, +}; + +/* + * Maps common IO regions for tcc8k. + * + */ +void __init tcc8k_map_common_io(void) +{ + iotable_init(tcc8k_io_desc, ARRAY_SIZE(tcc8k_io_desc)); +} diff --git a/arch/arm/mach-tcc8k/irq.c b/arch/arm/mach-tcc8k/irq.c new file mode 100644 index 000000000000..34575c4963f0 --- /dev/null +++ b/arch/arm/mach-tcc8k/irq.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) Telechips, Inc. + * Copyright (C) 2009-2010 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GNU GPL version 2. + */ + +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> + +#include <asm/irq.h> +#include <asm/mach/irq.h> + +#include <mach/tcc8k-regs.h> +#include <mach/irqs.h> + +#include "common.h" + +/* Disable IRQ */ +static void tcc8000_mask_ack_irq0(unsigned int irq) +{ + PIC0_IEN &= ~(1 << irq); + PIC0_CREQ |= (1 << irq); +} + +static void tcc8000_mask_ack_irq1(unsigned int irq) +{ + PIC1_IEN &= ~(1 << (irq - 32)); + PIC1_CREQ |= (1 << (irq - 32)); +} + +static void tcc8000_mask_irq0(unsigned int irq) +{ + PIC0_IEN &= ~(1 << irq); +} + +static void tcc8000_mask_irq1(unsigned int irq) +{ + PIC1_IEN &= ~(1 << (irq - 32)); +} + +static void tcc8000_ack_irq0(unsigned int irq) +{ + PIC0_CREQ |= (1 << irq); +} + +static void tcc8000_ack_irq1(unsigned int irq) +{ + PIC1_CREQ |= (1 << (irq - 32)); +} + +/* Enable IRQ */ +static void tcc8000_unmask_irq0(unsigned int irq) +{ + PIC0_IEN |= (1 << irq); + PIC0_INTOEN |= (1 << irq); +} + +static void tcc8000_unmask_irq1(unsigned int irq) +{ + PIC1_IEN |= (1 << (irq - 32)); + PIC1_INTOEN |= (1 << (irq - 32)); +} + +static struct irq_chip tcc8000_irq_chip0 = { + .name = "tcc_irq0", + .mask = tcc8000_mask_irq0, + .ack = tcc8000_ack_irq0, + .mask_ack = tcc8000_mask_ack_irq0, + .unmask = tcc8000_unmask_irq0, +}; + +static struct irq_chip tcc8000_irq_chip1 = { + .name = "tcc_irq1", + .mask = tcc8000_mask_irq1, + .ack = tcc8000_ack_irq1, + .mask_ack = tcc8000_mask_ack_irq1, + .unmask = tcc8000_unmask_irq1, +}; + +void __init tcc8k_init_irq(void) +{ + int irqno; + + /* Mask and clear all interrupts */ + PIC0_IEN = 0x00000000; + PIC0_CREQ = 0xffffffff; + PIC1_IEN = 0x00000000; + PIC1_CREQ = 0xffffffff; + + PIC0_MEN0 = 0x00000003; + PIC1_MEN1 = 0x00000003; + PIC1_MEN = 0x00000003; + + /* let all IRQs be level triggered */ + PIC0_TMODE = 0xffffffff; + PIC1_TMODE = 0xffffffff; + /* all IRQs are IRQs (not FIQs) */ + PIC0_IRQSEL = 0xffffffff; + PIC1_IRQSEL = 0xffffffff; + + for (irqno = 0; irqno < NR_IRQS; irqno++) { + if (irqno < 32) + set_irq_chip(irqno, &tcc8000_irq_chip0); + else + set_irq_chip(irqno, &tcc8000_irq_chip1); + set_irq_handler(irqno, handle_level_irq); + set_irq_flags(irqno, IRQF_VALID); + } +} diff --git a/arch/arm/mach-tcc8k/time.c b/arch/arm/mach-tcc8k/time.c new file mode 100644 index 000000000000..78d06008841d --- /dev/null +++ b/arch/arm/mach-tcc8k/time.c @@ -0,0 +1,149 @@ +/* + * TCC8000 system timer setup + * + * (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GPL version 2. + * + */ + +#include <linux/clk.h> +#include <linux/clockchips.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> + +#include <asm/mach/time.h> + +#include <mach/tcc8k-regs.h> +#include <mach/irqs.h> + +#include "common.h" + +static void __iomem *timer_base; + +static cycle_t tcc_get_cycles(struct clocksource *cs) +{ + return __raw_readl(timer_base + TC32MCNT_OFFS); +} + +static struct clocksource clocksource_tcc = { + .name = "tcc_tc32", + .rating = 200, + .read = tcc_get_cycles, + .mask = CLOCKSOURCE_MASK(32), + .shift = 28, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int tcc_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + unsigned long reg = __raw_readl(timer_base + TC32MCNT_OFFS); + + __raw_writel(reg + evt, timer_base + TC32CMP0_OFFS); + return 0; +} + +static void tcc_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long tc32irq; + + switch (mode) { + case CLOCK_EVT_MODE_ONESHOT: + tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS); + tc32irq |= TC32IRQ_IRQEN0; + __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS); + tc32irq &= ~TC32IRQ_IRQEN0; + __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS); + break; + case CLOCK_EVT_MODE_PERIODIC: + case CLOCK_EVT_MODE_RESUME: + break; + } +} + +static irqreturn_t tcc8k_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + /* Acknowledge TC32 interrupt by reading TC32IRQ */ + __raw_readl(timer_base + TC32IRQ_OFFS); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct clock_event_device clockevent_tcc = { + .name = "tcc_timer1", + .features = CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .set_mode = tcc_set_mode, + .set_next_event = tcc_set_next_event, + .rating = 200, +}; + +static struct irqaction tcc8k_timer_irq = { + .name = "TC32_timer", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = tcc8k_timer_interrupt, + .dev_id = &clockevent_tcc, +}; + +static int __init tcc_clockevent_init(struct clk *clock) +{ + unsigned int c = clk_get_rate(clock); + + clocksource_tcc.mult = clocksource_hz2mult(c, + clocksource_tcc.shift); + clocksource_register(&clocksource_tcc); + + clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC, + clockevent_tcc.shift); + clockevent_tcc.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &clockevent_tcc); + clockevent_tcc.min_delta_ns = + clockevent_delta2ns(0xff, &clockevent_tcc); + + clockevent_tcc.cpumask = cpumask_of(0); + + clockevents_register_device(&clockevent_tcc); + + return 0; +} + +void __init tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq) +{ + u32 reg; + + timer_base = base; + tcc8k_timer_irq.irq = irq; + + /* Enable clocks */ + clk_enable(clock); + + /* Initialize 32-bit timer */ + reg = __raw_readl(timer_base + TC32EN_OFFS); + reg &= ~TC32EN_ENABLE; /* Disable timer */ + __raw_writel(reg, timer_base + TC32EN_OFFS); + /* Free running timer, counting from 0 to 0xffffffff */ + __raw_writel(0, timer_base + TC32EN_OFFS); + __raw_writel(0, timer_base + TC32LDV_OFFS); + reg = __raw_readl(timer_base + TC32IRQ_OFFS); + reg |= TC32IRQ_IRQEN0; /* irq at match with CMP0 */ + __raw_writel(reg, timer_base + TC32IRQ_OFFS); + + __raw_writel(TC32EN_ENABLE, timer_base + TC32EN_OFFS); + + tcc_clockevent_init(clock); + setup_irq(irq, &tcc8k_timer_irq); +} diff --git a/arch/arm/mach-versatile/include/mach/vmalloc.h b/arch/arm/mach-versatile/include/mach/vmalloc.h index 427e3612db5d..ebd8a2543d3b 100644 --- a/arch/arm/mach-versatile/include/mach/vmalloc.h +++ b/arch/arm/mach-versatile/include/mach/vmalloc.h @@ -18,4 +18,4 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define VMALLOC_END (PAGE_OFFSET + 0x18000000) +#define VMALLOC_END 0xd8000000 diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index efb127022d42..71fb17349520 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -68,7 +68,7 @@ static void __init ct_ca9x4_init_irq(void) } #if 0 -static void ct_ca9x4_timer_init(void) +static void __init ct_ca9x4_timer_init(void) { writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); @@ -222,7 +222,7 @@ static struct platform_device pmu_device = { .resource = pmu_resources, }; -static void ct_ca9x4_init(void) +static void __init ct_ca9x4_init(void) { int i; diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 817f0ad38a0b..7eaa232180a5 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -48,7 +48,7 @@ void __init v2m_map_io(struct map_desc *tile, size_t num) } -static void v2m_timer_init(void) +static void __init v2m_timer_init(void) { writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index ab506272b2d3..17e7b0b57e49 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -204,8 +204,12 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, /* * Don't allow RAM to be mapped - this causes problems with ARMv6+ */ - if (WARN_ON(pfn_valid(pfn))) - return NULL; + if (pfn_valid(pfn)) { + printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n" + KERN_WARNING "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n" + KERN_WARNING "will fail in the next kernel release. Please fix your driver.\n"); + WARN_ON(1); + } type = get_mem_type(mtype); if (!type) diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 4f5b39687df5..b0a98305055c 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -144,3 +144,25 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) { return !(pfn + (size >> PAGE_SHIFT) > 0x00100000); } + +#ifdef CONFIG_STRICT_DEVMEM + +#include <linux/ioport.h> + +/* + * devmem_is_allowed() checks to see if /dev/mem access to a certain + * address is valid. The argument is a physical page number. + * We mimic x86 here by disallowing access to system RAM as well as + * device-exclusive MMIO regions. This effectively disable read()/write() + * on /dev/mem. + */ +int devmem_is_allowed(unsigned long pfn) +{ + if (iomem_is_exclusive(pfn << PAGE_SHIFT)) + return 0; + if (!page_is_ram(pfn)) + return 1; + return 0; +} + +#endif diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e2335811c02e..c32f731d56d3 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -248,7 +248,7 @@ static struct mem_type mem_types[] = { }, [MT_MEMORY] = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_USER | L_PTE_EXEC, + L_PTE_WRITE | L_PTE_EXEC, .prot_l1 = PMD_TYPE_TABLE, .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, @@ -259,7 +259,7 @@ static struct mem_type mem_types[] = { }, [MT_MEMORY_NONCACHED] = { .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_USER | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, + L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, .prot_l1 = PMD_TYPE_TABLE, .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 055e9d50d015..53cbe2225153 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -253,6 +253,14 @@ __v7_setup: orreq r10, r10, #1 << 22 @ set bit #22 mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register #endif +#ifdef CONFIG_ARM_ERRATA_743622 + teq r6, #0x20 @ present in r2p0 + teqne r6, #0x21 @ present in r2p1 + teqne r6, #0x22 @ present in r2p2 + mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register + orreq r10, r10, #1 << 6 @ set bit #6 + mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register +#endif 3: mov r10, #0 #ifdef HARVARD_CACHE @@ -376,7 +384,7 @@ __v7_ca9mp_proc_info: b __v7_ca9mp_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS .long cpu_v7_name .long v7_processor_functions .long v7wbi_tlb_fns diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 0691176899ff..72e09eb642dd 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -102,6 +102,7 @@ static int op_create_counter(int cpu, int event) if (IS_ERR(pevent)) { ret = PTR_ERR(pevent); } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) { + perf_event_release_kernel(pevent); pr_warning("oprofile: failed to enable event %d " "on CPU %d\n", event, cpu); ret = -EBUSY; @@ -365,6 +366,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ret = init_driverfs(); if (ret) { kfree(counter_config); + counter_config = NULL; return ret; } @@ -402,7 +404,6 @@ void oprofile_arch_exit(void) struct perf_event *event; if (*perf_events) { - exit_driverfs(); for_each_possible_cpu(cpu) { for (id = 0; id < perf_num_counters; ++id) { event = perf_events[cpu][id]; @@ -413,8 +414,10 @@ void oprofile_arch_exit(void) } } - if (counter_config) + if (counter_config) { kfree(counter_config); + exit_driverfs(); + } } #else int __init oprofile_arch_init(struct oprofile_operations *ops) diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 6785db4179b8..64e3a64520e0 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -92,6 +92,18 @@ config MXC_DEBUG_BOARD data/address de-multiplexing and decode, signal level shift, interrupt control and various board functions. +config HAVE_EPIT + bool + +config MXC_USE_EPIT + bool "Use EPIT instead of GPT" + depends on HAVE_EPIT + help + Use EPIT as the system timer on systems that have it. Normally you + don't have a reason to do so as the EPIT has the same features and + uses the same clocks as the GPT. Anyway, on some systems the GPT + may be in use for other purposes. + config MXC_ULPI bool @@ -110,4 +122,8 @@ config ARCH_MXC_AUDMUX_V1 config ARCH_MXC_AUDMUX_V2 bool +config IRAM_ALLOC + bool + select GENERIC_ALLOCATOR + endif diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 78d405ed8616..06875b4dd70f 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -10,9 +10,11 @@ obj-$(CONFIG_MXC_TZIC) += tzic.o obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o +obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o obj-$(CONFIG_MXC_PWM) += pwm.o obj-$(CONFIG_USB_EHCI_MXC) += ehci.o obj-$(CONFIG_MXC_ULPI) += ulpi.o +obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c index f9e7cdbd0005..62920490c0d6 100644 --- a/arch/arm/plat-mxc/audmux-v2.c +++ b/arch/arm/plat-mxc/audmux-v2.c @@ -186,7 +186,13 @@ EXPORT_SYMBOL_GPL(mxc_audmux_v2_configure_port); static int mxc_audmux_v2_init(void) { int ret; - +#if defined(CONFIG_ARCH_MX5) + if (cpu_is_mx51()) { + audmux_base = MX51_IO_ADDRESS(MX51_AUDMUX_BASE_ADDR); + ret = 0; + return ret; + } +#endif #if defined(CONFIG_ARCH_MX3) if (cpu_is_mx31()) audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR); diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig index 9ab784b776f9..404799487f17 100644 --- a/arch/arm/plat-mxc/devices/Kconfig +++ b/arch/arm/plat-mxc/devices/Kconfig @@ -1,3 +1,10 @@ +config IMX_HAVE_PLATFORM_ESDHC + bool + +config IMX_HAVE_PLATFORM_FEC + bool + default y if ARCH_MX25 || SOC_IMX27 || ARCH_MX35 || ARCH_MX51 + config IMX_HAVE_PLATFORM_FLEXCAN select HAVE_CAN_FLEXCAN bool @@ -5,6 +12,9 @@ config IMX_HAVE_PLATFORM_FLEXCAN config IMX_HAVE_PLATFORM_IMX_I2C bool +config IMX_HAVE_PLATFORM_IMX_SSI + bool + config IMX_HAVE_PLATFORM_IMX_UART bool diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile index 347da5161f7e..0a3c1f089413 100644 --- a/arch/arm/plat-mxc/devices/Makefile +++ b/arch/arm/plat-mxc/devices/Makefile @@ -1,8 +1,9 @@ -ifdef CONFIG_CAN_FLEXCAN -# the ifdef can be removed once the flexcan driver has been merged -obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o -endif +obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o +obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o +obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o +obj-y += platform-imx-dma.o obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o +obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o diff --git a/arch/arm/plat-mxc/devices/platform-esdhc.c b/arch/arm/plat-mxc/devices/platform-esdhc.c new file mode 100644 index 000000000000..2605bfa0dfb0 --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-esdhc.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ + +#include <mach/hardware.h> +#include <mach/devices-common.h> +#include <mach/esdhc.h> + +#define imx_esdhc_imx_data_entry_single(soc, _id, hwid) \ + { \ + .id = _id, \ + .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR, \ + .irq = soc ## _INT_ESDHC ## hwid, \ + } + +#define imx_esdhc_imx_data_entry(soc, id, hwid) \ + [id] = imx_esdhc_imx_data_entry_single(soc, id, hwid) + +#ifdef CONFIG_ARCH_MX25 +const struct imx_esdhc_imx_data imx25_esdhc_data[] __initconst = { +#define imx25_esdhc_data_entry(_id, _hwid) \ + imx_esdhc_imx_data_entry(MX25, _id, _hwid) + imx25_esdhc_data_entry(0, 1), + imx25_esdhc_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_ARCH_MX25 */ + +#ifdef CONFIG_ARCH_MX35 +const struct imx_esdhc_imx_data imx35_esdhc_data[] __initconst = { +#define imx35_esdhc_data_entry(_id, _hwid) \ + imx_esdhc_imx_data_entry(MX35, _id, _hwid) + imx35_esdhc_data_entry(0, 1), + imx35_esdhc_data_entry(1, 2), + imx35_esdhc_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_ARCH_MX35 */ + +#ifdef CONFIG_ARCH_MX51 +const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst = { +#define imx51_esdhc_data_entry(_id, _hwid) \ + imx_esdhc_imx_data_entry(MX51, _id, _hwid) + imx51_esdhc_data_entry(0, 1), + imx51_esdhc_data_entry(1, 2), + imx51_esdhc_data_entry(2, 3), + imx51_esdhc_data_entry(3, 4), +}; +#endif /* ifdef CONFIG_ARCH_MX51 */ + +struct platform_device *__init imx_add_esdhc( + const struct imx_esdhc_imx_data *data, + const struct esdhc_platform_data *pdata) +{ + struct resource res[] = { + { + .start = data->iobase, + .end = data->iobase + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = data->irq, + .end = data->irq, + .flags = IORESOURCE_IRQ, + }, + }; + + return imx_add_platform_device("sdhci-esdhc-imx", data->id, res, + ARRAY_SIZE(res), pdata, sizeof(*pdata)); +} diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c new file mode 100644 index 000000000000..11d087f4e219 --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-fec.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 Pengutronix + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include <asm/sizes.h> +#include <mach/hardware.h> +#include <mach/devices-common.h> + +#define imx_fec_data_entry_single(soc) \ + { \ + .iobase = soc ## _FEC_BASE_ADDR, \ + .irq = soc ## _INT_FEC, \ + } + +#ifdef CONFIG_ARCH_MX25 +const struct imx_fec_data imx25_fec_data __initconst = + imx_fec_data_entry_single(MX25); +#endif /* ifdef CONFIG_ARCH_MX25 */ + +#ifdef CONFIG_SOC_IMX27 +const struct imx_fec_data imx27_fec_data __initconst = + imx_fec_data_entry_single(MX27); +#endif /* ifdef CONFIG_SOC_IMX27 */ + +#ifdef CONFIG_ARCH_MX35 +const struct imx_fec_data imx35_fec_data __initconst = + imx_fec_data_entry_single(MX35); +#endif + +#ifdef CONFIG_ARCH_MX51 +const struct imx_fec_data imx51_fec_data __initconst = + imx_fec_data_entry_single(MX51); +#endif + +struct platform_device *__init imx_add_fec( + const struct imx_fec_data *data, + const struct fec_platform_data *pdata) +{ + struct resource res[] = { + { + .start = data->iobase, + .end = data->iobase + SZ_4K, + .flags = IORESOURCE_MEM, + }, { + .start = data->irq, + .end = data->irq, + .flags = IORESOURCE_IRQ, + }, + }; + + return imx_add_platform_device("fec", 0 /* -1? */, + res, ARRAY_SIZE(res), + pdata, sizeof(*pdata)); +} diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c new file mode 100644 index 000000000000..02d989018059 --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010 Pengutronix + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include <linux/compiler.h> +#include <linux/err.h> +#include <linux/init.h> + +#include <mach/hardware.h> +#include <mach/devices-common.h> +#ifdef SDMA_IS_MERGED +#include <mach/sdma.h> +#else +struct sdma_platform_data { + int sdma_version; + char *cpu_name; + int to_version; +}; +#endif + +struct imx_imx_sdma_data { + resource_size_t iobase; + resource_size_t irq; + struct sdma_platform_data pdata; +}; + +#define imx_imx_sdma_data_entry_single(soc, _sdma_version, _cpu_name, _to_version)\ + { \ + .iobase = soc ## _SDMA ## _BASE_ADDR, \ + .irq = soc ## _INT_SDMA, \ + .pdata = { \ + .sdma_version = _sdma_version, \ + .cpu_name = _cpu_name, \ + .to_version = _to_version, \ + }, \ + } + +#ifdef CONFIG_ARCH_MX25 +const struct imx_imx_sdma_data imx25_imx_sdma_data __initconst = + imx_imx_sdma_data_entry_single(MX25, 1, "imx25", 0); +#endif /* ifdef CONFIG_ARCH_MX25 */ + +#ifdef CONFIG_ARCH_MX31 +struct imx_imx_sdma_data imx31_imx_sdma_data __initdata = + imx_imx_sdma_data_entry_single(MX31, 1, "imx31", 0); +#endif /* ifdef CONFIG_ARCH_MX31 */ + +#ifdef CONFIG_ARCH_MX35 +struct imx_imx_sdma_data imx35_imx_sdma_data __initdata = + imx_imx_sdma_data_entry_single(MX35, 2, "imx35", 0); +#endif /* ifdef CONFIG_ARCH_MX35 */ + +#ifdef CONFIG_ARCH_MX51 +const struct imx_imx_sdma_data imx51_imx_sdma_data __initconst = + imx_imx_sdma_data_entry_single(MX51, 2, "imx51", 0); +#endif /* ifdef CONFIG_ARCH_MX51 */ + +static struct platform_device __init __maybe_unused *imx_add_imx_sdma( + const struct imx_imx_sdma_data *data) +{ + struct resource res[] = { + { + .start = data->iobase, + .end = data->iobase + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = data->irq, + .end = data->irq, + .flags = IORESOURCE_IRQ, + }, + }; + + return imx_add_platform_device("imx-sdma", -1, + res, ARRAY_SIZE(res), + &data->pdata, sizeof(data->pdata)); +} + +static struct platform_device __init __maybe_unused *imx_add_imx_dma(void) +{ + return imx_add_platform_device("imx-dma", -1, NULL, 0, NULL, 0); +} + +static int __init imxXX_add_imx_dma(void) +{ + struct platform_device *ret; + +#if defined(CONFIG_SOC_IMX21) || defined(CONFIG_SOC_IMX27) + if (cpu_is_mx21() || cpu_is_mx27()) + ret = imx_add_imx_dma(); + else +#endif + +#if defined(CONFIG_ARCH_MX25) + if (cpu_is_mx25()) + ret = imx_add_imx_sdma(&imx25_imx_sdma_data); + else +#endif + +#if defined(CONFIG_ARCH_MX31) + if (cpu_is_mx31()) { + imx31_imx_sdma_data.pdata.to_version = mx31_revision() >> 4; + ret = imx_add_imx_sdma(&imx31_imx_sdma_data); + } else +#endif + +#if defined(CONFIG_ARCH_MX35) + if (cpu_is_mx35()) { + imx35_imx_sdma_data.pdata.to_version = mx35_revision() >> 4; + ret = imx_add_imx_sdma(&imx35_imx_sdma_data); + } else +#endif + +#if defined(CONFIG_ARCH_MX51) + if (cpu_is_mx51()) + ret = imx_add_imx_sdma(&imx51_imx_sdma_data); + else +#endif + ret = ERR_PTR(-ENODEV); + + if (IS_ERR(ret)) + return PTR_ERR(ret); + + return 0; +} +arch_initcall(imxXX_add_imx_dma); diff --git a/arch/arm/plat-mxc/devices/platform-imx-i2c.c b/arch/arm/plat-mxc/devices/platform-imx-i2c.c index d0af9f7d8aed..679588453aad 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-i2c.c +++ b/arch/arm/plat-mxc/devices/platform-imx-i2c.c @@ -6,24 +6,95 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include <mach/hardware.h> #include <mach/devices-common.h> -struct platform_device *__init imx_add_imx_i2c(int id, - resource_size_t iobase, resource_size_t iosize, int irq, +#define imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size) \ + { \ + .id = _id, \ + .iobase = soc ## _I2C ## _hwid ## _BASE_ADDR, \ + .iosize = _size, \ + .irq = soc ## _INT_I2C ## _hwid, \ + } + +#define imx_imx_i2c_data_entry(soc, _id, _hwid, _size) \ + [_id] = imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size) + +#ifdef CONFIG_SOC_IMX1 +const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst = + imx_imx_i2c_data_entry_single(MX1, 0, , SZ_4K); +#endif /* ifdef CONFIG_SOC_IMX1 */ + +#ifdef CONFIG_SOC_IMX21 +const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst = + imx_imx_i2c_data_entry_single(MX21, 0, , SZ_4K); +#endif /* ifdef CONFIG_SOC_IMX21 */ + +#ifdef CONFIG_ARCH_MX25 +const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst = { +#define imx25_imx_i2c_data_entry(_id, _hwid) \ + imx_imx_i2c_data_entry(MX25, _id, _hwid, SZ_16K) + imx25_imx_i2c_data_entry(0, 1), + imx25_imx_i2c_data_entry(1, 2), + imx25_imx_i2c_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_ARCH_MX25 */ + +#ifdef CONFIG_SOC_IMX27 +const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = { +#define imx27_imx_i2c_data_entry(_id, _hwid) \ + imx_imx_i2c_data_entry(MX27, _id, _hwid, SZ_4K) + imx27_imx_i2c_data_entry(0, 1), + imx27_imx_i2c_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_SOC_IMX27 */ + +#ifdef CONFIG_ARCH_MX31 +const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst = { +#define imx31_imx_i2c_data_entry(_id, _hwid) \ + imx_imx_i2c_data_entry(MX31, _id, _hwid, SZ_4K) + imx31_imx_i2c_data_entry(0, 1), + imx31_imx_i2c_data_entry(1, 2), + imx31_imx_i2c_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_ARCH_MX31 */ + +#ifdef CONFIG_ARCH_MX35 +const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = { +#define imx35_imx_i2c_data_entry(_id, _hwid) \ + imx_imx_i2c_data_entry(MX35, _id, _hwid, SZ_4K) + imx35_imx_i2c_data_entry(0, 1), + imx35_imx_i2c_data_entry(1, 2), + imx35_imx_i2c_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_ARCH_MX35 */ + +#ifdef CONFIG_ARCH_MX51 +const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst = { +#define imx51_imx_i2c_data_entry(_id, _hwid) \ + imx_imx_i2c_data_entry(MX51, _id, _hwid, SZ_4K) + imx51_imx_i2c_data_entry(0, 1), + imx51_imx_i2c_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_ARCH_MX51 */ + +struct platform_device *__init imx_add_imx_i2c( + const struct imx_imx_i2c_data *data, const struct imxi2c_platform_data *pdata) { struct resource res[] = { { - .start = iobase, - .end = iobase + iosize - 1, + .start = data->iobase, + .end = data->iobase + data->iosize - 1, .flags = IORESOURCE_MEM, }, { - .start = irq, - .end = irq, + .start = data->irq, + .end = data->irq, .flags = IORESOURCE_IRQ, }, }; - return imx_add_platform_device("imx-i2c", id, res, ARRAY_SIZE(res), + return imx_add_platform_device("imx-i2c", data->id, + res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); } diff --git a/arch/arm/plat-mxc/devices/platform-imx-ssi.c b/arch/arm/plat-mxc/devices/platform-imx-ssi.c new file mode 100644 index 000000000000..38a7a0b8f2f1 --- /dev/null +++ b/arch/arm/plat-mxc/devices/platform-imx-ssi.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2010 Pengutronix + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ +#include <mach/hardware.h> +#include <mach/devices-common.h> + +#define imx_imx_ssi_data_entry(soc, _id, _hwid, _size) \ + [_id] = { \ + .id = _id, \ + .iobase = soc ## _SSI ## _hwid ## _BASE_ADDR, \ + .iosize = _size, \ + .irq = soc ## _INT_SSI ## _hwid, \ + .dmatx0 = soc ## _DMA_REQ_SSI ## _hwid ## _TX0, \ + .dmarx0 = soc ## _DMA_REQ_SSI ## _hwid ## _RX0, \ + .dmatx1 = soc ## _DMA_REQ_SSI ## _hwid ## _TX1, \ + .dmarx1 = soc ## _DMA_REQ_SSI ## _hwid ## _RX1, \ + } + +#ifdef CONFIG_SOC_IMX21 +const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst = { +#define imx21_imx_ssi_data_entry(_id, _hwid) \ + imx_imx_ssi_data_entry(MX21, _id, _hwid, SZ_4K) + imx21_imx_ssi_data_entry(0, 1), + imx21_imx_ssi_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_SOC_IMX21 */ + +#ifdef CONFIG_ARCH_MX25 +const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst = { +#define imx25_imx_ssi_data_entry(_id, _hwid) \ + imx_imx_ssi_data_entry(MX25, _id, _hwid, SZ_4K) + imx25_imx_ssi_data_entry(0, 1), + imx25_imx_ssi_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_ARCH_MX25 */ + +#ifdef CONFIG_SOC_IMX27 +const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = { +#define imx27_imx_ssi_data_entry(_id, _hwid) \ + imx_imx_ssi_data_entry(MX27, _id, _hwid, SZ_4K) + imx27_imx_ssi_data_entry(0, 1), + imx27_imx_ssi_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_SOC_IMX27 */ + +#ifdef CONFIG_ARCH_MX31 +const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst = { +#define imx31_imx_ssi_data_entry(_id, _hwid) \ + imx_imx_ssi_data_entry(MX31, _id, _hwid, SZ_4K) + imx31_imx_ssi_data_entry(0, 1), + imx31_imx_ssi_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_ARCH_MX31 */ + +#ifdef CONFIG_ARCH_MX35 +const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst = { +#define imx35_imx_ssi_data_entry(_id, _hwid) \ + imx_imx_ssi_data_entry(MX35, _id, _hwid, SZ_4K) + imx35_imx_ssi_data_entry(0, 1), + imx35_imx_ssi_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_ARCH_MX35 */ + +#ifdef CONFIG_ARCH_MX51 +const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst = { +#define imx51_imx_ssi_data_entry(_id, _hwid) \ + imx_imx_ssi_data_entry(MX51, _id, _hwid, SZ_4K) + imx51_imx_ssi_data_entry(0, 1), + imx51_imx_ssi_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_ARCH_MX51 */ + +struct platform_device *__init imx_add_imx_ssi( + const struct imx_imx_ssi_data *data, + const struct imx_ssi_platform_data *pdata) +{ + struct resource res[] = { + { + .start = data->iobase, + .end = data->iobase + data->iosize - 1, + .flags = IORESOURCE_MEM, + }, { + .start = data->irq, + .end = data->irq, + .flags = IORESOURCE_IRQ, + }, +#define DMARES(_name) { \ + .name = #_name, \ + .start = data->dma ## _name, \ + .end = data->dma ## _name, \ + .flags = IORESOURCE_DMA, \ +} + DMARES(tx0), + DMARES(rx0), + DMARES(tx1), + DMARES(rx1), + }; + + return imx_add_platform_device("imx-ssi", data->id, + res, ARRAY_SIZE(res), + pdata, sizeof(*pdata)); +} diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/plat-mxc/devices/platform-imx-uart.c index fa3dff1433e8..2039640adf27 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-uart.c +++ b/arch/arm/plat-mxc/devices/platform-imx-uart.c @@ -6,55 +6,148 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ +#include <mach/hardware.h> #include <mach/devices-common.h> -struct platform_device *__init imx_add_imx_uart_3irq(int id, - resource_size_t iobase, resource_size_t iosize, - resource_size_t irqrx, resource_size_t irqtx, - resource_size_t irqrts, +#define imx_imx_uart_3irq_data_entry(soc, _id, _hwid, _size) \ + [_id] = { \ + .id = _id, \ + .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \ + .iosize = _size, \ + .irqrx = soc ## _INT_UART ## _hwid ## RX, \ + .irqtx = soc ## _INT_UART ## _hwid ## TX, \ + .irqrts = soc ## _INT_UART ## _hwid ## RTS, \ + } + +#define imx_imx_uart_1irq_data_entry(soc, _id, _hwid, _size) \ + [_id] = { \ + .id = _id, \ + .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \ + .iosize = _size, \ + .irq = soc ## _INT_UART ## _hwid, \ + } + +#ifdef CONFIG_SOC_IMX1 +const struct imx_imx_uart_3irq_data imx1_imx_uart_data[] __initconst = { +#define imx1_imx_uart_data_entry(_id, _hwid) \ + imx_imx_uart_3irq_data_entry(MX1, _id, _hwid, 0xd0) + imx1_imx_uart_data_entry(0, 1), + imx1_imx_uart_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_SOC_IMX1 */ + +#ifdef CONFIG_SOC_IMX21 +const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst = { +#define imx21_imx_uart_data_entry(_id, _hwid) \ + imx_imx_uart_1irq_data_entry(MX21, _id, _hwid, SZ_4K) + imx21_imx_uart_data_entry(0, 1), + imx21_imx_uart_data_entry(1, 2), + imx21_imx_uart_data_entry(2, 3), + imx21_imx_uart_data_entry(3, 4), +}; +#endif + +#ifdef CONFIG_ARCH_MX25 +const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst = { +#define imx25_imx_uart_data_entry(_id, _hwid) \ + imx_imx_uart_1irq_data_entry(MX25, _id, _hwid, SZ_16K) + imx25_imx_uart_data_entry(0, 1), + imx25_imx_uart_data_entry(1, 2), + imx25_imx_uart_data_entry(2, 3), + imx25_imx_uart_data_entry(3, 4), + imx25_imx_uart_data_entry(4, 5), +}; +#endif /* ifdef CONFIG_ARCH_MX25 */ + +#ifdef CONFIG_SOC_IMX27 +const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = { +#define imx27_imx_uart_data_entry(_id, _hwid) \ + imx_imx_uart_1irq_data_entry(MX27, _id, _hwid, SZ_4K) + imx27_imx_uart_data_entry(0, 1), + imx27_imx_uart_data_entry(1, 2), + imx27_imx_uart_data_entry(2, 3), + imx27_imx_uart_data_entry(3, 4), + imx27_imx_uart_data_entry(4, 5), + imx27_imx_uart_data_entry(5, 6), +}; +#endif /* ifdef CONFIG_SOC_IMX27 */ + +#ifdef CONFIG_ARCH_MX31 +const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst = { +#define imx31_imx_uart_data_entry(_id, _hwid) \ + imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_4K) + imx31_imx_uart_data_entry(0, 1), + imx31_imx_uart_data_entry(1, 2), + imx31_imx_uart_data_entry(2, 3), + imx31_imx_uart_data_entry(3, 4), + imx31_imx_uart_data_entry(4, 5), +}; +#endif /* ifdef CONFIG_ARCH_MX31 */ + +#ifdef CONFIG_ARCH_MX35 +const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst = { +#define imx35_imx_uart_data_entry(_id, _hwid) \ + imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_16K) + imx35_imx_uart_data_entry(0, 1), + imx35_imx_uart_data_entry(1, 2), + imx35_imx_uart_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_ARCH_MX35 */ + +#ifdef CONFIG_ARCH_MX51 +const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst = { +#define imx51_imx_uart_data_entry(_id, _hwid) \ + imx_imx_uart_1irq_data_entry(MX51, _id, _hwid, SZ_4K) + imx51_imx_uart_data_entry(0, 1), + imx51_imx_uart_data_entry(1, 2), + imx51_imx_uart_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_ARCH_MX51 */ + +struct platform_device *__init imx_add_imx_uart_3irq( + const struct imx_imx_uart_3irq_data *data, const struct imxuart_platform_data *pdata) { struct resource res[] = { { - .start = iobase, - .end = iobase + iosize - 1, + .start = data->iobase, + .end = data->iobase + data->iosize - 1, .flags = IORESOURCE_MEM, }, { - .start = irqrx, - .end = irqrx, + .start = data->irqrx, + .end = data->irqrx, .flags = IORESOURCE_IRQ, }, { - .start = irqtx, - .end = irqtx, + .start = data->irqtx, + .end = data->irqtx, .flags = IORESOURCE_IRQ, }, { - .start = irqrts, - .end = irqrx, + .start = data->irqrts, + .end = data->irqrx, .flags = IORESOURCE_IRQ, }, }; - return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res), - pdata, sizeof(*pdata)); + return imx_add_platform_device("imx-uart", data->id, res, + ARRAY_SIZE(res), pdata, sizeof(*pdata)); } -struct platform_device *__init imx_add_imx_uart_1irq(int id, - resource_size_t iobase, resource_size_t iosize, - resource_size_t irq, +struct platform_device *__init imx_add_imx_uart_1irq( + const struct imx_imx_uart_1irq_data *data, const struct imxuart_platform_data *pdata) { struct resource res[] = { { - .start = iobase, - .end = iobase + iosize - 1, + .start = data->iobase, + .end = data->iobase + data->iosize - 1, .flags = IORESOURCE_MEM, }, { - .start = irq, - .end = irq, + .start = data->irq, + .end = data->irq, .flags = IORESOURCE_IRQ, }, }; - return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res), + return imx_add_platform_device("imx-uart", data->id, res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); } diff --git a/arch/arm/plat-mxc/devices/platform-mxc_nand.c b/arch/arm/plat-mxc/devices/platform-mxc_nand.c index 1c286418d123..3fdcc32e3d67 100644 --- a/arch/arm/plat-mxc/devices/platform-mxc_nand.c +++ b/arch/arm/plat-mxc/devices/platform-mxc_nand.c @@ -7,38 +7,77 @@ * Free Software Foundation. */ #include <asm/sizes.h> +#include <mach/hardware.h> #include <mach/devices-common.h> -static struct platform_device *__init imx_add_mxc_nand(resource_size_t iobase, - int irq, const struct mxc_nand_platform_data *pdata, - resource_size_t iosize) +#define imx_mxc_nand_data_entry_single(soc, _size) \ + { \ + .iobase = soc ## _NFC_BASE_ADDR, \ + .iosize = _size, \ + .irq = soc ## _INT_NFC \ + } + +#define imx_mxc_nandv3_data_entry_single(soc, _size) \ + { \ + .id = -1, \ + .iobase = soc ## _NFC_BASE_ADDR, \ + .iosize = _size, \ + .axibase = soc ## _NFC_AXI_BASE_ADDR, \ + .irq = soc ## _INT_NFC \ + } + +#ifdef CONFIG_SOC_IMX21 +const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst = + imx_mxc_nand_data_entry_single(MX21, SZ_4K); +#endif /* ifdef CONFIG_SOC_IMX21 */ + +#ifdef CONFIG_ARCH_MX25 +const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst = + imx_mxc_nand_data_entry_single(MX25, SZ_8K); +#endif /* ifdef CONFIG_ARCH_MX25 */ + +#ifdef CONFIG_SOC_IMX27 +const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst = + imx_mxc_nand_data_entry_single(MX27, SZ_4K); +#endif /* ifdef CONFIG_SOC_IMX27 */ + +#ifdef CONFIG_ARCH_MX31 +const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst = + imx_mxc_nand_data_entry_single(MX31, SZ_4K); +#endif + +#ifdef CONFIG_ARCH_MX35 +const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst = + imx_mxc_nand_data_entry_single(MX35, SZ_8K); +#endif + +#ifdef CONFIG_ARCH_MX51 +const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst = + imx_mxc_nandv3_data_entry_single(MX51, SZ_16K); +#endif + +struct platform_device *__init imx_add_mxc_nand( + const struct imx_mxc_nand_data *data, + const struct mxc_nand_platform_data *pdata) { - static int id = 0; - + /* AXI has to come first, that's how the mxc_nand driver expect it */ struct resource res[] = { { - .start = iobase, - .end = iobase + iosize - 1, + .start = data->axibase, + .end = data->axibase + SZ_16K - 1, .flags = IORESOURCE_MEM, }, { - .start = irq, - .end = irq, + .start = data->iobase, + .end = data->iobase + data->iosize - 1, + .flags = IORESOURCE_MEM, + }, { + .start = data->irq, + .end = data->irq, .flags = IORESOURCE_IRQ, }, }; - - return imx_add_platform_device("mxc_nand", id++, res, ARRAY_SIZE(res), + return imx_add_platform_device("mxc_nand", data->id, + res + !data->axibase, + ARRAY_SIZE(res) - !data->axibase, pdata, sizeof(*pdata)); } - -struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase, - int irq, const struct mxc_nand_platform_data *pdata) -{ - return imx_add_mxc_nand(iobase, irq, pdata, SZ_4K); -} - -struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase, - int irq, const struct mxc_nand_platform_data *pdata) -{ - return imx_add_mxc_nand(iobase, irq, pdata, SZ_8K); -} diff --git a/arch/arm/plat-mxc/devices/platform-spi_imx.c b/arch/arm/plat-mxc/devices/platform-spi_imx.c index 2831a6d3eb4b..e48340ec331e 100644 --- a/arch/arm/plat-mxc/devices/platform-spi_imx.c +++ b/arch/arm/plat-mxc/devices/platform-spi_imx.c @@ -6,25 +6,96 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. */ -#include <asm/sizes.h> +#include <mach/hardware.h> #include <mach/devices-common.h> -struct platform_device *__init imx_add_spi_imx(int id, - resource_size_t iobase, resource_size_t iosize, int irq, +#define imx_spi_imx_data_entry_single(soc, type, _devid, _id, hwid, _size) \ + { \ + .devid = _devid, \ + .id = _id, \ + .iobase = soc ## _ ## type ## hwid ## _BASE_ADDR, \ + .iosize = _size, \ + .irq = soc ## _INT_ ## type ## hwid, \ + } + +#define imx_spi_imx_data_entry(soc, type, devid, id, hwid, size) \ + [id] = imx_spi_imx_data_entry_single(soc, type, devid, id, hwid, size) + +#ifdef CONFIG_SOC_IMX21 +const struct imx_spi_imx_data imx21_cspi_data[] __initconst = { +#define imx21_cspi_data_entry(_id, _hwid) \ + imx_spi_imx_data_entry(MX21, CSPI, "imx21-cspi", _id, _hwid, SZ_4K) + imx21_cspi_data_entry(0, 1), + imx21_cspi_data_entry(1, 2), +#endif + +#ifdef CONFIG_ARCH_MX25 +const struct imx_spi_imx_data imx25_cspi_data[] __initconst = { +#define imx25_cspi_data_entry(_id, _hwid) \ + imx_spi_imx_data_entry(MX25, CSPI, "imx25-cspi", _id, _hwid, SZ_16K) + imx25_cspi_data_entry(0, 1), + imx25_cspi_data_entry(1, 2), + imx25_cspi_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_ARCH_MX25 */ + +#ifdef CONFIG_SOC_IMX27 +const struct imx_spi_imx_data imx27_cspi_data[] __initconst = { +#define imx27_cspi_data_entry(_id, _hwid) \ + imx_spi_imx_data_entry(MX27, CSPI, "imx27-cspi", _id, _hwid, SZ_4K) + imx27_cspi_data_entry(0, 1), + imx27_cspi_data_entry(1, 2), + imx27_cspi_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_SOC_IMX27 */ + +#ifdef CONFIG_ARCH_MX31 +const struct imx_spi_imx_data imx31_cspi_data[] __initconst = { +#define imx31_cspi_data_entry(_id, _hwid) \ + imx_spi_imx_data_entry(MX31, CSPI, "imx31-cspi", _id, _hwid, SZ_4K) + imx31_cspi_data_entry(0, 1), + imx31_cspi_data_entry(1, 2), + imx31_cspi_data_entry(2, 3), +}; +#endif /* ifdef CONFIG_ARCH_MX31 */ + +#ifdef CONFIG_ARCH_MX35 +const struct imx_spi_imx_data imx35_cspi_data[] __initconst = { +#define imx35_cspi_data_entry(_id, _hwid) \ + imx_spi_imx_data_entry(MX35, CSPI, "imx35-cspi", _id, _hwid, SZ_4K) + imx35_cspi_data_entry(0, 1), + imx35_cspi_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_ARCH_MX35 */ + +#ifdef CONFIG_ARCH_MX51 +const struct imx_spi_imx_data imx51_cspi_data __initconst = + imx_spi_imx_data_entry_single(MX51, CSPI, "imx51-cspi", 0, , SZ_4K); + +const struct imx_spi_imx_data imx51_ecspi_data[] __initconst = { +#define imx51_ecspi_data_entry(_id, _hwid) \ + imx_spi_imx_data_entry(MX51, ECSPI, "imx51-ecspi", _id, _hwid, SZ_4K) + imx51_ecspi_data_entry(0, 1), + imx51_ecspi_data_entry(1, 2), +}; +#endif /* ifdef CONFIG_ARCH_MX51 */ + +struct platform_device *__init imx_add_spi_imx( + const struct imx_spi_imx_data *data, const struct spi_imx_master *pdata) { struct resource res[] = { { - .start = iobase, - .end = iobase + iosize - 1, + .start = data->iobase, + .end = data->iobase + data->iosize - 1, .flags = IORESOURCE_MEM, }, { - .start = irq, - .end = irq, + .start = data->irq, + .end = data->irq, .flags = IORESOURCE_IRQ, }, }; - return imx_add_platform_device("spi_imx", id, res, ARRAY_SIZE(res), - pdata, sizeof(*pdata)); + return imx_add_platform_device(data->devid, data->id, + res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); } diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c index 35a064ff02ba..9915607683de 100644 --- a/arch/arm/plat-mxc/ehci.c +++ b/arch/arm/plat-mxc/ehci.c @@ -249,8 +249,8 @@ int mxc_initialize_usb_hw(int port, unsigned int flags) #ifdef CONFIG_ARCH_MX51 if (cpu_is_mx51()) { void __iomem *usb_base; - u32 usbotg_base; - u32 usbother_base; + void __iomem *usbotg_base; + void __iomem *usbother_base; int ret = 0; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c new file mode 100644 index 000000000000..ee9582f4972e --- /dev/null +++ b/arch/arm/plat-mxc/epit.c @@ -0,0 +1,242 @@ +/* + * linux/arch/arm/plat-mxc/epit.c + * + * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#define EPITCR 0x00 +#define EPITSR 0x04 +#define EPITLR 0x08 +#define EPITCMPR 0x0c +#define EPITCNR 0x10 + +#define EPITCR_EN (1 << 0) +#define EPITCR_ENMOD (1 << 1) +#define EPITCR_OCIEN (1 << 2) +#define EPITCR_RLD (1 << 3) +#define EPITCR_PRESC(x) (((x) & 0xfff) << 4) +#define EPITCR_SWR (1 << 16) +#define EPITCR_IOVW (1 << 17) +#define EPITCR_DBGEN (1 << 18) +#define EPITCR_WAITEN (1 << 19) +#define EPITCR_RES (1 << 20) +#define EPITCR_STOPEN (1 << 21) +#define EPITCR_OM_DISCON (0 << 22) +#define EPITCR_OM_TOGGLE (1 << 22) +#define EPITCR_OM_CLEAR (2 << 22) +#define EPITCR_OM_SET (3 << 22) +#define EPITCR_CLKSRC_OFF (0 << 24) +#define EPITCR_CLKSRC_PERIPHERAL (1 << 24) +#define EPITCR_CLKSRC_REF_HIGH (1 << 24) +#define EPITCR_CLKSRC_REF_LOW (3 << 24) + +#define EPITSR_OCIF (1 << 0) + +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/clockchips.h> +#include <linux/clk.h> + +#include <mach/hardware.h> +#include <asm/mach/time.h> +#include <mach/common.h> + +static struct clock_event_device clockevent_epit; +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; + +static void __iomem *timer_base; + +static inline void epit_irq_disable(void) +{ + u32 val; + + val = __raw_readl(timer_base + EPITCR); + val &= ~EPITCR_OCIEN; + __raw_writel(val, timer_base + EPITCR); +} + +static inline void epit_irq_enable(void) +{ + u32 val; + + val = __raw_readl(timer_base + EPITCR); + val |= EPITCR_OCIEN; + __raw_writel(val, timer_base + EPITCR); +} + +static void epit_irq_acknowledge(void) +{ + __raw_writel(EPITSR_OCIF, timer_base + EPITSR); +} + +static cycle_t epit_read(struct clocksource *cs) +{ + return 0 - __raw_readl(timer_base + EPITCNR); +} + +static struct clocksource clocksource_epit = { + .name = "epit", + .rating = 200, + .read = epit_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init epit_clocksource_init(struct clk *timer_clk) +{ + unsigned int c = clk_get_rate(timer_clk); + + clocksource_epit.mult = clocksource_hz2mult(c, + clocksource_epit.shift); + clocksource_register(&clocksource_epit); + + return 0; +} + +/* clock event */ + +static int epit_set_next_event(unsigned long evt, + struct clock_event_device *unused) +{ + unsigned long tcmp; + + tcmp = __raw_readl(timer_base + EPITCNR); + + __raw_writel(tcmp - evt, timer_base + EPITCMPR); + + return 0; +} + +static void epit_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long flags; + + /* + * The timer interrupt generation is disabled at least + * for enough time to call epit_set_next_event() + */ + local_irq_save(flags); + + /* Disable interrupt in GPT module */ + epit_irq_disable(); + + if (mode != clockevent_mode) { + /* Set event time into far-far future */ + + /* Clear pending interrupt */ + epit_irq_acknowledge(); + } + + /* Remember timer mode */ + clockevent_mode = mode; + local_irq_restore(flags); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + printk(KERN_ERR "epit_set_mode: Periodic mode is not " + "supported for i.MX EPIT\n"); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* + * Do not put overhead of interrupt enable/disable into + * epit_set_next_event(), the core has about 4 minutes + * to call epit_set_next_event() or shutdown clock after + * mode switching + */ + local_irq_save(flags); + epit_irq_enable(); + local_irq_restore(flags); + break; + case CLOCK_EVT_MODE_SHUTDOWN: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_RESUME: + /* Left event sources disabled, no more interrupts appear */ + break; + } +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t epit_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &clockevent_epit; + + epit_irq_acknowledge(); + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +static struct irqaction epit_timer_irq = { + .name = "i.MX EPIT Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = epit_timer_interrupt, +}; + +static struct clock_event_device clockevent_epit = { + .name = "epit", + .features = CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .set_mode = epit_set_mode, + .set_next_event = epit_set_next_event, + .rating = 200, +}; + +static int __init epit_clockevent_init(struct clk *timer_clk) +{ + unsigned int c = clk_get_rate(timer_clk); + + clockevent_epit.mult = div_sc(c, NSEC_PER_SEC, + clockevent_epit.shift); + clockevent_epit.max_delta_ns = + clockevent_delta2ns(0xfffffffe, &clockevent_epit); + clockevent_epit.min_delta_ns = + clockevent_delta2ns(0x800, &clockevent_epit); + + clockevent_epit.cpumask = cpumask_of(0); + + clockevents_register_device(&clockevent_epit); + + return 0; +} + +void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq) +{ + clk_enable(timer_clk); + + timer_base = base; + + /* + * Initialise to a known state (all timers off, and timing reset) + */ + __raw_writel(0x0, timer_base + EPITCR); + + __raw_writel(0xffffffff, timer_base + EPITLR); + __raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, + timer_base + EPITCR); + + /* init and register the timer to the framework */ + epit_clocksource_init(timer_clk); + epit_clockevent_init(timer_clk); + + /* Make irqs happen */ + setup_irq(irq, &epit_timer_irq); +} diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index 57ec4a896a5d..9d38da077edb 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -235,7 +235,7 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) unsigned long flags; spin_lock_irqsave(&port->lock, flags); - l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); + l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset); __raw_writel(l, reg); spin_unlock_irqrestore(&port->lock, flags); } diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h new file mode 100644 index 000000000000..94b60dd47137 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h @@ -0,0 +1,33 @@ +/* + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__ +#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__ + +#include <mach/hardware.h> + +/* + * These symbols are used by drivers/net/cs89x0.c. + * This is ugly as hell, but we have to provide them until + * someone fixed the driver. + */ + +/* Base address of PBC controller */ +#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT +/* Offsets for the PBC Controller register */ + +/* Ethernet Controller IO base address */ +#define PBC_CS8900A_IOBASE 0x020000 + +#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) + +#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) + +#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 2941472582d2..7a1e1f89ff09 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -32,6 +32,7 @@ extern void mx31_init_irq(void); extern void mx35_init_irq(void); extern void mx51_init_irq(void); extern void mxc91231_init_irq(void); +extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); extern int mx1_clocks_init(unsigned long fref); extern int mx21_clocks_init(unsigned long lref, unsigned long fref); diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h index c5f68c587309..86d7575a564d 100644 --- a/arch/arm/plat-mxc/include/mach/devices-common.h +++ b/arch/arm/plat-mxc/include/mach/devices-common.h @@ -14,47 +14,105 @@ struct platform_device *imx_add_platform_device(const char *name, int id, const struct resource *res, unsigned int num_resources, const void *data, size_t size_data); -#if defined (CONFIG_CAN_FLEXCAN) || defined (CONFIG_CAN_FLEXCAN_MODULE) +#include <linux/fec.h> +struct imx_fec_data { + resource_size_t iobase; + resource_size_t irq; +}; +struct platform_device *__init imx_add_fec( + const struct imx_fec_data *data, + const struct fec_platform_data *pdata); + #include <linux/can/platform/flexcan.h> struct platform_device *__init imx_add_flexcan(int id, resource_size_t iobase, resource_size_t iosize, resource_size_t irq, const struct flexcan_platform_data *pdata); -#else -/* the ifdef can be removed once the flexcan driver has been merged */ -struct flexcan_platform_data; -static inline struct platform_device *__init imx_add_flexcan(int id, - resource_size_t iobase, resource_size_t iosize, - resource_size_t irq, - const struct flexcan_platform_data *pdata) -{ - return NULL; -} -#endif #include <mach/i2c.h> -struct platform_device *__init imx_add_imx_i2c(int id, - resource_size_t iobase, resource_size_t iosize, int irq, +struct imx_imx_i2c_data { + int id; + resource_size_t iobase; + resource_size_t iosize; + resource_size_t irq; +}; +struct platform_device *__init imx_add_imx_i2c( + const struct imx_imx_i2c_data *data, const struct imxi2c_platform_data *pdata); +#include <mach/ssi.h> +struct imx_imx_ssi_data { + int id; + resource_size_t iobase; + resource_size_t iosize; + resource_size_t irq; + resource_size_t dmatx0; + resource_size_t dmarx0; + resource_size_t dmatx1; + resource_size_t dmarx1; +}; +struct platform_device *__init imx_add_imx_ssi( + const struct imx_imx_ssi_data *data, + const struct imx_ssi_platform_data *pdata); + #include <mach/imx-uart.h> -struct platform_device *__init imx_add_imx_uart_3irq(int id, - resource_size_t iobase, resource_size_t iosize, - resource_size_t irqrx, resource_size_t irqtx, - resource_size_t irqrts, +struct imx_imx_uart_3irq_data { + int id; + resource_size_t iobase; + resource_size_t iosize; + resource_size_t irqrx; + resource_size_t irqtx; + resource_size_t irqrts; +}; +struct platform_device *__init imx_add_imx_uart_3irq( + const struct imx_imx_uart_3irq_data *data, const struct imxuart_platform_data *pdata); -struct platform_device *__init imx_add_imx_uart_1irq(int id, - resource_size_t iobase, resource_size_t iosize, - resource_size_t irq, + +struct imx_imx_uart_1irq_data { + int id; + resource_size_t iobase; + resource_size_t iosize; + resource_size_t irq; +}; +struct platform_device *__init imx_add_imx_uart_1irq( + const struct imx_imx_uart_1irq_data *data, const struct imxuart_platform_data *pdata); #include <mach/mxc_nand.h> -struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase, - int irq, const struct mxc_nand_platform_data *pdata); -struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase, - int irq, const struct mxc_nand_platform_data *pdata); +struct imx_mxc_nand_data { + /* + * id is traditionally 0, but -1 is more appropriate. We use -1 for new + * machines but don't change existing devices as the nand device usually + * appears in the kernel command line to pass its partitioning. + */ + int id; + resource_size_t iobase; + resource_size_t iosize; + resource_size_t axibase; + resource_size_t irq; +}; +struct platform_device *__init imx_add_mxc_nand( + const struct imx_mxc_nand_data *data, + const struct mxc_nand_platform_data *pdata); #include <mach/spi.h> -struct platform_device *__init imx_add_spi_imx(int id, - resource_size_t iobase, resource_size_t iosize, int irq, +struct imx_spi_imx_data { + const char *devid; + int id; + resource_size_t iobase; + resource_size_t iosize; + int irq; +}; +struct platform_device *__init imx_add_spi_imx( + const struct imx_spi_imx_data *data, const struct spi_imx_master *pdata); + +#include <mach/esdhc.h> +struct imx_esdhc_imx_data { + int id; + resource_size_t iobase; + resource_size_t irq; +}; +struct platform_device *__init imx_add_esdhc( + const struct imx_esdhc_imx_data *data, + const struct esdhc_platform_data *pdata); diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h new file mode 100644 index 000000000000..a48a9aaa56b1 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/esdhc.h @@ -0,0 +1,16 @@ +/* + * Copyright 2010 Wolfram Sang <w.sang@pengutronix.de> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#ifndef __ASM_ARCH_IMX_ESDHC_H +#define __ASM_ARCH_IMX_ESDHC_H + +struct esdhc_platform_data { + unsigned int wp_gpio; /* write protect pin */ +}; +#endif /* __ASM_ARCH_IMX_ESDHC_H */ diff --git a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h index 656acb45d434..a21d3313f994 100644 --- a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h +++ b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h @@ -28,19 +28,22 @@ * its own devices, it calls baseboard's init function. * TODO: Add your own baseboard init function and call it from * inside eukrea_cpuimx25_init() eukrea_cpuimx27_init() - * eukrea_cpuimx35_init() or eukrea_cpuimx51_init(). + * eukrea_cpuimx35_init() eukrea_cpuimx51_init() + * or eukrea_cpuimx51sd_init(). * * This example here is for the development board. Refer * mach-mx25/eukrea_mbimxsd-baseboard.c for cpuimx25 * mach-imx/eukrea_mbimx27-baseboard.c for cpuimx27 * mach-mx3/eukrea_mbimxsd-baseboard.c for cpuimx35 * mach-mx5/eukrea_mbimx51-baseboard.c for cpuimx51 + * mach-mx5/eukrea_mbimxsd-baseboard.c for cpuimx51sd */ extern void eukrea_mbimxsd25_baseboard_init(void); extern void eukrea_mbimx27_baseboard_init(void); extern void eukrea_mbimxsd35_baseboard_init(void); extern void eukrea_mbimx51_baseboard_init(void); +extern void eukrea_mbimxsd51_baseboard_init(void); #endif diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h index 21bfa46785bb..e46b1c2836d4 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h @@ -45,6 +45,18 @@ typedef enum iomux_config { PAD_CTL_PKE | PAD_CTL_HYS) #define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \ PAD_CTL_SRE_FAST) +#define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \ + PAD_CTL_SRE_FAST) +#define MX51_SDHCI_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \ + PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_SRE_FAST | \ + PAD_CTL_DVS) + +#define MX51_PAD_CTRL_1 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \ + PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_HYS) +#define MX51_PAD_CTRL_2 (PAD_CTL_HYS | PAD_CTL_PKE) +#define MX51_PAD_CTRL_3 (PAD_CTL_PKE | PAD_CTL_PUS_100K_UP) +#define MX51_PAD_CTRL_4 (PAD_CTL_DVS | PAD_CTL_HYS | PAD_CTL_PKE) +#define MX51_PAD_CTRL_5 (PAD_CTL_DVS | PAD_CTL_DSE_HIGH) /* * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode> @@ -106,14 +118,20 @@ typedef enum iomux_config { #define MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0x0cc, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0x0d0, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_EB2__GPIO_2_22 IOMUX_PAD(0x468, 0x0d4, 1, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_EB2__FEC_MDIO IOMUX_PAD(0x468, 0x0d4, 3, 0x0, 0, MX51_PAD_CTRL_1 | PAD_CTL_PUS_22K_UP) #define MX51_PAD_EIM_EB3__GPIO_2_23 IOMUX_PAD(0x46c, 0x0d8, 1, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_EB3__FEC_RDAT1 IOMUX_PAD(0x46c, 0x0d8, 3, 0x0, 0, MX51_PAD_CTRL_2) #define MX51_PAD_EIM_OE__GPIO_2_24 IOMUX_PAD(0x470, 0x0dc, 1, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_CS0__GPIO_2_25 IOMUX_PAD(0x474, 0x0e0, 1, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_CS1__GPIO_2_26 IOMUX_PAD(0x478, 0x0e4, 1, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_CS2__GPIO_2_27 IOMUX_PAD(0x47c, 0x0e8, 1, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS2__FEC_RDAT2 IOMUX_PAD(0x47c, 0x0e8, 3, 0x0, 0, MX51_PAD_CTRL_2) #define MX51_PAD_EIM_CS3__GPIO_2_28 IOMUX_PAD(0x480, 0x0ec, 1, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS3__FEC_RDAT3 IOMUX_PAD(0x480, 0x0ec, 3, 0x0, 0, MX51_PAD_CTRL_2) #define MX51_PAD_EIM_CS4__GPIO_2_29 IOMUX_PAD(0x484, 0x0f0, 1, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS4__FEC_RX_ER IOMUX_PAD(0x484, 0x0f0, 3, 0x0, 0, MX51_PAD_CTRL_2) #define MX51_PAD_EIM_CS5__GPIO_2_30 IOMUX_PAD(0x488, 0x0f4, 1, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_EIM_CS5__FEC_CRS IOMUX_PAD(0x488, 0x0f4, 3, 0x0, 0, MX51_PAD_CTRL_2) #define MX51_PAD_EIM_DTACK__GPIO_2_31 IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_LBA__GPIO_3_1 IOMUX_PAD(0x494, 0x0FC, 1, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_EIM_CRE__GPIO_3_2 IOMUX_PAD(0x4A0, 0x100, 1, 0x0, 0, NO_PAD_CTRL) @@ -126,18 +144,32 @@ typedef enum iomux_config { #define MX51_PAD_NANDF_RB0__GPIO_3_8 IOMUX_PAD(0x4F8, 0x11C, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_RB1__GPIO_3_9 IOMUX_PAD(0x4FC, 0x120, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_RB2__GPIO_3_10 IOMUX_PAD(0x500, 0x124, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB2__ECSPI2_SCLK IOMUX_PAD(0x500, 0x124, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL) +#define MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x0, 0, MX51_PAD_CTRL_2) #define MX51_PAD_NANDF_RB3__GPIO_3_11 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RB3__ECSPI2_MISO IOMUX_PAD(0x504, 0x128, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL) +#define MX51_PAD_NANDF_RB3__FEC_RXCLK IOMUX_PAD(0x504, 0x128, 1, 0x0, 0, MX51_PAD_CTRL_2) +#define MX51_PAD_NANDF_RB6__FEC_RDAT0 IOMUX_PAD(0x5DC, 0x134, 1, 0x0, 0, MX51_PAD_CTRL_4) +#define MX51_PAD_NANDF_RB7__FEC_TDAT0 IOMUX_PAD(0x5E0, 0x138, 1, 0x0, 0, MX51_PAD_CTRL_5) #define MX51_PAD_GPIO_NAND__GPIO_3_12 IOMUX_PAD(0x514, 0x12C, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS0__GPIO_3_16 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS1__GPIO_3_17 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_CS2__GPIO_3_18 IOMUX_PAD(0x520, 0x138, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS2__FEC_TX_ER IOMUX_PAD(0x520, 0x138, 2, 0x0, 0, MX51_PAD_CTRL_5) #define MX51_PAD_NANDF_CS3__GPIO_3_19 IOMUX_PAD(0x524, 0x13C, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13C, 2, 0x0, 0, MX51_PAD_CTRL_5) #define MX51_PAD_NANDF_CS4__GPIO_3_20 IOMUX_PAD(0x528, 0x140, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS4__FEC_TDAT1 IOMUX_PAD(0x528, 0x140, 2, 0x0, 0, MX51_PAD_CTRL_5) #define MX51_PAD_NANDF_CS5__GPIO_3_21 IOMUX_PAD(0x52C, 0x144, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS5__FEC_TDAT2 IOMUX_PAD(0x52C, 0x144, 2, 0x0, 0, MX51_PAD_CTRL_5) #define MX51_PAD_NANDF_CS6__GPIO_3_22 IOMUX_PAD(0x530, 0x148, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS6__FEC_TDAT3 IOMUX_PAD(0x530, 0x148, 2, 0x0, 0, MX51_PAD_CTRL_5) #define MX51_PAD_NANDF_CS7__GPIO_3_23 IOMUX_PAD(0x534, 0x14C, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_CS7__FEC_TX_EN IOMUX_PAD(0x534, 0x14C, 1, 0x0, 0, MX51_PAD_CTRL_5) #define MX51_PAD_NANDF_RDY_INT__GPIO_3_24 IOMUX_PAD(0x538, 0x150, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x0, 0, MX51_PAD_CTRL_4) #define MX51_PAD_NANDF_D15__GPIO_3_25 IOMUX_PAD(0x53C, 0x154, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_NANDF_D15__ECSPI2_MOSI IOMUX_PAD(0x53C, 0x154, 2, 0x0, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_NANDF_D14__GPIO_3_26 IOMUX_PAD(0x540, 0x158, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_D13__GPIO_3_27 IOMUX_PAD(0x544, 0x15C, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_NANDF_D12__GPIO_3_28 IOMUX_PAD(0x548, 0x160, 3, 0x0, 0, NO_PAD_CTRL) @@ -185,15 +217,25 @@ typedef enum iomux_config { #define MX51_PAD_I2C1_CLK__HSI2C_CLK IOMUX_PAD(0x5E8, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_I2C1_DAT__GPIO_4_17 IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_I2C1_DAT__HSI2C_DAT IOMUX_PAD(0x5EC, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_AUD3_BB_TXD__AUD3_BB_TXD IOMUX_PAD(0x5F0, 0x200, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_AUD3_BB_TXD__GPIO_4_18 IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_AUD3_BB_RXD__AUD3_BB_RXD IOMUX_PAD(0x5F4, 0x204, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_AUD3_BB_RXD__GPIO_4_19 IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_AUD3_BB_CK__AUD3_BB_CK IOMUX_PAD(0x5F8, 0x208, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_AUD3_BB_CK__GPIO_4_20 IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_AUD3_BB_FS__AUD3_BB_FS IOMUX_PAD(0x5FC, 0x20C, IOMUX_CONFIG_SION, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_AUD3_BB_FS__GPIO_4_21 IOMUX_PAD(0x5FC, 0x20C, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x600, 0x210, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_CSPI1_MOSI__GPIO_4_22 IOMUX_PAD(0x600, 0x210, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x604, 0x214, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_CSPI1_MISO__GPIO_4_23 IOMUX_PAD(0x604, 0x214, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x608, 0x218, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_CSPI1_SS0__GPIO_4_24 IOMUX_PAD(0x608, 0x218, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_SS1__ECSPI1_SS1 IOMUX_PAD(0x60C, 0x21C, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_CSPI1_SS1__GPIO_4_25 IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_RDY__ECSPI1_RDY IOMUX_PAD(0x610, 0x220, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_CSPI1_RDY__GPIO_4_26 IOMUX_PAD(0x610, 0x220, 3, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x614, 0x224, 0, 0x0, 0, MX51_ECSPI_PAD_CTRL) #define MX51_PAD_CSPI1_SCLK__GPIO_4_27 IOMUX_PAD(0x614, 0x224, 3, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, 0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST) #define MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61C, 0x22C, 0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST) @@ -236,14 +278,14 @@ typedef enum iomux_config { #define MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 0, 0x0, 0, MX51_USBH1_PAD_CTRL) #define MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 0, 0x0, 0, MX51_USBH1_PAD_CTRL) #define MX51_PAD_DI1_PIN11__GPIO_3_0 IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_DI1_PIN12__GPIO_3_1 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_DI1_PIN13__GPIO_3_2 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_DI1_D0_CS__GPIO_3_3 IOMUX_PAD(0x6B4, 0x2B4, 4, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_DI1_D1_CS__GPIO_3_4 IOMUX_PAD(0x6B8, 0x2B8, 4, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_DISPB2_SER_DIN__GPIO_3_5 IOMUX_PAD(0x6BC, 0x2BC, 4, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_DISPB2_SER_DIO__GPIO_3_6 IOMUX_PAD(0x6C0, 0x2C0, 4, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_DISPB2_SER_CLK__GPIO_3_7 IOMUX_PAD(0x6C4, 0x2C4, 4, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_DISPB2_SER_RS__GPIO_3_8 IOMUX_PAD(0x6C8, 0x2C8, 4, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_DI1_PIN12__GPIO_3_1 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x978, 1, NO_PAD_CTRL) +#define MX51_PAD_DI1_PIN13__GPIO_3_2 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x97c, 1, NO_PAD_CTRL) +#define MX51_PAD_DI1_D0_CS__GPIO_3_3 IOMUX_PAD(0x6B4, 0x2B4, 4, 0x980, 1, NO_PAD_CTRL) +#define MX51_PAD_DI1_D1_CS__GPIO_3_4 IOMUX_PAD(0x6B8, 0x2B8, 4, 0x984, 1, NO_PAD_CTRL) +#define MX51_PAD_DISPB2_SER_DIN__GPIO_3_5 IOMUX_PAD(0x6BC, 0x2BC, 4, 0x988, 1, NO_PAD_CTRL) +#define MX51_PAD_DISPB2_SER_DIO__GPIO_3_6 IOMUX_PAD(0x6C0, 0x2C0, 4, 0x98c, 1, NO_PAD_CTRL) +#define MX51_PAD_DISPB2_SER_CLK__GPIO_3_7 IOMUX_PAD(0x6C4, 0x2C4, 4, 0x990, 1, NO_PAD_CTRL) +#define MX51_PAD_DISPB2_SER_RS__GPIO_3_8 IOMUX_PAD(0x6C8, 0x2C8, 4, 0x994, 1, NO_PAD_CTRL) #define MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL) @@ -294,32 +336,50 @@ typedef enum iomux_config { #define MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_1_0__GPIO_1_0 IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7C0, 0x3B8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7C4, 0x3BC, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7C8, 0x3C0, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7CC, 0x3C4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7D0, 0x3C8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_1_2__GPIO_1_2 IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD1_CMD__AUD5_RXFS IOMUX_PAD(0x79C, 0x394, 1, 0x8e0, 1, NO_PAD_CTRL) +#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS) +#define MX51_PAD_SD1_CLK__AUD5_RXC IOMUX_PAD(0x7A0, 0x398, 1, 0x8dc, 1, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD1_DATA0__AUD5_TXD IOMUX_PAD(0x7A4, 0x39C, 1, 0x8d8, 2, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD1_DATA1__AUD5_RXD IOMUX_PAD(0x7A8, 0x3A0, 1, 0x8d4, 2, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD1_DATA2__AUD5_TXC IOMUX_PAD(0x7AC, 0x3A4, 1, 0x8e4, 2, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD1_DATA3__AUD5_TXFS IOMUX_PAD(0x7B0, 0x3A8, 1, 0x8e8, 2, NO_PAD_CTRL) +#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, IOMUX_CONFIG_SION, 0x0, 1, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7C0, 0x3B8, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS) +#define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7C4, 0x3BC, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7C8, 0x3C0, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7CC, 0x3C4, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7D0, 0x3C8, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) +#define MX51_PAD_GPIO_1_0__GPIO_1_0 IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO_1_2__GPIO_1_2 IOMUX_PAD(0x7D4, 0x3CC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_GPIO_1_2__I2C2_SCL IOMUX_PAD(0x7D4, 0x3CC, (2 | IOMUX_CONFIG_SION), \ 0x9b8, 3, MX51_I2C_PAD_CTRL) -#define MX51_PAD_GPIO_1_3__GPIO_1_3 IOMUX_PAD(0x7D8, 0x3D0, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO_1_3__GPIO_1_3 IOMUX_PAD(0x7D8, 0x3D0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_GPIO_1_3__I2C2_SDA IOMUX_PAD(0x7D8, 0x3D0, (2 | IOMUX_CONFIG_SION), \ 0x9bc, 3, MX51_I2C_PAD_CTRL) #define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, MX51_GPIO_PAD_CTRL) -#define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL) -#define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, MX51_GPIO_PAD_CTRL) -#define MX51_PAD_GPIO_1_9__GPIO_1_9 IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) +#define MX51_PAD_GPIO_1_9__GPIO_1_9 IOMUX_PAD(0x818, 0x3EC, 1, 0x0, 0, MX51_GPIO_PAD_CTRL) #endif /* __MACH_IOMUX_MX51_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/iram.h b/arch/arm/plat-mxc/include/mach/iram.h new file mode 100644 index 000000000000..022690c33702 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iram.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include <linux/errno.h> + +#ifdef CONFIG_IRAM_ALLOC + +int __init iram_init(unsigned long base, unsigned long size); +void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr); +void iram_free(unsigned long dma_addr, unsigned int size); + +#else + +static inline int __init iram_init(unsigned long base, unsigned long size) +{ + return -ENOMEM; +} + +static inline void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) +{ + return NULL; +} + +static inline void iram_free(unsigned long base, unsigned long size) {} + +#endif diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h index ed98b9c9f389..8bc59720b6e4 100644 --- a/arch/arm/plat-mxc/include/mach/mx21.h +++ b/arch/arm/plat-mxc/include/mach/mx21.h @@ -120,7 +120,7 @@ #define MX21_INT_GPT1 26 #define MX21_INT_WDOG 27 #define MX21_INT_PCMCIA 28 -#define MX21_INT_NANDFC 29 +#define MX21_INT_NFC 29 #define MX21_INT_BMI 30 #define MX21_INT_CSI 31 #define MX21_INT_DMACH0 32 diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h index 4a6f800990f8..cf46a45b0d4e 100644 --- a/arch/arm/plat-mxc/include/mach/mx25.h +++ b/arch/arm/plat-mxc/include/mach/mx25.h @@ -50,8 +50,11 @@ #define MX25_SSI1_BASE_ADDR 0x50034000 #define MX25_NFC_BASE_ADDR 0xbb000000 #define MX25_DRYICE_BASE_ADDR 0x53ffc000 +#define MX25_ESDHC1_BASE_ADDR 0x53fb4000 +#define MX25_ESDHC2_BASE_ADDR 0x53fb8000 #define MX25_LCDC_BASE_ADDR 0x53fbc000 #define MX25_KPP_BASE_ADDR 0x43fa8000 +#define MX25_SDMA_BASE_ADDR 0x53fd4000 #define MX25_OTG_BASE_ADDR 0x53ff4000 #define MX25_CSI_BASE_ADDR 0x53ff8000 @@ -59,6 +62,8 @@ #define MX25_INT_I2C1 3 #define MX25_INT_I2C2 4 #define MX25_INT_UART4 5 +#define MX25_INT_ESDHC2 8 +#define MX25_INT_ESDHC1 9 #define MX25_INT_I2C3 10 #define MX25_INT_SSI2 11 #define MX25_INT_SSI1 12 @@ -69,7 +74,8 @@ #define MX25_INT_KPP 24 #define MX25_INT_DRYICE 25 #define MX25_INT_UART2 32 -#define MX25_INT_NANDFC 33 +#define MX25_INT_NFC 33 +#define MX25_INT_SDMA 34 #define MX25_INT_LCDC 39 #define MX25_INT_UART5 40 #define MX25_INT_CAN1 43 @@ -77,4 +83,13 @@ #define MX25_INT_UART1 45 #define MX25_INT_FEC 57 +#define MX25_DMA_REQ_SSI2_RX1 22 +#define MX25_DMA_REQ_SSI2_TX1 23 +#define MX25_DMA_REQ_SSI2_RX0 24 +#define MX25_DMA_REQ_SSI2_TX0 25 +#define MX25_DMA_REQ_SSI1_RX1 26 +#define MX25_DMA_REQ_SSI1_TX1 27 +#define MX25_DMA_REQ_SSI1_RX0 28 +#define MX25_DMA_REQ_SSI1_TX0 29 + #endif /* ifndef __MACH_MX25_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h index a8ab2e02a8ca..2237ba2e5351 100644 --- a/arch/arm/plat-mxc/include/mach/mx27.h +++ b/arch/arm/plat-mxc/include/mach/mx27.h @@ -167,7 +167,7 @@ static inline void mx27_setup_weimcs(size_t cs, #define MX27_INT_GPT1 26 #define MX27_INT_WDOG 27 #define MX27_INT_PCMCIA 28 -#define MX27_INT_NANDFC 29 +#define MX27_INT_NFC 29 #define MX27_INT_ATA 30 #define MX27_INT_CSI 31 #define MX27_INT_DMACH0 32 diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h index afee3ab9d62e..03e2afabc9fc 100644 --- a/arch/arm/plat-mxc/include/mach/mx31.h +++ b/arch/arm/plat-mxc/include/mach/mx31.h @@ -168,7 +168,7 @@ static inline void mx31_setup_weimcs(size_t cs, #define MX31_INT_POWER_FAIL 30 #define MX31_INT_CCM_DVFS 31 #define MX31_INT_UART2 32 -#define MX31_INT_NANDFC 33 +#define MX31_INT_NFC 33 #define MX31_INT_SDMA 34 #define MX31_INT_USB1 35 #define MX31_INT_USB2 36 @@ -197,6 +197,15 @@ static inline void mx31_setup_weimcs(size_t cs, #define MX31_INT_EXT_WDOG 62 #define MX31_INT_EXT_TV 63 +#define MX31_DMA_REQ_SSI2_RX1 22 +#define MX31_DMA_REQ_SSI2_TX1 23 +#define MX31_DMA_REQ_SSI2_RX0 24 +#define MX31_DMA_REQ_SSI2_TX0 25 +#define MX31_DMA_REQ_SSI1_RX1 26 +#define MX31_DMA_REQ_SSI1_TX1 27 +#define MX31_DMA_REQ_SSI1_RX0 28 +#define MX31_DMA_REQ_SSI1_TX0 29 + #define MX31_PROD_SIGNATURE 0x1 /* For MX31 */ /* silicon revisions specific to i.MX31 */ diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h index af3038c12e39..ff905cb32458 100644 --- a/arch/arm/plat-mxc/include/mach/mx35.h +++ b/arch/arm/plat-mxc/include/mach/mx35.h @@ -1,5 +1,6 @@ #ifndef __MACH_MX35_H__ #define __MACH_MX35_H__ + /* * IRAM */ @@ -52,6 +53,9 @@ #define MX35_GPIO3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xa4000) #define MX35_SCC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xac000) #define MX35_RNGA_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb0000) +#define MX35_ESDHC1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb4000) +#define MX35_ESDHC2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb8000) +#define MX35_ESDHC3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xbc000) #define MX35_IPU_CTRL_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc0000) #define MX35_AUDMUX_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc4000) #define MX35_GPIO1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xcc000) @@ -63,6 +67,8 @@ #define MX35_CAN1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe4000) #define MX35_CAN2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe8000) #define MX35_RTIC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xec000) +#define MX35_IIM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf0000) + #define MX35_OTG_BASE_ADDR 0x53ff4000 #define MX35_ROMP_BASE_ADDR 0x60000000 @@ -122,9 +128,9 @@ #define MX35_INT_I2C3 3 #define MX35_INT_I2C2 4 #define MX35_INT_RTIC 6 -#define MX35_INT_MMC_SDHC1 7 -#define MX35_INT_MMC_SDHC2 8 -#define MX35_INT_MMC_SDHC3 9 +#define MX35_INT_ESDHC1 7 +#define MX35_INT_ESDHC2 8 +#define MX35_INT_ESDHC3 9 #define MX35_INT_I2C1 10 #define MX35_INT_SSI1 11 #define MX35_INT_SSI2 12 @@ -145,7 +151,7 @@ #define MX35_INT_GPT 29 #define MX35_INT_POWER_FAIL 30 #define MX35_INT_UART2 32 -#define MX35_INT_NANDFC 33 +#define MX35_INT_NFC 33 #define MX35_INT_SDMA 34 #define MX35_INT_USBHS 35 #define MX35_INT_USBOTG 37 @@ -173,22 +179,18 @@ #define MX35_INT_EXT_WDOG 62 #define MX35_INT_EXT_TV 63 +#define MX35_DMA_REQ_SSI2_RX1 22 +#define MX35_DMA_REQ_SSI2_TX1 23 +#define MX35_DMA_REQ_SSI2_RX0 24 +#define MX35_DMA_REQ_SSI2_TX0 25 +#define MX35_DMA_REQ_SSI1_RX1 26 +#define MX35_DMA_REQ_SSI1_TX1 27 +#define MX35_DMA_REQ_SSI1_RX0 28 +#define MX35_DMA_REQ_SSI1_TX0 29 + #define MX35_PROD_SIGNATURE 0x1 /* For MX31 */ -/* silicon revisions specific to i.MX31 */ -#define MX35_CHIP_REV_1_0 0x10 -#define MX35_CHIP_REV_1_1 0x11 -#define MX35_CHIP_REV_1_2 0x12 -#define MX35_CHIP_REV_1_3 0x13 -#define MX35_CHIP_REV_2_0 0x20 -#define MX35_CHIP_REV_2_1 0x21 -#define MX35_CHIP_REV_2_2 0x22 -#define MX35_CHIP_REV_2_3 0x23 -#define MX35_CHIP_REV_3_0 0x30 -#define MX35_CHIP_REV_3_1 0x31 -#define MX35_CHIP_REV_3_2 0x32 - -#define MX35_SYSTEM_REV_MIN MX35_CHIP_REV_1_0 +#define MX35_SYSTEM_REV_MIN MX3x_CHIP_REV_1_0 #define MX35_SYSTEM_REV_NUM 3 #ifdef IMX_NEEDS_DEPRECATED_SYMBOLS diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h index 7a356de385f5..d1bd26d7b8a6 100644 --- a/arch/arm/plat-mxc/include/mach/mx3x.h +++ b/arch/arm/plat-mxc/include/mach/mx3x.h @@ -240,7 +240,7 @@ #define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */ -/* silicon revisions specific to i.MX31 */ +/* silicon revisions specific to i.MX31 and i.MX35 */ #define MX3x_CHIP_REV_1_0 0x10 #define MX3x_CHIP_REV_1_1 0x11 #define MX3x_CHIP_REV_1_2 0x12 @@ -267,6 +267,14 @@ static inline int mx31_revision(void) { return mx31_cpu_rev; } + +extern unsigned int mx35_cpu_rev; +extern void mx35_read_cpu_rev(void); + +static inline int mx35_revision(void) +{ + return mx35_cpu_rev; +} #endif #ifdef IMX_NEEDS_DEPRECATED_SYMBOLS @@ -389,19 +397,6 @@ static inline int mx31_revision(void) #define MXC_INT_EXT_WDOG MX3x_INT_EXT_WDOG #define MXC_INT_EXT_TV MX3x_INT_EXT_TV #define PROD_SIGNATURE MX3x_PROD_SIGNATURE -#define CHIP_REV_1_0 MX3x_CHIP_REV_1_0 -#define CHIP_REV_1_1 MX3x_CHIP_REV_1_1 -#define CHIP_REV_1_2 MX3x_CHIP_REV_1_2 -#define CHIP_REV_1_3 MX3x_CHIP_REV_1_3 -#define CHIP_REV_2_0 MX3x_CHIP_REV_2_0 -#define CHIP_REV_2_1 MX3x_CHIP_REV_2_1 -#define CHIP_REV_2_2 MX3x_CHIP_REV_2_2 -#define CHIP_REV_2_3 MX3x_CHIP_REV_2_3 -#define CHIP_REV_3_0 MX3x_CHIP_REV_3_0 -#define CHIP_REV_3_1 MX3x_CHIP_REV_3_1 -#define CHIP_REV_3_2 MX3x_CHIP_REV_3_2 -#define SYSTEM_REV_MIN MX3x_SYSTEM_REV_MIN -#define SYSTEM_REV_NUM MX3x_SYSTEM_REV_NUM #endif #endif /* ifndef __MACH_MX3x_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index 5aad344d5651..2af7a1056fc1 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -1,5 +1,5 @@ -#ifndef __ASM_ARCH_MXC_MX51_H__ -#define __ASM_ARCH_MXC_MX51_H__ +#ifndef __MACH_MX51_H__ +#define __MACH_MX51_H__ /* * MX51 memory map: @@ -7,24 +7,23 @@ * * Virt Phys Size What * --------------------------------------------------------------------------- - * FA3E0000 1FFE0000 128K IRAM (SCCv2 RAM) + * fa3e0000 1ffe0000 128K IRAM (SCCv2 RAM) * 30000000 256M GPU * 40000000 512M IPU - * FA200000 60000000 1M DEBUG - * FB100000 70000000 1M SPBA 0 - * FB000000 73F00000 1M AIPS 1 - * FB200000 83F00000 1M AIPS 2 - * 8FFFC000 16K TZIC (interrupt controller) + * fa200000 60000000 1M DEBUG + * fb100000 70000000 1M SPBA 0 + * fb000000 73f00000 1M AIPS 1 + * fb200000 83f00000 1M AIPS 2 + * 8fffc000 16K TZIC (interrupt controller) * 90000000 256M CSD0 SDRAM/DDR - * A0000000 256M CSD1 SDRAM/DDR - * B0000000 128M CS0 Flash - * B8000000 128M CS1 Flash - * C0000000 128M CS2 Flash - * C8000000 64M CS3 Flash - * CC000000 32M CS4 SRAM - * CE000000 32M CS5 SRAM - * CFFF0000 64K NFC (NAND Flash AXI) - * + * a0000000 256M CSD1 SDRAM/DDR + * b0000000 128M CS0 Flash + * b8000000 128M CS1 Flash + * c0000000 128M CS2 Flash + * c8000000 64M CS3 Flash + * cc000000 32M CS4 SRAM + * ce000000 32M CS5 SRAM + * cfff0000 64K NFC (NAND Flash AXI) */ /* @@ -36,65 +35,151 @@ /* * IRAM */ -#define MX51_IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */ -#define MX51_IRAM_BASE_ADDR_VIRT 0xFA3E0000 +#define MX51_IRAM_BASE_ADDR 0x1ffe0000 /* internal ram */ +#define MX51_IRAM_BASE_ADDR_VIRT 0xfa3e0000 #define MX51_IRAM_PARTITIONS 16 -#define MX51_IRAM_PARTITIONS_TO1 12 #define MX51_IRAM_SIZE (MX51_IRAM_PARTITIONS * SZ_8K) /* 128KB */ +#define MX51_GPU_BASE_ADDR 0x20000000 +#define MX51_GPU_CTRL_BASE_ADDR 0x30000000 +#define MX51_IPU_CTRL_BASE_ADDR 0x40000000 + +#define MX51_DEBUG_BASE_ADDR 0x60000000 +#define MX51_DEBUG_BASE_ADDR_VIRT 0xfa200000 +#define MX51_DEBUG_SIZE SZ_1M + +#define MX51_ETB_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x01000) +#define MX51_ETM_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x02000) +#define MX51_TPIU_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x03000) +#define MX51_CTI0_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x04000) +#define MX51_CTI1_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x05000) +#define MX51_CTI2_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x06000) +#define MX51_CTI3_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x07000) +#define MX51_CORTEX_DBG_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x08000) + /* - * NFC + * SPBA global module enabled #0 */ -#define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */ -#define MX51_NFC_AXI_SIZE SZ_64K +#define MX51_SPBA0_BASE_ADDR 0x70000000 +#define MX51_SPBA0_BASE_ADDR_VIRT 0xfb100000 +#define MX51_SPBA0_SIZE SZ_1M + +#define MX51_ESDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x04000) +#define MX51_ESDHC2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x08000) +#define MX51_UART3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0c000) +#define MX51_ECSPI1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x10000) +#define MX51_SSI2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x14000) +#define MX51_ESDHC3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x20000) +#define MX51_ESDHC4_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x24000) +#define MX51_SPDIF_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x28000) +#define MX51_ATA_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x30000) +#define MX51_SLIM_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x34000) +#define MX51_HSI2C_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x38000) +#define MX51_SPBA_CTRL_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x3c000) /* - * Graphics Memory of GPU + * AIPS 1 */ -#define MX51_GPU_BASE_ADDR 0x20000000 -#define MX51_GPU2D_BASE_ADDR 0xD0000000 +#define MX51_AIPS1_BASE_ADDR 0x73f00000 +#define MX51_AIPS1_BASE_ADDR_VIRT 0xfb000000 +#define MX51_AIPS1_SIZE SZ_1M + +#define MX51_OTG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x80000) +#define MX51_GPIO1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x84000) +#define MX51_GPIO2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x88000) +#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x8c000) +#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x90000) +#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x94000) +#define MX51_WDOG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x98000) +#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x9c000) +#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa0000) +#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa4000) +#define MX51_IOMUXC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa8000) +#define MX51_EPIT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xac000) +#define MX51_EPIT2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb0000) +#define MX51_PWM1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb4000) +#define MX51_PWM2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb8000) +#define MX51_UART1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xbc000) +#define MX51_UART2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xc0000) +#define MX51_SRC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd0000) +#define MX51_CCM_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd4000) +#define MX51_GPC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd8000) -#define MX51_TZIC_BASE_ADDR_TO1 0x8FFFC000 -#define MX51_TZIC_BASE_ADDR 0xE0000000 +/* + * AIPS 2 + */ +#define MX51_AIPS2_BASE_ADDR 0x83f00000 +#define MX51_AIPS2_BASE_ADDR_VIRT 0xfb200000 +#define MX51_AIPS2_SIZE SZ_1M -#define MX51_DEBUG_BASE_ADDR 0x60000000 -#define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000 -#define MX51_DEBUG_SIZE SZ_1M -#define MX51_ETB_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00001000) -#define MX51_ETM_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00002000) -#define MX51_TPIU_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00003000) -#define MX51_CTI0_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00004000) -#define MX51_CTI1_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00005000) -#define MX51_CTI2_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00006000) -#define MX51_CTI3_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00007000) -#define MX51_CORTEX_DBG_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x00008000) +#define MX51_PLL1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x80000) +#define MX51_PLL2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x84000) +#define MX51_PLL3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x88000) +#define MX51_AHBMAX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x94000) +#define MX51_IIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x98000) +#define MX51_CSU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x9c000) +#define MX51_ARM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa0000) +#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa4000) +#define MX51_FIRI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa8000) +#define MX51_ECSPI2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xac000) +#define MX51_SDMA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb0000) +#define MX51_SCC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb4000) +#define MX51_ROMCP_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb8000) +#define MX51_RTIC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xbc000) +#define MX51_CSPI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc0000) +#define MX51_I2C2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc4000) +#define MX51_I2C1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc8000) +#define MX51_SSI1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xcc000) +#define MX51_AUDMUX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd0000) +#define MX51_M4IF_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd8000) +#define MX51_ESDCTL_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd9000) +#define MX51_WEIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xda000) +#define MX51_NFC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdb000) +#define MX51_EMI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdbf00) +#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdc000) +#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe0000) +#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe4000) +#define MX51_SSI3BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe8000) +#define MX51_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xec000) +#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf0000) +#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf4000) +#define MX51_SAHARA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf8000) + +#define MX51_CSD0_BASE_ADDR 0x90000000 +#define MX51_CSD1_BASE_ADDR 0xa0000000 +#define MX51_CS0_BASE_ADDR 0xb0000000 +#define MX51_CS1_BASE_ADDR 0xb8000000 +#define MX51_CS2_BASE_ADDR 0xc0000000 +#define MX51_CS3_BASE_ADDR 0xc8000000 +#define MX51_CS4_BASE_ADDR 0xcc000000 +#define MX51_CS5_BASE_ADDR 0xce000000 /* - * SPBA global module enabled #0 + * NFC */ -#define MX51_SPBA0_BASE_ADDR 0x70000000 -#define MX51_SPBA0_BASE_ADDR_VIRT 0xFB100000 -#define MX51_SPBA0_SIZE SZ_1M +#define MX51_NFC_AXI_BASE_ADDR 0xcfff0000 /* NAND flash AXI */ +#define MX51_NFC_AXI_SIZE SZ_64K + +#define MX51_GPU2D_BASE_ADDR 0xd0000000 +#define MX51_TZIC_BASE_ADDR 0xe0000000 -#define MX51_MMC_SDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00004000) -#define MX51_MMC_SDHC2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00008000) -#define MX51_UART3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0000C000) -#define MX51_CSPI1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00010000) -#define MX51_SSI2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00014000) -#define MX51_MMC_SDHC3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00020000) -#define MX51_MMC_SDHC4_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00024000) -#define MX51_SPDIF_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00028000) -#define MX51_ATA_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00030000) -#define MX51_SLIM_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00034000) -#define MX51_HSI2C_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x00038000) -#define MX51_SPBA_CTRL_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0003C000) +#define MX51_IO_ADDRESS(x) ( \ + IMX_IO_ADDRESS(x, MX51_IRAM) ?: \ + IMX_IO_ADDRESS(x, MX51_DEBUG) ?: \ + IMX_IO_ADDRESS(x, MX51_SPBA0) ?: \ + IMX_IO_ADDRESS(x, MX51_AIPS1) ?: \ + IMX_IO_ADDRESS(x, MX51_AIPS2)) + +/* This is currently used in <mach/debug-macro.S>, but should go away */ +#define MX51_AIPS1_IO_ADDRESS(x) \ + (((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT) /* * defines for SPBA modules */ #define MX51_SPBA_SDHC1 0x04 #define MX51_SPBA_SDHC2 0x08 -#define MX51_SPBA_UART3 0x0C +#define MX51_SPBA_UART3 0x0c #define MX51_SPBA_CSPI1 0x10 #define MX51_SPBA_SSI2 0x14 #define MX51_SPBA_SDHC3 0x20 @@ -103,35 +188,7 @@ #define MX51_SPBA_ATA 0x30 #define MX51_SPBA_SLIM 0x34 #define MX51_SPBA_HSI2C 0x38 -#define MX51_SPBA_CTRL 0x3C - -/* - * AIPS 1 - */ -#define MX51_AIPS1_BASE_ADDR 0x73F00000 -#define MX51_AIPS1_BASE_ADDR_VIRT 0xFB000000 -#define MX51_AIPS1_SIZE SZ_1M - -#define MX51_OTG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00080000) -#define MX51_GPIO1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00084000) -#define MX51_GPIO2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00088000) -#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x0008C000) -#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00090000) -#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00094000) -#define MX51_WDOG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x00098000) -#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x0009C000) -#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A0000) -#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A4000) -#define MX51_IOMUXC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000A8000) -#define MX51_EPIT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000AC000) -#define MX51_EPIT2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B0000) -#define MX51_PWM1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B4000) -#define MX51_PWM2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000B8000) -#define MX51_UART1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000BC000) -#define MX51_UART2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000C0000) -#define MX51_SRC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D0000) -#define MX51_CCM_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D4000) -#define MX51_GPC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x000D8000) +#define MX51_SPBA_CTRL 0x3c /* * Defines for modules using static and dynamic DMA channels @@ -164,282 +221,186 @@ #define MX51_MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL #define MX51_MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL -/* - * AIPS 2 - */ -#define MX51_AIPS2_BASE_ADDR 0x83F00000 -#define MX51_AIPS2_BASE_ADDR_VIRT 0xFB200000 -#define MX51_AIPS2_SIZE SZ_1M - -#define MX51_PLL1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00080000) -#define MX51_PLL2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00084000) -#define MX51_PLL3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00088000) -#define MX51_AHBMAX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00094000) -#define MX51_IIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x00098000) -#define MX51_CSU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x0009C000) -#define MX51_ARM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A0000) -#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A4000) -#define MX51_FIRI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000A8000) -#define MX51_CSPI2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000AC000) -#define MX51_SDMA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B0000) -#define MX51_SCC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B4000) -#define MX51_ROMCP_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000B8000) -#define MX51_RTIC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000BC000) -#define MX51_CSPI3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C0000) -#define MX51_I2C2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C4000) -#define MX51_I2C1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000C8000) -#define MX51_SSI1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000CC000) -#define MX51_AUDMUX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D0000) -#define MX51_M4IF_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D8000) -#define MX51_ESDCTL_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000D9000) -#define MX51_WEIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DA000) -#define MX51_NFC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DB000) -#define MX51_EMI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DBF00) -#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000DC000) -#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E0000) -#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E4000) -#define MX51_SSI3BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000E8000) -#define MX51_MXC_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000EC000) -#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F0000) -#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F4000) -#define MX51_SAHARA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x000F8000) - -/* - * Memory regions and CS - */ -#define MX51_GPU_CTRL_BASE_ADDR 0x30000000 -#define MX51_IPU_CTRL_BASE_ADDR 0x40000000 -#define MX51_CSD0_BASE_ADDR 0x90000000 -#define MX51_CSD1_BASE_ADDR 0xA0000000 -#define MX51_CS0_BASE_ADDR 0xB0000000 -#define MX51_CS1_BASE_ADDR 0xB8000000 -#define MX51_CS2_BASE_ADDR 0xC0000000 -#define MX51_CS3_BASE_ADDR 0xC8000000 -#define MX51_CS4_BASE_ADDR 0xCC000000 -#define MX51_CS5_BASE_ADDR 0xCE000000 - -/* Does given address belongs to the specified memory region? */ -#define ADDRESS_IN_REGION(addr, start, size) \ - (((addr) >= (start)) && ((addr) < (start)+(size))) - -/* Does given address belongs to the specified named `module'? */ -#define MX51_IS_MODULE(addr, module) \ - ADDRESS_IN_REGION(addr, MX51_ ## module ## _BASE_ADDR, \ - MX51_ ## module ## _SIZE) -/* - * This macro defines the physical to virtual address mapping for all the - * peripheral modules. It is used by passing in the physical address as x - * and returning the virtual address. If the physical address is not mapped, - * it returns 0xDEADBEEF - */ - -#define MX51_IO_ADDRESS(x) \ - (void __iomem *) \ - (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \ - MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \ - 0xDEADBEEF) - -/* - * define the address mapping macros: in physical address order - */ -#define MX51_IRAM_IO_ADDRESS(x) \ - (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT) - -#define MX51_DEBUG_IO_ADDRESS(x) \ - (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT) - -#define MX51_SPBA0_IO_ADDRESS(x) \ - (((x) - MX51_SPBA0_BASE_ADDR) + MX51_SPBA0_BASE_ADDR_VIRT) - -#define MX51_AIPS1_IO_ADDRESS(x) \ - (((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT) - -#define MX51_AIPS2_IO_ADDRESS(x) \ - (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT) - #define MX51_IS_MEM_DEVICE_NONSHARED(x) 0 /* * DMA request assignments */ -#define MX51_DMA_REQ_SSI3_TX1 47 -#define MX51_DMA_REQ_SSI3_RX1 46 -#define MX51_DMA_REQ_SPDIF 45 -#define MX51_DMA_REQ_UART3_TX 44 -#define MX51_DMA_REQ_UART3_RX 43 -#define MX51_DMA_REQ_SLIM_B_TX 42 -#define MX51_DMA_REQ_SDHC4 41 -#define MX51_DMA_REQ_SDHC3 40 -#define MX51_DMA_REQ_CSPI_TX 39 -#define MX51_DMA_REQ_CSPI_RX 38 -#define MX51_DMA_REQ_SSI3_TX2 37 -#define MX51_DMA_REQ_IPU 36 -#define MX51_DMA_REQ_SSI3_RX2 35 -#define MX51_DMA_REQ_EPIT2 34 -#define MX51_DMA_REQ_CTI2_1 33 -#define MX51_DMA_REQ_EMI_WR 32 -#define MX51_DMA_REQ_CTI2_0 31 -#define MX51_DMA_REQ_EMI_RD 30 -#define MX51_DMA_REQ_SSI1_TX1 29 -#define MX51_DMA_REQ_SSI1_RX1 28 -#define MX51_DMA_REQ_SSI1_TX2 27 -#define MX51_DMA_REQ_SSI1_RX2 26 -#define MX51_DMA_REQ_SSI2_TX1 25 -#define MX51_DMA_REQ_SSI2_RX1 24 -#define MX51_DMA_REQ_SSI2_TX2 23 -#define MX51_DMA_REQ_SSI2_RX2 22 -#define MX51_DMA_REQ_SDHC2 21 -#define MX51_DMA_REQ_SDHC1 20 -#define MX51_DMA_REQ_UART1_TX 19 -#define MX51_DMA_REQ_UART1_RX 18 -#define MX51_DMA_REQ_UART2_TX 17 -#define MX51_DMA_REQ_UART2_RX 16 -#define MX51_DMA_REQ_GPU 15 -#define MX51_DMA_REQ_EXTREQ1 14 -#define MX51_DMA_REQ_FIRI_TX 13 -#define MX51_DMA_REQ_FIRI_RX 12 -#define MX51_DMA_REQ_HS_I2C_RX 11 -#define MX51_DMA_REQ_HS_I2C_TX 10 -#define MX51_DMA_REQ_CSPI2_TX 9 -#define MX51_DMA_REQ_CSPI2_RX 8 -#define MX51_DMA_REQ_CSPI1_TX 7 -#define MX51_DMA_REQ_CSPI1_RX 6 -#define MX51_DMA_REQ_SLIM_B 5 -#define MX51_DMA_REQ_ATA_TX_END 4 -#define MX51_DMA_REQ_ATA_TX 3 -#define MX51_DMA_REQ_ATA_RX 2 -#define MX51_DMA_REQ_GPC 1 -#define MX51_DMA_REQ_VPU 0 +#define MX51_DMA_REQ_VPU 0 +#define MX51_DMA_REQ_GPC 1 +#define MX51_DMA_REQ_ATA_RX 2 +#define MX51_DMA_REQ_ATA_TX 3 +#define MX51_DMA_REQ_ATA_TX_END 4 +#define MX51_DMA_REQ_SLIM_B 5 +#define MX51_DMA_REQ_CSPI1_RX 6 +#define MX51_DMA_REQ_CSPI1_TX 7 +#define MX51_DMA_REQ_CSPI2_RX 8 +#define MX51_DMA_REQ_CSPI2_TX 9 +#define MX51_DMA_REQ_HS_I2C_TX 10 +#define MX51_DMA_REQ_HS_I2C_RX 11 +#define MX51_DMA_REQ_FIRI_RX 12 +#define MX51_DMA_REQ_FIRI_TX 13 +#define MX51_DMA_REQ_EXTREQ1 14 +#define MX51_DMA_REQ_GPU 15 +#define MX51_DMA_REQ_UART2_RX 16 +#define MX51_DMA_REQ_UART2_TX 17 +#define MX51_DMA_REQ_UART1_RX 18 +#define MX51_DMA_REQ_UART1_TX 19 +#define MX51_DMA_REQ_SDHC1 20 +#define MX51_DMA_REQ_SDHC2 21 +#define MX51_DMA_REQ_SSI2_RX1 22 +#define MX51_DMA_REQ_SSI2_TX1 23 +#define MX51_DMA_REQ_SSI2_RX0 24 +#define MX51_DMA_REQ_SSI2_TX0 25 +#define MX51_DMA_REQ_SSI1_RX1 26 +#define MX51_DMA_REQ_SSI1_TX1 27 +#define MX51_DMA_REQ_SSI1_RX0 28 +#define MX51_DMA_REQ_SSI1_TX0 29 +#define MX51_DMA_REQ_EMI_RD 30 +#define MX51_DMA_REQ_CTI2_0 31 +#define MX51_DMA_REQ_EMI_WR 32 +#define MX51_DMA_REQ_CTI2_1 33 +#define MX51_DMA_REQ_EPIT2 34 +#define MX51_DMA_REQ_SSI3_RX2 35 +#define MX51_DMA_REQ_IPU 36 +#define MX51_DMA_REQ_SSI3_TX2 37 +#define MX51_DMA_REQ_CSPI_RX 38 +#define MX51_DMA_REQ_CSPI_TX 39 +#define MX51_DMA_REQ_SDHC3 40 +#define MX51_DMA_REQ_SDHC4 41 +#define MX51_DMA_REQ_SLIM_B_TX 42 +#define MX51_DMA_REQ_UART3_RX 43 +#define MX51_DMA_REQ_UART3_TX 44 +#define MX51_DMA_REQ_SPDIF 45 +#define MX51_DMA_REQ_SSI3_RX1 46 +#define MX51_DMA_REQ_SSI3_TX1 47 /* * Interrupt numbers */ -#define MX51_MXC_INT_BASE 0 -#define MX51_MXC_INT_RESV0 0 -#define MX51_MXC_INT_MMC_SDHC1 1 -#define MX51_MXC_INT_MMC_SDHC2 2 -#define MX51_MXC_INT_MMC_SDHC3 3 -#define MX51_MXC_INT_MMC_SDHC4 4 -#define MX51_MXC_INT_RESV5 5 -#define MX51_MXC_INT_SDMA 6 -#define MX51_MXC_INT_IOMUX 7 -#define MX51_MXC_INT_NFC 8 -#define MX51_MXC_INT_VPU 9 -#define MX51_MXC_INT_IPU_ERR 10 -#define MX51_MXC_INT_IPU_SYN 11 -#define MX51_MXC_INT_GPU 12 -#define MX51_MXC_INT_RESV13 13 -#define MX51_MXC_INT_USB_H1 14 -#define MX51_MXC_INT_EMI 15 -#define MX51_MXC_INT_USB_H2 16 -#define MX51_MXC_INT_USB_H3 17 -#define MX51_MXC_INT_USB_OTG 18 -#define MX51_MXC_INT_SAHARA_H0 19 -#define MX51_MXC_INT_SAHARA_H1 20 -#define MX51_MXC_INT_SCC_SMN 21 -#define MX51_MXC_INT_SCC_STZ 22 -#define MX51_MXC_INT_SCC_SCM 23 -#define MX51_MXC_INT_SRTC_NTZ 24 -#define MX51_MXC_INT_SRTC_TZ 25 -#define MX51_MXC_INT_RTIC 26 -#define MX51_MXC_INT_CSU 27 -#define MX51_MXC_INT_SLIM_B 28 -#define MX51_MXC_INT_SSI1 29 -#define MX51_MXC_INT_SSI2 30 -#define MX51_MXC_INT_UART1 31 -#define MX51_MXC_INT_UART2 32 -#define MX51_MXC_INT_UART3 33 -#define MX51_MXC_INT_RESV34 34 -#define MX51_MXC_INT_RESV35 35 -#define MX51_MXC_INT_CSPI1 36 -#define MX51_MXC_INT_CSPI2 37 -#define MX51_MXC_INT_CSPI 38 -#define MX51_MXC_INT_GPT 39 -#define MX51_MXC_INT_EPIT1 40 -#define MX51_MXC_INT_EPIT2 41 -#define MX51_MXC_INT_GPIO1_INT7 42 -#define MX51_MXC_INT_GPIO1_INT6 43 -#define MX51_MXC_INT_GPIO1_INT5 44 -#define MX51_MXC_INT_GPIO1_INT4 45 -#define MX51_MXC_INT_GPIO1_INT3 46 -#define MX51_MXC_INT_GPIO1_INT2 47 -#define MX51_MXC_INT_GPIO1_INT1 48 -#define MX51_MXC_INT_GPIO1_INT0 49 -#define MX51_MXC_INT_GPIO1_LOW 50 -#define MX51_MXC_INT_GPIO1_HIGH 51 -#define MX51_MXC_INT_GPIO2_LOW 52 -#define MX51_MXC_INT_GPIO2_HIGH 53 -#define MX51_MXC_INT_GPIO3_LOW 54 -#define MX51_MXC_INT_GPIO3_HIGH 55 -#define MX51_MXC_INT_GPIO4_LOW 56 -#define MX51_MXC_INT_GPIO4_HIGH 57 -#define MX51_MXC_INT_WDOG1 58 -#define MX51_MXC_INT_WDOG2 59 -#define MX51_MXC_INT_KPP 60 -#define MX51_MXC_INT_PWM1 61 -#define MX51_MXC_INT_I2C1 62 -#define MX51_MXC_INT_I2C2 63 -#define MX51_MXC_INT_HS_I2C 64 -#define MX51_MXC_INT_RESV65 65 -#define MX51_MXC_INT_RESV66 66 -#define MX51_MXC_INT_SIM_IPB 67 -#define MX51_MXC_INT_SIM_DAT 68 -#define MX51_MXC_INT_IIM 69 -#define MX51_MXC_INT_ATA 70 -#define MX51_MXC_INT_CCM1 71 -#define MX51_MXC_INT_CCM2 72 -#define MX51_MXC_INT_GPC1 73 -#define MX51_MXC_INT_GPC2 74 -#define MX51_MXC_INT_SRC 75 -#define MX51_MXC_INT_NM 76 -#define MX51_MXC_INT_PMU 77 -#define MX51_MXC_INT_CTI_IRQ 78 -#define MX51_MXC_INT_CTI1_TG0 79 -#define MX51_MXC_INT_CTI1_TG1 80 -#define MX51_MXC_INT_MCG_ERR 81 -#define MX51_MXC_INT_MCG_TMR 82 -#define MX51_MXC_INT_MCG_FUNC 83 -#define MX51_MXC_INT_GPU2_IRQ 84 -#define MX51_MXC_INT_GPU2_BUSY 85 -#define MX51_MXC_INT_RESV86 86 -#define MX51_MXC_INT_FEC 87 -#define MX51_MXC_INT_OWIRE 88 -#define MX51_MXC_INT_CTI1_TG2 89 -#define MX51_MXC_INT_SJC 90 -#define MX51_MXC_INT_SPDIF 91 -#define MX51_MXC_INT_TVE 92 -#define MX51_MXC_INT_FIRI 93 -#define MX51_MXC_INT_PWM2 94 -#define MX51_MXC_INT_SLIM_EXP 95 -#define MX51_MXC_INT_SSI3 96 -#define MX51_MXC_INT_EMI_BOOT 97 -#define MX51_MXC_INT_CTI1_TG3 98 -#define MX51_MXC_INT_SMC_RX 99 -#define MX51_MXC_INT_VPU_IDLE 100 -#define MX51_MXC_INT_EMI_NFC 101 -#define MX51_MXC_INT_GPU_IDLE 102 +#define MX51_MXC_INT_BASE 0 +#define MX51_MXC_INT_RESV0 0 +#define MX51_INT_ESDHC1 1 +#define MX51_INT_ESDHC2 2 +#define MX51_INT_ESDHC3 3 +#define MX51_INT_ESDHC4 4 +#define MX51_MXC_INT_RESV5 5 +#define MX51_INT_SDMA 6 +#define MX51_MXC_INT_IOMUX 7 +#define MX51_INT_NFC 8 +#define MX51_MXC_INT_VPU 9 +#define MX51_MXC_INT_IPU_ERR 10 +#define MX51_MXC_INT_IPU_SYN 11 +#define MX51_MXC_INT_GPU 12 +#define MX51_MXC_INT_RESV13 13 +#define MX51_MXC_INT_USB_H1 14 +#define MX51_MXC_INT_EMI 15 +#define MX51_MXC_INT_USB_H2 16 +#define MX51_MXC_INT_USB_H3 17 +#define MX51_MXC_INT_USB_OTG 18 +#define MX51_MXC_INT_SAHARA_H0 19 +#define MX51_MXC_INT_SAHARA_H1 20 +#define MX51_MXC_INT_SCC_SMN 21 +#define MX51_MXC_INT_SCC_STZ 22 +#define MX51_MXC_INT_SCC_SCM 23 +#define MX51_MXC_INT_SRTC_NTZ 24 +#define MX51_MXC_INT_SRTC_TZ 25 +#define MX51_MXC_INT_RTIC 26 +#define MX51_MXC_INT_CSU 27 +#define MX51_MXC_INT_SLIM_B 28 +#define MX51_INT_SSI1 29 +#define MX51_INT_SSI2 30 +#define MX51_INT_UART1 31 +#define MX51_INT_UART2 32 +#define MX51_INT_UART3 33 +#define MX51_MXC_INT_RESV34 34 +#define MX51_MXC_INT_RESV35 35 +#define MX51_INT_ECSPI1 36 +#define MX51_INT_ECSPI2 37 +#define MX51_INT_CSPI 38 +#define MX51_MXC_INT_GPT 39 +#define MX51_MXC_INT_EPIT1 40 +#define MX51_MXC_INT_EPIT2 41 +#define MX51_MXC_INT_GPIO1_INT7 42 +#define MX51_MXC_INT_GPIO1_INT6 43 +#define MX51_MXC_INT_GPIO1_INT5 44 +#define MX51_MXC_INT_GPIO1_INT4 45 +#define MX51_MXC_INT_GPIO1_INT3 46 +#define MX51_MXC_INT_GPIO1_INT2 47 +#define MX51_MXC_INT_GPIO1_INT1 48 +#define MX51_MXC_INT_GPIO1_INT0 49 +#define MX51_MXC_INT_GPIO1_LOW 50 +#define MX51_MXC_INT_GPIO1_HIGH 51 +#define MX51_MXC_INT_GPIO2_LOW 52 +#define MX51_MXC_INT_GPIO2_HIGH 53 +#define MX51_MXC_INT_GPIO3_LOW 54 +#define MX51_MXC_INT_GPIO3_HIGH 55 +#define MX51_MXC_INT_GPIO4_LOW 56 +#define MX51_MXC_INT_GPIO4_HIGH 57 +#define MX51_MXC_INT_WDOG1 58 +#define MX51_MXC_INT_WDOG2 59 +#define MX51_MXC_INT_KPP 60 +#define MX51_MXC_INT_PWM1 61 +#define MX51_INT_I2C1 62 +#define MX51_INT_I2C2 63 +#define MX51_MXC_INT_HS_I2C 64 +#define MX51_MXC_INT_RESV65 65 +#define MX51_MXC_INT_RESV66 66 +#define MX51_MXC_INT_SIM_IPB 67 +#define MX51_MXC_INT_SIM_DAT 68 +#define MX51_MXC_INT_IIM 69 +#define MX51_MXC_INT_ATA 70 +#define MX51_MXC_INT_CCM1 71 +#define MX51_MXC_INT_CCM2 72 +#define MX51_MXC_INT_GPC1 73 +#define MX51_MXC_INT_GPC2 74 +#define MX51_MXC_INT_SRC 75 +#define MX51_MXC_INT_NM 76 +#define MX51_MXC_INT_PMU 77 +#define MX51_MXC_INT_CTI_IRQ 78 +#define MX51_MXC_INT_CTI1_TG0 79 +#define MX51_MXC_INT_CTI1_TG1 80 +#define MX51_MXC_INT_MCG_ERR 81 +#define MX51_MXC_INT_MCG_TMR 82 +#define MX51_MXC_INT_MCG_FUNC 83 +#define MX51_MXC_INT_GPU2_IRQ 84 +#define MX51_MXC_INT_GPU2_BUSY 85 +#define MX51_MXC_INT_RESV86 86 +#define MX51_INT_FEC 87 +#define MX51_MXC_INT_OWIRE 88 +#define MX51_MXC_INT_CTI1_TG2 89 +#define MX51_MXC_INT_SJC 90 +#define MX51_MXC_INT_SPDIF 91 +#define MX51_MXC_INT_TVE 92 +#define MX51_MXC_INT_FIRI 93 +#define MX51_MXC_INT_PWM2 94 +#define MX51_MXC_INT_SLIM_EXP 95 +#define MX51_MXC_INT_SSI3 96 +#define MX51_MXC_INT_EMI_BOOT 97 +#define MX51_MXC_INT_CTI1_TG3 98 +#define MX51_MXC_INT_SMC_RX 99 +#define MX51_MXC_INT_VPU_IDLE 100 +#define MX51_MXC_INT_EMI_NFC 101 +#define MX51_MXC_INT_GPU_IDLE 102 /* silicon revisions specific to i.MX51 */ -#define MX51_CHIP_REV_1_0 0x10 -#define MX51_CHIP_REV_1_1 0x11 -#define MX51_CHIP_REV_1_2 0x12 -#define MX51_CHIP_REV_1_3 0x13 -#define MX51_CHIP_REV_2_0 0x20 -#define MX51_CHIP_REV_2_1 0x21 -#define MX51_CHIP_REV_2_2 0x22 -#define MX51_CHIP_REV_2_3 0x23 -#define MX51_CHIP_REV_3_0 0x30 -#define MX51_CHIP_REV_3_1 0x31 -#define MX51_CHIP_REV_3_2 0x32 - -/* Mandatory defines used globally */ +#define MX51_CHIP_REV_1_0 0x10 +#define MX51_CHIP_REV_1_1 0x11 +#define MX51_CHIP_REV_1_2 0x12 +#define MX51_CHIP_REV_1_3 0x13 +#define MX51_CHIP_REV_2_0 0x20 +#define MX51_CHIP_REV_2_1 0x21 +#define MX51_CHIP_REV_2_2 0x22 +#define MX51_CHIP_REV_2_3 0x23 +#define MX51_CHIP_REV_3_0 0x30 +#define MX51_CHIP_REV_3_1 0x31 +#define MX51_CHIP_REV_3_2 0x32 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) - extern int mx51_revision(void); #endif -#endif /* __ASM_ARCH_MXC_MX51_H__ */ +/* tape-out 1 defines */ +#define MX51_TZIC_BASE_ADDR_TO1 0x8fffc000 + +#endif /* ifndef __MACH_MX51_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h index 4acd1143a9bd..95be51bfe9a9 100644 --- a/arch/arm/plat-mxc/include/mach/system.h +++ b/arch/arm/plat-mxc/include/mach/system.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,8 +28,34 @@ static inline void arch_idle(void) mxc91231_prepare_idle(); } #endif - - cpu_do_idle(); + /* fix i.MX31 errata TLSbo65953 and i.MX35 errata ENGcm09472 */ + if (cpu_is_mx31() || cpu_is_mx35()) { + unsigned long reg = 0; + __asm__ __volatile__( + /* disable I and D cache */ + "mrc p15, 0, %0, c1, c0, 0\n" + "bic %0, %0, #0x00001000\n" + "bic %0, %0, #0x00000004\n" + "mcr p15, 0, %0, c1, c0, 0\n" + /* invalidate I cache */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c5, 0\n" + /* clear and invalidate D cache */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c14, 0\n" + /* WFI */ + "mov %0, #0\n" + "mcr p15, 0, %0, c7, c0, 4\n" + "nop\n" "nop\n" "nop\n" "nop\n" + "nop\n" "nop\n" "nop\n" + /* enable I and D cache */ + "mrc p15, 0, %0, c1, c0, 0\n" + "orr %0, %0, #0x00001000\n" + "orr %0, %0, #0x00000004\n" + "mcr p15, 0, %0, c1, c0, 0\n" + : "=r" (reg)); + } else + cpu_do_idle(); } void arch_reset(char mode, const char *cmd); diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h index d9bd37e4667a..9dd9c2085aad 100644 --- a/arch/arm/plat-mxc/include/mach/uncompress.h +++ b/arch/arm/plat-mxc/include/mach/uncompress.h @@ -99,6 +99,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id) uart_base = MX3X_UART2_BASE_ADDR; break; case MACH_TYPE_MX51_BABBAGE: + case MACH_TYPE_EUKREA_CPUIMX51SD: uart_base = MX51_UART1_BASE_ADDR; break; default: diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/plat-mxc/iram_alloc.c new file mode 100644 index 000000000000..074c3869626a --- /dev/null +++ b/arch/arm/plat-mxc/iram_alloc.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/genalloc.h> +#include <mach/iram.h> + +static unsigned long iram_phys_base; +static void __iomem *iram_virt_base; +static struct gen_pool *iram_pool; + +static inline void __iomem *iram_phys_to_virt(unsigned long p) +{ + return iram_virt_base + (p - iram_phys_base); +} + +void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr) +{ + if (!iram_pool) + return NULL; + + *dma_addr = gen_pool_alloc(iram_pool, size); + pr_debug("iram alloc - %dB@0x%lX\n", size, *dma_addr); + if (!*dma_addr) + return NULL; + return iram_phys_to_virt(*dma_addr); +} +EXPORT_SYMBOL(iram_alloc); + +void iram_free(unsigned long addr, unsigned int size) +{ + if (!iram_pool) + return; + + gen_pool_free(iram_pool, addr, size); +} +EXPORT_SYMBOL(iram_free); + +int __init iram_init(unsigned long base, unsigned long size) +{ + iram_phys_base = base; + + iram_pool = gen_pool_create(PAGE_SHIFT, -1); + if (!iram_pool) + return -ENOMEM; + + gen_pool_add(iram_pool, base, size, -1); + iram_virt_base = ioremap(iram_phys_base, size); + if (!iram_virt_base) + return -EIO; + + pr_debug("i.MX IRAM pool: %ld KB@0x%p\n", size / 1024, iram_virt_base); + return 0; +} diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index e39a417a368d..a92cb499313f 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -33,7 +33,7 @@ config OMAP_DEBUG_DEVICES config OMAP_DEBUG_LEDS bool depends on OMAP_DEBUG_DEVICES - default y if LEDS + default y if LEDS_CLASS config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index a202a2ce6e3d..6cd151b31bc5 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -320,6 +320,7 @@ void flush_iotlb_page(struct iommu *obj, u32 da) if ((start <= da) && (da < start + bytes)) { dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n", __func__, start, da, bytes); + iotlb_load_cr(obj, &cr); iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); } } diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index e31496e35b0f..0c8612fd8312 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -156,7 +156,7 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) /* Writing zero to RSYNC_ERR clears the IRQ */ MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); } else { - complete(&mcbsp_rx->tx_irq_completion); + complete(&mcbsp_rx->rx_irq_completion); } return IRQ_HANDLED; diff --git a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h index 7b4eadc6df3a..abcc36eb1242 100644 --- a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h +++ b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h @@ -25,6 +25,13 @@ * * 4. matrix key and direct key will use the same debounce_interval by * default, which should be sufficient in most cases + * + * pxa168 keypad platform specific parameter + * + * NOTE: + * clear_wakeup_event callback is a workaround required to clear the + * keypad interrupt. The keypad wake must be cleared in addition to + * reading the MI/DI bits in the KPC register. */ struct pxa27x_keypad_platform_data { @@ -52,6 +59,9 @@ struct pxa27x_keypad_platform_data { /* key debounce interval */ unsigned int debounce_interval; + + /* clear wakeup event requirement for pxa168 */ + void (*clear_wakeup_event)(void); }; extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info); diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index c6a855db2fb6..25960966af7c 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -7,7 +7,7 @@ config PLAT_S5P bool - depends on (ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310) + depends on (ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5PV310) default y select ARM_VIC if !ARCH_S5PV310 select ARM_GIC if ARCH_S5PV310 @@ -30,7 +30,7 @@ config S5P_EXT_INT bool help Use the external interrupts (other than GPIO interrupts.) - Note: Do not choose this for S5P6440. + Note: Do not choose this for S5P6440 and S5P6450. config S5P_DEV_FIMC0 bool @@ -46,3 +46,8 @@ config S5P_DEV_FIMC2 bool help Compile in platform device definitions for FIMC controller 2 + +config S5P_DEV_ONENAND + bool + help + Compile in platform device definition for OneNAND controller diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index b2e029673950..f3e917e27da8 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o +obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c index b5e255265f20..8aaf4e6b60c3 100644 --- a/arch/arm/plat-s5p/clock.c +++ b/arch/arm/plat-s5p/clock.c @@ -74,6 +74,13 @@ struct clk clk_fout_epll = { .ctrlbit = (1 << 31), }; +/* DPLL clock output */ +struct clk clk_fout_dpll = { + .name = "fout_dpll", + .id = -1, + .ctrlbit = (1 << 31), +}; + /* VPLL clock output */ struct clk clk_fout_vpll = { .name = "fout_vpll", @@ -122,6 +129,17 @@ struct clksrc_sources clk_src_epll = { .nr_sources = ARRAY_SIZE(clk_src_epll_list), }; +/* Possible clock sources for DPLL Mux */ +static struct clk *clk_src_dpll_list[] = { + [0] = &clk_fin_dpll, + [1] = &clk_fout_dpll, +}; + +struct clksrc_sources clk_src_dpll = { + .sources = clk_src_dpll_list, + .nr_sources = ARRAY_SIZE(clk_src_dpll_list), +}; + struct clk clk_vpll = { .name = "vpll", .id = -1, @@ -145,6 +163,7 @@ static struct clk *s5p_clks[] __initdata = { &clk_fout_apll, &clk_fout_mpll, &clk_fout_epll, + &clk_fout_dpll, &clk_fout_vpll, &clk_arm, &clk_vpll, diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c index b07a078fd284..74f7f5a5446c 100644 --- a/arch/arm/plat-s5p/cpu.c +++ b/arch/arm/plat-s5p/cpu.c @@ -19,6 +19,7 @@ #include <plat/cpu.h> #include <plat/s5p6440.h> #include <plat/s5p6442.h> +#include <plat/s5p6450.h> #include <plat/s5pc100.h> #include <plat/s5pv210.h> #include <plat/s5pv310.h> @@ -27,6 +28,7 @@ static const char name_s5p6440[] = "S5P6440"; static const char name_s5p6442[] = "S5P6442"; +static const char name_s5p6450[] = "S5P6450"; static const char name_s5pc100[] = "S5PC100"; static const char name_s5pv210[] = "S5PV210/S5PC110"; static const char name_s5pv310[] = "S5PV310"; @@ -38,7 +40,7 @@ static struct cpu_table cpu_ids[] __initdata = { .map_io = s5p6440_map_io, .init_clocks = s5p6440_init_clocks, .init_uarts = s5p6440_init_uarts, - .init = s5p6440_init, + .init = s5p64x0_init, .name = name_s5p6440, }, { .idcode = 0x36442000, @@ -49,6 +51,14 @@ static struct cpu_table cpu_ids[] __initdata = { .init = s5p6442_init, .name = name_s5p6442, }, { + .idcode = 0x36450000, + .idmask = 0xffffff00, + .map_io = s5p6450_map_io, + .init_clocks = s5p6450_init_clocks, + .init_uarts = s5p6450_init_uarts, + .init = s5p64x0_init, + .name = name_s5p6450, + }, { .idcode = 0x43100000, .idmask = 0xfffff000, .map_io = s5pc100_map_io, @@ -89,33 +99,11 @@ static struct map_desc s5p_iodesc[] __initdata = { .length = SZ_64K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S3C_VA_UART, - .pfn = __phys_to_pfn(S3C_PA_UART), - .length = SZ_512K, - .type = MT_DEVICE, -#ifdef CONFIG_ARM_VIC - }, { - .virtual = (unsigned long)VA_VIC0, - .pfn = __phys_to_pfn(S5P_PA_VIC0), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)VA_VIC1, - .pfn = __phys_to_pfn(S5P_PA_VIC1), - .length = SZ_16K, - .type = MT_DEVICE, -#endif - }, { .virtual = (unsigned long)S3C_VA_TIMER, .pfn = __phys_to_pfn(S5P_PA_TIMER), .length = SZ_16K, .type = MT_DEVICE, }, { - .virtual = (unsigned long)S5P_VA_GPIO, - .pfn = __phys_to_pfn(S5P_PA_GPIO), - .length = SZ_4K, - .type = MT_DEVICE, - }, { .virtual = (unsigned long)S3C_VA_WATCHDOG, .pfn = __phys_to_pfn(S3C_PA_WDT), .length = SZ_4K, diff --git a/arch/arm/mach-s5pv210/dev-onenand.c b/arch/arm/plat-s5p/dev-onenand.c index f8ede33ee82b..6db926202caa 100644 --- a/arch/arm/mach-s5pv210/dev-onenand.c +++ b/arch/arm/plat-s5p/dev-onenand.c @@ -1,10 +1,12 @@ -/* - * linux/arch/arm/mach-s5pv210/dev-onenand.c +/* linux/arch/arm/plat-s5p/dev-onenand.c + * + * Copyright 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * Copyright (c) 2008-2010 Samsung Electronics * Kyungmin Park <kyungmin.park@samsung.com> * - * S5PC110 series device definition for OneNAND devices + * S5P series device definition for OneNAND devices * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -19,15 +21,15 @@ #include <mach/irqs.h> #include <mach/map.h> -static struct resource s5pc110_onenand_resources[] = { +static struct resource s5p_onenand_resources[] = { [0] = { - .start = S5PC110_PA_ONENAND, - .end = S5PC110_PA_ONENAND + SZ_128K - 1, + .start = S5P_PA_ONENAND, + .end = S5P_PA_ONENAND + SZ_128K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = S5PC110_PA_ONENAND_DMA, - .end = S5PC110_PA_ONENAND_DMA + SZ_8K - 1, + .start = S5P_PA_ONENAND_DMA, + .end = S5P_PA_ONENAND_DMA + SZ_8K - 1, .flags = IORESOURCE_MEM, }, [2] = { @@ -37,19 +39,19 @@ static struct resource s5pc110_onenand_resources[] = { }, }; -struct platform_device s5pc110_device_onenand = { +struct platform_device s5p_device_onenand = { .name = "s5pc110-onenand", .id = -1, - .num_resources = ARRAY_SIZE(s5pc110_onenand_resources), - .resource = s5pc110_onenand_resources, + .num_resources = ARRAY_SIZE(s5p_onenand_resources), + .resource = s5p_onenand_resources, }; -void s5pc110_onenand_set_platdata(struct onenand_platform_data *pdata) +void s5p_onenand_set_platdata(struct onenand_platform_data *pdata) { struct onenand_platform_data *pd; pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL); if (!pd) printk(KERN_ERR "%s: no memory for platform data\n", __func__); - s5pc110_device_onenand.dev.platform_data = pd; + s5p_device_onenand.dev.platform_data = pd; } diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c index a89331ef4ae1..6a7342886171 100644 --- a/arch/arm/plat-s5p/dev-uart.c +++ b/arch/arm/plat-s5p/dev-uart.c @@ -119,6 +119,56 @@ static struct resource s5p_uart3_resource[] = { #endif }; +static struct resource s5p_uart4_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 4 + [0] = { + .start = S5P_PA_UART4, + .end = S5P_PA_UART4 + S5P_SZ_UART, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S5P_UART_RX4, + .end = IRQ_S5P_UART_RX4, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_S5P_UART_TX4, + .end = IRQ_S5P_UART_TX4, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_S5P_UART_ERR4, + .end = IRQ_S5P_UART_ERR4, + .flags = IORESOURCE_IRQ, + }, +#endif +}; + +static struct resource s5p_uart5_resource[] = { +#if CONFIG_SERIAL_SAMSUNG_UARTS > 5 + [0] = { + .start = S5P_PA_UART5, + .end = S5P_PA_UART5 + S5P_SZ_UART, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_S5P_UART_RX5, + .end = IRQ_S5P_UART_RX5, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_S5P_UART_TX5, + .end = IRQ_S5P_UART_TX5, + .flags = IORESOURCE_IRQ, + }, + [3] = { + .start = IRQ_S5P_UART_ERR5, + .end = IRQ_S5P_UART_ERR5, + .flags = IORESOURCE_IRQ, + }, +#endif +}; + struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { [0] = { .resources = s5p_uart0_resource, @@ -136,4 +186,12 @@ struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = { .resources = s5p_uart3_resource, .nr_resources = ARRAY_SIZE(s5p_uart3_resource), }, + [4] = { + .resources = s5p_uart4_resource, + .nr_resources = ARRAY_SIZE(s5p_uart4_resource), + }, + [5] = { + .resources = s5p_uart5_resource, + .nr_resources = ARRAY_SIZE(s5p_uart5_resource), + }, }; diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h index 4e8fe08cb70d..bf28fadee7ae 100644 --- a/arch/arm/plat-s5p/include/plat/pll.h +++ b/arch/arm/plat-s5p/include/plat/pll.h @@ -47,6 +47,7 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con, } #define PLL46XX_KDIV_MASK (0xFFFF) +#define PLL4650C_KDIV_MASK (0xFFF) #define PLL46XX_MDIV_MASK (0x1FF) #define PLL46XX_PDIV_MASK (0x3F) #define PLL46XX_SDIV_MASK (0x7) @@ -57,6 +58,7 @@ static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con, enum pll46xx_type_t { pll_4600, pll_4650, + pll_4650c, }; static inline unsigned long s5p_get_pll46xx(unsigned long baseclk, @@ -72,6 +74,11 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk, sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; kdiv = pll_con1 & PLL46XX_KDIV_MASK; + if (pll_type == pll_4650c) + kdiv = pll_con1 & PLL4650C_KDIV_MASK; + else + kdiv = pll_con1 & PLL46XX_KDIV_MASK; + tmp = baseclk; if (pll_type == pll_4600) { diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h index 09418b1101fe..17036c898409 100644 --- a/arch/arm/plat-s5p/include/plat/s5p-clock.h +++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h @@ -1,7 +1,7 @@ /* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h * - * Copyright 2009 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ + * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com * * Header file for s5p clock support * @@ -20,6 +20,7 @@ #define clk_fin_apll clk_ext_xtal_mux #define clk_fin_mpll clk_ext_xtal_mux #define clk_fin_epll clk_ext_xtal_mux +#define clk_fin_dpll clk_ext_xtal_mux #define clk_fin_vpll clk_ext_xtal_mux #define clk_fin_hpll clk_ext_xtal_mux @@ -30,6 +31,7 @@ extern struct clk s5p_clk_27m; extern struct clk clk_fout_apll; extern struct clk clk_fout_mpll; extern struct clk clk_fout_epll; +extern struct clk clk_fout_dpll; extern struct clk clk_fout_vpll; extern struct clk clk_arm; extern struct clk clk_vpll; @@ -37,8 +39,8 @@ extern struct clk clk_vpll; extern struct clksrc_sources clk_src_apll; extern struct clksrc_sources clk_src_mpll; extern struct clksrc_sources clk_src_epll; +extern struct clksrc_sources clk_src_dpll; -extern int s5p6440_clk48m_ctrl(struct clk *clk, int enable); extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); #endif /* __ASM_PLAT_S5P_CLOCK_H */ diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h index a4cd75afeb3b..528585d2cafc 100644 --- a/arch/arm/plat-s5p/include/plat/s5p6440.h +++ b/arch/arm/plat-s5p/include/plat/s5p6440.h @@ -12,24 +12,23 @@ /* Common init code for S5P6440 related SoCs */ -extern void s5p6440_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); extern void s5p6440_register_clocks(void); extern void s5p6440_setup_clocks(void); #ifdef CONFIG_CPU_S5P6440 -extern int s5p6440_init(void); +extern int s5p64x0_init(void); extern void s5p6440_init_irq(void); extern void s5p6440_map_io(void); extern void s5p6440_init_clocks(int xtal); -#define s5p6440_init_uarts s5p6440_common_init_uarts +extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no); #else #define s5p6440_init_clocks NULL #define s5p6440_init_uarts NULL #define s5p6440_map_io NULL -#define s5p6440_init NULL +#define s5p64x0_init NULL #endif /* S5P6440 timer */ diff --git a/arch/arm/plat-s5p/include/plat/s5p6450.h b/arch/arm/plat-s5p/include/plat/s5p6450.h new file mode 100644 index 000000000000..640a41c26be3 --- /dev/null +++ b/arch/arm/plat-s5p/include/plat/s5p6450.h @@ -0,0 +1,36 @@ +/* arch/arm/plat-s5p/include/plat/s5p6450.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Header file for s5p6450 cpu support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/* Common init code for S5P6450 related SoCs */ + +extern void s5p6450_register_clocks(void); +extern void s5p6450_setup_clocks(void); + +#ifdef CONFIG_CPU_S5P6450 + +extern int s5p64x0_init(void); +extern void s5p6450_init_irq(void); +extern void s5p6450_map_io(void); +extern void s5p6450_init_clocks(int xtal); + +extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no); + +#else +#define s5p6450_init_clocks NULL +#define s5p6450_init_uarts NULL +#define s5p6450_map_io NULL +#define s5p64x0_init NULL +#endif + +/* S5P6450 timer */ + +extern struct sys_timer s5p6450_timer; diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index 04d9521ddc9f..e8f2be2d67f2 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -435,7 +435,6 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) static int s3c_adc_resume(struct platform_device *pdev) { struct adc_device *adc = platform_get_drvdata(pdev); - unsigned long flags; clk_enable(adc->clk); enable_irq(adc->irq); diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 90a20512d68d..e8d20b0bc50e 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -48,6 +48,9 @@ #include <plat/clock.h> #include <plat/cpu.h> +#include <linux/serial_core.h> +#include <plat/regs-serial.h> /* for s3c24xx_uart_devs */ + /* clock information */ static LIST_HEAD(clocks); @@ -65,6 +68,28 @@ static int clk_null_enable(struct clk *clk, int enable) return 0; } +static int dev_is_s3c_uart(struct device *dev) +{ + struct platform_device **pdev = s3c24xx_uart_devs; + int i; + for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++) + if (*pdev && dev == &(*pdev)->dev) + return 1; + return 0; +} + +/* + * Serial drivers call get_clock() very early, before platform bus + * has been set up, this requires a special check to let them get + * a proper clock + */ + +static int dev_is_platform_device(struct device *dev) +{ + return dev->bus == &platform_bus_type || + (dev->bus == NULL && dev_is_s3c_uart(dev)); +} + /* Clock API calls */ struct clk *clk_get(struct device *dev, const char *id) @@ -73,7 +98,7 @@ struct clk *clk_get(struct device *dev, const char *id) struct clk *clk = ERR_PTR(-ENOENT); int idno; - if (dev == NULL || dev->bus != &platform_bus_type) + if (dev == NULL || !dev_is_platform_device(dev)) idno = -1; else idno = to_platform_device(dev)->id; diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 6412933d6fbb..9addb3dfb4bc 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -79,7 +79,7 @@ extern struct sysdev_class s3c2442_sysclass; extern struct sysdev_class s3c2443_sysclass; extern struct sysdev_class s3c6410_sysclass; extern struct sysdev_class s3c64xx_sysclass; -extern struct sysdev_class s5p6440_sysclass; +extern struct sysdev_class s5p64x0_sysclass; extern struct sysdev_class s5p6442_sysclass; extern struct sysdev_class s5pv210_sysclass; diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 85f6f23a510f..7d448e138792 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -67,13 +67,15 @@ extern struct platform_device s5pv210_device_spi0; extern struct platform_device s5pv210_device_spi1; extern struct platform_device s5p6440_device_spi0; extern struct platform_device s5p6440_device_spi1; +extern struct platform_device s5p6450_device_spi0; +extern struct platform_device s5p6450_device_spi1; extern struct platform_device s3c_device_hwmon; extern struct platform_device s3c_device_nand; extern struct platform_device s3c_device_onenand; extern struct platform_device s3c64xx_device_onenand1; -extern struct platform_device s5pc110_device_onenand; +extern struct platform_device s5p_device_onenand; extern struct platform_device s3c_device_usbgadget; extern struct platform_device s3c_device_usb_hsotg; @@ -95,6 +97,9 @@ extern struct platform_device s5p6442_device_spi; extern struct platform_device s5p6440_device_pcm; extern struct platform_device s5p6440_device_iis; +extern struct platform_device s5p6450_device_iis0; +extern struct platform_device s5p6450_device_pcm0; + extern struct platform_device s5pc100_device_ac97; extern struct platform_device s5pc100_device_pcm0; extern struct platform_device s5pc100_device_pcm1; diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h index 5fe6721b57f7..810744213120 100644 --- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h +++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h @@ -32,6 +32,12 @@ enum dma_ch { DMACH_UART2_TX, DMACH_UART3_RX, DMACH_UART3_TX, + DMACH_UART4_RX, + DMACH_UART4_TX, + DMACH_UART5_RX, + DMACH_UART5_TX, + DMACH_USI_RX, + DMACH_USI_TX, DMACH_IRDA, DMACH_I2S0_RX, DMACH_I2S0_TX, @@ -64,6 +70,20 @@ enum dma_ch { DMACH_MSM_REQ2, DMACH_MSM_REQ1, DMACH_MSM_REQ0, + DMACH_SLIMBUS0_RX, + DMACH_SLIMBUS0_TX, + DMACH_SLIMBUS0AUX_RX, + DMACH_SLIMBUS0AUX_TX, + DMACH_SLIMBUS1_RX, + DMACH_SLIMBUS1_TX, + DMACH_SLIMBUS2_RX, + DMACH_SLIMBUS2_TX, + DMACH_SLIMBUS3_RX, + DMACH_SLIMBUS3_TX, + DMACH_SLIMBUS4_RX, + DMACH_SLIMBUS4_TX, + DMACH_SLIMBUS5_RX, + DMACH_SLIMBUS5_TX, /* END Marker, also used to denote a reserved channel */ DMACH_MAX, }; diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index e5aba8f95b79..ae8e802bdca8 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h @@ -65,7 +65,7 @@ struct s3c64xx_spi_info { extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); -extern void s5p6440_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); +extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); extern void s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); #endif /* __S3C64XX_PLAT_SPI_H */ diff --git a/arch/arm/plat-tcc/Kconfig b/arch/arm/plat-tcc/Kconfig new file mode 100644 index 000000000000..1bf499570f42 --- /dev/null +++ b/arch/arm/plat-tcc/Kconfig @@ -0,0 +1,20 @@ +if ARCH_TCC_926 + +menu "Telechips ARM926-based CPUs" + +choice + prompt "Telechips CPU type:" + default ARCH_TCC8K + +config ARCH_TCC8K + bool TCC8000 + select USB_ARCH_HAS_OHCI + help + Support for Telechips TCC8000 systems + +endchoice + +source "arch/arm/mach-tcc8k/Kconfig" + +endmenu +endif diff --git a/arch/arm/plat-tcc/Makefile b/arch/arm/plat-tcc/Makefile new file mode 100644 index 000000000000..eceabc869b8f --- /dev/null +++ b/arch/arm/plat-tcc/Makefile @@ -0,0 +1,3 @@ +# "Telechips Platform Common Modules" + +obj-y := clock.o system.o diff --git a/arch/arm/plat-tcc/clock.c b/arch/arm/plat-tcc/clock.c new file mode 100644 index 000000000000..f3ced10d5271 --- /dev/null +++ b/arch/arm/plat-tcc/clock.c @@ -0,0 +1,179 @@ +/* + * Clock framework for Telechips SoCs + * Based on arch/arm/plat-mxc/clock.c + * + * Copyright (C) 2004 - 2005 Nokia corporation + * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> + * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com> + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * Copyright 2010 Hans J. Koch, hjk@linutronix.de + * + * Licensed under the terms of the GPL v2. + */ + +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/string.h> + +#include <mach/clock.h> +#include <mach/hardware.h> + +static DEFINE_MUTEX(clocks_mutex); + +/*------------------------------------------------------------------------- + * Standard clock functions defined in include/linux/clk.h + *-------------------------------------------------------------------------*/ + +static void __clk_disable(struct clk *clk) +{ + BUG_ON(clk->refcount == 0); + + if (!(--clk->refcount) && clk->disable) { + /* Unconditionally disable the clock in hardware */ + clk->disable(clk); + /* recursively disable parents */ + if (clk->parent) + __clk_disable(clk->parent); + } +} + +static int __clk_enable(struct clk *clk) +{ + int ret = 0; + + if (clk->refcount++ == 0 && clk->enable) { + if (clk->parent) + ret = __clk_enable(clk->parent); + if (ret) + return ret; + else + return clk->enable(clk); + } + + return 0; +} + +/* This function increments the reference count on the clock and enables the + * clock if not already enabled. The parent clock tree is recursively enabled + */ +int clk_enable(struct clk *clk) +{ + int ret = 0; + + if (!clk) + return -EINVAL; + + mutex_lock(&clocks_mutex); + ret = __clk_enable(clk); + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_enable); + +/* This function decrements the reference count on the clock and disables + * the clock when reference count is 0. The parent clock tree is + * recursively disabled + */ +void clk_disable(struct clk *clk) +{ + if (!clk) + return; + + mutex_lock(&clocks_mutex); + __clk_disable(clk); + mutex_unlock(&clocks_mutex); +} +EXPORT_SYMBOL_GPL(clk_disable); + +/* Retrieve the *current* clock rate. If the clock itself + * does not provide a special calculation routine, ask + * its parent and so on, until one is able to return + * a valid clock rate + */ +unsigned long clk_get_rate(struct clk *clk) +{ + if (!clk) + return 0UL; + + if (clk->get_rate) + return clk->get_rate(clk); + + return clk_get_rate(clk->parent); +} +EXPORT_SYMBOL_GPL(clk_get_rate); + +/* Round the requested clock rate to the nearest supported + * rate that is less than or equal to the requested rate. + * This is dependent on the clock's current parent. + */ +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (!clk) + return 0; + if (!clk->round_rate) + return 0; + + return clk->round_rate(clk, rate); +} +EXPORT_SYMBOL_GPL(clk_round_rate); + +/* Set the clock to the requested clock rate. The rate must + * match a supported rate exactly based on what clk_round_rate returns + */ +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EINVAL; + + if (!clk) + return ret; + if (!clk->set_rate || !rate) + return ret; + + mutex_lock(&clocks_mutex); + ret = clk->set_rate(clk, rate); + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_rate); + +/* Set the clock's parent to another clock source */ +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *old; + int ret = -EINVAL; + + if (!clk) + return ret; + if (!clk->set_parent || !parent) + return ret; + + mutex_lock(&clocks_mutex); + old = clk->parent; + if (clk->refcount) + __clk_enable(parent); + ret = clk->set_parent(clk, parent); + if (ret) + old = parent; + if (clk->refcount) + __clk_disable(old); + mutex_unlock(&clocks_mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_set_parent); + +/* Retrieve the clock's parent clock source */ +struct clk *clk_get_parent(struct clk *clk) +{ + if (!clk) + return NULL; + + return clk->parent; +} +EXPORT_SYMBOL_GPL(clk_get_parent); diff --git a/arch/arm/plat-tcc/include/mach/clkdev.h b/arch/arm/plat-tcc/include/mach/clkdev.h new file mode 100644 index 000000000000..04b37a89801c --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/clkdev.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/plat-tcc/include/mach/clock.h b/arch/arm/plat-tcc/include/mach/clock.h new file mode 100644 index 000000000000..a12f58ad71a8 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/clock.h @@ -0,0 +1,48 @@ +/* + * Low level clock header file for Telechips TCC architecture + * (C) 2010 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the GPL v2. + */ + +#ifndef __ASM_ARCH_TCC_CLOCK_H__ +#define __ASM_ARCH_TCC_CLOCK_H__ + +#ifndef __ASSEMBLY__ + +struct clk { + struct clk *parent; + /* id number of a root clock, 0 for normal clocks */ + int root_id; + /* Reference count of clock enable/disable */ + int refcount; + /* Address of associated BCLKCTRx register. Must be set. */ + void __iomem *bclkctr; + /* Bit position for BCLKCTRx. Must be set. */ + int bclk_shift; + /* Address of ACLKxxx register, if any. */ + void __iomem *aclkreg; + /* get the current clock rate (always a fresh value) */ + unsigned long (*get_rate) (struct clk *); + /* Function ptr to set the clock to a new rate. The rate must match a + supported rate returned from round_rate. Leave blank if clock is not + programmable */ + int (*set_rate) (struct clk *, unsigned long); + /* Function ptr to round the requested clock rate to the nearest + supported rate that is less than or equal to the requested rate. */ + unsigned long (*round_rate) (struct clk *, unsigned long); + /* Function ptr to enable the clock. Leave blank if clock can not + be gated. */ + int (*enable) (struct clk *); + /* Function ptr to disable the clock. Leave blank if clock can not + be gated. */ + void (*disable) (struct clk *); + /* Function ptr to set the parent clock of the clock. */ + int (*set_parent) (struct clk *, struct clk *); +}; + +int clk_register(struct clk *clk); +void clk_unregister(struct clk *clk); + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_ARCH_MXC_CLOCK_H__ */ diff --git a/arch/arm/plat-tcc/include/mach/debug-macro.S b/arch/arm/plat-tcc/include/mach/debug-macro.S new file mode 100644 index 000000000000..97537845df64 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/debug-macro.S @@ -0,0 +1,33 @@ +/* + * Copyright (C) 1994-1999 Russell King + * Copyright (C) 2008-2009 Telechips + * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + + .macro addruart,rx,tmp + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x90000000 @ physical base address + movne \rx, #0xF1000000 @ virtual base + orr \rx, \rx, #0x00007000 @ UART0 + .endm + + .macro senduart,rd,rx + strb \rd, [\rx, #0x44] + .endm + + .macro waituart,rd,rx + .endm + + .macro busyuart,rd,rx +1001: + ldr \rd, [\rx, #0x14] + tst \rd, #0x20 + + beq 1001b + .endm diff --git a/arch/arm/plat-tcc/include/mach/entry-macro.S b/arch/arm/plat-tcc/include/mach/entry-macro.S new file mode 100644 index 000000000000..748f401e4b6d --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/entry-macro.S @@ -0,0 +1,68 @@ +/* + * include/asm-arm/arch-tcc83x/entry-macro.S + * + * Author : <linux@telechips.com> + * Created: June 10, 2008 + * Description: Low-level IRQ helper macros for Telechips-based platforms + * + * Copyright (C) 2008-2009 Telechips + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <mach/hardware.h> +#include <mach/irqs.h> + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + ldr \base, =0xF2003000 @ base address of PIC registers + + @@ read MREQ register of PIC0 + + mov \irqnr, #0 + ldr \irqstat, [\base, #0x00000014 ] @ lower 32 interrupts + cmp \irqstat, #0 + bne 1001f + + @@ read MREQ register of PIC1 + + ldr \irqstat, [\base, #0x00000094] @ upper 32 interrupts + cmp \irqstat, #0 + beq 1002f + mov \irqnr, #0x20 + +1001: + movs \tmp, \irqstat, lsl #16 + movne \irqstat, \tmp + addeq \irqnr, \irqnr, #16 + + movs \tmp, \irqstat, lsl #8 + movne \irqstat, \tmp + addeq \irqnr, \irqnr, #8 + + movs \tmp, \irqstat, lsl #4 + movne \irqstat, \tmp + addeq \irqnr, \irqnr, #4 + + movs \tmp, \irqstat, lsl #2 + movne \irqstat, \tmp + addeq \irqnr, \irqnr, #2 + + movs \tmp, \irqstat, lsl #1 + addeq \irqnr, \irqnr, #1 + orrs \base, \base, #1 +1002: + @@ exit here, Z flag unset if IRQ + + .endm diff --git a/arch/arm/plat-tcc/include/mach/hardware.h b/arch/arm/plat-tcc/include/mach/hardware.h new file mode 100644 index 000000000000..e70d126ccaf3 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/hardware.h @@ -0,0 +1,43 @@ +/* + * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com> + * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com> + * and Dirk Behme <dirk.behme@de.bosch.com> + * Rewritten by: <linux@telechips.com> + * Description: Hardware definitions for TCC8300 processors and boards + * + * Copyright (C) 2001 RidgeRun, Inc. + * Copyright (C) 2008-2009 Telechips + * + * Modifications for mainline (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GNU Pulic License version 2. + */ + +#ifndef __ASM_ARCH_TCC_HARDWARE_H +#define __ASM_ARCH_TCC_HARDWARE_H + +#include <asm/sizes.h> +#ifndef __ASSEMBLER__ +#include <asm/types.h> +#endif +#include <mach/io.h> + +/* + * ---------------------------------------------------------------------------- + * Clocks + * ---------------------------------------------------------------------------- + */ +#define CLKGEN_REG_BASE 0xfffece00 +#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0) +#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4) +#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8) +#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC) +#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10) +#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14) +#define ARM_SYSST (CLKGEN_REG_BASE + 0x18) +#define ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24) + +/* DPLL control registers */ +#define DPLL_CTL 0xfffecf00 + +#endif /* __ASM_ARCH_TCC_HARDWARE_H */ diff --git a/arch/arm/plat-tcc/include/mach/io.h b/arch/arm/plat-tcc/include/mach/io.h new file mode 100644 index 000000000000..3e911d3ea0f1 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/io.h @@ -0,0 +1,23 @@ +/* + * IO definitions for TCC8000 processors and boards + * + * Copyright (C) 1997-1999 Russell King + * Copyright (C) 2008-2009 Telechips + * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GNU Public License version 2. + */ + +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +/* + * We don't actually have real ISA nor PCI buses, but there is so many + * drivers out there that might just work if we fake them... + */ +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/plat-tcc/include/mach/irqs.h b/arch/arm/plat-tcc/include/mach/irqs.h new file mode 100644 index 000000000000..da863894d498 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/irqs.h @@ -0,0 +1,83 @@ +/* + * IRQ definitions for TCC8xxx + * + * Copyright (C) 2008-2009 Telechips + * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GPL v2. + * + */ + +#ifndef __ASM_ARCH_TCC_IRQS_H +#define __ASM_ARCH_TCC_IRQS_H + +#define NR_IRQS 64 + +/* PIC0 interrupts */ +#define INT_ADMA1 0 +#define INT_BDMA 1 +#define INT_ADMA0 2 +#define INT_GDMA1 3 +#define INT_I2S0RX 4 +#define INT_I2S0TX 5 +#define INT_TC 6 +#define INT_UART0 7 +#define INT_USBD 8 +#define INT_SPI0TX 9 +#define INT_UDMA 10 +#define INT_LIRQ 11 +#define INT_GDMA2 12 +#define INT_GDMA0 13 +#define INT_TC32 14 +#define INT_LCD 15 +#define INT_ADC 16 +#define INT_I2C 17 +#define INT_RTCP 18 +#define INT_RTCA 19 +#define INT_NFC 20 +#define INT_SD0 21 +#define INT_GSB0 22 +#define INT_PK 23 +#define INT_USBH0 24 +#define INT_USBH1 25 +#define INT_G2D 26 +#define INT_ECC 27 +#define INT_SPI0RX 28 +#define INT_UART1 29 +#define INT_MSCL 30 +#define INT_GSB1 31 +/* PIC1 interrupts */ +#define INT_E0 32 +#define INT_E1 33 +#define INT_E2 34 +#define INT_E3 35 +#define INT_E4 36 +#define INT_E5 37 +#define INT_E6 38 +#define INT_E7 39 +#define INT_UART2 40 +#define INT_UART3 41 +#define INT_SPI1TX 42 +#define INT_SPI1RX 43 +#define INT_GSB2 44 +#define INT_SPDIF 45 +#define INT_CDIF 46 +#define INT_VBON 47 +#define INT_VBOFF 48 +#define INT_SD1 49 +#define INT_UART4 50 +#define INT_GDMA3 51 +#define INT_I2S1RX 52 +#define INT_I2S1TX 53 +#define INT_CAN0 54 +#define INT_CAN1 55 +#define INT_GSB3 56 +#define INT_KRST 57 +#define INT_UNUSED 58 +#define INT_SD0D3 59 +#define INT_SD1D3 60 +#define INT_GPS0 61 +#define INT_GPS1 62 +#define INT_GPS2 63 + +#endif /* ASM_ARCH_TCC_IRQS_H */ diff --git a/arch/arm/plat-tcc/include/mach/memory.h b/arch/arm/plat-tcc/include/mach/memory.h new file mode 100644 index 000000000000..cd91ba8a670b --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/memory.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 RidgeRun, Inc. + * Copyright (C) 2008-2009 Telechips + * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GPL v2. + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +/* + * Physical DRAM offset. + */ +#define PHYS_OFFSET UL(0x20000000) + +#endif diff --git a/arch/arm/plat-tcc/include/mach/system.h b/arch/arm/plat-tcc/include/mach/system.h new file mode 100644 index 000000000000..909e6035d843 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/system.h @@ -0,0 +1,31 @@ +/* + * Author: <linux@telechips.com> + * Created: June 10, 2008 + * Description: LINUX SYSTEM FUNCTIONS for TCC83x + * + * Copyright (C) 2008-2009 Telechips + * + * Licensed under the terms of the GPL v2. + * + */ + +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H +#include <linux/clk.h> + +#include <asm/mach-types.h> +#include <mach/hardware.h> + +extern void plat_tcc_reboot(void); + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode, const char *cmd) +{ + plat_tcc_reboot(); +} + +#endif diff --git a/arch/arm/plat-tcc/include/mach/tcc8k-regs.h b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h new file mode 100644 index 000000000000..1d9428295332 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h @@ -0,0 +1,807 @@ +/* + * Telechips TCC8000 register definitions + * + * (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GPLv2. + */ + +#ifndef TCC8K_REGS_H +#define TCC8K_REGS_H + +#include <linux/types.h> + +#define EXT_SDRAM_BASE 0x20000000 +#define INT_SRAM_BASE 0x30000000 +#define INT_SRAM_SIZE SZ_32K +#define CS0_BASE 0x40000000 +#define CS1_BASE 0x50000000 +#define CS1_SIZE SZ_64K +#define CS2_BASE 0x60000000 +#define CS3_BASE 0x70000000 +#define AHB_PERI_BASE 0x80000000 +#define AHB_PERI_SIZE SZ_64K +#define APB0_PERI_BASE 0x90000000 +#define APB0_PERI_SIZE SZ_128K +#define APB1_PERI_BASE 0x98000000 +#define APB1_PERI_SIZE SZ_128K +#define DATA_TCM_BASE 0xa0000000 +#define DATA_TCM_SIZE SZ_8K +#define EXT_MEM_CTRL_BASE 0xf0000000 +#define EXT_MEM_CTRL_SIZE SZ_4K + +#define CS1_BASE_VIRT (void __iomem *)0xf7000000 +#define AHB_PERI_BASE_VIRT (void __iomem *)0xf4000000 +#define APB0_PERI_BASE_VIRT (void __iomem *)0xf1000000 +#define APB1_PERI_BASE_VIRT (void __iomem *)0xf2000000 +#define EXT_MEM_CTRL_BASE_VIRT (void __iomem *)0xf3000000 +#define INT_SRAM_BASE_VIRT (void __iomem *)0xf5000000 +#define DATA_TCM_BASE_VIRT (void __iomem *)0xf6000000 + +#define __REG(x) (*((volatile u32 *)(x))) + +/* USB Device Controller Registers */ +#define UDC_BASE (AHB_PERI_BASE_VIRT + 0x8000) +#define UDC_BASE_PHYS (AHB_PERI_BASE + 0x8000) + +#define UDC_IR_OFFS 0x00 +#define UDC_EIR_OFFS 0x04 +#define UDC_EIER_OFFS 0x08 +#define UDC_FAR_OFFS 0x0c +#define UDC_FNR_OFFS 0x10 +#define UDC_EDR_OFFS 0x14 +#define UDC_RT_OFFS 0x18 +#define UDC_SSR_OFFS 0x1c +#define UDC_SCR_OFFS 0x20 +#define UDC_EP0SR_OFFS 0x24 +#define UDC_EP0CR_OFFS 0x28 + +#define UDC_ESR_OFFS 0x2c +#define UDC_ECR_OFFS 0x30 +#define UDC_BRCR_OFFS 0x34 +#define UDC_BWCR_OFFS 0x38 +#define UDC_MPR_OFFS 0x3c +#define UDC_DCR_OFFS 0x40 +#define UDC_DTCR_OFFS 0x44 +#define UDC_DFCR_OFFS 0x48 +#define UDC_DTTCR1_OFFS 0x4c +#define UDC_DTTCR2_OFFS 0x50 +#define UDC_ESR2_OFFS 0x54 + +#define UDC_SCR2_OFFS 0x58 +#define UDC_EP0BUF_OFFS 0x60 +#define UDC_EP1BUF_OFFS 0x64 +#define UDC_EP2BUF_OFFS 0x68 +#define UDC_EP3BUF_OFFS 0x6c +#define UDC_PLICR_OFFS 0xa0 +#define UDC_PCR_OFFS 0xa4 + +#define UDC_UPCR0_OFFS 0xc8 +#define UDC_UPCR1_OFFS 0xcc +#define UDC_UPCR2_OFFS 0xd0 +#define UDC_UPCR3_OFFS 0xd4 + +/* Bits in UDC_EIR */ +#define UDC_EIR_EP0I (1 << 0) +#define UDC_EIR_EP1I (1 << 1) +#define UDC_EIR_EP2I (1 << 2) +#define UDC_EIR_EP3I (1 << 3) +#define UDC_EIR_EPI_MASK 0x0f + +/* Bits in UDC_EIER */ +#define UDC_EIER_EP0IE (1 << 0) +#define UDC_EIER_EP1IE (1 << 1) +#define UDC_EIER_EP2IE (1 << 2) +#define UDC_EIER_EP3IE (1 << 3) + +/* Bits in UDC_FNR */ +#define UDC_FNR_FN_MASK 0x7ff +#define UDC_FNR_SM (1 << 13) +#define UDC_FNR_FTL (1 << 14) + +/* Bits in UDC_SSR */ +#define UDC_SSR_HFRES (1 << 0) +#define UDC_SSR_HFSUSP (1 << 1) +#define UDC_SSR_HFRM (1 << 2) +#define UDC_SSR_SDE (1 << 3) +#define UDC_SSR_HSP (1 << 4) +#define UDC_SSR_DM (1 << 5) +#define UDC_SSR_DP (1 << 6) +#define UDC_SSR_TBM (1 << 7) +#define UDC_SSR_VBON (1 << 8) +#define UDC_SSR_VBOFF (1 << 9) +#define UDC_SSR_EOERR (1 << 10) +#define UDC_SSR_DCERR (1 << 11) +#define UDC_SSR_TCERR (1 << 12) +#define UDC_SSR_BSERR (1 << 13) +#define UDC_SSR_TMERR (1 << 14) +#define UDC_SSR_BAERR (1 << 15) + +/* Bits in UDC_SCR */ +#define UDC_SCR_HRESE (1 << 0) +#define UDC_SCR_HSSPE (1 << 1) +#define UDC_SCR_RRDE (1 << 5) +#define UDC_SCR_SPDEN (1 << 6) +#define UDC_SCR_DIEN (1 << 12) + +/* Bits in UDC_EP0SR */ +#define UDC_EP0SR_RSR (1 << 0) +#define UDC_EP0SR_TST (1 << 1) +#define UDC_EP0SR_SHT (1 << 4) +#define UDC_EP0SR_LWO (1 << 6) + +/* Bits in UDC_EP0CR */ +#define UDC_EP0CR_ESS (1 << 1) + +/* Bits in UDC_ESR */ +#define UDC_ESR_RPS (1 << 0) +#define UDC_ESR_TPS (1 << 1) +#define UDC_ESR_LWO (1 << 4) +#define UDC_ESR_FFS (1 << 6) + +/* Bits in UDC_ECR */ +#define UDC_ECR_ESS (1 << 1) +#define UDC_ECR_CDP (1 << 2) + +#define UDC_ECR_FLUSH (1 << 6) +#define UDC_ECR_DUEN (1 << 7) + +/* Bits in UDC_UPCR0 */ +#define UDC_UPCR0_VBD (1 << 1) +#define UDC_UPCR0_VBDS (1 << 6) +#define UDC_UPCR0_RCD_12 (0x0 << 9) +#define UDC_UPCR0_RCD_24 (0x1 << 9) +#define UDC_UPCR0_RCD_48 (0x2 << 9) +#define UDC_UPCR0_RCS_EXT (0x1 << 11) +#define UDC_UPCR0_RCS_XTAL (0x0 << 11) + +/* Bits in UDC_UPCR1 */ +#define UDC_UPCR1_CDT(x) ((x) << 0) +#define UDC_UPCR1_OTGT(x) ((x) << 3) +#define UDC_UPCR1_SQRXT(x) ((x) << 8) +#define UDC_UPCR1_TXFSLST(x) ((x) << 12) + +/* Bits in UDC_UPCR2 */ +#define UDC_UPCR2_TP (1 << 0) +#define UDC_UPCR2_TXRT(x) ((x) << 2) +#define UDC_UPCR2_TXVRT(x) ((x) << 5) +#define UDC_UPCR2_OPMODE(x) ((x) << 9) +#define UDC_UPCR2_XCVRSEL(x) ((x) << 12) +#define UDC_UPCR2_TM (1 << 14) + +/* USB Host Controller registers */ +#define USBH0_BASE (AHB_PERI_BASE_VIRT + 0xb000) +#define USBH1_BASE (AHB_PERI_BASE_VIRT + 0xb800) + +#define OHCI_INT_ENABLE_OFFS 0x10 + +#define RH_DESCRIPTOR_A_OFFS 0x48 +#define RH_DESCRIPTOR_B_OFFS 0x4c + +#define USBHTCFG0_OFFS 0x100 +#define USBHHCFG0_OFFS 0x104 +#define USBHHCFG1_OFFS 0x104 + +/* DMA controller registers */ +#define DMAC0_BASE (AHB_PERI_BASE + 0x4000) +#define DMAC1_BASE (AHB_PERI_BASE + 0xa000) +#define DMAC2_BASE (AHB_PERI_BASE + 0x4800) +#define DMAC3_BASE (AHB_PERI_BASE + 0xa800) + +#define DMAC_CH_OFFSET(ch) (ch * 0x30) + +#define ST_SADR_OFFS 0x00 +#define SPARAM_OFFS 0x04 +#define C_SADR_OFFS 0x0c +#define ST_DADR_OFFS 0x10 +#define DPARAM_OFFS 0x14 +#define C_DADR_OFFS 0x1c +#define HCOUNT_OFFS 0x20 +#define CHCTRL_OFFS 0x24 +#define RPTCTRL_OFFS 0x28 +#define EXTREQ_A_OFFS 0x2c + +/* Bits in CHCTRL register */ +#define CHCTRL_EN (1 << 0) + +#define CHCTRL_IEN (1 << 2) +#define CHCTRL_FLAG (1 << 3) +#define CHCTRL_WSIZE8 (0 << 4) +#define CHCTRL_WSIZE16 (1 << 4) +#define CHCTRL_WSIZE32 (2 << 4) + +#define CHCTRL_BSIZE1 (0 << 6) +#define CHCTRL_BSIZE2 (1 << 6) +#define CHCTRL_BSIZE4 (2 << 6) +#define CHCTRL_BSIZE8 (3 << 6) + +#define CHCTRL_TYPE_SINGLE_E (0 << 8) +#define CHCTRL_TYPE_HW (1 << 8) +#define CHCTRL_TYPE_SW (2 << 8) +#define CHCTRL_TYPE_SINGLE_L (3 << 8) + +#define CHCTRL_BST (1 << 10) + +/* Use DMA controller 0, channel 2 for USB */ +#define USB_DMA_BASE (DMAC0_BASE + DMAC_CH_OFFSET(2)) + +/* NAND flash controller registers */ +#define NFC_BASE (AHB_PERI_BASE_VIRT + 0xd000) +#define NFC_BASE_PHYS (AHB_PERI_BASE + 0xd000) + +#define NFC_CMD_OFFS 0x00 +#define NFC_LADDR_OFFS 0x04 +#define NFC_BADDR_OFFS 0x08 +#define NFC_SADDR_OFFS 0x0c +#define NFC_WDATA_OFFS 0x10 +#define NFC_LDATA_OFFS 0x20 +#define NFC_SDATA_OFFS 0x40 +#define NFC_CTRL_OFFS 0x50 +#define NFC_PSTART_OFFS 0x54 +#define NFC_RSTART_OFFS 0x58 +#define NFC_DSIZE_OFFS 0x5c +#define NFC_IREQ_OFFS 0x60 +#define NFC_RST_OFFS 0x64 +#define NFC_CTRL1_OFFS 0x68 +#define NFC_MDATA_OFFS 0x70 + +#define NFC_WDATA_PHYS_ADDR (NFC_BASE_PHYS + NFC_WDATA_OFFS) + +/* Bits in NFC_CTRL */ +#define NFC_CTRL_BHLD_MASK (0xf << 0) +#define NFC_CTRL_BPW_MASK (0xf << 4) +#define NFC_CTRL_BSTP_MASK (0xf << 8) +#define NFC_CTRL_CADDR_MASK (0x7 << 12) +#define NFC_CTRL_CADDR_1 (0x0 << 12) +#define NFC_CTRL_CADDR_2 (0x1 << 12) +#define NFC_CTRL_CADDR_3 (0x2 << 12) +#define NFC_CTRL_CADDR_4 (0x3 << 12) +#define NFC_CTRL_CADDR_5 (0x4 << 12) +#define NFC_CTRL_MSK (1 << 15) +#define NFC_CTRL_PSIZE256 (0 << 16) +#define NFC_CTRL_PSIZE512 (1 << 16) +#define NFC_CTRL_PSIZE1024 (2 << 16) +#define NFC_CTRL_PSIZE2048 (3 << 16) +#define NFC_CTRL_PSIZE4096 (4 << 16) +#define NFC_CTRL_PSIZE_MASK (7 << 16) +#define NFC_CTRL_BSIZE1 (0 << 19) +#define NFC_CTRL_BSIZE2 (1 << 19) +#define NFC_CTRL_BSIZE4 (2 << 19) +#define NFC_CTRL_BSIZE8 (3 << 19) +#define NFC_CTRL_BSIZE_MASK (3 << 19) +#define NFC_CTRL_RDY (1 << 21) +#define NFC_CTRL_CS0SEL (1 << 22) +#define NFC_CTRL_CS1SEL (1 << 23) +#define NFC_CTRL_CS2SEL (1 << 24) +#define NFC_CTRL_CS3SEL (1 << 25) +#define NFC_CTRL_CSMASK (0xf << 22) +#define NFC_CTRL_BW (1 << 26) +#define NFC_CTRL_FS (1 << 27) +#define NFC_CTRL_DEN (1 << 28) +#define NFC_CTRL_READ_IEN (1 << 29) +#define NFC_CTRL_PROG_IEN (1 << 30) +#define NFC_CTRL_RDY_IEN (1 << 31) + +/* Bits in NFC_IREQ */ +#define NFC_IREQ_IRQ0 (1 << 0) +#define NFC_IREQ_IRQ1 (1 << 1) +#define NFC_IREQ_IRQ2 (1 << 2) + +#define NFC_IREQ_FLAG0 (1 << 4) +#define NFC_IREQ_FLAG1 (1 << 5) +#define NFC_IREQ_FLAG2 (1 << 6) + +/* MMC controller registers */ +#define MMC0_BASE (AHB_PERI_BASE_VIRT + 0xe000) +#define MMC1_BASE (AHB_PERI_BASE_VIRT + 0xe800) + +/* UART base addresses */ + +#define UART0_BASE (APB0_PERI_BASE_VIRT + 0x07000) +#define UART0_BASE_PHYS (APB0_PERI_BASE + 0x07000) +#define UART1_BASE (APB0_PERI_BASE_VIRT + 0x08000) +#define UART1_BASE_PHYS (APB0_PERI_BASE + 0x08000) +#define UART2_BASE (APB0_PERI_BASE_VIRT + 0x09000) +#define UART2_BASE_PHYS (APB0_PERI_BASE + 0x09000) +#define UART3_BASE (APB0_PERI_BASE_VIRT + 0x0a000) +#define UART3_BASE_PHYS (APB0_PERI_BASE + 0x0a000) +#define UART4_BASE (APB0_PERI_BASE_VIRT + 0x15000) +#define UART4_BASE_PHYS (APB0_PERI_BASE + 0x15000) + +#define UART_BASE UART0_BASE +#define UART_BASE_PHYS UART0_BASE_PHYS + +/* ECC controller */ +#define ECC_CTR_BASE (APB0_PERI_BASE_VIRT + 0xd000) + +#define ECC_CTRL_OFFS 0x00 +#define ECC_BASE_OFFS 0x04 +#define ECC_MASK_OFFS 0x08 +#define ECC_CLEAR_OFFS 0x0c +#define ECC4_0_OFFS 0x10 +#define ECC4_1_OFFS 0x14 + +#define ECC_EADDR0_OFFS 0x50 + +#define ECC_ERRNUM_OFFS 0x90 +#define ECC_IREQ_OFFS 0x94 + +/* Bits in ECC_CTRL */ +#define ECC_CTRL_ECC4_DIEN (1 << 28) +#define ECC_CTRL_ECC8_DIEN (1 << 29) +#define ECC_CTRL_ECC12_DIEN (1 << 30) +#define ECC_CTRL_ECC_DISABLE 0x0 +#define ECC_CTRL_ECC_SLC_ENC 0x8 +#define ECC_CTRL_ECC_SLC_DEC 0x9 +#define ECC_CTRL_ECC4_ENC 0xa +#define ECC_CTRL_ECC4_DEC 0xb +#define ECC_CTRL_ECC8_ENC 0xc +#define ECC_CTRL_ECC8_DEC 0xd +#define ECC_CTRL_ECC12_ENC 0xe +#define ECC_CTRL_ECC12_DEC 0xf + +/* Bits in ECC_IREQ */ +#define ECC_IREQ_E4DI (1 << 4) + +#define ECC_IREQ_E4DF (1 << 20) +#define ECC_IREQ_E4EF (1 << 21) + +/* Interrupt controller */ + +#define PIC0_BASE (APB1_PERI_BASE_VIRT + 0x3000) +#define PIC0_BASE_PHYS (APB1_PERI_BASE + 0x3000) + +#define PIC0_IEN_OFFS 0x00 +#define PIC0_CREQ_OFFS 0x04 +#define PIC0_IREQ_OFFS 0x08 +#define PIC0_IRQSEL_OFFS 0x0c +#define PIC0_SRC_OFFS 0x10 +#define PIC0_MREQ_OFFS 0x14 +#define PIC0_TSTREQ_OFFS 0x18 +#define PIC0_POL_OFFS 0x1c +#define PIC0_IRQ_OFFS 0x20 +#define PIC0_FIQ_OFFS 0x24 +#define PIC0_MIRQ_OFFS 0x28 +#define PIC0_MFIQ_OFFS 0x2c +#define PIC0_TMODE_OFFS 0x30 +#define PIC0_SYNC_OFFS 0x34 +#define PIC0_WKUP_OFFS 0x38 +#define PIC0_TMODEA_OFFS 0x3c +#define PIC0_INTOEN_OFFS 0x40 +#define PIC0_MEN0_OFFS 0x44 +#define PIC0_MEN_OFFS 0x48 + +#define PIC0_IEN __REG(PIC0_BASE + PIC0_IEN_OFFS) +#define PIC0_IEN_PHYS __REG(PIC0_BASE_PHYS + PIC0_IEN_OFFS) +#define PIC0_CREQ __REG(PIC0_BASE + PIC0_CREQ_OFFS) +#define PIC0_CREQ_PHYS __REG(PIC0_BASE_PHYS + PIC0_CREQ_OFFS) +#define PIC0_IREQ __REG(PIC0_BASE + PIC0_IREQ_OFFS) +#define PIC0_IRQSEL __REG(PIC0_BASE + PIC0_IRQSEL_OFFS) +#define PIC0_IRQSEL_PHYS __REG(PIC0_BASE_PHYS + PIC0_IRQSEL_OFFS) +#define PIC0_SRC __REG(PIC0_BASE + PIC0_SRC_OFFS) +#define PIC0_MREQ __REG(PIC0_BASE + PIC0_MREQ_OFFS) +#define PIC0_TSTREQ __REG(PIC0_BASE + PIC0_TSTREQ_OFFS) +#define PIC0_POL __REG(PIC0_BASE + PIC0_POL_OFFS) +#define PIC0_IRQ __REG(PIC0_BASE + PIC0_IRQ_OFFS) +#define PIC0_FIQ __REG(PIC0_BASE + PIC0_FIQ_OFFS) +#define PIC0_MIRQ __REG(PIC0_BASE + PIC0_MIRQ_OFFS) +#define PIC0_MFIQ __REG(PIC0_BASE + PIC0_MFIQ_OFFS) +#define PIC0_TMODE __REG(PIC0_BASE + PIC0_TMODE_OFFS) +#define PIC0_TMODE_PHYS __REG(PIC0_BASE_PHYS + PIC0_TMODE_OFFS) +#define PIC0_SYNC __REG(PIC0_BASE + PIC0_SYNC_OFFS) +#define PIC0_WKUP __REG(PIC0_BASE + PIC0_WKUP_OFFS) +#define PIC0_TMODEA __REG(PIC0_BASE + PIC0_TMODEA_OFFS) +#define PIC0_INTOEN __REG(PIC0_BASE + PIC0_INTOEN_OFFS) +#define PIC0_MEN0 __REG(PIC0_BASE + PIC0_MEN0_OFFS) +#define PIC0_MEN __REG(PIC0_BASE + PIC0_MEN_OFFS) + +#define PIC1_BASE (APB1_PERI_BASE_VIRT + 0x3080) + +#define PIC1_IEN_OFFS 0x00 +#define PIC1_CREQ_OFFS 0x04 +#define PIC1_IREQ_OFFS 0x08 +#define PIC1_IRQSEL_OFFS 0x0c +#define PIC1_SRC_OFFS 0x10 +#define PIC1_MREQ_OFFS 0x14 +#define PIC1_TSTREQ_OFFS 0x18 +#define PIC1_POL_OFFS 0x1c +#define PIC1_IRQ_OFFS 0x20 +#define PIC1_FIQ_OFFS 0x24 +#define PIC1_MIRQ_OFFS 0x28 +#define PIC1_MFIQ_OFFS 0x2c +#define PIC1_TMODE_OFFS 0x30 +#define PIC1_SYNC_OFFS 0x34 +#define PIC1_WKUP_OFFS 0x38 +#define PIC1_TMODEA_OFFS 0x3c +#define PIC1_INTOEN_OFFS 0x40 +#define PIC1_MEN1_OFFS 0x44 +#define PIC1_MEN_OFFS 0x48 + +#define PIC1_IEN __REG(PIC1_BASE + PIC1_IEN_OFFS) +#define PIC1_CREQ __REG(PIC1_BASE + PIC1_CREQ_OFFS) +#define PIC1_IREQ __REG(PIC1_BASE + PIC1_IREQ_OFFS) +#define PIC1_IRQSEL __REG(PIC1_BASE + PIC1_IRQSEL_OFFS) +#define PIC1_SRC __REG(PIC1_BASE + PIC1_SRC_OFFS) +#define PIC1_MREQ __REG(PIC1_BASE + PIC1_MREQ_OFFS) +#define PIC1_TSTREQ __REG(PIC1_BASE + PIC1_TSTREQ_OFFS) +#define PIC1_POL __REG(PIC1_BASE + PIC1_POL_OFFS) +#define PIC1_IRQ __REG(PIC1_BASE + PIC1_IRQ_OFFS) +#define PIC1_FIQ __REG(PIC1_BASE + PIC1_FIQ_OFFS) +#define PIC1_MIRQ __REG(PIC1_BASE + PIC1_MIRQ_OFFS) +#define PIC1_MFIQ __REG(PIC1_BASE + PIC1_MFIQ_OFFS) +#define PIC1_TMODE __REG(PIC1_BASE + PIC1_TMODE_OFFS) +#define PIC1_SYNC __REG(PIC1_BASE + PIC1_SYNC_OFFS) +#define PIC1_WKUP __REG(PIC1_BASE + PIC1_WKUP_OFFS) +#define PIC1_TMODEA __REG(PIC1_BASE + PIC1_TMODEA_OFFS) +#define PIC1_INTOEN __REG(PIC1_BASE + PIC1_INTOEN_OFFS) +#define PIC1_MEN1 __REG(PIC1_BASE + PIC1_MEN1_OFFS) +#define PIC1_MEN __REG(PIC1_BASE + PIC1_MEN_OFFS) + +/* Timer registers */ +#define TIMER_BASE (APB1_PERI_BASE_VIRT + 0x4000) +#define TIMER_BASE_PHYS (APB1_PERI_BASE + 0x4000) + +#define TWDCFG_OFFS 0x70 + +#define TC32EN_OFFS 0x80 +#define TC32LDV_OFFS 0x84 +#define TC32CMP0_OFFS 0x88 +#define TC32CMP1_OFFS 0x8c +#define TC32PCNT_OFFS 0x90 +#define TC32MCNT_OFFS 0x94 +#define TC32IRQ_OFFS 0x98 + +/* Bits in TC32EN */ +#define TC32EN_PRESCALE_MASK 0x00ffffff +#define TC32EN_ENABLE (1 << 24) +#define TC32EN_LOADZERO (1 << 25) +#define TC32EN_STOPMODE (1 << 26) +#define TC32EN_LDM0 (1 << 28) +#define TC32EN_LDM1 (1 << 29) + +/* Bits in TC32IRQ */ +#define TC32IRQ_MSTAT_MASK 0x0000001f +#define TC32IRQ_RSTAT_MASK (0x1f << 8) +#define TC32IRQ_IRQEN0 (1 << 16) +#define TC32IRQ_IRQEN1 (1 << 17) +#define TC32IRQ_IRQEN2 (1 << 18) +#define TC32IRQ_IRQEN3 (1 << 19) +#define TC32IRQ_IRQEN4 (1 << 20) +#define TC32IRQ_RSYNC (1 << 30) +#define TC32IRQ_IRQCLR (1 << 31) + +/* GPIO registers */ +#define GPIOPD_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOPD_DAT_OFFS 0x00 +#define GPIOPD_DOE_OFFS 0x04 +#define GPIOPD_FS0_OFFS 0x08 +#define GPIOPD_FS1_OFFS 0x0c +#define GPIOPD_FS2_OFFS 0x10 +#define GPIOPD_RPU_OFFS 0x30 +#define GPIOPD_RPD_OFFS 0x34 +#define GPIOPD_DV0_OFFS 0x38 +#define GPIOPD_DV1_OFFS 0x3c + +#define GPIOPS_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOPS_DAT_OFFS 0x40 +#define GPIOPS_DOE_OFFS 0x44 +#define GPIOPS_FS0_OFFS 0x48 +#define GPIOPS_FS1_OFFS 0x4c +#define GPIOPS_FS2_OFFS 0x50 +#define GPIOPS_FS3_OFFS 0x54 +#define GPIOPS_RPU_OFFS 0x70 +#define GPIOPS_RPD_OFFS 0x74 +#define GPIOPS_DV0_OFFS 0x78 +#define GPIOPS_DV1_OFFS 0x7c + +#define GPIOPS_FS1_SDH0_BITS 0x000000ff +#define GPIOPS_FS1_SDH1_BITS 0x0000ff00 + +#define GPIOPU_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOPU_DAT_OFFS 0x80 +#define GPIOPU_DOE_OFFS 0x84 +#define GPIOPU_FS0_OFFS 0x88 +#define GPIOPU_FS1_OFFS 0x8c +#define GPIOPU_FS2_OFFS 0x90 +#define GPIOPU_RPU_OFFS 0xb0 +#define GPIOPU_RPD_OFFS 0xb4 +#define GPIOPU_DV0_OFFS 0xb8 +#define GPIOPU_DV1_OFFS 0xbc + +#define GPIOPU_FS0_TXD0 (1 << 0) +#define GPIOPU_FS0_RXD0 (1 << 1) +#define GPIOPU_FS0_CTS0 (1 << 2) +#define GPIOPU_FS0_RTS0 (1 << 3) +#define GPIOPU_FS0_TXD1 (1 << 4) +#define GPIOPU_FS0_RXD1 (1 << 5) +#define GPIOPU_FS0_CTS1 (1 << 6) +#define GPIOPU_FS0_RTS1 (1 << 7) +#define GPIOPU_FS0_TXD2 (1 << 8) +#define GPIOPU_FS0_RXD2 (1 << 9) +#define GPIOPU_FS0_CTS2 (1 << 10) +#define GPIOPU_FS0_RTS2 (1 << 11) +#define GPIOPU_FS0_TXD3 (1 << 12) +#define GPIOPU_FS0_RXD3 (1 << 13) +#define GPIOPU_FS0_CTS3 (1 << 14) +#define GPIOPU_FS0_RTS3 (1 << 15) +#define GPIOPU_FS0_TXD4 (1 << 16) +#define GPIOPU_FS0_RXD4 (1 << 17) +#define GPIOPU_FS0_CTS4 (1 << 18) +#define GPIOPU_FS0_RTS4 (1 << 19) + +#define GPIOFC_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOFC_DAT_OFFS 0xc0 +#define GPIOFC_DOE_OFFS 0xc4 +#define GPIOFC_FS0_OFFS 0xc8 +#define GPIOFC_FS1_OFFS 0xcc +#define GPIOFC_FS2_OFFS 0xd0 +#define GPIOFC_FS3_OFFS 0xd4 +#define GPIOFC_RPU_OFFS 0xf0 +#define GPIOFC_RPD_OFFS 0xf4 +#define GPIOFC_DV0_OFFS 0xf8 +#define GPIOFC_DV1_OFFS 0xfc + +#define GPIOFD_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOFD_DAT_OFFS 0x100 +#define GPIOFD_DOE_OFFS 0x104 +#define GPIOFD_FS0_OFFS 0x108 +#define GPIOFD_FS1_OFFS 0x10c +#define GPIOFD_FS2_OFFS 0x110 +#define GPIOFD_RPU_OFFS 0x130 +#define GPIOFD_RPD_OFFS 0x134 +#define GPIOFD_DV0_OFFS 0x138 +#define GPIOFD_DV1_OFFS 0x13c + +#define GPIOLC_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOLC_DAT_OFFS 0x140 +#define GPIOLC_DOE_OFFS 0x144 +#define GPIOLC_FS0_OFFS 0x148 +#define GPIOLC_FS1_OFFS 0x14c +#define GPIOLC_RPU_OFFS 0x170 +#define GPIOLC_RPD_OFFS 0x174 +#define GPIOLC_DV0_OFFS 0x178 +#define GPIOLC_DV1_OFFS 0x17c + +#define GPIOLD_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOLD_DAT_OFFS 0x180 +#define GPIOLD_DOE_OFFS 0x184 +#define GPIOLD_FS0_OFFS 0x188 +#define GPIOLD_FS1_OFFS 0x18c +#define GPIOLD_FS2_OFFS 0x190 +#define GPIOLD_RPU_OFFS 0x1b0 +#define GPIOLD_RPD_OFFS 0x1b4 +#define GPIOLD_DV0_OFFS 0x1b8 +#define GPIOLD_DV1_OFFS 0x1bc + +#define GPIOAD_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOAD_DAT_OFFS 0x1c0 +#define GPIOAD_DOE_OFFS 0x1c4 +#define GPIOAD_FS0_OFFS 0x1c8 +#define GPIOAD_RPU_OFFS 0x1f0 +#define GPIOAD_RPD_OFFS 0x1f4 +#define GPIOAD_DV0_OFFS 0x1f8 +#define GPIOAD_DV1_OFFS 0x1fc + +#define GPIOXC_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOXC_DAT_OFFS 0x200 +#define GPIOXC_DOE_OFFS 0x204 +#define GPIOXC_FS0_OFFS 0x208 +#define GPIOXC_RPU_OFFS 0x230 +#define GPIOXC_RPD_OFFS 0x234 +#define GPIOXC_DV0_OFFS 0x238 +#define GPIOXC_DV1_OFFS 0x23c + +#define GPIOXC_FS0 __REG(GPIOXC_BASE + GPIOXC_FS0_OFFS) + +#define GPIOXC_FS0_CS0 (1 << 26) +#define GPIOXC_FS0_CS1 (1 << 27) + +#define GPIOXD_BASE (APB1_PERI_BASE_VIRT + 0x5000) + +#define GPIOXD_DAT_OFFS 0x240 +#define GPIOXD_FS0_OFFS 0x248 +#define GPIOXD_RPU_OFFS 0x270 +#define GPIOXD_RPD_OFFS 0x274 +#define GPIOXD_DV0_OFFS 0x278 +#define GPIOXD_DV1_OFFS 0x27c + +#define GPIOPK_BASE (APB1_PERI_BASE_VIRT + 0x1c000) + +#define GPIOPK_RST_OFFS 0x008 +#define GPIOPK_DAT_OFFS 0x100 +#define GPIOPK_DOE_OFFS 0x104 +#define GPIOPK_FS0_OFFS 0x108 +#define GPIOPK_FS1_OFFS 0x10c +#define GPIOPK_FS2_OFFS 0x110 +#define GPIOPK_IRQST_OFFS 0x210 +#define GPIOPK_IRQEN_OFFS 0x214 +#define GPIOPK_IRQPOL_OFFS 0x218 +#define GPIOPK_IRQTM0_OFFS 0x21c +#define GPIOPK_IRQTM1_OFFS 0x220 +#define GPIOPK_CTL_OFFS 0x22c + +#define PMGPIO_BASE (APB1_PERI_BASE_VIRT + 0x10000) +#define BACKUP_RAM_BASE PMGPIO_BASE + +#define PMGPIO_DAT_OFFS 0x800 +#define PMGPIO_DOE_OFFS 0x804 +#define PMGPIO_FS0_OFFS 0x808 +#define PMGPIO_RPU_OFFS 0x810 +#define PMGPIO_RPD_OFFS 0x814 +#define PMGPIO_DV0_OFFS 0x818 +#define PMGPIO_DV1_OFFS 0x81c +#define PMGPIO_EE0_OFFS 0x820 +#define PMGPIO_EE1_OFFS 0x824 +#define PMGPIO_CTL_OFFS 0x828 +#define PMGPIO_DI_OFFS 0x82c +#define PMGPIO_STR_OFFS 0x830 +#define PMGPIO_STF_OFFS 0x834 +#define PMGPIO_POL_OFFS 0x838 +#define PMGPIO_APB_OFFS 0x800 + +/* Clock controller registers */ +#define CKC_BASE ((void __iomem *)(APB1_PERI_BASE_VIRT + 0x6000)) + +#define CLKCTRL_OFFS 0x00 +#define PLL0CFG_OFFS 0x04 +#define PLL1CFG_OFFS 0x08 +#define CLKDIVC0_OFFS 0x0c + +#define BCLKCTR0_OFFS 0x14 +#define SWRESET0_OFFS 0x18 + +#define BCLKCTR1_OFFS 0x60 +#define SWRESET1_OFFS 0x64 +#define PWDCTL_OFFS 0x68 +#define PLL2CFG_OFFS 0x6c +#define CLKDIVC1_OFFS 0x70 + +#define ACLKREF_OFFS 0x80 +#define ACLKI2C_OFFS 0x84 +#define ACLKSPI0_OFFS 0x88 +#define ACLKSPI1_OFFS 0x8c +#define ACLKUART0_OFFS 0x90 +#define ACLKUART1_OFFS 0x94 +#define ACLKUART2_OFFS 0x98 +#define ACLKUART3_OFFS 0x9c +#define ACLKUART4_OFFS 0xa0 +#define ACLKTCT_OFFS 0xa4 +#define ACLKTCX_OFFS 0xa8 +#define ACLKTCZ_OFFS 0xac +#define ACLKADC_OFFS 0xb0 +#define ACLKDAI0_OFFS 0xb4 +#define ACLKDAI1_OFFS 0xb8 +#define ACLKLCD_OFFS 0xbc +#define ACLKSPDIF_OFFS 0xc0 +#define ACLKUSBH_OFFS 0xc4 +#define ACLKSDH0_OFFS 0xc8 +#define ACLKSDH1_OFFS 0xcc +#define ACLKC3DEC_OFFS 0xd0 +#define ACLKEXT_OFFS 0xd4 +#define ACLKCAN0_OFFS 0xd8 +#define ACLKCAN1_OFFS 0xdc +#define ACLKGSB0_OFFS 0xe0 +#define ACLKGSB1_OFFS 0xe4 +#define ACLKGSB2_OFFS 0xe8 +#define ACLKGSB3_OFFS 0xec + +#define PLLxCFG_PD (1 << 31) + +/* CLKCTRL bits */ +#define CLKCTRL_XE (1 << 31) + +/* CLKDIVCx bits */ +#define CLKDIVC0_XTE (1 << 7) +#define CLKDIVC0_XE (1 << 15) +#define CLKDIVC0_P1E (1 << 23) +#define CLKDIVC0_P0E (1 << 31) + +#define CLKDIVC1_P2E (1 << 7) + +/* BCLKCTR0 clock bits */ +#define BCLKCTR0_USBD (1 << 4) +#define BCLKCTR0_ECC (1 << 9) +#define BCLKCTR0_USBH0 (1 << 11) +#define BCLKCTR0_NFC (1 << 16) + +/* BCLKCTR1 clock bits */ +#define BCLKCTR1_USBH1 (1 << 20) + +/* SWRESET0 bits */ +#define SWRESET0_USBD (1 << 4) +#define SWRESET0_USBH0 (1 << 11) + +/* SWRESET1 bits */ +#define SWRESET1_USBH1 (1 << 20) + +/* System clock sources. + * Note: These are the clock sources that serve as parents for + * all other clocks. They have no parents themselves. + * + * These values are used for struct clk->root_id. All clocks + * that are not system clock sources have this value set to + * CLK_SRC_NOROOT. + * The values for system clocks start with CLK_SRC_PLL0 == 0 + * because this gives us exactly the values needed for the lower + * 4 bits of ACLK_* registers. Therefore, CLK_SRC_NOROOT is + * defined as -1 to not disturb the order. + */ +enum root_clks { + CLK_SRC_NOROOT = -1, + CLK_SRC_PLL0 = 0, + CLK_SRC_PLL1, + CLK_SRC_PLL0DIV, + CLK_SRC_PLL1DIV, + CLK_SRC_XI, + CLK_SRC_XIDIV, + CLK_SRC_XTI, + CLK_SRC_XTIDIV, + CLK_SRC_PLL2, + CLK_SRC_PLL2DIV, + CLK_SRC_PK0, + CLK_SRC_PK1, + CLK_SRC_PK2, + CLK_SRC_PK3, + CLK_SRC_PK4, + CLK_SRC_48MHZ +}; + +#define CLK_SRC_MASK 0xf + +/* Bits in ACLK* registers */ +#define ACLK_EN (1 << 28) +#define ACLK_SEL_SHIFT 24 +#define ACLK_SEL_MASK 0x0f000000 +#define ACLK_DIV_MASK 0x00000fff + +/* System configuration registers */ + +#define SCFG_BASE (APB1_PERI_BASE_VIRT + 0x13000) + +#define BMI_OFFS 0x00 +#define AHBCON0_OFFS 0x04 +#define APBPWE_OFFS 0x08 +#define DTCMWAIT_OFFS 0x0c +#define ECCSEL_OFFS 0x10 +#define AHBCON1_OFFS 0x14 +#define SDHCFG_OFFS 0x18 +#define REMAP_OFFS 0x20 +#define LCDSIAE_OFFS 0x24 +#define XMCCFG_OFFS 0xe0 +#define IMCCFG_OFFS 0xe4 + +/* Values for ECCSEL */ +#define ECCSEL_EXTMEM 0x0 +#define ECCSEL_DTCM 0x1 +#define ECCSEL_INT_SRAM 0x2 +#define ECCSEL_AHB 0x3 + +/* Bits in XMCCFG */ +#define XMCCFG_NFCE (1 << 1) +#define XMCCFG_FDXD (1 << 2) + +/* External memory controller registers */ + +#define EMC_BASE EXT_MEM_CTRL_BASE + +#define SDCFG_OFFS 0x00 +#define SDFSM_OFFS 0x04 +#define MCFG_OFFS 0x08 + +#define CSCFG0_OFFS 0x10 +#define CSCFG1_OFFS 0x14 +#define CSCFG2_OFFS 0x18 +#define CSCFG3_OFFS 0x1c + +#define MCFG_SDEN (1 << 4) + +#endif /* TCC8K_REGS_H */ diff --git a/arch/arm/plat-tcc/include/mach/timex.h b/arch/arm/plat-tcc/include/mach/timex.h new file mode 100644 index 000000000000..057acbe651d9 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/timex.h @@ -0,0 +1,5 @@ +/* + * A definition needed by arch core code. + * + */ +#define CLOCK_TICK_RATE (HZ * 100000UL) diff --git a/arch/arm/plat-tcc/include/mach/uncompress.h b/arch/arm/plat-tcc/include/mach/uncompress.h new file mode 100644 index 000000000000..7a3e33a27a30 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/uncompress.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de> + * + * This file is licensed under the terms of the GPL version 2. + */ + +#include <linux/serial_reg.h> +#include <linux/types.h> + +#include <mach/tcc8k-regs.h> + +unsigned int system_rev; + +#define ID_MASK 0x7fff + +static void putc(int c) +{ + u32 *uart_lsr = (u32 *)(UART_BASE_PHYS + (UART_LSR << 2)); + u32 *uart_tx = (u32 *)(UART_BASE_PHYS + (UART_TX << 2)); + + while (!(*uart_lsr & UART_LSR_THRE)) + barrier(); + *uart_tx = c; +} + +static inline void flush(void) +{ +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/arch/arm/plat-tcc/include/mach/vmalloc.h b/arch/arm/plat-tcc/include/mach/vmalloc.h new file mode 100644 index 000000000000..99414d9c2b94 --- /dev/null +++ b/arch/arm/plat-tcc/include/mach/vmalloc.h @@ -0,0 +1,10 @@ +/* + * Author: <linux@telechips.com> + * Created: June 10, 2008 + * + * Copyright (C) 2000 Russell King. + * Copyright (C) 2008-2009 Telechips + * + * Licensed under the terms of the GPL v2. + */ +#define VMALLOC_END 0xf0000000UL diff --git a/arch/arm/plat-tcc/system.c b/arch/arm/plat-tcc/system.c new file mode 100644 index 000000000000..cc208fae3e7a --- /dev/null +++ b/arch/arm/plat-tcc/system.c @@ -0,0 +1,25 @@ +/* + * System functions for Telechips TCCxxxx SoCs + * + * Copyright (C) Hans J. Koch <hjk@linutronix.de> + * + * Licensed under the terms of the GPL v2. + * + */ + +#include <linux/io.h> + +#include <mach/tcc8k-regs.h> + +/* System reboot */ +void plat_tcc_reboot(void) +{ + /* Make sure clocks are on */ + __raw_writel(0xffffffff, CKC_BASE + BCLKCTR0_OFFS); + + /* Enable watchdog reset */ + __raw_writel(0x49, TIMER_BASE + TWDCFG_OFFS); + /* Wait for reset */ + while(1) + ; +} diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index f51572772e21..9ac87255a03a 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -90,6 +90,7 @@ config PLATFORM_AT32AP select ARCH_REQUIRE_GPIOLIB select GENERIC_ALLOCATOR select HAVE_FB_ATMEL + select HAVE_NET_MACB # # CPU types diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c index 98f94d041d9c..a727f54d64d6 100644 --- a/arch/avr32/kernel/module.c +++ b/arch/avr32/kernel/module.c @@ -314,10 +314,9 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, vfree(module->arch.syminfo); module->arch.syminfo = NULL; - return module_bug_finalize(hdr, sechdrs, module); + return 0; } void module_arch_cleanup(struct module *module) { - module_bug_cleanup(module); } diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c index 0865e291c20d..db4953dc4e1b 100644 --- a/arch/h8300/kernel/module.c +++ b/arch/h8300/kernel/module.c @@ -112,10 +112,9 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - return module_bug_finalize(hdr, sechdrs, me); + return 0; } void module_arch_cleanup(struct module *mod) { - module_bug_cleanup(mod); } diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c index 8f0640847ad2..05285d08e547 100644 --- a/arch/m68k/mac/macboing.c +++ b/arch/m68k/mac/macboing.c @@ -162,7 +162,7 @@ static void mac_init_asc( void ) void mac_mksound( unsigned int freq, unsigned int length ) { __u32 cfreq = ( freq << 5 ) / 468; - __u32 flags; + unsigned long flags; int i; if ( mac_special_bell == NULL ) @@ -224,7 +224,7 @@ static void mac_nosound( unsigned long ignored ) */ static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume ) { - __u32 flags; + unsigned long flags; /* if the bell is already ringing, ring longer */ if ( mac_bell_duration > 0 ) @@ -271,7 +271,7 @@ static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsig static void mac_quadra_ring_bell( unsigned long ignored ) { int i, count = mac_asc_samplespersec / HZ; - __u32 flags; + unsigned long flags; /* * we neither want a sound buffer overflow nor underflow, so we need to match diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3ad59dde4852..5526faabfc21 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -13,6 +13,7 @@ config MIPS select HAVE_KPROBES select HAVE_KRETPROBES select RTC_LIB if !MACH_LOONGSON + select GENERIC_ATOMIC64 if !64BIT mainmenu "Linux/MIPS Kernel Configuration" @@ -1646,8 +1647,16 @@ config MIPS_MT_SMP select SYS_SUPPORTS_SMP select SMP_UP help - This is a kernel model which is also known a VSMP or lately - has been marketesed into SMVP. + This is a kernel model which is known a VSMP but lately has been + marketesed into SMVP. + Virtual SMP uses the processor's VPEs to implement virtual + processors. In currently available configuration of the 34K processor + this allows for a dual processor. Both processors will share the same + primary caches; each will obtain the half of the TLB for it's own + exclusive use. For a layman this model can be described as similar to + what Intel calls Hyperthreading. + + For further information see http://www.linux-mips.org/wiki/34K#VSMP config MIPS_MT_SMTC bool "SMTC: Use all TCs on all VPEs for SMP" @@ -1664,6 +1673,14 @@ config MIPS_MT_SMTC help This is a kernel model which is known a SMTC or lately has been marketesed into SMVP. + is presenting the available TC's of the core as processors to Linux. + On currently available 34K processors this means a Linux system will + see up to 5 processors. The implementation of the SMTC kernel differs + significantly from VSMP and cannot efficiently coexist in the same + kernel binary so the choice between VSMP and SMTC is a compile time + decision. + + For further information see http://www.linux-mips.org/wiki/34K#SMTC endchoice diff --git a/arch/mips/alchemy/common/prom.c b/arch/mips/alchemy/common/prom.c index c29511b11d44..534021059629 100644 --- a/arch/mips/alchemy/common/prom.c +++ b/arch/mips/alchemy/common/prom.c @@ -43,7 +43,7 @@ int prom_argc; char **prom_argv; char **prom_envp; -void prom_init_cmdline(void) +void __init prom_init_cmdline(void) { int i; @@ -104,7 +104,7 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) } } -int prom_get_ethernet_addr(char *ethernet_addr) +int __init prom_get_ethernet_addr(char *ethernet_addr) { char *ethaddr_str; @@ -123,7 +123,6 @@ int prom_get_ethernet_addr(char *ethernet_addr) return 0; } -EXPORT_SYMBOL(prom_get_ethernet_addr); void __init prom_free_prom_memory(void) { diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index ed9bb709c9a3..5fd7f7a58b7e 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -59,7 +59,7 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE hostprogs-y := calc_vmlinuz_load_addr VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ - $(objtree)/$(KBUILD_IMAGE) $(VMLINUX_LOAD_ADDRESS)) + $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS)) vmlinuzobjs-y += $(obj)/piggy.o diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig index 094c17e38e16..47323ca452dc 100644 --- a/arch/mips/cavium-octeon/Kconfig +++ b/arch/mips/cavium-octeon/Kconfig @@ -83,3 +83,7 @@ config ARCH_SPARSEMEM_ENABLE def_bool y select SPARSEMEM_STATIC depends on CPU_CAVIUM_OCTEON + +config CAVIUM_OCTEON_HELPER + def_bool y + depends on OCTEON_ETHERNET || PCI diff --git a/arch/mips/cavium-octeon/cpu.c b/arch/mips/cavium-octeon/cpu.c index c664c8cc2b42..a5b427909b5c 100644 --- a/arch/mips/cavium-octeon/cpu.c +++ b/arch/mips/cavium-octeon/cpu.c @@ -41,7 +41,7 @@ static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action, return NOTIFY_OK; /* Let default notifier send signals */ } -static int cnmips_cu2_setup(void) +static int __init cnmips_cu2_setup(void) { return cu2_notifier(cnmips_cu2_call, 0); } diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile index 2fd66db6939e..7f41c5be2190 100644 --- a/arch/mips/cavium-octeon/executive/Makefile +++ b/arch/mips/cavium-octeon/executive/Makefile @@ -11,4 +11,4 @@ obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o -obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-jtag.o +obj-$(CONFIG_CAVIUM_OCTEON_HELPER) += cvmx-helper-errata.o cvmx-helper-jtag.o diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index c63c56bfd184..47d87da379f9 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -782,6 +782,10 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) */ #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0) +#else /* !CONFIG_64BIT */ + +#include <asm-generic/atomic64.h> + #endif /* CONFIG_64BIT */ /* diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h index 2cb2f0c2c4f8..3532e2c5f098 100644 --- a/arch/mips/include/asm/cop2.h +++ b/arch/mips/include/asm/cop2.h @@ -24,7 +24,7 @@ extern int cu2_notifier_call_chain(unsigned long val, void *v); #define cu2_notifier(fn, pri) \ ({ \ - static struct notifier_block fn##_nb __cpuinitdata = { \ + static struct notifier_block fn##_nb = { \ .notifier_call = fn, \ .priority = pri \ }; \ diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 9b9436a4d816..86548da650e7 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h @@ -321,6 +321,7 @@ struct gic_intrmask_regs { */ struct gic_intr_map { unsigned int cpunum; /* Directed to this CPU */ +#define GIC_UNUSED 0xdead /* Dummy data */ unsigned int pin; /* Directed to this Pin */ unsigned int polarity; /* Polarity : +/- */ unsigned int trigtype; /* Trigger : Edge/Levl */ diff --git a/arch/mips/include/asm/mach-tx49xx/kmalloc.h b/arch/mips/include/asm/mach-tx49xx/kmalloc.h index b74caf65482b..ff9a8b86cb93 100644 --- a/arch/mips/include/asm/mach-tx49xx/kmalloc.h +++ b/arch/mips/include/asm/mach-tx49xx/kmalloc.h @@ -1,6 +1,6 @@ #ifndef __ASM_MACH_TX49XX_KMALLOC_H #define __ASM_MACH_TX49XX_KMALLOC_H -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES #endif /* __ASM_MACH_TX49XX_KMALLOC_H */ diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index cea872fc6f5c..d11aa02a956a 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -88,9 +88,6 @@ #define GIC_EXT_INTR(x) x -/* Dummy data */ -#define X 0xdead - /* External Interrupts used for IPI */ #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index a16beafcea91..e59cd1ac09c2 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -150,6 +150,20 @@ typedef struct { unsigned long pgprot; } pgprot_t; ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) #endif #define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET)) + +/* + * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad + * (lmo) rsp. 8431fd094d625b94d364fe393076ccef88e6ce18 (kernel.org). The + * discussion can be found in lkml posting + * <a2ebde260608230500o3407b108hc03debb9da6e62c@mail.gmail.com> which is + * archived at http://lists.linuxcoding.com/kernel/2006-q3/msg17360.html + * + * It is unclear if the misscompilations mentioned in + * http://lkml.org/lkml/2010/8/8/138 also affect MIPS so we keep this one + * until GCC 3.x has been retired before we can apply + * https://patchwork.linux-mips.org/patch/1541/ + */ + #define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0)) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) diff --git a/arch/mips/include/asm/siginfo.h b/arch/mips/include/asm/siginfo.h index 96e28f18dad1..1ca64b4d33d9 100644 --- a/arch/mips/include/asm/siginfo.h +++ b/arch/mips/include/asm/siginfo.h @@ -88,6 +88,7 @@ typedef struct siginfo { #ifdef __ARCH_SI_TRAPNO int _trapno; /* TRAP # which caused the signal */ #endif + short _addr_lsb; } _sigfault; /* SIGPOLL, SIGXFSZ (To do ...) */ diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 2376f2e06e47..70df9c0d3c5b 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -146,7 +146,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) /* work to do on interrupt/exception return */ -#define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP) +#define _TIF_WORK_MASK (0x0000ffef & \ + ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT)) /* work to do on any return to u-space */ #define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP) diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index baa318a59c97..550725b881d5 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h @@ -356,16 +356,19 @@ #define __NR_perf_event_open (__NR_Linux + 333) #define __NR_accept4 (__NR_Linux + 334) #define __NR_recvmmsg (__NR_Linux + 335) +#define __NR_fanotify_init (__NR_Linux + 336) +#define __NR_fanotify_mark (__NR_Linux + 337) +#define __NR_prlimit64 (__NR_Linux + 338) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 335 +#define __NR_Linux_syscalls 338 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 335 +#define __NR_O32_Linux_syscalls 338 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -668,16 +671,19 @@ #define __NR_perf_event_open (__NR_Linux + 292) #define __NR_accept4 (__NR_Linux + 293) #define __NR_recvmmsg (__NR_Linux + 294) +#define __NR_fanotify_init (__NR_Linux + 295) +#define __NR_fanotify_mark (__NR_Linux + 296) +#define __NR_prlimit64 (__NR_Linux + 297) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 294 +#define __NR_Linux_syscalls 297 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 294 +#define __NR_64_Linux_syscalls 297 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -985,16 +991,19 @@ #define __NR_accept4 (__NR_Linux + 297) #define __NR_recvmmsg (__NR_Linux + 298) #define __NR_getdents64 (__NR_Linux + 299) +#define __NR_fanotify_init (__NR_Linux + 300) +#define __NR_fanotify_mark (__NR_Linux + 301) +#define __NR_prlimit64 (__NR_Linux + 302) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 299 +#define __NR_Linux_syscalls 302 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 299 +#define __NR_N32_Linux_syscalls 302 #ifdef __KERNEL__ diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index b181f2f0ea8e..82ba9f62f49e 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c @@ -7,7 +7,6 @@ #include <asm/io.h> #include <asm/gic.h> #include <asm/gcmpregs.h> -#include <asm/mips-boards/maltaint.h> #include <asm/irq.h> #include <linux/hardirq.h> #include <asm-generic/bitops/find.h> @@ -131,7 +130,7 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) int i; irq -= _irqbase; - pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq); + pr_debug("%s(%d) called\n", __func__, irq); cpumask_and(&tmp, cpumask, cpu_online_mask); if (cpus_empty(tmp)) return -1; @@ -222,7 +221,7 @@ static void __init gic_basic_init(int numintrs, int numvpes, /* Setup specifics */ for (i = 0; i < mapsize; i++) { cpu = intrmap[i].cpunum; - if (cpu == X) + if (cpu == GIC_UNUSED) continue; if (cpu == 0 && i != 0 && intrmap[i].flags == 0) continue; diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 1f4e2fa64140..f4546e97c60d 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -283,7 +283,7 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, struct pt_regs *regs = args->regs; int trap = (regs->cp0_cause & 0x7c) >> 2; - /* Userpace events, ignore. */ + /* Userspace events, ignore. */ if (user_mode(regs)) return NOTIFY_DONE; diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 80e2ba694bab..29811f043399 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -251,7 +251,7 @@ void sp_work_handle_request(void) memset(&tz, 0, sizeof(tz)); if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, (int)&tz, 0, 0)) == 0) - ret.retval = tv.tv_sec; + ret.retval = tv.tv_sec; break; case MTSP_SYSCALL_EXIT: diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index c2dab140dc98..6343b4a5b835 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -341,3 +341,10 @@ asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf, { return sys_lookup_dcookie(merge_64(a0, a1), buf, len); } + +SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags, + u64, a3, u64, a4, int, dfd, const char __user *, pathname) +{ + return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4), + dfd, pathname); +} diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 17202bbe843f..584415eef8c9 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -583,7 +583,10 @@ einval: li v0, -ENOSYS sys sys_rt_tgsigqueueinfo 4 sys sys_perf_event_open 5 sys sys_accept4 4 - sys sys_recvmmsg 5 + sys sys_recvmmsg 5 /* 4335 */ + sys sys_fanotify_init 2 + sys sys_fanotify_mark 6 + sys sys_prlimit64 4 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index a8a6c596eb04..5573f8e4e326 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -416,9 +416,12 @@ sys_call_table: PTR sys_pipe2 PTR sys_inotify_init1 PTR sys_preadv - PTR sys_pwritev /* 5390 */ + PTR sys_pwritev /* 5290 */ PTR sys_rt_tgsigqueueinfo PTR sys_perf_event_open PTR sys_accept4 - PTR sys_recvmmsg + PTR sys_recvmmsg + PTR sys_fanotify_init /* 5295 */ + PTR sys_fanotify_mark + PTR sys_prlimit64 .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index a3d66137731a..1e38ec97672e 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -419,5 +419,8 @@ EXPORT(sysn32_call_table) PTR sys_perf_event_open PTR sys_accept4 PTR compat_sys_recvmmsg - PTR sys_getdents + PTR sys_getdents64 + PTR sys_fanotify_init /* 6300 */ + PTR sys_fanotify_mark + PTR sys_prlimit64 .size sysn32_call_table,.-sysn32_call_table diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 813689ef2384..171979fc98e5 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -538,5 +538,8 @@ sys_call_table: PTR compat_sys_rt_tgsigqueueinfo PTR sys_perf_event_open PTR sys_accept4 - PTR compat_sys_recvmmsg + PTR compat_sys_recvmmsg /* 4335 */ + PTR sys_fanotify_init + PTR sys_32_fanotify_mark + PTR sys_prlimit64 .size sys_call_table,.-sys_call_table diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 7ba890860d98..469d4019f795 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -44,27 +44,39 @@ static inline int cpu_is_noncoherent_r10000(struct device *dev) static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) { + gfp_t dma_flag; + /* ignore region specifiers */ gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM); -#ifdef CONFIG_ZONE_DMA +#ifdef CONFIG_ISA if (dev == NULL) - gfp |= __GFP_DMA; - else if (dev->coherent_dma_mask < DMA_BIT_MASK(24)) - gfp |= __GFP_DMA; + dma_flag = __GFP_DMA; else #endif -#ifdef CONFIG_ZONE_DMA32 +#if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA) if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) - gfp |= __GFP_DMA32; + dma_flag = __GFP_DMA; + else if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) + dma_flag = __GFP_DMA32; + else +#endif +#if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA) + if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) + dma_flag = __GFP_DMA32; + else +#endif +#if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32) + if (dev->coherent_dma_mask < DMA_BIT_MASK(64)) + dma_flag = __GFP_DMA; else #endif - ; + dma_flag = 0; /* Don't invoke OOM killer */ gfp |= __GFP_NORETRY; - return gfp; + return gfp | dma_flag; } void *dma_alloc_noncoherent(struct device *dev, size_t size, diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c index 1ef75cd80a0d..274af3be1442 100644 --- a/arch/mips/mm/sc-rm7k.c +++ b/arch/mips/mm/sc-rm7k.c @@ -30,7 +30,7 @@ #define tc_lsize 32 extern unsigned long icache_way_size, dcache_way_size; -unsigned long tcache_size; +static unsigned long tcache_size; #include <asm/r4kcache.h> diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index 15949b0be811..b79b24afe3a2 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -385,6 +385,8 @@ static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap); */ #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK +#define X GIC_UNUSED + static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { { X, X, X, X, 0 }, { X, X, X, X, 0 }, @@ -404,6 +406,7 @@ static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { { X, X, X, X, 0 }, /* The remainder of this table is initialised by fill_ipi_map */ }; +#undef X /* * GCMP needs to be detected before any SMP initialisation diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c index 71f7d27b0d4c..f31218e17d3c 100644 --- a/arch/mips/pci/pci-rc32434.c +++ b/arch/mips/pci/pci-rc32434.c @@ -118,7 +118,7 @@ static int __init rc32434_pcibridge_init(void) if (!((pcicvalue == PCIM_H_EA) || (pcicvalue == PCIM_H_IA_FIX) || (pcicvalue == PCIM_H_IA_RR))) { - pr_err(KERN_ERR "PCI init error!!!\n"); + pr_err("PCI init error!!!\n"); /* Not in Host Mode, return ERROR */ return -1; } diff --git a/arch/mips/pnx8550/common/reset.c b/arch/mips/pnx8550/common/reset.c index fadd8744a6bc..e7a12ff304b9 100644 --- a/arch/mips/pnx8550/common/reset.c +++ b/arch/mips/pnx8550/common/reset.c @@ -22,29 +22,19 @@ */ #include <linux/kernel.h> +#include <asm/processor.h> #include <asm/reboot.h> #include <glb.h> void pnx8550_machine_restart(char *command) { - char head[] = "************* Machine restart *************"; - char foot[] = "*******************************************"; - - printk("\n\n"); - printk("%s\n", head); - if (command != NULL) - printk("* %s\n", command); - printk("%s\n", foot); - PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST; } void pnx8550_machine_halt(void) { - printk("*** Machine halt. (Not implemented) ***\n"); -} - -void pnx8550_machine_power_off(void) -{ - printk("*** Machine power off. (Not implemented) ***\n"); + while (1) { + if (cpu_wait) + cpu_wait(); + } } diff --git a/arch/mips/pnx8550/common/setup.c b/arch/mips/pnx8550/common/setup.c index 64246c9c875c..43cb3945fdbf 100644 --- a/arch/mips/pnx8550/common/setup.c +++ b/arch/mips/pnx8550/common/setup.c @@ -44,7 +44,6 @@ extern void __init board_setup(void); extern void pnx8550_machine_restart(char *); extern void pnx8550_machine_halt(void); -extern void pnx8550_machine_power_off(void); extern struct resource ioport_resource; extern struct resource iomem_resource; extern char *prom_getcmdline(void); @@ -100,7 +99,7 @@ void __init plat_mem_setup(void) _machine_restart = pnx8550_machine_restart; _machine_halt = pnx8550_machine_halt; - pm_power_off = pnx8550_machine_power_off; + pm_power_off = pnx8550_machine_halt; /* Clear the Global 2 Register, PCI Inta Output Enable Registers Bit 1:Enable DAC Powerdown diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c index 6aea7fd76993..196a111e2e29 100644 --- a/arch/mn10300/kernel/module.c +++ b/arch/mn10300/kernel/module.c @@ -206,7 +206,7 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - return module_bug_finalize(hdr, sechdrs, me); + return 0; } /* @@ -214,5 +214,4 @@ int module_finalize(const Elf_Ehdr *hdr, */ void module_arch_cleanup(struct module *mod) { - module_bug_cleanup(mod); } diff --git a/arch/mn10300/mm/cache.c b/arch/mn10300/mm/cache.c index 1b76719ec1c3..9261217e8d2c 100644 --- a/arch/mn10300/mm/cache.c +++ b/arch/mn10300/mm/cache.c @@ -54,13 +54,30 @@ EXPORT_SYMBOL(flush_icache_page); void flush_icache_range(unsigned long start, unsigned long end) { #ifdef CONFIG_MN10300_CACHE_WBACK - unsigned long addr, size, off; + unsigned long addr, size, base, off; struct page *page; pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *ppte, pte; + if (end > 0x80000000UL) { + /* addresses above 0xa0000000 do not go through the cache */ + if (end > 0xa0000000UL) { + end = 0xa0000000UL; + if (start >= end) + return; + } + + /* kernel addresses between 0x80000000 and 0x9fffffff do not + * require page tables, so we just map such addresses directly */ + base = (start >= 0x80000000UL) ? start : 0x80000000UL; + mn10300_dcache_flush_range(base, end); + if (base == start) + goto invalidate; + end = base; + } + for (; start < end; start += size) { /* work out how much of the page to flush */ off = start & (PAGE_SIZE - 1); @@ -104,6 +121,7 @@ void flush_icache_range(unsigned long start, unsigned long end) } #endif +invalidate: mn10300_icache_inv(); } EXPORT_SYMBOL(flush_icache_range); diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 159a2b81e90c..6e81bb596e5b 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -941,11 +941,10 @@ int module_finalize(const Elf_Ehdr *hdr, nsyms = newptr - (Elf_Sym *)symhdr->sh_addr; DEBUGP("NEW num_symtab %lu\n", nsyms); symhdr->sh_size = nsyms * sizeof(Elf_Sym); - return module_bug_finalize(hdr, sechdrs, me); + return 0; } void module_arch_cleanup(struct module *mod) { deregister_unwind_table(mod); - module_bug_cleanup(mod); } diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 477c663e0140..49cee9df225b 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -63,11 +63,6 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { const Elf_Shdr *sect; - int err; - - err = module_bug_finalize(hdr, sechdrs, me); - if (err) - return err; /* Apply feature fixups */ sect = find_section(hdr, sechdrs, "__ftr_fixup"); @@ -101,5 +96,4 @@ int module_finalize(const Elf_Ehdr *hdr, void module_arch_cleanup(struct module *mod) { - module_bug_cleanup(mod); } diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 5b243bd3eb3b..3dc2a8d262b8 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c @@ -57,7 +57,7 @@ static struct clk *mpc5121_clk_get(struct device *dev, const char *id) int id_match = 0; if (dev == NULL || id == NULL) - return NULL; + return clk; mutex_lock(&clocks_mutex); list_for_each_entry(p, &clocks, node) { diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 45c0cb9b67e6..18c104820198 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -99,7 +99,7 @@ static void __init efika_pcisetup(void) if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING EFIKA_PLATFORM_NAME ": Can't get bus-range for %s\n", pcictrl->full_name); - return; + goto out_put; } if (bus_range[1] == bus_range[0]) @@ -111,12 +111,12 @@ static void __init efika_pcisetup(void) printk(" controlled by %s\n", pcictrl->full_name); printk("\n"); - hose = pcibios_alloc_controller(of_node_get(pcictrl)); + hose = pcibios_alloc_controller(pcictrl); if (!hose) { printk(KERN_WARNING EFIKA_PLATFORM_NAME ": Can't allocate PCI controller structure for %s\n", pcictrl->full_name); - return; + goto out_put; } hose->first_busno = bus_range[0]; @@ -124,6 +124,9 @@ static void __init efika_pcisetup(void) hose->ops = &rtas_pci_ops; pci_process_bridge_OF_ranges(hose, pcictrl, 0); + return; +out_put: + of_node_put(pcictrl); } #else diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 6e905314ad5d..41f3a7eda1de 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -325,12 +325,16 @@ int mpc5200_psc_ac97_gpio_reset(int psc_number) clrbits32(&simple_gpio->simple_dvo, sync | out); clrbits8(&wkup_gpio->wkup_dvo, reset); - /* wait at lease 1 us */ - udelay(2); + /* wait for 1 us */ + udelay(1); /* Deassert reset */ setbits8(&wkup_gpio->wkup_dvo, reset); + /* wait at least 200ns */ + /* 7 ~= (200ns * timebase) / ns2sec */ + __delay(7); + /* Restore pin-muxing */ out_be32(&simple_gpio->port_config, mux); diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 22cfd634c355..f7167ee4604c 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -407,10 +407,9 @@ int module_finalize(const Elf_Ehdr *hdr, { vfree(me->arch.syminfo); me->arch.syminfo = NULL; - return module_bug_finalize(hdr, sechdrs, me); + return 0; } void module_arch_cleanup(struct module *mod) { - module_bug_cleanup(mod); } diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c index 43adddfe4c04..ae0be697a89e 100644 --- a/arch/sh/kernel/module.c +++ b/arch/sh/kernel/module.c @@ -149,13 +149,11 @@ int module_finalize(const Elf_Ehdr *hdr, int ret = 0; ret |= module_dwarf_finalize(hdr, sechdrs, me); - ret |= module_bug_finalize(hdr, sechdrs, me); return ret; } void module_arch_cleanup(struct module *mod) { - module_bug_cleanup(mod); module_dwarf_cleanup(mod); } diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 2ab233ba32c1..47d0c37897d5 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -255,18 +255,6 @@ static void uml_net_tx_timeout(struct net_device *dev) netif_wake_queue(dev); } -static int uml_net_set_mac(struct net_device *dev, void *addr) -{ - struct uml_net_private *lp = netdev_priv(dev); - struct sockaddr *hwaddr = addr; - - spin_lock_irq(&lp->lock); - eth_mac_addr(dev, hwaddr->sa_data); - spin_unlock_irq(&lp->lock); - - return 0; -} - static int uml_net_change_mtu(struct net_device *dev, int new_mtu) { dev->mtu = new_mtu; @@ -373,7 +361,7 @@ static const struct net_device_ops uml_netdev_ops = { .ndo_start_xmit = uml_net_start_xmit, .ndo_set_multicast_list = uml_net_set_multicast_list, .ndo_tx_timeout = uml_net_tx_timeout, - .ndo_set_mac_address = uml_net_set_mac, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = uml_net_change_mtu, .ndo_validate_addr = eth_validate_addr, }; @@ -472,7 +460,8 @@ static void eth_configure(int n, void *init, char *mac, ((*transport->user->init)(&lp->user, dev) != 0)) goto out_unregister; - eth_mac_addr(dev, device->mac); + /* don't use eth_mac_addr, it will not work here */ + memcpy(dev->dev_addr, device->mac, ETH_ALEN); dev->mtu = transport->user->mtu; dev->netdev_ops = ¨_netdev_ops; dev->ethtool_ops = ¨_net_ethtool_ops; diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 0350311906ae..2d93bdbc9ac0 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -34,7 +34,7 @@ #include <asm/ia32.h> #undef WARN_OLD -#undef CORE_DUMP /* probably broken */ +#undef CORE_DUMP /* definitely broken */ static int load_aout_binary(struct linux_binprm *, struct pt_regs *regs); static int load_aout_library(struct file *); @@ -131,21 +131,15 @@ static void set_brk(unsigned long start, unsigned long end) * macros to write out all the necessary info. */ -static int dump_write(struct file *file, const void *addr, int nr) -{ - return file->f_op->write(file, addr, nr, &file->f_pos) == nr; -} +#include <linux/coredump.h> #define DUMP_WRITE(addr, nr) \ if (!dump_write(file, (void *)(addr), (nr))) \ goto end_coredump; -#define DUMP_SEEK(offset) \ - if (file->f_op->llseek) { \ - if (file->f_op->llseek(file, (offset), 0) != (offset)) \ - goto end_coredump; \ - } else \ - file->f_pos = (offset) +#define DUMP_SEEK(offset) \ + if (!dump_seek(file, offset)) \ + goto end_coredump; #define START_DATA() (u.u_tsize << PAGE_SHIFT) #define START_STACK(u) (u.start_stack) @@ -217,12 +211,6 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, dump_size = dump.u_ssize << PAGE_SHIFT; DUMP_WRITE(dump_start, dump_size); } - /* - * Finally dump the task struct. Not be used by gdb, but - * could be useful - */ - set_fs(KERNEL_DS); - DUMP_WRITE(current, sizeof(*current)); end_coredump: set_fs(fs); return has_dumped; diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index fb7a5f052e2b..fb16f17e59be 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -61,7 +61,7 @@ struct cstate_entry { unsigned int ecx; } states[ACPI_PROCESSOR_MAX_POWER]; }; -static struct cstate_entry *cpu_cstate_entry; /* per CPU ptr */ +static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index f1efebaf5510..5c5b8f3dddb5 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -306,14 +306,19 @@ void arch_init_copy_chip_data(struct irq_desc *old_desc, old_cfg = old_desc->chip_data; - memcpy(cfg, old_cfg, sizeof(struct irq_cfg)); + cfg->vector = old_cfg->vector; + cfg->move_in_progress = old_cfg->move_in_progress; + cpumask_copy(cfg->domain, old_cfg->domain); + cpumask_copy(cfg->old_domain, old_cfg->old_domain); init_copy_irq_2_pin(old_cfg, cfg, node); } -static void free_irq_cfg(struct irq_cfg *old_cfg) +static void free_irq_cfg(struct irq_cfg *cfg) { - kfree(old_cfg); + free_cpumask_var(cfg->domain); + free_cpumask_var(cfg->old_domain); + kfree(cfg); } void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 490dac63c2d2..f2f9ac7da25c 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -545,7 +545,7 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c) } } -static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) +void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c) { u32 tfms, xlvl; u32 ebx; diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 3624e8a0f71b..f668bb1f7d43 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -33,5 +33,6 @@ extern const struct cpu_dev *const __x86_cpu_dev_start[], *const __x86_cpu_dev_end[]; extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); +extern void get_cpu_cap(struct cpuinfo_x86 *c); #endif diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c index 994230d4dc4e..4f6f679f2799 100644 --- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c @@ -368,16 +368,22 @@ static int __init pcc_cpufreq_do_osc(acpi_handle *handle) return -ENODEV; out_obj = output.pointer; - if (out_obj->type != ACPI_TYPE_BUFFER) - return -ENODEV; + if (out_obj->type != ACPI_TYPE_BUFFER) { + ret = -ENODEV; + goto out_free; + } errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); - if (errors) - return -ENODEV; + if (errors) { + ret = -ENODEV; + goto out_free; + } supported = *((u32 *)(out_obj->buffer.pointer + 4)); - if (!(supported & 0x1)) - return -ENODEV; + if (!(supported & 0x1)) { + ret = -ENODEV; + goto out_free; + } out_free: kfree(output.pointer); diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 85f69cdeae10..b4389441efbb 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -39,6 +39,7 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); c->cpuid_level = cpuid_eax(0); + get_cpu_cap(c); } } diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 5e975298fa81..39aaee5c1ab2 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -141,6 +141,7 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) address = (low & MASK_BLKPTR_LO) >> 21; if (!address) break; + address += MCG_XBLK_ADDR; } else ++address; @@ -148,12 +149,8 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) if (rdmsr_safe(address, &low, &high)) break; - if (!(high & MASK_VALID_HI)) { - if (block) - continue; - else - break; - } + if (!(high & MASK_VALID_HI)) + continue; if (!(high & MASK_CNTP_HI) || (high & MASK_LOCKED_HI)) diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index d9368eeda309..169d8804a9f8 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -216,7 +216,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev, err = sysfs_add_file_to_group(&sys_dev->kobj, &attr_core_power_limit_count.attr, thermal_attr_group.name); - if (cpu_has(c, X86_FEATURE_PTS)) + if (cpu_has(c, X86_FEATURE_PTS)) { err = sysfs_add_file_to_group(&sys_dev->kobj, &attr_package_throttle_count.attr, thermal_attr_group.name); @@ -224,6 +224,7 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev, err = sysfs_add_file_to_group(&sys_dev->kobj, &attr_package_power_limit_count.attr, thermal_attr_group.name); + } return err; } diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index b560db3305be..249015173992 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c @@ -660,8 +660,12 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) for (idx = 0; idx < x86_pmu.num_counters; idx++) { int overflow; - if (!test_bit(idx, cpuc->active_mask)) + if (!test_bit(idx, cpuc->active_mask)) { + /* catch in-flight IRQs */ + if (__test_and_clear_bit(idx, cpuc->running)) + handled++; continue; + } event = cpuc->events[idx]; hwc = &event->hw; diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 410fdb3f1939..7494999141b3 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -506,7 +506,7 @@ static int hpet_assign_irq(struct hpet_dev *dev) { unsigned int irq; - irq = create_irq(); + irq = create_irq_nr(0, -1); if (!irq) return -EINVAL; diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index e0bc186d7501..1c355c550960 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -239,11 +239,10 @@ int module_finalize(const Elf_Ehdr *hdr, apply_paravirt(pseg, pseg + para->sh_size); } - return module_bug_finalize(hdr, sechdrs, me); + return 0; } void module_arch_cleanup(struct module *mod) { alternatives_smp_module_del(mod); - module_bug_cleanup(mod); } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index bc5b9b8d4a33..81ed28cb36e6 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -766,7 +766,6 @@ static void init_vmcb(struct vcpu_svm *svm) control->iopm_base_pa = iopm_base; control->msrpm_base_pa = __pa(svm->msrpm); - control->tsc_offset = 0; control->int_ctl = V_INTR_MASKING_MASK; init_seg(&save->es); @@ -902,6 +901,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; svm->asid_generation = 0; init_vmcb(svm); + svm->vmcb->control.tsc_offset = 0-native_read_tsc(); err = fx_init(&svm->vcpu); if (err) diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index f9897f7a9ef1..9c0d0d399c30 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -420,9 +420,11 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) return -1; } - for_each_node_mask(i, nodes_parsed) - e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, - nodes[i].end >> PAGE_SHIFT); + for (i = 0; i < num_node_memblks; i++) + e820_register_active_regions(memblk_nodeid[i], + node_memblk_range[i].start >> PAGE_SHIFT, + node_memblk_range[i].end >> PAGE_SHIFT); + /* for out of order entries in SRAT */ sort_node_map(); if (!nodes_cover_memory(nodes)) { diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 009b819f48d0..f1575c9a2572 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -674,6 +674,7 @@ static int __init ppro_init(char **cpu_type) case 0x0f: case 0x16: case 0x17: + case 0x1d: *cpu_type = "i386/core_2"; break; case 0x1a: diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 1a5353a753fc..b2bb5aa3b054 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -489,8 +489,9 @@ static void xen_hvm_setup_cpu_clockevents(void) __init void xen_hvm_init_time_ops(void) { /* vector callback is needed otherwise we cannot receive interrupts - * on cpu > 0 */ - if (!xen_have_vector_callback && num_present_cpus() > 1) + * on cpu > 0 and at this point we don't know how many cpus are + * available */ + if (!xen_have_vector_callback) return; if (!xen_feature(XENFEAT_hvm_safe_pvclock)) { printk(KERN_INFO "Xen doesn't support pvclock on HVM," diff --git a/block/elevator.c b/block/elevator.c index 205b09a5bd9e..4e11559aa2b0 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -938,6 +938,7 @@ int elv_register_queue(struct request_queue *q) } } kobject_uevent(&e->kobj, KOBJ_ADD); + e->registered = 1; } return error; } @@ -947,6 +948,7 @@ static void __elv_unregister_queue(struct elevator_queue *e) { kobject_uevent(&e->kobj, KOBJ_REMOVE); kobject_del(&e->kobj); + e->registered = 0; } void elv_unregister_queue(struct request_queue *q) @@ -1042,11 +1044,13 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) spin_unlock_irq(q->queue_lock); - __elv_unregister_queue(old_elevator); + if (old_elevator->registered) { + __elv_unregister_queue(old_elevator); - err = elv_register_queue(q); - if (err) - goto fail_register; + err = elv_register_queue(q); + if (err) + goto fail_register; + } /* * finally exit old elevator and turn off BYPASS. diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b811f2173f6f..88681aca88c5 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -105,7 +105,7 @@ config ACPI_EC_DEBUGFS Be aware that using this interface can confuse your Embedded Controller in a way that a normal reboot is not enough. You then - have to power of your system, and remove the laptop battery for + have to power off your system, and remove the laptop battery for some seconds. An Embedded Controller typically is available on laptops and reads sensor values like battery state and temperature. diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index b76848c80be3..6b115f6c4313 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -382,31 +382,32 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device) device_remove_file(&device->dev, &dev_attr_rrtime); } -/* Query firmware how many CPUs should be idle */ -static int acpi_pad_pur(acpi_handle handle, int *num_cpus) +/* + * Query firmware how many CPUs should be idle + * return -1 on failure + */ +static int acpi_pad_pur(acpi_handle handle) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; union acpi_object *package; - int rev, num, ret = -EINVAL; + int num = -1; if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) - return -EINVAL; + return num; if (!buffer.length || !buffer.pointer) - return -EINVAL; + return num; package = buffer.pointer; - if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2) - goto out; - rev = package->package.elements[0].integer.value; - num = package->package.elements[1].integer.value; - if (rev != 1 || num < 0) - goto out; - *num_cpus = num; - ret = 0; -out: + + if (package->type == ACPI_TYPE_PACKAGE && + package->package.count == 2 && + package->package.elements[0].integer.value == 1) /* rev 1 */ + + num = package->package.elements[1].integer.value; + kfree(buffer.pointer); - return ret; + return num; } /* Notify firmware how many CPUs are idle */ @@ -433,7 +434,8 @@ static void acpi_pad_handle_notify(acpi_handle handle) uint32_t idle_cpus; mutex_lock(&isolated_cpus_lock); - if (acpi_pad_pur(handle, &num_cpus)) { + num_cpus = acpi_pad_pur(handle); + if (num_cpus < 0) { mutex_unlock(&isolated_cpus_lock); return; } diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index df85b53a674f..7dad9160f209 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -854,6 +854,7 @@ struct acpi_bit_register_info { ACPI_BITMASK_POWER_BUTTON_STATUS | \ ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ ACPI_BITMASK_RT_CLOCK_STATUS | \ + ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \ ACPI_BITMASK_WAKE_STATUS) #define ACPI_BITMASK_TIMER_ENABLE 0x0001 diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 74c24d517f81..4093522eed45 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -109,7 +109,7 @@ void acpi_ex_enter_interpreter(void) * * DESCRIPTION: Reacquire the interpreter execution region from within the * interpreter code. Failure to enter the interpreter region is a - * fatal system error. Used in conjuction with + * fatal system error. Used in conjunction with * relinquish_interpreter * ******************************************************************************/ diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 22cfcfbd9fff..491191e6cf69 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c @@ -149,7 +149,7 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) /* * 16-, 32-, and 64-bit cases must use the move macros that perform - * endian conversion and/or accomodate hardware that cannot perform + * endian conversion and/or accommodate hardware that cannot perform * misaligned memory transfers */ case ACPI_RSC_MOVE16: diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 907e350f1c7d..fca34ccfd294 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -34,6 +34,6 @@ config ACPI_APEI_ERST_DEBUG depends on ACPI_APEI help ERST is a way provided by APEI to save and retrieve hardware - error infomation to and from a persistent store. Enable this + error information to and from a persistent store. Enable this if you want to debugging and testing the ERST kernel support and firmware implementation. diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 73fd0c7487c1..4a904a4bf05f 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -445,11 +445,15 @@ EXPORT_SYMBOL_GPL(apei_resources_sub); int apei_resources_request(struct apei_resources *resources, const char *desc) { - struct apei_res *res, *res_bak; + struct apei_res *res, *res_bak = NULL; struct resource *r; + int rc; - apei_resources_sub(resources, &apei_resources_all); + rc = apei_resources_sub(resources, &apei_resources_all); + if (rc) + return rc; + rc = -EINVAL; list_for_each_entry(res, &resources->iomem, list) { r = request_mem_region(res->start, res->end - res->start, desc); @@ -475,7 +479,11 @@ int apei_resources_request(struct apei_resources *resources, } } - apei_resources_merge(&apei_resources_all, resources); + rc = apei_resources_merge(&apei_resources_all, resources); + if (rc) { + pr_err(APEI_PFX "Fail to merge resources!\n"); + goto err_unmap_ioport; + } return 0; err_unmap_ioport: @@ -491,12 +499,13 @@ err_unmap_iomem: break; release_mem_region(res->start, res->end - res->start); } - return -EINVAL; + return rc; } EXPORT_SYMBOL_GPL(apei_resources_request); void apei_resources_release(struct apei_resources *resources) { + int rc; struct apei_res *res; list_for_each_entry(res, &resources->iomem, list) @@ -504,7 +513,9 @@ void apei_resources_release(struct apei_resources *resources) list_for_each_entry(res, &resources->ioport, list) release_region(res->start, res->end - res->start); - apei_resources_sub(&apei_resources_all, resources); + rc = apei_resources_sub(&apei_resources_all, resources); + if (rc) + pr_err(APEI_PFX "Fail to sub resources!\n"); } EXPORT_SYMBOL_GPL(apei_resources_release); diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 465c885938ee..cf29df69380b 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -426,7 +426,9 @@ DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, static int einj_check_table(struct acpi_table_einj *einj_tab) { - if (einj_tab->header_length != sizeof(struct acpi_table_einj)) + if ((einj_tab->header_length != + (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header))) + && (einj_tab->header_length != sizeof(struct acpi_table_einj))) return -EINVAL; if (einj_tab->header.length < sizeof(struct acpi_table_einj)) return -EINVAL; diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 5281ddda2777..da1228a9a544 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c @@ -2,7 +2,7 @@ * APEI Error Record Serialization Table debug support * * ERST is a way provided by APEI to save and retrieve hardware error - * infomation to and from a persistent store. This file provide the + * information to and from a persistent store. This file provide the * debugging/testing support for ERST kernel support and firmware * implementation. * @@ -111,11 +111,13 @@ retry: goto out; } if (len > erst_dbg_buf_len) { - kfree(erst_dbg_buf); + void *p; rc = -ENOMEM; - erst_dbg_buf = kmalloc(len, GFP_KERNEL); - if (!erst_dbg_buf) + p = kmalloc(len, GFP_KERNEL); + if (!p) goto out; + kfree(erst_dbg_buf); + erst_dbg_buf = p; erst_dbg_buf_len = len; goto retry; } @@ -150,11 +152,13 @@ static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf, if (mutex_lock_interruptible(&erst_dbg_mutex)) return -EINTR; if (usize > erst_dbg_buf_len) { - kfree(erst_dbg_buf); + void *p; rc = -ENOMEM; - erst_dbg_buf = kmalloc(usize, GFP_KERNEL); - if (!erst_dbg_buf) + p = kmalloc(usize, GFP_KERNEL); + if (!p) goto out; + kfree(erst_dbg_buf); + erst_dbg_buf = p; erst_dbg_buf_len = usize; } rc = copy_from_user(erst_dbg_buf, ubuf, usize); diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 18645f4e83cd..1211c03149e8 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -2,7 +2,7 @@ * APEI Error Record Serialization Table support * * ERST is a way provided by APEI to save and retrieve hardware error - * infomation to and from a persistent store. + * information to and from a persistent store. * * For more information about ERST, please refer to ACPI Specification * version 4.0, section 17.4. @@ -266,13 +266,30 @@ static int erst_exec_move_data(struct apei_exec_context *ctx, { int rc; u64 offset; + void *src, *dst; + + /* ioremap does not work in interrupt context */ + if (in_interrupt()) { + pr_warning(ERST_PFX + "MOVE_DATA can not be used in interrupt context"); + return -EBUSY; + } rc = __apei_exec_read_register(entry, &offset); if (rc) return rc; - memmove((void *)ctx->dst_base + offset, - (void *)ctx->src_base + offset, - ctx->var2); + + src = ioremap(ctx->src_base + offset, ctx->var2); + if (!src) + return -ENOMEM; + dst = ioremap(ctx->dst_base + offset, ctx->var2); + if (!dst) + return -ENOMEM; + + memmove(dst, src, ctx->var2); + + iounmap(src); + iounmap(dst); return 0; } @@ -750,7 +767,9 @@ __setup("erst_disable", setup_erst_disable); static int erst_check_table(struct acpi_table_erst *erst_tab) { - if (erst_tab->header_length != sizeof(struct acpi_table_erst)) + if ((erst_tab->header_length != + (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) + && (erst_tab->header_length != sizeof(struct acpi_table_einj))) return -EINVAL; if (erst_tab->header.length < sizeof(struct acpi_table_erst)) return -EINVAL; diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 385a6059714a..0d505e59214d 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -302,7 +302,7 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) struct ghes *ghes = NULL; int rc = -EINVAL; - generic = ghes_dev->dev.platform_data; + generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; if (!generic->enabled) return -ENODEV; diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 343168d18266..1a3508a7fe03 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -137,20 +137,23 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) { - struct acpi_hest_generic *generic; struct platform_device *ghes_dev; struct ghes_arr *ghes_arr = data; int rc; if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) return 0; - generic = (struct acpi_hest_generic *)hest_hdr; - if (!generic->enabled) + + if (!((struct acpi_hest_generic *)hest_hdr)->enabled) return 0; ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); if (!ghes_dev) return -ENOMEM; - ghes_dev->dev.platform_data = generic; + + rc = platform_device_add_data(ghes_dev, &hest_hdr, sizeof(void *)); + if (rc) + goto err; + rc = platform_device_add(ghes_dev); if (rc) goto err; diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 8f8bd736d4ff..542e53903891 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c @@ -142,7 +142,7 @@ static void __iomem *acpi_pre_map(phys_addr_t paddr, list_add_tail_rcu(&map->list, &acpi_iomaps); spin_unlock_irqrestore(&acpi_iomaps_lock, flags); - return vaddr + (paddr - pg_off); + return map->vaddr + (paddr - map->paddr); err_unmap: iounmap(vaddr); return NULL; diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index dc58402b0a17..98417201e9ce 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -273,7 +273,6 @@ static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_CYCLE_COUNT, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, POWER_SUPPLY_PROP_ENERGY_FULL, diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2bb28b9d91c4..af308d03f492 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -183,6 +183,8 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) { printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); acpi_osi_setup("!Windows 2006"); + acpi_osi_setup("!Windows 2006 SP1"); + acpi_osi_setup("!Windows 2006 SP2"); return 0; } static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) @@ -202,6 +204,23 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, { + /* + * There have a NVIF method in MSI GX723 DSDT need call by Nvidia + * driver (e.g. nouveau) when user press brightness hotkey. + * Currently, nouveau driver didn't do the job and it causes there + * have a infinite while loop in DSDT when user press hotkey. + * We add MSI GX723's dmi information to this table for workaround + * this issue. + * Will remove MSI GX723 from the table after nouveau grows support. + */ + .callback = dmi_disable_osi_vista, + .ident = "MSI GX723", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), + DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), + }, + }, + { .callback = dmi_disable_osi_vista, .ident = "Sony VGN-NS10J_S", .matches = { @@ -226,6 +245,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, { + .callback = dmi_disable_osi_vista, + .ident = "Toshiba Satellite L355", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), + }, + }, + { .callback = dmi_disable_osi_win7, .ident = "ASUS K50IJ", .matches = { @@ -233,6 +260,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), }, }, + { + .callback = dmi_disable_osi_vista, + .ident = "Toshiba P305D", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), + }, + }, /* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 5c221ab535d5..310e3b9749cb 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -55,7 +55,7 @@ EXPORT_SYMBOL(acpi_root_dir); static int set_power_nocheck(const struct dmi_system_id *id) { printk(KERN_NOTICE PREFIX "%s detected - " - "disable power check in power transistion\n", id->ident); + "disable power check in power transition\n", id->ident); acpi_power_nocheck = 1; return 0; } @@ -80,23 +80,15 @@ static int set_copy_dsdt(const struct dmi_system_id *id) static struct dmi_system_id dsdt_dmi_table[] __initdata = { /* - * Insyde BIOS on some TOSHIBA machines corrupt the DSDT. + * Invoke DSDT corruption work-around on all Toshiba Satellite. * https://bugzilla.kernel.org/show_bug.cgi?id=14679 */ { .callback = set_copy_dsdt, - .ident = "TOSHIBA Satellite A505", + .ident = "TOSHIBA Satellite", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"), - }, - }, - { - .callback = set_copy_dsdt, - .ident = "TOSHIBA Satellite L505D", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), }, }, {} @@ -1027,7 +1019,7 @@ static int __init acpi_init(void) /* * If the laptop falls into the DMI check table, the power state check - * will be disabled in the course of device power transistion. + * will be disabled in the course of device power transition. */ dmi_check_system(power_nocheck_dmi_table); diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 8a3b840c0bb2..d94d2953c974 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -369,7 +369,9 @@ static void __exit acpi_fan_exit(void) acpi_bus_unregister_driver(&acpi_fan_driver); +#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); +#endif return; } diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e9699aaed109..bec561c14beb 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -29,12 +29,6 @@ static int set_no_mwait(const struct dmi_system_id *id) static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { { - set_no_mwait, "IFL91 board", { - DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), - DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), - DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, - { set_no_mwait, "Extensa 5220", { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -352,4 +346,5 @@ void __init acpi_early_processor_set_pdc(void) acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, early_init_pdc, NULL, NULL, NULL); + acpi_get_devices("ACPI0007", early_init_pdc, NULL, NULL); } diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 156021892389..347eb21b2353 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -850,7 +850,7 @@ static int __init acpi_processor_init(void) printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", acpi_idle_driver.name); } else { - printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s", + printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n", cpuidle_get_driver()->name); } diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index ba1bd263d903..3a73a93596e8 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -447,8 +447,8 @@ int acpi_processor_notify_smm(struct module *calling_module) if (!try_module_get(calling_module)) return -EINVAL; - /* is_done is set to negative if an error occured, - * and to postitive if _no_ error occured, but SMM + /* is_done is set to negative if an error occurred, + * and to postitive if _no_ error occurred, but SMM * was already notified. This avoids double notification * which might lead to unexpected results... */ diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index cf82989ae756..4754ff6e70e6 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -363,6 +363,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) return 0; } +static int __init init_nvs_nosave(const struct dmi_system_id *d) +{ + acpi_nvs_nosave(); + return 0; +} + static struct dmi_system_id __initdata acpisleep_dmi_table[] = { { .callback = init_old_suspend_ordering, @@ -397,6 +403,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), }, }, + { + .callback = init_nvs_nosave, + .ident = "Sony Vaio VGN-SR11M", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"), + }, + }, + { + .callback = init_nvs_nosave, + .ident = "Everex StepNote Series", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), + }, + }, {}, }; #endif /* CONFIG_SUSPEND */ diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 68e2e4582fa2..f8588f81048a 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -100,7 +100,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = { ACPI_DEBUG_INIT(ACPI_LV_EVENTS), }; -static int param_get_debug_layer(char *buffer, struct kernel_param *kp) +static int param_get_debug_layer(char *buffer, const struct kernel_param *kp) { int result = 0; int i; @@ -128,7 +128,7 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp) return result; } -static int param_get_debug_level(char *buffer, struct kernel_param *kp) +static int param_get_debug_level(char *buffer, const struct kernel_param *kp) { int result = 0; int i; @@ -149,10 +149,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) return result; } -module_param_call(debug_layer, param_set_uint, param_get_debug_layer, - &acpi_dbg_layer, 0644); -module_param_call(debug_level, param_set_uint, param_get_debug_level, - &acpi_dbg_level, 0644); +static struct kernel_param_ops param_ops_debug_layer = { + .set = param_set_uint, + .get = param_get_debug_layer, +}; + +static struct kernel_param_ops param_ops_debug_level = { + .set = param_set_uint, + .get = param_get_debug_level, +}; + +module_param_cb(debug_layer, ¶m_ops_debug_layer, &acpi_dbg_layer, 0644); +module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); static char trace_method_name[6]; module_param_string(trace_method_name, trace_method_name, 6, 0644); diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index c5fef01b3c95..b83676126598 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -59,8 +59,8 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, "support\n")); *cap |= ACPI_VIDEO_BACKLIGHT; if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) - printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness " - "control misses _BQC function\n"); + printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, " + "cannot determine initial brightness\n"); /* We have backlight support, no need to scan further */ return AE_CTRL_TERMINATE; } diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index ee9ddeb53417..8cb0347dec28 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -3156,7 +3156,6 @@ static int __devinit ia_init_one(struct pci_dev *pdev, { struct atm_dev *dev; IADEV *iadev; - unsigned long flags; int ret; iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); @@ -3188,19 +3187,14 @@ static int __devinit ia_init_one(struct pci_dev *pdev, ia_dev[iadev_count] = iadev; _ia_dev[iadev_count] = dev; iadev_count++; - spin_lock_init(&iadev->misc_lock); - /* First fixes first. I don't want to think about this now. */ - spin_lock_irqsave(&iadev->misc_lock, flags); if (ia_init(dev) || ia_start(dev)) { IF_INIT(printk("IA register failed!\n");) iadev_count--; ia_dev[iadev_count] = NULL; _ia_dev[iadev_count] = NULL; - spin_unlock_irqrestore(&iadev->misc_lock, flags); ret = -EINVAL; goto err_out_deregister_dev; } - spin_unlock_irqrestore(&iadev->misc_lock, flags); IF_EVENT(printk("iadev_count = %d\n", iadev_count);) iadev->next_board = ia_boards; diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h index b2cd20f549cb..077735e0e04b 100644 --- a/drivers/atm/iphase.h +++ b/drivers/atm/iphase.h @@ -1022,7 +1022,7 @@ typedef struct iadev_t { struct dle_q rx_dle_q; struct free_desc_q *rx_free_desc_qhead; struct sk_buff_head rx_dma_q; - spinlock_t rx_lock, misc_lock; + spinlock_t rx_lock; struct atm_vcc **rx_open; /* list of all open VCs */ u16 num_rx_desc, rx_buf_sz, rxing; u32 rx_pkt_ram, rx_tmp_cnt; diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index f916ddf63938..f46138ab38b6 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -444,6 +444,7 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); struct solos_card *card = atmdev->dev_data; struct sk_buff *skb; + unsigned int len; spin_lock(&card->cli_queue_lock); skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]); @@ -451,11 +452,12 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, if(skb == NULL) return sprintf(buf, "No data.\n"); - memcpy(buf, skb->data, skb->len); - dev_dbg(&card->dev->dev, "len: %d\n", skb->len); + len = skb->len; + memcpy(buf, skb->data, len); + dev_dbg(&card->dev->dev, "len: %d\n", len); kfree_skb(skb); - return skb->len; + return len; } static int send_command(struct solos_card *card, int dev, const char *buf, size_t size) diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 2aafafca2b13..1101e251a629 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -202,6 +202,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str) struct virtio_blk *vblk = disk->private_data; struct request *req; struct bio *bio; + int err; bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES, GFP_KERNEL); @@ -215,7 +216,10 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str) } req->cmd_type = REQ_TYPE_SPECIAL; - return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); + err = blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); + blk_put_request(req); + + return err; } static int virtblk_locked_ioctl(struct block_device *bdev, fmode_t mode, diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c2408bbe9c2e..f508690eb958 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -80,7 +80,7 @@ * Limiting Performance Impact * --------------------------- * C states, especially those with large exit latencies, can have a real - * noticable impact on workloads, which is not acceptable for most sysadmins, + * noticeable impact on workloads, which is not acceptable for most sysadmins, * and in addition, less performance has a power price of its own. * * As a general rule of thumb, menu assumes that the following heuristic diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 216f9d383b5b..effd140fc042 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -879,7 +879,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca) dma->device_issue_pending = ioat2_issue_pending; dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; dma->device_free_chan_resources = ioat2_free_chan_resources; - dma->device_tx_status = ioat_tx_status; + dma->device_tx_status = ioat_dma_tx_status; err = ioat_probe(device); if (err) diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index fb64cf36ba61..eb6b54dbb806 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -580,7 +580,6 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( sh_chan = to_sh_chan(chan); param = chan->private; - slave_addr = param->config->addr; /* Someone calling slave DMA on a public channel? */ if (!param || !sg_len) { @@ -589,6 +588,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( return NULL; } + slave_addr = param->config->addr; + /* * if (param != NULL), this is a successfully requested slave channel, * therefore param->config != NULL too. diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e0187d16dd7c..0fd5b85a0f75 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1140,6 +1140,7 @@ static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { ATTR_COUNTER(0), ATTR_COUNTER(1), ATTR_COUNTER(2), + { .attr = { .name = NULL } } }; static struct mcidev_sysfs_group i7core_udimm_counters = { diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index bf92d07510df..5663d2719063 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -148,7 +148,7 @@ int drm_gem_object_init(struct drm_device *dev, return -ENOMEM; kref_init(&obj->refcount); - kref_init(&obj->handlecount); + atomic_set(&obj->handle_count, 0); obj->size = size; atomic_inc(&dev->object_count); @@ -462,28 +462,6 @@ drm_gem_object_free(struct kref *kref) } EXPORT_SYMBOL(drm_gem_object_free); -/** - * Called after the last reference to the object has been lost. - * Must be called without holding struct_mutex - * - * Frees the object - */ -void -drm_gem_object_free_unlocked(struct kref *kref) -{ - struct drm_gem_object *obj = (struct drm_gem_object *) kref; - struct drm_device *dev = obj->dev; - - if (dev->driver->gem_free_object_unlocked != NULL) - dev->driver->gem_free_object_unlocked(obj); - else if (dev->driver->gem_free_object != NULL) { - mutex_lock(&dev->struct_mutex); - dev->driver->gem_free_object(obj); - mutex_unlock(&dev->struct_mutex); - } -} -EXPORT_SYMBOL(drm_gem_object_free_unlocked); - static void drm_gem_object_ref_bug(struct kref *list_kref) { BUG(); @@ -496,12 +474,8 @@ static void drm_gem_object_ref_bug(struct kref *list_kref) * called before drm_gem_object_free or we'll be touching * freed memory */ -void -drm_gem_object_handle_free(struct kref *kref) +void drm_gem_object_handle_free(struct drm_gem_object *obj) { - struct drm_gem_object *obj = container_of(kref, - struct drm_gem_object, - handlecount); struct drm_device *dev = obj->dev; /* Remove any name for this object */ @@ -528,6 +502,10 @@ void drm_gem_vm_open(struct vm_area_struct *vma) struct drm_gem_object *obj = vma->vm_private_data; drm_gem_object_reference(obj); + + mutex_lock(&obj->dev->struct_mutex); + drm_vm_open_locked(vma); + mutex_unlock(&obj->dev->struct_mutex); } EXPORT_SYMBOL(drm_gem_vm_open); @@ -535,7 +513,10 @@ void drm_gem_vm_close(struct vm_area_struct *vma) { struct drm_gem_object *obj = vma->vm_private_data; - drm_gem_object_unreference_unlocked(obj); + mutex_lock(&obj->dev->struct_mutex); + drm_vm_close_locked(vma); + drm_gem_object_unreference(obj); + mutex_unlock(&obj->dev->struct_mutex); } EXPORT_SYMBOL(drm_gem_vm_close); diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 2ef2c7827243..974e970ce3f8 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c @@ -255,7 +255,7 @@ int drm_gem_one_name_info(int id, void *ptr, void *data) seq_printf(m, "%6d %8zd %7d %8d\n", obj->name, obj->size, - atomic_read(&obj->handlecount.refcount), + atomic_read(&obj->handle_count), atomic_read(&obj->refcount.refcount)); return 0; } diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index fda67468e603..5df450683aab 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -433,15 +433,7 @@ static void drm_vm_open(struct vm_area_struct *vma) mutex_unlock(&dev->struct_mutex); } -/** - * \c close method for all virtual memory types. - * - * \param vma virtual memory area. - * - * Search the \p vma private data entry in drm_device::vmalist, unlink it, and - * free it. - */ -static void drm_vm_close(struct vm_area_struct *vma) +void drm_vm_close_locked(struct vm_area_struct *vma) { struct drm_file *priv = vma->vm_file->private_data; struct drm_device *dev = priv->minor->dev; @@ -451,7 +443,6 @@ static void drm_vm_close(struct vm_area_struct *vma) vma->vm_start, vma->vm_end - vma->vm_start); atomic_dec(&dev->vma_count); - mutex_lock(&dev->struct_mutex); list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { if (pt->vma == vma) { list_del(&pt->head); @@ -459,6 +450,23 @@ static void drm_vm_close(struct vm_area_struct *vma) break; } } +} + +/** + * \c close method for all virtual memory types. + * + * \param vma virtual memory area. + * + * Search the \p vma private data entry in drm_device::vmalist, unlink it, and + * free it. + */ +static void drm_vm_close(struct vm_area_struct *vma) +{ + struct drm_file *priv = vma->vm_file->private_data; + struct drm_device *dev = priv->minor->dev; + + mutex_lock(&dev->struct_mutex); + drm_vm_close_locked(vma); mutex_unlock(&dev->struct_mutex); } diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 61b4caf220fa..fb07e73581e8 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -116,7 +116,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) static const struct file_operations i810_buffer_fops = { .open = drm_open, .release = drm_release, - .unlocked_ioctl = drm_ioctl, + .unlocked_ioctl = i810_ioctl, .mmap = i810_mmap_buffers, .fasync = drm_fasync, }; diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 671aa18415ac..cc92c7e6236f 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c @@ -118,7 +118,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) static const struct file_operations i830_buffer_fops = { .open = drm_open, .release = drm_release, - .unlocked_ioctl = drm_ioctl, + .unlocked_ioctl = i830_ioctl, .mmap = i830_mmap_buffers, .fasync = drm_fasync, }; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9d67b4853030..2dd2c93ebfa3 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1787,9 +1787,9 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) } } - div_u64(diff, diff1); + diff = div_u64(diff, diff1); ret = ((m * diff) + c); - div_u64(ret, 10); + ret = div_u64(ret, 10); dev_priv->last_count1 = total_count; dev_priv->last_time1 = now; @@ -1858,7 +1858,7 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) /* More magic constants... */ diff = diff * 1181; - div_u64(diff, diffms * 10); + diff = div_u64(diff, diffms * 10); dev_priv->gfx_power = diff; } @@ -2231,6 +2231,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->mchdev_lock = &mchdev_lock; spin_unlock(&mchdev_lock); + /* XXX Prevent module unload due to memory corruption bugs. */ + __module_get(THIS_MODULE); + return 0; out_workqueue_free: diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bced9b25c71e..90b1d6753b9d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -136,14 +136,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, return -ENOMEM; ret = drm_gem_handle_create(file_priv, obj, &handle); + /* drop reference from allocate - handle holds it now */ + drm_gem_object_unreference_unlocked(obj); if (ret) { - drm_gem_object_unreference_unlocked(obj); return ret; } - /* Sink the floating reference from kref_init(handlecount) */ - drm_gem_object_handle_unreference_unlocked(obj); - args->handle = handle; return 0; } @@ -471,14 +469,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, return -ENOENT; obj_priv = to_intel_bo(obj); - /* Bounds check source. - * - * XXX: This could use review for overflow issues... - */ - if (args->offset > obj->size || args->size > obj->size || - args->offset + args->size > obj->size) { - drm_gem_object_unreference_unlocked(obj); - return -EINVAL; + /* Bounds check source. */ + if (args->offset > obj->size || args->size > obj->size - args->offset) { + ret = -EINVAL; + goto err; + } + + if (!access_ok(VERIFY_WRITE, + (char __user *)(uintptr_t)args->data_ptr, + args->size)) { + ret = -EFAULT; + goto err; } if (i915_gem_object_needs_bit17_swizzle(obj)) { @@ -490,8 +491,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, file_priv); } +err: drm_gem_object_unreference_unlocked(obj); - return ret; } @@ -580,8 +581,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; - if (!access_ok(VERIFY_READ, user_data, remain)) - return -EFAULT; mutex_lock(&dev->struct_mutex); @@ -934,14 +933,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, return -ENOENT; obj_priv = to_intel_bo(obj); - /* Bounds check destination. - * - * XXX: This could use review for overflow issues... - */ - if (args->offset > obj->size || args->size > obj->size || - args->offset + args->size > obj->size) { - drm_gem_object_unreference_unlocked(obj); - return -EINVAL; + /* Bounds check destination. */ + if (args->offset > obj->size || args->size > obj->size - args->offset) { + ret = -EINVAL; + goto err; + } + + if (!access_ok(VERIFY_READ, + (char __user *)(uintptr_t)args->data_ptr, + args->size)) { + ret = -EFAULT; + goto err; } /* We can only do the GTT pwrite on untiled buffers, as otherwise @@ -975,8 +977,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, DRM_INFO("pwrite failed %d\n", ret); #endif +err: drm_gem_object_unreference_unlocked(obj); - return ret; } @@ -3258,6 +3260,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, (int) reloc->offset, reloc->read_domains, reloc->write_domain); + drm_gem_object_unreference(target_obj); + i915_gem_object_unpin(obj); return -EINVAL; } if (reloc->write_domain & I915_GEM_DOMAIN_CPU || diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index e85246ef691c..5c428fa3e0b3 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -93,7 +93,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen { drm_i915_private_t *dev_priv = dev->dev_private; struct list_head eviction_list, unwind_list; - struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; + struct drm_i915_gem_object *obj_priv; struct list_head *render_iter, *bsd_iter; int ret = 0; @@ -175,39 +175,34 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen return -ENOSPC; found: + /* drm_mm doesn't allow any other other operations while + * scanning, therefore store to be evicted objects on a + * temporary list. */ INIT_LIST_HEAD(&eviction_list); - list_for_each_entry_safe(obj_priv, tmp_obj_priv, - &unwind_list, evict_list) { + while (!list_empty(&unwind_list)) { + obj_priv = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + evict_list); if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { - /* drm_mm doesn't allow any other other operations while - * scanning, therefore store to be evicted objects on a - * temporary list. */ list_move(&obj_priv->evict_list, &eviction_list); - } else - drm_gem_object_unreference(&obj_priv->base); + continue; + } + list_del(&obj_priv->evict_list); + drm_gem_object_unreference(&obj_priv->base); } /* Unbinding will emit any required flushes */ - list_for_each_entry_safe(obj_priv, tmp_obj_priv, - &eviction_list, evict_list) { -#if WATCH_LRU - DRM_INFO("%s: evicting %p\n", __func__, &obj_priv->base); -#endif - ret = i915_gem_object_unbind(&obj_priv->base); - if (ret) - return ret; - + while (!list_empty(&eviction_list)) { + obj_priv = list_first_entry(&eviction_list, + struct drm_i915_gem_object, + evict_list); + if (ret == 0) + ret = i915_gem_object_unbind(&obj_priv->base); + list_del(&obj_priv->evict_list); drm_gem_object_unreference(&obj_priv->base); } - /* The just created free hole should be on the top of the free stack - * maintained by drm_mm, so this BUG_ON actually executes in O(1). - * Furthermore all accessed data has just recently been used, so it - * should be really fast, too. */ - BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size, - alignment, 0)); - - return 0; + return ret; } int diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b5bf51a4502d..979228594599 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1013,8 +1013,8 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) DRM_DEBUG_KMS("vblank wait timed out\n"); } -/** - * intel_wait_for_vblank_off - wait for vblank after disabling a pipe +/* + * intel_wait_for_pipe_off - wait for pipe to turn off * @dev: drm device * @pipe: pipe to wait for * @@ -1022,25 +1022,39 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) * spinning on the vblank interrupt status bit, since we won't actually * see an interrupt when the pipe is disabled. * - * So this function waits for the display line value to settle (it - * usually ends up stopping at the start of the next frame). + * On Gen4 and above: + * wait for the pipe register state bit to turn off + * + * Otherwise: + * wait for the display line value to settle (it usually + * ends up stopping at the start of the next frame). + * */ -void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) +static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); - unsigned long timeout = jiffies + msecs_to_jiffies(100); - u32 last_line; - - /* Wait for the display line to settle */ - do { - last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; - mdelay(5); - } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && - time_after(timeout, jiffies)); - - if (time_after(jiffies, timeout)) - DRM_DEBUG_KMS("vblank wait timed out\n"); + + if (INTEL_INFO(dev)->gen >= 4) { + int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF); + + /* Wait for the Pipe State to go off */ + if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, + 100, 0)) + DRM_DEBUG_KMS("pipe_off wait timed out\n"); + } else { + u32 last_line; + int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); + unsigned long timeout = jiffies + msecs_to_jiffies(100); + + /* Wait for the display line to settle */ + do { + last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; + mdelay(5); + } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && + time_after(timeout, jiffies)); + if (time_after(jiffies, timeout)) + DRM_DEBUG_KMS("pipe_off wait timed out\n"); + } } /* Parameters have changed, update FBC info */ @@ -2328,13 +2342,13 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) I915_READ(dspbase_reg); } - /* Wait for vblank for the disable to take effect */ - intel_wait_for_vblank_off(dev, pipe); - /* Don't disable pipe A or pipe A PLLs if needed */ if (pipeconf_reg == PIPEACONF && - (dev_priv->quirks & QUIRK_PIPEA_FORCE)) + (dev_priv->quirks & QUIRK_PIPEA_FORCE)) { + /* Wait for vblank for the disable to take effect */ + intel_wait_for_vblank(dev, pipe); goto skip_pipe_off; + } /* Next, disable display pipes */ temp = I915_READ(pipeconf_reg); @@ -2343,8 +2357,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) I915_READ(pipeconf_reg); } - /* Wait for vblank for the disable to take effect. */ - intel_wait_for_vblank_off(dev, pipe); + /* Wait for the pipe to turn off */ + intel_wait_for_pipe_off(dev, pipe); temp = I915_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) != 0) { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1a51ee07de3e..9ab8708ac6ba 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1138,18 +1138,14 @@ static bool intel_dp_set_link_train(struct intel_dp *intel_dp, uint32_t dp_reg_value, uint8_t dp_train_pat, - uint8_t train_set[4], - bool first) + uint8_t train_set[4]) { struct drm_device *dev = intel_dp->base.enc.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); int ret; I915_WRITE(intel_dp->output_reg, dp_reg_value); POSTING_READ(intel_dp->output_reg); - if (first) - intel_wait_for_vblank(dev, intel_crtc->pipe); intel_dp_aux_native_write_1(intel_dp, DP_TRAINING_PATTERN_SET, @@ -1174,10 +1170,15 @@ intel_dp_link_train(struct intel_dp *intel_dp) uint8_t voltage; bool clock_recovery = false; bool channel_eq = false; - bool first = true; int tries; u32 reg; uint32_t DP = intel_dp->DP; + struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); + + /* Enable output, wait for it to become active */ + I915_WRITE(intel_dp->output_reg, intel_dp->DP); + POSTING_READ(intel_dp->output_reg); + intel_wait_for_vblank(dev, intel_crtc->pipe); /* Write the link configuration data */ intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, @@ -1210,9 +1211,8 @@ intel_dp_link_train(struct intel_dp *intel_dp) reg = DP | DP_LINK_TRAIN_PAT_1; if (!intel_dp_set_link_train(intel_dp, reg, - DP_TRAINING_PATTERN_1, train_set, first)) + DP_TRAINING_PATTERN_1, train_set)) break; - first = false; /* Set training pattern 1 */ udelay(100); @@ -1266,8 +1266,7 @@ intel_dp_link_train(struct intel_dp *intel_dp) /* channel eq pattern */ if (!intel_dp_set_link_train(intel_dp, reg, - DP_TRAINING_PATTERN_2, train_set, - false)) + DP_TRAINING_PATTERN_2, train_set)) break; udelay(400); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ad312ca6b3e5..8828b3ac6414 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -229,7 +229,6 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, struct drm_crtc *crtc); int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 7bdc96256bf5..b61966c126d3 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -237,8 +237,10 @@ int intel_fbdev_destroy(struct drm_device *dev, drm_fb_helper_fini(&ifbdev->helper); drm_framebuffer_cleanup(&ifb->base); - if (ifb->obj) + if (ifb->obj) { drm_gem_object_unreference(ifb->obj); + ifb->obj = NULL; + } return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index ead7b8fc53fc..19620a6709f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -167,11 +167,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, goto out; ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); + /* drop reference from allocate - handle holds it now */ + drm_gem_object_unreference_unlocked(nvbo->gem); out: - drm_gem_object_handle_unreference_unlocked(nvbo->gem); - - if (ret) - drm_gem_object_unreference_unlocked(nvbo->gem); return ret; } diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 79082d4398ae..2f93d46ae69a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1137,7 +1137,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(RCU_IND_INDEX, 0x203); efuse_straps_3 = RREG32(RCU_IND_DATA); - efuse_box_bit_127_124 = (u8)(efuse_straps_3 & 0xF0000000) >> 28; + efuse_box_bit_127_124 = (u8)((efuse_straps_3 & 0xF0000000) >> 28); switch(efuse_box_bit_127_124) { case 0x0: @@ -1407,6 +1407,7 @@ int evergreen_mc_init(struct radeon_device *rdev) rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; rdev->mc.visible_vram_size = rdev->mc.aper_size; + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; r600_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); @@ -1520,7 +1521,7 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) { u32 tmp; - WREG32(CP_INT_CNTL, 0); + WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); WREG32(GRBM_INT_CNTL, 0); WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e151f16a8f86..e59422320bb6 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1030,6 +1030,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) return r; } rdev->cp.ready = true; + rdev->mc.active_vram_size = rdev->mc.real_vram_size; return 0; } @@ -1047,6 +1048,7 @@ void r100_cp_fini(struct radeon_device *rdev) void r100_cp_disable(struct radeon_device *rdev) { /* Disable ring */ + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; rdev->cp.ready = false; WREG32(RADEON_CP_CSQ_MODE, 0); WREG32(RADEON_CP_CSQ_CNTL, 0); @@ -2295,6 +2297,7 @@ void r100_vram_init_sizes(struct radeon_device *rdev) /* FIXME we don't use the second aperture yet when we could use it */ if (rdev->mc.visible_vram_size > rdev->mc.aper_size) rdev->mc.visible_vram_size = rdev->mc.aper_size; + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); if (rdev->flags & RADEON_IS_IGP) { uint32_t tom; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index ddc3adea1dda..7b65e4efe8af 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1248,6 +1248,7 @@ int r600_mc_init(struct radeon_device *rdev) rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.visible_vram_size = rdev->mc.aper_size; + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; r600_vram_gtt_location(rdev, &rdev->mc); if (rdev->flags & RADEON_IS_IGP) { @@ -1917,6 +1918,7 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) */ void r600_cp_stop(struct radeon_device *rdev) { + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); } @@ -2910,7 +2912,7 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) { u32 tmp; - WREG32(CP_INT_CNTL, 0); + WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); WREG32(GRBM_INT_CNTL, 0); WREG32(DxMODE_INT_MASK, 0); if (ASIC_IS_DCE3(rdev)) { @@ -3528,7 +3530,8 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL */ - if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { + if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && + rdev->vram_scratch.ptr) { void __iomem *ptr = (void *)rdev->vram_scratch.ptr; u32 tmp; diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 9ceb2a1ce799..3473c00781ff 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -532,6 +532,7 @@ int r600_blit_init(struct radeon_device *rdev) memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); radeon_bo_kunmap(rdev->r600_blit.shader_obj); radeon_bo_unreserve(rdev->r600_blit.shader_obj); + rdev->mc.active_vram_size = rdev->mc.real_vram_size; return 0; } @@ -539,6 +540,7 @@ void r600_blit_fini(struct radeon_device *rdev) { int r; + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; if (rdev->r600_blit.shader_obj == NULL) return; /* If we can't reserve the bo, unref should be enough to destroy diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index a168d644bf9e..9ff38c99a6ea 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -344,6 +344,7 @@ struct radeon_mc { * about vram size near mc fb location */ u64 mc_vram_size; u64 visible_vram_size; + u64 active_vram_size; u64 gtt_size; u64 gtt_start; u64 gtt_end; diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index ebae14c4b768..8e43ddae70cc 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -317,6 +317,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, *connector_type = DRM_MODE_CONNECTOR_DVID; } + /* MSI K9A2GM V2/V3 board has no HDMI or DVI */ + if ((dev->pdev->device == 0x796e) && + (dev->pdev->subsystem_vendor == 0x1462) && + (dev->pdev->subsystem_device == 0x7302)) { + if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) || + (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) + return false; + } + /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ if ((dev->pdev->device == 0x7941) && (dev->pdev->subsystem_vendor == 0x147b) && @@ -1549,39 +1558,39 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev) switch (tv_info->ucTV_BootUpDefaultStandard) { case ATOM_TV_NTSC: tv_std = TV_STD_NTSC; - DRM_INFO("Default TV standard: NTSC\n"); + DRM_DEBUG_KMS("Default TV standard: NTSC\n"); break; case ATOM_TV_NTSCJ: tv_std = TV_STD_NTSC_J; - DRM_INFO("Default TV standard: NTSC-J\n"); + DRM_DEBUG_KMS("Default TV standard: NTSC-J\n"); break; case ATOM_TV_PAL: tv_std = TV_STD_PAL; - DRM_INFO("Default TV standard: PAL\n"); + DRM_DEBUG_KMS("Default TV standard: PAL\n"); break; case ATOM_TV_PALM: tv_std = TV_STD_PAL_M; - DRM_INFO("Default TV standard: PAL-M\n"); + DRM_DEBUG_KMS("Default TV standard: PAL-M\n"); break; case ATOM_TV_PALN: tv_std = TV_STD_PAL_N; - DRM_INFO("Default TV standard: PAL-N\n"); + DRM_DEBUG_KMS("Default TV standard: PAL-N\n"); break; case ATOM_TV_PALCN: tv_std = TV_STD_PAL_CN; - DRM_INFO("Default TV standard: PAL-CN\n"); + DRM_DEBUG_KMS("Default TV standard: PAL-CN\n"); break; case ATOM_TV_PAL60: tv_std = TV_STD_PAL_60; - DRM_INFO("Default TV standard: PAL-60\n"); + DRM_DEBUG_KMS("Default TV standard: PAL-60\n"); break; case ATOM_TV_SECAM: tv_std = TV_STD_SECAM; - DRM_INFO("Default TV standard: SECAM\n"); + DRM_DEBUG_KMS("Default TV standard: SECAM\n"); break; default: tv_std = TV_STD_NTSC; - DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); + DRM_DEBUG_KMS("Unknown TV standard; defaulting to NTSC\n"); break; } } diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index a04b7a6ad95f..7b7ea269549c 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -913,47 +913,47 @@ radeon_combios_get_tv_info(struct radeon_device *rdev) switch (RBIOS8(tv_info + 7) & 0xf) { case 1: tv_std = TV_STD_NTSC; - DRM_INFO("Default TV standard: NTSC\n"); + DRM_DEBUG_KMS("Default TV standard: NTSC\n"); break; case 2: tv_std = TV_STD_PAL; - DRM_INFO("Default TV standard: PAL\n"); + DRM_DEBUG_KMS("Default TV standard: PAL\n"); break; case 3: tv_std = TV_STD_PAL_M; - DRM_INFO("Default TV standard: PAL-M\n"); + DRM_DEBUG_KMS("Default TV standard: PAL-M\n"); break; case 4: tv_std = TV_STD_PAL_60; - DRM_INFO("Default TV standard: PAL-60\n"); + DRM_DEBUG_KMS("Default TV standard: PAL-60\n"); break; case 5: tv_std = TV_STD_NTSC_J; - DRM_INFO("Default TV standard: NTSC-J\n"); + DRM_DEBUG_KMS("Default TV standard: NTSC-J\n"); break; case 6: tv_std = TV_STD_SCART_PAL; - DRM_INFO("Default TV standard: SCART-PAL\n"); + DRM_DEBUG_KMS("Default TV standard: SCART-PAL\n"); break; default: tv_std = TV_STD_NTSC; - DRM_INFO + DRM_DEBUG_KMS ("Unknown TV standard; defaulting to NTSC\n"); break; } switch ((RBIOS8(tv_info + 9) >> 2) & 0x3) { case 0: - DRM_INFO("29.498928713 MHz TV ref clk\n"); + DRM_DEBUG_KMS("29.498928713 MHz TV ref clk\n"); break; case 1: - DRM_INFO("28.636360000 MHz TV ref clk\n"); + DRM_DEBUG_KMS("28.636360000 MHz TV ref clk\n"); break; case 2: - DRM_INFO("14.318180000 MHz TV ref clk\n"); + DRM_DEBUG_KMS("14.318180000 MHz TV ref clk\n"); break; case 3: - DRM_INFO("27.000000000 MHz TV ref clk\n"); + DRM_DEBUG_KMS("27.000000000 MHz TV ref clk\n"); break; default: break; @@ -1324,7 +1324,7 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder, if (tmds_info) { ver = RBIOS8(tmds_info); - DRM_INFO("DFP table revision: %d\n", ver); + DRM_DEBUG_KMS("DFP table revision: %d\n", ver); if (ver == 3) { n = RBIOS8(tmds_info + 5) + 1; if (n > 4) @@ -1408,7 +1408,7 @@ bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); if (offset) { ver = RBIOS8(offset); - DRM_INFO("External TMDS Table revision: %d\n", ver); + DRM_DEBUG_KMS("External TMDS Table revision: %d\n", ver); tmds->slave_addr = RBIOS8(offset + 4 + 2); tmds->slave_addr >>= 1; /* 7 bit addressing */ gpio = RBIOS8(offset + 4 + 3); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 127a395f70fb..b92d2f2fcbed 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -349,6 +349,8 @@ static void radeon_print_display_setup(struct drm_device *dev) DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); if (devices & ATOM_DEVICE_DFP5_SUPPORT) DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); + if (devices & ATOM_DEVICE_DFP6_SUPPORT) + DRM_INFO(" DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]); if (devices & ATOM_DEVICE_TV1_SUPPORT) DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); if (devices & ATOM_DEVICE_CV_SUPPORT) @@ -841,8 +843,9 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); - if (radeon_fb->obj) + if (radeon_fb->obj) { drm_gem_object_unreference_unlocked(radeon_fb->obj); + } drm_framebuffer_cleanup(fb); kfree(radeon_fb); } diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index c74a8b20d941..40b0c087b592 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -94,6 +94,7 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) ret = radeon_bo_reserve(rbo, false); if (likely(ret == 0)) { radeon_bo_kunmap(rbo); + radeon_bo_unpin(rbo); radeon_bo_unreserve(rbo); } drm_gem_object_unreference_unlocked(gobj); @@ -325,8 +326,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb { struct fb_info *info; struct radeon_framebuffer *rfb = &rfbdev->rfb; - struct radeon_bo *rbo; - int r; if (rfbdev->helper.fbdev) { info = rfbdev->helper.fbdev; @@ -338,14 +337,8 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb } if (rfb->obj) { - rbo = rfb->obj->driver_private; - r = radeon_bo_reserve(rbo, false); - if (likely(r == 0)) { - radeon_bo_kunmap(rbo); - radeon_bo_unpin(rbo); - radeon_bo_unreserve(rbo); - } - drm_gem_object_unreference_unlocked(rfb->obj); + radeonfb_destroy_pinned_object(rfb->obj); + rfb->obj = NULL; } drm_fb_helper_fini(&rfbdev->helper); drm_framebuffer_cleanup(&rfb->base); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c578f265b24c..d1e595d91723 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -201,11 +201,11 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, return r; } r = drm_gem_handle_create(filp, gobj, &handle); + /* drop reference from allocate - handle holds it now */ + drm_gem_object_unreference_unlocked(gobj); if (r) { - drm_gem_object_unreference_unlocked(gobj); return r; } - drm_gem_object_handle_unreference_unlocked(gobj); args->handle = handle; return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 0afd1e62347d..b3b5306bb578 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) u32 c = 0; rbo->placement.fpfn = 0; - rbo->placement.lpfn = 0; + rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements; if (domain & RADEON_GEM_DOMAIN_VRAM) diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 353998dc2c03..3481bc7f6f58 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -124,11 +124,8 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, int r; r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); - if (unlikely(r != 0)) { - if (r != -ERESTARTSYS) - dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo); + if (unlikely(r != 0)) return r; - } spin_lock(&bo->tbo.lock); if (mem_type) *mem_type = bo->tbo.mem.mem_type; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index cc05b230d7ef..51d5f7b5ab21 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -693,6 +693,7 @@ void rs600_mc_init(struct radeon_device *rdev) rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); rdev->mc.mc_vram_size = rdev->mc.real_vram_size; rdev->mc.visible_vram_size = rdev->mc.aper_size; + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); base = RREG32_MC(R_000004_MC_FB_LOCATION); base = G_000004_MC_FB_START(base) << 16; diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 3e3f75718be3..4dc2a87ea680 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -157,6 +157,7 @@ void rs690_mc_init(struct radeon_device *rdev) rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); rdev->mc.visible_vram_size = rdev->mc.aper_size; + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); base = G_000100_MC_FB_START(base) << 16; rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index bfa59db374d2..9490da700749 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -267,6 +267,7 @@ static void rv770_mc_program(struct radeon_device *rdev) */ void r700_cp_stop(struct radeon_device *rdev) { + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); } @@ -992,6 +993,7 @@ int rv770_mc_init(struct radeon_device *rdev) rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.visible_vram_size = rdev->mc.aper_size; + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; r600_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index cb4cf7ef4d1e..db809e034cc4 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -442,6 +442,43 @@ out_err: } /** + * Call bo::reserved and with the lru lock held. + * Will release GPU memory type usage on destruction. + * This is the place to put in driver specific hooks. + * Will release the bo::reserved lock and the + * lru lock on exit. + */ + +static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) +{ + struct ttm_bo_global *glob = bo->glob; + + if (bo->ttm) { + + /** + * Release the lru_lock, since we don't want to have + * an atomic requirement on ttm_tt[unbind|destroy]. + */ + + spin_unlock(&glob->lru_lock); + ttm_tt_unbind(bo->ttm); + ttm_tt_destroy(bo->ttm); + bo->ttm = NULL; + spin_lock(&glob->lru_lock); + } + + if (bo->mem.mm_node) { + drm_mm_put_block(bo->mem.mm_node); + bo->mem.mm_node = NULL; + } + + atomic_set(&bo->reserved, 0); + wake_up_all(&bo->event_queue); + spin_unlock(&glob->lru_lock); +} + + +/** * If bo idle, remove from delayed- and lru lists, and unref. * If not idle, and already on delayed list, do nothing. * If not idle, and not on delayed list, put on delayed list, @@ -456,6 +493,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) int ret; spin_lock(&bo->lock); +retry: (void) ttm_bo_wait(bo, false, false, !remove_all); if (!bo->sync_obj) { @@ -464,31 +502,52 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) spin_unlock(&bo->lock); spin_lock(&glob->lru_lock); - put_count = ttm_bo_del_from_lru(bo); + ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0); + + /** + * Someone else has the object reserved. Bail and retry. + */ - ret = ttm_bo_reserve_locked(bo, false, false, false, 0); - BUG_ON(ret); - if (bo->ttm) - ttm_tt_unbind(bo->ttm); + if (unlikely(ret == -EBUSY)) { + spin_unlock(&glob->lru_lock); + spin_lock(&bo->lock); + goto requeue; + } + + /** + * We can re-check for sync object without taking + * the bo::lock since setting the sync object requires + * also bo::reserved. A busy object at this point may + * be caused by another thread starting an accelerated + * eviction. + */ + + if (unlikely(bo->sync_obj)) { + atomic_set(&bo->reserved, 0); + wake_up_all(&bo->event_queue); + spin_unlock(&glob->lru_lock); + spin_lock(&bo->lock); + if (remove_all) + goto retry; + else + goto requeue; + } + + put_count = ttm_bo_del_from_lru(bo); if (!list_empty(&bo->ddestroy)) { list_del_init(&bo->ddestroy); ++put_count; } - if (bo->mem.mm_node) { - drm_mm_put_block(bo->mem.mm_node); - bo->mem.mm_node = NULL; - } - spin_unlock(&glob->lru_lock); - atomic_set(&bo->reserved, 0); + ttm_bo_cleanup_memtype_use(bo); while (put_count--) kref_put(&bo->list_kref, ttm_bo_ref_bug); return 0; } - +requeue: spin_lock(&glob->lru_lock); if (list_empty(&bo->ddestroy)) { void *sync_obj = bo->sync_obj; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 72ec2e2b6e97..a96ed6d9d010 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -148,13 +148,16 @@ static struct pci_device_id vmw_pci_id_list[] = { {0, 0, 0} }; -static char *vmw_devname = "vmwgfx"; +static int enable_fbdev; static int vmw_probe(struct pci_dev *, const struct pci_device_id *); static void vmw_master_init(struct vmw_master *); static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, void *ptr); +MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev"); +module_param_named(enable_fbdev, enable_fbdev, int, 0600); + static void vmw_print_capabilities(uint32_t capabilities) { DRM_INFO("Capabilities:\n"); @@ -192,8 +195,6 @@ static int vmw_request_device(struct vmw_private *dev_priv) { int ret; - vmw_kms_save_vga(dev_priv); - ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); if (unlikely(ret != 0)) { DRM_ERROR("Unable to initialize FIFO.\n"); @@ -206,9 +207,35 @@ static int vmw_request_device(struct vmw_private *dev_priv) static void vmw_release_device(struct vmw_private *dev_priv) { vmw_fifo_release(dev_priv, &dev_priv->fifo); - vmw_kms_restore_vga(dev_priv); } +int vmw_3d_resource_inc(struct vmw_private *dev_priv) +{ + int ret = 0; + + mutex_lock(&dev_priv->release_mutex); + if (unlikely(dev_priv->num_3d_resources++ == 0)) { + ret = vmw_request_device(dev_priv); + if (unlikely(ret != 0)) + --dev_priv->num_3d_resources; + } + mutex_unlock(&dev_priv->release_mutex); + return ret; +} + + +void vmw_3d_resource_dec(struct vmw_private *dev_priv) +{ + int32_t n3d; + + mutex_lock(&dev_priv->release_mutex); + if (unlikely(--dev_priv->num_3d_resources == 0)) + vmw_release_device(dev_priv); + n3d = (int32_t) dev_priv->num_3d_resources; + mutex_unlock(&dev_priv->release_mutex); + + BUG_ON(n3d < 0); +} static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) { @@ -228,6 +255,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->last_read_sequence = (uint32_t) -100; mutex_init(&dev_priv->hw_mutex); mutex_init(&dev_priv->cmdbuf_mutex); + mutex_init(&dev_priv->release_mutex); rwlock_init(&dev_priv->resource_lock); idr_init(&dev_priv->context_idr); idr_init(&dev_priv->surface_idr); @@ -244,6 +272,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->vram_start = pci_resource_start(dev->pdev, 1); dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); + dev_priv->enable_fb = enable_fbdev; + mutex_lock(&dev_priv->hw_mutex); vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); @@ -343,17 +373,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) dev->dev_private = dev_priv; - if (!dev->devname) - dev->devname = vmw_devname; - - if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { - ret = drm_irq_install(dev); - if (unlikely(ret != 0)) { - DRM_ERROR("Failed installing irq: %d\n", ret); - goto out_no_irq; - } - } - ret = pci_request_regions(dev->pdev, "vmwgfx probe"); dev_priv->stealth = (ret != 0); if (dev_priv->stealth) { @@ -369,26 +388,52 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) goto out_no_device; } } - ret = vmw_request_device(dev_priv); + ret = vmw_kms_init(dev_priv); if (unlikely(ret != 0)) - goto out_no_device; - vmw_kms_init(dev_priv); + goto out_no_kms; vmw_overlay_init(dev_priv); - vmw_fb_init(dev_priv); + if (dev_priv->enable_fb) { + ret = vmw_3d_resource_inc(dev_priv); + if (unlikely(ret != 0)) + goto out_no_fifo; + vmw_kms_save_vga(dev_priv); + vmw_fb_init(dev_priv); + DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? + "Detected device 3D availability.\n" : + "Detected no device 3D availability.\n"); + } else { + DRM_INFO("Delayed 3D detection since we're not " + "running the device in SVGA mode yet.\n"); + } + + if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { + ret = drm_irq_install(dev); + if (unlikely(ret != 0)) { + DRM_ERROR("Failed installing irq: %d\n", ret); + goto out_no_irq; + } + } dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; register_pm_notifier(&dev_priv->pm_nb); - DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n"); - return 0; -out_no_device: - if (dev_priv->capabilities & SVGA_CAP_IRQMASK) - drm_irq_uninstall(dev_priv->dev); - if (dev->devname == vmw_devname) - dev->devname = NULL; out_no_irq: + if (dev_priv->enable_fb) { + vmw_fb_close(dev_priv); + vmw_kms_restore_vga(dev_priv); + vmw_3d_resource_dec(dev_priv); + } +out_no_fifo: + vmw_overlay_close(dev_priv); + vmw_kms_close(dev_priv); +out_no_kms: + if (dev_priv->stealth) + pci_release_region(dev->pdev, 2); + else + pci_release_regions(dev->pdev); +out_no_device: ttm_object_device_release(&dev_priv->tdev); out_err4: iounmap(dev_priv->mmio_virt); @@ -415,19 +460,20 @@ static int vmw_driver_unload(struct drm_device *dev) unregister_pm_notifier(&dev_priv->pm_nb); - vmw_fb_close(dev_priv); + if (dev_priv->capabilities & SVGA_CAP_IRQMASK) + drm_irq_uninstall(dev_priv->dev); + if (dev_priv->enable_fb) { + vmw_fb_close(dev_priv); + vmw_kms_restore_vga(dev_priv); + vmw_3d_resource_dec(dev_priv); + } vmw_kms_close(dev_priv); vmw_overlay_close(dev_priv); - vmw_release_device(dev_priv); if (dev_priv->stealth) pci_release_region(dev->pdev, 2); else pci_release_regions(dev->pdev); - if (dev_priv->capabilities & SVGA_CAP_IRQMASK) - drm_irq_uninstall(dev_priv->dev); - if (dev->devname == vmw_devname) - dev->devname = NULL; ttm_object_device_release(&dev_priv->tdev); iounmap(dev_priv->mmio_virt); drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, @@ -500,7 +546,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, struct drm_ioctl_desc *ioctl = &vmw_ioctls[nr - DRM_COMMAND_BASE]; - if (unlikely(ioctl->cmd != cmd)) { + if (unlikely(ioctl->cmd_drv != cmd)) { DRM_ERROR("Invalid command format, ioctl %d\n", nr - DRM_COMMAND_BASE); return -EINVAL; @@ -589,6 +635,16 @@ static int vmw_master_set(struct drm_device *dev, struct vmw_master *vmaster = vmw_master(file_priv->master); int ret = 0; + if (!dev_priv->enable_fb) { + ret = vmw_3d_resource_inc(dev_priv); + if (unlikely(ret != 0)) + return ret; + vmw_kms_save_vga(dev_priv); + mutex_lock(&dev_priv->hw_mutex); + vmw_write(dev_priv, SVGA_REG_TRACES, 0); + mutex_unlock(&dev_priv->hw_mutex); + } + if (active) { BUG_ON(active != &dev_priv->fbdev_master); ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); @@ -617,7 +673,13 @@ static int vmw_master_set(struct drm_device *dev, return 0; out_no_active_lock: - vmw_release_device(dev_priv); + if (!dev_priv->enable_fb) { + mutex_lock(&dev_priv->hw_mutex); + vmw_write(dev_priv, SVGA_REG_TRACES, 1); + mutex_unlock(&dev_priv->hw_mutex); + vmw_kms_restore_vga(dev_priv); + vmw_3d_resource_dec(dev_priv); + } return ret; } @@ -645,11 +707,23 @@ static void vmw_master_drop(struct drm_device *dev, ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); + if (!dev_priv->enable_fb) { + ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); + if (unlikely(ret != 0)) + DRM_ERROR("Unable to clean VRAM on master drop.\n"); + mutex_lock(&dev_priv->hw_mutex); + vmw_write(dev_priv, SVGA_REG_TRACES, 1); + mutex_unlock(&dev_priv->hw_mutex); + vmw_kms_restore_vga(dev_priv); + vmw_3d_resource_dec(dev_priv); + } + dev_priv->active_master = &dev_priv->fbdev_master; ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); ttm_vt_unlock(&dev_priv->fbdev_master.lock); - vmw_fb_on(dev_priv); + if (dev_priv->enable_fb) + vmw_fb_on(dev_priv); } @@ -722,6 +796,7 @@ static struct drm_driver driver = { .irq_postinstall = vmw_irq_postinstall, .irq_uninstall = vmw_irq_uninstall, .irq_handler = vmw_irq_handler, + .get_vblank_counter = vmw_get_vblank_counter, .reclaim_buffers_locked = NULL, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 429f917b60bf..58de6393f611 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -277,6 +277,7 @@ struct vmw_private { bool stealth; bool is_opened; + bool enable_fb; /** * Master management. @@ -285,6 +286,9 @@ struct vmw_private { struct vmw_master *active_master; struct vmw_master fbdev_master; struct notifier_block pm_nb; + + struct mutex release_mutex; + uint32_t num_3d_resources; }; static inline struct vmw_private *vmw_priv(struct drm_device *dev) @@ -319,6 +323,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, return val; } +int vmw_3d_resource_inc(struct vmw_private *dev_priv); +void vmw_3d_resource_dec(struct vmw_private *dev_priv); + /** * GMR utilities - vmwgfx_gmr.c */ @@ -511,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, unsigned bbp, unsigned depth); int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); /** * Overlay control - vmwgfx_overlay.c diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 870967a97c15..409e172f4abf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -615,6 +615,11 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, if (unlikely(ret != 0)) goto err_unlock; + if (bo->mem.mem_type == TTM_PL_VRAM && + bo->mem.mm_node->start < bo->num_pages) + (void) ttm_bo_validate(bo, &vmw_sys_placement, false, + false, false); + ret = ttm_bo_validate(bo, &ne_placement, false, false, false); /* Could probably bug on */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index e6a1eb7ea954..0fe31766e4cf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -106,6 +106,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) mutex_lock(&dev_priv->hw_mutex); dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); + dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); vmw_write(dev_priv, SVGA_REG_ENABLE, 1); min = 4; @@ -175,6 +176,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) dev_priv->config_done_state); vmw_write(dev_priv, SVGA_REG_ENABLE, dev_priv->enable_state); + vmw_write(dev_priv, SVGA_REG_TRACES, + dev_priv->traces_state); mutex_unlock(&dev_priv->hw_mutex); vmw_fence_queue_takedown(&fifo->fence_queue); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 64d7f47df868..e882ba099f0c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -898,7 +898,19 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv) save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); + if (i == 0 && vmw_priv->num_displays == 1 && + save->width == 0 && save->height == 0) { + + /* + * It should be fairly safe to assume that these + * values are uninitialized. + */ + + save->width = vmw_priv->vga_width - save->pos_x; + save->height = vmw_priv->vga_height - save->pos_y; + } } + return 0; } @@ -984,3 +996,8 @@ out_unlock: ttm_read_unlock(&vmaster->lock); return ret; } + +u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc) +{ + return 0; +} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 7083b1a24df3..11cb39e3accb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -27,6 +27,8 @@ #include "vmwgfx_kms.h" +#define VMWGFX_LDU_NUM_DU 8 + #define vmw_crtc_to_ldu(x) \ container_of(x, struct vmw_legacy_display_unit, base.crtc) #define vmw_encoder_to_ldu(x) \ @@ -536,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) { + struct drm_device *dev = dev_priv->dev; + int i; + int ret; + if (dev_priv->ldu_priv) { DRM_INFO("ldu system already on\n"); return -EINVAL; @@ -553,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) drm_mode_create_dirty_info_property(dev_priv->dev); - vmw_ldu_init(dev_priv, 0); - /* for old hardware without multimon only enable one display */ if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { - vmw_ldu_init(dev_priv, 1); - vmw_ldu_init(dev_priv, 2); - vmw_ldu_init(dev_priv, 3); - vmw_ldu_init(dev_priv, 4); - vmw_ldu_init(dev_priv, 5); - vmw_ldu_init(dev_priv, 6); - vmw_ldu_init(dev_priv, 7); + for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i) + vmw_ldu_init(dev_priv, i); + ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU); + } else { + /* for old hardware without multimon only enable one display */ + vmw_ldu_init(dev_priv, 0); + ret = drm_vblank_init(dev, 1); } - return 0; + return ret; } int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) { + struct drm_device *dev = dev_priv->dev; + + drm_vblank_cleanup(dev); if (!dev_priv->ldu_priv) return -ENOSYS; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 5f2d5df01e5c..c8c40e9979db 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -211,6 +211,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) cmd->body.cid = cpu_to_le32(res->id); vmw_fifo_commit(dev_priv, sizeof(*cmd)); + vmw_3d_resource_dec(dev_priv); } static int vmw_context_init(struct vmw_private *dev_priv, @@ -247,6 +248,7 @@ static int vmw_context_init(struct vmw_private *dev_priv, cmd->body.cid = cpu_to_le32(res->id); vmw_fifo_commit(dev_priv, sizeof(*cmd)); + (void) vmw_3d_resource_inc(dev_priv); vmw_resource_activate(res, vmw_hw_context_destroy); return 0; } @@ -406,6 +408,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) cmd->body.sid = cpu_to_le32(res->id); vmw_fifo_commit(dev_priv, sizeof(*cmd)); + vmw_3d_resource_dec(dev_priv); } void vmw_surface_res_free(struct vmw_resource *res) @@ -473,6 +476,7 @@ int vmw_surface_init(struct vmw_private *dev_priv, } vmw_fifo_commit(dev_priv, submit_size); + (void) vmw_3d_resource_inc(dev_priv); vmw_resource_activate(res, vmw_hw_surface_destroy); return 0; } diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 537841ef44b9..75afb3b0e076 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c @@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev; /* Super-I/O Function prototypes */ static inline int superio_inb(int base, int reg); static inline int superio_inw(int base, int reg); -static inline void superio_enter(int base); +static inline int superio_enter(int base); static inline void superio_select(int base, int ld); static inline void superio_exit(int base); @@ -861,11 +861,20 @@ static int superio_inw(int base, int reg) return val; } -static inline void superio_enter(int base) +static inline int superio_enter(int base) { + /* Don't step on other drivers' I/O space by accident */ + if (!request_muxed_region(base, 2, DRVNAME)) { + printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", + base); + return -EBUSY; + } + /* according to the datasheet the key must be send twice! */ outb(SIO_UNLOCK_KEY, base); outb(SIO_UNLOCK_KEY, base); + + return 0; } static inline void superio_select(int base, int ld) @@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld) static inline void superio_exit(int base) { outb(SIO_LOCK_KEY, base); + release_region(base, 2); } static inline int fan_from_reg(u16 reg) @@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev) static int __init f71882fg_find(int sioaddr, unsigned short *address, struct f71882fg_sio_data *sio_data) { - int err = -ENODEV; u16 devid; - - /* Don't step on other drivers' I/O space by accident */ - if (!request_region(sioaddr, 2, DRVNAME)) { - printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", - (int)sioaddr); - return -EBUSY; - } - - superio_enter(sioaddr); + int err = superio_enter(sioaddr); + if (err) + return err; devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) { pr_debug(DRVNAME ": Not a Fintek device\n"); + err = -ENODEV; goto exit; } @@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, default: printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", (unsigned int)devid); + err = -ENODEV; goto exit; } @@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { printk(KERN_WARNING DRVNAME ": Device not activated\n"); + err = -ENODEV; goto exit; } *address = superio_inw(sioaddr, SIO_REG_ADDR); if (*address == 0) { printk(KERN_WARNING DRVNAME ": Base address not set\n"); + err = -ENODEV; goto exit; } *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ @@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, (int)superio_inb(sioaddr, SIO_REG_DEVREV)); exit: superio_exit(sioaddr); - release_region(sioaddr, 2); return err; } diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index f7bd2613cecc..f2de3be35df3 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -677,6 +677,11 @@ static int __devinit cpm_i2c_probe(struct platform_device *ofdev, dev_dbg(&ofdev->dev, "hw routines for %s registered.\n", cpm->adap.name); + /* + * register OF I2C devices + */ + of_i2c_register_devices(&cpm->adap); + return 0; out_shut: cpm_i2c_shutdown(cpm); diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 2222c87876b9..b8feac5f2ef4 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -357,9 +357,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->terminate = 0; - /* write the data into mode register */ - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); - /* * First byte should be set here, not after interrupt, * because transmit-data-ready interrupt can come before @@ -371,6 +368,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->buf_len--; } + /* write the data into mode register; start transmitting */ + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); + r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, dev->adapter.timeout); if (r == 0) { diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 43ca32fddde2..89eedf45d30e 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -761,6 +761,9 @@ static int __devinit iic_probe(struct platform_device *ofdev, dev_info(&ofdev->dev, "using %s mode\n", dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); + /* Now register all the child nodes */ + of_i2c_register_devices(adap); + return 0; error_cleanup: diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index a1c419a716af..b74e6dc6886c 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -632,6 +632,7 @@ static int __devinit fsl_i2c_probe(struct platform_device *op, dev_err(i2c->dev, "failed to add adapter\n"); goto fail_add; } + of_i2c_register_devices(&i2c->adap); return result; diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 0e9f85d0a835..56dbe54e8811 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c @@ -218,7 +218,7 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c) return result; } else if (result == 0) { dev_dbg(i2c->dev, "%s: timeout\n", __func__); - result = -ETIMEDOUT; + return -ETIMEDOUT; } return 0; diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index bbd77603a417..29933f87d8fa 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -71,8 +71,8 @@ static int pca_isa_readbyte(void *pd, int reg) static int pca_isa_waitforcompletion(void *pd) { - long ret = ~0; unsigned long timeout; + long ret; if (irq > -1) { ret = wait_event_timeout(pca_wait, @@ -81,11 +81,15 @@ static int pca_isa_waitforcompletion(void *pd) } else { /* Do polling */ timeout = jiffies + pca_isa_ops.timeout; - while (((pca_isa_readbyte(pd, I2C_PCA_CON) - & I2C_PCA_CON_SI) == 0) - && (ret = time_before(jiffies, timeout))) + do { + ret = time_before(jiffies, timeout); + if (pca_isa_readbyte(pd, I2C_PCA_CON) + & I2C_PCA_CON_SI) + break; udelay(100); + } while (ret); } + return ret > 0; } diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index ef5c78487eb7..5f6d7f89e225 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c @@ -80,8 +80,8 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val) static int i2c_pca_pf_waitforcompletion(void *pd) { struct i2c_pca_pf_data *i2c = pd; - long ret = ~0; unsigned long timeout; + long ret; if (i2c->irq) { ret = wait_event_timeout(i2c->wait, @@ -90,10 +90,13 @@ static int i2c_pca_pf_waitforcompletion(void *pd) } else { /* Do polling */ timeout = jiffies + i2c->adap.timeout; - while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) - & I2C_PCA_CON_SI) == 0) - && (ret = time_before(jiffies, timeout))) + do { + ret = time_before(jiffies, timeout); + if (i2c->algo_data.read_byte(i2c, I2C_PCA_CON) + & I2C_PCA_CON_SI) + break; udelay(100); + } while (ret); } return ret > 0; diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 72902e0bbfa7..bf831bf81587 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -662,8 +662,8 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got) unsigned long sda_delay; if (pdata->sda_delay) { - sda_delay = (freq / 1000) * pdata->sda_delay; - sda_delay /= 1000000; + sda_delay = clkin * pdata->sda_delay; + sda_delay = DIV_ROUND_UP(sda_delay, 1000000); sda_delay = DIV_ROUND_UP(sda_delay, 5); if (sda_delay > 3) sda_delay = 3; diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6649176de940..bea4c5021d26 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -32,7 +32,6 @@ #include <linux/init.h> #include <linux/idr.h> #include <linux/mutex.h> -#include <linux/of_i2c.h> #include <linux/of_device.h> #include <linux/completion.h> #include <linux/hardirq.h> @@ -197,11 +196,12 @@ static int i2c_device_pm_suspend(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (pm_runtime_suspended(dev)) - return 0; - - if (pm) - return pm->suspend ? pm->suspend(dev) : 0; + if (pm) { + if (pm_runtime_suspended(dev)) + return 0; + else + return pm->suspend ? pm->suspend(dev) : 0; + } return i2c_legacy_suspend(dev, PMSG_SUSPEND); } @@ -216,12 +216,6 @@ static int i2c_device_pm_resume(struct device *dev) else ret = i2c_legacy_resume(dev); - if (!ret) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } - return ret; } @@ -229,11 +223,12 @@ static int i2c_device_pm_freeze(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (pm_runtime_suspended(dev)) - return 0; - - if (pm) - return pm->freeze ? pm->freeze(dev) : 0; + if (pm) { + if (pm_runtime_suspended(dev)) + return 0; + else + return pm->freeze ? pm->freeze(dev) : 0; + } return i2c_legacy_suspend(dev, PMSG_FREEZE); } @@ -242,11 +237,12 @@ static int i2c_device_pm_thaw(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (pm_runtime_suspended(dev)) - return 0; - - if (pm) - return pm->thaw ? pm->thaw(dev) : 0; + if (pm) { + if (pm_runtime_suspended(dev)) + return 0; + else + return pm->thaw ? pm->thaw(dev) : 0; + } return i2c_legacy_resume(dev); } @@ -255,11 +251,12 @@ static int i2c_device_pm_poweroff(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (pm_runtime_suspended(dev)) - return 0; - - if (pm) - return pm->poweroff ? pm->poweroff(dev) : 0; + if (pm) { + if (pm_runtime_suspended(dev)) + return 0; + else + return pm->poweroff ? pm->poweroff(dev) : 0; + } return i2c_legacy_suspend(dev, PMSG_HIBERNATE); } @@ -876,9 +873,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) if (adap->nr < __i2c_first_dynamic_bus_num) i2c_scan_static_board_info(adap); - /* Register devices from the device tree */ - of_i2c_register_devices(adap); - /* Notify drivers */ mutex_lock(&core_lock); bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a10152bb1427..c37ef64d1465 100755..100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -83,7 +83,7 @@ static unsigned int mwait_substates; /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ static unsigned int lapic_timer_reliable_states; -static struct cpuidle_device *intel_idle_cpuidle_devices; +static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); static struct cpuidle_state *cpuidle_state_table; @@ -108,7 +108,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { .name = "NHM-C3", .desc = "MWAIT 0x10", .driver_data = (void *) 0x10, - .flags = CPUIDLE_FLAG_TIME_VALID, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 20, .power_usage = 500, .target_residency = 80, @@ -117,7 +117,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { .name = "NHM-C6", .desc = "MWAIT 0x20", .driver_data = (void *) 0x20, - .flags = CPUIDLE_FLAG_TIME_VALID, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 200, .power_usage = 350, .target_residency = 800, @@ -149,7 +149,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { .name = "ATM-C4", .desc = "MWAIT 0x30", .driver_data = (void *) 0x30, - .flags = CPUIDLE_FLAG_TIME_VALID, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, .exit_latency = 100, .power_usage = 250, .target_residency = 400, @@ -157,13 +157,13 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { { /* MWAIT C5 */ }, { /* MWAIT C6 */ .name = "ATM-C6", - .desc = "MWAIT 0x40", - .driver_data = (void *) 0x40, - .flags = CPUIDLE_FLAG_TIME_VALID, - .exit_latency = 200, + .desc = "MWAIT 0x52", + .driver_data = (void *) 0x52, + .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 140, .power_usage = 150, - .target_residency = 800, - .enter = NULL }, /* disabled */ + .target_residency = 560, + .enter = &intel_idle }, }; /** @@ -185,6 +185,16 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) local_irq_disable(); + /* + * If the state flag indicates that the TLB will be flushed or if this + * is the deepest c-state supported, do a voluntary leave mm to avoid + * costly and mostly unnecessary wakeups for flushing the user TLB's + * associated with the active mm. + */ + if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED || + (&dev->states[dev->state_count - 1] == state)) + leave_mm(cpu); + if (!(lapic_timer_reliable_states & (1 << (cstate)))) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index d85bd8a7967d..22239e988498 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -483,6 +483,9 @@ static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev, memcpy(joydev->abspam, abspam, len); + for (i = 0; i < joydev->nabs; i++) + joydev->absmap[joydev->abspam[i]] = i; + out: kfree(abspam); return retval; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 9cc488d21490..aa037fec2f86 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -338,7 +338,7 @@ config KEYBOARD_OPENCORES config KEYBOARD_PXA27x tristate "PXA27x/PXA3xx keypad support" - depends on PXA27x || PXA3xx + depends on PXA27x || PXA3xx || ARCH_MMP help Enable support for PXA27x/PXA3xx keypad controller. diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index f32404f99189..4b0ec35259a1 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c @@ -32,7 +32,7 @@ #include <asm/mach/map.h> #include <mach/hardware.h> -#include <mach/pxa27x_keypad.h> +#include <plat/pxa27x_keypad.h> /* * Keypad Controller registers */ @@ -330,11 +330,21 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad) keypad->direct_key_state = new_state; } +static void clear_wakeup_event(struct pxa27x_keypad *keypad) +{ + struct pxa27x_keypad_platform_data *pdata = keypad->pdata; + + if (pdata->clear_wakeup_event) + (pdata->clear_wakeup_event)(); +} + static irqreturn_t pxa27x_keypad_irq_handler(int irq, void *dev_id) { struct pxa27x_keypad *keypad = dev_id; unsigned long kpc = keypad_readl(KPC); + clear_wakeup_event(keypad); + if (kpc & KPC_DI) pxa27x_keypad_scan_direct(keypad); diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 0d4266a533a5..360698553eb5 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -404,6 +404,13 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu retval = uinput_validate_absbits(dev); if (retval < 0) goto exit; + if (test_bit(ABS_MT_SLOT, dev->absbit)) { + int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; + input_mt_create_slots(dev, nslot); + input_set_events_per_packet(dev, 6 * nslot); + } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { + input_set_events_per_packet(dev, 60); + } } udev->state = UIST_SETUP_COMPLETE; diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 42ba3691d908..b35876ee6908 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -103,27 +103,26 @@ static void wacom_sys_irq(struct urb *urb) static int wacom_open(struct input_dev *dev) { struct wacom *wacom = input_get_drvdata(dev); + int retval = 0; - mutex_lock(&wacom->lock); - - wacom->irq->dev = wacom->usbdev; - - if (usb_autopm_get_interface(wacom->intf) < 0) { - mutex_unlock(&wacom->lock); + if (usb_autopm_get_interface(wacom->intf) < 0) return -EIO; - } + + mutex_lock(&wacom->lock); if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { - usb_autopm_put_interface(wacom->intf); - mutex_unlock(&wacom->lock); - return -EIO; + retval = -EIO; + goto out; } wacom->open = true; wacom->intf->needs_remote_wakeup = 1; +out: mutex_unlock(&wacom->lock); - return 0; + if (retval) + usb_autopm_put_interface(wacom->intf); + return retval; } static void wacom_close(struct input_dev *dev) @@ -135,6 +134,8 @@ static void wacom_close(struct input_dev *dev) wacom->open = false; wacom->intf->needs_remote_wakeup = 0; mutex_unlock(&wacom->lock); + + usb_autopm_put_interface(wacom->intf); } static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 6e29badb969e..47fd7a041c52 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -442,8 +442,10 @@ static void wacom_intuos_general(struct wacom_wac *wacom) /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->type >= INTUOS4S && features->type <= INTUOS4L) + if ((features->type >= INTUOS4S && features->type <= INTUOS4L) || + features->type == WACOM_21UX2) { t = (t << 1) | (data[1] & 1); + } input_report_abs(input, ABS_PRESSURE, t); input_report_abs(input, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c index 485be8b1e1b3..f0225bc0f267 100644 --- a/drivers/isdn/sc/interrupt.c +++ b/drivers/isdn/sc/interrupt.c @@ -112,11 +112,19 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst) } else if(callid>=0x0000 && callid<=0x7FFF) { + int len; + pr_debug("%s: Got Incoming Call\n", sc_adapter[card]->devicename); - strcpy(setup.phone,&(rcvmsg.msg_data.byte_array[4])); - strcpy(setup.eazmsn, - sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn); + len = strlcpy(setup.phone, &(rcvmsg.msg_data.byte_array[4]), + sizeof(setup.phone)); + if (len >= sizeof(setup.phone)) + continue; + len = strlcpy(setup.eazmsn, + sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn, + sizeof(setup.eazmsn)); + if (len >= sizeof(setup.eazmsn)) + continue; setup.si1 = 7; setup.si2 = 0; setup.plan = 0; @@ -176,7 +184,9 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst) * Handle a GetMyNumber Rsp */ if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){ - strcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn,rcvmsg.msg_data.byte_array); + strlcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn, + rcvmsg.msg_data.byte_array, + sizeof(rcvmsg.msg_data.byte_array)); continue; } diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index e4112622e5a2..cc2a88d5192f 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -304,13 +304,22 @@ config LEDS_MC13783 config LEDS_NS2 tristate "LED support for Network Space v2 GPIO LEDs" - depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 + depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2 default y help This option enable support for the dual-GPIO LED found on the Network Space v2 board (and parents). This include Internet Space v2, Network Space (Max) v2 and d2 Network v2 boards. +config LEDS_NETXBIG + tristate "LED support for Big Network series LEDs" + depends on MACH_NET2BIG_V2 || MACH_NET5BIG_V2 + default y + help + This option enable support for LEDs found on the LaCie 2Big + and 5Big Network v2 boards. The LEDs are wired to a CPLD and are + controlled through a GPIO extension bus. + config LEDS_TRIGGERS bool "LED Trigger support" help diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 7d6b95831f8e..9c96db40ef6d 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o obj-$(CONFIG_LEDS_NS2) += leds-ns2.o +obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c new file mode 100644 index 000000000000..f2e51c134399 --- /dev/null +++ b/drivers/leds/leds-netxbig.c @@ -0,0 +1,449 @@ +/* + * leds-netxbig.c - Driver for the 2Big and 5Big Network series LEDs + * + * Copyright (C) 2010 LaCie + * + * Author: Simon Guinot <sguinot@lacie.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/platform_device.h> +#include <linux/gpio.h> +#include <linux/leds.h> +#include <mach/leds-netxbig.h> + +/* + * GPIO extension bus. + */ + +static DEFINE_SPINLOCK(gpio_ext_lock); + +static void gpio_ext_set_addr(struct netxbig_gpio_ext *gpio_ext, int addr) +{ + int pin; + + for (pin = 0; pin < gpio_ext->num_addr; pin++) + gpio_set_value(gpio_ext->addr[pin], (addr >> pin) & 1); +} + +static void gpio_ext_set_data(struct netxbig_gpio_ext *gpio_ext, int data) +{ + int pin; + + for (pin = 0; pin < gpio_ext->num_data; pin++) + gpio_set_value(gpio_ext->data[pin], (data >> pin) & 1); +} + +static void gpio_ext_enable_select(struct netxbig_gpio_ext *gpio_ext) +{ + /* Enable select is done on the raising edge. */ + gpio_set_value(gpio_ext->enable, 0); + gpio_set_value(gpio_ext->enable, 1); +} + +static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext, + int addr, int value) +{ + unsigned long flags; + + spin_lock_irqsave(&gpio_ext_lock, flags); + gpio_ext_set_addr(gpio_ext, addr); + gpio_ext_set_data(gpio_ext, value); + gpio_ext_enable_select(gpio_ext); + spin_unlock_irqrestore(&gpio_ext_lock, flags); +} + +static int __devinit gpio_ext_init(struct netxbig_gpio_ext *gpio_ext) +{ + int err; + int i; + + if (unlikely(!gpio_ext)) + return -EINVAL; + + /* Configure address GPIOs. */ + for (i = 0; i < gpio_ext->num_addr; i++) { + err = gpio_request(gpio_ext->addr[i], "GPIO extension addr"); + if (err) + goto err_free_addr; + err = gpio_direction_output(gpio_ext->addr[i], 0); + if (err) { + gpio_free(gpio_ext->addr[i]); + goto err_free_addr; + } + } + /* Configure data GPIOs. */ + for (i = 0; i < gpio_ext->num_data; i++) { + err = gpio_request(gpio_ext->data[i], "GPIO extension data"); + if (err) + goto err_free_data; + err = gpio_direction_output(gpio_ext->data[i], 0); + if (err) { + gpio_free(gpio_ext->data[i]); + goto err_free_data; + } + } + /* Configure "enable select" GPIO. */ + err = gpio_request(gpio_ext->enable, "GPIO extension enable"); + if (err) + goto err_free_data; + err = gpio_direction_output(gpio_ext->enable, 0); + if (err) { + gpio_free(gpio_ext->enable); + goto err_free_data; + } + + return 0; + +err_free_data: + for (i = i - 1; i >= 0; i--) + gpio_free(gpio_ext->data[i]); + i = gpio_ext->num_addr; +err_free_addr: + for (i = i - 1; i >= 0; i--) + gpio_free(gpio_ext->addr[i]); + + return err; +} + +static void __devexit gpio_ext_free(struct netxbig_gpio_ext *gpio_ext) +{ + int i; + + gpio_free(gpio_ext->enable); + for (i = gpio_ext->num_addr - 1; i >= 0; i--) + gpio_free(gpio_ext->addr[i]); + for (i = gpio_ext->num_data - 1; i >= 0; i--) + gpio_free(gpio_ext->data[i]); +} + +/* + * Class LED driver. + */ + +struct netxbig_led_data { + struct netxbig_gpio_ext *gpio_ext; + struct led_classdev cdev; + int mode_addr; + int *mode_val; + int bright_addr; + int bright_max; + struct netxbig_led_timer *timer; + int num_timer; + enum netxbig_led_mode mode; + int sata; + spinlock_t lock; +}; + +static int netxbig_led_get_timer_mode(enum netxbig_led_mode *mode, + unsigned long delay_on, + unsigned long delay_off, + struct netxbig_led_timer *timer, + int num_timer) +{ + int i; + + for (i = 0; i < num_timer; i++) { + if (timer[i].delay_on == delay_on && + timer[i].delay_off == delay_off) { + *mode = timer[i].mode; + return 0; + } + } + return -EINVAL; +} + +static int netxbig_led_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct netxbig_led_data *led_dat = + container_of(led_cdev, struct netxbig_led_data, cdev); + enum netxbig_led_mode mode; + int mode_val; + int ret; + + /* Look for a LED mode with the requested timer frequency. */ + ret = netxbig_led_get_timer_mode(&mode, *delay_on, *delay_off, + led_dat->timer, led_dat->num_timer); + if (ret < 0) + return ret; + + mode_val = led_dat->mode_val[mode]; + if (mode_val == NETXBIG_LED_INVALID_MODE) + return -EINVAL; + + spin_lock_irq(&led_dat->lock); + + gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); + led_dat->mode = mode; + + spin_unlock_irq(&led_dat->lock); + + return 0; +} + +static void netxbig_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct netxbig_led_data *led_dat = + container_of(led_cdev, struct netxbig_led_data, cdev); + enum netxbig_led_mode mode; + int mode_val, bright_val; + int set_brightness = 1; + unsigned long flags; + + spin_lock_irqsave(&led_dat->lock, flags); + + if (value == LED_OFF) { + mode = NETXBIG_LED_OFF; + set_brightness = 0; + } else { + if (led_dat->sata) + mode = NETXBIG_LED_SATA; + else if (led_dat->mode == NETXBIG_LED_OFF) + mode = NETXBIG_LED_ON; + else /* Keep 'timer' mode. */ + mode = led_dat->mode; + } + mode_val = led_dat->mode_val[mode]; + + gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); + led_dat->mode = mode; + /* + * Note that the brightness register is shared between all the + * SATA LEDs. So, change the brightness setting for a single + * SATA LED will affect all the others. + */ + if (set_brightness) { + bright_val = DIV_ROUND_UP(value * led_dat->bright_max, + LED_FULL); + gpio_ext_set_value(led_dat->gpio_ext, + led_dat->bright_addr, bright_val); + } + + spin_unlock_irqrestore(&led_dat->lock, flags); +} + +static ssize_t netxbig_led_sata_store(struct device *dev, + struct device_attribute *attr, + const char *buff, size_t count) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct netxbig_led_data *led_dat = + container_of(led_cdev, struct netxbig_led_data, cdev); + unsigned long enable; + enum netxbig_led_mode mode; + int mode_val; + int ret; + + ret = strict_strtoul(buff, 10, &enable); + if (ret < 0) + return ret; + + enable = !!enable; + + spin_lock_irq(&led_dat->lock); + + if (led_dat->sata == enable) { + ret = count; + goto exit_unlock; + } + + if (led_dat->mode != NETXBIG_LED_ON && + led_dat->mode != NETXBIG_LED_SATA) + mode = led_dat->mode; /* Keep modes 'off' and 'timer'. */ + else if (enable) + mode = NETXBIG_LED_SATA; + else + mode = NETXBIG_LED_ON; + + mode_val = led_dat->mode_val[mode]; + if (mode_val == NETXBIG_LED_INVALID_MODE) { + ret = -EINVAL; + goto exit_unlock; + } + + gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); + led_dat->mode = mode; + led_dat->sata = enable; + + ret = count; + +exit_unlock: + spin_unlock_irq(&led_dat->lock); + + return ret; +} + +static ssize_t netxbig_led_sata_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct netxbig_led_data *led_dat = + container_of(led_cdev, struct netxbig_led_data, cdev); + + return sprintf(buf, "%d\n", led_dat->sata); +} + +static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store); + +static void __devexit delete_netxbig_led(struct netxbig_led_data *led_dat) +{ + if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) + device_remove_file(led_dat->cdev.dev, &dev_attr_sata); + led_classdev_unregister(&led_dat->cdev); +} + +static int __devinit +create_netxbig_led(struct platform_device *pdev, + struct netxbig_led_data *led_dat, + const struct netxbig_led *template) +{ + struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; + int ret; + + spin_lock_init(&led_dat->lock); + led_dat->gpio_ext = pdata->gpio_ext; + led_dat->cdev.name = template->name; + led_dat->cdev.default_trigger = template->default_trigger; + led_dat->cdev.blink_set = netxbig_led_blink_set; + led_dat->cdev.brightness_set = netxbig_led_set; + /* + * Because the GPIO extension bus don't allow to read registers + * value, there is no way to probe the LED initial state. + * So, the initial sysfs LED value for the "brightness" and "sata" + * attributes are inconsistent. + * + * Note that the initial LED state can't be reconfigured. + * The reason is that the LED behaviour must stay uniform during + * the whole boot process (bootloader+linux). + */ + led_dat->sata = 0; + led_dat->cdev.brightness = LED_OFF; + led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; + led_dat->mode_addr = template->mode_addr; + led_dat->mode_val = template->mode_val; + led_dat->bright_addr = template->bright_addr; + led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1; + led_dat->timer = pdata->timer; + led_dat->num_timer = pdata->num_timer; + + ret = led_classdev_register(&pdev->dev, &led_dat->cdev); + if (ret < 0) + return ret; + + /* + * If available, expose the SATA activity blink capability through + * a "sata" sysfs attribute. + */ + if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) { + ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata); + if (ret) + led_classdev_unregister(&led_dat->cdev); + } + + return ret; +} + +static int __devinit netxbig_led_probe(struct platform_device *pdev) +{ + struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; + struct netxbig_led_data *leds_data; + int i; + int ret; + + if (!pdata) + return -EINVAL; + + leds_data = kzalloc(sizeof(struct netxbig_led_data) * pdata->num_leds, + GFP_KERNEL); + if (!leds_data) + return -ENOMEM; + + ret = gpio_ext_init(pdata->gpio_ext); + if (ret < 0) + goto err_free_data; + + for (i = 0; i < pdata->num_leds; i++) { + ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]); + if (ret < 0) + goto err_free_leds; + } + + platform_set_drvdata(pdev, leds_data); + + return 0; + +err_free_leds: + for (i = i - 1; i >= 0; i--) + delete_netxbig_led(&leds_data[i]); + + gpio_ext_free(pdata->gpio_ext); +err_free_data: + kfree(leds_data); + + return ret; +} + +static int __devexit netxbig_led_remove(struct platform_device *pdev) +{ + struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; + struct netxbig_led_data *leds_data; + int i; + + leds_data = platform_get_drvdata(pdev); + + for (i = 0; i < pdata->num_leds; i++) + delete_netxbig_led(&leds_data[i]); + + gpio_ext_free(pdata->gpio_ext); + kfree(leds_data); + + return 0; +} + +static struct platform_driver netxbig_led_driver = { + .probe = netxbig_led_probe, + .remove = __devexit_p(netxbig_led_remove), + .driver = { + .name = "leds-netxbig", + .owner = THIS_MODULE, + }, +}; +MODULE_ALIAS("platform:leds-netxbig"); + +static int __init netxbig_led_init(void) +{ + return platform_driver_register(&netxbig_led_driver); +} + +static void __exit netxbig_led_exit(void) +{ + platform_driver_unregister(&netxbig_led_driver); +} + +module_init(netxbig_led_init); +module_exit(netxbig_led_exit); + +MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); +MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index 350eb34f049c..f77d48d0b3e4 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c @@ -141,10 +141,12 @@ static ssize_t ns2_led_sata_store(struct device *dev, struct device_attribute *attr, const char *buff, size_t count) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct ns2_led_data *led_dat = + container_of(led_cdev, struct ns2_led_data, cdev); int ret; unsigned long enable; enum ns2_led_modes mode; - struct ns2_led_data *led_dat = dev_get_drvdata(dev); ret = strict_strtoul(buff, 10, &enable); if (ret < 0) @@ -172,7 +174,9 @@ static ssize_t ns2_led_sata_store(struct device *dev, static ssize_t ns2_led_sata_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct ns2_led_data *led_dat = dev_get_drvdata(dev); + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct ns2_led_data *led_dat = + container_of(led_cdev, struct ns2_led_data, cdev); return sprintf(buf, "%d\n", led_dat->sata); } @@ -234,7 +238,6 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat, if (ret < 0) goto err_free_slow; - dev_set_drvdata(led_dat->cdev.dev, led_dat); ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata); if (ret < 0) goto err_free_cdev; diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index ed4900ade93a..e4fb58db5454 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1000,10 +1000,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) page = bitmap->sb_page; offset = sizeof(bitmap_super_t); if (!file) - read_sb_page(bitmap->mddev, - bitmap->mddev->bitmap_info.offset, - page, - index, count); + page = read_sb_page( + bitmap->mddev, + bitmap->mddev->bitmap_info.offset, + page, + index, count); } else if (file) { page = read_page(file, index, bitmap, count); offset = 0; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ad83a4dcadc3..0b830bbe1d8b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1839,7 +1839,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i /* take from bio_init */ bio->bi_next = NULL; + bio->bi_flags &= ~(BIO_POOL_MASK-1); bio->bi_flags |= 1 << BIO_UPTODATE; + bio->bi_comp_cpu = -1; bio->bi_rw = READ; bio->bi_vcnt = 0; bio->bi_idx = 0; @@ -1912,7 +1914,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) break; BUG_ON(sync_blocks < (PAGE_SIZE>>9)); - if (len > (sync_blocks<<9)) + if ((len >> 9) > sync_blocks) len = sync_blocks<<9; } diff --git a/drivers/media/IR/ir-keytable.c b/drivers/media/IR/ir-keytable.c index 7e82a9df726b..7961d59f5cac 100644 --- a/drivers/media/IR/ir-keytable.c +++ b/drivers/media/IR/ir-keytable.c @@ -319,7 +319,7 @@ static void ir_timer_keyup(unsigned long cookie) * a keyup event might follow immediately after the keydown. */ spin_lock_irqsave(&ir->keylock, flags); - if (time_is_after_eq_jiffies(ir->keyup_jiffies)) + if (time_is_before_eq_jiffies(ir->keyup_jiffies)) ir_keyup(ir); spin_unlock_irqrestore(&ir->keylock, flags); } @@ -510,6 +510,13 @@ int __ir_input_register(struct input_dev *input_dev, (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? " in raw mode" : ""); + /* + * Default delay of 250ms is too short for some protocols, expecially + * since the timeout is currently set to 250ms. Increase it to 500ms, + * to avoid wrong repetition of the keycodes. + */ + input_dev->rep[REP_DELAY] = 500; + return 0; out_event: diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c index 77b5946413c0..e63f757d5d72 100644 --- a/drivers/media/IR/ir-lirc-codec.c +++ b/drivers/media/IR/ir-lirc-codec.c @@ -267,7 +267,7 @@ static int ir_lirc_register(struct input_dev *input_dev) features |= LIRC_CAN_SET_SEND_CARRIER; if (ir_dev->props->s_tx_duty_cycle) - features |= LIRC_CAN_SET_REC_DUTY_CYCLE; + features |= LIRC_CAN_SET_SEND_DUTY_CYCLE; } if (ir_dev->props->s_rx_carrier_range) diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c index 43094e7eccfa..8e0e1b1f8c87 100644 --- a/drivers/media/IR/ir-raw-event.c +++ b/drivers/media/IR/ir-raw-event.c @@ -279,9 +279,11 @@ int ir_raw_event_register(struct input_dev *input_dev) "rc%u", (unsigned int)ir->devno); if (IS_ERR(ir->raw->thread)) { + int ret = PTR_ERR(ir->raw->thread); + kfree(ir->raw); ir->raw = NULL; - return PTR_ERR(ir->raw->thread); + return ret; } mutex_lock(&ir_raw_handler_lock); diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c index 96dafc425c8e..46d42467f9b4 100644 --- a/drivers/media/IR/ir-sysfs.c +++ b/drivers/media/IR/ir-sysfs.c @@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d, char *tmp = buf; int i; - if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { enabled = ir_dev->rc_tab.ir_type; allowed = ir_dev->props->allowed_protos; - } else { + } else if (ir_dev->raw) { enabled = ir_dev->raw->enabled_protocols; allowed = ir_raw_get_allowed_protocols(); - } + } else + return sprintf(tmp, "[builtin]\n"); IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", (long long)allowed, @@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d, int rc, i, count = 0; unsigned long flags; - if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) type = ir_dev->rc_tab.ir_type; - else + else if (ir_dev->raw) type = ir_dev->raw->enabled_protocols; + else { + IR_dprintk(1, "Protocol switching not supported\n"); + return -EINVAL; + } while ((tmp = strsep((char **) &data, " \n")) != NULL) { if (!*tmp) @@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d, } } - if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { + if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); ir_dev->rc_tab.ir_type = type; spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c index 64264f7f838f..39557ad401b6 100644 --- a/drivers/media/IR/keymaps/rc-rc6-mce.c +++ b/drivers/media/IR/keymaps/rc-rc6-mce.c @@ -19,6 +19,7 @@ static struct ir_scancode rc6_mce[] = { { 0x800f0416, KEY_PLAY }, { 0x800f0418, KEY_PAUSE }, + { 0x800f046e, KEY_PLAYPAUSE }, { 0x800f0419, KEY_STOP }, { 0x800f0417, KEY_RECORD }, @@ -37,6 +38,8 @@ static struct ir_scancode rc6_mce[] = { { 0x800f0411, KEY_VOLUMEDOWN }, { 0x800f0412, KEY_CHANNELUP }, { 0x800f0413, KEY_CHANNELDOWN }, + { 0x800f043a, KEY_BRIGHTNESSUP }, + { 0x800f0480, KEY_BRIGHTNESSDOWN }, { 0x800f0401, KEY_NUMERIC_1 }, { 0x800f0402, KEY_NUMERIC_2 }, diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index ac6bb2c01a48..bc620e10ef77 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c @@ -120,6 +120,10 @@ static struct usb_device_id mceusb_dev_table[] = { { USB_DEVICE(VENDOR_PHILIPS, 0x0613) }, /* Philips eHome Infrared Transceiver */ { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, + /* Philips/Spinel plus IR transceiver for ASUS */ + { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, + /* Philips/Spinel plus IR transceiver for ASUS */ + { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, /* Realtek MCE IR Receiver */ { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, /* SMK/Toshiba G83C0004D410 */ diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index fe818348b8a3..48397f103d32 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -673,9 +673,6 @@ static int dib0700_probe(struct usb_interface *intf, else dev->props.rc.core.bulk_mode = false; - /* Need a higher delay, to avoid wrong repeat */ - dev->rc_input_dev->rep[REP_DELAY] = 500; - dib0700_rc_setup(dev); return 0; diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index f634d2e784b2..e06acd1fecb6 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -940,6 +940,58 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) return adap->fe == NULL ? -ENODEV : 0; } +/* STK7770P */ +static struct dib7000p_config dib7770p_dib7000p_config = { + .output_mpeg2_in_188_bytes = 1, + + .agc_config_count = 1, + .agc = &dib7070_agc_config, + .bw = &dib7070_bw_config_12_mhz, + .tuner_is_baseband = 1, + .spur_protect = 1, + + .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, + + .hostbus_diversity = 1, + .enable_current_mirror = 1, + .disable_sample_and_hold = 0, +}; + +static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct usb_device_descriptor *p = &adap->dev->udev->descriptor; + if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && + p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + else + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(10); + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + msleep(10); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + + if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, + &dib7770p_dib7000p_config) != 0) { + err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", + __func__); + return -ENODEV; + } + + adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + &dib7770p_dib7000p_config); + return adap->fe == NULL ? -ENODEV : 0; +} + /* DIB807x generic */ static struct dibx000_agc_config dib807x_agc_config[2] = { { @@ -1781,7 +1833,7 @@ struct usb_device_id dib0700_usb_id_table[] = { /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, - { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, + { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) }, { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, /* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, @@ -2406,7 +2458,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, .pid_filter_ctrl = stk70x0p_pid_filter_ctrl, - .frontend_attach = stk7070p_frontend_attach, + .frontend_attach = stk7770p_frontend_attach, .tuner_attach = dib7770p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index 6b22ec64ab0c..f896337b4535 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c @@ -483,9 +483,7 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev, } } kfree(p); - if (fw) { - release_firmware(fw); - } + release_firmware(fw); return ret; } diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 2e28b973dfd3..3aed0d433921 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -260,6 +260,9 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad // dprintk( "908: %x, 909: %x\n", reg_908, reg_909); + reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4; + reg_908 |= (state->cfg.enable_current_mirror & 1) << 7; + dib7000p_write_word(state, 908, reg_908); dib7000p_write_word(state, 909, reg_909); } @@ -778,7 +781,10 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte default: case GUARD_INTERVAL_1_32: value *= 1; break; } - state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO + if (state->cfg.diversity_delay == 0) + state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo + else + state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo /* deactive the possibility of diversity reception if extended interleaver */ state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h index 805dd13a97ee..da17345bf5bd 100644 --- a/drivers/media/dvb/frontends/dib7000p.h +++ b/drivers/media/dvb/frontends/dib7000p.h @@ -33,6 +33,11 @@ struct dib7000p_config { int (*agc_control) (struct dvb_frontend *, u8 before); u8 output_mode; + u8 disable_sample_and_hold : 1; + + u8 enable_current_mirror : 1; + u8 diversity_delay; + }; #define DEFAULT_DIB7000P_I2C_ADDRESS 18 diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index d93468cd3a85..ff3b0fa901b3 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1098,33 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse); * * @return pointer to descriptor on success, NULL on error. */ -struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) + +struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev) { struct smscore_buffer_t *cb = NULL; unsigned long flags; - DEFINE_WAIT(wait); - spin_lock_irqsave(&coredev->bufferslock, flags); - - /* This function must return a valid buffer, since the buffer list is - * finite, we check that there is an available buffer, if not, we wait - * until such buffer become available. - */ - - prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE); - if (list_empty(&coredev->buffers)) { - spin_unlock_irqrestore(&coredev->bufferslock, flags); - schedule(); - spin_lock_irqsave(&coredev->bufferslock, flags); + if (!list_empty(&coredev->buffers)) { + cb = (struct smscore_buffer_t *) coredev->buffers.next; + list_del(&cb->entry); } + spin_unlock_irqrestore(&coredev->bufferslock, flags); + return cb; +} - finish_wait(&coredev->buffer_mng_waitq, &wait); - - cb = (struct smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); +struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) +{ + struct smscore_buffer_t *cb = NULL; - spin_unlock_irqrestore(&coredev->bufferslock, flags); + wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev))); return cb; } diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 67a4ec8768a6..4ce541a5eb47 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -395,7 +395,7 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, radio->registers[POWERCFG] = POWERCFG_ENABLE; if (si470x_set_register(radio, POWERCFG) < 0) { retval = -EIO; - goto err_all; + goto err_video; } msleep(110); diff --git a/drivers/media/video/cx231xx/Makefile b/drivers/media/video/cx231xx/Makefile index 755dd0ce65ff..6f2b57384488 100644 --- a/drivers/media/video/cx231xx/Makefile +++ b/drivers/media/video/cx231xx/Makefile @@ -11,4 +11,5 @@ EXTRA_CFLAGS += -Idrivers/media/video EXTRA_CFLAGS += -Idrivers/media/common/tuners EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c index 6bdc0ef18119..f2a4900014bc 100644 --- a/drivers/media/video/cx231xx/cx231xx-cards.c +++ b/drivers/media/video/cx231xx/cx231xx-cards.c @@ -32,6 +32,7 @@ #include <media/v4l2-chip-ident.h> #include <media/cx25840.h> +#include "dvb-usb-ids.h" #include "xc5000.h" #include "cx231xx.h" @@ -175,6 +176,8 @@ struct usb_device_id cx231xx_id_table[] = { .driver_info = CX231XX_BOARD_CNXT_RDE_250}, {USB_DEVICE(0x0572, 0x58A1), .driver_info = CX231XX_BOARD_CNXT_RDU_250}, + {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff), + .driver_info = CX231XX_BOARD_UNKNOWN}, {}, }; @@ -226,14 +229,16 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) dev->board.name, dev->model); /* set the direction for GPIO pins */ - cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); - cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); - cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); + if (dev->board.tuner_gpio) { + cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); + cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); + cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); - /* request some modules if any required */ + /* request some modules if any required */ - /* reset the Tuner */ - cx231xx_gpio_set(dev, dev->board.tuner_gpio); + /* reset the Tuner */ + cx231xx_gpio_set(dev, dev->board.tuner_gpio); + } /* set the mode to Analog mode initially */ cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 86ca8c2359dd..f5a3e74c3c7c 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1996,7 +1996,7 @@ static int cx25840_probe(struct i2c_client *client, state->volume = v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, - 0, 65335, 65535 / 100, default_volume); + 0, 65535, 65535 / 100, default_volume); state->mute = v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 99dbae117591..0fa85cbefbb1 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -17,7 +17,7 @@ config VIDEO_CX88 config VIDEO_CX88_ALSA tristate "Conexant 2388x DMA audio support" - depends on VIDEO_CX88 && SND && EXPERIMENTAL + depends on VIDEO_CX88 && SND select SND_PCM ---help--- This is a video4linux driver for direct (DMA) audio on diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index b9846106913e..78abc1c1f9d5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -223,6 +223,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, usb_rcvintpipe(dev, ep->bEndpointAddress), buffer, buffer_len, int_irq, (void *)gspca_dev, interval); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; gspca_dev->int_urb = urb; ret = usb_submit_urb(urb, GFP_KERNEL); if (ret < 0) { diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 83a718f0f3f9..9052d5702556 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -2357,8 +2357,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, (data[33] << 10); avg_lum >>= 9; atomic_set(&sd->avg_lum, avg_lum); - gspca_frame_add(gspca_dev, LAST_PACKET, - data, len); + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); return; } if (gspca_dev->last_packet_type == LAST_PACKET) { diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index be03a712731c..f0316d02f09f 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -466,6 +466,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar struct fb_vblank vblank; u32 trace; + memset(&vblank, 0, sizeof(struct fb_vblank)); + vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC; trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16; diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index 4525335f9bd4..a7210d981388 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -239,7 +239,7 @@ static int device_process(struct m2mtest_ctx *ctx, return -EFAULT; } - if (in_buf->vb.size < out_buf->vb.size) { + if (in_buf->vb.size > out_buf->vb.size) { v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n"); return -EINVAL; } @@ -1014,6 +1014,7 @@ static int m2mtest_remove(struct platform_device *pdev) v4l2_m2m_release(dev->m2m_dev); del_timer_sync(&dev->timer); video_unregister_device(dev->vfd); + video_device_release(dev->vfd); v4l2_device_unregister(&dev->v4l2_dev); kfree(dev); diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index 758a4db27d65..c71af4e0e517 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c @@ -447,6 +447,9 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n", __func__, rect.left, rect.top, rect.width, rect.height); + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + ret = mt9m111_make_rect(client, &rect); if (!ret) mt9m111->rect = rect; @@ -466,12 +469,14 @@ static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) { + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + a->bounds.left = MT9M111_MIN_DARK_COLS; a->bounds.top = MT9M111_MIN_DARK_ROWS; a->bounds.width = MT9M111_MAX_WIDTH; a->bounds.height = MT9M111_MAX_HEIGHT; a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; a->pixelaspect.numerator = 1; a->pixelaspect.denominator = 1; @@ -487,6 +492,7 @@ static int mt9m111_g_fmt(struct v4l2_subdev *sd, mf->width = mt9m111->rect.width; mf->height = mt9m111->rect.height; mf->code = mt9m111->fmt->code; + mf->colorspace = mt9m111->fmt->colorspace; mf->field = V4L2_FIELD_NONE; return 0; diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index e7cd23cd6394..b48473c7896b 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -402,9 +402,6 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) return -EINVAL; break; - case 0: - /* No format change, only geometry */ - break; default: return -EINVAL; } diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 66ff174151b5..b6ea67221d1d 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -378,6 +378,9 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, spin_lock_irqsave(&pcdev->lock, flags); + if (*fb_active == NULL) + goto out; + vb = &(*fb_active)->vb; dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); @@ -402,6 +405,7 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, *fb_active = buf; +out: spin_unlock_irqrestore(&pcdev->lock, flags); } diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 1b992b847198..55ea914c7fcd 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c @@ -513,7 +513,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, if (ret >= 0) { ret = pvr2_ctrl_range_check(cptr,*valptr); } - if (maskptr) *maskptr = ~0; + *maskptr = ~0; } else if (cptr->info->type == pvr2_ctl_bool) { ret = parse_token(ptr,len,valptr,boolNames, ARRAY_SIZE(boolNames)); @@ -522,7 +522,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, } else if (ret == 0) { *valptr = (*valptr & 1) ? !0 : 0; } - if (maskptr) *maskptr = 1; + *maskptr = 1; } else if (cptr->info->type == pvr2_ctl_enum) { ret = parse_token( ptr,len,valptr, @@ -531,7 +531,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, if (ret >= 0) { ret = pvr2_ctrl_range_check(cptr,*valptr); } - if (maskptr) *maskptr = ~0; + *maskptr = ~0; } else if (cptr->info->type == pvr2_ctl_bitmask) { ret = parse_tlist( ptr,len,maskptr,valptr, diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index b151c7be8a50..6961c55baf9b 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -393,6 +393,37 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx) dbg("ctx->out_order_1p= %d", ctx->out_order_1p); } +static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) +{ + struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; + + f->dma_offset.y_h = f->offs_h; + if (!variant->pix_hoff) + f->dma_offset.y_h *= (f->fmt->depth >> 3); + + f->dma_offset.y_v = f->offs_v; + + f->dma_offset.cb_h = f->offs_h; + f->dma_offset.cb_v = f->offs_v; + + f->dma_offset.cr_h = f->offs_h; + f->dma_offset.cr_v = f->offs_v; + + if (!variant->pix_hoff) { + if (f->fmt->planes_cnt == 3) { + f->dma_offset.cb_h >>= 1; + f->dma_offset.cr_h >>= 1; + } + if (f->fmt->color == S5P_FIMC_YCBCR420) { + f->dma_offset.cb_v >>= 1; + f->dma_offset.cr_v >>= 1; + } + } + + dbg("in_offset: color= %d, y_h= %d, y_v= %d", + f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v); +} + /** * fimc_prepare_config - check dimensions, operation and color mode * and pre-calculate offset and the scaling coefficients. @@ -406,7 +437,6 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) { struct fimc_frame *s_frame, *d_frame; struct fimc_vid_buffer *buf = NULL; - struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; int ret = 0; s_frame = &ctx->s_frame; @@ -419,61 +449,16 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) swap(d_frame->width, d_frame->height); } - /* Prepare the output offset ratios for scaler. */ - d_frame->dma_offset.y_h = d_frame->offs_h; - if (!variant->pix_hoff) - d_frame->dma_offset.y_h *= (d_frame->fmt->depth >> 3); - - d_frame->dma_offset.y_v = d_frame->offs_v; - - d_frame->dma_offset.cb_h = d_frame->offs_h; - d_frame->dma_offset.cb_v = d_frame->offs_v; - - d_frame->dma_offset.cr_h = d_frame->offs_h; - d_frame->dma_offset.cr_v = d_frame->offs_v; + /* Prepare the DMA offset ratios for scaler. */ + fimc_prepare_dma_offset(ctx, &ctx->s_frame); + fimc_prepare_dma_offset(ctx, &ctx->d_frame); - if (!variant->pix_hoff && d_frame->fmt->planes_cnt == 3) { - d_frame->dma_offset.cb_h >>= 1; - d_frame->dma_offset.cb_v >>= 1; - d_frame->dma_offset.cr_h >>= 1; - d_frame->dma_offset.cr_v >>= 1; - } - - dbg("out offset: color= %d, y_h= %d, y_v= %d", - d_frame->fmt->color, - d_frame->dma_offset.y_h, d_frame->dma_offset.y_v); - - /* Prepare the input offset ratios for scaler. */ - s_frame->dma_offset.y_h = s_frame->offs_h; - if (!variant->pix_hoff) - s_frame->dma_offset.y_h *= (s_frame->fmt->depth >> 3); - s_frame->dma_offset.y_v = s_frame->offs_v; - - s_frame->dma_offset.cb_h = s_frame->offs_h; - s_frame->dma_offset.cb_v = s_frame->offs_v; - - s_frame->dma_offset.cr_h = s_frame->offs_h; - s_frame->dma_offset.cr_v = s_frame->offs_v; - - if (!variant->pix_hoff && s_frame->fmt->planes_cnt == 3) { - s_frame->dma_offset.cb_h >>= 1; - s_frame->dma_offset.cb_v >>= 1; - s_frame->dma_offset.cr_h >>= 1; - s_frame->dma_offset.cr_v >>= 1; - } - - dbg("in offset: color= %d, y_h= %d, y_v= %d", - s_frame->fmt->color, s_frame->dma_offset.y_h, - s_frame->dma_offset.y_v); - - fimc_set_yuv_order(ctx); - - /* Check against the scaler ratio. */ if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) || s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) { err("out of scaler range"); return -EINVAL; } + fimc_set_yuv_order(ctx); } /* Input DMA mode is not allowed when the scaler is disabled. */ @@ -822,7 +807,8 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) } else { v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, "Wrong buffer/video queue type (%d)\n", f->type); - return -EINVAL; + ret = -EINVAL; + goto s_fmt_out; } pix = &f->fmt.pix; @@ -1414,8 +1400,10 @@ static int fimc_probe(struct platform_device *pdev) } fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev)); - if (!fimc->work_queue) + if (!fimc->work_queue) { + ret = -ENOMEM; goto err_irq; + } ret = fimc_register_m2m_device(fimc); if (ret) @@ -1492,6 +1480,7 @@ static struct samsung_fimc_variant fimc2_variant_s5p = { }; static struct samsung_fimc_variant fimc01_variant_s5pv210 = { + .pix_hoff = 1, .has_inp_rot = 1, .has_out_rot = 1, .min_inp_pixsize = 16, @@ -1506,6 +1495,7 @@ static struct samsung_fimc_variant fimc01_variant_s5pv210 = { }; static struct samsung_fimc_variant fimc2_variant_s5pv210 = { + .pix_hoff = 1, .min_inp_pixsize = 16, .min_out_pixsize = 32, diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index ec697fcd406e..bb8d83d8ddaf 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4323,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = { }, [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { /* Beholder Intl. Ltd. 2008 */ - /*Dmitry Belimov <d.belimov@gmail.com> */ - .name = "Beholder BeholdTV Columbus TVFM", + /* Dmitry Belimov <d.belimov@gmail.com> */ + .name = "Beholder BeholdTV Columbus TV/FM", .audio_clock = 0x00187de7, .tuner_type = TUNER_ALPS_TSBE5_PAL, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, + .radio_type = TUNER_TEA5767, + .tuner_addr = 0xc2 >> 1, + .radio_addr = 0xc0 >> 1, .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x000A8004, .inputs = {{ diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c index 5713f3a4b76c..ddd25d32723d 100644 --- a/drivers/media/video/saa7164/saa7164-buffer.c +++ b/drivers/media/video/saa7164/saa7164-buffer.c @@ -136,10 +136,11 @@ ret: int saa7164_buffer_dealloc(struct saa7164_tsport *port, struct saa7164_buffer *buf) { - struct saa7164_dev *dev = port->dev; + struct saa7164_dev *dev; - if ((buf == 0) || (port == 0)) + if (!buf || !port) return SAA_ERR_BAD_PARAMETER; + dev = port->dev; dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf); diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 8bdd940f32e6..2ac85d8984f0 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -486,6 +486,12 @@ static int uvc_parse_format(struct uvc_device *dev, max(frame->dwFrameInterval[0], frame->dwDefaultFrameInterval)); + if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { + frame->bFrameIntervalType = 1; + frame->dwFrameInterval[0] = + frame->dwDefaultFrameInterval; + } + uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n", frame->wWidth, frame->wHeight, 10000000/frame->dwDefaultFrameInterval, @@ -2026,6 +2032,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0 }, + /* Chicony CNF7129 (Asus EEE 100HE) */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x04f2, + .idProduct = 0xb071, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_RESTRICT_FRAME_RATE }, /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -2091,6 +2106,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_PROBE_DEF }, + /* IMC Networks (Medion Akoya) */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x13d3, + .idProduct = 0x5103, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_STREAM_NO_FID }, /* Syntek (HP Spartan) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index bdacf3beabf5..892e0e51916c 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -182,6 +182,7 @@ struct uvc_xu_control { #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 #define UVC_QUIRK_PROBE_DEF 0x00000100 +#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 372b87efcd05..6ff9e4bac3ea 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -393,8 +393,10 @@ void videobuf_dma_contig_free(struct videobuf_queue *q, } /* read() method */ - dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); - mem->vaddr = NULL; + if (mem->vaddr) { + dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); + mem->vaddr = NULL; + } } EXPORT_SYMBOL_GPL(videobuf_dma_contig_free); diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 06f9a9c2a39a..2ad0bc252b0e 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -94,7 +94,7 @@ err: * must free the memory. */ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, - int nr_pages, int offset) + int nr_pages, int offset, size_t size) { struct scatterlist *sglist; int i; @@ -110,12 +110,14 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, /* DMA to highmem pages might not work */ goto highmem; sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset); + size -= PAGE_SIZE - offset; for (i = 1; i < nr_pages; i++) { if (NULL == pages[i]) goto nopage; if (PageHighMem(pages[i])) goto highmem; - sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0); + sg_set_page(&sglist[i], pages[i], min(PAGE_SIZE, size), 0); + size -= min(PAGE_SIZE, size); } return sglist; @@ -170,7 +172,8 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, first = (data & PAGE_MASK) >> PAGE_SHIFT; last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; - dma->offset = data & ~PAGE_MASK; + dma->offset = data & ~PAGE_MASK; + dma->size = size; dma->nr_pages = last-first+1; dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); if (NULL == dma->pages) @@ -252,7 +255,7 @@ int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma) if (dma->pages) { dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages, - dma->offset); + dma->offset, dma->size); } if (dma->vaddr) { dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr, diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 04028a9ee082..428377a5a6f5 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c @@ -429,24 +429,25 @@ static void max8925_irq_sync_unlock(unsigned int irq) irq_tsc = cache_tsc; for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { irq_data = &max8925_irqs[i]; + /* 1 -- disable, 0 -- enable */ switch (irq_data->mask_reg) { case MAX8925_CHG_IRQ1_MASK: - irq_chg[0] &= irq_data->enable; + irq_chg[0] &= ~irq_data->enable; break; case MAX8925_CHG_IRQ2_MASK: - irq_chg[1] &= irq_data->enable; + irq_chg[1] &= ~irq_data->enable; break; case MAX8925_ON_OFF_IRQ1_MASK: - irq_on[0] &= irq_data->enable; + irq_on[0] &= ~irq_data->enable; break; case MAX8925_ON_OFF_IRQ2_MASK: - irq_on[1] &= irq_data->enable; + irq_on[1] &= ~irq_data->enable; break; case MAX8925_RTC_IRQ_MASK: - irq_rtc &= irq_data->enable; + irq_rtc &= ~irq_data->enable; break; case MAX8925_TSC_IRQ_MASK: - irq_tsc &= irq_data->enable; + irq_tsc &= ~irq_data->enable; break; default: dev_err(chip->dev, "wrong IRQ\n"); diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 7dabe4dbd373..294183b6260b 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c @@ -394,8 +394,13 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type) irq = irq - wm831x->irq_base; - if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) - return -EINVAL; + if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { + /* Ignore internal-only IRQs */ + if (irq >= 0 && irq < WM831X_NUM_IRQS) + return 0; + else + return -EINVAL; + } switch (type) { case IRQ_TYPE_EDGE_BOTH: diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c index 714c6b487313..d5f3a3fd2319 100644 --- a/drivers/misc/bh1780gli.c +++ b/drivers/misc/bh1780gli.c @@ -190,7 +190,6 @@ static int __devexit bh1780_remove(struct i2c_client *client) ddata = i2c_get_clientdata(client); sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group); - i2c_set_clientdata(client, NULL); kfree(ddata); return 0; diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 133d51528f8d..513e0a76a4a7 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -413,7 +413,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); } while (prefetch_status); /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(); + gpmc_prefetch_reset(info->gpmc_cs); dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); return 0; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2cc81a54cbf3..77efe462b921 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2,6 +2,9 @@ # Network device configuration # +config HAVE_NET_MACB + bool + menuconfig NETDEVICES default y if UML depends on NET @@ -221,7 +224,7 @@ config MII config MACB tristate "Atmel MACB support" - depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 + depends on HAVE_NET_MACB select PHYLIB help The Atmel MACB ethernet interface is found on many AT32 and AT91 @@ -2428,7 +2431,7 @@ config UGETH_TX_ON_DEMAND config MV643XX_ETH tristate "Marvell Discovery (643XX) and Orion ethernet support" - depends on MV64X60 || PPC32 || PLAT_ORION + depends on (MV64X60 || PPC32 || PLAT_ORION) && INET select INET_LRO select PHYLIB help @@ -2803,7 +2806,7 @@ config NIU config PASEMI_MAC tristate "PA Semi 1/10Gbit MAC" - depends on PPC_PASEMI && PCI + depends on PPC_PASEMI && PCI && INET select PHYLIB select INET_LRO help diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 1e620e287ae0..efeffdf9e5fa 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2170,8 +2170,6 @@ static int __devinit b44_init_one(struct ssb_device *sdev, dev->irq = sdev->irq; SET_ETHTOOL_OPS(dev, &b44_ethtool_ops); - netif_carrier_off(dev); - err = ssb_bus_powerup(sdev->bus, 0); if (err) { dev_err(sdev->dev, @@ -2213,6 +2211,8 @@ static int __devinit b44_init_one(struct ssb_device *sdev, goto err_out_powerdown; } + netif_carrier_off(dev); + ssb_set_drvdata(sdev, dev); /* Chip reset provides power to the b44 MAC & PCI cores, which diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 3b16f62d5606..e953c6ad6e6d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -5164,6 +5164,15 @@ int bond_create(struct net *net, const char *name) res = dev_alloc_name(bond_dev, "bond%d"); if (res < 0) goto out; + } else { + /* + * If we're given a name to register + * we need to ensure that its not already + * registered + */ + res = -EEXIST; + if (__dev_get_by_name(net, name) != NULL) + goto out; } res = register_netdevice(bond_dev); diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index a333b42111b8..6372610ed240 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -533,8 +533,15 @@ static inline void ehea_fill_skb(struct net_device *dev, int length = cqe->num_bytes_transfered - 4; /*remove CRC */ skb_put(skb, length); - skb->ip_summed = CHECKSUM_UNNECESSARY; skb->protocol = eth_type_trans(skb, dev); + + /* The packet was not an IPV4 packet so a complemented checksum was + calculated. The value is found in the Internet Checksum field. */ + if (cqe->status & EHEA_CQE_BLIND_CKSUM) { + skb->ip_summed = CHECKSUM_COMPLETE; + skb->csum = csum_unfold(~cqe->inet_checksum_value); + } else + skb->ip_summed = CHECKSUM_UNNECESSARY; } static inline struct sk_buff *get_skb_by_index(struct sk_buff **skb_array, diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h index f608a6c54af5..38104734a3be 100644 --- a/drivers/net/ehea/ehea_qmr.h +++ b/drivers/net/ehea/ehea_qmr.h @@ -150,6 +150,7 @@ struct ehea_rwqe { #define EHEA_CQE_TYPE_RQ 0x60 #define EHEA_CQE_STAT_ERR_MASK 0x700F #define EHEA_CQE_STAT_FAT_ERR_MASK 0xF +#define EHEA_CQE_BLIND_CKSUM 0x8000 #define EHEA_CQE_STAT_ERR_TCP 0x4000 #define EHEA_CQE_STAT_ERR_IP 0x2000 #define EHEA_CQE_STAT_ERR_CRC 0x1000 diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 768b840aeb6b..cce32d43175f 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -678,24 +678,37 @@ static int fec_enet_mii_probe(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); struct phy_device *phy_dev = NULL; - int ret; + char mdio_bus_id[MII_BUS_ID_SIZE]; + char phy_name[MII_BUS_ID_SIZE + 3]; + int phy_id; fep->phy_dev = NULL; - /* find the first phy */ - phy_dev = phy_find_first(fep->mii_bus); - if (!phy_dev) { - printk(KERN_ERR "%s: no PHY found\n", dev->name); - return -ENODEV; + /* check for attached phy */ + for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) { + if ((fep->mii_bus->phy_mask & (1 << phy_id))) + continue; + if (fep->mii_bus->phy_map[phy_id] == NULL) + continue; + if (fep->mii_bus->phy_map[phy_id]->phy_id == 0) + continue; + strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE); + break; } - /* attach the mac to the phy */ - ret = phy_connect_direct(dev, phy_dev, - &fec_enet_adjust_link, 0, - PHY_INTERFACE_MODE_MII); - if (ret) { - printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return ret; + if (phy_id >= PHY_MAX_ADDR) { + printk(KERN_INFO "%s: no PHY, assuming direct connection " + "to switch\n", dev->name); + strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); + phy_id = 0; + } + + snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); + phy_dev = phy_connect(dev, phy_name, &fec_enet_adjust_link, 0, + PHY_INTERFACE_MODE_MII); + if (IS_ERR(phy_dev)) { + printk(KERN_ERR "%s: could not attach to PHY\n", dev->name); + return PTR_ERR(phy_dev); } /* mask with MAC supported features */ @@ -738,7 +751,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) fep->mii_bus->read = fec_enet_mdio_read; fep->mii_bus->write = fec_enet_mdio_write; fep->mii_bus->reset = fec_enet_mdio_reset; - snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); + snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id + 1); fep->mii_bus->priv = fep; fep->mii_bus->parent = &pdev->dev; @@ -1311,6 +1324,9 @@ fec_probe(struct platform_device *pdev) if (ret) goto failed_mii_init; + /* Carrier starts down, phylib will bring it up */ + netif_carrier_off(ndev); + ret = register_netdev(ndev); if (ret) goto failed_register; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index a0da4a17b025..992db2fa136e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1212,7 +1212,8 @@ static void rtl8169_update_counters(struct net_device *dev) if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) return; - counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); + counters = dma_alloc_coherent(&tp->pci_dev->dev, sizeof(*counters), + &paddr, GFP_KERNEL); if (!counters) return; @@ -1233,7 +1234,8 @@ static void rtl8169_update_counters(struct net_device *dev) RTL_W32(CounterAddrLow, 0); RTL_W32(CounterAddrHigh, 0); - pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); + dma_free_coherent(&tp->pci_dev->dev, sizeof(*counters), counters, + paddr); } static void rtl8169_get_ethtool_stats(struct net_device *dev, @@ -3292,15 +3294,15 @@ static int rtl8169_open(struct net_device *dev) /* * Rx and Tx desscriptors needs 256 bytes alignment. - * pci_alloc_consistent provides more. + * dma_alloc_coherent provides more. */ - tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES, - &tp->TxPhyAddr); + tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES, + &tp->TxPhyAddr, GFP_KERNEL); if (!tp->TxDescArray) goto err_pm_runtime_put; - tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES, - &tp->RxPhyAddr); + tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES, + &tp->RxPhyAddr, GFP_KERNEL); if (!tp->RxDescArray) goto err_free_tx_0; @@ -3334,12 +3336,12 @@ out: err_release_ring_2: rtl8169_rx_clear(tp); err_free_rx_1: - pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, - tp->RxPhyAddr); + dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, + tp->RxPhyAddr); tp->RxDescArray = NULL; err_free_tx_0: - pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, - tp->TxPhyAddr); + dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, + tp->TxPhyAddr); tp->TxDescArray = NULL; err_pm_runtime_put: pm_runtime_put_noidle(&pdev->dev); @@ -3975,7 +3977,7 @@ static void rtl8169_free_rx_skb(struct rtl8169_private *tp, { struct pci_dev *pdev = tp->pci_dev; - pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz, + dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), tp->rx_buf_sz, PCI_DMA_FROMDEVICE); dev_kfree_skb(*sk_buff); *sk_buff = NULL; @@ -4000,7 +4002,7 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct net_device *dev, struct RxDesc *desc, int rx_buf_sz, - unsigned int align) + unsigned int align, gfp_t gfp) { struct sk_buff *skb; dma_addr_t mapping; @@ -4008,13 +4010,13 @@ static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, pad = align ? align : NET_IP_ALIGN; - skb = netdev_alloc_skb(dev, rx_buf_sz + pad); + skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp); if (!skb) goto err_out; skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad); - mapping = pci_map_single(pdev, skb->data, rx_buf_sz, + mapping = dma_map_single(&pdev->dev, skb->data, rx_buf_sz, PCI_DMA_FROMDEVICE); rtl8169_map_to_asic(desc, mapping, rx_buf_sz); @@ -4039,7 +4041,7 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp) } static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, - u32 start, u32 end) + u32 start, u32 end, gfp_t gfp) { u32 cur; @@ -4054,7 +4056,7 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, tp->RxDescArray + i, - tp->rx_buf_sz, tp->align); + tp->rx_buf_sz, tp->align, gfp); if (!skb) break; @@ -4082,7 +4084,7 @@ static int rtl8169_init_ring(struct net_device *dev) memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); - if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC) + if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC) goto err_out; rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); @@ -4099,7 +4101,8 @@ static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, { unsigned int len = tx_skb->len; - pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE); + dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len, + PCI_DMA_TODEVICE); desc->opts1 = 0x00; desc->opts2 = 0x00; desc->addr = 0x00; @@ -4243,7 +4246,8 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, txd = tp->TxDescArray + entry; len = frag->size; addr = ((void *) page_address(frag->page)) + frag->page_offset; - mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE); + mapping = dma_map_single(&tp->pci_dev->dev, addr, len, + PCI_DMA_TODEVICE); /* anti gcc 2.95.3 bugware (sic) */ status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); @@ -4313,7 +4317,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, tp->tx_skb[entry].skb = skb; } - mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE); + mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len, + PCI_DMA_TODEVICE); tp->tx_skb[entry].len = len; txd->addr = cpu_to_le64(mapping); @@ -4477,8 +4482,8 @@ static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, if (!skb) goto out; - pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size, - PCI_DMA_FROMDEVICE); + dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size, + PCI_DMA_FROMDEVICE); skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); *sk_buff = skb; done = true; @@ -4549,11 +4554,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev, rtl8169_rx_csum(skb, desc); if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { - pci_dma_sync_single_for_device(pdev, addr, + dma_sync_single_for_device(&pdev->dev, addr, pkt_size, PCI_DMA_FROMDEVICE); rtl8169_mark_to_asic(desc, tp->rx_buf_sz); } else { - pci_unmap_single(pdev, addr, tp->rx_buf_sz, + dma_unmap_single(&pdev->dev, addr, tp->rx_buf_sz, PCI_DMA_FROMDEVICE); tp->Rx_skbuff[entry] = NULL; } @@ -4583,7 +4588,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, count = cur_rx - tp->cur_rx; tp->cur_rx = cur_rx; - delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); + delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC); if (!delta && count) netif_info(tp, intr, dev, "no Rx buffer allocated\n"); tp->dirty_rx += delta; @@ -4769,10 +4774,10 @@ static int rtl8169_close(struct net_device *dev) free_irq(dev->irq, dev); - pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, - tp->RxPhyAddr); - pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, - tp->TxPhyAddr); + dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, + tp->RxPhyAddr); + dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, + tp->TxPhyAddr); tp->TxDescArray = NULL; tp->RxDescArray = NULL; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 40e5c46e7571..465ae7e84507 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -43,6 +43,7 @@ #include <linux/seq_file.h> #include <linux/mii.h> #include <linux/slab.h> +#include <linux/dmi.h> #include <asm/irq.h> #include "skge.h" @@ -3868,6 +3869,8 @@ static void __devinit skge_show_addr(struct net_device *dev) netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr); } +static int only_32bit_dma; + static int __devinit skge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -3889,7 +3892,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, pci_set_master(pdev); - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + if (!only_32bit_dma && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { using_dac = 1; err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { @@ -4147,8 +4150,21 @@ static struct pci_driver skge_driver = { .shutdown = skge_shutdown, }; +static struct dmi_system_id skge_32bit_dma_boards[] = { + { + .ident = "Gigabyte nForce boards", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co"), + DMI_MATCH(DMI_BOARD_NAME, "nForce"), + }, + }, + {} +}; + static int __init skge_init_module(void) { + if (dmi_check_system(skge_32bit_dma_boards)) + only_32bit_dma = 1; skge_debug_init(); return pci_register_driver(&skge_driver); } diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index bc3af78a869f..1ec4b9e0239a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4666,7 +4666,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) desc_idx, *post_ptr); drop_it_no_recycle: /* Other statistics kept track of by card. */ - tp->net_stats.rx_dropped++; + tp->rx_dropped++; goto next_pkt; } @@ -4726,7 +4726,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) if (len > (tp->dev->mtu + ETH_HLEN) && skb->protocol != htons(ETH_P_8021Q)) { dev_kfree_skb(skb); - goto next_pkt; + goto drop_it_no_recycle; } if (desc->type_flags & RXD_FLAG_VLAN && @@ -9240,6 +9240,8 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, stats->rx_missed_errors = old_stats->rx_missed_errors + get_stat64(&hw_stats->rx_discards); + stats->rx_dropped = tp->rx_dropped; + return stats; } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 4937bd190964..be7ff138a7f9 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2759,7 +2759,7 @@ struct tg3 { /* begin "everything else" cacheline(s) section */ - struct rtnl_link_stats64 net_stats; + unsigned long rx_dropped; struct rtnl_link_stats64 net_stats_prev; struct tg3_ethtool_stats estats; struct tg3_ethtool_stats estats_prev; diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 8cc9e319f435..1737d1488b35 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -1244,16 +1244,16 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) int i, result; struct device *dev = i2400m_dev(i2400m); const struct i2400m_msg_hdr *msg_hdr; - size_t pl_itr, pl_size, skb_len; + size_t pl_itr, pl_size; unsigned long flags; - unsigned num_pls, single_last; + unsigned num_pls, single_last, skb_len; skb_len = skb->len; - d_fnstart(4, dev, "(i2400m %p skb %p [size %zu])\n", + d_fnstart(4, dev, "(i2400m %p skb %p [size %u])\n", i2400m, skb, skb_len); result = -EIO; msg_hdr = (void *) skb->data; - result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb->len); + result = i2400m_rx_msg_hdr_check(i2400m, msg_hdr, skb_len); if (result < 0) goto error_msg_hdr_check; result = -EIO; @@ -1261,10 +1261,10 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ num_pls * sizeof(msg_hdr->pld[0]); pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN); - if (pl_itr > skb->len) { /* got all the payload descriptors? */ + if (pl_itr > skb_len) { /* got all the payload descriptors? */ dev_err(dev, "RX: HW BUG? message too short (%u bytes) for " "%u payload descriptors (%zu each, total %zu)\n", - skb->len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr); + skb_len, num_pls, sizeof(msg_hdr->pld[0]), pl_itr); goto error_pl_descr_short; } /* Walk each payload payload--check we really got it */ @@ -1272,7 +1272,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) /* work around old gcc warnings */ pl_size = i2400m_pld_size(&msg_hdr->pld[i]); result = i2400m_rx_pl_descr_check(i2400m, &msg_hdr->pld[i], - pl_itr, skb->len); + pl_itr, skb_len); if (result < 0) goto error_pl_descr_check; single_last = num_pls == 1 || i == num_pls - 1; @@ -1290,16 +1290,16 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb) if (i < i2400m->rx_pl_min) i2400m->rx_pl_min = i; i2400m->rx_num++; - i2400m->rx_size_acc += skb->len; - if (skb->len < i2400m->rx_size_min) - i2400m->rx_size_min = skb->len; - if (skb->len > i2400m->rx_size_max) - i2400m->rx_size_max = skb->len; + i2400m->rx_size_acc += skb_len; + if (skb_len < i2400m->rx_size_min) + i2400m->rx_size_min = skb_len; + if (skb_len > i2400m->rx_size_max) + i2400m->rx_size_max = skb_len; spin_unlock_irqrestore(&i2400m->rx_lock, flags); error_pl_descr_check: error_pl_descr_short: error_msg_hdr_check: - d_fnend(4, dev, "(i2400m %p skb %p [size %zu]) = %d\n", + d_fnend(4, dev, "(i2400m %p skb %p [size %u]) = %d\n", i2400m, skb, skb_len, result); return result; } diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index cc648b6ae31c..a3d95cca8f0c 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -543,7 +543,7 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah) if (conf_is_ht40(conf)) return clockrate * 2; - return clockrate * 2; + return clockrate; } static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9dd9e64c2b0b..8fd00a6e5120 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -1411,7 +1411,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) clear_bit(STATUS_SCAN_HW, &priv->status); clear_bit(STATUS_SCANNING, &priv->status); /* inform mac80211 scan aborted */ - queue_work(priv->workqueue, &priv->scan_completed); + queue_work(priv->workqueue, &priv->abort_scan); } int iwlagn_manage_ibss_station(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 59a308b02f95..d31661c1ce77 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3018,7 +3018,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) clear_bit(STATUS_SCANNING, &priv->status); /* inform mac80211 scan aborted */ - queue_work(priv->workqueue, &priv->scan_completed); + queue_work(priv->workqueue, &priv->abort_scan); } static void iwl3945_bg_restart(struct work_struct *data) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 89ed181cd90c..857ae01734a6 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -163,6 +163,26 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_d DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); /* + * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear + * for some HT machines to use C4 w/o hanging. + */ +static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev) +{ + u32 pmbase; + u16 pm1a; + + pci_read_config_dword(dev, 0x40, &pmbase); + pmbase = pmbase & 0xff80; + pm1a = inw(pmbase); + + if (pm1a & 0x10) { + dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n"); + outw(0x10, pmbase); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts); + +/* * Chipsets where PCI->PCI transfers vanish or hang */ static void __devinit quirk_nopcipci(struct pci_dev *dev) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 9024480a8228..c44a5e8b8b82 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -51,7 +51,6 @@ * TODO: * - handle CPU hotplug * - provide turbo enable/disable api - * - make sure we can write turbo enable/disable reg based on MISC_EN * * Related documents: * - CDI 403777, 403778 - Auburndale EDS vol 1 & 2 @@ -230,7 +229,7 @@ #define THM_TC2 0xac #define THM_DTV 0xb0 #define THM_ITV 0xd8 -#define ITV_ME_SEQNO_MASK 0x000f0000 /* ME should update every ~200ms */ +#define ITV_ME_SEQNO_MASK 0x00ff0000 /* ME should update every ~200ms */ #define ITV_ME_SEQNO_SHIFT (16) #define ITV_MCH_TEMP_MASK 0x0000ff00 #define ITV_MCH_TEMP_SHIFT (8) @@ -325,6 +324,7 @@ struct ips_driver { bool gpu_preferred; bool poll_turbo_status; bool second_cpu; + bool turbo_toggle_allowed; struct ips_mcp_limits *limits; /* Optional MCH interfaces for if i915 is in use */ @@ -415,7 +415,7 @@ static void ips_cpu_lower(struct ips_driver *ips) new_limit = cur_limit - 8; /* 1W decrease */ /* Clamp to SKU TDP limit */ - if (((new_limit * 10) / 8) < (ips->orig_turbo_limit & TURBO_TDP_MASK)) + if (new_limit < (ips->orig_turbo_limit & TURBO_TDP_MASK)) new_limit = ips->orig_turbo_limit & TURBO_TDP_MASK; thm_writew(THM_MPCPC, (new_limit * 10) / 8); @@ -461,7 +461,8 @@ static void ips_enable_cpu_turbo(struct ips_driver *ips) if (ips->__cpu_turbo_on) return; - on_each_cpu(do_enable_cpu_turbo, ips, 1); + if (ips->turbo_toggle_allowed) + on_each_cpu(do_enable_cpu_turbo, ips, 1); ips->__cpu_turbo_on = true; } @@ -498,7 +499,8 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips) if (!ips->__cpu_turbo_on) return; - on_each_cpu(do_disable_cpu_turbo, ips, 1); + if (ips->turbo_toggle_allowed) + on_each_cpu(do_disable_cpu_turbo, ips, 1); ips->__cpu_turbo_on = false; } @@ -598,17 +600,29 @@ static bool mcp_exceeded(struct ips_driver *ips) { unsigned long flags; bool ret = false; + u32 temp_limit; + u32 avg_power; + const char *msg = "MCP limit exceeded: "; spin_lock_irqsave(&ips->turbo_status_lock, flags); - if (ips->mcp_avg_temp > (ips->mcp_temp_limit * 100)) - ret = true; - if (ips->cpu_avg_power + ips->mch_avg_power > ips->mcp_power_limit) + + temp_limit = ips->mcp_temp_limit * 100; + if (ips->mcp_avg_temp > temp_limit) { + dev_info(&ips->dev->dev, + "%sAvg temp %u, limit %u\n", msg, ips->mcp_avg_temp, + temp_limit); ret = true; - spin_unlock_irqrestore(&ips->turbo_status_lock, flags); + } - if (ret) + avg_power = ips->cpu_avg_power + ips->mch_avg_power; + if (avg_power > ips->mcp_power_limit) { dev_info(&ips->dev->dev, - "MCP power or thermal limit exceeded\n"); + "%sAvg power %u, limit %u\n", msg, avg_power, + ips->mcp_power_limit); + ret = true; + } + + spin_unlock_irqrestore(&ips->turbo_status_lock, flags); return ret; } @@ -663,6 +677,27 @@ static bool mch_exceeded(struct ips_driver *ips) } /** + * verify_limits - verify BIOS provided limits + * @ips: IPS structure + * + * BIOS can optionally provide non-default limits for power and temp. Check + * them here and use the defaults if the BIOS values are not provided or + * are otherwise unusable. + */ +static void verify_limits(struct ips_driver *ips) +{ + if (ips->mcp_power_limit < ips->limits->mcp_power_limit || + ips->mcp_power_limit > 35000) + ips->mcp_power_limit = ips->limits->mcp_power_limit; + + if (ips->mcp_temp_limit < ips->limits->core_temp_limit || + ips->mcp_temp_limit < ips->limits->mch_temp_limit || + ips->mcp_temp_limit > 150) + ips->mcp_temp_limit = min(ips->limits->core_temp_limit, + ips->limits->mch_temp_limit); +} + +/** * update_turbo_limits - get various limits & settings from regs * @ips: IPS driver struct * @@ -680,12 +715,21 @@ static void update_turbo_limits(struct ips_driver *ips) u32 hts = thm_readl(THM_HTS); ips->cpu_turbo_enabled = !(hts & HTS_PCTD_DIS); - ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); + /* + * Disable turbo for now, until we can figure out why the power figures + * are wrong + */ + ips->cpu_turbo_enabled = false; + + if (ips->gpu_busy) + ips->gpu_turbo_enabled = !(hts & HTS_GTD_DIS); + ips->core_power_limit = thm_readw(THM_MPCPC); ips->mch_power_limit = thm_readw(THM_MMGPC); ips->mcp_temp_limit = thm_readw(THM_PTL); ips->mcp_power_limit = thm_readw(THM_MPPC); + verify_limits(ips); /* Ignore BIOS CPU vs GPU pref */ } @@ -858,7 +902,7 @@ static u32 get_cpu_power(struct ips_driver *ips, u32 *last, int period) ret = (ret * 1000) / 65535; *last = val; - return ret; + return 0; } static const u16 temp_decay_factor = 2; @@ -940,7 +984,6 @@ static int ips_monitor(void *data) kfree(mch_samples); kfree(cpu_samples); kfree(mchp_samples); - kthread_stop(ips->adjust); return -ENOMEM; } @@ -948,7 +991,7 @@ static int ips_monitor(void *data) ITV_ME_SEQNO_SHIFT; seqno_timestamp = get_jiffies_64(); - old_cpu_power = thm_readl(THM_CEC) / 65535; + old_cpu_power = thm_readl(THM_CEC); schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD)); /* Collect an initial average */ @@ -1150,11 +1193,18 @@ static irqreturn_t ips_irq_handler(int irq, void *arg) STS_GPL_SHIFT; /* ignore EC CPU vs GPU pref */ ips->cpu_turbo_enabled = !(sts & STS_PCTD_DIS); - ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); + /* + * Disable turbo for now, until we can figure + * out why the power figures are wrong + */ + ips->cpu_turbo_enabled = false; + if (ips->gpu_busy) + ips->gpu_turbo_enabled = !(sts & STS_GTD_DIS); ips->mcp_temp_limit = (sts & STS_PTL_MASK) >> STS_PTL_SHIFT; ips->mcp_power_limit = (tc1 & STS_PPL_MASK) >> STS_PPL_SHIFT; + verify_limits(ips); spin_unlock(&ips->turbo_status_lock); thm_writeb(THM_SEC, SEC_ACK); @@ -1333,8 +1383,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips) * turbo manually or we'll get an illegal MSR access, even though * turbo will still be available. */ - if (!(misc_en & IA32_MISC_TURBO_EN)) - ; /* add turbo MSR write allowed flag if necessary */ + if (misc_en & IA32_MISC_TURBO_EN) + ips->turbo_toggle_allowed = true; + else + ips->turbo_toggle_allowed = false; if (strstr(boot_cpu_data.x86_model_id, "CPU M")) limits = &ips_sv_limits; @@ -1351,9 +1403,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips) tdp = turbo_power & TURBO_TDP_MASK; /* Sanity check TDP against CPU */ - if (limits->mcp_power_limit != (tdp / 8) * 1000) { - dev_warn(&ips->dev->dev, "Warning: CPU TDP doesn't match expected value (found %d, expected %d)\n", - tdp / 8, limits->mcp_power_limit / 1000); + if (limits->core_power_limit != (tdp / 8) * 1000) { + dev_info(&ips->dev->dev, "CPU TDP doesn't match expected value (found %d, expected %d)\n", + tdp / 8, limits->core_power_limit / 1000); + limits->core_power_limit = (tdp / 8) * 1000; } out: @@ -1390,7 +1443,7 @@ static bool ips_get_i915_syms(struct ips_driver *ips) return true; out_put_busy: - symbol_put(i915_gpu_turbo_disable); + symbol_put(i915_gpu_busy); out_put_lower: symbol_put(i915_gpu_lower); out_put_raise: @@ -1532,22 +1585,27 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) /* Save turbo limits & ratios */ rdmsrl(TURBO_POWER_CURRENT_LIMIT, ips->orig_turbo_limit); - ips_enable_cpu_turbo(ips); - ips->cpu_turbo_enabled = true; + ips_disable_cpu_turbo(ips); + ips->cpu_turbo_enabled = false; - /* Set up the work queue and monitor/adjust threads */ - ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor"); - if (IS_ERR(ips->monitor)) { + /* Create thermal adjust thread */ + ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust"); + if (IS_ERR(ips->adjust)) { dev_err(&dev->dev, - "failed to create thermal monitor thread, aborting\n"); + "failed to create thermal adjust thread, aborting\n"); ret = -ENOMEM; goto error_free_irq; + } - ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust"); - if (IS_ERR(ips->adjust)) { + /* + * Set up the work queue and monitor thread. The monitor thread + * will wake up ips_adjust thread. + */ + ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor"); + if (IS_ERR(ips->monitor)) { dev_err(&dev->dev, - "failed to create thermal adjust thread, aborting\n"); + "failed to create thermal monitor thread, aborting\n"); ret = -ENOMEM; goto error_thread_cleanup; } @@ -1566,7 +1624,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) return ret; error_thread_cleanup: - kthread_stop(ips->monitor); + kthread_stop(ips->adjust); error_free_irq: free_irq(ips->dev->irq, ips); error_unmap: diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index df1fb53c09d2..a4be41614eeb 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -256,7 +256,6 @@ static int __devexit ad5398_remove(struct i2c_client *client) regulator_unregister(chip->rdev); kfree(chip); - i2c_set_clientdata(client, NULL); return 0; } diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 422a709d271d..cc8b337b9119 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -700,7 +700,7 @@ static void print_constraints(struct regulator_dev *rdev) constraints->min_uA != constraints->max_uA) { ret = _regulator_get_current_limit(rdev); if (ret > 0) - count += sprintf(buf + count, "at %d uA ", ret / 1000); + count += sprintf(buf + count, "at %d mA ", ret / 1000); } if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) @@ -2302,8 +2302,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, dev_set_name(&rdev->dev, "regulator.%d", atomic_inc_return(®ulator_no) - 1); ret = device_register(&rdev->dev); - if (ret != 0) + if (ret != 0) { + put_device(&rdev->dev); goto clean; + } dev_set_drvdata(&rdev->dev, rdev); diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index d61ecb885a8c..b8cc6389a541 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -191,8 +191,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c) struct isl_pmic *pmic = i2c_get_clientdata(i2c); int i; - i2c_set_clientdata(i2c, NULL); - for (i = 0; i < 3; i++) regulator_unregister(pmic->rdev[i]); diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 4520ace3f7e7..6b60a9c0366b 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -330,7 +330,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, /* set external clock frequency */ info->extclk_freq = pdata->extclk_freq; max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK, - info->extclk_freq); + info->extclk_freq << 6); } if (pdata->ramp_timing) { diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 9daed8db83d3..9de8516e3531 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -268,7 +268,6 @@ out_irq: free_irq(client->irq, client); out_free: - i2c_set_clientdata(client, NULL); kfree(ds3232); return ret; } @@ -287,7 +286,6 @@ static int __devexit ds3232_remove(struct i2c_client *client) } rtc_device_unregister(ds3232->rtc); - i2c_set_clientdata(client, NULL); kfree(ds3232); return 0; } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 12900f7083b0..3198c5335f0b 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -458,6 +458,7 @@ config SERIAL_SAMSUNG_UARTS int depends on ARM && PLAT_SAMSUNG default 2 if ARCH_S3C2400 + default 6 if ARCH_S5P6450 default 4 if SERIAL_SAMSUNG_UARTS_4 default 3 help @@ -526,12 +527,12 @@ config SERIAL_S3C24A0 Serial port support for the Samsung S3C24A0 SoC config SERIAL_S3C6400 - tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100) + tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support" + depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100) select SERIAL_SAMSUNG_UARTS_4 default y help - Serial port support for the Samsung S3C6400, S3C6410, S5P6440 + Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450 and S5PC100 SoCs config SERIAL_S5PV210 diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c index 324c385a653d..5dff45c76d32 100644 --- a/drivers/serial/mfd.c +++ b/drivers/serial/mfd.c @@ -27,6 +27,7 @@ #include <linux/init.h> #include <linux/console.h> #include <linux/sysrq.h> +#include <linux/slab.h> #include <linux/serial_reg.h> #include <linux/circ_buf.h> #include <linux/delay.h> diff --git a/drivers/serial/mrst_max3110.c b/drivers/serial/mrst_max3110.c index f6ad1ecbff79..51c15f58e01e 100644 --- a/drivers/serial/mrst_max3110.c +++ b/drivers/serial/mrst_max3110.c @@ -29,6 +29,7 @@ #include <linux/module.h> #include <linux/ioport.h> +#include <linux/irq.h> #include <linux/init.h> #include <linux/console.h> #include <linux/sysrq.h> diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c index b1156ba8ad14..7ac2bf5167cd 100644 --- a/drivers/serial/samsung.c +++ b/drivers/serial/samsung.c @@ -1101,7 +1101,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); port->mapbase = res->start; - port->membase = S3C_VA_UART + res->start - (S3C_PA_UART & 0xfff00000); + port->membase = S3C_VA_UART + (res->start & 0xfffff); ret = platform_get_irq(platdev, 0); if (ret < 0) port->irq = 0; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 91c2f4f3af10..7e631fa51098 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -143,10 +143,26 @@ config SPI_GPIO GPIO operations, you should be able to leverage that for better speed with a custom version of this driver; see the source code. +config SPI_IMX_VER_IMX1 + def_bool y if SOC_IMX1 + +config SPI_IMX_VER_0_0 + def_bool y if SOC_IMX21 || SOC_IMX27 + +config SPI_IMX_VER_0_4 + def_bool y if ARCH_MX31 + +config SPI_IMX_VER_0_7 + def_bool y if ARCH_MX25 || ARCH_MX35 || ARCH_MX51 + +config SPI_IMX_VER_2_3 + def_bool y if ARCH_MX51 + config SPI_IMX tristate "Freescale i.MX SPI controllers" depends on ARCH_MXC select SPI_BITBANG + default m if IMX_HAVE_PLATFORM_SPI_IMX help This enables using the Freescale i.MX SPI controllers in master mode. diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 0bcf4c1601a2..b5a78a1f4421 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -23,6 +23,7 @@ #include <linux/init.h> #include <linux/cache.h> #include <linux/mutex.h> +#include <linux/of_device.h> #include <linux/slab.h> #include <linux/mod_devicetable.h> #include <linux/spi/spi.h> @@ -86,6 +87,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) const struct spi_device *spi = to_spi_device(dev); const struct spi_driver *sdrv = to_spi_driver(drv); + /* Attempt an OF style match */ + if (of_driver_match_device(dev, drv)) + return 1; + if (sdrv->id_table) return !!spi_match_id(sdrv->id_table, spi); diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c index e24a63498acb..63e51b011d50 100644 --- a/drivers/spi/spi_gpio.c +++ b/drivers/spi/spi_gpio.c @@ -350,7 +350,7 @@ static int __init spi_gpio_probe(struct platform_device *pdev) spi_gpio->bitbang.master = spi_master_get(master); spi_gpio->bitbang.chipselect = spi_gpio_chipselect; - if ((master_flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_RX)) == 0) { + if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 7972e9077473..55a38e2c6c13 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -56,7 +56,28 @@ struct spi_imx_config { unsigned int speed_hz; unsigned int bpw; unsigned int mode; - int cs; + u8 cs; +}; + +enum spi_imx_devtype { + SPI_IMX_VER_IMX1, + SPI_IMX_VER_0_0, + SPI_IMX_VER_0_4, + SPI_IMX_VER_0_5, + SPI_IMX_VER_0_7, + SPI_IMX_VER_2_3, + SPI_IMX_VER_AUTODETECT, +}; + +struct spi_imx_data; + +struct spi_imx_devtype_data { + void (*intctrl)(struct spi_imx_data *, int); + int (*config)(struct spi_imx_data *, struct spi_imx_config *); + void (*trigger)(struct spi_imx_data *); + int (*rx_available)(struct spi_imx_data *); + void (*reset)(struct spi_imx_data *); + unsigned int fifosize; }; struct spi_imx_data { @@ -76,11 +97,7 @@ struct spi_imx_data { const void *tx_buf; unsigned int txfifo; /* number of words pushed in tx FIFO */ - /* SoC specific functions */ - void (*intctrl)(struct spi_imx_data *, int); - int (*config)(struct spi_imx_data *, struct spi_imx_config *); - void (*trigger)(struct spi_imx_data *); - int (*rx_available)(struct spi_imx_data *); + struct spi_imx_devtype_data devtype_data; }; #define MXC_SPI_BUF_RX(type) \ @@ -140,7 +157,7 @@ static unsigned int spi_imx_clkdiv_1(unsigned int fin, return max; } -/* MX1, MX31, MX35 */ +/* MX1, MX31, MX35, MX51 CSPI */ static unsigned int spi_imx_clkdiv_2(unsigned int fin, unsigned int fspi) { @@ -155,6 +172,128 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, return 7; } +#define SPI_IMX2_3_CTRL 0x08 +#define SPI_IMX2_3_CTRL_ENABLE (1 << 0) +#define SPI_IMX2_3_CTRL_XCH (1 << 2) +#define SPI_IMX2_3_CTRL_MODE(cs) (1 << ((cs) + 4)) +#define SPI_IMX2_3_CTRL_POSTDIV_OFFSET 8 +#define SPI_IMX2_3_CTRL_PREDIV_OFFSET 12 +#define SPI_IMX2_3_CTRL_CS(cs) ((cs) << 18) +#define SPI_IMX2_3_CTRL_BL_OFFSET 20 + +#define SPI_IMX2_3_CONFIG 0x0c +#define SPI_IMX2_3_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) +#define SPI_IMX2_3_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4)) +#define SPI_IMX2_3_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8)) +#define SPI_IMX2_3_CONFIG_SSBPOL(cs) (1 << ((cs) + 12)) + +#define SPI_IMX2_3_INT 0x10 +#define SPI_IMX2_3_INT_TEEN (1 << 0) +#define SPI_IMX2_3_INT_RREN (1 << 3) + +#define SPI_IMX2_3_STAT 0x18 +#define SPI_IMX2_3_STAT_RR (1 << 3) + +/* MX51 eCSPI */ +static unsigned int spi_imx2_3_clkdiv(unsigned int fin, unsigned int fspi) +{ + /* + * there are two 4-bit dividers, the pre-divider divides by + * $pre, the post-divider by 2^$post + */ + unsigned int pre, post; + + if (unlikely(fspi > fin)) + return 0; + + post = fls(fin) - fls(fspi); + if (fin > fspi << post) + post++; + + /* now we have: (fin <= fspi << post) with post being minimal */ + + post = max(4U, post) - 4; + if (unlikely(post > 0xf)) { + pr_err("%s: cannot set clock freq: %u (base freq: %u)\n", + __func__, fspi, fin); + return 0xff; + } + + pre = DIV_ROUND_UP(fin, fspi << post) - 1; + + pr_debug("%s: fin: %u, fspi: %u, post: %u, pre: %u\n", + __func__, fin, fspi, post, pre); + return (pre << SPI_IMX2_3_CTRL_PREDIV_OFFSET) | + (post << SPI_IMX2_3_CTRL_POSTDIV_OFFSET); +} + +static void __maybe_unused spi_imx2_3_intctrl(struct spi_imx_data *spi_imx, int enable) +{ + unsigned val = 0; + + if (enable & MXC_INT_TE) + val |= SPI_IMX2_3_INT_TEEN; + + if (enable & MXC_INT_RR) + val |= SPI_IMX2_3_INT_RREN; + + writel(val, spi_imx->base + SPI_IMX2_3_INT); +} + +static void __maybe_unused spi_imx2_3_trigger(struct spi_imx_data *spi_imx) +{ + u32 reg; + + reg = readl(spi_imx->base + SPI_IMX2_3_CTRL); + reg |= SPI_IMX2_3_CTRL_XCH; + writel(reg, spi_imx->base + SPI_IMX2_3_CTRL); +} + +static int __maybe_unused spi_imx2_3_config(struct spi_imx_data *spi_imx, + struct spi_imx_config *config) +{ + u32 ctrl = SPI_IMX2_3_CTRL_ENABLE, cfg = 0; + + /* set master mode */ + ctrl |= SPI_IMX2_3_CTRL_MODE(config->cs); + + /* set clock speed */ + ctrl |= spi_imx2_3_clkdiv(spi_imx->spi_clk, config->speed_hz); + + /* set chip select to use */ + ctrl |= SPI_IMX2_3_CTRL_CS(config->cs); + + ctrl |= (config->bpw - 1) << SPI_IMX2_3_CTRL_BL_OFFSET; + + cfg |= SPI_IMX2_3_CONFIG_SBBCTRL(config->cs); + + if (config->mode & SPI_CPHA) + cfg |= SPI_IMX2_3_CONFIG_SCLKPHA(config->cs); + + if (config->mode & SPI_CPOL) + cfg |= SPI_IMX2_3_CONFIG_SCLKPOL(config->cs); + + if (config->mode & SPI_CS_HIGH) + cfg |= SPI_IMX2_3_CONFIG_SSBPOL(config->cs); + + writel(ctrl, spi_imx->base + SPI_IMX2_3_CTRL); + writel(cfg, spi_imx->base + SPI_IMX2_3_CONFIG); + + return 0; +} + +static int __maybe_unused spi_imx2_3_rx_available(struct spi_imx_data *spi_imx) +{ + return readl(spi_imx->base + SPI_IMX2_3_STAT) & SPI_IMX2_3_STAT_RR; +} + +static void __maybe_unused spi_imx2_3_reset(struct spi_imx_data *spi_imx) +{ + /* drain receive buffer */ + while (spi_imx2_3_rx_available(spi_imx)) + readl(spi_imx->base + MXC_CSPIRXDATA); +} + #define MX31_INTREG_TEEN (1 << 0) #define MX31_INTREG_RREN (1 << 3) @@ -178,7 +317,7 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, * the i.MX35 has a slightly different register layout for bits * we do not use here. */ -static void mx31_intctrl(struct spi_imx_data *spi_imx, int enable) +static void __maybe_unused mx31_intctrl(struct spi_imx_data *spi_imx, int enable) { unsigned int val = 0; @@ -190,7 +329,7 @@ static void mx31_intctrl(struct spi_imx_data *spi_imx, int enable) writel(val, spi_imx->base + MXC_CSPIINT); } -static void mx31_trigger(struct spi_imx_data *spi_imx) +static void __maybe_unused mx31_trigger(struct spi_imx_data *spi_imx) { unsigned int reg; @@ -199,20 +338,16 @@ static void mx31_trigger(struct spi_imx_data *spi_imx) writel(reg, spi_imx->base + MXC_CSPICTRL); } -static int mx31_config(struct spi_imx_data *spi_imx, +static int __maybe_unused spi_imx0_4_config(struct spi_imx_data *spi_imx, struct spi_imx_config *config) { unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; + int cs = spi_imx->chipselect[config->cs]; reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << MX31_CSPICTRL_DR_SHIFT; - if (cpu_is_mx31()) - reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; - else if (cpu_is_mx25() || cpu_is_mx35()) { - reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; - reg |= MX31_CSPICTRL_SSCTL; - } + reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; if (config->mode & SPI_CPHA) reg |= MX31_CSPICTRL_PHA; @@ -220,23 +355,52 @@ static int mx31_config(struct spi_imx_data *spi_imx, reg |= MX31_CSPICTRL_POL; if (config->mode & SPI_CS_HIGH) reg |= MX31_CSPICTRL_SSPOL; - if (config->cs < 0) { - if (cpu_is_mx31()) - reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT; - else if (cpu_is_mx25() || cpu_is_mx35()) - reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; - } + if (cs < 0) + reg |= (cs + 32) << MX31_CSPICTRL_CS_SHIFT; + + writel(reg, spi_imx->base + MXC_CSPICTRL); + + return 0; +} + +static int __maybe_unused spi_imx0_7_config(struct spi_imx_data *spi_imx, + struct spi_imx_config *config) +{ + unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; + int cs = spi_imx->chipselect[config->cs]; + + reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << + MX31_CSPICTRL_DR_SHIFT; + + reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; + reg |= MX31_CSPICTRL_SSCTL; + + if (config->mode & SPI_CPHA) + reg |= MX31_CSPICTRL_PHA; + if (config->mode & SPI_CPOL) + reg |= MX31_CSPICTRL_POL; + if (config->mode & SPI_CS_HIGH) + reg |= MX31_CSPICTRL_SSPOL; + if (cs < 0) + reg |= (cs + 32) << MX35_CSPICTRL_CS_SHIFT; writel(reg, spi_imx->base + MXC_CSPICTRL); return 0; } -static int mx31_rx_available(struct spi_imx_data *spi_imx) +static int __maybe_unused mx31_rx_available(struct spi_imx_data *spi_imx) { return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR; } +static void __maybe_unused spi_imx0_4_reset(struct spi_imx_data *spi_imx) +{ + /* drain receive buffer */ + while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR) + readl(spi_imx->base + MXC_CSPIRXDATA); +} + #define MX27_INTREG_RR (1 << 4) #define MX27_INTREG_TEEN (1 << 9) #define MX27_INTREG_RREN (1 << 13) @@ -250,7 +414,7 @@ static int mx31_rx_available(struct spi_imx_data *spi_imx) #define MX27_CSPICTRL_DR_SHIFT 14 #define MX27_CSPICTRL_CS_SHIFT 19 -static void mx27_intctrl(struct spi_imx_data *spi_imx, int enable) +static void __maybe_unused mx27_intctrl(struct spi_imx_data *spi_imx, int enable) { unsigned int val = 0; @@ -262,7 +426,7 @@ static void mx27_intctrl(struct spi_imx_data *spi_imx, int enable) writel(val, spi_imx->base + MXC_CSPIINT); } -static void mx27_trigger(struct spi_imx_data *spi_imx) +static void __maybe_unused mx27_trigger(struct spi_imx_data *spi_imx) { unsigned int reg; @@ -271,10 +435,11 @@ static void mx27_trigger(struct spi_imx_data *spi_imx) writel(reg, spi_imx->base + MXC_CSPICTRL); } -static int mx27_config(struct spi_imx_data *spi_imx, +static int __maybe_unused mx27_config(struct spi_imx_data *spi_imx, struct spi_imx_config *config) { unsigned int reg = MX27_CSPICTRL_ENABLE | MX27_CSPICTRL_MASTER; + int cs = spi_imx->chipselect[config->cs]; reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz) << MX27_CSPICTRL_DR_SHIFT; @@ -286,19 +451,24 @@ static int mx27_config(struct spi_imx_data *spi_imx, reg |= MX27_CSPICTRL_POL; if (config->mode & SPI_CS_HIGH) reg |= MX27_CSPICTRL_SSPOL; - if (config->cs < 0) - reg |= (config->cs + 32) << MX27_CSPICTRL_CS_SHIFT; + if (cs < 0) + reg |= (cs + 32) << MX27_CSPICTRL_CS_SHIFT; writel(reg, spi_imx->base + MXC_CSPICTRL); return 0; } -static int mx27_rx_available(struct spi_imx_data *spi_imx) +static int __maybe_unused mx27_rx_available(struct spi_imx_data *spi_imx) { return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR; } +static void __maybe_unused spi_imx0_0_reset(struct spi_imx_data *spi_imx) +{ + writel(1, spi_imx->base + MXC_RESET); +} + #define MX1_INTREG_RR (1 << 3) #define MX1_INTREG_TEEN (1 << 8) #define MX1_INTREG_RREN (1 << 11) @@ -310,7 +480,7 @@ static int mx27_rx_available(struct spi_imx_data *spi_imx) #define MX1_CSPICTRL_MASTER (1 << 10) #define MX1_CSPICTRL_DR_SHIFT 13 -static void mx1_intctrl(struct spi_imx_data *spi_imx, int enable) +static void __maybe_unused mx1_intctrl(struct spi_imx_data *spi_imx, int enable) { unsigned int val = 0; @@ -322,7 +492,7 @@ static void mx1_intctrl(struct spi_imx_data *spi_imx, int enable) writel(val, spi_imx->base + MXC_CSPIINT); } -static void mx1_trigger(struct spi_imx_data *spi_imx) +static void __maybe_unused mx1_trigger(struct spi_imx_data *spi_imx) { unsigned int reg; @@ -331,7 +501,7 @@ static void mx1_trigger(struct spi_imx_data *spi_imx) writel(reg, spi_imx->base + MXC_CSPICTRL); } -static int mx1_config(struct spi_imx_data *spi_imx, +static int __maybe_unused mx1_config(struct spi_imx_data *spi_imx, struct spi_imx_config *config) { unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; @@ -350,11 +520,73 @@ static int mx1_config(struct spi_imx_data *spi_imx, return 0; } -static int mx1_rx_available(struct spi_imx_data *spi_imx) +static int __maybe_unused mx1_rx_available(struct spi_imx_data *spi_imx) { return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR; } +static void __maybe_unused mx1_reset(struct spi_imx_data *spi_imx) +{ + writel(1, spi_imx->base + MXC_RESET); +} + +/* + * These version numbers are taken from the Freescale driver. Unfortunately it + * doesn't support i.MX1, so this entry doesn't match the scheme. :-( + */ +static struct spi_imx_devtype_data spi_imx_devtype_data[] __devinitdata = { +#ifdef CONFIG_SPI_IMX_VER_IMX1 + [SPI_IMX_VER_IMX1] = { + .intctrl = mx1_intctrl, + .config = mx1_config, + .trigger = mx1_trigger, + .rx_available = mx1_rx_available, + .reset = mx1_reset, + .fifosize = 8, + }, +#endif +#ifdef CONFIG_SPI_IMX_VER_0_0 + [SPI_IMX_VER_0_0] = { + .intctrl = mx27_intctrl, + .config = mx27_config, + .trigger = mx27_trigger, + .rx_available = mx27_rx_available, + .reset = spi_imx0_0_reset, + .fifosize = 8, + }, +#endif +#ifdef CONFIG_SPI_IMX_VER_0_4 + [SPI_IMX_VER_0_4] = { + .intctrl = mx31_intctrl, + .config = spi_imx0_4_config, + .trigger = mx31_trigger, + .rx_available = mx31_rx_available, + .reset = spi_imx0_4_reset, + .fifosize = 8, + }, +#endif +#ifdef CONFIG_SPI_IMX_VER_0_7 + [SPI_IMX_VER_0_7] = { + .intctrl = mx31_intctrl, + .config = spi_imx0_7_config, + .trigger = mx31_trigger, + .rx_available = mx31_rx_available, + .reset = spi_imx0_4_reset, + .fifosize = 8, + }, +#endif +#ifdef CONFIG_SPI_IMX_VER_2_3 + [SPI_IMX_VER_2_3] = { + .intctrl = spi_imx2_3_intctrl, + .config = spi_imx2_3_config, + .trigger = spi_imx2_3_trigger, + .rx_available = spi_imx2_3_rx_available, + .reset = spi_imx2_3_reset, + .fifosize = 64, + }, +#endif +}; + static void spi_imx_chipselect(struct spi_device *spi, int is_active) { struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master); @@ -370,21 +602,21 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active) static void spi_imx_push(struct spi_imx_data *spi_imx) { - while (spi_imx->txfifo < 8) { + while (spi_imx->txfifo < spi_imx->devtype_data.fifosize) { if (!spi_imx->count) break; spi_imx->tx(spi_imx); spi_imx->txfifo++; } - spi_imx->trigger(spi_imx); + spi_imx->devtype_data.trigger(spi_imx); } static irqreturn_t spi_imx_isr(int irq, void *dev_id) { struct spi_imx_data *spi_imx = dev_id; - while (spi_imx->rx_available(spi_imx)) { + while (spi_imx->devtype_data.rx_available(spi_imx)) { spi_imx->rx(spi_imx); spi_imx->txfifo--; } @@ -398,11 +630,12 @@ static irqreturn_t spi_imx_isr(int irq, void *dev_id) /* No data left to push, but still waiting for rx data, * enable receive data available interrupt. */ - spi_imx->intctrl(spi_imx, MXC_INT_RR); + spi_imx->devtype_data.intctrl( + spi_imx, MXC_INT_RR); return IRQ_HANDLED; } - spi_imx->intctrl(spi_imx, 0); + spi_imx->devtype_data.intctrl(spi_imx, 0); complete(&spi_imx->xfer_done); return IRQ_HANDLED; @@ -417,7 +650,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, config.bpw = t ? t->bits_per_word : spi->bits_per_word; config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; config.mode = spi->mode; - config.cs = spi_imx->chipselect[spi->chip_select]; + config.cs = spi->chip_select; if (!config.speed_hz) config.speed_hz = spi->max_speed_hz; @@ -439,7 +672,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, } else BUG(); - spi_imx->config(spi_imx, &config); + spi_imx->devtype_data.config(spi_imx, &config); return 0; } @@ -458,7 +691,7 @@ static int spi_imx_transfer(struct spi_device *spi, spi_imx_push(spi_imx); - spi_imx->intctrl(spi_imx, MXC_INT_TE); + spi_imx->devtype_data.intctrl(spi_imx, MXC_INT_TE); wait_for_completion(&spi_imx->xfer_done); @@ -485,6 +718,39 @@ static void spi_imx_cleanup(struct spi_device *spi) { } +static struct platform_device_id spi_imx_devtype[] = { + { + .name = DRIVER_NAME, + .driver_data = SPI_IMX_VER_AUTODETECT, + }, { + .name = "imx1-cspi", + .driver_data = SPI_IMX_VER_IMX1, + }, { + .name = "imx21-cspi", + .driver_data = SPI_IMX_VER_0_0, + }, { + .name = "imx25-cspi", + .driver_data = SPI_IMX_VER_0_7, + }, { + .name = "imx27-cspi", + .driver_data = SPI_IMX_VER_0_0, + }, { + .name = "imx31-cspi", + .driver_data = SPI_IMX_VER_0_4, + }, { + .name = "imx35-cspi", + .driver_data = SPI_IMX_VER_0_7, + }, { + .name = "imx51-cspi", + .driver_data = SPI_IMX_VER_0_7, + }, { + .name = "imx51-ecspi", + .driver_data = SPI_IMX_VER_2_3, + }, { + /* sentinel */ + } +}; + static int __devinit spi_imx_probe(struct platform_device *pdev) { struct spi_imx_master *mxc_platform_info; @@ -536,6 +802,31 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) init_completion(&spi_imx->xfer_done); + if (pdev->id_entry->driver_data == SPI_IMX_VER_AUTODETECT) { + if (cpu_is_mx25() || cpu_is_mx35()) + spi_imx->devtype_data = + spi_imx_devtype_data[SPI_IMX_VER_0_7]; + else if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) + spi_imx->devtype_data = + spi_imx_devtype_data[SPI_IMX_VER_0_4]; + else if (cpu_is_mx27() || cpu_is_mx21()) + spi_imx->devtype_data = + spi_imx_devtype_data[SPI_IMX_VER_0_0]; + else if (cpu_is_mx1()) + spi_imx->devtype_data = + spi_imx_devtype_data[SPI_IMX_VER_IMX1]; + else + BUG(); + } else + spi_imx->devtype_data = + spi_imx_devtype_data[pdev->id_entry->driver_data]; + + if (!spi_imx->devtype_data.intctrl) { + dev_err(&pdev->dev, "no support for this device compiled in\n"); + ret = -ENODEV; + goto out_gpio_free; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "can't get platform resource\n"); @@ -567,24 +858,6 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) goto out_iounmap; } - if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) { - spi_imx->intctrl = mx31_intctrl; - spi_imx->config = mx31_config; - spi_imx->trigger = mx31_trigger; - spi_imx->rx_available = mx31_rx_available; - } else if (cpu_is_mx27() || cpu_is_mx21()) { - spi_imx->intctrl = mx27_intctrl; - spi_imx->config = mx27_config; - spi_imx->trigger = mx27_trigger; - spi_imx->rx_available = mx27_rx_available; - } else if (cpu_is_mx1()) { - spi_imx->intctrl = mx1_intctrl; - spi_imx->config = mx1_config; - spi_imx->trigger = mx1_trigger; - spi_imx->rx_available = mx1_rx_available; - } else - BUG(); - spi_imx->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(spi_imx->clk)) { dev_err(&pdev->dev, "unable to get clock\n"); @@ -595,15 +868,9 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) clk_enable(spi_imx->clk); spi_imx->spi_clk = clk_get_rate(spi_imx->clk); - if (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) - writel(1, spi_imx->base + MXC_RESET); - - /* drain receive buffer */ - if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) - while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR) - readl(spi_imx->base + MXC_CSPIRXDATA); + spi_imx->devtype_data.reset(spi_imx); - spi_imx->intctrl(spi_imx, 0); + spi_imx->devtype_data.intctrl(spi_imx, 0); ret = spi_bitbang_start(&spi_imx->bitbang); if (ret) { @@ -668,6 +935,7 @@ static struct platform_driver spi_imx_driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, }, + .id_table = spi_imx_devtype, .probe = spi_imx_probe, .remove = __devexit_p(spi_imx_remove), }; diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index d31b57f7baaf..1dd86b835cd8 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -408,11 +408,17 @@ static void mpc8xxx_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi) xfer_ofs = mspi->xfer_in_progress->len - mspi->count; - out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); + if (mspi->rx_dma == mspi->dma_dummy_rx) + out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma); + else + out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); out_be16(&rx_bd->cbd_datlen, 0); out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); - out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); + if (mspi->tx_dma == mspi->dma_dummy_tx) + out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma); + else + out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); out_be16(&tx_bd->cbd_datlen, xfer_len); out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | BD_SC_LAST); diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig index c725356cc346..de7ebb99d8f6 100644 --- a/drivers/staging/tm6000/Kconfig +++ b/drivers/staging/tm6000/Kconfig @@ -1,6 +1,6 @@ config VIDEO_TM6000 tristate "TV Master TM5600/6000/6010 driver" - depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL + depends on VIDEO_DEV && I2C && INPUT && IR_CORE && USB && EXPERIMENTAL select VIDEO_TUNER select MEDIA_TUNER_XC2028 select MEDIA_TUNER_XC5000 diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c index 32f7a0af6938..54f7667cc706 100644 --- a/drivers/staging/tm6000/tm6000-input.c +++ b/drivers/staging/tm6000/tm6000-input.c @@ -46,7 +46,7 @@ MODULE_PARM_DESC(enable_ir, "enable ir (default is enable"); } struct tm6000_ir_poll_result { - u8 rc_data[4]; + u16 rc_data; }; struct tm6000_IR { @@ -60,9 +60,9 @@ struct tm6000_IR { int polling; struct delayed_work work; u8 wait:1; + u8 key:1; struct urb *int_urb; u8 *urb_data; - u8 key:1; int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); @@ -122,13 +122,14 @@ static void tm6000_ir_urb_received(struct urb *urb) if (urb->status != 0) printk(KERN_INFO "not ready\n"); - else if (urb->actual_length > 0) + else if (urb->actual_length > 0) { memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); - dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], - ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); + dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], + ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); - ir->key = 1; + ir->key = 1; + } rc = usb_submit_urb(urb, GFP_ATOMIC); } @@ -140,30 +141,47 @@ static int default_polling_getkey(struct tm6000_IR *ir, int rc; u8 buf[2]; - if (ir->wait && !&dev->int_in) { - poll_result->rc_data[0] = 0xff; + if (ir->wait && !&dev->int_in) return 0; - } if (&dev->int_in) { - poll_result->rc_data[0] = ir->urb_data[0]; - poll_result->rc_data[1] = ir->urb_data[1]; + if (ir->ir.ir_type == IR_TYPE_RC5) + poll_result->rc_data = ir->urb_data[0]; + else + poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8; } else { tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); msleep(10); tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); msleep(10); - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 1); + if (ir->ir.ir_type == IR_TYPE_RC5) { + rc = tm6000_read_write_usb(dev, USB_DIR_IN | + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + REQ_02_GET_IR_CODE, 0, 0, buf, 1); - msleep(10); + msleep(10); - dprintk("read data=%02x\n", buf[0]); - if (rc < 0) - return rc; + dprintk("read data=%02x\n", buf[0]); + if (rc < 0) + return rc; - poll_result->rc_data[0] = buf[0]; + poll_result->rc_data = buf[0]; + } else { + rc = tm6000_read_write_usb(dev, USB_DIR_IN | + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + REQ_02_GET_IR_CODE, 0, 0, buf, 2); + + msleep(10); + + dprintk("read data=%04x\n", buf[0] | buf[1] << 8); + if (rc < 0) + return rc; + + poll_result->rc_data = buf[0] | buf[1] << 8; + } + if ((poll_result->rc_data & 0x00ff) != 0xff) + ir->key = 1; } return 0; } @@ -180,12 +198,11 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir) return; } - dprintk("ir->get_key result data=%02x %02x\n", - poll_result.rc_data[0], poll_result.rc_data[1]); + dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); - if (poll_result.rc_data[0] != 0xff && ir->key == 1) { + if (ir->key) { ir_input_keydown(ir->input->input_dev, &ir->ir, - poll_result.rc_data[0] | poll_result.rc_data[1] << 8); + (u32)poll_result.rc_data); ir_input_nokey(ir->input->input_dev, &ir->ir); ir->key = 0; diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 418163894775..afef7b0a4195 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -24,6 +24,7 @@ #include <linux/platform_device.h> #include <linux/clk.h> #include <mach/ohci.h> +#include <mach/pxa3xx-u2d.h> /* * UHC: USB Host Controller (OHCI-like) register definitions @@ -235,6 +236,9 @@ static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev) if (retval < 0) return retval; + if (cpu_is_pxa3xx()) + pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self); + uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE; __raw_writel(uhchr, ohci->mmio_base + UHCHR); __raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE); @@ -251,6 +255,9 @@ static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev) inf = dev->platform_data; + if (cpu_is_pxa3xx()) + pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self); + if (inf->exit) inf->exit(dev); diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c index a31a77ff6f3d..cea6403ae71c 100644 --- a/drivers/video/pxa168fb.c +++ b/drivers/video/pxa168fb.c @@ -784,12 +784,53 @@ failed: return ret; } +static int __devexit pxa168fb_remove(struct platform_device *pdev) +{ + struct pxa168fb_info *fbi = platform_get_drvdata(pdev); + struct fb_info *info; + int irq; + unsigned int data; + + if (!fbi) + return 0; + + /* disable DMA transfer */ + data = readl(fbi->reg_base + LCD_SPU_DMA_CTRL0); + data &= ~CFG_GRA_ENA_MASK; + writel(data, fbi->reg_base + LCD_SPU_DMA_CTRL0); + + info = fbi->info; + + unregister_framebuffer(info); + + writel(GRA_FRAME_IRQ0_ENA(0x0), fbi->reg_base + SPU_IRQ_ENA); + + if (info->cmap.len) + fb_dealloc_cmap(&info->cmap); + + irq = platform_get_irq(pdev, 0); + free_irq(irq, fbi); + + dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len), + info->screen_base, info->fix.smem_start); + + iounmap(fbi->reg_base); + + clk_disable(fbi->clk); + clk_put(fbi->clk); + + framebuffer_release(info); + + return 0; +} + static struct platform_driver pxa168fb_driver = { .driver = { .name = "pxa168-fb", .owner = THIS_MODULE, }, .probe = pxa168fb_probe, + .remove = __devexit_p(pxa168fb_remove), }; static int __init pxa168fb_init(void) @@ -798,6 +839,12 @@ static int __init pxa168fb_init(void) } module_init(pxa168fb_init); +static void __exit pxa168fb_exit(void) +{ + platform_driver_unregister(&pxa168fb_driver); +} +module_exit(pxa168fb_exit); + MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com> " "Green Wan <gwan@marvell.com>"); MODULE_DESCRIPTION("Framebuffer driver for PXA168/910"); diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 29bac5118877..d409495876f1 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -755,7 +755,10 @@ int register_xenstore_notifier(struct notifier_block *nb) { int ret = 0; - blocking_notifier_chain_register(&xenstore_chain, nb); + if (xenstored_ready > 0) + ret = nb->notifier_call(nb, 0, NULL); + else + blocking_notifier_chain_register(&xenstore_chain, nb); return ret; } @@ -769,7 +772,7 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_notifier); void xenbus_probe(struct work_struct *unused) { - BUG_ON((xenstored_ready <= 0)); + xenstored_ready = 1; /* Enumerate devices in xenstore and watch for changes. */ xenbus_probe_devices(&xenbus_frontend); @@ -835,8 +838,8 @@ static int __init xenbus_init(void) xen_store_evtchn = xen_start_info->store_evtchn; xen_store_mfn = xen_start_info->store_mfn; xen_store_interface = mfn_to_virt(xen_store_mfn); + xenstored_ready = 1; } - xenstored_ready = 1; } /* Initialize the interface to xenstore. */ diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index f96eff04e11a..a6395bdb26ae 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -134,10 +134,6 @@ static int aout_core_dump(struct coredump_params *cprm) if (!dump_write(file, dump_start, dump_size)) goto end_coredump; } -/* Finally dump the task struct. Not be used by gdb, but could be useful */ - set_fs(KERNEL_DS); - if (!dump_write(file, current, sizeof(*current))) - goto end_coredump; end_coredump: set_fs(fs); return has_dumped; diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 73c153092f72..5e9da996a151 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2283,7 +2283,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, { struct ceph_inode_info *ci = ceph_inode(inode); int mds = session->s_mds; - int seq = le32_to_cpu(grant->seq); + unsigned seq = le32_to_cpu(grant->seq); + unsigned issue_seq = le32_to_cpu(grant->issue_seq); int newcaps = le32_to_cpu(grant->caps); int issued, implemented, used, wanted, dirty; u64 size = le64_to_cpu(grant->size); @@ -2295,8 +2296,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, int revoked_rdcache = 0; int queue_invalidate = 0; - dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", - inode, cap, mds, seq, ceph_cap_string(newcaps)); + dout("handle_cap_grant inode %p cap %p mds%d seq %u/%u %s\n", + inode, cap, mds, seq, issue_seq, ceph_cap_string(newcaps)); dout(" size %llu max_size %llu, i_size %llu\n", size, max_size, inode->i_size); @@ -2392,6 +2393,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, } cap->seq = seq; + cap->issue_seq = issue_seq; /* file layout may have changed */ ci->i_layout = grant->layout; @@ -2774,15 +2776,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, if (op == CEPH_CAP_OP_IMPORT) __queue_cap_release(session, vino.ino, cap_id, mseq, seq); - - /* - * send any full release message to try to move things - * along for the mds (who clearly thinks we still have this - * cap). - */ - ceph_add_cap_releases(mdsc, session); - ceph_send_cap_releases(mdsc, session); - goto done; + goto flush_cap_releases; } /* these will work even if we don't have a cap yet */ @@ -2810,7 +2804,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, dout(" no cap on %p ino %llx.%llx from mds%d\n", inode, ceph_ino(inode), ceph_snap(inode), mds); spin_unlock(&inode->i_lock); - goto done; + goto flush_cap_releases; } /* note that each of these drops i_lock for us */ @@ -2834,6 +2828,17 @@ void ceph_handle_caps(struct ceph_mds_session *session, ceph_cap_op_name(op)); } + goto done; + +flush_cap_releases: + /* + * send any full release message to try to move things + * along for the mds (who clearly thinks we still have this + * cap). + */ + ceph_add_cap_releases(mdsc, session); + ceph_send_cap_releases(mdsc, session); + done: mutex_unlock(&session->s_mutex); done_unlocked: diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 4480cb1c63e7..e38423e82f2e 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c @@ -42,32 +42,37 @@ struct ceph_nfs_confh { static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, int connectable) { + int type; struct ceph_nfs_fh *fh = (void *)rawfh; struct ceph_nfs_confh *cfh = (void *)rawfh; struct dentry *parent = dentry->d_parent; struct inode *inode = dentry->d_inode; - int type; + int connected_handle_length = sizeof(*cfh)/4; + int handle_length = sizeof(*fh)/4; /* don't re-export snaps */ if (ceph_snap(inode) != CEPH_NOSNAP) return -EINVAL; - if (*max_len >= sizeof(*cfh)) { + if (*max_len >= connected_handle_length) { dout("encode_fh %p connectable\n", dentry); cfh->ino = ceph_ino(dentry->d_inode); cfh->parent_ino = ceph_ino(parent->d_inode); cfh->parent_name_hash = parent->d_name.hash; - *max_len = sizeof(*cfh); + *max_len = connected_handle_length; type = 2; - } else if (*max_len > sizeof(*fh)) { - if (connectable) - return -ENOSPC; + } else if (*max_len >= handle_length) { + if (connectable) { + *max_len = connected_handle_length; + return 255; + } dout("encode_fh %p\n", dentry); fh->ino = ceph_ino(dentry->d_inode); - *max_len = sizeof(*fh); + *max_len = handle_length; type = 1; } else { - return -ENOSPC; + *max_len = handle_length; + return 255; } return type; } diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 8c044a4f0457..66e4da6dba22 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -697,7 +697,7 @@ more: * start_request so that a tid has been assigned. */ spin_lock(&ci->i_unsafe_lock); - list_add(&ci->i_unsafe_writes, &req->r_unsafe_item); + list_add(&req->r_unsafe_item, &ci->i_unsafe_writes); spin_unlock(&ci->i_unsafe_lock); ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR); } diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index dfced1dacbcd..3b5571b8ce22 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c @@ -549,7 +549,7 @@ static void __unregister_request(struct ceph_osd_client *osdc, */ static void __cancel_request(struct ceph_osd_request *req) { - if (req->r_sent) { + if (req->r_sent && req->r_osd) { ceph_con_revoke(&req->r_osd->o_con, req->r_request); req->r_sent = 0; } diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c65c3419dd37..7e83b356cc9e 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -232,7 +232,7 @@ static int small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, void **request_buf) { - int rc = 0; + int rc; rc = cifs_reconnect_tcon(tcon, smb_command); if (rc) @@ -250,7 +250,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, if (tcon != NULL) cifs_stats_inc(&tcon->num_smbs_sent); - return rc; + return 0; } int @@ -281,16 +281,9 @@ small_smb_init_no_tc(const int smb_command, const int wct, /* If the return code is zero, this function must fill in request_buf pointer */ static int -smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, - void **request_buf /* returned */ , - void **response_buf /* returned */ ) +__smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, + void **request_buf, void **response_buf) { - int rc = 0; - - rc = cifs_reconnect_tcon(tcon, smb_command); - if (rc) - return rc; - *request_buf = cifs_buf_get(); if (*request_buf == NULL) { /* BB should we add a retry in here if not a writepage? */ @@ -309,7 +302,31 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, if (tcon != NULL) cifs_stats_inc(&tcon->num_smbs_sent); - return rc; + return 0; +} + +/* If the return code is zero, this function must fill in request_buf pointer */ +static int +smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, + void **request_buf, void **response_buf) +{ + int rc; + + rc = cifs_reconnect_tcon(tcon, smb_command); + if (rc) + return rc; + + return __smb_init(smb_command, wct, tcon, request_buf, response_buf); +} + +static int +smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon, + void **request_buf, void **response_buf) +{ + if (tcon->ses->need_reconnect || tcon->need_reconnect) + return -EHOSTDOWN; + + return __smb_init(smb_command, wct, tcon, request_buf, response_buf); } static int validate_t2(struct smb_t2_rsp *pSMB) @@ -4534,8 +4551,8 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) cFYI(1, "In QFSUnixInfo"); QFSUnixRetry: - rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, - (void **) &pSMBr); + rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, + (void **) &pSMB, (void **) &pSMBr); if (rc) return rc; @@ -4604,8 +4621,8 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) cFYI(1, "In SETFSUnixInfo"); SETFSUnixRetry: /* BB switch to small buf init to save memory */ - rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, - (void **) &pSMBr); + rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, + (void **) &pSMB, (void **) &pSMBr); if (rc) return rc; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 93f77d438d3c..53cce8cc2224 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -801,6 +801,8 @@ retry_iget5_locked: inode->i_flags |= S_NOATIME | S_NOCMTIME; if (inode->i_state & I_NEW) { inode->i_ino = hash; + if (S_ISREG(inode->i_mode)) + inode->i_data.backing_dev_info = sb->s_bdi; #ifdef CONFIG_CIFS_FSCACHE /* initialize per-inode cache cookie pointer */ CIFS_I(inode)->fscache = NULL; diff --git a/fs/exec.c b/fs/exec.c index 828dd2461d6b..03278c984ba0 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -2014,3 +2014,41 @@ fail_creds: fail: return; } + +/* + * Core dumping helper functions. These are the only things you should + * do on a core-file: use only these functions to write out all the + * necessary info. + */ +int dump_write(struct file *file, const void *addr, int nr) +{ + return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr; +} + +int dump_seek(struct file *file, loff_t off) +{ + int ret = 1; + + if (file->f_op->llseek && file->f_op->llseek != no_llseek) { + if (file->f_op->llseek(file, off, SEEK_CUR) < 0) + return 0; + } else { + char *buf = (char *)get_zeroed_page(GFP_KERNEL); + + if (!buf) + return 0; + while (off > 0) { + unsigned long n = off; + + if (n > PAGE_SIZE) + n = PAGE_SIZE; + if (!dump_write(file, buf, n)) { + ret = 0; + break; + } + off -= n; + } + free_page((unsigned long)buf); + } + return ret; +} diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index eb7368ebd8cd..3eadd97324b1 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -54,6 +54,9 @@ struct page_collect { unsigned nr_pages; unsigned long length; loff_t pg_first; /* keep 64bit also in 32-arches */ + bool read_4_write; /* This means two things: that the read is sync + * And the pages should not be unlocked. + */ }; static void _pcol_init(struct page_collect *pcol, unsigned expected_pages, @@ -71,6 +74,7 @@ static void _pcol_init(struct page_collect *pcol, unsigned expected_pages, pcol->nr_pages = 0; pcol->length = 0; pcol->pg_first = -1; + pcol->read_4_write = false; } static void _pcol_reset(struct page_collect *pcol) @@ -347,7 +351,8 @@ static int readpage_strip(void *data, struct page *page) if (PageError(page)) ClearPageError(page); - unlock_page(page); + if (!pcol->read_4_write) + unlock_page(page); EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," " splitting\n", inode->i_ino, page->index); @@ -428,6 +433,7 @@ static int _readpage(struct page *page, bool is_sync) /* readpage_strip might call read_exec(,is_sync==false) at several * places but not if we have a single page. */ + pcol.read_4_write = is_sync; ret = readpage_strip(&pcol, page); if (ret) { EXOFS_ERR("_readpage => %d\n", ret); diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 5581122bd2c0..ab38fef1c9a1 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -72,22 +72,11 @@ int writeback_in_progress(struct backing_dev_info *bdi) static inline struct backing_dev_info *inode_to_bdi(struct inode *inode) { struct super_block *sb = inode->i_sb; - struct backing_dev_info *bdi = inode->i_mapping->backing_dev_info; - /* - * For inodes on standard filesystems, we use superblock's bdi. For - * inodes on virtual filesystems, we want to use inode mapping's bdi - * because they can possibly point to something useful (think about - * block_dev filesystem). - */ - if (sb->s_bdi && sb->s_bdi != &noop_backing_dev_info) { - /* Some device inodes could play dirty tricks. Catch them... */ - WARN(bdi != sb->s_bdi && bdi_cap_writeback_dirty(bdi), - "Dirtiable inode bdi %s != sb bdi %s\n", - bdi->name, sb->s_bdi->name); - return sb->s_bdi; - } - return bdi; + if (strcmp(sb->s_type->name, "bdev") == 0) + return inode->i_mapping->backing_dev_info; + + return sb->s_bdi; } static void bdi_queue_work(struct backing_dev_info *bdi, diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index d367af1514ef..cde755cca564 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1354,7 +1354,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, loff_t file_size; unsigned int num; unsigned int offset; - size_t total_len; + size_t total_len = 0; req = fuse_get_req(fc); if (IS_ERR(req)) diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index cdfb8c6a4206..c16f8d8331b5 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -196,8 +196,6 @@ fh_lock(struct svc_fh *fhp) static inline void fh_unlock(struct svc_fh *fhp) { - BUG_ON(!fhp->fh_dentry); - if (fhp->fh_locked) { fill_post_wcc(fhp); mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex); diff --git a/fs/notify/Kconfig b/fs/notify/Kconfig index 22c629eedd82..b388443c3a09 100644 --- a/fs/notify/Kconfig +++ b/fs/notify/Kconfig @@ -3,4 +3,4 @@ config FSNOTIFY source "fs/notify/dnotify/Kconfig" source "fs/notify/inotify/Kconfig" -source "fs/notify/fanotify/Kconfig" +#source "fs/notify/fanotify/Kconfig" diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index 32499d213fc4..9975457c981f 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c @@ -128,7 +128,7 @@ static void *ocfs2_fast_follow_link(struct dentry *dentry, } /* Fast symlinks can't be large */ - len = strlen(target); + len = strnlen(target, ocfs2_fast_symlink_chars(inode->i_sb)); link = kzalloc(len + 1, GFP_NOFS); if (!link) { status = -ENOMEM; diff --git a/fs/proc/base.c b/fs/proc/base.c index a1c43e7c8a7b..8e4addaa5424 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2675,7 +2675,7 @@ static const struct pid_entry tgid_base_stuff[] = { INF("auxv", S_IRUSR, proc_pid_auxv), ONE("status", S_IRUGO, proc_pid_status), ONE("personality", S_IRUSR, proc_pid_personality), - INF("limits", S_IRUSR, proc_pid_limits), + INF("limits", S_IRUGO, proc_pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), #endif @@ -3011,7 +3011,7 @@ static const struct pid_entry tid_base_stuff[] = { INF("auxv", S_IRUSR, proc_pid_auxv), ONE("status", S_IRUGO, proc_pid_status), ONE("personality", S_IRUSR, proc_pid_personality), - INF("limits", S_IRUSR, proc_pid_limits), + INF("limits", S_IRUGO, proc_pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), #endif diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index f53505de0712..5cbb81e134ac 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -170,6 +170,7 @@ int reiserfs_prepare_write(struct file *f, struct page *page, int reiserfs_unpack(struct inode *inode, struct file *filp) { int retval = 0; + int depth; int index; struct page *page; struct address_space *mapping; @@ -188,8 +189,8 @@ int reiserfs_unpack(struct inode *inode, struct file *filp) /* we need to make sure nobody is changing the file size beneath ** us */ - mutex_lock(&inode->i_mutex); - reiserfs_write_lock(inode->i_sb); + reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb); + depth = reiserfs_write_lock_once(inode->i_sb); write_from = inode->i_size & (blocksize - 1); /* if we are on a block boundary, we are already unpacked. */ @@ -224,6 +225,6 @@ int reiserfs_unpack(struct inode *inode, struct file *filp) out: mutex_unlock(&inode->i_mutex); - reiserfs_write_unlock(inode->i_sb); + reiserfs_write_unlock_once(inode->i_sb, depth); return retval; } diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index d59c4a65d492..81976ffed7d6 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -668,14 +668,11 @@ xfs_inode_set_reclaim_tag( xfs_perag_put(pag); } -void -__xfs_inode_clear_reclaim_tag( - xfs_mount_t *mp, +STATIC void +__xfs_inode_clear_reclaim( xfs_perag_t *pag, xfs_inode_t *ip) { - radix_tree_tag_clear(&pag->pag_ici_root, - XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG); pag->pag_ici_reclaimable--; if (!pag->pag_ici_reclaimable) { /* clear the reclaim tag from the perag radix tree */ @@ -689,6 +686,17 @@ __xfs_inode_clear_reclaim_tag( } } +void +__xfs_inode_clear_reclaim_tag( + xfs_mount_t *mp, + xfs_perag_t *pag, + xfs_inode_t *ip) +{ + radix_tree_tag_clear(&pag->pag_ici_root, + XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG); + __xfs_inode_clear_reclaim(pag, ip); +} + /* * Inodes in different states need to be treated differently, and the return * value of xfs_iflush is not sufficient to get this right. The following table @@ -838,6 +846,7 @@ reclaim: if (!radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino))) ASSERT(0); + __xfs_inode_clear_reclaim(pag, ip); write_unlock(&pag->pag_ici_lock); /* diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index ed575fb4b495..7e206fc1fa36 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -405,9 +405,15 @@ xlog_cil_push( new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); new_ctx->ticket = xlog_cil_ticket_alloc(log); - /* lock out transaction commit, but don't block on background push */ + /* + * Lock out transaction commit, but don't block for background pushes + * unless we are well over the CIL space limit. See the definition of + * XLOG_CIL_HARD_SPACE_LIMIT() for the full explanation of the logic + * used here. + */ if (!down_write_trylock(&cil->xc_ctx_lock)) { - if (!push_seq) + if (!push_seq && + cil->xc_ctx->space_used < XLOG_CIL_HARD_SPACE_LIMIT(log)) goto out_free_ticket; down_write(&cil->xc_ctx_lock); } @@ -422,7 +428,7 @@ xlog_cil_push( goto out_skip; /* check for a previously pushed seqeunce */ - if (push_seq < cil->xc_ctx->sequence) + if (push_seq && push_seq < cil->xc_ctx->sequence) goto out_skip; /* diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index ced52b98b322..edcdfe01617f 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -426,13 +426,13 @@ struct xfs_cil { }; /* - * The amount of log space we should the CIL to aggregate is difficult to size. - * Whatever we chose we have to make we can get a reservation for the log space - * effectively, that it is large enough to capture sufficient relogging to - * reduce log buffer IO significantly, but it is not too large for the log or - * induces too much latency when writing out through the iclogs. We track both - * space consumed and the number of vectors in the checkpoint context, so we - * need to decide which to use for limiting. + * The amount of log space we allow the CIL to aggregate is difficult to size. + * Whatever we choose, we have to make sure we can get a reservation for the + * log space effectively, that it is large enough to capture sufficient + * relogging to reduce log buffer IO significantly, but it is not too large for + * the log or induces too much latency when writing out through the iclogs. We + * track both space consumed and the number of vectors in the checkpoint + * context, so we need to decide which to use for limiting. * * Every log buffer we write out during a push needs a header reserved, which * is at least one sector and more for v2 logs. Hence we need a reservation of @@ -459,16 +459,21 @@ struct xfs_cil { * checkpoint transaction ticket is specific to the checkpoint context, rather * than the CIL itself. * - * With dynamic reservations, we can basically make up arbitrary limits for the - * checkpoint size so long as they don't violate any other size rules. Hence - * the initial maximum size for the checkpoint transaction will be set to a - * quarter of the log or 8MB, which ever is smaller. 8MB is an arbitrary limit - * right now based on the latency of writing out a large amount of data through - * the circular iclog buffers. + * With dynamic reservations, we can effectively make up arbitrary limits for + * the checkpoint size so long as they don't violate any other size rules. + * Recovery imposes a rule that no transaction exceed half the log, so we are + * limited by that. Furthermore, the log transaction reservation subsystem + * tries to keep 25% of the log free, so we need to keep below that limit or we + * risk running out of free log space to start any new transactions. + * + * In order to keep background CIL push efficient, we will set a lower + * threshold at which background pushing is attempted without blocking current + * transaction commits. A separate, higher bound defines when CIL pushes are + * enforced to ensure we stay within our maximum checkpoint size bounds. + * threshold, yet give us plenty of space for aggregation on large logs. */ - -#define XLOG_CIL_SPACE_LIMIT(log) \ - (min((log->l_logsize >> 2), (8 * 1024 * 1024))) +#define XLOG_CIL_SPACE_LIMIT(log) (log->l_logsize >> 3) +#define XLOG_CIL_HARD_SPACE_LIMIT(log) (3 * (log->l_logsize >> 4)) /* * The reservation head lsn is not made up of a cycle number and block number. diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index c0786d446a00..984cdc62e30b 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -55,7 +55,7 @@ extern u8 acpi_gbl_permanent_mmap; /* - * Globals that are publically available, allowing for + * Globals that are publicly available, allowing for * run time configuration */ extern u32 acpi_dbg_level; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 7809d230adee..4c9461a4f9e6 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -612,7 +612,7 @@ struct drm_gem_object { struct kref refcount; /** Handle count of this object. Each handle also holds a reference */ - struct kref handlecount; + atomic_t handle_count; /* number of handles on this object */ /** Related drm device */ struct drm_device *dev; @@ -808,7 +808,6 @@ struct drm_driver { */ int (*gem_init_object) (struct drm_gem_object *obj); void (*gem_free_object) (struct drm_gem_object *obj); - void (*gem_free_object_unlocked) (struct drm_gem_object *obj); /* vga arb irq handler */ void (*vgaarb_irq)(struct drm_device *dev, bool state); @@ -1175,6 +1174,7 @@ extern int drm_release(struct inode *inode, struct file *filp); extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); extern void drm_vm_open_locked(struct vm_area_struct *vma); +extern void drm_vm_close_locked(struct vm_area_struct *vma); extern resource_size_t drm_core_get_map_ofs(struct drm_local_map * map); extern resource_size_t drm_core_get_reg_ofs(struct drm_device *dev); extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); @@ -1455,12 +1455,11 @@ int drm_gem_init(struct drm_device *dev); void drm_gem_destroy(struct drm_device *dev); void drm_gem_object_release(struct drm_gem_object *obj); void drm_gem_object_free(struct kref *kref); -void drm_gem_object_free_unlocked(struct kref *kref); struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, size_t size); int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, size_t size); -void drm_gem_object_handle_free(struct kref *kref); +void drm_gem_object_handle_free(struct drm_gem_object *obj); void drm_gem_vm_open(struct vm_area_struct *vma); void drm_gem_vm_close(struct vm_area_struct *vma); int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); @@ -1483,8 +1482,12 @@ drm_gem_object_unreference(struct drm_gem_object *obj) static inline void drm_gem_object_unreference_unlocked(struct drm_gem_object *obj) { - if (obj != NULL) - kref_put(&obj->refcount, drm_gem_object_free_unlocked); + if (obj != NULL) { + struct drm_device *dev = obj->dev; + mutex_lock(&dev->struct_mutex); + kref_put(&obj->refcount, drm_gem_object_free); + mutex_unlock(&dev->struct_mutex); + } } int drm_gem_handle_create(struct drm_file *file_priv, @@ -1495,7 +1498,7 @@ static inline void drm_gem_object_handle_reference(struct drm_gem_object *obj) { drm_gem_object_reference(obj); - kref_get(&obj->handlecount); + atomic_inc(&obj->handle_count); } static inline void @@ -1504,12 +1507,15 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj) if (obj == NULL) return; + if (atomic_read(&obj->handle_count) == 0) + return; /* * Must bump handle count first as this may be the last * ref, in which case the object would disappear before we * checked for a name */ - kref_put(&obj->handlecount, drm_gem_object_handle_free); + if (atomic_dec_and_test(&obj->handle_count)) + drm_gem_object_handle_free(obj); drm_gem_object_unreference(obj); } @@ -1519,12 +1525,17 @@ drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) if (obj == NULL) return; + if (atomic_read(&obj->handle_count) == 0) + return; + /* * Must bump handle count first as this may be the last * ref, in which case the object would disappear before we * checked for a name */ - kref_put(&obj->handlecount, drm_gem_object_handle_free); + + if (atomic_dec_and_test(&obj->handle_count)) + drm_gem_object_handle_free(obj); drm_gem_object_unreference_unlocked(obj); } diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 3a9940ef728b..883c1d439899 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -85,7 +85,6 @@ {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \ @@ -103,6 +102,7 @@ {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 267a86c74e2e..2040e6c4f172 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -246,9 +246,11 @@ struct ttm_buffer_object { atomic_t reserved; - /** * Members protected by the bo::lock + * In addition, setting sync_obj to anything else + * than NULL requires bo::reserved to be held. This allows for + * checking NULL while reserved but not holding bo::lock. */ void *sync_obj_arg; diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 626b629429ff..4e8ea8c8ec1e 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -118,7 +118,6 @@ header-y += eventpoll.h header-y += ext2_fs.h header-y += fadvise.h header-y += falloc.h -header-y += fanotify.h header-y += fb.h header-y += fcntl.h header-y += fd.h diff --git a/include/linux/coredump.h b/include/linux/coredump.h index 8ba66a9d9022..ba4b85a6d9b8 100644 --- a/include/linux/coredump.h +++ b/include/linux/coredump.h @@ -9,37 +9,7 @@ * These are the only things you should do on a core-file: use only these * functions to write out all the necessary info. */ -static inline int dump_write(struct file *file, const void *addr, int nr) -{ - return file->f_op->write(file, addr, nr, &file->f_pos) == nr; -} - -static inline int dump_seek(struct file *file, loff_t off) -{ - int ret = 1; - - if (file->f_op->llseek && file->f_op->llseek != no_llseek) { - if (file->f_op->llseek(file, off, SEEK_CUR) < 0) - return 0; - } else { - char *buf = (char *)get_zeroed_page(GFP_KERNEL); - - if (!buf) - return 0; - while (off > 0) { - unsigned long n = off; - - if (n > PAGE_SIZE) - n = PAGE_SIZE; - if (!dump_write(file, buf, n)) { - ret = 0; - break; - } - off -= n; - } - free_page((unsigned long)buf); - } - return ret; -} +extern int dump_write(struct file *file, const void *addr, int nr); +extern int dump_seek(struct file *file, loff_t off); #endif /* _LINUX_COREDUMP_H */ diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 36ca9721a0c2..1be416bbbb82 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -53,6 +53,7 @@ struct cpuidle_state { #define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */ #define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */ #define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ +#define CPUIDLE_FLAG_TLB_FLUSHED (0x200) /* tlb will be flushed */ #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c61d4ca27bcc..e2106495cc11 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -548,7 +548,7 @@ static inline bool dma_dev_has_pq_continue(struct dma_device *dma) return (dma->max_pq & DMA_HAS_PQ_CONTINUE) == DMA_HAS_PQ_CONTINUE; } -static unsigned short dma_dev_to_maxpq(struct dma_device *dma) +static inline unsigned short dma_dev_to_maxpq(struct dma_device *dma) { return dma->max_pq & ~DMA_HAS_PQ_CONTINUE; } diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 926b50322a46..4fd978e7eb83 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -93,6 +93,7 @@ struct elevator_queue struct elevator_type *elevator_type; struct mutex sysfs_lock; struct hlist_head *hash; + unsigned int registered:1; }; /* diff --git a/include/linux/module.h b/include/linux/module.h index 8a6b9fdc7ffa..aace066bad8f 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -686,17 +686,16 @@ extern int module_sysfs_initialized; #ifdef CONFIG_GENERIC_BUG -int module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, +void module_bug_finalize(const Elf_Ehdr *, const Elf_Shdr *, struct module *); void module_bug_cleanup(struct module *); #else /* !CONFIG_GENERIC_BUG */ -static inline int module_bug_finalize(const Elf_Ehdr *hdr, +static inline void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod) { - return 0; } static inline void module_bug_cleanup(struct module *mod) {} #endif /* CONFIG_GENERIC_BUG */ diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 9fbc54a2585d..83af1f8d8b74 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -454,7 +454,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) * Makes rcu_dereference_check() do the dirty work. */ #define rcu_dereference_bh(p) \ - rcu_dereference_check(p, rcu_read_lock_bh_held()) + rcu_dereference_check(p, rcu_read_lock_bh_held() || irqs_disabled()) /** * rcu_dereference_sched - fetch RCU-protected pointer, checking for RCU-sched diff --git a/include/linux/wait.h b/include/linux/wait.h index 0836ccc57121..3efc9f3f43a0 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -614,6 +614,7 @@ int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); (wait)->private = current; \ (wait)->func = autoremove_wake_function; \ INIT_LIST_HEAD(&(wait)->task_list); \ + (wait)->flags = 0; \ } while (0) /** diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index 97e07f46a0fa..aa4ebb42a565 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h @@ -48,6 +48,7 @@ struct videobuf_dmabuf { /* for userland buffer */ int offset; + size_t size; struct page **pages; /* for kernel buffers */ diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 27a902d9b3a9..30fce0128dd7 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -161,12 +161,30 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l { struct sk_buff *skb; + release_sock(sk); if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { skb_reserve(skb, BT_SKB_RESERVE); bt_cb(skb)->incoming = 0; } + lock_sock(sk); + + if (!skb && *err) + return NULL; + + *err = sock_error(sk); + if (*err) + goto out; + + if (sk->sk_shutdown) { + *err = -ECONNRESET; + goto out; + } return skb; + +out: + kfree_skb(skb); + return NULL; } int bt_err(__u16 code); diff --git a/ipc/sem.c b/ipc/sem.c index 40a8f462a822..0e0d49bbb867 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -743,6 +743,8 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, { struct semid_ds out; + memset(&out, 0, sizeof(out)); + ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm); out.sem_otime = in->sem_otime; diff --git a/kernel/kfifo.c b/kernel/kfifo.c index 6b5580c57644..01a0700e873f 100644 --- a/kernel/kfifo.c +++ b/kernel/kfifo.c @@ -365,8 +365,6 @@ static unsigned int setup_sgl(struct __kfifo *fifo, struct scatterlist *sgl, n = setup_sgl_buf(sgl, fifo->data + off, nents, l); n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); - if (n) - sg_mark_end(sgl + n - 1); return n; } diff --git a/kernel/module.c b/kernel/module.c index d0b5f8db11b4..ccd641991842 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1537,6 +1537,7 @@ static int __unlink_module(void *_mod) { struct module *mod = _mod; list_del(&mod->list); + module_bug_cleanup(mod); return 0; } @@ -2625,6 +2626,7 @@ static struct module *load_module(void __user *umod, if (err < 0) goto ddebug; + module_bug_finalize(info.hdr, info.sechdrs, mod); list_add_rcu(&mod->list, &modules); mutex_unlock(&module_mutex); @@ -2650,6 +2652,8 @@ static struct module *load_module(void __user *umod, mutex_lock(&module_mutex); /* Unlink carefully: kallsyms could be walking list. */ list_del_rcu(&mod->list); + module_bug_cleanup(mod); + ddebug: if (!mod->taints) dynamic_debug_remove(info.debug); diff --git a/kernel/perf_event.c b/kernel/perf_event.c index db5b56064687..b98bed3d8182 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -2202,15 +2202,13 @@ static void perf_event_for_each(struct perf_event *event, static int perf_event_period(struct perf_event *event, u64 __user *arg) { struct perf_event_context *ctx = event->ctx; - unsigned long size; int ret = 0; u64 value; if (!event->attr.sample_period) return -EINVAL; - size = copy_from_user(&value, arg, sizeof(value)); - if (size != sizeof(value)) + if (copy_from_user(&value, arg, sizeof(value))) return -EFAULT; if (!value) diff --git a/kernel/signal.c b/kernel/signal.c index bded65187780..919562c3d6b7 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2215,6 +2215,14 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) #ifdef __ARCH_SI_TRAPNO err |= __put_user(from->si_trapno, &to->si_trapno); #endif +#ifdef BUS_MCEERR_AO + /* + * Other callers might not initialize the si_lsb field, + * so check explicitely for the right codes here. + */ + if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) + err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); +#endif break; case __SI_CHLD: err |= __put_user(from->si_pid, &to->si_pid); diff --git a/kernel/smp.c b/kernel/smp.c index 75c970c715d3..ed6aacfcb7ef 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -365,9 +365,10 @@ call: EXPORT_SYMBOL_GPL(smp_call_function_any); /** - * __smp_call_function_single(): Run a function on another CPU + * __smp_call_function_single(): Run a function on a specific CPU * @cpu: The CPU to run on. * @data: Pre-allocated and setup data structure + * @wait: If true, wait until function has completed on specified CPU. * * Like smp_call_function_single(), but allow caller to pass in a * pre-allocated data structure. Useful for embedding @data inside @@ -376,8 +377,10 @@ EXPORT_SYMBOL_GPL(smp_call_function_any); void __smp_call_function_single(int cpu, struct call_single_data *data, int wait) { - csd_lock(data); + unsigned int this_cpu; + unsigned long flags; + this_cpu = get_cpu(); /* * Can deadlock when called with interrupts disabled. * We allow cpu's that are not yet online though, as no one else can @@ -387,7 +390,15 @@ void __smp_call_function_single(int cpu, struct call_single_data *data, WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled() && !oops_in_progress); - generic_exec_single(cpu, data, wait); + if (cpu == this_cpu) { + local_irq_save(flags); + data->func(data->info); + local_irq_restore(flags); + } else { + csd_lock(data); + generic_exec_single(cpu, data, wait); + } + put_cpu(); } /** diff --git a/kernel/sysctl.c b/kernel/sysctl.c index f88552c6d227..3a45c224770f 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2485,7 +2485,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int kbuf[left] = 0; } - for (; left && vleft--; i++, min++, max++, first=0) { + for (; left && vleft--; i++, first = 0) { unsigned long val; if (write) { diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 492197e2f86c..bca96377fd4e 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -405,7 +405,7 @@ static inline int test_time_stamp(u64 delta) #define BUF_MAX_DATA_SIZE (BUF_PAGE_SIZE - (sizeof(u32) * 2)) /* Max number of timestamps that can fit on a page */ -#define RB_TIMESTAMPS_PER_PAGE (BUF_PAGE_SIZE / RB_LEN_TIME_STAMP) +#define RB_TIMESTAMPS_PER_PAGE (BUF_PAGE_SIZE / RB_LEN_TIME_EXTEND) int ring_buffer_print_page_header(struct trace_seq *s) { diff --git a/lib/bug.c b/lib/bug.c index 7cdfad88128f..19552096d16b 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -72,8 +72,8 @@ static const struct bug_entry *module_find_bug(unsigned long bugaddr) return NULL; } -int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, - struct module *mod) +void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, + struct module *mod) { char *secstrings; unsigned int i; @@ -97,8 +97,6 @@ int module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, * could potentially lead to deadlock and thus be counter-productive. */ list_add(&mod->bug_list, &module_bug_list); - - return 0; } void module_bug_cleanup(struct module *mod) diff --git a/lib/list_sort.c b/lib/list_sort.c index 4b5cb794c38b..a7616fa3162e 100644 --- a/lib/list_sort.c +++ b/lib/list_sort.c @@ -70,7 +70,7 @@ static void merge_and_restore_back_links(void *priv, * element comparison is needed, so the client's cmp() * routine can invoke cond_resched() periodically. */ - (*cmp)(priv, tail, tail); + (*cmp)(priv, tail->next, tail->next); tail->next->prev = tail; tail = tail->next; @@ -712,7 +712,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, if (!ptep) goto out; - if (pte_write(*ptep)) { + if (pte_write(*ptep) || pte_dirty(*ptep)) { pte_t entry; swapped = PageSwapCache(page); @@ -735,7 +735,9 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, set_pte_at(mm, addr, ptep, entry); goto out_unlock; } - entry = pte_wrprotect(entry); + if (pte_dirty(entry)) + set_page_dirty(page); + entry = pte_mkclean(pte_wrprotect(entry)); set_pte_at_notify(mm, addr, ptep, entry); } *orig_pte = *ptep; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 3eed583895a6..9be3cf8a5da4 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3587,9 +3587,13 @@ unlock: static void mem_cgroup_threshold(struct mem_cgroup *memcg) { - __mem_cgroup_threshold(memcg, false); - if (do_swap_account) - __mem_cgroup_threshold(memcg, true); + while (memcg) { + __mem_cgroup_threshold(memcg, false); + if (do_swap_account) + __mem_cgroup_threshold(memcg, true); + + memcg = parent_mem_cgroup(memcg); + } } static int compare_thresholds(const void *a, const void *b) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 9c26eeca1342..757f6b0accfe 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -183,7 +183,7 @@ EXPORT_SYMBOL_GPL(hwpoison_filter); * signal. */ static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno, - unsigned long pfn) + unsigned long pfn, struct page *page) { struct siginfo si; int ret; @@ -198,7 +198,7 @@ static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno, #ifdef __ARCH_SI_TRAPNO si.si_trapno = trapno; #endif - si.si_addr_lsb = PAGE_SHIFT; + si.si_addr_lsb = compound_order(compound_head(page)) + PAGE_SHIFT; /* * Don't use force here, it's convenient if the signal * can be temporarily blocked. @@ -235,7 +235,7 @@ void shake_page(struct page *p, int access) int nr; do { nr = shrink_slab(1000, GFP_KERNEL, 1000); - if (page_count(p) == 0) + if (page_count(p) == 1) break; } while (nr > 10); } @@ -327,7 +327,7 @@ static void add_to_kill(struct task_struct *tsk, struct page *p, * wrong earlier. */ static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno, - int fail, unsigned long pfn) + int fail, struct page *page, unsigned long pfn) { struct to_kill *tk, *next; @@ -352,7 +352,7 @@ static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno, * process anyways. */ else if (kill_proc_ao(tk->tsk, tk->addr, trapno, - pfn) < 0) + pfn, page) < 0) printk(KERN_ERR "MCE %#lx: Cannot send advisory machine check signal to %s:%d\n", pfn, tk->tsk->comm, tk->tsk->pid); @@ -928,7 +928,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, * any accesses to the poisoned memory. */ kill_procs_ao(&tokill, !!PageDirty(hpage), trapno, - ret != SWAP_SUCCESS, pfn); + ret != SWAP_SUCCESS, p, pfn); return ret; } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a8cfa9cc6e86..f12ad1836abe 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5182,9 +5182,9 @@ void *__init alloc_large_system_hash(const char *tablename, if (!table) panic("Failed to allocate %s hash table\n", tablename); - printk(KERN_INFO "%s hash table entries: %d (order: %d, %lu bytes)\n", + printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n", tablename, - (1U << log2qty), + (1UL << log2qty), ilog2(size) - PAGE_SHIFT, size); diff --git a/mm/rmap.c b/mm/rmap.c index 9d2ba01bd4f9..92e6757f196e 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -381,7 +381,13 @@ vma_address(struct page *page, struct vm_area_struct *vma) unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) { if (PageAnon(page)) { - if (vma->anon_vma->root != page_anon_vma(page)->root) + struct anon_vma *page__anon_vma = page_anon_vma(page); + /* + * Note: swapoff's unuse_vma() is more efficient with this + * check, and needs it to match anon_vma when KSM is active. + */ + if (!vma->anon_vma || !page__anon_vma || + vma->anon_vma->root != page__anon_vma->root) return -EFAULT; } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) { if (!vma->vm_file || diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 01ddb0472f86..0eb96f7e44be 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -24,8 +24,11 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, if (vlan_dev) skb->dev = vlan_dev; - else if (vlan_id) - goto drop; + else if (vlan_id) { + if (!(skb->dev->flags & IFF_PROMISC)) + goto drop; + skb->pkt_type = PACKET_OTHERHOST; + } return (polling ? netif_receive_skb(skb) : netif_rx(skb)); @@ -102,8 +105,11 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, if (vlan_dev) skb->dev = vlan_dev; - else if (vlan_id) - goto drop; + else if (vlan_id) { + if (!(skb->dev->flags & IFF_PROMISC)) + goto drop; + skb->pkt_type = PACKET_OTHERHOST; + } for (p = napi->gro_list; p; p = p->next) { NAPI_GRO_CB(p)->same_flow = diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 622b471e14e0..74bcc662c3dd 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -778,7 +778,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb) eg->packets_rcvd++; mpc->eg_ops->put(eg); - memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); + memset(ATM_SKB(new_skb), 0, sizeof(struct atm_skb_data)); netif_rx(new_skb); } diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index fadf26b4ed7c..0b54b7dd8401 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1441,33 +1441,23 @@ static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) static void l2cap_streaming_send(struct sock *sk) { - struct sk_buff *skb, *tx_skb; + struct sk_buff *skb; struct l2cap_pinfo *pi = l2cap_pi(sk); u16 control, fcs; - while ((skb = sk->sk_send_head)) { - tx_skb = skb_clone(skb, GFP_ATOMIC); - - control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); + while ((skb = skb_dequeue(TX_QUEUE(sk)))) { + control = get_unaligned_le16(skb->data + L2CAP_HDR_SIZE); control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT; - put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); + put_unaligned_le16(control, skb->data + L2CAP_HDR_SIZE); if (pi->fcs == L2CAP_FCS_CRC16) { - fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2); - put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2); + fcs = crc16(0, (u8 *)skb->data, skb->len - 2); + put_unaligned_le16(fcs, skb->data + skb->len - 2); } - l2cap_do_send(sk, tx_skb); + l2cap_do_send(sk, skb); pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; - - if (skb_queue_is_last(TX_QUEUE(sk), skb)) - sk->sk_send_head = NULL; - else - sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb); - - skb = skb_dequeue(TX_QUEUE(sk)); - kfree_skb(skb); } } @@ -1960,6 +1950,11 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us switch (optname) { case L2CAP_OPTIONS: + if (sk->sk_state == BT_CONNECTED) { + err = -EINVAL; + break; + } + opts.imtu = l2cap_pi(sk)->imtu; opts.omtu = l2cap_pi(sk)->omtu; opts.flush_to = l2cap_pi(sk)->flush_to; @@ -2771,10 +2766,10 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, case L2CAP_CONF_MTU: if (val < L2CAP_DEFAULT_MIN_MTU) { *result = L2CAP_CONF_UNACCEPT; - pi->omtu = L2CAP_DEFAULT_MIN_MTU; + pi->imtu = L2CAP_DEFAULT_MIN_MTU; } else - pi->omtu = val; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu); + pi->imtu = val; + l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); break; case L2CAP_CONF_FLUSH_TO: @@ -3071,6 +3066,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd return 0; } +static inline void set_default_fcs(struct l2cap_pinfo *pi) +{ + /* FCS is enabled only in ERTM or streaming mode, if one or both + * sides request it. + */ + if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING) + pi->fcs = L2CAP_FCS_NONE; + else if (!(pi->conf_state & L2CAP_CONF_NO_FCS_RECV)) + pi->fcs = L2CAP_FCS_CRC16; +} + static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) { struct l2cap_conf_req *req = (struct l2cap_conf_req *) data; @@ -3088,14 +3094,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!sk) return -ENOENT; - if (sk->sk_state != BT_CONFIG) { - struct l2cap_cmd_rej rej; - - rej.reason = cpu_to_le16(0x0002); - l2cap_send_cmd(conn, cmd->ident, L2CAP_COMMAND_REJ, - sizeof(rej), &rej); + if (sk->sk_state == BT_DISCONN) goto unlock; - } /* Reject if config buffer is too small. */ len = cmd_len - sizeof(*req); @@ -3135,9 +3135,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr goto unlock; if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) { - if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || - l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) - l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; + set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; @@ -3225,9 +3223,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE; if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) { - if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV) || - l2cap_pi(sk)->fcs != L2CAP_FCS_NONE) - l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16; + set_default_fcs(l2cap_pi(sk)); sk->sk_state = BT_CONNECTED; l2cap_pi(sk)->next_tx_seq = 0; diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 44a623275951..194b3a04cfd3 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -82,11 +82,14 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb) static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) { struct sock *sk = d->owner, *parent; + unsigned long flags; + if (!sk) return; BT_DBG("dlc %p state %ld err %d", d, d->state, err); + local_irq_save(flags); bh_lock_sock(sk); if (err) @@ -108,6 +111,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) } bh_unlock_sock(sk); + local_irq_restore(flags); if (parent && sock_flag(sk, SOCK_ZAPPED)) { /* We have to drop DLC lock here, otherwise diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 8ce904786116..4bf28f25f368 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -827,6 +827,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, long timeo; int err; int ifindex, headroom, tailroom; + unsigned int mtu; struct net_device *dev; lock_sock(sk); @@ -896,15 +897,23 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, cf_sk->sk.sk_state = CAIF_DISCONNECTED; goto out; } - dev = dev_get_by_index(sock_net(sk), ifindex); + + err = -ENODEV; + rcu_read_lock(); + dev = dev_get_by_index_rcu(sock_net(sk), ifindex); + if (!dev) { + rcu_read_unlock(); + goto out; + } cf_sk->headroom = LL_RESERVED_SPACE_EXTRA(dev, headroom); + mtu = dev->mtu; + rcu_read_unlock(); + cf_sk->tailroom = tailroom; - cf_sk->maxframe = dev->mtu - (headroom + tailroom); - dev_put(dev); + cf_sk->maxframe = mtu - (headroom + tailroom); if (cf_sk->maxframe < 1) { - pr_warning("CAIF: %s(): CAIF Interface MTU too small (%d)\n", - __func__, dev->mtu); - err = -ENODEV; + pr_warning("CAIF: %s(): CAIF Interface MTU too small (%u)\n", + __func__, mtu); goto out; } diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 7a85367b3c2f..8451ab481095 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -348,7 +348,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, if (info.cmd == ETHTOOL_GRXCLSRLALL) { if (info.rule_cnt > 0) { if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32)) - rule_buf = kmalloc(info.rule_cnt * sizeof(u32), + rule_buf = kzalloc(info.rule_cnt * sizeof(u32), GFP_USER); if (!rule_buf) return -ENOMEM; @@ -397,7 +397,7 @@ static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev, (KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index)) return -ENOMEM; full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size; - indir = kmalloc(full_size, GFP_USER); + indir = kzalloc(full_size, GFP_USER); if (!indir) return -ENOMEM; @@ -538,7 +538,7 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr) gstrings.len = ret; - data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); + data = kzalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); if (!data) return -ENOMEM; @@ -775,7 +775,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) if (regs.len > reglen) regs.len = reglen; - regbuf = kmalloc(reglen, GFP_USER); + regbuf = kzalloc(reglen, GFP_USER); if (!regbuf) return -ENOMEM; diff --git a/net/core/stream.c b/net/core/stream.c index d959e0f41528..f5df85dcd20b 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -141,10 +141,10 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); sk->sk_write_pending++; - sk_wait_event(sk, ¤t_timeo, !sk->sk_err && - !(sk->sk_shutdown & SEND_SHUTDOWN) && - sk_stream_memory_free(sk) && - vm_wait); + sk_wait_event(sk, ¤t_timeo, sk->sk_err || + (sk->sk_shutdown & SEND_SHUTDOWN) || + (sk_stream_memory_free(sk) && + !vm_wait)); sk->sk_write_pending--; if (vm_wait) { diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 571f8950ed06..7cd7760144f7 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -217,6 +217,7 @@ config NET_IPIP config NET_IPGRE tristate "IP: GRE tunnels over IP" + depends on IPV6 || IPV6=n help Tunneling means encapsulating data of one protocol type within another protocol and sending it over a channel that understands the @@ -412,7 +413,7 @@ config INET_XFRM_MODE_BEET If unsure, say Y. config INET_LRO - bool "Large Receive Offload (ipv4/tcp)" + tristate "Large Receive Offload (ipv4/tcp)" default y ---help--- Support for Large Receive Offload (ipv4/tcp). diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 1fdcacd36ce7..2a4bb76f2132 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -834,7 +834,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, int mark = 0; - if (len == 8 || IGMP_V2_SEEN(in_dev)) { + if (len == 8) { if (ih->code == 0) { /* Alas, old v1 router presents here. */ @@ -856,6 +856,18 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, igmpv3_clear_delrec(in_dev); } else if (len < 12) { return; /* ignore bogus packet; freed by caller */ + } else if (IGMP_V1_SEEN(in_dev)) { + /* This is a v3 query with v1 queriers present */ + max_delay = IGMP_Query_Response_Interval; + group = 0; + } else if (IGMP_V2_SEEN(in_dev)) { + /* this is a v3 query with v2 queriers present; + * Interpretation of the max_delay code is problematic here. + * A real v2 host would use ih_code directly, while v3 has a + * different encoding. We use the v3 encoding as more likely + * to be intended in a v3 query. + */ + max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); } else { /* v3 */ if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) return; diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index c35b469e851c..74c54b30600f 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -135,13 +135,16 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) /* This function calculates a "timeout" which is equivalent to the timeout of a * TCP connection after "boundary" unsuccessful, exponentially backed-off - * retransmissions with an initial RTO of TCP_RTO_MIN. + * retransmissions with an initial RTO of TCP_RTO_MIN or TCP_TIMEOUT_INIT if + * syn_set flag is set. */ static bool retransmits_timed_out(struct sock *sk, - unsigned int boundary) + unsigned int boundary, + bool syn_set) { unsigned int timeout, linear_backoff_thresh; unsigned int start_ts; + unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN; if (!inet_csk(sk)->icsk_retransmits) return false; @@ -151,12 +154,12 @@ static bool retransmits_timed_out(struct sock *sk, else start_ts = tcp_sk(sk)->retrans_stamp; - linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); + linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); if (boundary <= linear_backoff_thresh) - timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; + timeout = ((2 << boundary) - 1) * rto_base; else - timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + + timeout = ((2 << linear_backoff_thresh) - 1) * rto_base + (boundary - linear_backoff_thresh) * TCP_RTO_MAX; return (tcp_time_stamp - start_ts) >= timeout; @@ -167,14 +170,15 @@ static int tcp_write_timeout(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); int retry_until; - bool do_reset; + bool do_reset, syn_set = 0; if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { if (icsk->icsk_retransmits) dst_negative_advice(sk); retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; + syn_set = 1; } else { - if (retransmits_timed_out(sk, sysctl_tcp_retries1)) { + if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) { /* Black hole detection */ tcp_mtu_probing(icsk, sk); @@ -187,14 +191,14 @@ static int tcp_write_timeout(struct sock *sk) retry_until = tcp_orphan_retries(sk, alive); do_reset = alive || - !retransmits_timed_out(sk, retry_until); + !retransmits_timed_out(sk, retry_until, 0); if (tcp_out_of_resources(sk, do_reset)) return 1; } } - if (retransmits_timed_out(sk, retry_until)) { + if (retransmits_timed_out(sk, retry_until, syn_set)) { /* Has it gone just too far? */ tcp_write_err(sk); return 1; @@ -436,7 +440,7 @@ out_reset_timer: icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); } inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); - if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1)) + if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0)) __sk_dst_reset(sk); out:; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8323136bdc54..a275c6e1e25c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1556,14 +1556,13 @@ out: * i.e. Path MTU discovery */ -void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, - struct net_device *dev, u32 pmtu) +static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, + struct net *net, u32 pmtu, int ifindex) { struct rt6_info *rt, *nrt; - struct net *net = dev_net(dev); int allfrag = 0; - rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0); + rt = rt6_lookup(net, daddr, saddr, ifindex, 0); if (rt == NULL) return; @@ -1631,6 +1630,27 @@ out: dst_release(&rt->dst); } +void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, + struct net_device *dev, u32 pmtu) +{ + struct net *net = dev_net(dev); + + /* + * RFC 1981 states that a node "MUST reduce the size of the packets it + * is sending along the path" that caused the Packet Too Big message. + * Since it's not possible in the general case to determine which + * interface was used to send the original packet, we update the MTU + * on the interface that will be used to send future packets. We also + * update the MTU on the interface that received the Packet Too Big in + * case the original packet was forced out that interface with + * SO_BINDTODEVICE or similar. This is the next best thing to the + * correct behaviour, which would be to update the MTU on all + * interfaces. + */ + rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0); + rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex); +} + /* * Misc support functions */ diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index c893f236acea..8f23401832b7 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -175,6 +175,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state); + del_timer_sync(&tid_tx->addba_resp_timer); + /* * After this packets are no longer handed right through * to the driver but are put onto tid_tx->pending instead, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index fa0f37e4afe4..28624282c5f3 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2199,9 +2199,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, struct net_device *prev_dev = NULL; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - if (status->flag & RX_FLAG_INTERNAL_CMTR) - goto out_free_skb; - if (skb_headroom(skb) < sizeof(*rthdr) && pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) goto out_free_skb; @@ -2260,7 +2257,6 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, } else goto out_free_skb; - status->flag |= RX_FLAG_INTERNAL_CMTR; return; out_free_skb: diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 10caec5ea8fa..34da67995d94 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -377,7 +377,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { skb2->dev = prev_dev; - netif_receive_skb(skb2); + netif_rx(skb2); } } @@ -386,7 +386,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) } if (prev_dev) { skb->dev = prev_dev; - netif_receive_skb(skb); + netif_rx(skb); skb = NULL; } rcu_read_unlock(); diff --git a/net/phonet/pep.c b/net/phonet/pep.c index b2a3ae6cad78..15003021f4f0 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -225,12 +225,13 @@ static void pipe_grant_credits(struct sock *sk) static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) { struct pep_sock *pn = pep_sk(sk); - struct pnpipehdr *hdr = pnp_hdr(skb); + struct pnpipehdr *hdr; int wake = 0; if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) return -EINVAL; + hdr = pnp_hdr(skb); if (hdr->data[0] != PN_PEP_TYPE_COMMON) { LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n", (unsigned)hdr->data[0]); diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 7416a5c73b2a..b0c2a82178af 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -137,7 +137,7 @@ next_knode: int toff = off + key->off + (off2 & key->offmask); __be32 *data, _data; - if (skb_headroom(skb) + toff < 0) + if (skb_headroom(skb) + toff > INT_MAX) goto out; data = skb_header_pointer(skb, toff, 4, &_data); diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 86366390038a..ddbbf7c81fa1 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -543,16 +543,20 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc) id = ntohs(hmacs->hmac_ids[i]); /* Check the id is in the supported range */ - if (id > SCTP_AUTH_HMAC_ID_MAX) + if (id > SCTP_AUTH_HMAC_ID_MAX) { + id = 0; continue; + } /* See is we support the id. Supported IDs have name and * length fields set, so that we can allocated and use * them. We can safely just check for name, for without the * name, we can't allocate the TFM. */ - if (!sctp_hmac_list[id].hmac_name) + if (!sctp_hmac_list[id].hmac_name) { + id = 0; continue; + } break; } diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ca44917872d2..fbb70770ad05 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -916,6 +916,11 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, /* Walk through the addrs buffer and count the number of addresses. */ addr_buf = kaddrs; while (walk_size < addrs_size) { + if (walk_size + sizeof(sa_family_t) > addrs_size) { + kfree(kaddrs); + return -EINVAL; + } + sa_addr = (struct sockaddr *)addr_buf; af = sctp_get_af_specific(sa_addr->sa_family); @@ -1002,9 +1007,13 @@ static int __sctp_connect(struct sock* sk, /* Walk through the addrs buffer and count the number of addresses. */ addr_buf = kaddrs; while (walk_size < addrs_size) { + if (walk_size + sizeof(sa_family_t) > addrs_size) { + err = -EINVAL; + goto out_free; + } + sa_addr = (union sctp_addr *)addr_buf; af = sctp_get_af_specific(sa_addr->sa.sa_family); - port = ntohs(sa_addr->v4.sin_port); /* If the address family is not supported or if this address * causes the address buffer to overflow return EINVAL. @@ -1014,6 +1023,8 @@ static int __sctp_connect(struct sock* sk, goto out_free; } + port = ntohs(sa_addr->v4.sin_port); + /* Save current address so we can work with it */ memcpy(&to, sa_addr, af->sockaddr_len); diff --git a/samples/kfifo/dma-example.c b/samples/kfifo/dma-example.c index ee03a4f0b64f..06473791c08a 100644 --- a/samples/kfifo/dma-example.c +++ b/samples/kfifo/dma-example.c @@ -24,6 +24,7 @@ static int __init example_init(void) { int i; unsigned int ret; + unsigned int nents; struct scatterlist sg[10]; printk(KERN_INFO "DMA fifo test start\n"); @@ -61,9 +62,9 @@ static int __init example_init(void) * byte at the beginning, after the kfifo_skip(). */ sg_init_table(sg, ARRAY_SIZE(sg)); - ret = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); - printk(KERN_INFO "DMA sgl entries: %d\n", ret); - if (!ret) { + nents = kfifo_dma_in_prepare(&fifo, sg, ARRAY_SIZE(sg), FIFO_SIZE); + printk(KERN_INFO "DMA sgl entries: %d\n", nents); + if (!nents) { /* fifo is full and no sgl was created */ printk(KERN_WARNING "error kfifo_dma_in_prepare\n"); return -EIO; @@ -71,7 +72,7 @@ static int __init example_init(void) /* receive data */ printk(KERN_INFO "scatterlist for receive:\n"); - for (i = 0; i < ARRAY_SIZE(sg); i++) { + for (i = 0; i < nents; i++) { printk(KERN_INFO "sg[%d] -> " "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", @@ -91,16 +92,16 @@ static int __init example_init(void) kfifo_dma_in_finish(&fifo, ret); /* Prepare to transmit data, example: 8 bytes */ - ret = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); - printk(KERN_INFO "DMA sgl entries: %d\n", ret); - if (!ret) { + nents = kfifo_dma_out_prepare(&fifo, sg, ARRAY_SIZE(sg), 8); + printk(KERN_INFO "DMA sgl entries: %d\n", nents); + if (!nents) { /* no data was available and no sgl was created */ printk(KERN_WARNING "error kfifo_dma_out_prepare\n"); return -EIO; } printk(KERN_INFO "scatterlist for transmit:\n"); - for (i = 0; i < ARRAY_SIZE(sg); i++) { + for (i = 0; i < nents; i++) { printk(KERN_INFO "sg[%d] -> " "page_link 0x%.8lx offset 0x%.8x length 0x%.8x\n", diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 5b7c86ea43a1..7ef429cd5cb3 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -427,7 +427,7 @@ static void check_conf(struct menu *menu) if (sym->name && !sym_is_choice_value(sym)) { printf("CONFIG_%s\n", sym->name); } - } else { + } else if (input_mode != oldnoconfig) { if (!conf_cnt++) printf(_("*\n* Restart config...\n*\n")); rootEntry = menu_get_parent_menu(menu); diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 6ee2e4fb1481..170459c224a1 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -165,7 +165,6 @@ struct menu { struct symbol *sym; struct property *prompt; struct expr *dep; - struct expr *dir_dep; unsigned int flags; char *help; struct file *file; diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 4fb590247f33..edda8b49619d 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -107,7 +107,6 @@ static struct expr *menu_check_dep(struct expr *e) void menu_add_dep(struct expr *dep) { current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); - current_entry->dir_dep = current_entry->dep; } void menu_set_type(int type) @@ -291,10 +290,6 @@ void menu_finalize(struct menu *parent) for (menu = parent->list; menu; menu = menu->next) menu_finalize(menu); } else if (sym) { - /* ignore inherited dependencies for dir_dep */ - sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep)); - sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr); - basedep = parent->prompt ? parent->prompt->visible.expr : NULL; basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); basedep = expr_eliminate_dups(expr_transform(basedep)); @@ -325,6 +320,8 @@ void menu_finalize(struct menu *parent) parent->next = last_menu->next; last_menu->next = NULL; } + + sym->dir_dep.expr = parent->dep; } for (menu = parent->list; menu; menu = menu->next) { if (sym && sym_is_choice(sym) && diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 943712ca6c0a..1f8b305449db 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -350,6 +350,7 @@ void sym_calc_value(struct symbol *sym) } } calc_newval: +#if 0 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { fprintf(stderr, "warning: ("); expr_fprint(sym->rev_dep.expr, stderr); @@ -358,6 +359,7 @@ void sym_calc_value(struct symbol *sym) expr_fprint(sym->dir_dep.expr, stderr); fprintf(stderr, ")\n"); } +#endif newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) diff --git a/sound/core/control.c b/sound/core/control.c index 070aab490191..45a818002d99 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -31,6 +31,7 @@ /* max number of user-defined controls */ #define MAX_USER_CONTROLS 32 +#define MAX_CONTROL_COUNT 1028 struct snd_kctl_ioctl { struct list_head list; /* list of all ioctls */ @@ -195,6 +196,10 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, if (snd_BUG_ON(!control || !control->count)) return NULL; + + if (control->count > MAX_CONTROL_COUNT) + return NULL; + kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); if (kctl == NULL) { snd_printk(KERN_ERR "Cannot allocate control instance\n"); diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c index 1adb8a3c2b62..42d7844ecd0b 100644 --- a/sound/i2c/other/ak4xxx-adda.c +++ b/sound/i2c/other/ak4xxx-adda.c @@ -900,7 +900,7 @@ static int proc_init(struct snd_akm4xxx *ak) return 0; } #else /* !CONFIG_PROC_FS */ -static int proc_init(struct snd_akm4xxx *ak) {} +static int proc_init(struct snd_akm4xxx *ak) { return 0; } #endif int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak) diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 92aa762ffb7e..07f803e6d203 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -391,11 +391,11 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SND_DEV_DSP: case SND_DEV_DSP16: case SND_DEV_AUDIO: - return audio_ioctl(dev, file, cmd, p); + ret = audio_ioctl(dev, file, cmd, p); break; case SND_DEV_MIDIN: - return MIDIbuf_ioctl(dev, file, cmd, p); + ret = MIDIbuf_ioctl(dev, file, cmd, p); break; } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 95148e58026c..c16c5ba0fda0 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1747,6 +1747,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "HP dv6", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061, "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */ + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x363e, + "HP DV6", STAC_HP_DV5), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, "HP", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 4f1fa77c1feb..1950e19af1cf 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -1017,7 +1017,7 @@ builtin-revert.o wt-status.o: wt-status.h # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So # we depend the various files onto their directories. DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h -$(DIRECTORY_DEPS): $(sort $(dir $(DIRECTORY_DEPS))) +$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS))) # In the second step, we make a rule to actually create these directories $(sort $(dir $(DIRECTORY_DEPS))): $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null diff --git a/tools/perf/perf.h b/tools/perf/perf.h index ef7aa0a0c526..95aaf565c704 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -73,6 +73,18 @@ void get_term_dimensions(struct winsize *ws); #define cpu_relax() asm volatile("":::"memory") #endif +#ifdef __mips__ +#include "../../arch/mips/include/asm/unistd.h" +#define rmb() asm volatile( \ + ".set mips2\n\t" \ + "sync\n\t" \ + ".set mips0" \ + : /* no output */ \ + : /* no input */ \ + : "memory") +#define cpu_relax() asm volatile("" ::: "memory") +#endif + #include <time.h> #include <unistd.h> #include <sys/types.h> diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 7ea983acfaea..f7af2fca965d 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -97,7 +97,7 @@ void setup_python_scripting(void) register_python_scripting(&python_scripting_unsupported_ops); } #else -struct scripting_ops python_scripting_ops; +extern struct scripting_ops python_scripting_ops; void setup_python_scripting(void) { @@ -158,7 +158,7 @@ void setup_perl_scripting(void) register_perl_scripting(&perl_scripting_unsupported_ops); } #else -struct scripting_ops perl_scripting_ops; +extern struct scripting_ops perl_scripting_ops; void setup_perl_scripting(void) { diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index dafdf6775d77..6866aa4c41e0 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c @@ -773,7 +773,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *ev_name) switch (key) { case 'a': - if (browser->selection->map == NULL && + if (browser->selection->map == NULL || browser->selection->map->dso->annotate_warned) continue; goto do_annotate; |