diff options
426 files changed, 20299 insertions, 15550 deletions
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 9555be1ed99..e783fd62e30 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 @@ -13,12 +13,25 @@ Supported chips: from Super I/O config space (8 I/O ports) Datasheet: Publicly available at the ITE website http://www.ite.com.tw/ + * IT8716F + Prefix: 'it8716' + Addresses scanned: from Super I/O config space (8 I/O ports) + Datasheet: Publicly available at the ITE website + http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP + * IT8718F + Prefix: 'it8718' + Addresses scanned: from Super I/O config space (8 I/O ports) + Datasheet: Publicly available at the ITE website + http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip + http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip * SiS950 [clone of IT8705F] Prefix: 'it87' Addresses scanned: from Super I/O config space (8 I/O ports) Datasheet: No longer be available -Author: Christophe Gauthron <chrisg@0-in.com> +Authors: + Christophe Gauthron <chrisg@0-in.com> + Jean Delvare <khali@linux-fr.org> Module Parameters @@ -43,26 +56,46 @@ Module Parameters Description ----------- -This driver implements support for the IT8705F, IT8712F and SiS950 chips. - -This driver also supports IT8712F, which adds SMBus access, and a VID -input, used to report the Vcore voltage of the Pentium processor. -The IT8712F additionally features VID inputs. +This driver implements support for the IT8705F, IT8712F, IT8716F, +IT8718F and SiS950 chips. These chips are 'Super I/O chips', supporting floppy disks, infrared ports, joysticks and other miscellaneous stuff. For hardware monitoring, they include an 'environment controller' with 3 temperature sensors, 3 fan rotation speed sensors, 8 voltage sensors, and associated alarms. +The IT8712F and IT8716F additionally feature VID inputs, used to report +the Vcore voltage of the processor. The early IT8712F have 5 VID pins, +the IT8716F and late IT8712F have 6. They are shared with other functions +though, so the functionality may not be available on a given system. +The driver dumbly assume it is there. + +The IT8718F also features VID inputs (up to 8 pins) but the value is +stored in the Super-I/O configuration space. Due to technical limitations, +this value can currently only be read once at initialization time, so +the driver won't notice and report changes in the VID value. The two +upper VID bits share their pins with voltage inputs (in5 and in6) so you +can't have both on a given board. + +The IT8716F, IT8718F and later IT8712F revisions have support for +2 additional fans. They are not yet supported by the driver. + +The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional +16-bit tachometer counters for fans 1 to 3. This is better (no more fan +clock divider mess) but not compatible with the older chips and +revisions. For now, the driver only uses the 16-bit mode on the +IT8716F and IT8718F. + Temperatures are measured in degrees Celsius. An alarm is triggered once when the Overtemperature Shutdown limit is crossed. Fan rotation speeds are reported in RPM (rotations per minute). An alarm is -triggered if the rotation speed has dropped below a programmable limit. Fan -readings can be divided by a programmable divider (1, 2, 4 or 8) to give the -readings more range or accuracy. Not all RPM values can accurately be -represented, so some rounding is done. With a divider of 2, the lowest -representable value is around 2600 RPM. +triggered if the rotation speed has dropped below a programmable limit. When +16-bit tachometer counters aren't used, fan readings can be divided by +a programmable divider (1, 2, 4 or 8) to give the readings more range or +accuracy. With a divider of 2, the lowest representable value is around +2600 RPM. Not all RPM values can accurately be represented, so some rounding +is done. Voltage sensors (also known as IN sensors) report their values in volts. An alarm is triggered if the voltage has crossed a programmable minimum or @@ -71,9 +104,9 @@ zero'; this is important for negative voltage measurements. All voltage inputs can measure voltages between 0 and 4.08 volts, with a resolution of 0.016 volt. The battery voltage in8 does not have limit registers. -The VID lines (IT8712F only) encode the core voltage value: the voltage -level your processor should work with. This is hardcoded by the mainboard -and/or processor itself. It is a value in volts. +The VID lines (IT8712F/IT8716F/IT8718F) encode the core voltage value: +the voltage level your processor should work with. This is hardcoded by +the mainboard and/or processor itself. It is a value in volts. If an alarm triggers, it will remain triggered until the hardware register is read at least once. This means that the cause for the alarm may already diff --git a/Documentation/hwmon/k8temp b/Documentation/hwmon/k8temp new file mode 100644 index 00000000000..bab445ab0f5 --- /dev/null +++ b/Documentation/hwmon/k8temp @@ -0,0 +1,52 @@ +Kernel driver k8temp +==================== + +Supported chips: + * AMD K8 CPU + Prefix: 'k8temp' + Addresses scanned: PCI space + Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf + +Author: Rudolf Marek +Contact: Rudolf Marek <r.marek@sh.cvut.cz> + +Description +----------- + +This driver permits reading temperature sensor(s) embedded inside AMD K8 CPUs. +Official documentation says that it works from revision F of K8 core, but +in fact it seems to be implemented for all revisions of K8 except the first +two revisions (SH-B0 and SH-B3). + +There can be up to four temperature sensors inside single CPU. The driver +will auto-detect the sensors and will display only temperatures from +implemented sensors. + +Mapping of /sys files is as follows: + +temp1_input - temperature of Core 0 and "place" 0 +temp2_input - temperature of Core 0 and "place" 1 +temp3_input - temperature of Core 1 and "place" 0 +temp4_input - temperature of Core 1 and "place" 1 + +Temperatures are measured in degrees Celsius and measurement resolution is +1 degree C. It is expected that future CPU will have better resolution. The +temperature is updated once a second. Valid temperatures are from -49 to +206 degrees C. + +Temperature known as TCaseMax was specified for processors up to revision E. +This temperature is defined as temperature between heat-spreader and CPU +case, so the internal CPU temperature supplied by this driver can be higher. +There is no easy way how to measure the temperature which will correlate +with TCaseMax temperature. + +For newer revisions of CPU (rev F, socket AM2) there is a mathematically +computed temperature called TControl, which must be lower than TControlMax. + +The relationship is following: + +temp1_input - TjOffset*2 < TControlMax, + +TjOffset is not yet exported by the driver, TControlMax is usually +70 degrees C. The rule of the thumb -> CPU temperature should not cross +60 degrees C too much. diff --git a/Documentation/hwmon/vt1211 b/Documentation/hwmon/vt1211 new file mode 100644 index 00000000000..77fa633b97a --- /dev/null +++ b/Documentation/hwmon/vt1211 @@ -0,0 +1,206 @@ +Kernel driver vt1211 +==================== + +Supported chips: + * VIA VT1211 + Prefix: 'vt1211' + Addresses scanned: none, address read from Super-I/O config space + Datasheet: Provided by VIA upon request and under NDA + +Authors: Juerg Haefliger <juergh@gmail.com> + +This driver is based on the driver for kernel 2.4 by Mark D. Studebaker and +its port to kernel 2.6 by Lars Ekman. + +Thanks to Joseph Chan and Fiona Gatt from VIA for providing documentation and +technical support. + + +Module Parameters +----------------- + +* uch_config: int Override the BIOS default universal channel (UCH) + configuration for channels 1-5. + Legal values are in the range of 0-31. Bit 0 maps to + UCH1, bit 1 maps to UCH2 and so on. Setting a bit to 1 + enables the thermal input of that particular UCH and + setting a bit to 0 enables the voltage input. + +* int_mode: int Override the BIOS default temperature interrupt mode. + The only possible value is 0 which forces interrupt + mode 0. In this mode, any pending interrupt is cleared + when the status register is read but is regenerated as + long as the temperature stays above the hysteresis + limit. + +Be aware that overriding BIOS defaults might cause some unwanted side effects! + + +Description +----------- + +The VIA VT1211 Super-I/O chip includes complete hardware monitoring +capabilities. It monitors 2 dedicated temperature sensor inputs (temp1 and +temp2), 1 dedicated voltage (in5) and 2 fans. Additionally, the chip +implements 5 universal input channels (UCH1-5) that can be individually +programmed to either monitor a voltage or a temperature. + +This chip also provides manual and automatic control of fan speeds (according +to the datasheet). The driver only supports automatic control since the manual +mode doesn't seem to work as advertised in the datasheet. In fact I couldn't +get manual mode to work at all! Be aware that automatic mode hasn't been +tested very well (due to the fact that my EPIA M10000 doesn't have the fans +connected to the PWM outputs of the VT1211 :-(). + +The following table shows the relationship between the vt1211 inputs and the +sysfs nodes. + +Sensor Voltage Mode Temp Mode Default Use (from the datasheet) +------ ------------ --------- -------------------------------- +Reading 1 temp1 Intel thermal diode +Reading 3 temp2 Internal thermal diode +UCH1/Reading2 in0 temp3 NTC type thermistor +UCH2 in1 temp4 +2.5V +UCH3 in2 temp5 VccP (processor core) +UCH4 in3 temp6 +5V +UCH5 in4 temp7 +12V ++3.3V in5 Internal VCC (+3.3V) + + +Voltage Monitoring +------------------ + +Voltages are sampled by an 8-bit ADC with a LSB of ~10mV. The supported input +range is thus from 0 to 2.60V. Voltage values outside of this range need +external scaling resistors. This external scaling needs to be compensated for +via compute lines in sensors.conf, like: + +compute inx @*(1+R1/R2), @/(1+R1/R2) + +The board level scaling resistors according to VIA's recommendation are as +follows. And this is of course totally dependent on the actual board +implementation :-) You will have to find documentation for your own +motherboard and edit sensors.conf accordingly. + + Expected +Voltage R1 R2 Divider Raw Value +----------------------------------------------- ++2.5V 2K 10K 1.2 2083 mV +VccP --- --- 1.0 1400 mV (1) ++5V 14K 10K 2.4 2083 mV ++12V 47K 10K 5.7 2105 mV ++3.3V (int) 2K 3.4K 1.588 3300 mV (2) ++3.3V (ext) 6.8K 10K 1.68 1964 mV + +(1) Depending on the CPU (1.4V is for a VIA C3 Nehemiah). +(2) R1 and R2 for 3.3V (int) are internal to the VT1211 chip and the driver + performs the scaling and returns the properly scaled voltage value. + +Each measured voltage has an associated low and high limit which triggers an +alarm when crossed. + + +Temperature Monitoring +---------------------- + +Temperatures are reported in millidegree Celsius. Each measured temperature +has a high limit which triggers an alarm if crossed. There is an associated +hysteresis value with each temperature below which the temperature has to drop +before the alarm is cleared (this is only true for interrupt mode 0). The +interrupt mode can be forced to 0 in case the BIOS doesn't do it +automatically. See the 'Module Parameters' section for details. + +All temperature channels except temp2 are external. Temp2 is the VT1211 +internal thermal diode and the driver does all the scaling for temp2 and +returns the temperature in millidegree Celsius. For the external channels +temp1 and temp3-temp7, scaling depends on the board implementation and needs +to be performed in userspace via sensors.conf. + +Temp1 is an Intel-type thermal diode which requires the following formula to +convert between sysfs readings and real temperatures: + +compute temp1 (@-Offset)/Gain, (@*Gain)+Offset + +According to the VIA VT1211 BIOS porting guide, the following gain and offset +values should be used: + +Diode Type Offset Gain +---------- ------ ---- +Intel CPU 88.638 0.9528 + 65.000 0.9686 *) +VIA C3 Ezra 83.869 0.9528 +VIA C3 Ezra-T 73.869 0.9528 + +*) This is the formula from the lm_sensors 2.10.0 sensors.conf file. I don't +know where it comes from or how it was derived, it's just listed here for +completeness. + +Temp3-temp7 support NTC thermistors. For these channels, the driver returns +the voltages as seen at the individual pins of UCH1-UCH5. The voltage at the +pin (Vpin) is formed by a voltage divider made of the thermistor (Rth) and a +scaling resistor (Rs): + +Vpin = 2200 * Rth / (Rs + Rth) (2200 is the ADC max limit of 2200 mV) + +The equation for the thermistor is as follows (google it if you want to know +more about it): + +Rth = Ro * exp(B * (1 / T - 1 / To)) (To is 298.15K (25C) and Ro is the + nominal resistance at 25C) + +Mingling the above two equations and assuming Rs = Ro and B = 3435 yields the +following formula for sensors.conf: + +compute tempx 1 / (1 / 298.15 - (` (2200 / @ - 1)) / 3435) - 273.15, + 2200 / (1 + (^ (3435 / 298.15 - 3435 / (273.15 + @)))) + + +Fan Speed Control +----------------- + +The VT1211 provides 2 programmable PWM outputs to control the speeds of 2 +fans. Writing a 2 to any of the two pwm[1-2]_enable sysfs nodes will put the +PWM controller in automatic mode. There is only a single controller that +controls both PWM outputs but each PWM output can be individually enabled and +disabled. + +Each PWM has 4 associated distinct output duty-cycles: full, high, low and +off. Full and off are internally hard-wired to 255 (100%) and 0 (0%), +respectively. High and low can be programmed via +pwm[1-2]_auto_point[2-3]_pwm. Each PWM output can be associated with a +different thermal input but - and here's the weird part - only one set of +thermal thresholds exist that controls both PWMs output duty-cycles. The +thermal thresholds are accessible via pwm[1-2]_auto_point[1-4]_temp. Note +that even though there are 2 sets of 4 auto points each, they map to the same +registers in the VT1211 and programming one set is sufficient (actually only +the first set pwm1_auto_point[1-4]_temp is writable, the second set is +read-only). + +PWM Auto Point PWM Output Duty-Cycle +------------------------------------------------ +pwm[1-2]_auto_point4_pwm full speed duty-cycle (hard-wired to 255) +pwm[1-2]_auto_point3_pwm high speed duty-cycle +pwm[1-2]_auto_point2_pwm low speed duty-cycle +pwm[1-2]_auto_point1_pwm off duty-cycle (hard-wired to 0) + +Temp Auto Point Thermal Threshold +--------------------------------------------- +pwm[1-2]_auto_point4_temp full speed temp +pwm[1-2]_auto_point3_temp high speed temp +pwm[1-2]_auto_point2_temp low speed temp +pwm[1-2]_auto_point1_temp off temp + +Long story short, the controller implements the following algorithm to set the +PWM output duty-cycle based on the input temperature: + +Thermal Threshold Output Duty-Cycle + (Rising Temp) (Falling Temp) +---------------------------------------------------------- + full speed duty-cycle full speed duty-cycle +full speed temp + high speed duty-cycle full speed duty-cycle +high speed temp + low speed duty-cycle high speed duty-cycle +low speed temp + off duty-cycle low speed duty-cycle +off temp diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf new file mode 100644 index 00000000000..fae3b781d82 --- /dev/null +++ b/Documentation/hwmon/w83627ehf @@ -0,0 +1,85 @@ +Kernel driver w83627ehf +======================= + +Supported chips: + * Winbond W83627EHF/EHG (ISA access ONLY) + Prefix: 'w83627ehf' + Addresses scanned: ISA address retrieved from Super I/O registers + Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf + +Authors: + Jean Delvare <khali@linux-fr.org> + Yuan Mu (Winbond) + Rudolf Marek <r.marek@sh.cvut.cz> + +Description +----------- + +This driver implements support for the Winbond W83627EHF and W83627EHG +super I/O chips. We will refer to them collectively as Winbond chips. + +The chips implement three temperature sensors, five fan rotation +speed sensors, ten analog voltage sensors, alarms with beep warnings (control +unimplemented), and some automatic fan regulation strategies (plus manual +fan control mode). + +Temperatures are measured in degrees Celsius and measurement resolution is 1 +degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when +the temperature gets higher than high limit; it stays on until the temperature +falls below the Hysteresis value. + +Fan rotation speeds are reported in RPM (rotations per minute). An alarm is +triggered if the rotation speed has dropped below a programmable limit. Fan +readings can be divided by a programmable divider (1, 2, 4, 8, 16, 32, 64 or +128) to give the readings more range or accuracy. The driver sets the most +suitable fan divisor itself. Some fans might not be present because they +share pins with other functions. + +Voltage sensors (also known as IN sensors) report their values in millivolts. +An alarm is triggered if the voltage has crossed a programmable minimum +or maximum limit. + +The driver supports automatic fan control mode known as Thermal Cruise. +In this mode, the chip attempts to keep the measured temperature in a +predefined temperature range. If the temperature goes out of range, fan +is driven slower/faster to reach the predefined range again. + +The mode works for fan1-fan4. Mapping of temperatures to pwm outputs is as +follows: + +temp1 -> pwm1 +temp2 -> pwm2 +temp3 -> pwm3 +prog -> pwm4 (the programmable setting is not supported by the driver) + +/sys files +---------- + +pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range: + 0 (stop) to 255 (full) + +pwm[1-4]_enable - this file controls mode of fan/temperature control: + * 1 Manual Mode, write to pwm file any value 0-255 (full speed) + * 2 Thermal Cruise + +Thermal Cruise mode +------------------- + +If the temperature is in the range defined by: + +pwm[1-4]_target - set target temperature, unit millidegree Celcius + (range 0 - 127000) +pwm[1-4]_tolerance - tolerance, unit millidegree Celcius (range 0 - 15000) + +there are no changes to fan speed. Once the temperature leaves the interval, +fan speed increases (temp is higher) or decreases if lower than desired. +There are defined steps and times, but not exported by the driver yet. + +pwm[1-4]_min_output - minimum fan speed (range 1 - 255), when the temperature + is below defined range. +pwm[1-4]_stop_time - how many milliseconds [ms] must elapse to switch + corresponding fan off. (when the temperature was below + defined range). + +Note: last two functions are influenced by other control bits, not yet exported + by the driver, so a change might not have any effect. diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d index 83a3836289c..19b2ed739fa 100644 --- a/Documentation/hwmon/w83791d +++ b/Documentation/hwmon/w83791d @@ -5,7 +5,7 @@ Supported chips: * Winbond W83791D Prefix: 'w83791d' Addresses scanned: I2C 0x2c - 0x2f - Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791Da.pdf + Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791D_W83791Gb.pdf Author: Charles Spirakis <bezaur@gmail.com> @@ -20,6 +20,9 @@ Credits: Chunhao Huang <DZShen@Winbond.com.tw>, Rudolf Marek <r.marek@sh.cvut.cz> +Additional contributors: + Sven Anders <anders@anduras.de> + Module Parameters ----------------- @@ -46,7 +49,8 @@ Module Parameters Description ----------- -This driver implements support for the Winbond W83791D chip. +This driver implements support for the Winbond W83791D chip. The W83791G +chip appears to be the same as the W83791D but is lead free. Detection of the chip can sometimes be foiled because it can be in an internal state that allows no clean access (Bank with ID register is not @@ -71,34 +75,36 @@ Voltage sensors (also known as IN sensors) report their values in millivolts. An alarm is triggered if the voltage has crossed a programmable minimum or maximum limit. -Alarms are provided as output from a "realtime status register". The -following bits are defined: - -bit - alarm on: -0 - Vcore -1 - VINR0 -2 - +3.3VIN -3 - 5VDD -4 - temp1 -5 - temp2 -6 - fan1 -7 - fan2 -8 - +12VIN -9 - -12VIN -10 - -5VIN -11 - fan3 -12 - chassis -13 - temp3 -14 - VINR1 -15 - reserved -16 - tart1 -17 - tart2 -18 - tart3 -19 - VSB -20 - VBAT -21 - fan4 -22 - fan5 -23 - reserved +The bit ordering for the alarm "realtime status register" and the +"beep enable registers" are different. + +in0 (VCORE) : alarms: 0x000001 beep_enable: 0x000001 +in1 (VINR0) : alarms: 0x000002 beep_enable: 0x002000 <== mismatch +in2 (+3.3VIN): alarms: 0x000004 beep_enable: 0x000004 +in3 (5VDD) : alarms: 0x000008 beep_enable: 0x000008 +in4 (+12VIN) : alarms: 0x000100 beep_enable: 0x000100 +in5 (-12VIN) : alarms: 0x000200 beep_enable: 0x000200 +in6 (-5VIN) : alarms: 0x000400 beep_enable: 0x000400 +in7 (VSB) : alarms: 0x080000 beep_enable: 0x010000 <== mismatch +in8 (VBAT) : alarms: 0x100000 beep_enable: 0x020000 <== mismatch +in9 (VINR1) : alarms: 0x004000 beep_enable: 0x004000 +temp1 : alarms: 0x000010 beep_enable: 0x000010 +temp2 : alarms: 0x000020 beep_enable: 0x000020 +temp3 : alarms: 0x002000 beep_enable: 0x000002 <== mismatch +fan1 : alarms: 0x000040 beep_enable: 0x000040 +fan2 : alarms: 0x000080 beep_enable: 0x000080 +fan3 : alarms: 0x000800 beep_enable: 0x000800 +fan4 : alarms: 0x200000 beep_enable: 0x200000 +fan5 : alarms: 0x400000 beep_enable: 0x400000 +tart1 : alarms: 0x010000 beep_enable: 0x040000 <== mismatch +tart2 : alarms: 0x020000 beep_enable: 0x080000 <== mismatch +tart3 : alarms: 0x040000 beep_enable: 0x100000 <== mismatch +case_open : alarms: 0x001000 beep_enable: 0x001000 +user_enable : alarms: -------- beep_enable: 0x800000 + +*** NOTE: It is the responsibility of user-space code to handle the fact +that the beep enable and alarm bits are in different positions when using that +feature of the chip. When an alarm goes off, you can be warned by a beeping signal through your computer speaker. It is possible to enable all beeping globally, or only @@ -109,5 +115,6 @@ often will do no harm, but will return 'old' values. W83791D TODO: --------------- -Provide a patch for per-file alarms as discussed on the mailing list +Provide a patch for per-file alarms and beep enables as defined in the hwmon + documentation (Documentation/hwmon/sysfs-interface) Provide a patch for smart-fan control (still need appropriate motherboard/fans) diff --git a/MAINTAINERS b/MAINTAINERS index 63673e6513b..332b220f8a2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3309,6 +3309,12 @@ W: http://linuxtv.org T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git S: Maintained +VT1211 HARDWARE MONITOR DRIVER +P: Juerg Haefliger +M: juergh@gmail.com +L: lm-sensors@lm-sensors.org +S: Maintained + VT8231 HARDWARE MONITOR DRIVER P: Roger Lucas M: roger@planbit.co.uk diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f81a62380ad..f9362ee9955 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -17,6 +17,10 @@ config ARM Europe. There is an ARM Linux project with a web page at <http://www.arm.linux.org.uk/>. +config GENERIC_TIME + bool + default n + config MMU bool default y @@ -51,6 +55,10 @@ config GENERIC_HARDIRQS bool default y +config TRACE_IRQFLAGS_SUPPORT + bool + default y + config HARDIRQS_SW_RESEND bool default y @@ -91,7 +99,7 @@ config ARCH_MTD_XIP config VECTORS_BASE hex - default 0xffff0000 if MMU + default 0xffff0000 if MMU || CPU_HIGH_VECTOR default DRAM_BASE if REMAP_VECTORS_TO_RAM default 0x00000000 help @@ -198,16 +206,27 @@ config ARCH_IMX help Support for Motorola's i.MX family of processors (MX1, MXL). -config ARCH_IOP3XX - bool "IOP3xx-based" +config ARCH_IOP32X + bool "IOP32x-based" + depends on MMU + select PLAT_IOP + select PCI + help + Support for Intel's 80219 and IOP32X (XScale) family of + processors. + +config ARCH_IOP33X + bool "IOP33x-based" depends on MMU + select PLAT_IOP select PCI help - Support for Intel's IOP3XX (XScale) family of processors. + Support for Intel's IOP33X (XScale) family of processors. config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU + select GENERIC_TIME help Support for Intel's IXP4XX (XScale) family of processors. @@ -308,7 +327,9 @@ source "arch/arm/mach-footbridge/Kconfig" source "arch/arm/mach-integrator/Kconfig" -source "arch/arm/mach-iop3xx/Kconfig" +source "arch/arm/mach-iop32x/Kconfig" + +source "arch/arm/mach-iop33x/Kconfig" source "arch/arm/mach-ixp4xx/Kconfig" @@ -348,6 +369,9 @@ source "arch/arm/mach-netx/Kconfig" config ARCH_ACORN bool +config PLAT_IOP + bool + source arch/arm/mm/Kconfig # bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER @@ -602,6 +626,7 @@ config LEDS_CPU config ALIGNMENT_TRAP bool + depends on CPU_CP15_MMU default y if !ARCH_EBSA110 help ARM processors can not fetch/store information which is not @@ -633,11 +658,12 @@ config ZBOOT_ROM_BSS hex "Compressed ROM boot loader BSS address" default "0" help - The base address of 64KiB of read/write memory in the target - for the ROM-able zImage, which must be available while the - decompressor is running. Platforms which normally make use of - ROM-able zImage formats normally set this to a suitable - value in their defconfig file. + The base address of an area of read/write memory in the target + for the ROM-able zImage which must be available while the + decompressor is running. It must be large enough to hold the + entire decompressed kernel plus an additional 128 KiB. + Platforms which normally make use of ROM-able zImage formats + normally set this to a suitable value in their defconfig file. If ZBOOT_ROM is not enabled, this has no effect. @@ -832,7 +858,7 @@ source "drivers/base/Kconfig" source "drivers/connector/Kconfig" -if ALIGNMENT_TRAP +if ALIGNMENT_TRAP || !CPU_CP15_MMU source "drivers/mtd/Kconfig" endif @@ -844,7 +870,7 @@ source "drivers/block/Kconfig" source "drivers/acorn/block/Kconfig" -if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ +if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ || ARCH_IXP23XX diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu index e1574be2ded..f087376748d 100644 --- a/arch/arm/Kconfig-nommu +++ b/arch/arm/Kconfig-nommu @@ -25,6 +25,14 @@ config FLASH_SIZE hex 'FLASH Size' if SET_MEM_PARAM default 0x00400000 +config PROCESSOR_ID + hex + default 0x00007700 + depends on !CPU_CP15 + help + If processor has no CP15 register, this processor ID is + used instead of the auto-probing which utilizes the register. + config REMAP_VECTORS_TO_RAM bool 'Install vectors to the begining of RAM' if DRAM_BASE depends on DRAM_BASE diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 92873cdee31..2a0b2c8a1fe 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -55,7 +55,12 @@ arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 # This selects how we optimise for the processor. tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 +tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi +tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi +tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi +tune-$(CONFIG_CPU_ARM946T) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi @@ -101,7 +106,8 @@ endif machine-$(CONFIG_ARCH_INTEGRATOR) := integrator textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 machine-$(CONFIG_ARCH_CLPS711X) := clps711x - machine-$(CONFIG_ARCH_IOP3XX) := iop3xx + machine-$(CONFIG_ARCH_IOP32X) := iop32x + machine-$(CONFIG_ARCH_IOP33X) := iop33x machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx @@ -157,6 +163,7 @@ core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) core-$(CONFIG_VFP) += arch/arm/vfp/ # If we have a common platform directory, then include it in the build. +core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/ core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 2adc1527e0e..adddc713168 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -51,7 +51,11 @@ OBJS += head-at91rm9200.o endif ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) +ifeq ($(CONFIG_CPU_CP15),y) OBJS += big-endian.o +else +# The endian should be set by h/w design. +endif endif # diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 14a9ff9c68d..e5ab51b9cce 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -20,11 +20,21 @@ #ifdef DEBUG #if defined(CONFIG_DEBUG_ICEDCC) + +#ifdef CONFIG_CPU_V6 + .macro loadsp, rb + .endm + .macro writeb, ch, rb + mcr p14, 0, \ch, c0, c5, 0 + .endm +#else .macro loadsp, rb .endm .macro writeb, ch, rb mcr p14, 0, \ch, c0, c1, 0 .endm +#endif + #else #include <asm/arch/debug-macro.S> @@ -42,12 +52,6 @@ add \rb, \rb, #0x00010000 @ Ser1 #endif .endm -#elif defined(CONFIG_ARCH_IOP331) - .macro loadsp, rb - mov \rb, #0xff000000 - orr \rb, \rb, #0x00ff0000 - orr \rb, \rb, #0x0000f700 @ location of the UART - .endm #elif defined(CONFIG_ARCH_S3C2410) .macro loadsp, rb mov \rb, #0x50000000 @@ -78,9 +82,11 @@ kphex r6, 8 /* processor id */ kputc #':' kphex r7, 8 /* architecture id */ +#ifdef CONFIG_CPU_CP15 kputc #':' mrc p15, 0, r0, c1, c0 kphex r0, 8 /* control reg */ +#endif kputc #'\n' kphex r5, 8 /* decompressed kernel start */ kputc #'-' @@ -503,7 +509,11 @@ call_kernel: bl cache_clean_flush */ call_cache_fn: adr r12, proc_types +#ifdef CONFIG_CPU_CP15 mrc p15, 0, r6, c0, c0 @ get processor ID +#else + ldr r6, =CONFIG_PROCESSOR_ID +#endif 1: ldr r1, [r12, #0] @ get value ldr r2, [r12, #4] @ get mask eor r1, r1, r6 @ (real ^ match) diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index ace3fb5835d..283891c736c 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -30,6 +30,25 @@ static void putstr(const char *ptr); #include <asm/arch/uncompress.h> #ifdef CONFIG_DEBUG_ICEDCC + +#ifdef CONFIG_CPU_V6 + +static void icedcc_putc(int ch) +{ + int status, i = 0x4000000; + + do { + if (--i < 0) + return; + + asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status)); + } while (status & (1 << 29)); + + asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); +} + +#else + static void icedcc_putc(int ch) { int status, i = 0x4000000; @@ -44,6 +63,8 @@ static void icedcc_putc(int ch) asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch)); } +#endif + #define putc(ch) icedcc_putc(ch) #define flush() do { } while (0) #endif diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c index bafe8b19be8..6d094c15754 100644 --- a/arch/arm/common/icst307.c +++ b/arch/arm/common/icst307.c @@ -57,7 +57,7 @@ icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq) break; } while (i < ARRAY_SIZE(idx2s)); - if (i > ARRAY_SIZE(idx2s)) + if (i >= ARRAY_SIZE(idx2s)) return vco; vco.s = idx2s[i]; @@ -119,7 +119,7 @@ icst307_ps_to_vco(const struct icst307_params *p, unsigned long period) break; } while (i < ARRAY_SIZE(idx2s)); - if (i > ARRAY_SIZE(idx2s)) + if (i >= ARRAY_SIZE(idx2s)) return vco; vco.s = idx2s[i]; diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c index 943ef88c037..3d377c5bdef 100644 --- a/arch/arm/common/icst525.c +++ b/arch/arm/common/icst525.c @@ -55,7 +55,7 @@ icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq) break; } while (i < ARRAY_SIZE(idx2s)); - if (i > ARRAY_SIZE(idx2s)) + if (i >= ARRAY_SIZE(idx2s)) return vco; vco.s = idx2s[i]; @@ -118,7 +118,7 @@ icst525_ps_to_vco(const struct icst525_params *p, unsigned long period) break; } while (i < ARRAY_SIZE(idx2s)); - if (i > ARRAY_SIZE(idx2s)) + if (i >= ARRAY_SIZE(idx2s)) return vco; vco.s = idx2s[i]; diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 4e0dcaef6eb..181ef1ead5b 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -121,6 +121,13 @@ static struct locomo_dev_info locomo_devices[] = { .offset = 0, .length = 0, }, + { + .devid = LOCOMO_DEVID_SPI, + .irq = {}, + .name = "locomo-spi", + .offset = LOCOMO_SPI, + .length = 0x30, + }, }; @@ -374,7 +381,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc, struct irqdesc *d; void __iomem *mapbase = get_irq_chipdata(irq); - req = locomo_readl(mapbase + LOCOMO_SPIIR) & 0x000F; + req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F; if (req) { irq = LOCOMO_IRQ_SPI_START; d = irq_desc + irq; @@ -391,35 +398,35 @@ static void locomo_spi_ack_irq(unsigned int irq) { void __iomem *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_SPIWE); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIWE); + locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); - r = locomo_readl(mapbase + LOCOMO_SPIIS); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIIS); + locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS); - r = locomo_readl(mapbase + LOCOMO_SPIWE); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIWE); + locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); } static void locomo_spi_mask_irq(unsigned int irq) { void __iomem *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_SPIIE); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIIE); + locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); } static void locomo_spi_unmask_irq(unsigned int irq) { void __iomem *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_SPIIE); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIIE); + locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); } static struct irq_chip locomo_spi_chip = { @@ -814,12 +821,15 @@ static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev) return (struct locomo *)dev_get_drvdata(ldev->dev.parent); } -void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir) +void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir) { - struct locomo *lchip = locomo_chip_driver(ldev); + struct locomo *lchip = dev_get_drvdata(dev); unsigned long flags; unsigned int r; + if (!lchip) + return; + spin_lock_irqsave(&lchip->lock, flags); r = locomo_readl(lchip->base + LOCOMO_GPD); @@ -836,12 +846,15 @@ void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned in spin_unlock_irqrestore(&lchip->lock, flags); } -unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) +int locomo_gpio_read_level(struct device *dev, unsigned int bits) { - struct locomo *lchip = locomo_chip_driver(ldev); + struct locomo *lchip = dev_get_drvdata(dev); unsigned long flags; unsigned int ret; + if (!lchip) + return -ENODEV; + spin_lock_irqsave(&lchip->lock, flags); ret = locomo_readl(lchip->base + LOCOMO_GPL); spin_unlock_irqrestore(&lchip->lock, flags); @@ -850,12 +863,15 @@ unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) return ret; } -unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) +int locomo_gpio_read_output(struct device *dev, unsigned int bits) { - struct locomo *lchip = locomo_chip_driver(ldev); + struct locomo *lchip = dev_get_drvdata(dev); unsigned long flags; unsigned int ret; + if (!lchip) + return -ENODEV; + spin_lock_irqsave(&lchip->lock, flags); ret = locomo_readl(lchip->base + LOCOMO_GPO); spin_unlock_irqrestore(&lchip->lock, flags); @@ -864,12 +880,15 @@ unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) return ret; } -void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set) +void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set) { - struct locomo *lchip = locomo_chip_driver(ldev); + struct locomo *lchip = dev_get_drvdata(dev); unsigned long flags; unsigned int r; + if (!lchip) + return; + spin_lock_irqsave(&lchip->lock, flags); r = locomo_readl(lchip->base + LOCOMO_GPO); @@ -1058,9 +1077,9 @@ void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf) struct locomo *lchip = locomo_chip_driver(dev); if (vr) - locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1); + locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1); else - locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0); + locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0); spin_lock_irqsave(&lchip->lock, flags); locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 59b5ddec480..f412dedda68 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -40,6 +40,7 @@ #define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ #define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ #define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ + #define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ #define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ @@ -575,6 +576,9 @@ static int corgi_pxa_pm_enter(suspend_state_t state) while (corgi_enter_suspend(alarm_time,alarm_status,state)) {} + if (sharpsl_pm.machinfo->earlyresume) + sharpsl_pm.machinfo->earlyresume(); + dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); return 0; diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 2948b4589a8..3b4802a849e 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig @@ -126,6 +126,7 @@ CONFIG_CRUNCH=y # EP93xx Platforms # CONFIG_MACH_EDB9302=y +CONFIG_MACH_EDB9312=y CONFIG_MACH_EDB9315=y CONFIG_MACH_EDB9315A=y CONFIG_MACH_GESBC9312=y diff --git a/arch/arm/configs/ep80219_defconfig b/arch/arm/configs/iop32x_defconfig index 3c73b707c2f..0d67f66e78c 100644 --- a/arch/arm/configs/ep80219_defconfig +++ b/arch/arm/configs/iop32x_defconfig @@ -1,50 +1,63 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 22:34:12 2005 +# Linux kernel version: 2.6.18-rc7 +# Tue Sep 19 00:30:18 2006 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_UID16=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -52,24 +65,52 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y # +# Block layer +# +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# # System Type # +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +CONFIG_ARCH_IOP32X=y +# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set @@ -77,28 +118,19 @@ CONFIG_ARCH_IOP3XX=y # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set # -# IOP3xx Implementation Options +# IOP32x Implementation Options # # -# IOP3xx Platform Types +# IOP32x Platform Types # -# CONFIG_ARCH_IQ80321 is not set +CONFIG_MACH_GLANTANK=y +CONFIG_ARCH_IQ80321=y CONFIG_ARCH_IQ31244=y -# CONFIG_ARCH_IQ80331 is not set -# CONFIG_MACH_IQ80332 is not set -CONFIG_ARCH_EP80219=y -CONFIG_ARCH_IOP321=y -# CONFIG_ARCH_IOP331 is not set - -# -# IOP3xx Chipset Features -# +CONFIG_MACH_N2100=y +CONFIG_PLAT_IOP=y # # Processor Type @@ -109,7 +141,6 @@ CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_MINICACHE=y # # Processor Features @@ -121,8 +152,7 @@ CONFIG_XSCALE_PMU=y # Bus support # CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support @@ -133,6 +163,19 @@ CONFIG_PCI_NAMES=y # Kernel Features # # CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set CONFIG_ALIGNMENT_TRAP=y # @@ -140,7 +183,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp" # CONFIG_XIP_KERNEL is not set # @@ -166,6 +209,93 @@ CONFIG_BINFMT_AOUT=y # Power management options # # CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -177,6 +307,13 @@ CONFIG_BINFMT_AOUT=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) @@ -200,6 +337,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -225,18 +363,18 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0xf0000000 -CONFIG_MTD_PHYSMAP_LEN=0x00800000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers @@ -245,7 +383,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -261,6 +398,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_NAND is not set # +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# # Parallel port support # # CONFIG_PARPORT is not set @@ -272,7 +414,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -284,17 +425,9 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -305,6 +438,7 @@ CONFIG_IOSCHED_CFQ=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -316,6 +450,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -330,10 +465,12 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers # +# CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set @@ -344,25 +481,19 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_DPT_I2O is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set @@ -377,8 +508,7 @@ CONFIG_BLK_DEV_MD=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y # CONFIG_MD_RAID10 is not set -CONFIG_MD_RAID5=y -# CONFIG_MD_RAID6 is not set +# CONFIG_MD_RAID456 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=y @@ -392,6 +522,9 @@ CONFIG_BLK_DEV_DM=y # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -404,71 +537,8 @@ CONFIG_BLK_DEV_DM=y # CONFIG_I2O is not set # -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing +# Network device support # -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -481,14 +551,21 @@ CONFIG_NETDEVICES=y # CONFIG_ARCNET is not set # +# PHY device support +# +# CONFIG_PHYLIB is not set + +# # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set # # Tulip family network device support @@ -526,16 +603,23 @@ CONFIG_E1000_NAPI=y # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set +CONFIG_R8169=y +# CONFIG_R8169_NAPI is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -558,6 +642,8 @@ CONFIG_E1000_NAPI=y # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -595,7 +681,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # # CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -603,6 +688,7 @@ CONFIG_SOUND_GAMEPORT=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -610,7 +696,9 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -618,6 +706,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -631,8 +720,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set -# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -647,6 +736,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -671,14 +761,13 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set CONFIG_I2C_IOP3XX=y -# CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -689,15 +778,45 @@ CONFIG_I2C_IOP3XX=y # CONFIG_I2C_PCA_ISA is not set # -# Hardware Sensors Chip support +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus # -# CONFIG_I2C_SENSOR is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -712,36 +831,45 @@ CONFIG_I2C_IOP3XX=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set # -# Other I2C Chip support +# Misc devices # -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # -# Misc devices +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers # # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -751,6 +879,7 @@ CONFIG_I2C_IOP3XX=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -758,6 +887,7 @@ CONFIG_I2C_IOP3XX=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -769,7 +899,125 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set + +# +# USB DSL modem support +# # # USB Gadget Support @@ -782,10 +1030,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_MMC is not set # +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -795,22 +1050,22 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set - -# -# XFS support -# +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=y -CONFIG_XFS_EXPORT=y -# CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y +# CONFIG_XFS_RT is not set +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -830,12 +1085,10 @@ CONFIG_DNOTIFY=y # CONFIG_PROC_FS=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -850,8 +1103,9 @@ CONFIG_RAMFS=y # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_NAND is not set -# CONFIG_JFFS2_FS_NOR_ECC is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -868,16 +1122,19 @@ CONFIG_JFFS2_RTIME=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -886,6 +1143,7 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -905,6 +1163,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -921,11 +1180,34 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set # # Security options @@ -946,7 +1228,9 @@ CONFIG_DEBUG_USER=y # Library routines # # CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y diff --git a/arch/arm/configs/iq80332_defconfig b/arch/arm/configs/iop33x_defconfig index 11959b705d8..2a8fc153969 100644 --- a/arch/arm/configs/iq80332_defconfig +++ b/arch/arm/configs/iop33x_defconfig @@ -1,50 +1,63 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 17:33:39 2005 +# Linux kernel version: 2.6.18-rc7 +# Tue Sep 19 00:30:42 2006 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_UID16=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -52,24 +65,52 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y # +# Block layer +# +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" + +# # System Type # +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +CONFIG_ARCH_IOP33X=y # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set @@ -77,28 +118,17 @@ CONFIG_ARCH_IOP3XX=y # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set # -# IOP3xx Implementation Options +# IOP33x Implementation Options # # -# IOP3xx Platform Types +# IOP33x Platform Types # -# CONFIG_ARCH_IQ80321 is not set -# CONFIG_ARCH_IQ31244 is not set -# CONFIG_ARCH_IQ80331 is not set +CONFIG_ARCH_IQ80331=y CONFIG_MACH_IQ80332=y -# CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP331=y - -# -# IOP3xx Chipset Features -# -# CONFIG_IOP331_STEPD is not set +CONFIG_PLAT_IOP=y # # Processor Type @@ -109,7 +139,6 @@ CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_MINICACHE=y # # Processor Features @@ -121,8 +150,7 @@ CONFIG_XSCALE_PMU=y # Bus support # CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support @@ -133,6 +161,19 @@ CONFIG_PCI_NAMES=y # Kernel Features # # CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set CONFIG_ALIGNMENT_TRAP=y # @@ -140,7 +181,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp" # CONFIG_XIP_KERNEL is not set # @@ -166,6 +207,93 @@ CONFIG_BINFMT_AOUT=y # Power management options # # CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -177,6 +305,13 @@ CONFIG_BINFMT_AOUT=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) @@ -200,6 +335,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -222,6 +358,7 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set @@ -229,18 +366,18 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0xc0000000 -CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x0 CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers @@ -249,7 +386,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -265,6 +401,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_NAND is not set # +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# # Parallel port support # # CONFIG_PARPORT is not set @@ -276,7 +417,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -288,17 +428,9 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -309,6 +441,7 @@ CONFIG_IOSCHED_CFQ=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -320,6 +453,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -334,10 +468,12 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers # +# CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set @@ -348,25 +484,19 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_DPT_I2O is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set @@ -381,8 +511,7 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y # CONFIG_MD_RAID10 is not set -CONFIG_MD_RAID5=y -# CONFIG_MD_RAID6 is not set +# CONFIG_MD_RAID456 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=y @@ -396,6 +525,9 @@ CONFIG_BLK_DEV_DM=y # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -408,71 +540,8 @@ CONFIG_BLK_DEV_DM=y # CONFIG_I2O is not set # -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - +# Network device support # -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -485,6 +554,10 @@ CONFIG_NETDEVICES=y # CONFIG_ARCNET is not set # +# PHY device support +# + +# # Ethernet (10 or 100Mbit) # # CONFIG_NET_ETHERNET is not set @@ -501,14 +574,20 @@ CONFIG_E1000_NAPI=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -531,6 +610,8 @@ CONFIG_E1000_NAPI=y # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -568,7 +649,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # # CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -576,6 +656,7 @@ CONFIG_SOUND_GAMEPORT=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -583,7 +664,9 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -591,6 +674,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -604,8 +688,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set -# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -620,6 +704,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -644,14 +729,13 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set CONFIG_I2C_IOP3XX=y -# CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -662,15 +746,45 @@ CONFIG_I2C_IOP3XX=y # CONFIG_I2C_PCA_ISA is not set # -# Hardware Sensors Chip support +# Miscellaneous I2C Chip support # -# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -685,36 +799,45 @@ CONFIG_I2C_IOP3XX=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set # -# Other I2C Chip support +# Misc devices # -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set # -# Misc devices +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers # # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -724,6 +847,7 @@ CONFIG_I2C_IOP3XX=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -731,6 +855,7 @@ CONFIG_I2C_IOP3XX=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -742,9 +867,14 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB is not set # +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# # USB Gadget Support # # CONFIG_USB_GADGET is not set @@ -755,10 +885,17 @@ CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_MMC is not set # +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -768,22 +905,22 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set - -# -# XFS support -# +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=y -CONFIG_XFS_EXPORT=y -# CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y +# CONFIG_XFS_RT is not set +# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -803,12 +940,10 @@ CONFIG_DNOTIFY=y # CONFIG_PROC_FS=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -834,16 +969,19 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -852,6 +990,7 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -871,6 +1010,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -887,11 +1027,34 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set # # Security options @@ -912,5 +1075,7 @@ CONFIG_DEBUG_USER=y # Library routines # # CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set # CONFIG_CRC32 is not set # CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y diff --git a/arch/arm/configs/iq31244_defconfig b/arch/arm/configs/iq31244_defconfig deleted file mode 100644 index 32467160a6d..00000000000 --- a/arch/arm/configs/iq31244_defconfig +++ /dev/null @@ -1,922 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 02:10:38 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# IOP3xx Implementation Options -# - -# -# IOP3xx Platform Types -# -# CONFIG_ARCH_IQ80321 is not set -CONFIG_ARCH_IQ31244=y -# CONFIG_ARCH_IQ80331 is not set -# CONFIG_MACH_IQ80332 is not set -# CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP321=y -# CONFIG_ARCH_IOP331 is not set - -# -# IOP3xx Chipset Features -# - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_XSCALE=y -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV5T=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_MINICACHE=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -CONFIG_XSCALE_PMU=y - -# -# Bus support -# -CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -CONFIG_PCI_NAMES=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y -CONFIG_MTD_REDBOOT_PARTS_READONLY=y -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0xf0000000 -CONFIG_MTD_PHYSMAP_LEN=0x00800000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -# CONFIG_MD_LINEAR is not set -CONFIG_MD_RAID0=y -CONFIG_MD_RAID1=y -# CONFIG_MD_RAID10 is not set -CONFIG_MD_RAID5=y -# CONFIG_MD_RAID6 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_CRYPT is not set -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -CONFIG_E1000=y -CONFIG_E1000_NAPI=y -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -CONFIG_I2C_IOP3XX=y -# CONFIG_I2C_ISA is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Hardware Sensors Chip support -# -# CONFIG_I2C_SENSOR is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set - -# -# Other I2C Chip support -# -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -CONFIG_XFS_FS=y -CONFIG_XFS_EXPORT=y -# CONFIG_XFS_RT is not set -# CONFIG_XFS_QUOTA is not set -CONFIG_XFS_SECURITY=y -CONFIG_XFS_POSIX_ACL=y -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_NAND is not set -# CONFIG_JFFS2_FS_NOR_ECC is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V4 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_USER=y - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig deleted file mode 100644 index b000da753c4..00000000000 --- a/arch/arm/configs/iq80321_defconfig +++ /dev/null @@ -1,843 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 13:24:10 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# IOP3xx Implementation Options -# - -# -# IOP3xx Platform Types -# -CONFIG_ARCH_IQ80321=y -# CONFIG_ARCH_IQ31244 is not set -# CONFIG_ARCH_IQ80331 is not set -# CONFIG_MACH_IQ80332 is not set -# CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP321=y -# CONFIG_ARCH_IOP331 is not set - -# -# IOP3xx Chipset Features -# - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_XSCALE=y -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV5T=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_MINICACHE=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -CONFIG_XSCALE_PMU=y - -# -# Bus support -# -CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -CONFIG_PCI_NAMES=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y -CONFIG_MTD_REDBOOT_PARTS_READONLY=y -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0xf0000000 -CONFIG_MTD_PHYSMAP_LEN=0x00800000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=1 -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -CONFIG_E1000=y -CONFIG_E1000_NAPI=y -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -CONFIG_I2C_IOP3XX=y -# CONFIG_I2C_ISA is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Hardware Sensors Chip support -# -# CONFIG_I2C_SENSOR is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set - -# -# Other I2C Chip support -# -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -CONFIG_XFS_FS=y -CONFIG_XFS_EXPORT=y -# CONFIG_XFS_RT is not set -# CONFIG_XFS_QUOTA is not set -CONFIG_XFS_SECURITY=y -CONFIG_XFS_POSIX_ACL=y -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_NAND is not set -# CONFIG_JFFS2_FS_NOR_ECC is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V4 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_USER=y - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/iq80331_defconfig b/arch/arm/configs/iq80331_defconfig deleted file mode 100644 index 46c79e1efe0..00000000000 --- a/arch/arm/configs/iq80331_defconfig +++ /dev/null @@ -1,916 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 15:13:37 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# IOP3xx Implementation Options -# - -# -# IOP3xx Platform Types -# -# CONFIG_ARCH_IQ80321 is not set -# CONFIG_ARCH_IQ31244 is not set -CONFIG_ARCH_IQ80331=y -# CONFIG_MACH_IQ80332 is not set -# CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP331=y - -# -# IOP3xx Chipset Features -# -CONFIG_IOP331_STEPD=y - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_XSCALE=y -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV5T=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_MINICACHE=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -CONFIG_XSCALE_PMU=y - -# -# Bus support -# -CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -CONFIG_PCI_NAMES=y - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y -CONFIG_MTD_REDBOOT_PARTS_READONLY=y -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_GEOMETRY is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0xc0000000 -CONFIG_MTD_PHYSMAP_LEN=0x00800000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=1 -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=y -CONFIG_MD_RAID0=y -CONFIG_MD_RAID1=y -# CONFIG_MD_RAID10 is not set -CONFIG_MD_RAID5=y -# CONFIG_MD_RAID6 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_CRYPT is not set -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -CONFIG_E1000=y -CONFIG_E1000_NAPI=y -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -CONFIG_I2C_IOP3XX=y -# CONFIG_I2C_ISA is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Hardware Sensors Chip support -# -# CONFIG_I2C_SENSOR is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set - -# -# Other I2C Chip support -# -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -CONFIG_XFS_FS=y -CONFIG_XFS_EXPORT=y -# CONFIG_XFS_RT is not set -# CONFIG_XFS_QUOTA is not set -CONFIG_XFS_SECURITY=y -CONFIG_XFS_POSIX_ACL=y -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_XATTR is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V4 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_USER=y - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC32 is not set -# CONFIG_LIBCRC32C is not set diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index f20814e6f49..a8322264104 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1,14 +1,19 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-git9 -# Sun Jun 25 23:56:32 2006 +# Linux kernel version: 2.6.18 +# Wed Sep 20 20:27:31 2006 # CONFIG_ARM=y CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -26,14 +31,15 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -46,6 +52,8 @@ CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -84,7 +92,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set @@ -94,7 +102,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP23XX is not set @@ -122,13 +131,18 @@ CONFIG_ARCH_SMDK2410=y CONFIG_ARCH_S3C2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_SMDK2440_CPU2442=y +CONFIG_MACH_S3C2413=y CONFIG_MACH_SMDK2413=y CONFIG_MACH_VR1000=y CONFIG_MACH_RX3715=y CONFIG_MACH_OTOM=y CONFIG_MACH_NEXCODER_2440=y +CONFIG_MACH_VSTMS=y CONFIG_S3C2410_CLOCK=y +CONFIG_S3C2410_PM=y +CONFIG_CPU_S3C2410_DMA=y CONFIG_CPU_S3C2410=y +CONFIG_S3C2412_PM=y CONFIG_CPU_S3C2412=y CONFIG_CPU_S3C244X=y CONFIG_CPU_S3C2440=y @@ -156,7 +170,7 @@ CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_ARM926T=y -CONFIG_CPU_32v4=y +CONFIG_CPU_32v4T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV4T=y CONFIG_CPU_ABRT_EV5TJ=y @@ -200,6 +214,7 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set CONFIG_ALIGNMENT_TRAP=y # @@ -304,7 +319,6 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -460,6 +474,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m @@ -640,6 +655,7 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -716,6 +732,7 @@ CONFIG_S3C2410_WATCHDOG=y # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set +CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set CONFIG_S3C2410_RTC=y # CONFIG_DTLK is not set @@ -857,12 +874,12 @@ CONFIG_VIDEO_V4L2=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set -CONFIG_FB_FIRMWARE_EDID=y # CONFIG_FB_BACKLIGHT is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set @@ -995,7 +1012,7 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CY7C63 is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set @@ -1095,6 +1112,7 @@ CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y # CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -1202,14 +1220,19 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y @@ -1251,3 +1274,4 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index 33c55689f99..ecf4f9472d9 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c @@ -25,6 +25,7 @@ #include <linux/list.h> #include <linux/init.h> #include <linux/completion.h> +#include <linux/kthread.h> #include <asm/apm.h> /* apm_power_info */ #include <asm/system.h> @@ -80,7 +81,7 @@ struct apm_user { */ static int suspends_pending; static int apm_disabled; -static int arm_apm_active; +static struct task_struct *kapmd_tsk; static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); @@ -97,7 +98,6 @@ static LIST_HEAD(apm_user_list); * to be suspending the system. */ static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); -static DECLARE_COMPLETION(kapmd_exit); static DEFINE_SPINLOCK(kapmd_queue_lock); static struct apm_queue kapmd_queue; @@ -468,16 +468,13 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length) static int kapmd(void *arg) { - daemonize("kapmd"); - current->flags |= PF_NOFREEZE; - do { apm_event_t event; wait_event_interruptible(kapmd_wait, - !queue_empty(&kapmd_queue) || !arm_apm_active); + !queue_empty(&kapmd_queue) || kthread_should_stop()); - if (!arm_apm_active) + if (kthread_should_stop()) break; spin_lock_irq(&kapmd_queue_lock); @@ -508,7 +505,7 @@ static int kapmd(void *arg) } } while (1); - complete_and_exit(&kapmd_exit, 0); + return 0; } static int __init apm_init(void) @@ -520,13 +517,14 @@ static int __init apm_init(void) return -ENODEV; } - arm_apm_active = 1; - - ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); - if (ret < 0) { - arm_apm_active = 0; + kapmd_tsk = kthread_create(kapmd, NULL, "kapmd"); + if (IS_ERR(kapmd_tsk)) { + ret = PTR_ERR(kapmd_tsk); + kapmd_tsk = NULL; return ret; } + kapmd_tsk->flags |= PF_NOFREEZE; + wake_up_process(kapmd_tsk); #ifdef CONFIG_PROC_FS create_proc_info_entry("apm", 0, NULL, apm_get_info); @@ -535,10 +533,7 @@ static int __init apm_init(void) ret = misc_register(&apm_device); if (ret != 0) { remove_proc_entry("apm", NULL); - - arm_apm_active = 0; - wake_up(&kapmd_wait); - wait_for_completion(&kapmd_exit); + kthread_stop(kapmd_tsk); } return ret; @@ -549,9 +544,7 @@ static void __exit apm_exit(void) misc_deregister(&apm_device); remove_proc_entry("apm", NULL); - arm_apm_active = 0; - wake_up(&kapmd_wait); - wait_for_completion(&kapmd_exit); + kthread_stop(kapmd_tsk); } module_init(apm_init); diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index a5747e58a9d..5617566477b 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -21,6 +21,36 @@ #if defined(CONFIG_DEBUG_ICEDCC) @@ debug using ARM EmbeddedICE DCC channel + +#if defined(CONFIG_CPU_V6) + + .macro addruart, rx + .endm + + .macro senduart, rd, rx + mcr p14, 0, \rd, c0, c5, 0 + .endm + + .macro busyuart, rd, rx +1001: + mrc p14, 0, \rx, c0, c1, 0 + tst \rx, #0x20000000 + beq 1001b + .endm + + .macro waituart, rd, rx + mov \rd, #0x2000000 +1001: + subs \rd, \rd, #1 + bmi 1002f + mrc p14, 0, \rx, c0, c1, 0 + tst \rx, #0x20000000 + bne 1001b +1002: + .endm + +#else + .macro addruart, rx .endm @@ -46,9 +76,12 @@ bne 1001b 1002: .endm + +#endif /* CONFIG_CPU_V6 */ + #else #include <asm/arch/debug-macro.S> -#endif +#endif /* CONFIG_DEBUG_ICEDCC */ /* * Useful debugging routines diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index de4e3313790..bd623b73445 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -191,6 +191,9 @@ __dabt_svc: __irq_svc: svc_entry +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_off +#endif #ifdef CONFIG_PREEMPT get_thread_info tsk ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -211,6 +214,10 @@ preempt_return: #endif ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr_cxsf, r0 +#ifdef CONFIG_TRACE_IRQFLAGS + tst r0, #PSR_I_BIT + bleq trace_hardirqs_on +#endif ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .ltorg @@ -398,6 +405,9 @@ __dabt_usr: __irq_usr: usr_entry +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_off +#endif get_thread_info tsk #ifdef CONFIG_PREEMPT ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -412,6 +422,9 @@ __irq_usr: teq r0, r7 strne r0, [r0, -r0] #endif +#ifdef CONFIG_TRACE_IRQFLAGS + bl trace_hardirqs_on +#endif mov why, #0 b ret_to_user diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index ac9eb3d3051..f359a189dcf 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -9,7 +9,6 @@ * published by the Free Software Foundation. * * Common kernel startup code (non-paged MM) - * for 32-bit CPUs which has a process ID register(CP15). * */ #include <linux/linkage.h> @@ -40,7 +39,11 @@ ENTRY(stext) msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode @ and irqs disabled +#ifndef CONFIG_CPU_CP15 + ldr r9, =CONFIG_PROCESSOR_ID +#else mrc p15, 0, r9, c0, c0 @ get processor id +#endif bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? beq __error_p @ yes, error 'p' @@ -58,6 +61,7 @@ ENTRY(stext) */ .type __after_proc_init, %function __after_proc_init: +#ifdef CONFIG_CPU_CP15 mrc p15, 0, r0, c1, c0, 0 @ read control reg #ifdef CONFIG_ALIGNMENT_TRAP orr r0, r0, #CR_A @@ -73,7 +77,13 @@ __after_proc_init: #ifdef CONFIG_CPU_ICACHE_DISABLE bic r0, r0, #CR_I #endif +#ifdef CONFIG_CPU_HIGH_VECTOR + orr r0, r0, #CR_V +#else + bic r0, r0, #CR_V +#endif mcr p15, 0, r0, c1, c0, 0 @ write control reg +#endif /* CONFIG_CPU_CP15 */ mov pc, r13 @ clear the BSS and jump @ to start_kernel diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 298363d9704..1b061583408 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -2,6 +2,7 @@ * linux/arch/arm/kernel/module.c * * Copyright (C) 2002 Russell King. + * Modified for nommu by Hyok S. Choi * * 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 @@ -32,6 +33,7 @@ extern void _etext; #define MODULE_START (((unsigned long)&_etext + ~PGDIR_MASK) & PGDIR_MASK) #endif +#ifdef CONFIG_MMU void *module_alloc(unsigned long size) { struct vm_struct *area; @@ -46,6 +48,12 @@ void *module_alloc(unsigned long size) return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); } +#else /* CONFIG_MMU */ +void *module_alloc(unsigned long size) +{ + return size == 0 ? NULL : vmalloc(size); +} +#endif /* !CONFIG_MMU */ void module_free(struct module *module, void *region) { diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 3079535afcc..bf35c178a87 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -221,16 +221,26 @@ void __show_regs(struct pt_regs *regs) processor_modes[processor_mode(regs)], thumb_mode(regs) ? " (T)" : "", get_fs() == get_ds() ? "kernel" : "user"); +#if CONFIG_CPU_CP15 { - unsigned int ctrl, transbase, dac; + unsigned int ctrl; __asm__ ( " mrc p15, 0, %0, c1, c0\n" - " mrc p15, 0, %1, c2, c0\n" - " mrc p15, 0, %2, c3, c0\n" - : "=r" (ctrl), "=r" (transbase), "=r" (dac)); - printk("Control: %04X Table: %08X DAC: %08X\n", - ctrl, transbase, dac); + : "=r" (ctrl)); + printk("Control: %04X\n", ctrl); } +#ifdef CONFIG_CPU_CP15_MMU + { + unsigned int transbase, dac; + __asm__ ( + " mrc p15, 0, %0, c2, c0\n" + " mrc p15, 0, %1, c3, c0\n" + : "=r" (transbase), "=r" (dac)); + printk("Table: %08X DAC: %08X\n", + transbase, dac); + } +#endif +#endif } void show_regs(struct pt_regs * regs) diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 09a67d77185..d4dceb5f06e 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -69,10 +69,12 @@ EXPORT_SYMBOL(profile_pc); */ int (*set_rtc)(void); +#ifndef CONFIG_GENERIC_TIME static unsigned long dummy_gettimeoffset(void) { return 0; } +#endif /* * Scheduler clock - returns current time in nanosec units. @@ -230,6 +232,7 @@ static inline void do_leds(void) #define do_leds() #endif +#ifndef CONFIG_GENERIC_TIME void do_gettimeofday(struct timeval *tv) { unsigned long flags; @@ -291,6 +294,7 @@ int do_settimeofday(struct timespec *tv) } EXPORT_SYMBOL(do_settimeofday); +#endif /* !CONFIG_GENERIC_TIME */ /** * save_time_delta - Save the offset between system time and RTC time @@ -500,8 +504,10 @@ device_initcall(timer_init_sysfs); void __init time_init(void) { +#ifndef CONFIG_GENERIC_TIME if (system_timer->offset == NULL) system_timer->offset = dummy_gettimeoffset; +#endif system_timer->init(); #ifdef CONFIG_NO_IDLE_HZ diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index aeeed806f99..bede380c07a 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -191,7 +191,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) if (tsk != current) fp = thread_saved_fp(tsk); else - asm("mov%? %0, fp" : "=r" (fp)); + asm("mov %0, fp" : "=r" (fp) : : "cc"); c_backtrace(fp, 0x10); barrier(); diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index 0985b1c42c7..dcf6136fedf 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c @@ -17,6 +17,7 @@ #include <asm/hardware.h> #include "generic.h" +#include "clock.h" static struct map_desc at91rm9200_io_desc[] __initdata = { { @@ -26,87 +27,224 @@ static struct map_desc at91rm9200_io_desc[] __initdata = { .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_SPI, - .pfn = __phys_to_pfn(AT91_BASE_SPI), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_SSC2, - .pfn = __phys_to_pfn(AT91_BASE_SSC2), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_SSC1, - .pfn = __phys_to_pfn(AT91_BASE_SSC1), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_SSC0, - .pfn = __phys_to_pfn(AT91_BASE_SSC0), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_US3, - .pfn = __phys_to_pfn(AT91_BASE_US3), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_US2, - .pfn = __phys_to_pfn(AT91_BASE_US2), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_US1, - .pfn = __phys_to_pfn(AT91_BASE_US1), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_US0, - .pfn = __phys_to_pfn(AT91_BASE_US0), + .pfn = __phys_to_pfn(AT91RM9200_BASE_SPI), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_EMAC, - .pfn = __phys_to_pfn(AT91_BASE_EMAC), + .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_TWI, - .pfn = __phys_to_pfn(AT91_BASE_TWI), + .pfn = __phys_to_pfn(AT91RM9200_BASE_TWI), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_MCI, - .pfn = __phys_to_pfn(AT91_BASE_MCI), + .pfn = __phys_to_pfn(AT91RM9200_BASE_MCI), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_UDP, - .pfn = __phys_to_pfn(AT91_BASE_UDP), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_TCB1, - .pfn = __phys_to_pfn(AT91_BASE_TCB1), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_TCB0, - .pfn = __phys_to_pfn(AT91_BASE_TCB0), + .pfn = __phys_to_pfn(AT91RM9200_BASE_UDP), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_SRAM_VIRT_BASE, - .pfn = __phys_to_pfn(AT91_SRAM_BASE), - .length = AT91_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), + .length = AT91RM9200_SRAM_SIZE, .type = MT_DEVICE, }, }; -void __init at91rm9200_map_io(void) +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91RM9200_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91RM9200_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ether_clk = { + .name = "ether_clk", + .pmc_mask = 1 << AT91RM9200_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91RM9200_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91RM9200_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91RM9200_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91RM9200_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91RM9200_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91RM9200_ID_US3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi_clk = { + .name = "spi_clk", + .pmc_mask = 1 << AT91RM9200_ID_SPI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91RM9200_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91RM9200_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91RM9200_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioD_clk = { + .name = "pioD_clk", + .pmc_mask = 1 << AT91RM9200_ID_PIOD, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &pioD_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &usart3_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi_clk, + // ssc 0 .. ssc2 + // tc0 .. tc5 + &ohci_clk, + ðer_clk, + // irq0 .. irq6 +}; + +/* + * The four programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 2, +}; +static struct clk pck3 = { + .name = "pck3", + .pmc_mask = AT91_PMC_PCK3, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 3, +}; + +static void __init at91rm9200_register_clocks(void) { + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); + clk_register(&pck3); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91rm9200_gpio[] = { + { + .id = AT91RM9200_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91RM9200_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91RM9200_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + }, { + .id = AT91RM9200_ID_PIOD, + .offset = AT91_PIOD, + .clock = &pioD_clk, + } +}; + +/* -------------------------------------------------------------------- + * AT91RM9200 processor initialization + * -------------------------------------------------------------------- */ +void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks) +{ + /* Map peripherals */ iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91rm9200_register_clocks(); + + /* Initialize GPIO subsystem */ + at91_gpio_init(at91rm9200_gpio, banks); } + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + /* * The default interrupt priority levels (0 = lowest, 7 = highest). */ @@ -145,10 +283,14 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { 0 /* Advanced Interrupt Controller (IRQ6) */ }; -void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) +void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS]) { if (!priority) priority = at91rm9200_default_irq_priority; + /* Initialize the AIC interrupt controller */ at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); } diff --git a/arch/arm/mach-at91rm9200/board-1arm.c b/arch/arm/mach-at91rm9200/board-1arm.c index dc79e0992af..36eecd7161f 100644 --- a/arch/arm/mach-at91rm9200/board-1arm.c +++ b/arch/arm/mach-at91rm9200/board-1arm.c @@ -34,20 +34,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init onearm_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(PQFP_GPIO_BANKS); -} /* * Serial port configuration. @@ -62,15 +53,18 @@ static struct at91_uart_config __initdata onearm_uart_config = { static void __init onearm_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_PQFP); /* Setup the serial ports and console */ at91_init_serial(&onearm_uart_config); } +static void __init onearm_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + static struct at91_eth_data __initdata onearm_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91rm9200/board-carmeva.c index 2c138b542eb..50e513681ae 100644 --- a/arch/arm/mach-at91rm9200/board-carmeva.c +++ b/arch/arm/mach-at91rm9200/board-carmeva.c @@ -35,20 +35,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init carmeva_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(BGA_GPIO_BANKS); -} /* * Serial port configuration. @@ -63,15 +54,19 @@ static struct at91_uart_config __initdata carmeva_uart_config = { static void __init carmeva_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 20.000 MHz crystal */ - at91_clock_init(20000000); + /* Initialize processor: 20.000 MHz crystal */ + at91rm9200_initialize(20000000, AT91RM9200_BGA); /* Setup the serial ports and console */ at91_init_serial(&carmeva_uart_config); } +static void __init carmeva_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + + static struct at91_eth_data __initdata carmeva_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c index 794d3fbb449..8eeae491ce7 100644 --- a/arch/arm/mach-at91rm9200/board-csb337.c +++ b/arch/arm/mach-at91rm9200/board-csb337.c @@ -34,20 +34,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init csb337_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(BGA_GPIO_BANKS); -} /* * Serial port configuration. @@ -62,10 +53,8 @@ static struct at91_uart_config __initdata csb337_uart_config = { static void __init csb337_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 3.6864 MHz crystal */ - at91_clock_init(3686400); + /* Initialize processor: 3.6864 MHz crystal */ + at91rm9200_initialize(3686400, AT91RM9200_BGA); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); @@ -74,6 +63,11 @@ static void __init csb337_map_io(void) at91_init_serial(&csb337_uart_config); } +static void __init csb337_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + static struct at91_eth_data __initdata csb337_eth_data = { .phy_irq_pin = AT91_PIN_PC2, .is_rmii = 0, diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c index c8b6f334246..a29fa0e822c 100644 --- a/arch/arm/mach-at91rm9200/board-csb637.c +++ b/arch/arm/mach-at91rm9200/board-csb637.c @@ -33,20 +33,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init csb637_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(BGA_GPIO_BANKS); -} /* * Serial port configuration. @@ -61,10 +52,8 @@ static struct at91_uart_config __initdata csb637_uart_config = { static void __init csb637_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 3.6864 MHz crystal */ - at91_clock_init(3686400); + /* Initialize processor: 3.6864 MHz crystal */ + at91rm9200_initialize(3686400, AT91RM9200_BGA); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); @@ -73,6 +62,11 @@ static void __init csb637_map_io(void) at91_init_serial(&csb637_uart_config); } +static void __init csb637_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + static struct at91_eth_data __initdata csb637_eth_data = { .phy_irq_pin = AT91_PIN_PC0, .is_rmii = 0, diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index 65873037e02..c699f3984d4 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c @@ -37,20 +37,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init dk_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(BGA_GPIO_BANKS); -} /* * Serial port configuration. @@ -65,10 +56,8 @@ static struct at91_uart_config __initdata dk_uart_config = { static void __init dk_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_BGA); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); @@ -77,6 +66,11 @@ static void __init dk_map_io(void) at91_init_serial(&dk_uart_config); } +static void __init dk_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + static struct at91_eth_data __initdata dk_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -128,6 +122,29 @@ static struct spi_board_info dk_spi_devices[] = { #endif }; +static struct mtd_partition __initdata dk_nand_partition[] = { + { + .name = "NAND Partition 1", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition *nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(dk_nand_partition); + return dk_nand_partition; +} + +static struct at91_nand_data __initdata dk_nand_data = { + .ale = 22, + .cle = 21, + .det_pin = AT91_PIN_PB1, + .rdy_pin = AT91_PIN_PC2, + // .enable_pin = ... not there + .partition_info = nand_partitions, +}; + static void __init dk_board_init(void) { /* Serial */ @@ -153,6 +170,8 @@ static void __init dk_board_init(void) at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ at91_add_device_mmc(&dk_mmc_data); #endif + /* NAND */ + at91_add_device_nand(&dk_nand_data); /* VGA */ // dk_add_device_video(); } diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91rm9200/board-eb9200.c index a3e2df968a6..c6e0d51fbea 100644 --- a/arch/arm/mach-at91rm9200/board-eb9200.c +++ b/arch/arm/mach-at91rm9200/board-eb9200.c @@ -35,20 +35,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init eb9200_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(BGA_GPIO_BANKS); -} /* * Serial port configuration. @@ -63,15 +54,18 @@ static struct at91_uart_config __initdata eb9200_uart_config = { static void __init eb9200_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_BGA); /* Setup the serial ports and console */ at91_init_serial(&eb9200_uart_config); } +static void __init eb9200_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + static struct at91_eth_data __initdata eb9200_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index 868192351dd..830eb793217 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c @@ -37,20 +37,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init ek_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(BGA_GPIO_BANKS); -} /* * Serial port configuration. @@ -65,10 +56,8 @@ static struct at91_uart_config __initdata ek_uart_config = { static void __init ek_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_BGA); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); @@ -77,6 +66,11 @@ static void __init ek_map_io(void) at91_init_serial(&ek_uart_config); } +static void __init ek_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + static struct at91_eth_data __initdata ek_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, diff --git a/arch/arm/mach-at91rm9200/board-kafa.c b/arch/arm/mach-at91rm9200/board-kafa.c index bf760c5e0c4..91e301924f2 100644 --- a/arch/arm/mach-at91rm9200/board-kafa.c +++ b/arch/arm/mach-at91rm9200/board-kafa.c @@ -34,20 +34,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init kafa_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(PQFP_GPIO_BANKS); -} /* * Serial port configuration. @@ -62,10 +53,8 @@ static struct at91_uart_config __initdata kafa_uart_config = { static void __init kafa_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_PQFP); /* Set up the LEDs */ at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); @@ -74,6 +63,11 @@ static void __init kafa_map_io(void) at91_init_serial(&kafa_uart_config); } +static void __init kafa_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + static struct at91_eth_data __initdata kafa_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 0, diff --git a/arch/arm/mach-at91rm9200/board-kb9202.c b/arch/arm/mach-at91rm9200/board-kb9202.c index f06d2b54cc9..272fe43bcec 100644 --- a/arch/arm/mach-at91rm9200/board-kb9202.c +++ b/arch/arm/mach-at91rm9200/board-kb9202.c @@ -35,20 +35,11 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> -#include <asm/hardware.h> #include <asm/arch/board.h> #include <asm/arch/gpio.h> #include "generic.h" -static void __init kb9202_init_irq(void) -{ - /* Initialize AIC controller */ - at91rm9200_init_irq(NULL); - - /* Set up the GPIO interrupts */ - at91_gpio_irq_setup(PQFP_GPIO_BANKS); -} /* * Serial port configuration. @@ -63,10 +54,8 @@ static struct at91_uart_config __initdata kb9202_uart_config = { static void __init kb9202_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 10 MHz crystal */ - at91_clock_init(10000000); + /* Initialize processor: 10 MHz crystal */ + at91rm9200_initialize(10000000, AT91RM9200_PQFP); /* Set up the LEDs */ at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); @@ -75,6 +64,11 @@ static void __init kb9202_map_io(void) at91_init_serial(&kb9202_uart_config); } +static void __init kb9202_init_irq(void) +{ + at91rm9200_init_interrupts(NULL); +} + static struct at91_eth_data __initdata kb9202_eth_data = { .phy_irq_pin = AT91_PIN_PB29, .is_rmii = 0, @@ -95,6 +89,29 @@ static struct at91_mmc_data __initdata kb9202_mmc_data = { .wire4 = 1, }; +static struct mtd_partition __initdata kb9202_nand_partition[] = { + { + .name = "nand_fs", + .offset = 0, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition *nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(kb9202_nand_partition); + return kb9202_nand_partition; +} + +static struct at91_nand_data __initdata kb9202_nand_data = { + .ale = 22, + .cle = 21, + // .det_pin = ... not there + .rdy_pin = AT91_PIN_PC29, + .enable_pin = AT91_PIN_PC28, + .partition_info = nand_partitions, +}; + static void __init kb9202_board_init(void) { /* Serial */ @@ -111,6 +128,8 @@ static void __init kb9202_board_init(void) at91_add_device_i2c(); /* SPI */ at91_add_device_spi(NULL, 0); + /* NAND */ + at91_add_device_nand(&kb9202_nand_data); } MACHINE_START(KB9200, "KB920x") diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c index edc2cc837ae..a43b061a7c8 100644 --- a/arch/arm/mach-at91rm9200/clock.c +++ b/arch/arm/mach-at91rm9200/clock.c @@ -29,7 +29,7 @@ #include <asm/hardware.h> -#include "generic.h" +#include "clock.h" /* @@ -38,23 +38,15 @@ * PLLB be used at other rates (on boards that don't need USB), etc. */ -struct clk { - const char *name; /* unique clock name */ - const char *function; /* function of the clock */ - struct device *dev; /* device associated with function */ - unsigned long rate_hz; - struct clk *parent; - u32 pmc_mask; - void (*mode)(struct clk *, int); - unsigned id:2; /* PCK0..3, or 32k/main/a/b */ - unsigned primary:1; - unsigned pll:1; - unsigned programmable:1; - u16 users; -}; +#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) +#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) +#define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) + + +static LIST_HEAD(clocks); +static DEFINE_SPINLOCK(clk_lock); -static spinlock_t clk_lock; -static u32 at91_pllb_usb_init; +static u32 at91_pllb_usb_init; /* * Four primary clock sources: two crystal oscillators (32K, main), and @@ -67,21 +59,20 @@ static struct clk clk32k = { .rate_hz = AT91_SLOW_CLOCK, .users = 1, /* always on */ .id = 0, - .primary = 1, + .type = CLK_TYPE_PRIMARY, }; static struct clk main_clk = { .name = "main", .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ .id = 1, - .primary = 1, + .type = CLK_TYPE_PRIMARY, }; static struct clk plla = { .name = "plla", .parent = &main_clk, .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ .id = 2, - .primary = 1, - .pll = 1, + .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, }; static void pllb_mode(struct clk *clk, int is_on) @@ -94,6 +85,7 @@ static void pllb_mode(struct clk *clk, int is_on) } else value = 0; + // REVISIT: Add work-around for AT91RM9200 Errata #26 ? at91_sys_write(AT91_CKGR_PLLBR, value); do { @@ -107,8 +99,7 @@ static struct clk pllb = { .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ .mode = pllb_mode, .id = 3, - .primary = 1, - .pll = 1, + .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, }; static void pmc_sys_mode(struct clk *clk, int is_on) @@ -133,41 +124,6 @@ static struct clk uhpck = { .mode = pmc_sys_mode, }; -#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS -/* - * The four programmable clocks can be parented by any primary clock. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .mode = pmc_sys_mode, - .programmable = 1, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .mode = pmc_sys_mode, - .programmable = 1, - .id = 1, -}; -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .mode = pmc_sys_mode, - .programmable = 1, - .id = 2, -}; -static struct clk pck3 = { - .name = "pck3", - .pmc_mask = AT91_PMC_PCK3, - .mode = pmc_sys_mode, - .programmable = 1, - .id = 3, -}; -#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ - /* * The master clock is divided from the CPU clock (by 1-4). It's used for @@ -187,131 +143,21 @@ static void pmc_periph_mode(struct clk *clk, int is_on) at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); } -static struct clk udc_clk = { - .name = "udc_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_UDP, - .mode = pmc_periph_mode, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_UHP, - .mode = pmc_periph_mode, -}; -static struct clk ether_clk = { - .name = "ether_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_EMAC, - .mode = pmc_periph_mode, -}; -static struct clk mmc_clk = { - .name = "mci_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_MCI, - .mode = pmc_periph_mode, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_TWI, - .mode = pmc_periph_mode, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_US0, - .mode = pmc_periph_mode, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_US1, - .mode = pmc_periph_mode, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_US2, - .mode = pmc_periph_mode, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_US3, - .mode = pmc_periph_mode, -}; -static struct clk spi_clk = { - .name = "spi0_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_SPI, - .mode = pmc_periph_mode, -}; -static struct clk pioA_clk = { - .name = "pioA_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_PIOA, - .mode = pmc_periph_mode, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_PIOB, - .mode = pmc_periph_mode, -}; -static struct clk pioC_clk = { - .name = "pioC_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_PIOC, - .mode = pmc_periph_mode, -}; -static struct clk pioD_clk = { - .name = "pioD_clk", - .parent = &mck, - .pmc_mask = 1 << AT91_ID_PIOD, - .mode = pmc_periph_mode, -}; - -static struct clk *const clock_list[] = { - /* four primary clocks -- MUST BE FIRST! */ - &clk32k, - &main_clk, - &plla, - &pllb, - - /* PLLB children (USB) */ - &udpck, - &uhpck, - -#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS - /* programmable clocks */ - &pck0, - &pck1, - &pck2, - &pck3, -#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ - - /* MCK and peripherals */ - &mck, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &usart3_clk, - &mmc_clk, - &udc_clk, - &twi_clk, - &spi_clk, - &pioA_clk, - &pioB_clk, - &pioC_clk, - &pioD_clk, - // ssc0..ssc2 - // tc0..tc5 - // irq0..irq6 - &ohci_clk, - ðer_clk, -}; +static struct clk __init *at91_css_to_clk(unsigned long css) +{ + switch (css) { + case AT91_PMC_CSS_SLOW: + return &clk32k; + case AT91_PMC_CSS_MAIN: + return &main_clk; + case AT91_PMC_CSS_PLLA: + return &plla; + case AT91_PMC_CSS_PLLB: + return &pllb; + } + return NULL; +} /* * Associate a particular clock with a function (eg, "uart") and device. @@ -329,14 +175,12 @@ void __init at91_clock_associate(const char *id, struct device *dev, const char clk->dev = dev; } -/* clocks are all static for now; no refcounting necessary */ +/* clocks cannot be de-registered no refcounting necessary */ struct clk *clk_get(struct device *dev, const char *id) { - int i; - - for (i = 0; i < ARRAY_SIZE(clock_list); i++) { - struct clk *clk = clock_list[i]; + struct clk *clk; + list_for_each_entry(clk, &clocks, node) { if (strcmp(id, clk->name) == 0) return clk; if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) @@ -424,7 +268,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate) unsigned prescale; unsigned long actual; - if (!clk->programmable) + if (!clk_is_programmable(clk)) return -EINVAL; spin_lock_irqsave(&clk_lock, flags); @@ -446,7 +290,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) unsigned prescale; unsigned long actual; - if (!clk->programmable) + if (!clk_is_programmable(clk)) return -EINVAL; if (clk->users) return -EBUSY; @@ -484,7 +328,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) if (clk->users) return -EBUSY; - if (!parent->primary || !clk->programmable) + if (!clk_is_primary(parent) || !clk_is_programmable(clk)) return -EINVAL; spin_lock_irqsave(&clk_lock, flags); @@ -497,6 +341,18 @@ int clk_set_parent(struct clk *clk, struct clk *parent) } EXPORT_SYMBOL(clk_set_parent); +/* establish PCK0..PCK3 parentage and rate */ +static void init_programmable_clock(struct clk *clk) +{ + struct clk *parent; + u32 pckr; + + pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); + parent = at91_css_to_clk(pckr & AT91_PMC_CSS); + clk->parent = parent; + clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); +} + #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ /*------------------------------------------------------------------------*/ @@ -506,6 +362,7 @@ EXPORT_SYMBOL(clk_set_parent); static int at91_clk_show(struct seq_file *s, void *unused) { u32 scsr, pcsr, sr; + struct clk *clk; unsigned i; seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); @@ -523,9 +380,8 @@ static int at91_clk_show(struct seq_file *s, void *unused) seq_printf(s, "\n"); - for (i = 0; i < ARRAY_SIZE(clock_list); i++) { - char *state; - struct clk *clk = clock_list[i]; + list_for_each_entry(clk, &clocks, node) { + char *state; if (clk->mode == pmc_sys_mode) state = (scsr & clk->pmc_mask) ? "on" : "off"; @@ -570,6 +426,28 @@ postcore_initcall(at91_clk_debugfs_init); /*------------------------------------------------------------------------*/ +/* Register a new clock */ +int __init clk_register(struct clk *clk) +{ + if (clk_is_peripheral(clk)) { + clk->parent = &mck; + clk->mode = pmc_periph_mode; + list_add_tail(&clk->node, &clocks); + } +#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS + else if (clk_is_programmable(clk)) { + clk->mode = pmc_sys_mode; + init_programmable_clock(clk); + list_add_tail(&clk->node, &clocks); + } +#endif + + return 0; +} + + +/*------------------------------------------------------------------------*/ + static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) { unsigned mul, div; @@ -640,20 +518,17 @@ fail: return 0; } - /* * Several unused clocks may be active. Turn them off. */ -static void at91_periphclk_reset(void) +static void __init at91_periphclk_reset(void) { unsigned long reg; - int i; + struct clk *clk; reg = at91_sys_read(AT91_PMC_PCSR); - for (i = 0; i < ARRAY_SIZE(clock_list); i++) { - struct clk *clk = clock_list[i]; - + list_for_each_entry(clk, &clocks, node) { if (clk->mode != pmc_periph_mode) continue; @@ -664,11 +539,25 @@ static void at91_periphclk_reset(void) at91_sys_write(AT91_PMC_PCDR, reg); } +static struct clk *const standard_pmc_clocks[] __initdata = { + /* four primary clocks */ + &clk32k, + &main_clk, + &plla, + &pllb, + + /* PLLB children (USB) */ + &udpck, + &uhpck, + + /* MCK */ + &mck +}; + int __init at91_clock_init(unsigned long main_clock) { unsigned tmp, freq, mckr; - - spin_lock_init(&clk_lock); + int i; /* * When the bootloader initialized the main oscillator correctly, @@ -709,11 +598,15 @@ int __init at91_clock_init(unsigned long main_clock) * For now, assume this parentage won't change. */ mckr = at91_sys_read(AT91_PMC_MCKR); - mck.parent = clock_list[mckr & AT91_PMC_CSS]; + mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); freq = mck.parent->rate_hz; freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ + /* Register the PMC's standard clocks */ + for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) + list_add_tail(&standard_pmc_clocks[i]->node, &clocks); + /* MCK and CPU clock are "always on" */ clk_enable(&mck); @@ -722,35 +615,8 @@ int __init at91_clock_init(unsigned long main_clock) (unsigned) main_clock / 1000000, ((unsigned) main_clock % 1000000) / 1000); -#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS - /* establish PCK0..PCK3 parentage */ - for (tmp = 0; tmp < ARRAY_SIZE(clock_list); tmp++) { - struct clk *clk = clock_list[tmp], *parent; - u32 pckr; - - if (!clk->programmable) - continue; - - pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); - parent = clock_list[pckr & AT91_PMC_CSS]; - clk->parent = parent; - clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); - - if (clk->users == 0) { - /* not being used, so switch it off */ - at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); - } - } -#else /* disable all programmable clocks */ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3); -#endif - - /* enable the PIO clocks */ - clk_enable(&pioA_clk); - clk_enable(&pioB_clk); - clk_enable(&pioC_clk); - clk_enable(&pioD_clk); /* disable all other unused peripheral clocks */ at91_periphclk_reset(); diff --git a/arch/arm/mach-at91rm9200/clock.h b/arch/arm/mach-at91rm9200/clock.h new file mode 100644 index 00000000000..0592e662ab3 --- /dev/null +++ b/arch/arm/mach-at91rm9200/clock.h @@ -0,0 +1,30 @@ +/* + * linux/arch/arm/mach-at91rm9200/clock.h + * + * 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. + */ + +#define CLK_TYPE_PRIMARY 0x1 +#define CLK_TYPE_PLL 0x2 +#define CLK_TYPE_PROGRAMMABLE 0x4 +#define CLK_TYPE_PERIPHERAL 0x8 + + +struct clk { + struct list_head node; + const char *name; /* unique clock name */ + const char *function; /* function of the clock */ + struct device *dev; /* device associated with function */ + unsigned long rate_hz; + struct clk *parent; + u32 pmc_mask; + void (*mode)(struct clk *, int); + unsigned id:2; /* PCK0..3, or 32k/main/a/b */ + unsigned type; /* clock type */ + u16 users; +}; + + +extern int __init clk_register(struct clk *clk); diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c index 4352acb8817..01525530c28 100644 --- a/arch/arm/mach-at91rm9200/devices.c +++ b/arch/arm/mach-at91rm9200/devices.c @@ -35,13 +35,13 @@ static struct at91_usbh_data usbh_data; static struct resource at91_usbh_resources[] = { [0] = { - .start = AT91_UHP_BASE, - .end = AT91_UHP_BASE + SZ_1M - 1, + .start = AT91RM9200_UHP_BASE, + .end = AT91RM9200_UHP_BASE + SZ_1M - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_UHP, - .end = AT91_ID_UHP, + .start = AT91RM9200_ID_UHP, + .end = AT91RM9200_ID_UHP, .flags = IORESOURCE_IRQ, }, }; @@ -80,13 +80,13 @@ static struct at91_udc_data udc_data; static struct resource at91_udc_resources[] = { [0] = { - .start = AT91_BASE_UDP, - .end = AT91_BASE_UDP + SZ_16K - 1, + .start = AT91RM9200_BASE_UDP, + .end = AT91RM9200_BASE_UDP + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_UDP, - .end = AT91_ID_UDP, + .start = AT91RM9200_ID_UDP, + .end = AT91RM9200_ID_UDP, .flags = IORESOURCE_IRQ, }, }; @@ -131,13 +131,13 @@ static struct at91_eth_data eth_data; static struct resource at91_eth_resources[] = { [0] = { - .start = AT91_BASE_EMAC, - .end = AT91_BASE_EMAC + SZ_16K - 1, + .start = AT91_VA_BASE_EMAC, + .end = AT91_VA_BASE_EMAC + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_EMAC, - .end = AT91_ID_EMAC, + .start = AT91RM9200_ID_EMAC, + .end = AT91RM9200_ID_EMAC, .flags = IORESOURCE_IRQ, }, }; @@ -263,13 +263,13 @@ static struct at91_mmc_data mmc_data; static struct resource at91_mmc_resources[] = { [0] = { - .start = AT91_BASE_MCI, - .end = AT91_BASE_MCI + SZ_16K - 1, + .start = AT91RM9200_BASE_MCI, + .end = AT91RM9200_BASE_MCI + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_MCI, - .end = AT91_ID_MCI, + .start = AT91RM9200_ID_MCI, + .end = AT91RM9200_ID_MCI, .flags = IORESOURCE_IRQ, }, }; @@ -423,13 +423,13 @@ static u64 spi_dmamask = 0xffffffffUL; static struct resource at91_spi_resources[] = { [0] = { - .start = AT91_BASE_SPI, - .end = AT91_BASE_SPI + SZ_16K - 1, + .start = AT91RM9200_BASE_SPI, + .end = AT91RM9200_BASE_SPI + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_SPI, - .end = AT91_ID_SPI, + .start = AT91RM9200_ID_SPI, + .end = AT91RM9200_ID_SPI, .flags = IORESOURCE_IRQ, }, }; @@ -582,13 +582,13 @@ static inline void configure_dbgu_pins(void) static struct resource uart0_resources[] = { [0] = { - .start = AT91_BASE_US0, - .end = AT91_BASE_US0 + SZ_16K - 1, + .start = AT91RM9200_BASE_US0, + .end = AT91RM9200_BASE_US0 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_US0, - .end = AT91_ID_US0, + .start = AT91RM9200_ID_US0, + .end = AT91RM9200_ID_US0, .flags = IORESOURCE_IRQ, }, }; @@ -624,13 +624,13 @@ static inline void configure_usart0_pins(void) static struct resource uart1_resources[] = { [0] = { - .start = AT91_BASE_US1, - .end = AT91_BASE_US1 + SZ_16K - 1, + .start = AT91RM9200_BASE_US1, + .end = AT91RM9200_BASE_US1 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_US1, - .end = AT91_ID_US1, + .start = AT91RM9200_ID_US1, + .end = AT91RM9200_ID_US1, .flags = IORESOURCE_IRQ, }, }; @@ -665,13 +665,13 @@ static inline void configure_usart1_pins(void) static struct resource uart2_resources[] = { [0] = { - .start = AT91_BASE_US2, - .end = AT91_BASE_US2 + SZ_16K - 1, + .start = AT91RM9200_BASE_US2, + .end = AT91RM9200_BASE_US2 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_US2, - .end = AT91_ID_US2, + .start = AT91RM9200_ID_US2, + .end = AT91RM9200_ID_US2, .flags = IORESOURCE_IRQ, }, }; @@ -700,13 +700,13 @@ static inline void configure_usart2_pins(void) static struct resource uart3_resources[] = { [0] = { - .start = AT91_BASE_US3, - .end = AT91_BASE_US3 + SZ_16K - 1, + .start = AT91RM9200_BASE_US3, + .end = AT91RM9200_BASE_US3 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_US3, - .end = AT91_ID_US3, + .start = AT91RM9200_ID_US3, + .end = AT91RM9200_ID_US3, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h index 7979d8ab7e0..694e411e285 100644 --- a/arch/arm/mach-at91rm9200/generic.h +++ b/arch/arm/mach-at91rm9200/generic.h @@ -8,18 +8,17 @@ * published by the Free Software Foundation. */ + /* Processors */ +extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks); + /* Interrupts */ -extern void __init at91rm9200_init_irq(unsigned int priority[]); +extern void __init at91rm9200_init_interrupts(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]); -extern void __init at91_gpio_irq_setup(unsigned banks); /* Timer */ struct sys_timer; extern struct sys_timer at91rm9200_timer; - /* Memory Map */ -extern void __init at91rm9200_map_io(void); - /* Clocks */ extern int __init at91_clock_init(unsigned long main_clock); struct device; @@ -29,3 +28,14 @@ extern void __init at91_clock_associate(const char *id, struct device *dev, cons extern void at91_irq_suspend(void); extern void at91_irq_resume(void); + /* GPIO */ +#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ +#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ + +struct at91_gpio_bank { + unsigned short id; /* peripheral ID */ + unsigned long offset; /* offset from system peripheral base */ + struct clk *clock; /* associated clock */ +}; +extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); +extern void __init at91_gpio_irq_setup(void); diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c index cec199fd672..58c9bf5e952 100644 --- a/arch/arm/mach-at91rm9200/gpio.c +++ b/arch/arm/mach-at91rm9200/gpio.c @@ -9,6 +9,7 @@ * (at your option) any later version. */ +#include <linux/clk.h> #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -20,12 +21,12 @@ #include <asm/hardware.h> #include <asm/arch/gpio.h> -static const u32 pio_controller_offset[4] = { - AT91_PIOA, - AT91_PIOB, - AT91_PIOC, - AT91_PIOD, -}; +#include "generic.h" + + +static struct at91_gpio_bank *gpio; +static int gpio_banks; + static inline void __iomem *pin_to_controller(unsigned pin) { @@ -33,8 +34,8 @@ static inline void __iomem *pin_to_controller(unsigned pin) pin -= PIN_BASE; pin /= 32; - if (likely(pin < BGA_GPIO_BANKS)) - return sys_base + pio_controller_offset[pin]; + if (likely(pin < gpio_banks)) + return sys_base + gpio[pin].offset; return NULL; } @@ -179,7 +180,6 @@ EXPORT_SYMBOL(at91_set_multi_drive); /*--------------------------------------------------------------------------*/ - /* * assuming the pin is muxed as a gpio output, set its value. */ @@ -216,8 +216,8 @@ EXPORT_SYMBOL(at91_get_gpio_value); #ifdef CONFIG_PM -static u32 wakeups[BGA_GPIO_BANKS]; -static u32 backups[BGA_GPIO_BANKS]; +static u32 wakeups[MAX_GPIO_BANKS]; +static u32 backups[MAX_GPIO_BANKS]; static int gpio_irq_set_wake(unsigned pin, unsigned state) { @@ -226,7 +226,7 @@ static int gpio_irq_set_wake(unsigned pin, unsigned state) pin -= PIN_BASE; pin /= 32; - if (unlikely(pin >= BGA_GPIO_BANKS)) + if (unlikely(pin >= MAX_GPIO_BANKS)) return -EINVAL; if (state) @@ -241,8 +241,8 @@ void at91_gpio_suspend(void) { int i; - for (i = 0; i < BGA_GPIO_BANKS; i++) { - u32 pio = pio_controller_offset[i]; + for (i = 0; i < gpio_banks; i++) { + u32 pio = gpio[i].offset; /* * Note: drivers should have disabled GPIO interrupts that @@ -257,14 +257,14 @@ void at91_gpio_suspend(void) * first place! */ backups[i] = at91_sys_read(pio + PIO_IMR); - at91_sys_write(pio_controller_offset[i] + PIO_IDR, backups[i]); - at91_sys_write(pio_controller_offset[i] + PIO_IER, wakeups[i]); + at91_sys_write(pio + PIO_IDR, backups[i]); + at91_sys_write(pio + PIO_IER, wakeups[i]); if (!wakeups[i]) { - disable_irq_wake(AT91_ID_PIOA + i); - at91_sys_write(AT91_PMC_PCDR, 1 << (AT91_ID_PIOA + i)); + disable_irq_wake(gpio[i].id); + at91_sys_write(AT91_PMC_PCDR, 1 << gpio[i].id); } else { - enable_irq_wake(AT91_ID_PIOA + i); + enable_irq_wake(gpio[i].id); #ifdef CONFIG_PM_DEBUG printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]); #endif @@ -276,16 +276,13 @@ void at91_gpio_resume(void) { int i; - for (i = 0; i < BGA_GPIO_BANKS; i++) { - at91_sys_write(pio_controller_offset[i] + PIO_IDR, wakeups[i]); - at91_sys_write(pio_controller_offset[i] + PIO_IER, backups[i]); - } + for (i = 0; i < gpio_banks; i++) { + u32 pio = gpio[i].offset; - at91_sys_write(AT91_PMC_PCER, - (1 << AT91_ID_PIOA) - | (1 << AT91_ID_PIOB) - | (1 << AT91_ID_PIOC) - | (1 << AT91_ID_PIOD)); + at91_sys_write(pio + PIO_IDR, wakeups[i]); + at91_sys_write(pio + PIO_IER, backups[i]); + at91_sys_write(AT91_PMC_PCER, 1 << gpio[i].id); + } } #else @@ -377,20 +374,25 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs /* now it may re-trigger */ } -/* call this from board-specific init_irq */ -void __init at91_gpio_irq_setup(unsigned banks) +/*--------------------------------------------------------------------------*/ + +/* + * Called from the processor-specific init to enable GPIO interrupt support. + */ +void __init at91_gpio_irq_setup(void) { - unsigned pioc, pin, id; + unsigned pioc, pin; - if (banks > 4) - banks = 4; - for (pioc = 0, pin = PIN_BASE, id = AT91_ID_PIOA; - pioc < banks; - pioc++, id++) { + for (pioc = 0, pin = PIN_BASE; + pioc < gpio_banks; + pioc++) { void __iomem *controller; + unsigned id = gpio[pioc].id; unsigned i; - controller = (void __iomem *) AT91_VA_BASE_SYS + pio_controller_offset[pioc]; + clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ + + controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset; __raw_writel(~0, controller + PIO_IDR); set_irq_data(id, (void *) pin); @@ -408,5 +410,16 @@ void __init at91_gpio_irq_setup(unsigned banks) set_irq_chained_handler(id, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks); + pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); +} + +/* + * Called from the processor-specific init to enable GPIO pin support. + */ +void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) +{ + BUG_ON(nr_banks > MAX_GPIO_BANKS); + + gpio = data; + gpio_banks = nr_banks; } diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c index c3a5e777f9f..3e488117ca9 100644 --- a/arch/arm/mach-at91rm9200/irq.c +++ b/arch/arm/mach-at91rm9200/irq.c @@ -34,8 +34,6 @@ #include <asm/mach/irq.h> #include <asm/mach/map.h> -#include "generic.h" - static void at91_aic_mask_irq(unsigned int irq) { @@ -61,12 +59,12 @@ static int at91_aic_set_type(unsigned irq, unsigned type) srctype = AT91_AIC_SRCTYPE_RISING; break; case IRQT_LOW: - if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ return -EINVAL; srctype = AT91_AIC_SRCTYPE_LOW; break; case IRQT_FALLING: - if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ return -EINVAL; srctype = AT91_AIC_SRCTYPE_FALLING; break; diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 47e5480feb7..32c95d8eaac 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c @@ -123,13 +123,13 @@ static int at91_pm_enter(suspend_state_t state) (at91_sys_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) - | (1 << AT91_ID_IRQ0) - | (1 << AT91_ID_IRQ1) - | (1 << AT91_ID_IRQ2) - | (1 << AT91_ID_IRQ3) - | (1 << AT91_ID_IRQ4) - | (1 << AT91_ID_IRQ5) - | (1 << AT91_ID_IRQ6)) + | (1 << AT91RM9200_ID_IRQ0) + | (1 << AT91RM9200_ID_IRQ1) + | (1 << AT91RM9200_ID_IRQ2) + | (1 << AT91RM9200_ID_IRQ3) + | (1 << AT91RM9200_ID_IRQ4) + | (1 << AT91RM9200_ID_IRQ5) + | (1 << AT91RM9200_ID_IRQ6)) & at91_sys_read(AT91_AIC_IMR), state); diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index f1b740083ae..e346b03cd92 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig @@ -15,6 +15,12 @@ config MACH_EDB9302 Say 'Y' here if you want your kernel to support the Cirrus Logic EDB9302 Evaluation Board. +config MACH_EDB9312 + bool "Support Cirrus Logic EDB9312" + help + Say 'Y' here if you want your kernel to support the Cirrus + Logic EDB9312 Evaluation Board. + config MACH_EDB9315 bool "Support Cirrus Logic EDB9315" help diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index 1f5a6b0487e..c2eb18b530c 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -7,6 +7,7 @@ obj-n := obj- := obj-$(CONFIG_MACH_EDB9302) += edb9302.o +obj-$(CONFIG_MACH_EDB9312) += edb9312.o obj-$(CONFIG_MACH_EDB9315) += edb9315.o obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o diff --git a/arch/arm/mach-ep93xx/edb9312.c b/arch/arm/mach-ep93xx/edb9312.c new file mode 100644 index 00000000000..9e399211108 --- /dev/null +++ b/arch/arm/mach-ep93xx/edb9312.c @@ -0,0 +1,63 @@ +/* + * arch/arm/mach-ep93xx/edb9312.c + * Cirrus Logic EDB9312 support. + * + * Copyright (C) 2006 Infosys Technologies Limited + * Toufeeq Hussain <toufeeq_hussain@infosys.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. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +static struct physmap_flash_data edb9312_flash_data = { + .width = 4, +}; + +static struct resource edb9312_flash_resource = { + .start = 0x60000000, + .end = 0x61ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device edb9312_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &edb9312_flash_data, + }, + .num_resources = 1, + .resource = &edb9312_flash_resource, +}; + +static void __init edb9312_init_machine(void) +{ + ep93xx_init_devices(); + platform_device_register(&edb9312_flash); +} + +MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board") + /* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */ + .phys_io = EP93XX_APB_PHYS_BASE, + .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ep93xx_map_io, + .init_irq = ep93xx_init_irq, + .timer = &ep93xx_timer, + .init_machine = edb9312_init_machine, +MACHINE_END diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 823e25d4547..a1ae49df5c3 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -69,16 +69,16 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, if (addr) switch (size) { case 1: - asm("ldr%?b %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where)); + asm("ldrb %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; case 2: - asm("ldr%?h %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where)); + asm("ldrh %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; case 4: - asm("ldr%? %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where)); + asm("ldr %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; } @@ -103,16 +103,19 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, if (addr) switch (size) { case 1: - asm("str%?b %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where)); + asm("strb %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where) + : "cc"); break; case 2: - asm("str%?h %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where)); + asm("strh %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where) + : "cc"); break; case 4: - asm("str%? %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where)); + asm("str %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where) + : "cc"); break; } diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig new file mode 100644 index 00000000000..c072d94070d --- /dev/null +++ b/arch/arm/mach-iop32x/Kconfig @@ -0,0 +1,35 @@ +if ARCH_IOP32X + +menu "IOP32x Implementation Options" + +comment "IOP32x Platform Types" + +config MACH_GLANTANK + bool "Enable support for the IO-Data GLAN Tank" + help + Say Y here if you want to run your kernel on the GLAN Tank + NAS appliance or machines from IO-Data's HDL-Gxxx, HDL-GWxxx + and HDL-GZxxx series. + +config ARCH_IQ80321 + bool "Enable support for IQ80321" + help + Say Y here if you want to run your kernel on the Intel IQ80321 + evaluation kit for the IOP321 processor. + +config ARCH_IQ31244 + bool "Enable support for EP80219/IQ31244" + help + Say Y here if you want to run your kernel on the Intel EP80219 + evaluation kit for the Intel 80219 processor (a IOP321 variant) + or the IQ31244 evaluation kit for the IOP321 processor. + +config MACH_N2100 + bool "Enable support for the Thecus n2100" + help + Say Y here if you want to run your kernel on the Thecus n2100 + NAS appliance. + +endmenu + +endif diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile new file mode 100644 index 00000000000..7b05b37e1f9 --- /dev/null +++ b/arch/arm/mach-iop32x/Makefile @@ -0,0 +1,13 @@ +# +# Makefile for the linux kernel. +# + +obj-y := irq.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_MACH_GLANTANK) += glantank.o +obj-$(CONFIG_ARCH_IQ80321) += iq80321.o +obj-$(CONFIG_ARCH_IQ31244) += iq31244.o +obj-$(CONFIG_MACH_N2100) += n2100.o diff --git a/arch/arm/mach-iop32x/Makefile.boot b/arch/arm/mach-iop32x/Makefile.boot new file mode 100644 index 00000000000..47000dccd61 --- /dev/null +++ b/arch/arm/mach-iop32x/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0xa0008000 +params_phys-y := 0xa0000100 +initrd_phys-y := 0xa0800000 diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c new file mode 100644 index 00000000000..b9b765057db --- /dev/null +++ b/arch/arm/mach-iop32x/glantank.c @@ -0,0 +1,195 @@ +/* + * arch/arm/mach-iop32x/glantank.c + * + * Board support code for the GLAN Tank. + * + * Copyright (C) 2006 Martin Michlmayr <tbm@cyrius.com> + * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> + * + * 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. + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/pci.h> +#include <asm/mach/time.h> +#include <asm/mach-types.h> +#include <asm/page.h> + +/* + * GLAN Tank timer tick configuration. + */ +static void __init glantank_timer_init(void) +{ + /* 33.333 MHz crystal. */ + iop3xx_init_time(200000000); +} + +static struct sys_timer glantank_timer = { + .init = glantank_timer_init, + .offset = iop3xx_gettimeoffset, +}; + + +/* + * GLAN Tank I/O. + */ +static struct map_desc glantank_io_desc[] __initdata = { + { /* on-board devices */ + .virtual = GLANTANK_UART, + .pfn = __phys_to_pfn(GLANTANK_UART), + .length = 0x00100000, + .type = MT_DEVICE + }, +}; + +void __init glantank_map_io(void) +{ + iop3xx_map_io(); + iotable_init(glantank_io_desc, ARRAY_SIZE(glantank_io_desc)); +} + + +/* + * GLAN Tank PCI. + */ +#define INTA IRQ_IOP32X_XINT0 +#define INTB IRQ_IOP32X_XINT1 +#define INTC IRQ_IOP32X_XINT2 +#define INTD IRQ_IOP32X_XINT3 + +static inline int __init +glantank_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {INTD, INTD, INTD, INTD}, /* UART (8250) */ + {INTA, INTA, INTA, INTA}, /* Ethernet (E1000) */ + {INTB, INTB, INTB, INTB}, /* IDE (AEC6280R) */ + {INTC, INTC, INTC, INTC}, /* USB (NEC) */ + }; + + BUG_ON(pin < 1 || pin > 4); + + return pci_irq_table[slot % 4][pin - 1]; +} + +static struct hw_pci glantank_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = glantank_pci_map_irq, +}; + +static int __init glantank_pci_init(void) +{ + if (machine_is_glantank()) + pci_common_init(&glantank_pci); + + return 0; +} + +subsys_initcall(glantank_pci_init); + + +/* + * GLAN Tank machine initialization. + */ +static struct physmap_flash_data glantank_flash_data = { + .width = 1, +}; + +static struct resource glantank_flash_resource = { + .start = 0xf0000000, + .end = 0xf007ffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device glantank_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &glantank_flash_data, + }, + .num_resources = 1, + .resource = &glantank_flash_resource, +}; + +static struct plat_serial8250_port glantank_serial_port[] = { + { + .mapbase = GLANTANK_UART, + .membase = (char *)GLANTANK_UART, + .irq = IRQ_IOP32X_XINT3, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = 1843200, + }, + { }, +}; + +static struct resource glantank_uart_resource = { + .start = GLANTANK_UART, + .end = GLANTANK_UART + 7, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device glantank_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = glantank_serial_port, + }, + .num_resources = 1, + .resource = &glantank_uart_resource, +}; + +static void glantank_power_off(void) +{ + __raw_writeb(0x01, 0xfe8d0004); + + while (1) + ; +} + +static void __init glantank_init_machine(void) +{ + platform_device_register(&iop3xx_i2c0_device); + platform_device_register(&iop3xx_i2c1_device); + platform_device_register(&glantank_flash_device); + platform_device_register(&glantank_serial_device); + + pm_power_off = glantank_power_off; +} + +MACHINE_START(GLANTANK, "GLAN Tank") + /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ + .phys_io = GLANTANK_UART, + .io_pg_offst = ((GLANTANK_UART) >> 18) & 0xfffc, + .boot_params = 0xa0000100, + .map_io = glantank_map_io, + .init_irq = iop32x_init_irq, + .timer = &glantank_timer, + .init_machine = glantank_init_machine, +MACHINE_END diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c new file mode 100644 index 00000000000..be4aedfa0de --- /dev/null +++ b/arch/arm/mach-iop32x/iq31244.c @@ -0,0 +1,293 @@ +/* + * arch/arm/mach-iop32x/iq31244.c + * + * Board support code for the Intel EP80219 and IQ31244 platforms. + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * Copyright 2003 (c) MontaVista, Software, Inc. + * Copyright (C) 2004 Intel Corp. + * + * 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. + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/pm.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/pci.h> +#include <asm/mach/time.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> + + +/* + * The EP80219 and IQ31244 use the same machine ID. To find out + * which of the two we're running on, we look at the processor ID. + */ +static int is_80219(void) +{ + extern int processor_id; + return !!((processor_id & 0xffffffe0) == 0x69052e20); +} + + +/* + * EP80219/IQ31244 timer tick configuration. + */ +static void __init iq31244_timer_init(void) +{ + if (is_80219()) { + /* 33.333 MHz crystal. */ + iop3xx_init_time(200000000); + } else { + /* 33.000 MHz crystal. */ + iop3xx_init_time(198000000); + } +} + +static struct sys_timer iq31244_timer = { + .init = iq31244_timer_init, + .offset = iop3xx_gettimeoffset, +}; + + +/* + * IQ31244 I/O. + */ +static struct map_desc iq31244_io_desc[] __initdata = { + { /* on-board devices */ + .virtual = IQ31244_UART, + .pfn = __phys_to_pfn(IQ31244_UART), + .length = 0x00100000, + .type = MT_DEVICE, + }, +}; + +void __init iq31244_map_io(void) +{ + iop3xx_map_io(); + iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc)); +} + + +/* + * EP80219/IQ31244 PCI. + */ +static inline int __init +ep80219_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (slot == 0) { + /* CFlash */ + irq = IRQ_IOP32X_XINT1; + } else if (slot == 1) { + /* 82551 Pro 100 */ + irq = IRQ_IOP32X_XINT0; + } else if (slot == 2) { + /* PCI-X Slot */ + irq = IRQ_IOP32X_XINT3; + } else if (slot == 3) { + /* SATA */ + irq = IRQ_IOP32X_XINT2; + } else { + printk(KERN_ERR "ep80219_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +static struct hw_pci ep80219_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = ep80219_pci_map_irq, +}; + +static inline int __init +iq31244_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (slot == 0) { + /* CFlash */ + irq = IRQ_IOP32X_XINT1; + } else if (slot == 1) { + /* SATA */ + irq = IRQ_IOP32X_XINT2; + } else if (slot == 2) { + /* PCI-X Slot */ + irq = IRQ_IOP32X_XINT3; + } else if (slot == 3) { + /* 82546 GigE */ + irq = IRQ_IOP32X_XINT0; + } else { + printk(KERN_ERR "iq31244_pci_map_irq called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +static struct hw_pci iq31244_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = iq31244_pci_map_irq, +}; + +static int __init iq31244_pci_init(void) +{ + if (machine_is_iq31244()) { + if (is_80219()) { + pci_common_init(&ep80219_pci); + } else { + pci_common_init(&iq31244_pci); + } + } + + return 0; +} + +subsys_initcall(iq31244_pci_init); + + +/* + * IQ31244 machine initialisation. + */ +static struct physmap_flash_data iq31244_flash_data = { + .width = 2, +}; + +static struct resource iq31244_flash_resource = { + .start = 0xf0000000, + .end = 0xf07fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq31244_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &iq31244_flash_data, + }, + .num_resources = 1, + .resource = &iq31244_flash_resource, +}; + +static struct plat_serial8250_port iq31244_serial_port[] = { + { + .mapbase = IQ31244_UART, + .membase = (char *)IQ31244_UART, + .irq = IRQ_IOP32X_XINT1, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = 1843200, + }, + { }, +}; + +static struct resource iq31244_uart_resource = { + .start = IQ31244_UART, + .end = IQ31244_UART + 7, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq31244_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = iq31244_serial_port, + }, + .num_resources = 1, + .resource = &iq31244_uart_resource, +}; + +/* + * This function will send a SHUTDOWN_COMPLETE message to the PIC + * controller over I2C. We are not using the i2c subsystem since + * we are going to power off and it may be removed + */ +void ep80219_power_off(void) +{ + /* + * Send the Address byte w/ the start condition + */ + *IOP3XX_IDBR1 = 0x60; + *IOP3XX_ICR1 = 0xE9; + mdelay(1); + + /* + * Send the START_MSG byte w/ no start or stop condition + */ + *IOP3XX_IDBR1 = 0x0F; + *IOP3XX_ICR1 = 0xE8; + mdelay(1); + + /* + * Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or + * stop condition + */ + *IOP3XX_IDBR1 = 0x03; + *IOP3XX_ICR1 = 0xE8; + mdelay(1); + + /* + * Send an ignored byte w/ stop condition + */ + *IOP3XX_IDBR1 = 0x00; + *IOP3XX_ICR1 = 0xEA; + + while (1) + ; +} + +static void __init iq31244_init_machine(void) +{ + platform_device_register(&iop3xx_i2c0_device); + platform_device_register(&iop3xx_i2c1_device); + platform_device_register(&iq31244_flash_device); + platform_device_register(&iq31244_serial_device); + + if (is_80219()) + pm_power_off = ep80219_power_off; +} + +MACHINE_START(IQ31244, "Intel IQ31244") + /* Maintainer: Intel Corp. */ + .phys_io = IQ31244_UART, + .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, + .boot_params = 0xa0000100, + .map_io = iq31244_map_io, + .init_irq = iop32x_init_irq, + .timer = &iq31244_timer, + .init_machine = iq31244_init_machine, +MACHINE_END diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c new file mode 100644 index 00000000000..1f37b550188 --- /dev/null +++ b/arch/arm/mach-iop32x/iq80321.c @@ -0,0 +1,193 @@ +/* + * arch/arm/mach-iop32x/iq80321.c + * + * Board support code for the Intel IQ80321 platform. + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * 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. + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/pci.h> +#include <asm/mach/time.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> + +/* + * IQ80321 timer tick configuration. + */ +static void __init iq80321_timer_init(void) +{ + /* 33.333 MHz crystal. */ + iop3xx_init_time(200000000); +} + +static struct sys_timer iq80321_timer = { + .init = iq80321_timer_init, + .offset = iop3xx_gettimeoffset, +}; + + +/* + * IQ80321 I/O. + */ +static struct map_desc iq80321_io_desc[] __initdata = { + { /* on-board devices */ + .virtual = IQ80321_UART, + .pfn = __phys_to_pfn(IQ80321_UART), + .length = 0x00100000, + .type = MT_DEVICE, + }, +}; + +void __init iq80321_map_io(void) +{ + iop3xx_map_io(); + iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc)); +} + + +/* + * IQ80321 PCI. + */ +static inline int __init +iq80321_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if ((slot == 2 || slot == 6) && pin == 1) { + /* PCI-X Slot INTA */ + irq = IRQ_IOP32X_XINT2; + } else if ((slot == 2 || slot == 6) && pin == 2) { + /* PCI-X Slot INTA */ + irq = IRQ_IOP32X_XINT3; + } else if ((slot == 2 || slot == 6) && pin == 3) { + /* PCI-X Slot INTA */ + irq = IRQ_IOP32X_XINT0; + } else if ((slot == 2 || slot == 6) && pin == 4) { + /* PCI-X Slot INTA */ + irq = IRQ_IOP32X_XINT1; + } else if (slot == 4 || slot == 8) { + /* Gig-E */ + irq = IRQ_IOP32X_XINT0; + } else { + printk(KERN_ERR "iq80321_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +static struct hw_pci iq80321_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = iq80321_pci_map_irq, +}; + +static int __init iq80321_pci_init(void) +{ + if (machine_is_iq80321()) + pci_common_init(&iq80321_pci); + + return 0; +} + +subsys_initcall(iq80321_pci_init); + + +/* + * IQ80321 machine initialisation. + */ +static struct physmap_flash_data iq80321_flash_data = { + .width = 1, +}; + +static struct resource iq80321_flash_resource = { + .start = 0xf0000000, + .end = 0xf07fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq80321_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &iq80321_flash_data, + }, + .num_resources = 1, + .resource = &iq80321_flash_resource, +}; + +static struct plat_serial8250_port iq80321_serial_port[] = { + { + .mapbase = IQ80321_UART, + .membase = (char *)IQ80321_UART, + .irq = IRQ_IOP32X_XINT1, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = 1843200, + }, + { }, +}; + +static struct resource iq80321_uart_resource = { + .start = IQ80321_UART, + .end = IQ80321_UART + 7, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq80321_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = iq80321_serial_port, + }, + .num_resources = 1, + .resource = &iq80321_uart_resource, +}; + +static void __init iq80321_init_machine(void) +{ + platform_device_register(&iop3xx_i2c0_device); + platform_device_register(&iop3xx_i2c1_device); + platform_device_register(&iq80321_flash_device); + platform_device_register(&iq80321_serial_device); +} + +MACHINE_START(IQ80321, "Intel IQ80321") + /* Maintainer: Intel Corp. */ + .phys_io = IQ80321_UART, + .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, + .boot_params = 0xa0000100, + .map_io = iq80321_map_io, + .init_irq = iop32x_init_irq, + .timer = &iq80321_timer, + .init_machine = iq80321_init_machine, +MACHINE_END diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c new file mode 100644 index 00000000000..69d6302f40c --- /dev/null +++ b/arch/arm/mach-iop32x/irq.c @@ -0,0 +1,76 @@ +/* + * arch/arm/mach-iop32x/irq.c + * + * Generic IOP32X IRQ handling functionality + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * + * 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/interrupt.h> +#include <linux/list.h> +#include <asm/mach/irq.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +static u32 iop32x_mask; + +static inline void intctl_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intstr_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static void +iop32x_irq_mask(unsigned int irq) +{ + iop32x_mask &= ~(1 << irq); + intctl_write(iop32x_mask); +} + +static void +iop32x_irq_unmask(unsigned int irq) +{ + iop32x_mask |= 1 << irq; + intctl_write(iop32x_mask); +} + +struct irq_chip ext_chip = { + .name = "IOP32x", + .ack = iop32x_irq_mask, + .mask = iop32x_irq_mask, + .unmask = iop32x_irq_unmask, +}; + +void __init iop32x_init_irq(void) +{ + int i; + + intctl_write(0); + intstr_write(0); + if (machine_is_glantank() || + machine_is_iq80321() || + machine_is_iq31244() || + machine_is_n2100()) + *IOP3XX_PCIIRSR = 0x0f; + + for (i = 0; i < NR_IRQS; i++) { + set_irq_chip(i, &ext_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } +} diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c new file mode 100644 index 00000000000..a2c94a47b2b --- /dev/null +++ b/arch/arm/mach-iop32x/n2100.c @@ -0,0 +1,251 @@ +/* + * arch/arm/mach-iop32x/n2100.c + * + * Board support code for the Thecus N2100 platform. + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * Copyright 2003 (c) MontaVista, Software, Inc. + * Copyright (C) 2004 Intel Corp. + * + * 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. + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/pm.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <linux/reboot.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/pci.h> +#include <asm/mach/time.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> + +/* + * N2100 timer tick configuration. + */ +static void __init n2100_timer_init(void) +{ + /* 33.000 MHz crystal. */ + iop3xx_init_time(198000000); +} + +static struct sys_timer n2100_timer = { + .init = n2100_timer_init, + .offset = iop3xx_gettimeoffset, +}; + + +/* + * N2100 I/O. + */ +static struct map_desc n2100_io_desc[] __initdata = { + { /* on-board devices */ + .virtual = N2100_UART, + .pfn = __phys_to_pfn(N2100_UART), + .length = 0x00100000, + .type = MT_DEVICE + }, +}; + +void __init n2100_map_io(void) +{ + iop3xx_map_io(); + iotable_init(n2100_io_desc, ARRAY_SIZE(n2100_io_desc)); +} + + +/* + * N2100 PCI. + */ +static inline int __init +n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (PCI_SLOT(dev->devfn) == 1) { + /* RTL8110SB #1 */ + irq = IRQ_IOP32X_XINT0; + } else if (PCI_SLOT(dev->devfn) == 2) { + /* RTL8110SB #2 */ + irq = IRQ_IOP32X_XINT1; + } else if (PCI_SLOT(dev->devfn) == 3) { + /* Sil3512 */ + irq = IRQ_IOP32X_XINT2; + } else if (PCI_SLOT(dev->devfn) == 4 && pin == 1) { + /* VT6212 INTA */ + irq = IRQ_IOP32X_XINT1; + } else if (PCI_SLOT(dev->devfn) == 4 && pin == 2) { + /* VT6212 INTB */ + irq = IRQ_IOP32X_XINT0; + } else if (PCI_SLOT(dev->devfn) == 4 && pin == 3) { + /* VT6212 INTC */ + irq = IRQ_IOP32X_XINT2; + } else if (PCI_SLOT(dev->devfn) == 5) { + /* Mini-PCI slot */ + irq = IRQ_IOP32X_XINT3; + } else { + printk(KERN_ERR "n2100_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +static struct hw_pci n2100_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = n2100_pci_map_irq, +}; + +static int __init n2100_pci_init(void) +{ + if (machine_is_n2100()) + pci_common_init(&n2100_pci); + + return 0; +} + +subsys_initcall(n2100_pci_init); + + +/* + * N2100 machine initialisation. + */ +static struct physmap_flash_data n2100_flash_data = { + .width = 2, +}; + +static struct resource n2100_flash_resource = { + .start = 0xf0000000, + .end = 0xf0ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device n2100_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &n2100_flash_data, + }, + .num_resources = 1, + .resource = &n2100_flash_resource, +}; + + +static struct plat_serial8250_port n2100_serial_port[] = { + { + .mapbase = N2100_UART, + .membase = (char *)N2100_UART, + .irq = 0, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = 1843200, + }, + { }, +}; + +static struct resource n2100_uart_resource = { + .start = N2100_UART, + .end = N2100_UART + 7, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device n2100_serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = n2100_serial_port, + }, + .num_resources = 1, + .resource = &n2100_uart_resource, +}; + + +/* + * Pull PCA9532 GPIO #8 low to power off the machine. + */ +static void n2100_power_off(void) +{ + local_irq_disable(); + + /* Start condition, I2C address of PCA9532, write transaction. */ + *IOP3XX_IDBR0 = 0xc0; + *IOP3XX_ICR0 = 0xe9; + mdelay(1); + + /* Write address 0x08. */ + *IOP3XX_IDBR0 = 0x08; + *IOP3XX_ICR0 = 0xe8; + mdelay(1); + + /* Write data 0x01, stop condition. */ + *IOP3XX_IDBR0 = 0x01; + *IOP3XX_ICR0 = 0xea; + + while (1) + ; +} + + +static struct timer_list power_button_poll_timer; + +static void power_button_poll(unsigned long dummy) +{ + if (gpio_line_get(N2100_POWER_BUTTON) == 0) { + ctrl_alt_del(); + return; + } + + power_button_poll_timer.expires = jiffies + (HZ / 10); + add_timer(&power_button_poll_timer); +} + + +static void __init n2100_init_machine(void) +{ + platform_device_register(&iop3xx_i2c0_device); + platform_device_register(&n2100_flash_device); + platform_device_register(&n2100_serial_device); + + pm_power_off = n2100_power_off; + + init_timer(&power_button_poll_timer); + power_button_poll_timer.function = power_button_poll; + power_button_poll_timer.expires = jiffies + (HZ / 10); + add_timer(&power_button_poll_timer); +} + +MACHINE_START(N2100, "Thecus N2100") + /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ + .phys_io = N2100_UART, + .io_pg_offst = ((N2100_UART) >> 18) & 0xfffc, + .boot_params = 0xa0000100, + .map_io = n2100_map_io, + .init_irq = iop32x_init_irq, + .timer = &n2100_timer, + .init_machine = n2100_init_machine, +MACHINE_END diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig new file mode 100644 index 00000000000..9aa016bb18f --- /dev/null +++ b/arch/arm/mach-iop33x/Kconfig @@ -0,0 +1,21 @@ +if ARCH_IOP33X + +menu "IOP33x Implementation Options" + +comment "IOP33x Platform Types" + +config ARCH_IQ80331 + bool "Enable support for IQ80331" + help + Say Y here if you want to run your kernel on the Intel IQ80331 + evaluation kit for the IOP331 chipset. + +config MACH_IQ80332 + bool "Enable support for IQ80332" + help + Say Y here if you want to run your kernel on the Intel IQ80332 + evaluation kit for the IOP332 chipset. + +endmenu + +endif diff --git a/arch/arm/mach-iop33x/Makefile b/arch/arm/mach-iop33x/Makefile new file mode 100644 index 00000000000..90081d8c9d1 --- /dev/null +++ b/arch/arm/mach-iop33x/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel. +# + +obj-y := irq.o uart.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_IQ80331) += iq80331.o +obj-$(CONFIG_MACH_IQ80332) += iq80332.o diff --git a/arch/arm/mach-iop33x/Makefile.boot b/arch/arm/mach-iop33x/Makefile.boot new file mode 100644 index 00000000000..67039c3e0c4 --- /dev/null +++ b/arch/arm/mach-iop33x/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c new file mode 100644 index 00000000000..97a7b748826 --- /dev/null +++ b/arch/arm/mach-iop33x/iq80331.c @@ -0,0 +1,148 @@ +/* + * arch/arm/mach-iop33x/iq80331.c + * + * Board support code for the Intel IQ80331 platform. + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2003 Intel Corp. + * + * 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. + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/pci.h> +#include <asm/mach/time.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> + +/* + * IQ80331 timer tick configuration. + */ +static void __init iq80331_timer_init(void) +{ + /* D-Step parts run at a higher internal bus frequency */ + if (*IOP3XX_ATURID >= 0xa) + iop3xx_init_time(333000000); + else + iop3xx_init_time(266000000); +} + +static struct sys_timer iq80331_timer = { + .init = iq80331_timer_init, + .offset = iop3xx_gettimeoffset, +}; + + +/* + * IQ80331 PCI. + */ +static inline int __init +iq80331_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (slot == 1 && pin == 1) { + /* PCI-X Slot INTA */ + irq = IRQ_IOP33X_XINT1; + } else if (slot == 1 && pin == 2) { + /* PCI-X Slot INTB */ + irq = IRQ_IOP33X_XINT2; + } else if (slot == 1 && pin == 3) { + /* PCI-X Slot INTC */ + irq = IRQ_IOP33X_XINT3; + } else if (slot == 1 && pin == 4) { + /* PCI-X Slot INTD */ + irq = IRQ_IOP33X_XINT0; + } else if (slot == 2) { + /* GigE */ + irq = IRQ_IOP33X_XINT2; + } else { + printk(KERN_ERR "iq80331_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +static struct hw_pci iq80331_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = iq80331_pci_map_irq, +}; + +static int __init iq80331_pci_init(void) +{ + if (machine_is_iq80331()) + pci_common_init(&iq80331_pci); + + return 0; +} + +subsys_initcall(iq80331_pci_init); + + +/* + * IQ80331 machine initialisation. + */ +static struct physmap_flash_data iq80331_flash_data = { + .width = 1, +}; + +static struct resource iq80331_flash_resource = { + .start = 0xc0000000, + .end = 0xc07fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq80331_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &iq80331_flash_data, + }, + .num_resources = 1, + .resource = &iq80331_flash_resource, +}; + +static void __init iq80331_init_machine(void) +{ + platform_device_register(&iop3xx_i2c0_device); + platform_device_register(&iop3xx_i2c1_device); + platform_device_register(&iop33x_uart0_device); + platform_device_register(&iop33x_uart1_device); + platform_device_register(&iq80331_flash_device); +} + +MACHINE_START(IQ80331, "Intel IQ80331") + /* Maintainer: Intel Corp. */ + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = iop3xx_map_io, + .init_irq = iop33x_init_irq, + .timer = &iq80331_timer, + .init_machine = iq80331_init_machine, +MACHINE_END diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c new file mode 100644 index 00000000000..9887bfc1c07 --- /dev/null +++ b/arch/arm/mach-iop33x/iq80332.c @@ -0,0 +1,148 @@ +/* + * arch/arm/mach-iop33x/iq80332.c + * + * Board support code for the Intel IQ80332 platform. + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2004 Intel Corp. + * + * 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. + */ + +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/mtd/physmap.h> +#include <linux/platform_device.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/pci.h> +#include <asm/mach/time.h> +#include <asm/mach-types.h> +#include <asm/page.h> +#include <asm/pgtable.h> + +/* + * IQ80332 timer tick configuration. + */ +static void __init iq80332_timer_init(void) +{ + /* D-Step parts and the iop333 run at a higher internal bus frequency */ + if (*IOP3XX_ATURID >= 0xa || *IOP3XX_ATUDID == 0x374) + iop3xx_init_time(333000000); + else + iop3xx_init_time(266000000); +} + +static struct sys_timer iq80332_timer = { + .init = iq80332_timer_init, + .offset = iop3xx_gettimeoffset, +}; + + +/* + * IQ80332 PCI. + */ +static inline int __init +iq80332_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (slot == 4 && pin == 1) { + /* PCI-X Slot INTA */ + irq = IRQ_IOP33X_XINT0; + } else if (slot == 4 && pin == 2) { + /* PCI-X Slot INTB */ + irq = IRQ_IOP33X_XINT1; + } else if (slot == 4 && pin == 3) { + /* PCI-X Slot INTC */ + irq = IRQ_IOP33X_XINT2; + } else if (slot == 4 && pin == 4) { + /* PCI-X Slot INTD */ + irq = IRQ_IOP33X_XINT3; + } else if (slot == 6) { + /* GigE */ + irq = IRQ_IOP33X_XINT2; + } else { + printk(KERN_ERR "iq80332_pci_map_irq() called for unknown " + "device PCI:%d:%d:%d\n", dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + irq = -1; + } + + return irq; +} + +static struct hw_pci iq80332_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iop3xx_pci_setup, + .preinit = iop3xx_pci_preinit, + .scan = iop3xx_pci_scan_bus, + .map_irq = iq80332_pci_map_irq, +}; + +static int __init iq80332_pci_init(void) +{ + if (machine_is_iq80332()) + pci_common_init(&iq80332_pci); + + return 0; +} + +subsys_initcall(iq80332_pci_init); + + +/* + * IQ80332 machine initialisation. + */ +static struct physmap_flash_data iq80332_flash_data = { + .width = 1, +}; + +static struct resource iq80332_flash_resource = { + .start = 0xc0000000, + .end = 0xc07fffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq80332_flash_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &iq80332_flash_data, + }, + .num_resources = 1, + .resource = &iq80332_flash_resource, +}; + +static void __init iq80332_init_machine(void) +{ + platform_device_register(&iop3xx_i2c0_device); + platform_device_register(&iop3xx_i2c1_device); + platform_device_register(&iop33x_uart0_device); + platform_device_register(&iop33x_uart1_device); + platform_device_register(&iq80332_flash_device); +} + +MACHINE_START(IQ80332, "Intel IQ80332") + /* Maintainer: Intel Corp. */ + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = iop3xx_map_io, + .init_irq = iop33x_init_irq, + .timer = &iq80332_timer, + .init_machine = iq80332_init_machine, +MACHINE_END diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c new file mode 100644 index 00000000000..63304b3d0d7 --- /dev/null +++ b/arch/arm/mach-iop33x/irq.c @@ -0,0 +1,127 @@ +/* + * arch/arm/mach-iop33x/irq.c + * + * Generic IOP331 IRQ handling functionality + * + * Author: Dave Jiang <dave.jiang@intel.com> + * Copyright (C) 2003 Intel Corp. + * + * 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/interrupt.h> +#include <linux/list.h> +#include <asm/mach/irq.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/mach-types.h> + +static u32 iop33x_mask0; +static u32 iop33x_mask1; + +static inline void intctl0_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intctl1_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intstr0_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intstr1_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intbase_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static inline void intsize_write(u32 val) +{ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val)); + iop3xx_cp6_disable(); +} + +static void +iop33x_irq_mask1 (unsigned int irq) +{ + iop33x_mask0 &= ~(1 << irq); + intctl0_write(iop33x_mask0); +} + +static void +iop33x_irq_mask2 (unsigned int irq) +{ + iop33x_mask1 &= ~(1 << (irq - 32)); + intctl1_write(iop33x_mask1); +} + +static void +iop33x_irq_unmask1(unsigned int irq) +{ + iop33x_mask0 |= 1 << irq; + intctl0_write(iop33x_mask0); +} + +static void +iop33x_irq_unmask2(unsigned int irq) +{ + iop33x_mask1 |= (1 << (irq - 32)); + intctl1_write(iop33x_mask1); +} + +struct irq_chip iop33x_irqchip1 = { + .name = "IOP33x-1", + .ack = iop33x_irq_mask1, + .mask = iop33x_irq_mask1, + .unmask = iop33x_irq_unmask1, +}; + +struct irq_chip iop33x_irqchip2 = { + .name = "IOP33x-2", + .ack = iop33x_irq_mask2, + .mask = iop33x_irq_mask2, + .unmask = iop33x_irq_unmask2, +}; + +void __init iop33x_init_irq(void) +{ + int i; + + intctl0_write(0); + intctl1_write(0); + intstr0_write(0); + intstr1_write(0); + intbase_write(0); + intsize_write(1); + if (machine_is_iq80331()) + *IOP3XX_PCIIRSR = 0x0f; + + for (i = 0; i < NR_IRQS; i++) { + set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } +} diff --git a/arch/arm/mach-iop33x/uart.c b/arch/arm/mach-iop33x/uart.c new file mode 100644 index 00000000000..ac297cd0276 --- /dev/null +++ b/arch/arm/mach-iop33x/uart.c @@ -0,0 +1,105 @@ +/* + * arch/arm/mach-iop33x/uart.c + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2004 Intel Corporation. + * + * 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/mm.h> +#include <linux/init.h> +#include <linux/major.h> +#include <linux/fs.h> +#include <linux/platform_device.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_8250.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/mach/map.h> +#include <asm/setup.h> +#include <asm/system.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/hardware/iop3xx.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#define IOP33X_UART_XTAL 33334000 + +static struct plat_serial8250_port iop33x_uart0_data[] = { + { + .membase = (char *)IOP33X_UART0_VIRT, + .mapbase = IOP33X_UART0_PHYS, + .irq = IRQ_IOP33X_UART0, + .uartclk = IOP33X_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct resource iop33x_uart0_resources[] = { + [0] = { + .start = IOP33X_UART0_PHYS, + .end = IOP33X_UART0_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP33X_UART0, + .end = IRQ_IOP33X_UART0, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device iop33x_uart0_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = iop33x_uart0_data, + }, + .num_resources = 2, + .resource = iop33x_uart0_resources, +}; + + +static struct resource iop33x_uart1_resources[] = { + [0] = { + .start = IOP33X_UART1_PHYS, + .end = IOP33X_UART1_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP33X_UART1, + .end = IRQ_IOP33X_UART1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct plat_serial8250_port iop33x_uart1_data[] = { + { + .membase = (char *)IOP33X_UART1_VIRT, + .mapbase = IOP33X_UART1_PHYS, + .irq = IRQ_IOP33X_UART1, + .uartclk = IOP33X_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +struct platform_device iop33x_uart1_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM1, + .dev = { + .platform_data = iop33x_uart1_data, + }, + .num_resources = 2, + .resource = iop33x_uart1_resources, +}; diff --git a/arch/arm/mach-iop3xx/Kconfig b/arch/arm/mach-iop3xx/Kconfig deleted file mode 100644 index 4422f238860..00000000000 --- a/arch/arm/mach-iop3xx/Kconfig +++ /dev/null @@ -1,66 +0,0 @@ -if ARCH_IOP3XX - -menu "IOP3xx Implementation Options" - -comment "IOP3xx Platform Types" - -config ARCH_IQ80321 - bool "Enable support for IQ80321" - select ARCH_IOP321 - help - Say Y here if you want to run your kernel on the Intel IQ80321 - evaluation kit for the IOP321 chipset. - -config ARCH_IQ31244 - bool "Enable support for IQ31244" - select ARCH_IOP321 - help - Say Y here if you want to run your kernel on the Intel IQ31244 - evaluation kit for the IOP321 chipset. - -config ARCH_IQ80331 - bool "Enable support for IQ80331" - select ARCH_IOP331 - help - Say Y here if you want to run your kernel on the Intel IQ80331 - evaluation kit for the IOP331 chipset. - -config MACH_IQ80332 - bool "Enable support for IQ80332" - select ARCH_IOP331 - help - Say Y here if you want to run your kernel on the Intel IQ80332 - evaluation kit for the IOP332 chipset. - -config ARCH_EP80219 - bool "Enable support for EP80219" - select ARCH_IOP321 - select ARCH_IQ31244 - help - Say Y here if you want to run your kernel on the Intel EP80219 - evaluation kit for the Intel 80219 chipset (a IOP321 variant). - -# Which IOP variant are we running? -config ARCH_IOP321 - bool - help - The IQ80321 uses the IOP321 variant. - The IQ31244 and EP80219 uses the IOP321 variant. - -config ARCH_IOP331 - bool - default ARCH_IQ80331 - help - The IQ80331, IQ80332, and IQ80333 uses the IOP331 variant. - -comment "IOP3xx Chipset Features" - -config IOP331_STEPD - bool "Chip stepping D of the IOP80331 processor or IOP80333" - depends on (ARCH_IOP331) - help - Say Y here if you have StepD of the IOP80331 or IOP8033 - based platforms. - -endmenu -endif diff --git a/arch/arm/mach-iop3xx/Makefile b/arch/arm/mach-iop3xx/Makefile deleted file mode 100644 index b17eb1f4610..00000000000 --- a/arch/arm/mach-iop3xx/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := common.o - -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_ARCH_IOP321) += iop321-setup.o iop321-irq.o iop321-pci.o iop321-time.o - -obj-$(CONFIG_ARCH_IOP331) += iop331-setup.o iop331-irq.o iop331-pci.o iop331-time.o - -obj-$(CONFIG_ARCH_IQ80321) += iq80321-mm.o iq80321-pci.o - -obj-$(CONFIG_ARCH_IQ31244) += iq31244-mm.o iq31244-pci.o - -obj-$(CONFIG_ARCH_IQ80331) += iq80331-mm.o iq80331-pci.o - -obj-$(CONFIG_MACH_IQ80332) += iq80332-mm.o iq80332-pci.o diff --git a/arch/arm/mach-iop3xx/Makefile.boot b/arch/arm/mach-iop3xx/Makefile.boot deleted file mode 100644 index 6387aa20461..00000000000 --- a/arch/arm/mach-iop3xx/Makefile.boot +++ /dev/null @@ -1,9 +0,0 @@ - zreladdr-y := 0xa0008000 -params_phys-y := 0xa0000100 -initrd_phys-y := 0xa0800000 -ifeq ($(CONFIG_ARCH_IOP331),y) - zreladdr-y := 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 -endif - diff --git a/arch/arm/mach-iop3xx/common.c b/arch/arm/mach-iop3xx/common.c deleted file mode 100644 index d7f50e57e75..00000000000 --- a/arch/arm/mach-iop3xx/common.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * arch/arm/mach-iop3xx/common.c - * - * Common routines shared across all IOP3xx implementations - * - * Author: Deepak Saxena <dsaxena@mvista.com> - * - * Copyright 2003 (c) MontaVista, Software, Inc. - * - * 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/delay.h> -#include <asm/hardware.h> - -/* - * Shared variables - */ -unsigned long iop3xx_pcibios_min_io = 0; -unsigned long iop3xx_pcibios_min_mem = 0; - -#ifdef CONFIG_ARCH_EP80219 -#include <linux/kernel.h> -/* - * Default power-off for EP80219 - */ - -static inline void ep80219_send_to_pic(__u8 c) { -} - -void ep80219_power_off(void) -{ - /* - * This function will send a SHUTDOWN_COMPLETE message to the PIC controller - * over I2C. We are not using the i2c subsystem since we are going to power - * off and it may be removed - */ - - /* Send the Address byte w/ the start condition */ - *IOP321_IDBR1 = 0x60; - *IOP321_ICR1 = 0xE9; - mdelay(1); - - /* Send the START_MSG byte w/ no start or stop condition */ - *IOP321_IDBR1 = 0x0F; - *IOP321_ICR1 = 0xE8; - mdelay(1); - - /* Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or stop condition */ - *IOP321_IDBR1 = 0x03; - *IOP321_ICR1 = 0xE8; - mdelay(1); - - /* Send an ignored byte w/ stop condition */ - *IOP321_IDBR1 = 0x00; - *IOP321_ICR1 = 0xEA; - - while (1) ; -} - -#include <linux/init.h> -#include <linux/pm.h> - -static int __init ep80219_init(void) -{ - pm_power_off = ep80219_power_off; - return 0; -} -arch_initcall(ep80219_init); -#endif diff --git a/arch/arm/mach-iop3xx/iop321-irq.c b/arch/arm/mach-iop3xx/iop321-irq.c deleted file mode 100644 index 88ac333472c..00000000000 --- a/arch/arm/mach-iop3xx/iop321-irq.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/iop321-irq.c - * - * Generic IOP321 IRQ handling functionality - * - * Author: Rory Bolt <rorybolt@pacbell.net> - * Copyright (C) 2002 Rory Bolt - * - * 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. - * - * Added IOP3XX chipset and IQ80321 board masking code. - * - */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/list.h> - -#include <asm/mach/irq.h> -#include <asm/irq.h> -#include <asm/hardware.h> - -#include <asm/mach-types.h> - -static u32 iop321_mask /* = 0 */; - -static inline void intctl_write(u32 val) -{ - asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); -} - -static inline void intstr_write(u32 val) -{ - asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val)); -} - -static void -iop321_irq_mask (unsigned int irq) -{ - - iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS)); - - intctl_write(iop321_mask); -} - -static void -iop321_irq_unmask (unsigned int irq) -{ - iop321_mask |= (1 << (irq - IOP321_IRQ_OFS)); - - intctl_write(iop321_mask); -} - -struct irq_chip ext_chip = { - .name = "IOP", - .ack = iop321_irq_mask, - .mask = iop321_irq_mask, - .unmask = iop321_irq_unmask, -}; - -void __init iop321_init_irq(void) -{ - unsigned int i, tmp; - - /* Enable access to coprocessor 6 for dealing with IRQs. - * From RMK: - * Basically, the Intel documentation here is poor. It appears that - * you need to set the bit to be able to access the coprocessor from - * SVC mode. Whether that allows access from user space or not is - * unclear. - */ - asm volatile ( - "mrc p15, 0, %0, c15, c1, 0\n\t" - "orr %0, %0, %1\n\t" - "mcr p15, 0, %0, c15, c1, 0\n\t" - /* The action is delayed, so we have to do this: */ - "mrc p15, 0, %0, c15, c1, 0\n\t" - "mov %0, %0\n\t" - "sub pc, pc, #4" - : "=r" (tmp) : "i" (1 << 6) ); - - intctl_write(0); // disable all interrupts - intstr_write(0); // treat all as IRQ - if(machine_is_iq80321() || - machine_is_iq31244()) // all interrupts are inputs to chip - *IOP321_PCIIRSR = 0x0f; - - for(i = IOP321_IRQ_OFS; i < NR_IOP321_IRQS; i++) - { - set_irq_chip(i, &ext_chip); - set_irq_handler(i, do_level_IRQ); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - - } -} - diff --git a/arch/arm/mach-iop3xx/iop321-pci.c b/arch/arm/mach-iop3xx/iop321-pci.c deleted file mode 100644 index 8ba6a0e2313..00000000000 --- a/arch/arm/mach-iop3xx/iop321-pci.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iop321-pci.c - * - * PCI support for the Intel IOP321 chipset - * - * Author: Rory Bolt <rorybolt@pacbell.net> - * Copyright (C) 2002 Rory Bolt - * - * 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/pci.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/ioport.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/hardware.h> -#include <asm/mach/pci.h> - -#include <asm/arch/iop321.h> - -// #define DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) do { } while (0) -#endif - -/* - * This routine builds either a type0 or type1 configuration command. If the - * bus is on the 80321 then a type0 made, else a type1 is created. - */ -static u32 iop321_cfg_address(struct pci_bus *bus, int devfn, int where) -{ - struct pci_sys_data *sys = bus->sysdata; - u32 addr; - - if (sys->busnr == bus->number) - addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); - else - addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; - - addr |= PCI_FUNC(devfn) << 8 | (where & ~3); - - return addr; -} - -/* - * This routine checks the status of the last configuration cycle. If an error - * was detected it returns a 1, else it returns a 0. The errors being checked - * are parity, master abort, target abort (master and target). These types of - * errors occure during a config cycle where there is no device, like during - * the discovery stage. - */ -static int iop321_pci_status(void) -{ - unsigned int status; - int ret = 0; - - /* - * Check the status registers. - */ - status = *IOP321_ATUSR; - if (status & 0xf900) - { - DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); - *IOP321_ATUSR = status & 0xf900; - ret = 1; - } - status = *IOP321_ATUISR; - if (status & 0x679f) - { - DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); - *IOP321_ATUISR = status & 0x679f; - ret = 1; - } - return ret; -} - -/* - * Simply write the address register and read the configuration - * data. Note that the 4 nop's ensure that we are able to handle - * a delayed abort (in theory.) - */ -static inline u32 iop321_read(unsigned long addr) -{ - u32 val; - - __asm__ __volatile__( - "str %1, [%2]\n\t" - "ldr %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : "=r" (val) - : "r" (addr), "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); - - return val; -} - -/* - * The read routines must check the error status of the last configuration - * cycle. If there was an error, the routine returns all hex f's. - */ -static int -iop321_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *value) -{ - unsigned long addr = iop321_cfg_address(bus, devfn, where); - u32 val = iop321_read(addr) >> ((where & 3) * 8); - - if( iop321_pci_status() ) - val = 0xffffffff; - - *value = val; - - return PCIBIOS_SUCCESSFUL; -} - -static int -iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 value) -{ - unsigned long addr = iop321_cfg_address(bus, devfn, where); - u32 val; - - if (size != 4) { - val = iop321_read(addr); - if (!iop321_pci_status() == 0) - return PCIBIOS_SUCCESSFUL; - - where = (where & 3) * 8; - - if (size == 1) - val &= ~(0xff << where); - else - val &= ~(0xffff << where); - - *IOP321_OCCDR = val | value << where; - } else { - asm volatile( - "str %1, [%2]\n\t" - "str %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : - : "r" (value), "r" (addr), - "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); - } - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops iop321_ops = { - .read = iop321_read_config, - .write = iop321_write_config, -}; - -/* - * When a PCI device does not exist during config cycles, the 80200 gets a - * bus error instead of returning 0xffffffff. This handler simply returns. - */ -int -iop321_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -{ - DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", - addr, fsr, regs->ARM_pc, regs->ARM_lr); - - /* - * If it was an imprecise abort, then we need to correct the - * return address to be _after_ the instruction. - */ - if (fsr & (1 << 10)) - regs->ARM_pc += 4; - - return 0; -} - -/* - * Scan an IOP321 PCI bus. sys->bus defines which bus we scan. - */ -struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_bus(sys->busnr, &iop321_ops, sys); -} - -void iop321_init(void) -{ - DBG("PCI: Intel 80321 PCI init code.\n"); - DBG("ATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD); - DBG("ATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n", - *IOP321_OMWTVR0, - *IOP321_OIOWTVR); - DBG("ATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR); - DBG("ATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n", - *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0); - DBG("ATU: IOP321_OMWTVR0=0x%08x\n", *IOP321_OMWTVR0); - DBG("ATU: IOP321_IABAR1=0x%08x IOP321_IALR1=0x%08x\n", - *IOP321_IABAR1, *IOP321_IALR1); - DBG("ATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n", - *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR); - DBG("ATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n", - *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2); - DBG("ATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n", - *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3); - - hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort"); -} - diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c deleted file mode 100644 index b6d096903c4..00000000000 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/iop321-setup.c - * - * Author: Nicolas Pitre <nico@cam.org> - * Copyright (C) 2001 MontaVista Software, Inc. - * Copyright (C) 2004 Intel Corporation. - * - * 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/mm.h> -#include <linux/init.h> -#include <linux/major.h> -#include <linux/fs.h> -#include <linux/platform_device.h> -#include <linux/serial.h> -#include <linux/tty.h> -#include <linux/serial_core.h> - -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/page.h> -#include <asm/mach/map.h> -#include <asm/setup.h> -#include <asm/system.h> -#include <asm/memory.h> -#include <asm/hardware.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#define IOP321_UART_XTAL 1843200 - -/* - * Standard IO mapping for all IOP321 based systems - */ -static struct map_desc iop321_std_desc[] __initdata = { - { /* mem mapped registers */ - .virtual = IOP321_VIRT_MEM_BASE, - .pfn = __phys_to_pfn(IOP321_PHYS_MEM_BASE), - .length = 0x00002000, - .type = MT_DEVICE - }, { /* PCI IO space */ - .virtual = IOP321_PCI_LOWER_IO_VA, - .pfn = __phys_to_pfn(IOP321_PCI_LOWER_IO_PA), - .length = IOP321_PCI_IO_WINDOW_SIZE, - .type = MT_DEVICE - } -}; - -#ifdef CONFIG_ARCH_IQ80321 -#define UARTBASE IQ80321_UART -#define IRQ_UART IRQ_IQ80321_UART -#endif - -#ifdef CONFIG_ARCH_IQ31244 -#define UARTBASE IQ31244_UART -#define IRQ_UART IRQ_IQ31244_UART -#endif - -static struct uart_port iop321_serial_ports[] = { - { - .membase = (char*)(UARTBASE), - .mapbase = (UARTBASE), - .irq = IRQ_UART, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 0, - .uartclk = IOP321_UART_XTAL, - .line = 0, - .type = PORT_16550A, - .fifosize = 16 - } -}; - -static struct resource iop32x_i2c_0_resources[] = { - [0] = { - .start = 0xfffff680, - .end = 0xfffff698, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP321_I2C_0, - .end = IRQ_IOP321_I2C_0, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop32x_i2c_1_resources[] = { - [0] = { - .start = 0xfffff6a0, - .end = 0xfffff6b8, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP321_I2C_1, - .end = IRQ_IOP321_I2C_1, - .flags = IORESOURCE_IRQ - } -}; - -static struct platform_device iop32x_i2c_0_controller = { - .name = "IOP3xx-I2C", - .id = 0, - .num_resources = 2, - .resource = iop32x_i2c_0_resources -}; - -static struct platform_device iop32x_i2c_1_controller = { - .name = "IOP3xx-I2C", - .id = 1, - .num_resources = 2, - .resource = iop32x_i2c_1_resources -}; - -static struct platform_device *iop32x_devices[] __initdata = { - &iop32x_i2c_0_controller, - &iop32x_i2c_1_controller -}; - -void __init iop32x_init(void) -{ - if(iop_is_321()) - { - platform_add_devices(iop32x_devices, - ARRAY_SIZE(iop32x_devices)); - } -} - -void __init iop321_map_io(void) -{ - iotable_init(iop321_std_desc, ARRAY_SIZE(iop321_std_desc)); - early_serial_setup(&iop321_serial_ports[0]); -} - -#ifdef CONFIG_ARCH_IQ80321 -extern void iq80321_map_io(void); -extern struct sys_timer iop321_timer; -extern void iop321_init_time(void); -#endif - -#ifdef CONFIG_ARCH_IQ31244 -extern void iq31244_map_io(void); -extern struct sys_timer iop321_timer; -extern void iop321_init_time(void); -#endif - -#if defined(CONFIG_ARCH_IQ80321) -MACHINE_START(IQ80321, "Intel IQ80321") - /* Maintainer: Intel Corporation */ - .phys_io = IQ80321_UART, - .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, - .map_io = iq80321_map_io, - .init_irq = iop321_init_irq, - .timer = &iop321_timer, - .boot_params = 0xa0000100, - .init_machine = iop32x_init, -MACHINE_END -#elif defined(CONFIG_ARCH_IQ31244) -MACHINE_START(IQ31244, "Intel IQ31244") - /* Maintainer: Intel Corp. */ - .phys_io = IQ31244_UART, - .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, - .map_io = iq31244_map_io, - .init_irq = iop321_init_irq, - .timer = &iop321_timer, - .boot_params = 0xa0000100, - .init_machine = iop32x_init, -MACHINE_END -#else -#error No machine descriptor defined for this IOP3XX implementation -#endif diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c deleted file mode 100644 index 04b1a6f7eba..00000000000 --- a/arch/arm/mach-iop3xx/iop321-time.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iop321-time.c - * - * Timer code for IOP321 based systems - * - * Author: Deepak Saxena <dsaxena@mvista.com> - * - * Copyright 2002-2003 MontaVista Software Inc. - * - * 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. - */ - -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/time.h> -#include <linux/init.h> -#include <linux/timex.h> - -#include <asm/hardware.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> -#include <asm/mach/irq.h> -#include <asm/mach/time.h> - -#define IOP321_TIME_SYNC 0 - -static inline unsigned long get_elapsed(void) -{ - return LATCH - *IOP321_TU_TCR0; -} - -static unsigned long iop321_gettimeoffset(void) -{ - unsigned long elapsed, usec; - u32 tisr1, tisr2; - - /* - * If an interrupt was pending before we read the timer, - * we've already wrapped. Factor this into the time. - * If an interrupt was pending after we read the timer, - * it may have wrapped between checking the interrupt - * status and reading the timer. Re-read the timer to - * be sure its value is after the wrap. - */ - - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); - elapsed = get_elapsed(); - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); - - if(tisr1 & 1) - elapsed += LATCH; - else if (tisr2 & 1) - elapsed = LATCH + get_elapsed(); - - /* - * Now convert them to usec. - */ - usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); - - return usec; -} - -static irqreturn_t -iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - u32 tisr; - - write_seqlock(&xtime_lock); - - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); - tisr |= 1; - asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); - - timer_tick(regs); - - write_sequnlock(&xtime_lock); - - return IRQ_HANDLED; -} - -static struct irqaction iop321_timer_irq = { - .name = "IOP321 Timer Tick", - .handler = iop321_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -static void __init iop321_timer_init(void) -{ - u32 timer_ctl; - - setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq); - - timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD | - IOP321_TMR_RATIO_1_1; - - asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); - - asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); -} - -struct sys_timer iop321_timer = { - .init = &iop321_timer_init, - .offset = iop321_gettimeoffset, -}; diff --git a/arch/arm/mach-iop3xx/iop331-irq.c b/arch/arm/mach-iop3xx/iop331-irq.c deleted file mode 100644 index cab11722ced..00000000000 --- a/arch/arm/mach-iop3xx/iop331-irq.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/iop331-irq.c - * - * Generic IOP331 IRQ handling functionality - * - * Author: Dave Jiang <dave.jiang@intel.com> - * Copyright (C) 2003 Intel Corp. - * - * 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/interrupt.h> -#include <linux/list.h> - -#include <asm/mach/irq.h> -#include <asm/irq.h> -#include <asm/hardware.h> - -#include <asm/mach-types.h> - -static u32 iop331_mask0 = 0; -static u32 iop331_mask1 = 0; - -static inline void intctl_write0(u32 val) -{ - // INTCTL0 - asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); -} - -static inline void intctl_write1(u32 val) -{ - // INTCTL1 - asm volatile("mcr p6,0,%0,c1,c0,0"::"r" (val)); -} - -static inline void intstr_write0(u32 val) -{ - // INTSTR0 - asm volatile("mcr p6,0,%0,c2,c0,0"::"r" (val)); -} - -static inline void intstr_write1(u32 val) -{ - // INTSTR1 - asm volatile("mcr p6,0,%0,c3,c0,0"::"r" (val)); -} - -static void -iop331_irq_mask1 (unsigned int irq) -{ - iop331_mask0 &= ~(1 << (irq - IOP331_IRQ_OFS)); - intctl_write0(iop331_mask0); -} - -static void -iop331_irq_mask2 (unsigned int irq) -{ - iop331_mask1 &= ~(1 << (irq - IOP331_IRQ_OFS - 32)); - intctl_write1(iop331_mask1); -} - -static void -iop331_irq_unmask1(unsigned int irq) -{ - iop331_mask0 |= (1 << (irq - IOP331_IRQ_OFS)); - intctl_write0(iop331_mask0); -} - -static void -iop331_irq_unmask2(unsigned int irq) -{ - iop331_mask1 |= (1 << (irq - IOP331_IRQ_OFS - 32)); - intctl_write1(iop331_mask1); -} - -struct irq_chip iop331_irqchip1 = { - .name = "IOP-1", - .ack = iop331_irq_mask1, - .mask = iop331_irq_mask1, - .unmask = iop331_irq_unmask1, -}; - -struct irq_chip iop331_irqchip2 = { - .name = "IOP-2", - .ack = iop331_irq_mask2, - .mask = iop331_irq_mask2, - .unmask = iop331_irq_unmask2, -}; - -void __init iop331_init_irq(void) -{ - unsigned int i, tmp; - - /* Enable access to coprocessor 6 for dealing with IRQs. - * From RMK: - * Basically, the Intel documentation here is poor. It appears that - * you need to set the bit to be able to access the coprocessor from - * SVC mode. Whether that allows access from user space or not is - * unclear. - */ - asm volatile ( - "mrc p15, 0, %0, c15, c1, 0\n\t" - "orr %0, %0, %1\n\t" - "mcr p15, 0, %0, c15, c1, 0\n\t" - /* The action is delayed, so we have to do this: */ - "mrc p15, 0, %0, c15, c1, 0\n\t" - "mov %0, %0\n\t" - "sub pc, pc, #4" - : "=r" (tmp) : "i" (1 << 6) ); - - intctl_write0(0); // disable all interrupts - intctl_write1(0); - intstr_write0(0); // treat all as IRQ - intstr_write1(0); - if(machine_is_iq80331()) // all interrupts are inputs to chip - *IOP331_PCIIRSR = 0x0f; - - for(i = IOP331_IRQ_OFS; i < NR_IOP331_IRQS; i++) - { - set_irq_chip(i, (i < 32) ? &iop331_irqchip1 : &iop331_irqchip2); - set_irq_handler(i, do_level_IRQ); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } -} - diff --git a/arch/arm/mach-iop3xx/iop331-pci.c b/arch/arm/mach-iop3xx/iop331-pci.c deleted file mode 100644 index 44dd213b48a..00000000000 --- a/arch/arm/mach-iop3xx/iop331-pci.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iop331-pci.c - * - * PCI support for the Intel IOP331 chipset - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright (C) 2003, 2004 Intel Corp. - * - * 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/pci.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/ioport.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/hardware.h> -#include <asm/mach/pci.h> - -#include <asm/arch/iop331.h> - -#undef DEBUG -#undef DEBUG1 - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) do { } while (0) -#endif - -#ifdef DEBUG1 -#define DBG1(x...) printk(x) -#else -#define DBG1(x...) do { } while (0) -#endif - -/* - * This routine builds either a type0 or type1 configuration command. If the - * bus is on the 80331 then a type0 made, else a type1 is created. - */ -static u32 iop331_cfg_address(struct pci_bus *bus, int devfn, int where) -{ - struct pci_sys_data *sys = bus->sysdata; - u32 addr; - - if (sys->busnr == bus->number) - addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); - else - addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; - - addr |= PCI_FUNC(devfn) << 8 | (where & ~3); - - return addr; -} - -/* - * This routine checks the status of the last configuration cycle. If an error - * was detected it returns a 1, else it returns a 0. The errors being checked - * are parity, master abort, target abort (master and target). These types of - * errors occure during a config cycle where there is no device, like during - * the discovery stage. - */ -static int iop331_pci_status(void) -{ - unsigned int status; - int ret = 0; - - /* - * Check the status registers. - */ - status = *IOP331_ATUSR; - if (status & 0xf900) - { - DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); - *IOP331_ATUSR = status & 0xf900; - ret = 1; - } - status = *IOP331_ATUISR; - if (status & 0x679f) - { - DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); - *IOP331_ATUISR = status & 0x679f; - ret = 1; - } - return ret; -} - -/* - * Simply write the address register and read the configuration - * data. Note that the 4 nop's ensure that we are able to handle - * a delayed abort (in theory.) - */ -static inline u32 iop331_read(unsigned long addr) -{ - u32 val; - - __asm__ __volatile__( - "str %1, [%2]\n\t" - "ldr %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : "=r" (val) - : "r" (addr), "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); - - return val; -} - -/* - * The read routines must check the error status of the last configuration - * cycle. If there was an error, the routine returns all hex f's. - */ -static int -iop331_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *value) -{ - unsigned long addr = iop331_cfg_address(bus, devfn, where); - u32 val = iop331_read(addr) >> ((where & 3) * 8); - - if( iop331_pci_status() ) - val = 0xffffffff; - - *value = val; - - return PCIBIOS_SUCCESSFUL; -} - -static int -iop331_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 value) -{ - unsigned long addr = iop331_cfg_address(bus, devfn, where); - u32 val; - - if (size != 4) { - val = iop331_read(addr); - if (!iop331_pci_status() == 0) - return PCIBIOS_SUCCESSFUL; - - where = (where & 3) * 8; - - if (size == 1) - val &= ~(0xff << where); - else - val &= ~(0xffff << where); - - *IOP331_OCCDR = val | value << where; - } else { - asm volatile( - "str %1, [%2]\n\t" - "str %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : - : "r" (value), "r" (addr), - "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); - } - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops iop331_ops = { - .read = iop331_read_config, - .write = iop331_write_config, -}; - -/* - * When a PCI device does not exist during config cycles, the XScale gets a - * bus error instead of returning 0xffffffff. This handler simply returns. - */ -int -iop331_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -{ - DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", - addr, fsr, regs->ARM_pc, regs->ARM_lr); - - /* - * If it was an imprecise abort, then we need to correct the - * return address to be _after_ the instruction. - */ - if (fsr & (1 << 10)) - regs->ARM_pc += 4; - - return 0; -} - -/* - * Scan an IOP331 PCI bus. sys->bus defines which bus we scan. - */ -struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_bus(sys->busnr, &iop331_ops, sys); -} - -void iop331_init(void) -{ - DBG1("PCI: Intel 80331 PCI init code.\n"); - DBG1("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD); - DBG1("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n", - *IOP331_OMWTVR0, - *IOP331_OIOWTVR); - DBG1("\tATU: IOP331_OMWTVR1=0x%04x\n", *IOP331_OMWTVR1); - DBG1("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR); - DBG1("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0); - DBG1("\tATU: IOP31_IABAR1=0x%08x IOP331_IALR1=0x%08x\n", *IOP331_IABAR1, *IOP331_IALR1); - DBG1("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR); - DBG1("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2); - DBG1("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3); - - hook_fault_code(16+6, iop331_pci_abort, SIGBUS, "imprecise external abort"); -} - diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c deleted file mode 100644 index 3cc98d892ad..00000000000 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/iop331-setup.c - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright (C) 2004 Intel Corporation. - * - * 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/mm.h> -#include <linux/init.h> -#include <linux/major.h> -#include <linux/fs.h> -#include <linux/platform_device.h> -#include <linux/serial.h> -#include <linux/tty.h> -#include <linux/serial_8250.h> - -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/page.h> -#include <asm/mach/map.h> -#include <asm/setup.h> -#include <asm/system.h> -#include <asm/memory.h> -#include <asm/hardware.h> -#include <asm/mach-types.h> -#include <asm/mach/arch.h> - -#define IOP331_UART_XTAL 33334000 - -/* - * Standard IO mapping for all IOP331 based systems - */ -static struct map_desc iop331_std_desc[] __initdata = { - { /* mem mapped registers */ - .virtual = IOP331_VIRT_MEM_BASE, - .pfn = __phys_to_pfn(IOP331_PHYS_MEM_BASE), - .length = 0x00002000, - .type = MT_DEVICE - }, { /* PCI IO space */ - .virtual = IOP331_PCI_LOWER_IO_VA, - .pfn = __phys_to_pfn(IOP331_PCI_LOWER_IO_PA), - .length = IOP331_PCI_IO_WINDOW_SIZE, - .type = MT_DEVICE - } -}; - -static struct resource iop33x_uart0_resources[] = { - [0] = { - .start = IOP331_UART0_PHYS, - .end = IOP331_UART0_PHYS + 0x3f, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP331_UART0, - .end = IRQ_IOP331_UART0, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop33x_uart1_resources[] = { - [0] = { - .start = IOP331_UART1_PHYS, - .end = IOP331_UART1_PHYS + 0x3f, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP331_UART1, - .end = IRQ_IOP331_UART1, - .flags = IORESOURCE_IRQ - } -}; - -static struct plat_serial8250_port iop33x_uart0_data[] = { - { - .membase = (char*)(IOP331_UART0_VIRT), - .mapbase = (IOP331_UART0_PHYS), - .irq = IRQ_IOP331_UART0, - .uartclk = IOP331_UART_XTAL, - .regshift = 2, - .iotype = UPIO_MEM, - .flags = UPF_SKIP_TEST, - }, - { }, -}; - -static struct plat_serial8250_port iop33x_uart1_data[] = { - { - .membase = (char*)(IOP331_UART1_VIRT), - .mapbase = (IOP331_UART1_PHYS), - .irq = IRQ_IOP331_UART1, - .uartclk = IOP331_UART_XTAL, - .regshift = 2, - .iotype = UPIO_MEM, - .flags = UPF_SKIP_TEST, - }, - { }, -}; - -static struct platform_device iop33x_uart0 = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev.platform_data = iop33x_uart0_data, - .num_resources = 2, - .resource = iop33x_uart0_resources, -}; - -static struct platform_device iop33x_uart1 = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM1, - .dev.platform_data = iop33x_uart1_data, - .num_resources = 2, - .resource = iop33x_uart1_resources, -}; - -static struct resource iop33x_i2c_0_resources[] = { - [0] = { - .start = 0xfffff680, - .end = 0xfffff698, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP331_I2C_0, - .end = IRQ_IOP331_I2C_0, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop33x_i2c_1_resources[] = { - [0] = { - .start = 0xfffff6a0, - .end = 0xfffff6b8, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP331_I2C_1, - .end = IRQ_IOP331_I2C_1, - .flags = IORESOURCE_IRQ - } -}; - -static struct platform_device iop33x_i2c_0_controller = { - .name = "IOP3xx-I2C", - .id = 0, - .num_resources = 2, - .resource = iop33x_i2c_0_resources -}; - -static struct platform_device iop33x_i2c_1_controller = { - .name = "IOP3xx-I2C", - .id = 1, - .num_resources = 2, - .resource = iop33x_i2c_1_resources -}; - -static struct platform_device *iop33x_devices[] __initdata = { - &iop33x_uart0, - &iop33x_uart1, - &iop33x_i2c_0_controller, - &iop33x_i2c_1_controller -}; - -void __init iop33x_init(void) -{ - if(iop_is_331()) - { - platform_add_devices(iop33x_devices, - ARRAY_SIZE(iop33x_devices)); - } -} - -void __init iop331_map_io(void) -{ - iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc)); -} - -#ifdef CONFIG_ARCH_IOP331 -extern void iop331_init_irq(void); -extern struct sys_timer iop331_timer; -#endif - -#ifdef CONFIG_ARCH_IQ80331 -extern void iq80331_map_io(void); -#endif - -#ifdef CONFIG_MACH_IQ80332 -extern void iq80332_map_io(void); -#endif - -#if defined(CONFIG_ARCH_IQ80331) -MACHINE_START(IQ80331, "Intel IQ80331") - /* Maintainer: Intel Corp. */ - .phys_io = 0xfefff000, - .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical - .map_io = iq80331_map_io, - .init_irq = iop331_init_irq, - .timer = &iop331_timer, - .boot_params = 0x0100, - .init_machine = iop33x_init, -MACHINE_END - -#elif defined(CONFIG_MACH_IQ80332) -MACHINE_START(IQ80332, "Intel IQ80332") - /* Maintainer: Intel Corp. */ - .phys_io = 0xfefff000, - .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical - .map_io = iq80332_map_io, - .init_irq = iop331_init_irq, - .timer = &iop331_timer, - .boot_params = 0x0100, - .init_machine = iop33x_init, -MACHINE_END - -#else -#error No machine descriptor defined for this IOP3XX implementation -#endif - - diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c deleted file mode 100644 index 0c09e74c574..00000000000 --- a/arch/arm/mach-iop3xx/iop331-time.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iop331-time.c - * - * Timer code for IOP331 based systems - * - * Author: Dave Jiang <dave.jiang@intel.com> - * - * Copyright 2003 Intel Corp. - * - * 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. - */ - -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/time.h> -#include <linux/init.h> -#include <linux/timex.h> - -#include <asm/hardware.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> -#include <asm/mach/irq.h> -#include <asm/mach/time.h> - -static inline unsigned long get_elapsed(void) -{ - return LATCH - *IOP331_TU_TCR0; -} - -static unsigned long iop331_gettimeoffset(void) -{ - unsigned long elapsed, usec; - u32 tisr1, tisr2; - - /* - * If an interrupt was pending before we read the timer, - * we've already wrapped. Factor this into the time. - * If an interrupt was pending after we read the timer, - * it may have wrapped between checking the interrupt - * status and reading the timer. Re-read the timer to - * be sure its value is after the wrap. - */ - - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); - elapsed = get_elapsed(); - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); - - if(tisr1 & 1) - elapsed += LATCH; - else if (tisr2 & 1) - elapsed = LATCH + get_elapsed(); - - /* - * Now convert them to usec. - */ - usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); - - return usec; -} - -static irqreturn_t -iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - u32 tisr; - - write_seqlock(&xtime_lock); - - asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); - tisr |= 1; - asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); - - timer_tick(regs); - - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; -} - -static struct irqaction iop331_timer_irq = { - .name = "IOP331 Timer Tick", - .handler = iop331_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -static void __init iop331_timer_init(void) -{ - u32 timer_ctl; - - setup_irq(IRQ_IOP331_TIMER0, &iop331_timer_irq); - - timer_ctl = IOP331_TMR_EN | IOP331_TMR_PRIVILEGED | IOP331_TMR_RELOAD | - IOP331_TMR_RATIO_1_1; - - asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); - - asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); - -} - -struct sys_timer iop331_timer = { - .init = iop331_timer_init, - .offset = iop331_gettimeoffset, -}; diff --git a/arch/arm/mach-iop3xx/iq31244-mm.c b/arch/arm/mach-iop3xx/iq31244-mm.c deleted file mode 100644 index e874b54eefe..00000000000 --- a/arch/arm/mach-iop3xx/iq31244-mm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/mm.c - * - * Low level memory initialization for iq80321 platform - * - * Author: Rory Bolt <rorybolt@pacbell.net> - * Copyright (C) 2002 Rory Bolt - * - * 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. - * - */ - -#include <linux/mm.h> -#include <linux/init.h> - -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/page.h> - -#include <asm/mach/map.h> - - -/* - * IQ80321 specific IO mappings - * - * We use RedBoot's setup for the onboard devices. - */ -static struct map_desc iq31244_io_desc[] __initdata = { - { /* on-board devices */ - .virtual = IQ31244_UART, - .pfn = __phys_to_pfn(IQ31244_UART), - .length = 0x00100000, - .type = MT_DEVICE - } -}; - -void __init iq31244_map_io(void) -{ - iop321_map_io(); - - iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc)); -} diff --git a/arch/arm/mach-iop3xx/iq31244-pci.c b/arch/arm/mach-iop3xx/iq31244-pci.c deleted file mode 100644 index f3c6413fa5b..00000000000 --- a/arch/arm/mach-iop3xx/iq31244-pci.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iq80321-pci.c - * - * PCI support for the Intel IQ80321 reference board - * - * Author: Rory Bolt <rorybolt@pacbell.net> - * Copyright (C) 2002 Rory Bolt - * Copyright (C) 2004 Intel Corp. - * - * 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/pci.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include <asm/hardware.h> -#include <asm/irq.h> -#include <asm/mach/pci.h> -#include <asm/mach-types.h> - -/* - * The following macro is used to lookup irqs in a standard table - * format for those systems that do not already have PCI - * interrupts properly routed. We assume 1 <= pin <= 4 - */ -#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ -({ int _ctl_ = -1; \ - unsigned int _idsel = idsel - minid; \ - if (_idsel <= maxid) \ - _ctl_ = pci_irq_table[_idsel][pin-1]; \ - _ctl_; }) - -#define INTA IRQ_IQ31244_INTA -#define INTB IRQ_IQ31244_INTB -#define INTC IRQ_IQ31244_INTC -#define INTD IRQ_IQ31244_INTD - -#define INTE IRQ_IQ31244_I82546 - -static inline int __init -iq31244_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ -#ifdef CONFIG_ARCH_EP80219 - {INTB, INTB, INTB, INTB}, /* CFlash */ - {INTE, INTE, INTE, INTE}, /* 82551 Pro 100 */ - {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ - {INTC, INTC, INTC, INTC}, /* SATA */ -#else - {INTB, INTB, INTB, INTB}, /* CFlash */ - {INTC, INTC, INTC, INTC}, /* SATA */ - {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ - {INTE, INTE, INTE, INTE}, /* 82546 GigE */ -#endif // CONFIG_ARCH_EP80219 - }; - - BUG_ON(pin < 1 || pin > 4); - - return PCI_IRQ_TABLE_LOOKUP(0, 7); -} - -static int iq31244_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if(nr != 0) - return 0; - - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP321_PCI_LOWER_IO_VA; - res[0].end = IOP321_PCI_UPPER_IO_VA; - res[0].name = "IQ31244 PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - - res[1].start = IOP321_PCI_LOWER_MEM_PA; - res[1].end = IOP321_PCI_UPPER_MEM_PA; - res[1].name = "IQ31244 PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - - request_resource(&ioport_resource, &res[0]); - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP321_PCI_MEM_OFFSET; - sys->io_offset = IOP321_PCI_IO_OFFSET; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -static void iq31244_preinit(void) -{ - iop321_init(); -} - -static struct hw_pci iq31244_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iq31244_setup, - .scan = iop321_scan_bus, - .preinit = iq31244_preinit, - .map_irq = iq31244_map_irq -}; - -static int __init iq31244_pci_init(void) -{ - if (machine_is_iq31244()) - pci_common_init(&iq31244_pci); - return 0; -} - -subsys_initcall(iq31244_pci_init); - - - - diff --git a/arch/arm/mach-iop3xx/iq80321-mm.c b/arch/arm/mach-iop3xx/iq80321-mm.c deleted file mode 100644 index d9cac5e1fc3..00000000000 --- a/arch/arm/mach-iop3xx/iq80321-mm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/mm.c - * - * Low level memory initialization for iq80321 platform - * - * Author: Rory Bolt <rorybolt@pacbell.net> - * Copyright (C) 2002 Rory Bolt - * - * 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. - * - */ - -#include <linux/mm.h> -#include <linux/init.h> - -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/page.h> - -#include <asm/mach/map.h> - - -/* - * IQ80321 specific IO mappings - * - * We use RedBoot's setup for the onboard devices. - */ -static struct map_desc iq80321_io_desc[] __initdata = { - { /* on-board devices */ - .virtual = IQ80321_UART, - .pfn = __phys_to_pfn(IQ80321_UART), - .length = 0x00100000, - .type = MT_DEVICE - } -}; - -void __init iq80321_map_io(void) -{ - iop321_map_io(); - - iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc)); -} diff --git a/arch/arm/mach-iop3xx/iq80321-pci.c b/arch/arm/mach-iop3xx/iq80321-pci.c deleted file mode 100644 index d9758d3f6e7..00000000000 --- a/arch/arm/mach-iop3xx/iq80321-pci.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iq80321-pci.c - * - * PCI support for the Intel IQ80321 reference board - * - * Author: Rory Bolt <rorybolt@pacbell.net> - * Copyright (C) 2002 Rory Bolt - * Copyright (C) 2004 Intel Corp. - * - * 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/pci.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include <asm/hardware.h> -#include <asm/irq.h> -#include <asm/mach/pci.h> -#include <asm/mach-types.h> - -/* - * The following macro is used to lookup irqs in a standard table - * format for those systems that do not already have PCI - * interrupts properly routed. We assume 1 <= pin <= 4 - */ -#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ -({ int _ctl_ = -1; \ - unsigned int _idsel = idsel - minid; \ - if (_idsel <= maxid) \ - _ctl_ = pci_irq_table[_idsel][pin-1]; \ - _ctl_; }) - -#define INTA IRQ_IQ80321_INTA -#define INTB IRQ_IQ80321_INTB -#define INTC IRQ_IQ80321_INTC -#define INTD IRQ_IQ80321_INTD - -#define INTE IRQ_IQ80321_I82544 - -static inline int __init -iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {INTE, INTE, INTE, INTE}, /* Gig-E */ - {-1, -1, -1, -1}, /* Unused */ - {INTC, INTD, INTA, INTB}, /* PCI-X Slot */ - {-1, -1, -1, -1}, - }; - - BUG_ON(pin < 1 || pin > 4); - -// return PCI_IRQ_TABLE_LOOKUP(4, 7); - return pci_irq_table[idsel%4][pin-1]; -} - -static int iq80321_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if(nr != 0) - return 0; - - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP321_PCI_LOWER_IO_VA; - res[0].end = IOP321_PCI_UPPER_IO_VA; - res[0].name = "IQ80321 PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - - res[1].start = IOP321_PCI_LOWER_MEM_PA; - res[1].end = IOP321_PCI_UPPER_MEM_PA; - res[1].name = "IQ80321 PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - - request_resource(&ioport_resource, &res[0]); - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP321_PCI_MEM_OFFSET; - sys->io_offset = IOP321_PCI_IO_OFFSET; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -static void iq80321_preinit(void) -{ - iop321_init(); -} - -static struct hw_pci iq80321_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iq80321_setup, - .scan = iop321_scan_bus, - .preinit = iq80321_preinit, - .map_irq = iq80321_map_irq -}; - -static int __init iq80321_pci_init(void) -{ - if (machine_is_iq80321()) - pci_common_init(&iq80321_pci); - return 0; -} - -subsys_initcall(iq80321_pci_init); - - - - diff --git a/arch/arm/mach-iop3xx/iq80331-mm.c b/arch/arm/mach-iop3xx/iq80331-mm.c deleted file mode 100644 index 129eb49b067..00000000000 --- a/arch/arm/mach-iop3xx/iq80331-mm.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/mm.c - * - * Low level memory initialization for iq80331 platform - * - * Author: Dave Jiang <dave.jiang@intel.com> - * Copyright (C) 2003 Intel Corp. - * - * 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. - * - */ - -#include <linux/mm.h> -#include <linux/init.h> - -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/page.h> - -#include <asm/mach/map.h> - - -/* - * IQ80331 specific IO mappings - * - * We use RedBoot's setup for the onboard devices. - */ - -void __init iq80331_map_io(void) -{ - iop331_map_io(); -} diff --git a/arch/arm/mach-iop3xx/iq80331-pci.c b/arch/arm/mach-iop3xx/iq80331-pci.c deleted file mode 100644 index 40d86100249..00000000000 --- a/arch/arm/mach-iop3xx/iq80331-pci.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iq80331-pci.c - * - * PCI support for the Intel IQ80331 reference board - * - * Author: Dave Jiang <dave.jiang@intel.com> - * Copyright (C) 2003, 2004 Intel Corp. - * - * 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/pci.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include <asm/hardware.h> -#include <asm/irq.h> -#include <asm/mach/pci.h> -#include <asm/mach-types.h> - -/* - * The following macro is used to lookup irqs in a standard table - * format for those systems that do not already have PCI - * interrupts properly routed. We assume 1 <= pin <= 4 - */ -#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ -({ int _ctl_ = -1; \ - unsigned int _idsel = idsel - minid; \ - if (_idsel <= maxid) \ - _ctl_ = pci_irq_table[_idsel][pin-1]; \ - _ctl_; }) - -#define INTA IRQ_IQ80331_INTA -#define INTB IRQ_IQ80331_INTB -#define INTC IRQ_IQ80331_INTC -#define INTD IRQ_IQ80331_INTD - -//#define INTE IRQ_IQ80331_I82544 - -static inline int __init -iq80331_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {INTB, INTC, INTD, INTA}, /* PCI-X Slot */ - {INTC, INTC, INTC, INTC}, /* GigE */ - }; - - BUG_ON(pin < 1 || pin > 4); - - return PCI_IRQ_TABLE_LOOKUP(1, 7); -} - -static int iq80331_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if(nr != 0) - return 0; - - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP331_PCI_LOWER_IO_VA; - res[0].end = IOP331_PCI_UPPER_IO_VA; - res[0].name = "IQ80331 PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - - res[1].start = IOP331_PCI_LOWER_MEM_PA; - res[1].end = IOP331_PCI_UPPER_MEM_PA; - res[1].name = "IQ80331 PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - - request_resource(&ioport_resource, &res[0]); - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP331_PCI_MEM_OFFSET; - sys->io_offset = IOP331_PCI_IO_OFFSET; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -static void iq80331_preinit(void) -{ - iop331_init(); -} - -static struct hw_pci iq80331_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iq80331_setup, - .scan = iop331_scan_bus, - .preinit = iq80331_preinit, - .map_irq = iq80331_map_irq -}; - -static int __init iq80331_pci_init(void) -{ - if (machine_is_iq80331()) - pci_common_init(&iq80331_pci); - return 0; -} - -subsys_initcall(iq80331_pci_init); - - - - diff --git a/arch/arm/mach-iop3xx/iq80332-mm.c b/arch/arm/mach-iop3xx/iq80332-mm.c deleted file mode 100644 index 2feaf7591f5..00000000000 --- a/arch/arm/mach-iop3xx/iq80332-mm.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/arm/mach-iop3xx/mm.c - * - * Low level memory initialization for iq80332 platform - * - * Author: Dave Jiang <dave.jiang@intel.com> - * Copyright (C) 2004 Intel Corp. - * - * 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. - * - */ - -#include <linux/mm.h> -#include <linux/init.h> - -#include <asm/io.h> -#include <asm/pgtable.h> -#include <asm/page.h> - -#include <asm/mach/map.h> - - -/* - * IQ80332 specific IO mappings - * - * We use RedBoot's setup for the onboard devices. - */ - -void __init iq80332_map_io(void) -{ - iop331_map_io(); -} diff --git a/arch/arm/mach-iop3xx/iq80332-pci.c b/arch/arm/mach-iop3xx/iq80332-pci.c deleted file mode 100644 index afc0676318e..00000000000 --- a/arch/arm/mach-iop3xx/iq80332-pci.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * arch/arm/mach-iop3xx/iq80332-pci.c - * - * PCI support for the Intel IQ80332 reference board - * - * Author: Dave Jiang <dave.jiang@intel.com> - * Copyright (C) 2004 Intel Corp. - * - * 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/pci.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include <asm/hardware.h> -#include <asm/irq.h> -#include <asm/mach/pci.h> -#include <asm/mach-types.h> - -/* - * The following macro is used to lookup irqs in a standard table - * format for those systems that do not already have PCI - * interrupts properly routed. We assume 1 <= pin <= 4 - */ -#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ -({ int _ctl_ = -1; \ - unsigned int _idsel = idsel - minid; \ - if (_idsel <= maxid) \ - _ctl_ = pci_irq_table[_idsel][pin-1]; \ - _ctl_; }) - -#define INTA IRQ_IQ80332_INTA -#define INTB IRQ_IQ80332_INTB -#define INTC IRQ_IQ80332_INTC -#define INTD IRQ_IQ80332_INTD - -//#define INTE IRQ_IQ80332_I82544 - -static inline int __init -iq80332_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) -{ - static int pci_irq_table[][8] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {-1, -1, -1, -1}, - {-1, -1, -1, -1}, - {-1, -1, -1, -1}, - {INTA, INTB, INTC, INTD}, /* PCI-X Slot */ - {-1, -1, -1, -1}, - {INTC, INTC, INTC, INTC}, /* GigE */ - {-1, -1, -1, -1}, - {-1, -1, -1, -1}, - }; - - BUG_ON(pin < 1 || pin > 4); - - return PCI_IRQ_TABLE_LOOKUP(1, 7); -} - -static int iq80332_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if(nr != 0) - return 0; - - res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP331_PCI_LOWER_IO_VA; - res[0].end = IOP331_PCI_UPPER_IO_VA; - res[0].name = "IQ80332 PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - - res[1].start = IOP331_PCI_LOWER_MEM_PA; - res[1].end = IOP331_PCI_UPPER_MEM_PA; - res[1].name = "IQ80332 PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - - request_resource(&ioport_resource, &res[0]); - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP331_PCI_MEM_OFFSET; - sys->io_offset = IOP331_PCI_IO_OFFSET; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -static void iq80332_preinit(void) -{ - iop331_init(); -} - -static struct hw_pci iq80332_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iq80332_setup, - .scan = iop331_scan_bus, - .preinit = iq80332_preinit, - .map_irq = iq80332_map_irq -}; - -static int __init iq80332_pci_init(void) -{ - if (machine_is_iq80332()) - pci_common_init(&iq80332_pci); - return 0; -} - -subsys_initcall(iq80332_pci_init); - - - - diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 7c25dbd5a18..35dd8b3824b 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -26,6 +26,7 @@ #include <linux/bitops.h> #include <linux/time.h> #include <linux/timex.h> +#include <linux/clocksource.h> #include <asm/hardware.h> #include <asm/uaccess.h> @@ -255,16 +256,6 @@ static unsigned volatile last_jiffy_time; #define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) -/* IRQs are disabled before entering here from do_gettimeofday() */ -static unsigned long ixp4xx_gettimeoffset(void) -{ - u32 elapsed; - - elapsed = *IXP4XX_OSTS - last_jiffy_time; - - return elapsed / CLOCK_TICKS_PER_USEC; -} - static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); @@ -309,7 +300,6 @@ static void __init ixp4xx_timer_init(void) struct sys_timer ixp4xx_timer = { .init = ixp4xx_timer_init, - .offset = ixp4xx_gettimeoffset, }; static struct resource ixp46x_i2c_resources[] = { @@ -365,3 +355,29 @@ void __init ixp4xx_sys_init(void) ixp4xx_exp_bus_size >> 20); } +cycle_t ixp4xx_get_cycles(void) +{ + return *IXP4XX_OSTS; +} + +static struct clocksource clocksource_ixp4xx = { + .name = "OSTS", + .rating = 200, + .read = ixp4xx_get_cycles, + .mask = CLOCKSOURCE_MASK(32), + .shift = 20, + .is_continuous = 1, +}; + +unsigned long ixp4xx_timer_freq = FREQ; +static int __init ixp4xx_clocksource_init(void) +{ + clocksource_ixp4xx.mult = + clocksource_hz2mult(ixp4xx_timer_freq, + clocksource_ixp4xx.shift); + clocksource_register(&clocksource_ixp4xx); + + return 0; +} + +device_initcall(ixp4xx_clocksource_init); diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index 749a337494d..162c266e5f8 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -159,6 +159,8 @@ static void nslu2_power_off(void) static void __init nslu2_init(void) { + ixp4xx_timer_freq = NSLU2_FREQ; + ixp4xx_sys_init(); nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index f1958e882e8..638490e62d5 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -20,6 +20,7 @@ #include <linux/clk.h> #include <asm/io.h> +#include <asm/mach-types.h> #include <asm/arch/cpu.h> #include <asm/arch/usb.h> @@ -586,77 +587,53 @@ static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) *-------------------------------------------------------------------------*/ #ifdef CONFIG_OMAP_RESET_CLOCKS -/* - * Resets some clocks that may be left on from bootloader, - * but leaves serial clocks on. See also omap_late_clk_reset(). - */ -static inline void omap1_early_clk_reset(void) -{ - //omap_writel(0x3 << 29, MOD_CONF_CTRL_0); -} -static int __init omap1_late_clk_reset(void) +static void __init omap1_clk_disable_unused(struct clk *clk) { - /* Turn off all unused clocks */ - struct clk *p; __u32 regval32; - /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ - regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); - omap_writew(regval32, SOFT_REQ_REG); - omap_writew(0, SOFT_REQ_REG2); - - list_for_each_entry(p, &clocks, node) { - if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) || - p->enable_reg == 0) - continue; - - /* Clocks in the DSP domain need api_ck. Just assume bootloader - * has not enabled any DSP clocks */ - if ((u32)p->enable_reg == DSP_IDLECT2) { - printk(KERN_INFO "Skipping reset check for DSP domain " - "clock \"%s\"\n", p->name); - continue; - } + /* Clocks in the DSP domain need api_ck. Just assume bootloader + * has not enabled any DSP clocks */ + if ((u32)clk->enable_reg == DSP_IDLECT2) { + printk(KERN_INFO "Skipping reset check for DSP domain " + "clock \"%s\"\n", clk->name); + return; + } - /* Is the clock already disabled? */ - if (p->flags & ENABLE_REG_32BIT) { - if (p->flags & VIRTUAL_IO_ADDRESS) - regval32 = __raw_readl(p->enable_reg); - else - regval32 = omap_readl(p->enable_reg); - } else { - if (p->flags & VIRTUAL_IO_ADDRESS) - regval32 = __raw_readw(p->enable_reg); + /* Is the clock already disabled? */ + if (clk->flags & ENABLE_REG_32BIT) { + if (clk->flags & VIRTUAL_IO_ADDRESS) + regval32 = __raw_readl(clk->enable_reg); else - regval32 = omap_readw(p->enable_reg); - } - - if ((regval32 & (1 << p->enable_bit)) == 0) - continue; + regval32 = omap_readl(clk->enable_reg); + } else { + if (clk->flags & VIRTUAL_IO_ADDRESS) + regval32 = __raw_readw(clk->enable_reg); + else + regval32 = omap_readw(clk->enable_reg); + } - /* FIXME: This clock seems to be necessary but no-one - * has asked for its activation. */ - if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera - || p == &ck_dpll1out.clk // FIX: SoSSI, SSR - || p == &arm_gpio_ck // FIX: GPIO code for 1510 - ) { - printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", - p->name); - continue; - } + if ((regval32 & (1 << clk->enable_bit)) == 0) + return; - printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); - p->disable(p); - printk(" done\n"); + /* FIXME: This clock seems to be necessary but no-one + * has asked for its activation. */ + if (clk == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera + || clk == &ck_dpll1out.clk // FIX: SoSSI, SSR + || clk == &arm_gpio_ck // FIX: GPIO code for 1510 + ) { + printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", + clk->name); + return; } - return 0; + printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); + clk->disable(clk); + printk(" done\n"); } -late_initcall(omap1_late_clk_reset); #else -#define omap1_early_clk_reset() {} +#define omap1_clk_disable_unused NULL #endif static struct clk_functions omap1_clk_functions = { @@ -664,6 +641,7 @@ static struct clk_functions omap1_clk_functions = { .clk_disable = omap1_clk_disable, .clk_round_rate = omap1_clk_round_rate, .clk_set_rate = omap1_clk_set_rate, + .clk_disable_unused = omap1_clk_disable_unused, }; int __init omap1_clk_init(void) @@ -671,8 +649,13 @@ int __init omap1_clk_init(void) struct clk ** clkp; const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ + u32 reg; + + /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ + reg = omap_readw(SOFT_REQ_REG) & (1 << 4); + omap_writew(reg, SOFT_REQ_REG); + omap_writew(0, SOFT_REQ_REG2); - omap1_early_clk_reset(); clk_init(&omap1_clk_functions); /* By default all idlect1 clocks are allowed to idle */ @@ -772,6 +755,12 @@ int __init omap1_clk_init(void) omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); #endif + /* Amstrad Delta wants BCLK high when inactive */ + if (machine_is_ams_delta()) + omap_writel(omap_readl(ULPD_CLOCK_CTRL) | + (1 << SDW_MCLK_INV_BIT), + ULPD_CLOCK_CTRL); + /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ /* (on 730, bit 13 must not be cleared) */ if (cpu_is_omap730()) diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index b7c68819c4e..f7df00205c4 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h @@ -89,6 +89,7 @@ struct arm_idlect1_clk { #define EN_DSPTIMCK 5 /* Various register defines for clock controls scattered around OMAP chip */ +#define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */ #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ @@ -741,6 +742,18 @@ static struct clk i2c_fck = { .disable = &omap1_clk_disable_generic, }; +static struct clk i2c_ick = { + .name = "i2c_ick", + .id = 1, + .flags = CLOCK_IN_OMAP16XX | + VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT | + ALWAYS_ENABLED, + .parent = &armper_ck.clk, + .recalc = &followparent_recalc, + .enable = &omap1_clk_enable_generic, + .disable = &omap1_clk_disable_generic, +}; + static struct clk * onchip_clks[] = { /* non-ULPD clocks */ &ck_ref, @@ -790,6 +803,7 @@ static struct clk * onchip_clks[] = { /* Virtual clocks */ &virtual_ck_mpu, &i2c_fck, + &i2c_ick, }; #endif diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index fa74ef7af15..5432335bc49 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c @@ -199,6 +199,17 @@ MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1) MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) +/* OMAP-1610 SPI */ +MUX_CFG("U19_1610_SPIF_SCK", 7, 21, 6, 1, 15, 0, 1, 1, 1) +MUX_CFG("U18_1610_SPIF_DIN", 8, 0, 6, 1, 18, 1, 1, 0, 1) +MUX_CFG("P20_1610_SPIF_DIN", 6, 27, 4, 1, 7, 1, 1, 0, 1) +MUX_CFG("W21_1610_SPIF_DOUT", 8, 3, 6, 1, 19, 0, 1, 0, 1) +MUX_CFG("R18_1610_SPIF_DOUT", 7, 9, 3, 1, 11, 0, 1, 0, 1) +MUX_CFG("N14_1610_SPIF_CS0", 8, 9, 6, 1, 21, 0, 1, 1, 1) +MUX_CFG("N15_1610_SPIF_CS1", 7, 18, 6, 1, 14, 0, 1, 1, 1) +MUX_CFG("T19_1610_SPIF_CS2", 7, 15, 4, 1, 13, 0, 1, 1, 1) +MUX_CFG("P15_1610_SPIF_CS3", 8, 12, 3, 1, 22, 0, 1, 1, 1) + /* OMAP-1610 Flash */ MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1) MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1) diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 7993b7bae2b..2db6b732b08 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -166,8 +166,8 @@ static struct omap_uart_config apollon_uart_config __initdata = { static struct omap_mmc_config apollon_mmc_config __initdata = { .mmc [0] = { - .enabled = 0, - .wire4 = 0, + .enabled = 1, + .wire4 = 1, .wp_pin = -1, .power_pin = -1, .switch_pin = -1, @@ -257,6 +257,9 @@ static void __init omap_apollon_init(void) /* REVISIT: where's the correct place */ omap_cfg_reg(W19_24XX_SYS_NIRQ); + /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */ + CONTROL_DEVCONF |= (1 << 24); + /* * Make sure the serial ports are muxed on at this point. * You have to mux them off in device drivers later on diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index d1b648a4efb..0de201c3d50 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -32,10 +32,14 @@ #include "memory.h" #include "clock.h" +#undef DEBUG + //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ static struct prcm_config *curr_prcm_set; static u32 curr_perf_level = PRCM_FULL_SPEED; +static struct clk *vclk; +static struct clk *sclk; /*------------------------------------------------------------------------- * Omap2 specific clock functions @@ -79,6 +83,14 @@ static void omap2_propagate_rate(struct clk * clk) propagate_rate(clk); } +static void omap2_set_osc_ck(int enable) +{ + if (enable) + PRCM_CLKSRC_CTRL &= ~(0x3 << 3); + else + PRCM_CLKSRC_CTRL |= 0x3 << 3; +} + /* Enable an APLL if off */ static void omap2_clk_fixed_enable(struct clk *clk) { @@ -101,12 +113,54 @@ static void omap2_clk_fixed_enable(struct clk *clk) else if (clk == &apll54_ck) cval = (1 << 6); - while (!CM_IDLEST_CKGEN & cval) { /* Wait for lock */ + while (!(CM_IDLEST_CKGEN & cval)) { /* Wait for lock */ ++i; udelay(1); - if (i == 100000) + if (i == 100000) { + printk(KERN_ERR "Clock %s didn't lock\n", clk->name); + break; + } + } +} + +static void omap2_clk_wait_ready(struct clk *clk) +{ + unsigned long reg, other_reg, st_reg; + u32 bit; + int i; + + reg = (unsigned long) clk->enable_reg; + if (reg == (unsigned long) &CM_FCLKEN1_CORE || + reg == (unsigned long) &CM_FCLKEN2_CORE) + other_reg = (reg & ~0xf0) | 0x10; + else if (reg == (unsigned long) &CM_ICLKEN1_CORE || + reg == (unsigned long) &CM_ICLKEN2_CORE) + other_reg = (reg & ~0xf0) | 0x00; + else + return; + + /* No check for DSS or cam clocks */ + if ((reg & 0x0f) == 0) { + if (clk->enable_bit <= 1 || clk->enable_bit == 31) + return; + } + + /* Check if both functional and interface clocks + * are running. */ + bit = 1 << clk->enable_bit; + if (!(__raw_readl(other_reg) & bit)) + return; + st_reg = (other_reg & ~0xf0) | 0x20; + i = 0; + while (!(__raw_readl(st_reg) & bit)) { + i++; + if (i == 100000) { + printk(KERN_ERR "Timeout enabling clock %s\n", clk->name); break; + } } + if (i) + pr_debug("Clock %s stable after %d loops\n", clk->name, i); } /* Enables clock without considering parent dependencies or use count @@ -119,6 +173,11 @@ static int _omap2_clk_enable(struct clk * clk) if (clk->flags & ALWAYS_ENABLED) return 0; + if (unlikely(clk == &osc_ck)) { + omap2_set_osc_ck(1); + return 0; + } + if (unlikely(clk->enable_reg == 0)) { printk(KERN_ERR "clock.c: Enable for %s without enable code\n", clk->name); @@ -133,6 +192,9 @@ static int _omap2_clk_enable(struct clk * clk) regval32 = __raw_readl(clk->enable_reg); regval32 |= (1 << clk->enable_bit); __raw_writel(regval32, clk->enable_reg); + wmb(); + + omap2_clk_wait_ready(clk); return 0; } @@ -155,6 +217,11 @@ static void _omap2_clk_disable(struct clk *clk) { u32 regval32; + if (unlikely(clk == &osc_ck)) { + omap2_set_osc_ck(0); + return; + } + if (clk->enable_reg == 0) return; @@ -166,6 +233,7 @@ static void _omap2_clk_disable(struct clk *clk) regval32 = __raw_readl(clk->enable_reg); regval32 &= ~(1 << clk->enable_bit); __raw_writel(regval32, clk->enable_reg); + wmb(); } static int omap2_clk_enable(struct clk *clk) @@ -695,12 +763,14 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate) reg_val = __raw_readl(reg); reg_val &= ~(field_mask << div_off); reg_val |= (field_val << div_off); - __raw_writel(reg_val, reg); + wmb(); clk->rate = clk->parent->rate / field_val; - if (clk->flags & DELAYED_APP) + if (clk->flags & DELAYED_APP) { __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); + wmb(); + } ret = 0; } else if (clk->set_rate != 0) ret = clk->set_rate(clk, rate); @@ -836,10 +906,12 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) reg_val = __raw_readl(reg) & ~(field_mask << src_off); reg_val |= (field_val << src_off); __raw_writel(reg_val, reg); + wmb(); - if (clk->flags & DELAYED_APP) + if (clk->flags & DELAYED_APP) { __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); - + wmb(); + } if (clk->usecount > 0) _omap2_clk_enable(clk); @@ -953,12 +1025,29 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate) * Omap2 clock reset and init functions *-------------------------------------------------------------------------*/ +#ifdef CONFIG_OMAP_RESET_CLOCKS +static void __init omap2_clk_disable_unused(struct clk *clk) +{ + u32 regval32; + + regval32 = __raw_readl(clk->enable_reg); + if ((regval32 & (1 << clk->enable_bit)) == 0) + return; + + printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); + _omap2_clk_disable(clk); +} +#else +#define omap2_clk_disable_unused NULL +#endif + static struct clk_functions omap2_clk_functions = { .clk_enable = omap2_clk_enable, .clk_disable = omap2_clk_disable, .clk_round_rate = omap2_clk_round_rate, .clk_set_rate = omap2_clk_set_rate, .clk_set_parent = omap2_clk_set_parent, + .clk_disable_unused = omap2_clk_disable_unused, }; static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) @@ -984,27 +1073,19 @@ static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) sys->rate = sclk; } -#ifdef CONFIG_OMAP_RESET_CLOCKS -static void __init omap2_disable_unused_clocks(void) +/* + * Set clocks for bypass mode for reboot to work. + */ +void omap2_clk_prepare_for_reboot(void) { - struct clk *ck; - u32 regval32; + u32 rate; - list_for_each_entry(ck, &clocks, node) { - if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || - ck->enable_reg == 0) - continue; - - regval32 = __raw_readl(ck->enable_reg); - if ((regval32 & (1 << ck->enable_bit)) == 0) - continue; + if (vclk == NULL || sclk == NULL) + return; - printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); - _omap2_clk_disable(ck); - } + rate = clk_get_rate(sclk); + clk_set_rate(vclk, rate); } -late_initcall(omap2_disable_unused_clocks); -#endif /* * Switch the MPU rate if specified on cmdline. @@ -1077,8 +1158,27 @@ int __init omap2_clk_init(void) */ clk_enable(&sync_32k_ick); clk_enable(&omapctrl_ick); + + /* Force the APLLs active during bootup to avoid disabling and + * enabling them unnecessarily. */ + clk_enable(&apll96_ck); + clk_enable(&apll54_ck); + if (cpu_is_omap2430()) clk_enable(&sdrc_ick); + /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */ + vclk = clk_get(NULL, "virt_prcm_set"); + sclk = clk_get(NULL, "sys_ck"); + + return 0; +} + +static int __init omap2_disable_aplls(void) +{ + clk_disable(&apll96_ck); + clk_disable(&apll54_ck); + return 0; } +late_initcall(omap2_disable_aplls); diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 2781dfbc516..8816f5a33a2 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -560,7 +560,7 @@ static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ .name = "osc_ck", .rate = 26000000, /* fixed up in clock init */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, + RATE_FIXED | RATE_PROPAGATES, }; /* With out modem likely 12MHz, with modem likely 13MHz */ @@ -1368,7 +1368,8 @@ static struct clk mcbsp5_fck = { }; static struct clk mcspi1_ick = { - .name = "mcspi1_ick", + .name = "mcspi_ick", + .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1377,7 +1378,8 @@ static struct clk mcspi1_ick = { }; static struct clk mcspi1_fck = { - .name = "mcspi1_fck", + .name = "mcspi_fck", + .id = 1, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1386,7 +1388,8 @@ static struct clk mcspi1_fck = { }; static struct clk mcspi2_ick = { - .name = "mcspi2_ick", + .name = "mcspi_ick", + .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1395,7 +1398,8 @@ static struct clk mcspi2_ick = { }; static struct clk mcspi2_fck = { - .name = "mcspi2_fck", + .name = "mcspi_fck", + .id = 2, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1404,7 +1408,8 @@ static struct clk mcspi2_fck = { }; static struct clk mcspi3_ick = { - .name = "mcspi3_ick", + .name = "mcspi_ick", + .id = 3, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, @@ -1413,7 +1418,8 @@ static struct clk mcspi3_ick = { }; static struct clk mcspi3_fck = { - .name = "mcspi3_fck", + .name = "mcspi_fck", + .id = 3, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index c7a48f921fe..f4f04d87df3 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -13,6 +13,8 @@ #include <linux/init.h> #include <linux/err.h> #include <linux/clk.h> +#include <linux/ioport.h> +#include <linux/spinlock.h> #include <asm/io.h> #include <asm/arch/gpmc.h> @@ -41,6 +43,19 @@ #define GPMC_CS0 0x60 #define GPMC_CS_SIZE 0x30 +#define GPMC_CS_NUM 8 +#define GPMC_MEM_START 0x00000000 +#define GPMC_MEM_END 0x3FFFFFFF +#define BOOT_ROM_SPACE 0x100000 /* 1MB */ + +#define GPMC_CHUNK_SHIFT 24 /* 16 MB */ +#define GPMC_SECTION_SHIFT 28 /* 128 MB */ + +static struct resource gpmc_mem_root; +static struct resource gpmc_cs_mem[GPMC_CS_NUM]; +static spinlock_t gpmc_mem_lock = SPIN_LOCK_UNLOCKED; +static unsigned gpmc_cs_map; + static void __iomem *gpmc_base = (void __iomem *) IO_ADDRESS(GPMC_BASE); static void __iomem *gpmc_cs_base = @@ -187,9 +202,168 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) return 0; } -unsigned long gpmc_cs_get_base_addr(int cs) +static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) +{ + u32 l; + u32 mask; + + mask = (1 << GPMC_SECTION_SHIFT) - size; + l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); + l &= ~0x3f; + l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; + l &= ~(0x0f << 8); + l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; + l |= 1 << 6; /* CSVALID */ + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); +} + +static void gpmc_cs_disable_mem(int cs) +{ + u32 l; + + l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); + l &= ~(1 << 6); /* CSVALID */ + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); +} + +static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size) +{ + u32 l; + u32 mask; + + l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); + *base = (l & 0x3f) << GPMC_CHUNK_SHIFT; + mask = (l >> 8) & 0x0f; + *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT); +} + +static int gpmc_cs_mem_enabled(int cs) +{ + u32 l; + + l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); + return l & (1 << 6); +} + +static void gpmc_cs_set_reserved(int cs, int reserved) { - return (gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7) & 0x1f) << 24; + gpmc_cs_map &= ~(1 << cs); + gpmc_cs_map |= (reserved ? 1 : 0) << cs; +} + +static int gpmc_cs_reserved(int cs) +{ + return gpmc_cs_map & (1 << cs); +} + +static unsigned long gpmc_mem_align(unsigned long size) +{ + int order; + + size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1); + order = GPMC_CHUNK_SHIFT - 1; + do { + size >>= 1; + order++; + } while (size); + size = 1 << order; + return size; +} + +static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size) +{ + struct resource *res = &gpmc_cs_mem[cs]; + int r; + + size = gpmc_mem_align(size); + spin_lock(&gpmc_mem_lock); + res->start = base; + res->end = base + size - 1; + r = request_resource(&gpmc_mem_root, res); + spin_unlock(&gpmc_mem_lock); + + return r; +} + +int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) +{ + struct resource *res = &gpmc_cs_mem[cs]; + int r = -1; + + if (cs > GPMC_CS_NUM) + return -ENODEV; + + size = gpmc_mem_align(size); + if (size > (1 << GPMC_SECTION_SHIFT)) + return -ENOMEM; + + spin_lock(&gpmc_mem_lock); + if (gpmc_cs_reserved(cs)) { + r = -EBUSY; + goto out; + } + if (gpmc_cs_mem_enabled(cs)) + r = adjust_resource(res, res->start & ~(size - 1), size); + if (r < 0) + r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0, + size, NULL, NULL); + if (r < 0) + goto out; + + gpmc_cs_enable_mem(cs, res->start, res->end - res->start + 1); + *base = res->start; + gpmc_cs_set_reserved(cs, 1); +out: + spin_unlock(&gpmc_mem_lock); + return r; +} + +void gpmc_cs_free(int cs) +{ + spin_lock(&gpmc_mem_lock); + if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) { + printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); + BUG(); + spin_unlock(&gpmc_mem_lock); + return; + } + gpmc_cs_disable_mem(cs); + release_resource(&gpmc_cs_mem[cs]); + gpmc_cs_set_reserved(cs, 0); + spin_unlock(&gpmc_mem_lock); +} + +void __init gpmc_mem_init(void) +{ + int cs; + unsigned long boot_rom_space = 0; + + if (cpu_is_omap242x()) { + u32 l; + l = omap_readl(OMAP242X_CONTROL_STATUS); + /* In case of internal boot the 1st MB is redirected to the + * boot ROM memory space. + */ + if (l & (1 << 3)) + boot_rom_space = BOOT_ROM_SPACE; + } else + /* We assume internal boot if the mode can't be + * determined. + */ + boot_rom_space = BOOT_ROM_SPACE; + gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; + gpmc_mem_root.end = GPMC_MEM_END; + + /* Reserve all regions that has been set up by bootloader */ + for (cs = 0; cs < GPMC_CS_NUM; cs++) { + u32 base, size; + + if (!gpmc_cs_mem_enabled(cs)) + continue; + gpmc_cs_get_memconf(cs, &base, &size); + if (gpmc_cs_insert_mem(cs, base, size) < 0) + BUG(); + } } void __init gpmc_init(void) @@ -206,4 +380,6 @@ void __init gpmc_init(void) l &= 0x03 << 3; l |= (0x02 << 3) | (1 << 0); gpmc_write_reg(GPMC_SYSCONFIG, l); + + gpmc_mem_init(); } diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index dfc3b35cc1f..1ed2fff4691 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -41,18 +41,6 @@ static struct omap_irq_bank { .nr_irqs = 96, }, { /* XXX: DSP INTC */ - -#if 0 - /* - * Commented out for now until we fix the IVA clocking - */ -#ifdef CONFIG_ARCH_OMAP2420 - }, { - /* IVA INTC (2420 only) */ - .base_reg = OMAP24XX_IVA_INTC_BASE, - .nr_irqs = 16, /* Actually 32, but only 16 are used */ -#endif -#endif } }; diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 60ef084faff..f538d0fdb13 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -104,6 +104,20 @@ MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1) MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) +/* MMC/SDIO */ +MUX_CFG_24XX("G19_24XX_MMC_CLKO", 0x0f3, 0, 0, 0, 1) +MUX_CFG_24XX("H18_24XX_MMC_CMD", 0x0f4, 0, 0, 0, 1) +MUX_CFG_24XX("F20_24XX_MMC_DAT0", 0x0f5, 0, 0, 0, 1) +MUX_CFG_24XX("H14_24XX_MMC_DAT1", 0x0f6, 0, 0, 0, 1) +MUX_CFG_24XX("E19_24XX_MMC_DAT2", 0x0f7, 0, 0, 0, 1) +MUX_CFG_24XX("D19_24XX_MMC_DAT3", 0x0f8, 0, 0, 0, 1) +MUX_CFG_24XX("F19_24XX_MMC_DAT_DIR0", 0x0f9, 0, 0, 0, 1) +MUX_CFG_24XX("E20_24XX_MMC_DAT_DIR1", 0x0fa, 0, 0, 0, 1) +MUX_CFG_24XX("F18_24XX_MMC_DAT_DIR2", 0x0fb, 0, 0, 0, 1) +MUX_CFG_24XX("E18_24XX_MMC_DAT_DIR3", 0x0fc, 0, 0, 0, 1) +MUX_CFG_24XX("G18_24XX_MMC_CMD_DIR", 0x0fd, 0, 0, 0, 1) +MUX_CFG_24XX("H15_24XX_MMC_CLKI", 0x0fe, 0, 0, 0, 1) + /* Keypad GPIO*/ MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index c2bf57ef682..90f530540c6 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -19,6 +19,8 @@ #include "prcm-regs.h" +extern void omap2_clk_prepare_for_reboot(void); + u32 omap_prcm_get_reset_sources(void) { return RM_RSTST_WKUP & 0x7f; @@ -28,12 +30,6 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources); /* Resets clock rates and reboots the system. Only called from system.h */ void omap_prcm_arch_reset(char mode) { - u32 rate; - struct clk *vclk, *sclk; - - vclk = clk_get(NULL, "virt_prcm_set"); - sclk = clk_get(NULL, "sys_ck"); - rate = clk_get_rate(sclk); - clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */ + omap2_clk_prepare_for_reboot(); RM_RSTCTRL_WKUP |= 2; } diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index bbd138be6a7..df37594c30f 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -2,6 +2,13 @@ if ARCH_S3C2410 menu "S3C24XX Implementations" +config MACH_AML_M5900 + bool "AML M5900 Series" + select CPU_S3C2410 + help + Say Y here if you are using the American Microsystems M5900 Series + <http://www.amltd.com> + config MACH_ANUBIS bool "Simtec Electronics ANUBIS" select CPU_S3C2440 @@ -126,6 +133,12 @@ config MACH_NEXCODER_2440 help Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board +config MACH_VSTMS + bool "VMSTMS" + select CPU_S3C2412 + help + Say Y here if you are using an VSTMS board + endmenu config S3C2410_CLOCK @@ -133,10 +146,24 @@ config S3C2410_CLOCK help Clock code for the S3C2410, and similar processors +config S3C2410_PM + bool + depends on CONFIG_PM + help + Power Management code common to S3C2410 and better + +config CPU_S3C2410_DMA + bool + depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442) + default y if CPU_S3C2410 || CPU_S3C2442 + help + DMA device selection for S3C2410 and compatible CPUs + config CPU_S3C2410 bool depends on ARCH_S3C2410 select S3C2410_CLOCK + select S3C2410_PM help Support for S3C2410 and S3C2410A family from the S3C24XX line of Samsung Mobile CPUs. @@ -149,6 +176,13 @@ config CPU_S3C2412_ONLY !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412 default y if CPU_S3C2412 +config S3C2412_PM + bool + default y if PM + depends on CPU_S3C2412 + help + Internal config node to apply S3C2412 power management + config CPU_S3C2412 bool depends on ARCH_S3C2410 @@ -165,6 +199,7 @@ config CPU_S3C2440 bool depends on ARCH_S3C2410 select S3C2410_CLOCK + select S3C2410_PM select CPU_S3C244X help Support for S3C2440 Samsung Mobile CPU based systems. @@ -173,6 +208,7 @@ config CPU_S3C2442 bool depends on ARCH_S3C2420 select S3C2410_CLOCK + select S3C2410_PM select CPU_S3C244X help Support for S3C2442 Samsung Mobile CPU based systems. @@ -256,7 +292,7 @@ config S3C2410_PM_CHECK_CHUNKSIZE config PM_SIMTEC bool - depends on PM && (ARCH_BAST || MACH_VR1000) + depends on PM && (ARCH_BAST || MACH_VR1000 || MACH_AML_M5900) default y config S3C2410_LOWLEVEL_UART_PORT diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 0eadec91621..d66013365b6 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -9,6 +9,8 @@ obj-y := cpu.o irq.o time.o gpio.o clock.o devs.o obj-m := obj-n := obj- := +obj-dma-y := +obj-dma-n := # DMA obj-$(CONFIG_S3C2410_DMA) += dma.o @@ -20,6 +22,10 @@ obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o obj-$(CONFIG_CPU_S3C2410) += s3c2410.o obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o +obj-$(CONFIG_CPU_S3C2410) += s3c2410-irq.o + +obj-$(CONFIG_S3C2410_PM) += s3c2410-pm.o s3c2410-sleep.o +obj-$(CONFIG_CPU_S3C2410_DMA) += s3c2410-dma.o # Power Management support @@ -30,6 +36,9 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o obj-$(CONFIG_CPU_S3C2412) += s3c2412.o obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o +obj-dma-$(CONFIG_CPU_S3C2412) += s3c2412-dma.o + +obj-$(CONFIG_S3C2412_PM) += s3c2412-pm.o # # S3C244X support @@ -47,6 +56,7 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o +obj-dma-$(CONFIG_CPU_S3C2440) += s3c2440-dma.o # S3C2442 support @@ -57,8 +67,13 @@ obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o +# merge in dma objects + +obj-y += $(obj-dma-y) + # machine specific support +obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o @@ -71,5 +86,6 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o obj-$(CONFIG_MACH_OTOM) += mach-otom.o obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o +obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o obj-$(CONFIG_MACH_SMDK) += common-smdk.o
\ No newline at end of file diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c index def4441d244..440e9aa0211 100644 --- a/arch/arm/mach-s3c2410/bast-irq.c +++ b/arch/arm/mach-s3c2410/bast-irq.c @@ -18,10 +18,6 @@ * 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 - * - * Modifications: - * 08-Jan-2003 BJD Moved from central IRQ code - * 21-Aug-2005 BJD Fixed missing code and compile errors */ diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c index 1c3c6adae6c..9d4899eddf1 100644 --- a/arch/arm/mach-s3c2410/cpu.c +++ b/arch/arm/mach-s3c2410/cpu.c @@ -124,6 +124,15 @@ static struct cpu_table cpu_ids[] __initdata = { .init = s3c2412_init, .name = name_s3c2412, }, + { /* a newer version of the s3c2412 */ + .idcode = 0x32412003, + .idmask = 0xffffffff, + .map_io = s3c2412_map_io, + .init_clocks = s3c2412_init_clocks, + .init_uarts = s3c2412_init_uarts, + .init = s3c2412_init, + .name = name_s3c2412, + }, { .idcode = 0x0, /* S3C2400 doesn't have an idcode */ .idmask = 0xffffffff, diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h index 726e2eaf879..14fb0bade71 100644 --- a/arch/arm/mach-s3c2410/devs.h +++ b/arch/arm/mach-s3c2410/devs.h @@ -8,11 +8,6 @@ * 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. - * - * Modifications: - * 18-Aug-2004 BJD Created initial version - * 27-Aug-2004 BJD Added timers 0 through 3 - * 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv */ #include <linux/platform_device.h> diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index cc92a7b2db8..d264bbbd8be 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -1,35 +1,16 @@ -/* linux/arch/arm/mach-bast/dma.c +/* linux/arch/arm/mach-s3c2410/dma.c * - * (c) 2003-2005 Simtec Electronics + * (c) 2003-2005,2006 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * * S3C2410 DMA core * - * http://www.simtec.co.uk/products/EB2410ITX/ + * http://armlinux.simtec.co.uk/ * * 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. - * - * Changelog: - * 27-Feb-2005 BJD Added kmem cache for dma descriptors - * 18-Nov-2004 BJD Removed error for loading onto stopped channel - * 10-Nov-2004 BJD Ensure all external symbols exported for modules - * 10-Nov-2004 BJD Use sys_device and sysdev_class for power management - * 08-Aug-2004 BJD Apply rmk's suggestions - * 21-Jul-2004 BJD Ported to linux 2.6 - * 12-Jul-2004 BJD Finished re-write and change of API - * 06-Jul-2004 BJD Rewrote dma code to try and cope with various problems - * 23-May-2003 BJD Created file - * 19-Aug-2003 BJD Cleanup, header fix, added URL - * - * This file is based on the Sangwook Lee/Samsung patches, re-written due - * to various ommisions from the code (such as flexible dma configuration) - * for use with the BAST system board. - * - * The re-write is pretty much complete, and should be good enough for any - * possible DMA function - */ +*/ #ifdef CONFIG_S3C2410_DMA_DEBUG @@ -55,10 +36,14 @@ #include <asm/mach/dma.h> #include <asm/arch/map.h> +#include "dma.h" + /* io map for dma */ static void __iomem *dma_base; static kmem_cache_t *dma_kmem; +struct s3c24xx_dma_selection dma_sel; + /* dma channel state information */ struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; @@ -79,7 +64,6 @@ dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val) pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg); writel(val, dma_regaddr(chan, reg)); } - #endif #define dma_rdreg(chan, reg) readl((chan)->regs + (reg)) @@ -151,12 +135,20 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan) #define dbg_showchan(chan) do { } while(0) #endif /* CONFIG_S3C2410_DMA_DEBUG */ -#define check_channel(chan) \ - do { if ((chan) >= S3C2410_DMA_CHANNELS) { \ - printk(KERN_ERR "%s: invalid channel %d\n", __FUNCTION__, (chan)); \ - return -EINVAL; \ - } } while(0) +static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX]; +/* lookup_dma_channel + * + * change the dma channel number given into a real dma channel id +*/ + +static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel) +{ + if (channel & DMACH_LOW_LEVEL) + return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL]; + else + return dma_chan_map[channel]; +} /* s3c2410_dma_stats_timeout * @@ -321,8 +313,10 @@ static inline void s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf, enum s3c2410_dma_buffresult result) { +#if 0 pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n", chan->callback_fn, buf, buf->id, buf->size, result); +#endif if (chan->callback_fn != NULL) { (chan->callback_fn)(chan, buf->id, buf->size, result); @@ -439,7 +433,6 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) return 0; } - /* s3c2410_dma_enqueue * * queue an given buffer for dma transfer. @@ -460,11 +453,12 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) int s3c2410_dma_enqueue(unsigned int channel, void *id, dma_addr_t data, int size) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); struct s3c2410_dma_buf *buf; unsigned long flags; - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: id=%p, data=%08x, size=%d\n", __FUNCTION__, id, (unsigned int)data, size); @@ -562,8 +556,10 @@ s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf) static inline void s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) { +#if 0 pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n", chan->number, chan->load_state); +#endif switch (chan->load_state) { case S3C2410_DMALOAD_NONE: @@ -718,7 +714,8 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) if (chan->load_state == S3C2410_DMALOAD_NONE) { pr_debug("dma%d: end of transfer, stopping channel (%ld)\n", chan->number, jiffies); - s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP); + s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL, + S3C2410_DMAOP_STOP); } } @@ -726,37 +723,34 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) return IRQ_HANDLED; } +static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel); + /* s3c2410_request_dma * * get control of an dma channel */ -int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client, +int s3c2410_dma_request(unsigned int channel, + struct s3c2410_dma_client *client, void *dev) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan; unsigned long flags; int err; pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", channel, client->name, dev); - check_channel(channel); - local_irq_save(flags); - dbg_showchan(chan); - - if (chan->in_use) { - if (client != chan->client) { - printk(KERN_ERR "dma%d: already in use\n", channel); - local_irq_restore(flags); - return -EBUSY; - } else { - printk(KERN_ERR "dma%d: client already has channel\n", channel); - } + chan = s3c2410_dma_map_channel(channel); + if (chan == NULL) { + local_irq_restore(flags); + return -EBUSY; } + dbg_showchan(chan); + chan->client = client; chan->in_use = 1; @@ -809,14 +803,14 @@ EXPORT_SYMBOL(s3c2410_dma_request); int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); unsigned long flags; - check_channel(channel); + if (chan == NULL) + return -EINVAL; local_irq_save(flags); - if (chan->client != client) { printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n", channel, chan->client, client); @@ -837,8 +831,12 @@ int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) if (chan->irq_claimed) free_irq(chan->irq, (void *)chan); + chan->irq_claimed = 0; + if (!(channel & DMACH_LOW_LEVEL)) + dma_chan_map[channel] = NULL; + local_irq_restore(flags); return 0; @@ -848,8 +846,8 @@ EXPORT_SYMBOL(s3c2410_dma_free); static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) { - unsigned long tmp; unsigned long flags; + unsigned long tmp; pr_debug("%s:\n", __FUNCTION__); @@ -997,9 +995,10 @@ s3c2410_dma_started(struct s3c2410_dma_chan *chan) int s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; switch (op) { case S3C2410_DMAOP_START: @@ -1046,12 +1045,19 @@ int s3c2410_dma_config(dmach_t channel, int xferunit, int dcon) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", __FUNCTION__, channel, xferunit, dcon); - check_channel(channel); + if (chan == NULL) + return -EINVAL; + + printk("Initial dcon is %08x\n", dcon); + + dcon |= chan->dcon & dma_sel.dcon_mask; + + printk("New dcon is %08x\n", dcon); switch (xferunit) { case 1: @@ -1086,9 +1092,10 @@ EXPORT_SYMBOL(s3c2410_dma_config); int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags); @@ -1106,9 +1113,10 @@ EXPORT_SYMBOL(s3c2410_dma_setflags); int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn); @@ -1121,9 +1129,10 @@ EXPORT_SYMBOL(s3c2410_dma_set_opfn); int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn); @@ -1153,9 +1162,10 @@ int s3c2410_dma_devconfig(int channel, int hwcfg, unsigned long devaddr) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", __FUNCTION__, (int)source, hwcfg, devaddr); @@ -1200,9 +1210,10 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig); int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; if (src != NULL) *src = dma_rdreg(chan, S3C2410_DMA_DCSRC); @@ -1252,7 +1263,7 @@ static int s3c2410_dma_resume(struct sys_device *dev) #define s3c2410_dma_resume NULL #endif /* CONFIG_PM */ -static struct sysdev_class dma_sysclass = { +struct sysdev_class dma_sysclass = { set_kset_name("s3c24xx-dma"), .suspend = s3c2410_dma_suspend, .resume = s3c2410_dma_resume, @@ -1265,7 +1276,6 @@ static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f) memset(p, 0, sizeof(struct s3c2410_dma_buf)); } - /* initialisation code */ static int __init s3c2410_init_dma(void) @@ -1274,7 +1284,7 @@ static int __init s3c2410_init_dma(void) int channel; int ret; - printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n"); + printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n"); dma_base = ioremap(S3C24XX_PA_DMA, 0x200); if (dma_base == NULL) { @@ -1282,6 +1292,8 @@ static int __init s3c2410_init_dma(void) return -ENOMEM; } + printk("Registering sysclass\n"); + ret = sysdev_class_register(&dma_sysclass); if (ret != 0) { printk(KERN_ERR "dma sysclass registration failed\n"); @@ -1335,4 +1347,95 @@ static int __init s3c2410_init_dma(void) return ret; } -__initcall(s3c2410_init_dma); +core_initcall(s3c2410_init_dma); + +static inline int is_channel_valid(unsigned int channel) +{ + return (channel & DMA_CH_VALID); +} + +/* s3c2410_dma_map_channel() + * + * turn the virtual channel number into a real, and un-used hardware + * channel. + * + * currently this code uses first-free channel from the specified harware + * map, not taking into account anything that the board setup code may + * have to say about the likely peripheral set to be in use. +*/ + +struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) +{ + struct s3c24xx_dma_map *ch_map; + struct s3c2410_dma_chan *dmach; + int ch; + + if (dma_sel.map == NULL || channel > dma_sel.map_size) + return NULL; + + ch_map = dma_sel.map + channel; + + for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) { + if (!is_channel_valid(ch_map->channels[ch])) + continue; + + if (s3c2410_chans[ch].in_use == 0) { + printk("mapped channel %d to %d\n", channel, ch); + break; + } + } + + if (ch >= S3C2410_DMA_CHANNELS) + return NULL; + + /* update our channel mapping */ + + dmach = &s3c2410_chans[ch]; + dma_chan_map[channel] = dmach; + + /* select the channel */ + + (dma_sel.select)(dmach, ch_map); + + return dmach; +} + +static void s3c24xx_dma_show_ch(struct s3c24xx_dma_map *map, int ch) +{ + /* show the channel configuration */ + + printk("%2d: %20s, channels %c%c%c%c\n", ch, map->name, + (is_channel_valid(map->channels[0]) ? '0' : '-'), + (is_channel_valid(map->channels[1]) ? '1' : '-'), + (is_channel_valid(map->channels[2]) ? '2' : '-'), + (is_channel_valid(map->channels[3]) ? '3' : '-')); +} + +static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch) +{ + if (1) + s3c24xx_dma_show_ch(map, ch); + + return 0; +} + +int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel) +{ + struct s3c24xx_dma_map *nmap; + size_t map_sz = sizeof(*nmap) * sel->map_size; + int ptr; + + nmap = kmalloc(map_sz, GFP_KERNEL); + if (nmap == NULL) + return -ENOMEM; + + memcpy(nmap, sel->map, map_sz); + memcpy(&dma_sel, sel, sizeof(*sel)); + + dma_sel.map = nmap; + + for (ptr = 0; ptr < sel->map_size; ptr++) + s3c24xx_dma_check_entry(nmap+ptr, ptr); + + return 0; +} diff --git a/arch/arm/mach-s3c2410/dma.h b/arch/arm/mach-s3c2410/dma.h new file mode 100644 index 00000000000..0ebfe0aab80 --- /dev/null +++ b/arch/arm/mach-s3c2410/dma.h @@ -0,0 +1,45 @@ +/* arch/arm/mach-s3c2410/dma.h + * + * Copyright (C) 2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * Samsung S3C24XX DMA 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. +*/ + +extern struct sysdev_class dma_sysclass; +extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; + +#define DMA_CH_VALID (1<<31) + +struct s3c24xx_dma_addr { + unsigned long from; + unsigned long to; +}; + +/* struct s3c24xx_dma_map + * + * this holds the mapping information for the channel selected + * to be connected to the specified device +*/ + +struct s3c24xx_dma_map { + const char *name; + struct s3c24xx_dma_addr hw_addr; + + unsigned long channels[S3C2410_DMA_CHANNELS]; +}; + +struct s3c24xx_dma_selection { + struct s3c24xx_dma_map *map; + unsigned long map_size; + unsigned long dcon_mask; + + void (*select)(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map); +}; + +extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c index cd39e868458..db6393c9986 100644 --- a/arch/arm/mach-s3c2410/gpio.c +++ b/arch/arm/mach-s3c2410/gpio.c @@ -18,21 +18,7 @@ * 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 - * - * Changelog - * 13-Sep-2004 BJD Implemented change of MISCCR - * 14-Sep-2004 BJD Added getpin call - * 14-Sep-2004 BJD Fixed bug in setpin() call - * 30-Sep-2004 BJD Fixed cfgpin() mask bug - * 01-Oct-2004 BJD Added getcfg() to get pin configuration - * 01-Oct-2004 BJD Fixed mask bug in pullup() call - * 01-Oct-2004 BJD Added getirq() to turn pin into irqno - * 04-Oct-2004 BJD Added irq filter controls for GPIO - * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code - * 13-Mar-2005 BJD Updates for __iomem - * 26-Oct-2005 BJD Added generic configuration types - * 15-Jan-2006 LCVR Added support for the S3C2400 - */ +*/ #include <linux/kernel.h> diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index cd6139b3599..3e9f3462c61 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -181,17 +181,19 @@ s3c_irq_unmask(unsigned int irqno) } struct irqchip s3c_irq_level_chip = { - .ack = s3c_irq_maskack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake + .name = "s3c-level", + .ack = s3c_irq_maskack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .set_wake = s3c_irq_wake }; static struct irqchip s3c_irq_chip = { - .ack = s3c_irq_ack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake + .name = "s3c", + .ack = s3c_irq_ack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .set_wake = s3c_irq_wake }; static void @@ -343,19 +345,21 @@ s3c_irqext_type(unsigned int irq, unsigned int type) } static struct irqchip s3c_irqext_chip = { - .mask = s3c_irqext_mask, - .unmask = s3c_irqext_unmask, - .ack = s3c_irqext_ack, - .set_type = s3c_irqext_type, - .set_wake = s3c_irqext_wake + .name = "s3c-ext", + .mask = s3c_irqext_mask, + .unmask = s3c_irqext_unmask, + .ack = s3c_irqext_ack, + .set_type = s3c_irqext_type, + .set_wake = s3c_irqext_wake }; static struct irqchip s3c_irq_eint0t4 = { - .ack = s3c_irq_ack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake, - .set_type = s3c_irqext_type, + .name = "s3c-ext0", + .ack = s3c_irq_ack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .set_wake = s3c_irq_wake, + .set_type = s3c_irqext_type, }; /* mask values for the parent registers for each of the interrupt types */ @@ -387,9 +391,10 @@ s3c_irq_uart0_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart0 = { - .mask = s3c_irq_uart0_mask, - .unmask = s3c_irq_uart0_unmask, - .ack = s3c_irq_uart0_ack, + .name = "s3c-uart0", + .mask = s3c_irq_uart0_mask, + .unmask = s3c_irq_uart0_unmask, + .ack = s3c_irq_uart0_ack, }; /* UART1 */ @@ -413,9 +418,10 @@ s3c_irq_uart1_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart1 = { - .mask = s3c_irq_uart1_mask, - .unmask = s3c_irq_uart1_unmask, - .ack = s3c_irq_uart1_ack, + .name = "s3c-uart1", + .mask = s3c_irq_uart1_mask, + .unmask = s3c_irq_uart1_unmask, + .ack = s3c_irq_uart1_ack, }; /* UART2 */ @@ -439,9 +445,10 @@ s3c_irq_uart2_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart2 = { - .mask = s3c_irq_uart2_mask, - .unmask = s3c_irq_uart2_unmask, - .ack = s3c_irq_uart2_ack, + .name = "s3c-uart2", + .mask = s3c_irq_uart2_mask, + .unmask = s3c_irq_uart2_unmask, + .ack = s3c_irq_uart2_ack, }; /* ADC and Touchscreen */ @@ -465,9 +472,10 @@ s3c_irq_adc_ack(unsigned int irqno) } static struct irqchip s3c_irq_adc = { - .mask = s3c_irq_adc_mask, - .unmask = s3c_irq_adc_unmask, - .ack = s3c_irq_adc_ack, + .name = "s3c-adc", + .mask = s3c_irq_adc_mask, + .unmask = s3c_irq_adc_unmask, + .ack = s3c_irq_adc_ack, }; /* irq demux for adc */ @@ -569,23 +577,104 @@ s3c_irq_demux_uart2(unsigned int irq, } static void -s3c_irq_demux_extint(unsigned int irq, - struct irqdesc *desc, - struct pt_regs *regs) +s3c_irq_demux_extint8(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) { unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); eintpnd &= ~eintmsk; + eintpnd &= ~0xff; /* ignore lower irqs */ - if (eintpnd) { - irq = fls(eintpnd); - irq += (IRQ_EINT4 - (4 + 1)); + /* we may as well handle all the pending IRQs here */ + while (eintpnd) { + irq = __ffs(eintpnd); + eintpnd &= ~(1<<irq); + + irq += (IRQ_EINT4 - 4); desc_handle_irq(irq, irq_desc + irq, regs); } + +} + +static void +s3c_irq_demux_extint4t7(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) +{ + unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); + unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); + + eintpnd &= ~eintmsk; + eintpnd &= 0xff; /* only lower irqs */ + + /* we may as well handle all the pending IRQs here */ + + while (eintpnd) { + irq = __ffs(eintpnd); + eintpnd &= ~(1<<irq); + + irq += (IRQ_EINT4 - 4); + + desc_handle_irq(irq, irq_desc + irq, regs); + } +} + +#ifdef CONFIG_PM + +static struct sleep_save irq_save[] = { + SAVE_ITEM(S3C2410_INTMSK), + SAVE_ITEM(S3C2410_INTSUBMSK), +}; + +/* the extint values move between the s3c2410/s3c2440 and the s3c2412 + * so we use an array to hold them, and to calculate the address of + * the register at run-time +*/ + +static unsigned long save_extint[3]; +static unsigned long save_eintflt[4]; +static unsigned long save_eintmask; + +int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(save_extint); i++) + save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4)); + + for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) + save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4)); + + s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); + save_eintmask = __raw_readl(S3C24XX_EINTMASK); + + return 0; } +int s3c24xx_irq_resume(struct sys_device *dev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(save_extint); i++) + __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4)); + + for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) + __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4)); + + s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); + __raw_writel(save_eintmask, S3C24XX_EINTMASK); + + return 0; +} + +#else +#define s3c24xx_irq_suspend NULL +#define s3c24xx_irq_resume NULL +#endif + /* s3c24xx_init_irq * * Initialise S3C2410 IRQ system @@ -674,8 +763,8 @@ void __init s3c24xx_init_irq(void) /* setup the cascade irq handlers */ - set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint); - set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint); + set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7); + set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8); set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c new file mode 100644 index 00000000000..ba5109af40b --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -0,0 +1,266 @@ +/*********************************************************************** + * + * linux/arch/arm/mach-s3c2410/mach-amlm5900.c + * + * Copyright (c) 2006 American Microsystems Limited + * David Anders <danders@amltd.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 + * + * @History: + * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by + * Ben Dooks <ben@simtec.co.uk> + * + ***********************************************************************/ + +#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/device.h> +#include <linux/platform_device.h> +#include <linux/proc_fs.h> + + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> +#include <asm/mach/flash.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/arch/fb.h> + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-lcd.h> +#include <asm/arch/regs-gpio.h> + +#include "devs.h" +#include "cpu.h" + +#ifdef CONFIG_MTD_PARTITIONS + +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/map.h> +#include <linux/mtd/physmap.h> + +static struct resource amlm5900_nor_resource = { + .start = 0x00000000, + .end = 0x01000000 - 1, + .flags = IORESOURCE_MEM, +}; + + + +static struct mtd_partition amlm5900_mtd_partitions[] = { + { + .name = "System", + .size = 0x240000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "Kernel", + .size = 0x100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "Ramdisk", + .size = 0x300000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "JFFS2", + .size = 0x9A0000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "Settings", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct physmap_flash_data amlm5900_flash_data = { + .width = 2, + .parts = amlm5900_mtd_partitions, + .nr_parts = ARRAY_SIZE(amlm5900_mtd_partitions), +}; + +static struct platform_device amlm5900_device_nor = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &amlm5900_flash_data, + }, + .num_resources = 1, + .resource = &amlm5900_nor_resource, +}; +#endif + +static struct map_desc amlm5900_iodesc[] __initdata = { + { + .virtual = (u32)S3C24XX_VA_SPI, + .pfn = __phys_to_pfn(S3C2410_PA_SPI), + .length = SZ_1M, + .type = MT_DEVICE + } +}; + +#define UCON S3C2410_UCON_DEFAULT +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c2410_uartcfg amlm5900_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + } +}; + + +static struct platform_device *amlm5900_devices[] __initdata = { +#ifdef CONFIG_FB_S3C2410 + &s3c_device_lcd, +#endif + &s3c_device_adc, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_usb, + &s3c_device_rtc, + &s3c_device_usbgadget, + &s3c_device_sdi, +#ifdef CONFIG_MTD_PARTITIONS + &amlm5900_device_nor, +#endif +}; + +static struct s3c24xx_board amlm5900_board __initdata = { + .devices = amlm5900_devices, + .devices_count = ARRAY_SIZE(amlm5900_devices) +}; + +void __init amlm5900_map_io(void) +{ + s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs)); + s3c24xx_set_board(&amlm5900_board); +} + +#ifdef CONFIG_FB_S3C2410 +static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { + .width = 160, + .height = 160, + +/* commented out until stn patch is submitted +* .type = S3C2410_LCDCON1_STN4, +*/ + .gpccon = 0xaaaaaaaa, + .gpccon_mask = 0xffffffff, + .gpcup = 0x0000ffff, + .gpcup_mask = 0xffffffff, + + .gpdcon = 0xaaaaaaaa, + .gpdcon_mask = 0xffffffff, + .gpdup = 0x0000ffff, + .gpdup_mask = 0xffffffff, + + .xres = { + .min = 160, + .max = 160, + .defval = 160, + }, + + .yres = { + .min = 160, + .max = 160, + .defval = 160, + }, + + .bpp = { + .min = 4, + .max = 4, + .defval = 4, + }, + + .regs = { + .lcdcon1 = 0x00008225, + .lcdcon2 = 0x0027c000, + .lcdcon3 = 0x00182708, + .lcdcon4 = 0x00000002, + .lcdcon5 = 0x00000001, + } +}; +#endif + +static irqreturn_t +amlm5900_wake_interrupt(int irq, void *ignored, struct pt_regs *regs) +{ + return IRQ_HANDLED; +} + +static void amlm5900_init_pm(void) +{ + int ret = 0; + + ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt, + IRQF_TRIGGER_RISING | IRQF_SHARED, + "amlm5900_wakeup", &amlm5900_wake_interrupt); + if (ret != 0) { + printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret); + } else { + enable_irq_wake(IRQ_EINT9); + /* configure the suspend/resume status pin */ + s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); + s3c2410_gpio_pullup(S3C2410_GPF2, 0); + } +} +static void __init amlm5900_init(void) +{ + amlm5900_init_pm(); +#ifdef CONFIG_FB_S3C2410 + s3c24xx_fb_set_platdata(&amlm5900_lcd_info); +#endif +} + +MACHINE_START(AML_M5900, "AML_M5900") + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = amlm5900_map_io, + .init_irq = s3c24xx_init_irq, + .init_machine = amlm5900_init, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c index 60641d452db..e94cdcd9659 100644 --- a/arch/arm/mach-s3c2410/mach-anubis.c +++ b/arch/arm/mach-s3c2410/mach-anubis.c @@ -4,15 +4,9 @@ * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> * - * - * * 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. - * - * Modifications: - * 02-May-2005 BJD Copied from mach-bast.c - * 20-Sep-2005 BJD Added static to non-exported items */ #include <linux/kernel.h> diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index d661c6b7ff5..e2205ff1b0e 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -11,15 +11,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * Modifications: - * 01-Nov-2004 BJD Initial version - * 12-Nov-2004 BJD Updated for release - * 04-Jan-2005 BJD Fixes for pre-release - * 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa - * 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA - * 14-Mar-2005 BJD void __iomem fixes - * 20-Sep-2005 BJD Added static to non-exported items - * 26-Oct-2005 BJD Added framebuffer data */ #include <linux/kernel.h> diff --git a/arch/arm/mach-s3c2410/mach-vstms.c b/arch/arm/mach-s3c2410/mach-vstms.c new file mode 100644 index 00000000000..ea554e7c006 --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-vstms.c @@ -0,0 +1,168 @@ +/* linux/arch/arm/mach-s3c2410/mach-vstms.c + * + * (C) 2006 Thomas Gleixner <tglx@linutronix.de> + * + * Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics + * + * 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/platform_device.h> + +#include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/nand_ecc.h> +#include <linux/mtd/partitions.h> + +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/irq.h> + +#include <asm/hardware.h> +#include <asm/hardware/iomd.h> +#include <asm/setup.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-lcd.h> + +#include <asm/arch/idle.h> +#include <asm/arch/fb.h> + +#include <asm/arch/nand.h> + +#include "s3c2410.h" +#include "s3c2412.h" +#include "clock.h" +#include "devs.h" +#include "cpu.h" + + +static struct map_desc vstms_iodesc[] __initdata = { +}; + +static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + }, + [1] = { + .hwport = 1, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = 0x3c5, + .ulcon = 0x03, + .ufcon = 0x51, + } +}; + +static struct mtd_partition vstms_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = 0x7C000, + .offset = 0, + }, + [1] = { + .name = "UBoot Config", + .offset = 0x7C000, + .size = 0x4000, + }, + [2] = { + .name = "Kernel", + .offset = 0x80000, + .size = 0x200000, + }, + [3] = { + .name = "RFS", + .offset = 0x280000, + .size = 0x3d80000, + }, +}; + +static struct s3c2410_nand_set vstms_nand_sets[] = { + [0] = { + .name = "NAND", + .nr_chips = 1, + .nr_partitions = ARRAY_SIZE(vstms_nand_part), + .partitions = vstms_nand_part, + }, +}; + +/* choose a set of timings which should suit most 512Mbit + * chips and beyond. +*/ + +static struct s3c2410_platform_nand vstms_nand_info = { + .tacls = 20, + .twrph0 = 60, + .twrph1 = 20, + .nr_sets = ARRAY_SIZE(vstms_nand_sets), + .sets = vstms_nand_sets, +}; + +static struct platform_device *vstms_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_wdt, + &s3c_device_i2c, + &s3c_device_iis, + &s3c_device_rtc, + &s3c_device_nand, +}; + +static struct s3c24xx_board vstms_board __initdata = { + .devices = vstms_devices, + .devices_count = ARRAY_SIZE(vstms_devices) +}; + +static void __init vstms_fixup(struct machine_desc *desc, + struct tag *tags, char **cmdline, + struct meminfo *mi) +{ + if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) { + mi->nr_banks=1; + mi->bank[0].start = 0x30000000; + mi->bank[0].size = SZ_64M; + mi->bank[0].node = 0; + } +} + +static void __init vstms_map_io(void) +{ + s3c_device_nand.dev.platform_data = &vstms_nand_info; + + s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc)); + s3c24xx_init_clocks(12000000); + s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs)); + s3c24xx_set_board(&vstms_board); +} + +MACHINE_START(VSTMS, "VSTMS") + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + + .fixup = vstms_fixup, + .init_irq = s3c24xx_init_irq, + .map_io = vstms_map_io, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c index 7b244566a43..42cd05e298f 100644 --- a/arch/arm/mach-s3c2410/pm-simtec.c +++ b/arch/arm/mach-s3c2410/pm-simtec.c @@ -49,7 +49,8 @@ static __init int pm_simtec_init(void) /* check which machine we are running on */ if (!machine_is_bast() && !machine_is_vr1000() && - !machine_is_anubis() && !machine_is_osiris()) + !machine_is_anubis() && !machine_is_osiris() && + !machine_is_aml_m5900()) return 0; printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index a589fe76d91..b49a0b3b72b 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c @@ -1,9 +1,9 @@ /* linux/arch/arm/mach-s3c2410/pm.c * - * Copyright (c) 2004 Simtec Electronics + * Copyright (c) 2004,2006 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * - * S3C2410 Power Manager (Suspend-To-RAM) support + * S3C24XX Power Manager (Suspend-To-RAM) support * * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information * @@ -24,9 +24,6 @@ * Parts based on arch/arm/mach-pxa/pm.c * * Thanks to Dimitry Andric for debugging - * - * Modifications: - * 10-Mar-2005 LCVR Changed S3C2410_VA_UART to S3C24XX_VA_UART */ #include <linux/init.h> @@ -38,6 +35,7 @@ #include <linux/ioport.h> #include <linux/delay.h> +#include <asm/cacheflush.h> #include <asm/hardware.h> #include <asm/io.h> @@ -55,14 +53,6 @@ unsigned long s3c_pm_flags; -/* cache functions from arch/arm/mm/proc-arm920.S */ - -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -extern void arm920_flush_kern_cache_all(void); -#else -static void arm920_flush_kern_cache_all(void) { } -#endif - #define PFX "s3c24xx-pm: " static struct sleep_save core_save[] = { @@ -92,19 +82,6 @@ static struct sleep_save core_save[] = { SAVE_ITEM(S3C2410_REFRESH), }; -/* this lot should be really saved by the IRQ code */ -static struct sleep_save irq_save[] = { - SAVE_ITEM(S3C2410_EXTINT0), - SAVE_ITEM(S3C2410_EXTINT1), - SAVE_ITEM(S3C2410_EXTINT2), - SAVE_ITEM(S3C2410_EINFLT0), - SAVE_ITEM(S3C2410_EINFLT1), - SAVE_ITEM(S3C2410_EINFLT2), - SAVE_ITEM(S3C2410_EINFLT3), - SAVE_ITEM(S3C2410_EINTMASK), - SAVE_ITEM(S3C2410_INTMSK) -}; - static struct sleep_save gpio_save[] = { SAVE_ITEM(S3C2410_GPACON), SAVE_ITEM(S3C2410_GPADAT), @@ -165,7 +142,7 @@ static struct sleep_save uart_save[] = { extern void printascii(const char *); -static void pm_dbg(const char *fmt, ...) +void pm_dbg(const char *fmt, ...) { va_list va; char buff[256]; @@ -509,6 +486,9 @@ static void s3c2410_pm_configure_extint(void) } } +void (*pm_cpu_prep)(void); +void (*pm_cpu_sleep)(void); + #define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) /* s3c2410_pm_enter @@ -519,7 +499,6 @@ static void s3c2410_pm_configure_extint(void) static int s3c2410_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; - unsigned long tmp; /* ensure the debug is initialised (if enabled) */ @@ -527,6 +506,11 @@ static int s3c2410_pm_enter(suspend_state_t state) DBG("s3c2410_pm_enter(%d)\n", state); + if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { + printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); + return -EINVAL; + } + if (state != PM_SUSPEND_MEM) { printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n"); return -EINVAL; @@ -554,17 +538,9 @@ static int s3c2410_pm_enter(suspend_state_t state) DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys); - /* ensure at least GESTATUS3 has the resume address */ - - __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3); - - DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); - DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); - /* save all necessary core registers not covered by the drivers */ s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); - s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); @@ -581,10 +557,16 @@ static int s3c2410_pm_enter(suspend_state_t state) /* ack any outstanding external interrupts before we go to sleep */ __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); + __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND); + __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND); + + /* call cpu specific preperation */ + + pm_cpu_prep(); /* flush cache back to ram */ - arm920_flush_kern_cache_all(); + flush_cache_all(); s3c2410_pm_check_store(); @@ -592,23 +574,23 @@ static int s3c2410_pm_enter(suspend_state_t state) __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ - s3c2410_cpu_suspend(regs_save); + /* s3c2410_cpu_save will also act as our return point from when + * we resume as it saves its own register state, so use the return + * code to differentiate return from save and return from sleep */ + + if (s3c2410_cpu_save(regs_save) == 0) { + flush_cache_all(); + pm_cpu_sleep(); + } /* restore the cpu state */ cpu_init(); - /* unset the return-from-sleep flag, to ensure reset */ - - tmp = __raw_readl(S3C2410_GSTATUS2); - tmp &= S3C2410_GSTATUS2_OFFRESET; - __raw_writel(tmp, S3C2410_GSTATUS2); - /* restore the system state */ s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); - s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); s3c2410_pm_debug_init(); diff --git a/arch/arm/mach-s3c2410/pm.h b/arch/arm/mach-s3c2410/pm.h index 7a5e714c738..ffe197a119f 100644 --- a/arch/arm/mach-s3c2410/pm.h +++ b/arch/arm/mach-s3c2410/pm.h @@ -34,13 +34,19 @@ extern unsigned long s3c_irqwake_eintmask; extern unsigned long s3c_irqwake_intallow; extern unsigned long s3c_irqwake_eintallow; +/* per-cpu sleep functions */ + +extern void (*pm_cpu_prep)(void); +extern void (*pm_cpu_sleep)(void); + /* Flags for PM Control */ extern unsigned long s3c_pm_flags; /* from sleep.S */ -extern void s3c2410_cpu_suspend(unsigned long *saveblk); +extern int s3c2410_cpu_save(unsigned long *saveblk); +extern void s3c2410_cpu_suspend(void); extern void s3c2410_cpu_resume(void); extern unsigned long s3c2410_sleep_save_phys; @@ -57,3 +63,11 @@ struct sleep_save { extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count); extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count); + +#ifdef CONFIG_PM +extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); +extern int s3c24xx_irq_resume(struct sys_device *dev); +#else +#define s3c24xx_irq_suspend NULL +#define s3c24xx_irq_resume NULL +#endif diff --git a/arch/arm/mach-s3c2410/s3c2410-dma.c b/arch/arm/mach-s3c2410/s3c2410-dma.c new file mode 100644 index 00000000000..51e5098b32e --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2410-dma.c @@ -0,0 +1,158 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c + * + * (c) 2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 DMA selection + * + * http://armlinux.simtec.co.uk/ + * + * 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/init.h> +#include <linux/sysdev.h> + +#include <asm/dma.h> +#include <asm/arch/dma.h> +#include "dma.h" + +#include "cpu.h" + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-ac97.h> +#include <asm/arch/regs-mem.h> +#include <asm/arch/regs-lcd.h> +#include <asm/arch/regs-sdi.h> +#include <asm/arch/regs-iis.h> +#include <asm/arch/regs-spi.h> + +static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = { + [DMACH_XD0] = { + .name = "xdreq0", + .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID, + }, + [DMACH_XD1] = { + .name = "xdreq1", + .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID, + }, + [DMACH_SDI] = { + .name = "sdi", + .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID, + .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, + .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_SPI0] = { + .name = "spi0", + .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, + .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, + }, + [DMACH_SPI1] = { + .name = "spi1", + .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT, + .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT, + }, + [DMACH_UART0] = { + .name = "uart0", + .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, + }, + [DMACH_UART1] = { + .name = "uart1", + .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, + }, + [DMACH_UART2] = { + .name = "uart2", + .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, + }, + [DMACH_TIMER] = { + .name = "timer", + .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID, + .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID, + }, + [DMACH_I2S_IN] = { + .name = "i2s-sdi", + .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID, + .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_I2S_OUT] = { + .name = "i2s-sdo", + .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_USB_EP1] = { + .name = "usb-ep1", + .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID, + }, + [DMACH_USB_EP2] = { + .name = "usb-ep2", + .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID, + }, + [DMACH_USB_EP3] = { + .name = "usb-ep3", + .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID, + }, + [DMACH_USB_EP4] = { + .name = "usb-ep4", + .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID, + }, +}; + +static void s3c2410_dma_select(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map) +{ + chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID; +} + +static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = { + .select = s3c2410_dma_select, + .dcon_mask = 7 << 24, + .map = s3c2410_dma_mappings, + .map_size = ARRAY_SIZE(s3c2410_dma_mappings), +}; + +static int s3c2410_dma_add(struct sys_device *sysdev) +{ + return s3c24xx_dma_init_map(&s3c2410_dma_sel); +} + +static struct sysdev_driver s3c2410_dma_driver = { + .add = s3c2410_dma_add, +}; + +static int __init s3c2410_dma_init(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver); +} + +arch_initcall(s3c2410_dma_init); + +/* S3C2442 DMA contains the same selection table as the S3C2410 */ + +static struct sysdev_driver s3c2442_dma_driver = { + .add = s3c2410_dma_add, +}; + +static int __init s3c2442_dma_init(void) +{ + return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver); +} + +arch_initcall(s3c2442_dma_init); + + diff --git a/arch/arm/mach-s3c2410/s3c2410-irq.c b/arch/arm/mach-s3c2410/s3c2410-irq.c new file mode 100644 index 00000000000..c796c9c76e7 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2410-irq.c @@ -0,0 +1,48 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * 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/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/ptrace.h> +#include <linux/sysdev.h> + +#include "cpu.h" +#include "pm.h" + +static int s3c2410_irq_add(struct sys_device *sysdev) +{ + return 0; +} + +static struct sysdev_driver s3c2410_irq_driver = { + .add = s3c2410_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, +}; + +static int s3c2410_irq_init(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); +} + +arch_initcall(s3c2410_irq_init); diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c new file mode 100644 index 00000000000..e51d7666951 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2410-pm.c @@ -0,0 +1,120 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support + * + * 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/init.h> +#include <linux/suspend.h> +#include <linux/errno.h> +#include <linux/time.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/io.h> + +#include <asm/mach-types.h> + +#include <asm/arch/regs-gpio.h> + +#include "cpu.h" +#include "pm.h" + +#ifdef CONFIG_S3C2410_PM_DEBUG +extern void pm_dbg(const char *fmt, ...); +#define DBG(fmt...) pm_dbg(fmt) +#else +#define DBG(fmt...) printk(KERN_DEBUG fmt) +#endif + +static void s3c2410_pm_prepare(void) +{ + /* ensure at least GSTATUS3 has the resume address */ + + __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3); + + DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); + DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); + + if ( machine_is_aml_m5900() ) + s3c2410_gpio_setpin(S3C2410_GPF2, 1); + +} + +int s3c2410_pm_resume(struct sys_device *dev) +{ + unsigned long tmp; + + /* unset the return-from-sleep flag, to ensure reset */ + + tmp = __raw_readl(S3C2410_GSTATUS2); + tmp &= S3C2410_GSTATUS2_OFFRESET; + __raw_writel(tmp, S3C2410_GSTATUS2); + + if ( machine_is_aml_m5900() ) + s3c2410_gpio_setpin(S3C2410_GPF2, 0); + + return 0; +} + +static int s3c2410_pm_add(struct sys_device *dev) +{ + pm_cpu_prep = s3c2410_pm_prepare; + pm_cpu_sleep = s3c2410_cpu_suspend; + + return 0; +} + +static struct sysdev_driver s3c2410_pm_driver = { + .add = s3c2410_pm_add, + .resume = s3c2410_pm_resume, +}; + +/* register ourselves */ + +static int __init s3c2410_pm_drvinit(void) +{ + return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver); +} + +arch_initcall(s3c2410_pm_drvinit); + +static struct sysdev_driver s3c2440_pm_driver = { + .add = s3c2410_pm_add, + .resume = s3c2410_pm_resume, +}; + +static int __init s3c2440_pm_drvinit(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver); +} + +arch_initcall(s3c2440_pm_drvinit); + +static struct sysdev_driver s3c2442_pm_driver = { + .add = s3c2410_pm_add, + .resume = s3c2410_pm_resume, +}; + +static int __init s3c2442_pm_drvinit(void) +{ + return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver); +} + +arch_initcall(s3c2442_pm_drvinit); diff --git a/arch/arm/mach-s3c2410/s3c2410-sleep.S b/arch/arm/mach-s3c2410/s3c2410-sleep.S new file mode 100644 index 00000000000..9179a102458 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2410-sleep.S @@ -0,0 +1,68 @@ +/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2410 Power Manager (Suspend-To-RAM) support + * + * Based on PXA/SA1100 sleep code by: + * Nicolas Pitre, (c) 2002 Monta Vista Software Inc + * Cliff Brake, (c) 2001 + * + * 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/linkage.h> +#include <asm/assembler.h> +#include <asm/hardware.h> +#include <asm/arch/map.h> + +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-clock.h> +#include <asm/arch/regs-mem.h> +#include <asm/arch/regs-serial.h> + + /* s3c2410_cpu_suspend + * + * put the cpu into sleep mode + */ + +ENTRY(s3c2410_cpu_suspend) + @@ prepare cpu to sleep + + ldr r4, =S3C2410_REFRESH + ldr r5, =S3C24XX_MISCCR + ldr r6, =S3C2410_CLKCON + ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) + ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) + ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB) + + orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command + orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals + orr r9, r9, #S3C2410_CLKCON_POWER @ power down command + + teq pc, #0 @ first as a trial-run to load cache + bl s3c2410_do_sleep + teq r0, r0 @ now do it for real + b s3c2410_do_sleep @ + + @@ align next bit of code to cache line + .align 8 +s3c2410_do_sleep: + streq r7, [ r4 ] @ SDRAM sleep command + streq r8, [ r5 ] @ SDRAM power-down config + streq r9, [ r6 ] @ CPU sleep +1: beq 1b + mov pc, r14 diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index a110cff9cf6..183e4033ce6 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c @@ -8,17 +8,6 @@ * 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. - * - * Modifications: - * 16-May-2003 BJD Created initial version - * 16-Aug-2003 BJD Fixed header files and copyright, added URL - * 05-Sep-2003 BJD Moved to kernel v2.6 - * 18-Jan-2004 BJD Added serial port configuration - * 21-Aug-2004 BJD Added new struct s3c2410_board handler - * 28-Sep-2004 BJD Updates for new serial port bits - * 04-Nov-2004 BJD Updated UART configuration process - * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate - * 13-Aug-2005 DA Removed UART from initial I/O mappings */ #include <linux/kernel.h> diff --git a/arch/arm/mach-s3c2410/s3c2412-dma.c b/arch/arm/mach-s3c2410/s3c2412-dma.c new file mode 100644 index 00000000000..171f3706d36 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2412-dma.c @@ -0,0 +1,160 @@ +/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c + * + * (c) 2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2412 DMA selection + * + * http://armlinux.simtec.co.uk/ + * + * 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/init.h> +#include <linux/sysdev.h> + +#include <asm/dma.h> +#include <asm/arch/dma.h> +#include <asm/io.h> + +#include "dma.h" +#include "cpu.h" + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-ac97.h> +#include <asm/arch/regs-mem.h> +#include <asm/arch/regs-lcd.h> +#include <asm/arch/regs-sdi.h> +#include <asm/arch/regs-iis.h> +#include <asm/arch/regs-spi.h> + +#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID } + +static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = { + [DMACH_XD0] = { + .name = "xdreq0", + .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), + }, + [DMACH_XD1] = { + .name = "xdreq1", + .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), + }, + [DMACH_SDI] = { + .name = "sdi", + .channels = MAP(S3C2412_DMAREQSEL_SDI), + .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, + .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_SPI0] = { + .name = "spi0", + .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), + .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, + .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, + }, + [DMACH_SPI1] = { + .name = "spi1", + .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), + .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT, + .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT, + }, + [DMACH_UART0] = { + .name = "uart0", + .channels = MAP(S3C2412_DMAREQSEL_UART0_0), + .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, + }, + [DMACH_UART1] = { + .name = "uart1", + .channels = MAP(S3C2412_DMAREQSEL_UART1_0), + .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, + }, + [DMACH_UART2] = { + .name = "uart2", + .channels = MAP(S3C2412_DMAREQSEL_UART2_0), + .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, + }, + [DMACH_UART0_SRC2] = { + .name = "uart0", + .channels = MAP(S3C2412_DMAREQSEL_UART0_1), + .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, + }, + [DMACH_UART1_SRC2] = { + .name = "uart1", + .channels = MAP(S3C2412_DMAREQSEL_UART1_1), + .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, + }, + [DMACH_UART2_SRC2] = { + .name = "uart2", + .channels = MAP(S3C2412_DMAREQSEL_UART2_1), + .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, + }, + [DMACH_TIMER] = { + .name = "timer", + .channels = MAP(S3C2412_DMAREQSEL_TIMER), + }, + [DMACH_I2S_IN] = { + .name = "i2s-sdi", + .channels = MAP(S3C2412_DMAREQSEL_I2SRX), + .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_I2S_OUT] = { + .name = "i2s-sdo", + .channels = MAP(S3C2412_DMAREQSEL_I2STX), + .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_USB_EP1] = { + .name = "usb-ep1", + .channels = MAP(S3C2412_DMAREQSEL_USBEP1), + }, + [DMACH_USB_EP2] = { + .name = "usb-ep2", + .channels = MAP(S3C2412_DMAREQSEL_USBEP2), + }, + [DMACH_USB_EP3] = { + .name = "usb-ep3", + .channels = MAP(S3C2412_DMAREQSEL_USBEP3), + }, + [DMACH_USB_EP4] = { + .name = "usb-ep4", + .channels = MAP(S3C2412_DMAREQSEL_USBEP4), + }, +}; + +static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map) +{ + writel(chan->regs + S3C2412_DMA_DMAREQSEL, + map->channels[0] | S3C2412_DMAREQSEL_HW); +} + +static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { + .select = s3c2412_dma_select, + .dcon_mask = 0, + .map = s3c2412_dma_mappings, + .map_size = ARRAY_SIZE(s3c2412_dma_mappings), +}; + +static int s3c2412_dma_add(struct sys_device *sysdev) +{ + return s3c24xx_dma_init_map(&s3c2412_dma_sel); +} + +static struct sysdev_driver s3c2412_dma_driver = { + .add = s3c2412_dma_add, +}; + +static int __init s3c2412_dma_init(void) +{ + return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver); +} + +arch_initcall(s3c2412_dma_init); diff --git a/arch/arm/mach-s3c2410/s3c2412-irq.c b/arch/arm/mach-s3c2410/s3c2412-irq.c index c80ec93dfea..7f741547658 100644 --- a/arch/arm/mach-s3c2410/s3c2412-irq.c +++ b/arch/arm/mach-s3c2410/s3c2412-irq.c @@ -37,6 +37,7 @@ #include "cpu.h" #include "irq.h" +#include "pm.h" /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by * having them turn up in both the INT* and the EINT* registers. Whilst @@ -120,6 +121,8 @@ static int s3c2412_irq_add(struct sys_device *sysdev) static struct sysdev_driver s3c2412_irq_driver = { .add = s3c2412_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, }; static int s3c2412_irq_init(void) diff --git a/arch/arm/mach-s3c2410/s3c2412-pm.c b/arch/arm/mach-s3c2410/s3c2412-pm.c new file mode 100644 index 00000000000..19b63322d25 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2412-pm.c @@ -0,0 +1,128 @@ +/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c + * + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * http://armlinux.simtec.co.uk/. + * + * 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/sysdev.h> +#include <linux/platform_device.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> + +#include <asm/arch/regs-power.h> +#include <asm/arch/regs-gpioj.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-dsc.h> + +#include "cpu.h" +#include "pm.h" + +#include "s3c2412.h" + +static void s3c2412_cpu_suspend(void) +{ + unsigned long tmp; + + /* set our standby method to sleep */ + + tmp = __raw_readl(S3C2412_PWRCFG); + tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP; + __raw_writel(tmp, S3C2412_PWRCFG); + + /* issue the standby signal into the pm unit. Note, we + * issue a write-buffer drain just in case */ + + tmp = 0; + + asm("b 1f\n\t" + ".align 5\n\t" + "1:\n\t" + "mcr p15, 0, %0, c7, c10, 4\n\t" + "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp)); + + /* we should never get past here */ + + panic("sleep resumed to originator?"); +} + +static void s3c2412_pm_prepare(void) +{ +} + +static int s3c2412_pm_add(struct sys_device *sysdev) +{ + pm_cpu_prep = s3c2412_pm_prepare; + pm_cpu_sleep = s3c2412_cpu_suspend; + + return 0; +} + +static struct sleep_save s3c2412_sleep[] = { + SAVE_ITEM(S3C2412_DSC0), + SAVE_ITEM(S3C2412_DSC1), + SAVE_ITEM(S3C2413_GPJDAT), + SAVE_ITEM(S3C2413_GPJCON), + SAVE_ITEM(S3C2413_GPJUP), + + /* save the PWRCFG to get back to original sleep method */ + + SAVE_ITEM(S3C2412_PWRCFG), + + /* save the sleep configuration anyway, just in case these + * get damaged during wakeup */ + + SAVE_ITEM(S3C2412_GPBSLPCON), + SAVE_ITEM(S3C2412_GPCSLPCON), + SAVE_ITEM(S3C2412_GPDSLPCON), + SAVE_ITEM(S3C2412_GPESLPCON), + SAVE_ITEM(S3C2412_GPFSLPCON), + SAVE_ITEM(S3C2412_GPGSLPCON), + SAVE_ITEM(S3C2412_GPHSLPCON), + SAVE_ITEM(S3C2413_GPJSLPCON), +}; + +static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state) +{ + s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); + return 0; +} + +static int s3c2412_pm_resume(struct sys_device *dev) +{ + unsigned long tmp; + + tmp = __raw_readl(S3C2412_PWRCFG); + tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK; + tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE; + __raw_writel(tmp, S3C2412_PWRCFG); + + s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); + return 0; +} + +static struct sysdev_driver s3c2412_pm_driver = { + .add = s3c2412_pm_add, + .suspend = s3c2412_pm_suspend, + .resume = s3c2412_pm_resume, +}; + +static __init int s3c2412_pm_init(void) +{ + return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver); +} + +arch_initcall(s3c2412_pm_init); diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2410/s3c2412.c index 2d163f7600b..e76431c4146 100644 --- a/arch/arm/mach-s3c2410/s3c2412.c +++ b/arch/arm/mach-s3c2410/s3c2412.c @@ -8,17 +8,6 @@ * 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. - * - * Modifications: - * 16-May-2003 BJD Created initial version - * 16-Aug-2003 BJD Fixed header files and copyright, added URL - * 05-Sep-2003 BJD Moved to kernel v2.6 - * 18-Jan-2004 BJD Added serial port configuration - * 21-Aug-2004 BJD Added new struct s3c2410_board handler - * 28-Sep-2004 BJD Updates for new serial port bits - * 04-Nov-2004 BJD Updated UART configuration process - * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate - * 13-Aug-2005 DA Removed UART from initial I/O mappings */ #include <linux/kernel.h> @@ -56,6 +45,13 @@ #ifndef CONFIG_CPU_S3C2412_ONLY void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; + +static inline void s3c2412_init_gpio2(void) +{ + s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10; +} +#else +#define s3c2412_init_gpio2() do { } while(0) #endif /* Initial IO mappings */ @@ -76,6 +72,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no) /* rename devices that are s3c2412/s3c2413 specific */ s3c_device_sdi.name = "s3c2412-sdi"; + s3c_device_lcd.name = "s3c2412-lcd"; s3c_device_nand.name = "s3c2412-nand"; } @@ -110,7 +107,7 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size) { /* move base of IO */ - s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10; + s3c2412_init_gpio2(); /* set our idle function */ @@ -161,48 +158,8 @@ void __init s3c2412_init_clocks(int xtal) * as a driver which may support both 2410 and 2440 may try and use it. */ -#ifdef CONFIG_PM -static struct sleep_save s3c2412_sleep[] = { - SAVE_ITEM(S3C2412_DSC0), - SAVE_ITEM(S3C2412_DSC1), - SAVE_ITEM(S3C2413_GPJDAT), - SAVE_ITEM(S3C2413_GPJCON), - SAVE_ITEM(S3C2413_GPJUP), - - /* save the sleep configuration anyway, just in case these - * get damaged during wakeup */ - - SAVE_ITEM(S3C2412_GPBSLPCON), - SAVE_ITEM(S3C2412_GPCSLPCON), - SAVE_ITEM(S3C2412_GPDSLPCON), - SAVE_ITEM(S3C2412_GPESLPCON), - SAVE_ITEM(S3C2412_GPFSLPCON), - SAVE_ITEM(S3C2412_GPGSLPCON), - SAVE_ITEM(S3C2412_GPHSLPCON), - SAVE_ITEM(S3C2413_GPJSLPCON), -}; - -static int s3c2412_suspend(struct sys_device *dev, pm_message_t state) -{ - s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); - return 0; -} - -static int s3c2412_resume(struct sys_device *dev) -{ - s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); - return 0; -} - -#else -#define s3c2412_suspend NULL -#define s3c2412_resume NULL -#endif - struct sysdev_class s3c2412_sysclass = { set_kset_name("s3c2412-core"), - .suspend = s3c2412_suspend, - .resume = s3c2412_resume }; static int __init s3c2412_core_init(void) diff --git a/arch/arm/mach-s3c2410/s3c2440-dma.c b/arch/arm/mach-s3c2410/s3c2440-dma.c new file mode 100644 index 00000000000..11e109c84a1 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2440-dma.c @@ -0,0 +1,164 @@ +/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c + * + * (c) 2006 Simtec Electronics + * Ben Dooks <ben@simtec.co.uk> + * + * S3C2440 DMA selection + * + * http://armlinux.simtec.co.uk/ + * + * 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/init.h> +#include <linux/sysdev.h> + +#include <asm/dma.h> +#include <asm/arch/dma.h> +#include "dma.h" + +#include "cpu.h" + +#include <asm/arch/regs-serial.h> +#include <asm/arch/regs-gpio.h> +#include <asm/arch/regs-ac97.h> +#include <asm/arch/regs-mem.h> +#include <asm/arch/regs-lcd.h> +#include <asm/arch/regs-sdi.h> +#include <asm/arch/regs-iis.h> +#include <asm/arch/regs-spi.h> + +static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = { + [DMACH_XD0] = { + .name = "xdreq0", + .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID, + }, + [DMACH_XD1] = { + .name = "xdreq1", + .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID, + }, + [DMACH_SDI] = { + .name = "sdi", + .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID, + .channels[1] = S3C2440_DCON_CH1_SDI | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID, + .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, + .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_SPI0] = { + .name = "spi0", + .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, + .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, + }, + [DMACH_SPI1] = { + .name = "spi1", + .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT, + .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT, + }, + [DMACH_UART0] = { + .name = "uart0", + .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, + }, + [DMACH_UART1] = { + .name = "uart1", + .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, + }, + [DMACH_UART2] = { + .name = "uart2", + .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, + .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, + }, + [DMACH_TIMER] = { + .name = "timer", + .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID, + .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID, + }, + [DMACH_I2S_IN] = { + .name = "i2s-sdi", + .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID, + .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_I2S_OUT] = { + .name = "i2s-sdo", + .channels[0] = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID, + .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID, + .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, + }, + [DMACH_PCM_IN] = { + .name = "pcm-in", + .channels[0] = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID, + .channels[2] = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID, + .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, + }, + [DMACH_PCM_OUT] = { + .name = "pcm-out", + .channels[1] = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID, + .channels[3] = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID, + .hw_addr.to = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, + }, + [DMACH_MIC_IN] = { + .name = "mic-in", + .channels[2] = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID, + .channels[3] = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID, + .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, + }, + [DMACH_USB_EP1] = { + .name = "usb-ep1", + .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID, + }, + [DMACH_USB_EP2] = { + .name = "usb-ep2", + .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID, + }, + [DMACH_USB_EP3] = { + .name = "usb-ep3", + .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID, + }, + [DMACH_USB_EP4] = { + .name = "usb-ep4", + .channels[3] = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID, + }, +}; + +static void s3c2440_dma_select(struct s3c2410_dma_chan *chan, + struct s3c24xx_dma_map *map) +{ + chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID; +} + +static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = { + .select = s3c2440_dma_select, + .dcon_mask = 7 << 24, + .map = s3c2440_dma_mappings, + .map_size = ARRAY_SIZE(s3c2440_dma_mappings), +}; + +static int s3c2440_dma_add(struct sys_device *sysdev) +{ + return s3c24xx_dma_init_map(&s3c2440_dma_sel); +} + +static struct sysdev_driver s3c2440_dma_driver = { + .add = s3c2440_dma_add, +}; + +static int __init s3c2440_dma_init(void) +{ + return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_dma_driver); +} + +arch_initcall(s3c2440_dma_init); + diff --git a/arch/arm/mach-s3c2410/s3c2440-dsc.c b/arch/arm/mach-s3c2410/s3c2440-dsc.c index 16fa2a3b38f..c92ea66ba45 100644 --- a/arch/arm/mach-s3c2410/s3c2440-dsc.c +++ b/arch/arm/mach-s3c2410/s3c2440-dsc.c @@ -8,11 +8,6 @@ * 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. - * - * Modifications: - * 29-Aug-2004 BJD Start of drive-strength control - * 09-Nov-2004 BJD Added symbol export - * 11-Jan-2005 BJD Include fix */ #include <linux/kernel.h> diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c index 1667ba1fa43..fc08febe2e5 100644 --- a/arch/arm/mach-s3c2410/s3c2440-irq.c +++ b/arch/arm/mach-s3c2410/s3c2440-irq.c @@ -119,7 +119,7 @@ static int s3c2440_irq_add(struct sys_device *sysdev) } static struct sysdev_driver s3c2440_irq_driver = { - .add = s3c2440_irq_add, + .add = s3c2440_irq_add, }; static int s3c2440_irq_init(void) diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/mach-s3c2410/s3c244x-irq.c index 44c5affa9b8..0d13546c350 100644 --- a/arch/arm/mach-s3c2410/s3c244x-irq.c +++ b/arch/arm/mach-s3c2410/s3c244x-irq.c @@ -120,7 +120,9 @@ static int s3c244x_irq_add(struct sys_device *sysdev) } static struct sysdev_driver s3c2440_irq_driver = { - .add = s3c244x_irq_add, + .add = s3c244x_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, }; static int s3c2440_irq_init(void) @@ -131,9 +133,12 @@ static int s3c2440_irq_init(void) arch_initcall(s3c2440_irq_init); static struct sysdev_driver s3c2442_irq_driver = { - .add = s3c244x_irq_add, + .add = s3c244x_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, }; + static int s3c2442_irq_init(void) { return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver); diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S index a7561a79fc8..2018c2e1dcc 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c2410/sleep.S @@ -41,15 +41,25 @@ .text - /* s3c2410_cpu_suspend + /* s3c2410_cpu_save * - * put the cpu into sleep mode + * save enough of the CPU state to allow us to re-start + * pm.c code. as we store items like the sp/lr, we will + * end up returning from this function when the cpu resumes + * so the return value is set to mark this. + * + * This arangement means we avoid having to flush the cache + * from this code. * * entry: - * r0 = sleep save block + * r0 = pointer to save block + * + * exit: + * r0 = 0 => we stored everything + * 1 => resumed from sleep */ -ENTRY(s3c2410_cpu_suspend) +ENTRY(s3c2410_cpu_save) stmfd sp!, { r4 - r12, lr } @@ store co-processor registers @@ -62,44 +72,14 @@ ENTRY(s3c2410_cpu_suspend) stmia r0, { r4 - r13 } - @@ flush the caches to ensure everything is back out to - @@ SDRAM before the core powers down - -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - bl arm920_flush_kern_cache_all -#endif - - @@ prepare cpu to sleep - - ldr r4, =S3C2410_REFRESH - ldr r5, =S3C24XX_MISCCR - ldr r6, =S3C2410_CLKCON - ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) - ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) - ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB) - - orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command - orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals - orr r9, r9, #S3C2410_CLKCON_POWER @ power down command - - teq pc, #0 @ first as a trial-run to load cache - bl s3c2410_do_sleep - teq r0, r0 @ now do it for real - b s3c2410_do_sleep @ - - @@ align next bit of code to cache line - .align 8 -s3c2410_do_sleep: - streq r7, [ r4 ] @ SDRAM sleep command - streq r8, [ r5 ] @ SDRAM power-down config - streq r9, [ r6 ] @ CPU sleep -1: beq 1b - mov pc, r14 + mov r0, #0 + ldmfd sp, { r4 - r12, pc } @@ return to the caller, after having the MMU @@ turned on, this restores the last bits from the @@ stack resume_with_mmu: + mov r0, #1 ldmfd sp!, { r4 - r12, pc } .ltorg diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c index 6b22d8f0a00..c635efa7cd3 100644 --- a/arch/arm/mach-s3c2410/usb-simtec.c +++ b/arch/arm/mach-s3c2410/usb-simtec.c @@ -10,12 +10,6 @@ * 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. - * - * Modifications: - * 14-Sep-2004 BJD Created - * 18-Oct-2004 BJD Cleanups, and added code to report OC cleared - * 09-Aug-2005 BJD Renamed s3c2410_report_oc to s3c2410_usb_report_oc - * 09-Aug-2005 BJD Ports powered only if both are enabled */ #define DEBUG diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index a0dfa390e34..6496eb645ce 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -91,30 +91,29 @@ static struct mcp_plat_data collie_mcp_data = { /* * low-level UART features. */ -static struct locomo_dev *uart_dev = NULL; +struct platform_device collie_locomo_device; static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) { - if (!uart_dev) return; - if (mctrl & TIOCM_RTS) - locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0); + locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0); else - locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1); + locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1); if (mctrl & TIOCM_DTR) - locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0); + locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0); else - locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1); + locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1); } static u_int collie_uart_get_mctrl(struct uart_port *port) { int ret = TIOCM_CD; unsigned int r; - if (!uart_dev) return ret; - r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); + r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); + if (r == -ENODEV) + return ret; if (r & LOCOMO_GPIO_CTS) ret |= TIOCM_CTS; if (r & LOCOMO_GPIO_DSR) @@ -130,13 +129,11 @@ static struct sa1100_port_fns collie_port_fns __initdata = { static int collie_uart_probe(struct locomo_dev *dev) { - uart_dev = dev; return 0; } static int collie_uart_remove(struct locomo_dev *dev) { - uart_dev = NULL; return 0; } @@ -170,7 +167,7 @@ static struct resource locomo_resources[] = { }, }; -static struct platform_device locomo_device = { +struct platform_device collie_locomo_device = { .name = "locomo", .id = 0, .num_resources = ARRAY_SIZE(locomo_resources), @@ -178,7 +175,7 @@ static struct platform_device locomo_device = { }; static struct platform_device *devices[] __initdata = { - &locomo_device, + &collie_locomo_device, &colliescoop_device, }; diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 41b370090b6..13bbd08ff84 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c @@ -117,7 +117,6 @@ static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int wh } else { switch (size) { case 1: - addr &= ~3; v = __raw_readb(addr); break; diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index b4f220dd5eb..c0bfb8212b7 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -15,6 +15,7 @@ config CPU_ARM610 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V3 if MMU select CPU_TLB_V3 if MMU help @@ -24,6 +25,20 @@ config CPU_ARM610 Say Y if you want support for the ARM610 processor. Otherwise, say N. +# ARM7TDMI +config CPU_ARM7TDMI + bool "Support ARM7TDMI processor" + depends on !MMU + select CPU_32v4T + select CPU_ABRT_LV4T + select CPU_CACHE_V4 + help + A 32-bit RISC microprocessor based on the ARM7 processor core + which has no memory control unit and cache. + + Say Y if you want support for the ARM7TDMI processor. + Otherwise, say N. + # ARM710 config CPU_ARM710 bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC @@ -31,6 +46,7 @@ config CPU_ARM710 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V3 if MMU select CPU_TLB_V3 if MMU help @@ -50,6 +66,7 @@ config CPU_ARM720T select CPU_ABRT_LV4T select CPU_CACHE_V4 select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WT if MMU select CPU_TLB_V4WT if MMU help @@ -59,6 +76,36 @@ config CPU_ARM720T Say Y if you want support for the ARM720T processor. Otherwise, say N. +# ARM740T +config CPU_ARM740T + bool "Support ARM740T processor" if ARCH_INTEGRATOR + depends on !MMU + select CPU_32v4T + select CPU_ABRT_LV4T + select CPU_CACHE_V3 # although the core is v4t + select CPU_CP15_MPU + help + A 32-bit RISC processor with 8KB cache or 4KB variants, + write buffer and MPU(Protection Unit) built around + an ARM7TDMI core. + + Say Y if you want support for the ARM740T processor. + Otherwise, say N. + +# ARM9TDMI +config CPU_ARM9TDMI + bool "Support ARM9TDMI processor" + depends on !MMU + select CPU_32v4T + select CPU_ABRT_NOMMU + select CPU_CACHE_V4 + help + A 32-bit RISC microprocessor based on the ARM9 processor core + which has no memory control unit and cache. + + Say Y if you want support for the ARM9TDMI processor. + Otherwise, say N. + # ARM920T config CPU_ARM920T bool "Support ARM920T processor" @@ -68,6 +115,7 @@ config CPU_ARM920T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -89,6 +137,7 @@ config CPU_ARM922T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -108,6 +157,7 @@ config CPU_ARM925T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -126,6 +176,7 @@ config CPU_ARM926T select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -136,6 +187,39 @@ config CPU_ARM926T Say Y if you want support for the ARM926T processor. Otherwise, say N. +# ARM940T +config CPU_ARM940T + bool "Support ARM940T processor" if ARCH_INTEGRATOR + depends on !MMU + select CPU_32v4T + select CPU_ABRT_NOMMU + select CPU_CACHE_VIVT + select CPU_CP15_MPU + help + ARM940T is a member of the ARM9TDMI family of general- + purpose microprocessors with MPU and seperate 4KB + instruction and 4KB data cases, each with a 4-word line + length. + + Say Y if you want support for the ARM940T processor. + Otherwise, say N. + +# ARM946E-S +config CPU_ARM946E + bool "Support ARM946E-S processor" if ARCH_INTEGRATOR + depends on !MMU + select CPU_32v5 + select CPU_ABRT_NOMMU + select CPU_CACHE_VIVT + select CPU_CP15_MPU + help + ARM946E-S is a member of the ARM9E-S family of high- + performance, 32-bit system-on-chip processor solutions. + The TCM and ARMv5TE 32-bit instruction set is supported. + + Say Y if you want support for the ARM946E-S processor. + Otherwise, say N. + # ARM1020 - needs validating config CPU_ARM1020 bool "Support ARM1020T (rev 0) processor" @@ -144,6 +228,7 @@ config CPU_ARM1020 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -161,6 +246,7 @@ config CPU_ARM1020E select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU depends on n @@ -172,6 +258,7 @@ config CPU_ARM1022 select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU # can probably do better select CPU_TLB_V4WBI if MMU help @@ -189,6 +276,7 @@ config CPU_ARM1026 select CPU_32v5 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU # can probably do better select CPU_TLB_V4WBI if MMU help @@ -207,6 +295,7 @@ config CPU_SA110 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WB if MMU help @@ -227,16 +316,18 @@ config CPU_SA1100 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_TLB_V4WB if MMU # XScale config CPU_XSCALE bool - depends on ARCH_IOP3XX || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 + depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 default y select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_TLB_V4WBI if MMU # XScale Core Version 3 @@ -247,6 +338,7 @@ config CPU_XSC3 select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT + select CPU_CP15_MMU select CPU_TLB_V4WBI if MMU select IO_36 @@ -258,6 +350,7 @@ config CPU_V6 select CPU_ABRT_EV6 select CPU_CACHE_V6 select CPU_CACHE_VIPT + select CPU_CP15_MMU select CPU_COPY_V6 if MMU select CPU_TLB_V6 if MMU @@ -299,6 +392,9 @@ config CPU_32v6 bool # The abort model +config CPU_ABRT_NOMMU + bool + config CPU_ABRT_EV4 bool @@ -380,6 +476,23 @@ config CPU_TLB_V6 endif +config CPU_CP15 + bool + help + Processor has the CP15 register. + +config CPU_CP15_MMU + bool + select CPU_CP15 + help + Processor has the CP15 register, which has MMU related registers. + +config CPU_CP15_MPU + bool + select CPU_CP15 + help + Processor has the CP15 register, which has MPU related registers. + # # CPU supports 36-bit I/O # @@ -390,7 +503,7 @@ comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 + depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 default y help Say Y if you want to include kernel support for running user space @@ -411,23 +524,48 @@ config CPU_BIG_ENDIAN port must properly enable any big-endian related features of your chipset/board/processor. +config CPU_HIGH_VECTOR + depends !MMU && CPU_CP15 && !CPU_ARM740T + bool "Select the High exception vector" + default n + help + Say Y here to select high exception vector(0xFFFF0000~). + The exception vector can be vary depending on the platform + design in nommu mode. If your platform needs to select + high exception vector, say Y. + Otherwise or if you are unsure, say N, and the low exception + vector (0x00000000~) will be used. + config CPU_ICACHE_DISABLE - bool "Disable I-Cache" - depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6 + bool "Disable I-Cache (I-bit)" + depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3) help Say Y here to disable the processor instruction cache. Unless you have a reason not to or are unsure, say N. config CPU_DCACHE_DISABLE - bool "Disable D-Cache" - depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6 + bool "Disable D-Cache (C-bit)" + depends on CPU_CP15 help Say Y here to disable the processor data cache. Unless you have a reason not to or are unsure, say N. +config CPU_DCACHE_SIZE + hex + depends on CPU_ARM740T || CPU_ARM946E + default 0x00001000 if CPU_ARM740T + default 0x00002000 # default size for ARM946E-S + help + Some cores are synthesizable to have various sized cache. For + ARM946E-S case, it can vary from 0KB to 1MB. + To support such cache operations, it is efficient to know the size + before compile time. + If your SoC is configured to have a different size, define the value + here with proper conditions. + config CPU_DCACHE_WRITETHROUGH bool "Force write through D-cache" - depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE + depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE default y if CPU_ARM925T help Say Y here to use the data cache in writethrough mode. Unless you @@ -435,7 +573,7 @@ config CPU_DCACHE_WRITETHROUGH config CPU_CACHE_ROUND_ROBIN bool "Round robin I and D cache replacement algorithm" - depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) + depends on (CPU_ARM926T || CPU_ARM946E || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) help Say Y here to use the predictable round-robin cache replacement policy. Unless you specifically require this or are unsure, say N. diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 21a2770226e..d2f5672ecf6 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -6,7 +6,7 @@ obj-y := consistent.o extable.o fault.o init.o \ iomap.o obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ - mm-armv.o + pgd.o mmu.o ifneq ($(CONFIG_MMU),y) obj-y += nommu.o @@ -17,6 +17,7 @@ obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o +obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o obj-$(CONFIG_CPU_ABRT_EV4T) += abort-ev4t.o obj-$(CONFIG_CPU_ABRT_LV4T) += abort-lv4t.o @@ -33,7 +34,7 @@ obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o -obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o +obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o @@ -46,11 +47,16 @@ obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o +obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o +obj-$(CONFIG_CPU_ARM740T) += proc-arm740.o +obj-$(CONFIG_CPU_ARM9TDMI) += proc-arm9tdmi.o obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o +obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o +obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index db743e51021..9fb7b0e25ea 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S @@ -19,11 +19,16 @@ */ ENTRY(v4t_late_abort) tst r3, #PSR_T_BIT @ check for thumb mode +#ifdef CONFIG_CPU_CP15_MMU mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR +#else + mov r0, #0 @ clear r0, r1 (no FSR/FAR) + mov r1, #0 +#endif bne .data_thumb_abort ldr r8, [r2] @ read arm instruction - bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR tst r8, #1 << 20 @ L = 1 -> write? orreq r1, r1, #1 << 11 @ yes. and r7, r8, #15 << 24 diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S new file mode 100644 index 00000000000..a7cc7f9ee45 --- /dev/null +++ b/arch/arm/mm/abort-nommu.S @@ -0,0 +1,19 @@ +#include <linux/linkage.h> +#include <asm/assembler.h> +/* + * Function: nommu_early_abort + * + * Params : r2 = address of aborted instruction + * : r3 = saved SPSR + * + * Returns : r0 = 0 (abort address) + * : r1 = 0 (FSR) + * + * Note: There is no FSR/FAR on !CPU_CP15_MMU cores. + * Just fill zero into the registers. + */ + .align 5 +ENTRY(nommu_early_abort) + mov r0, #0 @ clear r0, r1 (no FSR/FAR) + mov r1, #0 + mov pc, lr diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index e0d21bbbe7d..aa109f074dd 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -735,7 +735,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) /* * We got a fault - fix it up, or die. */ - do_bad_area(current, current->mm, addr, fsr, regs); + do_bad_area(addr, fsr, regs); return 0; swp: diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S index b8ad5d58ebe..b2908063ed6 100644 --- a/arch/arm/mm/cache-v4.S +++ b/arch/arm/mm/cache-v4.S @@ -29,9 +29,13 @@ ENTRY(v4_flush_user_cache_all) * Clean and invalidate the entire cache. */ ENTRY(v4_flush_kern_cache_all) +#ifdef CPU_CP15 mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush ID cache mov pc, lr +#else + /* FALLTHROUGH */ +#endif /* * flush_user_cache_range(start, end, flags) @@ -44,9 +48,13 @@ ENTRY(v4_flush_kern_cache_all) * - flags - vma_area_struct flags describing address space */ ENTRY(v4_flush_user_cache_range) +#ifdef CPU_CP15 mov ip, #0 mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache mov pc, lr +#else + /* FALLTHROUGH */ +#endif /* * coherent_kern_range(start, end) @@ -108,8 +116,10 @@ ENTRY(v4_dma_inv_range) * - end - virtual end address */ ENTRY(v4_dma_flush_range) +#ifdef CPU_CP15 mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush ID cache +#endif /* FALLTHROUGH */ /* diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c new file mode 100644 index 00000000000..79e80020242 --- /dev/null +++ b/arch/arm/mm/context.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mm/context.c + * + * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, 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. + */ +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/mmu_context.h> +#include <asm/tlbflush.h> + +unsigned int cpu_last_asid = { 1 << ASID_BITS }; + +/* + * We fork()ed a process, and we need a new context for the child + * to run in. We reserve version 0 for initial tasks so we will + * always allocate an ASID. + */ +void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + mm->context.id = 0; +} + +void __new_context(struct mm_struct *mm) +{ + unsigned int asid; + + asid = ++cpu_last_asid; + if (asid == 0) + asid = cpu_last_asid = 1 << ASID_BITS; + + /* + * If we've used up all our ASIDs, we need + * to start a new version and flush the TLB. + */ + if ((asid & ~ASID_MASK) == 0) + flush_tlb_all(); + + mm->context.id = asid; +} diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c index fc69dccdace..df1645e14b4 100644 --- a/arch/arm/mm/copypage-v4mc.c +++ b/arch/arm/mm/copypage-v4mc.c @@ -20,6 +20,8 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> +#include "mm.h" + /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently. @@ -27,8 +29,6 @@ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_CACHEABLE) -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - static DEFINE_SPINLOCK(minicache_lock); /* diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 269ce6913ee..3d0d3a963d2 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -17,6 +17,8 @@ #include <asm/tlbflush.h> #include <asm/cacheflush.h> +#include "mm.h" + #if SHMLBA > 16384 #error FIX ME #endif @@ -24,8 +26,6 @@ #define from_address (0xffff8000) #define to_address (0xffffc000) -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - static DEFINE_SPINLOCK(v6_lock); /* diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c index 42a6ee255ce..84ebe0aa379 100644 --- a/arch/arm/mm/copypage-xscale.c +++ b/arch/arm/mm/copypage-xscale.c @@ -20,6 +20,8 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> +#include "mm.h" + /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently. @@ -29,8 +31,6 @@ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_CACHEABLE) -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - static DEFINE_SPINLOCK(minicache_lock); /* diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index c5e0622c776..f0943d160ff 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -131,10 +131,11 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, force_sig_info(sig, &si, tsk); } -void -do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr, - unsigned int fsr, struct pt_regs *regs) +void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->active_mm; + /* * If we are in kernel mode at this point, we * have no context to handle this fault with. @@ -319,7 +320,6 @@ static int do_translation_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - struct task_struct *tsk; unsigned int index; pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; @@ -351,9 +351,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr, return 0; bad_area: - tsk = current; - - do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); + do_bad_area(addr, fsr, regs); return 0; } @@ -364,8 +362,7 @@ bad_area: static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - struct task_struct *tsk = current; - do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); + do_bad_area(addr, fsr, regs); return 0; } diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h index 73b59e83227..49e9e3804de 100644 --- a/arch/arm/mm/fault.h +++ b/arch/arm/mm/fault.h @@ -1,6 +1,3 @@ -void do_bad_area(struct task_struct *tsk, struct mm_struct *mm, - unsigned long addr, unsigned int fsr, struct pt_regs *regs); - -void show_pte(struct mm_struct *mm, unsigned long addr); +void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs); unsigned long search_exception_table(unsigned long addr); diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index d438ce41cdd..454205b789d 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -15,12 +15,12 @@ #include <asm/system.h> #include <asm/tlbflush.h> +#include "mm.h" + #ifdef CONFIG_CPU_CACHE_VIPT #define ALIAS_FLUSH_START 0xffff4000 -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) { unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); @@ -107,7 +107,7 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, /* VIPT non-aliasing cache */ if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask) && - vma->vm_flags | VM_EXEC) { + vma->vm_flags & VM_EXEC) { unsigned long addr = (unsigned long)kaddr; /* only flushing the kernel mapping on non-aliasing VIPT */ __cpuc_coherent_kern_range(addr, addr + len); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index fe3f7f62500..22217fe2650 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -25,10 +25,9 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); +#include "mm.h" -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -extern void _stext, _text, _etext, __data_start, _end, __init_begin, __init_end; +extern void _text, _etext, __data_start, _end, __init_begin, __init_end; extern unsigned long phys_initrd_start; extern unsigned long phys_initrd_size; @@ -38,12 +37,6 @@ extern unsigned long phys_initrd_size; */ static struct meminfo meminfo __initdata = { 0, }; -/* - * empty_zero_page is a special page that is used for - * zero-initialized data and COW. - */ -struct page *empty_zero_page; - void show_mem(void) { int free = 0, total = 0, reserved = 0; @@ -83,16 +76,6 @@ void show_mem(void) printk("%d pages swap cached\n", cached); } -static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) -{ - return pmd_offset(pgd, virt); -} - -static inline pmd_t *pmd_off_k(unsigned long virt) -{ - return pmd_off(pgd_offset_k(virt), virt); -} - #define for_each_nodebank(iter,mi,no) \ for (iter = 0; iter < mi->nr_banks; iter++) \ if (mi->bank[iter].node == no) @@ -176,62 +159,20 @@ static int __init check_initrd(struct meminfo *mi) return initrd_node; } -/* - * Reserve the various regions of node 0 - */ -static __init void reserve_node_zero(pg_data_t *pgdat) +static inline void map_memory_bank(struct membank *bank) { - unsigned long res_size = 0; - - /* - * Register the kernel text and data with bootmem. - * Note that this can only be in node 0. - */ -#ifdef CONFIG_XIP_KERNEL - reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); -#else - reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); -#endif - - /* - * Reserve the page tables. These are already in use, - * and can only be in node 0. - */ - reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), - PTRS_PER_PGD * sizeof(pgd_t)); - - /* - * Hmm... This should go elsewhere, but we really really need to - * stop things allocating the low memory; ideally we need a better - * implementation of GFP_DMA which does not assume that DMA-able - * memory starts at zero. - */ - if (machine_is_integrator() || machine_is_cintegrator()) - res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; +#ifdef CONFIG_MMU + struct map_desc map; - /* - * These should likewise go elsewhere. They pre-reserve the - * screen memory region at the start of main system memory. - */ - if (machine_is_edb7211()) - res_size = 0x00020000; - if (machine_is_p720t()) - res_size = 0x00014000; + map.pfn = __phys_to_pfn(bank->start); + map.virtual = __phys_to_virt(bank->start); + map.length = bank->size; + map.type = MT_MEMORY; -#ifdef CONFIG_SA1111 - /* - * Because of the SA1111 DMA bug, we want to preserve our - * precious DMA-able memory... - */ - res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + create_mapping(&map); #endif - if (res_size) - reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); } -void __init build_mem_type_table(void); -void __init create_mapping(struct map_desc *md); - static unsigned long __init bootmem_init_node(int node, int initrd_node, struct meminfo *mi) { @@ -248,23 +189,18 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) * Calculate the pfn range, and map the memory banks for this node. */ for_each_nodebank(i, mi, node) { + struct membank *bank = &mi->bank[i]; unsigned long start, end; - struct map_desc map; - start = mi->bank[i].start >> PAGE_SHIFT; - end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT; + start = bank->start >> PAGE_SHIFT; + end = (bank->start + bank->size) >> PAGE_SHIFT; if (start_pfn > start) start_pfn = start; if (end_pfn < end) end_pfn = end; - map.pfn = __phys_to_pfn(mi->bank[i].start); - map.virtual = __phys_to_virt(mi->bank[i].start); - map.length = mi->bank[i].size; - map.type = MT_MEMORY; - - create_mapping(&map); + map_memory_bank(bank); } /* @@ -346,9 +282,9 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) return end_pfn; } -static void __init bootmem_init(struct meminfo *mi) +void __init bootmem_init(struct meminfo *mi) { - unsigned long addr, memend_pfn = 0; + unsigned long memend_pfn = 0; int node, initrd_node, i; /* @@ -361,26 +297,6 @@ static void __init bootmem_init(struct meminfo *mi) memcpy(&meminfo, mi, sizeof(meminfo)); /* - * Clear out all the mappings below the kernel image. - */ - for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); -#ifdef CONFIG_XIP_KERNEL - /* The XIP kernel is mapped in the module area -- skip over it */ - addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; -#endif - for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - - /* - * Clear out all the kernel space mappings, except for the first - * memory bank, up to the end of the vmalloc region. - */ - for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); - addr < VMALLOC_END; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - - /* * Locate which node contains the ramdisk image, if any. */ initrd_node = check_initrd(mi); @@ -413,114 +329,6 @@ static void __init bootmem_init(struct meminfo *mi) max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET; } -/* - * Set up device the mappings. Since we clear out the page tables for all - * mappings above VMALLOC_END, we will remove any debug device mappings. - * This means you have to be careful how you debug this function, or any - * called function. This means you can't use any function or debugging - * method which may touch any device, otherwise the kernel _will_ crash. - */ -static void __init devicemaps_init(struct machine_desc *mdesc) -{ - struct map_desc map; - unsigned long addr; - void *vectors; - - /* - * Allocate the vector page early. - */ - vectors = alloc_bootmem_low_pages(PAGE_SIZE); - BUG_ON(!vectors); - - for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - - /* - * Map the kernel if it is XIP. - * It is always first in the modulearea. - */ -#ifdef CONFIG_XIP_KERNEL - map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK); - map.virtual = MODULE_START; - map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK; - map.type = MT_ROM; - create_mapping(&map); -#endif - - /* - * Map the cache flushing regions. - */ -#ifdef FLUSH_BASE - map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); - map.virtual = FLUSH_BASE; - map.length = SZ_1M; - map.type = MT_CACHECLEAN; - create_mapping(&map); -#endif -#ifdef FLUSH_BASE_MINICACHE - map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); - map.virtual = FLUSH_BASE_MINICACHE; - map.length = SZ_1M; - map.type = MT_MINICLEAN; - create_mapping(&map); -#endif - - /* - * Create a mapping for the machine vectors at the high-vectors - * location (0xffff0000). If we aren't using high-vectors, also - * create a mapping at the low-vectors virtual address. - */ - map.pfn = __phys_to_pfn(virt_to_phys(vectors)); - map.virtual = 0xffff0000; - map.length = PAGE_SIZE; - map.type = MT_HIGH_VECTORS; - create_mapping(&map); - - if (!vectors_high()) { - map.virtual = 0; - map.type = MT_LOW_VECTORS; - create_mapping(&map); - } - - /* - * Ask the machine support to map in the statically mapped devices. - */ - if (mdesc->map_io) - mdesc->map_io(); - - /* - * Finally flush the caches and tlb to ensure that we're in a - * consistent state wrt the writebuffer. This also ensures that - * any write-allocated cache lines in the vector page are written - * back. After this point, we can start to touch devices again. - */ - local_flush_tlb_all(); - flush_cache_all(); -} - -/* - * paging_init() sets up the page tables, initialises the zone memory - * maps, and sets up the zero page, bad page and bad page tables. - */ -void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) -{ - void *zero_page; - - build_mem_type_table(); - bootmem_init(mi); - devicemaps_init(mdesc); - - top_pmd = pmd_off_k(0xffff0000); - - /* - * allocate the zero page. Note that we count on this going ok. - */ - zero_page = alloc_bootmem_low_pages(PAGE_SIZE); - memzero(zero_page, PAGE_SIZE); - empty_zero_page = virt_to_page(zero_page); - flush_dcache_page(empty_zero_page); -} - static inline void free_area(unsigned long addr, unsigned long end, char *s) { unsigned int size = (end - addr) >> 10; diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c deleted file mode 100644 index 38769f5862b..00000000000 --- a/arch/arm/mm/mm-armv.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * linux/arch/arm/mm/mm-armv.c - * - * Copyright (C) 1998-2005 Russell King - * - * 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. - * - * Page table sludge for ARM v3 and v4 processor architectures. - */ -#include <linux/module.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/bootmem.h> -#include <linux/highmem.h> -#include <linux/nodemask.h> - -#include <asm/pgalloc.h> -#include <asm/page.h> -#include <asm/setup.h> -#include <asm/tlbflush.h> - -#include <asm/mach/map.h> - -#define CPOLICY_UNCACHED 0 -#define CPOLICY_BUFFERED 1 -#define CPOLICY_WRITETHROUGH 2 -#define CPOLICY_WRITEBACK 3 -#define CPOLICY_WRITEALLOC 4 - -static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; -static unsigned int ecc_mask __initdata = 0; -pgprot_t pgprot_kernel; - -EXPORT_SYMBOL(pgprot_kernel); - -pmd_t *top_pmd; - -struct cachepolicy { - const char policy[16]; - unsigned int cr_mask; - unsigned int pmd; - unsigned int pte; -}; - -static struct cachepolicy cache_policies[] __initdata = { - { - .policy = "uncached", - .cr_mask = CR_W|CR_C, - .pmd = PMD_SECT_UNCACHED, - .pte = 0, - }, { - .policy = "buffered", - .cr_mask = CR_C, - .pmd = PMD_SECT_BUFFERED, - .pte = PTE_BUFFERABLE, - }, { - .policy = "writethrough", - .cr_mask = 0, - .pmd = PMD_SECT_WT, - .pte = PTE_CACHEABLE, - }, { - .policy = "writeback", - .cr_mask = 0, - .pmd = PMD_SECT_WB, - .pte = PTE_BUFFERABLE|PTE_CACHEABLE, - }, { - .policy = "writealloc", - .cr_mask = 0, - .pmd = PMD_SECT_WBWA, - .pte = PTE_BUFFERABLE|PTE_CACHEABLE, - } -}; - -/* - * These are useful for identifing cache coherency - * problems by allowing the cache or the cache and - * writebuffer to be turned off. (Note: the write - * buffer should not be on and the cache off). - */ -static void __init early_cachepolicy(char **p) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(cache_policies); i++) { - int len = strlen(cache_policies[i].policy); - - if (memcmp(*p, cache_policies[i].policy, len) == 0) { - cachepolicy = i; - cr_alignment &= ~cache_policies[i].cr_mask; - cr_no_alignment &= ~cache_policies[i].cr_mask; - *p += len; - break; - } - } - if (i == ARRAY_SIZE(cache_policies)) - printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); - flush_cache_all(); - set_cr(cr_alignment); -} - -static void __init early_nocache(char **__unused) -{ - char *p = "buffered"; - printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); - early_cachepolicy(&p); -} - -static void __init early_nowrite(char **__unused) -{ - char *p = "uncached"; - printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); - early_cachepolicy(&p); -} - -static void __init early_ecc(char **p) -{ - if (memcmp(*p, "on", 2) == 0) { - ecc_mask = PMD_PROTECTION; - *p += 2; - } else if (memcmp(*p, "off", 3) == 0) { - ecc_mask = 0; - *p += 3; - } -} - -__early_param("nocache", early_nocache); -__early_param("nowb", early_nowrite); -__early_param("cachepolicy=", early_cachepolicy); -__early_param("ecc=", early_ecc); - -static int __init noalign_setup(char *__unused) -{ - cr_alignment &= ~CR_A; - cr_no_alignment &= ~CR_A; - set_cr(cr_alignment); - return 1; -} - -__setup("noalign", noalign_setup); - -#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) - -static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) -{ - return pmd_offset(pgd, virt); -} - -static inline pmd_t *pmd_off_k(unsigned long virt) -{ - return pmd_off(pgd_offset_k(virt), virt); -} - -/* - * need to get a 16k page for level 1 - */ -pgd_t *get_pgd_slow(struct mm_struct *mm) -{ - pgd_t *new_pgd, *init_pgd; - pmd_t *new_pmd, *init_pmd; - pte_t *new_pte, *init_pte; - - new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); - if (!new_pgd) - goto no_pgd; - - memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); - - /* - * Copy over the kernel and IO PGD entries - */ - init_pgd = pgd_offset_k(0); - memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, - (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); - - clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); - - if (!vectors_high()) { - /* - * On ARM, first page must always be allocated since it - * contains the machine vectors. - */ - new_pmd = pmd_alloc(mm, new_pgd, 0); - if (!new_pmd) - goto no_pmd; - - new_pte = pte_alloc_map(mm, new_pmd, 0); - if (!new_pte) - goto no_pte; - - init_pmd = pmd_offset(init_pgd, 0); - init_pte = pte_offset_map_nested(init_pmd, 0); - set_pte(new_pte, *init_pte); - pte_unmap_nested(init_pte); - pte_unmap(new_pte); - } - - return new_pgd; - -no_pte: - pmd_free(new_pmd); -no_pmd: - free_pages((unsigned long)new_pgd, 2); -no_pgd: - return NULL; -} - -void free_pgd_slow(pgd_t *pgd) -{ - pmd_t *pmd; - struct page *pte; - - if (!pgd) - return; - - /* pgd is always present and good */ - pmd = pmd_off(pgd, 0); - if (pmd_none(*pmd)) - goto free; - if (pmd_bad(*pmd)) { - pmd_ERROR(*pmd); - pmd_clear(pmd); - goto free; - } - - pte = pmd_page(*pmd); - pmd_clear(pmd); - dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); - pte_lock_deinit(pte); - pte_free(pte); - pmd_free(pmd); -free: - free_pages((unsigned long) pgd, 2); -} - -/* - * Create a SECTION PGD between VIRT and PHYS in domain - * DOMAIN with protection PROT. This operates on half- - * pgdir entry increments. - */ -static inline void -alloc_init_section(unsigned long virt, unsigned long phys, int prot) -{ - pmd_t *pmdp = pmd_off_k(virt); - - if (virt & (1 << 20)) - pmdp++; - - *pmdp = __pmd(phys | prot); - flush_pmd_entry(pmdp); -} - -/* - * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT - */ -static inline void -alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) -{ - int i; - - for (i = 0; i < 16; i += 1) { - alloc_init_section(virt, phys, prot | PMD_SECT_SUPER); - - virt += (PGDIR_SIZE / 2); - } -} - -/* - * Add a PAGE mapping between VIRT and PHYS in domain - * DOMAIN with protection PROT. Note that due to the - * way we map the PTEs, we must allocate two PTE_SIZE'd - * blocks - one for the Linux pte table, and one for - * the hardware pte table. - */ -static inline void -alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) -{ - pmd_t *pmdp = pmd_off_k(virt); - pte_t *ptep; - - if (pmd_none(*pmdp)) { - ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * - sizeof(pte_t)); - - __pmd_populate(pmdp, __pa(ptep) | prot_l1); - } - ptep = pte_offset_kernel(pmdp, virt); - - set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); -} - -struct mem_types { - unsigned int prot_pte; - unsigned int prot_l1; - unsigned int prot_sect; - unsigned int domain; -}; - -static struct mem_types mem_types[] __initdata = { - [MT_DEVICE] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_WRITE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | - PMD_SECT_AP_WRITE, - .domain = DOMAIN_IO, - }, - [MT_CACHECLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4, - .domain = DOMAIN_KERNEL, - }, - [MT_MINICLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE, - .domain = DOMAIN_KERNEL, - }, - [MT_LOW_VECTORS] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_EXEC, - .prot_l1 = PMD_TYPE_TABLE, - .domain = DOMAIN_USER, - }, - [MT_HIGH_VECTORS] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_USER | L_PTE_EXEC, - .prot_l1 = PMD_TYPE_TABLE, - .domain = DOMAIN_USER, - }, - [MT_MEMORY] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE, - .domain = DOMAIN_KERNEL, - }, - [MT_ROM] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4, - .domain = DOMAIN_KERNEL, - }, - [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_WRITE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | - PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | - PMD_SECT_TEX(1), - .domain = DOMAIN_IO, - }, - [MT_NONSHARED_DEVICE] = { - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV | - PMD_SECT_AP_WRITE, - .domain = DOMAIN_IO, - } -}; - -/* - * Adjust the PMD section entries according to the CPU in use. - */ -void __init build_mem_type_table(void) -{ - struct cachepolicy *cp; - unsigned int cr = get_cr(); - unsigned int user_pgprot, kern_pgprot; - int cpu_arch = cpu_architecture(); - int i; - -#if defined(CONFIG_CPU_DCACHE_DISABLE) - if (cachepolicy > CPOLICY_BUFFERED) - cachepolicy = CPOLICY_BUFFERED; -#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) - if (cachepolicy > CPOLICY_WRITETHROUGH) - cachepolicy = CPOLICY_WRITETHROUGH; -#endif - if (cpu_arch < CPU_ARCH_ARMv5) { - if (cachepolicy >= CPOLICY_WRITEALLOC) - cachepolicy = CPOLICY_WRITEBACK; - ecc_mask = 0; - } - - /* - * Xscale must not have PMD bit 4 set for section mappings. - */ - if (cpu_is_xscale()) - for (i = 0; i < ARRAY_SIZE(mem_types); i++) - mem_types[i].prot_sect &= ~PMD_BIT4; - - /* - * ARMv5 and lower, excluding Xscale, bit 4 must be set for - * page tables. - */ - if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale()) - for (i = 0; i < ARRAY_SIZE(mem_types); i++) - if (mem_types[i].prot_l1) - mem_types[i].prot_l1 |= PMD_BIT4; - - cp = &cache_policies[cachepolicy]; - kern_pgprot = user_pgprot = cp->pte; - - /* - * Enable CPU-specific coherency if supported. - * (Only available on XSC3 at the moment.) - */ - if (arch_is_coherent()) { - if (cpu_is_xsc3()) { - mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; - } - } - - /* - * ARMv6 and above have extended page tables. - */ - if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { - /* - * bit 4 becomes XN which we must clear for the - * kernel memory mapping. - */ - mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN; - mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN; - - /* - * Mark cache clean areas and XIP ROM read only - * from SVC mode and no access from userspace. - */ - mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - - /* - * Mark the device area as "shared device" - */ - mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; - mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; - - /* - * User pages need to be mapped with the ASID - * (iow, non-global) - */ - user_pgprot |= L_PTE_ASID; - -#ifdef CONFIG_SMP - /* - * Mark memory with the "shared" attribute for SMP systems - */ - user_pgprot |= L_PTE_SHARED; - kern_pgprot |= L_PTE_SHARED; - mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; -#endif - } - - for (i = 0; i < 16; i++) { - unsigned long v = pgprot_val(protection_map[i]); - v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot; - protection_map[i] = __pgprot(v); - } - - mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot; - mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot; - - if (cpu_arch >= CPU_ARCH_ARMv5) { -#ifndef CONFIG_SMP - /* - * Only use write-through for non-SMP systems - */ - mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; - mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; -#endif - } else { - mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); - } - - pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | - L_PTE_DIRTY | L_PTE_WRITE | - L_PTE_EXEC | kern_pgprot); - - mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; - mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; - mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; - mem_types[MT_ROM].prot_sect |= cp->pmd; - - switch (cp->pmd) { - case PMD_SECT_WT: - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; - break; - case PMD_SECT_WB: - case PMD_SECT_WBWA: - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; - break; - } - printk("Memory policy: ECC %sabled, Data cache %s\n", - ecc_mask ? "en" : "dis", cp->policy); -} - -#define vectors_base() (vectors_high() ? 0xffff0000 : 0) - -/* - * Create the page directory entries and any necessary - * page tables for the mapping specified by `md'. We - * are able to cope here with varying sizes and address - * offsets, and we take full advantage of sections and - * supersections. - */ -void __init create_mapping(struct map_desc *md) -{ - unsigned long virt, length; - int prot_sect, prot_l1, domain; - pgprot_t prot_pte; - unsigned long off = (u32)__pfn_to_phys(md->pfn); - - if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { - printk(KERN_WARNING "BUG: not creating mapping for " - "0x%08llx at 0x%08lx in user region\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - - if ((md->type == MT_DEVICE || md->type == MT_ROM) && - md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { - printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " - "overlaps vmalloc space\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - } - - domain = mem_types[md->type].domain; - prot_pte = __pgprot(mem_types[md->type].prot_pte); - prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); - prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); - - /* - * Catch 36-bit addresses - */ - if(md->pfn >= 0x100000) { - if(domain) { - printk(KERN_ERR "MM: invalid domain in supersection " - "mapping for 0x%08llx at 0x%08lx\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - if((md->virtual | md->length | __pfn_to_phys(md->pfn)) - & ~SUPERSECTION_MASK) { - printk(KERN_ERR "MM: cannot create mapping for " - "0x%08llx at 0x%08lx invalid alignment\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - - /* - * Shift bits [35:32] of address into bits [23:20] of PMD - * (See ARMv6 spec). - */ - off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); - } - - virt = md->virtual; - off -= virt; - length = md->length; - - if (mem_types[md->type].prot_l1 == 0 && - (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { - printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " - "be mapped using pages, ignoring.\n", - __pfn_to_phys(md->pfn), md->virtual); - return; - } - - while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, prot_l1, prot_pte); - - virt += PAGE_SIZE; - length -= PAGE_SIZE; - } - - /* N.B. ARMv6 supersections are only defined to work with domain 0. - * Since domain assignments can in fact be arbitrary, the - * 'domain == 0' check below is required to insure that ARMv6 - * supersections are only allocated for domain 0 regardless - * of the actual domain assignments in use. - */ - if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) - && domain == 0) { - /* - * Align to supersection boundary if !high pages. - * High pages have already been checked for proper - * alignment above and they will fail the SUPSERSECTION_MASK - * check because of the way the address is encoded into - * offset. - */ - if (md->pfn <= 0x100000) { - while ((virt & ~SUPERSECTION_MASK || - (virt + off) & ~SUPERSECTION_MASK) && - length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); - - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); - } - } - - while (length >= SUPERSECTION_SIZE) { - alloc_init_supersection(virt, virt + off, prot_sect); - - virt += SUPERSECTION_SIZE; - length -= SUPERSECTION_SIZE; - } - } - - /* - * A section mapping covers half a "pgdir" entry. - */ - while (length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); - - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); - } - - while (length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, prot_l1, prot_pte); - - virt += PAGE_SIZE; - length -= PAGE_SIZE; - } -} - -/* - * In order to soft-boot, we need to insert a 1:1 mapping in place of - * the user-mode pages. This will then ensure that we have predictable - * results when turning the mmu off - */ -void setup_mm_for_reboot(char mode) -{ - unsigned long base_pmdval; - pgd_t *pgd; - int i; - - if (current->mm && current->mm->pgd) - pgd = current->mm->pgd; - else - pgd = init_mm.pgd; - - base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; - if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) - base_pmdval |= PMD_BIT4; - - for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) { - unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval; - pmd_t *pmd; - - pmd = pmd_off(pgd, i << PGDIR_SHIFT); - pmd[0] = __pmd(pmdval); - pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); - flush_pmd_entry(pmd); - } -} - -/* - * Create the architecture specific mappings - */ -void __init iotable_init(struct map_desc *io_desc, int nr) -{ - int i; - - for (i = 0; i < nr; i++) - create_mapping(io_desc + i); -} diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h new file mode 100644 index 00000000000..bb2bc9ab6bd --- /dev/null +++ b/arch/arm/mm/mm.h @@ -0,0 +1,22 @@ +/* the upper-most page table pointer */ +extern pmd_t *top_pmd; + +#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) + +static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) +{ + return pmd_offset(pgd, virt); +} + +static inline pmd_t *pmd_off_k(unsigned long virt) +{ + return pmd_off(pgd_offset_k(virt), virt); +} + +struct map_desc; +struct meminfo; +struct pglist_data; + +void __init create_mapping(struct map_desc *md); +void __init bootmem_init(struct meminfo *mi); +void reserve_node_zero(struct pglist_data *pgdat); diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 29e54807c5b..b0b5f469407 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -114,3 +114,25 @@ full_search: } } + +/* + * You really shouldn't be using read() or write() on /dev/mem. This + * might go away in the future. + */ +int valid_phys_addr_range(unsigned long addr, size_t size) +{ + if (addr + size > __pa(high_memory)) + return 0; + + return 1; +} + +/* + * We don't use supersection mappings for mmap() on /dev/mem, which + * means that we can't map the memory area above the 4G barrier into + * userspace. + */ +int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) +{ + return !(pfn + (size >> PAGE_SHIFT) > 0x00100000); +} diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 0d90227a0a3..e566cbe4b22 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -1,45 +1,771 @@ /* * linux/arch/arm/mm/mmu.c * - * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved. + * Copyright (C) 1995-2005 Russell King * * 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/errno.h> #include <linux/init.h> -#include <linux/sched.h> -#include <linux/mm.h> +#include <linux/bootmem.h> +#include <linux/mman.h> +#include <linux/nodemask.h> -#include <asm/mmu_context.h> -#include <asm/tlbflush.h> +#include <asm/mach-types.h> +#include <asm/setup.h> +#include <asm/sizes.h> +#include <asm/tlb.h> -unsigned int cpu_last_asid = { 1 << ASID_BITS }; +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "mm.h" + +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); + +extern void _stext, __data_start, _end; +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +/* + * empty_zero_page is a special page that is used for + * zero-initialized data and COW. + */ +struct page *empty_zero_page; /* - * We fork()ed a process, and we need a new context for the child - * to run in. We reserve version 0 for initial tasks so we will - * always allocate an ASID. + * The pmd table for the upper-most set of pages. */ -void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) +pmd_t *top_pmd; + +#define CPOLICY_UNCACHED 0 +#define CPOLICY_BUFFERED 1 +#define CPOLICY_WRITETHROUGH 2 +#define CPOLICY_WRITEBACK 3 +#define CPOLICY_WRITEALLOC 4 + +static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; +static unsigned int ecc_mask __initdata = 0; +pgprot_t pgprot_kernel; + +EXPORT_SYMBOL(pgprot_kernel); + +struct cachepolicy { + const char policy[16]; + unsigned int cr_mask; + unsigned int pmd; + unsigned int pte; +}; + +static struct cachepolicy cache_policies[] __initdata = { + { + .policy = "uncached", + .cr_mask = CR_W|CR_C, + .pmd = PMD_SECT_UNCACHED, + .pte = 0, + }, { + .policy = "buffered", + .cr_mask = CR_C, + .pmd = PMD_SECT_BUFFERED, + .pte = PTE_BUFFERABLE, + }, { + .policy = "writethrough", + .cr_mask = 0, + .pmd = PMD_SECT_WT, + .pte = PTE_CACHEABLE, + }, { + .policy = "writeback", + .cr_mask = 0, + .pmd = PMD_SECT_WB, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + }, { + .policy = "writealloc", + .cr_mask = 0, + .pmd = PMD_SECT_WBWA, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + } +}; + +/* + * These are useful for identifing cache coherency + * problems by allowing the cache or the cache and + * writebuffer to be turned off. (Note: the write + * buffer should not be on and the cache off). + */ +static void __init early_cachepolicy(char **p) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cache_policies); i++) { + int len = strlen(cache_policies[i].policy); + + if (memcmp(*p, cache_policies[i].policy, len) == 0) { + cachepolicy = i; + cr_alignment &= ~cache_policies[i].cr_mask; + cr_no_alignment &= ~cache_policies[i].cr_mask; + *p += len; + break; + } + } + if (i == ARRAY_SIZE(cache_policies)) + printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); + flush_cache_all(); + set_cr(cr_alignment); +} +__early_param("cachepolicy=", early_cachepolicy); + +static void __init early_nocache(char **__unused) +{ + char *p = "buffered"; + printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); + early_cachepolicy(&p); +} +__early_param("nocache", early_nocache); + +static void __init early_nowrite(char **__unused) +{ + char *p = "uncached"; + printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); + early_cachepolicy(&p); +} +__early_param("nowb", early_nowrite); + +static void __init early_ecc(char **p) +{ + if (memcmp(*p, "on", 2) == 0) { + ecc_mask = PMD_PROTECTION; + *p += 2; + } else if (memcmp(*p, "off", 3) == 0) { + ecc_mask = 0; + *p += 3; + } +} +__early_param("ecc=", early_ecc); + +static int __init noalign_setup(char *__unused) { - mm->context.id = 0; + cr_alignment &= ~CR_A; + cr_no_alignment &= ~CR_A; + set_cr(cr_alignment); + return 1; } +__setup("noalign", noalign_setup); + +struct mem_types { + unsigned int prot_pte; + unsigned int prot_l1; + unsigned int prot_sect; + unsigned int domain; +}; -void __new_context(struct mm_struct *mm) +static struct mem_types mem_types[] __initdata = { + [MT_DEVICE] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, + }, + [MT_CACHECLEAN] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4, + .domain = DOMAIN_KERNEL, + }, + [MT_MINICLEAN] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE, + .domain = DOMAIN_KERNEL, + }, + [MT_LOW_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, + [MT_HIGH_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_USER | L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, + [MT_MEMORY] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE, + .domain = DOMAIN_KERNEL, + }, + [MT_ROM] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4, + .domain = DOMAIN_KERNEL, + }, + [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | + PMD_SECT_TEX(1), + .domain = DOMAIN_IO, + }, + [MT_NONSHARED_DEVICE] = { + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, + } +}; + +/* + * Adjust the PMD section entries according to the CPU in use. + */ +static void __init build_mem_type_table(void) { - unsigned int asid; + struct cachepolicy *cp; + unsigned int cr = get_cr(); + unsigned int user_pgprot, kern_pgprot; + int cpu_arch = cpu_architecture(); + int i; - asid = ++cpu_last_asid; - if (asid == 0) - asid = cpu_last_asid = 1 << ASID_BITS; +#if defined(CONFIG_CPU_DCACHE_DISABLE) + if (cachepolicy > CPOLICY_BUFFERED) + cachepolicy = CPOLICY_BUFFERED; +#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) + if (cachepolicy > CPOLICY_WRITETHROUGH) + cachepolicy = CPOLICY_WRITETHROUGH; +#endif + if (cpu_arch < CPU_ARCH_ARMv5) { + if (cachepolicy >= CPOLICY_WRITEALLOC) + cachepolicy = CPOLICY_WRITEBACK; + ecc_mask = 0; + } + + /* + * Xscale must not have PMD bit 4 set for section mappings. + */ + if (cpu_is_xscale()) + for (i = 0; i < ARRAY_SIZE(mem_types); i++) + mem_types[i].prot_sect &= ~PMD_BIT4; /* - * If we've used up all our ASIDs, we need - * to start a new version and flush the TLB. + * ARMv5 and lower, excluding Xscale, bit 4 must be set for + * page tables. */ - if ((asid & ~ASID_MASK) == 0) - flush_tlb_all(); + if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale()) + for (i = 0; i < ARRAY_SIZE(mem_types); i++) + if (mem_types[i].prot_l1) + mem_types[i].prot_l1 |= PMD_BIT4; + + cp = &cache_policies[cachepolicy]; + kern_pgprot = user_pgprot = cp->pte; + + /* + * Enable CPU-specific coherency if supported. + * (Only available on XSC3 at the moment.) + */ + if (arch_is_coherent()) { + if (cpu_is_xsc3()) { + mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; + } + } + + /* + * ARMv6 and above have extended page tables. + */ + if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { + /* + * bit 4 becomes XN which we must clear for the + * kernel memory mapping. + */ + mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN; + mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN; + + /* + * Mark cache clean areas and XIP ROM read only + * from SVC mode and no access from userspace. + */ + mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + + /* + * Mark the device area as "shared device" + */ + mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; + mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; + + /* + * User pages need to be mapped with the ASID + * (iow, non-global) + */ + user_pgprot |= L_PTE_ASID; + +#ifdef CONFIG_SMP + /* + * Mark memory with the "shared" attribute for SMP systems + */ + user_pgprot |= L_PTE_SHARED; + kern_pgprot |= L_PTE_SHARED; + mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; +#endif + } + + for (i = 0; i < 16; i++) { + unsigned long v = pgprot_val(protection_map[i]); + v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot; + protection_map[i] = __pgprot(v); + } + + mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot; + mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot; + + if (cpu_arch >= CPU_ARCH_ARMv5) { +#ifndef CONFIG_SMP + /* + * Only use write-through for non-SMP systems + */ + mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; + mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; +#endif + } else { + mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); + } + + pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | + L_PTE_DIRTY | L_PTE_WRITE | + L_PTE_EXEC | kern_pgprot); + + mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; + mem_types[MT_ROM].prot_sect |= cp->pmd; + + switch (cp->pmd) { + case PMD_SECT_WT: + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; + break; + case PMD_SECT_WB: + case PMD_SECT_WBWA: + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; + break; + } + printk("Memory policy: ECC %sabled, Data cache %s\n", + ecc_mask ? "en" : "dis", cp->policy); +} + +#define vectors_base() (vectors_high() ? 0xffff0000 : 0) + +/* + * Create a SECTION PGD between VIRT and PHYS in domain + * DOMAIN with protection PROT. This operates on half- + * pgdir entry increments. + */ +static inline void +alloc_init_section(unsigned long virt, unsigned long phys, int prot) +{ + pmd_t *pmdp = pmd_off_k(virt); + + if (virt & (1 << 20)) + pmdp++; + + *pmdp = __pmd(phys | prot); + flush_pmd_entry(pmdp); +} + +/* + * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT + */ +static inline void +alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) +{ + int i; + + for (i = 0; i < 16; i += 1) { + alloc_init_section(virt, phys, prot | PMD_SECT_SUPER); + + virt += (PGDIR_SIZE / 2); + } +} + +/* + * Add a PAGE mapping between VIRT and PHYS in domain + * DOMAIN with protection PROT. Note that due to the + * way we map the PTEs, we must allocate two PTE_SIZE'd + * blocks - one for the Linux pte table, and one for + * the hardware pte table. + */ +static inline void +alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) +{ + pmd_t *pmdp = pmd_off_k(virt); + pte_t *ptep; + + if (pmd_none(*pmdp)) { + ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * + sizeof(pte_t)); + + __pmd_populate(pmdp, __pa(ptep) | prot_l1); + } + ptep = pte_offset_kernel(pmdp, virt); + + set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); +} + +/* + * Create the page directory entries and any necessary + * page tables for the mapping specified by `md'. We + * are able to cope here with varying sizes and address + * offsets, and we take full advantage of sections and + * supersections. + */ +void __init create_mapping(struct map_desc *md) +{ + unsigned long virt, length; + int prot_sect, prot_l1, domain; + pgprot_t prot_pte; + unsigned long off = (u32)__pfn_to_phys(md->pfn); + + if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { + printk(KERN_WARNING "BUG: not creating mapping for " + "0x%08llx at 0x%08lx in user region\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + + if ((md->type == MT_DEVICE || md->type == MT_ROM) && + md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { + printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " + "overlaps vmalloc space\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + } + + domain = mem_types[md->type].domain; + prot_pte = __pgprot(mem_types[md->type].prot_pte); + prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); + prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); + + /* + * Catch 36-bit addresses + */ + if(md->pfn >= 0x100000) { + if(domain) { + printk(KERN_ERR "MM: invalid domain in supersection " + "mapping for 0x%08llx at 0x%08lx\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + if((md->virtual | md->length | __pfn_to_phys(md->pfn)) + & ~SUPERSECTION_MASK) { + printk(KERN_ERR "MM: cannot create mapping for " + "0x%08llx at 0x%08lx invalid alignment\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + + /* + * Shift bits [35:32] of address into bits [23:20] of PMD + * (See ARMv6 spec). + */ + off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); + } + + virt = md->virtual; + off -= virt; + length = md->length; + + if (mem_types[md->type].prot_l1 == 0 && + (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { + printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " + "be mapped using pages, ignoring.\n", + __pfn_to_phys(md->pfn), md->virtual); + return; + } + + while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } + + /* N.B. ARMv6 supersections are only defined to work with domain 0. + * Since domain assignments can in fact be arbitrary, the + * 'domain == 0' check below is required to insure that ARMv6 + * supersections are only allocated for domain 0 regardless + * of the actual domain assignments in use. + */ + if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) + && domain == 0) { + /* + * Align to supersection boundary if !high pages. + * High pages have already been checked for proper + * alignment above and they will fail the SUPSERSECTION_MASK + * check because of the way the address is encoded into + * offset. + */ + if (md->pfn <= 0x100000) { + while ((virt & ~SUPERSECTION_MASK || + (virt + off) & ~SUPERSECTION_MASK) && + length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + } + + while (length >= SUPERSECTION_SIZE) { + alloc_init_supersection(virt, virt + off, prot_sect); + + virt += SUPERSECTION_SIZE; + length -= SUPERSECTION_SIZE; + } + } + + /* + * A section mapping covers half a "pgdir" entry. + */ + while (length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + + while (length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } +} + +/* + * Create the architecture specific mappings + */ +void __init iotable_init(struct map_desc *io_desc, int nr) +{ + int i; + + for (i = 0; i < nr; i++) + create_mapping(io_desc + i); +} + +static inline void prepare_page_table(struct meminfo *mi) +{ + unsigned long addr; + + /* + * Clear out all the mappings below the kernel image. + */ + for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + +#ifdef CONFIG_XIP_KERNEL + /* The XIP kernel is mapped in the module area -- skip over it */ + addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; +#endif + for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Clear out all the kernel space mappings, except for the first + * memory bank, up to the end of the vmalloc region. + */ + for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); + addr < VMALLOC_END; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); +} + +/* + * Reserve the various regions of node 0 + */ +void __init reserve_node_zero(pg_data_t *pgdat) +{ + unsigned long res_size = 0; + + /* + * Register the kernel text and data with bootmem. + * Note that this can only be in node 0. + */ +#ifdef CONFIG_XIP_KERNEL + reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); +#else + reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); +#endif + + /* + * Reserve the page tables. These are already in use, + * and can only be in node 0. + */ + reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), + PTRS_PER_PGD * sizeof(pgd_t)); + + /* + * Hmm... This should go elsewhere, but we really really need to + * stop things allocating the low memory; ideally we need a better + * implementation of GFP_DMA which does not assume that DMA-able + * memory starts at zero. + */ + if (machine_is_integrator() || machine_is_cintegrator()) + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + + /* + * These should likewise go elsewhere. They pre-reserve the + * screen memory region at the start of main system memory. + */ + if (machine_is_edb7211()) + res_size = 0x00020000; + if (machine_is_p720t()) + res_size = 0x00014000; + +#ifdef CONFIG_SA1111 + /* + * Because of the SA1111 DMA bug, we want to preserve our + * precious DMA-able memory... + */ + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; +#endif + if (res_size) + reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); +} + +/* + * Set up device the mappings. Since we clear out the page tables for all + * mappings above VMALLOC_END, we will remove any debug device mappings. + * This means you have to be careful how you debug this function, or any + * called function. This means you can't use any function or debugging + * method which may touch any device, otherwise the kernel _will_ crash. + */ +static void __init devicemaps_init(struct machine_desc *mdesc) +{ + struct map_desc map; + unsigned long addr; + void *vectors; + + /* + * Allocate the vector page early. + */ + vectors = alloc_bootmem_low_pages(PAGE_SIZE); + BUG_ON(!vectors); + + for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Map the kernel if it is XIP. + * It is always first in the modulearea. + */ +#ifdef CONFIG_XIP_KERNEL + map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK); + map.virtual = MODULE_START; + map.length = ((unsigned long)&_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK; + map.type = MT_ROM; + create_mapping(&map); +#endif + + /* + * Map the cache flushing regions. + */ +#ifdef FLUSH_BASE + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); + map.virtual = FLUSH_BASE; + map.length = SZ_1M; + map.type = MT_CACHECLEAN; + create_mapping(&map); +#endif +#ifdef FLUSH_BASE_MINICACHE + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); + map.virtual = FLUSH_BASE_MINICACHE; + map.length = SZ_1M; + map.type = MT_MINICLEAN; + create_mapping(&map); +#endif + + /* + * Create a mapping for the machine vectors at the high-vectors + * location (0xffff0000). If we aren't using high-vectors, also + * create a mapping at the low-vectors virtual address. + */ + map.pfn = __phys_to_pfn(virt_to_phys(vectors)); + map.virtual = 0xffff0000; + map.length = PAGE_SIZE; + map.type = MT_HIGH_VECTORS; + create_mapping(&map); + + if (!vectors_high()) { + map.virtual = 0; + map.type = MT_LOW_VECTORS; + create_mapping(&map); + } + + /* + * Ask the machine support to map in the statically mapped devices. + */ + if (mdesc->map_io) + mdesc->map_io(); + + /* + * Finally flush the caches and tlb to ensure that we're in a + * consistent state wrt the writebuffer. This also ensures that + * any write-allocated cache lines in the vector page are written + * back. After this point, we can start to touch devices again. + */ + local_flush_tlb_all(); + flush_cache_all(); +} + +/* + * paging_init() sets up the page tables, initialises the zone memory + * maps, and sets up the zero page, bad page and bad page tables. + */ +void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) +{ + void *zero_page; + + build_mem_type_table(); + prepare_page_table(mi); + bootmem_init(mi); + devicemaps_init(mdesc); + + top_pmd = pmd_off_k(0xffff0000); + + /* + * allocate the zero page. Note that we count on this going ok. + */ + zero_page = alloc_bootmem_low_pages(PAGE_SIZE); + memzero(zero_page, PAGE_SIZE); + empty_zero_page = virt_to_page(zero_page); + flush_dcache_page(empty_zero_page); +} + +/* + * In order to soft-boot, we need to insert a 1:1 mapping in place of + * the user-mode pages. This will then ensure that we have predictable + * results when turning the mmu off + */ +void setup_mm_for_reboot(char mode) +{ + unsigned long base_pmdval; + pgd_t *pgd; + int i; + + if (current->mm && current->mm->pgd) + pgd = current->mm->pgd; + else + pgd = init_mm.pgd; + + base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; + if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) + base_pmdval |= PMD_BIT4; + + for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) { + unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval; + pmd_t *pmd; - mm->context.id = asid; + pmd = pmd_off(pgd, i << PGDIR_SHIFT); + pmd[0] = __pmd(pmdval); + pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); + flush_pmd_entry(pmd); + } } diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 1464ed817b5..d0e66424a59 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -11,6 +11,49 @@ #include <asm/io.h> #include <asm/page.h> +#include "mm.h" + +extern void _stext, __data_start, _end; + +/* + * Reserve the various regions of node 0 + */ +void __init reserve_node_zero(pg_data_t *pgdat) +{ + /* + * Register the kernel text and data with bootmem. + * Note that this can only be in node 0. + */ +#ifdef CONFIG_XIP_KERNEL + reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); +#else + reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); +#endif + + /* + * Register the exception vector page. + * some architectures which the DRAM is the exception vector to trap, + * alloc_page breaks with error, although it is not NULL, but "0." + */ + reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE); +} + +/* + * paging_init() sets up the page tables, initialises the zone memory + * maps, and sets up the zero page, bad page and bad page tables. + */ +void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) +{ + bootmem_init(mi); +} + +/* + * We don't need to do anything here for nommu machines. + */ +void setup_mm_for_reboot(char mode) +{ +} + void flush_dcache_page(struct page *page) { __cpuc_flush_dcache_page(page_address(page)); diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c new file mode 100644 index 00000000000..20c1b0df75f --- /dev/null +++ b/arch/arm/mm/pgd.c @@ -0,0 +1,101 @@ +/* + * linux/arch/arm/mm/pgd.c + * + * Copyright (C) 1998-2005 Russell King + * + * 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/mm.h> +#include <linux/highmem.h> + +#include <asm/pgalloc.h> +#include <asm/page.h> +#include <asm/tlbflush.h> + +#include "mm.h" + +#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) + +/* + * need to get a 16k page for level 1 + */ +pgd_t *get_pgd_slow(struct mm_struct *mm) +{ + pgd_t *new_pgd, *init_pgd; + pmd_t *new_pmd, *init_pmd; + pte_t *new_pte, *init_pte; + + new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); + if (!new_pgd) + goto no_pgd; + + memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); + + /* + * Copy over the kernel and IO PGD entries + */ + init_pgd = pgd_offset_k(0); + memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, + (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + + clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); + + if (!vectors_high()) { + /* + * On ARM, first page must always be allocated since it + * contains the machine vectors. + */ + new_pmd = pmd_alloc(mm, new_pgd, 0); + if (!new_pmd) + goto no_pmd; + + new_pte = pte_alloc_map(mm, new_pmd, 0); + if (!new_pte) + goto no_pte; + + init_pmd = pmd_offset(init_pgd, 0); + init_pte = pte_offset_map_nested(init_pmd, 0); + set_pte(new_pte, *init_pte); + pte_unmap_nested(init_pte); + pte_unmap(new_pte); + } + + return new_pgd; + +no_pte: + pmd_free(new_pmd); +no_pmd: + free_pages((unsigned long)new_pgd, 2); +no_pgd: + return NULL; +} + +void free_pgd_slow(pgd_t *pgd) +{ + pmd_t *pmd; + struct page *pte; + + if (!pgd) + return; + + /* pgd is always present and good */ + pmd = pmd_off(pgd, 0); + if (pmd_none(*pmd)) + goto free; + if (pmd_bad(*pmd)) { + pmd_ERROR(*pmd); + pmd_clear(pmd); + goto free; + } + + pte = pmd_page(*pmd); + pmd_clear(pmd); + dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); + pte_lock_deinit(pte); + pte_free(pte); + pmd_free(pmd); +free: + free_pages((unsigned long) pgd, 2); +} diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S new file mode 100644 index 00000000000..40713818a87 --- /dev/null +++ b/arch/arm/mm/proc-arm740.S @@ -0,0 +1,174 @@ +/* + * linux/arch/arm/mm/arm740.S: utility functions for ARM740 + * + * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@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/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/asm-offsets.h> +#include <asm/pgtable-hwdef.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> + + .text +/* + * cpu_arm740_proc_init() + * cpu_arm740_do_idle() + * cpu_arm740_dcache_clean_area() + * cpu_arm740_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm740_proc_init) +ENTRY(cpu_arm740_do_idle) +ENTRY(cpu_arm740_dcache_clean_area) +ENTRY(cpu_arm740_switch_mm) + mov pc, lr + +/* + * cpu_arm740_proc_fin() + */ +ENTRY(cpu_arm740_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x3f000000 @ bank/f/lock/s + bic r0, r0, #0x0000000c @ w-buffer/cache + mcr p15, 0, r0, c1, c0, 0 @ disable caches + mcr p15, 0, r0, c7, c0, 0 @ invalidate cache + ldmfd sp!, {pc} + +/* + * cpu_arm740_reset(loc) + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ +ENTRY(cpu_arm740_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c0, 0 @ invalidate cache + mrc p15, 0, ip, c1, c0, 0 @ get ctrl register + bic ip, ip, #0x0000000c @ ............wc.. + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + + __INIT + + .type __arm740_setup, #function +__arm740_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c0, 0 @ invalidate caches + + mcr p15, 0, r0, c6, c3 @ disable area 3~7 + mcr p15, 0, r0, c6, c4 + mcr p15, 0, r0, c6, c5 + mcr p15, 0, r0, c6, c6 + mcr p15, 0, r0, c6, c7 + + mov r0, #0x0000003F @ base = 0, size = 4GB + mcr p15, 0, r0, c6, c0 @ set area 0, default + + ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM + ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the area register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c1 @ set area 1, RAM + + ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH + ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the area register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH + + mov r0, #0x06 + mcr p15, 0, r0, c2, c0 @ Region 1&2 cacheable +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #0x00 @ disable whole write buffer +#else + mov r0, #0x02 @ Region 1 write bufferred +#endif + mcr p15, 0, r0, c3, c0 + + mov r0, #0x10000 + sub r0, r0, #1 @ r0 = 0xffff + mcr p15, 0, r0, c5, c0 @ all read/write access + + mrc p15, 0, r0, c1, c0 @ get control register + bic r0, r0, #0x3F000000 @ set to standard caching mode + @ need some benchmark + orr r0, r0, #0x0000000d @ MPU/Cache/WB + + mov pc, lr + + .size __arm740_setup, . - __arm740_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm740_processor_functions, #object +ENTRY(arm740_processor_functions) + .word v4t_late_abort + .word cpu_arm740_proc_init + .word cpu_arm740_proc_fin + .word cpu_arm740_reset + .word cpu_arm740_do_idle + .word cpu_arm740_dcache_clean_area + .word cpu_arm740_switch_mm + .word 0 @ cpu_*_set_pte + .size arm740_processor_functions, . - arm740_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm740_name, #object +cpu_arm740_name: + .ascii "ARM740T" + .size cpu_arm740_name, . - cpu_arm740_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + .type __arm740_proc_info,#object +__arm740_proc_info: + .long 0x41807400 + .long 0xfffffff0 + .long 0 + b __arm740_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_arm740_name + .long arm740_processor_functions + .long 0 + .long 0 + .long v3_cache_fns @ cache model + .size __arm740_proc_info, . - __arm740_proc_info + + diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S new file mode 100644 index 00000000000..22d7e3100ea --- /dev/null +++ b/arch/arm/mm/proc-arm7tdmi.S @@ -0,0 +1,249 @@ +/* + * linux/arch/arm/mm/proc-arm7tdmi.S: utility functions for ARM7TDMI + * + * Copyright (C) 2003-2006 Hyok S. Choi <hyok.choi@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/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/asm-offsets.h> +#include <asm/pgtable-hwdef.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> + + .text +/* + * cpu_arm7tdmi_proc_init() + * cpu_arm7tdmi_do_idle() + * cpu_arm7tdmi_dcache_clean_area() + * cpu_arm7tdmi_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm7tdmi_proc_init) +ENTRY(cpu_arm7tdmi_do_idle) +ENTRY(cpu_arm7tdmi_dcache_clean_area) +ENTRY(cpu_arm7tdmi_switch_mm) + mov pc, lr + +/* + * cpu_arm7tdmi_proc_fin() + */ +ENTRY(cpu_arm7tdmi_proc_fin) + mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, r0 + mov pc, lr + +/* + * Function: cpu_arm7tdmi_reset(loc) + * Params : loc(r0) address to jump to + * Purpose : Sets up everything for a reset and jump to the location for soft reset. + */ +ENTRY(cpu_arm7tdmi_reset) + mov pc, r0 + + __INIT + + .type __arm7tdmi_setup, #function +__arm7tdmi_setup: + mov pc, lr + .size __arm7tdmi_setup, . - __arm7tdmi_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm7tdmi_processor_functions, #object +ENTRY(arm7tdmi_processor_functions) + .word v4t_late_abort + .word cpu_arm7tdmi_proc_init + .word cpu_arm7tdmi_proc_fin + .word cpu_arm7tdmi_reset + .word cpu_arm7tdmi_do_idle + .word cpu_arm7tdmi_dcache_clean_area + .word cpu_arm7tdmi_switch_mm + .word 0 @ cpu_*_set_pte + .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm7tdmi_name, #object +cpu_arm7tdmi_name: + .asciz "ARM7TDMI" + .size cpu_arm7tdmi_name, . - cpu_arm7tdmi_name + + .type cpu_triscenda7_name, #object +cpu_triscenda7_name: + .asciz "Triscend-A7x" + .size cpu_triscenda7_name, . - cpu_triscenda7_name + + .type cpu_at91_name, #object +cpu_at91_name: + .asciz "Atmel-AT91M40xxx" + .size cpu_at91_name, . - cpu_at91_name + + .type cpu_s3c3410_name, #object +cpu_s3c3410_name: + .asciz "Samsung-S3C3410" + .size cpu_s3c3410_name, . - cpu_s3c3410_name + + .type cpu_s3c44b0x_name, #object +cpu_s3c44b0x_name: + .asciz "Samsung-S3C44B0x" + .size cpu_s3c44b0x_name, . - cpu_s3c44b0x_name + + .type cpu_s3c4510b, #object +cpu_s3c4510b_name: + .asciz "Samsung-S3C4510B" + .size cpu_s3c4510b_name, . - cpu_s3c4510b_name + + .type cpu_s3c4530_name, #object +cpu_s3c4530_name: + .asciz "Samsung-S3C4530" + .size cpu_s3c4530_name, . - cpu_s3c4530_name + + .type cpu_netarm_name, #object +cpu_netarm_name: + .asciz "NETARM" + .size cpu_netarm_name, . - cpu_netarm_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + + .type __arm7tdmi_proc_info, #object +__arm7tdmi_proc_info: + .long 0x41007700 + .long 0xfff8ff00 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_26BIT + .long cpu_arm7tdmi_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __arm7tdmi_proc_info, . - __arm7dmi_proc_info + + .type __triscenda7_proc_info, #object +__triscenda7_proc_info: + .long 0x0001d2ff + .long 0x0001ffff + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_triscenda7_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __triscenda7_proc_info, . - __triscenda7_proc_info + + .type __at91_proc_info, #object +__at91_proc_info: + .long 0x14000040 + .long 0xfff000e0 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_at91_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __at91_proc_info, . - __at91_proc_info + + .type __s3c4510b_proc_info, #object +__s3c4510b_proc_info: + .long 0x36365000 + .long 0xfffff000 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_s3c4510b_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __s3c4510b_proc_info, . - __s3c4510b_proc_info + + .type __s3c4530_proc_info, #object +__s3c4530_proc_info: + .long 0x4c000000 + .long 0xfff000e0 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_s3c4530_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __s3c4530_proc_info, . - __s3c4530_proc_info + + .type __s3c3410_proc_info, #object +__s3c3410_proc_info: + .long 0x34100000 + .long 0xffff0000 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_s3c3410_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __s3c3410_proc_info, . - __s3c3410_proc_info + + .type __s3c44b0x_proc_info, #object +__s3c44b0x_proc_info: + .long 0x44b00000 + .long 0xffff0000 + .long 0 + .long 0 + b __arm7tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_s3c44b0x_name + .long arm7tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __s3c44b0x_proc_info, . - __s3c44b0x_proc_info diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S new file mode 100644 index 00000000000..2397f4b6e15 --- /dev/null +++ b/arch/arm/mm/proc-arm940.S @@ -0,0 +1,369 @@ +/* + * linux/arch/arm/mm/arm940.S: utility functions for ARM940T + * + * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@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/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/pgtable-hwdef.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> + +/* ARM940T has a 4KB DCache comprising 256 lines of 4 words */ +#define CACHE_DLINESIZE 16 +#define CACHE_DSEGMENTS 4 +#define CACHE_DENTRIES 64 + + .text +/* + * cpu_arm940_proc_init() + * cpu_arm940_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm940_proc_init) +ENTRY(cpu_arm940_switch_mm) + mov pc, lr + +/* + * cpu_arm940_proc_fin() + */ +ENTRY(cpu_arm940_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm940_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x00001000 @ i-cache + bic r0, r0, #0x00000004 @ d-cache + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm940_reset(loc) + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ +ENTRY(cpu_arm940_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ flush I cache + mcr p15, 0, ip, c7, c6, 0 @ flush D cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x00000005 @ .............c.p + bic ip, ip, #0x00001000 @ i-cache + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm940_do_idle() + */ + .align 5 +ENTRY(cpu_arm940_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* + * flush_user_cache_all() + */ +ENTRY(arm940_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm940_flush_kern_cache_all) + mov r2, #VM_EXEC + /* FALLTHROUGH */ + +/* + * flush_user_cache_range(start, end, flags) + * + * There is no efficient way to flush a range of cache entries + * in the specified address range. Thus, flushes all. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags describing address space + */ +ENTRY(arm940_flush_user_cache_range) + mov ip, #0 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ flush D cache +#else + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 3 to 0 +#endif + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_coherent_user_range) + /* FALLTHROUGH */ + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + */ +ENTRY(arm940_flush_kern_dcache_page) + mov ip, #0 + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 7 to 0 + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * There is no efficient way to invalidate a specifid virtual + * address range. Thus, invalidates all. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_dma_inv_range) + mov ip, #0 + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c6, 2 @ flush D entry + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 7 to 0 + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * There is no efficient way to clean a specifid virtual + * address range. Thus, cleans all. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_dma_clean_range) +ENTRY(cpu_arm940_dcache_clean_area) + mov ip, #0 +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: mcr p15, 0, r3, c7, c10, 2 @ clean D entry + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 7 to 0 +#endif + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * There is no efficient way to clean and invalidate a specifid + * virtual address range. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm940_dma_flush_range) + mov ip, #0 + mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries +2: +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r3, c7, c14, 2 @ clean/flush D entry +#else + mcr p15, 0, r3, c7, c10, 2 @ clean D entry +#endif + subs r3, r3, #1 << 26 + bcs 2b @ entries 63 to 0 + subs r1, r1, #1 << 4 + bcs 1b @ segments 7 to 0 + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm940_cache_fns) + .long arm940_flush_kern_cache_all + .long arm940_flush_user_cache_all + .long arm940_flush_user_cache_range + .long arm940_coherent_kern_range + .long arm940_coherent_user_range + .long arm940_flush_kern_dcache_page + .long arm940_dma_inv_range + .long arm940_dma_clean_range + .long arm940_dma_flush_range + + __INIT + + .type __arm940_setup, #function +__arm940_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + + mcr p15, 0, r0, c6, c3, 0 @ disable data area 3~7 + mcr p15, 0, r0, c6, c4, 0 + mcr p15, 0, r0, c6, c5, 0 + mcr p15, 0, r0, c6, c6, 0 + mcr p15, 0, r0, c6, c7, 0 + + mcr p15, 0, r0, c6, c3, 1 @ disable instruction area 3~7 + mcr p15, 0, r0, c6, c4, 1 + mcr p15, 0, r0, c6, c5, 1 + mcr p15, 0, r0, c6, c6, 1 + mcr p15, 0, r0, c6, c7, 1 + + mov r0, #0x0000003F @ base = 0, size = 4GB + mcr p15, 0, r0, c6, c0, 0 @ set area 0, default + mcr p15, 0, r0, c6, c0, 1 + + ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM + ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the area register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c1, 0 @ set area 1, RAM + mcr p15, 0, r0, c6, c1, 1 + + ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH + ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the area register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c2, 0 @ set area 2, ROM/FLASH + mcr p15, 0, r0, c6, c2, 1 + + mov r0, #0x06 + mcr p15, 0, r0, c2, c0, 0 @ Region 1&2 cacheable + mcr p15, 0, r0, c2, c0, 1 +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #0x00 @ disable whole write buffer +#else + mov r0, #0x02 @ Region 1 write bufferred +#endif + mcr p15, 0, r0, c3, c0, 0 + + mov r0, #0x10000 + sub r0, r0, #1 @ r0 = 0xffff + mcr p15, 0, r0, c5, c0, 0 @ all read/write access + mcr p15, 0, r0, c5, c0, 1 + + mrc p15, 0, r0, c1, c0 @ get control register + orr r0, r0, #0x00001000 @ I-cache + orr r0, r0, #0x00000005 @ MPU/D-cache + + mov pc, lr + + .size __arm940_setup, . - __arm940_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm940_processor_functions, #object +ENTRY(arm940_processor_functions) + .word nommu_early_abort + .word cpu_arm940_proc_init + .word cpu_arm940_proc_fin + .word cpu_arm940_reset + .word cpu_arm940_do_idle + .word cpu_arm940_dcache_clean_area + .word cpu_arm940_switch_mm + .word 0 @ cpu_*_set_pte + .size arm940_processor_functions, . - arm940_processor_functions + + .section ".rodata" + +.type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm940_name, #object +cpu_arm940_name: + .ascii "ARM940T" + .size cpu_arm940_name, . - cpu_arm940_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + + .type __arm940_proc_info,#object +__arm940_proc_info: + .long 0x41009400 + .long 0xff00fff0 + .long 0 + b __arm940_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm940_name + .long arm940_processor_functions + .long 0 + .long 0 + .long arm940_cache_fns + .size __arm940_proc_info, . - __arm940_proc_info + diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S new file mode 100644 index 00000000000..e1861756442 --- /dev/null +++ b/arch/arm/mm/proc-arm946.S @@ -0,0 +1,424 @@ +/* + * linux/arch/arm/mm/arm946.S: utility functions for ARM946E-S + * + * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com) + * + * (Many of cache codes are from proc-arm926.S) + * + * 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/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/pgtable-hwdef.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> + +/* + * ARM946E-S is synthesizable to have 0KB to 1MB sized D-Cache, + * comprising 256 lines of 32 bytes (8 words). + */ +#define CACHE_DSIZE (CONFIG_CPU_DCACHE_SIZE) /* typically 8KB. */ +#define CACHE_DLINESIZE 32 /* fixed */ +#define CACHE_DSEGMENTS 4 /* fixed */ +#define CACHE_DENTRIES (CACHE_DSIZE / CACHE_DSEGMENTS / CACHE_DLINESIZE) +#define CACHE_DLIMIT (CACHE_DSIZE * 4) /* benchmark needed */ + + .text +/* + * cpu_arm946_proc_init() + * cpu_arm946_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm946_proc_init) +ENTRY(cpu_arm946_switch_mm) + mov pc, lr + +/* + * cpu_arm946_proc_fin() + */ +ENTRY(cpu_arm946_proc_fin) + stmfd sp!, {lr} + mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, ip + bl arm946_flush_kern_cache_all + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x00001000 @ i-cache + bic r0, r0, #0x00000004 @ d-cache + mcr p15, 0, r0, c1, c0, 0 @ disable caches + ldmfd sp!, {pc} + +/* + * cpu_arm946_reset(loc) + * Params : r0 = address to jump to + * Notes : This sets up everything for a reset + */ +ENTRY(cpu_arm946_reset) + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ flush I cache + mcr p15, 0, ip, c7, c6, 0 @ flush D cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mrc p15, 0, ip, c1, c0, 0 @ ctrl register + bic ip, ip, #0x00000005 @ .............c.p + bic ip, ip, #0x00001000 @ i-cache + mcr p15, 0, ip, c1, c0, 0 @ ctrl register + mov pc, r0 + +/* + * cpu_arm946_do_idle() + */ + .align 5 +ENTRY(cpu_arm946_do_idle) + mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt + mov pc, lr + +/* + * flush_user_cache_all() + */ +ENTRY(arm946_flush_user_cache_all) + /* FALLTHROUGH */ + +/* + * flush_kern_cache_all() + * + * Clean and invalidate the entire cache. + */ +ENTRY(arm946_flush_kern_cache_all) + mov r2, #VM_EXEC + mov ip, #0 +__flush_whole_cache: +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, ip, c7, c6, 0 @ flush D cache +#else + mov r1, #(CACHE_DSEGMENTS - 1) << 29 @ 4 segments +1: orr r3, r1, #(CACHE_DENTRIES - 1) << 4 @ n entries +2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index + subs r3, r3, #1 << 4 + bcs 2b @ entries n to 0 + subs r1, r1, #1 << 29 + bcs 1b @ segments 3 to 0 +#endif + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c5, 0 @ flush I cache + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_user_cache_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address range. + * + * - start - start address (inclusive) + * - end - end address (exclusive) + * - flags - vm_flags describing address space + * (same as arm926) + */ +ENTRY(arm946_flush_user_cache_range) + mov ip, #0 + sub r3, r1, r0 @ calculate total size + cmp r3, #CACHE_DLIMIT + bhs __flush_whole_cache + +1: tst r2, #VM_EXEC +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#else + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry + mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE +#endif + cmp r0, r1 + blo 1b + tst r2, #VM_EXEC + mcrne p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + */ +ENTRY(arm946_coherent_kern_range) + /* FALLTHROUGH */ + +/* + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * + * - start - virtual start address + * - end - virtual end address + * (same as arm926) + */ +ENTRY(arm946_coherent_user_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * flush_kern_dcache_page(void *page) + * + * Ensure no D cache aliasing occurs, either with itself or + * the I cache + * + * - addr - page aligned address + * (same as arm926) + */ +ENTRY(arm946_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ +1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_inv_range(start, end) + * + * Invalidate (discard) the specified virtual address range. + * May not write back any entries. If 'start' or 'end' + * are not cache line aligned, those lines must be written + * back. + * + * - start - virtual start address + * - end - virtual end address + * (same as arm926) + */ +ENTRY(arm946_dma_inv_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + tst r0, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #CACHE_DLINESIZE - 1 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +#endif + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_clean_range(start, end) + * + * Clean the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as arm926) + */ +ENTRY(arm946_dma_clean_range) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + bic r0, r0, #CACHE_DLINESIZE - 1 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * + * - start - virtual start address + * - end - virtual end address + * + * (same as arm926) + */ +ENTRY(arm946_dma_flush_range) + bic r0, r0, #CACHE_DLINESIZE - 1 +1: +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry +#else + mcr p15, 0, r0, c7, c10, 1 @ clean D entry +#endif + add r0, r0, #CACHE_DLINESIZE + cmp r0, r1 + blo 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +ENTRY(arm946_cache_fns) + .long arm946_flush_kern_cache_all + .long arm946_flush_user_cache_all + .long arm946_flush_user_cache_range + .long arm946_coherent_kern_range + .long arm946_coherent_user_range + .long arm946_flush_kern_dcache_page + .long arm946_dma_inv_range + .long arm946_dma_clean_range + .long arm946_dma_flush_range + + +ENTRY(cpu_arm946_dcache_clean_area) +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #CACHE_DLINESIZE + subs r1, r1, #CACHE_DLINESIZE + bhi 1b +#endif + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + + __INIT + + .type __arm946_setup, #function +__arm946_setup: + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache + mcr p15, 0, r0, c7, c10, 4 @ drain WB + + mcr p15, 0, r0, c6, c3, 0 @ disable memory region 3~7 + mcr p15, 0, r0, c6, c4, 0 + mcr p15, 0, r0, c6, c5, 0 + mcr p15, 0, r0, c6, c6, 0 + mcr p15, 0, r0, c6, c7, 0 + + mov r0, #0x0000003F @ base = 0, size = 4GB + mcr p15, 0, r0, c6, c0, 0 @ set region 0, default + + ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM + ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the region register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c1, 0 @ set region 1, RAM + + ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH + ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) + mov r2, #10 @ 11 is the minimum (4KB) +1: add r2, r2, #1 @ area size *= 2 + mov r1, r1, lsr #1 + bne 1b @ count not zero r-shift + orr r0, r0, r2, lsl #1 @ the region register value + orr r0, r0, #1 @ set enable bit + mcr p15, 0, r0, c6, c2, 0 @ set region 2, ROM/FLASH + + mov r0, #0x06 + mcr p15, 0, r0, c2, c0, 0 @ region 1,2 d-cacheable + mcr p15, 0, r0, c2, c0, 1 @ region 1,2 i-cacheable +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH + mov r0, #0x00 @ disable whole write buffer +#else + mov r0, #0x02 @ region 1 write bufferred +#endif + mcr p15, 0, r0, c3, c0, 0 + +/* + * Access Permission Settings for future permission control by PU. + * + * priv. user + * region 0 (whole) rw -- : b0001 + * region 1 (RAM) rw rw : b0011 + * region 2 (FLASH) rw r- : b0010 + * region 3~7 (none) -- -- : b0000 + */ + mov r0, #0x00000031 + orr r0, r0, #0x00000200 + mcr p15, 0, r0, c5, c0, 2 @ set data access permission + mcr p15, 0, r0, c5, c0, 3 @ set inst. access permission + + mrc p15, 0, r0, c1, c0 @ get control register + orr r0, r0, #0x00001000 @ I-cache + orr r0, r0, #0x00000005 @ MPU/D-cache +#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN + orr r0, r0, #0x00004000 @ .1.. .... .... .... +#endif + mov pc, lr + + .size __arm946_setup, . - __arm946_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm946_processor_functions, #object +ENTRY(arm946_processor_functions) + .word nommu_early_abort + .word cpu_arm946_proc_init + .word cpu_arm946_proc_fin + .word cpu_arm946_reset + .word cpu_arm946_do_idle + + .word cpu_arm946_dcache_clean_area + .word cpu_arm946_switch_mm + .word 0 @ cpu_*_set_pte + .size arm946_processor_functions, . - arm946_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv5te" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v5t" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm946_name, #object +cpu_arm946_name: + .ascii "ARM946E-S" + .size cpu_arm946_name, . - cpu_arm946_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + .type __arm946_proc_info,#object +__arm946_proc_info: + .long 0x41009460 + .long 0xff00fff0 + .long 0 + b __arm946_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB + .long cpu_arm946_name + .long arm946_processor_functions + .long 0 + .long 0 + .long arm940_cache_fns + .size __arm946_proc_info, . - __arm946_proc_info + diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S new file mode 100644 index 00000000000..918ebf65d4f --- /dev/null +++ b/arch/arm/mm/proc-arm9tdmi.S @@ -0,0 +1,134 @@ +/* + * linux/arch/arm/mm/proc-arm9tdmi.S: utility functions for ARM9TDMI + * + * Copyright (C) 2003-2006 Hyok S. Choi <hyok.choi@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/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> +#include <asm/asm-offsets.h> +#include <asm/pgtable-hwdef.h> +#include <asm/pgtable.h> +#include <asm/procinfo.h> +#include <asm/ptrace.h> + + .text +/* + * cpu_arm9tdmi_proc_init() + * cpu_arm9tdmi_do_idle() + * cpu_arm9tdmi_dcache_clean_area() + * cpu_arm9tdmi_switch_mm() + * + * These are not required. + */ +ENTRY(cpu_arm9tdmi_proc_init) +ENTRY(cpu_arm9tdmi_do_idle) +ENTRY(cpu_arm9tdmi_dcache_clean_area) +ENTRY(cpu_arm9tdmi_switch_mm) + mov pc, lr + +/* + * cpu_arm9tdmi_proc_fin() + */ +ENTRY(cpu_arm9tdmi_proc_fin) + mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE + msr cpsr_c, r0 + mov pc, lr + +/* + * Function: cpu_arm9tdmi_reset(loc) + * Params : loc(r0) address to jump to + * Purpose : Sets up everything for a reset and jump to the location for soft reset. + */ +ENTRY(cpu_arm9tdmi_reset) + mov pc, r0 + + __INIT + + .type __arm9tdmi_setup, #function +__arm9tdmi_setup: + mov pc, lr + .size __arm9tdmi_setup, . - __arm9tdmi_setup + + __INITDATA + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type arm9tdmi_processor_functions, #object +ENTRY(arm9tdmi_processor_functions) + .word nommu_early_abort + .word cpu_arm9tdmi_proc_init + .word cpu_arm9tdmi_proc_fin + .word cpu_arm9tdmi_reset + .word cpu_arm9tdmi_do_idle + .word cpu_arm9tdmi_dcache_clean_area + .word cpu_arm9tdmi_switch_mm + .word 0 @ cpu_*_set_pte + .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions + + .section ".rodata" + + .type cpu_arch_name, #object +cpu_arch_name: + .asciz "armv4t" + .size cpu_arch_name, . - cpu_arch_name + + .type cpu_elf_name, #object +cpu_elf_name: + .asciz "v4" + .size cpu_elf_name, . - cpu_elf_name + + .type cpu_arm9tdmi_name, #object +cpu_arm9tdmi_name: + .asciz "ARM9TDMI" + .size cpu_arm9tdmi_name, . - cpu_arm9tdmi_name + + .type cpu_p2001_name, #object +cpu_p2001_name: + .asciz "P2001" + .size cpu_p2001_name, . - cpu_p2001_name + + .align + + .section ".proc.info.init", #alloc, #execinstr + + .type __arm9tdmi_proc_info, #object +__arm9tdmi_proc_info: + .long 0x41009900 + .long 0xfff8ff00 + .long 0 + .long 0 + b __arm9tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_arm9tdmi_name + .long arm9tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __arm9tdmi_proc_info, . - __arm9dmi_proc_info + + .type __p2001_proc_info, #object +__p2001_proc_info: + .long 0x41029000 + .long 0xffffffff + .long 0 + .long 0 + b __arm9tdmi_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT + .long cpu_p2001_name + .long arm9tdmi_processor_functions + .long 0 + .long 0 + .long v4_cache_fns + .size __p2001_proc_info, . - __p2001_proc_info diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 3ca0c92e98a..e8b377d637f 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -311,12 +311,6 @@ ENTRY(xscale_flush_kern_dcache_page) * - end - virtual end address */ ENTRY(xscale_dma_inv_range) - mrc p15, 0, r2, c0, c0, 0 @ read ID - eor r2, r2, #0x69000000 - eor r2, r2, #0x00052000 - bics r2, r2, #1 - beq xscale_dma_flush_range - tst r0, #CACHELINESIZE - 1 bic r0, r0, #CACHELINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry @@ -375,6 +369,30 @@ ENTRY(xscale_cache_fns) .long xscale_dma_clean_range .long xscale_dma_flush_range +/* + * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't + * clear the dirty bits, which means that if we invalidate a dirty line, + * the dirty data can still be written back to external memory later on. + * + * The recommended workaround is to always do a clean D-cache line before + * doing an invalidate D-cache line, so on the affected processors, + * dma_inv_range() is implemented as dma_flush_range(). + * + * See erratum #25 of "Intel 80200 Processor Specification Update", + * revision January 22, 2003, available at: + * http://www.intel.com/design/iio/specupdt/273415.htm + */ +ENTRY(xscale_80200_A0_A1_cache_fns) + .long xscale_flush_kern_cache_all + .long xscale_flush_user_cache_all + .long xscale_flush_user_cache_range + .long xscale_coherent_kern_range + .long xscale_coherent_user_range + .long xscale_flush_kern_dcache_page + .long xscale_dma_flush_range + .long xscale_dma_clean_range + .long xscale_dma_flush_range + ENTRY(cpu_xscale_dcache_clean_area) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHELINESIZE @@ -531,6 +549,11 @@ cpu_elf_name: .asciz "v5" .size cpu_elf_name, . - cpu_elf_name + .type cpu_80200_A0_A1_name, #object +cpu_80200_A0_A1_name: + .asciz "XScale-80200 A0/A1" + .size cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name + .type cpu_80200_name, #object cpu_80200_name: .asciz "XScale-80200" @@ -595,6 +618,29 @@ cpu_pxa270_name: .section ".proc.info.init", #alloc, #execinstr + .type __80200_A0_A1_proc_info,#object +__80200_A0_A1_proc_info: + .long 0x69052000 + .long 0xfffffffe + .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + .long PMD_TYPE_SECT | \ + PMD_SECT_AP_WRITE | \ + PMD_SECT_AP_READ + b __xscale_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long cpu_80200_name + .long xscale_processor_functions + .long v4wbi_tlb_fns + .long xscale_mc_user_fns + .long xscale_80200_A0_A1_cache_fns + .size __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info + .type __80200_proc_info,#object __80200_proc_info: .long 0x69052000 diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c index 34fdc733743..6576143f255 100644 --- a/arch/arm/oprofile/op_model_xscale.c +++ b/arch/arm/oprofile/op_model_xscale.c @@ -36,11 +36,11 @@ #ifdef CONFIG_ARCH_IOP310 #define XSCALE_PMU_IRQ IRQ_XS80200_PMU #endif -#ifdef CONFIG_ARCH_IOP321 -#define XSCALE_PMU_IRQ IRQ_IOP321_CORE_PMU +#ifdef CONFIG_ARCH_IOP32X +#define XSCALE_PMU_IRQ IRQ_IOP32X_CORE_PMU #endif -#ifdef CONFIG_ARCH_IOP331 -#define XSCALE_PMU_IRQ IRQ_IOP331_CORE_PMU +#ifdef CONFIG_ARCH_IOP33X +#define XSCALE_PMU_IRQ IRQ_IOP33X_CORE_PMU #endif #ifdef CONFIG_ARCH_PXA #define XSCALE_PMU_IRQ IRQ_PMU @@ -88,7 +88,7 @@ static struct pmu_counter results[MAX_COUNTERS]; /* * There are two versions of the PMU in current XScale processors * with differing register layouts and number of performance counters. - * e.g. IOP321 is xsc1 whilst IOP331 is xsc2. + * e.g. IOP32x is xsc1 whilst IOP33x is xsc2. * We detect which register layout to use in xscale_detect_pmu() */ enum { PMU_XSC1, PMU_XSC2 }; diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile new file mode 100644 index 00000000000..23da00b1151 --- /dev/null +++ b/arch/arm/plat-iop/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the linux kernel. +# + +obj-y := gpio.o i2c.o pci.o setup.o time.o +obj-m := +obj-n := +obj- := diff --git a/arch/arm/plat-iop/gpio.c b/arch/arm/plat-iop/gpio.c new file mode 100644 index 00000000000..eda43608341 --- /dev/null +++ b/arch/arm/plat-iop/gpio.c @@ -0,0 +1,48 @@ +/* + * arch/arm/plat-iop/gpio.c + * GPIO handling for Intel IOP3xx processors. + * + * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> + * + * 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. + */ + +#include <linux/device.h> +#include <asm/hardware/iop3xx.h> + +void gpio_line_config(int line, int direction) +{ + unsigned long flags; + + local_irq_save(flags); + if (direction == GPIO_IN) { + *IOP3XX_GPOE |= 1 << line; + } else if (direction == GPIO_OUT) { + *IOP3XX_GPOE &= ~(1 << line); + } + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_line_config); + +int gpio_line_get(int line) +{ + return !!(*IOP3XX_GPID & (1 << line)); +} +EXPORT_SYMBOL(gpio_line_get); + +void gpio_line_set(int line, int value) +{ + unsigned long flags; + + local_irq_save(flags); + if (value == GPIO_LOW) { + *IOP3XX_GPOD &= ~(1 << line); + } else if (value == GPIO_HIGH) { + *IOP3XX_GPOD |= 1 << line; + } + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_line_set); diff --git a/arch/arm/plat-iop/i2c.c b/arch/arm/plat-iop/i2c.c new file mode 100644 index 00000000000..e99909bdba7 --- /dev/null +++ b/arch/arm/plat-iop/i2c.c @@ -0,0 +1,81 @@ +/* + * arch/arm/plat-iop/i2c.c + * + * Author: Nicolas Pitre <nico@cam.org> + * Copyright (C) 2001 MontaVista Software, Inc. + * Copyright (C) 2004 Intel Corporation. + * + * 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/mm.h> +#include <linux/init.h> +#include <linux/major.h> +#include <linux/fs.h> +#include <linux/platform_device.h> +#include <linux/serial.h> +#include <linux/tty.h> +#include <linux/serial_core.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/mach/map.h> +#include <asm/setup.h> +#include <asm/system.h> +#include <asm/memory.h> +#include <asm/hardware.h> +#include <asm/hardware/iop3xx.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> + +#ifdef CONFIG_ARCH_IOP32X +#define IRQ_IOP3XX_I2C_0 IRQ_IOP32X_I2C_0 +#define IRQ_IOP3XX_I2C_1 IRQ_IOP32X_I2C_1 +#endif +#ifdef CONFIG_ARCH_IOP33X +#define IRQ_IOP3XX_I2C_0 IRQ_IOP33X_I2C_0 +#define IRQ_IOP3XX_I2C_1 IRQ_IOP33X_I2C_1 +#endif + +static struct resource iop3xx_i2c0_resources[] = { + [0] = { + .start = 0xfffff680, + .end = 0xfffff697, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP3XX_I2C_0, + .end = IRQ_IOP3XX_I2C_0, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device iop3xx_i2c0_device = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop3xx_i2c0_resources, +}; + + +static struct resource iop3xx_i2c1_resources[] = { + [0] = { + .start = 0xfffff6a0, + .end = 0xfffff6b7, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP3XX_I2C_1, + .end = IRQ_IOP3XX_I2C_1, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device iop3xx_i2c1_device = { + .name = "IOP3xx-I2C", + .id = 1, + .num_resources = 2, + .resource = iop3xx_i2c1_resources, +}; diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c new file mode 100644 index 00000000000..e647812654f --- /dev/null +++ b/arch/arm/plat-iop/pci.c @@ -0,0 +1,247 @@ +/* + * arch/arm/plat-iop/pci.c + * + * PCI support for the Intel IOP32X and IOP33X processors + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * + * 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/pci.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/hardware.h> +#include <asm/mach/pci.h> +#include <asm/hardware/iop3xx.h> + +// #define DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +/* + * This routine builds either a type0 or type1 configuration command. If the + * bus is on the 803xx then a type0 made, else a type1 is created. + */ +static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + if (sys->busnr == bus->number) + addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); + else + addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; + + addr |= PCI_FUNC(devfn) << 8 | (where & ~3); + + return addr; +} + +/* + * This routine checks the status of the last configuration cycle. If an error + * was detected it returns a 1, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop3xx_pci_status(void) +{ + unsigned int status; + int ret = 0; + + /* + * Check the status registers. + */ + status = *IOP3XX_ATUSR; + if (status & 0xf900) { + DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); + *IOP3XX_ATUSR = status & 0xf900; + ret = 1; + } + + status = *IOP3XX_ATUISR; + if (status & 0x679f) { + DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); + *IOP3XX_ATUISR = status & 0x679f; + ret = 1; + } + + return ret; +} + +/* + * Simply write the address register and read the configuration + * data. Note that the 4 nop's ensure that we are able to handle + * a delayed abort (in theory.) + */ +static inline u32 iop3xx_read(unsigned long addr) +{ + u32 val; + + __asm__ __volatile__( + "str %1, [%2]\n\t" + "ldr %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : "=r" (val) + : "r" (addr), "r" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR)); + + return val; +} + +/* + * The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop3xx_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = iop3xx_cfg_address(bus, devfn, where); + u32 val = iop3xx_read(addr) >> ((where & 3) * 8); + + if (iop3xx_pci_status()) + val = 0xffffffff; + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop3xx_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop3xx_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop3xx_read(addr); + if (iop3xx_pci_status()) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + *IOP3XX_OCCDR = val | value << where; + } else { + asm volatile( + "str %1, [%2]\n\t" + "str %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : + : "r" (value), "r" (addr), + "r" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR)); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop3xx_ops = { + .read = iop3xx_read_config, + .write = iop3xx_write_config, +}; + +/* + * When a PCI device does not exist during config cycles, the 80200 gets a + * bus error instead of returning 0xffffffff. This handler simply returns. + */ +static int +iop3xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", + addr, fsr, regs->ARM_pc, regs->ARM_lr); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +int iop3xx_pci_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if (nr != 0) + return 0; + + res = kzalloc(2 * sizeof(struct resource), GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP3XX_PCI_LOWER_IO_VA; + res[0].end = IOP3XX_PCI_LOWER_IO_VA + IOP3XX_PCI_IO_WINDOW_SIZE - 1; + res[0].name = "IOP3XX PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + request_resource(&ioport_resource, &res[0]); + + res[1].start = IOP3XX_PCI_LOWER_MEM_PA; + res[1].end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1; + res[1].name = "IOP3XX PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - IOP3XX_PCI_LOWER_MEM_BA; + sys->io_offset = IOP3XX_PCI_LOWER_IO_VA - IOP3XX_PCI_LOWER_IO_BA; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &iop3xx_ops, sys); +} + +void iop3xx_pci_preinit(void) +{ + DBG("PCI: Intel 803xx PCI init code.\n"); + DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD); + DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n", + *IOP3XX_OMWTVR0, + *IOP3XX_OIOWTVR); + DBG("ATU: IOP3XX_ATUCR=0x%08x\n", *IOP3XX_ATUCR); + DBG("ATU: IOP3XX_IABAR0=0x%08x IOP3XX_IALR0=0x%08x IOP3XX_IATVR0=%08x\n", + *IOP3XX_IABAR0, *IOP3XX_IALR0, *IOP3XX_IATVR0); + DBG("ATU: IOP3XX_OMWTVR0=0x%08x\n", *IOP3XX_OMWTVR0); + DBG("ATU: IOP3XX_IABAR1=0x%08x IOP3XX_IALR1=0x%08x\n", + *IOP3XX_IABAR1, *IOP3XX_IALR1); + DBG("ATU: IOP3XX_ERBAR=0x%08x IOP3XX_ERLR=0x%08x IOP3XX_ERTVR=%08x\n", + *IOP3XX_ERBAR, *IOP3XX_ERLR, *IOP3XX_ERTVR); + DBG("ATU: IOP3XX_IABAR2=0x%08x IOP3XX_IALR2=0x%08x IOP3XX_IATVR2=%08x\n", + *IOP3XX_IABAR2, *IOP3XX_IALR2, *IOP3XX_IATVR2); + DBG("ATU: IOP3XX_IABAR3=0x%08x IOP3XX_IALR3=0x%08x IOP3XX_IATVR3=%08x\n", + *IOP3XX_IABAR3, *IOP3XX_IALR3, *IOP3XX_IATVR3); + + hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort"); +} diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c new file mode 100644 index 00000000000..4689db638e9 --- /dev/null +++ b/arch/arm/plat-iop/setup.c @@ -0,0 +1,38 @@ +/* + * arch/arm/plat-iop/setup.c + * + * Author: Nicolas Pitre <nico@cam.org> + * Copyright (C) 2001 MontaVista Software, Inc. + * Copyright (C) 2004 Intel Corporation. + * + * 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/mm.h> +#include <linux/init.h> +#include <asm/mach/map.h> +#include <asm/hardware/iop3xx.h> + +/* + * Standard IO mapping for all IOP3xx based systems + */ +static struct map_desc iop3xx_std_desc[] __initdata = { + { /* mem mapped registers */ + .virtual = IOP3XX_PERIPHERAL_VIRT_BASE, + .pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE), + .length = IOP3XX_PERIPHERAL_SIZE, + .type = MT_DEVICE, + }, { /* PCI IO space */ + .virtual = IOP3XX_PCI_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA), + .length = IOP3XX_PCI_IO_WINDOW_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init iop3xx_map_io(void) +{ + iotable_init(iop3xx_std_desc, ARRAY_SIZE(iop3xx_std_desc)); +} diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c new file mode 100644 index 00000000000..06282dffbdc --- /dev/null +++ b/arch/arm/plat-iop/time.c @@ -0,0 +1,98 @@ +/* + * arch/arm/plat-iop/time.c + * + * Timer code for IOP32x and IOP33x based systems + * + * Author: Deepak Saxena <dsaxena@mvista.com> + * + * Copyright 2002-2003 MontaVista Software Inc. + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/time.h> +#include <linux/init.h> +#include <linux/timex.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/mach/irq.h> +#include <asm/mach/time.h> + +#ifdef CONFIG_ARCH_IOP32X +#define IRQ_IOP3XX_TIMER0 IRQ_IOP32X_TIMER0 +#else +#ifdef CONFIG_ARCH_IOP33X +#define IRQ_IOP3XX_TIMER0 IRQ_IOP33X_TIMER0 +#endif +#endif + +static unsigned long ticks_per_jiffy; +static unsigned long ticks_per_usec; +static unsigned long next_jiffy_time; + +unsigned long iop3xx_gettimeoffset(void) +{ + unsigned long offset; + + offset = next_jiffy_time - *IOP3XX_TU_TCR1; + + return offset / ticks_per_usec; +} + +static irqreturn_t +iop3xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + write_seqlock(&xtime_lock); + + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (1)); + iop3xx_cp6_disable(); + + while ((signed long)(next_jiffy_time - *IOP3XX_TU_TCR1) + >= ticks_per_jiffy) { + timer_tick(regs); + next_jiffy_time -= ticks_per_jiffy; + } + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction iop3xx_timer_irq = { + .name = "IOP3XX Timer Tick", + .handler = iop3xx_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_TIMER, +}; + +void __init iop3xx_init_time(unsigned long tick_rate) +{ + u32 timer_ctl; + + ticks_per_jiffy = (tick_rate + HZ/2) / HZ; + ticks_per_usec = tick_rate / 1000000; + next_jiffy_time = 0xffffffff; + + timer_ctl = IOP3XX_TMR_EN | IOP3XX_TMR_PRIVILEGED | + IOP3XX_TMR_RELOAD | IOP3XX_TMR_RATIO_1_1; + + /* + * We use timer 0 for our timer interrupt, and timer 1 as + * monotonic counter for tracking missed jiffies. + */ + iop3xx_cp6_enable(); + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (ticks_per_jiffy - 1)); + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); + asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (0xffffffff)); + asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (timer_ctl)); + iop3xx_cp6_disable(); + + setup_irq(IRQ_IOP3XX_TIMER0, &iop3xx_timer_irq); +} diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 7f45c7c3e67..f1179ad4be1 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -100,6 +100,7 @@ void clk_disable(struct clk *clk) return; spin_lock_irqsave(&clockfw_lock, flags); + BUG_ON(clk->usecount == 0); if (arch_clock->clk_disable) arch_clock->clk_disable(clk); spin_unlock_irqrestore(&clockfw_lock, flags); @@ -322,6 +323,31 @@ EXPORT_SYMBOL(clk_allow_idle); /*-------------------------------------------------------------------------*/ +#ifdef CONFIG_OMAP_RESET_CLOCKS +/* + * Disable any unused clocks left on by the bootloader + */ +static int __init clk_disable_unused(void) +{ + struct clk *ck; + unsigned long flags; + + list_for_each_entry(ck, &clocks, node) { + if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || + ck->enable_reg == 0) + continue; + + spin_lock_irqsave(&clockfw_lock, flags); + if (arch_clock->clk_disable_unused) + arch_clock->clk_disable_unused(ck); + spin_unlock_irqrestore(&clockfw_lock, flags); + } + + return 0; +} +late_initcall(clk_disable_unused); +#endif + int __init clk_init(struct clk_functions * custom_clocks) { if (!custom_clocks) { diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 1812f237d12..dbc3f44e07a 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -148,7 +148,7 @@ static inline void omap_init_kp(void) {} #ifdef CONFIG_ARCH_OMAP24XX #define OMAP_MMC1_BASE 0x4809c000 -#define OMAP_MMC1_INT 83 +#define OMAP_MMC1_INT INT_24XX_MMC_IRQ #else #define OMAP_MMC1_BASE 0xfffb7800 #define OMAP_MMC1_INT INT_MMC @@ -225,7 +225,14 @@ static void __init omap_init_mmc(void) /* block 1 is always available and has just one pinout option */ mmc = &mmc_conf->mmc[0]; if (mmc->enabled) { - if (!cpu_is_omap24xx()) { + if (cpu_is_omap24xx()) { + omap_cfg_reg(H18_24XX_MMC_CMD); + omap_cfg_reg(H15_24XX_MMC_CLKI); + omap_cfg_reg(G19_24XX_MMC_CLKO); + omap_cfg_reg(F20_24XX_MMC_DAT0); + omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); + omap_cfg_reg(G18_24XX_MMC_CMD_DIR); + } else { omap_cfg_reg(MMC_CMD); omap_cfg_reg(MMC_CLK); omap_cfg_reg(MMC_DAT0); @@ -236,7 +243,14 @@ static void __init omap_init_mmc(void) } } if (mmc->wire4) { - if (!cpu_is_omap24xx()) { + if (cpu_is_omap24xx()) { + omap_cfg_reg(H14_24XX_MMC_DAT1); + omap_cfg_reg(E19_24XX_MMC_DAT2); + omap_cfg_reg(D19_24XX_MMC_DAT3); + omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); + omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); + omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); + } else { omap_cfg_reg(MMC_DAT1); /* NOTE: DAT2 can be on W10 (here) or M15 */ if (!mmc->nomux) diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 9eddc950714..1bbb431843c 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -119,32 +119,41 @@ static void clear_lch_regs(int lch) omap_writew(0, lch_base + i); } -void omap_set_dma_priority(int dst_port, int priority) +void omap_set_dma_priority(int lch, int dst_port, int priority) { unsigned long reg; u32 l; - switch (dst_port) { - case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ - reg = OMAP_TC_OCPT1_PRIOR; - break; - case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ - reg = OMAP_TC_OCPT2_PRIOR; - break; - case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ - reg = OMAP_TC_EMIFF_PRIOR; - break; - case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ - reg = OMAP_TC_EMIFS_PRIOR; - break; - default: - BUG(); - return; + if (cpu_class_is_omap1()) { + switch (dst_port) { + case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ + reg = OMAP_TC_OCPT1_PRIOR; + break; + case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ + reg = OMAP_TC_OCPT2_PRIOR; + break; + case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ + reg = OMAP_TC_EMIFF_PRIOR; + break; + case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ + reg = OMAP_TC_EMIFS_PRIOR; + break; + default: + BUG(); + return; + } + l = omap_readl(reg); + l &= ~(0xf << 8); + l |= (priority & 0xf) << 8; + omap_writel(l, reg); + } + + if (cpu_is_omap24xx()) { + if (priority) + OMAP_DMA_CCR_REG(lch) |= (1 << 6); + else + OMAP_DMA_CCR_REG(lch) &= ~(1 << 6); } - l = omap_readl(reg); - l &= ~(0xf << 8); - l |= (priority & 0xf) << 8; - omap_writel(l, reg); } void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, @@ -234,6 +243,14 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) OMAP1_DMA_LCH_CTRL_REG(lch) = w; } +void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) +{ + if (cpu_is_omap24xx()) { + OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16); + OMAP_DMA_CSDP_REG(lch) |= (mode << 16); + } +} + /* Note that src_port is only for omap1 */ void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start, @@ -698,6 +715,32 @@ void omap_stop_dma(int lch) } /* + * Allows changing the DMA callback function or data. This may be needed if + * the driver shares a single DMA channel for multiple dma triggers. + */ +int omap_set_dma_callback(int lch, + void (* callback)(int lch, u16 ch_status, void *data), + void *data) +{ + unsigned long flags; + + if (lch < 0) + return -ENODEV; + + spin_lock_irqsave(&dma_chan_lock, flags); + if (dma_chan[lch].dev_id == -1) { + printk(KERN_ERR "DMA callback for not set for free channel\n"); + spin_unlock_irqrestore(&dma_chan_lock, flags); + return -EINVAL; + } + dma_chan[lch].callback = callback; + dma_chan[lch].data = data; + spin_unlock_irqrestore(&dma_chan_lock, flags); + + return 0; +} + +/* * Returns current physical source address for the given DMA channel. * If the channel is running the caller must disable interrupts prior calling * this function and process the returned value before re-enabling interrupt to @@ -1339,6 +1382,14 @@ static int __init omap_init_dma(void) dma_chan_count = 16; } else dma_chan_count = 9; + if (cpu_is_omap16xx()) { + u16 w; + + /* this would prevent OMAP sleep */ + w = omap_readw(OMAP1610_DMA_LCD_CTRL); + w &= ~(1 << 8); + omap_writew(w, OMAP1610_DMA_LCD_CTRL); + } } else if (cpu_is_omap24xx()) { u8 revision = omap_readb(OMAP_DMA4_REVISION); printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", @@ -1414,11 +1465,13 @@ EXPORT_SYMBOL(omap_request_dma); EXPORT_SYMBOL(omap_free_dma); EXPORT_SYMBOL(omap_start_dma); EXPORT_SYMBOL(omap_stop_dma); +EXPORT_SYMBOL(omap_set_dma_callback); EXPORT_SYMBOL(omap_enable_dma_irq); EXPORT_SYMBOL(omap_disable_dma_irq); EXPORT_SYMBOL(omap_set_dma_transfer_params); EXPORT_SYMBOL(omap_set_dma_color_mode); +EXPORT_SYMBOL(omap_set_dma_write_mode); EXPORT_SYMBOL(omap_set_dma_src_params); EXPORT_SYMBOL(omap_set_dma_src_index); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 50524436de6..bcbb8d7392b 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -75,10 +75,14 @@ struct omap_dm_timer { #endif void __iomem *io_base; unsigned reserved:1; + unsigned enabled:1; }; #ifdef CONFIG_ARCH_OMAP1 +#define omap_dm_clk_enable(x) +#define omap_dm_clk_disable(x) + static struct omap_dm_timer dm_timers[] = { { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, @@ -92,6 +96,9 @@ static struct omap_dm_timer dm_timers[] = { #elif defined(CONFIG_ARCH_OMAP2) +#define omap_dm_clk_enable(x) clk_enable(x) +#define omap_dm_clk_disable(x) clk_disable(x) + static struct omap_dm_timer dm_timers[] = { { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, @@ -154,24 +161,28 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) { u32 l; - if (timer != &dm_timers[0]) { + if (!cpu_class_is_omap2() || timer != &dm_timers[0]) { omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); omap_dm_timer_wait_for_reset(timer); } - omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK); + omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); /* Set to smart-idle mode */ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG); l |= 0x02 << 3; + + if (cpu_class_is_omap2() && timer == &dm_timers[0]) { + /* Enable wake-up only for GPT1 on OMAP2 CPUs*/ + l |= 1 << 2; + /* Non-posted mode */ + omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0); + } omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l); } static void omap_dm_timer_prepare(struct omap_dm_timer *timer) { -#ifdef CONFIG_ARCH_OMAP2 - clk_enable(timer->iclk); - clk_enable(timer->fclk); -#endif + omap_dm_timer_enable(timer); omap_dm_timer_reset(timer); } @@ -223,15 +234,36 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id) void omap_dm_timer_free(struct omap_dm_timer *timer) { + omap_dm_timer_enable(timer); omap_dm_timer_reset(timer); -#ifdef CONFIG_ARCH_OMAP2 - clk_disable(timer->iclk); - clk_disable(timer->fclk); -#endif + omap_dm_timer_disable(timer); + WARN_ON(!timer->reserved); timer->reserved = 0; } +void omap_dm_timer_enable(struct omap_dm_timer *timer) +{ + if (timer->enabled) + return; + + omap_dm_clk_enable(timer->fclk); + omap_dm_clk_enable(timer->iclk); + + timer->enabled = 1; +} + +void omap_dm_timer_disable(struct omap_dm_timer *timer) +{ + if (!timer->enabled) + return; + + omap_dm_clk_disable(timer->iclk); + omap_dm_clk_disable(timer->fclk); + + timer->enabled = 0; +} + int omap_dm_timer_get_irq(struct omap_dm_timer *timer) { return timer->irq; @@ -276,7 +308,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) { - return timer->fclk; + return timer->fclk; } __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) @@ -406,11 +438,16 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value) { omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); + omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value); } unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) { - return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); + unsigned int l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); + + return l; } void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) @@ -420,12 +457,16 @@ void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) { - return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); + unsigned int l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); + + return l; } void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) { - return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); + omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); } int omap_dm_timers_active(void) @@ -436,9 +477,14 @@ int omap_dm_timers_active(void) struct omap_dm_timer *timer; timer = &dm_timers[i]; + + if (!timer->enabled) + continue; + if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & - OMAP_TIMER_CTRL_ST) + OMAP_TIMER_CTRL_ST) { return 1; + } } return 0; } diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index cd7f973fb28..f55f99ae58a 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -94,6 +94,8 @@ #define OMAP24XX_GPIO_SYSCONFIG 0x0010 #define OMAP24XX_GPIO_SYSSTATUS 0x0014 #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 +#define OMAP24XX_GPIO_IRQSTATUS2 0x0028 +#define OMAP24XX_GPIO_IRQENABLE2 0x002c #define OMAP24XX_GPIO_IRQENABLE1 0x001c #define OMAP24XX_GPIO_CTRL 0x0030 #define OMAP24XX_GPIO_OE 0x0034 @@ -110,8 +112,6 @@ #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 #define OMAP24XX_GPIO_SETDATAOUT 0x0094 -#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) - struct gpio_bank { void __iomem *base; u16 irq; @@ -216,11 +216,13 @@ static inline int gpio_valid(int gpio) { if (gpio < 0) return -1; +#ifndef CONFIG_ARCH_OMAP24XX if (OMAP_GPIO_IS_MPUIO(gpio)) { - if ((gpio & OMAP_MPUIO_MASK) > 16) + if (gpio >= OMAP_MAX_GPIO_LINES + 16) return -1; return 0; } +#endif #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap15xx() && gpio < 16) return 0; @@ -529,6 +531,10 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) return; } __raw_writel(gpio_mask, reg); + + /* Workaround for clearing DSP GPIO interrupts to allow retention */ + if (cpu_is_omap2420()) + __raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2); } static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) @@ -662,6 +668,14 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) } } +static void _reset_gpio(struct gpio_bank *bank, int gpio) +{ + _set_gpio_direction(bank, get_gpio_index(gpio), 1); + _set_gpio_irqenable(bank, gpio, 0); + _clear_gpio_irqstatus(bank, gpio); + _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); +} + /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ static int gpio_wake_enable(unsigned int irq, unsigned int enable) { @@ -672,9 +686,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) if (check_gpio(gpio) < 0) return -ENODEV; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); - spin_unlock(&bank->lock); return retval; } @@ -696,7 +708,9 @@ int omap_request_gpio(int gpio) } bank->reserved_map |= (1 << get_gpio_index(gpio)); - /* Set trigger to none. You need to enable the trigger after request_irq */ + /* Set trigger to none. You need to enable the desired trigger with + * request_irq() or set_irq_type(). + */ _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); #ifdef CONFIG_ARCH_OMAP15XX @@ -756,9 +770,7 @@ void omap_free_gpio(int gpio) } #endif bank->reserved_map &= ~(1 << get_gpio_index(gpio)); - _set_gpio_direction(bank, get_gpio_index(gpio), 1); - _set_gpio_irqenable(bank, gpio, 0); - _clear_gpio_irqstatus(bank, gpio); + _reset_gpio(bank, gpio); spin_unlock(&bank->lock); } @@ -898,6 +910,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, } +static void gpio_irq_shutdown(unsigned int irq) +{ + unsigned int gpio = irq - IH_GPIO_BASE; + struct gpio_bank *bank = get_gpio_bank(gpio); + + _reset_gpio(bank, gpio); +} + static void gpio_ack_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; @@ -946,6 +966,7 @@ static void mpuio_unmask_irq(unsigned int irq) static struct irq_chip gpio_irq_chip = { .name = "GPIO", + .shutdown = gpio_irq_shutdown, .ack = gpio_ack_irq, .mask = gpio_mask_irq, .unmask = gpio_unmask_irq, @@ -985,7 +1006,7 @@ static int __init _omap_gpio_init(void) else clk_enable(gpio_ick); gpio_fck = clk_get(NULL, "gpios_fck"); - if (IS_ERR(gpio_ick)) + if (IS_ERR(gpio_fck)) printk("Could not get gpios_fck\n"); else clk_enable(gpio_fck); @@ -1144,8 +1165,8 @@ static int omap_gpio_resume(struct sys_device *dev) wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; break; case METHOD_GPIO_24XX: - wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; - wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; + wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; + wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; break; default: continue; diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 196aac3ac32..ade9a0fa6ef 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -75,8 +75,6 @@ static struct clk *mcbsp1_ick = 0; static struct clk *mcbsp1_fck = 0; static struct clk *mcbsp2_ick = 0; static struct clk *mcbsp2_fck = 0; -static struct clk *sys_ck = 0; -static struct clk *sys_clkout = 0; #endif static void omap_mcbsp_dump_reg(u8 id) @@ -232,7 +230,6 @@ static void omap2_mcbsp2_mux_setup(void) omap_cfg_reg(W15_24XX_MCBSP2_DR); omap_cfg_reg(V15_24XX_MCBSP2_DX); omap_cfg_reg(V14_24XX_GPIO117); - omap_cfg_reg(W14_24XX_SYS_CLKOUT); } #endif @@ -984,13 +981,7 @@ static int __init omap_mcbsp_init(void) if (cpu_is_omap24xx()) { mcbsp_info = mcbsp_24xx; mcbsp_count = ARRAY_SIZE(mcbsp_24xx); - - /* REVISIT: where's the right place? */ omap2_mcbsp2_mux_setup(); - sys_ck = clk_get(0, "sys_ck"); - sys_clkout = clk_get(0, "sys_clkout"); - clk_set_parent(sys_clkout, sys_ck); - clk_enable(sys_clkout); } #endif for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c deleted file mode 100644 index 04b4102727a..00000000000 --- a/arch/arm/plat-omap/pm.c +++ /dev/null @@ -1,670 +0,0 @@ -/* - * linux/arch/arm/plat-omap/pm.c - * - * OMAP Power Management Routines - * - * Original code for the SA11x0: - * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> - * - * Modified for the PXA250 by Nicolas Pitre: - * Copyright (c) 2002 Monta Vista Software, Inc. - * - * Modified for the OMAP1510 by David Singleton: - * Copyright (c) 2002 Monta Vista Software, Inc. - * - * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR 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. - * - * 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/pm.h> -#include <linux/sched.h> -#include <linux/proc_fs.h> -#include <linux/pm.h> -#include <linux/interrupt.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/mach/time.h> -#include <asm/mach/irq.h> - -#include <asm/mach-types.h> -#include <asm/arch/irqs.h> -#include <asm/arch/tc.h> -#include <asm/arch/pm.h> -#include <asm/arch/mux.h> -#include <asm/arch/tps65010.h> -#include <asm/arch/dsp_common.h> - -#include <asm/arch/clock.h> -#include <asm/arch/sram.h> - -static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; -static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; -static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE]; -static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; -static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; - -static void (*omap_sram_idle)(void) = NULL; -static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; - -/* - * Let's power down on idle, but only if we are really - * idle, because once we start down the path of - * going idle we continue to do idle even if we get - * a clock tick interrupt . . - */ -void omap_pm_idle(void) -{ - unsigned int mask32 = 0; - - /* - * If the DSP is being used let's just idle the CPU, the overhead - * to wake up from Big Sleep is big, milliseconds versus micro - * seconds for wait for interrupt. - */ - - local_irq_disable(); - local_fiq_disable(); - if (need_resched()) { - local_fiq_enable(); - local_irq_enable(); - return; - } - mask32 = omap_readl(ARM_SYSST); - - /* - * Prevent the ULPD from entering low power state by setting - * POWER_CTRL_REG:4 = 0 - */ - omap_writew(omap_readw(ULPD_POWER_CTRL) & - ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL); - - /* - * Since an interrupt may set up a timer, we don't want to - * reprogram the hardware timer with interrupts enabled. - * Re-enable interrupts only after returning from idle. - */ - timer_dyn_reprogram(); - - if ((mask32 & DSP_IDLE) == 0) { - __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); - } else - omap_sram_idle(); - - local_fiq_enable(); - local_irq_enable(); -} - -/* - * Configuration of the wakeup event is board specific. For the - * moment we put it into this helper function. Later it may move - * to board specific files. - */ -static void omap_pm_wakeup_setup(void) -{ - u32 level1_wake = 0; - u32 level2_wake = OMAP_IRQ_BIT(INT_UART2); - - /* - * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, - * and the L2 wakeup interrupts: keypad and UART2. Note that the - * drivers must still separately call omap_set_gpio_wakeup() to - * wake up to a GPIO interrupt. - */ - if (cpu_is_omap730()) - level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) | - OMAP_IRQ_BIT(INT_730_IH2_IRQ); - else if (cpu_is_omap1510()) - level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | - OMAP_IRQ_BIT(INT_1510_IH2_IRQ); - else if (cpu_is_omap16xx()) - level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | - OMAP_IRQ_BIT(INT_1610_IH2_IRQ); - - omap_writel(~level1_wake, OMAP_IH1_MIR); - - if (cpu_is_omap730()) { - omap_writel(~level2_wake, OMAP_IH2_0_MIR); - omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR); - } else if (cpu_is_omap1510()) { - level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); - omap_writel(~level2_wake, OMAP_IH2_MIR); - } else if (cpu_is_omap16xx()) { - level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); - omap_writel(~level2_wake, OMAP_IH2_0_MIR); - - /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ - omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR); - omap_writel(~0x0, OMAP_IH2_2_MIR); - omap_writel(~0x0, OMAP_IH2_3_MIR); - } - - /* New IRQ agreement, recalculate in cascade order */ - omap_writel(1, OMAP_IH2_CONTROL); - omap_writel(1, OMAP_IH1_CONTROL); -} - -void omap_pm_suspend(void) -{ - unsigned long arg0 = 0, arg1 = 0; - - printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev); - - omap_serial_wake_trigger(1); - - if (machine_is_omap_osk()) { - /* Stop LED1 (D9) blink */ - tps65010_set_led(LED1, OFF); - } - - omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); - - /* - * Step 1: turn off interrupts (FIXME: NOTE: already disabled) - */ - - local_irq_disable(); - local_fiq_disable(); - - /* - * Step 2: save registers - * - * The omap is a strange/beautiful device. The caches, memory - * and register state are preserved across power saves. - * We have to save and restore very little register state to - * idle the omap. - * - * Save interrupt, MPUI, ARM and UPLD control registers. - */ - - if (cpu_is_omap730()) { - MPUI730_SAVE(OMAP_IH1_MIR); - MPUI730_SAVE(OMAP_IH2_0_MIR); - MPUI730_SAVE(OMAP_IH2_1_MIR); - MPUI730_SAVE(MPUI_CTRL); - MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI730_SAVE(MPUI_DSP_API_CONFIG); - MPUI730_SAVE(EMIFS_CONFIG); - MPUI730_SAVE(EMIFF_SDRAM_CONFIG); - - } else if (cpu_is_omap1510()) { - MPUI1510_SAVE(OMAP_IH1_MIR); - MPUI1510_SAVE(OMAP_IH2_MIR); - MPUI1510_SAVE(MPUI_CTRL); - MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI1510_SAVE(MPUI_DSP_API_CONFIG); - MPUI1510_SAVE(EMIFS_CONFIG); - MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); - } else if (cpu_is_omap16xx()) { - MPUI1610_SAVE(OMAP_IH1_MIR); - MPUI1610_SAVE(OMAP_IH2_0_MIR); - MPUI1610_SAVE(OMAP_IH2_1_MIR); - MPUI1610_SAVE(OMAP_IH2_2_MIR); - MPUI1610_SAVE(OMAP_IH2_3_MIR); - MPUI1610_SAVE(MPUI_CTRL); - MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI1610_SAVE(MPUI_DSP_API_CONFIG); - MPUI1610_SAVE(EMIFS_CONFIG); - MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); - } - - ARM_SAVE(ARM_CKCTL); - ARM_SAVE(ARM_IDLECT1); - ARM_SAVE(ARM_IDLECT2); - if (!(cpu_is_omap1510())) - ARM_SAVE(ARM_IDLECT3); - ARM_SAVE(ARM_EWUPCT); - ARM_SAVE(ARM_RSTCT1); - ARM_SAVE(ARM_RSTCT2); - ARM_SAVE(ARM_SYSST); - ULPD_SAVE(ULPD_CLOCK_CTRL); - ULPD_SAVE(ULPD_STATUS_REQ); - - /* (Step 3 removed - we now allow deep sleep by default) */ - - /* - * Step 4: OMAP DSP Shutdown - */ - - - /* - * Step 5: Wakeup Event Setup - */ - - omap_pm_wakeup_setup(); - - /* - * Step 6: ARM and Traffic controller shutdown - */ - - /* disable ARM watchdog */ - omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); - omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); - - /* - * Step 6b: ARM and Traffic controller shutdown - * - * Step 6 continues here. Prepare jump to power management - * assembly code in internal SRAM. - * - * Since the omap_cpu_suspend routine has been copied to - * SRAM, we'll do an indirect procedure call to it and pass the - * contents of arm_idlect1 and arm_idlect2 so it can restore - * them when it wakes up and it will return. - */ - - arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; - arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; - - /* - * Step 6c: ARM and Traffic controller shutdown - * - * Jump to assembly code. The processor will stay there - * until wake up. - */ - omap_sram_suspend(arg0, arg1); - - /* - * If we are here, processor is woken up! - */ - - /* - * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did - */ - - if (!(cpu_is_omap1510())) - ARM_RESTORE(ARM_IDLECT3); - ARM_RESTORE(ARM_CKCTL); - ARM_RESTORE(ARM_EWUPCT); - ARM_RESTORE(ARM_RSTCT1); - ARM_RESTORE(ARM_RSTCT2); - ARM_RESTORE(ARM_SYSST); - ULPD_RESTORE(ULPD_CLOCK_CTRL); - ULPD_RESTORE(ULPD_STATUS_REQ); - - if (cpu_is_omap730()) { - MPUI730_RESTORE(EMIFS_CONFIG); - MPUI730_RESTORE(EMIFF_SDRAM_CONFIG); - MPUI730_RESTORE(OMAP_IH1_MIR); - MPUI730_RESTORE(OMAP_IH2_0_MIR); - MPUI730_RESTORE(OMAP_IH2_1_MIR); - } else if (cpu_is_omap1510()) { - MPUI1510_RESTORE(MPUI_CTRL); - MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); - MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); - MPUI1510_RESTORE(EMIFS_CONFIG); - MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG); - MPUI1510_RESTORE(OMAP_IH1_MIR); - MPUI1510_RESTORE(OMAP_IH2_MIR); - } else if (cpu_is_omap16xx()) { - MPUI1610_RESTORE(MPUI_CTRL); - MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG); - MPUI1610_RESTORE(MPUI_DSP_API_CONFIG); - MPUI1610_RESTORE(EMIFS_CONFIG); - MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG); - - MPUI1610_RESTORE(OMAP_IH1_MIR); - MPUI1610_RESTORE(OMAP_IH2_0_MIR); - MPUI1610_RESTORE(OMAP_IH2_1_MIR); - MPUI1610_RESTORE(OMAP_IH2_2_MIR); - MPUI1610_RESTORE(OMAP_IH2_3_MIR); - } - - omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); - - /* - * Reenable interrupts - */ - - local_irq_enable(); - local_fiq_enable(); - - omap_serial_wake_trigger(0); - - printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); - - if (machine_is_omap_osk()) { - /* Let LED1 (D9) blink again */ - tps65010_set_led(LED1, BLINK); - } -} - -#if defined(DEBUG) && defined(CONFIG_PROC_FS) -static int g_read_completed; - -/* - * Read system PM registers for debugging - */ -static int omap_pm_read_proc( - char *page_buffer, - char **my_first_byte, - off_t virtual_start, - int length, - int *eof, - void *data) -{ - int my_buffer_offset = 0; - char * const my_base = page_buffer; - - ARM_SAVE(ARM_CKCTL); - ARM_SAVE(ARM_IDLECT1); - ARM_SAVE(ARM_IDLECT2); - if (!(cpu_is_omap1510())) - ARM_SAVE(ARM_IDLECT3); - ARM_SAVE(ARM_EWUPCT); - ARM_SAVE(ARM_RSTCT1); - ARM_SAVE(ARM_RSTCT2); - ARM_SAVE(ARM_SYSST); - - ULPD_SAVE(ULPD_IT_STATUS); - ULPD_SAVE(ULPD_CLOCK_CTRL); - ULPD_SAVE(ULPD_SOFT_REQ); - ULPD_SAVE(ULPD_STATUS_REQ); - ULPD_SAVE(ULPD_DPLL_CTRL); - ULPD_SAVE(ULPD_POWER_CTRL); - - if (cpu_is_omap730()) { - MPUI730_SAVE(MPUI_CTRL); - MPUI730_SAVE(MPUI_DSP_STATUS); - MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI730_SAVE(MPUI_DSP_API_CONFIG); - MPUI730_SAVE(EMIFF_SDRAM_CONFIG); - MPUI730_SAVE(EMIFS_CONFIG); - } else if (cpu_is_omap1510()) { - MPUI1510_SAVE(MPUI_CTRL); - MPUI1510_SAVE(MPUI_DSP_STATUS); - MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI1510_SAVE(MPUI_DSP_API_CONFIG); - MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); - MPUI1510_SAVE(EMIFS_CONFIG); - } else if (cpu_is_omap16xx()) { - MPUI1610_SAVE(MPUI_CTRL); - MPUI1610_SAVE(MPUI_DSP_STATUS); - MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); - MPUI1610_SAVE(MPUI_DSP_API_CONFIG); - MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); - MPUI1610_SAVE(EMIFS_CONFIG); - } - - if (virtual_start == 0) { - g_read_completed = 0; - - my_buffer_offset += sprintf(my_base + my_buffer_offset, - "ARM_CKCTL_REG: 0x%-8x \n" - "ARM_IDLECT1_REG: 0x%-8x \n" - "ARM_IDLECT2_REG: 0x%-8x \n" - "ARM_IDLECT3_REG: 0x%-8x \n" - "ARM_EWUPCT_REG: 0x%-8x \n" - "ARM_RSTCT1_REG: 0x%-8x \n" - "ARM_RSTCT2_REG: 0x%-8x \n" - "ARM_SYSST_REG: 0x%-8x \n" - "ULPD_IT_STATUS_REG: 0x%-4x \n" - "ULPD_CLOCK_CTRL_REG: 0x%-4x \n" - "ULPD_SOFT_REQ_REG: 0x%-4x \n" - "ULPD_DPLL_CTRL_REG: 0x%-4x \n" - "ULPD_STATUS_REQ_REG: 0x%-4x \n" - "ULPD_POWER_CTRL_REG: 0x%-4x \n", - ARM_SHOW(ARM_CKCTL), - ARM_SHOW(ARM_IDLECT1), - ARM_SHOW(ARM_IDLECT2), - ARM_SHOW(ARM_IDLECT3), - ARM_SHOW(ARM_EWUPCT), - ARM_SHOW(ARM_RSTCT1), - ARM_SHOW(ARM_RSTCT2), - ARM_SHOW(ARM_SYSST), - ULPD_SHOW(ULPD_IT_STATUS), - ULPD_SHOW(ULPD_CLOCK_CTRL), - ULPD_SHOW(ULPD_SOFT_REQ), - ULPD_SHOW(ULPD_DPLL_CTRL), - ULPD_SHOW(ULPD_STATUS_REQ), - ULPD_SHOW(ULPD_POWER_CTRL)); - - if (cpu_is_omap730()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, - "MPUI730_CTRL_REG 0x%-8x \n" - "MPUI730_DSP_STATUS_REG: 0x%-8x \n" - "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n" - "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n" - "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n" - "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n", - MPUI730_SHOW(MPUI_CTRL), - MPUI730_SHOW(MPUI_DSP_STATUS), - MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG), - MPUI730_SHOW(MPUI_DSP_API_CONFIG), - MPUI730_SHOW(EMIFF_SDRAM_CONFIG), - MPUI730_SHOW(EMIFS_CONFIG)); - } else if (cpu_is_omap1510()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, - "MPUI1510_CTRL_REG 0x%-8x \n" - "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" - "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n" - "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n" - "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n" - "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n", - MPUI1510_SHOW(MPUI_CTRL), - MPUI1510_SHOW(MPUI_DSP_STATUS), - MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG), - MPUI1510_SHOW(MPUI_DSP_API_CONFIG), - MPUI1510_SHOW(EMIFF_SDRAM_CONFIG), - MPUI1510_SHOW(EMIFS_CONFIG)); - } else if (cpu_is_omap16xx()) { - my_buffer_offset += sprintf(my_base + my_buffer_offset, - "MPUI1610_CTRL_REG 0x%-8x \n" - "MPUI1610_DSP_STATUS_REG: 0x%-8x \n" - "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n" - "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n" - "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n" - "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n", - MPUI1610_SHOW(MPUI_CTRL), - MPUI1610_SHOW(MPUI_DSP_STATUS), - MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG), - MPUI1610_SHOW(MPUI_DSP_API_CONFIG), - MPUI1610_SHOW(EMIFF_SDRAM_CONFIG), - MPUI1610_SHOW(EMIFS_CONFIG)); - } - - g_read_completed++; - } else if (g_read_completed >= 1) { - *eof = 1; - return 0; - } - g_read_completed++; - - *my_first_byte = page_buffer; - return my_buffer_offset; -} - -static void omap_pm_init_proc(void) -{ - struct proc_dir_entry *entry; - - entry = create_proc_read_entry("driver/omap_pm", - S_IWUSR | S_IRUGO, NULL, - omap_pm_read_proc, NULL); -} - -#endif /* DEBUG && CONFIG_PROC_FS */ - -/* - * omap_pm_prepare - Do preliminary suspend work. - * @state: suspend state we're entering. - * - */ -//#include <asm/hardware.h> - -static int omap_pm_prepare(suspend_state_t state) -{ - int error = 0; - - switch (state) - { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - break; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return error; -} - - -/* - * omap_pm_enter - Actually enter a sleep state. - * @state: State we're entering. - * - */ - -static int omap_pm_enter(suspend_state_t state) -{ - switch (state) - { - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - omap_pm_suspend(); - break; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return 0; -} - - -/** - * omap_pm_finish - Finish up suspend sequence. - * @state: State we're coming out of. - * - * This is called after we wake back up (or if entering the sleep state - * failed). - */ - -static int omap_pm_finish(suspend_state_t state) -{ - return 0; -} - - -static irqreturn_t omap_wakeup_interrupt(int irq, void * dev, - struct pt_regs * regs) -{ - return IRQ_HANDLED; -} - -static struct irqaction omap_wakeup_irq = { - .name = "peripheral wakeup", - .flags = IRQF_DISABLED, - .handler = omap_wakeup_interrupt -}; - - - -static struct pm_ops omap_pm_ops ={ - .pm_disk_mode = 0, - .prepare = omap_pm_prepare, - .enter = omap_pm_enter, - .finish = omap_pm_finish, -}; - -static int __init omap_pm_init(void) -{ - printk("Power Management for TI OMAP.\n"); - /* - * We copy the assembler sleep/wakeup routines to SRAM. - * These routines need to be in SRAM as that's the only - * memory the MPU can see when it wakes up. - */ - if (cpu_is_omap730()) { - omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend, - omap730_idle_loop_suspend_sz); - omap_sram_suspend = omap_sram_push(omap730_cpu_suspend, - omap730_cpu_suspend_sz); - } else if (cpu_is_omap1510()) { - omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, - omap1510_idle_loop_suspend_sz); - omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, - omap1510_cpu_suspend_sz); - } else if (cpu_is_omap16xx()) { - omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend, - omap1610_idle_loop_suspend_sz); - omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend, - omap1610_cpu_suspend_sz); - } - - if (omap_sram_idle == NULL || omap_sram_suspend == NULL) { - printk(KERN_ERR "PM not initialized: Missing SRAM support\n"); - return -ENODEV; - } - - pm_idle = omap_pm_idle; - - if (cpu_is_omap730()) - setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq); - else if (cpu_is_omap16xx()) - setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); - -#if 0 - /* --- BEGIN BOARD-DEPENDENT CODE --- */ - /* Sleepx mask direction */ - omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); - /* Unmask sleepx signal */ - omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); - /* --- END BOARD-DEPENDENT CODE --- */ -#endif - - /* Program new power ramp-up time - * (0 for most boards since we don't lower voltage when in deep sleep) - */ - omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3); - - /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */ - omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); - - /* Configure IDLECT3 */ - if (cpu_is_omap730()) - omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3); - else if (cpu_is_omap16xx()) - omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); - - pm_set_ops(&omap_pm_ops); - -#if defined(DEBUG) && defined(CONFIG_PROC_FS) - omap_pm_init_proc(); -#endif - - if (cpu_is_omap16xx()) { - /* configure LOW_PWR pin */ - omap_cfg_reg(T20_1610_LOW_PWR); - } - - return 0; -} -__initcall(omap_pm_init); - diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index e75718301b0..19014b2ff4c 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -174,10 +174,7 @@ void __init omap_map_sram(void) if (cpu_is_omap24xx()) { omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; - if (is_sram_locked()) - base = OMAP2_SRAM_PUB_PA; - else - base = OMAP2_SRAM_PA; + base = OMAP2_SRAM_PA; base = ROUND_DOWN(base, PAGE_SIZE); omap_sram_io_desc[0].pfn = __phys_to_pfn(base); } diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c index 281ecc7fcdf..cf6df3378d3 100644 --- a/arch/arm/plat-omap/timer32k.c +++ b/arch/arm/plat-omap/timer32k.c @@ -105,6 +105,8 @@ static inline unsigned long omap_32k_timer_read(int reg) static inline void omap_32k_timer_start(unsigned long load_val) { + if (!load_val) + load_val = 1; omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); } @@ -192,14 +194,11 @@ unsigned long long sched_clock(void) * issues with dynamic tick. In the dynamic tick case, we need to lock * with irqsave. */ -static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { - unsigned long flags; unsigned long now; - write_seqlock_irqsave(&xtime_lock, flags); - omap_32k_timer_ack_irq(); now = omap_32k_sync_timer_read(); @@ -215,6 +214,23 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, * continuous timer can be overridden from pm_idle to be longer. */ omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); + + return IRQ_HANDLED; +} + +static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id, + struct pt_regs *regs) +{ + return _omap_32k_timer_interrupt(irq, dev_id, regs); +} + +static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long flags; + + write_seqlock_irqsave(&xtime_lock, flags); + _omap_32k_timer_interrupt(irq, dev_id, regs); write_sequnlock_irqrestore(&xtime_lock, flags); return IRQ_HANDLED; @@ -230,7 +246,15 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, */ void omap_32k_timer_reprogram(unsigned long next_tick) { - omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); + unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1; + unsigned long now = omap_32k_sync_timer_read(); + unsigned long idled = now - omap_32k_last_tick; + + if (idled + 1 < ticks) + ticks -= idled; + else + ticks = 1; + omap_32k_timer_start(ticks); } static struct irqaction omap_32k_timer_irq; @@ -252,7 +276,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = { .enable = omap_32k_timer_enable_dyn_tick, .disable = omap_32k_timer_disable_dyn_tick, .reprogram = omap_32k_timer_reprogram, - .handler = omap_32k_timer_interrupt, + .handler = omap_32k_timer_handler, }; #endif /* CONFIG_NO_IDLE_HZ */ diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index e1372a25311..b02af1d740f 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon Jun 26 22:26:08 2006 +# Last update: Sat Sep 23 13:20:43 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -329,7 +329,7 @@ nimbra29x ARCH_NIMBRA29X NIMBRA29X 311 nimbra210 ARCH_NIMBRA210 NIMBRA210 312 hhp_d95xx ARCH_HHP_D95XX HHP_D95XX 313 labarm ARCH_LABARM LABARM 314 -comcerto ARCH_M825XX M825XX 315 +m825xx ARCH_M825XX M825XX 315 m7100 SA1100_M7100 M7100 316 nipc2 ARCH_NIPC2 NIPC2 317 fu7202 ARCH_FU7202 FU7202 318 @@ -857,12 +857,12 @@ osiris MACH_OSIRIS OSIRIS 842 maestro MACH_MAESTRO MAESTRO 843 tunge2 MACH_TUNGE2 TUNGE2 844 ixbbm MACH_IXBBM IXBBM 845 -mx27ads MACH_MX27 MX27 846 +mx27ads MACH_MX27ADS MX27ADS 846 ax8004 MACH_AX8004 AX8004 847 at91sam9261ek MACH_AT91SAM9261EK AT91SAM9261EK 848 loft MACH_LOFT LOFT 849 magpie MACH_MAGPIE MAGPIE 850 -mx21ads MACH_MX21 MX21 851 +mx21ads MACH_MX21ADS MX21ADS 851 mb87m3400 MACH_MB87M3400 MB87M3400 852 mguard_delta MACH_MGUARD_DELTA MGUARD_DELTA 853 davinci_dvdp MACH_DAVINCI_DVDP DAVINCI_DVDP 854 @@ -1058,7 +1058,7 @@ akai9307 MACH_AKAI9307 AKAI9307 1044 fontaine MACH_FONTAINE FONTAINE 1045 wombat MACH_WOMBAT WOMBAT 1046 acq300 MACH_ACQ300 ACQ300 1047 -mod_270 MACH_MOD_270 MOD_270 1048 +mod272 MACH_MOD_270 MOD_270 1048 vmc_vc0820 MACH_VC0820 VC0820 1049 ani_aim MACH_ANI_AIM ANI_AIM 1050 jellyfish MACH_JELLYFISH JELLYFISH 1051 @@ -1093,3 +1093,67 @@ msm6100 MACH_MSM6100 MSM6100 1079 eti_b1 MACH_ETI_B1 ETI_B1 1080 za9l_series MACH_ZILOG_ZA9L ZILOG_ZA9L 1081 bit2440 MACH_BIT2440 BIT2440 1082 +nbi MACH_NBI NBI 1083 +smdk2443 MACH_SMDK2443 SMDK2443 1084 +vdavinci MACH_VDAVINCI VDAVINCI 1085 +atc6 MACH_ATC6 ATC6 1086 +multmdw MACH_MULTMDW MULTMDW 1087 +mba2440 MACH_MBA2440 MBA2440 1088 +ecsd MACH_ECSD ECSD 1089 +zire31 MACH_ZIRE31 ZIRE31 1090 +fsg MACH_FSG FSG 1091 +razor101 MACH_RAZOR101 RAZOR101 1092 +opera_tdm MACH_OPERA_TDM OPERA_TDM 1093 +comcerto MACH_COMCERTO COMCERTO 1094 +tb0319 MACH_TB0319 TB0319 1095 +kws8000 MACH_KWS8000 KWS8000 1096 +b2 MACH_B2 B2 1097 +lcl54 MACH_LCL54 LCL54 1098 +at91sam9260ek MACH_AT91SAM9260EK AT91SAM9260EK 1099 +glantank MACH_GLANTANK GLANTANK 1100 +n2100 MACH_N2100 N2100 1101 +n4100 MACH_N4100 N4100 1102 +rsc4 MACH_VERTICAL_RSC4 VERTICAL_RSC4 1103 +sg8100 MACH_SG8100 SG8100 1104 +im42xx MACH_IM42XX IM42XX 1105 +ftxx MACH_FTXX FTXX 1106 +lwfusion MACH_LWFUSION LWFUSION 1107 +qt2410 MACH_QT2410 QT2410 1108 +kixrp435 MACH_KIXRP435 KIXRP435 1109 +ccw9c MACH_CCW9C CCW9C 1110 +dabhs MACH_DABHS DABHS 1111 +gzmx MACH_GZMX GZMX 1112 +ipnw100ap MACH_IPNW100AP IPNW100AP 1113 +cc9p9360dev MACH_CC9P9360DEV CC9P9360DEV 1114 +cc9p9750dev MACH_CC9P9750DEV CC9P9750DEV 1115 +cc9p9360val MACH_CC9P9360VAL CC9P9360VAL 1116 +cc9p9750val MACH_CC9P9750VAL CC9P9750VAL 1117 +nx70v MACH_NX70V NX70V 1118 +at91rm9200df MACH_AT91RM9200DF AT91RM9200DF 1119 +se_pilot2 MACH_SE_PILOT2 SE_PILOT2 1120 +mtcn_t800 MACH_MTCN_T800 MTCN_T800 1121 +vcmx212 MACH_VCMX212 VCMX212 1122 +lynx MACH_LYNX LYNX 1123 +at91sam9260id MACH_AT91SAM9260ID AT91SAM9260ID 1124 +hw86052 MACH_HW86052 HW86052 1125 +pilz_pmi3 MACH_PILZ_PMI3 PILZ_PMI3 1126 +edb9302a MACH_EDB9302A EDB9302A 1127 +edb9307a MACH_EDB9307A EDB9307A 1128 +ct_dfs MACH_CT_DFS CT_DFS 1129 +pilz_pmi4 MACH_PILZ_PMI4 PILZ_PMI4 1130 +xceednp_ixp MACH_XCEEDNP_IXP XCEEDNP_IXP 1131 +smdk2442b MACH_SMDK2442B SMDK2442B 1132 +xnode MACH_XNODE XNODE 1133 +aidx270 MACH_AIDX270 AIDX270 1134 +rema MACH_REMA REMA 1135 +bps1000 MACH_BPS1000 BPS1000 1136 +hw90350 MACH_HW90350 HW90350 1137 +omap_sdp3430 MACH_OMAP_SDP3430 OMAP_SDP3430 1138 +bluetouch MACH_BLUETOUCH BLUETOUCH 1139 +vstms MACH_VSTMS VSTMS 1140 +xsbase270 MACH_XSBASE270 XSBASE270 1141 +at91sam9260ek_cn MACH_AT91SAM9260EK_CN AT91SAM9260EK_CN 1142 +adsturboxb MACH_ADSTURBOXB ADSTURBOXB 1143 +oti4110 MACH_OTI4110 OTI4110 1144 +hme_pxa MACH_HME_PXA HME_PXA 1145 +deisterdca MACH_DEISTERDCA DEISTERDCA 1146 diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h index 96fdf30f6a3..f2797896e6d 100644 --- a/arch/arm/vfp/vfp.h +++ b/arch/arm/vfp/vfp.h @@ -355,3 +355,18 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); * we check for an error. */ #define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG) + +/* + * A flag to tell vfp instruction type. + * OP_SCALAR - this operation always operates in scalar mode + * OP_SD - the instruction exceptionally writes to a single precision result. + * OP_DD - the instruction exceptionally writes to a double precision result. + */ +#define OP_SCALAR (1 << 0) +#define OP_SD (1 << 1) +#define OP_DD (1 << 1) + +struct op { + u32 (* const fn)(int dd, int dn, int dm, u32 fpscr); + u32 flags; +}; diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index add48e36c2d..4fc05ee0a2e 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -659,22 +659,22 @@ static u32 vfp_double_ftosiz(int dd, int unused, int dm, u32 fpscr) } -static u32 (* const fop_extfns[32])(int dd, int unused, int dm, u32 fpscr) = { - [FEXT_TO_IDX(FEXT_FCPY)] = vfp_double_fcpy, - [FEXT_TO_IDX(FEXT_FABS)] = vfp_double_fabs, - [FEXT_TO_IDX(FEXT_FNEG)] = vfp_double_fneg, - [FEXT_TO_IDX(FEXT_FSQRT)] = vfp_double_fsqrt, - [FEXT_TO_IDX(FEXT_FCMP)] = vfp_double_fcmp, - [FEXT_TO_IDX(FEXT_FCMPE)] = vfp_double_fcmpe, - [FEXT_TO_IDX(FEXT_FCMPZ)] = vfp_double_fcmpz, - [FEXT_TO_IDX(FEXT_FCMPEZ)] = vfp_double_fcmpez, - [FEXT_TO_IDX(FEXT_FCVT)] = vfp_double_fcvts, - [FEXT_TO_IDX(FEXT_FUITO)] = vfp_double_fuito, - [FEXT_TO_IDX(FEXT_FSITO)] = vfp_double_fsito, - [FEXT_TO_IDX(FEXT_FTOUI)] = vfp_double_ftoui, - [FEXT_TO_IDX(FEXT_FTOUIZ)] = vfp_double_ftouiz, - [FEXT_TO_IDX(FEXT_FTOSI)] = vfp_double_ftosi, - [FEXT_TO_IDX(FEXT_FTOSIZ)] = vfp_double_ftosiz, +static struct op fops_ext[32] = { + [FEXT_TO_IDX(FEXT_FCPY)] = { vfp_double_fcpy, 0 }, + [FEXT_TO_IDX(FEXT_FABS)] = { vfp_double_fabs, 0 }, + [FEXT_TO_IDX(FEXT_FNEG)] = { vfp_double_fneg, 0 }, + [FEXT_TO_IDX(FEXT_FSQRT)] = { vfp_double_fsqrt, 0 }, + [FEXT_TO_IDX(FEXT_FCMP)] = { vfp_double_fcmp, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FCMPE)] = { vfp_double_fcmpe, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FCMPZ)] = { vfp_double_fcmpz, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FCMPEZ)] = { vfp_double_fcmpez, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FCVT)] = { vfp_double_fcvts, OP_SCALAR|OP_SD }, + [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_double_fuito, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_double_fsito, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FTOUI)] = { vfp_double_ftoui, OP_SCALAR|OP_SD }, + [FEXT_TO_IDX(FEXT_FTOUIZ)] = { vfp_double_ftouiz, OP_SCALAR|OP_SD }, + [FEXT_TO_IDX(FEXT_FTOSI)] = { vfp_double_ftosi, OP_SCALAR|OP_SD }, + [FEXT_TO_IDX(FEXT_FTOSIZ)] = { vfp_double_ftosiz, OP_SCALAR|OP_SD }, }; @@ -1108,16 +1108,16 @@ static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr) return FPSCR_IOC; } -static u32 (* const fop_fns[16])(int dd, int dn, int dm, u32 fpscr) = { - [FOP_TO_IDX(FOP_FMAC)] = vfp_double_fmac, - [FOP_TO_IDX(FOP_FNMAC)] = vfp_double_fnmac, - [FOP_TO_IDX(FOP_FMSC)] = vfp_double_fmsc, - [FOP_TO_IDX(FOP_FNMSC)] = vfp_double_fnmsc, - [FOP_TO_IDX(FOP_FMUL)] = vfp_double_fmul, - [FOP_TO_IDX(FOP_FNMUL)] = vfp_double_fnmul, - [FOP_TO_IDX(FOP_FADD)] = vfp_double_fadd, - [FOP_TO_IDX(FOP_FSUB)] = vfp_double_fsub, - [FOP_TO_IDX(FOP_FDIV)] = vfp_double_fdiv, +static struct op fops[16] = { + [FOP_TO_IDX(FOP_FMAC)] = { vfp_double_fmac, 0 }, + [FOP_TO_IDX(FOP_FNMAC)] = { vfp_double_fnmac, 0 }, + [FOP_TO_IDX(FOP_FMSC)] = { vfp_double_fmsc, 0 }, + [FOP_TO_IDX(FOP_FNMSC)] = { vfp_double_fnmsc, 0 }, + [FOP_TO_IDX(FOP_FMUL)] = { vfp_double_fmul, 0 }, + [FOP_TO_IDX(FOP_FNMUL)] = { vfp_double_fnmul, 0 }, + [FOP_TO_IDX(FOP_FADD)] = { vfp_double_fadd, 0 }, + [FOP_TO_IDX(FOP_FSUB)] = { vfp_double_fsub, 0 }, + [FOP_TO_IDX(FOP_FDIV)] = { vfp_double_fdiv, 0 }, }; #define FREG_BANK(x) ((x) & 0x0c) @@ -1131,69 +1131,60 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) unsigned int dn = vfp_get_dn(inst); unsigned int dm = vfp_get_dm(inst); unsigned int vecitr, veclen, vecstride; - u32 (*fop)(int, int, s32, u32); + struct op *fop; - veclen = fpscr & FPSCR_LENGTH_MASK; vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2; + fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; + /* * fcvtds takes an sN register number as destination, not dN. * It also always operates on scalars. */ - if ((inst & FEXT_MASK) == FEXT_FCVT) { - veclen = 0; + if (fop->flags & OP_SD) dest = vfp_get_sd(inst); - } else + else dest = vfp_get_dd(inst); /* * If destination bank is zero, vector length is always '1'. * ARM DDI0100F C5.1.3, C5.3.2. */ - if (FREG_BANK(dest) == 0) + if ((fop->flags & OP_SCALAR) || (FREG_BANK(dest) == 0)) veclen = 0; + else + veclen = fpscr & FPSCR_LENGTH_MASK; pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, (veclen >> FPSCR_LENGTH_BIT) + 1); - fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; - if (!fop) + if (!fop->fn) goto invalid; for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { u32 except; + char type; - if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT) - pr_debug("VFP: itr%d (s%u) = op[%u] (d%u)\n", - vecitr >> FPSCR_LENGTH_BIT, - dest, dn, dm); - else if (op == FOP_EXT) - pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n", + type = fop->flags & OP_SD ? 's' : 'd'; + if (op == FOP_EXT) + pr_debug("VFP: itr%d (%c%u) = op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, - dest, dn, dm); + type, dest, dn, dm); else - pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n", + pr_debug("VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, - dest, dn, FOP_TO_IDX(op), dm); + type, dest, dn, FOP_TO_IDX(op), dm); - except = fop(dest, dn, dm, fpscr); + except = fop->fn(dest, dn, dm, fpscr); pr_debug("VFP: itr%d: exceptions=%08x\n", vecitr >> FPSCR_LENGTH_BIT, except); exceptions |= except; /* - * This ensures that comparisons only operate on scalars; - * comparisons always return with one FPSCR status bit set. - */ - if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) - break; - - /* * CHECK: It appears to be undefined whether we stop when * we encounter an exception. We continue. */ - dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6); dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6); if (FREG_BANK(dm) != 0) diff --git a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h index 6c819aeae00..7f343a4beca 100644 --- a/arch/arm/vfp/vfpinstr.h +++ b/arch/arm/vfp/vfpinstr.h @@ -73,14 +73,14 @@ #define fmrx(_vfp_) ({ \ u32 __v; \ - asm("mrc%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ - : "=r" (__v)); \ + asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ + : "=r" (__v) : : "cc"); \ __v; \ }) #define fmxr(_vfp_,_var_) \ - asm("mcr%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ - : : "r" (_var_)) + asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ + : : "r" (_var_) : "cc") u32 vfp_single_cpdo(u32 inst, u32 fpscr); u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs); diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 4178f6cc3d3..dedbb449632 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -40,10 +40,19 @@ unsigned int VFP_arch; static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) { struct thread_info *thread = v; - union vfp_state *vfp = &thread->vfpstate; + union vfp_state *vfp; - switch (cmd) { - case THREAD_NOTIFY_FLUSH: + if (likely(cmd == THREAD_NOTIFY_SWITCH)) { + /* + * Always disable VFP so we can lazily save/restore the + * old state. + */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); + return NOTIFY_DONE; + } + + vfp = &thread->vfpstate; + if (cmd == THREAD_NOTIFY_FLUSH) { /* * Per-thread VFP initialisation. */ @@ -56,29 +65,12 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) * Disable VFP to ensure we initialise it first. */ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); - - /* - * FALLTHROUGH: Ensure we don't try to overwrite our newly - * initialised state information on the first fault. - */ - - case THREAD_NOTIFY_RELEASE: - /* - * Per-thread VFP cleanup. - */ - if (last_VFP_context == vfp) - last_VFP_context = NULL; - break; - - case THREAD_NOTIFY_SWITCH: - /* - * Always disable VFP so we can lazily save/restore the - * old state. - */ - fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); - break; } + /* flush and release case: Per-thread VFP cleanup. */ + if (last_VFP_context == vfp) + last_VFP_context = NULL; + return NOTIFY_DONE; } diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 8f6c179cafb..ab5e9503bae 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -702,22 +702,22 @@ static u32 vfp_single_ftosiz(int sd, int unused, s32 m, u32 fpscr) return vfp_single_ftosi(sd, unused, m, FPSCR_ROUND_TOZERO); } -static u32 (* const fop_extfns[32])(int sd, int unused, s32 m, u32 fpscr) = { - [FEXT_TO_IDX(FEXT_FCPY)] = vfp_single_fcpy, - [FEXT_TO_IDX(FEXT_FABS)] = vfp_single_fabs, - [FEXT_TO_IDX(FEXT_FNEG)] = vfp_single_fneg, - [FEXT_TO_IDX(FEXT_FSQRT)] = vfp_single_fsqrt, - [FEXT_TO_IDX(FEXT_FCMP)] = vfp_single_fcmp, - [FEXT_TO_IDX(FEXT_FCMPE)] = vfp_single_fcmpe, - [FEXT_TO_IDX(FEXT_FCMPZ)] = vfp_single_fcmpz, - [FEXT_TO_IDX(FEXT_FCMPEZ)] = vfp_single_fcmpez, - [FEXT_TO_IDX(FEXT_FCVT)] = vfp_single_fcvtd, - [FEXT_TO_IDX(FEXT_FUITO)] = vfp_single_fuito, - [FEXT_TO_IDX(FEXT_FSITO)] = vfp_single_fsito, - [FEXT_TO_IDX(FEXT_FTOUI)] = vfp_single_ftoui, - [FEXT_TO_IDX(FEXT_FTOUIZ)] = vfp_single_ftouiz, - [FEXT_TO_IDX(FEXT_FTOSI)] = vfp_single_ftosi, - [FEXT_TO_IDX(FEXT_FTOSIZ)] = vfp_single_ftosiz, +static struct op fops_ext[32] = { + [FEXT_TO_IDX(FEXT_FCPY)] = { vfp_single_fcpy, 0 }, + [FEXT_TO_IDX(FEXT_FABS)] = { vfp_single_fabs, 0 }, + [FEXT_TO_IDX(FEXT_FNEG)] = { vfp_single_fneg, 0 }, + [FEXT_TO_IDX(FEXT_FSQRT)] = { vfp_single_fsqrt, 0 }, + [FEXT_TO_IDX(FEXT_FCMP)] = { vfp_single_fcmp, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FCMPE)] = { vfp_single_fcmpe, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FCMPZ)] = { vfp_single_fcmpz, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FCMPEZ)] = { vfp_single_fcmpez, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FCVT)] = { vfp_single_fcvtd, OP_SCALAR|OP_DD }, + [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_single_fuito, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_single_fsito, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FTOUI)] = { vfp_single_ftoui, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FTOUIZ)] = { vfp_single_ftouiz, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FTOSI)] = { vfp_single_ftosi, OP_SCALAR }, + [FEXT_TO_IDX(FEXT_FTOSIZ)] = { vfp_single_ftosiz, OP_SCALAR }, }; @@ -1151,16 +1151,16 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) return FPSCR_IOC; } -static u32 (* const fop_fns[16])(int sd, int sn, s32 m, u32 fpscr) = { - [FOP_TO_IDX(FOP_FMAC)] = vfp_single_fmac, - [FOP_TO_IDX(FOP_FNMAC)] = vfp_single_fnmac, - [FOP_TO_IDX(FOP_FMSC)] = vfp_single_fmsc, - [FOP_TO_IDX(FOP_FNMSC)] = vfp_single_fnmsc, - [FOP_TO_IDX(FOP_FMUL)] = vfp_single_fmul, - [FOP_TO_IDX(FOP_FNMUL)] = vfp_single_fnmul, - [FOP_TO_IDX(FOP_FADD)] = vfp_single_fadd, - [FOP_TO_IDX(FOP_FSUB)] = vfp_single_fsub, - [FOP_TO_IDX(FOP_FDIV)] = vfp_single_fdiv, +static struct op fops[16] = { + [FOP_TO_IDX(FOP_FMAC)] = { vfp_single_fmac, 0 }, + [FOP_TO_IDX(FOP_FNMAC)] = { vfp_single_fnmac, 0 }, + [FOP_TO_IDX(FOP_FMSC)] = { vfp_single_fmsc, 0 }, + [FOP_TO_IDX(FOP_FNMSC)] = { vfp_single_fnmsc, 0 }, + [FOP_TO_IDX(FOP_FMUL)] = { vfp_single_fmul, 0 }, + [FOP_TO_IDX(FOP_FNMUL)] = { vfp_single_fnmul, 0 }, + [FOP_TO_IDX(FOP_FADD)] = { vfp_single_fadd, 0 }, + [FOP_TO_IDX(FOP_FSUB)] = { vfp_single_fsub, 0 }, + [FOP_TO_IDX(FOP_FDIV)] = { vfp_single_fdiv, 0 }, }; #define FREG_BANK(x) ((x) & 0x18) @@ -1174,70 +1174,63 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) unsigned int sn = vfp_get_sn(inst); unsigned int sm = vfp_get_sm(inst); unsigned int vecitr, veclen, vecstride; - u32 (*fop)(int, int, s32, u32); + struct op *fop; - veclen = fpscr & FPSCR_LENGTH_MASK; vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK); + fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; + /* * fcvtsd takes a dN register number as destination, not sN. * Technically, if bit 0 of dd is set, this is an invalid * instruction. However, we ignore this for efficiency. * It also only operates on scalars. */ - if ((inst & FEXT_MASK) == FEXT_FCVT) { - veclen = 0; + if (fop->flags & OP_DD) dest = vfp_get_dd(inst); - } else + else dest = vfp_get_sd(inst); /* * If destination bank is zero, vector length is always '1'. * ARM DDI0100F C5.1.3, C5.3.2. */ - if (FREG_BANK(dest) == 0) + if ((fop->flags & OP_SCALAR) || FREG_BANK(dest) == 0) veclen = 0; + else + veclen = fpscr & FPSCR_LENGTH_MASK; pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, (veclen >> FPSCR_LENGTH_BIT) + 1); - fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; - if (!fop) + if (!fop->fn) goto invalid; for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { s32 m = vfp_get_float(sm); u32 except; + char type; - if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT) - pr_debug("VFP: itr%d (d%u) = op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m); - else if (op == FOP_EXT) - pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m); + type = fop->flags & OP_DD ? 'd' : 's'; + if (op == FOP_EXT) + pr_debug("VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, + sm, m); else - pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, dest, sn, + pr_debug("VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, FOP_TO_IDX(op), sm, m); - except = fop(dest, sn, m, fpscr); + except = fop->fn(dest, sn, m, fpscr); pr_debug("VFP: itr%d: exceptions=%08x\n", vecitr >> FPSCR_LENGTH_BIT, except); exceptions |= except; /* - * This ensures that comparisons only operate on scalars; - * comparisons always return with one FPSCR status bit set. - */ - if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) - break; - - /* * CHECK: It appears to be undefined whether we stop when * we encounter an exception. We continue. */ - dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7); sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7); if (FREG_BANK(sm) != 0) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b216ca659cd..f900a516f09 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -51,6 +51,10 @@ config 64BIT Select this option if you have a 64 bit IBM zSeries machine and want to use the 64 bit addressing mode. +config 32BIT + bool + default y if !64BIT + config SMP bool "Symmetric multi-processing support" ---help--- @@ -149,6 +153,14 @@ config MARCH_Z990 This will be slightly faster but does not work on older machines such as the z900. +config MARCH_Z9_109 + bool "IBM System z9" + help + Select this to enable optimizations for IBM System z9-109, IBM + System z9 Enterprise Class (z9 EC), and IBM System z9 Business + Class (z9 BC). The kernel will be slightly faster but will not + work on older machines such as the z990, z890, z900, and z800. + endchoice config PACK_STACK diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 74ef57dcfa6..5deb9f7544a 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -33,6 +33,7 @@ endif cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5) cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900) cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990) +cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109) # # Prevent tail-call optimizations, to get clearer backtraces: diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index b69ed742f98..9a8f6ff2165 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -157,12 +157,12 @@ int appldata_diag(char record_nr, u16 function, unsigned long buffer, .prod_nr = {0xD3, 0xC9, 0xD5, 0xE4, 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */ .prod_fn = 0xD5D3, /* "NL" */ - .record_nr = record_nr, .version_nr = 0xF2F6, /* "26" */ .release_nr = 0xF0F1, /* "01" */ - .mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1], }; + id.record_nr = record_nr; + id.mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1]; return appldata_asm(&id, function, (void *) buffer, length); } /************************ timer, work, DIAG <END> ****************************/ diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index efd836c2e4a..2b137089f62 100644 --- a/arch/s390/crypto/crypt_s390.h +++ b/arch/s390/crypto/crypt_s390.h @@ -105,63 +105,6 @@ struct crypt_s390_query_status { }; /* - * Standard fixup and ex_table sections for crypt_s390 inline functions. - * label 0: the s390 crypto operation - * label 1: just after 1 to catch illegal operation exception - * (unsupported model) - * label 6: the return point after fixup - * label 7: set error value if exception _in_ crypto operation - * label 8: set error value if illegal operation exception - * [ret] is the variable to receive the error code - * [ERR] is the error code value - */ -#ifndef CONFIG_64BIT -#define __crypt_s390_fixup \ - ".section .fixup,\"ax\" \n" \ - "7: lhi %0,%h[e1] \n" \ - " bras 1,9f \n" \ - " .long 6b \n" \ - "8: lhi %0,%h[e2] \n" \ - " bras 1,9f \n" \ - " .long 6b \n" \ - "9: l 1,0(1) \n" \ - " br 1 \n" \ - ".previous \n" \ - ".section __ex_table,\"a\" \n" \ - " .align 4 \n" \ - " .long 0b,7b \n" \ - " .long 1b,8b \n" \ - ".previous" -#else /* CONFIG_64BIT */ -#define __crypt_s390_fixup \ - ".section .fixup,\"ax\" \n" \ - "7: lhi %0,%h[e1] \n" \ - " jg 6b \n" \ - "8: lhi %0,%h[e2] \n" \ - " jg 6b \n" \ - ".previous\n" \ - ".section __ex_table,\"a\" \n" \ - " .align 8 \n" \ - " .quad 0b,7b \n" \ - " .quad 1b,8b \n" \ - ".previous" -#endif /* CONFIG_64BIT */ - -/* - * Standard code for setting the result of s390 crypto instructions. - * %0: the register which will receive the result - * [result]: the register containing the result (e.g. second operand length - * to compute number of processed bytes]. - */ -#ifndef CONFIG_64BIT -#define __crypt_s390_set_result \ - " lr %0,%[result] \n" -#else /* CONFIG_64BIT */ -#define __crypt_s390_set_result \ - " lgr %0,%[result] \n" -#endif - -/* * Executes the KM (CIPHER MESSAGE) operation of the CPU. * @param func: the function code passed to KM; see crypt_s390_km_func * @param param: address of parameter block; see POP for details on each func @@ -176,28 +119,24 @@ crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len) { register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; register void* __param asm("1") = param; - register u8* __dest asm("4") = dest; register const u8* __src asm("2") = src; register long __src_len asm("3") = src_len; + register u8* __dest asm("4") = dest; int ret; - ret = 0; - __asm__ __volatile__ ( - "0: .insn rre,0xB92E0000,%1,%2 \n" /* KM opcode */ + asm volatile( + "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */ "1: brc 1,0b \n" /* handle partial completion */ - __crypt_s390_set_result - "6: \n" - __crypt_s390_fixup - : "+d" (ret), "+a" (__dest), "+a" (__src), - [result] "+d" (__src_len) - : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), - "a" (__param) - : "cc", "memory" - ); - if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ - ret = src_len - ret; - } - return ret; + " ahi %0,%h7\n" + "2: ahi %0,%h8\n" + "3:\n" + EX_TABLE(0b,3b) EX_TABLE(1b,2b) + : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) + : "d" (__func), "a" (__param), "0" (-EFAULT), + "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); + if (ret < 0) + return ret; + return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; } /* @@ -215,28 +154,24 @@ crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len) { register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; register void* __param asm("1") = param; - register u8* __dest asm("4") = dest; register const u8* __src asm("2") = src; register long __src_len asm("3") = src_len; + register u8* __dest asm("4") = dest; int ret; - ret = 0; - __asm__ __volatile__ ( - "0: .insn rre,0xB92F0000,%1,%2 \n" /* KMC opcode */ + asm volatile( + "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */ "1: brc 1,0b \n" /* handle partial completion */ - __crypt_s390_set_result - "6: \n" - __crypt_s390_fixup - : "+d" (ret), "+a" (__dest), "+a" (__src), - [result] "+d" (__src_len) - : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), - "a" (__param) - : "cc", "memory" - ); - if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ - ret = src_len - ret; - } - return ret; + " ahi %0,%h7\n" + "2: ahi %0,%h8\n" + "3:\n" + EX_TABLE(0b,3b) EX_TABLE(1b,2b) + : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) + : "d" (__func), "a" (__param), "0" (-EFAULT), + "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); + if (ret < 0) + return ret; + return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; } /* @@ -258,22 +193,19 @@ crypt_s390_kimd(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - ret = 0; - __asm__ __volatile__ ( - "0: .insn rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */ - "1: brc 1,0b \n" /* handle partical completion */ - __crypt_s390_set_result - "6: \n" - __crypt_s390_fixup - : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) - : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), - "a" (__param) - : "cc", "memory" - ); - if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){ - ret = src_len - ret; - } - return ret; + asm volatile( + "0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */ + "1: brc 1,0b \n" /* handle partial completion */ + " ahi %0,%h6\n" + "2: ahi %0,%h7\n" + "3:\n" + EX_TABLE(0b,3b) EX_TABLE(1b,2b) + : "=d" (ret), "+a" (__src), "+d" (__src_len) + : "d" (__func), "a" (__param), "0" (-EFAULT), + "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); + if (ret < 0) + return ret; + return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; } /* @@ -294,22 +226,19 @@ crypt_s390_klmd(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - ret = 0; - __asm__ __volatile__ ( - "0: .insn rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */ - "1: brc 1,0b \n" /* handle partical completion */ - __crypt_s390_set_result - "6: \n" - __crypt_s390_fixup - : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) - : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), - "a" (__param) - : "cc", "memory" - ); - if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ - ret = src_len - ret; - } - return ret; + asm volatile( + "0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */ + "1: brc 1,0b \n" /* handle partial completion */ + " ahi %0,%h6\n" + "2: ahi %0,%h7\n" + "3:\n" + EX_TABLE(0b,3b) EX_TABLE(1b,2b) + : "=d" (ret), "+a" (__src), "+d" (__src_len) + : "d" (__func), "a" (__param), "0" (-EFAULT), + "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); + if (ret < 0) + return ret; + return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; } /* @@ -331,22 +260,19 @@ crypt_s390_kmac(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - ret = 0; - __asm__ __volatile__ ( - "0: .insn rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */ - "1: brc 1,0b \n" /* handle partical completion */ - __crypt_s390_set_result - "6: \n" - __crypt_s390_fixup - : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) - : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), - "a" (__param) - : "cc", "memory" - ); - if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ - ret = src_len - ret; - } - return ret; + asm volatile( + "0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */ + "1: brc 1,0b \n" /* handle partial completion */ + " ahi %0,%h6\n" + "2: ahi %0,%h7\n" + "3:\n" + EX_TABLE(0b,3b) EX_TABLE(1b,2b) + : "=d" (ret), "+a" (__src), "+d" (__src_len) + : "d" (__func), "a" (__param), "0" (-EFAULT), + "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); + if (ret < 0) + return ret; + return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; } /** diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 75144efbb92..443fa377d9f 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -333,22 +333,14 @@ static int diag204(unsigned long subcode, unsigned long size, void *addr) register unsigned long _subcode asm("0") = subcode; register unsigned long _size asm("1") = size; - asm volatile (" diag %2,%0,0x204\n" - "0: \n" ".section __ex_table,\"a\"\n" -#ifndef __s390x__ - " .align 4\n" - " .long 0b,0b\n" -#else - " .align 8\n" - " .quad 0b,0b\n" -#endif - ".previous":"+d" (_subcode), "+d"(_size) - :"d"(addr) - :"memory"); + asm volatile( + " diag %2,%0,0x204\n" + "0:\n" + EX_TABLE(0b,0b) + : "+d" (_subcode), "+d" (_size) : "d" (addr) : "memory"); if (_subcode) return -1; - else - return _size; + return _size; } /* @@ -403,7 +395,8 @@ static void *diag204_get_buffer(enum diag204_format fmt, int *pages) *pages = 1; return diag204_alloc_rbuf(); } else {/* INFO_EXT */ - *pages = diag204(SUBC_RSI | INFO_EXT, 0, NULL); + *pages = diag204((unsigned long)SUBC_RSI | + (unsigned long)INFO_EXT, 0, NULL); if (*pages <= 0) return ERR_PTR(-ENOSYS); else @@ -490,8 +483,7 @@ out: static void diag224(void *ptr) { - asm volatile(" diag %0,%1,0x224\n" - : :"d" (0), "d"(ptr) : "memory"); + asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory"); } static int diag224_get_name_table(void) diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 91b2884fa5c..c46e3d48e41 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -544,10 +544,7 @@ sys32_execve(struct pt_regs regs) current->ptrace &= ~PT_DTRACE; task_unlock(current); current->thread.fp_regs.fpc=0; - __asm__ __volatile__ - ("sr 0,0\n\t" - "sfpc 0,0\n\t" - : : :"0"); + asm volatile("sfpc %0,0" : : "d" (0)); } putname(filename); out: diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 4d53b273935..4aabeeaa7cf 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -4,97 +4,97 @@ * * Copyright (C) IBM Corp. 2000,2006 * Author(s): Gerhard Tonn (ton@de.ibm.com), -* Thomas Spatzier (tspat@de.ibm.com) -*/ +* Thomas Spatzier (tspat@de.ibm.com) +*/ - .globl sys32_exit_wrapper + .globl sys32_exit_wrapper sys32_exit_wrapper: lgfr %r2,%r2 # int jg sys_exit # branch to sys_exit - - .globl sys32_read_wrapper + + .globl sys32_read_wrapper sys32_read_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # char * llgfr %r4,%r4 # size_t jg sys32_read # branch to sys_read - .globl sys32_write_wrapper + .globl sys32_write_wrapper sys32_write_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # const char * llgfr %r4,%r4 # size_t jg sys32_write # branch to system call - .globl sys32_open_wrapper + .globl sys32_open_wrapper sys32_open_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int lgfr %r4,%r4 # int jg sys_open # branch to system call - .globl sys32_close_wrapper + .globl sys32_close_wrapper sys32_close_wrapper: llgfr %r2,%r2 # unsigned int jg sys_close # branch to system call - .globl sys32_creat_wrapper + .globl sys32_creat_wrapper sys32_creat_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int jg sys_creat # branch to system call - .globl sys32_link_wrapper + .globl sys32_link_wrapper sys32_link_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * jg sys_link # branch to system call - .globl sys32_unlink_wrapper + .globl sys32_unlink_wrapper sys32_unlink_wrapper: llgtr %r2,%r2 # const char * jg sys_unlink # branch to system call - .globl sys32_chdir_wrapper + .globl sys32_chdir_wrapper sys32_chdir_wrapper: llgtr %r2,%r2 # const char * jg sys_chdir # branch to system call - .globl sys32_time_wrapper + .globl sys32_time_wrapper sys32_time_wrapper: llgtr %r2,%r2 # int * jg compat_sys_time # branch to system call - .globl sys32_mknod_wrapper + .globl sys32_mknod_wrapper sys32_mknod_wrapper: llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int + lgfr %r3,%r3 # int llgfr %r4,%r4 # dev jg sys_mknod # branch to system call - .globl sys32_chmod_wrapper + .globl sys32_chmod_wrapper sys32_chmod_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # mode_t jg sys_chmod # branch to system call - .globl sys32_lchown16_wrapper + .globl sys32_lchown16_wrapper sys32_lchown16_wrapper: llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_uid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_uid_emu31_t jg sys32_lchown16 # branch to system call - .globl sys32_lseek_wrapper + .globl sys32_lseek_wrapper sys32_lseek_wrapper: llgfr %r2,%r2 # unsigned int lgfr %r3,%r3 # off_t llgfr %r4,%r4 # unsigned int jg sys_lseek # branch to system call -#sys32_getpid_wrapper # void +#sys32_getpid_wrapper # void - .globl sys32_mount_wrapper + .globl sys32_mount_wrapper sys32_mount_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # char * @@ -103,19 +103,19 @@ sys32_mount_wrapper: llgtr %r6,%r6 # void * jg compat_sys_mount # branch to system call - .globl sys32_oldumount_wrapper + .globl sys32_oldumount_wrapper sys32_oldumount_wrapper: llgtr %r2,%r2 # char * jg sys_oldumount # branch to system call - .globl sys32_setuid16_wrapper + .globl sys32_setuid16_wrapper sys32_setuid16_wrapper: - llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r2,%r2 # __kernel_old_uid_emu31_t jg sys32_setuid16 # branch to system call -#sys32_getuid16_wrapper # void +#sys32_getuid16_wrapper # void - .globl sys32_ptrace_wrapper + .globl sys32_ptrace_wrapper sys32_ptrace_wrapper: lgfr %r2,%r2 # long lgfr %r3,%r3 # long @@ -123,168 +123,168 @@ sys32_ptrace_wrapper: llgfr %r5,%r5 # long jg sys_ptrace # branch to system call - .globl sys32_alarm_wrapper + .globl sys32_alarm_wrapper sys32_alarm_wrapper: llgfr %r2,%r2 # unsigned int jg sys_alarm # branch to system call -#sys32_pause_wrapper # void +#sys32_pause_wrapper # void - .globl compat_sys_utime_wrapper + .globl compat_sys_utime_wrapper compat_sys_utime_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct compat_utimbuf * jg compat_sys_utime # branch to system call - .globl sys32_access_wrapper + .globl sys32_access_wrapper sys32_access_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int jg sys_access # branch to system call - .globl sys32_nice_wrapper + .globl sys32_nice_wrapper sys32_nice_wrapper: lgfr %r2,%r2 # int jg sys_nice # branch to system call -#sys32_sync_wrapper # void +#sys32_sync_wrapper # void - .globl sys32_kill_wrapper + .globl sys32_kill_wrapper sys32_kill_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int jg sys_kill # branch to system call - .globl sys32_rename_wrapper + .globl sys32_rename_wrapper sys32_rename_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * jg sys_rename # branch to system call - .globl sys32_mkdir_wrapper + .globl sys32_mkdir_wrapper sys32_mkdir_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int jg sys_mkdir # branch to system call - .globl sys32_rmdir_wrapper + .globl sys32_rmdir_wrapper sys32_rmdir_wrapper: llgtr %r2,%r2 # const char * jg sys_rmdir # branch to system call - .globl sys32_dup_wrapper + .globl sys32_dup_wrapper sys32_dup_wrapper: llgfr %r2,%r2 # unsigned int jg sys_dup # branch to system call - .globl sys32_pipe_wrapper + .globl sys32_pipe_wrapper sys32_pipe_wrapper: llgtr %r2,%r2 # u32 * jg sys_pipe # branch to system call - .globl compat_sys_times_wrapper + .globl compat_sys_times_wrapper compat_sys_times_wrapper: llgtr %r2,%r2 # struct compat_tms * jg compat_sys_times # branch to system call - .globl sys32_brk_wrapper + .globl sys32_brk_wrapper sys32_brk_wrapper: llgtr %r2,%r2 # unsigned long jg sys_brk # branch to system call - .globl sys32_setgid16_wrapper + .globl sys32_setgid16_wrapper sys32_setgid16_wrapper: - llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r2,%r2 # __kernel_old_gid_emu31_t jg sys32_setgid16 # branch to system call -#sys32_getgid16_wrapper # void +#sys32_getgid16_wrapper # void .globl sys32_signal_wrapper sys32_signal_wrapper: - lgfr %r2,%r2 # int + lgfr %r2,%r2 # int llgtr %r3,%r3 # __sighandler_t jg sys_signal -#sys32_geteuid16_wrapper # void +#sys32_geteuid16_wrapper # void -#sys32_getegid16_wrapper # void +#sys32_getegid16_wrapper # void - .globl sys32_acct_wrapper + .globl sys32_acct_wrapper sys32_acct_wrapper: llgtr %r2,%r2 # char * jg sys_acct # branch to system call - .globl sys32_umount_wrapper + .globl sys32_umount_wrapper sys32_umount_wrapper: llgtr %r2,%r2 # char * lgfr %r3,%r3 # int jg sys_umount # branch to system call - .globl compat_sys_ioctl_wrapper + .globl compat_sys_ioctl_wrapper compat_sys_ioctl_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned int llgfr %r4,%r4 # unsigned int jg compat_sys_ioctl # branch to system call - .globl compat_sys_fcntl_wrapper + .globl compat_sys_fcntl_wrapper compat_sys_fcntl_wrapper: llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int + llgfr %r3,%r3 # unsigned int llgfr %r4,%r4 # unsigned long jg compat_sys_fcntl # branch to system call - .globl sys32_setpgid_wrapper + .globl sys32_setpgid_wrapper sys32_setpgid_wrapper: lgfr %r2,%r2 # pid_t lgfr %r3,%r3 # pid_t jg sys_setpgid # branch to system call - .globl sys32_umask_wrapper + .globl sys32_umask_wrapper sys32_umask_wrapper: lgfr %r2,%r2 # int jg sys_umask # branch to system call - .globl sys32_chroot_wrapper + .globl sys32_chroot_wrapper sys32_chroot_wrapper: llgtr %r2,%r2 # char * jg sys_chroot # branch to system call .globl sys32_ustat_wrapper sys32_ustat_wrapper: - llgfr %r2,%r2 # dev_t + llgfr %r2,%r2 # dev_t llgtr %r3,%r3 # struct ustat * jg sys_ustat - .globl sys32_dup2_wrapper + .globl sys32_dup2_wrapper sys32_dup2_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned int jg sys_dup2 # branch to system call -#sys32_getppid_wrapper # void +#sys32_getppid_wrapper # void -#sys32_getpgrp_wrapper # void +#sys32_getpgrp_wrapper # void -#sys32_setsid_wrapper # void +#sys32_setsid_wrapper # void - .globl sys32_sigaction_wrapper + .globl sys32_sigaction_wrapper sys32_sigaction_wrapper: - lgfr %r2,%r2 # int + lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct old_sigaction * llgtr %r4,%r4 # struct old_sigaction32 * jg sys32_sigaction # branch to system call - .globl sys32_setreuid16_wrapper + .globl sys32_setreuid16_wrapper sys32_setreuid16_wrapper: - llgfr %r2,%r2 # __kernel_old_uid_emu31_t - llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t jg sys32_setreuid16 # branch to system call - .globl sys32_setregid16_wrapper + .globl sys32_setregid16_wrapper sys32_setregid16_wrapper: - llgfr %r2,%r2 # __kernel_old_gid_emu31_t - llgfr %r3,%r3 # __kernel_old_gid_emu31_t + llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r3,%r3 # __kernel_old_gid_emu31_t jg sys32_setregid16 # branch to system call .globl sys_sigsuspend_wrapper @@ -294,95 +294,95 @@ sys_sigsuspend_wrapper: llgfr %r4,%r4 # old_sigset_t jg sys_sigsuspend - .globl compat_sys_sigpending_wrapper + .globl compat_sys_sigpending_wrapper compat_sys_sigpending_wrapper: llgtr %r2,%r2 # compat_old_sigset_t * jg compat_sys_sigpending # branch to system call - .globl sys32_sethostname_wrapper + .globl sys32_sethostname_wrapper sys32_sethostname_wrapper: llgtr %r2,%r2 # char * lgfr %r3,%r3 # int jg sys_sethostname # branch to system call - .globl compat_sys_setrlimit_wrapper + .globl compat_sys_setrlimit_wrapper compat_sys_setrlimit_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct rlimit_emu31 * jg compat_sys_setrlimit # branch to system call - .globl compat_sys_old_getrlimit_wrapper + .globl compat_sys_old_getrlimit_wrapper compat_sys_old_getrlimit_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct rlimit_emu31 * jg compat_sys_old_getrlimit # branch to system call - .globl compat_sys_getrlimit_wrapper + .globl compat_sys_getrlimit_wrapper compat_sys_getrlimit_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct rlimit_emu31 * jg compat_sys_getrlimit # branch to system call - .globl sys32_mmap2_wrapper + .globl sys32_mmap2_wrapper sys32_mmap2_wrapper: llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * jg sys32_mmap2 # branch to system call - .globl compat_sys_getrusage_wrapper + .globl compat_sys_getrusage_wrapper compat_sys_getrusage_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # struct rusage_emu31 * jg compat_sys_getrusage # branch to system call - .globl sys32_gettimeofday_wrapper + .globl sys32_gettimeofday_wrapper sys32_gettimeofday_wrapper: llgtr %r2,%r2 # struct timeval_emu31 * llgtr %r3,%r3 # struct timezone * jg sys32_gettimeofday # branch to system call - .globl sys32_settimeofday_wrapper + .globl sys32_settimeofday_wrapper sys32_settimeofday_wrapper: llgtr %r2,%r2 # struct timeval_emu31 * llgtr %r3,%r3 # struct timezone * jg sys32_settimeofday # branch to system call - .globl sys32_getgroups16_wrapper + .globl sys32_getgroups16_wrapper sys32_getgroups16_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # __kernel_old_gid_emu31_t * jg sys32_getgroups16 # branch to system call - .globl sys32_setgroups16_wrapper + .globl sys32_setgroups16_wrapper sys32_setgroups16_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # __kernel_old_gid_emu31_t * jg sys32_setgroups16 # branch to system call - .globl sys32_symlink_wrapper + .globl sys32_symlink_wrapper sys32_symlink_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * jg sys_symlink # branch to system call - .globl sys32_readlink_wrapper + .globl sys32_readlink_wrapper sys32_readlink_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # char * lgfr %r4,%r4 # int jg sys_readlink # branch to system call - .globl sys32_uselib_wrapper + .globl sys32_uselib_wrapper sys32_uselib_wrapper: llgtr %r2,%r2 # const char * jg sys_uselib # branch to system call - .globl sys32_swapon_wrapper + .globl sys32_swapon_wrapper sys32_swapon_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int jg sys_swapon # branch to system call - .globl sys32_reboot_wrapper + .globl sys32_reboot_wrapper sys32_reboot_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -390,121 +390,121 @@ sys32_reboot_wrapper: llgtr %r5,%r5 # void * jg sys_reboot # branch to system call - .globl old32_readdir_wrapper + .globl old32_readdir_wrapper old32_readdir_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * llgfr %r4,%r4 # unsigned int jg compat_sys_old_readdir # branch to system call - .globl old32_mmap_wrapper + .globl old32_mmap_wrapper old32_mmap_wrapper: llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * jg old32_mmap # branch to system call - .globl sys32_munmap_wrapper + .globl sys32_munmap_wrapper sys32_munmap_wrapper: llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # size_t + llgfr %r3,%r3 # size_t jg sys_munmap # branch to system call - .globl sys32_truncate_wrapper + .globl sys32_truncate_wrapper sys32_truncate_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # unsigned long jg sys_truncate # branch to system call - .globl sys32_ftruncate_wrapper + .globl sys32_ftruncate_wrapper sys32_ftruncate_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned long jg sys_ftruncate # branch to system call - .globl sys32_fchmod_wrapper + .globl sys32_fchmod_wrapper sys32_fchmod_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # mode_t jg sys_fchmod # branch to system call - .globl sys32_fchown16_wrapper + .globl sys32_fchown16_wrapper sys32_fchown16_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # compat_uid_t llgfr %r4,%r4 # compat_uid_t jg sys32_fchown16 # branch to system call - .globl sys32_getpriority_wrapper + .globl sys32_getpriority_wrapper sys32_getpriority_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int jg sys_getpriority # branch to system call - .globl sys32_setpriority_wrapper + .globl sys32_setpriority_wrapper sys32_setpriority_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int lgfr %r4,%r4 # int jg sys_setpriority # branch to system call - .globl compat_sys_statfs_wrapper + .globl compat_sys_statfs_wrapper compat_sys_statfs_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct compat_statfs * jg compat_sys_statfs # branch to system call - .globl compat_sys_fstatfs_wrapper + .globl compat_sys_fstatfs_wrapper compat_sys_fstatfs_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct compat_statfs * jg compat_sys_fstatfs # branch to system call - .globl compat_sys_socketcall_wrapper + .globl compat_sys_socketcall_wrapper compat_sys_socketcall_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # u32 * jg compat_sys_socketcall # branch to system call - .globl sys32_syslog_wrapper + .globl sys32_syslog_wrapper sys32_syslog_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # char * lgfr %r4,%r4 # int jg sys_syslog # branch to system call - .globl compat_sys_setitimer_wrapper + .globl compat_sys_setitimer_wrapper compat_sys_setitimer_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # struct itimerval_emu31 * llgtr %r4,%r4 # struct itimerval_emu31 * jg compat_sys_setitimer # branch to system call - .globl compat_sys_getitimer_wrapper + .globl compat_sys_getitimer_wrapper compat_sys_getitimer_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # struct itimerval_emu31 * jg compat_sys_getitimer # branch to system call - .globl compat_sys_newstat_wrapper + .globl compat_sys_newstat_wrapper compat_sys_newstat_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct stat_emu31 * jg compat_sys_newstat # branch to system call - .globl compat_sys_newlstat_wrapper + .globl compat_sys_newlstat_wrapper compat_sys_newlstat_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct stat_emu31 * jg compat_sys_newlstat # branch to system call - .globl compat_sys_newfstat_wrapper + .globl compat_sys_newfstat_wrapper compat_sys_newfstat_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct stat_emu31 * jg compat_sys_newfstat # branch to system call -#sys32_vhangup_wrapper # void +#sys32_vhangup_wrapper # void - .globl compat_sys_wait4_wrapper + .globl compat_sys_wait4_wrapper compat_sys_wait4_wrapper: lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # unsigned int * @@ -512,17 +512,17 @@ compat_sys_wait4_wrapper: llgtr %r5,%r5 # struct rusage * jg compat_sys_wait4 # branch to system call - .globl sys32_swapoff_wrapper + .globl sys32_swapoff_wrapper sys32_swapoff_wrapper: llgtr %r2,%r2 # const char * jg sys_swapoff # branch to system call - .globl sys32_sysinfo_wrapper + .globl sys32_sysinfo_wrapper sys32_sysinfo_wrapper: llgtr %r2,%r2 # struct sysinfo_emu31 * jg sys32_sysinfo # branch to system call - .globl sys32_ipc_wrapper + .globl sys32_ipc_wrapper sys32_ipc_wrapper: llgfr %r2,%r2 # uint lgfr %r3,%r3 # int @@ -531,59 +531,59 @@ sys32_ipc_wrapper: llgfr %r6,%r6 # u32 jg sys32_ipc # branch to system call - .globl sys32_fsync_wrapper + .globl sys32_fsync_wrapper sys32_fsync_wrapper: llgfr %r2,%r2 # unsigned int jg sys_fsync # branch to system call -#sys32_sigreturn_wrapper # done in sigreturn_glue +#sys32_sigreturn_wrapper # done in sigreturn_glue -#sys32_clone_wrapper # done in clone_glue +#sys32_clone_wrapper # done in clone_glue - .globl sys32_setdomainname_wrapper + .globl sys32_setdomainname_wrapper sys32_setdomainname_wrapper: llgtr %r2,%r2 # char * lgfr %r3,%r3 # int jg sys_setdomainname # branch to system call - .globl sys32_newuname_wrapper + .globl sys32_newuname_wrapper sys32_newuname_wrapper: llgtr %r2,%r2 # struct new_utsname * jg s390x_newuname # branch to system call - .globl compat_sys_adjtimex_wrapper + .globl compat_sys_adjtimex_wrapper compat_sys_adjtimex_wrapper: llgtr %r2,%r2 # struct compat_timex * jg compat_sys_adjtimex # branch to system call - .globl sys32_mprotect_wrapper + .globl sys32_mprotect_wrapper sys32_mprotect_wrapper: llgtr %r2,%r2 # unsigned long (actually pointer llgfr %r3,%r3 # size_t llgfr %r4,%r4 # unsigned long jg sys_mprotect # branch to system call - .globl compat_sys_sigprocmask_wrapper + .globl compat_sys_sigprocmask_wrapper compat_sys_sigprocmask_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # compat_old_sigset_t * llgtr %r4,%r4 # compat_old_sigset_t * jg compat_sys_sigprocmask # branch to system call - .globl sys32_init_module_wrapper + .globl sys32_init_module_wrapper sys32_init_module_wrapper: llgtr %r2,%r2 # void * llgfr %r3,%r3 # unsigned long llgtr %r4,%r4 # char * jg sys32_init_module # branch to system call - .globl sys32_delete_module_wrapper + .globl sys32_delete_module_wrapper sys32_delete_module_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # unsigned int jg sys32_delete_module # branch to system call - .globl sys32_quotactl_wrapper + .globl sys32_quotactl_wrapper sys32_quotactl_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # const char * @@ -591,45 +591,45 @@ sys32_quotactl_wrapper: llgtr %r5,%r5 # caddr_t jg sys_quotactl # branch to system call - .globl sys32_getpgid_wrapper + .globl sys32_getpgid_wrapper sys32_getpgid_wrapper: lgfr %r2,%r2 # pid_t jg sys_getpgid # branch to system call - .globl sys32_fchdir_wrapper + .globl sys32_fchdir_wrapper sys32_fchdir_wrapper: llgfr %r2,%r2 # unsigned int jg sys_fchdir # branch to system call - .globl sys32_bdflush_wrapper + .globl sys32_bdflush_wrapper sys32_bdflush_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # long jg sys_bdflush # branch to system call - .globl sys32_sysfs_wrapper + .globl sys32_sysfs_wrapper sys32_sysfs_wrapper: lgfr %r2,%r2 # int llgfr %r3,%r3 # unsigned long llgfr %r4,%r4 # unsigned long jg sys_sysfs # branch to system call - .globl sys32_personality_wrapper + .globl sys32_personality_wrapper sys32_personality_wrapper: llgfr %r2,%r2 # unsigned long jg s390x_personality # branch to system call - .globl sys32_setfsuid16_wrapper + .globl sys32_setfsuid16_wrapper sys32_setfsuid16_wrapper: - llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r2,%r2 # __kernel_old_uid_emu31_t jg sys32_setfsuid16 # branch to system call - .globl sys32_setfsgid16_wrapper + .globl sys32_setfsgid16_wrapper sys32_setfsgid16_wrapper: - llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r2,%r2 # __kernel_old_gid_emu31_t jg sys32_setfsgid16 # branch to system call - .globl sys32_llseek_wrapper + .globl sys32_llseek_wrapper sys32_llseek_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned long @@ -638,14 +638,14 @@ sys32_llseek_wrapper: llgfr %r6,%r6 # unsigned int jg sys_llseek # branch to system call - .globl sys32_getdents_wrapper + .globl sys32_getdents_wrapper sys32_getdents_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * llgfr %r4,%r4 # unsigned int jg compat_sys_getdents # branch to system call - .globl compat_sys_select_wrapper + .globl compat_sys_select_wrapper compat_sys_select_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # compat_fd_set * @@ -654,113 +654,113 @@ compat_sys_select_wrapper: llgtr %r6,%r6 # struct compat_timeval * jg compat_sys_select # branch to system call - .globl sys32_flock_wrapper + .globl sys32_flock_wrapper sys32_flock_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned int jg sys_flock # branch to system call - .globl sys32_msync_wrapper + .globl sys32_msync_wrapper sys32_msync_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t lgfr %r4,%r4 # int jg sys_msync # branch to system call - .globl compat_sys_readv_wrapper + .globl compat_sys_readv_wrapper compat_sys_readv_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct compat_iovec * llgfr %r4,%r4 # unsigned long jg compat_sys_readv # branch to system call - .globl compat_sys_writev_wrapper + .globl compat_sys_writev_wrapper compat_sys_writev_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct compat_iovec * llgfr %r4,%r4 # unsigned long jg compat_sys_writev # branch to system call - .globl sys32_getsid_wrapper + .globl sys32_getsid_wrapper sys32_getsid_wrapper: lgfr %r2,%r2 # pid_t jg sys_getsid # branch to system call - .globl sys32_fdatasync_wrapper + .globl sys32_fdatasync_wrapper sys32_fdatasync_wrapper: llgfr %r2,%r2 # unsigned int jg sys_fdatasync # branch to system call -#sys32_sysctl_wrapper # tbd +#sys32_sysctl_wrapper # tbd - .globl sys32_mlock_wrapper + .globl sys32_mlock_wrapper sys32_mlock_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t jg sys_mlock # branch to system call - .globl sys32_munlock_wrapper + .globl sys32_munlock_wrapper sys32_munlock_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t jg sys_munlock # branch to system call - .globl sys32_mlockall_wrapper + .globl sys32_mlockall_wrapper sys32_mlockall_wrapper: lgfr %r2,%r2 # int jg sys_mlockall # branch to system call -#sys32_munlockall_wrapper # void +#sys32_munlockall_wrapper # void - .globl sys32_sched_setparam_wrapper + .globl sys32_sched_setparam_wrapper sys32_sched_setparam_wrapper: lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # struct sched_param * jg sys_sched_setparam # branch to system call - .globl sys32_sched_getparam_wrapper + .globl sys32_sched_getparam_wrapper sys32_sched_getparam_wrapper: lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # struct sched_param * jg sys_sched_getparam # branch to system call - .globl sys32_sched_setscheduler_wrapper + .globl sys32_sched_setscheduler_wrapper sys32_sched_setscheduler_wrapper: lgfr %r2,%r2 # pid_t lgfr %r3,%r3 # int llgtr %r4,%r4 # struct sched_param * jg sys_sched_setscheduler # branch to system call - .globl sys32_sched_getscheduler_wrapper + .globl sys32_sched_getscheduler_wrapper sys32_sched_getscheduler_wrapper: lgfr %r2,%r2 # pid_t jg sys_sched_getscheduler # branch to system call -#sys32_sched_yield_wrapper # void +#sys32_sched_yield_wrapper # void - .globl sys32_sched_get_priority_max_wrapper + .globl sys32_sched_get_priority_max_wrapper sys32_sched_get_priority_max_wrapper: lgfr %r2,%r2 # int jg sys_sched_get_priority_max # branch to system call - .globl sys32_sched_get_priority_min_wrapper + .globl sys32_sched_get_priority_min_wrapper sys32_sched_get_priority_min_wrapper: lgfr %r2,%r2 # int jg sys_sched_get_priority_min # branch to system call - .globl sys32_sched_rr_get_interval_wrapper + .globl sys32_sched_rr_get_interval_wrapper sys32_sched_rr_get_interval_wrapper: lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # struct compat_timespec * jg sys32_sched_rr_get_interval # branch to system call - .globl compat_sys_nanosleep_wrapper + .globl compat_sys_nanosleep_wrapper compat_sys_nanosleep_wrapper: llgtr %r2,%r2 # struct compat_timespec * llgtr %r3,%r3 # struct compat_timespec * jg compat_sys_nanosleep # branch to system call - .globl sys32_mremap_wrapper + .globl sys32_mremap_wrapper sys32_mremap_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # unsigned long @@ -769,49 +769,49 @@ sys32_mremap_wrapper: llgfr %r6,%r6 # unsigned long jg sys_mremap # branch to system call - .globl sys32_setresuid16_wrapper + .globl sys32_setresuid16_wrapper sys32_setresuid16_wrapper: - llgfr %r2,%r2 # __kernel_old_uid_emu31_t - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_uid_emu31_t + llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_uid_emu31_t jg sys32_setresuid16 # branch to system call - .globl sys32_getresuid16_wrapper + .globl sys32_getresuid16_wrapper sys32_getresuid16_wrapper: llgtr %r2,%r2 # __kernel_old_uid_emu31_t * llgtr %r3,%r3 # __kernel_old_uid_emu31_t * llgtr %r4,%r4 # __kernel_old_uid_emu31_t * jg sys32_getresuid16 # branch to system call - .globl sys32_poll_wrapper + .globl sys32_poll_wrapper sys32_poll_wrapper: - llgtr %r2,%r2 # struct pollfd * - llgfr %r3,%r3 # unsigned int - lgfr %r4,%r4 # long + llgtr %r2,%r2 # struct pollfd * + llgfr %r3,%r3 # unsigned int + lgfr %r4,%r4 # long jg sys_poll # branch to system call - .globl compat_sys_nfsservctl_wrapper + .globl compat_sys_nfsservctl_wrapper compat_sys_nfsservctl_wrapper: - lgfr %r2,%r2 # int + lgfr %r2,%r2 # int llgtr %r3,%r3 # struct compat_nfsctl_arg* llgtr %r4,%r4 # union compat_nfsctl_res* jg compat_sys_nfsservctl # branch to system call - .globl sys32_setresgid16_wrapper + .globl sys32_setresgid16_wrapper sys32_setresgid16_wrapper: - llgfr %r2,%r2 # __kernel_old_gid_emu31_t - llgfr %r3,%r3 # __kernel_old_gid_emu31_t - llgfr %r4,%r4 # __kernel_old_gid_emu31_t + llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r3,%r3 # __kernel_old_gid_emu31_t + llgfr %r4,%r4 # __kernel_old_gid_emu31_t jg sys32_setresgid16 # branch to system call - .globl sys32_getresgid16_wrapper + .globl sys32_getresgid16_wrapper sys32_getresgid16_wrapper: llgtr %r2,%r2 # __kernel_old_gid_emu31_t * llgtr %r3,%r3 # __kernel_old_gid_emu31_t * llgtr %r4,%r4 # __kernel_old_gid_emu31_t * jg sys32_getresgid16 # branch to system call - .globl sys32_prctl_wrapper + .globl sys32_prctl_wrapper sys32_prctl_wrapper: lgfr %r2,%r2 # int llgfr %r3,%r3 # unsigned long @@ -820,9 +820,9 @@ sys32_prctl_wrapper: llgfr %r6,%r6 # unsigned long jg sys_prctl # branch to system call -#sys32_rt_sigreturn_wrapper # done in rt_sigreturn_glue +#sys32_rt_sigreturn_wrapper # done in rt_sigreturn_glue - .globl sys32_rt_sigaction_wrapper + .globl sys32_rt_sigaction_wrapper sys32_rt_sigaction_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct sigaction_emu31 * @@ -830,7 +830,7 @@ sys32_rt_sigaction_wrapper: llgfr %r5,%r5 # size_t jg sys32_rt_sigaction # branch to system call - .globl sys32_rt_sigprocmask_wrapper + .globl sys32_rt_sigprocmask_wrapper sys32_rt_sigprocmask_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # old_sigset_emu31 * @@ -838,13 +838,13 @@ sys32_rt_sigprocmask_wrapper: llgfr %r5,%r5 # size_t jg sys32_rt_sigprocmask # branch to system call - .globl sys32_rt_sigpending_wrapper + .globl sys32_rt_sigpending_wrapper sys32_rt_sigpending_wrapper: llgtr %r2,%r2 # sigset_emu31 * llgfr %r3,%r3 # size_t jg sys32_rt_sigpending # branch to system call - .globl compat_sys_rt_sigtimedwait_wrapper + .globl compat_sys_rt_sigtimedwait_wrapper compat_sys_rt_sigtimedwait_wrapper: llgtr %r2,%r2 # const sigset_emu31_t * llgtr %r3,%r3 # siginfo_emu31_t * @@ -852,7 +852,7 @@ compat_sys_rt_sigtimedwait_wrapper: llgfr %r5,%r5 # size_t jg compat_sys_rt_sigtimedwait # branch to system call - .globl sys32_rt_sigqueueinfo_wrapper + .globl sys32_rt_sigqueueinfo_wrapper sys32_rt_sigqueueinfo_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -865,7 +865,7 @@ compat_sys_rt_sigsuspend_wrapper: llgfr %r3,%r3 # compat_size_t jg compat_sys_rt_sigsuspend - .globl sys32_pread64_wrapper + .globl sys32_pread64_wrapper sys32_pread64_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # char * @@ -874,7 +874,7 @@ sys32_pread64_wrapper: llgfr %r6,%r6 # u32 jg sys32_pread64 # branch to system call - .globl sys32_pwrite64_wrapper + .globl sys32_pwrite64_wrapper sys32_pwrite64_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # const char * @@ -883,26 +883,26 @@ sys32_pwrite64_wrapper: llgfr %r6,%r6 # u32 jg sys32_pwrite64 # branch to system call - .globl sys32_chown16_wrapper + .globl sys32_chown16_wrapper sys32_chown16_wrapper: llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_gid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_gid_emu31_t jg sys32_chown16 # branch to system call - .globl sys32_getcwd_wrapper + .globl sys32_getcwd_wrapper sys32_getcwd_wrapper: llgtr %r2,%r2 # char * llgfr %r3,%r3 # unsigned long jg sys_getcwd # branch to system call - .globl sys32_capget_wrapper + .globl sys32_capget_wrapper sys32_capget_wrapper: llgtr %r2,%r2 # cap_user_header_t llgtr %r3,%r3 # cap_user_data_t jg sys_capget # branch to system call - .globl sys32_capset_wrapper + .globl sys32_capset_wrapper sys32_capset_wrapper: llgtr %r2,%r2 # cap_user_header_t llgtr %r3,%r3 # const cap_user_data_t @@ -910,11 +910,11 @@ sys32_capset_wrapper: .globl sys32_sigaltstack_wrapper sys32_sigaltstack_wrapper: - llgtr %r2,%r2 # const stack_emu31_t * - llgtr %r3,%r3 # stack_emu31_t * + llgtr %r2,%r2 # const stack_emu31_t * + llgtr %r3,%r3 # stack_emu31_t * jg sys32_sigaltstack - .globl sys32_sendfile_wrapper + .globl sys32_sendfile_wrapper sys32_sendfile_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -922,33 +922,33 @@ sys32_sendfile_wrapper: llgfr %r5,%r5 # size_t jg sys32_sendfile # branch to system call -#sys32_vfork_wrapper # done in vfork_glue +#sys32_vfork_wrapper # done in vfork_glue - .globl sys32_truncate64_wrapper + .globl sys32_truncate64_wrapper sys32_truncate64_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # unsigned long llgfr %r4,%r4 # unsigned long jg sys32_truncate64 # branch to system call - .globl sys32_ftruncate64_wrapper + .globl sys32_ftruncate64_wrapper sys32_ftruncate64_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned long llgfr %r4,%r4 # unsigned long jg sys32_ftruncate64 # branch to system call - .globl sys32_lchown_wrapper + .globl sys32_lchown_wrapper sys32_lchown_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # uid_t llgfr %r4,%r4 # gid_t jg sys_lchown # branch to system call -#sys32_getuid_wrapper # void -#sys32_getgid_wrapper # void -#sys32_geteuid_wrapper # void -#sys32_getegid_wrapper # void +#sys32_getuid_wrapper # void +#sys32_getgid_wrapper # void +#sys32_geteuid_wrapper # void +#sys32_getegid_wrapper # void .globl sys32_setreuid_wrapper sys32_setreuid_wrapper: @@ -962,111 +962,111 @@ sys32_setregid_wrapper: llgfr %r3,%r3 # gid_t jg sys_setregid # branch to system call - .globl sys32_getgroups_wrapper + .globl sys32_getgroups_wrapper sys32_getgroups_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # gid_t * jg sys_getgroups # branch to system call - .globl sys32_setgroups_wrapper + .globl sys32_setgroups_wrapper sys32_setgroups_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # gid_t * jg sys_setgroups # branch to system call - .globl sys32_fchown_wrapper + .globl sys32_fchown_wrapper sys32_fchown_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # uid_t llgfr %r4,%r4 # gid_t jg sys_fchown # branch to system call - .globl sys32_setresuid_wrapper + .globl sys32_setresuid_wrapper sys32_setresuid_wrapper: llgfr %r2,%r2 # uid_t llgfr %r3,%r3 # uid_t llgfr %r4,%r4 # uid_t jg sys_setresuid # branch to system call - .globl sys32_getresuid_wrapper + .globl sys32_getresuid_wrapper sys32_getresuid_wrapper: llgtr %r2,%r2 # uid_t * llgtr %r3,%r3 # uid_t * llgtr %r4,%r4 # uid_t * jg sys_getresuid # branch to system call - .globl sys32_setresgid_wrapper + .globl sys32_setresgid_wrapper sys32_setresgid_wrapper: llgfr %r2,%r2 # gid_t llgfr %r3,%r3 # gid_t llgfr %r4,%r4 # gid_t jg sys_setresgid # branch to system call - .globl sys32_getresgid_wrapper + .globl sys32_getresgid_wrapper sys32_getresgid_wrapper: llgtr %r2,%r2 # gid_t * llgtr %r3,%r3 # gid_t * llgtr %r4,%r4 # gid_t * jg sys_getresgid # branch to system call - .globl sys32_chown_wrapper + .globl sys32_chown_wrapper sys32_chown_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # uid_t llgfr %r4,%r4 # gid_t jg sys_chown # branch to system call - .globl sys32_setuid_wrapper + .globl sys32_setuid_wrapper sys32_setuid_wrapper: llgfr %r2,%r2 # uid_t jg sys_setuid # branch to system call - .globl sys32_setgid_wrapper + .globl sys32_setgid_wrapper sys32_setgid_wrapper: llgfr %r2,%r2 # gid_t jg sys_setgid # branch to system call - .globl sys32_setfsuid_wrapper + .globl sys32_setfsuid_wrapper sys32_setfsuid_wrapper: llgfr %r2,%r2 # uid_t jg sys_setfsuid # branch to system call - .globl sys32_setfsgid_wrapper + .globl sys32_setfsgid_wrapper sys32_setfsgid_wrapper: llgfr %r2,%r2 # gid_t jg sys_setfsgid # branch to system call - .globl sys32_pivot_root_wrapper + .globl sys32_pivot_root_wrapper sys32_pivot_root_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * jg sys_pivot_root # branch to system call - .globl sys32_mincore_wrapper + .globl sys32_mincore_wrapper sys32_mincore_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t llgtr %r4,%r4 # unsigned char * jg sys_mincore # branch to system call - .globl sys32_madvise_wrapper + .globl sys32_madvise_wrapper sys32_madvise_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t lgfr %r4,%r4 # int jg sys_madvise # branch to system call - .globl sys32_getdents64_wrapper + .globl sys32_getdents64_wrapper sys32_getdents64_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * llgfr %r4,%r4 # unsigned int jg sys_getdents64 # branch to system call - .globl compat_sys_fcntl64_wrapper + .globl compat_sys_fcntl64_wrapper compat_sys_fcntl64_wrapper: llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int + llgfr %r3,%r3 # unsigned int llgfr %r4,%r4 # unsigned long jg compat_sys_fcntl64 # branch to system call @@ -1087,10 +1087,10 @@ sys32_stime_wrapper: llgtr %r2,%r2 # long * jg compat_sys_stime # branch to system call - .globl sys32_sysctl_wrapper + .globl sys32_sysctl_wrapper sys32_sysctl_wrapper: - llgtr %r2,%r2 # struct __sysctl_args32 * - jg sys32_sysctl + llgtr %r2,%r2 # struct __sysctl_args32 * + jg sys32_sysctl .globl sys32_fstat64_wrapper sys32_fstat64_wrapper: @@ -1098,7 +1098,7 @@ sys32_fstat64_wrapper: llgtr %r3,%r3 # struct stat64 * jg sys32_fstat64 # branch to system call - .globl compat_sys_futex_wrapper + .globl compat_sys_futex_wrapper compat_sys_futex_wrapper: llgtr %r2,%r2 # u32 * lgfr %r3,%r3 # int @@ -1213,22 +1213,22 @@ sys32_sched_getaffinity_wrapper: llgtr %r4,%r4 # unsigned long * jg compat_sys_sched_getaffinity - .globl sys32_exit_group_wrapper + .globl sys32_exit_group_wrapper sys32_exit_group_wrapper: lgfr %r2,%r2 # int jg sys_exit_group # branch to system call - .globl sys32_set_tid_address_wrapper + .globl sys32_set_tid_address_wrapper sys32_set_tid_address_wrapper: llgtr %r2,%r2 # int * jg sys_set_tid_address # branch to system call - .globl sys_epoll_create_wrapper + .globl sys_epoll_create_wrapper sys_epoll_create_wrapper: lgfr %r2,%r2 # int jg sys_epoll_create # branch to system call - .globl sys_epoll_ctl_wrapper + .globl sys_epoll_ctl_wrapper sys_epoll_ctl_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -1236,7 +1236,7 @@ sys_epoll_ctl_wrapper: llgtr %r5,%r5 # struct epoll_event * jg sys_epoll_ctl # branch to system call - .globl sys_epoll_wait_wrapper + .globl sys_epoll_wait_wrapper sys_epoll_wait_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # struct epoll_event * diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 4ef44e536b2..1eae74e72f9 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c @@ -25,11 +25,8 @@ static char cpcmd_buf[241]; */ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) { - const int mask = 0x40000000L; - unsigned long flags; - int return_code; - int return_len; - int cmdlen; + unsigned long flags, cmdlen; + int return_code, return_len; spin_lock_irqsave(&cpcmd_lock, flags); cmdlen = strlen(cmd); @@ -38,64 +35,44 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) ASCEBC(cpcmd_buf, cmdlen); if (response != NULL && rlen > 0) { + register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; + register unsigned long reg3 asm ("3") = (addr_t) response; + register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L; + register unsigned long reg5 asm ("5") = rlen; + memset(response, 0, rlen); + asm volatile( #ifndef CONFIG_64BIT - asm volatile ( "lra 2,0(%2)\n" - "lr 4,%3\n" - "o 4,%6\n" - "lra 3,0(%4)\n" - "lr 5,%5\n" - "diag 2,4,0x8\n" - "brc 8, 1f\n" - "ar 5, %5\n" - "1: \n" - "lr %0,4\n" - "lr %1,5\n" - : "=d" (return_code), "=d" (return_len) - : "a" (cpcmd_buf), "d" (cmdlen), - "a" (response), "d" (rlen), "m" (mask) - : "cc", "2", "3", "4", "5" ); + " diag %2,%0,0x8\n" + " brc 8,1f\n" + " ar %1,%4\n" #else /* CONFIG_64BIT */ - asm volatile ( "lrag 2,0(%2)\n" - "lgr 4,%3\n" - "o 4,%6\n" - "lrag 3,0(%4)\n" - "lgr 5,%5\n" - "sam31\n" - "diag 2,4,0x8\n" - "sam64\n" - "brc 8, 1f\n" - "agr 5, %5\n" - "1: \n" - "lgr %0,4\n" - "lgr %1,5\n" - : "=d" (return_code), "=d" (return_len) - : "a" (cpcmd_buf), "d" (cmdlen), - "a" (response), "d" (rlen), "m" (mask) - : "cc", "2", "3", "4", "5" ); + " sam31\n" + " diag %2,%0,0x8\n" + " sam64\n" + " brc 8,1f\n" + " agr %1,%4\n" #endif /* CONFIG_64BIT */ + "1:\n" + : "+d" (reg4), "+d" (reg5) + : "d" (reg2), "d" (reg3), "d" (rlen) : "cc"); + return_code = (int) reg4; + return_len = (int) reg5; EBCASC(response, rlen); } else { + register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; + register unsigned long reg3 asm ("3") = cmdlen; return_len = 0; + asm volatile( #ifndef CONFIG_64BIT - asm volatile ( "lra 2,0(%1)\n" - "lr 3,%2\n" - "diag 2,3,0x8\n" - "lr %0,3\n" - : "=d" (return_code) - : "a" (cpcmd_buf), "d" (cmdlen) - : "2", "3" ); + " diag %1,%0,0x8\n" #else /* CONFIG_64BIT */ - asm volatile ( "lrag 2,0(%1)\n" - "lgr 3,%2\n" - "sam31\n" - "diag 2,3,0x8\n" - "sam64\n" - "lgr %0,3\n" - : "=d" (return_code) - : "a" (cpcmd_buf), "d" (cmdlen) - : "2", "3" ); + " sam31\n" + " diag %1,%0,0x8\n" + " sam64\n" #endif /* CONFIG_64BIT */ + : "+d" (reg3) : "d" (reg2) : "cc"); + return_code = (int) reg3; } spin_unlock_irqrestore(&cpcmd_lock, flags); if (response_code != NULL) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 0c712b78a7e..dddc3de3040 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -4,8 +4,8 @@ * * Copyright (C) IBM Corp. 1999,2006 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - * Hartmut Penner (hp@de.ibm.com), - * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), + * Hartmut Penner (hp@de.ibm.com), + * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * Heiko Carstens <heiko.carstens@de.ibm.com> */ @@ -24,29 +24,29 @@ * Stack layout for the system_call stack entry. * The first few entries are identical to the user_regs_struct. */ -SP_PTREGS = STACK_FRAME_OVERHEAD -SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS -SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW -SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS -SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 -SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 -SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 -SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 -SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 -SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 -SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 -SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 -SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36 -SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 -SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44 -SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 -SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52 -SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 -SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 -SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 -SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC -SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP -SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS +SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW +SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS +SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 +SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 +SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 +SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 +SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 +SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 +SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 +SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 +SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36 +SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 +SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44 +SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 +SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52 +SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 +SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 +SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 +SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC +SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP +SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) @@ -81,14 +81,14 @@ STACK_SIZE = 1 << STACK_SHIFT * R15 - kernel stack pointer */ - .macro STORE_TIMER lc_offset + .macro STORE_TIMER lc_offset #ifdef CONFIG_VIRT_CPU_ACCOUNTING stpt \lc_offset #endif .endm #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .macro UPDATE_VTIME lc_from,lc_to,lc_sum + .macro UPDATE_VTIME lc_from,lc_to,lc_sum lm %r10,%r11,\lc_from sl %r10,\lc_to sl %r11,\lc_to+4 @@ -147,7 +147,7 @@ STACK_SIZE = 1 << STACK_SHIFT 2: .endm - .macro CREATE_STACK_FRAME psworg,savearea + .macro CREATE_STACK_FRAME psworg,savearea s %r15,BASED(.Lc_spsize) # make room for registers & psw mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack la %r12,\psworg @@ -160,7 +160,7 @@ STACK_SIZE = 1 << STACK_SHIFT st %r12,__SF_BACKCHAIN(%r15) # clear back chain .endm - .macro RESTORE_ALL psworg,sync + .macro RESTORE_ALL psworg,sync mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore .if !\sync ni \psworg+1,0xfd # clear wait state bit @@ -177,16 +177,16 @@ STACK_SIZE = 1 << STACK_SHIFT * Returns: * gpr2 = prev */ - .globl __switch_to + .globl __switch_to __switch_to: - basr %r1,0 + basr %r1,0 __switch_to_base: tm __THREAD_per(%r3),0xe8 # new process is using per ? bz __switch_to_noper-__switch_to_base(%r1) # if not we're fine - stctl %c9,%c11,__SF_EMPTY(%r15) # We are using per stuff - clc __THREAD_per(12,%r3),__SF_EMPTY(%r15) - be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's - lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't + stctl %c9,%c11,__SF_EMPTY(%r15) # We are using per stuff + clc __THREAD_per(12,%r3),__SF_EMPTY(%r15) + be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's + lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't __switch_to_noper: l %r4,__THREAD_info(%r2) # get thread_info of prev tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? @@ -195,13 +195,13 @@ __switch_to_noper: l %r4,__THREAD_info(%r3) # get thread_info of next oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next __switch_to_no_mcck: - stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task + stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp lm %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task st %r3,__LC_CURRENT # __LC_CURRENT = current task struct lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 - l %r3,__THREAD_info(%r3) # load thread_info from task struct + l %r3,__THREAD_info(%r3) # load thread_info from task struct st %r3,__LC_THREAD_INFO ahi %r3,STACK_SIZE st %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack @@ -213,7 +213,7 @@ __critical_start: * are executed with interrupts enabled. */ - .globl system_call + .globl system_call system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: @@ -233,24 +233,24 @@ sysc_update: #endif sysc_do_svc: l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - sla %r7,2 # *4 and test for svc 0 - bnz BASED(sysc_nr_ok) # svc number > 0 + sla %r7,2 # *4 and test for svc 0 + bnz BASED(sysc_nr_ok) # svc number > 0 # svc 0: system call number in %r1 cl %r1,BASED(.Lnr_syscalls) bnl BASED(sysc_nr_ok) - lr %r7,%r1 # copy svc number to %r7 - sla %r7,2 # *4 + lr %r7,%r1 # copy svc number to %r7 + sla %r7,2 # *4 sysc_nr_ok: mvc SP_ARGS(4,%r15),SP_R7(%r15) sysc_do_restart: l %r8,BASED(.Lsysc_table) tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) l %r8,0(%r7,%r8) # get system call addr. - bnz BASED(sysc_tracesys) - basr %r14,%r8 # call sys_xxxx - st %r2,SP_R2(%r15) # store return value (change R2 on stack) - # ATTENTION: check sys_execve_glue before - # changing anything here !! + bnz BASED(sysc_tracesys) + basr %r14,%r8 # call sys_xxxx + st %r2,SP_R2(%r15) # store return value (change R2 on stack) + # ATTENTION: check sys_execve_glue before + # changing anything here !! sysc_return: tm SP_PSW+1(%r15),0x01 # returning to user ? @@ -258,14 +258,14 @@ sysc_return: tm __TI_flags+3(%r9),_TIF_WORK_SVC bnz BASED(sysc_work) # there is work to do (signals etc.) sysc_leave: - RESTORE_ALL __LC_RETURN_PSW,1 + RESTORE_ALL __LC_RETURN_PSW,1 # # recheck if there is more work to do # sysc_work_loop: tm __TI_flags+3(%r9),_TIF_WORK_SVC - bz BASED(sysc_leave) # there is no work to do + bz BASED(sysc_leave) # there is no work to do # # One of the work bits is on. Find out which one. # @@ -284,11 +284,11 @@ sysc_work: # # _TIF_NEED_RESCHED is set, call schedule -# -sysc_reschedule: - l %r1,BASED(.Lschedule) - la %r14,BASED(sysc_work_loop) - br %r1 # call scheduler +# +sysc_reschedule: + l %r1,BASED(.Lschedule) + la %r14,BASED(sysc_work_loop) + br %r1 # call scheduler # # _TIF_MCCK_PENDING is set, call handler @@ -301,11 +301,11 @@ sysc_mcck_pending: # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # -sysc_sigpending: +sysc_sigpending: ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Ldo_signal) - basr %r14,%r1 # call do_signal + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Ldo_signal) + basr %r14,%r1 # call do_signal tm __TI_flags+3(%r9),_TIF_RESTART_SVC bo BASED(sysc_restart) tm __TI_flags+3(%r9),_TIF_SINGLE_STEP @@ -317,11 +317,11 @@ sysc_sigpending: # sysc_restart: ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC - l %r7,SP_R2(%r15) # load new svc number + l %r7,SP_R2(%r15) # load new svc number sla %r7,2 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument - lm %r2,%r6,SP_R2(%r15) # load svc arguments - b BASED(sysc_do_restart) # restart svc + lm %r2,%r6,SP_R2(%r15) # load svc arguments + b BASED(sysc_do_restart) # restart svc # # _TIF_SINGLE_STEP is set, call do_single_step @@ -338,8 +338,8 @@ sysc_singlestep: # call trace before and after sys_call # sysc_tracesys: - l %r1,BASED(.Ltrace) - la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Ltrace) + la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,0 srl %r7,2 st %r7,SP_R2(%r15) @@ -347,19 +347,19 @@ sysc_tracesys: clc SP_R2(4,%r15),BASED(.Lnr_syscalls) bnl BASED(sysc_tracenogo) l %r8,BASED(.Lsysc_table) - l %r7,SP_R2(%r15) # strace might have changed the - sll %r7,2 # system call + l %r7,SP_R2(%r15) # strace might have changed the + sll %r7,2 # system call l %r8,0(%r7,%r8) sysc_tracego: lm %r3,%r6,SP_R3(%r15) l %r2,SP_ORIG_R2(%r15) - basr %r14,%r8 # call sys_xxx - st %r2,SP_R2(%r15) # store return value + basr %r14,%r8 # call sys_xxx + st %r2,SP_R2(%r15) # store return value sysc_tracenogo: tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - bz BASED(sysc_return) + bz BASED(sysc_return) l %r1,BASED(.Ltrace) - la %r2,SP_PTREGS(%r15) # load pt_regs + la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,1 la %r14,BASED(sysc_return) br %r1 @@ -367,17 +367,17 @@ sysc_tracenogo: # # a new process exits the kernel with ret_from_fork # - .globl ret_from_fork + .globl ret_from_fork ret_from_fork: l %r13,__LC_SVC_NEW_PSW+4 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? bo BASED(0f) st %r15,SP_R15(%r15) # store stack pointer for new kthread -0: l %r1,BASED(.Lschedtail) - basr %r14,%r1 +0: l %r1,BASED(.Lschedtail) + basr %r14,%r1 TRACE_IRQS_ON - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts b BASED(sysc_return) # @@ -386,52 +386,51 @@ ret_from_fork: # but are called with different parameter. # return-address is set up above # -sys_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lclone) - br %r1 # branch to sys_clone - -sys_fork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lfork) - br %r1 # branch to sys_fork - -sys_vfork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lvfork) - br %r1 # branch to sys_vfork - -sys_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lexecve) - lr %r12,%r14 # save return address - basr %r14,%r1 # call sys_execve - ltr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8 - # in system_call/sysc_tracesys - -sys_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lsigreturn) - br %r1 # branch to sys_sigreturn - -sys_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lrt_sigreturn) - br %r1 # branch to sys_sigreturn +sys_clone_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Lclone) + br %r1 # branch to sys_clone -sys_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lsigaltstack) - br %r1 # branch to sys_sigreturn +sys_fork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Lfork) + br %r1 # branch to sys_fork +sys_vfork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Lvfork) + br %r1 # branch to sys_vfork + +sys_execve_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Lexecve) + lr %r12,%r14 # save return address + basr %r14,%r1 # call sys_execve + ltr %r2,%r2 # check if execve failed + bnz 0(%r12) # it did fail -> store result in gpr2 + b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8 + # in system_call/sysc_tracesys + +sys_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + l %r1,BASED(.Lsigreturn) + br %r1 # branch to sys_sigreturn + +sys_rt_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + l %r1,BASED(.Lrt_sigreturn) + br %r1 # branch to sys_sigreturn + +sys_sigaltstack_glue: + la %r4,SP_PTREGS(%r15) # load pt_regs as parameter + l %r1,BASED(.Lsigaltstack) + br %r1 # branch to sys_sigreturn /* * Program check handler routine */ - .globl pgm_check_handler + .globl pgm_check_handler pgm_check_handler: /* * First we need to check for a special case: @@ -448,8 +447,8 @@ pgm_check_handler: */ STORE_TIMER __LC_SYNC_ENTER_TIMER SAVE_ALL_BASE __LC_SAVE_AREA - tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception - bnz BASED(pgm_per) # got per exception -> special case + tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception + bnz BASED(pgm_per) # got per exception -> special case SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -461,29 +460,29 @@ pgm_check_handler: pgm_no_vtime: #endif l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - l %r3,__LC_PGM_ILC # load program interruption code + l %r3,__LC_PGM_ILC # load program interruption code la %r8,0x7f nr %r8,%r3 pgm_do_call: - l %r7,BASED(.Ljump_table) - sll %r8,2 - l %r7,0(%r8,%r7) # load address of handler routine - la %r2,SP_PTREGS(%r15) # address of register-save area - la %r14,BASED(sysc_return) - br %r7 # branch to interrupt-handler + l %r7,BASED(.Ljump_table) + sll %r8,2 + l %r7,0(%r8,%r7) # load address of handler routine + la %r2,SP_PTREGS(%r15) # address of register-save area + la %r14,BASED(sysc_return) + br %r7 # branch to interrupt-handler # # handle per exception # pgm_per: - tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on - bnz BASED(pgm_per_std) # ok, normal per event from user space + tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on + bnz BASED(pgm_per_std) # ok, normal per event from user space # ok its one of the special cases, now we need to find out which one - clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW - be BASED(pgm_svcper) + clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW + be BASED(pgm_svcper) # no interesting special case, ignore PER event - lm %r12,%r15,__LC_SAVE_AREA - lpsw 0x28 + lm %r12,%r15,__LC_SAVE_AREA + lpsw 0x28 # # Normal per exception @@ -507,10 +506,10 @@ pgm_no_vtime2: oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP tm SP_PSW+1(%r15),0x01 # kernel per event ? bz BASED(kernel_per) - l %r3,__LC_PGM_ILC # load program interruption code + l %r3,__LC_PGM_ILC # load program interruption code la %r8,0x7f - nr %r8,%r3 # clear per-event-bit and ilc - be BASED(sysc_return) # only per or per+check ? + nr %r8,%r3 # clear per-event-bit and ilc + be BASED(sysc_return) # only per or per+check ? b BASED(pgm_do_call) # @@ -552,7 +551,7 @@ kernel_per: * IO interrupt handler routine */ - .globl io_int_handler + .globl io_int_handler io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK @@ -569,42 +568,42 @@ io_no_vtime: #endif l %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF - l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ - la %r2,SP_PTREGS(%r15) # address of register-save area - basr %r14,%r1 # branch to standard irq handler + l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ + la %r2,SP_PTREGS(%r15) # address of register-save area + basr %r14,%r1 # branch to standard irq handler TRACE_IRQS_ON io_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? + tm SP_PSW+1(%r15),0x01 # returning to user ? #ifdef CONFIG_PREEMPT - bno BASED(io_preempt) # no -> check for preemptive scheduling + bno BASED(io_preempt) # no -> check for preemptive scheduling #else - bno BASED(io_leave) # no-> skip resched & signal + bno BASED(io_leave) # no-> skip resched & signal #endif tm __TI_flags+3(%r9),_TIF_WORK_INT - bnz BASED(io_work) # there is work to do (signals etc.) + bnz BASED(io_work) # there is work to do (signals etc.) io_leave: - RESTORE_ALL __LC_RETURN_PSW,0 + RESTORE_ALL __LC_RETURN_PSW,0 io_done: #ifdef CONFIG_PREEMPT io_preempt: icm %r0,15,__TI_precount(%r9) - bnz BASED(io_leave) + bnz BASED(io_leave) l %r1,SP_R15(%r15) s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 io_resume_loop: tm __TI_flags+3(%r9),_TIF_NEED_RESCHED bno BASED(io_leave) - mvc __TI_precount(4,%r9),BASED(.Lc_pactive) - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - l %r1,BASED(.Lschedule) + mvc __TI_precount(4,%r9),BASED(.Lc_pactive) + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + l %r1,BASED(.Lschedule) basr %r14,%r1 # call schedule - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts - xc __TI_precount(4,%r9),__TI_precount(%r9) + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + xc __TI_precount(4,%r9),__TI_precount(%r9) b BASED(io_resume_loop) #endif @@ -615,16 +614,16 @@ io_work: l %r1,__LC_KERNEL_STACK s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 # # One of the work bits is on. Find out which one. # Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGMASK, _TIF_NEED_RESCHED -# and _TIF_MCCK_PENDING +# and _TIF_MCCK_PENDING # io_work_loop: tm __TI_flags+3(%r9),_TIF_MCCK_PENDING - bo BASED(io_mcck_pending) + bo BASED(io_mcck_pending) tm __TI_flags+3(%r9),_TIF_NEED_RESCHED bo BASED(io_reschedule) tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) @@ -637,36 +636,36 @@ io_work_loop: io_mcck_pending: l %r1,BASED(.Ls390_handle_mcck) la %r14,BASED(io_work_loop) - br %r1 # TIF bit will be cleared by handler + br %r1 # TIF bit will be cleared by handler # # _TIF_NEED_RESCHED is set, call schedule -# -io_reschedule: - l %r1,BASED(.Lschedule) - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - basr %r14,%r1 # call scheduler - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts +# +io_reschedule: + l %r1,BASED(.Lschedule) + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + basr %r14,%r1 # call scheduler + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts tm __TI_flags+3(%r9),_TIF_WORK_INT - bz BASED(io_leave) # there is no work to do + bz BASED(io_leave) # there is no work to do b BASED(io_work_loop) # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # -io_sigpending: - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Ldo_signal) - basr %r14,%r1 # call do_signal - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts +io_sigpending: + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Ldo_signal) + basr %r14,%r1 # call do_signal + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts b BASED(io_work_loop) /* * External interrupt handler routine */ - .globl ext_int_handler + .globl ext_int_handler ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK @@ -683,8 +682,8 @@ ext_no_vtime: #endif l %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF - la %r2,SP_PTREGS(%r15) # address of register-save area - lh %r3,__LC_EXT_INT_CODE # get interruption code + la %r2,SP_PTREGS(%r15) # address of register-save area + lh %r3,__LC_EXT_INT_CODE # get interruption code l %r1,BASED(.Ldo_extint) basr %r14,%r1 TRACE_IRQS_ON @@ -696,13 +695,13 @@ __critical_end: * Machine check handler routines */ - .globl mcck_int_handler + .globl mcck_int_handler mcck_int_handler: spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+32 la %r12,__LC_MCK_OLD_PSW - tm __LC_MCCK_CODE,0x80 # system damage? + tm __LC_MCCK_CODE,0x80 # system damage? bo BASED(mcck_int_main) # yes -> rest of mcck code invalid #ifdef CONFIG_VIRT_CPU_ACCOUNTING mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER @@ -741,7 +740,7 @@ mcck_int_main: l %r15,__LC_PANIC_STACK # load panic stack 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 #ifdef CONFIG_VIRT_CPU_ACCOUNTING - tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? + tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? bno BASED(mcck_no_vtime) # no -> skip cleanup critical tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(mcck_no_vtime) @@ -752,14 +751,14 @@ mcck_no_vtime: #endif l %r9,__LC_THREAD_INFO # load pointer to thread_info struct la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Ls390_mcck) - basr %r14,%r1 # call machine check handler - tm SP_PSW+1(%r15),0x01 # returning to user ? + l %r1,BASED(.Ls390_mcck) + basr %r14,%r1 # call machine check handler + tm SP_PSW+1(%r15),0x01 # returning to user ? bno BASED(mcck_return) - l %r1,__LC_KERNEL_STACK # switch to kernel stack + l %r1,__LC_KERNEL_STACK # switch to kernel stack s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 stosm __SF_EMPTY(%r15),0x04 # turn dat on tm __TI_flags+3(%r9),_TIF_MCCK_PENDING @@ -783,36 +782,36 @@ mcck_return: lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 lpsw __LC_RETURN_MCCK_PSW # back to caller - RESTORE_ALL __LC_RETURN_MCCK_PSW,0 + RESTORE_ALL __LC_RETURN_MCCK_PSW,0 #ifdef CONFIG_SMP /* * Restart interruption handler, kick starter for additional CPUs */ - .globl restart_int_handler + .globl restart_int_handler restart_int_handler: - l %r15,__LC_SAVE_AREA+60 # load ksp - lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs - lam %a0,%a15,__LC_AREGS_SAVE_AREA - lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone - stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on - basr %r14,0 - l %r14,restart_addr-.(%r14) - br %r14 # branch to start_secondary + l %r15,__LC_SAVE_AREA+60 # load ksp + lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs + lam %a0,%a15,__LC_AREGS_SAVE_AREA + lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone + stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on + basr %r14,0 + l %r14,restart_addr-.(%r14) + br %r14 # branch to start_secondary restart_addr: - .long start_secondary + .long start_secondary #else /* * If we do not run with SMP enabled, let the new CPU crash ... */ - .globl restart_int_handler + .globl restart_int_handler restart_int_handler: - basr %r1,0 + basr %r1,0 restart_base: - lpsw restart_crash-restart_base(%r1) - .align 8 + lpsw restart_crash-restart_base(%r1) + .align 8 restart_crash: - .long 0x000a0000,0x00000000 + .long 0x000a0000,0x00000000 restart_go: #endif @@ -834,11 +833,11 @@ stack_overflow: be BASED(0f) la %r1,__LC_SAVE_AREA+16 0: mvc SP_R12(16,%r15),0(%r1) # move %r12-%r15 to stack - xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain + xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain l %r1,BASED(1f) # branch to kernel_stack_overflow - la %r2,SP_PTREGS(%r15) # load pt_regs + la %r2,SP_PTREGS(%r15) # load pt_regs br %r1 -1: .long kernel_stack_overflow +1: .long kernel_stack_overflow #endif cleanup_table_system_call: @@ -940,10 +939,10 @@ cleanup_novtime: cleanup_system_call_insn: .long sysc_saveall + 0x80000000 #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .long system_call + 0x80000000 - .long sysc_vtime + 0x80000000 - .long sysc_stime + 0x80000000 - .long sysc_update + 0x80000000 + .long system_call + 0x80000000 + .long sysc_vtime + 0x80000000 + .long sysc_stime + 0x80000000 + .long sysc_update + 0x80000000 #endif cleanup_sysc_return: @@ -1009,57 +1008,57 @@ cleanup_io_leave_insn: /* * Integer constants */ - .align 4 -.Lc_spsize: .long SP_SIZE -.Lc_overhead: .long STACK_FRAME_OVERHEAD -.Lc_pactive: .long PREEMPT_ACTIVE -.Lnr_syscalls: .long NR_syscalls -.L0x018: .short 0x018 -.L0x020: .short 0x020 -.L0x028: .short 0x028 -.L0x030: .short 0x030 -.L0x038: .short 0x038 -.Lc_1: .long 1 + .align 4 +.Lc_spsize: .long SP_SIZE +.Lc_overhead: .long STACK_FRAME_OVERHEAD +.Lc_pactive: .long PREEMPT_ACTIVE +.Lnr_syscalls: .long NR_syscalls +.L0x018: .short 0x018 +.L0x020: .short 0x020 +.L0x028: .short 0x028 +.L0x030: .short 0x030 +.L0x038: .short 0x038 +.Lc_1: .long 1 /* * Symbol constants */ -.Ls390_mcck: .long s390_do_machine_check +.Ls390_mcck: .long s390_do_machine_check .Ls390_handle_mcck: - .long s390_handle_mcck -.Lmck_old_psw: .long __LC_MCK_OLD_PSW -.Ldo_IRQ: .long do_IRQ -.Ldo_extint: .long do_extint -.Ldo_signal: .long do_signal -.Lhandle_per: .long do_single_step -.Ljump_table: .long pgm_check_table -.Lschedule: .long schedule -.Lclone: .long sys_clone -.Lexecve: .long sys_execve -.Lfork: .long sys_fork -.Lrt_sigreturn:.long sys_rt_sigreturn + .long s390_handle_mcck +.Lmck_old_psw: .long __LC_MCK_OLD_PSW +.Ldo_IRQ: .long do_IRQ +.Ldo_extint: .long do_extint +.Ldo_signal: .long do_signal +.Lhandle_per: .long do_single_step +.Ljump_table: .long pgm_check_table +.Lschedule: .long schedule +.Lclone: .long sys_clone +.Lexecve: .long sys_execve +.Lfork: .long sys_fork +.Lrt_sigreturn: .long sys_rt_sigreturn .Lrt_sigsuspend: - .long sys_rt_sigsuspend -.Lsigreturn: .long sys_sigreturn -.Lsigsuspend: .long sys_sigsuspend -.Lsigaltstack: .long sys_sigaltstack -.Ltrace: .long syscall_trace -.Lvfork: .long sys_vfork -.Lschedtail: .long schedule_tail -.Lsysc_table: .long sys_call_table + .long sys_rt_sigsuspend +.Lsigreturn: .long sys_sigreturn +.Lsigsuspend: .long sys_sigsuspend +.Lsigaltstack: .long sys_sigaltstack +.Ltrace: .long syscall_trace +.Lvfork: .long sys_vfork +.Lschedtail: .long schedule_tail +.Lsysc_table: .long sys_call_table #ifdef CONFIG_TRACE_IRQFLAGS -.Ltrace_irq_on:.long trace_hardirqs_on +.Ltrace_irq_on: .long trace_hardirqs_on .Ltrace_irq_off: - .long trace_hardirqs_off + .long trace_hardirqs_off #endif .Lcritical_start: - .long __critical_start + 0x80000000 + .long __critical_start + 0x80000000 .Lcritical_end: - .long __critical_end + 0x80000000 + .long __critical_end + 0x80000000 .Lcleanup_critical: - .long cleanup_critical + .long cleanup_critical - .section .rodata, "a" + .section .rodata, "a" #define SYSCALL(esa,esame,emu) .long esa sys_call_table: #include "syscalls.S" diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 29bbfbab733..0f758c329a5 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -4,8 +4,8 @@ * * Copyright (C) IBM Corp. 1999,2006 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - * Hartmut Penner (hp@de.ibm.com), - * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), + * Hartmut Penner (hp@de.ibm.com), + * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * Heiko Carstens <heiko.carstens@de.ibm.com> */ @@ -24,29 +24,29 @@ * Stack layout for the system_call stack entry. * The first few entries are identical to the user_regs_struct. */ -SP_PTREGS = STACK_FRAME_OVERHEAD -SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS -SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW -SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS -SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 -SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 -SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 -SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 -SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 -SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 -SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 -SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 -SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 72 -SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 80 -SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 88 -SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 96 -SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 104 -SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112 -SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120 -SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 -SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC -SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP -SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS +SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW +SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS +SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 +SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 +SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 +SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 +SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 +SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 +SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 +SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 +SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 72 +SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 80 +SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 88 +SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 96 +SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 104 +SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112 +SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120 +SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 +SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC +SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP +SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SIZE = 1 << STACK_SHIFT @@ -71,14 +71,14 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ #define TRACE_IRQS_OFF #endif - .macro STORE_TIMER lc_offset + .macro STORE_TIMER lc_offset #ifdef CONFIG_VIRT_CPU_ACCOUNTING stpt \lc_offset #endif .endm #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .macro UPDATE_VTIME lc_from,lc_to,lc_sum + .macro UPDATE_VTIME lc_from,lc_to,lc_sum lg %r10,\lc_from slg %r10,\lc_to alg %r10,\lc_sum @@ -94,7 +94,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ * R15 - kernel stack pointer */ - .macro SAVE_ALL_BASE savearea + .macro SAVE_ALL_BASE savearea stmg %r12,%r15,\savearea larl %r13,system_call .endm @@ -139,8 +139,8 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ .endm .macro CREATE_STACK_FRAME psworg,savearea - aghi %r15,-SP_SIZE # make room for registers & psw - mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack + aghi %r15,-SP_SIZE # make room for registers & psw + mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack la %r12,\psworg stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 icm %r12,12,__LC_SVC_ILC @@ -149,7 +149,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack la %r12,0 stg %r12,__SF_BACKCHAIN(%r15) - .endm + .endm .macro RESTORE_ALL psworg,sync mvc \psworg(16),SP_PSW(%r15) # move user PSW to lowcore @@ -168,29 +168,29 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ * Returns: * gpr2 = prev */ - .globl __switch_to + .globl __switch_to __switch_to: tm __THREAD_per+4(%r3),0xe8 # is the new process using per ? jz __switch_to_noper # if not we're fine - stctg %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff - clc __THREAD_per(24,%r3),__SF_EMPTY(%r15) - je __switch_to_noper # we got away without bashing TLB's - lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't + stctg %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff + clc __THREAD_per(24,%r3),__SF_EMPTY(%r15) + je __switch_to_noper # we got away without bashing TLB's + lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't __switch_to_noper: - lg %r4,__THREAD_info(%r2) # get thread_info of prev + lg %r4,__THREAD_info(%r2) # get thread_info of prev tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? jz __switch_to_no_mcck ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev lg %r4,__THREAD_info(%r3) # get thread_info of next oi __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next __switch_to_no_mcck: - stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task + stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp - lmg %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task + lmg %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task stg %r3,__LC_CURRENT # __LC_CURRENT = current task struct lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 - lg %r3,__THREAD_info(%r3) # load thread_info from task struct + lg %r3,__THREAD_info(%r3) # load thread_info from task struct stg %r3,__LC_THREAD_INFO aghi %r3,STACK_SIZE stg %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack @@ -202,14 +202,14 @@ __critical_start: * are executed with interrupts enabled. */ - .globl system_call + .globl system_call system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA - llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore + CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA + llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING sysc_vtime: tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -222,45 +222,45 @@ sysc_update: #endif sysc_do_svc: lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct - slag %r7,%r7,2 # *4 and test for svc 0 + slag %r7,%r7,2 # *4 and test for svc 0 jnz sysc_nr_ok # svc 0: system call number in %r1 cl %r1,BASED(.Lnr_syscalls) jnl sysc_nr_ok - lgfr %r7,%r1 # clear high word in r1 - slag %r7,%r7,2 # svc 0: system call number in %r1 + lgfr %r7,%r1 # clear high word in r1 + slag %r7,%r7,2 # svc 0: system call number in %r1 sysc_nr_ok: mvc SP_ARGS(8,%r15),SP_R7(%r15) sysc_do_restart: - larl %r10,sys_call_table + larl %r10,sys_call_table #ifdef CONFIG_COMPAT tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ? jno sysc_noemu - larl %r10,sys_call_table_emu # use 31 bit emulation system calls + larl %r10,sys_call_table_emu # use 31 bit emulation system calls sysc_noemu: #endif tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - lgf %r8,0(%r7,%r10) # load address of system call routine - jnz sysc_tracesys - basr %r14,%r8 # call sys_xxxx - stg %r2,SP_R2(%r15) # store return value (change R2 on stack) - # ATTENTION: check sys_execve_glue before - # changing anything here !! + lgf %r8,0(%r7,%r10) # load address of system call routine + jnz sysc_tracesys + basr %r14,%r8 # call sys_xxxx + stg %r2,SP_R2(%r15) # store return value (change R2 on stack) + # ATTENTION: check sys_execve_glue before + # changing anything here !! sysc_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? - jno sysc_leave + tm SP_PSW+1(%r15),0x01 # returning to user ? + jno sysc_leave tm __TI_flags+7(%r9),_TIF_WORK_SVC - jnz sysc_work # there is work to do (signals etc.) + jnz sysc_work # there is work to do (signals etc.) sysc_leave: - RESTORE_ALL __LC_RETURN_PSW,1 + RESTORE_ALL __LC_RETURN_PSW,1 # # recheck if there is more work to do # sysc_work_loop: tm __TI_flags+7(%r9),_TIF_WORK_SVC - jz sysc_leave # there is no work to do + jz sysc_leave # there is no work to do # # One of the work bits is on. Find out which one. # @@ -279,25 +279,25 @@ sysc_work: # # _TIF_NEED_RESCHED is set, call schedule -# -sysc_reschedule: - larl %r14,sysc_work_loop - jg schedule # return point is sysc_return +# +sysc_reschedule: + larl %r14,sysc_work_loop + jg schedule # return point is sysc_return # # _TIF_MCCK_PENDING is set, call handler # sysc_mcck_pending: larl %r14,sysc_work_loop - jg s390_handle_mcck # TIF bit will be cleared by handler + jg s390_handle_mcck # TIF bit will be cleared by handler # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # -sysc_sigpending: +sysc_sigpending: ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP - la %r2,SP_PTREGS(%r15) # load pt_regs - brasl %r14,do_signal # call do_signal + la %r2,SP_PTREGS(%r15) # load pt_regs + brasl %r14,do_signal # call do_signal tm __TI_flags+7(%r9),_TIF_RESTART_SVC jo sysc_restart tm __TI_flags+7(%r9),_TIF_SINGLE_STEP @@ -309,11 +309,11 @@ sysc_sigpending: # sysc_restart: ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC - lg %r7,SP_R2(%r15) # load new svc number - slag %r7,%r7,2 # *4 + lg %r7,SP_R2(%r15) # load new svc number + slag %r7,%r7,2 # *4 mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument - lmg %r2,%r6,SP_R2(%r15) # load svc arguments - j sysc_do_restart # restart svc + lmg %r2,%r6,SP_R2(%r15) # load svc arguments + j sysc_do_restart # restart svc # # _TIF_SINGLE_STEP is set, call do_single_step @@ -326,49 +326,48 @@ sysc_singlestep: larl %r14,sysc_return # load adr. of system return jg do_single_step # branch to do_sigtrap - # # call syscall_trace before and after system call # special linkage: %r12 contains the return address for trace_svc # sysc_tracesys: - la %r2,SP_PTREGS(%r15) # load pt_regs + la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,0 srl %r7,2 - stg %r7,SP_R2(%r15) - brasl %r14,syscall_trace + stg %r7,SP_R2(%r15) + brasl %r14,syscall_trace lghi %r0,NR_syscalls clg %r0,SP_R2(%r15) jnh sysc_tracenogo - lg %r7,SP_R2(%r15) # strace might have changed the - sll %r7,2 # system call + lg %r7,SP_R2(%r15) # strace might have changed the + sll %r7,2 # system call lgf %r8,0(%r7,%r10) sysc_tracego: - lmg %r3,%r6,SP_R3(%r15) - lg %r2,SP_ORIG_R2(%r15) - basr %r14,%r8 # call sys_xxx - stg %r2,SP_R2(%r15) # store return value + lmg %r3,%r6,SP_R3(%r15) + lg %r2,SP_ORIG_R2(%r15) + basr %r14,%r8 # call sys_xxx + stg %r2,SP_R2(%r15) # store return value sysc_tracenogo: tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - jz sysc_return - la %r2,SP_PTREGS(%r15) # load pt_regs + jz sysc_return + la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,1 - larl %r14,sysc_return # return point is sysc_return + larl %r14,sysc_return # return point is sysc_return jg syscall_trace # # a new process exits the kernel with ret_from_fork # - .globl ret_from_fork + .globl ret_from_fork ret_from_fork: lg %r13,__LC_SVC_NEW_PSW+8 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? jo 0f stg %r15,SP_R15(%r15) # store stack pointer for new kthread -0: brasl %r14,schedule_tail +0: brasl %r14,schedule_tail TRACE_IRQS_ON - stosm 24(%r15),0x03 # reenable interrupts + stosm 24(%r15),0x03 # reenable interrupts j sysc_return # @@ -377,78 +376,78 @@ ret_from_fork: # but are called with different parameter. # return-address is set up above # -sys_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_clone # branch to sys_clone +sys_clone_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_clone # branch to sys_clone #ifdef CONFIG_COMPAT -sys32_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys32_clone # branch to sys32_clone +sys32_clone_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys32_clone # branch to sys32_clone #endif -sys_fork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_fork # branch to sys_fork - -sys_vfork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_vfork # branch to sys_vfork - -sys_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - lgr %r12,%r14 # save return address - brasl %r14,sys_execve # call sys_execve - ltgr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 6(%r12) # SKIP STG 2,SP_R2(15) in - # system_call/sysc_tracesys +sys_fork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_fork # branch to sys_fork + +sys_vfork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_vfork # branch to sys_vfork + +sys_execve_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + lgr %r12,%r14 # save return address + brasl %r14,sys_execve # call sys_execve + ltgr %r2,%r2 # check if execve failed + bnz 0(%r12) # it did fail -> store result in gpr2 + b 6(%r12) # SKIP STG 2,SP_R2(15) in + # system_call/sysc_tracesys #ifdef CONFIG_COMPAT -sys32_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - lgr %r12,%r14 # save return address - brasl %r14,sys32_execve # call sys32_execve - ltgr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 6(%r12) # SKIP STG 2,SP_R2(15) in - # system_call/sysc_tracesys +sys32_execve_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + lgr %r12,%r14 # save return address + brasl %r14,sys32_execve # call sys32_execve + ltgr %r2,%r2 # check if execve failed + bnz 0(%r12) # it did fail -> store result in gpr2 + b 6(%r12) # SKIP STG 2,SP_R2(15) in + # system_call/sysc_tracesys #endif -sys_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_sigreturn # branch to sys_sigreturn +sys_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_sigreturn # branch to sys_sigreturn #ifdef CONFIG_COMPAT -sys32_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_sigreturn # branch to sys32_sigreturn +sys32_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_sigreturn # branch to sys32_sigreturn #endif -sys_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_rt_sigreturn # branch to sys_sigreturn +sys_rt_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_rt_sigreturn # branch to sys_sigreturn #ifdef CONFIG_COMPAT -sys32_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_rt_sigreturn # branch to sys32_sigreturn +sys32_rt_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_rt_sigreturn # branch to sys32_sigreturn #endif sys_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_sigaltstack # branch to sys_sigreturn + la %r4,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_sigaltstack # branch to sys_sigreturn #ifdef CONFIG_COMPAT sys32_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_sigaltstack_wrapper # branch to sys_sigreturn + la %r4,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_sigaltstack_wrapper # branch to sys_sigreturn #endif /* * Program check handler routine */ - .globl pgm_check_handler + .globl pgm_check_handler pgm_check_handler: /* * First we need to check for a special case: @@ -465,8 +464,8 @@ pgm_check_handler: */ STORE_TIMER __LC_SYNC_ENTER_TIMER SAVE_ALL_BASE __LC_SAVE_AREA - tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception - jnz pgm_per # got per exception -> special case + tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception + jnz pgm_per # got per exception -> special case SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -478,29 +477,29 @@ pgm_check_handler: pgm_no_vtime: #endif lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct - lgf %r3,__LC_PGM_ILC # load program interruption code + lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f ngr %r8,%r3 pgm_do_call: - sll %r8,3 - larl %r1,pgm_check_table - lg %r1,0(%r8,%r1) # load address of handler routine - la %r2,SP_PTREGS(%r15) # address of register-save area + sll %r8,3 + larl %r1,pgm_check_table + lg %r1,0(%r8,%r1) # load address of handler routine + la %r2,SP_PTREGS(%r15) # address of register-save area larl %r14,sysc_return - br %r1 # branch to interrupt-handler + br %r1 # branch to interrupt-handler # # handle per exception # pgm_per: - tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on - jnz pgm_per_std # ok, normal per event from user space + tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on + jnz pgm_per_std # ok, normal per event from user space # ok its one of the special cases, now we need to find out which one - clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW - je pgm_svcper + clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW + je pgm_svcper # no interesting special case, ignore PER event lmg %r12,%r15,__LC_SAVE_AREA - lpswe __LC_PGM_OLD_PSW + lpswe __LC_PGM_OLD_PSW # # Normal per exception @@ -524,9 +523,9 @@ pgm_no_vtime2: mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP - lgf %r3,__LC_PGM_ILC # load program interruption code + lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f - ngr %r8,%r3 # clear per-event-bit and ilc + ngr %r8,%r3 # clear per-event-bit and ilc je sysc_return j pgm_do_call @@ -544,7 +543,7 @@ pgm_svcper: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime3: #endif - llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore + llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct lg %r1,__TI_task(%r9) mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID @@ -568,7 +567,7 @@ kernel_per: /* * IO interrupt handler routine */ - .globl io_int_handler + .globl io_int_handler io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK @@ -585,42 +584,42 @@ io_no_vtime: #endif lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF - la %r2,SP_PTREGS(%r15) # address of register-save area - brasl %r14,do_IRQ # call standard irq handler + la %r2,SP_PTREGS(%r15) # address of register-save area + brasl %r14,do_IRQ # call standard irq handler TRACE_IRQS_ON io_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? + tm SP_PSW+1(%r15),0x01 # returning to user ? #ifdef CONFIG_PREEMPT - jno io_preempt # no -> check for preemptive scheduling + jno io_preempt # no -> check for preemptive scheduling #else - jno io_leave # no-> skip resched & signal + jno io_leave # no-> skip resched & signal #endif tm __TI_flags+7(%r9),_TIF_WORK_INT - jnz io_work # there is work to do (signals etc.) + jnz io_work # there is work to do (signals etc.) io_leave: - RESTORE_ALL __LC_RETURN_PSW,0 + RESTORE_ALL __LC_RETURN_PSW,0 io_done: #ifdef CONFIG_PREEMPT io_preempt: - icm %r0,15,__TI_precount(%r9) - jnz io_leave + icm %r0,15,__TI_precount(%r9) + jnz io_leave # switch to kernel stack lg %r1,SP_R15(%r15) aghi %r1,-SP_SIZE mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain lgr %r15,%r1 io_resume_loop: tm __TI_flags+7(%r9),_TIF_NEED_RESCHED jno io_leave - larl %r1,.Lc_pactive - mvc __TI_precount(4,%r9),0(%r1) - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - brasl %r14,schedule # call schedule - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts - xc __TI_precount(4,%r9),__TI_precount(%r9) + larl %r1,.Lc_pactive + mvc __TI_precount(4,%r9),0(%r1) + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + brasl %r14,schedule # call schedule + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + xc __TI_precount(4,%r9),__TI_precount(%r9) j io_resume_loop #endif @@ -631,7 +630,7 @@ io_work: lg %r1,__LC_KERNEL_STACK aghi %r1,-SP_SIZE mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain lgr %r15,%r1 # # One of the work bits is on. Find out which one. @@ -656,11 +655,11 @@ io_mcck_pending: # # _TIF_NEED_RESCHED is set, call schedule -# -io_reschedule: - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - brasl %r14,schedule # call scheduler - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts +# +io_reschedule: + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + brasl %r14,schedule # call scheduler + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts tm __TI_flags+7(%r9),_TIF_WORK_INT jz io_leave # there is no work to do j io_work_loop @@ -668,17 +667,17 @@ io_reschedule: # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # -io_sigpending: - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - la %r2,SP_PTREGS(%r15) # load pt_regs +io_sigpending: + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,do_signal # call do_signal - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts j io_work_loop /* * External interrupt handler routine */ - .globl ext_int_handler + .globl ext_int_handler ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK @@ -695,9 +694,9 @@ ext_no_vtime: #endif lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF - la %r2,SP_PTREGS(%r15) # address of register-save area - llgh %r3,__LC_EXT_INT_CODE # get interruption code - brasl %r14,do_extint + la %r2,SP_PTREGS(%r15) # address of register-save area + llgh %r3,__LC_EXT_INT_CODE # get interruption code + brasl %r14,do_extint TRACE_IRQS_ON j io_return @@ -706,14 +705,14 @@ __critical_end: /* * Machine check handler routines */ - .globl mcck_int_handler + .globl mcck_int_handler mcck_int_handler: la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer - lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs + lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+64 la %r12,__LC_MCK_OLD_PSW - tm __LC_MCCK_CODE,0x80 # system damage? + tm __LC_MCCK_CODE,0x80 # system damage? jo mcck_int_main # yes -> rest of mcck code invalid #ifdef CONFIG_VIRT_CPU_ACCOUNTING la %r14,4095 @@ -737,19 +736,19 @@ mcck_int_handler: #endif tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? jno mcck_int_main # no -> skip cleanup critical - tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit + tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit jnz mcck_int_main # from user -> load kernel stack clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) jhe mcck_int_main - clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) + clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) jl mcck_int_main - brasl %r14,cleanup_critical + brasl %r14,cleanup_critical mcck_int_main: - lg %r14,__LC_PANIC_STACK # are we already on the panic stack? + lg %r14,__LC_PANIC_STACK # are we already on the panic stack? slgr %r14,%r15 srag %r14,%r14,PAGE_SHIFT jz 0f - lg %r15,__LC_PANIC_STACK # load panic stack + lg %r15,__LC_PANIC_STACK # load panic stack 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? @@ -764,7 +763,7 @@ mcck_no_vtime: lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,s390_do_machine_check - tm SP_PSW+1(%r15),0x01 # returning to user ? + tm SP_PSW+1(%r15),0x01 # returning to user ? jno mcck_return lg %r1,__LC_KERNEL_STACK # switch to kernel stack aghi %r1,-SP_SIZE @@ -794,28 +793,28 @@ mcck_return: /* * Restart interruption handler, kick starter for additional CPUs */ - .globl restart_int_handler + .globl restart_int_handler restart_int_handler: - lg %r15,__LC_SAVE_AREA+120 # load ksp - lghi %r10,__LC_CREGS_SAVE_AREA - lctlg %c0,%c15,0(%r10) # get new ctl regs - lghi %r10,__LC_AREGS_SAVE_AREA - lam %a0,%a15,0(%r10) - lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone - stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on - jg start_secondary + lg %r15,__LC_SAVE_AREA+120 # load ksp + lghi %r10,__LC_CREGS_SAVE_AREA + lctlg %c0,%c15,0(%r10) # get new ctl regs + lghi %r10,__LC_AREGS_SAVE_AREA + lam %a0,%a15,0(%r10) + lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone + stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on + jg start_secondary #else /* * If we do not run with SMP enabled, let the new CPU crash ... */ - .globl restart_int_handler + .globl restart_int_handler restart_int_handler: - basr %r1,0 + basr %r1,0 restart_base: - lpswe restart_crash-restart_base(%r1) - .align 8 + lpswe restart_crash-restart_base(%r1) + .align 8 restart_crash: - .long 0x000a0000,0x00000000,0x00000000,0x00000000 + .long 0x000a0000,0x00000000,0x00000000,0x00000000 restart_go: #endif @@ -836,9 +835,9 @@ stack_overflow: chi %r12,__LC_PGM_OLD_PSW je 0f la %r1,__LC_SAVE_AREA+32 -0: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain - la %r2,SP_PTREGS(%r15) # load pt_regs +0: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain + la %r2,SP_PTREGS(%r15) # load pt_regs jg kernel_stack_overflow #endif @@ -941,10 +940,10 @@ cleanup_novtime: cleanup_system_call_insn: .quad sysc_saveall #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .quad system_call - .quad sysc_vtime - .quad sysc_stime - .quad sysc_update + .quad system_call + .quad sysc_vtime + .quad sysc_stime + .quad sysc_update #endif cleanup_sysc_return: @@ -1010,21 +1009,21 @@ cleanup_io_leave_insn: /* * Integer constants */ - .align 4 + .align 4 .Lconst: -.Lc_pactive: .long PREEMPT_ACTIVE -.Lnr_syscalls: .long NR_syscalls -.L0x0130: .short 0x130 -.L0x0140: .short 0x140 -.L0x0150: .short 0x150 -.L0x0160: .short 0x160 -.L0x0170: .short 0x170 +.Lc_pactive: .long PREEMPT_ACTIVE +.Lnr_syscalls: .long NR_syscalls +.L0x0130: .short 0x130 +.L0x0140: .short 0x140 +.L0x0150: .short 0x150 +.L0x0160: .short 0x160 +.L0x0170: .short 0x170 .Lcritical_start: - .quad __critical_start + .quad __critical_start .Lcritical_end: - .quad __critical_end + .quad __critical_end - .section .rodata, "a" + .section .rodata, "a" #define SYSCALL(esa,esame,emu) .long esame sys_call_table: #include "syscalls.S" diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 0f1db268a8a..0cf59bb7a85 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -36,449 +36,449 @@ #endif #ifndef CONFIG_IPL - .org 0 - .long 0x00080000,0x80000000+startup # Just a restart PSW + .org 0 + .long 0x00080000,0x80000000+startup # Just a restart PSW #else #ifdef CONFIG_IPL_TAPE #define IPL_BS 1024 - .org 0 - .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded - .long 0x27000000,0x60000001 # by ipl to addresses 0-23. - .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). - .long 0x00000000,0x00000000 # external old psw - .long 0x00000000,0x00000000 # svc old psw - .long 0x00000000,0x00000000 # program check old psw - .long 0x00000000,0x00000000 # machine check old psw - .long 0x00000000,0x00000000 # io old psw - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x000a0000,0x00000058 # external new psw - .long 0x000a0000,0x00000060 # svc new psw - .long 0x000a0000,0x00000068 # program check new psw - .long 0x000a0000,0x00000070 # machine check new psw - .long 0x00080000,0x80000000+.Lioint # io new psw + .org 0 + .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded + .long 0x27000000,0x60000001 # by ipl to addresses 0-23. + .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). + .long 0x00000000,0x00000000 # external old psw + .long 0x00000000,0x00000000 # svc old psw + .long 0x00000000,0x00000000 # program check old psw + .long 0x00000000,0x00000000 # machine check old psw + .long 0x00000000,0x00000000 # io old psw + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x000a0000,0x00000058 # external new psw + .long 0x000a0000,0x00000060 # svc new psw + .long 0x000a0000,0x00000068 # program check new psw + .long 0x000a0000,0x00000070 # machine check new psw + .long 0x00080000,0x80000000+.Lioint # io new psw - .org 0x100 + .org 0x100 # # subroutine for loading from tape -# Paramters: +# Paramters: # R1 = device number # R2 = load address -.Lloader: - st %r14,.Lldret - la %r3,.Lorbread # r3 = address of orb - la %r5,.Lirb # r5 = address of irb - st %r2,.Lccwread+4 # initialize CCW data addresses - lctl %c6,%c6,.Lcr6 - slr %r2,%r2 +.Lloader: + st %r14,.Lldret + la %r3,.Lorbread # r3 = address of orb + la %r5,.Lirb # r5 = address of irb + st %r2,.Lccwread+4 # initialize CCW data addresses + lctl %c6,%c6,.Lcr6 + slr %r2,%r2 .Lldlp: - la %r6,3 # 3 retries + la %r6,3 # 3 retries .Lssch: - ssch 0(%r3) # load chunk of IPL_BS bytes - bnz .Llderr + ssch 0(%r3) # load chunk of IPL_BS bytes + bnz .Llderr .Lw4end: - bas %r14,.Lwait4io - tm 8(%r5),0x82 # do we have a problem ? - bnz .Lrecov - slr %r7,%r7 - icm %r7,3,10(%r5) # get residual count - lcr %r7,%r7 - la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read - ar %r2,%r7 # add to total size - tm 8(%r5),0x01 # found a tape mark ? - bnz .Ldone - l %r0,.Lccwread+4 # update CCW data addresses - ar %r0,%r7 - st %r0,.Lccwread+4 - b .Lldlp + bas %r14,.Lwait4io + tm 8(%r5),0x82 # do we have a problem ? + bnz .Lrecov + slr %r7,%r7 + icm %r7,3,10(%r5) # get residual count + lcr %r7,%r7 + la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read + ar %r2,%r7 # add to total size + tm 8(%r5),0x01 # found a tape mark ? + bnz .Ldone + l %r0,.Lccwread+4 # update CCW data addresses + ar %r0,%r7 + st %r0,.Lccwread+4 + b .Lldlp .Ldone: - l %r14,.Lldret - br %r14 # r2 contains the total size + l %r14,.Lldret + br %r14 # r2 contains the total size .Lrecov: - bas %r14,.Lsense # do the sensing - bct %r6,.Lssch # dec. retry count & branch - b .Llderr + bas %r14,.Lsense # do the sensing + bct %r6,.Lssch # dec. retry count & branch + b .Llderr # # Sense subroutine # .Lsense: - st %r14,.Lsnsret - la %r7,.Lorbsense - ssch 0(%r7) # start sense command - bnz .Llderr - bas %r14,.Lwait4io - l %r14,.Lsnsret - tm 8(%r5),0x82 # do we have a problem ? - bnz .Llderr - br %r14 + st %r14,.Lsnsret + la %r7,.Lorbsense + ssch 0(%r7) # start sense command + bnz .Llderr + bas %r14,.Lwait4io + l %r14,.Lsnsret + tm 8(%r5),0x82 # do we have a problem ? + bnz .Llderr + br %r14 # # Wait for interrupt subroutine # .Lwait4io: - lpsw .Lwaitpsw + lpsw .Lwaitpsw .Lioint: - c %r1,0xb8 # compare subchannel number - bne .Lwait4io - tsch 0(%r5) - slr %r0,%r0 - tm 8(%r5),0x82 # do we have a problem ? - bnz .Lwtexit - tm 8(%r5),0x04 # got device end ? - bz .Lwait4io + c %r1,0xb8 # compare subchannel number + bne .Lwait4io + tsch 0(%r5) + slr %r0,%r0 + tm 8(%r5),0x82 # do we have a problem ? + bnz .Lwtexit + tm 8(%r5),0x04 # got device end ? + bz .Lwait4io .Lwtexit: - br %r14 + br %r14 .Llderr: - lpsw .Lcrash + lpsw .Lcrash - .align 8 + .align 8 .Lorbread: - .long 0x00000000,0x0080ff00,.Lccwread - .align 8 + .long 0x00000000,0x0080ff00,.Lccwread + .align 8 .Lorbsense: - .long 0x00000000,0x0080ff00,.Lccwsense - .align 8 + .long 0x00000000,0x0080ff00,.Lccwsense + .align 8 .Lccwread: - .long 0x02200000+IPL_BS,0x00000000 + .long 0x02200000+IPL_BS,0x00000000 .Lccwsense: - .long 0x04200001,0x00000000 + .long 0x04200001,0x00000000 .Lwaitpsw: - .long 0x020a0000,0x80000000+.Lioint + .long 0x020a0000,0x80000000+.Lioint -.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -.Lcr6: .long 0xff000000 - .align 8 -.Lcrash:.long 0x000a0000,0x00000000 -.Lldret:.long 0 +.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.Lcr6: .long 0xff000000 + .align 8 +.Lcrash:.long 0x000a0000,0x00000000 +.Lldret:.long 0 .Lsnsret: .long 0 -#endif /* CONFIG_IPL_TAPE */ +#endif /* CONFIG_IPL_TAPE */ #ifdef CONFIG_IPL_VM -#define IPL_BS 0x730 - .org 0 - .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded - .long 0x02000018,0x60000050 # by ipl to addresses 0-23. - .long 0x02000068,0x60000050 # (a PSW and two CCWs). - .fill 80-24,1,0x40 # bytes 24-79 are discarded !! - .long 0x020000f0,0x60000050 # The next 160 byte are loaded - .long 0x02000140,0x60000050 # to addresses 0x18-0xb7 - .long 0x02000190,0x60000050 # They form the continuation - .long 0x020001e0,0x60000050 # of the CCW program started - .long 0x02000230,0x60000050 # by ipl and load the range - .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image - .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730 - .long 0x02000320,0x60000050 # in memory. At the end of - .long 0x02000370,0x60000050 # the channel program the PSW - .long 0x020003c0,0x60000050 # at location 0 is loaded. - .long 0x02000410,0x60000050 # Initial processing starts - .long 0x02000460,0x60000050 # at 0xf0 = iplstart. - .long 0x020004b0,0x60000050 - .long 0x02000500,0x60000050 - .long 0x02000550,0x60000050 - .long 0x020005a0,0x60000050 - .long 0x020005f0,0x60000050 - .long 0x02000640,0x60000050 - .long 0x02000690,0x60000050 - .long 0x020006e0,0x20000050 +#define IPL_BS 0x730 + .org 0 + .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded + .long 0x02000018,0x60000050 # by ipl to addresses 0-23. + .long 0x02000068,0x60000050 # (a PSW and two CCWs). + .fill 80-24,1,0x40 # bytes 24-79 are discarded !! + .long 0x020000f0,0x60000050 # The next 160 byte are loaded + .long 0x02000140,0x60000050 # to addresses 0x18-0xb7 + .long 0x02000190,0x60000050 # They form the continuation + .long 0x020001e0,0x60000050 # of the CCW program started + .long 0x02000230,0x60000050 # by ipl and load the range + .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image + .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730 + .long 0x02000320,0x60000050 # in memory. At the end of + .long 0x02000370,0x60000050 # the channel program the PSW + .long 0x020003c0,0x60000050 # at location 0 is loaded. + .long 0x02000410,0x60000050 # Initial processing starts + .long 0x02000460,0x60000050 # at 0xf0 = iplstart. + .long 0x020004b0,0x60000050 + .long 0x02000500,0x60000050 + .long 0x02000550,0x60000050 + .long 0x020005a0,0x60000050 + .long 0x020005f0,0x60000050 + .long 0x02000640,0x60000050 + .long 0x02000690,0x60000050 + .long 0x020006e0,0x20000050 - .org 0xf0 + .org 0xf0 # # subroutine for loading cards from the reader # -.Lloader: - la %r3,.Lorb # r2 = address of orb into r2 - la %r5,.Lirb # r4 = address of irb - la %r6,.Lccws - la %r7,20 +.Lloader: + la %r3,.Lorb # r2 = address of orb into r2 + la %r5,.Lirb # r4 = address of irb + la %r6,.Lccws + la %r7,20 .Linit: - st %r2,4(%r6) # initialize CCW data addresses - la %r2,0x50(%r2) - la %r6,8(%r6) - bct 7,.Linit + st %r2,4(%r6) # initialize CCW data addresses + la %r2,0x50(%r2) + la %r6,8(%r6) + bct 7,.Linit - lctl %c6,%c6,.Lcr6 # set IO subclass mask - slr %r2,%r2 + lctl %c6,%c6,.Lcr6 # set IO subclass mask + slr %r2,%r2 .Lldlp: - ssch 0(%r3) # load chunk of 1600 bytes - bnz .Llderr + ssch 0(%r3) # load chunk of 1600 bytes + bnz .Llderr .Lwait4irq: - mvc 0x78(8),.Lnewpsw # set up IO interrupt psw - lpsw .Lwaitpsw + mvc 0x78(8),.Lnewpsw # set up IO interrupt psw + lpsw .Lwaitpsw .Lioint: - c %r1,0xb8 # compare subchannel number - bne .Lwait4irq - tsch 0(%r5) + c %r1,0xb8 # compare subchannel number + bne .Lwait4irq + tsch 0(%r5) - slr %r0,%r0 - ic %r0,8(%r5) # get device status - chi %r0,8 # channel end ? - be .Lcont - chi %r0,12 # channel end + device end ? - be .Lcont + slr %r0,%r0 + ic %r0,8(%r5) # get device status + chi %r0,8 # channel end ? + be .Lcont + chi %r0,12 # channel end + device end ? + be .Lcont - l %r0,4(%r5) - s %r0,8(%r3) # r0/8 = number of ccws executed - mhi %r0,10 # *10 = number of bytes in ccws - lh %r3,10(%r5) # get residual count - sr %r0,%r3 # #ccws*80-residual=#bytes read - ar %r2,%r0 - - br %r14 # r2 contains the total size + l %r0,4(%r5) + s %r0,8(%r3) # r0/8 = number of ccws executed + mhi %r0,10 # *10 = number of bytes in ccws + lh %r3,10(%r5) # get residual count + sr %r0,%r3 # #ccws*80-residual=#bytes read + ar %r2,%r0 + + br %r14 # r2 contains the total size .Lcont: - ahi %r2,0x640 # add 0x640 to total size - la %r6,.Lccws - la %r7,20 + ahi %r2,0x640 # add 0x640 to total size + la %r6,.Lccws + la %r7,20 .Lincr: - l %r0,4(%r6) # update CCW data addresses - ahi %r0,0x640 - st %r0,4(%r6) - ahi %r6,8 - bct 7,.Lincr + l %r0,4(%r6) # update CCW data addresses + ahi %r0,0x640 + st %r0,4(%r6) + ahi %r6,8 + bct 7,.Lincr - b .Lldlp + b .Lldlp .Llderr: - lpsw .Lcrash + lpsw .Lcrash - .align 8 -.Lorb: .long 0x00000000,0x0080ff00,.Lccws -.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -.Lcr6: .long 0xff000000 -.Lloadp:.long 0,0 - .align 8 -.Lcrash:.long 0x000a0000,0x00000000 + .align 8 +.Lorb: .long 0x00000000,0x0080ff00,.Lccws +.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.Lcr6: .long 0xff000000 +.Lloadp:.long 0,0 + .align 8 +.Lcrash:.long 0x000a0000,0x00000000 .Lnewpsw: - .long 0x00080000,0x80000000+.Lioint + .long 0x00080000,0x80000000+.Lioint .Lwaitpsw: - .long 0x020a0000,0x80000000+.Lioint + .long 0x020a0000,0x80000000+.Lioint - .align 8 -.Lccws: .rept 19 - .long 0x02600050,0x00000000 - .endr - .long 0x02200050,0x00000000 -#endif /* CONFIG_IPL_VM */ + .align 8 +.Lccws: .rept 19 + .long 0x02600050,0x00000000 + .endr + .long 0x02200050,0x00000000 +#endif /* CONFIG_IPL_VM */ iplstart: - lh %r1,0xb8 # test if subchannel number - bct %r1,.Lnoload # is valid - l %r1,0xb8 # load ipl subchannel number - la %r2,IPL_BS # load start address - bas %r14,.Lloader # load rest of ipl image - l %r12,.Lparm # pointer to parameter area - st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number + lh %r1,0xb8 # test if subchannel number + bct %r1,.Lnoload # is valid + l %r1,0xb8 # load ipl subchannel number + la %r2,IPL_BS # load start address + bas %r14,.Lloader # load rest of ipl image + l %r12,.Lparm # pointer to parameter area + st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number # # load parameter file from ipl device # .Lagain1: - l %r2,.Linitrd # ramdisk loc. is temp - bas %r14,.Lloader # load parameter file - ltr %r2,%r2 # got anything ? - bz .Lnopf - chi %r2,895 - bnh .Lnotrunc - la %r2,895 + l %r2,.Linitrd # ramdisk loc. is temp + bas %r14,.Lloader # load parameter file + ltr %r2,%r2 # got anything ? + bz .Lnopf + chi %r2,895 + bnh .Lnotrunc + la %r2,895 .Lnotrunc: - l %r4,.Linitrd - clc 0(3,%r4),.L_hdr # if it is HDRx - bz .Lagain1 # skip dataset header - clc 0(3,%r4),.L_eof # if it is EOFx - bz .Lagain1 # skip dateset trailer - la %r5,0(%r4,%r2) - lr %r3,%r2 + l %r4,.Linitrd + clc 0(3,%r4),.L_hdr # if it is HDRx + bz .Lagain1 # skip dataset header + clc 0(3,%r4),.L_eof # if it is EOFx + bz .Lagain1 # skip dateset trailer + la %r5,0(%r4,%r2) + lr %r3,%r2 .Lidebc: - tm 0(%r5),0x80 # high order bit set ? - bo .Ldocv # yes -> convert from EBCDIC - ahi %r5,-1 - bct %r3,.Lidebc - b .Lnocv + tm 0(%r5),0x80 # high order bit set ? + bo .Ldocv # yes -> convert from EBCDIC + ahi %r5,-1 + bct %r3,.Lidebc + b .Lnocv .Ldocv: - l %r3,.Lcvtab - tr 0(256,%r4),0(%r3) # convert parameters to ascii - tr 256(256,%r4),0(%r3) - tr 512(256,%r4),0(%r3) - tr 768(122,%r4),0(%r3) -.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line - mvc 0(256,%r3),0(%r4) - mvc 256(256,%r3),256(%r4) - mvc 512(256,%r3),512(%r4) - mvc 768(122,%r3),768(%r4) - slr %r0,%r0 - b .Lcntlp + l %r3,.Lcvtab + tr 0(256,%r4),0(%r3) # convert parameters to ascii + tr 256(256,%r4),0(%r3) + tr 512(256,%r4),0(%r3) + tr 768(122,%r4),0(%r3) +.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line + mvc 0(256,%r3),0(%r4) + mvc 256(256,%r3),256(%r4) + mvc 512(256,%r3),512(%r4) + mvc 768(122,%r3),768(%r4) + slr %r0,%r0 + b .Lcntlp .Ldelspc: - ic %r0,0(%r2,%r3) - chi %r0,0x20 # is it a space ? - be .Lcntlp - ahi %r2,1 - b .Leolp + ic %r0,0(%r2,%r3) + chi %r0,0x20 # is it a space ? + be .Lcntlp + ahi %r2,1 + b .Leolp .Lcntlp: - brct %r2,.Ldelspc + brct %r2,.Ldelspc .Leolp: - slr %r0,%r0 - stc %r0,0(%r2,%r3) # terminate buffer + slr %r0,%r0 + stc %r0,0(%r2,%r3) # terminate buffer .Lnopf: # # load ramdisk from ipl device -# +# .Lagain2: - l %r2,.Linitrd # addr of ramdisk - st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) - bas %r14,.Lloader # load ramdisk - st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk - ltr %r2,%r2 - bnz .Lrdcont - st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found + l %r2,.Linitrd # addr of ramdisk + st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) + bas %r14,.Lloader # load ramdisk + st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd + ltr %r2,%r2 + bnz .Lrdcont + st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found .Lrdcont: - l %r2,.Linitrd + l %r2,.Linitrd - clc 0(3,%r2),.L_hdr # skip HDRx and EOFx - bz .Lagain2 - clc 0(3,%r2),.L_eof - bz .Lagain2 + clc 0(3,%r2),.L_hdr # skip HDRx and EOFx + bz .Lagain2 + clc 0(3,%r2),.L_eof + bz .Lagain2 #ifdef CONFIG_IPL_VM # # reset files in VM reader # - stidp __LC_CPUID # store cpuid - tm __LC_CPUID,0xff # running VM ? - bno .Lnoreset - la %r2,.Lreset - lhi %r3,26 - diag %r2,%r3,8 - la %r5,.Lirb - stsch 0(%r5) # check if irq is pending - tm 30(%r5),0x0f # by verifying if any of the - bnz .Lwaitforirq # activity or status control - tm 31(%r5),0xff # bits is set in the schib - bz .Lnoreset + stidp __LC_CPUID # store cpuid + tm __LC_CPUID,0xff # running VM ? + bno .Lnoreset + la %r2,.Lreset + lhi %r3,26 + diag %r2,%r3,8 + la %r5,.Lirb + stsch 0(%r5) # check if irq is pending + tm 30(%r5),0x0f # by verifying if any of the + bnz .Lwaitforirq # activity or status control + tm 31(%r5),0xff # bits is set in the schib + bz .Lnoreset .Lwaitforirq: - mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw + mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw .Lwaitrdrirq: - lpsw .Lrdrwaitpsw + lpsw .Lrdrwaitpsw .Lrdrint: - c %r1,0xb8 # compare subchannel number - bne .Lwaitrdrirq - la %r5,.Lirb - tsch 0(%r5) + c %r1,0xb8 # compare subchannel number + bne .Lwaitrdrirq + la %r5,.Lirb + tsch 0(%r5) .Lnoreset: - b .Lnoload + b .Lnoload - .align 8 + .align 8 .Lrdrnewpsw: - .long 0x00080000,0x80000000+.Lrdrint + .long 0x00080000,0x80000000+.Lrdrint .Lrdrwaitpsw: - .long 0x020a0000,0x80000000+.Lrdrint + .long 0x020a0000,0x80000000+.Lrdrint #endif # # everything loaded, go for it # .Lnoload: - l %r1,.Lstartup - br %r1 + l %r1,.Lstartup + br %r1 -.Linitrd:.long _end + 0x400000 # default address of initrd +.Linitrd:.long _end + 0x400000 # default address of initrd .Lparm: .long PARMAREA .Lstartup: .long startup -.Lcvtab:.long _ebcasc # ebcdic to ascii table -.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 - .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 - .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" -.L_eof: .long 0xc5d6c600 /* C'EOF' */ -.L_hdr: .long 0xc8c4d900 /* C'HDR' */ +.Lcvtab:.long _ebcasc # ebcdic to ascii table +.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 + .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 + .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" +.L_eof: .long 0xc5d6c600 /* C'EOF' */ +.L_hdr: .long 0xc8c4d900 /* C'HDR' */ -#endif /* CONFIG_IPL */ +#endif /* CONFIG_IPL */ # # SALIPL loader support. Based on a patch by Rob van der Heij. # This entry point is called directly from the SALIPL loader and # doesn't need a builtin ipl record. # - .org 0x800 - .globl start + .org 0x800 + .globl start start: - stm %r0,%r15,0x07b0 # store registers - basr %r12,%r0 + stm %r0,%r15,0x07b0 # store registers + basr %r12,%r0 .base: - l %r11,.parm - l %r8,.cmd # pointer to command buffer + l %r11,.parm + l %r8,.cmd # pointer to command buffer - ltr %r9,%r9 # do we have SALIPL parameters? - bp .sk8x8 + ltr %r9,%r9 # do we have SALIPL parameters? + bp .sk8x8 - mvc 0(64,%r8),0x00b0 # copy saved registers - xc 64(240-64,%r8),0(%r8) # remainder of buffer - tr 0(64,%r8),.lowcase - b .gotr + mvc 0(64,%r8),0x00b0 # copy saved registers + xc 64(240-64,%r8),0(%r8) # remainder of buffer + tr 0(64,%r8),.lowcase + b .gotr .sk8x8: - mvc 0(240,%r8),0(%r9) # copy iplparms into buffer + mvc 0(240,%r8),0(%r9) # copy iplparms into buffer .gotr: - l %r10,.tbl # EBCDIC to ASCII table - tr 0(240,%r8),0(%r10) - stidp __LC_CPUID # Are we running on VM maybe - cli __LC_CPUID,0xff - bnz .test - .long 0x83300060 # diag 3,0,x'0060' - storage size - b .done + l %r10,.tbl # EBCDIC to ASCII table + tr 0(240,%r8),0(%r10) + stidp __LC_CPUID # Are we running on VM maybe + cli __LC_CPUID,0xff + bnz .test + .long 0x83300060 # diag 3,0,x'0060' - storage size + b .done .test: - mvc 0x68(8),.pgmnw # set up pgm check handler - l %r2,.fourmeg - lr %r3,%r2 - bctr %r3,%r0 # 4M-1 -.loop: iske %r0,%r3 - ar %r3,%r2 + mvc 0x68(8),.pgmnw # set up pgm check handler + l %r2,.fourmeg + lr %r3,%r2 + bctr %r3,%r0 # 4M-1 +.loop: iske %r0,%r3 + ar %r3,%r2 .pgmx: - sr %r3,%r2 - la %r3,1(%r3) + sr %r3,%r2 + la %r3,1(%r3) .done: - l %r1,.memsize - st %r3,ARCH_OFFSET(%r1) - slr %r0,%r0 - st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11) - st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11) - j startup # continue with startup -.tbl: .long _ebcasc # translate table -.cmd: .long COMMAND_LINE # address of command line buffer -.parm: .long PARMAREA + l %r1,.memsize + st %r3,ARCH_OFFSET(%r1) + slr %r0,%r0 + st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11) + st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11) + j startup # continue with startup +.tbl: .long _ebcasc # translate table +.cmd: .long COMMAND_LINE # address of command line buffer +.parm: .long PARMAREA .memsize: .long memory_size .fourmeg: .long 0x00400000 # 4M -.pgmnw: .long 0x00080000,.pgmx +.pgmnw: .long 0x00080000,.pgmx .lowcase: - .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 + .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f - .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 + .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f - .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 + .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f - .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 + .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f - .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 + .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f - .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 + .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f - .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 + .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f - .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 + .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f - .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 + .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f - .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 + .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f - .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 + .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf - .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 + .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf - .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg + .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi - .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop + .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz - .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 + .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff #ifdef CONFIG_64BIT diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index a8bdd96494c..48998d50b00 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -15,232 +15,232 @@ # this is called either by the ipl loader or directly by PSW restart # or linload or SALIPL # - .org 0x10000 -startup:basr %r13,0 # get base -.LPG0: l %r13,0f-.LPG0(%r13) - b 0(%r13) -0: .long startup_continue + .org 0x10000 +startup:basr %r13,0 # get base +.LPG0: l %r13,0f-.LPG0(%r13) + b 0(%r13) +0: .long startup_continue # # params at 10400 (setup.h) # - .org PARMAREA - .quad 0 # IPL_DEVICE - .quad 0 # INITRD_START - .quad 0 # INITRD_SIZE + .org PARMAREA + .quad 0 # IPL_DEVICE + .quad 0 # INITRD_START + .quad 0 # INITRD_SIZE - .org COMMAND_LINE - .byte "root=/dev/ram0 ro" - .byte 0 + .org COMMAND_LINE + .byte "root=/dev/ram0 ro" + .byte 0 - .org 0x11000 + .org 0x11000 startup_continue: - basr %r13,0 # get base -.LPG1: sll %r13,1 # remove high order bit - srl %r13,1 - lhi %r1,1 # mode 1 = esame - mvi __LC_AR_MODE_ID,1 # set esame flag - slr %r0,%r0 # set cpuid to zero - sigp %r1,%r0,0x12 # switch to esame mode - sam64 # switch to 64 bit mode - lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area - # move IPL device to lowcore - mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) + basr %r13,0 # get base +.LPG1: sll %r13,1 # remove high order bit + srl %r13,1 + lhi %r1,1 # mode 1 = esame + mvi __LC_AR_MODE_ID,1 # set esame flag + slr %r0,%r0 # set cpuid to zero + sigp %r1,%r0,0x12 # switch to esame mode + sam64 # switch to 64 bit mode + lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers + lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area + # move IPL device to lowcore + mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) # # Setup stack # - larl %r15,init_thread_union - lg %r14,__TI_task(%r15) # cache current in lowcore - stg %r14,__LC_CURRENT - aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE - stg %r15,__LC_KERNEL_STACK # set end of kernel stack - aghi %r15,-160 - xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain + larl %r15,init_thread_union + lg %r14,__TI_task(%r15) # cache current in lowcore + stg %r14,__LC_CURRENT + aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE + stg %r15,__LC_KERNEL_STACK # set end of kernel stack + aghi %r15,-160 + xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain - brasl %r14,ipl_save_parameters + brasl %r14,ipl_save_parameters # # clear bss memory # - larl %r2,__bss_start # start of bss segment - larl %r3,_end # end of bss segment - sgr %r3,%r2 # length of bss - sgr %r4,%r4 # - sgr %r5,%r5 # set src,length and pad to zero - mvcle %r2,%r4,0 # clear mem - jo .-4 # branch back, if not finish + larl %r2,__bss_start # start of bss segment + larl %r3,_end # end of bss segment + sgr %r3,%r2 # length of bss + sgr %r4,%r4 # + sgr %r5,%r5 # set src,length and pad to zero + mvcle %r2,%r4,0 # clear mem + jo .-4 # branch back, if not finish - l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word + l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word .Lservicecall: - stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts + stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts - stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0 - la %r1,0x200 # set bit 22 - og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 - stg %r1,.Lcr-.LPG1(%r13) - lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0 + stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0 + la %r1,0x200 # set bit 22 + og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 + stg %r1,.Lcr-.LPG1(%r13) + lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0 - mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw - larl %r1,.Lsclph - stg %r1,__LC_EXT_NEW_PSW+8 # set handler + mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw + larl %r1,.Lsclph + stg %r1,__LC_EXT_NEW_PSW+8 # set handler - larl %r4,.Lsccb # %r4 is our index for sccb stuff - lgr %r1,%r4 # our sccb - .insn rre,0xb2200000,%r2,%r1 # service call - ipm %r1 - srl %r1,28 # get cc code - xr %r3,%r3 - chi %r1,3 - be .Lfchunk-.LPG1(%r13) # leave - chi %r1,2 - be .Lservicecall-.LPG1(%r13) - lpswe .Lwaitsclp-.LPG1(%r13) + larl %r4,.Lsccb # %r4 is our index for sccb stuff + lgr %r1,%r4 # our sccb + .insn rre,0xb2200000,%r2,%r1 # service call + ipm %r1 + srl %r1,28 # get cc code + xr %r3,%r3 + chi %r1,3 + be .Lfchunk-.LPG1(%r13) # leave + chi %r1,2 + be .Lservicecall-.LPG1(%r13) + lpswe .Lwaitsclp-.LPG1(%r13) .Lsclph: - lh %r1,.Lsccbr-.Lsccb(%r4) - chi %r1,0x10 # 0x0010 is the sucess code - je .Lprocsccb # let's process the sccb - chi %r1,0x1f0 - bne .Lfchunk-.LPG1(%r13) # unhandled error code - c %r2,.Lrcp-.LPG1(%r13) # Did we try Read SCP forced - bne .Lfchunk-.LPG1(%r13) # if no, give up - l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP - b .Lservicecall-.LPG1(%r13) + lh %r1,.Lsccbr-.Lsccb(%r4) + chi %r1,0x10 # 0x0010 is the sucess code + je .Lprocsccb # let's process the sccb + chi %r1,0x1f0 + bne .Lfchunk-.LPG1(%r13) # unhandled error code + c %r2,.Lrcp-.LPG1(%r13) # Did we try Read SCP forced + bne .Lfchunk-.LPG1(%r13) # if no, give up + l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP + b .Lservicecall-.LPG1(%r13) .Lprocsccb: - lghi %r1,0 - icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 - jnz .Lscnd - lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one + lghi %r1,0 + icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 + jnz .Lscnd + lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one .Lscnd: - xr %r3,%r3 # same logic - ic %r3,.Lscpa1-.Lsccb(%r4) - chi %r3,0x00 - jne .Lcompmem - l %r3,.Lscpa2-.Lsccb(%r4) + xr %r3,%r3 # same logic + ic %r3,.Lscpa1-.Lsccb(%r4) + chi %r3,0x00 + jne .Lcompmem + l %r3,.Lscpa2-.Lsccb(%r4) .Lcompmem: - mlgr %r2,%r1 # mem in MB on 128-bit - l %r1,.Lonemb-.LPG1(%r13) - mlgr %r2,%r1 # mem size in bytes in %r3 - b .Lfchunk-.LPG1(%r13) + mlgr %r2,%r1 # mem in MB on 128-bit + l %r1,.Lonemb-.LPG1(%r13) + mlgr %r2,%r1 # mem size in bytes in %r3 + b .Lfchunk-.LPG1(%r13) - .align 4 + .align 4 .Lpmask: - .byte 0 - .align 8 + .byte 0 + .align 8 .Lcr: - .quad 0x00 # place holder for cr0 + .quad 0x00 # place holder for cr0 .Lwaitsclp: - .quad 0x0102000180000000,.Lsclph + .quad 0x0102000180000000,.Lsclph .Lrcp: - .int 0x00120001 # Read SCP forced code + .int 0x00120001 # Read SCP forced code .Lrcp2: - .int 0x00020001 # Read SCP code + .int 0x00020001 # Read SCP code .Lonemb: - .int 0x100000 + .int 0x100000 .Lfchunk: - # set program check new psw mask - mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) + # set program check new psw mask + mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # # find memory chunks. # - lgr %r9,%r3 # end of mem - larl %r1,.Lchkmem # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - la %r1,1 # test in increments of 128KB - sllg %r1,%r1,17 - larl %r3,memory_chunk - slgr %r4,%r4 # set start of chunk to zero - slgr %r5,%r5 # set end of chunk to zero - slr %r6,%r6 # set access code to zero - la %r10,MEMORY_CHUNKS # number of chunks + lgr %r9,%r3 # end of mem + larl %r1,.Lchkmem # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 + la %r1,1 # test in increments of 128KB + sllg %r1,%r1,17 + larl %r3,memory_chunk + slgr %r4,%r4 # set start of chunk to zero + slgr %r5,%r5 # set end of chunk to zero + slr %r6,%r6 # set access code to zero + la %r10,MEMORY_CHUNKS # number of chunks .Lloop: - tprot 0(%r5),0 # test protection of first byte - ipm %r7 - srl %r7,28 - clr %r6,%r7 # compare cc with last access code - je .Lsame - j .Lchkmem + tprot 0(%r5),0 # test protection of first byte + ipm %r7 + srl %r7,28 + clr %r6,%r7 # compare cc with last access code + je .Lsame + j .Lchkmem .Lsame: - algr %r5,%r1 # add 128KB to end of chunk - # no need to check here, - brc 12,.Lloop # this is the same chunk -.Lchkmem: # > 16EB or tprot got a program check - clgr %r4,%r5 # chunk size > 0? - je .Lchkloop - stg %r4,0(%r3) # store start address of chunk - lgr %r0,%r5 - slgr %r0,%r4 - stg %r0,8(%r3) # store size of chunk - st %r6,20(%r3) # store type of chunk - la %r3,24(%r3) - larl %r8,memory_size - stg %r5,0(%r8) # store memory size - ahi %r10,-1 # update chunk number + algr %r5,%r1 # add 128KB to end of chunk + # no need to check here, + brc 12,.Lloop # this is the same chunk +.Lchkmem: # > 16EB or tprot got a program check + clgr %r4,%r5 # chunk size > 0? + je .Lchkloop + stg %r4,0(%r3) # store start address of chunk + lgr %r0,%r5 + slgr %r0,%r4 + stg %r0,8(%r3) # store size of chunk + st %r6,20(%r3) # store type of chunk + la %r3,24(%r3) + larl %r8,memory_size + stg %r5,0(%r8) # store memory size + ahi %r10,-1 # update chunk number .Lchkloop: - lr %r6,%r7 # set access code to last cc + lr %r6,%r7 # set access code to last cc # we got an exception or we're starting a new # chunk , we must check if we should # still try to find valid memory (if we detected # the amount of available storage), and if we # have chunks left - lghi %r4,1 - sllg %r4,%r4,31 - clgr %r5,%r4 - je .Lhsaskip - xr %r0, %r0 - clgr %r0, %r9 # did we detect memory? - je .Ldonemem # if not, leave - chi %r10, 0 # do we have chunks left? - je .Ldonemem + lghi %r4,1 + sllg %r4,%r4,31 + clgr %r5,%r4 + je .Lhsaskip + xr %r0, %r0 + clgr %r0, %r9 # did we detect memory? + je .Ldonemem # if not, leave + chi %r10, 0 # do we have chunks left? + je .Ldonemem .Lhsaskip: - algr %r5,%r1 # add 128KB to end of chunk - lgr %r4,%r5 # potential new chunk - clgr %r5,%r9 # should we go on? - jl .Lloop -.Ldonemem: + algr %r5,%r1 # add 128KB to end of chunk + lgr %r4,%r5 # potential new chunk + clgr %r5,%r9 # should we go on? + jl .Lloop +.Ldonemem: - larl %r12,machine_flags + larl %r12,machine_flags # # find out if we are running under VM # - stidp __LC_CPUID # store cpuid - tm __LC_CPUID,0xff # running under VM ? - bno 0f-.LPG1(%r13) - oi 7(%r12),1 # set VM flag -0: lh %r0,__LC_CPUID+4 # get cpu version - chi %r0,0x7490 # running on a P/390 ? - bne 1f-.LPG1(%r13) - oi 7(%r12),4 # set P/390 flag + stidp __LC_CPUID # store cpuid + tm __LC_CPUID,0xff # running under VM ? + bno 0f-.LPG1(%r13) + oi 7(%r12),1 # set VM flag +0: lh %r0,__LC_CPUID+4 # get cpu version + chi %r0,0x7490 # running on a P/390 ? + bne 1f-.LPG1(%r13) + oi 7(%r12),4 # set P/390 flag 1: # # find out if we have the MVPG instruction # - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - sgr %r0,%r0 - lghi %r1,0 - lghi %r2,0 - mvpg %r1,%r2 # test MVPG instruction - oi 7(%r12),16 # set MVPG flag + la %r1,0f-.LPG1(%r13) # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 + sgr %r0,%r0 + lghi %r1,0 + lghi %r2,0 + mvpg %r1,%r2 # test MVPG instruction + oi 7(%r12),16 # set MVPG flag 0: # # find out if the diag 0x44 works in 64 bit mode # - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - diag 0,0,0x44 # test diag 0x44 - oi 7(%r12),32 # set diag44 flag -0: + la %r1,0f-.LPG1(%r13) # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 + diag 0,0,0x44 # test diag 0x44 + oi 7(%r12),32 # set diag44 flag +0: # # find out if we have the IDTE instruction # - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 + la %r1,0f-.LPG1(%r13) # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 .long 0xb2b10000 # store facility list tm 0xc8,0x08 # check bit for clearing-by-ASCE bno 0f-.LPG1(%r13) @@ -263,45 +263,45 @@ startup_continue: oi 6(%r12),2 # set MVCOS flag 1: - lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, - # virtual and never return ... - .align 16 -.Lentry:.quad 0x0000000180000000,_stext -.Lctl: .quad 0x04b50002 # cr0: various things - .quad 0 # cr1: primary space segment table - .quad .Lduct # cr2: dispatchable unit control table - .quad 0 # cr3: instruction authorization - .quad 0 # cr4: instruction authorization - .quad 0xffffffffffffffff # cr5: primary-aste origin - .quad 0 # cr6: I/O interrupts - .quad 0 # cr7: secondary space segment table - .quad 0 # cr8: access registers translation - .quad 0 # cr9: tracing off - .quad 0 # cr10: tracing off - .quad 0 # cr11: tracing off - .quad 0 # cr12: tracing off - .quad 0 # cr13: home space segment table - .quad 0xc0000000 # cr14: machine check handling off - .quad 0 # cr15: linkage stack operations -.Lduct: .long 0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0 -.Lpcmsk:.quad 0x0000000180000000 + lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, + # virtual and never return ... + .align 16 +.Lentry:.quad 0x0000000180000000,_stext +.Lctl: .quad 0x04b50002 # cr0: various things + .quad 0 # cr1: primary space segment table + .quad .Lduct # cr2: dispatchable unit control table + .quad 0 # cr3: instruction authorization + .quad 0 # cr4: instruction authorization + .quad 0xffffffffffffffff # cr5: primary-aste origin + .quad 0 # cr6: I/O interrupts + .quad 0 # cr7: secondary space segment table + .quad 0 # cr8: access registers translation + .quad 0 # cr9: tracing off + .quad 0 # cr10: tracing off + .quad 0 # cr11: tracing off + .quad 0 # cr12: tracing off + .quad 0 # cr13: home space segment table + .quad 0xc0000000 # cr14: machine check handling off + .quad 0 # cr15: linkage stack operations +.Lduct: .long 0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0 +.Lpcmsk:.quad 0x0000000180000000 .L4malign:.quad 0xffffffffffc00000 -.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 -.Lnop: .long 0x07000700 +.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 +.Lnop: .long 0x07000700 .Lparmaddr: .quad PARMAREA - .globl ipl_schib + .globl ipl_schib ipl_schib: .rept 13 .long 0 .endr - .globl ipl_flags + .globl ipl_flags ipl_flags: - .long 0 - .globl ipl_devno + .long 0 + .globl ipl_devno ipl_devno: .word 0 @@ -309,47 +309,47 @@ ipl_devno: .globl s390_readinfo_sccb s390_readinfo_sccb: .Lsccb: - .hword 0x1000 # length, one page - .byte 0x00,0x00,0x00 - .byte 0x80 # variable response bit set + .hword 0x1000 # length, one page + .byte 0x00,0x00,0x00 + .byte 0x80 # variable response bit set .Lsccbr: - .hword 0x00 # response code + .hword 0x00 # response code .Lscpincr1: - .hword 0x00 + .hword 0x00 .Lscpa1: - .byte 0x00 - .fill 89,1,0 + .byte 0x00 + .fill 89,1,0 .Lscpa2: - .int 0x00 + .int 0x00 .Lscpincr2: - .quad 0x00 - .fill 3984,1,0 + .quad 0x00 + .fill 3984,1,0 .org 0x13000 #ifdef CONFIG_SHARED_KERNEL - .org 0x100000 + .org 0x100000 #endif - + # # startup-code, running in absolute addressing mode # - .globl _stext -_stext: basr %r13,0 # get base + .globl _stext +_stext: basr %r13,0 # get base .LPG3: # check control registers - stctg %c0,%c15,0(%r15) - oi 6(%r15),0x40 # enable sigp emergency signal - oi 4(%r15),0x10 # switch on low address proctection - lctlg %c0,%c15,0(%r15) + stctg %c0,%c15,0(%r15) + oi 6(%r15),0x40 # enable sigp emergency signal + oi 4(%r15),0x10 # switch on low address proctection + lctlg %c0,%c15,0(%r15) - lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess - brasl %r14,start_kernel # go to C code + lam 0,15,.Laregs-.LPG3(%r13) # load acrs needed by uaccess + brasl %r14,start_kernel # go to C code # # We returned from start_kernel ?!? PANIK # - basr %r13,0 - lpswe .Ldw-.(%r13) # load disabled wait psw + basr %r13,0 + lpswe .Ldw-.(%r13) # load disabled wait psw - .align 8 -.Ldw: .quad 0x0002000180000000,0x0000000000000000 -.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .align 8 +.Ldw: .quad 0x0002000180000000,0x0000000000000000 +.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 6555cc48e28..1f5e782b3d0 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -120,24 +120,15 @@ static enum shutdown_action on_panic_action = SHUTDOWN_STOP; static int diag308(unsigned long subcode, void *addr) { - register unsigned long _addr asm("0") = (unsigned long)addr; + register unsigned long _addr asm("0") = (unsigned long) addr; register unsigned long _rc asm("1") = 0; - asm volatile ( - " diag %0,%2,0x308\n" - "0: \n" - ".section __ex_table,\"a\"\n" -#ifdef CONFIG_64BIT - " .align 8\n" - " .quad 0b, 0b\n" -#else - " .align 4\n" - " .long 0b, 0b\n" -#endif - ".previous\n" + asm volatile( + " diag %0,%2,0x308\n" + "0:\n" + EX_TABLE(0b,0b) : "+d" (_addr), "+d" (_rc) - : "d" (subcode) : "cc", "memory" ); - + : "d" (subcode) : "cc", "memory"); return _rc; } diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index d3cbfa3005e..6603fbb41d0 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -45,7 +45,7 @@ #include <asm/irq.h> #include <asm/timer.h> -asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); +asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); /* * Return saved PC of a blocked thread. used in kernel/sched. @@ -177,7 +177,8 @@ void show_regs(struct pt_regs *regs) extern void kernel_thread_starter(void); -__asm__(".align 4\n" +asm( + ".align 4\n" "kernel_thread_starter:\n" " la 2,0(10)\n" " basr 14,9\n" diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index 4562cdbce8e..0340477f3b0 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -32,58 +32,58 @@ do_reipl_asm: basr %r13,0 st %r13, __LC_PSW_SAVE_AREA+4 lctl %c6,%c6,.Lall-.Lpg0(%r13) - lr %r1,%r2 - mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13) - stsch .Lschib-.Lpg0(%r13) - oi .Lschib+5-.Lpg0(%r13),0x84 -.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 - msch .Lschib-.Lpg0(%r13) - lhi %r0,5 -.Lssch: ssch .Liplorb-.Lpg0(%r13) + lr %r1,%r2 + mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13) + stsch .Lschib-.Lpg0(%r13) + oi .Lschib+5-.Lpg0(%r13),0x84 +.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 + msch .Lschib-.Lpg0(%r13) + lhi %r0,5 +.Lssch: ssch .Liplorb-.Lpg0(%r13) jz .L001 - brct %r0,.Lssch + brct %r0,.Lssch bas %r14,.Ldisab-.Lpg0(%r13) -.L001: mvc __LC_IO_NEW_PSW(8),.Lionew-.Lpg0(%r13) -.Ltpi: lpsw .Lwaitpsw-.Lpg0(%r13) +.L001: mvc __LC_IO_NEW_PSW(8),.Lionew-.Lpg0(%r13) +.Ltpi: lpsw .Lwaitpsw-.Lpg0(%r13) .Lcont: c %r1,__LC_SUBCHANNEL_ID jnz .Ltpi clc __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13) jnz .Ltpi - tsch .Liplirb-.Lpg0(%r13) + tsch .Liplirb-.Lpg0(%r13) tm .Liplirb+9-.Lpg0(%r13),0xbf - jz .L002 - bas %r14,.Ldisab-.Lpg0(%r13) -.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 - jz .L003 - bas %r14,.Ldisab-.Lpg0(%r13) + jz .L002 + bas %r14,.Ldisab-.Lpg0(%r13) +.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 + jz .L003 + bas %r14,.Ldisab-.Lpg0(%r13) .L003: spx .Lnull-.Lpg0(%r13) - st %r1,__LC_SUBCHANNEL_ID - lpsw 0 - sigp 0,0,0(6) -.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) + st %r1,__LC_SUBCHANNEL_ID + lpsw 0 + sigp 0,0,0(6) +.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) lpsw .Ldispsw-.Lpg0(%r13) - .align 8 + .align 8 .Lclkcmp: .quad 0x0000000000000000 .Lall: .long 0xff000000 -.Lnull: .long 0x00000000 +.Lnull: .long 0x00000000 .Lctlsave1: .long 0x00000000 .Lctlsave2: .long 0x00000000 - .align 8 -.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 -.Lpcnew: .long 0x00080000,0x80000000+.Lecs -.Lionew: .long 0x00080000,0x80000000+.Lcont + .align 8 +.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 +.Lpcnew: .long 0x00080000,0x80000000+.Lecs +.Lionew: .long 0x00080000,0x80000000+.Lcont .Lwaitpsw: .long 0x020a0000,0x00000000+.Ltpi -.Ldispsw: .long 0x000a0000,0x00000000 -.Liplccws: .long 0x02000000,0x60000018 - .long 0x08000008,0x20000001 +.Ldispsw: .long 0x000a0000,0x00000000 +.Liplccws: .long 0x02000000,0x60000018 + .long 0x08000008,0x20000001 .Liplorb: .long 0x0049504c,0x0040ff80 .long 0x00000000+.Liplccws -.Lschib: .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 +.Lschib: .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 .Liplirb: .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 @@ -92,6 +92,3 @@ do_reipl_asm: basr %r13,0 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 - - - diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S index 95bd1e234f6..de7435054f7 100644 --- a/arch/s390/kernel/reipl64.S +++ b/arch/s390/kernel/reipl64.S @@ -4,7 +4,7 @@ * S390 version * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com) - Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) + Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) */ #include <asm/lowcore.h> @@ -32,46 +32,46 @@ do_reipl_asm: basr %r13,0 stctg %c0,%c0,.Lregsave-.Lpg0(%r13) ni .Lregsave+4-.Lpg0(%r13),0xef lctlg %c0,%c0,.Lregsave-.Lpg0(%r13) - lgr %r1,%r2 - mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) - stsch .Lschib-.Lpg0(%r13) - oi .Lschib+5-.Lpg0(%r13),0x84 -.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 - msch .Lschib-.Lpg0(%r13) - lghi %r0,5 -.Lssch: ssch .Liplorb-.Lpg0(%r13) + lgr %r1,%r2 + mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) + stsch .Lschib-.Lpg0(%r13) + oi .Lschib+5-.Lpg0(%r13),0x84 +.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 + msch .Lschib-.Lpg0(%r13) + lghi %r0,5 +.Lssch: ssch .Liplorb-.Lpg0(%r13) jz .L001 - brct %r0,.Lssch + brct %r0,.Lssch bas %r14,.Ldisab-.Lpg0(%r13) -.L001: mvc __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13) -.Ltpi: lpswe .Lwaitpsw-.Lpg0(%r13) +.L001: mvc __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13) +.Ltpi: lpswe .Lwaitpsw-.Lpg0(%r13) .Lcont: c %r1,__LC_SUBCHANNEL_ID jnz .Ltpi clc __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13) jnz .Ltpi - tsch .Liplirb-.Lpg0(%r13) + tsch .Liplirb-.Lpg0(%r13) tm .Liplirb+9-.Lpg0(%r13),0xbf - jz .L002 - bas %r14,.Ldisab-.Lpg0(%r13) -.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 - jz .L003 - bas %r14,.Ldisab-.Lpg0(%r13) + jz .L002 + bas %r14,.Ldisab-.Lpg0(%r13) +.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 + jz .L003 + bas %r14,.Ldisab-.Lpg0(%r13) .L003: spx .Lnull-.Lpg0(%r13) - st %r1,__LC_SUBCHANNEL_ID - lhi %r1,0 # mode 0 = esa - slr %r0,%r0 # set cpuid to zero - sigp %r1,%r0,0x12 # switch to esa mode - lpsw 0 -.Ldisab: sll %r14,1 - srl %r14,1 # need to kill hi bit to avoid specification exceptions. - st %r14,.Ldispsw+12-.Lpg0(%r13) + st %r1,__LC_SUBCHANNEL_ID + lhi %r1,0 # mode 0 = esa + slr %r0,%r0 # set cpuid to zero + sigp %r1,%r0,0x12 # switch to esa mode + lpsw 0 +.Ldisab: sll %r14,1 + srl %r14,1 # need to kill hi bit to avoid specification exceptions. + st %r14,.Ldispsw+12-.Lpg0(%r13) lpswe .Ldispsw-.Lpg0(%r13) - .align 8 + .align 8 .Lclkcmp: .quad 0x0000000000000000 .Lall: .quad 0x00000000ff000000 .Lregsave: .quad 0x0000000000000000 -.Lnull: .long 0x0000000000000000 - .align 16 +.Lnull: .long 0x0000000000000000 + .align 16 /* * These addresses have to be 31 bit otherwise * the sigp will throw a specifcation exception @@ -81,26 +81,26 @@ do_reipl_asm: basr %r13,0 * 31bit lpswe instruction a fact they appear to have * ommited from the pop. */ -.Lnewpsw: .quad 0x0000000080000000 - .quad .Lpg1 -.Lpcnew: .quad 0x0000000080000000 - .quad .Lecs -.Lionew: .quad 0x0000000080000000 - .quad .Lcont +.Lnewpsw: .quad 0x0000000080000000 + .quad .Lpg1 +.Lpcnew: .quad 0x0000000080000000 + .quad .Lecs +.Lionew: .quad 0x0000000080000000 + .quad .Lcont .Lwaitpsw: .quad 0x0202000080000000 - .quad .Ltpi -.Ldispsw: .quad 0x0002000080000000 - .quad 0x0000000000000000 -.Liplccws: .long 0x02000000,0x60000018 - .long 0x08000008,0x20000001 + .quad .Ltpi +.Ldispsw: .quad 0x0002000080000000 + .quad 0x0000000000000000 +.Liplccws: .long 0x02000000,0x60000018 + .long 0x08000008,0x20000001 .Liplorb: .long 0x0049504c,0x0040ff80 .long 0x00000000+.Liplccws -.Lschib: .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 +.Lschib: .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 .Liplirb: .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 @@ -109,4 +109,3 @@ do_reipl_asm: basr %r13,0 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 - diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S index 2a25ec7147f..f9899ff2e5b 100644 --- a/arch/s390/kernel/relocate_kernel.S +++ b/arch/s390/kernel/relocate_kernel.S @@ -3,7 +3,7 @@ * * (C) Copyright IBM Corp. 2005 * - * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> + * Author(s): Rolf Adelsberger, * Heiko Carstens <heiko.carstens@de.ibm.com> * */ @@ -24,14 +24,14 @@ .text .globl relocate_kernel relocate_kernel: - basr %r13,0 #base address + basr %r13,0 # base address .base: - stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) - spx zero64-.base(%r13) #absolute addressing mode + stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQ (external) + spx zero64-.base(%r13) # absolute addressing mode stctl %c0,%c15,ctlregs-.base(%r13) stm %r0,%r15,gprregs-.base(%r13) la %r1,load_psw-.base(%r13) - mvc 0(8,%r0),0(%r1) + mvc 0(8,%r0),0(%r1) la %r0,.back-.base(%r13) st %r0,4(%r0) oi 4(%r0),0x80 @@ -51,50 +51,50 @@ .back_pgm: lm %r0,%r15,gprregs-.base(%r13) .start_reloc: - lhi %r10,-1 #preparing the mask - sll %r10,12 #shift it such that it becomes 0xf000 + lhi %r10,-1 # preparing the mask + sll %r10,12 # shift it such that it becomes 0xf000 .top: - lhi %r7,4096 #load PAGE_SIZE in r7 - lhi %r9,4096 #load PAGE_SIZE in r9 - l %r5,0(%r2) #read another word for indirection page - ahi %r2,4 #increment pointer - tml %r5,0x1 #is it a destination page? - je .indir_check #NO, goto "indir_check" - lr %r6,%r5 #r6 = r5 - nr %r6,%r10 #mask it out and... - j .top #...next iteration + lhi %r7,4096 # load PAGE_SIZE in r7 + lhi %r9,4096 # load PAGE_SIZE in r9 + l %r5,0(%r2) # read another word for indirection page + ahi %r2,4 # increment pointer + tml %r5,0x1 # is it a destination page? + je .indir_check # NO, goto "indir_check" + lr %r6,%r5 # r6 = r5 + nr %r6,%r10 # mask it out and... + j .top # ...next iteration .indir_check: - tml %r5,0x2 #is it a indirection page? - je .done_test #NO, goto "done_test" - nr %r5,%r10 #YES, mask out, - lr %r2,%r5 #move it into the right register, - j .top #and read next... + tml %r5,0x2 # is it a indirection page? + je .done_test # NO, goto "done_test" + nr %r5,%r10 # YES, mask out, + lr %r2,%r5 # move it into the right register, + j .top # and read next... .done_test: - tml %r5,0x4 #is it the done indicator? - je .source_test #NO! Well, then it should be the source indicator... - j .done #ok, lets finish it here... + tml %r5,0x4 # is it the done indicator? + je .source_test # NO! Well, then it should be the source indicator... + j .done # ok, lets finish it here... .source_test: - tml %r5,0x8 #it should be a source indicator... - je .top #NO, ignore it... - lr %r8,%r5 #r8 = r5 - nr %r8,%r10 #masking - 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 + tml %r5,0x8 # it should be a source indicator... + je .top # NO, ignore it... + lr %r8,%r5 # r8 = r5 + nr %r8,%r10 # masking + 0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0 jo 0b j .top .done: - sr %r0,%r0 #clear register r0 - la %r4,load_psw-.base(%r13) #load psw-address into the register - o %r3,4(%r4) #or load address into psw + sr %r0,%r0 # clear register r0 + la %r4,load_psw-.base(%r13) # load psw-address into the register + o %r3,4(%r4) # or load address into psw st %r3,4(%r4) - mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 + mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0 tm have_diag308-.base(%r13),0x01 jno .no_diag308 diag %r0,%r0,0x308 .no_diag308: - sr %r1,%r1 #clear %r1 - sr %r2,%r2 #clear %r2 - sigp %r1,%r2,0x12 #set cpuid to zero - lpsw 0 #hopefully start new kernel... + sr %r1,%r1 # clear %r1 + sr %r2,%r2 # clear %r2 + sigp %r1,%r2,0x12 # set cpuid to zero + lpsw 0 # hopefully start new kernel... .align 8 zero64: diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S index 8cdb86e8911..4fb443042d9 100644 --- a/arch/s390/kernel/relocate_kernel64.S +++ b/arch/s390/kernel/relocate_kernel64.S @@ -3,7 +3,7 @@ * * (C) Copyright IBM Corp. 2005 * - * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> + * Author(s): Rolf Adelsberger, * Heiko Carstens <heiko.carstens@de.ibm.com> * */ @@ -25,10 +25,10 @@ .text .globl relocate_kernel relocate_kernel: - basr %r13,0 #base address + basr %r13,0 # base address .base: - stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQs - spx zero64-.base(%r13) #absolute addressing mode + stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQs + spx zero64-.base(%r13) # absolute addressing mode stctg %c0,%c15,ctlregs-.base(%r13) stmg %r0,%r15,gprregs-.base(%r13) lghi %r0,3 @@ -37,16 +37,16 @@ la %r0,.back_pgm-.base(%r13) stg %r0,0x1d8(%r0) la %r1,load_psw-.base(%r13) - mvc 0(8,%r0),0(%r1) + mvc 0(8,%r0),0(%r1) la %r0,.back-.base(%r13) st %r0,4(%r0) oi 4(%r0),0x80 lghi %r0,0 diag %r0,%r0,0x308 .back: - lhi %r1,1 #mode 1 = esame - sigp %r1,%r0,0x12 #switch to esame mode - sam64 #switch to 64 bit addressing mode + lhi %r1,1 # mode 1 = esame + sigp %r1,%r0,0x12 # switch to esame mode + sam64 # switch to 64 bit addressing mode basr %r13,0 .back_base: oi have_diag308-.back_base(%r13),0x01 @@ -56,50 +56,50 @@ .back_pgm: lmg %r0,%r15,gprregs-.base(%r13) .top: - lghi %r7,4096 #load PAGE_SIZE in r7 - lghi %r9,4096 #load PAGE_SIZE in r9 - lg %r5,0(%r2) #read another word for indirection page - aghi %r2,8 #increment pointer - tml %r5,0x1 #is it a destination page? - je .indir_check #NO, goto "indir_check" - lgr %r6,%r5 #r6 = r5 - nill %r6,0xf000 #mask it out and... - j .top #...next iteration + lghi %r7,4096 # load PAGE_SIZE in r7 + lghi %r9,4096 # load PAGE_SIZE in r9 + lg %r5,0(%r2) # read another word for indirection page + aghi %r2,8 # increment pointer + tml %r5,0x1 # is it a destination page? + je .indir_check # NO, goto "indir_check" + lgr %r6,%r5 # r6 = r5 + nill %r6,0xf000 # mask it out and... + j .top # ...next iteration .indir_check: - tml %r5,0x2 #is it a indirection page? - je .done_test #NO, goto "done_test" - nill %r5,0xf000 #YES, mask out, - lgr %r2,%r5 #move it into the right register, - j .top #and read next... + tml %r5,0x2 # is it a indirection page? + je .done_test # NO, goto "done_test" + nill %r5,0xf000 # YES, mask out, + lgr %r2,%r5 # move it into the right register, + j .top # and read next... .done_test: - tml %r5,0x4 #is it the done indicator? - je .source_test #NO! Well, then it should be the source indicator... - j .done #ok, lets finish it here... + tml %r5,0x4 # is it the done indicator? + je .source_test # NO! Well, then it should be the source indicator... + j .done # ok, lets finish it here... .source_test: - tml %r5,0x8 #it should be a source indicator... - je .top #NO, ignore it... - lgr %r8,%r5 #r8 = r5 - nill %r8,0xf000 #masking - 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 + tml %r5,0x8 # it should be a source indicator... + je .top # NO, ignore it... + lgr %r8,%r5 # r8 = r5 + nill %r8,0xf000 # masking + 0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0 jo 0b - j .top + j .top .done: - sgr %r0,%r0 #clear register r0 - la %r4,load_psw-.base(%r13) #load psw-address into the register - o %r3,4(%r4) #or load address into psw + sgr %r0,%r0 # clear register r0 + la %r4,load_psw-.base(%r13) # load psw-address into the register + o %r3,4(%r4) # or load address into psw st %r3,4(%r4) - mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 + mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0 tm have_diag308-.base(%r13),0x01 jno .no_diag308 diag %r0,%r0,0x308 .no_diag308: - sam31 #31 bit mode - sr %r1,%r1 #erase register r1 - sr %r2,%r2 #erase register r2 - sigp %r1,%r2,0x12 #set cpuid to zero - lpsw 0 #hopefully start new kernel... + sam31 # 31 bit mode + sr %r1,%r1 # erase register r1 + sr %r2,%r2 # erase register r2 + sigp %r1,%r2,0x12 # set cpuid to zero + lpsw 0 # hopefully start new kernel... - .align 8 + .align 8 zero64: .quad 0 load_psw: diff --git a/arch/s390/kernel/semaphore.c b/arch/s390/kernel/semaphore.c index 8dfb690c159..191303f6c1d 100644 --- a/arch/s390/kernel/semaphore.c +++ b/arch/s390/kernel/semaphore.c @@ -26,17 +26,17 @@ static inline int __sem_update_count(struct semaphore *sem, int incr) { int old_val, new_val; - __asm__ __volatile__(" l %0,0(%3)\n" - "0: ltr %1,%0\n" - " jhe 1f\n" - " lhi %1,0\n" - "1: ar %1,%4\n" - " cs %0,%1,0(%3)\n" - " jl 0b\n" - : "=&d" (old_val), "=&d" (new_val), - "=m" (sem->count) - : "a" (&sem->count), "d" (incr), "m" (sem->count) - : "cc" ); + asm volatile( + " l %0,0(%3)\n" + "0: ltr %1,%0\n" + " jhe 1f\n" + " lhi %1,0\n" + "1: ar %1,%4\n" + " cs %0,%1,0(%3)\n" + " jl 0b\n" + : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count) + : "a" (&sem->count), "d" (incr), "m" (sem->count) + : "cc"); return old_val; } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index e3d9325f602..a21cfbb9d97 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -101,7 +101,7 @@ void __devinit cpu_init (void) /* * Store processor id in lowcore (used e.g. in timer_interrupt) */ - asm volatile ("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); + asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); S390_lowcore.cpu_data.cpu_addr = addr; /* diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b2e6f4c8d38..a8e6199755d 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -63,7 +63,7 @@ static void smp_ext_bitcall(int, ec_bit_sig); static void smp_ext_bitcall_others(ec_bit_sig); /* - * Structure and data for smp_call_function(). This is designed to minimise +5B * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. */ static DEFINE_SPINLOCK(call_lock); @@ -418,59 +418,49 @@ void smp_send_reschedule(int cpu) /* * parameter area for the set/clear control bit callbacks */ -typedef struct -{ - __u16 start_ctl; - __u16 end_ctl; +struct ec_creg_mask_parms { unsigned long orvals[16]; unsigned long andvals[16]; -} ec_creg_mask_parms; +}; /* * callback for setting/clearing control bits */ void smp_ctl_bit_callback(void *info) { - ec_creg_mask_parms *pp; + struct ec_creg_mask_parms *pp = info; unsigned long cregs[16]; int i; - pp = (ec_creg_mask_parms *) info; - __ctl_store(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl); - for (i = pp->start_ctl; i <= pp->end_ctl; i++) + __ctl_store(cregs, 0, 15); + for (i = 0; i <= 15; i++) cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i]; - __ctl_load(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl); + __ctl_load(cregs, 0, 15); } /* * Set a bit in a control register of all cpus */ -void smp_ctl_set_bit(int cr, int bit) { - ec_creg_mask_parms parms; +void smp_ctl_set_bit(int cr, int bit) +{ + struct ec_creg_mask_parms parms; - parms.start_ctl = cr; - parms.end_ctl = cr; + memset(&parms.orvals, 0, sizeof(parms.orvals)); + memset(&parms.andvals, 0xff, sizeof(parms.andvals)); parms.orvals[cr] = 1 << bit; - parms.andvals[cr] = -1L; - preempt_disable(); - smp_call_function(smp_ctl_bit_callback, &parms, 0, 1); - __ctl_set_bit(cr, bit); - preempt_enable(); + on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); } /* * Clear a bit in a control register of all cpus */ -void smp_ctl_clear_bit(int cr, int bit) { - ec_creg_mask_parms parms; +void smp_ctl_clear_bit(int cr, int bit) +{ + struct ec_creg_mask_parms parms; - parms.start_ctl = cr; - parms.end_ctl = cr; - parms.orvals[cr] = 0; + memset(&parms.orvals, 0, sizeof(parms.orvals)); + memset(&parms.andvals, 0xff, sizeof(parms.andvals)); parms.andvals[cr] = ~(1L << bit); - preempt_disable(); - smp_call_function(smp_ctl_bit_callback, &parms, 0, 1); - __ctl_clear_bit(cr, bit); - preempt_enable(); + on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); } /* @@ -650,9 +640,9 @@ __cpu_up(unsigned int cpu) sf->gprs[9] = (unsigned long) sf; cpu_lowcore->save_area[15] = (unsigned long) sf; __ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15); - __asm__ __volatile__("stam 0,15,0(%0)" - : : "a" (&cpu_lowcore->access_regs_save_area) - : "memory"); + asm volatile( + " stam 0,15,0(%0)" + : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; cpu_lowcore->current_task = (unsigned long) idle; cpu_lowcore->cpu_data.cpu_nr = cpu; @@ -708,7 +698,7 @@ int __cpu_disable(void) { unsigned long flags; - ec_creg_mask_parms cr_parms; + struct ec_creg_mask_parms cr_parms; int cpu = smp_processor_id(); spin_lock_irqsave(&smp_reserve_lock, flags); @@ -724,30 +714,21 @@ __cpu_disable(void) pfault_fini(); #endif - /* disable all external interrupts */ + memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals)); + memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals)); - cr_parms.start_ctl = 0; - cr_parms.end_ctl = 0; + /* disable all external interrupts */ cr_parms.orvals[0] = 0; cr_parms.andvals[0] = ~(1<<15 | 1<<14 | 1<<13 | 1<<12 | 1<<11 | 1<<10 | 1<< 6 | 1<< 4); - smp_ctl_bit_callback(&cr_parms); - /* disable all I/O interrupts */ - - cr_parms.start_ctl = 6; - cr_parms.end_ctl = 6; cr_parms.orvals[6] = 0; cr_parms.andvals[6] = ~(1<<31 | 1<<30 | 1<<29 | 1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24); - smp_ctl_bit_callback(&cr_parms); - /* disable most machine checks */ - - cr_parms.start_ctl = 14; - cr_parms.end_ctl = 14; cr_parms.orvals[14] = 0; cr_parms.andvals[14] = ~(1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24); + smp_ctl_bit_callback(&cr_parms); spin_unlock_irqrestore(&smp_reserve_lock, flags); diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 74e6178fbaf..1981c6199fa 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -351,10 +351,12 @@ void __init time_init(void) int cc; /* kick the TOD clock */ - asm volatile ("STCK 0(%1)\n\t" - "IPM %0\n\t" - "SRL %0,28" : "=r" (cc) : "a" (&init_timer_cc) - : "memory", "cc"); + asm volatile( + " stck 0(%2)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (cc), "=m" (init_timer_cc) + : "a" (&init_timer_cc) : "cc"); switch (cc) { case 0: /* clock in set state: all is fine */ break; diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index c4982c96342..3eb4fab048b 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -597,8 +597,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) local_irq_enable(); if (MACHINE_HAS_IEEE) - __asm__ volatile ("stfpc %0\n\t" - : "=m" (current->thread.fp_regs.fpc)); + asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); #ifdef CONFIG_MATHEMU else if (regs->psw.mask & PSW_MASK_PSTATE) { diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index c42ffedfdb4..b0cfa6c4883 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -5,5 +5,6 @@ EXTRA_AFLAGS := -traditional lib-y += delay.o string.o uaccess_std.o +lib-$(CONFIG_32BIT) += div64.o lib-$(CONFIG_64BIT) += uaccess_mvcos.o lib-$(CONFIG_SMP) += spinlock.o diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 468f4ea33f9..027c4742a00 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -27,9 +27,7 @@ void __delay(unsigned long loops) * yield the megahertz number of the cpu. The important function * is udelay and that is done using the tod clock. -- martin. */ - __asm__ __volatile__( - "0: brct %0,0b" - : /* no outputs */ : "r" ((loops/2) + 1)); + asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); } /* @@ -38,13 +36,12 @@ void __delay(unsigned long loops) */ void __udelay(unsigned long usecs) { - uint64_t start_cc, end_cc; + uint64_t start_cc; if (usecs == 0) return; - asm volatile ("STCK %0" : "=m" (start_cc)); + start_cc = get_clock(); do { cpu_relax(); - asm volatile ("STCK %0" : "=m" (end_cc)); - } while (((end_cc - start_cc)/4096) < usecs); + } while (((get_clock() - start_cc)/4096) < usecs); } diff --git a/arch/s390/lib/div64.c b/arch/s390/lib/div64.c new file mode 100644 index 00000000000..0481f3424a1 --- /dev/null +++ b/arch/s390/lib/div64.c @@ -0,0 +1,151 @@ +/* + * arch/s390/lib/div64.c + * + * __div64_32 implementation for 31 bit. + * + * Copyright (C) IBM Corp. 2006 + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), + */ + +#include <linux/types.h> +#include <linux/module.h> + +#ifdef CONFIG_MARCH_G5 + +/* + * Function to divide an unsigned 64 bit integer by an unsigned + * 31 bit integer using signed 64/32 bit division. + */ +static uint32_t __div64_31(uint64_t *n, uint32_t base) +{ + register uint32_t reg2 asm("2"); + register uint32_t reg3 asm("3"); + uint32_t *words = (uint32_t *) n; + uint32_t tmp; + + /* Special case base==1, remainder = 0, quotient = n */ + if (base == 1) + return 0; + /* + * Special case base==0 will cause a fixed point divide exception + * on the dr instruction and may not happen anyway. For the + * following calculation we can assume base > 1. The first + * signed 64 / 32 bit division with an upper half of 0 will + * give the correct upper half of the 64 bit quotient. + */ + reg2 = 0UL; + reg3 = words[0]; + asm volatile( + " dr %0,%2\n" + : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" ); + words[0] = reg3; + reg3 = words[1]; + /* + * To get the lower half of the 64 bit quotient and the 32 bit + * remainder we have to use a little trick. Since we only have + * a signed division the quotient can get too big. To avoid this + * the 64 bit dividend is halved, then the signed division will + * work. Afterwards the quotient and the remainder are doubled. + * If the last bit of the dividend has been one the remainder + * is increased by one then checked against the base. If the + * remainder has overflown subtract base and increase the + * quotient. Simple, no ? + */ + asm volatile( + " nr %2,%1\n" + " srdl %0,1\n" + " dr %0,%3\n" + " alr %0,%0\n" + " alr %1,%1\n" + " alr %0,%2\n" + " clr %0,%3\n" + " jl 0f\n" + " slr %0,%3\n" + " alr %1,%2\n" + "0:\n" + : "+d" (reg2), "+d" (reg3), "=d" (tmp) + : "d" (base), "2" (1UL) : "cc" ); + words[1] = reg3; + return reg2; +} + +/* + * Function to divide an unsigned 64 bit integer by an unsigned + * 32 bit integer using the unsigned 64/31 bit division. + */ +uint32_t __div64_32(uint64_t *n, uint32_t base) +{ + uint32_t r; + + /* + * If the most significant bit of base is set, divide n by + * (base/2). That allows to use 64/31 bit division and gives a + * good approximation of the result: n = (base/2)*q + r. The + * result needs to be corrected with two simple transformations. + * If base is already < 2^31-1 __div64_31 can be used directly. + */ + r = __div64_31(n, ((signed) base < 0) ? (base/2) : base); + if ((signed) base < 0) { + uint64_t q = *n; + /* + * First transformation: + * n = (base/2)*q + r + * = ((base/2)*2)*(q/2) + ((q&1) ? (base/2) : 0) + r + * Since r < (base/2), r + (base/2) < base. + * With q1 = (q/2) and r1 = r + ((q&1) ? (base/2) : 0) + * n = ((base/2)*2)*q1 + r1 with r1 < base. + */ + if (q & 1) + r += base/2; + q >>= 1; + /* + * Second transformation. ((base/2)*2) could have lost the + * last bit. + * n = ((base/2)*2)*q1 + r1 + * = base*q1 - ((base&1) ? q1 : 0) + r1 + */ + if (base & 1) { + int64_t rx = r - q; + /* + * base is >= 2^31. The worst case for the while + * loop is n=2^64-1 base=2^31+1. That gives a + * maximum for q=(2^64-1)/2^31 = 0x1ffffffff. Since + * base >= 2^31 the loop is finished after a maximum + * of three iterations. + */ + while (rx < 0) { + rx += base; + q--; + } + r = rx; + } + *n = q; + } + return r; +} + +#else /* MARCH_G5 */ + +uint32_t __div64_32(uint64_t *n, uint32_t base) +{ + register uint32_t reg2 asm("2"); + register uint32_t reg3 asm("3"); + uint32_t *words = (uint32_t *) n; + + reg2 = 0UL; + reg3 = words[0]; + asm volatile( + " dlr %0,%2\n" + : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" ); + words[0] = reg3; + reg3 = words[1]; + asm volatile( + " dlr %0,%2\n" + : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" ); + words[1] = reg3; + return reg2; +} + +#endif /* MARCH_G5 */ + +EXPORT_SYMBOL(__div64_32); diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 86c96d6c191..121b2935a42 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -35,7 +35,7 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) tmp1 = -4096UL; asm volatile( "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" - " jz 4f\n" + " jz 7f\n" "1:"ALR" %0,%3\n" " "SLR" %1,%3\n" " "SLR" %2,%3\n" @@ -44,13 +44,23 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */ " "SLR" %4,%1\n" " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 5f\n" + " jnh 4f\n" "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" " "SLR" %0,%4\n" - " j 5f\n" - "4:"SLR" %0,%0\n" - "5: \n" - EX_TABLE(0b,2b) EX_TABLE(3b,5b) + " "ALR" %2,%4\n" + "4:"LHI" %4,-1\n" + " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ + " bras %3,6f\n" /* memset loop */ + " xc 0(1,%2),0(%2)\n" + "5: xc 0(256,%2),0(%2)\n" + " la %2,256(%2)\n" + "6:"AHI" %4,-256\n" + " jnm 5b\n" + " ex %4,0(%3)\n" + " j 8f\n" + "7:"SLR" %0,%0\n" + "8: \n" + EX_TABLE(0b,2b) EX_TABLE(3b,4b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : "d" (reg0) : "cc", "memory"); return size; diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index 9a4d4a29ea7..f44f0078b35 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c @@ -35,25 +35,35 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) tmp1 = -256UL; asm volatile( "0: mvcp 0(%0,%2),0(%1),%3\n" - " jz 5f\n" + " jz 8f\n" "1:"ALR" %0,%3\n" " la %1,256(%1)\n" " la %2,256(%2)\n" "2: mvcp 0(%0,%2),0(%1),%3\n" " jnz 1b\n" - " j 5f\n" + " j 8f\n" "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ " "LHI" %3,-4096\n" " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ " "SLR" %4,%1\n" " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 6f\n" + " jnh 5f\n" "4: mvcp 0(%4,%2),0(%1),%3\n" " "SLR" %0,%4\n" - " j 6f\n" - "5:"SLR" %0,%0\n" - "6: \n" - EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) + " "ALR" %2,%4\n" + "5:"LHI" %4,-1\n" + " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ + " bras %3,7f\n" /* memset loop */ + " xc 0(1,%2),0(%2)\n" + "6: xc 0(256,%2),0(%2)\n" + " la %2,256(%2)\n" + "7:"AHI" %4,-256\n" + " jnm 6b\n" + " ex %4,0(%3)\n" + " j 9f\n" + "8:"SLR" %0,%0\n" + "9: \n" + EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : : "cc", "memory"); return size; @@ -67,16 +77,22 @@ size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x) asm volatile( "0: mvcp 0(%0,%2),0(%1),%3\n" " "SLR" %0,%0\n" - " j 3f\n" + " j 5f\n" "1: la %4,255(%1)\n" /* %4 = ptr + 255 */ " "LHI" %3,-4096\n" " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ " "SLR" %4,%1\n" " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 3f\n" + " jnh 5f\n" "2: mvcp 0(%4,%2),0(%1),%3\n" " "SLR" %0,%4\n" - "3:\n" + " "ALR" %2,%4\n" + "3:"LHI" %4,-1\n" + " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ + " bras %3,4f\n" + " xc 0(1,%2),0(%2)\n" + "4: ex %4,0(%3)\n" + "5:\n" EX_TABLE(0b,1b) EX_TABLE(2b,3b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : : "cc", "memory"); diff --git a/arch/s390/math-emu/math.c b/arch/s390/math-emu/math.c index b4957c84e4d..6b9aec5a2c1 100644 --- a/arch/s390/math-emu/math.c +++ b/arch/s390/math-emu/math.c @@ -1564,52 +1564,52 @@ static int emu_tceb (struct pt_regs *regs, int rx, long val) { } static inline void emu_load_regd(int reg) { - if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ + if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; - asm volatile ( /* load reg from fp_regs.fprs[reg] */ - " bras 1,0f\n" - " ld 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (reg<<4),"a" (¤t->thread.fp_regs.fprs[reg].d) - : "1" ); + asm volatile( /* load reg from fp_regs.fprs[reg] */ + " bras 1,0f\n" + " ld 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (reg<<4),"a" (¤t->thread.fp_regs.fprs[reg].d) + : "1"); } static inline void emu_load_rege(int reg) { - if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ + if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; - asm volatile ( /* load reg from fp_regs.fprs[reg] */ - " bras 1,0f\n" - " le 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) - : "1" ); + asm volatile( /* load reg from fp_regs.fprs[reg] */ + " bras 1,0f\n" + " le 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) + : "1"); } static inline void emu_store_regd(int reg) { - if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ + if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; - asm volatile ( /* store reg to fp_regs.fprs[reg] */ - " bras 1,0f\n" - " std 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].d) - : "1" ); + asm volatile( /* store reg to fp_regs.fprs[reg] */ + " bras 1,0f\n" + " std 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].d) + : "1"); } static inline void emu_store_rege(int reg) { - if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ + if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; - asm volatile ( /* store reg to fp_regs.fprs[reg] */ - " bras 1,0f\n" - " ste 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) - : "1" ); + asm volatile( /* store reg to fp_regs.fprs[reg] */ + " bras 1,0f\n" + " ste 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) + : "1"); } int math_emu_b3(__u8 *opcode, struct pt_regs * regs) { @@ -2089,23 +2089,22 @@ int math_emu_ldr(__u8 *opcode) { if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */ /* we got an exception therfore ry can't be in {0,2,4,6} */ - __asm__ __volatile ( /* load rx from fp_regs.fprs[ry] */ - " bras 1,0f\n" - " ld 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (opc & 0xf0), - "a" (&fp_regs->fprs[opc & 0xf].d) - : "1" ); + asm volatile( /* load rx from fp_regs.fprs[ry] */ + " bras 1,0f\n" + " ld 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].d) + : "1"); } else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */ - __asm__ __volatile ( /* store ry to fp_regs.fprs[rx] */ - " bras 1,0f\n" - " std 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" ((opc & 0xf) << 4), - "a" (&fp_regs->fprs[(opc & 0xf0)>>4].d) - : "1" ); + asm volatile ( /* store ry to fp_regs.fprs[rx] */ + " bras 1,0f\n" + " std 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" ((opc & 0xf) << 4), + "a" (&fp_regs->fprs[(opc & 0xf0)>>4].d) + : "1"); } else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */ fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf]; return 0; @@ -2120,23 +2119,22 @@ int math_emu_ler(__u8 *opcode) { if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */ /* we got an exception therfore ry can't be in {0,2,4,6} */ - __asm__ __volatile ( /* load rx from fp_regs.fprs[ry] */ - " bras 1,0f\n" - " le 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (opc & 0xf0), - "a" (&fp_regs->fprs[opc & 0xf].f) - : "1" ); + asm volatile( /* load rx from fp_regs.fprs[ry] */ + " bras 1,0f\n" + " le 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].f) + : "1"); } else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */ - __asm__ __volatile ( /* store ry to fp_regs.fprs[rx] */ - " bras 1,0f\n" - " ste 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" ((opc & 0xf) << 4), - "a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f) - : "1" ); + asm volatile( /* store ry to fp_regs.fprs[rx] */ + " bras 1,0f\n" + " ste 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" ((opc & 0xf) << 4), + "a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f) + : "1"); } else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */ fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf]; return 0; diff --git a/arch/s390/math-emu/sfp-util.h b/arch/s390/math-emu/sfp-util.h index ab556b600f7..5b6ca4570ea 100644 --- a/arch/s390/math-emu/sfp-util.h +++ b/arch/s390/math-emu/sfp-util.h @@ -4,48 +4,51 @@ #include <asm/byteorder.h> #define add_ssaaaa(sh, sl, ah, al, bh, bl) ({ \ - unsigned int __sh = (ah); \ - unsigned int __sl = (al); \ - __asm__ (" alr %1,%3\n" \ - " brc 12,0f\n" \ - " ahi %0,1\n" \ - "0: alr %0,%2" \ - : "+&d" (__sh), "+d" (__sl) \ - : "d" (bh), "d" (bl) : "cc" ); \ - (sh) = __sh; \ - (sl) = __sl; \ + unsigned int __sh = (ah); \ + unsigned int __sl = (al); \ + asm volatile( \ + " alr %1,%3\n" \ + " brc 12,0f\n" \ + " ahi %0,1\n" \ + "0: alr %0,%2" \ + : "+&d" (__sh), "+d" (__sl) \ + : "d" (bh), "d" (bl) : "cc"); \ + (sh) = __sh; \ + (sl) = __sl; \ }) #define sub_ddmmss(sh, sl, ah, al, bh, bl) ({ \ - unsigned int __sh = (ah); \ - unsigned int __sl = (al); \ - __asm__ (" slr %1,%3\n" \ - " brc 3,0f\n" \ - " ahi %0,-1\n" \ - "0: slr %0,%2" \ - : "+&d" (__sh), "+d" (__sl) \ - : "d" (bh), "d" (bl) : "cc" ); \ - (sh) = __sh; \ - (sl) = __sl; \ + unsigned int __sh = (ah); \ + unsigned int __sl = (al); \ + asm volatile( \ + " slr %1,%3\n" \ + " brc 3,0f\n" \ + " ahi %0,-1\n" \ + "0: slr %0,%2" \ + : "+&d" (__sh), "+d" (__sl) \ + : "d" (bh), "d" (bl) : "cc"); \ + (sh) = __sh; \ + (sl) = __sl; \ }) /* a umul b = a mul b + (a>=2<<31) ? b<<32:0 + (b>=2<<31) ? a<<32:0 */ #define umul_ppmm(wh, wl, u, v) ({ \ - unsigned int __wh = u; \ - unsigned int __wl = v; \ - __asm__ (" ltr 1,%0\n" \ - " mr 0,%1\n" \ - " jnm 0f\n" \ - " alr 0,%1\n" \ - "0: ltr %1,%1\n" \ - " jnm 1f\n" \ - " alr 0,%0\n" \ - "1: lr %0,0\n" \ - " lr %1,1\n" \ - : "+d" (__wh), "+d" (__wl) \ - : : "0", "1", "cc" ); \ - wh = __wh; \ - wl = __wl; \ + unsigned int __wh = u; \ + unsigned int __wl = v; \ + asm volatile( \ + " ltr 1,%0\n" \ + " mr 0,%1\n" \ + " jnm 0f\n" \ + " alr 0,%1\n" \ + "0: ltr %1,%1\n" \ + " jnm 1f\n" \ + " alr 0,%0\n" \ + "1: lr %0,0\n" \ + " lr %1,1\n" \ + : "+d" (__wh), "+d" (__wl) \ + : : "0", "1", "cc"); \ + wh = __wh; \ + wl = __wl; \ }) #define udiv_qrnnd(q, r, n1, n0, d) \ diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 9b11e3e2090..226275d5c4f 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -142,17 +142,17 @@ dcss_diag (__u8 func, void *parameter, rx = (unsigned long) parameter; ry = (unsigned long) func; - __asm__ __volatile__( + asm volatile( #ifdef CONFIG_64BIT - " sam31\n" // switch to 31 bit - " diag %0,%1,0x64\n" - " sam64\n" // switch back to 64 bit + " sam31\n" + " diag %0,%1,0x64\n" + " sam64\n" #else - " diag %0,%1,0x64\n" + " diag %0,%1,0x64\n" #endif - " ipm %2\n" - " srl %2,28\n" - : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc" ); + " ipm %2\n" + " srl %2,28\n" + : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); *ret1 = rx; *ret2 = ry; return rc; diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 44f0cda7e72..f2b9a84dc2b 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -355,6 +355,7 @@ out_of_memory: up_read(&mm->mmap_sem); if (tsk->pid == 1) { yield(); + down_read(&mm->mmap_sem); goto survive; } printk("VM: killing process %s\n", tsk->comm); @@ -423,20 +424,13 @@ int pfault_init(void) if (pfault_disable) return -1; - __asm__ __volatile__( - " diag %1,%0,0x258\n" - "0: j 2f\n" - "1: la %0,8\n" + asm volatile( + " diag %1,%0,0x258\n" + "0: j 2f\n" + "1: la %0,8\n" "2:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" -#ifndef CONFIG_64BIT - " .long 0b,1b\n" -#else /* CONFIG_64BIT */ - " .quad 0b,1b\n" -#endif /* CONFIG_64BIT */ - ".previous" - : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" ); + EX_TABLE(0b,1b) + : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc"); __ctl_set_bit(0, 9); return rc; } @@ -449,18 +443,11 @@ void pfault_fini(void) if (pfault_disable) return; __ctl_clear_bit(0,9); - __asm__ __volatile__( - " diag %0,0,0x258\n" + asm volatile( + " diag %0,0,0x258\n" "0:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" -#ifndef CONFIG_64BIT - " .long 0b,0b\n" -#else /* CONFIG_64BIT */ - " .quad 0b,0b\n" -#endif /* CONFIG_64BIT */ - ".previous" - : : "a" (&refbk), "m" (refbk) : "cc" ); + EX_TABLE(0b,0b) + : : "a" (&refbk), "m" (refbk) : "cc"); } asmlinkage void diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index cfd9b8f7a52..127044e1707 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -45,26 +45,17 @@ void diag10(unsigned long addr) { if (addr >= 0x7ff00000) return; + asm volatile( #ifdef CONFIG_64BIT - asm volatile ( - " sam31\n" - " diag %0,%0,0x10\n" - "0: sam64\n" - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b, 0b\n" - ".previous\n" - : : "a" (addr)); + " sam31\n" + " diag %0,%0,0x10\n" + "0: sam64\n" #else - asm volatile ( - " diag %0,%0,0x10\n" + " diag %0,%0,0x10\n" "0:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b, 0b\n" - ".previous\n" - : : "a" (addr)); #endif + EX_TABLE(0b,0b) + : : "a" (addr)); } void show_mem(void) @@ -156,11 +147,10 @@ void __init paging_init(void) S390_lowcore.kernel_asce = pgdir_k; /* enable virtual mapping in kernel mode */ - __asm__ __volatile__(" LCTL 1,1,%0\n" - " LCTL 7,7,%0\n" - " LCTL 13,13,%0\n" - " SSM %1" - : : "m" (pgdir_k), "m" (ssm_mask)); + __ctl_load(pgdir_k, 1, 1); + __ctl_load(pgdir_k, 7, 7); + __ctl_load(pgdir_k, 13, 13); + __raw_local_irq_ssm(ssm_mask); local_flush_tlb(); return; @@ -241,11 +231,10 @@ void __init paging_init(void) S390_lowcore.kernel_asce = pgdir_k; /* enable virtual mapping in kernel mode */ - __asm__ __volatile__("lctlg 1,1,%0\n\t" - "lctlg 7,7,%0\n\t" - "lctlg 13,13,%0\n\t" - "ssm %1" - : :"m" (pgdir_k), "m" (ssm_mask)); + __ctl_load(pgdir_k, 1, 1); + __ctl_load(pgdir_k, 7, 7); + __ctl_load(pgdir_k, 13, 13); + __raw_local_irq_ssm(ssm_mask); local_flush_tlb(); diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 0e31a0c496e..9b88b25b6ed 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -53,7 +53,7 @@ config SENSORS_ADM1021 config SENSORS_ADM1025 tristate "Analog Devices ADM1025 and compatibles" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C select HWMON_VID help If you say yes here you get support for Analog Devices ADM1025 @@ -94,6 +94,16 @@ config SENSORS_ADM9240 This driver can also be built as a module. If so, the module will be called adm9240. +config SENSORS_K8TEMP + tristate "AMD K8 processor sensor" + depends on HWMON && X86 && PCI && EXPERIMENTAL + help + If you say yes here you get support for the temperature + sensor(s) inside your AMD K8 CPU. + + This driver can also be built as a module. If so, the module + will be called k8temp. + config SENSORS_ASB100 tristate "Asus ASB100 Bach" depends on HWMON && I2C && EXPERIMENTAL @@ -121,7 +131,7 @@ config SENSORS_ATXP1 config SENSORS_DS1621 tristate "Dallas Semiconductor DS1621 and DS1625" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C help If you say yes here you get support for Dallas Semiconductor DS1621 and DS1625 sensor chips. @@ -141,7 +151,7 @@ config SENSORS_F71805F config SENSORS_FSCHER tristate "FSC Hermes" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C help If you say yes here you get support for Fujitsu Siemens Computers Hermes sensor chips. @@ -151,7 +161,7 @@ config SENSORS_FSCHER config SENSORS_FSCPOS tristate "FSC Poseidon" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C help If you say yes here you get support for Fujitsu Siemens Computers Poseidon sensor chips. @@ -171,7 +181,7 @@ config SENSORS_GL518SM config SENSORS_GL520SM tristate "Genesys Logic GL520SM" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C select HWMON_VID help If you say yes here you get support for Genesys Logic GL520SM @@ -186,15 +196,15 @@ config SENSORS_IT87 select I2C_ISA select HWMON_VID help - If you say yes here you get support for ITE IT87xx sensor chips - and clones: SiS960. + If you say yes here you get support for ITE IT8705F, IT8712F, + IT8716F and IT8718F sensor chips, and the SiS960 clone. This driver can also be built as a module. If so, the module will be called it87. config SENSORS_LM63 tristate "National Semiconductor LM63" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C help If you say yes here you get support for the National Semiconductor LM63 remote diode digital temperature sensor with integrated fan @@ -231,7 +241,7 @@ config SENSORS_LM75 config SENSORS_LM77 tristate "National Semiconductor LM77" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C help If you say yes here you get support for National Semiconductor LM77 sensor chips. @@ -241,7 +251,7 @@ config SENSORS_LM77 config SENSORS_LM78 tristate "National Semiconductor LM78 and compatibles" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C select I2C_ISA select HWMON_VID help @@ -284,7 +294,7 @@ config SENSORS_LM85 config SENSORS_LM87 tristate "National Semiconductor LM87" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C select HWMON_VID help If you say yes here you get support for National Semiconductor LM87 @@ -309,7 +319,7 @@ config SENSORS_LM90 config SENSORS_LM92 tristate "National Semiconductor LM92 and compatibles" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C help If you say yes here you get support for National Semiconductor LM92 and Maxim MAX6635 sensor chips. @@ -319,7 +329,7 @@ config SENSORS_LM92 config SENSORS_MAX1619 tristate "Maxim MAX1619 sensor chip" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C help If you say yes here you get support for MAX1619 sensor chip. @@ -354,7 +364,7 @@ config SENSORS_SIS5595 config SENSORS_SMSC47M1 tristate "SMSC LPC47M10x and compatibles" - depends on HWMON && I2C && EXPERIMENTAL + depends on HWMON && I2C select I2C_ISA help If you say yes here you get support for the integrated fan @@ -407,8 +417,19 @@ config SENSORS_VIA686A This driver can also be built as a module. If so, the module will be called via686a. +config SENSORS_VT1211 + tristate "VIA VT1211" + depends on HWMON && EXPERIMENTAL + select HWMON_VID + help + If you say yes here then you get support for hardware monitoring + features of the VIA VT1211 Super-I/O chip. + + This driver can also be built as a module. If so, the module + will be called vt1211. + config SENSORS_VT8231 - tristate "VT8231" + tristate "VIA VT8231" depends on HWMON && I2C && PCI && EXPERIMENTAL select HWMON_VID select I2C_ISA diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 31415843a91..af01cc64f7d 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o obj-$(CONFIG_SENSORS_IT87) += it87.o +obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM70) += lm70.o obj-$(CONFIG_SENSORS_LM75) += lm75.o @@ -45,6 +46,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o +obj-$(CONFIG_SENSORS_VT1211) += vt1211.o obj-$(CONFIG_SENSORS_VT8231) += vt8231.o obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 35ad1b03272..e5cb0fdab9b 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -1354,13 +1354,39 @@ LEAVE_UPDATE: return NULL; } +#ifdef CONFIG_PM +static int abituguru_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct abituguru_data *data = platform_get_drvdata(pdev); + /* make sure all communications with the uguru are done and no new + ones are started */ + mutex_lock(&data->update_lock); + return 0; +} + +static int abituguru_resume(struct platform_device *pdev) +{ + struct abituguru_data *data = platform_get_drvdata(pdev); + /* See if the uGuru is still ready */ + if (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) + data->uguru_ready = 0; + mutex_unlock(&data->update_lock); + return 0; +} +#else +#define abituguru_suspend NULL +#define abituguru_resume NULL +#endif /* CONFIG_PM */ + static struct platform_driver abituguru_driver = { .driver = { .owner = THIS_MODULE, .name = ABIT_UGURU_NAME, }, - .probe = abituguru_probe, - .remove = __devexit_p(abituguru_remove), + .probe = abituguru_probe, + .remove = __devexit_p(abituguru_remove), + .suspend = abituguru_suspend, + .resume = abituguru_resume, }; static int __init abituguru_detect(void) diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 2b6e74dd4a8..c466329b2ef 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -190,6 +190,21 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, adm1021_detect); } +static struct attribute *adm1021_attributes[] = { + &dev_attr_temp1_max.attr, + &dev_attr_temp1_min.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp2_min.attr, + &dev_attr_temp2_input.attr, + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group adm1021_group = { + .attrs = adm1021_attributes, +}; + static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) { int i; @@ -287,22 +302,19 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) adm1021_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1021_group))) + goto error2; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto error2; + goto error3; } - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_min); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp2_max); - device_create_file(&new_client->dev, &dev_attr_temp2_min); - device_create_file(&new_client->dev, &dev_attr_temp2_input); - device_create_file(&new_client->dev, &dev_attr_alarms); - return 0; +error3: + sysfs_remove_group(&new_client->dev.kobj, &adm1021_group); error2: i2c_detach_client(new_client); error1: @@ -326,6 +338,7 @@ static int adm1021_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &adm1021_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c index a4c859c9fbf..8c562885b54 100644 --- a/drivers/hwmon/adm1025.c +++ b/drivers/hwmon/adm1025.c @@ -315,6 +315,49 @@ static int adm1025_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, adm1025_detect); } +static struct attribute *adm1025_attributes[] = { + &dev_attr_in0_input.attr, + &dev_attr_in1_input.attr, + &dev_attr_in2_input.attr, + &dev_attr_in3_input.attr, + &dev_attr_in5_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in1_min.attr, + &dev_attr_in2_min.attr, + &dev_attr_in3_min.attr, + &dev_attr_in5_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_max.attr, + &dev_attr_in5_max.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp1_min.attr, + &dev_attr_temp2_min.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp2_max.attr, + &dev_attr_alarms.attr, + &dev_attr_cpu0_vid.attr, + &dev_attr_vrm.attr, + NULL +}; + +static const struct attribute_group adm1025_group = { + .attrs = adm1025_attributes, +}; + +static struct attribute *adm1025_attributes_opt[] = { + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + NULL +}; + +static const struct attribute_group adm1025_group_opt = { + .attrs = adm1025_attributes_opt, +}; + /* * The following function does more than just detection. If detection * succeeds, it also registers the new chip. @@ -415,46 +458,31 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) adm1025_init_client(new_client); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1025_group))) goto exit_detach; - } - - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in5_input); - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in5_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_max); - device_create_file(&new_client->dev, &dev_attr_in5_max); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp2_input); - device_create_file(&new_client->dev, &dev_attr_temp1_min); - device_create_file(&new_client->dev, &dev_attr_temp2_min); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp2_max); - device_create_file(&new_client->dev, &dev_attr_alarms); - device_create_file(&new_client->dev, &dev_attr_cpu0_vid); - device_create_file(&new_client->dev, &dev_attr_vrm); /* Pin 11 is either in4 (+12V) or VID4 */ if (!(config & 0x20)) { - device_create_file(&new_client->dev, &dev_attr_in4_input); - device_create_file(&new_client->dev, &dev_attr_in4_min); - device_create_file(&new_client->dev, &dev_attr_in4_max); + if ((err = device_create_file(&new_client->dev, + &dev_attr_in4_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in4_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in4_max))) + goto exit_remove; + } + + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove; } return 0; +exit_remove: + sysfs_remove_group(&new_client->dev.kobj, &adm1025_group); + sysfs_remove_group(&new_client->dev.kobj, &adm1025_group_opt); exit_detach: i2c_detach_client(new_client); exit_free: @@ -511,6 +539,8 @@ static int adm1025_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &adm1025_group); + sysfs_remove_group(&client->dev.kobj, &adm1025_group_opt); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 6d4f8b8d358..b4618b2705f 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -323,15 +323,6 @@ static int adm1026_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, adm1026_detect); } -static int adm1026_detach_client(struct i2c_client *client) -{ - struct adm1026_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->class_dev); - i2c_detach_client(client); - kfree(data); - return 0; -} - static int adm1026_read_value(struct i2c_client *client, u8 reg) { int res; @@ -1450,6 +1441,135 @@ static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL); static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL); static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL); +static struct attribute *adm1026_attributes[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_max.dev_attr.attr, + &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in5_max.dev_attr.attr, + &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in6_max.dev_attr.attr, + &sensor_dev_attr_in6_min.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in7_max.dev_attr.attr, + &sensor_dev_attr_in7_min.dev_attr.attr, + &sensor_dev_attr_in8_input.dev_attr.attr, + &sensor_dev_attr_in8_max.dev_attr.attr, + &sensor_dev_attr_in8_min.dev_attr.attr, + &sensor_dev_attr_in9_input.dev_attr.attr, + &sensor_dev_attr_in9_max.dev_attr.attr, + &sensor_dev_attr_in9_min.dev_attr.attr, + &sensor_dev_attr_in10_input.dev_attr.attr, + &sensor_dev_attr_in10_max.dev_attr.attr, + &sensor_dev_attr_in10_min.dev_attr.attr, + &sensor_dev_attr_in11_input.dev_attr.attr, + &sensor_dev_attr_in11_max.dev_attr.attr, + &sensor_dev_attr_in11_min.dev_attr.attr, + &sensor_dev_attr_in12_input.dev_attr.attr, + &sensor_dev_attr_in12_max.dev_attr.attr, + &sensor_dev_attr_in12_min.dev_attr.attr, + &sensor_dev_attr_in13_input.dev_attr.attr, + &sensor_dev_attr_in13_max.dev_attr.attr, + &sensor_dev_attr_in13_min.dev_attr.attr, + &sensor_dev_attr_in14_input.dev_attr.attr, + &sensor_dev_attr_in14_max.dev_attr.attr, + &sensor_dev_attr_in14_min.dev_attr.attr, + &sensor_dev_attr_in15_input.dev_attr.attr, + &sensor_dev_attr_in15_max.dev_attr.attr, + &sensor_dev_attr_in15_min.dev_attr.attr, + &sensor_dev_attr_in16_input.dev_attr.attr, + &sensor_dev_attr_in16_max.dev_attr.attr, + &sensor_dev_attr_in16_min.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_div.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan3_div.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan4_div.dev_attr.attr, + &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan5_div.dev_attr.attr, + &sensor_dev_attr_fan5_min.dev_attr.attr, + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan6_div.dev_attr.attr, + &sensor_dev_attr_fan6_min.dev_attr.attr, + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan7_div.dev_attr.attr, + &sensor_dev_attr_fan7_min.dev_attr.attr, + &sensor_dev_attr_fan8_input.dev_attr.attr, + &sensor_dev_attr_fan8_div.dev_attr.attr, + &sensor_dev_attr_fan8_min.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp1_offset.dev_attr.attr, + &sensor_dev_attr_temp2_offset.dev_attr.attr, + &sensor_dev_attr_temp3_offset.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point1_temp_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + &dev_attr_temp1_crit_enable.attr, + &dev_attr_temp2_crit_enable.attr, + &dev_attr_temp3_crit_enable.attr, + &dev_attr_cpu0_vid.attr, + &dev_attr_vrm.attr, + &dev_attr_alarms.attr, + &dev_attr_alarm_mask.attr, + &dev_attr_gpio.attr, + &dev_attr_gpio_mask.attr, + &dev_attr_pwm1.attr, + &dev_attr_pwm2.attr, + &dev_attr_pwm3.attr, + &dev_attr_pwm1_enable.attr, + &dev_attr_pwm2_enable.attr, + &dev_attr_pwm3_enable.attr, + &dev_attr_temp1_auto_point1_pwm.attr, + &dev_attr_temp2_auto_point1_pwm.attr, + &dev_attr_temp3_auto_point1_pwm.attr, + &dev_attr_temp1_auto_point2_pwm.attr, + &dev_attr_temp2_auto_point2_pwm.attr, + &dev_attr_temp3_auto_point2_pwm.attr, + &dev_attr_analog_out.attr, + NULL +}; + +static const struct attribute_group adm1026_group = { + .attrs = adm1026_attributes, +}; + static int adm1026_detect(struct i2c_adapter *adapter, int address, int kind) { @@ -1554,145 +1674,20 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, adm1026_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1026_group))) + goto exitdetach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exitdetach; + goto exitremove; } - device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in8_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in8_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in9_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in9_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in9_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in10_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in10_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in10_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in11_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in11_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in11_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in12_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in12_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in12_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in13_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in13_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in13_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in14_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in14_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in14_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in15_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in15_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in15_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in16_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in16_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in16_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan4_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan4_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan4_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan5_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan5_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan5_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan6_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan6_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan6_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan7_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan7_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan7_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan8_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan8_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan8_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_offset.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_offset.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_offset.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_auto_point1_temp.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_auto_point1_temp.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_auto_point1_temp.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_auto_point1_temp_hyst.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_auto_point2_temp.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_auto_point2_temp.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_auto_point2_temp.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_crit.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_crit.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_crit.dev_attr); - device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable); - device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable); - device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable); - device_create_file(&new_client->dev, &dev_attr_cpu0_vid); - device_create_file(&new_client->dev, &dev_attr_vrm); - device_create_file(&new_client->dev, &dev_attr_alarms); - device_create_file(&new_client->dev, &dev_attr_alarm_mask); - device_create_file(&new_client->dev, &dev_attr_gpio); - device_create_file(&new_client->dev, &dev_attr_gpio_mask); - device_create_file(&new_client->dev, &dev_attr_pwm1); - device_create_file(&new_client->dev, &dev_attr_pwm2); - device_create_file(&new_client->dev, &dev_attr_pwm3); - device_create_file(&new_client->dev, &dev_attr_pwm1_enable); - device_create_file(&new_client->dev, &dev_attr_pwm2_enable); - device_create_file(&new_client->dev, &dev_attr_pwm3_enable); - device_create_file(&new_client->dev, &dev_attr_temp1_auto_point1_pwm); - device_create_file(&new_client->dev, &dev_attr_temp2_auto_point1_pwm); - device_create_file(&new_client->dev, &dev_attr_temp3_auto_point1_pwm); - device_create_file(&new_client->dev, &dev_attr_temp1_auto_point2_pwm); - device_create_file(&new_client->dev, &dev_attr_temp2_auto_point2_pwm); - device_create_file(&new_client->dev, &dev_attr_temp3_auto_point2_pwm); - device_create_file(&new_client->dev, &dev_attr_analog_out); return 0; /* Error out and cleanup code */ +exitremove: + sysfs_remove_group(&new_client->dev.kobj, &adm1026_group); exitdetach: i2c_detach_client(new_client); exitfree: @@ -1700,6 +1695,17 @@ exitfree: exit: return err; } + +static int adm1026_detach_client(struct i2c_client *client) +{ + struct adm1026_data *data = i2c_get_clientdata(client); + hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &adm1026_group); + i2c_detach_client(client); + kfree(data); + return 0; +} + static int __init sm_adm1026_init(void) { return i2c_add_driver(&adm1026_driver); diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 3bf2da621ae..122683fc91d 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c @@ -730,6 +730,61 @@ static int adm1031_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, adm1031_detect); } +static struct attribute *adm1031_attributes[] = { + &dev_attr_fan1_input.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan1_min.attr, + &dev_attr_pwm1.attr, + &dev_attr_auto_fan1_channel.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp1_min.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_crit.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp2_min.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp2_crit.attr, + + &dev_attr_auto_temp1_off.attr, + &dev_attr_auto_temp1_min.attr, + &dev_attr_auto_temp1_max.attr, + + &dev_attr_auto_temp2_off.attr, + &dev_attr_auto_temp2_min.attr, + &dev_attr_auto_temp2_max.attr, + + &dev_attr_auto_fan1_min_pwm.attr, + + &dev_attr_alarms.attr, + + NULL +}; + +static const struct attribute_group adm1031_group = { + .attrs = adm1031_attributes, +}; + +static struct attribute *adm1031_attributes_opt[] = { + &dev_attr_fan2_input.attr, + &dev_attr_fan2_div.attr, + &dev_attr_fan2_min.attr, + &dev_attr_pwm2.attr, + &dev_attr_auto_fan2_channel.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp3_min.attr, + &dev_attr_temp3_max.attr, + &dev_attr_temp3_crit.attr, + &dev_attr_auto_temp3_off.attr, + &dev_attr_auto_temp3_min.attr, + &dev_attr_auto_temp3_max.attr, + &dev_attr_auto_fan2_min_pwm.attr, + NULL +}; + +static const struct attribute_group adm1031_group_opt = { + .attrs = adm1031_attributes_opt, +}; + /* This function is called by i2c_probe */ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) { @@ -789,57 +844,26 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) adm1031_init_client(new_client); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1031_group))) goto exit_detach; - } - - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan1_div); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_pwm1); - device_create_file(&new_client->dev, &dev_attr_auto_fan1_channel); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_min); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_crit); - device_create_file(&new_client->dev, &dev_attr_temp2_input); - device_create_file(&new_client->dev, &dev_attr_temp2_min); - device_create_file(&new_client->dev, &dev_attr_temp2_max); - device_create_file(&new_client->dev, &dev_attr_temp2_crit); - - device_create_file(&new_client->dev, &dev_attr_auto_temp1_off); - device_create_file(&new_client->dev, &dev_attr_auto_temp1_min); - device_create_file(&new_client->dev, &dev_attr_auto_temp1_max); - - device_create_file(&new_client->dev, &dev_attr_auto_temp2_off); - device_create_file(&new_client->dev, &dev_attr_auto_temp2_min); - device_create_file(&new_client->dev, &dev_attr_auto_temp2_max); - - device_create_file(&new_client->dev, &dev_attr_auto_fan1_min_pwm); - - device_create_file(&new_client->dev, &dev_attr_alarms); if (kind == adm1031) { - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan2_div); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_pwm2); - device_create_file(&new_client->dev, - &dev_attr_auto_fan2_channel); - device_create_file(&new_client->dev, &dev_attr_temp3_input); - device_create_file(&new_client->dev, &dev_attr_temp3_min); - device_create_file(&new_client->dev, &dev_attr_temp3_max); - device_create_file(&new_client->dev, &dev_attr_temp3_crit); - device_create_file(&new_client->dev, &dev_attr_auto_temp3_off); - device_create_file(&new_client->dev, &dev_attr_auto_temp3_min); - device_create_file(&new_client->dev, &dev_attr_auto_temp3_max); - device_create_file(&new_client->dev, &dev_attr_auto_fan2_min_pwm); + if ((err = sysfs_create_group(&new_client->dev.kobj, + &adm1031_group_opt))) + goto exit_remove; + } + + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove; } return 0; +exit_remove: + sysfs_remove_group(&new_client->dev.kobj, &adm1031_group); + sysfs_remove_group(&new_client->dev.kobj, &adm1031_group_opt); exit_detach: i2c_detach_client(new_client); exit_free: @@ -854,6 +878,8 @@ static int adm1031_detach_client(struct i2c_client *client) int ret; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &adm1031_group); + sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt); if ((ret = i2c_detach_client(client)) != 0) { return ret; } diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 43f6991b588..377961c4a41 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c @@ -465,6 +465,45 @@ static ssize_t chassis_clear(struct device *dev, } static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear); +static struct attribute *adm9240_attributes[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in0_max.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in5_max.dev_attr.attr, + &dev_attr_temp1_input.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_div.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &dev_attr_alarms.attr, + &dev_attr_aout_output.attr, + &dev_attr_chassis_clear.attr, + &dev_attr_cpu0_vid.attr, + NULL +}; + +static const struct attribute_group adm9240_group = { + .attrs = adm9240_attributes, +}; + /*** sensor chip detect and driver install ***/ @@ -548,72 +587,19 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) adm9240_init_client(new_client); /* populate sysfs filesystem */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove; } - device_create_file(&new_client->dev, - &sensor_dev_attr_in0_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in0_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in0_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in1_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in1_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in1_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in2_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in2_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in2_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in3_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in3_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in3_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in4_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in4_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in4_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in5_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in5_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_in5_max.dev_attr); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_max_hyst.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_fan1_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_fan1_div.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_fan1_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_fan2_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_fan2_div.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_fan2_min.dev_attr); - device_create_file(&new_client->dev, &dev_attr_alarms); - device_create_file(&new_client->dev, &dev_attr_aout_output); - device_create_file(&new_client->dev, &dev_attr_chassis_clear); - device_create_file(&new_client->dev, &dev_attr_cpu0_vid); - return 0; +exit_remove: + sysfs_remove_group(&new_client->dev.kobj, &adm9240_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -635,6 +621,7 @@ static int adm9240_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &adm9240_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index facc1ccb833..57b1c7b7ac3 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c @@ -298,12 +298,6 @@ sysfs_in(4); sysfs_in(5); sysfs_in(6); -#define device_create_file_in(client, offset) do { \ - device_create_file(&client->dev, &dev_attr_in##offset##_input); \ - device_create_file(&client->dev, &dev_attr_in##offset##_min); \ - device_create_file(&client->dev, &dev_attr_in##offset##_max); \ -} while (0) - /* 3 Fans */ static ssize_t show_fan(struct device *dev, char *buf, int nr) { @@ -421,12 +415,6 @@ sysfs_fan(1); sysfs_fan(2); sysfs_fan(3); -#define device_create_file_fan(client, offset) do { \ - device_create_file(&client->dev, &dev_attr_fan##offset##_input); \ - device_create_file(&client->dev, &dev_attr_fan##offset##_min); \ - device_create_file(&client->dev, &dev_attr_fan##offset##_div); \ -} while (0) - /* 4 Temp. Sensors */ static int sprintf_temp_from_reg(u16 reg, char *buf, int nr) { @@ -515,12 +503,6 @@ sysfs_temp(3); sysfs_temp(4); /* VID */ -#define device_create_file_temp(client, num) do { \ - device_create_file(&client->dev, &dev_attr_temp##num##_input); \ - device_create_file(&client->dev, &dev_attr_temp##num##_max); \ - device_create_file(&client->dev, &dev_attr_temp##num##_max_hyst); \ -} while (0) - static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) { struct asb100_data *data = asb100_update_device(dev); @@ -528,8 +510,6 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char } static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); -#define device_create_file_vid(client) \ -device_create_file(&client->dev, &dev_attr_cpu0_vid) /* VRM */ static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) @@ -549,8 +529,6 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const /* Alarms */ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); -#define device_create_file_vrm(client) \ -device_create_file(&client->dev, &dev_attr_vrm); static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) { @@ -559,8 +537,6 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); -#define device_create_file_alarms(client) \ -device_create_file(&client->dev, &dev_attr_alarms) /* 1 PWM */ static ssize_t show_pwm1(struct device *dev, struct device_attribute *attr, char *buf) @@ -607,10 +583,65 @@ static ssize_t set_pwm_enable1(struct device *dev, struct device_attribute *attr static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1); static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable1, set_pwm_enable1); -#define device_create_file_pwm1(client) do { \ - device_create_file(&new_client->dev, &dev_attr_pwm1); \ - device_create_file(&new_client->dev, &dev_attr_pwm1_enable); \ -} while (0) + +static struct attribute *asb100_attributes[] = { + &dev_attr_in0_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_input.attr, + &dev_attr_in1_min.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_input.attr, + &dev_attr_in2_min.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_input.attr, + &dev_attr_in3_min.attr, + &dev_attr_in3_max.attr, + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + &dev_attr_in5_input.attr, + &dev_attr_in5_min.attr, + &dev_attr_in5_max.attr, + &dev_attr_in6_input.attr, + &dev_attr_in6_min.attr, + &dev_attr_in6_max.attr, + + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + &dev_attr_fan3_input.attr, + &dev_attr_fan3_min.attr, + &dev_attr_fan3_div.attr, + + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp2_max_hyst.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp3_max.attr, + &dev_attr_temp3_max_hyst.attr, + &dev_attr_temp4_input.attr, + &dev_attr_temp4_max.attr, + &dev_attr_temp4_max_hyst.attr, + + &dev_attr_cpu0_vid.attr, + &dev_attr_vrm.attr, + &dev_attr_alarms.attr, + &dev_attr_pwm1.attr, + &dev_attr_pwm1_enable.attr, + + NULL +}; + +static const struct attribute_group asb100_group = { + .attrs = asb100_attributes, +}; /* This function is called when: asb100_driver is inserted (when this module is loaded), for each @@ -810,38 +841,19 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2)); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &asb100_group))) + goto ERROR3; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto ERROR3; + goto ERROR4; } - device_create_file_in(new_client, 0); - device_create_file_in(new_client, 1); - device_create_file_in(new_client, 2); - device_create_file_in(new_client, 3); - device_create_file_in(new_client, 4); - device_create_file_in(new_client, 5); - device_create_file_in(new_client, 6); - - device_create_file_fan(new_client, 1); - device_create_file_fan(new_client, 2); - device_create_file_fan(new_client, 3); - - device_create_file_temp(new_client, 1); - device_create_file_temp(new_client, 2); - device_create_file_temp(new_client, 3); - device_create_file_temp(new_client, 4); - - device_create_file_vid(new_client); - device_create_file_vrm(new_client); - - device_create_file_alarms(new_client); - - device_create_file_pwm1(new_client); - return 0; +ERROR4: + sysfs_remove_group(&new_client->dev.kobj, &asb100_group); ERROR3: i2c_detach_client(data->lm75[1]); i2c_detach_client(data->lm75[0]); @@ -861,8 +873,10 @@ static int asb100_detach_client(struct i2c_client *client) int err; /* main client */ - if (data) + if (data) { hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &asb100_group); + } if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 728a1e8b919..0ccdd0750c4 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -27,6 +27,7 @@ #include <linux/hwmon-vid.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("System voltages control via Attansic ATXP1"); @@ -116,8 +117,7 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att { struct atxp1_data *data; struct i2c_client *client; - char vid; - char cvid; + int vid, cvid; unsigned int vcore; client = to_i2c_client(dev); @@ -251,6 +251,17 @@ static ssize_t atxp1_storegpio2(struct device *dev, struct device_attribute *att */ static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2); +static struct attribute *atxp1_attributes[] = { + &dev_attr_gpio1.attr, + &dev_attr_gpio2.attr, + &dev_attr_cpu0_vid.attr, + NULL +}; + +static const struct attribute_group atxp1_group = { + .attrs = atxp1_attributes, +}; + static int atxp1_attach_adapter(struct i2c_adapter *adapter) { @@ -320,21 +331,23 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) goto exit_free; } + /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file(&new_client->dev, &dev_attr_gpio1); - device_create_file(&new_client->dev, &dev_attr_gpio2); - device_create_file(&new_client->dev, &dev_attr_cpu0_vid); - dev_info(&new_client->dev, "Using VRM: %d.%d\n", data->vrm / 10, data->vrm % 10); return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &atxp1_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -349,6 +362,7 @@ static int atxp1_detach_client(struct i2c_client * client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &atxp1_group); err = i2c_detach_client(client); diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c index 478eb4bb857..c849c0c6ee9 100644 --- a/drivers/hwmon/ds1621.c +++ b/drivers/hwmon/ds1621.c @@ -29,6 +29,7 @@ #include <linux/hwmon.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> #include "lm75.h" /* Addresses to scan */ @@ -178,6 +179,18 @@ static DEVICE_ATTR(temp1_input, S_IRUGO , show_temp, NULL); static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO , show_temp_min, set_temp_min); static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); +static struct attribute *ds1621_attributes[] = { + &dev_attr_temp1_input.attr, + &dev_attr_temp1_min.attr, + &dev_attr_temp1_max.attr, + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group ds1621_group = { + .attrs = ds1621_attributes, +}; + static int ds1621_attach_adapter(struct i2c_adapter *adapter) { @@ -253,21 +266,19 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address, ds1621_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &ds1621_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file(&new_client->dev, &dev_attr_alarms); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_min); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - return 0; -/* OK, this is not exactly good programming practice, usually. But it is - very code-efficient in this case. */ + exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &ds1621_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -282,6 +293,7 @@ static int ds1621_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &ds1621_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index fd72440faf7..de17a72149d 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c @@ -1,7 +1,7 @@ /* * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated * hardware monitoring features - * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org> * * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates * complete hardware monitoring features: voltage, fan and temperature @@ -31,6 +31,7 @@ #include <linux/hwmon-sysfs.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> #include <asm/io.h> static struct platform_device *pdev; @@ -147,7 +148,7 @@ struct f71805f_data { u8 temp_high[3]; u8 temp_hyst[3]; u8 temp_mode; - u8 alarms[3]; + unsigned long alarms; }; static inline long in_from_reg(u8 reg) @@ -311,10 +312,9 @@ static struct f71805f_data *f71805f_update_device(struct device *dev) data->temp[nr] = f71805f_read8(data, F71805F_REG_TEMP(nr)); } - for (nr = 0; nr < 3; nr++) { - data->alarms[nr] = f71805f_read8(data, - F71805F_REG_STATUS(nr)); - } + data->alarms = f71805f_read8(data, F71805F_REG_STATUS(0)) + + (f71805f_read8(data, F71805F_REG_STATUS(1)) << 8) + + (f71805f_read8(data, F71805F_REG_STATUS(2)) << 16); data->last_updated = jiffies; data->valid = 1; @@ -557,8 +557,7 @@ static ssize_t show_alarms_in(struct device *dev, struct device_attribute { struct f71805f_data *data = f71805f_update_device(dev); - return sprintf(buf, "%d\n", data->alarms[0] | - ((data->alarms[1] & 0x01) << 8)); + return sprintf(buf, "%lu\n", data->alarms & 0x1ff); } static ssize_t show_alarms_fan(struct device *dev, struct device_attribute @@ -566,7 +565,7 @@ static ssize_t show_alarms_fan(struct device *dev, struct device_attribute { struct f71805f_data *data = f71805f_update_device(dev); - return sprintf(buf, "%d\n", data->alarms[2] & 0x07); + return sprintf(buf, "%lu\n", (data->alarms >> 16) & 0x07); } static ssize_t show_alarms_temp(struct device *dev, struct device_attribute @@ -574,7 +573,17 @@ static ssize_t show_alarms_temp(struct device *dev, struct device_attribute { struct f71805f_data *data = f71805f_update_device(dev); - return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07); + return sprintf(buf, "%lu\n", (data->alarms >> 11) & 0x07); +} + +static ssize_t show_alarm(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct f71805f_data *data = f71805f_update_device(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int bitnr = attr->index; + + return sprintf(buf, "%lu\n", (data->alarms >> bitnr) & 1); } static ssize_t show_name(struct device *dev, struct device_attribute @@ -585,88 +594,189 @@ static ssize_t show_name(struct device *dev, struct device_attribute return sprintf(buf, "%s\n", data->name); } -static struct device_attribute f71805f_dev_attr[] = { - __ATTR(in0_input, S_IRUGO, show_in0, NULL), - __ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max), - __ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min), - __ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL), - __ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL), - __ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL), - __ATTR(name, S_IRUGO, show_name, NULL), +static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL); +static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max); +static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min); +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1); +static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, + show_in_max, set_in_max, 1); +static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR, + show_in_min, set_in_min, 1); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2); +static SENSOR_DEVICE_ATTR(in2_max, S_IRUGO | S_IWUSR, + show_in_max, set_in_max, 2); +static SENSOR_DEVICE_ATTR(in2_min, S_IRUGO | S_IWUSR, + show_in_min, set_in_min, 2); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3); +static SENSOR_DEVICE_ATTR(in3_max, S_IRUGO | S_IWUSR, + show_in_max, set_in_max, 3); +static SENSOR_DEVICE_ATTR(in3_min, S_IRUGO | S_IWUSR, + show_in_min, set_in_min, 3); +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4); +static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR, + show_in_max, set_in_max, 4); +static SENSOR_DEVICE_ATTR(in4_min, S_IRUGO | S_IWUSR, + show_in_min, set_in_min, 4); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 5); +static SENSOR_DEVICE_ATTR(in5_max, S_IRUGO | S_IWUSR, + show_in_max, set_in_max, 5); +static SENSOR_DEVICE_ATTR(in5_min, S_IRUGO | S_IWUSR, + show_in_min, set_in_min, 5); +static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 6); +static SENSOR_DEVICE_ATTR(in6_max, S_IRUGO | S_IWUSR, + show_in_max, set_in_max, 6); +static SENSOR_DEVICE_ATTR(in6_min, S_IRUGO | S_IWUSR, + show_in_min, set_in_min, 6); +static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 7); +static SENSOR_DEVICE_ATTR(in7_max, S_IRUGO | S_IWUSR, + show_in_max, set_in_max, 7); +static SENSOR_DEVICE_ATTR(in7_min, S_IRUGO | S_IWUSR, + show_in_min, set_in_min, 7); +static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 8); +static SENSOR_DEVICE_ATTR(in8_max, S_IRUGO | S_IWUSR, + show_in_max, set_in_max, 8); +static SENSOR_DEVICE_ATTR(in8_min, S_IRUGO | S_IWUSR, + show_in_min, set_in_min, 8); + +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); +static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, + show_fan_min, set_fan_min, 0); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); +static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR, + show_fan_min, set_fan_min, 1); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); +static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR, + show_fan_min, set_fan_min, 2); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, + show_temp_max, set_temp_max, 0); +static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, + show_temp_hyst, set_temp_hyst, 0); +static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, + show_temp_max, set_temp_max, 1); +static SENSOR_DEVICE_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, + show_temp_hyst, set_temp_hyst, 1); +static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); +static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR, + show_temp_max, set_temp_max, 2); +static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, + show_temp_hyst, set_temp_hyst, 2); +static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2); + +static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 5); +static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 7); +static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 11); +static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 12); +static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13); +static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 16); +static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 17); +static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 18); +static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL); +static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL); +static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL); + +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + +static struct attribute *f71805f_attributes[] = { + &dev_attr_in0_input.attr, + &dev_attr_in0_max.attr, + &dev_attr_in0_min.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in5_max.dev_attr.attr, + &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in6_max.dev_attr.attr, + &sensor_dev_attr_in6_min.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in7_max.dev_attr.attr, + &sensor_dev_attr_in7_min.dev_attr.attr, + &sensor_dev_attr_in8_input.dev_attr.attr, + &sensor_dev_attr_in8_max.dev_attr.attr, + &sensor_dev_attr_in8_min.dev_attr.attr, + + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp1_type.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_type.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_type.dev_attr.attr, + + &sensor_dev_attr_in0_alarm.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, + &sensor_dev_attr_in3_alarm.dev_attr.attr, + &sensor_dev_attr_in4_alarm.dev_attr.attr, + &sensor_dev_attr_in5_alarm.dev_attr.attr, + &sensor_dev_attr_in6_alarm.dev_attr.attr, + &sensor_dev_attr_in7_alarm.dev_attr.attr, + &sensor_dev_attr_in8_alarm.dev_attr.attr, + &dev_attr_alarms_in.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, + &dev_attr_alarms_temp.attr, + &dev_attr_alarms_fan.attr, + + &dev_attr_name.attr, + NULL }; -static struct sensor_device_attribute f71805f_sensor_attr[] = { - SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), - SENSOR_ATTR(in1_max, S_IRUGO | S_IWUSR, - show_in_max, set_in_max, 1), - SENSOR_ATTR(in1_min, S_IRUGO | S_IWUSR, - show_in_min, set_in_min, 1), - SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), - SENSOR_ATTR(in2_max, S_IRUGO | S_IWUSR, - show_in_max, set_in_max, 2), - SENSOR_ATTR(in2_min, S_IRUGO | S_IWUSR, - show_in_min, set_in_min, 2), - SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), - SENSOR_ATTR(in3_max, S_IRUGO | S_IWUSR, - show_in_max, set_in_max, 3), - SENSOR_ATTR(in3_min, S_IRUGO | S_IWUSR, - show_in_min, set_in_min, 3), - SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), - SENSOR_ATTR(in4_max, S_IRUGO | S_IWUSR, - show_in_max, set_in_max, 4), - SENSOR_ATTR(in4_min, S_IRUGO | S_IWUSR, - show_in_min, set_in_min, 4), - SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), - SENSOR_ATTR(in5_max, S_IRUGO | S_IWUSR, - show_in_max, set_in_max, 5), - SENSOR_ATTR(in5_min, S_IRUGO | S_IWUSR, - show_in_min, set_in_min, 5), - SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), - SENSOR_ATTR(in6_max, S_IRUGO | S_IWUSR, - show_in_max, set_in_max, 6), - SENSOR_ATTR(in6_min, S_IRUGO | S_IWUSR, - show_in_min, set_in_min, 6), - SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), - SENSOR_ATTR(in7_max, S_IRUGO | S_IWUSR, - show_in_max, set_in_max, 7), - SENSOR_ATTR(in7_min, S_IRUGO | S_IWUSR, - show_in_min, set_in_min, 7), - SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), - SENSOR_ATTR(in8_max, S_IRUGO | S_IWUSR, - show_in_max, set_in_max, 8), - SENSOR_ATTR(in8_min, S_IRUGO | S_IWUSR, - show_in_min, set_in_min, 8), - - SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0), - SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, - show_temp_max, set_temp_max, 0), - SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, - show_temp_hyst, set_temp_hyst, 0), - SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), - SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1), - SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, - show_temp_max, set_temp_max, 1), - SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, - show_temp_hyst, set_temp_hyst, 1), - SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), - SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2), - SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, - show_temp_max, set_temp_max, 2), - SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, - show_temp_hyst, set_temp_hyst, 2), - SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), +static const struct attribute_group f71805f_group = { + .attrs = f71805f_attributes, }; -static struct sensor_device_attribute f71805f_fan_attr[] = { - SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), - SENSOR_ATTR(fan1_min, S_IRUGO | S_IWUSR, - show_fan_min, set_fan_min, 0), - SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), - SENSOR_ATTR(fan2_min, S_IRUGO | S_IWUSR, - show_fan_min, set_fan_min, 1), - SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), - SENSOR_ATTR(fan3_min, S_IRUGO | S_IWUSR, - show_fan_min, set_fan_min, 2), +static struct attribute *f71805f_attributes_fan[3][4] = { + { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_alarm.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan2_alarm.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan3_alarm.dev_attr.attr, + NULL + } +}; + +static const struct attribute_group f71805f_group_fan[3] = { + { .attrs = f71805f_attributes_fan[0] }, + { .attrs = f71805f_attributes_fan[1] }, + { .attrs = f71805f_attributes_fan[2] }, }; /* @@ -714,43 +824,35 @@ static int __devinit f71805f_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); - data->class_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - dev_err(&pdev->dev, "Class registration failed (%d)\n", err); - goto exit_free; - } - /* Initialize the F71805F chip */ f71805f_init_device(data); /* Register sysfs interface files */ - for (i = 0; i < ARRAY_SIZE(f71805f_dev_attr); i++) { - err = device_create_file(&pdev->dev, &f71805f_dev_attr[i]); - if (err) - goto exit_class; - } - for (i = 0; i < ARRAY_SIZE(f71805f_sensor_attr); i++) { - err = device_create_file(&pdev->dev, - &f71805f_sensor_attr[i].dev_attr); - if (err) - goto exit_class; - } - for (i = 0; i < ARRAY_SIZE(f71805f_fan_attr); i++) { - if (!(data->fan_enabled & (1 << (i / 2)))) + if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group))) + goto exit_free; + for (i = 0; i < 3; i++) { + if (!(data->fan_enabled & (1 << i))) continue; - err = device_create_file(&pdev->dev, - &f71805f_fan_attr[i].dev_attr); - if (err) - goto exit_class; + if ((err = sysfs_create_group(&pdev->dev.kobj, + &f71805f_group_fan[i]))) + goto exit_remove_files; + } + + data->class_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + dev_err(&pdev->dev, "Class registration failed (%d)\n", err); + goto exit_remove_files; } return 0; -exit_class: - dev_err(&pdev->dev, "Sysfs interface creation failed\n"); - hwmon_device_unregister(data->class_dev); +exit_remove_files: + sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); + for (i = 0; i < 3; i++) + sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]); exit_free: + platform_set_drvdata(pdev, NULL); kfree(data); exit: return err; @@ -759,9 +861,13 @@ exit: static int __devexit f71805f_remove(struct platform_device *pdev) { struct f71805f_data *data = platform_get_drvdata(pdev); + int i; platform_set_drvdata(pdev, NULL); hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&pdev->dev.kobj, &f71805f_group); + for (i = 0; i < 3; i++) + sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_fan[i]); kfree(data); return 0; diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c index 6bc76b40763..19717752cfc 100644 --- a/drivers/hwmon/fscher.c +++ b/drivers/hwmon/fscher.c @@ -34,6 +34,7 @@ #include <linux/hwmon.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> /* * Addresses to scan @@ -240,47 +241,45 @@ sysfs_alarms(FSCHER_REG_EVENTS) sysfs_control(FSCHER_REG_CONTROL) sysfs_watchdog(FSCHER_REG_WDOG_CONTROL, FSCHER_REG_WDOG_STATE, FSCHER_REG_WDOG_PRESET) -#define device_create_file_fan(client, offset) \ -do { \ - device_create_file(&client->dev, &dev_attr_fan##offset##_status); \ - device_create_file(&client->dev, &dev_attr_pwm##offset); \ - device_create_file(&client->dev, &dev_attr_fan##offset##_div); \ - device_create_file(&client->dev, &dev_attr_fan##offset##_input); \ -} while (0) - -#define device_create_file_temp(client, offset) \ -do { \ - device_create_file(&client->dev, &dev_attr_temp##offset##_status); \ - device_create_file(&client->dev, &dev_attr_temp##offset##_input); \ -} while (0) - -#define device_create_file_in(client, offset) \ -do { \ - device_create_file(&client->dev, &dev_attr_in##offset##_input); \ -} while (0) - -#define device_create_file_revision(client) \ -do { \ - device_create_file(&client->dev, &dev_attr_revision); \ -} while (0) - -#define device_create_file_alarms(client) \ -do { \ - device_create_file(&client->dev, &dev_attr_alarms); \ -} while (0) - -#define device_create_file_control(client) \ -do { \ - device_create_file(&client->dev, &dev_attr_control); \ -} while (0) - -#define device_create_file_watchdog(client) \ -do { \ - device_create_file(&client->dev, &dev_attr_watchdog_status); \ - device_create_file(&client->dev, &dev_attr_watchdog_control); \ - device_create_file(&client->dev, &dev_attr_watchdog_preset); \ -} while (0) - +static struct attribute *fscher_attributes[] = { + &dev_attr_revision.attr, + &dev_attr_alarms.attr, + &dev_attr_control.attr, + + &dev_attr_watchdog_status.attr, + &dev_attr_watchdog_control.attr, + &dev_attr_watchdog_preset.attr, + + &dev_attr_in0_input.attr, + &dev_attr_in1_input.attr, + &dev_attr_in2_input.attr, + + &dev_attr_fan1_status.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan1_input.attr, + &dev_attr_pwm1.attr, + &dev_attr_fan2_status.attr, + &dev_attr_fan2_div.attr, + &dev_attr_fan2_input.attr, + &dev_attr_pwm2.attr, + &dev_attr_fan3_status.attr, + &dev_attr_fan3_div.attr, + &dev_attr_fan3_input.attr, + &dev_attr_pwm3.attr, + + &dev_attr_temp1_status.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp2_status.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp3_status.attr, + &dev_attr_temp3_input.attr, + NULL +}; + +static const struct attribute_group fscher_group = { + .attrs = fscher_attributes, +}; + /* * Real code */ @@ -342,31 +341,19 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) fscher_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file_revision(new_client); - device_create_file_alarms(new_client); - device_create_file_control(new_client); - device_create_file_watchdog(new_client); - - device_create_file_in(new_client, 0); - device_create_file_in(new_client, 1); - device_create_file_in(new_client, 2); - - device_create_file_fan(new_client, 1); - device_create_file_fan(new_client, 2); - device_create_file_fan(new_client, 3); - - device_create_file_temp(new_client, 1); - device_create_file_temp(new_client, 2); - device_create_file_temp(new_client, 3); - return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &fscher_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -381,6 +368,7 @@ static int fscher_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &fscher_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 6dc4846b9ee..ea506a77f9c 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c @@ -38,6 +38,7 @@ #include <linux/hwmon.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> /* * Addresses to scan @@ -432,6 +433,44 @@ static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL); static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL); static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL); +static struct attribute *fscpos_attributes[] = { + &dev_attr_event.attr, + &dev_attr_in0_input.attr, + &dev_attr_in1_input.attr, + &dev_attr_in2_input.attr, + + &dev_attr_wdog_control.attr, + &dev_attr_wdog_preset.attr, + &dev_attr_wdog_state.attr, + + &dev_attr_temp1_input.attr, + &dev_attr_temp1_status.attr, + &dev_attr_temp1_reset.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp2_status.attr, + &dev_attr_temp2_reset.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp3_status.attr, + &dev_attr_temp3_reset.attr, + + &dev_attr_fan1_input.attr, + &dev_attr_fan1_status.attr, + &dev_attr_fan1_ripple.attr, + &dev_attr_pwm1.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_status.attr, + &dev_attr_fan2_ripple.attr, + &dev_attr_pwm2.attr, + &dev_attr_fan3_input.attr, + &dev_attr_fan3_status.attr, + &dev_attr_fan3_ripple.attr, + NULL +}; + +static const struct attribute_group fscpos_group = { + .attrs = fscpos_attributes, +}; + static int fscpos_attach_adapter(struct i2c_adapter *adapter) { if (!(adapter->class & I2C_CLASS_HWMON)) @@ -497,42 +536,19 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file(&new_client->dev, &dev_attr_event); - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_wdog_control); - device_create_file(&new_client->dev, &dev_attr_wdog_preset); - device_create_file(&new_client->dev, &dev_attr_wdog_state); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_status); - device_create_file(&new_client->dev, &dev_attr_temp1_reset); - device_create_file(&new_client->dev, &dev_attr_temp2_input); - device_create_file(&new_client->dev, &dev_attr_temp2_status); - device_create_file(&new_client->dev, &dev_attr_temp2_reset); - device_create_file(&new_client->dev, &dev_attr_temp3_input); - device_create_file(&new_client->dev, &dev_attr_temp3_status); - device_create_file(&new_client->dev, &dev_attr_temp3_reset); - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan1_status); - device_create_file(&new_client->dev, &dev_attr_fan1_ripple); - device_create_file(&new_client->dev, &dev_attr_pwm1); - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan2_status); - device_create_file(&new_client->dev, &dev_attr_fan2_ripple); - device_create_file(&new_client->dev, &dev_attr_pwm2); - device_create_file(&new_client->dev, &dev_attr_fan3_input); - device_create_file(&new_client->dev, &dev_attr_fan3_status); - device_create_file(&new_client->dev, &dev_attr_fan3_ripple); - return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &fscpos_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -547,6 +563,7 @@ static int fscpos_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &fscpos_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 6606aabdb49..c103640455a 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -44,6 +44,7 @@ #include <linux/hwmon.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; @@ -340,6 +341,42 @@ static DEVICE_ATTR(beep_enable, S_IWUSR|S_IRUGO, static DEVICE_ATTR(beep_mask, S_IWUSR|S_IRUGO, show_beep_mask, set_beep_mask); +static struct attribute *gl518_attributes[] = { + &dev_attr_in0_input.attr, + &dev_attr_in1_input.attr, + &dev_attr_in2_input.attr, + &dev_attr_in3_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in1_min.attr, + &dev_attr_in2_min.attr, + &dev_attr_in3_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_max.attr, + + &dev_attr_fan1_auto.attr, + &dev_attr_fan1_input.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_div.attr, + + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + + &dev_attr_alarms.attr, + &dev_attr_beep_enable.attr, + &dev_attr_beep_mask.attr, + NULL +}; + +static const struct attribute_group gl518_group = { + .attrs = gl518_attributes, +}; + /* * Real code */ @@ -420,43 +457,19 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) gl518_init_client((struct i2c_client *) new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &gl518_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_max); - device_create_file(&new_client->dev, &dev_attr_fan1_auto); - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_fan1_div); - device_create_file(&new_client->dev, &dev_attr_fan2_div); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); - device_create_file(&new_client->dev, &dev_attr_alarms); - device_create_file(&new_client->dev, &dev_attr_beep_enable); - device_create_file(&new_client->dev, &dev_attr_beep_mask); - return 0; -/* OK, this is not exactly good programming practice, usually. But it is - very code-efficient in this case. */ - +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &gl518_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -490,6 +503,7 @@ static int gl518_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &gl518_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 14e810f3c2c..ebe7b9aaa91 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -30,6 +30,7 @@ #include <linux/hwmon-vid.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> /* Type of the extra sensor */ static unsigned short extra_sensor_type; @@ -190,55 +191,29 @@ static DEVICE_ATTR(type##item, S_IRUGO, get_##type##0##item, NULL); #define sysfs_vid(n) \ sysfs_ro_n(cpu, n, _vid, GL520_REG_VID_INPUT) -#define device_create_file_vid(client, n) \ -device_create_file(&client->dev, &dev_attr_cpu##n##_vid) - #define sysfs_in(n) \ sysfs_ro_n(in, n, _input, GL520_REG_IN##n##INPUT) \ sysfs_rw_n(in, n, _min, GL520_REG_IN##n##_MIN) \ sysfs_rw_n(in, n, _max, GL520_REG_IN##n##_MAX) \ -#define device_create_file_in(client, n) \ -({device_create_file(&client->dev, &dev_attr_in##n##_input); \ -device_create_file(&client->dev, &dev_attr_in##n##_min); \ -device_create_file(&client->dev, &dev_attr_in##n##_max);}) - #define sysfs_fan(n) \ sysfs_ro_n(fan, n, _input, GL520_REG_FAN_INPUT) \ sysfs_rw_n(fan, n, _min, GL520_REG_FAN_MIN) \ sysfs_rw_n(fan, n, _div, GL520_REG_FAN_DIV) -#define device_create_file_fan(client, n) \ -({device_create_file(&client->dev, &dev_attr_fan##n##_input); \ -device_create_file(&client->dev, &dev_attr_fan##n##_min); \ -device_create_file(&client->dev, &dev_attr_fan##n##_div);}) - #define sysfs_fan_off(n) \ sysfs_rw_n(fan, n, _off, GL520_REG_FAN_OFF) \ -#define device_create_file_fan_off(client, n) \ -device_create_file(&client->dev, &dev_attr_fan##n##_off) - #define sysfs_temp(n) \ sysfs_ro_n(temp, n, _input, GL520_REG_TEMP##n##_INPUT) \ sysfs_rw_n(temp, n, _max, GL520_REG_TEMP##n##_MAX) \ sysfs_rw_n(temp, n, _max_hyst, GL520_REG_TEMP##n##_MAX_HYST) -#define device_create_file_temp(client, n) \ -({device_create_file(&client->dev, &dev_attr_temp##n##_input); \ -device_create_file(&client->dev, &dev_attr_temp##n##_max); \ -device_create_file(&client->dev, &dev_attr_temp##n##_max_hyst);}) - #define sysfs_alarms() \ sysfs_ro(alarms, , GL520_REG_ALARMS) \ sysfs_rw(beep_enable, , GL520_REG_BEEP_ENABLE) \ sysfs_rw(beep_mask, , GL520_REG_BEEP_MASK) -#define device_create_file_alarms(client) \ -({device_create_file(&client->dev, &dev_attr_alarms); \ -device_create_file(&client->dev, &dev_attr_beep_enable); \ -device_create_file(&client->dev, &dev_attr_beep_mask);}) - sysfs_vid(0) @@ -511,6 +486,59 @@ static ssize_t set_beep_mask(struct i2c_client *client, struct gl520_data *data, return count; } +static struct attribute *gl520_attributes[] = { + &dev_attr_cpu0_vid.attr, + + &dev_attr_in0_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_input.attr, + &dev_attr_in1_min.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_input.attr, + &dev_attr_in2_min.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_input.attr, + &dev_attr_in3_min.attr, + &dev_attr_in3_max.attr, + + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan1_off.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + + &dev_attr_alarms.attr, + &dev_attr_beep_enable.attr, + &dev_attr_beep_mask.attr, + NULL +}; + +static const struct attribute_group gl520_group = { + .attrs = gl520_attributes, +}; + +static struct attribute *gl520_attributes_opt[] = { + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + + &dev_attr_temp2_input.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp2_max_hyst.attr, + NULL +}; + +static const struct attribute_group gl520_group_opt = { + .attrs = gl520_attributes_opt, +}; + /* * Real code @@ -572,33 +600,39 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) gl520_init_client(new_client); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&new_client->dev.kobj, &gl520_group))) goto exit_detach; - } - - device_create_file_vid(new_client, 0); - device_create_file_in(new_client, 0); - device_create_file_in(new_client, 1); - device_create_file_in(new_client, 2); - device_create_file_in(new_client, 3); - if (!data->two_temps) - device_create_file_in(new_client, 4); - - device_create_file_fan(new_client, 1); - device_create_file_fan(new_client, 2); - device_create_file_fan_off(new_client, 1); + if (data->two_temps) { + if ((err = device_create_file(&new_client->dev, + &dev_attr_temp2_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp2_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp2_max_hyst))) + goto exit_remove_files; + } else { + if ((err = device_create_file(&new_client->dev, + &dev_attr_in4_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in4_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in4_max))) + goto exit_remove_files; + } - device_create_file_temp(new_client, 1); - if (data->two_temps) - device_create_file_temp(new_client, 2); - device_create_file_alarms(new_client); + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove_files; + } return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &gl520_group); + sysfs_remove_group(&new_client->dev.kobj, &gl520_group_opt); exit_detach: i2c_detach_client(new_client); exit_free: @@ -652,6 +686,8 @@ static int gl520_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &gl520_group); + sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c index 42b632889dd..8e7b5607f5a 100644 --- a/drivers/hwmon/hdaps.c +++ b/drivers/hwmon/hdaps.c @@ -587,7 +587,9 @@ static int __init hdaps_init(void) input_set_abs_params(hdaps_idev, ABS_Y, -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT); - input_register_device(hdaps_idev); + ret = input_register_device(hdaps_idev); + if (ret) + goto out_idev; /* start up our timer for the input device */ init_timer(&hdaps_timer); @@ -598,6 +600,8 @@ static int __init hdaps_init(void) printk(KERN_INFO "hdaps: driver successfully loaded.\n"); return 0; +out_idev: + input_free_device(hdaps_idev); out_group: sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group); out_device: diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index b0ee5749222..323ef06719c 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -4,10 +4,12 @@ Supports: IT8705F Super I/O chip w/LPC interface IT8712F Super I/O chip w/LPC interface & SMBus + IT8716F Super I/O chip w/LPC interface + IT8718F Super I/O chip w/LPC interface Sis950 A clone of the IT8705F Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> - Largely inspired by lm78.c of the same package + Copyright (C) 2005-2006 Jean Delvare <khali@linux-fr.org> 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 @@ -24,13 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - djg@pdp8.net David Gesswein 7/18/01 - Modified to fix bug with not all alarms enabled. - Added ability to read battery voltage and select temperature sensor - type at module load time. -*/ - #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -42,6 +37,7 @@ #include <linux/hwmon-vid.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> #include <asm/io.h> @@ -50,12 +46,13 @@ static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; static unsigned short isa_address; /* Insmod parameters */ -I2C_CLIENT_INSMOD_2(it87, it8712); +I2C_CLIENT_INSMOD_4(it87, it8712, it8716, it8718); #define REG 0x2e /* The register to read/write */ #define DEV 0x07 /* Register: Logical device select */ #define VAL 0x2f /* The value to read/write */ #define PME 0x04 /* The device with the fan registers in it */ +#define GPIO 0x07 /* The device with the IT8718F VID value in it */ #define DEVID 0x20 /* Register: Device ID */ #define DEVREV 0x22 /* Register: Device Revision */ @@ -77,10 +74,10 @@ static int superio_inw(int reg) } static inline void -superio_select(void) +superio_select(int ldn) { outb(DEV, REG); - outb(PME, VAL); + outb(ldn, VAL); } static inline void @@ -99,20 +96,27 @@ superio_exit(void) outb(0x02, VAL); } +/* Logical device 4 registers */ #define IT8712F_DEVID 0x8712 #define IT8705F_DEVID 0x8705 +#define IT8716F_DEVID 0x8716 +#define IT8718F_DEVID 0x8718 #define IT87_ACT_REG 0x30 #define IT87_BASE_REG 0x60 +/* Logical device 7 registers (IT8712F and later) */ +#define IT87_SIO_PINX2_REG 0x2c /* Pin selection */ +#define IT87_SIO_VID_REG 0xfc /* VID value */ + /* Update battery voltage after every reading if true */ static int update_vbat; /* Not all BIOSes properly configure the PWM registers */ static int fix_pwm_polarity; -/* Chip Type */ - +/* Values read from Super-I/O config space */ static u16 chip_type; +static u8 vid_value; /* Many IT87 constants specified below */ @@ -131,13 +135,21 @@ static u16 chip_type; #define IT87_REG_ALARM2 0x02 #define IT87_REG_ALARM3 0x03 +/* The IT8718F has the VID value in a different register, in Super-I/O + configuration space. */ #define IT87_REG_VID 0x0a +/* Warning: register 0x0b is used for something completely different in + new chips/revisions. I suspect only 16-bit tachometer mode will work + for these. */ #define IT87_REG_FAN_DIV 0x0b +#define IT87_REG_FAN_16BIT 0x0c /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */ #define IT87_REG_FAN(nr) (0x0d + (nr)) #define IT87_REG_FAN_MIN(nr) (0x10 + (nr)) +#define IT87_REG_FANX(nr) (0x18 + (nr)) +#define IT87_REG_FANX_MIN(nr) (0x1b + (nr)) #define IT87_REG_FAN_MAIN_CTRL 0x13 #define IT87_REG_FAN_CTL 0x14 #define IT87_REG_PWM(nr) (0x15 + (nr)) @@ -169,7 +181,16 @@ static inline u8 FAN_TO_REG(long rpm, int div) 254); } +static inline u16 FAN16_TO_REG(long rpm) +{ + if (rpm == 0) + return 0xffff; + return SENSORS_LIMIT((1350000 + rpm) / (rpm * 2), 1, 0xfffe); +} + #define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) +/* The divider is fixed to 2 in 16-bit mode */ +#define FAN16_FROM_REG(val) ((val)==0?-1:(val)==0xffff?0:1350000/((val)*2)) #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\ ((val)+500)/1000),-128,127)) @@ -181,7 +202,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) static int DIV_TO_REG(int val) { int answer = 0; - while ((val >>= 1) != 0) + while (answer < 7 && (val >>= 1)) answer++; return answer; } @@ -203,10 +224,11 @@ struct it87_data { unsigned long last_updated; /* In jiffies */ u8 in[9]; /* Register value */ - u8 in_max[9]; /* Register value */ - u8 in_min[9]; /* Register value */ - u8 fan[3]; /* Register value */ - u8 fan_min[3]; /* Register value */ + u8 in_max[8]; /* Register value */ + u8 in_min[8]; /* Register value */ + u8 has_fan; /* Bitfield, fans enabled */ + u16 fan[3]; /* Register values, possibly combined */ + u16 fan_min[3]; /* Register values, possibly combined */ u8 temp[3]; /* Register value */ u8 temp_high[3]; /* Register value */ u8 temp_low[3]; /* Register value */ @@ -545,15 +567,15 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct it87_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10); - int i, min[3]; + unsigned long val = simple_strtoul(buf, NULL, 10); + int min; u8 old; mutex_lock(&data->update_lock); old = it87_read_value(client, IT87_REG_FAN_DIV); - for (i = 0; i < 3; i++) - min[i] = FAN_FROM_REG(data->fan_min[i], DIV_FROM_REG(data->fan_div[i])); + /* Save fan min limit */ + min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); switch (nr) { case 0: @@ -573,10 +595,10 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, val |= 0x1 << 6; it87_write_value(client, IT87_REG_FAN_DIV, val); - for (i = 0; i < 3; i++) { - data->fan_min[i]=FAN_TO_REG(min[i], DIV_FROM_REG(data->fan_div[i])); - it87_write_value(client, IT87_REG_FAN_MIN(i), data->fan_min[i]); - } + /* Restore fan min limit */ + data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]); + mutex_unlock(&data->update_lock); return count; } @@ -657,6 +679,59 @@ show_pwm_offset(1); show_pwm_offset(2); show_pwm_offset(3); +/* A different set of callbacks for 16-bit fans */ +static ssize_t show_fan16(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + struct it87_data *data = it87_update_device(dev); + return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan[nr])); +} + +static ssize_t show_fan16_min(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + struct it87_data *data = it87_update_device(dev); + return sprintf(buf, "%d\n", FAN16_FROM_REG(data->fan_min[nr])); +} + +static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct it87_data *data = i2c_get_clientdata(client); + int val = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + data->fan_min[nr] = FAN16_TO_REG(val); + it87_write_value(client, IT87_REG_FAN_MIN(nr), + data->fan_min[nr] & 0xff); + it87_write_value(client, IT87_REG_FANX_MIN(nr), + data->fan_min[nr] >> 8); + mutex_unlock(&data->update_lock); + return count; +} + +/* We want to use the same sysfs file names as 8-bit fans, but we need + different variable names, so we have to use SENSOR_ATTR instead of + SENSOR_DEVICE_ATTR. */ +#define show_fan16_offset(offset) \ +static struct sensor_device_attribute sensor_dev_attr_fan##offset##_input16 \ + = SENSOR_ATTR(fan##offset##_input, S_IRUGO, \ + show_fan16, NULL, offset - 1); \ +static struct sensor_device_attribute sensor_dev_attr_fan##offset##_min16 \ + = SENSOR_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ + show_fan16_min, set_fan16_min, offset - 1) + +show_fan16_offset(1); +show_fan16_offset(2); +show_fan16_offset(3); + /* Alarms */ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) { @@ -684,8 +759,6 @@ store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf return count; } static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); -#define device_create_file_vrm(client) \ -device_create_file(&client->dev, &dev_attr_vrm) static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) @@ -694,8 +767,88 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); } static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); -#define device_create_file_vid(client) \ -device_create_file(&client->dev, &dev_attr_cpu0_vid) + +static struct attribute *it87_attributes[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in8_input.dev_attr.attr, + &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in6_min.dev_attr.attr, + &sensor_dev_attr_in7_min.dev_attr.attr, + &sensor_dev_attr_in0_max.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in5_max.dev_attr.attr, + &sensor_dev_attr_in6_max.dev_attr.attr, + &sensor_dev_attr_in7_max.dev_attr.attr, + + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp1_type.dev_attr.attr, + &sensor_dev_attr_temp2_type.dev_attr.attr, + &sensor_dev_attr_temp3_type.dev_attr.attr, + + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group it87_group = { + .attrs = it87_attributes, +}; + +static struct attribute *it87_attributes_opt[] = { + &sensor_dev_attr_fan1_input16.dev_attr.attr, + &sensor_dev_attr_fan1_min16.dev_attr.attr, + &sensor_dev_attr_fan2_input16.dev_attr.attr, + &sensor_dev_attr_fan2_min16.dev_attr.attr, + &sensor_dev_attr_fan3_input16.dev_attr.attr, + &sensor_dev_attr_fan3_min16.dev_attr.attr, + + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_div.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan3_div.dev_attr.attr, + + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm2_enable.dev_attr.attr, + &sensor_dev_attr_pwm3_enable.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + + &dev_attr_vrm.attr, + &dev_attr_cpu0_vid.attr, + NULL +}; + +static const struct attribute_group it87_group_opt = { + .attrs = it87_attributes_opt, +}; /* This function is called when: * it87_driver is inserted (when this module is loaded), for each @@ -721,10 +874,12 @@ static int __init it87_find(unsigned short *address) superio_enter(); chip_type = superio_inw(DEVID); if (chip_type != IT8712F_DEVID + && chip_type != IT8716F_DEVID + && chip_type != IT8718F_DEVID && chip_type != IT8705F_DEVID) goto exit; - superio_select(); + superio_select(PME); if (!(superio_inb(IT87_ACT_REG) & 0x01)) { pr_info("it87: Device not activated, skipping\n"); goto exit; @@ -740,6 +895,21 @@ static int __init it87_find(unsigned short *address) pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n", chip_type, *address, superio_inb(DEVREV) & 0x0f); + /* Read GPIO config and VID value from LDN 7 (GPIO) */ + if (chip_type != IT8705F_DEVID) { + int reg; + + superio_select(GPIO); + if (chip_type == it8718) + vid_value = superio_inb(IT87_SIO_VID_REG); + + reg = superio_inb(IT87_SIO_PINX2_REG); + if (reg & (1 << 0)) + pr_info("it87: in3 is VCC (+5V)\n"); + if (reg & (1 << 1)) + pr_info("it87: in7 is VCCH (+5V Stand-By)\n"); + } + exit: superio_exit(); return err; @@ -800,8 +970,19 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) i = it87_read_value(new_client, IT87_REG_CHIPID); if (i == 0x90) { kind = it87; - if ((is_isa) && (chip_type == IT8712F_DEVID)) - kind = it8712; + if (is_isa) { + switch (chip_type) { + case IT8712F_DEVID: + kind = it8712; + break; + case IT8716F_DEVID: + kind = it8716; + break; + case IT8718F_DEVID: + kind = it8718; + break; + } + } } else { if (kind == 0) @@ -818,6 +999,10 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) name = "it87"; } else if (kind == it8712) { name = "it8712"; + } else if (kind == it8716) { + name = "it8716"; + } else if (kind == it8718) { + name = "it8718"; } /* Fill in the remaining client fields and put it into the global list */ @@ -842,76 +1027,103 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) it87_init_client(new_client, data); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&new_client->dev.kobj, &it87_group))) goto ERROR3; + + /* Do not create fan files for disabled fans */ + if (data->type == it8716 || data->type == it8718) { + /* 16-bit tachometers */ + if (data->has_fan & (1 << 0)) { + if ((err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_input16.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_min16.dev_attr))) + goto ERROR4; + } + if (data->has_fan & (1 << 1)) { + if ((err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan2_input16.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan2_min16.dev_attr))) + goto ERROR4; + } + if (data->has_fan & (1 << 2)) { + if ((err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan3_input16.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan3_min16.dev_attr))) + goto ERROR4; + } + } else { + /* 8-bit tachometers with clock divider */ + if (data->has_fan & (1 << 0)) { + if ((err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_input.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_min.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan1_div.dev_attr))) + goto ERROR4; + } + if (data->has_fan & (1 << 1)) { + if ((err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan2_input.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan2_min.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan2_div.dev_attr))) + goto ERROR4; + } + if (data->has_fan & (1 << 2)) { + if ((err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan3_input.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan3_min.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_fan3_div.dev_attr))) + goto ERROR4; + } } - device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp1_type.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr); - device_create_file(&new_client->dev, &dev_attr_alarms); if (enable_pwm_interface) { - device_create_file(&new_client->dev, &sensor_dev_attr_pwm1_enable.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_pwm2_enable.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_pwm3_enable.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_pwm1.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_pwm2.dev_attr); - device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr); + if ((err = device_create_file(&new_client->dev, + &sensor_dev_attr_pwm1_enable.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_pwm2_enable.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_pwm3_enable.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_pwm1.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_pwm2.dev_attr)) + || (err = device_create_file(&new_client->dev, + &sensor_dev_attr_pwm3.dev_attr))) + goto ERROR4; } - if (data->type == it8712) { + if (data->type == it8712 || data->type == it8716 + || data->type == it8718) { data->vrm = vid_which_vrm(); - device_create_file_vrm(new_client); - device_create_file_vid(new_client); + /* VID reading from Super-I/O config space if available */ + data->vid = vid_value; + if ((err = device_create_file(&new_client->dev, + &dev_attr_vrm)) + || (err = device_create_file(&new_client->dev, + &dev_attr_cpu0_vid))) + goto ERROR4; + } + + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto ERROR4; } return 0; +ERROR4: + sysfs_remove_group(&new_client->dev.kobj, &it87_group); + sysfs_remove_group(&new_client->dev.kobj, &it87_group_opt); ERROR3: i2c_detach_client(new_client); ERROR2: @@ -929,6 +1141,8 @@ static int it87_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &it87_group); + sysfs_remove_group(&client->dev.kobj, &it87_group_opt); if ((err = i2c_detach_client(client))) return err; @@ -1045,6 +1259,22 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) data->manual_pwm_ctl[i] = 0xff; } + /* Some chips seem to have default value 0xff for all limit + * registers. For low voltage limits it makes no sense and triggers + * alarms, so change to 0 instead. For high temperature limits, it + * means -1 degree C, which surprisingly doesn't trigger an alarm, + * but is still confusing, so change to 127 degrees C. */ + for (i = 0; i < 8; i++) { + tmp = it87_read_value(client, IT87_REG_VIN_MIN(i)); + if (tmp == 0xff) + it87_write_value(client, IT87_REG_VIN_MIN(i), 0); + } + for (i = 0; i < 3; i++) { + tmp = it87_read_value(client, IT87_REG_TEMP_HIGH(i)); + if (tmp == 0xff) + it87_write_value(client, IT87_REG_TEMP_HIGH(i), 127); + } + /* Check if temperature channnels are reset manually or by some reason */ tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE); if ((tmp & 0x3f) == 0) { @@ -1068,6 +1298,18 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data) data->fan_main_ctrl |= 0x70; it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl); } + data->has_fan = (data->fan_main_ctrl >> 4) & 0x07; + + /* Set tachometers to 16-bit mode if needed */ + if (data->type == it8716 || data->type == it8718) { + tmp = it87_read_value(client, IT87_REG_FAN_16BIT); + if (~tmp & 0x07 & data->has_fan) { + dev_dbg(&client->dev, + "Setting fan1-3 to 16-bit mode\n"); + it87_write_value(client, IT87_REG_FAN_16BIT, + tmp | 0x07); + } + } /* Set current fan mode registers and the default settings for the * other mode registers */ @@ -1118,18 +1360,26 @@ static struct it87_data *it87_update_device(struct device *dev) data->in_max[i] = it87_read_value(client, IT87_REG_VIN_MAX(i)); } + /* in8 (battery) has no limit registers */ data->in[8] = it87_read_value(client, IT87_REG_VIN(8)); - /* Temperature sensor doesn't have limit registers, set - to min and max value */ - data->in_min[8] = 0; - data->in_max[8] = 255; for (i = 0; i < 3; i++) { - data->fan[i] = - it87_read_value(client, IT87_REG_FAN(i)); + /* Skip disabled fans */ + if (!(data->has_fan & (1 << i))) + continue; + data->fan_min[i] = it87_read_value(client, IT87_REG_FAN_MIN(i)); + data->fan[i] = it87_read_value(client, + IT87_REG_FAN(i)); + /* Add high byte if in 16-bit mode */ + if (data->type == it8716 || data->type == it8718) { + data->fan[i] |= it87_read_value(client, + IT87_REG_FANX(i)) << 8; + data->fan_min[i] |= it87_read_value(client, + IT87_REG_FANX_MIN(i)) << 8; + } } for (i = 0; i < 3; i++) { data->temp[i] = @@ -1140,10 +1390,14 @@ static struct it87_data *it87_update_device(struct device *dev) it87_read_value(client, IT87_REG_TEMP_LOW(i)); } - i = it87_read_value(client, IT87_REG_FAN_DIV); - data->fan_div[0] = i & 0x07; - data->fan_div[1] = (i >> 3) & 0x07; - data->fan_div[2] = (i & 0x40) ? 3 : 1; + /* Newer chips don't have clock dividers */ + if ((data->has_fan & 0x07) && data->type != it8716 + && data->type != it8718) { + i = it87_read_value(client, IT87_REG_FAN_DIV); + data->fan_div[0] = i & 0x07; + data->fan_div[1] = (i >> 3) & 0x07; + data->fan_div[2] = (i & 0x40) ? 3 : 1; + } data->alarms = it87_read_value(client, IT87_REG_ALARM1) | @@ -1153,9 +1407,11 @@ static struct it87_data *it87_update_device(struct device *dev) data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE); /* The 8705 does not have VID capability */ - if (data->type == it8712) { + if (data->type == it8712 || data->type == it8716) { data->vid = it87_read_value(client, IT87_REG_VID); - data->vid &= 0x1f; + /* The older IT8712F revisions had only 5 VID pins, + but we assume it is always safe to read 6 bits. */ + data->vid &= 0x3f; } data->last_updated = jiffies; data->valid = 1; @@ -1193,8 +1449,9 @@ static void __exit sm_it87_exit(void) } -MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>"); -MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver"); +MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>, " + "Jean Delvare <khali@linux-fr.org>"); +MODULE_DESCRIPTION("IT8705F/8712F/8716F/8718F, SiS950 driver"); module_param(update_vbat, bool, 0); MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); module_param(fix_pwm_polarity, bool, 0); diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c new file mode 100644 index 00000000000..f58b64ed09e --- /dev/null +++ b/drivers/hwmon/k8temp.c @@ -0,0 +1,294 @@ +/* + * k8temp.c - Linux kernel module for hardware monitoring + * + * Copyright (C) 2006 Rudolf Marek <r.marek@sh.cvut.cz> + * + * Inspired from the w83785 and amd756 drivers. + * + * 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/module.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/pci.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/err.h> +#include <linux/mutex.h> + +#define TEMP_FROM_REG(val) (((((val) >> 16) & 0xff) - 49) * 1000) +#define REG_TEMP 0xe4 +#define SEL_PLACE 0x40 +#define SEL_CORE 0x04 + +struct k8temp_data { + struct class_device *class_dev; + struct mutex update_lock; + const char *name; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + + /* registers values */ + u8 sensorsp; /* sensor presence bits - SEL_CORE & SEL_PLACE */ + u32 temp[2][2]; /* core, place */ +}; + +static struct k8temp_data *k8temp_update_device(struct device *dev) +{ + struct k8temp_data *data = dev_get_drvdata(dev); + struct pci_dev *pdev = to_pci_dev(dev); + u8 tmp; + + mutex_lock(&data->update_lock); + + if (!data->valid + || time_after(jiffies, data->last_updated + HZ)) { + pci_read_config_byte(pdev, REG_TEMP, &tmp); + tmp &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ + pci_write_config_byte(pdev, REG_TEMP, tmp); + pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]); + + if (data->sensorsp & SEL_PLACE) { + tmp |= SEL_PLACE; /* Select sensor 1, core0 */ + pci_write_config_byte(pdev, REG_TEMP, tmp); + pci_read_config_dword(pdev, REG_TEMP, + &data->temp[0][1]); + } + + if (data->sensorsp & SEL_CORE) { + tmp &= ~SEL_PLACE; /* Select sensor 0, core1 */ + tmp |= SEL_CORE; + pci_write_config_byte(pdev, REG_TEMP, tmp); + pci_read_config_dword(pdev, REG_TEMP, + &data->temp[1][0]); + + if (data->sensorsp & SEL_PLACE) { + tmp |= SEL_PLACE; /* Select sensor 1, core1 */ + pci_write_config_byte(pdev, REG_TEMP, tmp); + pci_read_config_dword(pdev, REG_TEMP, + &data->temp[1][1]); + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + return data; +} + +/* + * Sysfs stuff + */ + +static ssize_t show_name(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct k8temp_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", data->name); +} + + +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute_2 *attr = + to_sensor_dev_attr_2(devattr); + int core = attr->nr; + int place = attr->index; + struct k8temp_data *data = k8temp_update_device(dev); + + return sprintf(buf, "%d\n", + TEMP_FROM_REG(data->temp[core][place])); +} + +/* core, place */ + +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1); +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 1, 0); +static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1); +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + +static struct pci_device_id k8temp_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, + { 0 }, +}; + +MODULE_DEVICE_TABLE(pci, k8temp_ids); + +static int __devinit k8temp_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int err; + u8 scfg; + u32 temp; + struct k8temp_data *data; + u32 cpuid = cpuid_eax(1); + + /* this feature should be available since SH-C0 core */ + if ((cpuid == 0xf40) || (cpuid == 0xf50) || (cpuid == 0xf51)) { + err = -ENODEV; + goto exit; + } + + if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + pci_read_config_byte(pdev, REG_TEMP, &scfg); + scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ + pci_write_config_byte(pdev, REG_TEMP, scfg); + pci_read_config_byte(pdev, REG_TEMP, &scfg); + + if (scfg & (SEL_PLACE | SEL_CORE)) { + dev_err(&pdev->dev, "Configuration bit(s) stuck at 1!\n"); + err = -ENODEV; + goto exit_free; + } + + scfg |= (SEL_PLACE | SEL_CORE); + pci_write_config_byte(pdev, REG_TEMP, scfg); + + /* now we know if we can change core and/or sensor */ + pci_read_config_byte(pdev, REG_TEMP, &data->sensorsp); + + if (data->sensorsp & SEL_PLACE) { + scfg &= ~SEL_CORE; /* Select sensor 1, core0 */ + pci_write_config_byte(pdev, REG_TEMP, scfg); + pci_read_config_dword(pdev, REG_TEMP, &temp); + scfg |= SEL_CORE; /* prepare for next selection */ + if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is not likely */ + data->sensorsp &= ~SEL_PLACE; + } + + if (data->sensorsp & SEL_CORE) { + scfg &= ~SEL_PLACE; /* Select sensor 0, core1 */ + pci_write_config_byte(pdev, REG_TEMP, scfg); + pci_read_config_dword(pdev, REG_TEMP, &temp); + if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is not likely */ + data->sensorsp &= ~SEL_CORE; + } + + data->name = "k8temp"; + mutex_init(&data->update_lock); + dev_set_drvdata(&pdev->dev, data); + + /* Register sysfs hooks */ + err = device_create_file(&pdev->dev, + &sensor_dev_attr_temp1_input.dev_attr); + if (err) + goto exit_remove; + + /* sensor can be changed and reports something */ + if (data->sensorsp & SEL_PLACE) { + err = device_create_file(&pdev->dev, + &sensor_dev_attr_temp2_input.dev_attr); + if (err) + goto exit_remove; + } + + /* core can be changed and reports something */ + if (data->sensorsp & SEL_CORE) { + err = device_create_file(&pdev->dev, + &sensor_dev_attr_temp3_input.dev_attr); + if (err) + goto exit_remove; + if (data->sensorsp & SEL_PLACE) + err = device_create_file(&pdev->dev, + &sensor_dev_attr_temp4_input. + dev_attr); + if (err) + goto exit_remove; + } + + err = device_create_file(&pdev->dev, &dev_attr_name); + if (err) + goto exit_remove; + + data->class_dev = hwmon_device_register(&pdev->dev); + + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove; + } + + return 0; + +exit_remove: + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp1_input.dev_attr); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp2_input.dev_attr); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp3_input.dev_attr); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp4_input.dev_attr); + device_remove_file(&pdev->dev, &dev_attr_name); +exit_free: + dev_set_drvdata(&pdev->dev, NULL); + kfree(data); +exit: + return err; +} + +static void __devexit k8temp_remove(struct pci_dev *pdev) +{ + struct k8temp_data *data = dev_get_drvdata(&pdev->dev); + + hwmon_device_unregister(data->class_dev); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp1_input.dev_attr); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp2_input.dev_attr); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp3_input.dev_attr); + device_remove_file(&pdev->dev, + &sensor_dev_attr_temp4_input.dev_attr); + device_remove_file(&pdev->dev, &dev_attr_name); + dev_set_drvdata(&pdev->dev, NULL); + kfree(data); +} + +static struct pci_driver k8temp_driver = { + .name = "k8temp", + .id_table = k8temp_ids, + .probe = k8temp_probe, + .remove = __devexit_p(k8temp_remove), +}; + +static int __init k8temp_init(void) +{ + return pci_register_driver(&k8temp_driver); +} + +static void __exit k8temp_exit(void) +{ + pci_unregister_driver(&k8temp_driver); +} + +MODULE_AUTHOR("Rudolf Marek <r.marek@sh.cvut.cz>"); +MODULE_DESCRIPTION("AMD K8 core temperature monitor"); +MODULE_LICENSE("GPL"); + +module_init(k8temp_init) +module_exit(k8temp_exit) diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index 071f0fc6ade..d69f3cf0712 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c @@ -1,7 +1,7 @@ /* * lm63.c - driver for the National Semiconductor LM63 temperature sensor * with integrated fan control - * Copyright (C) 2004-2005 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2004-2006 Jean Delvare <khali@linux-fr.org> * Based on the lm90 driver. * * The LM63 is a sensor chip made by National Semiconductor. It measures @@ -46,6 +46,7 @@ #include <linux/hwmon.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> /* * Addresses to scan @@ -330,6 +331,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, return sprintf(buf, "%u\n", data->alarms); } +static ssize_t show_alarm(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct lm63_data *data = lm63_update_device(dev); + int bitnr = attr->index; + + return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); +} + static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan, set_fan, 1); @@ -350,8 +361,52 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2); static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, set_temp2_crit_hyst); +/* Individual alarm files */ +static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); +/* Raw alarm file for compatibility */ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static struct attribute *lm63_attributes[] = { + &dev_attr_pwm1.attr, + &dev_attr_pwm1_enable.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &dev_attr_temp2_crit_hyst.attr, + + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_input_fault.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group lm63_group = { + .attrs = lm63_attributes, +}; + +static struct attribute *lm63_attributes_fan1[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + + &sensor_dev_attr_fan1_min_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group lm63_group_fan1 = { + .attrs = lm63_attributes_fan1, +}; + /* * Real code */ @@ -438,37 +493,26 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) lm63_init_client(new_client); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&new_client->dev.kobj, + &lm63_group))) goto exit_detach; + if (data->config & 0x04) { /* tachometer enabled */ + if ((err = sysfs_create_group(&new_client->dev.kobj, + &lm63_group_fan1))) + goto exit_remove_files; } - if (data->config & 0x04) { /* tachometer enabled */ - device_create_file(&new_client->dev, - &sensor_dev_attr_fan1_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_fan1_min.dev_attr); + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove_files; } - device_create_file(&new_client->dev, &dev_attr_pwm1); - device_create_file(&new_client->dev, &dev_attr_pwm1_enable); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_crit.dev_attr); - device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst); - device_create_file(&new_client->dev, &dev_attr_alarms); return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &lm63_group); + sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); exit_detach: i2c_detach_client(new_client); exit_free: @@ -518,6 +562,8 @@ static int lm63_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm63_group); + sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index fc25b90ec24..7c65b8bb6d7 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c @@ -112,6 +112,18 @@ static int lm75_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, lm75_detect); } +static struct attribute *lm75_attributes[] = { + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + + NULL +}; + +static const struct attribute_group lm75_group = { + .attrs = lm75_attributes, +}; + /* This function is called by i2c_probe */ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) { @@ -199,18 +211,19 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) lm75_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove; } - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - return 0; +exit_remove: + sysfs_remove_group(&new_client->dev.kobj, &lm75_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -223,6 +236,7 @@ static int lm75_detach_client(struct i2c_client *client) { struct lm75_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm75_group); i2c_detach_client(client); kfree(data); return 0; diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index 459cc977380..dd969f1e841 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c @@ -212,6 +212,23 @@ static int lm77_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, lm77_detect); } +static struct attribute *lm77_attributes[] = { + &dev_attr_temp1_input.attr, + &dev_attr_temp1_crit.attr, + &dev_attr_temp1_min.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_crit_hyst.attr, + &dev_attr_temp1_min_hyst.attr, + &dev_attr_temp1_max_hyst.attr, + &dev_attr_alarms.attr, + + NULL +}; + +static const struct attribute_group lm77_group = { + .attrs = lm77_attributes, +}; + /* This function is called by i2c_probe */ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) { @@ -317,22 +334,19 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) lm77_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove; } - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_crit); - device_create_file(&new_client->dev, &dev_attr_temp1_min); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst); - device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); - device_create_file(&new_client->dev, &dev_attr_alarms); return 0; +exit_remove: + sysfs_remove_group(&new_client->dev.kobj, &lm77_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -345,6 +359,7 @@ static int lm77_detach_client(struct i2c_client *client) { struct lm77_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm77_group); i2c_detach_client(client); kfree(data); return 0; diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index fa1715b9a99..ac1b746df6d 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c @@ -482,6 +482,50 @@ static int lm78_isa_attach_adapter(struct i2c_adapter *adapter) return lm78_detect(adapter, isa_address, -1); } +static struct attribute *lm78_attributes[] = { + &dev_attr_in0_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_input.attr, + &dev_attr_in1_min.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_input.attr, + &dev_attr_in2_min.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_input.attr, + &dev_attr_in3_min.attr, + &dev_attr_in3_max.attr, + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + &dev_attr_in5_input.attr, + &dev_attr_in5_min.attr, + &dev_attr_in5_max.attr, + &dev_attr_in6_input.attr, + &dev_attr_in6_min.attr, + &dev_attr_in6_max.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + &dev_attr_fan3_input.attr, + &dev_attr_fan3_min.attr, + &dev_attr_fan3_div.attr, + &dev_attr_alarms.attr, + &dev_attr_cpu0_vid.attr, + + NULL +}; + +static const struct attribute_group lm78_group = { + .attrs = lm78_attributes, +}; + /* This function is called by i2c_probe */ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) { @@ -616,50 +660,19 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) } /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) + goto ERROR3; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto ERROR3; + goto ERROR4; } - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in3_max); - device_create_file(&new_client->dev, &dev_attr_in4_input); - device_create_file(&new_client->dev, &dev_attr_in4_min); - device_create_file(&new_client->dev, &dev_attr_in4_max); - device_create_file(&new_client->dev, &dev_attr_in5_input); - device_create_file(&new_client->dev, &dev_attr_in5_min); - device_create_file(&new_client->dev, &dev_attr_in5_max); - device_create_file(&new_client->dev, &dev_attr_in6_input); - device_create_file(&new_client->dev, &dev_attr_in6_min); - device_create_file(&new_client->dev, &dev_attr_in6_max); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan1_div); - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_fan2_div); - device_create_file(&new_client->dev, &dev_attr_fan3_input); - device_create_file(&new_client->dev, &dev_attr_fan3_min); - device_create_file(&new_client->dev, &dev_attr_fan3_div); - device_create_file(&new_client->dev, &dev_attr_alarms); - device_create_file(&new_client->dev, &dev_attr_cpu0_vid); - return 0; +ERROR4: + sysfs_remove_group(&new_client->dev.kobj, &lm78_group); ERROR3: i2c_detach_client(new_client); ERROR2: @@ -677,6 +690,7 @@ static int lm78_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm78_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c index b4ccdfc0120..064516d824a 100644 --- a/drivers/hwmon/lm80.c +++ b/drivers/hwmon/lm80.c @@ -394,6 +394,48 @@ static int lm80_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, lm80_detect); } +static struct attribute *lm80_attributes[] = { + &dev_attr_in0_min.attr, + &dev_attr_in1_min.attr, + &dev_attr_in2_min.attr, + &dev_attr_in3_min.attr, + &dev_attr_in4_min.attr, + &dev_attr_in5_min.attr, + &dev_attr_in6_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_max.attr, + &dev_attr_in4_max.attr, + &dev_attr_in5_max.attr, + &dev_attr_in6_max.attr, + &dev_attr_in0_input.attr, + &dev_attr_in1_input.attr, + &dev_attr_in2_input.attr, + &dev_attr_in3_input.attr, + &dev_attr_in4_input.attr, + &dev_attr_in5_input.attr, + &dev_attr_in6_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan1_input.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_div.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + &dev_attr_temp1_crit.attr, + &dev_attr_temp1_crit_hyst.attr, + &dev_attr_alarms.attr, + + NULL +}; + +static const struct attribute_group lm80_group = { + .attrs = lm80_attributes, +}; + static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) { int i, cur; @@ -452,48 +494,19 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind) data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2)); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm80_group))) + goto error_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto error_detach; + goto error_remove; } - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in4_min); - device_create_file(&new_client->dev, &dev_attr_in5_min); - device_create_file(&new_client->dev, &dev_attr_in6_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_max); - device_create_file(&new_client->dev, &dev_attr_in4_max); - device_create_file(&new_client->dev, &dev_attr_in5_max); - device_create_file(&new_client->dev, &dev_attr_in6_max); - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in4_input); - device_create_file(&new_client->dev, &dev_attr_in5_input); - device_create_file(&new_client->dev, &dev_attr_in6_input); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan1_div); - device_create_file(&new_client->dev, &dev_attr_fan2_div); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); - device_create_file(&new_client->dev, &dev_attr_temp1_crit); - device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst); - device_create_file(&new_client->dev, &dev_attr_alarms); - return 0; +error_remove: + sysfs_remove_group(&new_client->dev.kobj, &lm80_group); error_detach: i2c_detach_client(new_client); error_free: @@ -508,7 +521,7 @@ static int lm80_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); - + sysfs_remove_group(&client->dev.kobj, &lm80_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c index 2137d7879df..feb87b41e98 100644 --- a/drivers/hwmon/lm83.c +++ b/drivers/hwmon/lm83.c @@ -1,7 +1,7 @@ /* * lm83.c - Part of lm_sensors, Linux kernel modules for hardware * monitoring - * Copyright (C) 2003-2005 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2003-2006 Jean Delvare <khali@linux-fr.org> * * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is * a sensor chip made by National Semiconductor. It reports up to four @@ -40,6 +40,7 @@ #include <linux/hwmon.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> /* * Addresses to scan @@ -191,6 +192,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, return sprintf(buf, "%d\n", data->alarms); } +static ssize_t show_alarm(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct lm83_data *data = lm83_update_device(dev); + int bitnr = attr->index; + + return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); +} + static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); @@ -208,8 +219,64 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp, NULL, 8); static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp, set_temp, 8); static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp, NULL, 8); + +/* Individual alarm files */ +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp3_input_fault, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); +static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 8); +static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, show_alarm, NULL, 9); +static SENSOR_DEVICE_ATTR(temp4_input_fault, S_IRUGO, show_alarm, NULL, 10); +static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_alarm, NULL, 12); +static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 13); +static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 15); +/* Raw alarm file for compatibility */ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static struct attribute *lm83_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp3_crit.dev_attr.attr, + + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_input_fault.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group lm83_group = { + .attrs = lm83_attributes, +}; + +static struct attribute *lm83_attributes_opt[] = { + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp4_crit.dev_attr.attr, + + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_input_fault.dev_attr.attr, + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_input_fault.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group lm83_group_opt = { + .attrs = lm83_attributes_opt, +}; + /* * Real code */ @@ -318,59 +385,32 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) goto exit_free; /* - * Initialize the LM83 chip - * (Nothing to do for this one.) - */ - - /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - goto exit_detach; - } - - /* + * Register sysfs hooks * The LM82 can only monitor one external diode which is * at the same register as the LM83 temp3 entry - so we * declare 1 and 3 common, and then 2 and 4 only for the LM83. */ - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_input.dev_attr); - - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_max.dev_attr); - - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_crit.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp3_crit.dev_attr); - - device_create_file(&new_client->dev, &dev_attr_alarms); + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group))) + goto exit_detach; if (kind == lm83) { - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp4_input.dev_attr); - - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp4_max.dev_attr); - - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_crit.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp4_crit.dev_attr); + if ((err = sysfs_create_group(&new_client->dev.kobj, + &lm83_group_opt))) + goto exit_remove_files; + } + + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove_files; } return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &lm83_group); + sysfs_remove_group(&new_client->dev.kobj, &lm83_group_opt); exit_detach: i2c_detach_client(new_client); exit_free: @@ -385,6 +425,8 @@ static int lm83_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm83_group); + sysfs_remove_group(&client->dev.kobj, &lm83_group_opt); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 342e9663119..2c3293cf69d 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -1025,6 +1025,89 @@ static int lm85_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, lm85_detect); } +static struct attribute *lm85_attributes[] = { + &dev_attr_fan1_input.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan3_input.attr, + &dev_attr_fan4_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan3_min.attr, + &dev_attr_fan4_min.attr, + &dev_attr_pwm1.attr, + &dev_attr_pwm2.attr, + &dev_attr_pwm3.attr, + &dev_attr_pwm1_enable.attr, + &dev_attr_pwm2_enable.attr, + &dev_attr_pwm3_enable.attr, + &dev_attr_in0_input.attr, + &dev_attr_in1_input.attr, + &dev_attr_in2_input.attr, + &dev_attr_in3_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in1_min.attr, + &dev_attr_in2_min.attr, + &dev_attr_in3_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_max.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp1_min.attr, + &dev_attr_temp2_min.attr, + &dev_attr_temp3_min.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp3_max.attr, + &dev_attr_vrm.attr, + &dev_attr_cpu0_vid.attr, + &dev_attr_alarms.attr, + &dev_attr_pwm1_auto_channels.attr, + &dev_attr_pwm2_auto_channels.attr, + &dev_attr_pwm3_auto_channels.attr, + &dev_attr_pwm1_auto_pwm_min.attr, + &dev_attr_pwm2_auto_pwm_min.attr, + &dev_attr_pwm3_auto_pwm_min.attr, + &dev_attr_pwm1_auto_pwm_minctl.attr, + &dev_attr_pwm2_auto_pwm_minctl.attr, + &dev_attr_pwm3_auto_pwm_minctl.attr, + &dev_attr_pwm1_auto_pwm_freq.attr, + &dev_attr_pwm2_auto_pwm_freq.attr, + &dev_attr_pwm3_auto_pwm_freq.attr, + &dev_attr_temp1_auto_temp_off.attr, + &dev_attr_temp2_auto_temp_off.attr, + &dev_attr_temp3_auto_temp_off.attr, + &dev_attr_temp1_auto_temp_min.attr, + &dev_attr_temp2_auto_temp_min.attr, + &dev_attr_temp3_auto_temp_min.attr, + &dev_attr_temp1_auto_temp_max.attr, + &dev_attr_temp2_auto_temp_max.attr, + &dev_attr_temp3_auto_temp_max.attr, + &dev_attr_temp1_auto_temp_crit.attr, + &dev_attr_temp2_auto_temp_crit.attr, + &dev_attr_temp3_auto_temp_crit.attr, + + NULL +}; + +static const struct attribute_group lm85_group = { + .attrs = lm85_attributes, +}; + +static struct attribute *lm85_attributes_opt[] = { + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + + NULL +}; + +static const struct attribute_group lm85_group_opt = { + .attrs = lm85_attributes_opt, +}; + static int lm85_detect(struct i2c_adapter *adapter, int address, int kind) { @@ -1163,87 +1246,33 @@ static int lm85_detect(struct i2c_adapter *adapter, int address, lm85_init_client(new_client); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm85_group))) goto ERROR2; - } - - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan3_input); - device_create_file(&new_client->dev, &dev_attr_fan4_input); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_fan3_min); - device_create_file(&new_client->dev, &dev_attr_fan4_min); - device_create_file(&new_client->dev, &dev_attr_pwm1); - device_create_file(&new_client->dev, &dev_attr_pwm2); - device_create_file(&new_client->dev, &dev_attr_pwm3); - device_create_file(&new_client->dev, &dev_attr_pwm1_enable); - device_create_file(&new_client->dev, &dev_attr_pwm2_enable); - device_create_file(&new_client->dev, &dev_attr_pwm3_enable); - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_max); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp2_input); - device_create_file(&new_client->dev, &dev_attr_temp3_input); - device_create_file(&new_client->dev, &dev_attr_temp1_min); - device_create_file(&new_client->dev, &dev_attr_temp2_min); - device_create_file(&new_client->dev, &dev_attr_temp3_min); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp2_max); - device_create_file(&new_client->dev, &dev_attr_temp3_max); - device_create_file(&new_client->dev, &dev_attr_vrm); - device_create_file(&new_client->dev, &dev_attr_cpu0_vid); - device_create_file(&new_client->dev, &dev_attr_alarms); - device_create_file(&new_client->dev, &dev_attr_pwm1_auto_channels); - device_create_file(&new_client->dev, &dev_attr_pwm2_auto_channels); - device_create_file(&new_client->dev, &dev_attr_pwm3_auto_channels); - device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_min); - device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_min); - device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_min); - device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_minctl); - device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_minctl); - device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_minctl); - device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_freq); - device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_freq); - device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_freq); - device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_off); - device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_off); - device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_off); - device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_min); - device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_min); - device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_min); - device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_max); - device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_max); - device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_max); - device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_crit); - device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit); - device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit); /* The ADT7463 has an optional VRM 10 mode where pin 21 is used as a sixth digital VID input rather than an analog input. */ data->vid = lm85_read_value(new_client, LM85_REG_VID); - if (!(kind == adt7463 && (data->vid & 0x80))) { - device_create_file(&new_client->dev, &dev_attr_in4_input); - device_create_file(&new_client->dev, &dev_attr_in4_min); - device_create_file(&new_client->dev, &dev_attr_in4_max); + if (!(kind == adt7463 && (data->vid & 0x80))) + if ((err = device_create_file(&new_client->dev, + &dev_attr_in4_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in4_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in4_max))) + goto ERROR3; + + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto ERROR3; } return 0; /* Error out and cleanup code */ + ERROR3: + sysfs_remove_group(&new_client->dev.kobj, &lm85_group); + sysfs_remove_group(&new_client->dev.kobj, &lm85_group_opt); ERROR2: i2c_detach_client(new_client); ERROR1: @@ -1256,6 +1285,8 @@ static int lm85_detach_client(struct i2c_client *client) { struct lm85_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm85_group); + sysfs_remove_group(&client->dev.kobj, &lm85_group_opt); i2c_detach_client(client); kfree(data); return 0; diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index e6c1b638c97..3ce825489e3 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c @@ -542,6 +542,78 @@ static int lm87_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, lm87_detect); } +static struct attribute *lm87_attributes[] = { + &dev_attr_in1_input.attr, + &dev_attr_in1_min.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_input.attr, + &dev_attr_in2_min.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_input.attr, + &dev_attr_in3_min.attr, + &dev_attr_in3_max.attr, + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_min.attr, + &dev_attr_temp1_crit.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp2_min.attr, + &dev_attr_temp2_crit.attr, + + &dev_attr_alarms.attr, + &dev_attr_aout_output.attr, + + NULL +}; + +static const struct attribute_group lm87_group = { + .attrs = lm87_attributes, +}; + +static struct attribute *lm87_attributes_opt[] = { + &dev_attr_in6_input.attr, + &dev_attr_in6_min.attr, + &dev_attr_in6_max.attr, + + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + + &dev_attr_in7_input.attr, + &dev_attr_in7_min.attr, + &dev_attr_in7_max.attr, + + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + + &dev_attr_temp3_input.attr, + &dev_attr_temp3_max.attr, + &dev_attr_temp3_min.attr, + &dev_attr_temp3_crit.attr, + + &dev_attr_in0_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in5_input.attr, + &dev_attr_in5_min.attr, + &dev_attr_in5_max.attr, + + &dev_attr_cpu0_vid.attr, + &dev_attr_vrm.attr, + + NULL +}; + +static const struct attribute_group lm87_group_opt = { + .attrs = lm87_attributes_opt, +}; + /* * The following function does more than just detection. If detection * succeeds, it also registers the new chip. @@ -609,77 +681,90 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) data->in_scale[7] = 1875; /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group))) goto exit_detach; - } - - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in3_max); - device_create_file(&new_client->dev, &dev_attr_in4_input); - device_create_file(&new_client->dev, &dev_attr_in4_min); - device_create_file(&new_client->dev, &dev_attr_in4_max); if (data->channel & CHAN_NO_FAN(0)) { - device_create_file(&new_client->dev, &dev_attr_in6_input); - device_create_file(&new_client->dev, &dev_attr_in6_min); - device_create_file(&new_client->dev, &dev_attr_in6_max); + if ((err = device_create_file(&new_client->dev, + &dev_attr_in6_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in6_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in6_max))) + goto exit_remove; } else { - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan1_div); + if ((err = device_create_file(&new_client->dev, + &dev_attr_fan1_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan1_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan1_div))) + goto exit_remove; } + if (data->channel & CHAN_NO_FAN(1)) { - device_create_file(&new_client->dev, &dev_attr_in7_input); - device_create_file(&new_client->dev, &dev_attr_in7_min); - device_create_file(&new_client->dev, &dev_attr_in7_max); + if ((err = device_create_file(&new_client->dev, + &dev_attr_in7_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in7_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in7_max))) + goto exit_remove; } else { - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_fan2_div); + if ((err = device_create_file(&new_client->dev, + &dev_attr_fan2_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan2_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan2_div))) + goto exit_remove; } - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_min); - device_create_file(&new_client->dev, &dev_attr_temp1_crit); - device_create_file(&new_client->dev, &dev_attr_temp2_input); - device_create_file(&new_client->dev, &dev_attr_temp2_max); - device_create_file(&new_client->dev, &dev_attr_temp2_min); - device_create_file(&new_client->dev, &dev_attr_temp2_crit); - if (data->channel & CHAN_TEMP3) { - device_create_file(&new_client->dev, &dev_attr_temp3_input); - device_create_file(&new_client->dev, &dev_attr_temp3_max); - device_create_file(&new_client->dev, &dev_attr_temp3_min); - device_create_file(&new_client->dev, &dev_attr_temp3_crit); + if ((err = device_create_file(&new_client->dev, + &dev_attr_temp3_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_crit))) + goto exit_remove; } else { - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in5_input); - device_create_file(&new_client->dev, &dev_attr_in5_min); - device_create_file(&new_client->dev, &dev_attr_in5_max); + if ((err = device_create_file(&new_client->dev, + &dev_attr_in0_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in0_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in0_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in5_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in5_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in5_max))) + goto exit_remove; } if (!(data->channel & CHAN_NO_VID)) { - device_create_file(&new_client->dev, &dev_attr_cpu0_vid); - device_create_file(&new_client->dev, &dev_attr_vrm); + if ((err = device_create_file(&new_client->dev, + &dev_attr_cpu0_vid)) + || (err = device_create_file(&new_client->dev, + &dev_attr_vrm))) + goto exit_remove; } - device_create_file(&new_client->dev, &dev_attr_alarms); - device_create_file(&new_client->dev, &dev_attr_aout_output); + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove; + } return 0; +exit_remove: + sysfs_remove_group(&new_client->dev.kobj, &lm87_group); + sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt); exit_detach: i2c_detach_client(new_client); exit_free: @@ -732,6 +817,8 @@ static int lm87_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm87_group); + sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index d9eeaf7585b..6882ce75fee 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -1,7 +1,7 @@ /* * lm90.c - Part of lm_sensors, Linux kernel modules for hardware * monitoring - * Copyright (C) 2003-2005 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2003-2006 Jean Delvare <khali@linux-fr.org> * * Based on the lm83 driver. The LM90 is a sensor chip made by National * Semiconductor. It reports up to two temperatures (its own plus up to @@ -79,6 +79,7 @@ #include <linux/hwmon.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> /* * Addresses to scan @@ -327,6 +328,16 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy, return sprintf(buf, "%d\n", data->alarms); } +static ssize_t show_alarm(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct lm90_data *data = lm90_update_device(dev); + int bitnr = attr->index; + + return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); +} + static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8, @@ -344,8 +355,45 @@ static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8, static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst, set_temphyst, 3); static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4); + +/* Individual alarm files */ +static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); +static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_input_fault, S_IRUGO, show_alarm, NULL, 2); +static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5); +static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6); +/* Raw alarm file for compatibility */ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static struct attribute *lm90_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, + + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_input_fault.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group lm90_group = { + .attrs = lm90_attributes, +}; + /* pec used for ADM1032 only */ static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, char *buf) @@ -569,39 +617,25 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) lm90_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm90_group))) + goto exit_detach; + if (new_client->flags & I2C_CLIENT_PEC) { + if ((err = device_create_file(&new_client->dev, + &dev_attr_pec))) + goto exit_remove_files; + } + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_min.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_max.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_crit.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_crit.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_crit_hyst.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp2_crit_hyst.dev_attr); - device_create_file(&new_client->dev, &dev_attr_alarms); - - if (new_client->flags & I2C_CLIENT_PEC) - device_create_file(&new_client->dev, &dev_attr_pec); - return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &lm90_group); + device_remove_file(&new_client->dev, &dev_attr_pec); exit_detach: i2c_detach_client(new_client); exit_free: @@ -634,6 +668,8 @@ static int lm90_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm90_group); + device_remove_file(&client->dev, &dev_attr_pec); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c index 197f77226dc..30b536333f1 100644 --- a/drivers/hwmon/lm92.c +++ b/drivers/hwmon/lm92.c @@ -288,6 +288,23 @@ static int max6635_check(struct i2c_client *client) return 1; } +static struct attribute *lm92_attributes[] = { + &dev_attr_temp1_input.attr, + &dev_attr_temp1_crit.attr, + &dev_attr_temp1_crit_hyst.attr, + &dev_attr_temp1_min.attr, + &dev_attr_temp1_min_hyst.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + &dev_attr_alarms.attr, + + NULL +}; + +static const struct attribute_group lm92_group = { + .attrs = lm92_attributes, +}; + /* The following function does more than just detection. If detection succeeds, it also registers the new chip. */ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) @@ -359,23 +376,19 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) lm92_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove; } - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_crit); - device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst); - device_create_file(&new_client->dev, &dev_attr_temp1_min); - device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); - device_create_file(&new_client->dev, &dev_attr_alarms); - return 0; +exit_remove: + sysfs_remove_group(&new_client->dev.kobj, &lm92_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -397,6 +410,7 @@ static int lm92_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &lm92_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index b4135b5971f..2f58f651f03 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c @@ -34,6 +34,7 @@ #include <linux/hwmon.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, @@ -172,6 +173,22 @@ static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2, set_temp_hyst2); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static struct attribute *max1619_attributes[] = { + &dev_attr_temp1_input.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp2_min.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp2_crit.attr, + &dev_attr_temp2_crit_hyst.attr, + + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group max1619_group = { + .attrs = max1619_attributes, +}; + /* * Real code */ @@ -273,22 +290,19 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) max1619_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp2_input); - device_create_file(&new_client->dev, &dev_attr_temp2_min); - device_create_file(&new_client->dev, &dev_attr_temp2_max); - device_create_file(&new_client->dev, &dev_attr_temp2_crit); - device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst); - device_create_file(&new_client->dev, &dev_attr_alarms); - return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &max1619_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -318,6 +332,7 @@ static int max1619_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &max1619_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 236f9f29c62..3b8b81984ad 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c @@ -328,6 +328,12 @@ static struct sensor_device_attribute fan_min[] = { SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 2), }; +#define FAN_UNIT_ATTRS(X) \ + &fan_input[X].dev_attr.attr, \ + &fan_status[X].dev_attr.attr, \ + &fan_div[X].dev_attr.attr, \ + &fan_min[X].dev_attr.attr + static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); @@ -360,6 +366,19 @@ static struct sensor_device_attribute pwm[] = { SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2), }; +static struct attribute * pc8736x_fan_attr_array[] = { + FAN_UNIT_ATTRS(0), + FAN_UNIT_ATTRS(1), + FAN_UNIT_ATTRS(2), + &pwm[0].dev_attr.attr, + &pwm[1].dev_attr.attr, + &pwm[2].dev_attr.attr, + NULL +}; +static const struct attribute_group pc8736x_fan_group = { + .attrs = pc8736x_fan_attr_array, +}; + static ssize_t show_in_input(struct device *dev, struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); @@ -472,6 +491,61 @@ static struct sensor_device_attribute in_max[] = { SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10), }; +#define VIN_UNIT_ATTRS(X) \ + &in_input[X].dev_attr.attr, \ + &in_status[X].dev_attr.attr, \ + &in_min[X].dev_attr.attr, \ + &in_max[X].dev_attr.attr + +static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pc87360_data *data = pc87360_update_device(dev); + return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); +} +static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); + +static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pc87360_data *data = pc87360_update_device(dev); + return sprintf(buf, "%u\n", data->vrm); +} +static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct pc87360_data *data = i2c_get_clientdata(client); + data->vrm = simple_strtoul(buf, NULL, 10); + return count; +} +static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); + +static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pc87360_data *data = pc87360_update_device(dev); + return sprintf(buf, "%u\n", data->in_alarms); +} +static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL); + +static struct attribute *pc8736x_vin_attr_array[] = { + VIN_UNIT_ATTRS(0), + VIN_UNIT_ATTRS(1), + VIN_UNIT_ATTRS(2), + VIN_UNIT_ATTRS(3), + VIN_UNIT_ATTRS(4), + VIN_UNIT_ATTRS(5), + VIN_UNIT_ATTRS(6), + VIN_UNIT_ATTRS(7), + VIN_UNIT_ATTRS(8), + VIN_UNIT_ATTRS(9), + VIN_UNIT_ATTRS(10), + &dev_attr_cpu0_vid.attr, + &dev_attr_vrm.attr, + &dev_attr_alarms_in.attr, + NULL +}; +static const struct attribute_group pc8736x_vin_group = { + .attrs = pc8736x_vin_attr_array, +}; + static ssize_t show_therm_input(struct device *dev, struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); @@ -590,33 +664,22 @@ static struct sensor_device_attribute therm_crit[] = { show_therm_crit, set_therm_crit, 2+11), }; -static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct pc87360_data *data = pc87360_update_device(dev); - return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); -} -static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); - -static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct pc87360_data *data = pc87360_update_device(dev); - return sprintf(buf, "%u\n", data->vrm); -} -static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct pc87360_data *data = i2c_get_clientdata(client); - data->vrm = simple_strtoul(buf, NULL, 10); - return count; -} -static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm); - -static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct pc87360_data *data = pc87360_update_device(dev); - return sprintf(buf, "%u\n", data->in_alarms); -} -static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL); +#define THERM_UNIT_ATTRS(X) \ + &therm_input[X].dev_attr.attr, \ + &therm_status[X].dev_attr.attr, \ + &therm_min[X].dev_attr.attr, \ + &therm_max[X].dev_attr.attr, \ + &therm_crit[X].dev_attr.attr + +static struct attribute * pc8736x_therm_attr_array[] = { + THERM_UNIT_ATTRS(0), + THERM_UNIT_ATTRS(1), + THERM_UNIT_ATTRS(2), + NULL +}; +static const struct attribute_group pc8736x_therm_group = { + .attrs = pc8736x_therm_attr_array, +}; static ssize_t show_temp_input(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -736,6 +799,25 @@ static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *att } static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL); +#define TEMP_UNIT_ATTRS(X) \ + &temp_input[X].dev_attr.attr, \ + &temp_status[X].dev_attr.attr, \ + &temp_min[X].dev_attr.attr, \ + &temp_max[X].dev_attr.attr, \ + &temp_crit[X].dev_attr.attr + +static struct attribute * pc8736x_temp_attr_array[] = { + TEMP_UNIT_ATTRS(0), + TEMP_UNIT_ATTRS(1), + TEMP_UNIT_ATTRS(2), + /* include the few miscellaneous atts here */ + &dev_attr_alarms_temp.attr, + NULL +}; +static const struct attribute_group pc8736x_temp_group = { + .attrs = pc8736x_temp_attr_array, +}; + /* * Device detection, registration and update */ @@ -936,60 +1018,69 @@ static int pc87360_detect(struct i2c_adapter *adapter) pc87360_init_client(client, use_thermistors); } - /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + /* Register all-or-nothing sysfs groups */ + + if (data->innr && + (err = sysfs_create_group(&client->dev.kobj, + &pc8736x_vin_group))) goto ERROR3; - } - if (data->innr) { - for (i = 0; i < 11; i++) { - device_create_file(dev, &in_input[i].dev_attr); - device_create_file(dev, &in_min[i].dev_attr); - device_create_file(dev, &in_max[i].dev_attr); - device_create_file(dev, &in_status[i].dev_attr); - } - device_create_file(dev, &dev_attr_cpu0_vid); - device_create_file(dev, &dev_attr_vrm); - device_create_file(dev, &dev_attr_alarms_in); - } + if (data->innr == 14 && + (err = sysfs_create_group(&client->dev.kobj, + &pc8736x_therm_group))) + goto ERROR3; + + /* create device attr-files for varying sysfs groups */ if (data->tempnr) { for (i = 0; i < data->tempnr; i++) { - device_create_file(dev, &temp_input[i].dev_attr); - device_create_file(dev, &temp_min[i].dev_attr); - device_create_file(dev, &temp_max[i].dev_attr); - device_create_file(dev, &temp_crit[i].dev_attr); - device_create_file(dev, &temp_status[i].dev_attr); - } - device_create_file(dev, &dev_attr_alarms_temp); - } - - if (data->innr == 14) { - for (i = 0; i < 3; i++) { - device_create_file(dev, &therm_input[i].dev_attr); - device_create_file(dev, &therm_min[i].dev_attr); - device_create_file(dev, &therm_max[i].dev_attr); - device_create_file(dev, &therm_crit[i].dev_attr); - device_create_file(dev, &therm_status[i].dev_attr); + if ((err = device_create_file(dev, + &temp_input[i].dev_attr)) + || (err = device_create_file(dev, + &temp_min[i].dev_attr)) + || (err = device_create_file(dev, + &temp_max[i].dev_attr)) + || (err = device_create_file(dev, + &temp_crit[i].dev_attr)) + || (err = device_create_file(dev, + &temp_status[i].dev_attr))) + goto ERROR3; } + if ((err = device_create_file(dev, &dev_attr_alarms_temp))) + goto ERROR3; } for (i = 0; i < data->fannr; i++) { - if (FAN_CONFIG_MONITOR(data->fan_conf, i)) { - device_create_file(dev, &fan_input[i].dev_attr); - device_create_file(dev, &fan_min[i].dev_attr); - device_create_file(dev, &fan_div[i].dev_attr); - device_create_file(dev, &fan_status[i].dev_attr); - } - if (FAN_CONFIG_CONTROL(data->fan_conf, i)) - device_create_file(dev, &pwm[i].dev_attr); + if (FAN_CONFIG_MONITOR(data->fan_conf, i) + && ((err = device_create_file(dev, + &fan_input[i].dev_attr)) + || (err = device_create_file(dev, + &fan_min[i].dev_attr)) + || (err = device_create_file(dev, + &fan_div[i].dev_attr)) + || (err = device_create_file(dev, + &fan_status[i].dev_attr)))) + goto ERROR3; + + if (FAN_CONFIG_CONTROL(data->fan_conf, i) + && (err = device_create_file(dev, &pwm[i].dev_attr))) + goto ERROR3; } + data->class_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto ERROR3; + } return 0; ERROR3: + /* can still remove groups whose members were added individually */ + sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group); + sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group); + sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group); + sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group); + i2c_detach_client(client); ERROR2: for (i = 0; i < 3; i++) { @@ -1009,6 +1100,11 @@ static int pc87360_detach_client(struct i2c_client *client) hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group); + sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group); + sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group); + sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group); + if ((i = i2c_detach_client(client))) return i; diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 3783af4195b..95a4b5d9eaf 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c @@ -61,6 +61,7 @@ #include <linux/init.h> #include <linux/jiffies.h> #include <linux/mutex.h> +#include <linux/sysfs.h> #include <asm/io.h> @@ -473,6 +474,50 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch return sprintf(buf, "%d\n", data->alarms); } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + +static struct attribute *sis5595_attributes[] = { + &dev_attr_in0_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_input.attr, + &dev_attr_in1_min.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_input.attr, + &dev_attr_in2_min.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_input.attr, + &dev_attr_in3_min.attr, + &dev_attr_in3_max.attr, + + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group sis5595_group = { + .attrs = sis5595_attributes, +}; + +static struct attribute *sis5595_attributes_opt[] = { + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + NULL +}; + +static const struct attribute_group sis5595_group_opt = { + .attrs = sis5595_attributes_opt, +}; /* This is called when the module is loaded */ static int sis5595_detect(struct i2c_adapter *adapter) @@ -566,43 +611,37 @@ static int sis5595_detect(struct i2c_adapter *adapter) } /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &sis5595_group))) + goto exit_detach; + if (data->maxins == 4) { + if ((err = device_create_file(&new_client->dev, + &dev_attr_in4_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in4_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in4_max))) + goto exit_remove_files; + } else { + if ((err = device_create_file(&new_client->dev, + &dev_attr_temp1_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp1_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp1_max_hyst))) + goto exit_remove_files; + } + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in3_max); - if (data->maxins == 4) { - device_create_file(&new_client->dev, &dev_attr_in4_input); - device_create_file(&new_client->dev, &dev_attr_in4_min); - device_create_file(&new_client->dev, &dev_attr_in4_max); - } - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan1_div); - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_fan2_div); - device_create_file(&new_client->dev, &dev_attr_alarms); - if (data->maxins == 3) { - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); - } return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &sis5595_group); + sysfs_remove_group(&new_client->dev.kobj, &sis5595_group_opt); exit_detach: i2c_detach_client(new_client); exit_free: @@ -619,6 +658,8 @@ static int sis5595_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &sis5595_group); + sysfs_remove_group(&client->dev.kobj, &sis5595_group_opt); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index a85869393ba..72b0e2d8650 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -176,9 +176,6 @@ sysfs_temp(2); sysfs_temp(3); sysfs_temp(4); -#define device_create_file_temp(client, num) \ - device_create_file(&client->dev, &dev_attr_temp##num##_input) - /* FAN: 1 RPM/bit REG: count of 90kHz pulses / revolution */ static int fan_from_reg(u16 reg) @@ -205,8 +202,22 @@ sysfs_fan(2); sysfs_fan(3); sysfs_fan(4); -#define device_create_file_fan(client, num) \ - device_create_file(&client->dev, &dev_attr_fan##num##_input) +static struct attribute *smsc47b397_attributes[] = { + &dev_attr_temp1_input.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp4_input.attr, + &dev_attr_fan1_input.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan3_input.attr, + &dev_attr_fan4_input.attr, + + NULL +}; + +static const struct attribute_group smsc47b397_group = { + .attrs = smsc47b397_attributes, +}; static int smsc47b397_detach_client(struct i2c_client *client) { @@ -214,6 +225,7 @@ static int smsc47b397_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &smsc47b397_group); if ((err = i2c_detach_client(client))) return err; @@ -268,24 +280,19 @@ static int smsc47b397_detect(struct i2c_adapter *adapter) if ((err = i2c_attach_client(new_client))) goto error_free; + if ((err = sysfs_create_group(&new_client->dev.kobj, &smsc47b397_group))) + goto error_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto error_detach; + goto error_remove; } - device_create_file_temp(new_client, 1); - device_create_file_temp(new_client, 2); - device_create_file_temp(new_client, 3); - device_create_file_temp(new_client, 4); - - device_create_file_fan(new_client, 1); - device_create_file_fan(new_client, 2); - device_create_file_fan(new_client, 3); - device_create_file_fan(new_client, 4); - return 0; +error_remove: + sysfs_remove_group(&new_client->dev.kobj, &smsc47b397_group); error_detach: i2c_detach_client(new_client); error_free: diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 6c81b843d83..47132fd26b1 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -35,6 +35,7 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/mutex.h> +#include <linux/sysfs.h> #include <asm/io.h> /* Address is autodetected, there is no default value */ @@ -347,6 +348,30 @@ fan_present(2); static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); +/* Almost all sysfs files may or may not be created depending on the chip + setup so we create them individually. It is still convenient to define a + group to remove them all at once. */ +static struct attribute *smsc47m1_attributes[] = { + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + + &dev_attr_pwm1.attr, + &dev_attr_pwm1_enable.attr, + &dev_attr_pwm2.attr, + &dev_attr_pwm2_enable.attr, + + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group smsc47m1_group = { + .attrs = smsc47m1_attributes, +}; + static int __init smsc47m1_find(unsigned short *addr) { u8 val; @@ -429,7 +454,8 @@ static int smsc47m1_detect(struct i2c_adapter *adapter) pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05) == 0x04; if (!(fan1 || fan2 || pwm1 || pwm2)) { - dev_warn(&new_client->dev, "Device is not configured, will not use\n"); + dev_warn(&adapter->dev, "Device at 0x%x is not configured, " + "will not use\n", new_client->addr); err = -ENODEV; goto error_free; } @@ -446,46 +472,62 @@ static int smsc47m1_detect(struct i2c_adapter *adapter) smsc47m1_update_device(&new_client->dev, 1); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - goto error_detach; - } - if (fan1) { - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan1_div); + if ((err = device_create_file(&new_client->dev, + &dev_attr_fan1_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan1_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan1_div))) + goto error_remove_files; } else dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, " "skipping\n"); if (fan2) { - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_fan2_div); + if ((err = device_create_file(&new_client->dev, + &dev_attr_fan2_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan2_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan2_div))) + goto error_remove_files; } else dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, " "skipping\n"); if (pwm1) { - device_create_file(&new_client->dev, &dev_attr_pwm1); - device_create_file(&new_client->dev, &dev_attr_pwm1_enable); + if ((err = device_create_file(&new_client->dev, + &dev_attr_pwm1)) + || (err = device_create_file(&new_client->dev, + &dev_attr_pwm1_enable))) + goto error_remove_files; } else dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, " "skipping\n"); if (pwm2) { - device_create_file(&new_client->dev, &dev_attr_pwm2); - device_create_file(&new_client->dev, &dev_attr_pwm2_enable); + if ((err = device_create_file(&new_client->dev, + &dev_attr_pwm2)) + || (err = device_create_file(&new_client->dev, + &dev_attr_pwm2_enable))) + goto error_remove_files; } else dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, " "skipping\n"); - device_create_file(&new_client->dev, &dev_attr_alarms); + if ((err = device_create_file(&new_client->dev, &dev_attr_alarms))) + goto error_remove_files; + + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto error_remove_files; + } return 0; -error_detach: +error_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &smsc47m1_group); i2c_detach_client(new_client); error_free: kfree(data); @@ -500,6 +542,7 @@ static int smsc47m1_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &smsc47m1_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index bdc4570acf9..a6833f43739 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c @@ -30,6 +30,7 @@ #include <linux/hwmon-sysfs.h> #include <linux/hwmon-vid.h> #include <linux/err.h> +#include <linux/sysfs.h> /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; @@ -370,6 +371,75 @@ static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 0x0200); static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 0x0400); static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 0x0800); +static struct attribute *smsc47m192_attributes[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in0_max.dev_attr.attr, + &sensor_dev_attr_in0_alarm.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in1_alarm.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in2_alarm.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in3_alarm.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in5_max.dev_attr.attr, + &sensor_dev_attr_in5_alarm.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in6_min.dev_attr.attr, + &sensor_dev_attr_in6_max.dev_attr.attr, + &sensor_dev_attr_in6_alarm.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in7_min.dev_attr.attr, + &sensor_dev_attr_in7_max.dev_attr.attr, + &sensor_dev_attr_in7_alarm.dev_attr.attr, + + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_offset.dev_attr.attr, + &sensor_dev_attr_temp1_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_offset.dev_attr.attr, + &sensor_dev_attr_temp2_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_input_fault.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_offset.dev_attr.attr, + &sensor_dev_attr_temp3_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_input_fault.dev_attr.attr, + + &dev_attr_cpu0_vid.attr, + &dev_attr_vrm.attr, + NULL +}; + +static const struct attribute_group smsc47m192_group = { + .attrs = smsc47m192_attributes, +}; + +static struct attribute *smsc47m192_attributes_in4[] = { + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in4_alarm.dev_attr.attr, + NULL +}; + +static const struct attribute_group smsc47m192_group_in4 = { + .attrs = smsc47m192_attributes_in4, +}; + /* This function is called when: * smsc47m192_driver is inserted (when this module is loaded), for each available adapter @@ -471,80 +541,28 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, smsc47m192_init_client(client); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group))) goto exit_detach; - } - - device_create_file(&client->dev, &sensor_dev_attr_in0_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in0_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in0_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in0_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in1_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in1_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in1_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in1_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in2_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in2_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in2_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in2_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in3_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in3_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in3_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in3_alarm.dev_attr); /* Pin 110 is either in4 (+12V) or VID4 */ config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); if (!(config & 0x20)) { - device_create_file(&client->dev, - &sensor_dev_attr_in4_input.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_in4_min.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_in4_max.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_in4_alarm.dev_attr); + if ((err = sysfs_create_group(&client->dev.kobj, + &smsc47m192_group_in4))) + goto exit_remove_files; + } + + data->class_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove_files; } - device_create_file(&client->dev, &sensor_dev_attr_in5_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in5_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in5_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in5_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in6_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in6_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in6_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in6_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in7_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in7_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in7_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_in7_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp1_min.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp1_offset.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp1_alarm.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp2_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp2_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp2_min.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp2_offset.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp2_alarm.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp2_input_fault.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp3_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp3_max.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp3_min.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp3_offset.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_temp3_alarm.dev_attr); - device_create_file(&client->dev, - &sensor_dev_attr_temp3_input_fault.dev_attr); - device_create_file(&client->dev, &dev_attr_cpu0_vid); - device_create_file(&client->dev, &dev_attr_vrm); return 0; +exit_remove_files: + sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); + sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); exit_detach: i2c_detach_client(client); exit_free: @@ -559,6 +577,8 @@ static int smsc47m192_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); + sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 95ae056e5a9..f8acada0537 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c @@ -40,6 +40,7 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/mutex.h> +#include <linux/sysfs.h> #include <asm/io.h> @@ -570,6 +571,48 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static struct attribute *via686a_attributes[] = { + &dev_attr_in0_input.attr, + &dev_attr_in1_input.attr, + &dev_attr_in2_input.attr, + &dev_attr_in3_input.attr, + &dev_attr_in4_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in1_min.attr, + &dev_attr_in2_min.attr, + &dev_attr_in3_min.attr, + &dev_attr_in4_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_max.attr, + &dev_attr_in4_max.attr, + + &dev_attr_temp1_input.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp3_max.attr, + &dev_attr_temp1_max_hyst.attr, + &dev_attr_temp2_max_hyst.attr, + &dev_attr_temp3_max_hyst.attr, + + &dev_attr_fan1_input.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_div.attr, + + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group via686a_group = { + .attrs = via686a_attributes, +}; + /* The driver. I choose to use type i2c_driver, as at is identical to both smbus_driver and isa_driver, and clients could be of either kind */ static struct i2c_driver via686a_driver = { @@ -650,46 +693,19 @@ static int via686a_detect(struct i2c_adapter *adapter) via686a_init_client(new_client); /* Register sysfs hooks */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &via686a_group))) + goto exit_detach; + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove_files; } - device_create_file(&new_client->dev, &dev_attr_in0_input); - device_create_file(&new_client->dev, &dev_attr_in1_input); - device_create_file(&new_client->dev, &dev_attr_in2_input); - device_create_file(&new_client->dev, &dev_attr_in3_input); - device_create_file(&new_client->dev, &dev_attr_in4_input); - device_create_file(&new_client->dev, &dev_attr_in0_min); - device_create_file(&new_client->dev, &dev_attr_in1_min); - device_create_file(&new_client->dev, &dev_attr_in2_min); - device_create_file(&new_client->dev, &dev_attr_in3_min); - device_create_file(&new_client->dev, &dev_attr_in4_min); - device_create_file(&new_client->dev, &dev_attr_in0_max); - device_create_file(&new_client->dev, &dev_attr_in1_max); - device_create_file(&new_client->dev, &dev_attr_in2_max); - device_create_file(&new_client->dev, &dev_attr_in3_max); - device_create_file(&new_client->dev, &dev_attr_in4_max); - device_create_file(&new_client->dev, &dev_attr_temp1_input); - device_create_file(&new_client->dev, &dev_attr_temp2_input); - device_create_file(&new_client->dev, &dev_attr_temp3_input); - device_create_file(&new_client->dev, &dev_attr_temp1_max); - device_create_file(&new_client->dev, &dev_attr_temp2_max); - device_create_file(&new_client->dev, &dev_attr_temp3_max); - device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); - device_create_file(&new_client->dev, &dev_attr_temp2_max_hyst); - device_create_file(&new_client->dev, &dev_attr_temp3_max_hyst); - device_create_file(&new_client->dev, &dev_attr_fan1_input); - device_create_file(&new_client->dev, &dev_attr_fan2_input); - device_create_file(&new_client->dev, &dev_attr_fan1_min); - device_create_file(&new_client->dev, &dev_attr_fan2_min); - device_create_file(&new_client->dev, &dev_attr_fan1_div); - device_create_file(&new_client->dev, &dev_attr_fan2_div); - device_create_file(&new_client->dev, &dev_attr_alarms); - return 0; +exit_remove_files: + sysfs_remove_group(&new_client->dev.kobj, &via686a_group); exit_detach: i2c_detach_client(new_client); exit_free: @@ -705,6 +721,7 @@ static int via686a_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &via686a_group); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c new file mode 100644 index 00000000000..25cc56003d7 --- /dev/null +++ b/drivers/hwmon/vt1211.c @@ -0,0 +1,1355 @@ +/* + * vt1211.c - driver for the VIA VT1211 Super-I/O chip integrated hardware + * monitoring features + * Copyright (C) 2006 Juerg Haefliger <juergh@gmail.com> + * + * This driver is based on the driver for kernel 2.4 by Mark D. Studebaker + * and its port to kernel 2.6 by Lars Ekman. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/jiffies.h> +#include <linux/platform_device.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/hwmon-vid.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <asm/io.h> + +static int uch_config = -1; +module_param(uch_config, int, 0); +MODULE_PARM_DESC(uch_config, "Initialize the universal channel configuration"); + +static int int_mode = -1; +module_param(int_mode, int, 0); +MODULE_PARM_DESC(int_mode, "Force the temperature interrupt mode"); + +static struct platform_device *pdev; + +#define DRVNAME "vt1211" + +/* --------------------------------------------------------------------- + * Registers + * + * The sensors are defined as follows. + * + * Sensor Voltage Mode Temp Mode Notes (from the datasheet) + * -------- ------------ --------- -------------------------- + * Reading 1 temp1 Intel thermal diode + * Reading 3 temp2 Internal thermal diode + * UCH1/Reading2 in0 temp3 NTC type thermistor + * UCH2 in1 temp4 +2.5V + * UCH3 in2 temp5 VccP + * UCH4 in3 temp6 +5V + * UCH5 in4 temp7 +12V + * 3.3V in5 Internal VDD (+3.3V) + * + * --------------------------------------------------------------------- */ + +/* Voltages (in) numbered 0-5 (ix) */ +#define VT1211_REG_IN(ix) (0x21 + (ix)) +#define VT1211_REG_IN_MIN(ix) ((ix) == 0 ? 0x3e : 0x2a + 2 * (ix)) +#define VT1211_REG_IN_MAX(ix) ((ix) == 0 ? 0x3d : 0x29 + 2 * (ix)) + +/* Temperatures (temp) numbered 0-6 (ix) */ +static u8 regtemp[] = {0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25}; +static u8 regtempmax[] = {0x39, 0x1d, 0x3d, 0x2b, 0x2d, 0x2f, 0x31}; +static u8 regtemphyst[] = {0x3a, 0x1e, 0x3e, 0x2c, 0x2e, 0x30, 0x32}; + +/* Fans numbered 0-1 (ix) */ +#define VT1211_REG_FAN(ix) (0x29 + (ix)) +#define VT1211_REG_FAN_MIN(ix) (0x3b + (ix)) +#define VT1211_REG_FAN_DIV 0x47 + +/* PWMs numbered 0-1 (ix) */ +/* Auto points numbered 0-3 (ap) */ +#define VT1211_REG_PWM(ix) (0x60 + (ix)) +#define VT1211_REG_PWM_CLK 0x50 +#define VT1211_REG_PWM_CTL 0x51 +#define VT1211_REG_PWM_AUTO_TEMP(ap) (0x55 - (ap)) +#define VT1211_REG_PWM_AUTO_PWM(ix, ap) (0x58 + 2 * (ix) - (ap)) + +/* Miscellaneous registers */ +#define VT1211_REG_CONFIG 0x40 +#define VT1211_REG_ALARM1 0x41 +#define VT1211_REG_ALARM2 0x42 +#define VT1211_REG_VID 0x45 +#define VT1211_REG_UCH_CONFIG 0x4a +#define VT1211_REG_TEMP1_CONFIG 0x4b +#define VT1211_REG_TEMP2_CONFIG 0x4c + +/* In, temp & fan alarm bits */ +static const u8 bitalarmin[] = {11, 0, 1, 3, 8, 2, 9}; +static const u8 bitalarmtemp[] = {4, 15, 11, 0, 1, 3, 8}; +static const u8 bitalarmfan[] = {6, 7}; + +/* --------------------------------------------------------------------- + * Data structures and manipulation thereof + * --------------------------------------------------------------------- */ + +struct vt1211_data { + unsigned short addr; + const char *name; + struct class_device *class_dev; + + struct mutex update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + + /* Register values */ + u8 in[6]; + u8 in_max[6]; + u8 in_min[6]; + u8 temp[7]; + u8 temp_max[7]; + u8 temp_hyst[7]; + u8 fan[2]; + u8 fan_min[2]; + u8 fan_div[2]; + u8 fan_ctl; + u8 pwm[2]; + u8 pwm_ctl[2]; + u8 pwm_clk; + u8 pwm_auto_temp[4]; + u8 pwm_auto_pwm[2][4]; + u8 vid; /* Read once at init time */ + u8 vrm; + u8 uch_config; /* Read once at init time */ + u16 alarms; +}; + +/* ix = [0-5] */ +#define ISVOLT(ix, uch_config) ((ix) > 4 ? 1 : \ + !(((uch_config) >> ((ix) + 2)) & 1)) + +/* ix = [0-6] */ +#define ISTEMP(ix, uch_config) ((ix) < 2 ? 1 : \ + ((uch_config) >> (ix)) & 1) + +/* in5 (ix = 5) is special. It's the internal 3.3V so it's scaled in the + driver according to the VT1211 BIOS porting guide */ +#define IN_FROM_REG(ix, reg) ((reg) < 3 ? 0 : (ix) == 5 ? \ + (((reg) - 3) * 15882 + 479) / 958 : \ + (((reg) - 3) * 10000 + 479) / 958) +#define IN_TO_REG(ix, val) (SENSORS_LIMIT((ix) == 5 ? \ + ((val) * 958 + 7941) / 15882 + 3 : \ + ((val) * 958 + 5000) / 10000 + 3, 0, 255)) + +/* temp1 (ix = 0) is an intel thermal diode which is scaled in user space. + temp2 (ix = 1) is the internal temp diode so it's scaled in the driver + according to some measurements that I took on an EPIA M10000. + temp3-7 are thermistor based so the driver returns the voltage measured at + the pin (range 0V - 2.2V). */ +#define TEMP_FROM_REG(ix, reg) ((ix) == 0 ? (reg) * 1000 : \ + (ix) == 1 ? (reg) < 51 ? 0 : \ + ((reg) - 51) * 1000 : \ + ((253 - (reg)) * 2200 + 105) / 210) +#define TEMP_TO_REG(ix, val) SENSORS_LIMIT( \ + ((ix) == 0 ? ((val) + 500) / 1000 : \ + (ix) == 1 ? ((val) + 500) / 1000 + 51 : \ + 253 - ((val) * 210 + 1100) / 2200), 0, 255) + +#define DIV_FROM_REG(reg) (1 << (reg)) + +#define RPM_FROM_REG(reg, div) (((reg) == 0) || ((reg) == 255) ? 0 : \ + 1310720 / (reg) / DIV_FROM_REG(div)) +#define RPM_TO_REG(val, div) ((val) == 0 ? 255 : \ + SENSORS_LIMIT((1310720 / (val) / \ + DIV_FROM_REG(div)), 1, 254)) + +/* --------------------------------------------------------------------- + * Super-I/O constants and functions + * --------------------------------------------------------------------- */ + +/* Configuration & data index port registers */ +#define SIO_REG_CIP 0x2e +#define SIO_REG_DIP 0x2f + +/* Configuration registers */ +#define SIO_VT1211_LDN 0x07 /* logical device number */ +#define SIO_VT1211_DEVID 0x20 /* device ID */ +#define SIO_VT1211_DEVREV 0x21 /* device revision */ +#define SIO_VT1211_ACTIVE 0x30 /* HW monitor active */ +#define SIO_VT1211_BADDR 0x60 /* base I/O address */ +#define SIO_VT1211_ID 0x3c /* VT1211 device ID */ + +/* VT1211 logical device numbers */ +#define SIO_VT1211_LDN_HWMON 0x0b /* HW monitor */ + +static inline void superio_outb(int reg, int val) +{ + outb(reg, SIO_REG_CIP); + outb(val, SIO_REG_DIP); +} + +static inline int superio_inb(int reg) +{ + outb(reg, SIO_REG_CIP); + return inb(SIO_REG_DIP); +} + +static inline void superio_select(int ldn) +{ + outb(SIO_VT1211_LDN, SIO_REG_CIP); + outb(ldn, SIO_REG_DIP); +} + +static inline void superio_enter(void) +{ + outb(0x87, SIO_REG_CIP); + outb(0x87, SIO_REG_CIP); +} + +static inline void superio_exit(void) +{ + outb(0xaa, SIO_REG_CIP); +} + +/* --------------------------------------------------------------------- + * Device I/O access + * --------------------------------------------------------------------- */ + +static inline u8 vt1211_read8(struct vt1211_data *data, u8 reg) +{ + return inb(data->addr + reg); +} + +static inline void vt1211_write8(struct vt1211_data *data, u8 reg, u8 val) +{ + outb(val, data->addr + reg); +} + +static struct vt1211_data *vt1211_update_device(struct device *dev) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + int ix, val; + + mutex_lock(&data->update_lock); + + /* registers cache is refreshed after 1 second */ + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { + /* read VID */ + data->vid = vt1211_read8(data, VT1211_REG_VID) & 0x1f; + + /* voltage (in) registers */ + for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) { + if (ISVOLT(ix, data->uch_config)) { + data->in[ix] = vt1211_read8(data, + VT1211_REG_IN(ix)); + data->in_min[ix] = vt1211_read8(data, + VT1211_REG_IN_MIN(ix)); + data->in_max[ix] = vt1211_read8(data, + VT1211_REG_IN_MAX(ix)); + } + } + + /* temp registers */ + for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) { + if (ISTEMP(ix, data->uch_config)) { + data->temp[ix] = vt1211_read8(data, + regtemp[ix]); + data->temp_max[ix] = vt1211_read8(data, + regtempmax[ix]); + data->temp_hyst[ix] = vt1211_read8(data, + regtemphyst[ix]); + } + } + + /* fan & pwm registers */ + for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) { + data->fan[ix] = vt1211_read8(data, + VT1211_REG_FAN(ix)); + data->fan_min[ix] = vt1211_read8(data, + VT1211_REG_FAN_MIN(ix)); + data->pwm[ix] = vt1211_read8(data, + VT1211_REG_PWM(ix)); + } + val = vt1211_read8(data, VT1211_REG_FAN_DIV); + data->fan_div[0] = (val >> 4) & 3; + data->fan_div[1] = (val >> 6) & 3; + data->fan_ctl = val & 0xf; + + val = vt1211_read8(data, VT1211_REG_PWM_CTL); + data->pwm_ctl[0] = val & 0xf; + data->pwm_ctl[1] = (val >> 4) & 0xf; + + data->pwm_clk = vt1211_read8(data, VT1211_REG_PWM_CLK); + + /* pwm & temp auto point registers */ + data->pwm_auto_pwm[0][1] = vt1211_read8(data, + VT1211_REG_PWM_AUTO_PWM(0, 1)); + data->pwm_auto_pwm[0][2] = vt1211_read8(data, + VT1211_REG_PWM_AUTO_PWM(0, 2)); + data->pwm_auto_pwm[1][1] = vt1211_read8(data, + VT1211_REG_PWM_AUTO_PWM(1, 1)); + data->pwm_auto_pwm[1][2] = vt1211_read8(data, + VT1211_REG_PWM_AUTO_PWM(1, 2)); + for (ix = 0; ix < ARRAY_SIZE(data->pwm_auto_temp); ix++) { + data->pwm_auto_temp[ix] = vt1211_read8(data, + VT1211_REG_PWM_AUTO_TEMP(ix)); + } + + /* alarm registers */ + data->alarms = (vt1211_read8(data, VT1211_REG_ALARM2) << 8) | + vt1211_read8(data, VT1211_REG_ALARM1); + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +/* --------------------------------------------------------------------- + * Voltage sysfs interfaces + * ix = [0-5] + * --------------------------------------------------------------------- */ + +#define SHOW_IN_INPUT 0 +#define SHOW_SET_IN_MIN 1 +#define SHOW_SET_IN_MAX 2 +#define SHOW_IN_ALARM 3 + +static ssize_t show_in(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct vt1211_data *data = vt1211_update_device(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int fn = sensor_attr_2->nr; + int res; + + switch (fn) { + case SHOW_IN_INPUT: + res = IN_FROM_REG(ix, data->in[ix]); + break; + case SHOW_SET_IN_MIN: + res = IN_FROM_REG(ix, data->in_min[ix]); + break; + case SHOW_SET_IN_MAX: + res = IN_FROM_REG(ix, data->in_max[ix]); + break; + case SHOW_IN_ALARM: + res = (data->alarms >> bitalarmin[ix]) & 1; + break; + default: + res = 0; + dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); + } + + return sprintf(buf, "%d\n", res); +} + +static ssize_t set_in(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int fn = sensor_attr_2->nr; + long val = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + switch (fn) { + case SHOW_SET_IN_MIN: + data->in_min[ix] = IN_TO_REG(ix, val); + vt1211_write8(data, VT1211_REG_IN_MIN(ix), data->in_min[ix]); + break; + case SHOW_SET_IN_MAX: + data->in_max[ix] = IN_TO_REG(ix, val); + vt1211_write8(data, VT1211_REG_IN_MAX(ix), data->in_max[ix]); + break; + default: + dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); + } + mutex_unlock(&data->update_lock); + + return count; +} + +/* --------------------------------------------------------------------- + * Temperature sysfs interfaces + * ix = [0-6] + * --------------------------------------------------------------------- */ + +#define SHOW_TEMP_INPUT 0 +#define SHOW_SET_TEMP_MAX 1 +#define SHOW_SET_TEMP_MAX_HYST 2 +#define SHOW_TEMP_ALARM 3 + +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct vt1211_data *data = vt1211_update_device(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int fn = sensor_attr_2->nr; + int res; + + switch (fn) { + case SHOW_TEMP_INPUT: + res = TEMP_FROM_REG(ix, data->temp[ix]); + break; + case SHOW_SET_TEMP_MAX: + res = TEMP_FROM_REG(ix, data->temp_max[ix]); + break; + case SHOW_SET_TEMP_MAX_HYST: + res = TEMP_FROM_REG(ix, data->temp_hyst[ix]); + break; + case SHOW_TEMP_ALARM: + res = (data->alarms >> bitalarmtemp[ix]) & 1; + break; + default: + res = 0; + dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); + } + + return sprintf(buf, "%d\n", res); +} + +static ssize_t set_temp(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int fn = sensor_attr_2->nr; + long val = simple_strtol(buf, NULL, 10); + + mutex_lock(&data->update_lock); + switch (fn) { + case SHOW_SET_TEMP_MAX: + data->temp_max[ix] = TEMP_TO_REG(ix, val); + vt1211_write8(data, regtempmax[ix], + data->temp_max[ix]); + break; + case SHOW_SET_TEMP_MAX_HYST: + data->temp_hyst[ix] = TEMP_TO_REG(ix, val); + vt1211_write8(data, regtemphyst[ix], + data->temp_hyst[ix]); + break; + default: + dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); + } + mutex_unlock(&data->update_lock); + + return count; +} + +/* --------------------------------------------------------------------- + * Fan sysfs interfaces + * ix = [0-1] + * --------------------------------------------------------------------- */ + +#define SHOW_FAN_INPUT 0 +#define SHOW_SET_FAN_MIN 1 +#define SHOW_SET_FAN_DIV 2 +#define SHOW_FAN_ALARM 3 + +static ssize_t show_fan(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct vt1211_data *data = vt1211_update_device(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int fn = sensor_attr_2->nr; + int res; + + switch (fn) { + case SHOW_FAN_INPUT: + res = RPM_FROM_REG(data->fan[ix], data->fan_div[ix]); + break; + case SHOW_SET_FAN_MIN: + res = RPM_FROM_REG(data->fan_min[ix], data->fan_div[ix]); + break; + case SHOW_SET_FAN_DIV: + res = DIV_FROM_REG(data->fan_div[ix]); + break; + case SHOW_FAN_ALARM: + res = (data->alarms >> bitalarmfan[ix]) & 1; + break; + default: + res = 0; + dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); + } + + return sprintf(buf, "%d\n", res); +} + +static ssize_t set_fan(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int fn = sensor_attr_2->nr; + long val = simple_strtol(buf, NULL, 10); + int reg; + + mutex_lock(&data->update_lock); + + /* sync the data cache */ + reg = vt1211_read8(data, VT1211_REG_FAN_DIV); + data->fan_div[0] = (reg >> 4) & 3; + data->fan_div[1] = (reg >> 6) & 3; + data->fan_ctl = reg & 0xf; + + switch (fn) { + case SHOW_SET_FAN_MIN: + data->fan_min[ix] = RPM_TO_REG(val, data->fan_div[ix]); + vt1211_write8(data, VT1211_REG_FAN_MIN(ix), + data->fan_min[ix]); + break; + case SHOW_SET_FAN_DIV: + switch (val) { + case 1: data->fan_div[ix] = 0; break; + case 2: data->fan_div[ix] = 1; break; + case 4: data->fan_div[ix] = 2; break; + case 8: data->fan_div[ix] = 3; break; + default: + count = -EINVAL; + dev_warn(dev, "fan div value %ld not " + "supported. Choose one of 1, 2, " + "4, or 8.\n", val); + goto EXIT; + } + vt1211_write8(data, VT1211_REG_FAN_DIV, + ((data->fan_div[1] << 6) | + (data->fan_div[0] << 4) | + data->fan_ctl)); + break; + default: + dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); + } + +EXIT: + mutex_unlock(&data->update_lock); + return count; +} + +/* --------------------------------------------------------------------- + * PWM sysfs interfaces + * ix = [0-1] + * --------------------------------------------------------------------- */ + +#define SHOW_PWM 0 +#define SHOW_SET_PWM_ENABLE 1 +#define SHOW_SET_PWM_FREQ 2 +#define SHOW_SET_PWM_AUTO_CHANNELS_TEMP 3 + +static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct vt1211_data *data = vt1211_update_device(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int fn = sensor_attr_2->nr; + int res; + + switch (fn) { + case SHOW_PWM: + res = data->pwm[ix]; + break; + case SHOW_SET_PWM_ENABLE: + res = ((data->pwm_ctl[ix] >> 3) & 1) ? 2 : 0; + break; + case SHOW_SET_PWM_FREQ: + res = 90000 >> (data->pwm_clk & 7); + break; + case SHOW_SET_PWM_AUTO_CHANNELS_TEMP: + res = (data->pwm_ctl[ix] & 7) + 1; + break; + default: + res = 0; + dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); + } + + return sprintf(buf, "%d\n", res); +} + +static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int fn = sensor_attr_2->nr; + long val = simple_strtol(buf, NULL, 10); + int tmp, reg; + + mutex_lock(&data->update_lock); + + switch (fn) { + case SHOW_SET_PWM_ENABLE: + /* sync the data cache */ + reg = vt1211_read8(data, VT1211_REG_FAN_DIV); + data->fan_div[0] = (reg >> 4) & 3; + data->fan_div[1] = (reg >> 6) & 3; + data->fan_ctl = reg & 0xf; + reg = vt1211_read8(data, VT1211_REG_PWM_CTL); + data->pwm_ctl[0] = reg & 0xf; + data->pwm_ctl[1] = (reg >> 4) & 0xf; + switch (val) { + case 0: + data->pwm_ctl[ix] &= 7; + /* disable SmartGuardian if both PWM outputs are + * disabled */ + if ((data->pwm_ctl[ix ^ 1] & 1) == 0) { + data->fan_ctl &= 0xe; + } + break; + case 2: + data->pwm_ctl[ix] |= 8; + data->fan_ctl |= 1; + break; + default: + count = -EINVAL; + dev_warn(dev, "pwm mode %ld not supported. " + "Choose one of 0 or 2.\n", val); + goto EXIT; + } + vt1211_write8(data, VT1211_REG_PWM_CTL, + ((data->pwm_ctl[1] << 4) | + data->pwm_ctl[0])); + vt1211_write8(data, VT1211_REG_FAN_DIV, + ((data->fan_div[1] << 6) | + (data->fan_div[0] << 4) | + data->fan_ctl)); + break; + case SHOW_SET_PWM_FREQ: + val = 135000 / SENSORS_LIMIT(val, 135000 >> 7, 135000); + /* calculate tmp = log2(val) */ + tmp = 0; + for (val >>= 1; val > 0; val >>= 1) { + tmp++; + } + /* sync the data cache */ + reg = vt1211_read8(data, VT1211_REG_PWM_CLK); + data->pwm_clk = (reg & 0xf8) | tmp; + vt1211_write8(data, VT1211_REG_PWM_CLK, data->pwm_clk); + break; + case SHOW_SET_PWM_AUTO_CHANNELS_TEMP: + if ((val < 1) || (val > 7)) { + count = -EINVAL; + dev_warn(dev, "temp channel %ld not supported. " + "Choose a value between 1 and 7.\n", val); + goto EXIT; + } + if (!ISTEMP(val - 1, data->uch_config)) { + count = -EINVAL; + dev_warn(dev, "temp channel %ld is not available.\n", + val); + goto EXIT; + } + /* sync the data cache */ + reg = vt1211_read8(data, VT1211_REG_PWM_CTL); + data->pwm_ctl[0] = reg & 0xf; + data->pwm_ctl[1] = (reg >> 4) & 0xf; + data->pwm_ctl[ix] = (data->pwm_ctl[ix] & 8) | (val - 1); + vt1211_write8(data, VT1211_REG_PWM_CTL, + ((data->pwm_ctl[1] << 4) | data->pwm_ctl[0])); + break; + default: + dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); + } + +EXIT: + mutex_unlock(&data->update_lock); + return count; +} + +/* --------------------------------------------------------------------- + * PWM auto point definitions + * ix = [0-1] + * ap = [0-3] + * --------------------------------------------------------------------- */ + +/* + * pwm[ix+1]_auto_point[ap+1]_temp mapping table: + * Note that there is only a single set of temp auto points that controls both + * PWM controllers. We still create 2 sets of sysfs files to make it look + * more consistent even though they map to the same registers. + * + * ix ap : description + * ------------------- + * 0 0 : pwm1/2 off temperature (pwm_auto_temp[0]) + * 0 1 : pwm1/2 low speed temperature (pwm_auto_temp[1]) + * 0 2 : pwm1/2 high speed temperature (pwm_auto_temp[2]) + * 0 3 : pwm1/2 full speed temperature (pwm_auto_temp[3]) + * 1 0 : pwm1/2 off temperature (pwm_auto_temp[0]) + * 1 1 : pwm1/2 low speed temperature (pwm_auto_temp[1]) + * 1 2 : pwm1/2 high speed temperature (pwm_auto_temp[2]) + * 1 3 : pwm1/2 full speed temperature (pwm_auto_temp[3]) + */ + +static ssize_t show_pwm_auto_point_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct vt1211_data *data = vt1211_update_device(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int ap = sensor_attr_2->nr; + + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->pwm_ctl[ix] & 7, + data->pwm_auto_temp[ap])); +} + +static ssize_t set_pwm_auto_point_temp(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int ap = sensor_attr_2->nr; + long val = simple_strtol(buf, NULL, 10); + int reg; + + mutex_lock(&data->update_lock); + + /* sync the data cache */ + reg = vt1211_read8(data, VT1211_REG_PWM_CTL); + data->pwm_ctl[0] = reg & 0xf; + data->pwm_ctl[1] = (reg >> 4) & 0xf; + + data->pwm_auto_temp[ap] = TEMP_TO_REG(data->pwm_ctl[ix] & 7, val); + vt1211_write8(data, VT1211_REG_PWM_AUTO_TEMP(ap), + data->pwm_auto_temp[ap]); + mutex_unlock(&data->update_lock); + + return count; +} + +/* + * pwm[ix+1]_auto_point[ap+1]_pwm mapping table: + * Note that the PWM auto points 0 & 3 are hard-wired in the VT1211 and can't + * be changed. + * + * ix ap : description + * ------------------- + * 0 0 : pwm1 off (pwm_auto_pwm[0][0], hard-wired to 0) + * 0 1 : pwm1 low speed duty cycle (pwm_auto_pwm[0][1]) + * 0 2 : pwm1 high speed duty cycle (pwm_auto_pwm[0][2]) + * 0 3 : pwm1 full speed (pwm_auto_pwm[0][3], hard-wired to 255) + * 1 0 : pwm2 off (pwm_auto_pwm[1][0], hard-wired to 0) + * 1 1 : pwm2 low speed duty cycle (pwm_auto_pwm[1][1]) + * 1 2 : pwm2 high speed duty cycle (pwm_auto_pwm[1][2]) + * 1 3 : pwm2 full speed (pwm_auto_pwm[1][3], hard-wired to 255) +*/ + +static ssize_t show_pwm_auto_point_pwm(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct vt1211_data *data = vt1211_update_device(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int ap = sensor_attr_2->nr; + + return sprintf(buf, "%d\n", data->pwm_auto_pwm[ix][ap]); +} + +static ssize_t set_pwm_auto_point_pwm(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute_2 *sensor_attr_2 = + to_sensor_dev_attr_2(attr); + int ix = sensor_attr_2->index; + int ap = sensor_attr_2->nr; + long val = simple_strtol(buf, NULL, 10); + + if ((val < 0) || (val > 255)) { + dev_err(dev, "pwm value %ld is out of range. " + "Choose a value between 0 and 255." , val); + return -EINVAL; + } + + mutex_lock(&data->update_lock); + data->pwm_auto_pwm[ix][ap] = val; + vt1211_write8(data, VT1211_REG_PWM_AUTO_PWM(ix, ap), + data->pwm_auto_pwm[ix][ap]); + mutex_unlock(&data->update_lock); + + return count; +} + +/* --------------------------------------------------------------------- + * Miscellaneous sysfs interfaces (VRM, VID, name, and (legacy) alarms) + * --------------------------------------------------------------------- */ + +static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", data->vrm); +} + +static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + long val = simple_strtol(buf, NULL, 10); + + data->vrm = val; + + return count; +} + +static ssize_t show_vid(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm)); +} + +static ssize_t show_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct vt1211_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", data->name); +} + +static ssize_t show_alarms(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct vt1211_data *data = vt1211_update_device(dev); + + return sprintf(buf, "%d\n", data->alarms); +} + +/* --------------------------------------------------------------------- + * Device attribute structs + * --------------------------------------------------------------------- */ + +#define SENSOR_ATTR_IN_INPUT(ix) \ + SENSOR_ATTR_2(in##ix##_input, S_IRUGO, \ + show_in, NULL, SHOW_IN_INPUT, ix) + +static struct sensor_device_attribute_2 vt1211_sysfs_in_input[] = { + SENSOR_ATTR_IN_INPUT(0), + SENSOR_ATTR_IN_INPUT(1), + SENSOR_ATTR_IN_INPUT(2), + SENSOR_ATTR_IN_INPUT(3), + SENSOR_ATTR_IN_INPUT(4), + SENSOR_ATTR_IN_INPUT(5), +}; + +#define SENSOR_ATTR_IN_MIN(ix) \ + SENSOR_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \ + show_in, set_in, SHOW_SET_IN_MIN, ix) + +static struct sensor_device_attribute_2 vt1211_sysfs_in_min[] = { + SENSOR_ATTR_IN_MIN(0), + SENSOR_ATTR_IN_MIN(1), + SENSOR_ATTR_IN_MIN(2), + SENSOR_ATTR_IN_MIN(3), + SENSOR_ATTR_IN_MIN(4), + SENSOR_ATTR_IN_MIN(5), +}; + +#define SENSOR_ATTR_IN_MAX(ix) \ + SENSOR_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \ + show_in, set_in, SHOW_SET_IN_MAX, ix) + +static struct sensor_device_attribute_2 vt1211_sysfs_in_max[] = { + SENSOR_ATTR_IN_MAX(0), + SENSOR_ATTR_IN_MAX(1), + SENSOR_ATTR_IN_MAX(2), + SENSOR_ATTR_IN_MAX(3), + SENSOR_ATTR_IN_MAX(4), + SENSOR_ATTR_IN_MAX(5), +}; + +#define SENSOR_ATTR_IN_ALARM(ix) \ + SENSOR_ATTR_2(in##ix##_alarm, S_IRUGO, \ + show_in, NULL, SHOW_IN_ALARM, ix) + +static struct sensor_device_attribute_2 vt1211_sysfs_in_alarm[] = { + SENSOR_ATTR_IN_ALARM(0), + SENSOR_ATTR_IN_ALARM(1), + SENSOR_ATTR_IN_ALARM(2), + SENSOR_ATTR_IN_ALARM(3), + SENSOR_ATTR_IN_ALARM(4), + SENSOR_ATTR_IN_ALARM(5), +}; + +#define SENSOR_ATTR_TEMP_INPUT(ix) \ + SENSOR_ATTR_2(temp##ix##_input, S_IRUGO, \ + show_temp, NULL, SHOW_TEMP_INPUT, ix-1) + +static struct sensor_device_attribute_2 vt1211_sysfs_temp_input[] = { + SENSOR_ATTR_TEMP_INPUT(1), + SENSOR_ATTR_TEMP_INPUT(2), + SENSOR_ATTR_TEMP_INPUT(3), + SENSOR_ATTR_TEMP_INPUT(4), + SENSOR_ATTR_TEMP_INPUT(5), + SENSOR_ATTR_TEMP_INPUT(6), + SENSOR_ATTR_TEMP_INPUT(7), +}; + +#define SENSOR_ATTR_TEMP_MAX(ix) \ + SENSOR_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \ + show_temp, set_temp, SHOW_SET_TEMP_MAX, ix-1) + +static struct sensor_device_attribute_2 vt1211_sysfs_temp_max[] = { + SENSOR_ATTR_TEMP_MAX(1), + SENSOR_ATTR_TEMP_MAX(2), + SENSOR_ATTR_TEMP_MAX(3), + SENSOR_ATTR_TEMP_MAX(4), + SENSOR_ATTR_TEMP_MAX(5), + SENSOR_ATTR_TEMP_MAX(6), + SENSOR_ATTR_TEMP_MAX(7), +}; + +#define SENSOR_ATTR_TEMP_MAX_HYST(ix) \ + SENSOR_ATTR_2(temp##ix##_max_hyst, S_IRUGO | S_IWUSR, \ + show_temp, set_temp, SHOW_SET_TEMP_MAX_HYST, ix-1) + +static struct sensor_device_attribute_2 vt1211_sysfs_temp_max_hyst[] = { + SENSOR_ATTR_TEMP_MAX_HYST(1), + SENSOR_ATTR_TEMP_MAX_HYST(2), + SENSOR_ATTR_TEMP_MAX_HYST(3), + SENSOR_ATTR_TEMP_MAX_HYST(4), + SENSOR_ATTR_TEMP_MAX_HYST(5), + SENSOR_ATTR_TEMP_MAX_HYST(6), + SENSOR_ATTR_TEMP_MAX_HYST(7), +}; + +#define SENSOR_ATTR_TEMP_ALARM(ix) \ + SENSOR_ATTR_2(temp##ix##_alarm, S_IRUGO, \ + show_temp, NULL, SHOW_TEMP_ALARM, ix-1) + +static struct sensor_device_attribute_2 vt1211_sysfs_temp_alarm[] = { + SENSOR_ATTR_TEMP_ALARM(1), + SENSOR_ATTR_TEMP_ALARM(2), + SENSOR_ATTR_TEMP_ALARM(3), + SENSOR_ATTR_TEMP_ALARM(4), + SENSOR_ATTR_TEMP_ALARM(5), + SENSOR_ATTR_TEMP_ALARM(6), + SENSOR_ATTR_TEMP_ALARM(7), +}; + +#define SENSOR_ATTR_FAN(ix) \ + SENSOR_ATTR_2(fan##ix##_input, S_IRUGO, \ + show_fan, NULL, SHOW_FAN_INPUT, ix-1), \ + SENSOR_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \ + show_fan, set_fan, SHOW_SET_FAN_MIN, ix-1), \ + SENSOR_ATTR_2(fan##ix##_div, S_IRUGO | S_IWUSR, \ + show_fan, set_fan, SHOW_SET_FAN_DIV, ix-1), \ + SENSOR_ATTR_2(fan##ix##_alarm, S_IRUGO, \ + show_fan, NULL, SHOW_FAN_ALARM, ix-1) + +#define SENSOR_ATTR_PWM(ix) \ + SENSOR_ATTR_2(pwm##ix, S_IRUGO, \ + show_pwm, NULL, SHOW_PWM, ix-1), \ + SENSOR_ATTR_2(pwm##ix##_enable, S_IRUGO | S_IWUSR, \ + show_pwm, set_pwm, SHOW_SET_PWM_ENABLE, ix-1), \ + SENSOR_ATTR_2(pwm##ix##_auto_channels_temp, S_IRUGO | S_IWUSR, \ + show_pwm, set_pwm, SHOW_SET_PWM_AUTO_CHANNELS_TEMP, ix-1) + +#define SENSOR_ATTR_PWM_FREQ(ix) \ + SENSOR_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \ + show_pwm, set_pwm, SHOW_SET_PWM_FREQ, ix-1) + +#define SENSOR_ATTR_PWM_FREQ_RO(ix) \ + SENSOR_ATTR_2(pwm##ix##_freq, S_IRUGO, \ + show_pwm, NULL, SHOW_SET_PWM_FREQ, ix-1) + +#define SENSOR_ATTR_PWM_AUTO_POINT_TEMP(ix, ap) \ + SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_temp, S_IRUGO | S_IWUSR, \ + show_pwm_auto_point_temp, set_pwm_auto_point_temp, \ + ap-1, ix-1) + +#define SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(ix, ap) \ + SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_temp, S_IRUGO, \ + show_pwm_auto_point_temp, NULL, \ + ap-1, ix-1) + +#define SENSOR_ATTR_PWM_AUTO_POINT_PWM(ix, ap) \ + SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_pwm, S_IRUGO | S_IWUSR, \ + show_pwm_auto_point_pwm, set_pwm_auto_point_pwm, \ + ap-1, ix-1) + +#define SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(ix, ap) \ + SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_pwm, S_IRUGO, \ + show_pwm_auto_point_pwm, NULL, \ + ap-1, ix-1) + +static struct sensor_device_attribute_2 vt1211_sysfs_fan_pwm[] = { + SENSOR_ATTR_FAN(1), + SENSOR_ATTR_FAN(2), + SENSOR_ATTR_PWM(1), + SENSOR_ATTR_PWM(2), + SENSOR_ATTR_PWM_FREQ(1), + SENSOR_ATTR_PWM_FREQ_RO(2), + SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 1), + SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 2), + SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 3), + SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 4), + SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 1), + SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 2), + SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 3), + SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 4), + SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(1, 1), + SENSOR_ATTR_PWM_AUTO_POINT_PWM(1, 2), + SENSOR_ATTR_PWM_AUTO_POINT_PWM(1, 3), + SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(1, 4), + SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(2, 1), + SENSOR_ATTR_PWM_AUTO_POINT_PWM(2, 2), + SENSOR_ATTR_PWM_AUTO_POINT_PWM(2, 3), + SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(2, 4), +}; + +static struct device_attribute vt1211_sysfs_misc[] = { + __ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm), + __ATTR(cpu0_vid, S_IRUGO, show_vid, NULL), + __ATTR(name, S_IRUGO, show_name, NULL), + __ATTR(alarms, S_IRUGO, show_alarms, NULL), +}; + +/* --------------------------------------------------------------------- + * Device registration and initialization + * --------------------------------------------------------------------- */ + +static void __devinit vt1211_init_device(struct vt1211_data *data) +{ + /* set VRM */ + data->vrm = vid_which_vrm(); + + /* Read (and initialize) UCH config */ + data->uch_config = vt1211_read8(data, VT1211_REG_UCH_CONFIG); + if (uch_config > -1) { + data->uch_config = (data->uch_config & 0x83) | + (uch_config << 2); + vt1211_write8(data, VT1211_REG_UCH_CONFIG, data->uch_config); + } + + /* Initialize the interrupt mode (if request at module load time). + * The VT1211 implements 3 different modes for clearing interrupts: + * 0: Clear INT when status register is read. Regenerate INT as long + * as temp stays above hysteresis limit. + * 1: Clear INT when status register is read. DON'T regenerate INT + * until temp falls below hysteresis limit and exceeds hot limit + * again. + * 2: Clear INT when temp falls below max limit. + * + * The driver only allows to force mode 0 since that's the only one + * that makes sense for 'sensors' */ + if (int_mode == 0) { + vt1211_write8(data, VT1211_REG_TEMP1_CONFIG, 0); + vt1211_write8(data, VT1211_REG_TEMP2_CONFIG, 0); + } + + /* Fill in some hard wired values into our data struct */ + data->pwm_auto_pwm[0][3] = 255; + data->pwm_auto_pwm[1][3] = 255; +} + +static void vt1211_remove_sysfs(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_in_input); i++) { + device_remove_file(dev, + &vt1211_sysfs_in_input[i].dev_attr); + device_remove_file(dev, + &vt1211_sysfs_in_min[i].dev_attr); + device_remove_file(dev, + &vt1211_sysfs_in_max[i].dev_attr); + device_remove_file(dev, + &vt1211_sysfs_in_alarm[i].dev_attr); + } + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_temp_input); i++) { + device_remove_file(dev, + &vt1211_sysfs_temp_input[i].dev_attr); + device_remove_file(dev, + &vt1211_sysfs_temp_max[i].dev_attr); + device_remove_file(dev, + &vt1211_sysfs_temp_max_hyst[i].dev_attr); + device_remove_file(dev, + &vt1211_sysfs_temp_alarm[i].dev_attr); + } + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) { + device_remove_file(dev, + &vt1211_sysfs_fan_pwm[i].dev_attr); + } + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) { + device_remove_file(dev, &vt1211_sysfs_misc[i]); + } +} + +static int __devinit vt1211_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct vt1211_data *data; + struct resource *res; + int i, err; + + if (!(data = kzalloc(sizeof(struct vt1211_data), GFP_KERNEL))) { + err = -ENOMEM; + dev_err(dev, "Out of memory\n"); + goto EXIT; + } + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + data->addr = res->start; + data->name = DRVNAME; + mutex_init(&data->update_lock); + + platform_set_drvdata(pdev, data); + + /* Initialize the VT1211 chip */ + vt1211_init_device(data); + + /* Create sysfs interface files */ + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_in_input); i++) { + if (ISVOLT(i, data->uch_config)) { + if ((err = device_create_file(dev, + &vt1211_sysfs_in_input[i].dev_attr)) || + (err = device_create_file(dev, + &vt1211_sysfs_in_min[i].dev_attr)) || + (err = device_create_file(dev, + &vt1211_sysfs_in_max[i].dev_attr)) || + (err = device_create_file(dev, + &vt1211_sysfs_in_alarm[i].dev_attr))) { + goto EXIT_DEV_REMOVE; + } + } + } + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_temp_input); i++) { + if (ISTEMP(i, data->uch_config)) { + if ((err = device_create_file(dev, + &vt1211_sysfs_temp_input[i].dev_attr)) || + (err = device_create_file(dev, + &vt1211_sysfs_temp_max[i].dev_attr)) || + (err = device_create_file(dev, + &vt1211_sysfs_temp_max_hyst[i].dev_attr)) || + (err = device_create_file(dev, + &vt1211_sysfs_temp_alarm[i].dev_attr))) { + goto EXIT_DEV_REMOVE; + } + } + } + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) { + err = device_create_file(dev, + &vt1211_sysfs_fan_pwm[i].dev_attr); + if (err) { + goto EXIT_DEV_REMOVE; + } + } + for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) { + err = device_create_file(dev, + &vt1211_sysfs_misc[i]); + if (err) { + goto EXIT_DEV_REMOVE; + } + } + + /* Register device */ + data->class_dev = hwmon_device_register(dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + dev_err(dev, "Class registration failed (%d)\n", err); + goto EXIT_DEV_REMOVE_SILENT; + } + + return 0; + +EXIT_DEV_REMOVE: + dev_err(dev, "Sysfs interface creation failed (%d)\n", err); +EXIT_DEV_REMOVE_SILENT: + vt1211_remove_sysfs(pdev); + platform_set_drvdata(pdev, NULL); + kfree(data); +EXIT: + return err; +} + +static int __devexit vt1211_remove(struct platform_device *pdev) +{ + struct vt1211_data *data = platform_get_drvdata(pdev); + + hwmon_device_unregister(data->class_dev); + vt1211_remove_sysfs(pdev); + platform_set_drvdata(pdev, NULL); + kfree(data); + + return 0; +} + +static struct platform_driver vt1211_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRVNAME, + }, + .probe = vt1211_probe, + .remove = __devexit_p(vt1211_remove), +}; + +static int __init vt1211_device_add(unsigned short address) +{ + struct resource res = { + .start = address, + .end = address + 0x7f, + .flags = IORESOURCE_IO, + }; + int err; + + pdev = platform_device_alloc(DRVNAME, address); + if (!pdev) { + err = -ENOMEM; + printk(KERN_ERR DRVNAME ": Device allocation failed (%d)\n", + err); + goto EXIT; + } + + res.name = pdev->name; + err = platform_device_add_resources(pdev, &res, 1); + if (err) { + printk(KERN_ERR DRVNAME ": Device resource addition failed " + "(%d)\n", err); + goto EXIT_DEV_PUT; + } + + err = platform_device_add(pdev); + if (err) { + printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", + err); + goto EXIT_DEV_PUT; + } + + return 0; + +EXIT_DEV_PUT: + platform_device_put(pdev); +EXIT: + return err; +} + +static int __init vt1211_find(unsigned short *address) +{ + int err = -ENODEV; + + superio_enter(); + + if (superio_inb(SIO_VT1211_DEVID) != SIO_VT1211_ID) { + goto EXIT; + } + + superio_select(SIO_VT1211_LDN_HWMON); + + if ((superio_inb(SIO_VT1211_ACTIVE) & 1) == 0) { + printk(KERN_WARNING DRVNAME ": HW monitor is disabled, " + "skipping\n"); + goto EXIT; + } + + *address = ((superio_inb(SIO_VT1211_BADDR) << 8) | + (superio_inb(SIO_VT1211_BADDR + 1))) & 0xff00; + if (*address == 0) { + printk(KERN_WARNING DRVNAME ": Base address is not set, " + "skipping\n"); + goto EXIT; + } + + err = 0; + printk(KERN_INFO DRVNAME ": Found VT1211 chip at 0x%04x, " + "revision %u\n", *address, superio_inb(SIO_VT1211_DEVREV)); + +EXIT: + superio_exit(); + return err; +} + +static int __init vt1211_init(void) +{ + int err; + unsigned short address = 0; + + err = vt1211_find(&address); + if (err) { + goto EXIT; + } + + if ((uch_config < -1) || (uch_config > 31)) { + err = -EINVAL; + printk(KERN_WARNING DRVNAME ": Invalid UCH configuration %d. " + "Choose a value between 0 and 31.\n", uch_config); + goto EXIT; + } + + if ((int_mode < -1) || (int_mode > 0)) { + err = -EINVAL; + printk(KERN_WARNING DRVNAME ": Invalid interrupt mode %d. " + "Only mode 0 is supported.\n", int_mode); + goto EXIT; + } + + err = platform_driver_register(&vt1211_driver); + if (err) { + goto EXIT; + } + + /* Sets global pdev as a side effect */ + err = vt1211_device_add(address); + if (err) { + goto EXIT_DRV_UNREGISTER; + } + + return 0; + +EXIT_DRV_UNREGISTER: + platform_driver_unregister(&vt1211_driver); +EXIT: + return err; +} + +static void __exit vt1211_exit(void) +{ + platform_device_unregister(pdev); + platform_driver_unregister(&vt1211_driver); +} + +MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>"); +MODULE_DESCRIPTION("VT1211 sensors"); +MODULE_LICENSE("GPL"); + +module_init(vt1211_init); +module_exit(vt1211_exit); diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 236ccf0e915..93f93d4fb8a 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c @@ -451,37 +451,6 @@ define_temperature_sysfs(4); define_temperature_sysfs(5); define_temperature_sysfs(6); -#define CFG_INFO_TEMP(id) { &sensor_dev_attr_temp##id##_input.dev_attr, \ - &sensor_dev_attr_temp##id##_max_hyst.dev_attr, \ - &sensor_dev_attr_temp##id##_max.dev_attr } -#define CFG_INFO_VOLT(id) { &sensor_dev_attr_in##id##_input.dev_attr, \ - &sensor_dev_attr_in##id##_min.dev_attr, \ - &sensor_dev_attr_in##id##_max.dev_attr } - -struct str_device_attr_table { - struct device_attribute *input; - struct device_attribute *min; - struct device_attribute *max; -}; - -static struct str_device_attr_table cfg_info_temp[] = { - { &dev_attr_temp1_input, &dev_attr_temp1_max_hyst, &dev_attr_temp1_max }, - CFG_INFO_TEMP(2), - CFG_INFO_TEMP(3), - CFG_INFO_TEMP(4), - CFG_INFO_TEMP(5), - CFG_INFO_TEMP(6) -}; - -static struct str_device_attr_table cfg_info_volt[] = { - CFG_INFO_VOLT(0), - CFG_INFO_VOLT(1), - CFG_INFO_VOLT(2), - CFG_INFO_VOLT(3), - CFG_INFO_VOLT(4), - { &dev_attr_in5_input, &dev_attr_in5_min, &dev_attr_in5_max } -}; - /* Fans */ static ssize_t show_fan(struct device *dev, struct device_attribute *attr, char *buf) @@ -585,6 +554,107 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); +static struct attribute *vt8231_attributes_temps[6][4] = { + { + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max_hyst.attr, + &dev_attr_temp1_max.attr, + NULL + }, { + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp5_max.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_temp6_input.dev_attr.attr, + &sensor_dev_attr_temp6_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp6_max.dev_attr.attr, + NULL + } +}; + +static const struct attribute_group vt8231_group_temps[6] = { + { .attrs = vt8231_attributes_temps[0] }, + { .attrs = vt8231_attributes_temps[1] }, + { .attrs = vt8231_attributes_temps[2] }, + { .attrs = vt8231_attributes_temps[3] }, + { .attrs = vt8231_attributes_temps[4] }, + { .attrs = vt8231_attributes_temps[5] }, +}; + +static struct attribute *vt8231_attributes_volts[6][4] = { + { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in0_max.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + NULL + }, { + &dev_attr_in5_input.attr, + &dev_attr_in5_min.attr, + &dev_attr_in5_max.attr, + NULL + } +}; + +static const struct attribute_group vt8231_group_volts[6] = { + { .attrs = vt8231_attributes_volts[0] }, + { .attrs = vt8231_attributes_volts[1] }, + { .attrs = vt8231_attributes_volts[2] }, + { .attrs = vt8231_attributes_volts[3] }, + { .attrs = vt8231_attributes_volts[4] }, + { .attrs = vt8231_attributes_volts[5] }, +}; + +static struct attribute *vt8231_attributes[] = { + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan1_div.dev_attr.attr, + &sensor_dev_attr_fan2_div.dev_attr.attr, + &dev_attr_alarms.attr, + NULL +}; + +static const struct attribute_group vt8231_group = { + .attrs = vt8231_attributes, +}; + static struct i2c_driver vt8231_driver = { .driver = { .owner = THIS_MODULE, @@ -671,43 +741,43 @@ int vt8231_detect(struct i2c_adapter *adapter) vt8231_init_client(client); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&client->dev.kobj, &vt8231_group))) goto exit_detach; - } /* Must update device information to find out the config field */ data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG); - for (i = 0; i < ARRAY_SIZE(cfg_info_temp); i++) { + for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) { if (ISTEMP(i, data->uch_config)) { - device_create_file(&client->dev, - cfg_info_temp[i].input); - device_create_file(&client->dev, cfg_info_temp[i].max); - device_create_file(&client->dev, cfg_info_temp[i].min); + if ((err = sysfs_create_group(&client->dev.kobj, + &vt8231_group_temps[i]))) + goto exit_remove_files; } } - for (i = 0; i < ARRAY_SIZE(cfg_info_volt); i++) { + for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) { if (ISVOLT(i, data->uch_config)) { - device_create_file(&client->dev, - cfg_info_volt[i].input); - device_create_file(&client->dev, cfg_info_volt[i].max); - device_create_file(&client->dev, cfg_info_volt[i].min); + if ((err = sysfs_create_group(&client->dev.kobj, + &vt8231_group_volts[i]))) + goto exit_remove_files; } } - device_create_file(&client->dev, &sensor_dev_attr_fan1_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_fan2_input.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_fan1_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_fan2_min.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_fan1_div.dev_attr); - device_create_file(&client->dev, &sensor_dev_attr_fan2_div.dev_attr); - - device_create_file(&client->dev, &dev_attr_alarms); + data->class_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove_files; + } return 0; +exit_remove_files: + for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) + sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]); + + for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) + sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]); + + sysfs_remove_group(&client->dev.kobj, &vt8231_group); exit_detach: i2c_detach_client(client); exit_free: @@ -720,10 +790,18 @@ exit_release: static int vt8231_detach_client(struct i2c_client *client) { struct vt8231_data *data = i2c_get_clientdata(client); - int err; + int err, i; hwmon_device_unregister(data->class_dev); + for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) + sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]); + + for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) + sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]); + + sysfs_remove_group(&client->dev.kobj, &vt8231_group); + if ((err = i2c_detach_client(client))) { return err; } diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index b21d6b9d7ea..833faa275ff 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -2,6 +2,9 @@ w83627ehf - Driver for the hardware monitoring functionality of the Winbond W83627EHF Super-I/O chip Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> + Copyright (C) 2006 Yuan Mu (Winbond), + Rudolf Marek <r.marek@sh.cvut.cz> + David Hubbard <david.c.hubbard@gmail.com> Shamelessly ripped from the w83627hf driver Copyright (C) 2003 Mark Studebaker @@ -29,8 +32,8 @@ Supports the following chips: - Chip #vin #fan #pwm #temp chip_id man_id - w83627ehf 10 5 - 3 0x88 0x5ca3 + Chip #vin #fan #pwm #temp chip_id man_id + w83627ehf 10 5 4 3 0x88,0xa1 0x5ca3 */ #include <linux/module.h> @@ -145,10 +148,44 @@ static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 }; #define W83627EHF_REG_ALARM2 0x45A #define W83627EHF_REG_ALARM3 0x45B +/* SmartFan registers */ +/* DC or PWM output fan configuration */ +static const u8 W83627EHF_REG_PWM_ENABLE[] = { + 0x04, /* SYS FAN0 output mode and PWM mode */ + 0x04, /* CPU FAN0 output mode and PWM mode */ + 0x12, /* AUX FAN mode */ + 0x62, /* CPU fan1 mode */ +}; + +static const u8 W83627EHF_PWM_MODE_SHIFT[] = { 0, 1, 0, 6 }; +static const u8 W83627EHF_PWM_ENABLE_SHIFT[] = { 2, 4, 1, 4 }; + +/* FAN Duty Cycle, be used to control */ +static const u8 W83627EHF_REG_PWM[] = { 0x01, 0x03, 0x11, 0x61 }; +static const u8 W83627EHF_REG_TARGET[] = { 0x05, 0x06, 0x13, 0x63 }; +static const u8 W83627EHF_REG_TOLERANCE[] = { 0x07, 0x07, 0x14, 0x62 }; + + +/* Advanced Fan control, some values are common for all fans */ +static const u8 W83627EHF_REG_FAN_MIN_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 }; +static const u8 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0C, 0x0D, 0x17, 0x66 }; + /* * Conversions */ +/* 1 is PWM mode, output in ms */ +static inline unsigned int step_time_from_reg(u8 reg, u8 mode) +{ + return mode ? 100 * reg : 400 * reg; +} + +static inline u8 step_time_to_reg(unsigned int msec, u8 mode) +{ + return SENSORS_LIMIT((mode ? (msec + 50) / 100 : + (msec + 200) / 400), 1, 255); +} + static inline unsigned int fan_from_reg(u8 reg, unsigned int div) { @@ -170,12 +207,12 @@ temp1_from_reg(s8 reg) } static inline s8 -temp1_to_reg(int temp) +temp1_to_reg(int temp, int min, int max) { - if (temp <= -128000) - return -128; - if (temp >= 127000) - return 127; + if (temp <= min) + return min / 1000; + if (temp >= max) + return max / 1000; if (temp < 0) return (temp - 500) / 1000; return (temp + 500) / 1000; @@ -223,6 +260,16 @@ struct w83627ehf_data { s16 temp_max[2]; s16 temp_max_hyst[2]; u32 alarms; + + u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ + u8 pwm_enable[4]; /* 1->manual + 2->thermal cruise (also called SmartFan I) */ + u8 pwm[4]; + u8 target_temp[4]; + u8 tolerance[4]; + + u8 fan_min_output[4]; /* minimum fan speed */ + u8 fan_stop_time[4]; }; static inline int is_word_sized(u16 reg) @@ -349,6 +396,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct w83627ehf_data *data = i2c_get_clientdata(client); + int pwmcfg = 0, tolerance = 0; /* shut up the compiler */ int i; mutex_lock(&data->update_lock); @@ -416,6 +464,34 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) } } + for (i = 0; i < 4; i++) { + /* pwmcfg, tolarance mapped for i=0, i=1 to same reg */ + if (i != 1) { + pwmcfg = w83627ehf_read_value(client, + W83627EHF_REG_PWM_ENABLE[i]); + tolerance = w83627ehf_read_value(client, + W83627EHF_REG_TOLERANCE[i]); + } + data->pwm_mode[i] = + ((pwmcfg >> W83627EHF_PWM_MODE_SHIFT[i]) & 1) + ? 0 : 1; + data->pwm_enable[i] = + ((pwmcfg >> W83627EHF_PWM_ENABLE_SHIFT[i]) + & 3) + 1; + data->pwm[i] = w83627ehf_read_value(client, + W83627EHF_REG_PWM[i]); + data->fan_min_output[i] = w83627ehf_read_value(client, + W83627EHF_REG_FAN_MIN_OUTPUT[i]); + data->fan_stop_time[i] = w83627ehf_read_value(client, + W83627EHF_REG_FAN_STOP_TIME[i]); + data->target_temp[i] = + w83627ehf_read_value(client, + W83627EHF_REG_TARGET[i]) & + (data->pwm_mode[i] == 1 ? 0x7f : 0xff); + data->tolerance[i] = (tolerance >> (i == 1 ? 4 : 0)) + & 0x0f; + } + /* Measured temperatures and limits */ data->temp1 = w83627ehf_read_value(client, W83627EHF_REG_TEMP1); @@ -546,14 +622,6 @@ static struct sensor_device_attribute sda_in_max[] = { SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9), }; -static void device_create_file_in(struct device *dev, int i) -{ - device_create_file(dev, &sda_in_input[i].dev_attr); - device_create_file(dev, &sda_in_alarm[i].dev_attr); - device_create_file(dev, &sda_in_min[i].dev_attr); - device_create_file(dev, &sda_in_max[i].dev_attr); -} - #define show_fan_reg(reg) \ static ssize_t \ show_##reg(struct device *dev, struct device_attribute *attr, \ @@ -681,14 +749,6 @@ static struct sensor_device_attribute sda_fan_div[] = { SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4), }; -static void device_create_file_fan(struct device *dev, int i) -{ - device_create_file(dev, &sda_fan_input[i].dev_attr); - device_create_file(dev, &sda_fan_alarm[i].dev_attr); - device_create_file(dev, &sda_fan_div[i].dev_attr); - device_create_file(dev, &sda_fan_min[i].dev_attr); -} - #define show_temp1_reg(reg) \ static ssize_t \ show_##reg(struct device *dev, struct device_attribute *attr, \ @@ -711,7 +771,7 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ u32 val = simple_strtoul(buf, NULL, 10); \ \ mutex_lock(&data->update_lock); \ - data->temp1_##reg = temp1_to_reg(val); \ + data->temp1_##reg = temp1_to_reg(val, -128000, 127000); \ w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \ data->temp1_##reg); \ mutex_unlock(&data->update_lock); \ @@ -777,10 +837,309 @@ static struct sensor_device_attribute sda_temp[] = { SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), }; +#define show_pwm_reg(reg) \ +static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct w83627ehf_data *data = w83627ehf_update_device(dev); \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ + return sprintf(buf, "%d\n", data->reg[nr]); \ +} + +show_pwm_reg(pwm_mode) +show_pwm_reg(pwm_enable) +show_pwm_reg(pwm) + +static ssize_t +store_pwm_mode(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct w83627ehf_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + u32 val = simple_strtoul(buf, NULL, 10); + u16 reg; + + if (val > 1) + return -EINVAL; + mutex_lock(&data->update_lock); + reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); + data->pwm_mode[nr] = val; + reg &= ~(1 << W83627EHF_PWM_MODE_SHIFT[nr]); + if (!val) + reg |= 1 << W83627EHF_PWM_MODE_SHIFT[nr]; + w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t +store_pwm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct w83627ehf_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); + + mutex_lock(&data->update_lock); + data->pwm[nr] = val; + w83627ehf_write_value(client, W83627EHF_REG_PWM[nr], val); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t +store_pwm_enable(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct w83627ehf_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + u32 val = simple_strtoul(buf, NULL, 10); + u16 reg; + + if (!val || (val > 2)) /* only modes 1 and 2 are supported */ + return -EINVAL; + mutex_lock(&data->update_lock); + reg = w83627ehf_read_value(client, W83627EHF_REG_PWM_ENABLE[nr]); + data->pwm_enable[nr] = val; + reg &= ~(0x03 << W83627EHF_PWM_ENABLE_SHIFT[nr]); + reg |= (val - 1) << W83627EHF_PWM_ENABLE_SHIFT[nr]; + w83627ehf_write_value(client, W83627EHF_REG_PWM_ENABLE[nr], reg); + mutex_unlock(&data->update_lock); + return count; +} + + +#define show_tol_temp(reg) \ +static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct w83627ehf_data *data = w83627ehf_update_device(dev); \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ + return sprintf(buf, "%d\n", temp1_from_reg(data->reg[nr])); \ +} + +show_tol_temp(tolerance) +show_tol_temp(target_temp) + +static ssize_t +store_target_temp(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct w83627ehf_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 127000); + + mutex_lock(&data->update_lock); + data->target_temp[nr] = val; + w83627ehf_write_value(client, W83627EHF_REG_TARGET[nr], val); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t +store_tolerance(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct w83627ehf_data *data = i2c_get_clientdata(client); + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); + int nr = sensor_attr->index; + u16 reg; + /* Limit the temp to 0C - 15C */ + u8 val = temp1_to_reg(simple_strtoul(buf, NULL, 10), 0, 15000); + + mutex_lock(&data->update_lock); + reg = w83627ehf_read_value(client, W83627EHF_REG_TOLERANCE[nr]); + data->tolerance[nr] = val; + if (nr == 1) + reg = (reg & 0x0f) | (val << 4); + else + reg = (reg & 0xf0) | val; + w83627ehf_write_value(client, W83627EHF_REG_TOLERANCE[nr], reg); + mutex_unlock(&data->update_lock); + return count; +} + +static struct sensor_device_attribute sda_pwm[] = { + SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0), + SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), + SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), + SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3), +}; + +static struct sensor_device_attribute sda_pwm_mode[] = { + SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode, + store_pwm_mode, 0), + SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode, + store_pwm_mode, 1), + SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, show_pwm_mode, + store_pwm_mode, 2), + SENSOR_ATTR(pwm4_mode, S_IWUSR | S_IRUGO, show_pwm_mode, + store_pwm_mode, 3), +}; + +static struct sensor_device_attribute sda_pwm_enable[] = { + SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + store_pwm_enable, 0), + SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + store_pwm_enable, 1), + SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + store_pwm_enable, 2), + SENSOR_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_enable, + store_pwm_enable, 3), +}; + +static struct sensor_device_attribute sda_target_temp[] = { + SENSOR_ATTR(pwm1_target, S_IWUSR | S_IRUGO, show_target_temp, + store_target_temp, 0), + SENSOR_ATTR(pwm2_target, S_IWUSR | S_IRUGO, show_target_temp, + store_target_temp, 1), + SENSOR_ATTR(pwm3_target, S_IWUSR | S_IRUGO, show_target_temp, + store_target_temp, 2), + SENSOR_ATTR(pwm4_target, S_IWUSR | S_IRUGO, show_target_temp, + store_target_temp, 3), +}; + +static struct sensor_device_attribute sda_tolerance[] = { + SENSOR_ATTR(pwm1_tolerance, S_IWUSR | S_IRUGO, show_tolerance, + store_tolerance, 0), + SENSOR_ATTR(pwm2_tolerance, S_IWUSR | S_IRUGO, show_tolerance, + store_tolerance, 1), + SENSOR_ATTR(pwm3_tolerance, S_IWUSR | S_IRUGO, show_tolerance, + store_tolerance, 2), + SENSOR_ATTR(pwm4_tolerance, S_IWUSR | S_IRUGO, show_tolerance, + store_tolerance, 3), +}; + +/* Smart Fan registers */ + +#define fan_functions(reg, REG) \ +static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct w83627ehf_data *data = w83627ehf_update_device(dev); \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ + return sprintf(buf, "%d\n", data->reg[nr]); \ +}\ +static ssize_t \ +store_##reg(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{\ + struct i2c_client *client = to_i2c_client(dev); \ + struct w83627ehf_data *data = i2c_get_clientdata(client); \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ + u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ + mutex_lock(&data->update_lock); \ + data->reg[nr] = val; \ + w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ + mutex_unlock(&data->update_lock); \ + return count; \ +} + +fan_functions(fan_min_output, FAN_MIN_OUTPUT) + +#define fan_time_functions(reg, REG) \ +static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct w83627ehf_data *data = w83627ehf_update_device(dev); \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ + return sprintf(buf, "%d\n", \ + step_time_from_reg(data->reg[nr], data->pwm_mode[nr])); \ +} \ +\ +static ssize_t \ +store_##reg(struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct w83627ehf_data *data = i2c_get_clientdata(client); \ + struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ + int nr = sensor_attr->index; \ + u8 val = step_time_to_reg(simple_strtoul(buf, NULL, 10), \ + data->pwm_mode[nr]); \ + mutex_lock(&data->update_lock); \ + data->reg[nr] = val; \ + w83627ehf_write_value(client, W83627EHF_REG_##REG[nr], val); \ + mutex_unlock(&data->update_lock); \ + return count; \ +} \ + +fan_time_functions(fan_stop_time, FAN_STOP_TIME) + + +static struct sensor_device_attribute sda_sf3_arrays_fan4[] = { + SENSOR_ATTR(pwm4_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, + store_fan_stop_time, 3), + SENSOR_ATTR(pwm4_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, + store_fan_min_output, 3), +}; + +static struct sensor_device_attribute sda_sf3_arrays[] = { + SENSOR_ATTR(pwm1_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, + store_fan_stop_time, 0), + SENSOR_ATTR(pwm2_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, + store_fan_stop_time, 1), + SENSOR_ATTR(pwm3_stop_time, S_IWUSR | S_IRUGO, show_fan_stop_time, + store_fan_stop_time, 2), + SENSOR_ATTR(pwm1_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, + store_fan_min_output, 0), + SENSOR_ATTR(pwm2_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, + store_fan_min_output, 1), + SENSOR_ATTR(pwm3_min_output, S_IWUSR | S_IRUGO, show_fan_min_output, + store_fan_min_output, 2), +}; + /* * Driver and client management */ +static void w83627ehf_device_remove_files(struct device *dev) +{ + /* some entries in the following arrays may not have been used in + * device_create_file(), but device_remove_file() will ignore them */ + int i; + + for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) + device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) + device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); + for (i = 0; i < 10; i++) { + device_remove_file(dev, &sda_in_input[i].dev_attr); + device_remove_file(dev, &sda_in_alarm[i].dev_attr); + device_remove_file(dev, &sda_in_min[i].dev_attr); + device_remove_file(dev, &sda_in_max[i].dev_attr); + } + for (i = 0; i < 5; i++) { + device_remove_file(dev, &sda_fan_input[i].dev_attr); + device_remove_file(dev, &sda_fan_alarm[i].dev_attr); + device_remove_file(dev, &sda_fan_div[i].dev_attr); + device_remove_file(dev, &sda_fan_min[i].dev_attr); + } + for (i = 0; i < 4; i++) { + device_remove_file(dev, &sda_pwm[i].dev_attr); + device_remove_file(dev, &sda_pwm_mode[i].dev_attr); + device_remove_file(dev, &sda_pwm_enable[i].dev_attr); + device_remove_file(dev, &sda_target_temp[i].dev_attr); + device_remove_file(dev, &sda_tolerance[i].dev_attr); + } + for (i = 0; i < ARRAY_SIZE(sda_temp); i++) + device_remove_file(dev, &sda_temp[i].dev_attr); +} + static struct i2c_driver w83627ehf_driver; static void w83627ehf_init_client(struct i2c_client *client) @@ -810,6 +1169,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) struct i2c_client *client; struct w83627ehf_data *data; struct device *dev; + u8 fan4pin, fan5pin; int i, err = 0; if (!request_region(address + REGION_OFFSET, REGION_LENGTH, @@ -848,35 +1208,87 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) data->fan_min[i] = w83627ehf_read_value(client, W83627EHF_REG_FAN_MIN[i]); + /* fan4 and fan5 share some pins with the GPIO and serial flash */ + + superio_enter(); + fan5pin = superio_inb(0x24) & 0x2; + fan4pin = superio_inb(0x29) & 0x6; + superio_exit(); + /* It looks like fan4 and fan5 pins can be alternatively used as fan on/off switches */ + data->has_fan = 0x07; /* fan1, fan2 and fan3 */ i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1); - if (i & (1 << 2)) + if ((i & (1 << 2)) && (!fan4pin)) data->has_fan |= (1 << 3); - if (i & (1 << 0)) + if ((i & (1 << 0)) && (!fan5pin)) data->has_fan |= (1 << 4); /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - goto exit_detach; - } + for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) + if ((err = device_create_file(dev, + &sda_sf3_arrays[i].dev_attr))) + goto exit_remove; + + /* if fan4 is enabled create the sf3 files for it */ + if (data->has_fan & (1 << 3)) + for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { + if ((err = device_create_file(dev, + &sda_sf3_arrays_fan4[i].dev_attr))) + goto exit_remove; + } for (i = 0; i < 10; i++) - device_create_file_in(dev, i); + if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) + || (err = device_create_file(dev, + &sda_in_alarm[i].dev_attr)) + || (err = device_create_file(dev, + &sda_in_min[i].dev_attr)) + || (err = device_create_file(dev, + &sda_in_max[i].dev_attr))) + goto exit_remove; for (i = 0; i < 5; i++) { - if (data->has_fan & (1 << i)) - device_create_file_fan(dev, i); + if (data->has_fan & (1 << i)) { + if ((err = device_create_file(dev, + &sda_fan_input[i].dev_attr)) + || (err = device_create_file(dev, + &sda_fan_alarm[i].dev_attr)) + || (err = device_create_file(dev, + &sda_fan_div[i].dev_attr)) + || (err = device_create_file(dev, + &sda_fan_min[i].dev_attr))) + goto exit_remove; + if (i < 4 && /* w83627ehf only has 4 pwm */ + ((err = device_create_file(dev, + &sda_pwm[i].dev_attr)) + || (err = device_create_file(dev, + &sda_pwm_mode[i].dev_attr)) + || (err = device_create_file(dev, + &sda_pwm_enable[i].dev_attr)) + || (err = device_create_file(dev, + &sda_target_temp[i].dev_attr)) + || (err = device_create_file(dev, + &sda_tolerance[i].dev_attr)))) + goto exit_remove; + } } + for (i = 0; i < ARRAY_SIZE(sda_temp); i++) - device_create_file(dev, &sda_temp[i].dev_attr); + if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) + goto exit_remove; + + data->class_dev = hwmon_device_register(dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove; + } return 0; -exit_detach: +exit_remove: + w83627ehf_device_remove_files(dev); i2c_detach_client(client); exit_free: kfree(data); @@ -892,6 +1304,7 @@ static int w83627ehf_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); + w83627ehf_device_remove_files(&client->dev); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 30295028ea9..dfdc29c7712 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -512,13 +512,6 @@ static DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, show_regs_in_max0, store_regs_in_max0); -#define device_create_file_in(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_in##offset##_input); \ -device_create_file(&client->dev, &dev_attr_in##offset##_min); \ -device_create_file(&client->dev, &dev_attr_in##offset##_max); \ -} while (0) - #define show_fan_reg(reg) \ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ { \ @@ -576,12 +569,6 @@ sysfs_fan_min_offset(2); sysfs_fan_offset(3); sysfs_fan_min_offset(3); -#define device_create_file_fan(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_fan##offset##_input); \ -device_create_file(&client->dev, &dev_attr_fan##offset##_min); \ -} while (0) - #define show_temp_reg(reg) \ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ { \ @@ -656,13 +643,6 @@ sysfs_temp_offsets(1); sysfs_temp_offsets(2); sysfs_temp_offsets(3); -#define device_create_file_temp(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_temp##offset##_input); \ -device_create_file(&client->dev, &dev_attr_temp##offset##_max); \ -device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \ -} while (0) - static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) { @@ -670,8 +650,6 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); } static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); -#define device_create_file_vid(client) \ -device_create_file(&client->dev, &dev_attr_cpu0_vid) static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) @@ -692,8 +670,6 @@ store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf return count; } static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); -#define device_create_file_vrm(client) \ -device_create_file(&client->dev, &dev_attr_vrm) static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) @@ -702,8 +678,6 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%ld\n", (long) data->alarms); } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); -#define device_create_file_alarms(client) \ -device_create_file(&client->dev, &dev_attr_alarms) #define show_beep_reg(REG, reg) \ static ssize_t show_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \ @@ -766,12 +740,6 @@ static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \ sysfs_beep(ENABLE, enable); sysfs_beep(MASK, mask); -#define device_create_file_beep(client) \ -do { \ -device_create_file(&client->dev, &dev_attr_beep_enable); \ -device_create_file(&client->dev, &dev_attr_beep_mask); \ -} while (0) - static ssize_t show_fan_div_reg(struct device *dev, char *buf, int nr) { @@ -837,11 +805,6 @@ sysfs_fan_div(1); sysfs_fan_div(2); sysfs_fan_div(3); -#define device_create_file_fan_div(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_fan##offset##_div); \ -} while (0) - static ssize_t show_pwm_reg(struct device *dev, char *buf, int nr) { @@ -896,11 +859,6 @@ sysfs_pwm(1); sysfs_pwm(2); sysfs_pwm(3); -#define device_create_file_pwm(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_pwm##offset); \ -} while (0) - static ssize_t show_sensor_reg(struct device *dev, char *buf, int nr) { @@ -972,12 +930,6 @@ sysfs_sensor(1); sysfs_sensor(2); sysfs_sensor(3); -#define device_create_file_sensor(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_temp##offset##_type); \ -} while (0) - - static int __init w83627hf_find(int sioaddr, unsigned short *addr) { u16 val; @@ -1009,6 +961,85 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr) return 0; } +static struct attribute *w83627hf_attributes[] = { + &dev_attr_in0_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in2_input.attr, + &dev_attr_in2_min.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_input.attr, + &dev_attr_in3_min.attr, + &dev_attr_in3_max.attr, + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + &dev_attr_in7_input.attr, + &dev_attr_in7_min.attr, + &dev_attr_in7_max.attr, + &dev_attr_in8_input.attr, + &dev_attr_in8_min.attr, + &dev_attr_in8_max.attr, + + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, + &dev_attr_temp1_type.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp2_max.attr, + &dev_attr_temp2_max_hyst.attr, + &dev_attr_temp2_type.attr, + + &dev_attr_alarms.attr, + &dev_attr_beep_enable.attr, + &dev_attr_beep_mask.attr, + + &dev_attr_pwm1.attr, + &dev_attr_pwm2.attr, + + NULL +}; + +static const struct attribute_group w83627hf_group = { + .attrs = w83627hf_attributes, +}; + +static struct attribute *w83627hf_attributes_opt[] = { + &dev_attr_in1_input.attr, + &dev_attr_in1_min.attr, + &dev_attr_in1_max.attr, + &dev_attr_in5_input.attr, + &dev_attr_in5_min.attr, + &dev_attr_in5_max.attr, + &dev_attr_in6_input.attr, + &dev_attr_in6_min.attr, + &dev_attr_in6_max.attr, + + &dev_attr_fan3_input.attr, + &dev_attr_fan3_min.attr, + &dev_attr_fan3_div.attr, + + &dev_attr_temp3_input.attr, + &dev_attr_temp3_max.attr, + &dev_attr_temp3_max_hyst.attr, + &dev_attr_temp3_type.attr, + + &dev_attr_pwm3.attr, + + NULL +}; + +static const struct attribute_group w83627hf_group_opt = { + .attrs = w83627hf_attributes_opt, +}; + static int w83627hf_detect(struct i2c_adapter *adapter) { int val, kind; @@ -1108,62 +1139,72 @@ static int w83627hf_detect(struct i2c_adapter *adapter) data->fan_min[1] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(2)); data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3)); - /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + /* Register common device attributes */ + if ((err = sysfs_create_group(&new_client->dev.kobj, &w83627hf_group))) goto ERROR3; - } - - device_create_file_in(new_client, 0); - if (kind != w83697hf) - device_create_file_in(new_client, 1); - device_create_file_in(new_client, 2); - device_create_file_in(new_client, 3); - device_create_file_in(new_client, 4); - if (kind == w83627hf || kind == w83697hf) { - device_create_file_in(new_client, 5); - device_create_file_in(new_client, 6); - } - device_create_file_in(new_client, 7); - device_create_file_in(new_client, 8); - - device_create_file_fan(new_client, 1); - device_create_file_fan(new_client, 2); - if (kind != w83697hf) - device_create_file_fan(new_client, 3); - - device_create_file_temp(new_client, 1); - device_create_file_temp(new_client, 2); - if (kind != w83697hf) - device_create_file_temp(new_client, 3); - if (kind != w83697hf && data->vid != 0xff) { - device_create_file_vid(new_client); - device_create_file_vrm(new_client); - } + /* Register chip-specific device attributes */ + if (kind == w83627hf || kind == w83697hf) + if ((err = device_create_file(&new_client->dev, + &dev_attr_in5_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in5_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in5_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in6_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in6_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in6_max))) + goto ERROR4; - device_create_file_fan_div(new_client, 1); - device_create_file_fan_div(new_client, 2); if (kind != w83697hf) - device_create_file_fan_div(new_client, 3); - - device_create_file_alarms(new_client); - - device_create_file_beep(new_client); + if ((err = device_create_file(&new_client->dev, + &dev_attr_in1_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in1_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in1_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan3_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan3_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan3_div)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_max_hyst)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_type))) + goto ERROR4; + + if (kind != w83697hf && data->vid != 0xff) + if ((err = device_create_file(&new_client->dev, + &dev_attr_cpu0_vid)) + || (err = device_create_file(&new_client->dev, + &dev_attr_vrm))) + goto ERROR4; - device_create_file_pwm(new_client, 1); - device_create_file_pwm(new_client, 2); if (kind == w83627thf || kind == w83637hf || kind == w83687thf) - device_create_file_pwm(new_client, 3); + if ((err = device_create_file(&new_client->dev, + &dev_attr_pwm3))) + goto ERROR4; - device_create_file_sensor(new_client, 1); - device_create_file_sensor(new_client, 2); - if (kind != w83697hf) - device_create_file_sensor(new_client, 3); + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto ERROR4; + } return 0; + ERROR4: + sysfs_remove_group(&new_client->dev.kobj, &w83627hf_group); + sysfs_remove_group(&new_client->dev.kobj, &w83627hf_group_opt); ERROR3: i2c_detach_client(new_client); ERROR2: @@ -1181,6 +1222,9 @@ static int w83627hf_detach_client(struct i2c_client *client) hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &w83627hf_group); + sysfs_remove_group(&client->dev.kobj, &w83627hf_group_opt); + if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 95221b14e13..a4584ec6984 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -41,6 +41,7 @@ #include <linux/i2c-isa.h> #include <linux/hwmon.h> #include <linux/hwmon-vid.h> +#include <linux/sysfs.h> #include <linux/err.h> #include <linux/mutex.h> #include <asm/io.h> @@ -360,13 +361,6 @@ sysfs_in_offsets(6); sysfs_in_offsets(7); sysfs_in_offsets(8); -#define device_create_file_in(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_in##offset##_input); \ -device_create_file(&client->dev, &dev_attr_in##offset##_min); \ -device_create_file(&client->dev, &dev_attr_in##offset##_max); \ -} while (0) - #define show_fan_reg(reg) \ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ { \ @@ -421,12 +415,6 @@ sysfs_fan_min_offset(2); sysfs_fan_offset(3); sysfs_fan_min_offset(3); -#define device_create_file_fan(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_fan##offset##_input); \ -device_create_file(&client->dev, &dev_attr_fan##offset##_min); \ -} while (0) - #define show_temp_reg(reg) \ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ { \ @@ -497,13 +485,6 @@ sysfs_temp_offsets(1); sysfs_temp_offsets(2); sysfs_temp_offsets(3); -#define device_create_file_temp(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_temp##offset##_input); \ -device_create_file(&client->dev, &dev_attr_temp##offset##_max); \ -device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \ -} while (0) - static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) { @@ -511,10 +492,8 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); } -static -DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); -#define device_create_file_vid(client) \ -device_create_file(&client->dev, &dev_attr_cpu0_vid); +static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); + static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) { @@ -535,10 +514,8 @@ store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf return count; } -static -DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); -#define device_create_file_vrm(client) \ -device_create_file(&client->dev, &dev_attr_vrm); +static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); + static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) { @@ -546,10 +523,8 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%u\n", data->alarms); } -static -DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); -#define device_create_file_alarms(client) \ -device_create_file(&client->dev, &dev_attr_alarms); +static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); + static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf) { struct w83781d_data *data = w83781d_update_device(dev); @@ -615,12 +590,6 @@ static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_re sysfs_beep(ENABLE, enable); sysfs_beep(MASK, mask); -#define device_create_file_beep(client) \ -do { \ -device_create_file(&client->dev, &dev_attr_beep_enable); \ -device_create_file(&client->dev, &dev_attr_beep_mask); \ -} while (0) - static ssize_t show_fan_div_reg(struct device *dev, char *buf, int nr) { @@ -686,11 +655,6 @@ sysfs_fan_div(1); sysfs_fan_div(2); sysfs_fan_div(3); -#define device_create_file_fan_div(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_fan##offset##_div); \ -} while (0) - static ssize_t show_pwm_reg(struct device *dev, char *buf, int nr) { @@ -787,16 +751,6 @@ sysfs_pwmenable(2); /* only PWM2 can be enabled/disabled */ sysfs_pwm(3); sysfs_pwm(4); -#define device_create_file_pwm(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_pwm##offset); \ -} while (0) - -#define device_create_file_pwmenable(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_pwm##offset##_enable); \ -} while (0) - static ssize_t show_sensor_reg(struct device *dev, char *buf, int nr) { @@ -865,11 +819,6 @@ sysfs_sensor(1); sysfs_sensor(2); sysfs_sensor(3); -#define device_create_file_sensor(client, offset) \ -do { \ -device_create_file(&client->dev, &dev_attr_temp##offset##_type); \ -} while (0) - /* This function is called when: * w83781d_driver is inserted (when this module is loaded), for each available adapter @@ -994,11 +943,69 @@ ERROR_SC_0: return err; } +#define IN_UNIT_ATTRS(X) \ + &dev_attr_in##X##_input.attr, \ + &dev_attr_in##X##_min.attr, \ + &dev_attr_in##X##_max.attr + +#define FAN_UNIT_ATTRS(X) \ + &dev_attr_fan##X##_input.attr, \ + &dev_attr_fan##X##_min.attr, \ + &dev_attr_fan##X##_div.attr + +#define TEMP_UNIT_ATTRS(X) \ + &dev_attr_temp##X##_input.attr, \ + &dev_attr_temp##X##_max.attr, \ + &dev_attr_temp##X##_max_hyst.attr + +static struct attribute* w83781d_attributes[] = { + IN_UNIT_ATTRS(0), + IN_UNIT_ATTRS(2), + IN_UNIT_ATTRS(3), + IN_UNIT_ATTRS(4), + IN_UNIT_ATTRS(5), + IN_UNIT_ATTRS(6), + FAN_UNIT_ATTRS(1), + FAN_UNIT_ATTRS(2), + FAN_UNIT_ATTRS(3), + TEMP_UNIT_ATTRS(1), + TEMP_UNIT_ATTRS(2), + &dev_attr_cpu0_vid.attr, + &dev_attr_vrm.attr, + &dev_attr_alarms.attr, + &dev_attr_beep_mask.attr, + &dev_attr_beep_enable.attr, + NULL +}; +static const struct attribute_group w83781d_group = { + .attrs = w83781d_attributes, +}; + +static struct attribute *w83781d_attributes_opt[] = { + IN_UNIT_ATTRS(1), + IN_UNIT_ATTRS(7), + IN_UNIT_ATTRS(8), + TEMP_UNIT_ATTRS(3), + &dev_attr_pwm1.attr, + &dev_attr_pwm2.attr, + &dev_attr_pwm2_enable.attr, + &dev_attr_pwm3.attr, + &dev_attr_pwm4.attr, + &dev_attr_temp1_type.attr, + &dev_attr_temp2_type.attr, + &dev_attr_temp3_type.attr, + NULL +}; +static const struct attribute_group w83781d_group_opt = { + .attrs = w83781d_attributes_opt, +}; + static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind) { int i = 0, val1 = 0, val2; - struct i2c_client *new_client; + struct i2c_client *client; + struct device *dev; struct w83781d_data *data; int err; const char *client_name = ""; @@ -1075,13 +1082,14 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) goto ERROR1; } - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; + client = &data->client; + i2c_set_clientdata(client, data); + client->addr = address; mutex_init(&data->lock); - new_client->adapter = adapter; - new_client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver; - new_client->flags = 0; + client->adapter = adapter; + client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver; + client->flags = 0; + dev = &client->dev; /* Now, we do the remaining detection. */ @@ -1090,20 +1098,18 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) force_*=... parameter, and the Winbond will be reset to the right bank. */ if (kind < 0) { - if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80) { - dev_dbg(&new_client->dev, "Detection failed at step " - "3\n"); + if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) { + dev_dbg(dev, "Detection failed at step 3\n"); err = -ENODEV; goto ERROR2; } - val1 = w83781d_read_value(new_client, W83781D_REG_BANK); - val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN); + val1 = w83781d_read_value(client, W83781D_REG_BANK); + val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN); /* Check for Winbond or Asus ID if in bank 0 */ if ((!(val1 & 0x07)) && (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) { - dev_dbg(&new_client->dev, "Detection failed at step " - "4\n"); + dev_dbg(dev, "Detection failed at step 4\n"); err = -ENODEV; goto ERROR2; } @@ -1112,9 +1118,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) || ((val1 & 0x80) && (val2 == 0x5c)))) { if (w83781d_read_value - (new_client, W83781D_REG_I2C_ADDR) != address) { - dev_dbg(&new_client->dev, "Detection failed " - "at step 5\n"); + (client, W83781D_REG_I2C_ADDR) != address) { + dev_dbg(dev, "Detection failed at step 5\n"); err = -ENODEV; goto ERROR2; } @@ -1123,27 +1128,26 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) /* We have either had a force parameter, or we have already detected the Winbond. Put it now into bank 0 and Vendor ID High Byte */ - w83781d_write_value(new_client, W83781D_REG_BANK, - (w83781d_read_value(new_client, - W83781D_REG_BANK) & 0x78) | - 0x80); + w83781d_write_value(client, W83781D_REG_BANK, + (w83781d_read_value(client, W83781D_REG_BANK) + & 0x78) | 0x80); /* Determine the chip type. */ if (kind <= 0) { /* get vendor ID */ - val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN); + val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN); if (val2 == 0x5c) vendid = winbond; else if (val2 == 0x12) vendid = asus; else { - dev_dbg(&new_client->dev, "Chip was made by neither " + dev_dbg(dev, "Chip was made by neither " "Winbond nor Asus?\n"); err = -ENODEV; goto ERROR2; } - val1 = w83781d_read_value(new_client, W83781D_REG_WCHIPID); + val1 = w83781d_read_value(client, W83781D_REG_WCHIPID); if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) kind = w83781d; else if (val1 == 0x30 && vendid == winbond) @@ -1157,7 +1161,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) kind = as99127f; else { if (kind == 0) - dev_warn(&new_client->dev, "Ignoring 'force' " + dev_warn(dev, "Ignoring 'force' " "parameter for unknown chip at " "adapter %d, address 0x%02x\n", i2c_adapter_id(adapter), address); @@ -1179,20 +1183,20 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) } /* Fill in the remaining client fields and put into the global list */ - strlcpy(new_client->name, client_name, I2C_NAME_SIZE); + strlcpy(client->name, client_name, I2C_NAME_SIZE); data->type = kind; data->valid = 0; mutex_init(&data->update_lock); /* Tell the I2C layer a new client has arrived */ - if ((err = i2c_attach_client(new_client))) + if ((err = i2c_attach_client(client))) goto ERROR2; /* attach secondary i2c lm75-like clients */ if (!is_isa) { if ((err = w83781d_detect_subclients(adapter, address, - kind, new_client))) + kind, client))) goto ERROR3; } else { data->lm75[0] = NULL; @@ -1200,11 +1204,11 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) } /* Initialize the chip */ - w83781d_init_client(new_client); + w83781d_init_client(client); /* A few vars need to be filled upon startup */ for (i = 1; i <= 3; i++) { - data->fan_min[i - 1] = w83781d_read_value(new_client, + data->fan_min[i - 1] = w83781d_read_value(client, W83781D_REG_FAN_MIN(i)); } if (kind != w83781d && kind != as99127f) @@ -1212,65 +1216,68 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) data->pwmenable[i] = 1; /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(&new_client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&dev->kobj, &w83781d_group))) goto ERROR4; - } - device_create_file_in(new_client, 0); - if (kind != w83783s) - device_create_file_in(new_client, 1); - device_create_file_in(new_client, 2); - device_create_file_in(new_client, 3); - device_create_file_in(new_client, 4); - device_create_file_in(new_client, 5); - device_create_file_in(new_client, 6); + if (kind != w83783s) { + if ((err = device_create_file(dev, &dev_attr_in1_input)) + || (err = device_create_file(dev, &dev_attr_in1_min)) + || (err = device_create_file(dev, &dev_attr_in1_max))) + goto ERROR4; + } if (kind != as99127f && kind != w83781d && kind != w83783s) { - device_create_file_in(new_client, 7); - device_create_file_in(new_client, 8); + if ((err = device_create_file(dev, &dev_attr_in7_input)) + || (err = device_create_file(dev, &dev_attr_in7_min)) + || (err = device_create_file(dev, &dev_attr_in7_max)) + || (err = device_create_file(dev, &dev_attr_in8_input)) + || (err = device_create_file(dev, &dev_attr_in8_min)) + || (err = device_create_file(dev, &dev_attr_in8_max))) + goto ERROR4; + } + if (kind != w83783s) { + if ((err = device_create_file(dev, &dev_attr_temp3_input)) + || (err = device_create_file(dev, &dev_attr_temp3_max)) + || (err = device_create_file(dev, + &dev_attr_temp3_max_hyst))) + goto ERROR4; } - - device_create_file_fan(new_client, 1); - device_create_file_fan(new_client, 2); - device_create_file_fan(new_client, 3); - - device_create_file_temp(new_client, 1); - device_create_file_temp(new_client, 2); - if (kind != w83783s) - device_create_file_temp(new_client, 3); - - device_create_file_vid(new_client); - device_create_file_vrm(new_client); - - device_create_file_fan_div(new_client, 1); - device_create_file_fan_div(new_client, 2); - device_create_file_fan_div(new_client, 3); - - device_create_file_alarms(new_client); - - device_create_file_beep(new_client); if (kind != w83781d && kind != as99127f) { - device_create_file_pwm(new_client, 1); - device_create_file_pwm(new_client, 2); - device_create_file_pwmenable(new_client, 2); + if ((err = device_create_file(dev, &dev_attr_pwm1)) + || (err = device_create_file(dev, &dev_attr_pwm2)) + || (err = device_create_file(dev, &dev_attr_pwm2_enable))) + goto ERROR4; } if (kind == w83782d && !is_isa) { - device_create_file_pwm(new_client, 3); - device_create_file_pwm(new_client, 4); + if ((err = device_create_file(dev, &dev_attr_pwm3)) + || (err = device_create_file(dev, &dev_attr_pwm4))) + goto ERROR4; } if (kind != as99127f && kind != w83781d) { - device_create_file_sensor(new_client, 1); - device_create_file_sensor(new_client, 2); - if (kind != w83783s) - device_create_file_sensor(new_client, 3); + if ((err = device_create_file(dev, &dev_attr_temp1_type)) + || (err = device_create_file(dev, + &dev_attr_temp2_type))) + goto ERROR4; + if (kind != w83783s) { + if ((err = device_create_file(dev, + &dev_attr_temp3_type))) + goto ERROR4; + } + } + + data->class_dev = hwmon_device_register(dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto ERROR4; } return 0; ERROR4: + sysfs_remove_group(&dev->kobj, &w83781d_group); + sysfs_remove_group(&dev->kobj, &w83781d_group_opt); + if (data->lm75[1]) { i2c_detach_client(data->lm75[1]); kfree(data->lm75[1]); @@ -1280,7 +1287,7 @@ ERROR4: kfree(data->lm75[0]); } ERROR3: - i2c_detach_client(new_client); + i2c_detach_client(client); ERROR2: kfree(data); ERROR1: @@ -1297,9 +1304,11 @@ w83781d_detach_client(struct i2c_client *client) int err; /* main client */ - if (data) + if (data) { hwmon_device_unregister(data->class_dev); - + sysfs_remove_group(&client->dev.kobj, &w83781d_group); + sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); + } if (i2c_is_isa_client(client)) release_region(client->addr, W83781D_EXTENT); diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index eec43abd57f..d965d074cd6 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c @@ -27,9 +27,9 @@ The w83791d chip appears to be part way between the 83781d and the 83792d. Thus, this file is derived from both the w83792d.c and - w83781d.c files, but its output is more along the lines of the - 83781d (which means there are no changes to the user-mode sensors - program which treats the 83791d as an 83781d). + w83781d.c files. + + The w83791g chip is the same as the w83791d but lead-free. */ #include <linux/config.h> @@ -1172,6 +1172,7 @@ static struct w83791d_data *w83791d_update_device(struct device *dev) (w83791d_read(client, W83791D_REG_BEEP_CTRL[1]) << 8) + (w83791d_read(client, W83791D_REG_BEEP_CTRL[2]) << 16); + /* Extract global beep enable flag */ data->beep_enable = (data->beep_mask >> GLOBAL_BEEP_ENABLE_SHIFT) & 0x01; diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 7576ec9426a..4e108262576 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -43,6 +43,7 @@ #include <linux/hwmon-sysfs.h> #include <linux/err.h> #include <linux/mutex.h> +#include <linux/sysfs.h> /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END }; @@ -381,41 +382,6 @@ static ssize_t store_in_##reg (struct device *dev, \ store_in_reg(MIN, min); store_in_reg(MAX, max); -static struct sensor_device_attribute sda_in_input[] = { - SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), - SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), - SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), - SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), - SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), - SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), - SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), - SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), - SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8), -}; -static struct sensor_device_attribute sda_in_min[] = { - SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), - SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), - SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), - SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3), - SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4), - SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5), - SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6), - SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7), - SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8), -}; -static struct sensor_device_attribute sda_in_max[] = { - SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), - SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), - SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), - SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3), - SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4), - SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5), - SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6), - SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7), - SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8), -}; - - #define show_fan_reg(reg) \ static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \ char *buf) \ @@ -499,35 +465,6 @@ store_fan_div(struct device *dev, struct device_attribute *attr, return count; } -static struct sensor_device_attribute sda_fan_input[] = { - SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 1), - SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 2), - SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 3), - SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 4), - SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 5), - SENSOR_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 6), - SENSOR_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 7), -}; -static struct sensor_device_attribute sda_fan_min[] = { - SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 1), - SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 2), - SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 3), - SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 4), - SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 5), - SENSOR_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 6), - SENSOR_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 7), -}; -static struct sensor_device_attribute sda_fan_div[] = { - SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 1), - SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 2), - SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 3), - SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 4), - SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 5), - SENSOR_ATTR(fan6_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 6), - SENSOR_ATTR(fan7_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 7), -}; - - /* read/write the temperature1, includes measured value and limits */ static ssize_t show_temp1(struct device *dev, struct device_attribute *attr, @@ -595,24 +532,6 @@ static ssize_t store_temp23(struct device *dev, struct device_attribute *attr, return count; } -static struct sensor_device_attribute_2 sda_temp_input[] = { - SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0), - SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0), - SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0), -}; - -static struct sensor_device_attribute_2 sda_temp_max[] = { - SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp1, store_temp1, 0, 1), - SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 0, 2), - SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 1, 2), -}; - -static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { - SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1, store_temp1, 0, 2), - SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 0, 4), - SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 1, 4), -}; - /* get reatime status of all sensors items: voltage, temp, fan */ static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) @@ -621,9 +540,6 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%d\n", data->alarms); } -static -DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); - static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, char *buf) @@ -715,21 +631,6 @@ store_pwmenable(struct device *dev, struct device_attribute *attr, return count; } -static struct sensor_device_attribute sda_pwm[] = { - SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0), - SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), - SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2), -}; -static struct sensor_device_attribute sda_pwm_enable[] = { - SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, - show_pwmenable, store_pwmenable, 1), - SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, - show_pwmenable, store_pwmenable, 2), - SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, - show_pwmenable, store_pwmenable, 3), -}; - - static ssize_t show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) @@ -767,16 +668,6 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, return count; } -static struct sensor_device_attribute sda_pwm_mode[] = { - SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, - show_pwm_mode, store_pwm_mode, 0), - SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, - show_pwm_mode, store_pwm_mode, 1), - SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, - show_pwm_mode, store_pwm_mode, 2), -}; - - static ssize_t show_regs_chassis(struct device *dev, struct device_attribute *attr, char *buf) @@ -785,8 +676,6 @@ show_regs_chassis(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%d\n", data->chassis); } -static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); - static ssize_t show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf) { @@ -815,9 +704,6 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, - show_chassis_clear, store_chassis_clear); - /* For Smart Fan I / Thermal Cruise */ static ssize_t show_thermal_cruise(struct device *dev, struct device_attribute *attr, @@ -853,15 +739,6 @@ store_thermal_cruise(struct device *dev, struct device_attribute *attr, return count; } -static struct sensor_device_attribute sda_thermal_cruise[] = { - SENSOR_ATTR(thermal_cruise1, S_IWUSR | S_IRUGO, - show_thermal_cruise, store_thermal_cruise, 1), - SENSOR_ATTR(thermal_cruise2, S_IWUSR | S_IRUGO, - show_thermal_cruise, store_thermal_cruise, 2), - SENSOR_ATTR(thermal_cruise3, S_IWUSR | S_IRUGO, - show_thermal_cruise, store_thermal_cruise, 3), -}; - /* For Smart Fan I/Thermal Cruise and Smart Fan II */ static ssize_t show_tolerance(struct device *dev, struct device_attribute *attr, @@ -901,15 +778,6 @@ store_tolerance(struct device *dev, struct device_attribute *attr, return count; } -static struct sensor_device_attribute sda_tolerance[] = { - SENSOR_ATTR(tolerance1, S_IWUSR | S_IRUGO, - show_tolerance, store_tolerance, 1), - SENSOR_ATTR(tolerance2, S_IWUSR | S_IRUGO, - show_tolerance, store_tolerance, 2), - SENSOR_ATTR(tolerance3, S_IWUSR | S_IRUGO, - show_tolerance, store_tolerance, 3), -}; - /* For Smart Fan II */ static ssize_t show_sf2_point(struct device *dev, struct device_attribute *attr, @@ -946,36 +814,6 @@ store_sf2_point(struct device *dev, struct device_attribute *attr, return count; } -static struct sensor_device_attribute_2 sda_sf2_point[] = { - SENSOR_ATTR_2(sf2_point1_fan1, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 1, 1), - SENSOR_ATTR_2(sf2_point2_fan1, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 2, 1), - SENSOR_ATTR_2(sf2_point3_fan1, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 3, 1), - SENSOR_ATTR_2(sf2_point4_fan1, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 4, 1), - - SENSOR_ATTR_2(sf2_point1_fan2, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 1, 2), - SENSOR_ATTR_2(sf2_point2_fan2, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 2, 2), - SENSOR_ATTR_2(sf2_point3_fan2, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 3, 2), - SENSOR_ATTR_2(sf2_point4_fan2, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 4, 2), - - SENSOR_ATTR_2(sf2_point1_fan3, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 1, 3), - SENSOR_ATTR_2(sf2_point2_fan3, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 2, 3), - SENSOR_ATTR_2(sf2_point3_fan3, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 3, 3), - SENSOR_ATTR_2(sf2_point4_fan3, S_IRUGO | S_IWUSR, - show_sf2_point, store_sf2_point, 4, 3), -}; - - static ssize_t show_sf2_level(struct device *dev, struct device_attribute *attr, char *buf) @@ -1016,29 +854,6 @@ store_sf2_level(struct device *dev, struct device_attribute *attr, return count; } -static struct sensor_device_attribute_2 sda_sf2_level[] = { - SENSOR_ATTR_2(sf2_level1_fan1, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 1, 1), - SENSOR_ATTR_2(sf2_level2_fan1, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 2, 1), - SENSOR_ATTR_2(sf2_level3_fan1, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 3, 1), - - SENSOR_ATTR_2(sf2_level1_fan2, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 1, 2), - SENSOR_ATTR_2(sf2_level2_fan2, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 2, 2), - SENSOR_ATTR_2(sf2_level3_fan2, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 3, 2), - - SENSOR_ATTR_2(sf2_level1_fan3, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 1, 3), - SENSOR_ATTR_2(sf2_level2_fan3, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 2, 3), - SENSOR_ATTR_2(sf2_level3_fan3, S_IRUGO | S_IWUSR, - show_sf2_level, store_sf2_level, 3, 3), -}; - /* This function is called when: * w83792d_driver is inserted (when this module is loaded), for each available adapter @@ -1139,12 +954,297 @@ ERROR_SC_0: return err; } -static void device_create_file_fan(struct device *dev, int i) -{ - device_create_file(dev, &sda_fan_input[i].dev_attr); - device_create_file(dev, &sda_fan_div[i].dev_attr); - device_create_file(dev, &sda_fan_min[i].dev_attr); -} +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0); +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1); +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2); +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3); +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4); +static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 5); +static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 6); +static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 7); +static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 8); +static SENSOR_DEVICE_ATTR(in0_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 0); +static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 1); +static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 2); +static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 3); +static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 4); +static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 5); +static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 6); +static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 7); +static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, + show_in_min, store_in_min, 8); +static SENSOR_DEVICE_ATTR(in0_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 0); +static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 1); +static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 2); +static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 3); +static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 4); +static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 5); +static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 6); +static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 7); +static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, + show_in_max, store_in_max, 8); +static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0); +static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0); +static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, + show_temp1, store_temp1, 0, 1); +static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp23, + store_temp23, 0, 2); +static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp23, + store_temp23, 1, 2); +static SENSOR_DEVICE_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, + show_temp1, store_temp1, 0, 2); +static SENSOR_DEVICE_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, + show_temp23, store_temp23, 0, 4); +static SENSOR_DEVICE_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, + show_temp23, store_temp23, 1, 4); +static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); +static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL); +static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR, + show_chassis_clear, store_chassis_clear); +static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0); +static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1); +static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2); +static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, + show_pwmenable, store_pwmenable, 1); +static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, + show_pwmenable, store_pwmenable, 2); +static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, + show_pwmenable, store_pwmenable, 3); +static SENSOR_DEVICE_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, + show_pwm_mode, store_pwm_mode, 0); +static SENSOR_DEVICE_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, + show_pwm_mode, store_pwm_mode, 1); +static SENSOR_DEVICE_ATTR(pwm3_mode, S_IWUSR | S_IRUGO, + show_pwm_mode, store_pwm_mode, 2); +static SENSOR_DEVICE_ATTR(tolerance1, S_IWUSR | S_IRUGO, + show_tolerance, store_tolerance, 1); +static SENSOR_DEVICE_ATTR(tolerance2, S_IWUSR | S_IRUGO, + show_tolerance, store_tolerance, 2); +static SENSOR_DEVICE_ATTR(tolerance3, S_IWUSR | S_IRUGO, + show_tolerance, store_tolerance, 3); +static SENSOR_DEVICE_ATTR(thermal_cruise1, S_IWUSR | S_IRUGO, + show_thermal_cruise, store_thermal_cruise, 1); +static SENSOR_DEVICE_ATTR(thermal_cruise2, S_IWUSR | S_IRUGO, + show_thermal_cruise, store_thermal_cruise, 2); +static SENSOR_DEVICE_ATTR(thermal_cruise3, S_IWUSR | S_IRUGO, + show_thermal_cruise, store_thermal_cruise, 3); +static SENSOR_DEVICE_ATTR_2(sf2_point1_fan1, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 1, 1); +static SENSOR_DEVICE_ATTR_2(sf2_point2_fan1, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 2, 1); +static SENSOR_DEVICE_ATTR_2(sf2_point3_fan1, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 3, 1); +static SENSOR_DEVICE_ATTR_2(sf2_point4_fan1, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 4, 1); +static SENSOR_DEVICE_ATTR_2(sf2_point1_fan2, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 1, 2); +static SENSOR_DEVICE_ATTR_2(sf2_point2_fan2, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 2, 2); +static SENSOR_DEVICE_ATTR_2(sf2_point3_fan2, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 3, 2); +static SENSOR_DEVICE_ATTR_2(sf2_point4_fan2, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 4, 2); +static SENSOR_DEVICE_ATTR_2(sf2_point1_fan3, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 1, 3); +static SENSOR_DEVICE_ATTR_2(sf2_point2_fan3, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 2, 3); +static SENSOR_DEVICE_ATTR_2(sf2_point3_fan3, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 3, 3); +static SENSOR_DEVICE_ATTR_2(sf2_point4_fan3, S_IRUGO | S_IWUSR, + show_sf2_point, store_sf2_point, 4, 3); +static SENSOR_DEVICE_ATTR_2(sf2_level1_fan1, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 1, 1); +static SENSOR_DEVICE_ATTR_2(sf2_level2_fan1, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 2, 1); +static SENSOR_DEVICE_ATTR_2(sf2_level3_fan1, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 3, 1); +static SENSOR_DEVICE_ATTR_2(sf2_level1_fan2, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 1, 2); +static SENSOR_DEVICE_ATTR_2(sf2_level2_fan2, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 2, 2); +static SENSOR_DEVICE_ATTR_2(sf2_level3_fan2, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 3, 2); +static SENSOR_DEVICE_ATTR_2(sf2_level1_fan3, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 1, 3); +static SENSOR_DEVICE_ATTR_2(sf2_level2_fan3, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 2, 3); +static SENSOR_DEVICE_ATTR_2(sf2_level3_fan3, S_IRUGO | S_IWUSR, + show_sf2_level, store_sf2_level, 3, 3); +static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 1); +static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 2); +static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 3); +static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 4); +static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 5); +static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 6); +static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 7); +static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, + show_fan_min, store_fan_min, 1); +static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, + show_fan_min, store_fan_min, 2); +static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, + show_fan_min, store_fan_min, 3); +static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, + show_fan_min, store_fan_min, 4); +static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, + show_fan_min, store_fan_min, 5); +static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, + show_fan_min, store_fan_min, 6); +static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, + show_fan_min, store_fan_min, 7); +static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, + show_fan_div, store_fan_div, 1); +static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, + show_fan_div, store_fan_div, 2); +static SENSOR_DEVICE_ATTR(fan3_div, S_IWUSR | S_IRUGO, + show_fan_div, store_fan_div, 3); +static SENSOR_DEVICE_ATTR(fan4_div, S_IWUSR | S_IRUGO, + show_fan_div, store_fan_div, 4); +static SENSOR_DEVICE_ATTR(fan5_div, S_IWUSR | S_IRUGO, + show_fan_div, store_fan_div, 5); +static SENSOR_DEVICE_ATTR(fan6_div, S_IWUSR | S_IRUGO, + show_fan_div, store_fan_div, 6); +static SENSOR_DEVICE_ATTR(fan7_div, S_IWUSR | S_IRUGO, + show_fan_div, store_fan_div, 7); + +static struct attribute *w83792d_attributes_fan[4][4] = { + { + &sensor_dev_attr_fan4_input.dev_attr.attr, + &sensor_dev_attr_fan4_min.dev_attr.attr, + &sensor_dev_attr_fan4_div.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_fan5_input.dev_attr.attr, + &sensor_dev_attr_fan5_min.dev_attr.attr, + &sensor_dev_attr_fan5_div.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_fan6_input.dev_attr.attr, + &sensor_dev_attr_fan6_min.dev_attr.attr, + &sensor_dev_attr_fan6_div.dev_attr.attr, + NULL + }, { + &sensor_dev_attr_fan7_input.dev_attr.attr, + &sensor_dev_attr_fan7_min.dev_attr.attr, + &sensor_dev_attr_fan7_div.dev_attr.attr, + NULL + } +}; + +static const struct attribute_group w83792d_group_fan[4] = { + { .attrs = w83792d_attributes_fan[0] }, + { .attrs = w83792d_attributes_fan[1] }, + { .attrs = w83792d_attributes_fan[2] }, + { .attrs = w83792d_attributes_fan[3] }, +}; + +static struct attribute *w83792d_attributes[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_max.dev_attr.attr, + &sensor_dev_attr_in0_min.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_max.dev_attr.attr, + &sensor_dev_attr_in1_min.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_max.dev_attr.attr, + &sensor_dev_attr_in2_min.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_max.dev_attr.attr, + &sensor_dev_attr_in3_min.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_max.dev_attr.attr, + &sensor_dev_attr_in4_min.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in5_max.dev_attr.attr, + &sensor_dev_attr_in5_min.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in6_max.dev_attr.attr, + &sensor_dev_attr_in6_min.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + &sensor_dev_attr_in7_max.dev_attr.attr, + &sensor_dev_attr_in7_min.dev_attr.attr, + &sensor_dev_attr_in8_input.dev_attr.attr, + &sensor_dev_attr_in8_max.dev_attr.attr, + &sensor_dev_attr_in8_min.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1.dev_attr.attr, + &sensor_dev_attr_pwm1_mode.dev_attr.attr, + &sensor_dev_attr_pwm1_enable.dev_attr.attr, + &sensor_dev_attr_pwm2.dev_attr.attr, + &sensor_dev_attr_pwm2_mode.dev_attr.attr, + &sensor_dev_attr_pwm2_enable.dev_attr.attr, + &sensor_dev_attr_pwm3.dev_attr.attr, + &sensor_dev_attr_pwm3_mode.dev_attr.attr, + &sensor_dev_attr_pwm3_enable.dev_attr.attr, + &dev_attr_alarms.attr, + &dev_attr_chassis.attr, + &dev_attr_chassis_clear.attr, + &sensor_dev_attr_tolerance1.dev_attr.attr, + &sensor_dev_attr_thermal_cruise1.dev_attr.attr, + &sensor_dev_attr_tolerance2.dev_attr.attr, + &sensor_dev_attr_thermal_cruise2.dev_attr.attr, + &sensor_dev_attr_tolerance3.dev_attr.attr, + &sensor_dev_attr_thermal_cruise3.dev_attr.attr, + &sensor_dev_attr_sf2_point1_fan1.dev_attr.attr, + &sensor_dev_attr_sf2_point2_fan1.dev_attr.attr, + &sensor_dev_attr_sf2_point3_fan1.dev_attr.attr, + &sensor_dev_attr_sf2_point4_fan1.dev_attr.attr, + &sensor_dev_attr_sf2_point1_fan2.dev_attr.attr, + &sensor_dev_attr_sf2_point2_fan2.dev_attr.attr, + &sensor_dev_attr_sf2_point3_fan2.dev_attr.attr, + &sensor_dev_attr_sf2_point4_fan2.dev_attr.attr, + &sensor_dev_attr_sf2_point1_fan3.dev_attr.attr, + &sensor_dev_attr_sf2_point2_fan3.dev_attr.attr, + &sensor_dev_attr_sf2_point3_fan3.dev_attr.attr, + &sensor_dev_attr_sf2_point4_fan3.dev_attr.attr, + &sensor_dev_attr_sf2_level1_fan1.dev_attr.attr, + &sensor_dev_attr_sf2_level2_fan1.dev_attr.attr, + &sensor_dev_attr_sf2_level3_fan1.dev_attr.attr, + &sensor_dev_attr_sf2_level1_fan2.dev_attr.attr, + &sensor_dev_attr_sf2_level2_fan2.dev_attr.attr, + &sensor_dev_attr_sf2_level3_fan2.dev_attr.attr, + &sensor_dev_attr_sf2_level1_fan3.dev_attr.attr, + &sensor_dev_attr_sf2_level2_fan3.dev_attr.attr, + &sensor_dev_attr_sf2_level3_fan3.dev_attr.attr, + &sensor_dev_attr_fan1_input.dev_attr.attr, + &sensor_dev_attr_fan1_min.dev_attr.attr, + &sensor_dev_attr_fan1_div.dev_attr.attr, + &sensor_dev_attr_fan2_input.dev_attr.attr, + &sensor_dev_attr_fan2_min.dev_attr.attr, + &sensor_dev_attr_fan2_div.dev_attr.attr, + &sensor_dev_attr_fan3_input.dev_attr.attr, + &sensor_dev_attr_fan3_min.dev_attr.attr, + &sensor_dev_attr_fan3_div.dev_attr.attr, + NULL +}; + +static const struct attribute_group w83792d_group = { + .attrs = w83792d_attributes, +}; static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind) @@ -1268,59 +1368,46 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) } /* Register sysfs hooks */ - data->class_dev = hwmon_device_register(dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); + if ((err = sysfs_create_group(&dev->kobj, &w83792d_group))) goto ERROR3; - } - for (i = 0; i < 9; i++) { - device_create_file(dev, &sda_in_input[i].dev_attr); - device_create_file(dev, &sda_in_max[i].dev_attr); - device_create_file(dev, &sda_in_min[i].dev_attr); - } - for (i = 0; i < 3; i++) - device_create_file_fan(dev, i); /* Read GPIO enable register to check if pins for fan 4,5 are used as GPIO */ val1 = w83792d_read_value(client, W83792D_REG_GPIO_EN); + if (!(val1 & 0x40)) - device_create_file_fan(dev, 3); + if ((err = sysfs_create_group(&dev->kobj, + &w83792d_group_fan[0]))) + goto exit_remove_files; + if (!(val1 & 0x20)) - device_create_file_fan(dev, 4); + if ((err = sysfs_create_group(&dev->kobj, + &w83792d_group_fan[1]))) + goto exit_remove_files; val1 = w83792d_read_value(client, W83792D_REG_PIN); if (val1 & 0x40) - device_create_file_fan(dev, 5); + if ((err = sysfs_create_group(&dev->kobj, + &w83792d_group_fan[2]))) + goto exit_remove_files; + if (val1 & 0x04) - device_create_file_fan(dev, 6); - - for (i = 0; i < 3; i++) { - device_create_file(dev, &sda_temp_input[i].dev_attr); - device_create_file(dev, &sda_temp_max[i].dev_attr); - device_create_file(dev, &sda_temp_max_hyst[i].dev_attr); - device_create_file(dev, &sda_thermal_cruise[i].dev_attr); - device_create_file(dev, &sda_tolerance[i].dev_attr); - } + if ((err = sysfs_create_group(&dev->kobj, + &w83792d_group_fan[3]))) + goto exit_remove_files; - for (i = 0; i < ARRAY_SIZE(sda_pwm); i++) { - device_create_file(dev, &sda_pwm[i].dev_attr); - device_create_file(dev, &sda_pwm_enable[i].dev_attr); - device_create_file(dev, &sda_pwm_mode[i].dev_attr); + data->class_dev = hwmon_device_register(dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto exit_remove_files; } - device_create_file(dev, &dev_attr_alarms); - device_create_file(dev, &dev_attr_chassis); - device_create_file(dev, &dev_attr_chassis_clear); - - for (i = 0; i < ARRAY_SIZE(sda_sf2_point); i++) - device_create_file(dev, &sda_sf2_point[i].dev_attr); - - for (i = 0; i < ARRAY_SIZE(sda_sf2_level); i++) - device_create_file(dev, &sda_sf2_level[i].dev_attr); - return 0; +exit_remove_files: + sysfs_remove_group(&dev->kobj, &w83792d_group); + for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) + sysfs_remove_group(&dev->kobj, &w83792d_group_fan[i]); ERROR3: if (data->lm75[0] != NULL) { i2c_detach_client(data->lm75[0]); @@ -1342,11 +1429,16 @@ static int w83792d_detach_client(struct i2c_client *client) { struct w83792d_data *data = i2c_get_clientdata(client); - int err; + int err, i; /* main client */ - if (data) + if (data) { hwmon_device_unregister(data->class_dev); + sysfs_remove_group(&client->dev.kobj, &w83792d_group); + for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++) + sysfs_remove_group(&client->dev.kobj, + &w83792d_group_fan[i]); + } if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c index 3f2bac125fb..a3fcace412f 100644 --- a/drivers/hwmon/w83l785ts.c +++ b/drivers/hwmon/w83l785ts.c @@ -236,21 +236,30 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) * Nothing yet, assume it is already started. */ + err = device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_input.dev_attr); + if (err) + goto exit_remove; + + err = device_create_file(&new_client->dev, + &sensor_dev_attr_temp1_max.dev_attr); + if (err) + goto exit_remove; + /* Register sysfs hooks */ data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); - goto exit_detach; + goto exit_remove; } - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_input.dev_attr); - device_create_file(&new_client->dev, - &sensor_dev_attr_temp1_max.dev_attr); - return 0; -exit_detach: +exit_remove: + device_remove_file(&new_client->dev, + &sensor_dev_attr_temp1_input.dev_attr); + device_remove_file(&new_client->dev, + &sensor_dev_attr_temp1_max.dev_attr); i2c_detach_client(new_client); exit_free: kfree(data); @@ -264,7 +273,10 @@ static int w83l785ts_detach_client(struct i2c_client *client) int err; hwmon_device_unregister(data->class_dev); - + device_remove_file(&client->dev, + &sensor_dev_attr_temp1_input.dev_attr); + device_remove_file(&client->dev, + &sensor_dev_attr_temp1_max.dev_attr); if ((err = i2c_detach_client(client))) return err; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 9e56c3989d6..0d9667921f6 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -196,7 +196,7 @@ config I2C_IBM_IIC config I2C_IOP3XX tristate "Intel IOP3xx and IXP4xx on-chip I2C interface" - depends on (ARCH_IOP3XX || ARCH_IXP4XX) && I2C + depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX) && I2C help Say Y here if you want to use the IIC bus controller on the Intel IOP3xx I/O Processors or IXP4xx Network Processors. diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 8e413150af3..4436c89be58 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -82,14 +82,16 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) /* * Every time unit enable is asserted, GPOD needs to be cleared - * on IOP321 to avoid data corruption on the bus. + * on IOP3XX to avoid data corruption on the bus. */ -#ifdef CONFIG_ARCH_IOP321 -#define IOP321_GPOD_I2C0 0x00c0 /* clear these bits to enable ch0 */ -#define IOP321_GPOD_I2C1 0x0030 /* clear these bits to enable ch1 */ - - *IOP321_GPOD &= (iop3xx_adap->id == 0) ? ~IOP321_GPOD_I2C0 : - ~IOP321_GPOD_I2C1; +#ifdef CONFIG_PLAT_IOP + if (iop3xx_adap->id == 0) { + gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW); + gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW); + } else { + gpio_line_set(IOP3XX_GPIO_LINE(5), GPIO_LOW); + gpio_line_set(IOP3XX_GPIO_LINE(4), GPIO_LOW); + } #endif /* NB SR bits not same position as CR IE bits :-( */ iop3xx_adap->SR_enabled = diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c index 6b7638b8429..cb142a66098 100644 --- a/drivers/mmc/at91_mci.c +++ b/drivers/mmc/at91_mci.c @@ -822,6 +822,7 @@ static int at91_mci_probe(struct platform_device *pdev) mmc->f_min = 375000; mmc->f_max = 25000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + mmc->caps = MMC_CAP_BYTEBLOCK; host = mmc_priv(mmc); host->mmc = mmc; @@ -850,7 +851,7 @@ static int at91_mci_probe(struct platform_device *pdev) /* * Allocate the MCI interrupt */ - ret = request_irq(AT91_ID_MCI, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host); + ret = request_irq(AT91RM9200_ID_MCI, at91_mci_irq, IRQF_SHARED, DRIVER_NAME, host); if (ret) { printk(KERN_ERR "Failed to request MCI interrupt\n"); clk_disable(mci_clk); @@ -906,7 +907,7 @@ static int at91_mci_remove(struct platform_device *pdev) mmc_remove_host(mmc); at91_mci_disable(); - free_irq(AT91_ID_MCI, host); + free_irq(AT91RM9200_ID_MCI, host); mmc_free_host(mmc); clk_disable(mci_clk); /* Disable the peripheral clock */ diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c index fb6565b98f3..1b79dd271aa 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/imxmmc.c @@ -956,7 +956,7 @@ static int imxmci_probe(struct platform_device *pdev) mmc->f_min = 150000; mmc->f_max = CLK_RATE/2; mmc->ocr_avail = MMC_VDD_32_33; - mmc->caps |= MMC_CAP_4_BIT_DATA; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_BYTEBLOCK; /* MMC core transfer sizes tunable parameters */ mmc->max_hw_segs = 64; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 74eaaee66de..5b9caa7978d 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -996,7 +996,6 @@ static void mmc_read_scrs(struct mmc_host *host) mmc_set_data_timeout(&data, card, 0); - data.blksz_bits = 3; data.blksz = 1 << 3; data.blocks = 1; data.flags = MMC_DATA_READ; diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index a0e0dad1b41..db0e8ad439a 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c @@ -32,6 +32,7 @@ #include <linux/mmc/card.h> #include <linux/mmc/host.h> #include <linux/mmc/protocol.h> +#include <linux/mmc/host.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -165,6 +166,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) do { struct mmc_blk_request brq; struct mmc_command cmd; + u32 readcmd, writecmd; memset(&brq, 0, sizeof(struct mmc_blk_request)); brq.mrq.cmd = &brq.cmd; @@ -172,7 +174,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.cmd.arg = req->sector << 9; brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; - brq.data.blksz_bits = md->block_bits; brq.data.blksz = 1 << md->block_bits; brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); brq.stop.opcode = MMC_STOP_TRANSMISSION; @@ -181,20 +182,31 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ); - if (rq_data_dir(req) == READ) { - brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; - brq.data.flags |= MMC_DATA_READ; - } else { - brq.cmd.opcode = MMC_WRITE_BLOCK; - brq.data.flags |= MMC_DATA_WRITE; + /* + * If the host doesn't support multiple block writes, force + * block writes to single block. + */ + if (rq_data_dir(req) != READ && + !(card->host->caps & MMC_CAP_MULTIWRITE)) brq.data.blocks = 1; - } if (brq.data.blocks > 1) { brq.data.flags |= MMC_DATA_MULTI; brq.mrq.stop = &brq.stop; + readcmd = MMC_READ_MULTIPLE_BLOCK; + writecmd = MMC_WRITE_MULTIPLE_BLOCK; } else { brq.mrq.stop = NULL; + readcmd = MMC_READ_SINGLE_BLOCK; + writecmd = MMC_WRITE_BLOCK; + } + + if (rq_data_dir(req) == READ) { + brq.cmd.opcode = readcmd; + brq.data.flags |= MMC_DATA_READ; + } else { + brq.cmd.opcode = writecmd; + brq.data.flags |= MMC_DATA_WRITE; } brq.data.sg = mq->sg; @@ -219,27 +231,29 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) goto cmd_err; } - do { - int err; - - cmd.opcode = MMC_SEND_STATUS; - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - err = mmc_wait_for_cmd(card->host, &cmd, 5); - if (err) { - printk(KERN_ERR "%s: error %d requesting status\n", - req->rq_disk->disk_name, err); - goto cmd_err; - } - } while (!(cmd.resp[0] & R1_READY_FOR_DATA)); + if (rq_data_dir(req) != READ) { + do { + int err; + + cmd.opcode = MMC_SEND_STATUS; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + err = mmc_wait_for_cmd(card->host, &cmd, 5); + if (err) { + printk(KERN_ERR "%s: error %d requesting status\n", + req->rq_disk->disk_name, err); + goto cmd_err; + } + } while (!(cmd.resp[0] & R1_READY_FOR_DATA)); #if 0 - if (cmd.resp[0] & ~0x00000900) - printk(KERN_ERR "%s: status = %08x\n", - req->rq_disk->disk_name, cmd.resp[0]); - if (mmc_decode_status(cmd.resp)) - goto cmd_err; + if (cmd.resp[0] & ~0x00000900) + printk(KERN_ERR "%s: status = %08x\n", + req->rq_disk->disk_name, cmd.resp[0]); + if (mmc_decode_status(cmd.resp)) + goto cmd_err; #endif + } /* * A block was successfully transferred. diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 1886562abdd..2b5a0cc9ea5 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c @@ -69,12 +69,13 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) unsigned int datactrl, timeout, irqmask; unsigned long long clks; void __iomem *base; + int blksz_bits; DBG(host, "blksz %04x blks %04x flags %08x\n", - 1 << data->blksz_bits, data->blocks, data->flags); + data->blksz, data->blocks, data->flags); host->data = data; - host->size = data->blocks << data->blksz_bits; + host->size = data->blksz; host->data_xfered = 0; mmci_init_sg(host, data); @@ -88,7 +89,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) writel(timeout, base + MMCIDATATIMER); writel(host->size, base + MMCIDATALENGTH); - datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4; + blksz_bits = ffs(data->blksz) - 1; + BUG_ON(1 << blksz_bits != data->blksz); + + datactrl = MCI_DPSM_ENABLE | blksz_bits << 4; if (data->flags & MMC_DATA_READ) { datactrl |= MCI_DPSM_DIRECTION; irqmask = MCI_RXFIFOHALFFULLMASK; @@ -145,7 +149,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, unsigned int status) { if (status & MCI_DATABLOCKEND) { - host->data_xfered += 1 << data->blksz_bits; + host->data_xfered += data->blksz; } if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { if (status & MCI_DATACRCFAIL) @@ -505,6 +509,7 @@ static int mmci_probe(struct amba_device *dev, void *id) mmc->f_min = (host->mclk + 511) / 512; mmc->f_max = min(host->mclk, fmax); mmc->ocr_avail = plat->ocr_mask; + mmc->caps = MMC_CAP_MULTIWRITE; /* * We can do SGIO diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c index ddf06b32c15..52c9e52e6b7 100644 --- a/drivers/mmc/omap.c +++ b/drivers/mmc/omap.c @@ -1034,13 +1034,14 @@ static int __init mmc_omap_probe(struct platform_device *pdev) host->irq = pdev->resource[1].start; host->base = (void __iomem*)IO_ADDRESS(r->start); - if (minfo->wire4) - mmc->caps |= MMC_CAP_4_BIT_DATA; - mmc->ops = &mmc_omap_ops; mmc->f_min = 400000; mmc->f_max = 24000000; mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; + mmc->caps = MMC_CAP_BYTEBLOCK; + + if (minfo->wire4) + mmc->caps |= MMC_CAP_4_BIT_DATA; /* Use scatterlist DMA to reduce per-transfer costs. * NOTE max_seg_size assumption that small blocks aren't diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 4e21b3b9d33..fdfc3838dd7 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -1262,7 +1262,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) mmc->ops = &sdhci_ops; mmc->f_min = host->max_clk / 256; mmc->f_max = host->max_clk; - mmc->caps = MMC_CAP_4_BIT_DATA; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK; mmc->ocr_avail = 0; if (caps & SDHCI_CAN_VDD_330) diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index c351c6d1a18..6435a6822ad 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -1323,7 +1323,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev) mmc->f_min = 375000; mmc->f_max = 24000000; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->caps = MMC_CAP_4_BIT_DATA; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK; spin_lock_init(&host->lock); diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 95b28aa01f4..3ecf2cc53a7 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -947,7 +947,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add return -ENOMEM; dev->base_addr = AT91_VA_BASE_EMAC; - dev->irq = AT91_ID_EMAC; + dev->irq = AT91RM9200_ID_EMAC; SET_MODULE_OWNER(dev); /* Install the interrupt handler */ diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 23fa0b28917..9d051e5687e 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -63,44 +63,26 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ * and function code cmd. * In case of an exception return 3. Otherwise return result of bitwise OR of * resulting condition code and DIAG return code. */ -static __inline__ int -dia250(void *iob, int cmd) +static inline int dia250(void *iob, int cmd) { + register unsigned long reg0 asm ("0") = (unsigned long) iob; typedef union { struct dasd_diag_init_io init_io; struct dasd_diag_rw_io rw_io; } addr_type; int rc; - __asm__ __volatile__( -#ifdef CONFIG_64BIT - " lghi %0,3\n" - " lgr 0,%3\n" - " diag 0,%2,0x250\n" - "0: ipm %0\n" - " srl %0,28\n" - " or %0,1\n" - "1:\n" - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b,1b\n" - ".previous\n" -#else - " lhi %0,3\n" - " lr 0,%3\n" + rc = 3; + asm volatile( " diag 0,%2,0x250\n" "0: ipm %0\n" " srl %0,28\n" " or %0,1\n" "1:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,1b\n" - ".previous\n" -#endif - : "=&d" (rc), "=m" (*(addr_type *) iob) - : "d" (cmd), "d" (iob), "m" (*(addr_type *) iob) - : "0", "1", "cc"); + EX_TABLE(0b,1b) + : "+d" (rc), "=m" (*(addr_type *) iob) + : "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob) + : "1", "cc"); return rc; } diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index cab2c736683..a04d9120cef 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -89,28 +89,15 @@ MODULE_LICENSE("GPL"); */ static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index) { - int cc; + int cc = 2; /* return unused cc 2 if pgin traps */ - __asm__ __volatile__ ( - " lhi %0,2\n" /* return unused cc 2 if pgin traps */ - " .insn rre,0xb22e0000,%1,%2\n" /* pgin %1,%2 */ - "0: ipm %0\n" - " srl %0,28\n" + asm volatile( + " .insn rre,0xb22e0000,%1,%2\n" /* pgin %1,%2 */ + "0: ipm %0\n" + " srl %0,28\n" "1:\n" -#ifndef CONFIG_64BIT - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,1b\n" - ".previous" -#else - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b,1b\n" - ".previous" -#endif - : "=&d" (cc) - : "a" (__pa(page_addr)), "a" (xpage_index) - : "cc" ); + EX_TABLE(0b,1b) + : "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc"); if (cc == 3) return -ENXIO; if (cc == 2) { @@ -137,28 +124,15 @@ static int xpram_page_in (unsigned long page_addr, unsigned int xpage_index) */ static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index) { - int cc; + int cc = 2; /* return unused cc 2 if pgin traps */ - __asm__ __volatile__ ( - " lhi %0,2\n" /* return unused cc 2 if pgout traps */ - " .insn rre,0xb22f0000,%1,%2\n" /* pgout %1,%2 */ - "0: ipm %0\n" - " srl %0,28\n" + asm volatile( + " .insn rre,0xb22f0000,%1,%2\n" /* pgout %1,%2 */ + "0: ipm %0\n" + " srl %0,28\n" "1:\n" -#ifndef CONFIG_64BIT - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,1b\n" - ".previous" -#else - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b,1b\n" - ".previous" -#endif - : "=&d" (cc) - : "a" (__pa(page_addr)), "a" (xpage_index) - : "cc" ); + EX_TABLE(0b,1b) + : "+d" (cc) : "a" (__pa(page_addr)), "d" (xpage_index) : "cc"); if (cc == 3) return -ENXIO; if (cc == 2) { diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index ef004d08971..b4557fa3085 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -17,7 +17,6 @@ #include <asm/ccwdev.h> #include <asm/cio.h> -#include <asm/cpcmd.h> #include <asm/ebcdic.h> #include <asm/idals.h> diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 985d1613baa..31e335751d6 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -100,13 +100,12 @@ service_call(sclp_cmdw_t command, void *sccb) { int cc; - __asm__ __volatile__( - " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */ - " ipm %0\n" - " srl %0,28" - : "=&d" (cc) - : "d" (command), "a" (__pa(sccb)) - : "cc", "memory" ); + asm volatile( + " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */ + " ipm %0\n" + " srl %0,28" + : "=&d" (cc) : "d" (command), "a" (__pa(sccb)) + : "cc", "memory"); if (cc == 3) return -EIO; if (cc == 2) @@ -360,16 +359,6 @@ sclp_interrupt_handler(struct pt_regs *regs, __u16 code) sclp_process_queue(); } -/* Return current Time-Of-Day clock. */ -static inline u64 -sclp_get_clock(void) -{ - u64 result; - - asm volatile ("STCK 0(%1)" : "=m" (result) : "a" (&(result)) : "cc"); - return result; -} - /* Convert interval in jiffies to TOD ticks. */ static inline u64 sclp_tod_from_jiffies(unsigned long jiffies) @@ -382,7 +371,6 @@ sclp_tod_from_jiffies(unsigned long jiffies) void sclp_sync_wait(void) { - unsigned long psw_mask; unsigned long flags; unsigned long cr0, cr0_sync; u64 timeout; @@ -392,7 +380,7 @@ sclp_sync_wait(void) timeout = 0; if (timer_pending(&sclp_request_timer)) { /* Get timeout TOD value */ - timeout = sclp_get_clock() + + timeout = get_clock() + sclp_tod_from_jiffies(sclp_request_timer.expires - jiffies); } @@ -406,13 +394,12 @@ sclp_sync_wait(void) cr0_sync |= 0x00000200; cr0_sync &= 0xFFFFF3AC; __ctl_load(cr0_sync, 0, 0); - asm volatile ("STOSM 0(%1),0x01" - : "=m" (psw_mask) : "a" (&psw_mask) : "memory"); + __raw_local_irq_stosm(0x01); /* Loop until driver state indicates finished request */ while (sclp_running_state != sclp_running_state_idle) { /* Check for expired request timer */ if (timer_pending(&sclp_request_timer) && - sclp_get_clock() > timeout && + get_clock() > timeout && del_timer(&sclp_request_timer)) sclp_request_timer.function(sclp_request_timer.data); barrier(); diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 29718042c6c..06e2eeec847 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -698,7 +698,6 @@ tty3270_alloc_view(void) if (!tp->freemem_pages) goto out_tp; INIT_LIST_HEAD(&tp->freemem); - init_timer(&tp->timer); for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) { tp->freemem_pages[pages] = (void *) __get_free_pages(GFP_KERNEL|GFP_DMA, 0); diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index 807320a41fa..4b868f72fe8 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c @@ -54,48 +54,20 @@ enum vmwdt_func { static int __diag288(enum vmwdt_func func, unsigned int timeout, char *cmd, size_t len) { - register unsigned long __func asm("2"); - register unsigned long __timeout asm("3"); - register unsigned long __cmdp asm("4"); - register unsigned long __cmdl asm("5"); + register unsigned long __func asm("2") = func; + register unsigned long __timeout asm("3") = timeout; + register unsigned long __cmdp asm("4") = virt_to_phys(cmd); + register unsigned long __cmdl asm("5") = len; int err; - __func = func; - __timeout = timeout; - __cmdp = virt_to_phys(cmd); - __cmdl = len; - err = 0; - asm volatile ( -#ifdef CONFIG_64BIT - "diag %2,%4,0x288\n" - "1: \n" - ".section .fixup,\"ax\"\n" - "2: lghi %0,%1\n" - " jg 1b\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 1b,2b\n" - ".previous\n" -#else - "diag %2,%4,0x288\n" - "1: \n" - ".section .fixup,\"ax\"\n" - "2: lhi %0,%1\n" - " bras 1,3f\n" - " .long 1b\n" - "3: l 1,0(1)\n" - " br 1\n" - ".previous\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 1b,2b\n" - ".previous\n" -#endif - : "+&d"(err) - : "i"(-EINVAL), "d"(__func), "d"(__timeout), - "d"(__cmdp), "d"(__cmdl) - : "1", "cc"); + err = -EINVAL; + asm volatile( + " diag %1,%3,0x288\n" + "0: la %0,0\n" + "1:\n" + EX_TABLE(0b,1b) + : "=d" (err) : "d"(__func), "d"(__timeout), + "d"(__cmdp), "d"(__cmdl), "0" (-EINVAL) : "1", "cc"); return err; } diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 438db483035..1398367b5f6 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -42,18 +42,15 @@ diag210(struct diag210 * addr) spin_lock_irqsave(&diag210_lock, flags); diag210_tmp = *addr; - asm volatile ( - " lhi %0,-1\n" - " sam31\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1: sam64\n" - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b,1b\n" - ".previous" - : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory" ); + asm volatile( + " lhi %0,-1\n" + " sam31\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1: sam64\n" + EX_TABLE(0b,1b) + : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory"); *addr = diag210_tmp; spin_unlock_irqrestore(&diag210_lock, flags); @@ -66,17 +63,14 @@ diag210(struct diag210 * addr) { int ccode; - asm volatile ( - " lhi %0,-1\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" + asm volatile( + " lhi %0,-1\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" "1:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,1b\n" - ".previous" - : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory" ); + EX_TABLE(0b,1b) + : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory"); return ccode; } diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index 95a9462f9a9..ad6d8294006 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -25,106 +25,74 @@ struct tpi_info { static inline int stsch(struct subchannel_id schid, volatile struct schib *addr) { + register struct subchannel_id reg1 asm ("1") = schid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " stsch 0(%2)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (schid), "a" (addr), "m" (*addr) - : "cc", "1" ); + asm volatile( + " stsch 0(%2)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); return ccode; } static inline int stsch_err(struct subchannel_id schid, volatile struct schib *addr) { - int ccode; + register struct subchannel_id reg1 asm ("1") = schid; + int ccode = -EIO; - __asm__ __volatile__( - " lhi %0,%3\n" - " lr 1,%1\n" - " stsch 0(%2)\n" - "0: ipm %0\n" - " srl %0,28\n" + asm volatile( + " stsch 0(%2)\n" + "0: ipm %0\n" + " srl %0,28\n" "1:\n" -#ifdef CONFIG_64BIT - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b,1b\n" - ".previous" -#else - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,1b\n" - ".previous" -#endif - : "=&d" (ccode) - : "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr) - : "cc", "1" ); + EX_TABLE(0b,1b) + : "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); return ccode; } static inline int msch(struct subchannel_id schid, volatile struct schib *addr) { + register struct subchannel_id reg1 asm ("1") = schid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " msch 0(%2)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (schid), "a" (addr), "m" (*addr) - : "cc", "1" ); + asm volatile( + " msch 0(%2)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); return ccode; } static inline int msch_err(struct subchannel_id schid, volatile struct schib *addr) { - int ccode; + register struct subchannel_id reg1 asm ("1") = schid; + int ccode = -EIO; - __asm__ __volatile__( - " lhi %0,%3\n" - " lr 1,%1\n" - " msch 0(%2)\n" - "0: ipm %0\n" - " srl %0,28\n" + asm volatile( + " msch 0(%2)\n" + "0: ipm %0\n" + " srl %0,28\n" "1:\n" -#ifdef CONFIG_64BIT - ".section __ex_table,\"a\"\n" - " .align 8\n" - " .quad 0b,1b\n" - ".previous" -#else - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b,1b\n" - ".previous" -#endif - : "=&d" (ccode) - : "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr) - : "cc", "1" ); + EX_TABLE(0b,1b) + : "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); return ccode; } static inline int tsch(struct subchannel_id schid, volatile struct irb *addr) { + register struct subchannel_id reg1 asm ("1") = schid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " tsch 0(%2)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (schid), "a" (addr), "m" (*addr) - : "cc", "1" ); + asm volatile( + " tsch 0(%2)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); return ccode; } @@ -132,89 +100,77 @@ static inline int tpi( volatile struct tpi_info *addr) { int ccode; - __asm__ __volatile__( - " tpi 0(%1)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "a" (addr), "m" (*addr) - : "cc", "1" ); + asm volatile( + " tpi 0(%1)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "a" (addr), "m" (*addr) : "cc"); return ccode; } static inline int ssch(struct subchannel_id schid, volatile struct orb *addr) { + register struct subchannel_id reg1 asm ("1") = schid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " ssch 0(%2)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (schid), "a" (addr), "m" (*addr) - : "cc", "1" ); + asm volatile( + " ssch 0(%2)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); return ccode; } static inline int rsch(struct subchannel_id schid) { + register struct subchannel_id reg1 asm ("1") = schid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " rsch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (schid) - : "cc", "1" ); + asm volatile( + " rsch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1) : "cc"); return ccode; } static inline int csch(struct subchannel_id schid) { + register struct subchannel_id reg1 asm ("1") = schid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " csch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (schid) - : "cc", "1" ); + asm volatile( + " csch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1) : "cc"); return ccode; } static inline int hsch(struct subchannel_id schid) { + register struct subchannel_id reg1 asm ("1") = schid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " hsch\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (schid) - : "cc", "1" ); + asm volatile( + " hsch\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1) : "cc"); return ccode; } static inline int xsch(struct subchannel_id schid) { + register struct subchannel_id reg1 asm ("1") = schid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " .insn rre,0xb2760000,%1,0\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (schid) - : "cc", "1" ); + asm volatile( + " .insn rre,0xb2760000,%1,0\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1) : "cc"); return ccode; } @@ -223,41 +179,27 @@ static inline int chsc(void *chsc_area) typedef struct { char _[4096]; } addr_type; int cc; - __asm__ __volatile__ ( - ".insn rre,0xb25f0000,%2,0 \n\t" - "ipm %0 \n\t" - "srl %0,28 \n\t" + asm volatile( + " .insn rre,0xb25f0000,%2,0\n" + " ipm %0\n" + " srl %0,28\n" : "=d" (cc), "=m" (*(addr_type *) chsc_area) : "d" (chsc_area), "m" (*(addr_type *) chsc_area) - : "cc" ); - + : "cc"); return cc; } -static inline int iac( void) -{ - int ccode; - - __asm__ __volatile__( - " iac 1\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) : : "cc", "1" ); - return ccode; -} - static inline int rchp(int chpid) { + register unsigned int reg1 asm ("1") = chpid; int ccode; - __asm__ __volatile__( - " lr 1,%1\n" - " rchp\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) - : "d" (chpid) - : "cc", "1" ); + asm volatile( + " lr 1,%1\n" + " rchp\n" + " ipm %0\n" + " srl %0,28" + : "=d" (ccode) : "d" (reg1) : "cc"); return ccode; } diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 124569362f0..49bb9e371c3 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -274,12 +274,11 @@ do_sqbs(unsigned long sch, unsigned char state, int queue, register unsigned long _sch asm ("1") = sch; unsigned long _queuestart = ((unsigned long)queue << 32) | *start; - asm volatile ( - " .insn rsy,0xeb000000008A,%1,0,0(%2)\n\t" - : "+d" (_ccq), "+d" (_queuestart) - : "d" ((unsigned long)state), "d" (_sch) - : "memory", "cc" - ); + asm volatile( + " .insn rsy,0xeb000000008A,%1,0,0(%2)" + : "+d" (_ccq), "+d" (_queuestart) + : "d" ((unsigned long)state), "d" (_sch) + : "memory", "cc"); *count = _ccq & 0xff; *start = _queuestart & 0xff; @@ -299,12 +298,11 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue, unsigned long _queuestart = ((unsigned long)queue << 32) | *start; unsigned long _state = 0; - asm volatile ( - " .insn rrf,0xB99c0000,%1,%2,0,0 \n\t" - : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) - : "d" (_sch) - : "memory", "cc" - ); + asm volatile( + " .insn rrf,0xB99c0000,%1,%2,0,0" + : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) + : "d" (_sch) + : "memory", "cc" ); *count = _ccq & 0xff; *start = _queuestart & 0xff; *state = _state & 0xff; @@ -319,69 +317,35 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue, static inline int do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2) { + register unsigned long reg0 asm ("0") = 2; + register struct subchannel_id reg1 asm ("1") = schid; + register unsigned long reg2 asm ("2") = mask1; + register unsigned long reg3 asm ("3") = mask2; int cc; -#ifndef CONFIG_64BIT - asm volatile ( - "lhi 0,2 \n\t" - "lr 1,%1 \n\t" - "lr 2,%2 \n\t" - "lr 3,%3 \n\t" - "siga 0 \n\t" - "ipm %0 \n\t" - "srl %0,28 \n\t" + asm volatile( + " siga 0\n" + " ipm %0\n" + " srl %0,28\n" : "=d" (cc) - : "d" (schid), "d" (mask1), "d" (mask2) - : "cc", "0", "1", "2", "3" - ); -#else /* CONFIG_64BIT */ - asm volatile ( - "lghi 0,2 \n\t" - "llgfr 1,%1 \n\t" - "llgfr 2,%2 \n\t" - "llgfr 3,%3 \n\t" - "siga 0 \n\t" - "ipm %0 \n\t" - "srl %0,28 \n\t" - : "=d" (cc) - : "d" (schid), "d" (mask1), "d" (mask2) - : "cc", "0", "1", "2", "3" - ); -#endif /* CONFIG_64BIT */ + : "d" (reg0), "d" (reg1), "d" (reg2), "d" (reg3) : "cc"); return cc; } static inline int do_siga_input(struct subchannel_id schid, unsigned int mask) { + register unsigned long reg0 asm ("0") = 1; + register struct subchannel_id reg1 asm ("1") = schid; + register unsigned long reg2 asm ("2") = mask; int cc; -#ifndef CONFIG_64BIT - asm volatile ( - "lhi 0,1 \n\t" - "lr 1,%1 \n\t" - "lr 2,%2 \n\t" - "siga 0 \n\t" - "ipm %0 \n\t" - "srl %0,28 \n\t" - : "=d" (cc) - : "d" (schid), "d" (mask) - : "cc", "0", "1", "2", "memory" - ); -#else /* CONFIG_64BIT */ - asm volatile ( - "lghi 0,1 \n\t" - "llgfr 1,%1 \n\t" - "llgfr 2,%2 \n\t" - "siga 0 \n\t" - "ipm %0 \n\t" - "srl %0,28 \n\t" + asm volatile( + " siga 0\n" + " ipm %0\n" + " srl %0,28\n" : "=d" (cc) - : "d" (schid), "d" (mask) - : "cc", "0", "1", "2", "memory" - ); -#endif /* CONFIG_64BIT */ - + : "d" (reg0), "d" (reg1), "d" (reg2) : "cc", "memory"); return cc; } @@ -389,93 +353,35 @@ static inline int do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb, unsigned int fc) { + register unsigned long __fc asm("0") = fc; + register unsigned long __schid asm("1") = schid; + register unsigned long __mask asm("2") = mask; int cc; - __u32 busy_bit; - -#ifndef CONFIG_64BIT - asm volatile ( - "lhi 0,0 \n\t" - "lr 1,%2 \n\t" - "lr 2,%3 \n\t" - "siga 0 \n\t" - "0:" - "ipm %0 \n\t" - "srl %0,28 \n\t" - "srl 0,31 \n\t" - "lr %1,0 \n\t" - "1: \n\t" - ".section .fixup,\"ax\"\n\t" - "2: \n\t" - "lhi %0,%4 \n\t" - "bras 1,3f \n\t" - ".long 1b \n\t" - "3: \n\t" - "l 1,0(1) \n\t" - "br 1 \n\t" - ".previous \n\t" - ".section __ex_table,\"a\"\n\t" - ".align 4 \n\t" - ".long 0b,2b \n\t" - ".previous \n\t" - : "=d" (cc), "=d" (busy_bit) - : "d" (schid), "d" (mask), - "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) - : "cc", "0", "1", "2", "memory" - ); -#else /* CONFIG_64BIT */ - asm volatile ( - "llgfr 0,%5 \n\t" - "lgr 1,%2 \n\t" - "llgfr 2,%3 \n\t" - "siga 0 \n\t" - "0:" - "ipm %0 \n\t" - "srl %0,28 \n\t" - "srl 0,31 \n\t" - "llgfr %1,0 \n\t" - "1: \n\t" - ".section .fixup,\"ax\"\n\t" - "lghi %0,%4 \n\t" - "jg 1b \n\t" - ".previous\n\t" - ".section __ex_table,\"a\"\n\t" - ".align 8 \n\t" - ".quad 0b,1b \n\t" - ".previous \n\t" - : "=d" (cc), "=d" (busy_bit) - : "d" (schid), "d" (mask), - "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc) - : "cc", "0", "1", "2", "memory" - ); -#endif /* CONFIG_64BIT */ - - (*bb) = busy_bit; + + asm volatile( + " siga 0\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b,1b) + : "=d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask) + : "0" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) + : "cc", "memory"); + (*bb) = ((unsigned int) __fc) >> 31; return cc; } static inline unsigned long do_clear_global_summary(void) { - - unsigned long time; - -#ifndef CONFIG_64BIT - asm volatile ( - "lhi 1,3 \n\t" - ".insn rre,0xb2650000,2,0 \n\t" - "lr %0,3 \n\t" - : "=d" (time) : : "cc", "1", "2", "3" - ); -#else /* CONFIG_64BIT */ - asm volatile ( - "lghi 1,3 \n\t" - ".insn rre,0xb2650000,2,0 \n\t" - "lgr %0,3 \n\t" - : "=d" (time) : : "cc", "1", "2", "3" - ); -#endif /* CONFIG_64BIT */ - - return time; + register unsigned long __fn asm("1") = 3; + register unsigned long __tmp asm("2"); + register unsigned long __time asm("3"); + + asm volatile( + " .insn rre,0xb2650000,2,0" + : "+d" (__fn), "=d" (__tmp), "=d" (__time)); + return __time; } /* diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c index 821dde86e24..809dd8d7f47 100644 --- a/drivers/s390/net/iucv.c +++ b/drivers/s390/net/iucv.c @@ -534,19 +534,15 @@ iucv_add_handler (handler *new) * * Returns: return code from CP's IUCV call */ -static __inline__ ulong -b2f0(__u32 code, void *parm) +static inline ulong b2f0(__u32 code, void *parm) { + register unsigned long reg0 asm ("0"); + register unsigned long reg1 asm ("1"); iucv_dumpit("iparml before b2f0 call:", parm, sizeof(iucv_param)); - asm volatile ( - "LRA 1,0(%1)\n\t" - "LR 0,%0\n\t" - ".long 0xb2f01000" - : - : "d" (code), "a" (parm) - : "0", "1" - ); + reg0 = code; + reg1 = virt_to_phys(parm); + asm volatile(".long 0xb2f01000" : : "d" (reg0), "a" (reg1)); iucv_dumpit("iparml after b2f0 call:", parm, sizeof(iucv_param)); @@ -1248,6 +1244,8 @@ iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit) static int iucv_query_generic(int want_maxconn) { + register unsigned long reg0 asm ("0"); + register unsigned long reg1 asm ("1"); iparml_purge *parm = (iparml_purge *)grab_param(); int bufsize, maxconn; int ccode; @@ -1256,18 +1254,15 @@ iucv_query_generic(int want_maxconn) * Call b2f0 and store R0 (max buffer size), * R1 (max connections) and CC. */ - asm volatile ( - "LRA 1,0(%4)\n\t" - "LR 0,%3\n\t" - ".long 0xb2f01000\n\t" - "IPM %0\n\t" - "SRL %0,28\n\t" - "ST 0,%1\n\t" - "ST 1,%2\n\t" - : "=d" (ccode), "=m" (bufsize), "=m" (maxconn) - : "d" (QUERY), "a" (parm) - : "0", "1", "cc" - ); + reg0 = QUERY; + reg1 = virt_to_phys(parm); + asm volatile( + " .long 0xb2f01000\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc"); + bufsize = reg0; + maxconn = reg1; release_param(parm); if (ccode) diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index a914129a4da..479364d0332 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c @@ -253,11 +253,12 @@ s390_revalidate_registers(struct mci *mci) kill_task = 1; #ifndef CONFIG_64BIT - asm volatile("ld 0,0(%0)\n" - "ld 2,8(%0)\n" - "ld 4,16(%0)\n" - "ld 6,24(%0)" - : : "a" (&S390_lowcore.floating_pt_save_area)); + asm volatile( + " ld 0,0(%0)\n" + " ld 2,8(%0)\n" + " ld 4,16(%0)\n" + " ld 6,24(%0)" + : : "a" (&S390_lowcore.floating_pt_save_area)); #endif if (MACHINE_HAS_IEEE) { @@ -274,37 +275,36 @@ s390_revalidate_registers(struct mci *mci) * Floating point control register can't be restored. * Task will be terminated. */ - asm volatile ("lfpc 0(%0)" : : "a" (&zero), "m" (zero)); + asm volatile("lfpc 0(%0)" : : "a" (&zero), "m" (zero)); kill_task = 1; - } - else - asm volatile ( - "lfpc 0(%0)" - : : "a" (fpt_creg_save_area)); - - asm volatile("ld 0,0(%0)\n" - "ld 1,8(%0)\n" - "ld 2,16(%0)\n" - "ld 3,24(%0)\n" - "ld 4,32(%0)\n" - "ld 5,40(%0)\n" - "ld 6,48(%0)\n" - "ld 7,56(%0)\n" - "ld 8,64(%0)\n" - "ld 9,72(%0)\n" - "ld 10,80(%0)\n" - "ld 11,88(%0)\n" - "ld 12,96(%0)\n" - "ld 13,104(%0)\n" - "ld 14,112(%0)\n" - "ld 15,120(%0)\n" - : : "a" (fpt_save_area)); + } else + asm volatile("lfpc 0(%0)" : : "a" (fpt_creg_save_area)); + + asm volatile( + " ld 0,0(%0)\n" + " ld 1,8(%0)\n" + " ld 2,16(%0)\n" + " ld 3,24(%0)\n" + " ld 4,32(%0)\n" + " ld 5,40(%0)\n" + " ld 6,48(%0)\n" + " ld 7,56(%0)\n" + " ld 8,64(%0)\n" + " ld 9,72(%0)\n" + " ld 10,80(%0)\n" + " ld 11,88(%0)\n" + " ld 12,96(%0)\n" + " ld 13,104(%0)\n" + " ld 14,112(%0)\n" + " ld 15,120(%0)\n" + : : "a" (fpt_save_area)); } /* Revalidate access registers */ - asm volatile("lam 0,15,0(%0)" - : : "a" (&S390_lowcore.access_regs_save_area)); + asm volatile( + " lam 0,15,0(%0)" + : : "a" (&S390_lowcore.access_regs_save_area)); if (!mci->ar) /* * Access registers have unknown contents. @@ -321,11 +321,13 @@ s390_revalidate_registers(struct mci *mci) s390_handle_damage("invalid control registers."); else #ifdef CONFIG_64BIT - asm volatile("lctlg 0,15,0(%0)" - : : "a" (&S390_lowcore.cregs_save_area)); + asm volatile( + " lctlg 0,15,0(%0)" + : : "a" (&S390_lowcore.cregs_save_area)); #else - asm volatile("lctl 0,15,0(%0)" - : : "a" (&S390_lowcore.cregs_save_area)); + asm volatile( + " lctl 0,15,0(%0)" + : : "a" (&S390_lowcore.cregs_save_area)); #endif /* @@ -339,20 +341,23 @@ s390_revalidate_registers(struct mci *mci) * old contents (should be zero) otherwise set it to zero. */ if (!mci->pr) - asm volatile("sr 0,0\n" - "sckpf" - : : : "0", "cc"); + asm volatile( + " sr 0,0\n" + " sckpf" + : : : "0", "cc"); else asm volatile( - "l 0,0(%0)\n" - "sckpf" - : : "a" (&S390_lowcore.tod_progreg_save_area) : "0", "cc"); + " l 0,0(%0)\n" + " sckpf" + : : "a" (&S390_lowcore.tod_progreg_save_area) + : "0", "cc"); #endif /* Revalidate clock comparator register */ - asm volatile ("stck 0(%1)\n" - "sckc 0(%1)" - : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory"); + asm volatile( + " stck 0(%1)\n" + " sckc 0(%1)" + : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory"); /* Check if old PSW is valid */ if (!mci->wp) diff --git a/drivers/serial/at91_serial.c b/drivers/serial/at91_serial.c index 54c6b2adf7b..bf4bf103e5a 100644 --- a/drivers/serial/at91_serial.c +++ b/drivers/serial/at91_serial.c @@ -139,7 +139,7 @@ static void at91_set_mctrl(struct uart_port *port, u_int mctrl) * AT91RM9200 Errata #39: RTS0 is not internally connected to PA21. * We need to drive the pin manually. */ - if (port->mapbase == AT91_BASE_US0) { + if (port->mapbase == AT91RM9200_BASE_US0) { if (mctrl & TIOCM_RTS) at91_set_gpio_value(AT91_PIN_PA21, 0); else diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index b1046324441..113e484c763 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -24,6 +24,7 @@ #include <linux/device.h> #include <linux/usb.h> +#include <linux/workqueue.h> #include "hcd.h" #include "usb.h" @@ -302,11 +303,11 @@ int usb_driver_claim_interface(struct usb_driver *driver, dev->driver = &driver->drvwrap.driver; usb_set_intfdata(iface, priv); - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); iface->condition = USB_INTERFACE_BOUND; mark_active(iface); iface->pm_usage_cnt = !(driver->supports_autosuspend); - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); /* if interface was already added, bind now; else let * the future device_add() bind it, bypassing probe() @@ -355,11 +356,11 @@ void usb_driver_release_interface(struct usb_driver *driver, dev->driver = NULL; usb_set_intfdata(iface, NULL); - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); iface->condition = USB_INTERFACE_UNBOUND; mark_quiesced(iface); iface->needs_remote_wakeup = 0; - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); } EXPORT_SYMBOL(usb_driver_release_interface); @@ -788,7 +789,7 @@ EXPORT_SYMBOL_GPL_FUTURE(usb_deregister); #ifdef CONFIG_PM -/* Caller has locked udev->pm_mutex */ +/* Caller has locked udev's pm_mutex */ static int suspend_device(struct usb_device *udev, pm_message_t msg) { struct usb_device_driver *udriver; @@ -815,7 +816,7 @@ done: return status; } -/* Caller has locked udev->pm_mutex */ +/* Caller has locked udev's pm_mutex */ static int resume_device(struct usb_device *udev) { struct usb_device_driver *udriver; @@ -841,7 +842,7 @@ done: return status; } -/* Caller has locked intf's usb_device's pm_mutex */ +/* Caller has locked intf's usb_device's pm mutex */ static int suspend_interface(struct usb_interface *intf, pm_message_t msg) { struct usb_driver *driver; @@ -1063,7 +1064,7 @@ int usb_resume_both(struct usb_device *udev) /* Propagate the resume up the tree, if necessary */ if (udev->state == USB_STATE_SUSPENDED) { if (parent) { - mutex_lock_nested(&parent->pm_mutex, parent->level); + usb_pm_lock(parent); parent->auto_pm = 1; status = usb_resume_both(parent); } else { @@ -1078,7 +1079,7 @@ int usb_resume_both(struct usb_device *udev) if (status == 0) status = resume_device(udev); if (parent) - mutex_unlock(&parent->pm_mutex); + usb_pm_unlock(parent); } else { /* Needed only for setting udev->dev.power.power_state.event @@ -1103,8 +1104,8 @@ int usb_resume_both(struct usb_device *udev) /** * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces - * @udev - the usb_device to autosuspend - * @dec_usage_cnt - flag to decrement @udev's PM-usage counter + * @udev: the usb_device to autosuspend + * @dec_usage_cnt: flag to decrement @udev's PM-usage counter * * This routine should be called when a core subsystem is finished using * @udev and wants to allow it to autosuspend. Examples would be when @@ -1128,20 +1129,20 @@ int usb_resume_both(struct usb_device *udev) */ void usb_autosuspend_device(struct usb_device *udev, int dec_usage_cnt) { - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); udev->pm_usage_cnt -= dec_usage_cnt; if (udev->pm_usage_cnt <= 0) - schedule_delayed_work(&udev->autosuspend, + queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, USB_AUTOSUSPEND_DELAY); - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); // dev_dbg(&udev->dev, "%s: cnt %d\n", // __FUNCTION__, udev->pm_usage_cnt); } /** * usb_autoresume_device - immediately autoresume a USB device and its interfaces - * @udev - the usb_device to autoresume - * @inc_usage_cnt - flag to increment @udev's PM-usage counter + * @udev: the usb_device to autoresume + * @inc_usage_cnt: flag to increment @udev's PM-usage counter * * This routine should be called when a core subsystem wants to use @udev * and needs to guarantee that it is not suspended. In addition, the @@ -1167,13 +1168,13 @@ int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt) { int status; - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); udev->pm_usage_cnt += inc_usage_cnt; udev->auto_pm = 1; status = usb_resume_both(udev); if (status != 0) udev->pm_usage_cnt -= inc_usage_cnt; - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); // dev_dbg(&udev->dev, "%s: status %d cnt %d\n", // __FUNCTION__, status, udev->pm_usage_cnt); return status; @@ -1181,7 +1182,7 @@ int usb_autoresume_device(struct usb_device *udev, int inc_usage_cnt) /** * usb_autopm_put_interface - decrement a USB interface's PM-usage counter - * @intf - the usb_interface whose counter should be decremented + * @intf: the usb_interface whose counter should be decremented * * This routine should be called by an interface driver when it is * finished using @intf and wants to allow it to autosuspend. A typical @@ -1214,13 +1215,13 @@ void usb_autopm_put_interface(struct usb_interface *intf) { struct usb_device *udev = interface_to_usbdev(intf); - mutex_lock_nested(&udev->pm_mutex, udev->level); - if (intf->condition != USB_INTERFACE_UNBOUND) { - if (--intf->pm_usage_cnt <= 0) - schedule_delayed_work(&udev->autosuspend, - USB_AUTOSUSPEND_DELAY); + usb_pm_lock(udev); + if (intf->condition != USB_INTERFACE_UNBOUND && + --intf->pm_usage_cnt <= 0) { + queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, + USB_AUTOSUSPEND_DELAY); } - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); // dev_dbg(&intf->dev, "%s: cnt %d\n", // __FUNCTION__, intf->pm_usage_cnt); } @@ -1228,7 +1229,7 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface); /** * usb_autopm_get_interface - increment a USB interface's PM-usage counter - * @intf - the usb_interface whose counter should be incremented + * @intf: the usb_interface whose counter should be incremented * * This routine should be called by an interface driver when it wants to * use @intf and needs to guarantee that it is not suspended. In addition, @@ -1262,7 +1263,7 @@ int usb_autopm_get_interface(struct usb_interface *intf) struct usb_device *udev = interface_to_usbdev(intf); int status; - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); if (intf->condition == USB_INTERFACE_UNBOUND) status = -ENODEV; else { @@ -1272,7 +1273,7 @@ int usb_autopm_get_interface(struct usb_interface *intf) if (status != 0) --intf->pm_usage_cnt; } - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); // dev_dbg(&intf->dev, "%s: status %d cnt %d\n", // __FUNCTION__, status, intf->pm_usage_cnt); return status; @@ -1288,10 +1289,10 @@ static int usb_suspend(struct device *dev, pm_message_t message) if (is_usb_device(dev)) { struct usb_device *udev = to_usb_device(dev); - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); udev->auto_pm = 0; status = usb_suspend_both(udev, message); - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); } else status = 0; return status; @@ -1304,10 +1305,10 @@ static int usb_resume(struct device *dev) if (is_usb_device(dev)) { struct usb_device *udev = to_usb_device(dev); - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); udev->auto_pm = 0; status = usb_resume_both(udev); - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); /* Rebind drivers that had no suspend method? */ } else diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index e86f6295708..37f9f5e7425 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -345,7 +345,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) struct usb_ctrlrequest *cmd; u16 typeReq, wValue, wIndex, wLength; u8 *ubuf = urb->transfer_buffer; - u8 tbuf [sizeof (struct usb_hub_descriptor)]; + u8 tbuf [sizeof (struct usb_hub_descriptor)] + __attribute__((aligned(4))); const u8 *bufp = tbuf; int len = 0; int patch_wakeup = 0; @@ -835,8 +836,7 @@ void usb_enable_root_hub_irq (struct usb_bus *bus) struct usb_hcd *hcd; hcd = container_of (bus, struct usb_hcd, self); - if (hcd->driver->hub_irq_enable && !hcd->poll_rh && - hcd->state != HC_STATE_HALT) + if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT) hcd->driver->hub_irq_enable (hcd); } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2a8cb3c2b19..7676690a038 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1779,7 +1779,7 @@ static int remote_wakeup(struct usb_device *udev) * to the parent hub! */ usb_lock_device(udev); - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); if (udev->state == USB_STATE_SUSPENDED) { dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); /* TRSMRCY = 10 msec */ @@ -1788,7 +1788,7 @@ static int remote_wakeup(struct usb_device *udev) if (status == 0) udev->dev.power.power_state.event = PM_EVENT_ON; } - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); if (status == 0) usb_autoresume_device(udev, 0); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 60ef4ef0101..e4df9edf1bc 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -33,6 +33,7 @@ #include <linux/smp_lock.h> #include <linux/usb.h> #include <linux/mutex.h> +#include <linux/workqueue.h> #include <asm/io.h> #include <asm/scatterlist.h> @@ -47,6 +48,8 @@ const char *usbcore_name = "usbcore"; static int nousb; /* Disable USB when built into kernel image */ +struct workqueue_struct *ksuspend_usb_wq; /* For autosuspend */ + /** * usb_ifnum_to_if - get the interface object with a given interface number @@ -170,9 +173,9 @@ static void usb_release_dev(struct device *dev) udev = to_usb_device(dev); -#ifdef CONFIG_PM +#ifdef CONFIG_USB_SUSPEND cancel_delayed_work(&udev->autosuspend); - flush_scheduled_work(); + flush_workqueue(ksuspend_usb_wq); #endif usb_destroy_configuration(udev); usb_put_hcd(bus_to_hcd(udev->bus)); @@ -184,17 +187,44 @@ static void usb_release_dev(struct device *dev) #ifdef CONFIG_PM +static int ksuspend_usb_init(void) +{ + ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd"); + if (!ksuspend_usb_wq) + return -ENOMEM; + return 0; +} + +static void ksuspend_usb_cleanup(void) +{ + destroy_workqueue(ksuspend_usb_wq); +} + +#else + +#define ksuspend_usb_init() 0 +#define ksuspend_usb_cleanup() do {} while (0) + +#endif + +#ifdef CONFIG_USB_SUSPEND + /* usb_autosuspend_work - callback routine to autosuspend a USB device */ static void usb_autosuspend_work(void *_udev) { struct usb_device *udev = _udev; - mutex_lock_nested(&udev->pm_mutex, udev->level); + usb_pm_lock(udev); udev->auto_pm = 1; usb_suspend_both(udev, PMSG_SUSPEND); - mutex_unlock(&udev->pm_mutex); + usb_pm_unlock(udev); } +#else + +static void usb_autosuspend_work(void *_udev) +{} + #endif /** @@ -976,9 +1006,12 @@ static int __init usb_init(void) return 0; } + retval = ksuspend_usb_init(); + if (retval) + goto out; retval = bus_register(&usb_bus_type); if (retval) - goto out; + goto bus_register_failed; retval = usb_host_init(); if (retval) goto host_init_failed; @@ -1014,6 +1047,8 @@ major_init_failed: usb_host_cleanup(); host_init_failed: bus_unregister(&usb_bus_type); +bus_register_failed: + ksuspend_usb_cleanup(); out: return retval; } @@ -1035,6 +1070,7 @@ static void __exit usb_exit(void) usb_hub_cleanup(); usb_host_cleanup(); bus_unregister(&usb_bus_type); + ksuspend_usb_cleanup(); } subsys_initcall(usb_init); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 0c09ecced6e..f69df137ec0 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -36,6 +36,16 @@ extern int usb_resume_both(struct usb_device *udev); extern int usb_port_suspend(struct usb_device *dev); extern int usb_port_resume(struct usb_device *dev); +static inline void usb_pm_lock(struct usb_device *udev) +{ + mutex_lock_nested(&udev->pm_mutex, udev->level); +} + +static inline void usb_pm_unlock(struct usb_device *udev) +{ + mutex_unlock(&udev->pm_mutex); +} + #else #define usb_suspend_both(udev, msg) 0 @@ -45,6 +55,8 @@ static inline int usb_resume_both(struct usb_device *udev) } #define usb_port_suspend(dev) 0 #define usb_port_resume(dev) 0 +static inline void usb_pm_lock(struct usb_device *udev) {} +static inline void usb_pm_unlock(struct usb_device *udev) {} #endif @@ -58,10 +70,15 @@ extern int usb_autoresume_device(struct usb_device *udev, int inc_busy_cnt); #else #define usb_autosuspend_device(udev, dec_busy_cnt) do {} while (0) -#define usb_autoresume_device(udev, inc_busy_cnt) 0 +static inline int usb_autoresume_device(struct usb_device *udev, + int inc_busy_cnt) +{ + return 0; +} #endif +extern struct workqueue_struct *ksuspend_usb_wq; extern struct bus_type usb_bus_type; extern struct usb_device_driver usb_generic_driver; diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index d00958a01cf..77beba485a8 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1658,7 +1658,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) return -ENODEV; } - if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) { + if (!request_mem_region(AT91RM9200_BASE_UDP, SZ_16K, driver_name)) { DBG("someone's using UDC memory\n"); return -EBUSY; } @@ -1720,7 +1720,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) fail1: device_unregister(&udc->gadget.dev); fail0: - release_mem_region(AT91_BASE_UDP, SZ_16K); + release_mem_region(AT91RM9200_BASE_UDP, SZ_16K); DBG("%s probe failed, %d\n", driver_name, retval); return retval; } @@ -1742,7 +1742,7 @@ static int __devexit at91udc_remove(struct platform_device *pdev) free_irq(udc->board.vbus_pin, udc); free_irq(udc->udp_irq, udc); device_unregister(&udc->gadget.dev); - release_mem_region(AT91_BASE_UDP, SZ_16K); + release_mem_region(AT91RM9200_BASE_UDP, SZ_16K); clk_put(udc->iclk); clk_put(udc->fclk); diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index fdab97a27c0..4d2946e540c 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -816,15 +816,14 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) dum->gadget.dev.driver = &driver->driver; dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n", driver->driver.name); - if ((retval = driver->bind (&dum->gadget)) != 0) { - dum->driver = NULL; - dum->gadget.dev.driver = NULL; - return retval; - } + if ((retval = driver->bind (&dum->gadget)) != 0) + goto err_bind_gadget; driver->driver.bus = dum->gadget.dev.parent->bus; - driver_register (&driver->driver); - device_bind_driver (&dum->gadget.dev); + if ((retval = driver_register (&driver->driver)) != 0) + goto err_register; + if ((retval = device_bind_driver (&dum->gadget.dev)) != 0) + goto err_bind_driver; /* khubd will enumerate this in a while */ spin_lock_irq (&dum->lock); @@ -834,6 +833,19 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) usb_hcd_poll_rh_status (dummy_to_hcd (dum)); return 0; + +err_bind_driver: + driver_unregister (&driver->driver); +err_register: + driver->unbind (&dum->gadget); + spin_lock_irq (&dum->lock); + dum->pullup = 0; + set_link_state (dum); + spin_unlock_irq (&dum->lock); +err_bind_gadget: + dum->driver = NULL; + dum->gadget.dev.driver = NULL; + return retval; } EXPORT_SYMBOL (usb_gadget_register_driver); @@ -916,7 +928,9 @@ static int dummy_udc_probe (struct platform_device *pdev) usb_get_hcd (dummy_to_hcd (dum)); platform_set_drvdata (pdev, dum); - device_create_file (&dum->gadget.dev, &dev_attr_function); + rc = device_create_file (&dum->gadget.dev, &dev_attr_function); + if (rc < 0) + device_unregister (&dum->gadget.dev); return rc; } @@ -1864,8 +1878,7 @@ static int dummy_start (struct usb_hcd *hcd) #endif /* FIXME 'urbs' should be a per-device thing, maybe in usbcore */ - device_create_file (dummy_dev(dum), &dev_attr_urbs); - return 0; + return device_create_file (dummy_dev(dum), &dev_attr_urbs); } static void dummy_stop (struct usb_hcd *hcd) diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 8d7f1e84cd7..c83d3b6c68f 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -567,6 +567,7 @@ struct lun { unsigned int ro : 1; unsigned int prevent_medium_removal : 1; unsigned int registered : 1; + unsigned int info_valid : 1; u32 sense_data; u32 sense_data_info; @@ -1656,6 +1657,7 @@ static int do_read(struct fsg_dev *fsg) curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; curlun->sense_data_info = file_offset >> 9; + curlun->info_valid = 1; bh->inreq->length = 0; bh->state = BUF_STATE_FULL; break; @@ -1691,6 +1693,7 @@ static int do_read(struct fsg_dev *fsg) if (nread < amount) { curlun->sense_data = SS_UNRECOVERED_READ_ERROR; curlun->sense_data_info = file_offset >> 9; + curlun->info_valid = 1; break; } @@ -1785,6 +1788,7 @@ static int do_write(struct fsg_dev *fsg) curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; curlun->sense_data_info = usb_offset >> 9; + curlun->info_valid = 1; continue; } amount -= (amount & 511); @@ -1827,6 +1831,7 @@ static int do_write(struct fsg_dev *fsg) if (bh->outreq->status != 0) { curlun->sense_data = SS_COMMUNICATION_FAILURE; curlun->sense_data_info = file_offset >> 9; + curlun->info_valid = 1; break; } @@ -1868,6 +1873,7 @@ static int do_write(struct fsg_dev *fsg) if (nwritten < amount) { curlun->sense_data = SS_WRITE_ERROR; curlun->sense_data_info = file_offset >> 9; + curlun->info_valid = 1; break; } @@ -2010,6 +2016,7 @@ static int do_verify(struct fsg_dev *fsg) curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; curlun->sense_data_info = file_offset >> 9; + curlun->info_valid = 1; break; } @@ -2036,6 +2043,7 @@ static int do_verify(struct fsg_dev *fsg) if (nread == 0) { curlun->sense_data = SS_UNRECOVERED_READ_ERROR; curlun->sense_data_info = file_offset >> 9; + curlun->info_valid = 1; break; } file_offset += nread; @@ -2079,6 +2087,7 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) struct lun *curlun = fsg->curlun; u8 *buf = (u8 *) bh->buf; u32 sd, sdinfo; + int valid; /* * From the SCSI-2 spec., section 7.9 (Unit attention condition): @@ -2106,15 +2115,18 @@ static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) fsg->bad_lun_okay = 1; sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; sdinfo = 0; + valid = 0; } else { sd = curlun->sense_data; sdinfo = curlun->sense_data_info; + valid = curlun->info_valid << 7; curlun->sense_data = SS_NO_SENSE; curlun->sense_data_info = 0; + curlun->info_valid = 0; } memset(buf, 0, 18); - buf[0] = 0x80 | 0x70; // Valid, current error + buf[0] = valid | 0x70; // Valid, current error buf[2] = SK(sd); put_be32(&buf[3], sdinfo); // Sense information buf[7] = 18 - 8; // Additional sense length @@ -2703,6 +2715,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, if (fsg->cmnd[0] != SC_REQUEST_SENSE) { curlun->sense_data = SS_NO_SENSE; curlun->sense_data_info = 0; + curlun->info_valid = 0; } } else { fsg->curlun = curlun = NULL; @@ -3332,6 +3345,7 @@ static void handle_exception(struct fsg_dev *fsg) curlun->sense_data = curlun->unit_attention_data = SS_NO_SENSE; curlun->sense_data_info = 0; + curlun->info_valid = 0; } fsg->state = FSG_STATE_IDLE; } @@ -3873,21 +3887,26 @@ static int __init fsg_bind(struct usb_gadget *gadget) for (i = 0; i < fsg->nluns; ++i) { curlun = &fsg->luns[i]; curlun->ro = mod_data.ro[i]; + curlun->dev.release = lun_release; curlun->dev.parent = &gadget->dev; curlun->dev.driver = &fsg_driver.driver; dev_set_drvdata(&curlun->dev, fsg); snprintf(curlun->dev.bus_id, BUS_ID_SIZE, "%s-lun%d", gadget->dev.bus_id, i); - if ((rc = device_register(&curlun->dev)) != 0) + if ((rc = device_register(&curlun->dev)) != 0) { INFO(fsg, "failed to register LUN%d: %d\n", i, rc); - else { - curlun->registered = 1; - curlun->dev.release = lun_release; - device_create_file(&curlun->dev, &dev_attr_ro); - device_create_file(&curlun->dev, &dev_attr_file); - kref_get(&fsg->ref); + goto out; + } + if ((rc = device_create_file(&curlun->dev, + &dev_attr_ro)) != 0 || + (rc = device_create_file(&curlun->dev, + &dev_attr_file)) != 0) { + device_unregister(&curlun->dev); + goto out; } + curlun->registered = 1; + kref_get(&fsg->ref); if (mod_data.file[i] && *mod_data.file[i]) { if ((rc = open_backing_file(curlun, diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 1027aa04583..d1d68c40225 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -715,17 +715,8 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) return IRQ_NOTMINE; } - /* NOTE: vendors didn't always make the same implementation - * choices for RHSC. Sometimes it triggers on an edge (like - * setting and maybe clearing a port status change bit); and - * it's level-triggered on other silicon, active until khubd - * clears all active port status change bits. Poll by timer - * til it's fully debounced and the difference won't matter. - */ if (ints & OHCI_INTR_RHSC) { ohci_vdbg (ohci, "rhsc\n"); - ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrdisable); - hcd->poll_rh = 1; ohci->next_statechange = jiffies + STATECHANGE_DELAY; ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus); usb_hcd_poll_rh_status(hcd); @@ -743,13 +734,18 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) if (ints & OHCI_INTR_RD) { ohci_vdbg (ohci, "resume detect\n"); ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); - if (hcd->state != HC_STATE_QUIESCING) + hcd->poll_rh = 1; + if (ohci->autostop) { + spin_lock (&ohci->lock); + ohci_rh_resume (ohci); + spin_unlock (&ohci->lock); + } else usb_hcd_resume_root_hub(hcd); } if (ints & OHCI_INTR_WDH) { if (HC_IS_RUNNING(hcd->state)) - ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrdisable); + ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrdisable); spin_lock (&ohci->lock); dl_done_list (ohci, ptregs); spin_unlock (&ohci->lock); diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 0b899339cac..ec75774abea 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -44,27 +44,17 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd) ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); } -#ifdef CONFIG_PM - #define OHCI_SCHED_ENABLES \ (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) static void dl_done_list (struct ohci_hcd *, struct pt_regs *); static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); -static int ohci_restart (struct ohci_hcd *ohci); -static int ohci_bus_suspend (struct usb_hcd *hcd) +static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) +__releases(ohci->lock) +__acquires(ohci->lock) { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); int status = 0; - unsigned long flags; - - spin_lock_irqsave (&ohci->lock, flags); - - if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { - spin_unlock_irqrestore (&ohci->lock, flags); - return -ESHUTDOWN; - } ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); switch (ohci->hc_control & OHCI_CTRL_HCFS) { @@ -80,15 +70,16 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) ohci_dbg (ohci, "needs reinit!\n"); goto done; case OHCI_USB_SUSPEND: - ohci_dbg (ohci, "already suspended\n"); - goto done; + if (!ohci->autostop) { + ohci_dbg (ohci, "already suspended\n"); + goto done; + } } - ohci_dbg (ohci, "suspend root hub\n"); + ohci_dbg (ohci, "%s root hub\n", + autostop ? "auto-stop" : "suspend"); /* First stop any processing */ - if (ohci->hc_control & OHCI_SCHED_ENABLES) { - int limit; - + if (!autostop && (ohci->hc_control & OHCI_SCHED_ENABLES)) { ohci->hc_control &= ~OHCI_SCHED_ENABLES; ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); @@ -98,27 +89,22 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) * then the last WDH could take 6+ msec */ ohci_dbg (ohci, "stopping schedules ...\n"); - limit = 2000; - while (limit > 0) { - udelay (250); - limit =- 250; - if (ohci_readl (ohci, &ohci->regs->intrstatus) - & OHCI_INTR_SF) - break; - } - dl_done_list (ohci, NULL); - mdelay (7); + ohci->autostop = 0; + spin_unlock_irq (&ohci->lock); + msleep (8); + spin_lock_irq (&ohci->lock); } dl_done_list (ohci, NULL); finish_unlinks (ohci, ohci_frame_no(ohci), NULL); - ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus), - &ohci->regs->intrstatus); /* maybe resume can wake root hub */ - if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev)) + if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev) || + autostop) ohci->hc_control |= OHCI_CTRL_RWE; - else + else { + ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable); ohci->hc_control &= ~OHCI_CTRL_RWE; + } /* Suspend hub ... this is the "global (to this bus) suspend" mode, * which doesn't imply ports will first be individually suspended. @@ -129,13 +115,12 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) (void) ohci_readl (ohci, &ohci->regs->control); /* no resumes until devices finish suspending */ - ohci->next_statechange = jiffies + msecs_to_jiffies (5); - - /* no timer polling */ - hcd->poll_rh = 0; + if (!autostop) { + ohci->next_statechange = jiffies + msecs_to_jiffies (5); + ohci->autostop = 0; + } done: - spin_unlock_irqrestore (&ohci->lock, flags); return status; } @@ -147,25 +132,19 @@ static inline struct ed *find_head (struct ed *ed) return ed; } +static int ohci_restart (struct ohci_hcd *ohci); + /* caller has locked the root hub */ -static int ohci_bus_resume (struct usb_hcd *hcd) +static int ohci_rh_resume (struct ohci_hcd *ohci) +__releases(ohci->lock) +__acquires(ohci->lock) { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); + struct usb_hcd *hcd = ohci_to_hcd (ohci); u32 temp, enables; int status = -EINPROGRESS; - unsigned long flags; - - if (time_before (jiffies, ohci->next_statechange)) - msleep(5); - - spin_lock_irqsave (&ohci->lock, flags); - - if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { - spin_unlock_irqrestore (&ohci->lock, flags); - return -ESHUTDOWN; - } - + int autostopped = ohci->autostop; + ohci->autostop = 0; ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { @@ -185,7 +164,8 @@ static int ohci_bus_resume (struct usb_hcd *hcd) ohci->hc_control |= OHCI_USB_RESUME; ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); (void) ohci_readl (ohci, &ohci->regs->control); - ohci_dbg (ohci, "resume root hub\n"); + ohci_dbg (ohci, "%s root hub\n", + autostopped ? "auto-start" : "resume"); break; case OHCI_USB_RESUME: /* HCFS changes sometime after INTR_RD */ @@ -200,16 +180,24 @@ static int ohci_bus_resume (struct usb_hcd *hcd) ohci_dbg (ohci, "lost power\n"); status = -EBUSY; } - spin_unlock_irqrestore (&ohci->lock, flags); +#ifdef CONFIG_PM if (status == -EBUSY) { - (void) ohci_init (ohci); - return ohci_restart (ohci); + if (!autostopped) { + spin_unlock_irq (&ohci->lock); + (void) ohci_init (ohci); + status = ohci_restart (ohci); + spin_lock_irq (&ohci->lock); + } + return status; } +#endif if (status != -EINPROGRESS) return status; + if (autostopped) + goto skip_resume; + spin_unlock_irq (&ohci->lock); temp = ohci->num_ports; - enables = 0; while (temp--) { u32 stat = ohci_readl (ohci, &ohci->regs->roothub.portstatus [temp]); @@ -242,17 +230,21 @@ static int ohci_bus_resume (struct usb_hcd *hcd) /* Sometimes PCI D3 suspend trashes frame timings ... */ periodic_reinit (ohci); + /* the following code is executed with ohci->lock held and + * irqs disabled if and only if autostopped is true + */ + +skip_resume: /* interrupts might have been disabled */ ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable); if (ohci->ed_rm_list) ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable); - ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus), - &ohci->regs->intrstatus); /* Then re-enable operations */ ohci_writel (ohci, OHCI_USB_OPER, &ohci->regs->control); (void) ohci_readl (ohci, &ohci->regs->control); - msleep (3); + if (!autostopped) + msleep (3); temp = ohci->hc_control; temp &= OHCI_CTRL_RWC; @@ -262,7 +254,11 @@ static int ohci_bus_resume (struct usb_hcd *hcd) (void) ohci_readl (ohci, &ohci->regs->control); /* TRSMRCY */ - msleep (10); + if (!autostopped) { + msleep (10); + spin_lock_irq (&ohci->lock); + } + /* now ohci->lock is always held and irqs are always disabled */ /* keep it alive for more than ~5x suspend + resume costs */ ohci->next_statechange = jiffies + STATECHANGE_DELAY; @@ -299,6 +295,45 @@ static int ohci_bus_resume (struct usb_hcd *hcd) return 0; } +#ifdef CONFIG_PM + +static int ohci_bus_suspend (struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci (hcd); + int rc; + + spin_lock_irq (&ohci->lock); + + if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) + rc = -ESHUTDOWN; + else + rc = ohci_rh_suspend (ohci, 0); + spin_unlock_irq (&ohci->lock); + return rc; +} + +static int ohci_bus_resume (struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci (hcd); + int rc; + + if (time_before (jiffies, ohci->next_statechange)) + msleep(5); + + spin_lock_irq (&ohci->lock); + + if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) + rc = -ESHUTDOWN; + else + rc = ohci_rh_resume (ohci); + spin_unlock_irq (&ohci->lock); + + /* poll until we know a device is connected or we autostop */ + if (rc == 0) + usb_hcd_poll_rh_status(hcd); + return rc; +} + #endif /* CONFIG_PM */ /*-------------------------------------------------------------------------*/ @@ -310,21 +345,11 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int i, changed = 0, length = 1; - int can_suspend; + int any_connected = 0, rhsc_enabled = 1; unsigned long flags; - can_suspend = device_may_wakeup(&hcd->self.root_hub->dev); spin_lock_irqsave (&ohci->lock, flags); - /* handle autosuspended root: finish resuming before - * letting khubd or root hub timer see state changes. - */ - if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER - || !HC_IS_RUNNING(hcd->state))) { - can_suspend = 0; - goto done; - } - /* undocumented erratum seen on at least rev D */ if ((ohci->flags & OHCI_QUIRK_AMD756) && (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) { @@ -348,9 +373,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) for (i = 0; i < ohci->num_ports; i++) { u32 status = roothub_portstatus (ohci, i); - /* can't autosuspend with active ports */ - if ((status & RH_PS_PES) && !(status & RH_PS_PSS)) - can_suspend = 0; + /* can't autostop if ports are connected */ + any_connected |= (status & RH_PS_CCS); if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC)) { @@ -359,49 +383,73 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) buf [0] |= 1 << (i + 1); else buf [1] |= 1 << (i - 7); - continue; } } - /* after root hub changes, stop polling after debouncing - * for a while and maybe kicking in autosuspend + /* NOTE: vendors didn't always make the same implementation + * choices for RHSC. Sometimes it triggers on an edge (like + * setting and maybe clearing a port status change bit); and + * it's level-triggered on other silicon, active until khubd + * clears all active port status change bits. If it's still + * set (level-triggered) we must disable it and rely on + * polling until khubd re-enables it. */ - if (changed) { - ohci->next_statechange = jiffies + STATECHANGE_DELAY; - can_suspend = 0; - } else if (time_before (jiffies, ohci->next_statechange)) { - can_suspend = 0; - } else { -#ifdef CONFIG_PM - can_suspend = can_suspend - && !ohci->ed_rm_list - && ((OHCI_CTRL_HCFS | OHCI_SCHED_ENABLES) - & ohci->hc_control) - == OHCI_USB_OPER; -#endif - if (hcd->uses_new_polling) { + if (ohci_readl (ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC) { + ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable); + (void) ohci_readl (ohci, &ohci->regs->intrdisable); + rhsc_enabled = 0; + } + hcd->poll_rh = 1; + + /* carry out appropriate state changes */ + switch (ohci->hc_control & OHCI_CTRL_HCFS) { + + case OHCI_USB_OPER: + /* keep on polling until we know a device is connected + * and RHSC is enabled */ + if (!ohci->autostop) { + if (any_connected) { + if (rhsc_enabled) + hcd->poll_rh = 0; + } else { + ohci->autostop = 1; + ohci->next_statechange = jiffies + HZ; + } + + /* if no devices have been attached for one second, autostop */ + } else { + if (changed || any_connected) { + ohci->autostop = 0; + ohci->next_statechange = jiffies + + STATECHANGE_DELAY; + } else if (time_after_eq (jiffies, + ohci->next_statechange) + && !ohci->ed_rm_list + && !(ohci->hc_control & + OHCI_SCHED_ENABLES)) { + ohci_rh_suspend (ohci, 1); + } + } + break; + + /* if there is a port change, autostart or ask to be resumed */ + case OHCI_USB_SUSPEND: + case OHCI_USB_RESUME: + if (changed) { + if (ohci->autostop) + ohci_rh_resume (ohci); + else + usb_hcd_resume_root_hub (hcd); + } else { + /* everything is idle, no need for polling */ hcd->poll_rh = 0; - /* use INTR_RHSC iff INTR_RD won't apply */ - if (!can_suspend) - ohci_writel (ohci, OHCI_INTR_RHSC, - &ohci->regs->intrenable); } + break; } done: spin_unlock_irqrestore (&ohci->lock, flags); -#ifdef CONFIG_PM - /* save power by autosuspending idle root hubs; - * INTR_RD wakes us when there's work - */ - if (can_suspend && usb_trylock_device (hcd->self.root_hub) == 0) { - ohci_vdbg (ohci, "autosuspend\n"); - (void) ohci_bus_suspend (hcd); - usb_unlock_device (hcd->self.root_hub); - } -#endif - return changed ? length : 0; } @@ -572,9 +620,6 @@ static int ohci_hub_control ( break; case USB_PORT_FEAT_SUSPEND: temp = RH_PS_POCI; - if ((ohci->hc_control & OHCI_CTRL_HCFS) - != OHCI_USB_OPER) - usb_hcd_resume_root_hub(hcd); break; case USB_PORT_FEAT_C_SUSPEND: temp = RH_PS_PSSC; diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 3732db7d68e..87441855278 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -73,13 +73,14 @@ ohci_pci_start (struct usb_hcd *hcd) else if (pdev->vendor == PCI_VENDOR_ID_NS) { struct pci_dev *b; - b = pci_find_slot (pdev->bus->number, + b = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO && b->vendor == PCI_VENDOR_ID_NS) { ohci->flags |= OHCI_QUIRK_SUPERIO; ohci_dbg (ohci, "Using NSC SuperIO setup\n"); } + pci_dev_put(b); } /* Check for Compaq's ZFMicro chipset, which needs short diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 93fdc3c3534..a2f42a2f47c 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -388,6 +388,7 @@ struct ohci_hcd { u32 hc_control; /* copy of hc control reg */ unsigned long next_statechange; /* suspend/resume */ u32 fminterval; /* saved register */ + unsigned autostop:1; /* rh auto stopping/stopped */ unsigned long flags; /* for HC bugs */ #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index b2bafc37c41..5f861331932 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -225,7 +225,7 @@ static inline void mts_debug_dump(struct mts_desc* desc) { } -static inline void mts_show_command(Scsi_Cmnd *srb) +static inline void mts_show_command(struct scsi_cmnd *srb) { char *what = NULL; @@ -309,7 +309,7 @@ static inline void mts_show_command(Scsi_Cmnd *srb) #else -static inline void mts_show_command(Scsi_Cmnd * dummy) +static inline void mts_show_command(struct scsi_cmnd * dummy) { } @@ -338,7 +338,7 @@ static int mts_slave_configure (struct scsi_device *s) return 0; } -static int mts_scsi_abort (Scsi_Cmnd *srb) +static int mts_scsi_abort(struct scsi_cmnd *srb) { struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); @@ -349,7 +349,7 @@ static int mts_scsi_abort (Scsi_Cmnd *srb) return FAILED; } -static int mts_scsi_host_reset (Scsi_Cmnd *srb) +static int mts_scsi_host_reset(struct scsi_cmnd *srb) { struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); int result, rc; @@ -366,8 +366,8 @@ static int mts_scsi_host_reset (Scsi_Cmnd *srb) return result ? FAILED : SUCCESS; } -static -int mts_scsi_queuecommand (Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ); +static int +mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback); static void mts_transfer_cleanup( struct urb *transfer ); static void mts_do_sg(struct urb * transfer, struct pt_regs *regs); @@ -537,7 +537,7 @@ static const unsigned char mts_direction[256/8] = { #define MTS_DIRECTION_IS_IN(x) ((mts_direction[x>>3] >> (x & 7)) & 1) static void -mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) +mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc) { int pipe; struct scatterlist * sg; @@ -588,8 +588,8 @@ mts_build_transfer_context( Scsi_Cmnd *srb, struct mts_desc* desc ) } -static -int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ) +static int +mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback) { struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); int err = 0; diff --git a/drivers/usb/image/microtek.h b/drivers/usb/image/microtek.h index 926d4bdc674..d5d62a93905 100644 --- a/drivers/usb/image/microtek.h +++ b/drivers/usb/image/microtek.h @@ -8,14 +8,14 @@ * */ -typedef void (*mts_scsi_cmnd_callback)(Scsi_Cmnd *); +typedef void (*mts_scsi_cmnd_callback)(struct scsi_cmnd *); struct mts_transfer_context { struct mts_desc* instance; mts_scsi_cmnd_callback final_callback; - Scsi_Cmnd *srb; + struct scsi_cmnd *srb; void* data; unsigned data_length; diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 2a3e9e9b4b3..81b1ea01a17 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1600,6 +1600,9 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_ALCOR 0x058f #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 +#define USB_VENDOR_ID_SUN 0x0430 +#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab + /* * Alphabetically sorted blacklist by quirk type. */ @@ -1729,6 +1732,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 9a8d137d39f..78e419904ab 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c @@ -44,20 +44,25 @@ struct driver_interfacekit { int inputs; int outputs; int has_lcd; + int amnesiac; }; -#define ifkit(_sensors, _inputs, _outputs, _lcd) \ -static struct driver_interfacekit ph_##_sensors##_inputs##_outputs = { \ + +#define ifkit(_sensors, _inputs, _outputs, _lcd, _amnesiac) \ +{ \ .sensors = _sensors, \ .inputs = _inputs, \ .outputs = _outputs, \ .has_lcd = _lcd, \ + .amnesiac = _amnesiac \ }; -ifkit(0, 0, 4, 0); -ifkit(8, 8, 8, 0); -ifkit(0, 4, 7, 1); -ifkit(8, 8, 4, 0); -ifkit(0, 8, 8, 1); -ifkit(0, 16, 16, 0); + +static const struct driver_interfacekit ph_004 = ifkit(0, 0, 4, 0, 0); +static const struct driver_interfacekit ph_888n = ifkit(8, 8, 8, 0, 1); +static const struct driver_interfacekit ph_888o = ifkit(8, 8, 8, 0, 0); +static const struct driver_interfacekit ph_047 = ifkit(0, 4, 7, 1, 0); +static const struct driver_interfacekit ph_884 = ifkit(8, 8, 4, 0, 0); +static const struct driver_interfacekit ph_088 = ifkit(0, 8, 8, 1, 0); +static const struct driver_interfacekit ph_01616 = ifkit(0, 16, 16, 0, 0); static unsigned long device_no; @@ -77,6 +82,7 @@ struct interfacekit { dma_addr_t data_dma; struct work_struct do_notify; + struct work_struct do_resubmit; unsigned long input_events; unsigned long sensor_events; }; @@ -84,8 +90,10 @@ struct interfacekit { static struct usb_device_id id_table[] = { {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT004), .driver_info = (kernel_ulong_t)&ph_004}, - {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888), - .driver_info = (kernel_ulong_t)&ph_888}, + {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0, 0x814), + .driver_info = (kernel_ulong_t)&ph_888o}, + {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0x0815, 0xffff), + .driver_info = (kernel_ulong_t)&ph_888n}, {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT047), .driver_info = (kernel_ulong_t)&ph_047}, {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088), @@ -98,16 +106,11 @@ static struct usb_device_id id_table[] = { }; MODULE_DEVICE_TABLE(usb, id_table); -static int change_outputs(struct interfacekit *kit, int output_num, int enable) +static int set_outputs(struct interfacekit *kit) { u8 *buffer; int retval; - if (enable) - set_bit(output_num, &kit->outputs); - else - clear_bit(output_num, &kit->outputs); - buffer = kzalloc(4, GFP_KERNEL); if (!buffer) { dev_err(&kit->udev->dev, "%s - out of memory\n", __FUNCTION__); @@ -127,6 +130,9 @@ static int change_outputs(struct interfacekit *kit, int output_num, int enable) retval); kfree(buffer); + if (kit->ifkit->amnesiac) + schedule_delayed_work(&kit->do_resubmit, HZ / 2); + return retval < 0 ? retval : 0; } @@ -399,19 +405,29 @@ static void do_notify(void *data) } } +static void do_resubmit(void *data) +{ + set_outputs(data); +} + #define show_set_output(value) \ static ssize_t set_output##value(struct device *dev, \ struct device_attribute *attr, \ const char *buf, size_t count) \ { \ struct interfacekit *kit = dev_get_drvdata(dev); \ - int enabled; \ + int enable; \ int retval; \ \ - if (sscanf(buf, "%d", &enabled) < 1) \ + if (sscanf(buf, "%d", &enable) < 1) \ return -EINVAL; \ \ - retval = change_outputs(kit, value - 1, enabled); \ + if (enable) \ + set_bit(value - 1, &kit->outputs); \ + else \ + clear_bit(value - 1, &kit->outputs); \ + \ + retval = set_outputs(kit); \ \ return retval ? retval : count; \ } \ @@ -560,6 +576,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic kit->udev = usb_get_dev(dev); kit->intf = intf; INIT_WORK(&kit->do_notify, do_notify, kit); + INIT_WORK(&kit->do_resubmit, do_resubmit, kit); usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, interfacekit_irq, kit, endpoint->bInterval); @@ -663,6 +680,7 @@ static void interfacekit_disconnect(struct usb_interface *interface) usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma); cancel_delayed_work(&kit->do_notify); + cancel_delayed_work(&kit->do_resubmit); for (i=0; i<kit->ifkit->outputs; i++) device_remove_file(kit->dev, &dev_output_attrs[i]); diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 9b97aa6384c..9c0eacf7055 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c @@ -1456,6 +1456,10 @@ static const struct usb_device_id products [] = { USB_DEVICE (0x07d1, 0x3c05), .driver_info = (unsigned long) &ax88772_info, }, { + // DLink DUB-E100 H/W Ver B1 Alternate + USB_DEVICE (0x2001, 0x3c05), + .driver_info = (unsigned long) &ax88772_info, +}, { // Linksys USB1000 USB_DEVICE (0x1737, 0x0039), .driver_info = (unsigned long) &ax88178_info, diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index def3bb8e229..544d41fe9b9 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -165,6 +165,7 @@ static struct usb_device_id usb_klsi_table[] = { { USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */ { USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */ { USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */ + { USB_DEVICE(0x1668, 0x0323) }, /* Actiontec USB Ethernet */ { USB_DEVICE(0x2001, 0x4000) }, /* D-link DSB-650C */ {} /* Null terminator */ }; diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index b8e25af13f0..918cf5a77c0 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -45,7 +45,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.6.13 (2005/11/13)" +#define DRIVER_VERSION "v0.6.14 (2006/09/27)" #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>" #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver" @@ -339,7 +339,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) } fail: if (netif_msg_drv(pegasus)) - dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); + dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__); return ret; } @@ -376,7 +376,7 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) fail: if (netif_msg_drv(pegasus)) - dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); + dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__); return -ETIMEDOUT; } @@ -413,7 +413,7 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) fail: if (netif_msg_drv(pegasus)) - dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); + dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__); return -ETIMEDOUT; } @@ -461,7 +461,7 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) return ret; fail: if (netif_msg_drv(pegasus)) - dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__); + dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__); return -ETIMEDOUT; } #endif /* PEGASUS_WRITE_EEPROM */ @@ -481,8 +481,12 @@ static void set_ethernet_addr(pegasus_t * pegasus) { __u8 node_id[6]; - get_node_id(pegasus, node_id); - set_registers(pegasus, EthID, sizeof (node_id), node_id); + if (pegasus->features & PEGASUS_II) { + get_registers(pegasus, 0x10, sizeof(node_id), node_id); + } else { + get_node_id(pegasus, node_id); + set_registers(pegasus, EthID, sizeof (node_id), node_id); + } memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id)); } diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 6286aba86fa..d954ec34b01 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -214,14 +214,14 @@ static int cyberjack_write (struct usb_serial_port *port, const unsigned char *b return (0); } - spin_lock(&port->lock); + spin_lock_bh(&port->lock); if (port->write_urb_busy) { - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); dbg("%s - already writing", __FUNCTION__); return 0; } port->write_urb_busy = 1; - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); spin_lock_irqsave(&priv->lock, flags); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1f7b72553f3..e774a27c6c9 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -344,6 +344,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2104_PID) }, + { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2106_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_1_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2201_2_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2202_1_PID) }, @@ -507,6 +508,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) }, { USB_DEVICE(TESTO_VID, TESTO_USB_INTERFACE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_GAMMA_SCOUT_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13M_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 77299996f7e..f0edb87d2dd 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -111,6 +111,7 @@ #define SEALEVEL_2102_PID 0x2102 /* SeaLINK+485 (2102) */ #define SEALEVEL_2103_PID 0x2103 /* SeaLINK+232I (2103) */ #define SEALEVEL_2104_PID 0x2104 /* SeaLINK+485I (2104) */ +#define SEALEVEL_2106_PID 0x9020 /* SeaLINK+422 (2106) */ #define SEALEVEL_2201_1_PID 0x2211 /* SeaPORT+2/232 (2201) Port 1 */ #define SEALEVEL_2201_2_PID 0x2221 /* SeaPORT+2/232 (2201) Port 2 */ #define SEALEVEL_2202_1_PID 0x2212 /* SeaPORT+2/485 (2202) Port 1 */ @@ -472,6 +473,15 @@ */ #define FTDI_GAMMA_SCOUT_PID 0xD678 /* Gamma Scout online */ +/* + * Tactrix OpenPort (ECU) devices. + * OpenPort 1.3M submitted by Donour Sizemore. + * OpenPort 1.3S and 1.3U submitted by Ian Abbott. + */ +#define FTDI_TACTRIX_OPENPORT_13M_PID 0xCC48 /* OpenPort 1.3 Mitsubishi */ +#define FTDI_TACTRIX_OPENPORT_13S_PID 0xCC49 /* OpenPort 1.3 Subaru */ +#define FTDI_TACTRIX_OPENPORT_13U_PID 0xCC4A /* OpenPort 1.3 Universal */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 17271355639..21cbaa0fb96 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -175,14 +175,14 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char * /* only do something if we have a bulk out endpoint */ if (serial->num_bulk_out) { - spin_lock(&port->lock); + spin_lock_bh(&port->lock); if (port->write_urb_busy) { - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); dbg("%s - already writing", __FUNCTION__); return 0; } port->write_urb_busy = 1; - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); count = (count > port->bulk_out_size) ? port->bulk_out_size : count; diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index bfc6998cd16..cbc725a6c58 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -479,6 +479,7 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */ { USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */ { USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */ + { USB_DEVICE(0x0BB4, 0x0BCE) }, /* "High Tech Computer Corp" */ { USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */ { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */ { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */ diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 87306cb6f9f..812bc213a96 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -394,14 +394,14 @@ static int ipw_write(struct usb_serial_port *port, const unsigned char *buf, int return 0; } - spin_lock(&port->lock); + spin_lock_bh(&port->lock); if (port->write_urb_busy) { - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); dbg("%s - already writing", __FUNCTION__); return 0; } port->write_urb_busy = 1; - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); count = min(count, port->bulk_out_size); memcpy(port->bulk_out_buffer, buf, count); diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 1738b0b6a37..1b348df388e 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -342,14 +342,14 @@ static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int if (count == 0) return 0; - spin_lock(&port->lock); + spin_lock_bh(&port->lock); if (port->write_urb_busy) { - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); dbg("%s - already writing", __FUNCTION__); return 0; } port->write_urb_busy = 1; - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); transfer_buffer = port->write_urb->transfer_buffer; transfer_size = min(count, port->bulk_out_size - 1); diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 49b8dc039d1..59e777f1e8f 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -518,13 +518,13 @@ static int keyspan_pda_write(struct usb_serial_port *port, the TX urb is in-flight (wait until it completes) the device is full (wait until it says there is room) */ - spin_lock(&port->lock); + spin_lock_bh(&port->lock); if (port->write_urb_busy || priv->tx_throttled) { - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); return 0; } port->write_urb_busy = 1; - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); /* At this point the URB is in our control, nobody else can submit it again (the only sudden transition was the one from EINPROGRESS to diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index e49f40913c2..a764ff4e326 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -256,14 +256,14 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf return (0); } - spin_lock(&wport->lock); + spin_lock_bh(&wport->lock); if (wport->write_urb_busy) { - spin_unlock(&wport->lock); + spin_unlock_bh(&wport->lock); dbg("%s - already writing", __FUNCTION__); return 0; } wport->write_urb_busy = 1; - spin_unlock(&wport->lock); + spin_unlock_bh(&wport->lock); count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 1036d436ed2..9c18173e33f 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -82,6 +82,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, + { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 762cc290ef5..65a5039665e 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -93,3 +93,7 @@ /* Alcor Micro Corp. USB 2.0 TO RS-232 */ #define ALCOR_VENDOR_ID 0x058F #define ALCOR_PRODUCT_ID 0x9720 + +/* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */ +#define HUAWEI_VENDOR_ID 0x12d1 +#define HUAWEI_PRODUCT_ID 0x1001 diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 789771ecdb1..1e07dfad685 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -298,14 +298,14 @@ static int safe_write (struct usb_serial_port *port, const unsigned char *buf, i dbg ("%s - write request of 0 bytes", __FUNCTION__); return (0); } - spin_lock(&port->lock); + spin_lock_bh(&port->lock); if (port->write_urb_busy) { - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); dbg("%s - already writing", __FUNCTION__); return 0; } port->write_urb_busy = 1; - spin_unlock(&port->lock); + spin_unlock_bh(&port->lock); packet_length = port->bulk_out_size; // get max packetsize diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 40bf159f7d5..c9a8d50106d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -152,6 +152,13 @@ UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), +/* Reported by Jon Hart <Jon.Hart@web.de> */ +UNUSUAL_DEV( 0x0421, 0x0434, 0x0100, 0x0100, + "Nokia", + "E60", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ), + /* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and * Einar Th. Einarsson <einarthered@gmail.com> */ UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100, @@ -1277,6 +1284,13 @@ UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Jan Mate <mate@fiit.stuba.sk> */ +UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, + "Sony Ericsson", + "P990i", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> * Tested on hardware version 1.10. * Entry is needed only for the initializer function override. diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index caf1eca199b..628571c63ba 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -33,19 +33,19 @@ static unsigned long locomolcd_flags; static void locomolcd_on(int comadj) { - locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 0); - locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 1); + locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0); + locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1); mdelay(2); - locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 0); - locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 1); + locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0); + locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1); mdelay(2); locomo_m62332_senddata(locomolcd_dev, comadj, 0); mdelay(5); - locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 0); - locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 1); + locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0); + locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1); mdelay(10); /* TFTCRST | CPSOUT=0 | CPSEN */ @@ -58,8 +58,8 @@ static void locomolcd_on(int comadj) locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC); mdelay(10); - locomo_gpio_set_dir(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 0); - locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 1); + locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0); + locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1); } static void locomolcd_off(int comadj) @@ -68,16 +68,16 @@ static void locomolcd_off(int comadj) locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC); mdelay(1); - locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHA_ON, 0); + locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0); mdelay(110); - locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VEE_ON, 0); + locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0); mdelay(700); /* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */ locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC); - locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_MOD, 0); - locomo_gpio_write(locomolcd_dev, LOCOMO_GPIO_LCD_VSHD_ON, 0); + locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0); + locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0); } void locomolcd_power(int on) @@ -167,14 +167,14 @@ static int locomolcd_resume(struct locomo_dev *dev) #define locomolcd_resume NULL #endif -static int locomolcd_probe(struct locomo_dev *dev) +static int locomolcd_probe(struct locomo_dev *ldev) { unsigned long flags; local_irq_save(flags); - locomolcd_dev = dev; + locomolcd_dev = ldev; - locomo_gpio_set_dir(dev, LOCOMO_GPIO_FL_VR, 0); + locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0); /* the poodle_lcd_power function is called for the first time * from fs_initcall, which is before locomo is activated. diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200.h b/include/asm-arm/arch-at91rm9200/at91rm9200.h index 58f40931a5c..a5a86b1ff88 100644 --- a/include/asm-arm/arch-at91rm9200/at91rm9200.h +++ b/include/asm-arm/arch-at91rm9200/at91rm9200.h @@ -19,67 +19,80 @@ /* * Peripheral identifiers/interrupts. */ -#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ -#define AT91_ID_SYS 1 /* System Peripheral */ -#define AT91_ID_PIOA 2 /* Parallel IO Controller A */ -#define AT91_ID_PIOB 3 /* Parallel IO Controller B */ -#define AT91_ID_PIOC 4 /* Parallel IO Controller C */ -#define AT91_ID_PIOD 5 /* Parallel IO Controller D */ -#define AT91_ID_US0 6 /* USART 0 */ -#define AT91_ID_US1 7 /* USART 1 */ -#define AT91_ID_US2 8 /* USART 2 */ -#define AT91_ID_US3 9 /* USART 3 */ -#define AT91_ID_MCI 10 /* Multimedia Card Interface */ -#define AT91_ID_UDP 11 /* USB Device Port */ -#define AT91_ID_TWI 12 /* Two-Wire Interface */ -#define AT91_ID_SPI 13 /* Serial Peripheral Interface */ -#define AT91_ID_SSC0 14 /* Serial Synchronous Controller 0 */ -#define AT91_ID_SSC1 15 /* Serial Synchronous Controller 1 */ -#define AT91_ID_SSC2 16 /* Serial Synchronous Controller 2 */ -#define AT91_ID_TC0 17 /* Timer Counter 0 */ -#define AT91_ID_TC1 18 /* Timer Counter 1 */ -#define AT91_ID_TC2 19 /* Timer Counter 2 */ -#define AT91_ID_TC3 20 /* Timer Counter 3 */ -#define AT91_ID_TC4 21 /* Timer Counter 4 */ -#define AT91_ID_TC5 22 /* Timer Counter 5 */ -#define AT91_ID_UHP 23 /* USB Host port */ -#define AT91_ID_EMAC 24 /* Ethernet MAC */ -#define AT91_ID_IRQ0 25 /* Advanced Interrupt Controller (IRQ0) */ -#define AT91_ID_IRQ1 26 /* Advanced Interrupt Controller (IRQ1) */ -#define AT91_ID_IRQ2 27 /* Advanced Interrupt Controller (IRQ2) */ -#define AT91_ID_IRQ3 28 /* Advanced Interrupt Controller (IRQ3) */ -#define AT91_ID_IRQ4 29 /* Advanced Interrupt Controller (IRQ4) */ -#define AT91_ID_IRQ5 30 /* Advanced Interrupt Controller (IRQ5) */ -#define AT91_ID_IRQ6 31 /* Advanced Interrupt Controller (IRQ6) */ +#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ +#define AT91_ID_SYS 1 /* System Peripheral */ +#define AT91RM9200_ID_PIOA 2 /* Parallel IO Controller A */ +#define AT91RM9200_ID_PIOB 3 /* Parallel IO Controller B */ +#define AT91RM9200_ID_PIOC 4 /* Parallel IO Controller C */ +#define AT91RM9200_ID_PIOD 5 /* Parallel IO Controller D */ +#define AT91RM9200_ID_US0 6 /* USART 0 */ +#define AT91RM9200_ID_US1 7 /* USART 1 */ +#define AT91RM9200_ID_US2 8 /* USART 2 */ +#define AT91RM9200_ID_US3 9 /* USART 3 */ +#define AT91RM9200_ID_MCI 10 /* Multimedia Card Interface */ +#define AT91RM9200_ID_UDP 11 /* USB Device Port */ +#define AT91RM9200_ID_TWI 12 /* Two-Wire Interface */ +#define AT91RM9200_ID_SPI 13 /* Serial Peripheral Interface */ +#define AT91RM9200_ID_SSC0 14 /* Serial Synchronous Controller 0 */ +#define AT91RM9200_ID_SSC1 15 /* Serial Synchronous Controller 1 */ +#define AT91RM9200_ID_SSC2 16 /* Serial Synchronous Controller 2 */ +#define AT91RM9200_ID_TC0 17 /* Timer Counter 0 */ +#define AT91RM9200_ID_TC1 18 /* Timer Counter 1 */ +#define AT91RM9200_ID_TC2 19 /* Timer Counter 2 */ +#define AT91RM9200_ID_TC3 20 /* Timer Counter 3 */ +#define AT91RM9200_ID_TC4 21 /* Timer Counter 4 */ +#define AT91RM9200_ID_TC5 22 /* Timer Counter 5 */ +#define AT91RM9200_ID_UHP 23 /* USB Host port */ +#define AT91RM9200_ID_EMAC 24 /* Ethernet MAC */ +#define AT91RM9200_ID_IRQ0 25 /* Advanced Interrupt Controller (IRQ0) */ +#define AT91RM9200_ID_IRQ1 26 /* Advanced Interrupt Controller (IRQ1) */ +#define AT91RM9200_ID_IRQ2 27 /* Advanced Interrupt Controller (IRQ2) */ +#define AT91RM9200_ID_IRQ3 28 /* Advanced Interrupt Controller (IRQ3) */ +#define AT91RM9200_ID_IRQ4 29 /* Advanced Interrupt Controller (IRQ4) */ +#define AT91RM9200_ID_IRQ5 30 /* Advanced Interrupt Controller (IRQ5) */ +#define AT91RM9200_ID_IRQ6 31 /* Advanced Interrupt Controller (IRQ6) */ /* * Peripheral physical base addresses. */ -#define AT91_BASE_TCB0 0xfffa0000 -#define AT91_BASE_TC0 0xfffa0000 -#define AT91_BASE_TC1 0xfffa0040 -#define AT91_BASE_TC2 0xfffa0080 -#define AT91_BASE_TCB1 0xfffa4000 -#define AT91_BASE_TC3 0xfffa4000 -#define AT91_BASE_TC4 0xfffa4040 -#define AT91_BASE_TC5 0xfffa4080 -#define AT91_BASE_UDP 0xfffb0000 -#define AT91_BASE_MCI 0xfffb4000 -#define AT91_BASE_TWI 0xfffb8000 -#define AT91_BASE_EMAC 0xfffbc000 -#define AT91_BASE_US0 0xfffc0000 -#define AT91_BASE_US1 0xfffc4000 -#define AT91_BASE_US2 0xfffc8000 -#define AT91_BASE_US3 0xfffcc000 -#define AT91_BASE_SSC0 0xfffd0000 -#define AT91_BASE_SSC1 0xfffd4000 -#define AT91_BASE_SSC2 0xfffd8000 -#define AT91_BASE_SPI 0xfffe0000 +#define AT91RM9200_BASE_TCB0 0xfffa0000 +#define AT91RM9200_BASE_TC0 0xfffa0000 +#define AT91RM9200_BASE_TC1 0xfffa0040 +#define AT91RM9200_BASE_TC2 0xfffa0080 +#define AT91RM9200_BASE_TCB1 0xfffa4000 +#define AT91RM9200_BASE_TC3 0xfffa4000 +#define AT91RM9200_BASE_TC4 0xfffa4040 +#define AT91RM9200_BASE_TC5 0xfffa4080 +#define AT91RM9200_BASE_UDP 0xfffb0000 +#define AT91RM9200_BASE_MCI 0xfffb4000 +#define AT91RM9200_BASE_TWI 0xfffb8000 +#define AT91RM9200_BASE_EMAC 0xfffbc000 +#define AT91RM9200_BASE_US0 0xfffc0000 +#define AT91RM9200_BASE_US1 0xfffc4000 +#define AT91RM9200_BASE_US2 0xfffc8000 +#define AT91RM9200_BASE_US3 0xfffcc000 +#define AT91RM9200_BASE_SSC0 0xfffd0000 +#define AT91RM9200_BASE_SSC1 0xfffd4000 +#define AT91RM9200_BASE_SSC2 0xfffd8000 +#define AT91RM9200_BASE_SPI 0xfffe0000 #define AT91_BASE_SYS 0xfffff000 /* + * Internal Memory. + */ +#define AT91RM9200_ROM_BASE 0x00100000 /* Internal ROM base address */ +#define AT91RM9200_ROM_SIZE SZ_128K /* Internal ROM size (128Kb) */ + +#define AT91RM9200_SRAM_BASE 0x00200000 /* Internal SRAM base address */ +#define AT91RM9200_SRAM_SIZE SZ_16K /* Internal SRAM size (16Kb) */ + +#define AT91RM9200_UHP_BASE 0x00300000 /* USB Host controller */ + + +#if 0 +/* * PIO pin definitions (peripheral A/B multiplexing). */ #define AT91_PA0_MISO (1 << 0) /* A: SPI Master-In Slave-Out */ @@ -257,5 +270,6 @@ #define AT91_PD25_TPK13 (1 << 25) /* B: ETM Trace Packet Port 13 */ #define AT91_PD26_TPK14 (1 << 26) /* B: ETM Trace Packet Port 14 */ #define AT91_PD27_TPK15 (1 << 27) /* B: ETM Trace Packet Port 15 */ +#endif #endif diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_sys.h b/include/asm-arm/arch-at91rm9200/at91rm9200_sys.h index 0f4c12d5f0c..73693fea76a 100644 --- a/include/asm-arm/arch-at91rm9200/at91rm9200_sys.h +++ b/include/asm-arm/arch-at91rm9200/at91rm9200_sys.h @@ -80,6 +80,9 @@ #define AT91_CIDR_NVPTYP (7 << 28) /* Nonvolatile Program Memory Type */ #define AT91_CIDR_EXT (1 << 31) /* Extension Flag */ +#define AT91_AIC_FFER (AT91_AIC + 0x140) /* Fast Forcing Enable Register [SAM9 only] */ +#define AT91_AIC_FFDR (AT91_AIC + 0x144) /* Fast Forcing Disable Register [SAM9 only] */ +#define AT91_AIC_FFSR (AT91_AIC + 0x148) /* Fast Forcing Status Register [SAM9 only] */ /* * PIO Controllers. diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_twi.h b/include/asm-arm/arch-at91rm9200/at91rm9200_twi.h new file mode 100644 index 00000000000..93547d7482b --- /dev/null +++ b/include/asm-arm/arch-at91rm9200/at91rm9200_twi.h @@ -0,0 +1,57 @@ +/* + * include/asm-arm/arch-at91rm9200/at91rm9200_twi.h + * + * Copyright (C) 2005 Ivan Kokshaysky + * Copyright (C) SAN People + * + * Two-wire Interface (TWI) registers. + * Based on AT91RM9200 datasheet revision E. + * + * 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. + */ + +#ifndef AT91RM9200_TWI_H +#define AT91RM9200_TWI_H + +#define AT91_TWI_CR 0x00 /* Control Register */ +#define AT91_TWI_START (1 << 0) /* Send a Start Condition */ +#define AT91_TWI_STOP (1 << 1) /* Send a Stop Condition */ +#define AT91_TWI_MSEN (1 << 2) /* Master Transfer Enable */ +#define AT91_TWI_MSDIS (1 << 3) /* Master Transfer Disable */ +#define AT91_TWI_SWRST (1 << 7) /* Software Reset */ + +#define AT91_TWI_MMR 0x04 /* Master Mode Register */ +#define AT91_TWI_IADRSZ (3 << 8) /* Internal Device Address Size */ +#define AT91_TWI_IADRSZ_NO (0 << 8) +#define AT91_TWI_IADRSZ_1 (1 << 8) +#define AT91_TWI_IADRSZ_2 (2 << 8) +#define AT91_TWI_IADRSZ_3 (3 << 8) +#define AT91_TWI_MREAD (1 << 12) /* Master Read Direction */ +#define AT91_TWI_DADR (0x7f << 16) /* Device Address */ + +#define AT91_TWI_IADR 0x0c /* Internal Address Register */ + +#define AT91_TWI_CWGR 0x10 /* Clock Waveform Generator Register */ +#define AT91_TWI_CLDIV (0xff << 0) /* Clock Low Divisor */ +#define AT91_TWI_CHDIV (0xff << 8) /* Clock High Divisor */ +#define AT91_TWI_CKDIV (7 << 16) /* Clock Divider */ + +#define AT91_TWI_SR 0x20 /* Status Register */ +#define AT91_TWI_TXCOMP (1 << 0) /* Transmission Complete */ +#define AT91_TWI_RXRDY (1 << 1) /* Receive Holding Register Ready */ +#define AT91_TWI_TXRDY (1 << 2) /* Transmit Holding Register Ready */ +#define AT91_TWI_OVRE (1 << 6) /* Overrun Error */ +#define AT91_TWI_UNRE (1 << 7) /* Underrun Error */ +#define AT91_TWI_NACK (1 << 8) /* Not Acknowledged */ + +#define AT91_TWI_IER 0x24 /* Interrupt Enable Register */ +#define AT91_TWI_IDR 0x28 /* Interrupt Disable Register */ +#define AT91_TWI_IMR 0x2c /* Interrupt Mask Register */ +#define AT91_TWI_RHR 0x30 /* Receive Holding Register */ +#define AT91_TWI_THR 0x34 /* Transmit Holding Register */ + +#endif + diff --git a/include/asm-arm/arch-at91rm9200/gpio.h b/include/asm-arm/arch-at91rm9200/gpio.h index dbde1baaf25..a011d27876a 100644 --- a/include/asm-arm/arch-at91rm9200/gpio.h +++ b/include/asm-arm/arch-at91rm9200/gpio.h @@ -17,10 +17,9 @@ #define PIN_BASE NR_AIC_IRQS -#define PQFP_GPIO_BANKS 3 /* PQFP package has 3 banks */ -#define BGA_GPIO_BANKS 4 /* BGA package has 4 banks */ +#define MAX_GPIO_BANKS 4 -/* these pin numbers double as IRQ numbers, like AT91_ID_* values */ +/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ #define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) #define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) @@ -180,17 +179,18 @@ #ifndef __ASSEMBLY__ /* setup setup routines, called from board init or driver probe() */ -extern int at91_set_A_periph(unsigned pin, int use_pullup); -extern int at91_set_B_periph(unsigned pin, int use_pullup); -extern int at91_set_gpio_input(unsigned pin, int use_pullup); -extern int at91_set_gpio_output(unsigned pin, int value); -extern int at91_set_deglitch(unsigned pin, int is_on); -extern int at91_set_multi_drive(unsigned pin, int is_on); +extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); +extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); +extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); +extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); /* callable at any time */ extern int at91_set_gpio_value(unsigned pin, int value); extern int at91_get_gpio_value(unsigned pin); +/* callable only from core power-management code */ extern void at91_gpio_suspend(void); extern void at91_gpio_resume(void); #endif diff --git a/include/asm-arm/arch-at91rm9200/hardware.h b/include/asm-arm/arch-at91rm9200/hardware.h index 235d39d9110..6551b4d1ff7 100644 --- a/include/asm-arm/arch-at91rm9200/hardware.h +++ b/include/asm-arm/arch-at91rm9200/hardware.h @@ -34,27 +34,14 @@ * Virtual to Physical Address mapping for IO devices. */ #define AT91_VA_BASE_SYS AT91_IO_P2V(AT91_BASE_SYS) -#define AT91_VA_BASE_SPI AT91_IO_P2V(AT91_BASE_SPI) -#define AT91_VA_BASE_SSC2 AT91_IO_P2V(AT91_BASE_SSC2) -#define AT91_VA_BASE_SSC1 AT91_IO_P2V(AT91_BASE_SSC1) -#define AT91_VA_BASE_SSC0 AT91_IO_P2V(AT91_BASE_SSC0) -#define AT91_VA_BASE_US3 AT91_IO_P2V(AT91_BASE_US3) -#define AT91_VA_BASE_US2 AT91_IO_P2V(AT91_BASE_US2) -#define AT91_VA_BASE_US1 AT91_IO_P2V(AT91_BASE_US1) -#define AT91_VA_BASE_US0 AT91_IO_P2V(AT91_BASE_US0) -#define AT91_VA_BASE_EMAC AT91_IO_P2V(AT91_BASE_EMAC) -#define AT91_VA_BASE_TWI AT91_IO_P2V(AT91_BASE_TWI) -#define AT91_VA_BASE_MCI AT91_IO_P2V(AT91_BASE_MCI) -#define AT91_VA_BASE_UDP AT91_IO_P2V(AT91_BASE_UDP) -#define AT91_VA_BASE_TCB1 AT91_IO_P2V(AT91_BASE_TCB1) -#define AT91_VA_BASE_TCB0 AT91_IO_P2V(AT91_BASE_TCB0) - -/* Internal SRAM */ -#define AT91_SRAM_BASE 0x00200000 /* Internal SRAM base address */ -#define AT91_SRAM_SIZE 0x00004000 /* Internal SRAM SIZE (16Kb) */ +#define AT91_VA_BASE_SPI AT91_IO_P2V(AT91RM9200_BASE_SPI) +#define AT91_VA_BASE_EMAC AT91_IO_P2V(AT91RM9200_BASE_EMAC) +#define AT91_VA_BASE_TWI AT91_IO_P2V(AT91RM9200_BASE_TWI) +#define AT91_VA_BASE_MCI AT91_IO_P2V(AT91RM9200_BASE_MCI) +#define AT91_VA_BASE_UDP AT91_IO_P2V(AT91RM9200_BASE_UDP) /* Internal SRAM is mapped below the IO devices */ -#define AT91_SRAM_VIRT_BASE (AT91_IO_VIRT_BASE - AT91_SRAM_SIZE) +#define AT91_SRAM_VIRT_BASE (AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE) /* Serial ports */ #define AT91_NR_UART 5 /* 4 USART3's and one DBGU port */ @@ -71,9 +58,6 @@ /* Compact Flash */ #define AT91_CF_BASE 0x50000000 /* NCS4-NCS6: Compact Flash physical base address */ -/* Multi-Master Memory controller */ -#define AT91_UHP_BASE 0x00300000 /* USB Host controller */ - /* Clocks */ #define AT91_SLOW_CLOCK 32768 /* slow clock */ diff --git a/include/asm-arm/arch-at91rm9200/irqs.h b/include/asm-arm/arch-at91rm9200/irqs.h index f63842c2c09..763cb96c418 100644 --- a/include/asm-arm/arch-at91rm9200/irqs.h +++ b/include/asm-arm/arch-at91rm9200/irqs.h @@ -32,7 +32,7 @@ /* - * IRQ interrupt symbols are the AT91_ID_* symbols in at91rm9200.h + * IRQ interrupt symbols are the AT91xxx_ID_* symbols * for IRQs handled directly through the AIC, or else the AT91_PIN_* * symbols in gpio.h for ones handled indirectly as GPIOs. * We make provision for 4 banks of GPIO. diff --git a/include/asm-arm/arch-iop32x/debug-macro.S b/include/asm-arm/arch-iop32x/debug-macro.S new file mode 100644 index 00000000000..9022b6849e2 --- /dev/null +++ b/include/asm-arm/arch-iop32x/debug-macro.S @@ -0,0 +1,20 @@ +/* + * include/asm-arm/arch-iop32x/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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 + mov \rx, #0xfe000000 @ physical as well as virtual + orr \rx, \rx, #0x00800000 @ location of the UART + .endm + +#define UART_SHIFT 0 +#include <asm/hardware/debug-8250.S> diff --git a/include/asm-arm/arch-iop3xx/dma.h b/include/asm-arm/arch-iop32x/dma.h index 1e808db8af2..e977a9ef316 100644 --- a/include/asm-arm/arch-iop3xx/dma.h +++ b/include/asm-arm/arch-iop32x/dma.h @@ -1,7 +1,7 @@ /* - * linux/include/asm-arm/arch-iop3xx/dma.h + * include/asm-arm/arch-iop32x/dma.h * - * Copyright (C) 2004 Intel Corp. + * Copyright (C) 2004 Intel Corp. * * 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/include/asm-arm/arch-iop32x/entry-macro.S b/include/asm-arm/arch-iop32x/entry-macro.S new file mode 100644 index 00000000000..1500cbbd229 --- /dev/null +++ b/include/asm-arm/arch-iop32x/entry-macro.S @@ -0,0 +1,21 @@ +/* + * include/asm-arm/arch-iop32x/entry-macro.S + * + * Low-level IRQ helper macros for IOP32x-based platforms + * + * 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 <asm/arch/iop32x.h> + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \base, =IOP3XX_REG_ADDR(0x07D8) + ldr \irqstat, [\base] @ Read IINTSRC + cmp \irqstat, #0 + clzne \irqnr, \irqstat + rsbne \irqnr, \irqnr, #31 + .endm diff --git a/include/asm-arm/arch-iop32x/glantank.h b/include/asm-arm/arch-iop32x/glantank.h new file mode 100644 index 00000000000..3b065618dd0 --- /dev/null +++ b/include/asm-arm/arch-iop32x/glantank.h @@ -0,0 +1,13 @@ +/* + * include/asm/arch-iop32x/glantank.h + * + * IO-Data GLAN Tank board registers + */ + +#ifndef __GLANTANK_H +#define __GLANTANK_H + +#define GLANTANK_UART 0xfe800000 /* UART */ + + +#endif diff --git a/include/asm-arm/arch-iop32x/hardware.h b/include/asm-arm/arch-iop32x/hardware.h new file mode 100644 index 00000000000..6556ed5eee3 --- /dev/null +++ b/include/asm-arm/arch-iop32x/hardware.h @@ -0,0 +1,44 @@ +/* + * include/asm-arm/arch-iop32x/hardware.h + */ + +#ifndef __HARDWARE_H +#define __HARDWARE_H + +#include <asm/types.h> + +/* + * Note about PCI IO space mappings + * + * To make IO space accesses efficient, we store virtual addresses in + * the IO resources. + * + * The PCI IO space is located at virtual 0xfe000000 from physical + * 0x90000000. The PCI BARs must be programmed with physical addresses, + * but when we read them, we convert them to virtual addresses. See + * arch/arm/plat-iop/pci.c. + */ +#define pcibios_assign_all_busses() 1 +#define PCIBIOS_MIN_IO 0x00000000 +#define PCIBIOS_MIN_MEM 0x00000000 + +#ifndef __ASSEMBLY__ +void iop32x_init_irq(void); +#endif + + +/* + * Generic chipset bits + */ +#include "iop32x.h" + +/* + * Board specific bits + */ +#include "glantank.h" +#include "iq80321.h" +#include "iq31244.h" +#include "n2100.h" + + +#endif diff --git a/include/asm-arm/arch-iop3xx/io.h b/include/asm-arm/arch-iop32x/io.h index 36adbdf5055..12d9ee02cde 100644 --- a/include/asm-arm/arch-iop3xx/io.h +++ b/include/asm-arm/arch-iop32x/io.h @@ -1,21 +1,22 @@ /* - * linux/include/asm-arm/arch-iop3xx/io.h + * include/asm-arm/arch-iop32x/io.h * - * Copyright (C) 2001 MontaVista Software, Inc. + * Copyright (C) 2001 MontaVista Software, 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. */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H +#ifndef __IO_H +#define __IO_H #include <asm/hardware.h> -#define IO_SPACE_LIMIT 0xffffffff +#define IO_SPACE_LIMIT 0xffffffff #define __io(p) ((void __iomem *)(p)) #define __mem_pci(a) (a) + #endif diff --git a/include/asm-arm/arch-iop32x/iop32x.h b/include/asm-arm/arch-iop32x/iop32x.h new file mode 100644 index 00000000000..4bbd85f3ed2 --- /dev/null +++ b/include/asm-arm/arch-iop32x/iop32x.h @@ -0,0 +1,28 @@ +/* + * include/asm-arm/arch-iop32x/iop32x.h + * + * Intel IOP32X Chip definitions + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * 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 __IOP32X_H +#define __IOP32X_H + +/* + * Peripherals that are shared between the iop32x and iop33x but + * located at different addresses. + */ +#define IOP3XX_GPIO_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c0 + (reg)) +#define IOP3XX_TIMER_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg)) + +#include <asm/hardware/iop3xx.h> + + +#endif diff --git a/include/asm-arm/arch-iop3xx/iq31244.h b/include/asm-arm/arch-iop32x/iq31244.h index 4177cfa8100..fff4eafa1f6 100644 --- a/include/asm-arm/arch-iop3xx/iq31244.h +++ b/include/asm-arm/arch-iop32x/iq31244.h @@ -1,15 +1,11 @@ /* - * linux/include/asm/arch-iop3xx/iq31244.h + * include/asm-arm/arch-iop32x/iq31244.h * * Intel IQ31244 evaluation board registers */ -#ifndef _IQ31244_H_ -#define _IQ31244_H_ - -#define IQ31244_FLASHBASE 0xf0000000 /* Flash */ -#define IQ31244_FLASHSIZE 0x00800000 -#define IQ31244_FLASHWIDTH 2 +#ifndef __IQ31244_H +#define __IQ31244_H #define IQ31244_UART 0xfe800000 /* UART #1 */ #define IQ31244_7SEG_1 0xfe840000 /* 7-Segment MSB */ @@ -17,8 +13,5 @@ #define IQ31244_ROTARY_SW 0xfe8d0000 /* Rotary Switch */ #define IQ31244_BATT_STAT 0xfe8f0000 /* Battery Status */ -#ifndef __ASSEMBLY__ -extern void iq31244_map_io(void); -#endif -#endif // _IQ31244_H_ +#endif diff --git a/include/asm-arm/arch-iop3xx/iq80321.h b/include/asm-arm/arch-iop32x/iq80321.h index cb8725979ff..eb69db9b9a0 100644 --- a/include/asm-arm/arch-iop3xx/iq80321.h +++ b/include/asm-arm/arch-iop32x/iq80321.h @@ -1,15 +1,11 @@ /* - * linux/include/asm/arch-iop3xx/iq80321.h + * include/asm-arm/arch-iop32x/iq80321.h * * Intel IQ80321 evaluation board registers */ -#ifndef _IQ80321_H_ -#define _IQ80321_H_ - -#define IQ80321_FLASHBASE 0xf0000000 /* Flash */ -#define IQ80321_FLASHSIZE 0x00800000 -#define IQ80321_FLASHWIDTH 1 +#ifndef __IQ80321_H +#define __IQ80321_H #define IQ80321_UART 0xfe800000 /* UART #1 */ #define IQ80321_7SEG_1 0xfe840000 /* 7-Segment MSB */ @@ -17,8 +13,5 @@ #define IQ80321_ROTARY_SW 0xfe8d0000 /* Rotary Switch */ #define IQ80321_BATT_STAT 0xfe8f0000 /* Battery Status */ -#ifndef __ASSEMBLY__ -extern void iq80321_map_io(void); -#endif -#endif // _IQ80321_H_ +#endif diff --git a/include/asm-arm/arch-iop32x/irqs.h b/include/asm-arm/arch-iop32x/irqs.h new file mode 100644 index 00000000000..bbaef873afc --- /dev/null +++ b/include/asm-arm/arch-iop32x/irqs.h @@ -0,0 +1,50 @@ +/* + * include/asm-arm/arch-iop32x/irqs.h + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright: (C) 2002 Rory Bolt + * + * 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 __IRQS_H +#define __IRQS_H + +/* + * IOP80321 chipset interrupts + */ +#define IRQ_IOP32X_DMA0_EOT 0 +#define IRQ_IOP32X_DMA0_EOC 1 +#define IRQ_IOP32X_DMA1_EOT 2 +#define IRQ_IOP32X_DMA1_EOC 3 +#define IRQ_IOP32X_AA_EOT 6 +#define IRQ_IOP32X_AA_EOC 7 +#define IRQ_IOP32X_CORE_PMON 8 +#define IRQ_IOP32X_TIMER0 9 +#define IRQ_IOP32X_TIMER1 10 +#define IRQ_IOP32X_I2C_0 11 +#define IRQ_IOP32X_I2C_1 12 +#define IRQ_IOP32X_MESSAGING 13 +#define IRQ_IOP32X_ATU_BIST 14 +#define IRQ_IOP32X_PERFMON 15 +#define IRQ_IOP32X_CORE_PMU 16 +#define IRQ_IOP32X_BIU_ERR 17 +#define IRQ_IOP32X_ATU_ERR 18 +#define IRQ_IOP32X_MCU_ERR 19 +#define IRQ_IOP32X_DMA0_ERR 20 +#define IRQ_IOP32X_DMA1_ERR 21 +#define IRQ_IOP32X_AA_ERR 23 +#define IRQ_IOP32X_MSG_ERR 24 +#define IRQ_IOP32X_SSP 25 +#define IRQ_IOP32X_XINT0 27 +#define IRQ_IOP32X_XINT1 28 +#define IRQ_IOP32X_XINT2 29 +#define IRQ_IOP32X_XINT3 30 +#define IRQ_IOP32X_HPI 31 + +#define NR_IRQS 32 + + +#endif diff --git a/include/asm-arm/arch-iop32x/memory.h b/include/asm-arm/arch-iop32x/memory.h new file mode 100644 index 00000000000..764cd3f0d41 --- /dev/null +++ b/include/asm-arm/arch-iop32x/memory.h @@ -0,0 +1,26 @@ +/* + * include/asm-arm/arch-iop32x/memory.h + */ + +#ifndef __MEMORY_H +#define __MEMORY_H + +#include <asm/hardware.h> + +/* + * Physical DRAM offset. + */ +#define PHYS_OFFSET UL(0xa0000000) + +/* + * Virtual view <-> PCI DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP3XX_IATVR2)) | ((*IOP3XX_IABAR2) & 0xfffffff0)) +#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP3XX_IALR2)) | ( *IOP3XX_IATVR2))) + + +#endif diff --git a/include/asm-arm/arch-iop32x/n2100.h b/include/asm-arm/arch-iop32x/n2100.h new file mode 100644 index 00000000000..fed31a64842 --- /dev/null +++ b/include/asm-arm/arch-iop32x/n2100.h @@ -0,0 +1,19 @@ +/* + * include/asm/arch-iop32x/n2100.h + * + * Thecus N2100 board registers + */ + +#ifndef __N2100_H +#define __N2100_H + +#define N2100_UART 0xfe800000 /* UART */ + +#define N2100_COPY_BUTTON IOP3XX_GPIO_LINE(0) +#define N2100_PCA9532_RESET IOP3XX_GPIO_LINE(2) +#define N2100_RESET_BUTTON IOP3XX_GPIO_LINE(3) +#define N2100_HARDWARE_RESET IOP3XX_GPIO_LINE(4) +#define N2100_POWER_BUTTON IOP3XX_GPIO_LINE(5) + + +#endif diff --git a/include/asm-arm/arch-iop32x/system.h b/include/asm-arm/arch-iop32x/system.h new file mode 100644 index 00000000000..17b7eb7e9c0 --- /dev/null +++ b/include/asm-arm/arch-iop32x/system.h @@ -0,0 +1,33 @@ +/* + * include/asm-arm/arch-iop32x/system.h + * + * Copyright (C) 2001 MontaVista Software, 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 <asm/mach-types.h> + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode) +{ + local_irq_disable(); + + if (machine_is_n2100()) { + gpio_line_set(N2100_HARDWARE_RESET, GPIO_LOW); + gpio_line_config(N2100_HARDWARE_RESET, GPIO_OUT); + while (1) + ; + } + + *IOP3XX_PCSR = 0x30; + + /* Jump into ROM at address 0 */ + cpu_reset(0); +} diff --git a/include/asm-arm/arch-iop32x/timex.h b/include/asm-arm/arch-iop32x/timex.h new file mode 100644 index 00000000000..9934b087311 --- /dev/null +++ b/include/asm-arm/arch-iop32x/timex.h @@ -0,0 +1,9 @@ +/* + * include/asm-arm/arch-iop32x/timex.h + * + * IOP32x architecture timex specifications + */ + +#include <asm/hardware.h> + +#define CLOCK_TICK_RATE (100 * HZ) diff --git a/include/asm-arm/arch-iop32x/uncompress.h b/include/asm-arm/arch-iop32x/uncompress.h new file mode 100644 index 00000000000..e64f52bf2bc --- /dev/null +++ b/include/asm-arm/arch-iop32x/uncompress.h @@ -0,0 +1,39 @@ +/* + * include/asm-arm/arch-iop32x/uncompress.h + */ + +#include <asm/types.h> +#include <asm/mach-types.h> +#include <linux/serial_reg.h> +#include <asm/hardware.h> + +static volatile u8 *uart_base; + +#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) + +static inline void putc(char c) +{ + while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE) + barrier(); + uart_base[UART_TX] = c; +} + +static inline void flush(void) +{ +} + +static __inline__ void __arch_decomp_setup(unsigned long arch_id) +{ + if (machine_is_iq80321()) + uart_base = (volatile u8 *)IQ80321_UART; + else if (machine_is_iq31244()) + uart_base = (volatile u8 *)IQ31244_UART; + else + uart_base = (volatile u8 *)0xfe800000; +} + +/* + * nothing to do + */ +#define arch_decomp_setup() __arch_decomp_setup(arch_id) +#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-iop32x/vmalloc.h b/include/asm-arm/arch-iop32x/vmalloc.h new file mode 100644 index 00000000000..0a70baa1951 --- /dev/null +++ b/include/asm-arm/arch-iop32x/vmalloc.h @@ -0,0 +1,5 @@ +/* + * include/asm-arm/arch-iop32x/vmalloc.h + */ + +#define VMALLOC_END 0xfe000000 diff --git a/include/asm-arm/arch-iop33x/debug-macro.S b/include/asm-arm/arch-iop33x/debug-macro.S new file mode 100644 index 00000000000..9e7132ebe6a --- /dev/null +++ b/include/asm-arm/arch-iop33x/debug-macro.S @@ -0,0 +1,24 @@ +/* + * include/asm-arm/arch-iop33x/debug-macro.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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 + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ mmu enabled? + moveq \rx, #0xff000000 @ physical + movne \rx, #0xfe000000 @ virtual + orr \rx, \rx, #0x00ff0000 + orr \rx, \rx, #0x0000f700 + .endm + +#define UART_SHIFT 2 +#include <asm/hardware/debug-8250.S> diff --git a/include/asm-arm/arch-iop33x/dma.h b/include/asm-arm/arch-iop33x/dma.h new file mode 100644 index 00000000000..b7775fdc5ad --- /dev/null +++ b/include/asm-arm/arch-iop33x/dma.h @@ -0,0 +1,9 @@ +/* + * include/asm-arm/arch-iop33x/dma.h + * + * Copyright (C) 2004 Intel Corp. + * + * 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. + */ diff --git a/include/asm-arm/arch-iop33x/entry-macro.S b/include/asm-arm/arch-iop33x/entry-macro.S new file mode 100644 index 00000000000..92b791702e3 --- /dev/null +++ b/include/asm-arm/arch-iop33x/entry-macro.S @@ -0,0 +1,22 @@ +/* + * include/asm-arm/arch-iop33x/entry-macro.S + * + * Low-level IRQ helper macros for IOP33x-based platforms + * + * 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 <asm/arch/iop33x.h> + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \base, =IOP3XX_REG_ADDR(0x07C8) + ldr \irqstat, [\base] @ Read IINTVEC + cmp \irqstat, #0 + ldreq \irqstat, [\base] @ erratum 63 workaround + adds \irqnr, \irqstat, #1 + movne \irqnr, \irqstat, lsr #2 + .endm diff --git a/include/asm-arm/arch-iop33x/hardware.h b/include/asm-arm/arch-iop33x/hardware.h new file mode 100644 index 00000000000..0659cf94d04 --- /dev/null +++ b/include/asm-arm/arch-iop33x/hardware.h @@ -0,0 +1,46 @@ +/* + * include/asm-arm/arch-iop33x/hardware.h + */ + +#ifndef __HARDWARE_H +#define __HARDWARE_H + +#include <asm/types.h> + +/* + * Note about PCI IO space mappings + * + * To make IO space accesses efficient, we store virtual addresses in + * the IO resources. + * + * The PCI IO space is located at virtual 0xfe000000 from physical + * 0x90000000. The PCI BARs must be programmed with physical addresses, + * but when we read them, we convert them to virtual addresses. See + * arch/arm/mach-iop3xx/iop3xx-pci.c + */ +#define pcibios_assign_all_busses() 1 +#define PCIBIOS_MIN_IO 0x00000000 +#define PCIBIOS_MIN_MEM 0x00000000 + +#ifndef __ASSEMBLY__ +void iop33x_init_irq(void); + +extern struct platform_device iop33x_uart0_device; +extern struct platform_device iop33x_uart1_device; +#endif + + +/* + * Generic chipset bits + * + */ +#include "iop33x.h" + +/* + * Board specific bits + */ +#include "iq80331.h" +#include "iq80332.h" + + +#endif diff --git a/include/asm-arm/arch-iop33x/io.h b/include/asm-arm/arch-iop33x/io.h new file mode 100644 index 00000000000..c017402bab9 --- /dev/null +++ b/include/asm-arm/arch-iop33x/io.h @@ -0,0 +1,21 @@ +/* + * include/asm-arm/arch-iop33x/io.h + * + * Copyright (C) 2001 MontaVista Software, 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. + */ + +#ifndef __IO_H +#define __IO_H + +#include <asm/hardware.h> + +#define IO_SPACE_LIMIT 0xffffffff +#define __io(p) ((void __iomem *)(p)) +#define __mem_pci(a) (a) + + +#endif diff --git a/include/asm-arm/arch-iop33x/iop33x.h b/include/asm-arm/arch-iop33x/iop33x.h new file mode 100644 index 00000000000..7ac6e93db5f --- /dev/null +++ b/include/asm-arm/arch-iop33x/iop33x.h @@ -0,0 +1,33 @@ +/* + * include/asm-arm/arch-iop33x/iop33x.h + * + * Intel IOP33X Chip definitions + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2003, 2004 Intel Corp. + * + * 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 __IOP33X_H +#define __IOP33X_H + +/* + * Peripherals that are shared between the iop32x and iop33x but + * located at different addresses. + */ +#define IOP3XX_GPIO_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1780 + (reg)) +#define IOP3XX_TIMER_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07d0 + (reg)) + +#include <asm/hardware/iop3xx.h> + +/* UARTs */ +#define IOP33X_UART0_PHYS (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1700) +#define IOP33X_UART0_VIRT (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1700) +#define IOP33X_UART1_PHYS (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1740) +#define IOP33X_UART1_VIRT (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1740) + + +#endif diff --git a/include/asm-arm/arch-iop3xx/iq80331.h b/include/asm-arm/arch-iop33x/iq80331.h index 0668e78d483..79b9302017e 100644 --- a/include/asm-arm/arch-iop3xx/iq80331.h +++ b/include/asm-arm/arch-iop33x/iq80331.h @@ -1,23 +1,16 @@ /* - * linux/include/asm/arch-iop3xx/iq80331.h + * include/asm-arm/arch-iop33x/iq80331.h * * Intel IQ80331 evaluation board registers */ -#ifndef _IQ80331_H_ -#define _IQ80331_H_ - -#define IQ80331_FLASHBASE 0xc0000000 /* Flash */ -#define IQ80331_FLASHSIZE 0x00800000 -#define IQ80331_FLASHWIDTH 1 +#ifndef __IQ80331_H +#define __IQ80331_H #define IQ80331_7SEG_1 0xce840000 /* 7-Segment MSB */ #define IQ80331_7SEG_0 0xce850000 /* 7-Segment LSB (WO) */ #define IQ80331_ROTARY_SW 0xce8d0000 /* Rotary Switch */ #define IQ80331_BATT_STAT 0xce8f0000 /* Battery Status */ -#ifndef __ASSEMBLY__ -extern void iq80331_map_io(void); -#endif -#endif // _IQ80331_H_ +#endif diff --git a/include/asm-arm/arch-iop3xx/iq80332.h b/include/asm-arm/arch-iop33x/iq80332.h index e5fff1775d1..05316562949 100644 --- a/include/asm-arm/arch-iop3xx/iq80332.h +++ b/include/asm-arm/arch-iop33x/iq80332.h @@ -1,23 +1,16 @@ /* - * linux/include/asm/arch-iop3xx/iq80332.h + * include/asm-arm/arch-iop33x/iq80332.h * * Intel IQ80332 evaluation board registers */ -#ifndef _IQ80332_H_ -#define _IQ80332_H_ - -#define IQ80332_FLASHBASE 0xc0000000 /* Flash */ -#define IQ80332_FLASHSIZE 0x00800000 -#define IQ80332_FLASHWIDTH 1 +#ifndef __IQ80332_H +#define __IQ80332_H #define IQ80332_7SEG_1 0xce840000 /* 7-Segment MSB */ #define IQ80332_7SEG_0 0xce850000 /* 7-Segment LSB (WO) */ #define IQ80332_ROTARY_SW 0xce8d0000 /* Rotary Switch */ #define IQ80332_BATT_STAT 0xce8f0000 /* Battery Status */ -#ifndef __ASSEMBLY__ -extern void iq80332_map_io(void); -#endif -#endif // _IQ80332_H_ +#endif diff --git a/include/asm-arm/arch-iop33x/irqs.h b/include/asm-arm/arch-iop33x/irqs.h new file mode 100644 index 00000000000..d045f840339 --- /dev/null +++ b/include/asm-arm/arch-iop33x/irqs.h @@ -0,0 +1,60 @@ +/* + * include/asm-arm/arch-iop33x/irqs.h + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright: (C) 2003 Intel Corp. + * + * 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 __IRQS_H +#define __IRQS_H + +/* + * IOP80331 chipset interrupts + */ +#define IRQ_IOP33X_DMA0_EOT 0 +#define IRQ_IOP33X_DMA0_EOC 1 +#define IRQ_IOP33X_DMA1_EOT 2 +#define IRQ_IOP33X_DMA1_EOC 3 +#define IRQ_IOP33X_AA_EOT 6 +#define IRQ_IOP33X_AA_EOC 7 +#define IRQ_IOP33X_TIMER0 8 +#define IRQ_IOP33X_TIMER1 9 +#define IRQ_IOP33X_I2C_0 10 +#define IRQ_IOP33X_I2C_1 11 +#define IRQ_IOP33X_MSG 12 +#define IRQ_IOP33X_MSGIBQ 13 +#define IRQ_IOP33X_ATU_BIST 14 +#define IRQ_IOP33X_PERFMON 15 +#define IRQ_IOP33X_CORE_PMU 16 +#define IRQ_IOP33X_XINT0 24 +#define IRQ_IOP33X_XINT1 25 +#define IRQ_IOP33X_XINT2 26 +#define IRQ_IOP33X_XINT3 27 +#define IRQ_IOP33X_XINT8 32 +#define IRQ_IOP33X_XINT9 33 +#define IRQ_IOP33X_XINT10 34 +#define IRQ_IOP33X_XINT11 35 +#define IRQ_IOP33X_XINT12 36 +#define IRQ_IOP33X_XINT13 37 +#define IRQ_IOP33X_XINT14 38 +#define IRQ_IOP33X_XINT15 39 +#define IRQ_IOP33X_UART0 51 +#define IRQ_IOP33X_UART1 52 +#define IRQ_IOP33X_PBIE 53 +#define IRQ_IOP33X_ATU_CRW 54 +#define IRQ_IOP33X_ATU_ERR 55 +#define IRQ_IOP33X_MCU_ERR 56 +#define IRQ_IOP33X_DMA0_ERR 57 +#define IRQ_IOP33X_DMA1_ERR 58 +#define IRQ_IOP33X_AA_ERR 60 +#define IRQ_IOP33X_MSG_ERR 62 +#define IRQ_IOP33X_HPI 63 + +#define NR_IRQS 64 + + +#endif diff --git a/include/asm-arm/arch-iop33x/memory.h b/include/asm-arm/arch-iop33x/memory.h new file mode 100644 index 00000000000..0d39139b241 --- /dev/null +++ b/include/asm-arm/arch-iop33x/memory.h @@ -0,0 +1,26 @@ +/* + * include/asm-arm/arch-iop33x/memory.h + */ + +#ifndef __MEMORY_H +#define __MEMORY_H + +#include <asm/hardware.h> + +/* + * Physical DRAM offset. + */ +#define PHYS_OFFSET UL(0x00000000) + +/* + * Virtual view <-> PCI DMA view memory address translations + * virt_to_bus: Used to translate the virtual address to an + * address suitable to be passed to set_dma_addr + * bus_to_virt: Used to convert an address for DMA operations + * to an address that the kernel can use. + */ +#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP3XX_IATVR2)) | ((*IOP3XX_IABAR2) & 0xfffffff0)) +#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP3XX_IALR2)) | ( *IOP3XX_IATVR2))) + + +#endif diff --git a/include/asm-arm/arch-iop33x/system.h b/include/asm-arm/arch-iop33x/system.h new file mode 100644 index 00000000000..00dd07ece26 --- /dev/null +++ b/include/asm-arm/arch-iop33x/system.h @@ -0,0 +1,22 @@ +/* + * include/asm-arm/arch-iop33x/system.h + * + * Copyright (C) 2001 MontaVista Software, 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. + */ + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode) +{ + *IOP3XX_PCSR = 0x30; + + /* Jump into ROM at address 0 */ + cpu_reset(0); +} diff --git a/include/asm-arm/arch-iop33x/timex.h b/include/asm-arm/arch-iop33x/timex.h new file mode 100644 index 00000000000..fe3e1e369ff --- /dev/null +++ b/include/asm-arm/arch-iop33x/timex.h @@ -0,0 +1,9 @@ +/* + * include/asm-arm/arch-iop33x/timex.h + * + * IOP3xx architecture timex specifications + */ + +#include <asm/hardware.h> + +#define CLOCK_TICK_RATE (100 * HZ) diff --git a/include/asm-arm/arch-iop33x/uncompress.h b/include/asm-arm/arch-iop33x/uncompress.h new file mode 100644 index 00000000000..e17fbc05877 --- /dev/null +++ b/include/asm-arm/arch-iop33x/uncompress.h @@ -0,0 +1,37 @@ +/* + * include/asm-arm/arch-iop33x/uncompress.h + */ + +#include <asm/types.h> +#include <asm/mach-types.h> +#include <linux/serial_reg.h> +#include <asm/hardware.h> + +static volatile u32 *uart_base; + +#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) + +static inline void putc(char c) +{ + while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE) + barrier(); + uart_base[UART_TX] = c; +} + +static inline void flush(void) +{ +} + +static __inline__ void __arch_decomp_setup(unsigned long arch_id) +{ + if (machine_is_iq80331() || machine_is_iq80332()) + uart_base = (volatile u32 *)IOP33X_UART0_PHYS; + else + uart_base = (volatile u32 *)0xfe800000; +} + +/* + * nothing to do + */ +#define arch_decomp_setup() __arch_decomp_setup(arch_id) +#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-iop33x/vmalloc.h b/include/asm-arm/arch-iop33x/vmalloc.h new file mode 100644 index 00000000000..66f545a7f4f --- /dev/null +++ b/include/asm-arm/arch-iop33x/vmalloc.h @@ -0,0 +1,5 @@ +/* + * include/asm-arm/arch-iop33x/vmalloc.h + */ + +#define VMALLOC_END 0xfe000000 diff --git a/include/asm-arm/arch-iop3xx/debug-macro.S b/include/asm-arm/arch-iop3xx/debug-macro.S deleted file mode 100644 index ce007e53199..00000000000 --- a/include/asm-arm/arch-iop3xx/debug-macro.S +++ /dev/null @@ -1,35 +0,0 @@ -/* linux/include/asm-arm/arch-iop3xx/debug-macro.S - * - * Debugging macro include header - * - * Copyright (C) 1994-1999 Russell King - * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks - * - * 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 - mov \rx, #0xfe000000 @ physical -#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244) - orr \rx, \rx, #0x00800000 @ location of the UART -#elif defined(CONFIG_ARCH_IOP331) - mrc p15, 0, \rx, c1, c0 - tst \rx, #1 @ MMU enabled? - moveq \rx, #0x000fe000 @ Physical Base - movne \rx, #0 - orr \rx, \rx, #0xfe000000 - orr \rx, \rx, #0x00f00000 @ Virtual Base - orr \rx, \rx, #0x00001700 @ location of the UART -#else -#error Unknown IOP3XX implementation -#endif - .endm - -#if !defined(CONFIG_ARCH_IQ80321) || !defined(CONFIG_ARCH_IQ31244) || !defined(CONFIG_ARCH_IQ80331) -#define FLOW_CONTROL -#endif -#define UART_SHIFT 0 -#include <asm/hardware/debug-8250.S> diff --git a/include/asm-arm/arch-iop3xx/entry-macro.S b/include/asm-arm/arch-iop3xx/entry-macro.S deleted file mode 100644 index 926668c098a..00000000000 --- a/include/asm-arm/arch-iop3xx/entry-macro.S +++ /dev/null @@ -1,57 +0,0 @@ -/* - * include/asm-arm/arch-iop3xx/entry-macro.S - * - * Low-level IRQ helper macros for IOP3xx-based platforms - * - * 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 <asm/arch/irqs.h> - -#if defined(CONFIG_ARCH_IOP321) - .macro disable_fiq - .endm - - /* - * Note: only deal with normal interrupts, not FIQ - */ - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov \irqnr, #0 - mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC - cmp \irqstat, #0 - beq 1001f - clz \irqnr, \irqstat - mov \base, #31 - subs \irqnr,\base,\irqnr - add \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT -1001: - .endm - -#elif defined(CONFIG_ARCH_IOP331) - .macro disable_fiq - .endm - - /* - * Note: only deal with normal interrupts, not FIQ - */ - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp - mov \irqnr, #0 - mrc p6, 0, \irqstat, c4, c0, 0 @ Read IINTSRC0 - cmp \irqstat, #0 - bne 1002f - mrc p6, 0, \irqstat, c5, c0, 0 @ Read IINTSRC1 - cmp \irqstat, #0 - beq 1001f - clz \irqnr, \irqstat - rsbs \irqnr,\irqnr,#31 @ recommend by RMK - add \irqnr,\irqnr,#IRQ_IOP331_XINT8 - b 1001f -1002: clz \irqnr, \irqstat - rsbs \irqnr,\irqnr,#31 @ recommend by RMK - add \irqnr,\irqnr,#IRQ_IOP331_DMA0_EOT -1001: - .endm - -#endif - diff --git a/include/asm-arm/arch-iop3xx/hardware.h b/include/asm-arm/arch-iop3xx/hardware.h deleted file mode 100644 index 3b138171d08..00000000000 --- a/include/asm-arm/arch-iop3xx/hardware.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/hardware.h - */ -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -#include <asm/types.h> - -/* - * Note about PCI IO space mappings - * - * To make IO space accesses efficient, we store virtual addresses in - * the IO resources. - * - * The PCI IO space is located at virtual 0xfe000000 from physical - * 0x90000000. The PCI BARs must be programmed with physical addresses, - * but when we read them, we convert them to virtual addresses. See - * arch/arm/mach-iop3xx/iop3xx-pci.c - */ - -#define pcibios_assign_all_busses() 1 - - -/* - * The min PCI I/O and MEM space are dependent on what specific - * chipset/platform we are running on, so instead of hardcoding with - * #ifdefs, we just fill these in the platform level PCI init code. - */ -#ifndef __ASSEMBLY__ -extern unsigned long iop3xx_pcibios_min_io; -extern unsigned long iop3xx_pcibios_min_mem; - -extern unsigned int processor_id; -#endif - -/* - * We just set these to zero since they are really bogus anyways - */ -#define PCIBIOS_MIN_IO (iop3xx_pcibios_min_io) -#define PCIBIOS_MIN_MEM (iop3xx_pcibios_min_mem) - -/* - * Generic chipset bits - * - */ -#include "iop321.h" -#include "iop331.h" - -/* - * Board specific bits - */ -#include "iq80321.h" -#include "iq31244.h" -#include "iq80331.h" -#include "iq80332.h" - -#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/include/asm-arm/arch-iop3xx/iop321-irqs.h b/include/asm-arm/arch-iop3xx/iop321-irqs.h deleted file mode 100644 index 2fcc1654cb9..00000000000 --- a/include/asm-arm/arch-iop3xx/iop321-irqs.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/irqs.h - * - * Author: Rory Bolt <rorybolt@pacbell.net> - * Copyright: (C) 2002 Rory Bolt - * - * 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 _IOP321_IRQS_H_ -#define _IOP321_IRQS_H_ - -/* - * IOP80321 chipset interrupts - */ -#define IOP321_IRQ_OFS 0 -#define IOP321_IRQ(x) (IOP321_IRQ_OFS + (x)) - -/* - * On IRQ or FIQ register - */ -#define IRQ_IOP321_DMA0_EOT IOP321_IRQ(0) -#define IRQ_IOP321_DMA0_EOC IOP321_IRQ(1) -#define IRQ_IOP321_DMA1_EOT IOP321_IRQ(2) -#define IRQ_IOP321_DMA1_EOC IOP321_IRQ(3) -#define IRQ_IOP321_RSVD_4 IOP321_IRQ(4) -#define IRQ_IOP321_RSVD_5 IOP321_IRQ(5) -#define IRQ_IOP321_AA_EOT IOP321_IRQ(6) -#define IRQ_IOP321_AA_EOC IOP321_IRQ(7) -#define IRQ_IOP321_CORE_PMON IOP321_IRQ(8) -#define IRQ_IOP321_TIMER0 IOP321_IRQ(9) -#define IRQ_IOP321_TIMER1 IOP321_IRQ(10) -#define IRQ_IOP321_I2C_0 IOP321_IRQ(11) -#define IRQ_IOP321_I2C_1 IOP321_IRQ(12) -#define IRQ_IOP321_MESSAGING IOP321_IRQ(13) -#define IRQ_IOP321_ATU_BIST IOP321_IRQ(14) -#define IRQ_IOP321_PERFMON IOP321_IRQ(15) -#define IRQ_IOP321_CORE_PMU IOP321_IRQ(16) -#define IRQ_IOP321_BIU_ERR IOP321_IRQ(17) -#define IRQ_IOP321_ATU_ERR IOP321_IRQ(18) -#define IRQ_IOP321_MCU_ERR IOP321_IRQ(19) -#define IRQ_IOP321_DMA0_ERR IOP321_IRQ(20) -#define IRQ_IOP321_DMA1_ERR IOP321_IRQ(21) -#define IRQ_IOP321_RSVD_22 IOP321_IRQ(22) -#define IRQ_IOP321_AA_ERR IOP321_IRQ(23) -#define IRQ_IOP321_MSG_ERR IOP321_IRQ(24) -#define IRQ_IOP321_SSP IOP321_IRQ(25) -#define IRQ_IOP321_RSVD_26 IOP321_IRQ(26) -#define IRQ_IOP321_XINT0 IOP321_IRQ(27) -#define IRQ_IOP321_XINT1 IOP321_IRQ(28) -#define IRQ_IOP321_XINT2 IOP321_IRQ(29) -#define IRQ_IOP321_XINT3 IOP321_IRQ(30) -#define IRQ_IOP321_HPI IOP321_IRQ(31) - -#define NR_IOP321_IRQS (IOP321_IRQ(31) + 1) - -#define NR_IRQS NR_IOP321_IRQS - - -/* - * Interrupts available on the IQ80321 board - */ - -/* - * On board devices - */ -#define IRQ_IQ80321_I82544 IRQ_IOP321_XINT0 -#define IRQ_IQ80321_UART IRQ_IOP321_XINT1 - -/* - * PCI interrupts - */ -#define IRQ_IQ80321_INTA IRQ_IOP321_XINT0 -#define IRQ_IQ80321_INTB IRQ_IOP321_XINT1 -#define IRQ_IQ80321_INTC IRQ_IOP321_XINT2 -#define IRQ_IQ80321_INTD IRQ_IOP321_XINT3 - -/* - * Interrupts on the IQ31244 board - */ - -/* - * On board devices - */ -#define IRQ_IQ31244_UART IRQ_IOP321_XINT1 -#define IRQ_IQ31244_I82546 IRQ_IOP321_XINT0 -#define IRQ_IQ31244_SATA IRQ_IOP321_XINT2 -#define IRQ_IQ31244_PCIX_SLOT IRQ_IOP321_XINT3 - -/* - * PCI interrupts - */ -#define IRQ_IQ31244_INTA IRQ_IOP321_XINT0 -#define IRQ_IQ31244_INTB IRQ_IOP321_XINT1 -#define IRQ_IQ31244_INTC IRQ_IOP321_XINT2 -#define IRQ_IQ31244_INTD IRQ_IOP321_XINT3 - -#endif // _IOP321_IRQ_H_ diff --git a/include/asm-arm/arch-iop3xx/iop321.h b/include/asm-arm/arch-iop3xx/iop321.h deleted file mode 100644 index f8df778a356..00000000000 --- a/include/asm-arm/arch-iop3xx/iop321.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * linux/include/asm/arch-iop3xx/iop321.h - * - * Intel IOP321 Chip definitions - * - * Author: Rory Bolt <rorybolt@pacbell.net> - * Copyright (C) 2002 Rory Bolt - * Copyright (C) 2004 Intel Corp. - * - * 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 _IOP321_HW_H_ -#define _IOP321_HW_H_ - - -/* - * This is needed for mixed drivers that need to work on all - * IOP3xx variants but behave slightly differently on each. - */ -#ifndef __ASSEMBLY__ -#ifdef CONFIG_ARCH_IOP321 -#define iop_is_321() (((processor_id & 0xfffff5e0) == 0x69052420)) -#else -#define iop_is_321() 0 -#endif -#endif - -/* - * IOP321 I/O and Mem space regions for PCI autoconfiguration - */ -#define IOP321_PCI_IO_WINDOW_SIZE 0x00010000 -#define IOP321_PCI_LOWER_IO_PA 0x90000000 -#define IOP321_PCI_LOWER_IO_VA 0xfe000000 -#define IOP321_PCI_LOWER_IO_BA (*IOP321_OIOWTVR) -#define IOP321_PCI_UPPER_IO_PA (IOP321_PCI_LOWER_IO_PA + IOP321_PCI_IO_WINDOW_SIZE - 1) -#define IOP321_PCI_UPPER_IO_VA (IOP321_PCI_LOWER_IO_VA + IOP321_PCI_IO_WINDOW_SIZE - 1) -#define IOP321_PCI_UPPER_IO_BA (IOP321_PCI_LOWER_IO_BA + IOP321_PCI_IO_WINDOW_SIZE - 1) -#define IOP321_PCI_IO_OFFSET (IOP321_PCI_LOWER_IO_VA - IOP321_PCI_LOWER_IO_BA) - -/* #define IOP321_PCI_MEM_WINDOW_SIZE (~*IOP321_IALR1 + 1) */ -#define IOP321_PCI_MEM_WINDOW_SIZE 0x04000000 /* 64M outbound window */ -#define IOP321_PCI_LOWER_MEM_PA 0x80000000 -#define IOP321_PCI_LOWER_MEM_BA (*IOP321_OMWTVR0) -#define IOP321_PCI_UPPER_MEM_PA (IOP321_PCI_LOWER_MEM_PA + IOP321_PCI_MEM_WINDOW_SIZE - 1) -#define IOP321_PCI_UPPER_MEM_BA (IOP321_PCI_LOWER_MEM_BA + IOP321_PCI_MEM_WINDOW_SIZE - 1) -#define IOP321_PCI_MEM_OFFSET (IOP321_PCI_LOWER_MEM_PA - IOP321_PCI_LOWER_MEM_BA) - - -/* - * IOP321 chipset registers - */ -#define IOP321_VIRT_MEM_BASE 0xfeffe000 /* chip virtual mem address*/ -#define IOP321_PHYS_MEM_BASE 0xffffe000 /* chip physical memory address */ -#define IOP321_REG_ADDR(reg) (IOP321_VIRT_MEM_BASE | (reg)) - -/* Reserved 0x00000000 through 0x000000FF */ - -/* Address Translation Unit 0x00000100 through 0x000001FF */ -#define IOP321_ATUVID (volatile u16 *)IOP321_REG_ADDR(0x00000100) -#define IOP321_ATUDID (volatile u16 *)IOP321_REG_ADDR(0x00000102) -#define IOP321_ATUCMD (volatile u16 *)IOP321_REG_ADDR(0x00000104) -#define IOP321_ATUSR (volatile u16 *)IOP321_REG_ADDR(0x00000106) -#define IOP321_ATURID (volatile u8 *)IOP321_REG_ADDR(0x00000108) -#define IOP321_ATUCCR (volatile u32 *)IOP321_REG_ADDR(0x00000109) -#define IOP321_ATUCLSR (volatile u8 *)IOP321_REG_ADDR(0x0000010C) -#define IOP321_ATULT (volatile u8 *)IOP321_REG_ADDR(0x0000010D) -#define IOP321_ATUHTR (volatile u8 *)IOP321_REG_ADDR(0x0000010E) -#define IOP321_ATUBIST (volatile u8 *)IOP321_REG_ADDR(0x0000010F) -#define IOP321_IABAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000110) -#define IOP321_IAUBAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000114) -#define IOP321_IABAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000118) -#define IOP321_IAUBAR1 (volatile u32 *)IOP321_REG_ADDR(0x0000011C) -#define IOP321_IABAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000120) -#define IOP321_IAUBAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000124) -#define IOP321_ASVIR (volatile u16 *)IOP321_REG_ADDR(0x0000012C) -#define IOP321_ASIR (volatile u16 *)IOP321_REG_ADDR(0x0000012E) -#define IOP321_ERBAR (volatile u32 *)IOP321_REG_ADDR(0x00000130) -/* Reserved 0x00000134 through 0x0000013B */ -#define IOP321_ATUILR (volatile u8 *)IOP321_REG_ADDR(0x0000013C) -#define IOP321_ATUIPR (volatile u8 *)IOP321_REG_ADDR(0x0000013D) -#define IOP321_ATUMGNT (volatile u8 *)IOP321_REG_ADDR(0x0000013E) -#define IOP321_ATUMLAT (volatile u8 *)IOP321_REG_ADDR(0x0000013F) -#define IOP321_IALR0 (volatile u32 *)IOP321_REG_ADDR(0x00000140) -#define IOP321_IATVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000144) -#define IOP321_ERLR (volatile u32 *)IOP321_REG_ADDR(0x00000148) -#define IOP321_ERTVR (volatile u32 *)IOP321_REG_ADDR(0x0000014C) -#define IOP321_IALR1 (volatile u32 *)IOP321_REG_ADDR(0x00000150) -#define IOP321_IALR2 (volatile u32 *)IOP321_REG_ADDR(0x00000154) -#define IOP321_IATVR2 (volatile u32 *)IOP321_REG_ADDR(0x00000158) -#define IOP321_OIOWTVR (volatile u32 *)IOP321_REG_ADDR(0x0000015C) -#define IOP321_OMWTVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000160) -#define IOP321_OUMWTVR0 (volatile u32 *)IOP321_REG_ADDR(0x00000164) -#define IOP321_OMWTVR1 (volatile u32 *)IOP321_REG_ADDR(0x00000168) -#define IOP321_OUMWTVR1 (volatile u32 *)IOP321_REG_ADDR(0x0000016C) -/* Reserved 0x00000170 through 0x00000177*/ -#define IOP321_OUDWTVR (volatile u32 *)IOP321_REG_ADDR(0x00000178) -/* Reserved 0x0000017C through 0x0000017F*/ -#define IOP321_ATUCR (volatile u32 *)IOP321_REG_ADDR(0x00000180) -#define IOP321_PCSR (volatile u32 *)IOP321_REG_ADDR(0x00000184) -#define IOP321_ATUISR (volatile u32 *)IOP321_REG_ADDR(0x00000188) -#define IOP321_ATUIMR (volatile u32 *)IOP321_REG_ADDR(0x0000018C) -#define IOP321_IABAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000190) -#define IOP321_IAUBAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000194) -#define IOP321_IALR3 (volatile u32 *)IOP321_REG_ADDR(0x00000198) -#define IOP321_IATVR3 (volatile u32 *)IOP321_REG_ADDR(0x0000019C) -/* Reserved 0x000001A0 through 0x000001A3*/ -#define IOP321_OCCAR (volatile u32 *)IOP321_REG_ADDR(0x000001A4) -/* Reserved 0x000001A8 through 0x000001AB*/ -#define IOP321_OCCDR (volatile u32 *)IOP321_REG_ADDR(0x000001AC) -/* Reserved 0x000001B0 through 0x000001BB*/ -#define IOP321_PDSCR (volatile u32 *)IOP321_REG_ADDR(0x000001BC) -#define IOP321_PMCAPID (volatile u8 *)IOP321_REG_ADDR(0x000001C0) -#define IOP321_PMNEXT (volatile u8 *)IOP321_REG_ADDR(0x000001C1) -#define IOP321_APMCR (volatile u16 *)IOP321_REG_ADDR(0x000001C2) -#define IOP321_APMCSR (volatile u16 *)IOP321_REG_ADDR(0x000001C4) -/* Reserved 0x000001C6 through 0x000001DF */ -#define IOP321_PCIXCAPID (volatile u8 *)IOP321_REG_ADDR(0x000001E0) -#define IOP321_PCIXNEXT (volatile u8 *)IOP321_REG_ADDR(0x000001E1) -#define IOP321_PCIXCMD (volatile u16 *)IOP321_REG_ADDR(0x000001E2) -#define IOP321_PCIXSR (volatile u32 *)IOP321_REG_ADDR(0x000001E4) -#define IOP321_PCIIRSR (volatile u32 *)IOP321_REG_ADDR(0x000001EC) - -/* Messaging Unit 0x00000300 through 0x000003FF */ - -/* Reserved 0x00000300 through 0x0000030c */ -#define IOP321_IMR0 (volatile u32 *)IOP321_REG_ADDR(0x00000310) -#define IOP321_IMR1 (volatile u32 *)IOP321_REG_ADDR(0x00000314) -#define IOP321_OMR0 (volatile u32 *)IOP321_REG_ADDR(0x00000318) -#define IOP321_OMR1 (volatile u32 *)IOP321_REG_ADDR(0x0000031C) -#define IOP321_IDR (volatile u32 *)IOP321_REG_ADDR(0x00000320) -#define IOP321_IISR (volatile u32 *)IOP321_REG_ADDR(0x00000324) -#define IOP321_IIMR (volatile u32 *)IOP321_REG_ADDR(0x00000328) -#define IOP321_ODR (volatile u32 *)IOP321_REG_ADDR(0x0000032C) -#define IOP321_OISR (volatile u32 *)IOP321_REG_ADDR(0x00000330) -#define IOP321_OIMR (volatile u32 *)IOP321_REG_ADDR(0x00000334) -/* Reserved 0x00000338 through 0x0000034F */ -#define IOP321_MUCR (volatile u32 *)IOP321_REG_ADDR(0x00000350) -#define IOP321_QBAR (volatile u32 *)IOP321_REG_ADDR(0x00000354) -/* Reserved 0x00000358 through 0x0000035C */ -#define IOP321_IFHPR (volatile u32 *)IOP321_REG_ADDR(0x00000360) -#define IOP321_IFTPR (volatile u32 *)IOP321_REG_ADDR(0x00000364) -#define IOP321_IPHPR (volatile u32 *)IOP321_REG_ADDR(0x00000368) -#define IOP321_IPTPR (volatile u32 *)IOP321_REG_ADDR(0x0000036C) -#define IOP321_OFHPR (volatile u32 *)IOP321_REG_ADDR(0x00000370) -#define IOP321_OFTPR (volatile u32 *)IOP321_REG_ADDR(0x00000374) -#define IOP321_OPHPR (volatile u32 *)IOP321_REG_ADDR(0x00000378) -#define IOP321_OPTPR (volatile u32 *)IOP321_REG_ADDR(0x0000037C) -#define IOP321_IAR (volatile u32 *)IOP321_REG_ADDR(0x00000380) - -#define IOP321_IIxR_MASK 0x7f /* masks all */ -#define IOP321_IIxR_IRI 0x40 /* RC Index Register Interrupt */ -#define IOP321_IIxR_OFQF 0x20 /* RC Output Free Q Full (ERROR) */ -#define IOP321_IIxR_ipq 0x10 /* RC Inbound Post Q (post) */ -#define IOP321_IIxR_ERRDI 0x08 /* RO Error Doorbell Interrupt */ -#define IOP321_IIxR_IDI 0x04 /* RO Inbound Doorbell Interrupt */ -#define IOP321_IIxR_IM1 0x02 /* RC Inbound Message 1 Interrupt */ -#define IOP321_IIxR_IM0 0x01 /* RC Inbound Message 0 Interrupt */ - -/* Reserved 0x00000384 through 0x000003FF */ - -/* DMA Controller 0x00000400 through 0x000004FF */ -#define IOP321_DMA0_CCR (volatile u32 *)IOP321_REG_ADDR(0x00000400) -#define IOP321_DMA0_CSR (volatile u32 *)IOP321_REG_ADDR(0x00000404) -#define IOP321_DMA0_DAR (volatile u32 *)IOP321_REG_ADDR(0x0000040C) -#define IOP321_DMA0_NDAR (volatile u32 *)IOP321_REG_ADDR(0x00000410) -#define IOP321_DMA0_PADR (volatile u32 *)IOP321_REG_ADDR(0x00000414) -#define IOP321_DMA0_PUADR (volatile u32 *)IOP321_REG_ADDR(0x00000418) -#define IOP321_DMA0_LADR (volatile u32 *)IOP321_REG_ADDR(0X0000041C) -#define IOP321_DMA0_BCR (volatile u32 *)IOP321_REG_ADDR(0x00000420) -#define IOP321_DMA0_DCR (volatile u32 *)IOP321_REG_ADDR(0x00000424) -/* Reserved 0x00000428 through 0x0000043C */ -#define IOP321_DMA1_CCR (volatile u32 *)IOP321_REG_ADDR(0x00000440) -#define IOP321_DMA1_CSR (volatile u32 *)IOP321_REG_ADDR(0x00000444) -#define IOP321_DMA1_DAR (volatile u32 *)IOP321_REG_ADDR(0x0000044C) -#define IOP321_DMA1_NDAR (volatile u32 *)IOP321_REG_ADDR(0x00000450) -#define IOP321_DMA1_PADR (volatile u32 *)IOP321_REG_ADDR(0x00000454) -#define IOP321_DMA1_PUADR (volatile u32 *)IOP321_REG_ADDR(0x00000458) -#define IOP321_DMA1_LADR (volatile u32 *)IOP321_REG_ADDR(0x0000045C) -#define IOP321_DMA1_BCR (volatile u32 *)IOP321_REG_ADDR(0x00000460) -#define IOP321_DMA1_DCR (volatile u32 *)IOP321_REG_ADDR(0x00000464) -/* Reserved 0x00000468 through 0x000004FF */ - -/* Memory controller 0x00000500 through 0x0005FF */ - -/* Peripheral bus interface unit 0x00000680 through 0x0006FF */ -#define IOP321_PBCR (volatile u32 *)IOP321_REG_ADDR(0x00000680) -#define IOP321_PBISR (volatile u32 *)IOP321_REG_ADDR(0x00000684) -#define IOP321_PBBAR0 (volatile u32 *)IOP321_REG_ADDR(0x00000688) -#define IOP321_PBLR0 (volatile u32 *)IOP321_REG_ADDR(0x0000068C) -#define IOP321_PBBAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000690) -#define IOP321_PBLR1 (volatile u32 *)IOP321_REG_ADDR(0x00000694) -#define IOP321_PBBAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000698) -#define IOP321_PBLR2 (volatile u32 *)IOP321_REG_ADDR(0x0000069C) -#define IOP321_PBBAR3 (volatile u32 *)IOP321_REG_ADDR(0x000006A0) -#define IOP321_PBLR3 (volatile u32 *)IOP321_REG_ADDR(0x000006A4) -#define IOP321_PBBAR4 (volatile u32 *)IOP321_REG_ADDR(0x000006A8) -#define IOP321_PBLR4 (volatile u32 *)IOP321_REG_ADDR(0x000006AC) -#define IOP321_PBBAR5 (volatile u32 *)IOP321_REG_ADDR(0x000006B0) -#define IOP321_PBLR5 (volatile u32 *)IOP321_REG_ADDR(0x000006B4) -#define IOP321_PBDSCR (volatile u32 *)IOP321_REG_ADDR(0x000006B8) -/* Reserved 0x000006BC */ -#define IOP321_PMBR0 (volatile u32 *)IOP321_REG_ADDR(0x000006C0) -/* Reserved 0x000006C4 through 0x000006DC */ -#define IOP321_PMBR1 (volatile u32 *)IOP321_REG_ADDR(0x000006E0) -#define IOP321_PMBR2 (volatile u32 *)IOP321_REG_ADDR(0x000006E4) - -#define IOP321_PBCR_EN 0x1 - -#define IOP321_PBISR_BOOR_ERR 0x1 - -/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */ -#define IOP321_GTMR (volatile u32 *)IOP321_REG_ADDR(0x00000700) -#define IOP321_ESR (volatile u32 *)IOP321_REG_ADDR(0x00000704) -#define IOP321_EMISR (volatile u32 *)IOP321_REG_ADDR(0x00000708) -/* reserved 0x00000070c */ -#define IOP321_GTSR (volatile u32 *)IOP321_REG_ADDR(0x00000710) -/* PERC0 DOESN'T EXIST - index from 1! */ -#define IOP321_PERCR0 (volatile u32 *)IOP321_REG_ADDR(0x00000710) - -#define IOP321_GTMR_NGCE 0x04 /* (Not) Global Counter Enable */ - -/* Internal arbitration unit 0x00000780 through 0x0007BF */ -#define IOP321_IACR (volatile u32 *)IOP321_REG_ADDR(0x00000780) -#define IOP321_MTTR1 (volatile u32 *)IOP321_REG_ADDR(0x00000784) -#define IOP321_MTTR2 (volatile u32 *)IOP321_REG_ADDR(0x00000788) - -/* General Purpose I/O Registers */ -#define IOP321_GPOE (volatile u32 *)IOP321_REG_ADDR(0x000007C4) -#define IOP321_GPID (volatile u32 *)IOP321_REG_ADDR(0x000007C8) -#define IOP321_GPOD (volatile u32 *)IOP321_REG_ADDR(0x000007CC) - -/* Interrupt Controller */ -#define IOP321_INTCTL (volatile u32 *)IOP321_REG_ADDR(0x000007D0) -#define IOP321_INTSTR (volatile u32 *)IOP321_REG_ADDR(0x000007D4) -#define IOP321_IINTSRC (volatile u32 *)IOP321_REG_ADDR(0x000007D8) -#define IOP321_FINTSRC (volatile u32 *)IOP321_REG_ADDR(0x000007DC) - -/* Timers */ - -#define IOP321_TU_TMR0 (volatile u32 *)IOP321_REG_ADDR(0x000007E0) -#define IOP321_TU_TMR1 (volatile u32 *)IOP321_REG_ADDR(0x000007E4) - -#ifdef CONFIG_ARCH_IQ80321 -#define IOP321_TICK_RATE 200000000 /* 200 MHz clock */ -#elif defined(CONFIG_ARCH_IQ31244) -#define IOP321_TICK_RATE 198000000 /* 33.000 MHz crystal */ -#endif - -#ifdef CONFIG_ARCH_EP80219 -#undef IOP321_TICK_RATE -#define IOP321_TICK_RATE 200000000 /* 33.333333 Mhz crystal */ -#endif - -#define IOP321_TMR_TC 0x01 -#define IOP321_TMR_EN 0x02 -#define IOP321_TMR_RELOAD 0x04 -#define IOP321_TMR_PRIVILEGED 0x09 - -#define IOP321_TMR_RATIO_1_1 0x00 -#define IOP321_TMR_RATIO_4_1 0x10 -#define IOP321_TMR_RATIO_8_1 0x20 -#define IOP321_TMR_RATIO_16_1 0x30 - -#define IOP321_TU_TCR0 (volatile u32 *)IOP321_REG_ADDR(0x000007E8) -#define IOP321_TU_TCR1 (volatile u32 *)IOP321_REG_ADDR(0x000007EC) -#define IOP321_TU_TRR0 (volatile u32 *)IOP321_REG_ADDR(0x000007F0) -#define IOP321_TU_TRR1 (volatile u32 *)IOP321_REG_ADDR(0x000007F4) -#define IOP321_TU_TISR (volatile u32 *)IOP321_REG_ADDR(0x000007F8) -#define IOP321_TU_WDTCR (volatile u32 *)IOP321_REG_ADDR(0x000007FC) - -/* Application accelerator unit 0x00000800 - 0x000008FF */ -#define IOP321_AAU_ACR (volatile u32 *)IOP321_REG_ADDR(0x00000800) -#define IOP321_AAU_ASR (volatile u32 *)IOP321_REG_ADDR(0x00000804) -#define IOP321_AAU_ADAR (volatile u32 *)IOP321_REG_ADDR(0x00000808) -#define IOP321_AAU_ANDAR (volatile u32 *)IOP321_REG_ADDR(0x0000080C) -#define IOP321_AAU_SAR1 (volatile u32 *)IOP321_REG_ADDR(0x00000810) -#define IOP321_AAU_SAR2 (volatile u32 *)IOP321_REG_ADDR(0x00000814) -#define IOP321_AAU_SAR3 (volatile u32 *)IOP321_REG_ADDR(0x00000818) -#define IOP321_AAU_SAR4 (volatile u32 *)IOP321_REG_ADDR(0x0000081C) -#define IOP321_AAU_SAR5 (volatile u32 *)IOP321_REG_ADDR(0x0000082C) -#define IOP321_AAU_SAR6 (volatile u32 *)IOP321_REG_ADDR(0x00000830) -#define IOP321_AAU_SAR7 (volatile u32 *)IOP321_REG_ADDR(0x00000834) -#define IOP321_AAU_SAR8 (volatile u32 *)IOP321_REG_ADDR(0x00000838) -#define IOP321_AAU_SAR9 (volatile u32 *)IOP321_REG_ADDR(0x00000840) -#define IOP321_AAU_SAR10 (volatile u32 *)IOP321_REG_ADDR(0x00000844) -#define IOP321_AAU_SAR11 (volatile u32 *)IOP321_REG_ADDR(0x00000848) -#define IOP321_AAU_SAR12 (volatile u32 *)IOP321_REG_ADDR(0x0000084C) -#define IOP321_AAU_SAR13 (volatile u32 *)IOP321_REG_ADDR(0x00000850) -#define IOP321_AAU_SAR14 (volatile u32 *)IOP321_REG_ADDR(0x00000854) -#define IOP321_AAU_SAR15 (volatile u32 *)IOP321_REG_ADDR(0x00000858) -#define IOP321_AAU_SAR16 (volatile u32 *)IOP321_REG_ADDR(0x0000085C) -#define IOP321_AAU_SAR17 (volatile u32 *)IOP321_REG_ADDR(0x00000864) -#define IOP321_AAU_SAR18 (volatile u32 *)IOP321_REG_ADDR(0x00000868) -#define IOP321_AAU_SAR19 (volatile u32 *)IOP321_REG_ADDR(0x0000086C) -#define IOP321_AAU_SAR20 (volatile u32 *)IOP321_REG_ADDR(0x00000870) -#define IOP321_AAU_SAR21 (volatile u32 *)IOP321_REG_ADDR(0x00000874) -#define IOP321_AAU_SAR22 (volatile u32 *)IOP321_REG_ADDR(0x00000878) -#define IOP321_AAU_SAR23 (volatile u32 *)IOP321_REG_ADDR(0x0000087C) -#define IOP321_AAU_SAR24 (volatile u32 *)IOP321_REG_ADDR(0x00000880) -#define IOP321_AAU_SAR25 (volatile u32 *)IOP321_REG_ADDR(0x00000888) -#define IOP321_AAU_SAR26 (volatile u32 *)IOP321_REG_ADDR(0x0000088C) -#define IOP321_AAU_SAR27 (volatile u32 *)IOP321_REG_ADDR(0x00000890) -#define IOP321_AAU_SAR28 (volatile u32 *)IOP321_REG_ADDR(0x00000894) -#define IOP321_AAU_SAR29 (volatile u32 *)IOP321_REG_ADDR(0x00000898) -#define IOP321_AAU_SAR30 (volatile u32 *)IOP321_REG_ADDR(0x0000089C) -#define IOP321_AAU_SAR31 (volatile u32 *)IOP321_REG_ADDR(0x000008A0) -#define IOP321_AAU_SAR32 (volatile u32 *)IOP321_REG_ADDR(0x000008A4) -#define IOP321_AAU_DAR (volatile u32 *)IOP321_REG_ADDR(0x00000820) -#define IOP321_AAU_ABCR (volatile u32 *)IOP321_REG_ADDR(0x00000824) -#define IOP321_AAU_ADCR (volatile u32 *)IOP321_REG_ADDR(0x00000828) -#define IOP321_AAU_EDCR0 (volatile u32 *)IOP321_REG_ADDR(0x0000083c) -#define IOP321_AAU_EDCR1 (volatile u32 *)IOP321_REG_ADDR(0x00000860) -#define IOP321_AAU_EDCR2 (volatile u32 *)IOP321_REG_ADDR(0x00000884) - - -/* SSP serial port unit 0x00001600 - 0x0000167F */ -/* I2C bus interface unit 0x00001680 - 0x000016FF */ -#define IOP321_ICR0 (volatile u32 *)IOP321_REG_ADDR(0x00001680) -#define IOP321_ISR0 (volatile u32 *)IOP321_REG_ADDR(0x00001684) -#define IOP321_ISAR0 (volatile u32 *)IOP321_REG_ADDR(0x00001688) -#define IOP321_IDBR0 (volatile u32 *)IOP321_REG_ADDR(0x0000168C) -/* Reserved 0x00001690 */ -#define IOP321_IBMR0 (volatile u32 *)IOP321_REG_ADDR(0x00001694) -/* Reserved 0x00001698 */ -/* Reserved 0x0000169C */ -#define IOP321_ICR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A0) -#define IOP321_ISR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A4) -#define IOP321_ISAR1 (volatile u32 *)IOP321_REG_ADDR(0x000016A8) -#define IOP321_IDBR1 (volatile u32 *)IOP321_REG_ADDR(0x000016AC) -#define IOP321_IBMR1 (volatile u32 *)IOP321_REG_ADDR(0x000016B4) -/* Reserved 0x000016B8 through 0x000016FC */ - -/* for I2C bit defs see drivers/i2c/i2c-iop3xx.h */ - - -#ifndef __ASSEMBLY__ -extern void iop321_map_io(void); -extern void iop321_init_irq(void); -extern void iop321_time_init(void); -#endif - -#endif // _IOP321_HW_H_ diff --git a/include/asm-arm/arch-iop3xx/iop331-irqs.h b/include/asm-arm/arch-iop3xx/iop331-irqs.h deleted file mode 100644 index 7135ad7e335..00000000000 --- a/include/asm-arm/arch-iop3xx/iop331-irqs.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/irqs.h - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright: (C) 2003 Intel Corp. - * - * 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 _IOP331_IRQS_H_ -#define _IOP331_IRQS_H_ - -/* - * IOP80331 chipset interrupts - */ -#define IOP331_IRQ_OFS 0 -#define IOP331_IRQ(x) (IOP331_IRQ_OFS + (x)) - -/* - * On IRQ or FIQ register - */ -#define IRQ_IOP331_DMA0_EOT IOP331_IRQ(0) -#define IRQ_IOP331_DMA0_EOC IOP331_IRQ(1) -#define IRQ_IOP331_DMA1_EOT IOP331_IRQ(2) -#define IRQ_IOP331_DMA1_EOC IOP331_IRQ(3) -#define IRQ_IOP331_RSVD_4 IOP331_IRQ(4) -#define IRQ_IOP331_RSVD_5 IOP331_IRQ(5) -#define IRQ_IOP331_AA_EOT IOP331_IRQ(6) -#define IRQ_IOP331_AA_EOC IOP331_IRQ(7) -#define IRQ_IOP331_TIMER0 IOP331_IRQ(8) -#define IRQ_IOP331_TIMER1 IOP331_IRQ(9) -#define IRQ_IOP331_I2C_0 IOP331_IRQ(10) -#define IRQ_IOP331_I2C_1 IOP331_IRQ(11) -#define IRQ_IOP331_MSG IOP331_IRQ(12) -#define IRQ_IOP331_MSGIBQ IOP331_IRQ(13) -#define IRQ_IOP331_ATU_BIST IOP331_IRQ(14) -#define IRQ_IOP331_PERFMON IOP331_IRQ(15) -#define IRQ_IOP331_CORE_PMU IOP331_IRQ(16) -#define IRQ_IOP331_RSVD_17 IOP331_IRQ(17) -#define IRQ_IOP331_RSVD_18 IOP331_IRQ(18) -#define IRQ_IOP331_RSVD_19 IOP331_IRQ(19) -#define IRQ_IOP331_RSVD_20 IOP331_IRQ(20) -#define IRQ_IOP331_RSVD_21 IOP331_IRQ(21) -#define IRQ_IOP331_RSVD_22 IOP331_IRQ(22) -#define IRQ_IOP331_RSVD_23 IOP331_IRQ(23) -#define IRQ_IOP331_XINT0 IOP331_IRQ(24) -#define IRQ_IOP331_XINT1 IOP331_IRQ(25) -#define IRQ_IOP331_XINT2 IOP331_IRQ(26) -#define IRQ_IOP331_XINT3 IOP331_IRQ(27) -#define IRQ_IOP331_RSVD_28 IOP331_IRQ(28) -#define IRQ_IOP331_RSVD_29 IOP331_IRQ(29) -#define IRQ_IOP331_RSVD_30 IOP331_IRQ(30) -#define IRQ_IOP331_RSVD_31 IOP331_IRQ(31) -#define IRQ_IOP331_XINT8 IOP331_IRQ(32) // 0 -#define IRQ_IOP331_XINT9 IOP331_IRQ(33) // 1 -#define IRQ_IOP331_XINT10 IOP331_IRQ(34) // 2 -#define IRQ_IOP331_XINT11 IOP331_IRQ(35) // 3 -#define IRQ_IOP331_XINT12 IOP331_IRQ(36) // 4 -#define IRQ_IOP331_XINT13 IOP331_IRQ(37) // 5 -#define IRQ_IOP331_XINT14 IOP331_IRQ(38) // 6 -#define IRQ_IOP331_XINT15 IOP331_IRQ(39) // 7 -#define IRQ_IOP331_RSVD_40 IOP331_IRQ(40) // 8 -#define IRQ_IOP331_RSVD_41 IOP331_IRQ(41) // 9 -#define IRQ_IOP331_RSVD_42 IOP331_IRQ(42) // 10 -#define IRQ_IOP331_RSVD_43 IOP331_IRQ(43) // 11 -#define IRQ_IOP331_RSVD_44 IOP331_IRQ(44) // 12 -#define IRQ_IOP331_RSVD_45 IOP331_IRQ(45) // 13 -#define IRQ_IOP331_RSVD_46 IOP331_IRQ(46) // 14 -#define IRQ_IOP331_RSVD_47 IOP331_IRQ(47) // 15 -#define IRQ_IOP331_RSVD_48 IOP331_IRQ(48) // 16 -#define IRQ_IOP331_RSVD_49 IOP331_IRQ(49) // 17 -#define IRQ_IOP331_RSVD_50 IOP331_IRQ(50) // 18 -#define IRQ_IOP331_UART0 IOP331_IRQ(51) // 19 -#define IRQ_IOP331_UART1 IOP331_IRQ(52) // 20 -#define IRQ_IOP331_PBIE IOP331_IRQ(53) // 21 -#define IRQ_IOP331_ATU_CRW IOP331_IRQ(54) // 22 -#define IRQ_IOP331_ATU_ERR IOP331_IRQ(55) // 23 -#define IRQ_IOP331_MCU_ERR IOP331_IRQ(56) // 24 -#define IRQ_IOP331_DMA0_ERR IOP331_IRQ(57) // 25 -#define IRQ_IOP331_DMA1_ERR IOP331_IRQ(58) // 26 -#define IRQ_IOP331_RSVD_59 IOP331_IRQ(59) // 27 -#define IRQ_IOP331_AA_ERR IOP331_IRQ(60) // 28 -#define IRQ_IOP331_RSVD_61 IOP331_IRQ(61) // 29 -#define IRQ_IOP331_MSG_ERR IOP331_IRQ(62) // 30 -#define IRQ_IOP331_HPI IOP331_IRQ(63) // 31 - -#define NR_IOP331_IRQS (IOP331_IRQ(63) + 1) - -#define NR_IRQS NR_IOP331_IRQS - - -/* - * Interrupts available on the IQ80331 board - */ - -/* - * On board devices - */ -#define IRQ_IQ80331_I82544 IRQ_IOP331_XINT0 -#define IRQ_IQ80331_UART0 IRQ_IOP331_UART0 -#define IRQ_IQ80331_UART1 IRQ_IOP331_UART1 - -/* - * PCI interrupts - */ -#define IRQ_IQ80331_INTA IRQ_IOP331_XINT0 -#define IRQ_IQ80331_INTB IRQ_IOP331_XINT1 -#define IRQ_IQ80331_INTC IRQ_IOP331_XINT2 -#define IRQ_IQ80331_INTD IRQ_IOP331_XINT3 - -/* - * Interrupts available on the IQ80332 board - */ - -/* - * On board devices - */ -#define IRQ_IQ80332_I82544 IRQ_IOP331_XINT0 -#define IRQ_IQ80332_UART0 IRQ_IOP331_UART0 -#define IRQ_IQ80332_UART1 IRQ_IOP331_UART1 - -/* - * PCI interrupts - */ -#define IRQ_IQ80332_INTA IRQ_IOP331_XINT0 -#define IRQ_IQ80332_INTB IRQ_IOP331_XINT1 -#define IRQ_IQ80332_INTC IRQ_IOP331_XINT2 -#define IRQ_IQ80332_INTD IRQ_IOP331_XINT3 - -#endif // _IOP331_IRQ_H_ diff --git a/include/asm-arm/arch-iop3xx/iop331.h b/include/asm-arm/arch-iop3xx/iop331.h deleted file mode 100644 index fbf0cc11bdd..00000000000 --- a/include/asm-arm/arch-iop3xx/iop331.h +++ /dev/null @@ -1,363 +0,0 @@ -/* - * linux/include/asm/arch-iop3xx/iop331.h - * - * Intel IOP331 Chip definitions - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright (C) 2003, 2004 Intel Corp. - * - * 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 _IOP331_HW_H_ -#define _IOP331_HW_H_ - - -/* - * This is needed for mixed drivers that need to work on all - * IOP3xx variants but behave slightly differently on each. - */ -#ifndef __ASSEMBLY__ -#ifdef CONFIG_ARCH_IOP331 -/*#define iop_is_331() ((processor_id & 0xffffffb0) == 0x69054090) */ -#define iop_is_331() ((processor_id & 0xffffff30) == 0x69054010) -#else -#define iop_is_331() 0 -#endif -#endif - -/* - * IOP331 I/O and Mem space regions for PCI autoconfiguration - */ -#define IOP331_PCI_IO_WINDOW_SIZE 0x00010000 -#define IOP331_PCI_LOWER_IO_PA 0x90000000 -#define IOP331_PCI_LOWER_IO_VA 0xfe000000 -#define IOP331_PCI_LOWER_IO_BA (*IOP331_OIOWTVR) -#define IOP331_PCI_UPPER_IO_PA (IOP331_PCI_LOWER_IO_PA + IOP331_PCI_IO_WINDOW_SIZE - 1) -#define IOP331_PCI_UPPER_IO_VA (IOP331_PCI_LOWER_IO_VA + IOP331_PCI_IO_WINDOW_SIZE - 1) -#define IOP331_PCI_UPPER_IO_BA (IOP331_PCI_LOWER_IO_BA + IOP331_PCI_IO_WINDOW_SIZE - 1) -#define IOP331_PCI_IO_OFFSET (IOP331_PCI_LOWER_IO_VA - IOP331_PCI_LOWER_IO_BA) - -/* this can be 128M if OMWTVR1 is set */ -#define IOP331_PCI_MEM_WINDOW_SIZE 0x04000000 /* 64M outbound window */ -/* #define IOP331_PCI_MEM_WINDOW_SIZE (~*IOP331_IALR1 + 1) */ -#define IOP331_PCI_LOWER_MEM_PA 0x80000000 -#define IOP331_PCI_LOWER_MEM_BA (*IOP331_OMWTVR0) -#define IOP331_PCI_UPPER_MEM_PA (IOP331_PCI_LOWER_MEM_PA + IOP331_PCI_MEM_WINDOW_SIZE - 1) -#define IOP331_PCI_UPPER_MEM_BA (IOP331_PCI_LOWER_MEM_BA + IOP331_PCI_MEM_WINDOW_SIZE - 1) -#define IOP331_PCI_MEM_OFFSET (IOP331_PCI_LOWER_MEM_PA - IOP331_PCI_LOWER_MEM_BA) - -/* - * IOP331 chipset registers - */ -#define IOP331_VIRT_MEM_BASE 0xfeffe000 /* chip virtual mem address*/ -#define IOP331_PHYS_MEM_BASE 0xffffe000 /* chip physical memory address */ -#define IOP331_REG_ADDR(reg) (IOP331_VIRT_MEM_BASE | (reg)) - -/* Reserved 0x00000000 through 0x000000FF */ - -/* Address Translation Unit 0x00000100 through 0x000001FF */ -#define IOP331_ATUVID (volatile u16 *)IOP331_REG_ADDR(0x00000100) -#define IOP331_ATUDID (volatile u16 *)IOP331_REG_ADDR(0x00000102) -#define IOP331_ATUCMD (volatile u16 *)IOP331_REG_ADDR(0x00000104) -#define IOP331_ATUSR (volatile u16 *)IOP331_REG_ADDR(0x00000106) -#define IOP331_ATURID (volatile u8 *)IOP331_REG_ADDR(0x00000108) -#define IOP331_ATUCCR (volatile u32 *)IOP331_REG_ADDR(0x00000109) -#define IOP331_ATUCLSR (volatile u8 *)IOP331_REG_ADDR(0x0000010C) -#define IOP331_ATULT (volatile u8 *)IOP331_REG_ADDR(0x0000010D) -#define IOP331_ATUHTR (volatile u8 *)IOP331_REG_ADDR(0x0000010E) -#define IOP331_ATUBIST (volatile u8 *)IOP331_REG_ADDR(0x0000010F) -#define IOP331_IABAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000110) -#define IOP331_IAUBAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000114) -#define IOP331_IABAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000118) -#define IOP331_IAUBAR1 (volatile u32 *)IOP331_REG_ADDR(0x0000011C) -#define IOP331_IABAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000120) -#define IOP331_IAUBAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000124) -#define IOP331_ASVIR (volatile u16 *)IOP331_REG_ADDR(0x0000012C) -#define IOP331_ASIR (volatile u16 *)IOP331_REG_ADDR(0x0000012E) -#define IOP331_ERBAR (volatile u32 *)IOP331_REG_ADDR(0x00000130) -#define IOP331_ATU_CAPPTR (volatile u32 *)IOP331_REG_ADDR(0x00000134) -/* Reserved 0x00000138 through 0x0000013B */ -#define IOP331_ATUILR (volatile u8 *)IOP331_REG_ADDR(0x0000013C) -#define IOP331_ATUIPR (volatile u8 *)IOP331_REG_ADDR(0x0000013D) -#define IOP331_ATUMGNT (volatile u8 *)IOP331_REG_ADDR(0x0000013E) -#define IOP331_ATUMLAT (volatile u8 *)IOP331_REG_ADDR(0x0000013F) -#define IOP331_IALR0 (volatile u32 *)IOP331_REG_ADDR(0x00000140) -#define IOP331_IATVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000144) -#define IOP331_ERLR (volatile u32 *)IOP331_REG_ADDR(0x00000148) -#define IOP331_ERTVR (volatile u32 *)IOP331_REG_ADDR(0x0000014C) -#define IOP331_IALR1 (volatile u32 *)IOP331_REG_ADDR(0x00000150) -#define IOP331_IALR2 (volatile u32 *)IOP331_REG_ADDR(0x00000154) -#define IOP331_IATVR2 (volatile u32 *)IOP331_REG_ADDR(0x00000158) -#define IOP331_OIOWTVR (volatile u32 *)IOP331_REG_ADDR(0x0000015C) -#define IOP331_OMWTVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000160) -#define IOP331_OUMWTVR0 (volatile u32 *)IOP331_REG_ADDR(0x00000164) -#define IOP331_OMWTVR1 (volatile u32 *)IOP331_REG_ADDR(0x00000168) -#define IOP331_OUMWTVR1 (volatile u32 *)IOP331_REG_ADDR(0x0000016C) -/* Reserved 0x00000170 through 0x00000177*/ -#define IOP331_OUDWTVR (volatile u32 *)IOP331_REG_ADDR(0x00000178) -/* Reserved 0x0000017C through 0x0000017F*/ -#define IOP331_ATUCR (volatile u32 *)IOP331_REG_ADDR(0x00000180) -#define IOP331_PCSR (volatile u32 *)IOP331_REG_ADDR(0x00000184) -#define IOP331_ATUISR (volatile u32 *)IOP331_REG_ADDR(0x00000188) -#define IOP331_ATUIMR (volatile u32 *)IOP331_REG_ADDR(0x0000018C) -#define IOP331_IABAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000190) -#define IOP331_IAUBAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000194) -#define IOP331_IALR3 (volatile u32 *)IOP331_REG_ADDR(0x00000198) -#define IOP331_IATVR3 (volatile u32 *)IOP331_REG_ADDR(0x0000019C) -/* Reserved 0x000001A0 through 0x000001A3*/ -#define IOP331_OCCAR (volatile u32 *)IOP331_REG_ADDR(0x000001A4) -/* Reserved 0x000001A8 through 0x000001AB*/ -#define IOP331_OCCDR (volatile u32 *)IOP331_REG_ADDR(0x000001AC) -/* Reserved 0x000001B0 through 0x000001BB*/ -#define IOP331_VPDCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001B8) -#define IOP331_VPDNXTP (volatile u8 *)IOP331_REG_ADDR(0x000001B9) -#define IOP331_VPDAR (volatile u16 *)IOP331_REG_ADDR(0x000001BA) -#define IOP331_VPDDR (volatile u32 *)IOP331_REG_ADDR(0x000001BC) -#define IOP331_PMCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001C0) -#define IOP331_PMNEXT (volatile u8 *)IOP331_REG_ADDR(0x000001C1) -#define IOP331_APMCR (volatile u16 *)IOP331_REG_ADDR(0x000001C2) -#define IOP331_APMCSR (volatile u16 *)IOP331_REG_ADDR(0x000001C4) -/* Reserved 0x000001C6 through 0x000001CF */ -#define IOP331_MSICAPID (volatile u8 *)IOP331_REG_ADDR(0x000001D0) -#define IOP331_MSINXTP (volatile u8 *)IOP331_REG_ADDR(0x000001D1) -#define IOP331_MSIMCR (volatile u16 *)IOP331_REG_ADDR(0x000001D2) -#define IOP331_MSIMAR (volatile u32 *)IOP331_REG_ADDR(0x000001D4) -#define IOP331_MSIMUAR (volatile u32 *)IOP331_REG_ADDR(0x000001D8) -#define IOP331_MSIMDR (volatile u32 *)IOP331_REG_ADDR(0x000001DC) -#define IOP331_PCIXCAPID (volatile u8 *)IOP331_REG_ADDR(0x000001E0) -#define IOP331_PCIXNEXT (volatile u8 *)IOP331_REG_ADDR(0x000001E1) -#define IOP331_PCIXCMD (volatile u16 *)IOP331_REG_ADDR(0x000001E2) -#define IOP331_PCIXSR (volatile u32 *)IOP331_REG_ADDR(0x000001E4) -#define IOP331_PCIIRSR (volatile u32 *)IOP331_REG_ADDR(0x000001EC) - -/* Messaging Unit 0x00000300 through 0x000003FF */ - -/* Reserved 0x00000300 through 0x0000030c */ -#define IOP331_IMR0 (volatile u32 *)IOP331_REG_ADDR(0x00000310) -#define IOP331_IMR1 (volatile u32 *)IOP331_REG_ADDR(0x00000314) -#define IOP331_OMR0 (volatile u32 *)IOP331_REG_ADDR(0x00000318) -#define IOP331_OMR1 (volatile u32 *)IOP331_REG_ADDR(0x0000031C) -#define IOP331_IDR (volatile u32 *)IOP331_REG_ADDR(0x00000320) -#define IOP331_IISR (volatile u32 *)IOP331_REG_ADDR(0x00000324) -#define IOP331_IIMR (volatile u32 *)IOP331_REG_ADDR(0x00000328) -#define IOP331_ODR (volatile u32 *)IOP331_REG_ADDR(0x0000032C) -#define IOP331_OISR (volatile u32 *)IOP331_REG_ADDR(0x00000330) -#define IOP331_OIMR (volatile u32 *)IOP331_REG_ADDR(0x00000334) -/* Reserved 0x00000338 through 0x0000034F */ -#define IOP331_MUCR (volatile u32 *)IOP331_REG_ADDR(0x00000350) -#define IOP331_QBAR (volatile u32 *)IOP331_REG_ADDR(0x00000354) -/* Reserved 0x00000358 through 0x0000035C */ -#define IOP331_IFHPR (volatile u32 *)IOP331_REG_ADDR(0x00000360) -#define IOP331_IFTPR (volatile u32 *)IOP331_REG_ADDR(0x00000364) -#define IOP331_IPHPR (volatile u32 *)IOP331_REG_ADDR(0x00000368) -#define IOP331_IPTPR (volatile u32 *)IOP331_REG_ADDR(0x0000036C) -#define IOP331_OFHPR (volatile u32 *)IOP331_REG_ADDR(0x00000370) -#define IOP331_OFTPR (volatile u32 *)IOP331_REG_ADDR(0x00000374) -#define IOP331_OPHPR (volatile u32 *)IOP331_REG_ADDR(0x00000378) -#define IOP331_OPTPR (volatile u32 *)IOP331_REG_ADDR(0x0000037C) -#define IOP331_IAR (volatile u32 *)IOP331_REG_ADDR(0x00000380) -/* Reserved 0x00000384 through 0x000003FF */ - -/* DMA Controller 0x00000400 through 0x000004FF */ -#define IOP331_DMA0_CCR (volatile u32 *)IOP331_REG_ADDR(0x00000400) -#define IOP331_DMA0_CSR (volatile u32 *)IOP331_REG_ADDR(0x00000404) -#define IOP331_DMA0_DAR (volatile u32 *)IOP331_REG_ADDR(0x0000040C) -#define IOP331_DMA0_NDAR (volatile u32 *)IOP331_REG_ADDR(0x00000410) -#define IOP331_DMA0_PADR (volatile u32 *)IOP331_REG_ADDR(0x00000414) -#define IOP331_DMA0_PUADR (volatile u32 *)IOP331_REG_ADDR(0x00000418) -#define IOP331_DMA0_LADR (volatile u32 *)IOP331_REG_ADDR(0X0000041C) -#define IOP331_DMA0_BCR (volatile u32 *)IOP331_REG_ADDR(0x00000420) -#define IOP331_DMA0_DCR (volatile u32 *)IOP331_REG_ADDR(0x00000424) -/* Reserved 0x00000428 through 0x0000043C */ -#define IOP331_DMA1_CCR (volatile u32 *)IOP331_REG_ADDR(0x00000440) -#define IOP331_DMA1_CSR (volatile u32 *)IOP331_REG_ADDR(0x00000444) -#define IOP331_DMA1_DAR (volatile u32 *)IOP331_REG_ADDR(0x0000044C) -#define IOP331_DMA1_NDAR (volatile u32 *)IOP331_REG_ADDR(0x00000450) -#define IOP331_DMA1_PADR (volatile u32 *)IOP331_REG_ADDR(0x00000454) -#define IOP331_DMA1_PUADR (volatile u32 *)IOP331_REG_ADDR(0x00000458) -#define IOP331_DMA1_LADR (volatile u32 *)IOP331_REG_ADDR(0x0000045C) -#define IOP331_DMA1_BCR (volatile u32 *)IOP331_REG_ADDR(0x00000460) -#define IOP331_DMA1_DCR (volatile u32 *)IOP331_REG_ADDR(0x00000464) -/* Reserved 0x00000468 through 0x000004FF */ - -/* Memory controller 0x00000500 through 0x0005FF */ - -/* Peripheral bus interface unit 0x00000680 through 0x0006FF */ -#define IOP331_PBCR (volatile u32 *)IOP331_REG_ADDR(0x00000680) -#define IOP331_PBISR (volatile u32 *)IOP331_REG_ADDR(0x00000684) -#define IOP331_PBBAR0 (volatile u32 *)IOP331_REG_ADDR(0x00000688) -#define IOP331_PBLR0 (volatile u32 *)IOP331_REG_ADDR(0x0000068C) -#define IOP331_PBBAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000690) -#define IOP331_PBLR1 (volatile u32 *)IOP331_REG_ADDR(0x00000694) -#define IOP331_PBBAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000698) -#define IOP331_PBLR2 (volatile u32 *)IOP331_REG_ADDR(0x0000069C) -#define IOP331_PBBAR3 (volatile u32 *)IOP331_REG_ADDR(0x000006A0) -#define IOP331_PBLR3 (volatile u32 *)IOP331_REG_ADDR(0x000006A4) -#define IOP331_PBBAR4 (volatile u32 *)IOP331_REG_ADDR(0x000006A8) -#define IOP331_PBLR4 (volatile u32 *)IOP331_REG_ADDR(0x000006AC) -#define IOP331_PBBAR5 (volatile u32 *)IOP331_REG_ADDR(0x000006B0) -#define IOP331_PBLR5 (volatile u32 *)IOP331_REG_ADDR(0x000006B4) -#define IOP331_PBDSCR (volatile u32 *)IOP331_REG_ADDR(0x000006B8) -/* Reserved 0x000006BC */ -#define IOP331_PMBR0 (volatile u32 *)IOP331_REG_ADDR(0x000006C0) -/* Reserved 0x000006C4 through 0x000006DC */ -#define IOP331_PMBR1 (volatile u32 *)IOP331_REG_ADDR(0x000006E0) -#define IOP331_PMBR2 (volatile u32 *)IOP331_REG_ADDR(0x000006E4) - -#define IOP331_PBCR_EN 0x1 - -#define IOP331_PBISR_BOOR_ERR 0x1 - - - -/* Peripheral performance monitoring unit 0x00000700 through 0x00077F */ -/* Internal arbitration unit 0x00000780 through 0x0007BF */ - -/* Interrupt Controller */ -#define IOP331_INTCTL0 (volatile u32 *)IOP331_REG_ADDR(0x00000790) -#define IOP331_INTCTL1 (volatile u32 *)IOP331_REG_ADDR(0x00000794) -#define IOP331_INTSTR0 (volatile u32 *)IOP331_REG_ADDR(0x00000798) -#define IOP331_INTSTR1 (volatile u32 *)IOP331_REG_ADDR(0x0000079C) -#define IOP331_IINTSRC0 (volatile u32 *)IOP331_REG_ADDR(0x000007A0) -#define IOP331_IINTSRC1 (volatile u32 *)IOP331_REG_ADDR(0x000007A4) -#define IOP331_FINTSRC0 (volatile u32 *)IOP331_REG_ADDR(0x000007A8) -#define IOP331_FINTSRC1 (volatile u32 *)IOP331_REG_ADDR(0x000007AC) -#define IOP331_IPR0 (volatile u32 *)IOP331_REG_ADDR(0x000007B0) -#define IOP331_IPR1 (volatile u32 *)IOP331_REG_ADDR(0x000007B4) -#define IOP331_IPR2 (volatile u32 *)IOP331_REG_ADDR(0x000007B8) -#define IOP331_IPR3 (volatile u32 *)IOP331_REG_ADDR(0x000007BC) -#define IOP331_INTBASE (volatile u32 *)IOP331_REG_ADDR(0x000007C0) -#define IOP331_INTSIZE (volatile u32 *)IOP331_REG_ADDR(0x000007C4) -#define IOP331_IINTVEC (volatile u32 *)IOP331_REG_ADDR(0x000007C8) -#define IOP331_FINTVEC (volatile u32 *)IOP331_REG_ADDR(0x000007CC) - - -/* Timers */ - -#define IOP331_TU_TMR0 (volatile u32 *)IOP331_REG_ADDR(0x000007D0) -#define IOP331_TU_TMR1 (volatile u32 *)IOP331_REG_ADDR(0x000007D4) - -#define IOP331_TMR_TC 0x01 -#define IOP331_TMR_EN 0x02 -#define IOP331_TMR_RELOAD 0x04 -#define IOP331_TMR_PRIVILEGED 0x09 - -#define IOP331_TMR_RATIO_1_1 0x00 -#define IOP331_TMR_RATIO_4_1 0x10 -#define IOP331_TMR_RATIO_8_1 0x20 -#define IOP331_TMR_RATIO_16_1 0x30 - -#define IOP331_TU_TCR0 (volatile u32 *)IOP331_REG_ADDR(0x000007D8) -#define IOP331_TU_TCR1 (volatile u32 *)IOP331_REG_ADDR(0x000007DC) -#define IOP331_TU_TRR0 (volatile u32 *)IOP331_REG_ADDR(0x000007E0) -#define IOP331_TU_TRR1 (volatile u32 *)IOP331_REG_ADDR(0x000007E4) -#define IOP331_TU_TISR (volatile u32 *)IOP331_REG_ADDR(0x000007E8) -#define IOP331_TU_WDTCR (volatile u32 *)IOP331_REG_ADDR(0x000007EC) - -#if defined(CONFIG_ARCH_IOP331) -#define IOP331_TICK_RATE 266000000 /* 266 MHz IB clock */ -#endif - -#if defined(CONFIG_IOP331_STEPD) || defined(CONFIG_ARCH_IQ80333) -#undef IOP331_TICK_RATE -#define IOP331_TICK_RATE 333000000 /* 333 Mhz IB clock */ -#endif - -/* Application accelerator unit 0x00000800 - 0x000008FF */ -#define IOP331_AAU_ACR (volatile u32 *)IOP331_REG_ADDR(0x00000800) -#define IOP331_AAU_ASR (volatile u32 *)IOP331_REG_ADDR(0x00000804) -#define IOP331_AAU_ADAR (volatile u32 *)IOP331_REG_ADDR(0x00000808) -#define IOP331_AAU_ANDAR (volatile u32 *)IOP331_REG_ADDR(0x0000080C) -#define IOP331_AAU_SAR1 (volatile u32 *)IOP331_REG_ADDR(0x00000810) -#define IOP331_AAU_SAR2 (volatile u32 *)IOP331_REG_ADDR(0x00000814) -#define IOP331_AAU_SAR3 (volatile u32 *)IOP331_REG_ADDR(0x00000818) -#define IOP331_AAU_SAR4 (volatile u32 *)IOP331_REG_ADDR(0x0000081C) -#define IOP331_AAU_SAR5 (volatile u32 *)IOP331_REG_ADDR(0x0000082C) -#define IOP331_AAU_SAR6 (volatile u32 *)IOP331_REG_ADDR(0x00000830) -#define IOP331_AAU_SAR7 (volatile u32 *)IOP331_REG_ADDR(0x00000834) -#define IOP331_AAU_SAR8 (volatile u32 *)IOP331_REG_ADDR(0x00000838) -#define IOP331_AAU_SAR9 (volatile u32 *)IOP331_REG_ADDR(0x00000840) -#define IOP331_AAU_SAR10 (volatile u32 *)IOP331_REG_ADDR(0x00000844) -#define IOP331_AAU_SAR11 (volatile u32 *)IOP331_REG_ADDR(0x00000848) -#define IOP331_AAU_SAR12 (volatile u32 *)IOP331_REG_ADDR(0x0000084C) -#define IOP331_AAU_SAR13 (volatile u32 *)IOP331_REG_ADDR(0x00000850) -#define IOP331_AAU_SAR14 (volatile u32 *)IOP331_REG_ADDR(0x00000854) -#define IOP331_AAU_SAR15 (volatile u32 *)IOP331_REG_ADDR(0x00000858) -#define IOP331_AAU_SAR16 (volatile u32 *)IOP331_REG_ADDR(0x0000085C) -#define IOP331_AAU_SAR17 (volatile u32 *)IOP331_REG_ADDR(0x00000864) -#define IOP331_AAU_SAR18 (volatile u32 *)IOP331_REG_ADDR(0x00000868) -#define IOP331_AAU_SAR19 (volatile u32 *)IOP331_REG_ADDR(0x0000086C) -#define IOP331_AAU_SAR20 (volatile u32 *)IOP331_REG_ADDR(0x00000870) -#define IOP331_AAU_SAR21 (volatile u32 *)IOP331_REG_ADDR(0x00000874) -#define IOP331_AAU_SAR22 (volatile u32 *)IOP331_REG_ADDR(0x00000878) -#define IOP331_AAU_SAR23 (volatile u32 *)IOP331_REG_ADDR(0x0000087C) -#define IOP331_AAU_SAR24 (volatile u32 *)IOP331_REG_ADDR(0x00000880) -#define IOP331_AAU_SAR25 (volatile u32 *)IOP331_REG_ADDR(0x00000888) -#define IOP331_AAU_SAR26 (volatile u32 *)IOP331_REG_ADDR(0x0000088C) -#define IOP331_AAU_SAR27 (volatile u32 *)IOP331_REG_ADDR(0x00000890) -#define IOP331_AAU_SAR28 (volatile u32 *)IOP331_REG_ADDR(0x00000894) -#define IOP331_AAU_SAR29 (volatile u32 *)IOP331_REG_ADDR(0x00000898) -#define IOP331_AAU_SAR30 (volatile u32 *)IOP331_REG_ADDR(0x0000089C) -#define IOP331_AAU_SAR31 (volatile u32 *)IOP331_REG_ADDR(0x000008A0) -#define IOP331_AAU_SAR32 (volatile u32 *)IOP331_REG_ADDR(0x000008A4) -#define IOP331_AAU_DAR (volatile u32 *)IOP331_REG_ADDR(0x00000820) -#define IOP331_AAU_ABCR (volatile u32 *)IOP331_REG_ADDR(0x00000824) -#define IOP331_AAU_ADCR (volatile u32 *)IOP331_REG_ADDR(0x00000828) -#define IOP331_AAU_EDCR0 (volatile u32 *)IOP331_REG_ADDR(0x0000083c) -#define IOP331_AAU_EDCR1 (volatile u32 *)IOP331_REG_ADDR(0x00000860) -#define IOP331_AAU_EDCR2 (volatile u32 *)IOP331_REG_ADDR(0x00000884) - - -#define IOP331_SPDSCR (volatile u32 *)IOP331_REG_ADDR(0x000015C0) -#define IOP331_PPDSCR (volatile u32 *)IOP331_REG_ADDR(0x000015C8) -/* SSP serial port unit 0x00001600 - 0x0000167F */ - -/* I2C bus interface unit 0x00001680 - 0x000016FF */ -/* for I2C bit defs see drivers/i2c/i2c-iop3xx.h */ - -#define IOP331_ICR0 (volatile u32 *)IOP331_REG_ADDR(0x00001680) -#define IOP331_ISR0 (volatile u32 *)IOP331_REG_ADDR(0x00001684) -#define IOP331_ISAR0 (volatile u32 *)IOP331_REG_ADDR(0x00001688) -#define IOP331_IDBR0 (volatile u32 *)IOP331_REG_ADDR(0x0000168C) -/* Reserved 0x00001690 */ -#define IOP331_IBMR0 (volatile u32 *)IOP331_REG_ADDR(0x00001694) -/* Reserved 0x00001698 */ -/* Reserved 0x0000169C */ -#define IOP331_ICR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A0) -#define IOP331_ISR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A4) -#define IOP331_ISAR1 (volatile u32 *)IOP331_REG_ADDR(0x000016A8) -#define IOP331_IDBR1 (volatile u32 *)IOP331_REG_ADDR(0x000016AC) -#define IOP331_IBMR1 (volatile u32 *)IOP331_REG_ADDR(0x000016B4) -/* Reserved 0x000016B8 through 0x000016FF */ - -/* 0x00001700 through 0x0000172C UART 0 */ - -/* Reserved 0x00001730 through 0x0000173F */ - -/* 0x00001740 through 0x0000176C UART 1 */ - -#define IOP331_UART0_PHYS (IOP331_PHYS_MEM_BASE | 0x00001700) /* UART #1 physical */ -#define IOP331_UART1_PHYS (IOP331_PHYS_MEM_BASE | 0x00001740) /* UART #2 physical */ -#define IOP331_UART0_VIRT (IOP331_VIRT_MEM_BASE | 0x00001700) /* UART #1 virtual addr */ -#define IOP331_UART1_VIRT (IOP331_VIRT_MEM_BASE | 0x00001740) /* UART #2 virtual addr */ - -/* Reserved 0x00001770 through 0x0000177F */ - -/* General Purpose I/O Registers */ -#define IOP331_GPOE (volatile u32 *)IOP331_REG_ADDR(0x00001780) -#define IOP331_GPID (volatile u32 *)IOP331_REG_ADDR(0x00001784) -#define IOP331_GPOD (volatile u32 *)IOP331_REG_ADDR(0x00001788) - -/* Reserved 0x0000178c through 0x000019ff */ - - -#ifndef __ASSEMBLY__ -extern void iop331_map_io(void); -extern void iop331_init_irq(void); -extern void iop331_time_init(void); -#endif - -#endif // _IOP331_HW_H_ diff --git a/include/asm-arm/arch-iop3xx/irqs.h b/include/asm-arm/arch-iop3xx/irqs.h deleted file mode 100644 index b2c03f4c269..00000000000 --- a/include/asm-arm/arch-iop3xx/irqs.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/irqs.h - * - * Copyright: (C) 2001-2003 MontaVista Software 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. - * - */ - -/* - * Chipset-specific bits - */ -#ifdef CONFIG_ARCH_IOP321 -#include "iop321-irqs.h" -#endif - -#ifdef CONFIG_ARCH_IOP331 -#include "iop331-irqs.h" -#endif diff --git a/include/asm-arm/arch-iop3xx/memory.h b/include/asm-arm/arch-iop3xx/memory.h deleted file mode 100644 index e43ebd98474..00000000000 --- a/include/asm-arm/arch-iop3xx/memory.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/memory.h - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#include <asm/hardware.h> - -/* - * Physical DRAM offset. - */ -#ifndef CONFIG_ARCH_IOP331 -#define PHYS_OFFSET UL(0xa0000000) -#else -#define PHYS_OFFSET UL(0x00000000) -#endif - -/* - * Virtual view <-> PCI DMA view memory address translations - * virt_to_bus: Used to translate the virtual address to an - * address suitable to be passed to set_dma_addr - * bus_to_virt: Used to convert an address for DMA operations - * to an address that the kernel can use. - */ -#if defined(CONFIG_ARCH_IOP321) - -#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP321_IATVR2)) | ((*IOP321_IABAR2) & 0xfffffff0)) -#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP321_IALR2)) | ( *IOP321_IATVR2))) - -#elif defined(CONFIG_ARCH_IOP331) - -#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP331_IATVR2)) | ((*IOP331_IABAR2) & 0xfffffff0)) -#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP331_IALR2)) | ( *IOP331_IATVR2))) - -#endif - -#endif diff --git a/include/asm-arm/arch-iop3xx/system.h b/include/asm-arm/arch-iop3xx/system.h deleted file mode 100644 index af6ae8cd36c..00000000000 --- a/include/asm-arm/arch-iop3xx/system.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/system.h - * - * Copyright (C) 2001 MontaVista Software, 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. - */ - -static inline void arch_idle(void) -{ - cpu_do_idle(); -} - - -static inline void arch_reset(char mode) -{ -#ifdef CONFIG_ARCH_IOP321 - *IOP321_PCSR = 0x30; -#endif - -#ifdef CONFIG_ARCH_IOP331 - *IOP331_PCSR = 0x30; -#endif - - if ( 1 && mode == 's') { - /* Jump into ROM at address 0 */ - cpu_reset(0); - } else { - /* No on-chip reset capability */ - cpu_reset(0); - } -} - diff --git a/include/asm-arm/arch-iop3xx/timex.h b/include/asm-arm/arch-iop3xx/timex.h deleted file mode 100644 index 14ca8d0f7b2..00000000000 --- a/include/asm-arm/arch-iop3xx/timex.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/timex.h - * - * IOP3xx architecture timex specifications - */ -#include <asm/hardware.h> - -#if defined(CONFIG_ARCH_IQ80321) || defined(CONFIG_ARCH_IQ31244) - -#define CLOCK_TICK_RATE IOP321_TICK_RATE - -#elif defined(CONFIG_ARCH_IQ80331) || defined(CONFIG_MACH_IQ80332) - -#define CLOCK_TICK_RATE IOP331_TICK_RATE - -#else - -#error "No IOP3xx timex information for this architecture" - -#endif diff --git a/include/asm-arm/arch-iop3xx/uncompress.h b/include/asm-arm/arch-iop3xx/uncompress.h deleted file mode 100644 index fbdd5af644f..00000000000 --- a/include/asm-arm/arch-iop3xx/uncompress.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/uncompress.h - */ -#include <asm/types.h> -#include <asm/mach-types.h> -#include <linux/serial_reg.h> -#include <asm/hardware.h> - -#ifdef CONFIG_ARCH_IOP321 -#define UTYPE unsigned char * -#elif defined(CONFIG_ARCH_IOP331) -#define UTYPE u32 * -#else -#error "Missing IOP3xx arch type def" -#endif - -static volatile UTYPE uart_base; - -#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE) - -static inline void putc(char c) -{ - while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE) - barrier(); - *uart_base = c; -} - -static inline void flush(void) -{ -} - -static __inline__ void __arch_decomp_setup(unsigned long arch_id) -{ - if(machine_is_iq80321()) - uart_base = (volatile UTYPE)IQ80321_UART; - else if(machine_is_iq31244()) - uart_base = (volatile UTYPE)IQ31244_UART; - else if(machine_is_iq80331() || machine_is_iq80332()) - uart_base = (volatile UTYPE)IOP331_UART0_PHYS; - else - uart_base = (volatile UTYPE)0xfe800000; -} - -/* - * nothing to do - */ -#define arch_decomp_setup() __arch_decomp_setup(arch_id) -#define arch_decomp_wdog() diff --git a/include/asm-arm/arch-iop3xx/vmalloc.h b/include/asm-arm/arch-iop3xx/vmalloc.h deleted file mode 100644 index 0f2f6847f93..00000000000 --- a/include/asm-arm/arch-iop3xx/vmalloc.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * linux/include/asm-arm/arch-iop3xx/vmalloc.h - */ - -/* - * Just any arbitrary offset to the start of the vmalloc VM area: the - * current 8MB value just means that there will be a 8MB "hole" after the - * physical memory until the kernel virtual memory starts. That means that - * any out-of-bounds memory accesses will hopefully be caught. - * The vmalloc() routines leaves a hole of 4kB between each vmalloced - * area for the same reason. ;) - */ -//#define VMALLOC_END (0xe8000000) -/* increase usable physical RAM to ~992M per RMK */ -#define VMALLOC_END (0xfe000000) - diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h index 13aee17b047..8d10a918769 100644 --- a/include/asm-arm/arch-ixp4xx/platform.h +++ b/include/asm-arm/arch-ixp4xx/platform.h @@ -90,6 +90,11 @@ struct ixp4xx_i2c_pins { struct sys_timer; /* + * Frequency of clock used for primary clocksource + */ +extern unsigned long ixp4xx_timer_freq; + +/* * Functions used by platform-level setup code */ extern void ixp4xx_map_io(void); diff --git a/include/asm-arm/arch-l7200/io.h b/include/asm-arm/arch-l7200/io.h index cd080d8384d..d744d97c18a 100644 --- a/include/asm-arm/arch-l7200/io.h +++ b/include/asm-arm/arch-l7200/io.h @@ -31,9 +31,9 @@ static inline unsigned int __arch_getw(unsigned long a) { unsigned int value; - __asm__ __volatile__("ldr%?h %0, [%1, #0] @ getw" + __asm__ __volatile__("ldrh %0, [%1, #0] @ getw" : "=&r" (value) - : "r" (a)); + : "r" (a) : "cc"); return value; } @@ -42,8 +42,8 @@ static inline unsigned int __arch_getw(unsigned long a) static inline void __arch_putw(unsigned int value, unsigned long a) { - __asm__ __volatile__("str%?h %0, [%1, #0] @ putw" - : : "r" (value), "r" (a)); + __asm__ __volatile__("strh %0, [%1, #0] @ putw" + : : "r" (value), "r" (a) : "cc"); } /* diff --git a/include/asm-arm/arch-omap/board-ams-delta.h b/include/asm-arm/arch-omap/board-ams-delta.h index 0070f6d3b75..9aee15d9714 100644 --- a/include/asm-arm/arch-omap/board-ams-delta.h +++ b/include/asm-arm/arch-omap/board-ams-delta.h @@ -50,9 +50,20 @@ #define AMS_DELTA_LATCH2_NAND_NWE 0x0020 #define AMS_DELTA_LATCH2_NAND_ALE 0x0040 #define AMS_DELTA_LATCH2_NAND_CLE 0x0080 +#define AMD_DELTA_LATCH2_KEYBRD_PWR 0x0100 +#define AMD_DELTA_LATCH2_KEYBRD_DATA 0x0200 +#define AMD_DELTA_LATCH2_SCARD_RSTIN 0x0400 +#define AMD_DELTA_LATCH2_SCARD_CMDVCC 0x0800 #define AMS_DELTA_LATCH2_MODEM_NRESET 0x1000 #define AMS_DELTA_LATCH2_MODEM_CODEC 0x2000 +#define AMS_DELTA_GPIO_PIN_KEYBRD_DATA 0 +#define AMS_DELTA_GPIO_PIN_KEYBRD_CLK 1 +#define AMS_DELTA_GPIO_PIN_MODEM_IRQ 2 +#define AMS_DELTA_GPIO_PIN_HOOK_SWITCH 4 +#define AMS_DELTA_GPIO_PIN_SCARD_NOFF 6 +#define AMS_DELTA_GPIO_PIN_SCARD_IO 7 +#define AMS_DELTA_GPIO_PIN_CONFIG 11 #define AMS_DELTA_GPIO_PIN_NAND_RB 12 #ifndef __ASSEMBLY__ diff --git a/include/asm-arm/arch-omap/clock.h b/include/asm-arm/arch-omap/clock.h index f83003f5287..fa688104990 100644 --- a/include/asm-arm/arch-omap/clock.h +++ b/include/asm-arm/arch-omap/clock.h @@ -45,6 +45,7 @@ struct clk_functions { struct clk * (*clk_get_parent)(struct clk *clk); void (*clk_allow_idle)(struct clk *clk); void (*clk_deny_idle)(struct clk *clk); + void (*clk_disable_unused)(struct clk *clk); }; extern unsigned int mpurate; diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h index 1b1b02307e7..d591d0585bb 100644 --- a/include/asm-arm/arch-omap/dma.h +++ b/include/asm-arm/arch-omap/dma.h @@ -331,6 +331,12 @@ enum omap_dma_color_mode { OMAP_DMA_TRANSPARENT_COPY }; +enum omap_dma_write_mode { + OMAP_DMA_WRITE_NON_POSTED = 0, + OMAP_DMA_WRITE_POSTED, + OMAP_DMA_WRITE_LAST_NON_POSTED +}; + struct omap_dma_channel_params { int data_type; /* data type 8,16,32 */ int elem_count; /* number of elements in a frame */ @@ -338,13 +344,13 @@ struct omap_dma_channel_params { int src_port; /* Only on OMAP1 REVISIT: Is this needed? */ int src_amode; /* constant , post increment, indexed , double indexed */ - int src_start; /* source address : physical */ + unsigned long src_start; /* source address : physical */ int src_ei; /* source element index */ int src_fi; /* source frame index */ int dst_port; /* Only on OMAP1 REVISIT: Is this needed? */ int dst_amode; /* constant , post increment, indexed , double indexed */ - int dst_start; /* source address : physical */ + unsigned long dst_start; /* source address : physical */ int dst_ei; /* source element index */ int dst_fi; /* source frame index */ @@ -356,7 +362,7 @@ struct omap_dma_channel_params { }; -extern void omap_set_dma_priority(int dst_port, int priority); +extern void omap_set_dma_priority(int lch, int dst_port, int priority); extern int omap_request_dma(int dev_id, const char *dev_name, void (* callback)(int lch, u16 ch_status, void *data), void *data, int *dma_ch); @@ -371,6 +377,7 @@ extern void omap_set_dma_transfer_params(int lch, int data_type, int dma_trigger, int src_or_dst_synch); extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color); +extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode); extern void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start, @@ -394,6 +401,9 @@ extern void omap_set_dma_params(int lch, extern void omap_dma_link_lch (int lch_head, int lch_queue); extern void omap_dma_unlink_lch (int lch_head, int lch_queue); +extern int omap_set_dma_callback(int lch, + void (* callback)(int lch, u16 ch_status, void *data), + void *data); extern dma_addr_t omap_get_dma_src_pos(int lch); extern dma_addr_t omap_get_dma_dst_pos(int lch); extern int omap_get_dma_src_addr_counter(int lch); diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h index 7a289ff0740..b5f3a71b899 100644 --- a/include/asm-arm/arch-omap/dmtimer.h +++ b/include/asm-arm/arch-omap/dmtimer.h @@ -52,6 +52,8 @@ int omap_dm_timer_init(void); struct omap_dm_timer *omap_dm_timer_request(void); struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); void omap_dm_timer_free(struct omap_dm_timer *timer); +void omap_dm_timer_enable(struct omap_dm_timer *timer); +void omap_dm_timer_disable(struct omap_dm_timer *timer); int omap_dm_timer_get_irq(struct omap_dm_timer *timer); diff --git a/include/asm-arm/arch-omap/gpmc.h b/include/asm-arm/arch-omap/gpmc.h index 1a0a5207822..7c03ef6c14c 100644 --- a/include/asm-arm/arch-omap/gpmc.h +++ b/include/asm-arm/arch-omap/gpmc.h @@ -85,7 +85,7 @@ extern void gpmc_cs_write_reg(int cs, int idx, u32 val); extern u32 gpmc_cs_read_reg(int cs, int idx); extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk); extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t); -extern unsigned long gpmc_cs_get_base_addr(int cs); - +extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); +extern void gpmc_cs_free(int cs); #endif diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h index 2542495d8a4..c5bb05a69b8 100644 --- a/include/asm-arm/arch-omap/irqs.h +++ b/include/asm-arm/arch-omap/irqs.h @@ -237,6 +237,7 @@ #define INT_24XX_SDMA_IRQ1 13 #define INT_24XX_SDMA_IRQ2 14 #define INT_24XX_SDMA_IRQ3 15 +#define INT_24XX_CAM_IRQ 24 #define INT_24XX_DSS_IRQ 25 #define INT_24XX_GPIO_BANK1 29 #define INT_24XX_GPIO_BANK2 30 @@ -261,6 +262,7 @@ #define INT_24XX_UART1_IRQ 72 #define INT_24XX_UART2_IRQ 73 #define INT_24XX_UART3_IRQ 74 +#define INT_24XX_MMC_IRQ 83 /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and * 16 MPUIO lines */ diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h index 679869c5e68..828cc5c114e 100644 --- a/include/asm-arm/arch-omap/mux.h +++ b/include/asm-arm/arch-omap/mux.h @@ -320,6 +320,17 @@ enum omap1xxx_index { P15_1610_UWIRE_CS3, N15_1610_UWIRE_CS1, + /* OMAP-1610 SPI */ + U19_1610_SPIF_SCK, + U18_1610_SPIF_DIN, + P20_1610_SPIF_DIN, + W21_1610_SPIF_DOUT, + R18_1610_SPIF_DOUT, + N14_1610_SPIF_CS0, + N15_1610_SPIF_CS1, + T19_1610_SPIF_CS2, + P15_1610_SPIF_CS3, + /* OMAP-1610 Flash */ L3_1610_FLASH_CS2B_OE, M8_1610_FLASH_CS2B_WE, @@ -461,6 +472,20 @@ enum omap24xx_index { K15_24XX_UART3_TX, K14_24XX_UART3_RX, + /* MMC/SDIO */ + G19_24XX_MMC_CLKO, + H18_24XX_MMC_CMD, + F20_24XX_MMC_DAT0, + H14_24XX_MMC_DAT1, + E19_24XX_MMC_DAT2, + D19_24XX_MMC_DAT3, + F19_24XX_MMC_DAT_DIR0, + E20_24XX_MMC_DAT_DIR1, + F18_24XX_MMC_DAT_DIR2, + E18_24XX_MMC_DAT_DIR3, + G18_24XX_MMC_CMD_DIR, + H15_24XX_MMC_CLKI, + /* Keypad GPIO*/ T19_24XX_KBR0, R19_24XX_KBR1, diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h index 3661e465b0a..7ac22483697 100644 --- a/include/asm-arm/arch-s3c2410/dma.h +++ b/include/asm-arm/arch-s3c2410/dma.h @@ -23,6 +23,39 @@ #define MAX_DMA_ADDRESS 0x40000000 #define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ +/* We use `virtual` dma channels to hide the fact we have only a limited + * number of DMA channels, and not of all of them (dependant on the device) + * can be attached to any DMA source. We therefore let the DMA core handle + * the allocation of hardware channels to clients. +*/ + +enum dma_ch { + DMACH_XD0, + DMACH_XD1, + DMACH_SDI, + DMACH_SPI0, + DMACH_SPI1, + DMACH_UART0, + DMACH_UART1, + DMACH_UART2, + DMACH_TIMER, + DMACH_I2S_IN, + DMACH_I2S_OUT, + DMACH_PCM_IN, + DMACH_PCM_OUT, + DMACH_MIC_IN, + DMACH_USB_EP1, + DMACH_USB_EP2, + DMACH_USB_EP3, + DMACH_USB_EP4, + DMACH_UART0_SRC2, /* s3c2412 second uart sources */ + DMACH_UART1_SRC2, + DMACH_UART2_SRC2, + DMACH_MAX, /* the end entry */ +}; + +#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ + /* we have 4 dma channels */ #define S3C2410_DMA_CHANNELS (4) @@ -149,6 +182,8 @@ struct s3c2410_dma_stats { unsigned long timeout_failed; }; +struct s3c2410_dma_map; + /* struct s3c2410_dma_chan * * full state information for each DMA channel @@ -174,6 +209,8 @@ struct s3c2410_dma_chan { unsigned long load_timeout; unsigned int flags; /* channel flags */ + struct s3c24xx_dma_map *map; /* channel hw maps */ + /* channel's hardware position and configuration */ void __iomem *regs; /* channels registers */ void __iomem *addr_reg; /* data address register */ @@ -283,6 +320,7 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn); #define S3C2410_DMA_DCSRC (0x18) #define S3C2410_DMA_DCDST (0x1C) #define S3C2410_DMA_DMASKTRIG (0x20) +#define S3C2412_DMA_DMAREQSEL (0x24) #define S3C2410_DISRCC_INC (1<<0) #define S3C2410_DISRCC_APB (1<<1) @@ -349,4 +387,32 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn); #define S3C2440_DCON_CH3_PCMOUT (6<<24) #endif +#ifdef CONFIG_CPU_S3C2412 + +#define S3C2412_DMAREQSEL_SRC(x) ((x)<<1) + +#define S3C2412_DMAREQSEL_HW (1) + +#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0) +#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1) +#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2) +#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3) +#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4) +#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5) +#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9) +#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10) +#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13) +#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14) +#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15) +#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16) +#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17) +#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18) +#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19) +#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20) +#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21) +#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22) +#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23) +#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24) + +#endif #endif /* __ASM_ARCH_DMA_H */ diff --git a/include/asm-arm/arch-s3c2410/map.h b/include/asm-arm/arch-s3c2410/map.h index 27ba0ac3fdd..7895042d176 100644 --- a/include/asm-arm/arch-s3c2410/map.h +++ b/include/asm-arm/arch-s3c2410/map.h @@ -160,6 +160,11 @@ #define S3C2440_PA_CAMIF (0x4F000000) #define S3C2440_SZ_CAMIF SZ_1M +/* AC97 */ + +#define S3C2440_PA_AC97 (0x5B000000) +#define S3C2440_SZ_AC97 SZ_1M + /* ISA style IO, for each machine to sort out mappings for, if it * implements it. We reserve two 16M regions for ISA. */ diff --git a/include/asm-arm/arch-s3c2410/osiris-map.h b/include/asm-arm/arch-s3c2410/osiris-map.h index e2d406218ae..a14164dfa52 100644 --- a/include/asm-arm/arch-s3c2410/osiris-map.h +++ b/include/asm-arm/arch-s3c2410/osiris-map.h @@ -18,22 +18,22 @@ /* start peripherals off after the S3C2410 */ -#define OSIRIS_IOADDR(x) (S3C2410_ADDR((x) + 0x05000000)) +#define OSIRIS_IOADDR(x) (S3C2410_ADDR((x) + 0x04000000)) -#define OSIRIS_PA_CPLD (S3C2410_CS1 | (3<<25)) +#define OSIRIS_PA_CPLD (S3C2410_CS1 | (1<<26)) /* we put the CPLD registers next, to get them out of the way */ -#define OSIRIS_VA_CTRL1 OSIRIS_IOADDR(0x00000000) /* 0x01300000 */ +#define OSIRIS_VA_CTRL1 OSIRIS_IOADDR(0x00000000) #define OSIRIS_PA_CTRL1 (OSIRIS_PA_CPLD) -#define OSIRIS_VA_CTRL2 OSIRIS_IOADDR(0x00100000) /* 0x01400000 */ -#define OSIRIS_PA_CTRL2 (OSIRIS_PA_CPLD + (1<<24)) +#define OSIRIS_VA_CTRL2 OSIRIS_IOADDR(0x00100000) +#define OSIRIS_PA_CTRL2 (OSIRIS_PA_CPLD + (1<<23)) -#define OSIRIS_VA_CTRL3 OSIRIS_IOADDR(0x00200000) /* 0x01500000 */ -#define OSIRIS_PA_CTRL3 (OSIRIS_PA_CPLD + (2<<24)) +#define OSIRIS_VA_CTRL3 OSIRIS_IOADDR(0x00200000) +#define OSIRIS_PA_CTRL3 (OSIRIS_PA_CPLD + (2<<23)) -#define OSIRIS_VA_CTRL4 OSIRIS_IOADDR(0x00300000) /* 0x01600000 */ -#define OSIRIS_PA_CTRL4 (OSIRIS_PA_CPLD + (3<<24)) +#define OSIRIS_VA_CTRL4 OSIRIS_IOADDR(0x00300000) +#define OSIRIS_PA_CTRL4 (OSIRIS_PA_CPLD + (3<<23)) #endif /* __ASM_ARCH_OSIRISMAP_H */ diff --git a/include/asm-arm/arch-s3c2410/regs-ac97.h b/include/asm-arm/arch-s3c2410/regs-ac97.h new file mode 100644 index 00000000000..bdd6a4f93d7 --- /dev/null +++ b/include/asm-arm/arch-s3c2410/regs-ac97.h @@ -0,0 +1,23 @@ +/* linux/include/asm-arm/arch-s3c2410/regs-ac97.h + * + * Copyright (c) 2006 Simtec Electronics <linux@simtec.co.uk> + * http://www.simtec.co.uk/products/SWLINUX/ + * + * 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. + * + * S3C2440 AC97 Controller +*/ + +#ifndef __ASM_ARCH_REGS_AC97_H +#define __ASM_ARCH_REGS_AC97_H __FILE__ + +#define S3C_AC97_GLBCTRL (0x00) +#define S3C_AC97_GLBSTAT (0x04) +#define S3C_AC97_CODEC_CMD (0x08) +#define S3C_AC97_PCM_ADDR (0x10) +#define S3C_AC97_PCM_DATA (0x18) +#define S3C_AC97_MIC_DATA (0x1C) + +#endif /* __ASM_ARCH_REGS_AC97_H */ diff --git a/include/asm-arm/arch-s3c2410/regs-lcd.h b/include/asm-arm/arch-s3c2410/regs-lcd.h index b306d6e3135..6d7881c8cfc 100644 --- a/include/asm-arm/arch-s3c2410/regs-lcd.h +++ b/include/asm-arm/arch-s3c2410/regs-lcd.h @@ -63,6 +63,8 @@ #define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F) #define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF) +/* LDCCON4 changes for STN mode on the S3C2412 */ + #define S3C2410_LCDCON4_MVAL(x) ((x) << 8) #define S3C2410_LCDCON4_HSPW(x) ((x) << 0) #define S3C2410_LCDCON4_WLH(x) ((x) << 0) @@ -113,10 +115,38 @@ #define S3C2410_LCDINT_FRSYNC (1<<1) #define S3C2410_LCDINT_FICNT (1<<0) +/* s3c2442 extra stn registers */ + +#define S3C2442_REDLUT S3C2410_LCDREG(0x20) +#define S3C2442_GREENLUT S3C2410_LCDREG(0x24) +#define S3C2442_BLUELUT S3C2410_LCDREG(0x28) +#define S3C2442_DITHMODE S3C2410_LCDREG(0x20) + #define S3C2410_LPCSEL S3C2410_LCDREG(0x60) #define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4)) +/* S3C2412 registers */ + +#define S3C2412_TPAL S3C2410_LCDREG(0x20) + +#define S3C2412_LCDINTPND S3C2410_LCDREG(0x24) +#define S3C2412_LCDSRCPND S3C2410_LCDREG(0x28) +#define S3C2412_LCDINTMSK S3C2410_LCDREG(0x2C) + +#define S3C2412_TCONSEL S3C2410_LCDREG(0x30) + +#define S3C2412_LCDCON6 S3C2410_LCDREG(0x34) +#define S3C2412_LCDCON7 S3C2410_LCDREG(0x38) +#define S3C2412_LCDCON8 S3C2410_LCDREG(0x3C) +#define S3C2412_LCDCON9 S3C2410_LCDREG(0x40) + +#define S3C2412_REDLUT(x) S3C2410_LCDREG(0x44 + ((x)*4)) +#define S3C2412_GREENLUT(x) S3C2410_LCDREG(0x60 + ((x)*4)) +#define S3C2412_BLUELUT(x) S3C2410_LCDREG(0x98 + ((x)*4)) + +#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4)) + #endif /* ___ASM_ARCH_REGS_LCD_H */ diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h index 4b0ce3e7de9..ea88aa6bfc7 100644 --- a/include/asm-arm/atomic.h +++ b/include/asm-arm/atomic.h @@ -128,10 +128,10 @@ static inline int atomic_add_return(int i, atomic_t *v) unsigned long flags; int val; - local_irq_save(flags); + raw_local_irq_save(flags); val = v->counter; v->counter = val += i; - local_irq_restore(flags); + raw_local_irq_restore(flags); return val; } @@ -141,10 +141,10 @@ static inline int atomic_sub_return(int i, atomic_t *v) unsigned long flags; int val; - local_irq_save(flags); + raw_local_irq_save(flags); val = v->counter; v->counter = val -= i; - local_irq_restore(flags); + raw_local_irq_restore(flags); return val; } @@ -154,11 +154,11 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) int ret; unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); ret = v->counter; if (likely(ret == old)) v->counter = new; - local_irq_restore(flags); + raw_local_irq_restore(flags); return ret; } @@ -167,9 +167,9 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); *addr &= ~mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); } #endif /* __LINUX_ARM_ARCH__ */ diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h index 0ac54b1a8ba..b41831b6432 100644 --- a/include/asm-arm/bitops.h +++ b/include/asm-arm/bitops.h @@ -37,9 +37,9 @@ static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long * p += bit >> 5; - local_irq_save(flags); + raw_local_irq_save(flags); *p |= mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); } static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p) @@ -49,9 +49,9 @@ static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long p += bit >> 5; - local_irq_save(flags); + raw_local_irq_save(flags); *p &= ~mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); } static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p) @@ -61,9 +61,9 @@ static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned lon p += bit >> 5; - local_irq_save(flags); + raw_local_irq_save(flags); *p ^= mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); } static inline int @@ -75,10 +75,10 @@ ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p) p += bit >> 5; - local_irq_save(flags); + raw_local_irq_save(flags); res = *p; *p = res | mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); return res & mask; } @@ -92,10 +92,10 @@ ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p) p += bit >> 5; - local_irq_save(flags); + raw_local_irq_save(flags); res = *p; *p = res & ~mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); return res & mask; } @@ -109,10 +109,10 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p) p += bit >> 5; - local_irq_save(flags); + raw_local_irq_save(flags); res = *p; *p = res ^ mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); return res & mask; } diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index e4a2569c636..f0845646aac 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -25,7 +25,7 @@ #undef _CACHE #undef MULTI_CACHE -#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) +#if defined(CONFIG_CPU_CACHE_V3) # ifdef _CACHE # define MULTI_CACHE 1 # else @@ -33,7 +33,7 @@ # endif #endif -#if defined(CONFIG_CPU_ARM720T) +#if defined(CONFIG_CPU_CACHE_V4) # ifdef _CACHE # define MULTI_CACHE 1 # else @@ -54,7 +54,23 @@ # endif #endif -#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) +#if defined(CONFIG_CPU_ARM940T) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm940 +# endif +#endif + +#if defined(CONFIG_CPU_ARM946E) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm946 +# endif +#endif + +#if defined(CONFIG_CPU_CACHE_V4WB) # ifdef _CACHE # define MULTI_CACHE 1 # else diff --git a/include/asm-arm/flat.h b/include/asm-arm/flat.h new file mode 100644 index 00000000000..96694647858 --- /dev/null +++ b/include/asm-arm/flat.h @@ -0,0 +1,16 @@ +/* + * include/asm-arm/flat.h -- uClinux flat-format executables + */ + +#ifndef __ARM_FLAT_H__ +#define __ARM_FLAT_H__ + +#define flat_stack_align(sp) /* nothing needed */ +#define flat_argvp_envp_on_stack() 1 +#define flat_old_ram_flag(flags) (flags) +#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) +#define flat_get_addr_from_rp(rp, relval, flags) get_unaligned(rp) +#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) +#define flat_get_relocate_addr(rel) (rel) + +#endif /* __ARM_FLAT_H__ */ diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h new file mode 100644 index 00000000000..1018a7486ab --- /dev/null +++ b/include/asm-arm/hardware/iop3xx.h @@ -0,0 +1,301 @@ +/* + * include/asm-arm/hardware/iop3xx.h + * + * Intel IOP32X and IOP33X register definitions + * + * Author: Rory Bolt <rorybolt@pacbell.net> + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * 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 __IOP3XX_H +#define __IOP3XX_H + +/* + * IOP3XX GPIO handling + */ +#define GPIO_IN 0 +#define GPIO_OUT 1 +#define GPIO_LOW 0 +#define GPIO_HIGH 1 +#define IOP3XX_GPIO_LINE(x) (x) + +#ifndef __ASSEMBLY__ +extern void gpio_line_config(int line, int direction); +extern int gpio_line_get(int line); +extern void gpio_line_set(int line, int value); +#endif + + +/* + * IOP3XX processor registers + */ +#define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000 +#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfeffe000 +#define IOP3XX_PERIPHERAL_SIZE 0x00002000 +#define IOP3XX_REG_ADDR(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + (reg)) + +/* Address Translation Unit */ +#define IOP3XX_ATUVID (volatile u16 *)IOP3XX_REG_ADDR(0x0100) +#define IOP3XX_ATUDID (volatile u16 *)IOP3XX_REG_ADDR(0x0102) +#define IOP3XX_ATUCMD (volatile u16 *)IOP3XX_REG_ADDR(0x0104) +#define IOP3XX_ATUSR (volatile u16 *)IOP3XX_REG_ADDR(0x0106) +#define IOP3XX_ATURID (volatile u8 *)IOP3XX_REG_ADDR(0x0108) +#define IOP3XX_ATUCCR (volatile u32 *)IOP3XX_REG_ADDR(0x0109) +#define IOP3XX_ATUCLSR (volatile u8 *)IOP3XX_REG_ADDR(0x010c) +#define IOP3XX_ATULT (volatile u8 *)IOP3XX_REG_ADDR(0x010d) +#define IOP3XX_ATUHTR (volatile u8 *)IOP3XX_REG_ADDR(0x010e) +#define IOP3XX_ATUBIST (volatile u8 *)IOP3XX_REG_ADDR(0x010f) +#define IOP3XX_IABAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0110) +#define IOP3XX_IAUBAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0114) +#define IOP3XX_IABAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0118) +#define IOP3XX_IAUBAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x011c) +#define IOP3XX_IABAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0120) +#define IOP3XX_IAUBAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0124) +#define IOP3XX_ASVIR (volatile u16 *)IOP3XX_REG_ADDR(0x012c) +#define IOP3XX_ASIR (volatile u16 *)IOP3XX_REG_ADDR(0x012e) +#define IOP3XX_ERBAR (volatile u32 *)IOP3XX_REG_ADDR(0x0130) +#define IOP3XX_ATUILR (volatile u8 *)IOP3XX_REG_ADDR(0x013c) +#define IOP3XX_ATUIPR (volatile u8 *)IOP3XX_REG_ADDR(0x013d) +#define IOP3XX_ATUMGNT (volatile u8 *)IOP3XX_REG_ADDR(0x013e) +#define IOP3XX_ATUMLAT (volatile u8 *)IOP3XX_REG_ADDR(0x013f) +#define IOP3XX_IALR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0140) +#define IOP3XX_IATVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0144) +#define IOP3XX_ERLR (volatile u32 *)IOP3XX_REG_ADDR(0x0148) +#define IOP3XX_ERTVR (volatile u32 *)IOP3XX_REG_ADDR(0x014c) +#define IOP3XX_IALR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0150) +#define IOP3XX_IALR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0154) +#define IOP3XX_IATVR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0158) +#define IOP3XX_OIOWTVR (volatile u32 *)IOP3XX_REG_ADDR(0x015c) +#define IOP3XX_OMWTVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0160) +#define IOP3XX_OUMWTVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0164) +#define IOP3XX_OMWTVR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0168) +#define IOP3XX_OUMWTVR1 (volatile u32 *)IOP3XX_REG_ADDR(0x016c) +#define IOP3XX_OUDWTVR (volatile u32 *)IOP3XX_REG_ADDR(0x0178) +#define IOP3XX_ATUCR (volatile u32 *)IOP3XX_REG_ADDR(0x0180) +#define IOP3XX_PCSR (volatile u32 *)IOP3XX_REG_ADDR(0x0184) +#define IOP3XX_ATUISR (volatile u32 *)IOP3XX_REG_ADDR(0x0188) +#define IOP3XX_ATUIMR (volatile u32 *)IOP3XX_REG_ADDR(0x018c) +#define IOP3XX_IABAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0190) +#define IOP3XX_IAUBAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0194) +#define IOP3XX_IALR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0198) +#define IOP3XX_IATVR3 (volatile u32 *)IOP3XX_REG_ADDR(0x019c) +#define IOP3XX_OCCAR (volatile u32 *)IOP3XX_REG_ADDR(0x01a4) +#define IOP3XX_OCCDR (volatile u32 *)IOP3XX_REG_ADDR(0x01ac) +#define IOP3XX_PDSCR (volatile u32 *)IOP3XX_REG_ADDR(0x01bc) +#define IOP3XX_PMCAPID (volatile u8 *)IOP3XX_REG_ADDR(0x01c0) +#define IOP3XX_PMNEXT (volatile u8 *)IOP3XX_REG_ADDR(0x01c1) +#define IOP3XX_APMCR (volatile u16 *)IOP3XX_REG_ADDR(0x01c2) +#define IOP3XX_APMCSR (volatile u16 *)IOP3XX_REG_ADDR(0x01c4) +#define IOP3XX_PCIXCAPID (volatile u8 *)IOP3XX_REG_ADDR(0x01e0) +#define IOP3XX_PCIXNEXT (volatile u8 *)IOP3XX_REG_ADDR(0x01e1) +#define IOP3XX_PCIXCMD (volatile u16 *)IOP3XX_REG_ADDR(0x01e2) +#define IOP3XX_PCIXSR (volatile u32 *)IOP3XX_REG_ADDR(0x01e4) +#define IOP3XX_PCIIRSR (volatile u32 *)IOP3XX_REG_ADDR(0x01ec) + +/* Messaging Unit */ +#define IOP3XX_IMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0310) +#define IOP3XX_IMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0314) +#define IOP3XX_OMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0318) +#define IOP3XX_OMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x031c) +#define IOP3XX_IDR (volatile u32 *)IOP3XX_REG_ADDR(0x0320) +#define IOP3XX_IISR (volatile u32 *)IOP3XX_REG_ADDR(0x0324) +#define IOP3XX_IIMR (volatile u32 *)IOP3XX_REG_ADDR(0x0328) +#define IOP3XX_ODR (volatile u32 *)IOP3XX_REG_ADDR(0x032c) +#define IOP3XX_OISR (volatile u32 *)IOP3XX_REG_ADDR(0x0330) +#define IOP3XX_OIMR (volatile u32 *)IOP3XX_REG_ADDR(0x0334) +#define IOP3XX_MUCR (volatile u32 *)IOP3XX_REG_ADDR(0x0350) +#define IOP3XX_QBAR (volatile u32 *)IOP3XX_REG_ADDR(0x0354) +#define IOP3XX_IFHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0360) +#define IOP3XX_IFTPR (volatile u32 *)IOP3XX_REG_ADDR(0x0364) +#define IOP3XX_IPHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0368) +#define IOP3XX_IPTPR (volatile u32 *)IOP3XX_REG_ADDR(0x036c) +#define IOP3XX_OFHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0370) +#define IOP3XX_OFTPR (volatile u32 *)IOP3XX_REG_ADDR(0x0374) +#define IOP3XX_OPHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0378) +#define IOP3XX_OPTPR (volatile u32 *)IOP3XX_REG_ADDR(0x037c) +#define IOP3XX_IAR (volatile u32 *)IOP3XX_REG_ADDR(0x0380) + +/* DMA Controller */ +#define IOP3XX_DMA0_CCR (volatile u32 *)IOP3XX_REG_ADDR(0x0400) +#define IOP3XX_DMA0_CSR (volatile u32 *)IOP3XX_REG_ADDR(0x0404) +#define IOP3XX_DMA0_DAR (volatile u32 *)IOP3XX_REG_ADDR(0x040c) +#define IOP3XX_DMA0_NDAR (volatile u32 *)IOP3XX_REG_ADDR(0x0410) +#define IOP3XX_DMA0_PADR (volatile u32 *)IOP3XX_REG_ADDR(0x0414) +#define IOP3XX_DMA0_PUADR (volatile u32 *)IOP3XX_REG_ADDR(0x0418) +#define IOP3XX_DMA0_LADR (volatile u32 *)IOP3XX_REG_ADDR(0x041c) +#define IOP3XX_DMA0_BCR (volatile u32 *)IOP3XX_REG_ADDR(0x0420) +#define IOP3XX_DMA0_DCR (volatile u32 *)IOP3XX_REG_ADDR(0x0424) +#define IOP3XX_DMA1_CCR (volatile u32 *)IOP3XX_REG_ADDR(0x0440) +#define IOP3XX_DMA1_CSR (volatile u32 *)IOP3XX_REG_ADDR(0x0444) +#define IOP3XX_DMA1_DAR (volatile u32 *)IOP3XX_REG_ADDR(0x044c) +#define IOP3XX_DMA1_NDAR (volatile u32 *)IOP3XX_REG_ADDR(0x0450) +#define IOP3XX_DMA1_PADR (volatile u32 *)IOP3XX_REG_ADDR(0x0454) +#define IOP3XX_DMA1_PUADR (volatile u32 *)IOP3XX_REG_ADDR(0x0458) +#define IOP3XX_DMA1_LADR (volatile u32 *)IOP3XX_REG_ADDR(0x045c) +#define IOP3XX_DMA1_BCR (volatile u32 *)IOP3XX_REG_ADDR(0x0460) +#define IOP3XX_DMA1_DCR (volatile u32 *)IOP3XX_REG_ADDR(0x0464) + +/* Peripheral bus interface */ +#define IOP3XX_PBCR (volatile u32 *)IOP3XX_REG_ADDR(0x0680) +#define IOP3XX_PBISR (volatile u32 *)IOP3XX_REG_ADDR(0x0684) +#define IOP3XX_PBBAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0688) +#define IOP3XX_PBLR0 (volatile u32 *)IOP3XX_REG_ADDR(0x068c) +#define IOP3XX_PBBAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0690) +#define IOP3XX_PBLR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0694) +#define IOP3XX_PBBAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0698) +#define IOP3XX_PBLR2 (volatile u32 *)IOP3XX_REG_ADDR(0x069c) +#define IOP3XX_PBBAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x06a0) +#define IOP3XX_PBLR3 (volatile u32 *)IOP3XX_REG_ADDR(0x06a4) +#define IOP3XX_PBBAR4 (volatile u32 *)IOP3XX_REG_ADDR(0x06a8) +#define IOP3XX_PBLR4 (volatile u32 *)IOP3XX_REG_ADDR(0x06ac) +#define IOP3XX_PBBAR5 (volatile u32 *)IOP3XX_REG_ADDR(0x06b0) +#define IOP3XX_PBLR5 (volatile u32 *)IOP3XX_REG_ADDR(0x06b4) +#define IOP3XX_PMBR0 (volatile u32 *)IOP3XX_REG_ADDR(0x06c0) +#define IOP3XX_PMBR1 (volatile u32 *)IOP3XX_REG_ADDR(0x06e0) +#define IOP3XX_PMBR2 (volatile u32 *)IOP3XX_REG_ADDR(0x06e4) + +/* Peripheral performance monitoring unit */ +#define IOP3XX_GTMR (volatile u32 *)IOP3XX_REG_ADDR(0x0700) +#define IOP3XX_ESR (volatile u32 *)IOP3XX_REG_ADDR(0x0704) +#define IOP3XX_EMISR (volatile u32 *)IOP3XX_REG_ADDR(0x0708) +#define IOP3XX_GTSR (volatile u32 *)IOP3XX_REG_ADDR(0x0710) +/* PERCR0 DOESN'T EXIST - index from 1! */ +#define IOP3XX_PERCR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0710) + +/* General Purpose I/O */ +#define IOP3XX_GPOE (volatile u32 *)IOP3XX_GPIO_REG(0x0004) +#define IOP3XX_GPID (volatile u32 *)IOP3XX_GPIO_REG(0x0008) +#define IOP3XX_GPOD (volatile u32 *)IOP3XX_GPIO_REG(0x000c) + +/* Timers */ +#define IOP3XX_TU_TMR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0000) +#define IOP3XX_TU_TMR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0004) +#define IOP3XX_TU_TCR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0008) +#define IOP3XX_TU_TCR1 (volatile u32 *)IOP3XX_TIMER_REG(0x000c) +#define IOP3XX_TU_TRR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0010) +#define IOP3XX_TU_TRR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0014) +#define IOP3XX_TU_TISR (volatile u32 *)IOP3XX_TIMER_REG(0x0018) +#define IOP3XX_TU_WDTCR (volatile u32 *)IOP3XX_TIMER_REG(0x001c) +#define IOP3XX_TMR_TC 0x01 +#define IOP3XX_TMR_EN 0x02 +#define IOP3XX_TMR_RELOAD 0x04 +#define IOP3XX_TMR_PRIVILEGED 0x09 +#define IOP3XX_TMR_RATIO_1_1 0x00 +#define IOP3XX_TMR_RATIO_4_1 0x10 +#define IOP3XX_TMR_RATIO_8_1 0x20 +#define IOP3XX_TMR_RATIO_16_1 0x30 + +/* Application accelerator unit */ +#define IOP3XX_AAU_ACR (volatile u32 *)IOP3XX_REG_ADDR(0x0800) +#define IOP3XX_AAU_ASR (volatile u32 *)IOP3XX_REG_ADDR(0x0804) +#define IOP3XX_AAU_ADAR (volatile u32 *)IOP3XX_REG_ADDR(0x0808) +#define IOP3XX_AAU_ANDAR (volatile u32 *)IOP3XX_REG_ADDR(0x080c) +#define IOP3XX_AAU_SAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0810) +#define IOP3XX_AAU_SAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0814) +#define IOP3XX_AAU_SAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0818) +#define IOP3XX_AAU_SAR4 (volatile u32 *)IOP3XX_REG_ADDR(0x081c) +#define IOP3XX_AAU_DAR (volatile u32 *)IOP3XX_REG_ADDR(0x0820) +#define IOP3XX_AAU_ABCR (volatile u32 *)IOP3XX_REG_ADDR(0x0824) +#define IOP3XX_AAU_ADCR (volatile u32 *)IOP3XX_REG_ADDR(0x0828) +#define IOP3XX_AAU_SAR5 (volatile u32 *)IOP3XX_REG_ADDR(0x082c) +#define IOP3XX_AAU_SAR6 (volatile u32 *)IOP3XX_REG_ADDR(0x0830) +#define IOP3XX_AAU_SAR7 (volatile u32 *)IOP3XX_REG_ADDR(0x0834) +#define IOP3XX_AAU_SAR8 (volatile u32 *)IOP3XX_REG_ADDR(0x0838) +#define IOP3XX_AAU_EDCR0 (volatile u32 *)IOP3XX_REG_ADDR(0x083c) +#define IOP3XX_AAU_SAR9 (volatile u32 *)IOP3XX_REG_ADDR(0x0840) +#define IOP3XX_AAU_SAR10 (volatile u32 *)IOP3XX_REG_ADDR(0x0844) +#define IOP3XX_AAU_SAR11 (volatile u32 *)IOP3XX_REG_ADDR(0x0848) +#define IOP3XX_AAU_SAR12 (volatile u32 *)IOP3XX_REG_ADDR(0x084c) +#define IOP3XX_AAU_SAR13 (volatile u32 *)IOP3XX_REG_ADDR(0x0850) +#define IOP3XX_AAU_SAR14 (volatile u32 *)IOP3XX_REG_ADDR(0x0854) +#define IOP3XX_AAU_SAR15 (volatile u32 *)IOP3XX_REG_ADDR(0x0858) +#define IOP3XX_AAU_SAR16 (volatile u32 *)IOP3XX_REG_ADDR(0x085c) +#define IOP3XX_AAU_EDCR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0860) +#define IOP3XX_AAU_SAR17 (volatile u32 *)IOP3XX_REG_ADDR(0x0864) +#define IOP3XX_AAU_SAR18 (volatile u32 *)IOP3XX_REG_ADDR(0x0868) +#define IOP3XX_AAU_SAR19 (volatile u32 *)IOP3XX_REG_ADDR(0x086c) +#define IOP3XX_AAU_SAR20 (volatile u32 *)IOP3XX_REG_ADDR(0x0870) +#define IOP3XX_AAU_SAR21 (volatile u32 *)IOP3XX_REG_ADDR(0x0874) +#define IOP3XX_AAU_SAR22 (volatile u32 *)IOP3XX_REG_ADDR(0x0878) +#define IOP3XX_AAU_SAR23 (volatile u32 *)IOP3XX_REG_ADDR(0x087c) +#define IOP3XX_AAU_SAR24 (volatile u32 *)IOP3XX_REG_ADDR(0x0880) +#define IOP3XX_AAU_EDCR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0884) +#define IOP3XX_AAU_SAR25 (volatile u32 *)IOP3XX_REG_ADDR(0x0888) +#define IOP3XX_AAU_SAR26 (volatile u32 *)IOP3XX_REG_ADDR(0x088c) +#define IOP3XX_AAU_SAR27 (volatile u32 *)IOP3XX_REG_ADDR(0x0890) +#define IOP3XX_AAU_SAR28 (volatile u32 *)IOP3XX_REG_ADDR(0x0894) +#define IOP3XX_AAU_SAR29 (volatile u32 *)IOP3XX_REG_ADDR(0x0898) +#define IOP3XX_AAU_SAR30 (volatile u32 *)IOP3XX_REG_ADDR(0x089c) +#define IOP3XX_AAU_SAR31 (volatile u32 *)IOP3XX_REG_ADDR(0x08a0) +#define IOP3XX_AAU_SAR32 (volatile u32 *)IOP3XX_REG_ADDR(0x08a4) + +/* I2C bus interface unit */ +#define IOP3XX_ICR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1680) +#define IOP3XX_ISR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1684) +#define IOP3XX_ISAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1688) +#define IOP3XX_IDBR0 (volatile u32 *)IOP3XX_REG_ADDR(0x168c) +#define IOP3XX_IBMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1694) +#define IOP3XX_ICR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a0) +#define IOP3XX_ISR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a4) +#define IOP3XX_ISAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a8) +#define IOP3XX_IDBR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16ac) +#define IOP3XX_IBMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16b4) + + +/* + * IOP3XX I/O and Mem space regions for PCI autoconfiguration + */ +#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x04000000 +#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000 +#define IOP3XX_PCI_LOWER_MEM_BA (*IOP3XX_OMWTVR0) + +#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000 +#define IOP3XX_PCI_LOWER_IO_PA 0x90000000 +#define IOP3XX_PCI_LOWER_IO_VA 0xfe000000 +#define IOP3XX_PCI_LOWER_IO_BA (*IOP3XX_OIOWTVR) + + +#ifndef __ASSEMBLY__ +void iop3xx_map_io(void); +void iop3xx_init_time(unsigned long); +unsigned long iop3xx_gettimeoffset(void); + +extern struct platform_device iop3xx_i2c0_device; +extern struct platform_device iop3xx_i2c1_device; + +extern inline void iop3xx_cp6_enable(void) +{ + u32 temp; + + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "orr %0, %0, #(1 << 6)\n\t" + "mcr p15, 0, %0, c15, c1, 0\n\t" + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4\n\t" + : "=r" (temp) ); +} + +extern inline void iop3xx_cp6_disable(void) +{ + u32 temp; + + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "bic %0, %0, #(1 << 6)\n\t" + "mcr p15, 0, %0, c15, c1, 0\n\t" + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4\n\t" + : "=r" (temp) ); +} +#endif + + +#endif diff --git a/include/asm-arm/hardware/locomo.h b/include/asm-arm/hardware/locomo.h index 22dfb173776..adab77780ed 100644 --- a/include/asm-arm/hardware/locomo.h +++ b/include/asm-arm/hardware/locomo.h @@ -54,17 +54,18 @@ #define LOCOMO_DAC_SDAOEB 0x01 /* SDA pin output data */ /* SPI interface */ -#define LOCOMO_SPIMD 0x60 /* SPI mode setting */ -#define LOCOMO_SPICT 0x64 /* SPI mode control */ -#define LOCOMO_SPIST 0x68 /* SPI status */ -#define LOCOMO_SPIIS 0x70 /* SPI interrupt status */ -#define LOCOMO_SPIWE 0x74 /* SPI interrupt status write enable */ -#define LOCOMO_SPIIE 0x78 /* SPI interrupt enable */ -#define LOCOMO_SPIIR 0x7c /* SPI interrupt request */ -#define LOCOMO_SPITD 0x80 /* SPI transfer data write */ -#define LOCOMO_SPIRD 0x84 /* SPI receive data read */ -#define LOCOMO_SPITS 0x88 /* SPI transfer data shift */ -#define LOCOMO_SPIRS 0x8C /* SPI receive data shift */ +#define LOCOMO_SPI 0x60 +#define LOCOMO_SPIMD 0x00 /* SPI mode setting */ +#define LOCOMO_SPICT 0x04 /* SPI mode control */ +#define LOCOMO_SPIST 0x08 /* SPI status */ +#define LOCOMO_SPIIS 0x10 /* SPI interrupt status */ +#define LOCOMO_SPIWE 0x14 /* SPI interrupt status write enable */ +#define LOCOMO_SPIIE 0x18 /* SPI interrupt enable */ +#define LOCOMO_SPIIR 0x1c /* SPI interrupt request */ +#define LOCOMO_SPITD 0x20 /* SPI transfer data write */ +#define LOCOMO_SPIRD 0x24 /* SPI receive data read */ +#define LOCOMO_SPITS 0x28 /* SPI transfer data shift */ +#define LOCOMO_SPIRS 0x2C /* SPI receive data shift */ #define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */ #define LOCOMO_SPI_OVRN (1 << 2) /* Over Run bit */ #define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */ @@ -161,6 +162,7 @@ extern struct bus_type locomo_bus_type; #define LOCOMO_DEVID_AUDIO 3 #define LOCOMO_DEVID_LED 4 #define LOCOMO_DEVID_UART 5 +#define LOCOMO_DEVID_SPI 6 struct locomo_dev { struct device dev; @@ -197,10 +199,11 @@ int locomo_driver_register(struct locomo_driver *); void locomo_driver_unregister(struct locomo_driver *); /* GPIO control functions */ -void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir); -unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits); -unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits); -void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set); +void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir); +int locomo_gpio_read_level(struct device *dev, unsigned int bits); +int locomo_gpio_read_output(struct device *dev, unsigned int bits); +void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set); + /* M62332 control function */ void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel); diff --git a/include/asm-arm/hardware/sharpsl_pm.h b/include/asm-arm/hardware/sharpsl_pm.h index ecf15b83956..a836e76a14f 100644 --- a/include/asm-arm/hardware/sharpsl_pm.h +++ b/include/asm-arm/hardware/sharpsl_pm.h @@ -25,6 +25,7 @@ struct sharpsl_charger_machinfo { void (*measure_temp)(int); void (*presuspend)(void); void (*postsuspend)(void); + void (*earlyresume)(void); unsigned long (*read_devdata)(int); #define SHARPSL_BATT_VOLT 1 #define SHARPSL_BATT_TEMP 2 diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index bf7b9dea30f..8076a85c367 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -280,6 +280,10 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); #define BIOVEC_MERGEABLE(vec1, vec2) \ ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) +#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); + /* * Convert a physical pointer to a virtual kernel pointer for /dev/mem * access diff --git a/include/asm-arm/irqflags.h b/include/asm-arm/irqflags.h new file mode 100644 index 00000000000..6d09974e664 --- /dev/null +++ b/include/asm-arm/irqflags.h @@ -0,0 +1,132 @@ +#ifndef __ASM_ARM_IRQFLAGS_H +#define __ASM_ARM_IRQFLAGS_H + +#ifdef __KERNEL__ + +#include <asm/ptrace.h> + +/* + * CPU interrupt mask handling. + */ +#if __LINUX_ARM_ARCH__ >= 6 + +#define raw_local_irq_save(x) \ + ({ \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_save\n" \ + "cpsid i" \ + : "=r" (x) : : "memory", "cc"); \ + }) + +#define raw_local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc") +#define raw_local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc") +#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") +#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") + +#else + +/* + * Save the current interrupt enable state & disable IRQs + */ +#define raw_local_irq_save(x) \ + ({ \ + unsigned long temp; \ + (void) (&temp == &x); \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_save\n" \ +" orr %1, %0, #128\n" \ +" msr cpsr_c, %1" \ + : "=r" (x), "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Enable IRQs + */ +#define raw_local_irq_enable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_enable\n" \ +" bic %0, %0, #128\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Disable IRQs + */ +#define raw_local_irq_disable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_irq_disable\n" \ +" orr %0, %0, #128\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Enable FIQs + */ +#define local_fiq_enable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ stf\n" \ +" bic %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Disable FIQs + */ +#define local_fiq_disable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ clf\n" \ +" orr %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +#endif + +/* + * Save the current interrupt enable state. + */ +#define raw_local_save_flags(x) \ + ({ \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ local_save_flags" \ + : "=r" (x) : : "memory", "cc"); \ + }) + +/* + * restore saved IRQ & FIQ state + */ +#define raw_local_irq_restore(x) \ + __asm__ __volatile__( \ + "msr cpsr_c, %0 @ local_irq_restore\n" \ + : \ + : "r" (x) \ + : "memory", "cc") + +#define raw_irqs_disabled_flags(flags) \ +({ \ + (int)((flags) & PSR_I_BIT); \ +}) + +#endif +#endif diff --git a/include/asm-arm/mach/pci.h b/include/asm-arm/mach/pci.h index 923e0ca6620..24621c49a0c 100644 --- a/include/asm-arm/mach/pci.h +++ b/include/asm-arm/mach/pci.h @@ -52,13 +52,9 @@ void pci_common_init(struct hw_pci *); /* * PCI controllers */ -extern int iop321_setup(int nr, struct pci_sys_data *); -extern struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *); -extern void iop321_init(void); - -extern int iop331_setup(int nr, struct pci_sys_data *); -extern struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *); -extern void iop331_init(void); +extern int iop3xx_pci_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *); +extern void iop3xx_pci_preinit(void); extern int dc21285_setup(int nr, struct pci_sys_data *); extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *); diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h index dee0bc336fe..1eb93f5c0d6 100644 --- a/include/asm-arm/mach/time.h +++ b/include/asm-arm/mach/time.h @@ -38,7 +38,9 @@ struct sys_timer { void (*init)(void); void (*suspend)(void); void (*resume)(void); +#ifndef CONFIG_GENERIC_TIME unsigned long (*offset)(void); +#endif #ifdef CONFIG_NO_IDLE_HZ struct dyn_tick_timer *dyn_tick; diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h index 02bd3ee935b..7e85db77d99 100644 --- a/include/asm-arm/page.h +++ b/include/asm-arm/page.h @@ -174,9 +174,6 @@ typedef unsigned long pgprot_t; #endif /* STRICT_MM_TYPECHECKS */ -/* the upper-most page table pointer */ -extern pmd_t *top_pmd; - #endif /* CONFIG_MMU */ #include <asm/memory.h> diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h index 4d10d319fa3..ed8cb5963e9 100644 --- a/include/asm-arm/pgtable.h +++ b/include/asm-arm/pgtable.h @@ -136,6 +136,13 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR) /* + * section address mask and size definitions. + */ +#define SECTION_SHIFT 20 +#define SECTION_SIZE (1UL << SECTION_SHIFT) +#define SECTION_MASK (~(SECTION_SIZE-1)) + +/* * ARMv6 supersection address mask and size definitions. */ #define SUPERSECTION_SHIFT 24 diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index 1bde92cdaeb..ea7e54c319b 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -33,6 +33,14 @@ # define CPU_NAME cpu_arm6 # endif # endif +# ifdef CONFIG_CPU_ARM7TDMI +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm7tdmi +# endif +# endif # ifdef CONFIG_CPU_ARM710 # ifdef CPU_NAME # undef MULTI_CPU @@ -49,6 +57,22 @@ # define CPU_NAME cpu_arm720 # endif # endif +# ifdef CONFIG_CPU_ARM740T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm740 +# endif +# endif +# ifdef CONFIG_CPU_ARM9TDMI +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm9tdmi +# endif +# endif # ifdef CONFIG_CPU_ARM920T # ifdef CPU_NAME # undef MULTI_CPU @@ -81,6 +105,22 @@ # define CPU_NAME cpu_arm926 # endif # endif +# ifdef CONFIG_CPU_ARM940T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm940 +# endif +# endif +# ifdef CONFIG_CPU_ARM946E +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm946 +# endif +# endif # ifdef CONFIG_CPU_SA110 # ifdef CPU_NAME # undef MULTI_CPU diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h index ea3ed246523..aa4b5782f0c 100644 --- a/include/asm-arm/setup.h +++ b/include/asm-arm/setup.h @@ -194,13 +194,15 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn } # define NR_BANKS 8 #endif +struct membank { + unsigned long start; + unsigned long size; + int node; +}; + struct meminfo { int nr_banks; - struct { - unsigned long start; - unsigned long size; - int node; - } bank[NR_BANKS]; + struct membank bank[NR_BANKS]; }; /* diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 0947cbf9b69..f05fbe31576 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -46,6 +46,7 @@ #define CPUID_TCM 2 #define CPUID_TLBTYPE 3 +#ifdef CONFIG_CPU_CP15 #define read_cpuid(reg) \ ({ \ unsigned int __val; \ @@ -55,6 +56,9 @@ : "cc"); \ __val; \ }) +#else +#define read_cpuid(reg) (processor_id) +#endif /* * This is used to ensure the compiler did actually allocate the register we @@ -207,130 +211,7 @@ static inline void sched_cacheflush(void) { } -/* - * CPU interrupt mask handling. - */ -#if __LINUX_ARM_ARCH__ >= 6 - -#define local_irq_save(x) \ - ({ \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_save\n" \ - "cpsid i" \ - : "=r" (x) : : "memory", "cc"); \ - }) - -#define local_irq_enable() __asm__("cpsie i @ __sti" : : : "memory", "cc") -#define local_irq_disable() __asm__("cpsid i @ __cli" : : : "memory", "cc") -#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") -#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") - -#else - -/* - * Save the current interrupt enable state & disable IRQs - */ -#define local_irq_save(x) \ - ({ \ - unsigned long temp; \ - (void) (&temp == &x); \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_save\n" \ -" orr %1, %0, #128\n" \ -" msr cpsr_c, %1" \ - : "=r" (x), "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Enable IRQs - */ -#define local_irq_enable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_enable\n" \ -" bic %0, %0, #128\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Disable IRQs - */ -#define local_irq_disable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_irq_disable\n" \ -" orr %0, %0, #128\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Enable FIQs - */ -#define local_fiq_enable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ stf\n" \ -" bic %0, %0, #64\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -/* - * Disable FIQs - */ -#define local_fiq_disable() \ - ({ \ - unsigned long temp; \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ clf\n" \ -" orr %0, %0, #64\n" \ -" msr cpsr_c, %0" \ - : "=r" (temp) \ - : \ - : "memory", "cc"); \ - }) - -#endif - -/* - * Save the current interrupt enable state. - */ -#define local_save_flags(x) \ - ({ \ - __asm__ __volatile__( \ - "mrs %0, cpsr @ local_save_flags" \ - : "=r" (x) : : "memory", "cc"); \ - }) - -/* - * restore saved IRQ & FIQ state - */ -#define local_irq_restore(x) \ - __asm__ __volatile__( \ - "msr cpsr_c, %0 @ local_irq_restore\n" \ - : \ - : "r" (x) \ - : "memory", "cc") - -#define irqs_disabled() \ -({ \ - unsigned long flags; \ - local_save_flags(flags); \ - (int)(flags & PSR_I_BIT); \ -}) +#include <linux/irqflags.h> #ifdef CONFIG_SMP @@ -405,17 +286,17 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size #error SMP is not supported on this platform #endif case 1: - local_irq_save(flags); + raw_local_irq_save(flags); ret = *(volatile unsigned char *)ptr; *(volatile unsigned char *)ptr = x; - local_irq_restore(flags); + raw_local_irq_restore(flags); break; case 4: - local_irq_save(flags); + raw_local_irq_save(flags); ret = *(volatile unsigned long *)ptr; *(volatile unsigned long *)ptr = x; - local_irq_restore(flags); + raw_local_irq_restore(flags); break; #else case 1: diff --git a/include/asm-arm/timeofday.h b/include/asm-arm/timeofday.h new file mode 100644 index 00000000000..27254bd5b94 --- /dev/null +++ b/include/asm-arm/timeofday.h @@ -0,0 +1,4 @@ +#ifndef _ASM_ARM_TIMEOFDAY_H +#define _ASM_ARM_TIMEOFDAY_H +#include <asm-generic/timeofday.h> +#endif diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h index d97fc76189a..cd10a0b5f8a 100644 --- a/include/asm-arm/tlbflush.h +++ b/include/asm-arm/tlbflush.h @@ -247,16 +247,16 @@ static inline void local_flush_tlb_all(void) const unsigned int __tlb_flag = __cpu_tlb_flags; if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V3_FULL)) - asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL)) - asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL)) - asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) - asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); } static inline void local_flush_tlb_mm(struct mm_struct *mm) @@ -266,25 +266,25 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) const unsigned int __tlb_flag = __cpu_tlb_flags; if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) { if (tlb_flag(TLB_V3_FULL)) - asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V4_U_FULL)) - asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V4_D_FULL)) - asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V4_I_FULL)) - asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); } if (tlb_flag(TLB_V6_U_ASID)) - asm("mcr%? p15, 0, %0, c8, c7, 2" : : "r" (asid)); + asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc"); if (tlb_flag(TLB_V6_D_ASID)) - asm("mcr%? p15, 0, %0, c8, c6, 2" : : "r" (asid)); + asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc"); if (tlb_flag(TLB_V6_I_ASID)) - asm("mcr%? p15, 0, %0, c8, c5, 2" : : "r" (asid)); + asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); } static inline void @@ -296,27 +296,27 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero)); if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { if (tlb_flag(TLB_V3_PAGE)) - asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (uaddr)); + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc"); if (tlb_flag(TLB_V4_U_PAGE)) - asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr)); + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); if (tlb_flag(TLB_V4_D_PAGE)) - asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr)); + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); if (tlb_flag(TLB_V4_I_PAGE)) - asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr)); + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) - asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); } if (tlb_flag(TLB_V6_U_PAGE)) - asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr)); + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); if (tlb_flag(TLB_V6_D_PAGE)) - asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr)); + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); if (tlb_flag(TLB_V6_I_PAGE)) - asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr)); + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); } static inline void local_flush_tlb_kernel_page(unsigned long kaddr) @@ -327,31 +327,31 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) kaddr &= PAGE_MASK; if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V3_PAGE)) - asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (kaddr)); + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc"); if (tlb_flag(TLB_V4_U_PAGE)) - asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr)); + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); if (tlb_flag(TLB_V4_D_PAGE)) - asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr)); + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); if (tlb_flag(TLB_V4_I_PAGE)) - asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr)); + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) - asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V6_U_PAGE)) - asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr)); + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); if (tlb_flag(TLB_V6_D_PAGE)) - asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr)); + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); if (tlb_flag(TLB_V6_I_PAGE)) - asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr)); + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); /* The ARM ARM states that the completion of a TLB maintenance * operation is only guaranteed by a DSB instruction */ if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE)) - asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); } /* @@ -373,11 +373,11 @@ static inline void flush_pmd_entry(pmd_t *pmd) const unsigned int __tlb_flag = __cpu_tlb_flags; if (tlb_flag(TLB_DCLEAN)) - asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd" - : : "r" (pmd)); + asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd) : "cc"); if (tlb_flag(TLB_WB)) - asm("mcr%? p15, 0, %0, c7, c10, 4 @ flush_pmd" - : : "r" (zero)); + asm("mcr p15, 0, %0, c7, c10, 4 @ flush_pmd" + : : "r" (zero) : "cc"); } static inline void clean_pmd_entry(pmd_t *pmd) @@ -385,8 +385,8 @@ static inline void clean_pmd_entry(pmd_t *pmd) const unsigned int __tlb_flag = __cpu_tlb_flags; if (tlb_flag(TLB_DCLEAN)) - asm("mcr%? p15, 0, %0, c7, c10, 1 @ flush_pmd" - : : "r" (pmd)); + asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd) : "cc"); } #undef tlb_flag diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h index 1b39c2f322c..795b9e5b9e6 100644 --- a/include/asm-arm/unaligned.h +++ b/include/asm-arm/unaligned.h @@ -3,7 +3,7 @@ #include <asm/types.h> -extern int __bug_unaligned_x(void *ptr); +extern int __bug_unaligned_x(const void *ptr); /* * What is the most efficient way of loading/storing an unaligned value? @@ -51,44 +51,32 @@ extern int __bug_unaligned_x(void *ptr); #define __get_unaligned_4_be(__p) \ (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) -#define __get_unaligned_le(ptr) \ - ({ \ - __typeof__(*(ptr)) __v; \ - __u8 *__p = (__u8 *)(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: __v = *(ptr); break; \ - case 2: __v = __get_unaligned_2_le(__p); break; \ - case 4: __v = __get_unaligned_4_le(__p); break; \ - case 8: { \ - unsigned int __v1, __v2; \ - __v2 = __get_unaligned_4_le((__p+4)); \ - __v1 = __get_unaligned_4_le(__p); \ - __v = ((unsigned long long)__v2 << 32 | __v1); \ - } \ - break; \ - default: __v = __bug_unaligned_x(__p); break; \ - } \ - __v; \ +#define __get_unaligned_8_le(__p) \ + ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \ + __get_unaligned_4_le(__p)) + +#define __get_unaligned_8_be(__p) \ + ((unsigned long long)__get_unaligned_4_be(__p) << 32 | \ + __get_unaligned_4_be((__p+4))) + +#define __get_unaligned_le(ptr) \ + ({ \ + const __u8 *__p = (const __u8 *)(ptr); \ + __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p, \ + __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_le(__p), \ + __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_le(__p), \ + __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_le(__p), \ + (void)__bug_unaligned_x(__p))))); \ }) -#define __get_unaligned_be(ptr) \ - ({ \ - __typeof__(*(ptr)) __v; \ - __u8 *__p = (__u8 *)(ptr); \ - switch (sizeof(*(ptr))) { \ - case 1: __v = *(ptr); break; \ - case 2: __v = __get_unaligned_2_be(__p); break; \ - case 4: __v = __get_unaligned_4_be(__p); break; \ - case 8: { \ - unsigned int __v1, __v2; \ - __v2 = __get_unaligned_4_be(__p); \ - __v1 = __get_unaligned_4_be((__p+4)); \ - __v = ((unsigned long long)__v2 << 32 | __v1); \ - } \ - break; \ - default: __v = __bug_unaligned_x(__p); break; \ - } \ - __v; \ +#define __get_unaligned_be(ptr) \ + ({ \ + const __u8 *__p = (const __u8 *)(ptr); \ + __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p, \ + __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_be(__p), \ + __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_be(__p), \ + __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_be(__p), \ + (void)__bug_unaligned_x(__p))))); \ }) diff --git a/include/asm-s390/appldata.h b/include/asm-s390/appldata.h index b1770703b70..79283dac828 100644 --- a/include/asm-s390/appldata.h +++ b/include/asm-s390/appldata.h @@ -80,7 +80,7 @@ static inline int appldata_asm(struct appldata_product_id *id, parm_list.product_id_addr = (unsigned long) id; parm_list.buffer_addr = virt_to_phys(buffer); asm volatile( - "diag %1,%0,0xdc" + " diag %1,%0,0xdc" : "=d" (ry) : "d" (&parm_list), "m" (parm_list), "m" (*id) : "cc"); diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index 399bf02894d..af20c746248 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h @@ -30,20 +30,43 @@ typedef struct { #ifdef __KERNEL__ +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + #define __CS_LOOP(ptr, op_val, op_string) ({ \ typeof(ptr->counter) old_val, new_val; \ - __asm__ __volatile__(" l %0,0(%3)\n" \ - "0: lr %1,%0\n" \ - op_string " %1,%4\n" \ - " cs %0,%1,0(%3)\n" \ - " jl 0b" \ - : "=&d" (old_val), "=&d" (new_val), \ - "=m" (((atomic_t *)(ptr))->counter) \ - : "a" (ptr), "d" (op_val), \ - "m" (((atomic_t *)(ptr))->counter) \ - : "cc", "memory" ); \ + asm volatile( \ + " l %0,%2\n" \ + "0: lr %1,%0\n" \ + op_string " %1,%3\n" \ + " cs %0,%1,%2\n" \ + " jl 0b" \ + : "=&d" (old_val), "=&d" (new_val), \ + "=Q" (((atomic_t *)(ptr))->counter) \ + : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ + : "cc", "memory"); \ new_val; \ }) + +#else /* __GNUC__ */ + +#define __CS_LOOP(ptr, op_val, op_string) ({ \ + typeof(ptr->counter) old_val, new_val; \ + asm volatile( \ + " l %0,0(%3)\n" \ + "0: lr %1,%0\n" \ + op_string " %1,%4\n" \ + " cs %0,%1,0(%3)\n" \ + " jl 0b" \ + : "=&d" (old_val), "=&d" (new_val), \ + "=m" (((atomic_t *)(ptr))->counter) \ + : "a" (ptr), "d" (op_val), \ + "m" (((atomic_t *)(ptr))->counter) \ + : "cc", "memory"); \ + new_val; \ +}) + +#endif /* __GNUC__ */ + #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) @@ -81,10 +104,19 @@ static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) { - __asm__ __volatile__(" cs %0,%3,0(%2)\n" - : "+d" (old), "=m" (v->counter) - : "a" (v), "d" (new), "m" (v->counter) - : "cc", "memory" ); +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + asm volatile( + " cs %0,%2,%1" + : "+d" (old), "=Q" (v->counter) + : "d" (new), "Q" (v->counter) + : "cc", "memory"); +#else /* __GNUC__ */ + asm volatile( + " cs %0,%3,0(%2)" + : "+d" (old), "=m" (v->counter) + : "a" (v), "d" (new), "m" (v->counter) + : "cc", "memory"); +#endif /* __GNUC__ */ return old; } @@ -113,20 +145,43 @@ typedef struct { } __attribute__ ((aligned (8))) atomic64_t; #define ATOMIC64_INIT(i) { (i) } +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + #define __CSG_LOOP(ptr, op_val, op_string) ({ \ typeof(ptr->counter) old_val, new_val; \ - __asm__ __volatile__(" lg %0,0(%3)\n" \ - "0: lgr %1,%0\n" \ - op_string " %1,%4\n" \ - " csg %0,%1,0(%3)\n" \ - " jl 0b" \ - : "=&d" (old_val), "=&d" (new_val), \ - "=m" (((atomic_t *)(ptr))->counter) \ - : "a" (ptr), "d" (op_val), \ - "m" (((atomic_t *)(ptr))->counter) \ - : "cc", "memory" ); \ + asm volatile( \ + " lg %0,%2\n" \ + "0: lgr %1,%0\n" \ + op_string " %1,%3\n" \ + " csg %0,%1,%2\n" \ + " jl 0b" \ + : "=&d" (old_val), "=&d" (new_val), \ + "=Q" (((atomic_t *)(ptr))->counter) \ + : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ + : "cc", "memory" ); \ new_val; \ }) + +#else /* __GNUC__ */ + +#define __CSG_LOOP(ptr, op_val, op_string) ({ \ + typeof(ptr->counter) old_val, new_val; \ + asm volatile( \ + " lg %0,0(%3)\n" \ + "0: lgr %1,%0\n" \ + op_string " %1,%4\n" \ + " csg %0,%1,0(%3)\n" \ + " jl 0b" \ + : "=&d" (old_val), "=&d" (new_val), \ + "=m" (((atomic_t *)(ptr))->counter) \ + : "a" (ptr), "d" (op_val), \ + "m" (((atomic_t *)(ptr))->counter) \ + : "cc", "memory" ); \ + new_val; \ +}) + +#endif /* __GNUC__ */ + #define atomic64_read(v) ((v)->counter) #define atomic64_set(v,i) (((v)->counter) = (i)) @@ -163,10 +218,19 @@ static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) static __inline__ long long atomic64_cmpxchg(atomic64_t *v, long long old, long long new) { - __asm__ __volatile__(" csg %0,%3,0(%2)\n" - : "+d" (old), "=m" (v->counter) - : "a" (v), "d" (new), "m" (v->counter) - : "cc", "memory" ); +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + asm volatile( + " csg %0,%2,%1" + : "+d" (old), "=Q" (v->counter) + : "d" (new), "Q" (v->counter) + : "cc", "memory"); +#else /* __GNUC__ */ + asm volatile( + " csg %0,%3,0(%2)" + : "+d" (old), "=m" (v->counter) + : "a" (v), "d" (new), "m" (v->counter) + : "cc", "memory"); +#endif /* __GNUC__ */ return old; } diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index 0ddcdba79e4..f79c9b792af 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h @@ -67,16 +67,35 @@ extern const char _sb_findmap[]; #define __BITOPS_AND "nr" #define __BITOPS_XOR "xr" -#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ - __asm__ __volatile__(" l %0,0(%4)\n" \ - "0: lr %1,%0\n" \ - __op_string " %1,%3\n" \ - " cs %0,%1,0(%4)\n" \ - " jl 0b" \ - : "=&d" (__old), "=&d" (__new), \ - "=m" (*(unsigned long *) __addr) \ - : "d" (__val), "a" (__addr), \ - "m" (*(unsigned long *) __addr) : "cc" ); +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + +#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ + asm volatile( \ + " l %0,%2\n" \ + "0: lr %1,%0\n" \ + __op_string " %1,%3\n" \ + " cs %0,%1,%2\n" \ + " jl 0b" \ + : "=&d" (__old), "=&d" (__new), \ + "=Q" (*(unsigned long *) __addr) \ + : "d" (__val), "Q" (*(unsigned long *) __addr) \ + : "cc"); + +#else /* __GNUC__ */ + +#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ + asm volatile( \ + " l %0,0(%4)\n" \ + "0: lr %1,%0\n" \ + __op_string " %1,%3\n" \ + " cs %0,%1,0(%4)\n" \ + " jl 0b" \ + : "=&d" (__old), "=&d" (__new), \ + "=m" (*(unsigned long *) __addr) \ + : "d" (__val), "a" (__addr), \ + "m" (*(unsigned long *) __addr) : "cc"); + +#endif /* __GNUC__ */ #else /* __s390x__ */ @@ -86,21 +105,41 @@ extern const char _sb_findmap[]; #define __BITOPS_AND "ngr" #define __BITOPS_XOR "xgr" -#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ - __asm__ __volatile__(" lg %0,0(%4)\n" \ - "0: lgr %1,%0\n" \ - __op_string " %1,%3\n" \ - " csg %0,%1,0(%4)\n" \ - " jl 0b" \ - : "=&d" (__old), "=&d" (__new), \ - "=m" (*(unsigned long *) __addr) \ - : "d" (__val), "a" (__addr), \ - "m" (*(unsigned long *) __addr) : "cc" ); +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + +#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ + asm volatile( \ + " lg %0,%2\n" \ + "0: lgr %1,%0\n" \ + __op_string " %1,%3\n" \ + " csg %0,%1,%2\n" \ + " jl 0b" \ + : "=&d" (__old), "=&d" (__new), \ + "=Q" (*(unsigned long *) __addr) \ + : "d" (__val), "Q" (*(unsigned long *) __addr) \ + : "cc"); + +#else /* __GNUC__ */ + +#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ + asm volatile( \ + " lg %0,0(%4)\n" \ + "0: lgr %1,%0\n" \ + __op_string " %1,%3\n" \ + " csg %0,%1,0(%4)\n" \ + " jl 0b" \ + : "=&d" (__old), "=&d" (__new), \ + "=m" (*(unsigned long *) __addr) \ + : "d" (__val), "a" (__addr), \ + "m" (*(unsigned long *) __addr) : "cc"); + + +#endif /* __GNUC__ */ #endif /* __s390x__ */ #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) -#define __BITOPS_BARRIER() __asm__ __volatile__ ( "" : : : "memory" ) +#define __BITOPS_BARRIER() asm volatile("" : : : "memory") #ifdef CONFIG_SMP /* @@ -217,10 +256,10 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); - asm volatile("oc 0(1,%1),0(%2)" - : "=m" (*(char *) addr) - : "a" (addr), "a" (_oi_bitmap + (nr & 7)), - "m" (*(char *) addr) : "cc" ); + asm volatile( + " oc 0(1,%1),0(%2)" + : "=m" (*(char *) addr) : "a" (addr), + "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" ); } static inline void @@ -229,40 +268,7 @@ __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr) unsigned long addr; addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); - switch (nr&7) { - case 0: - asm volatile ("oi 0(%1),0x01" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 1: - asm volatile ("oi 0(%1),0x02" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 2: - asm volatile ("oi 0(%1),0x04" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 3: - asm volatile ("oi 0(%1),0x08" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 4: - asm volatile ("oi 0(%1),0x10" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 5: - asm volatile ("oi 0(%1),0x20" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 6: - asm volatile ("oi 0(%1),0x40" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 7: - asm volatile ("oi 0(%1),0x80" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - } + *(unsigned char *) addr |= 1 << (nr & 7); } #define set_bit_simple(nr,addr) \ @@ -279,10 +285,10 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); - asm volatile("nc 0(1,%1),0(%2)" - : "=m" (*(char *) addr) - : "a" (addr), "a" (_ni_bitmap + (nr & 7)), - "m" (*(char *) addr) : "cc" ); + asm volatile( + " nc 0(1,%1),0(%2)" + : "=m" (*(char *) addr) : "a" (addr), + "a" (_ni_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc"); } static inline void @@ -291,40 +297,7 @@ __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr) unsigned long addr; addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); - switch (nr&7) { - case 0: - asm volatile ("ni 0(%1),0xFE" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 1: - asm volatile ("ni 0(%1),0xFD": "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 2: - asm volatile ("ni 0(%1),0xFB" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 3: - asm volatile ("ni 0(%1),0xF7" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 4: - asm volatile ("ni 0(%1),0xEF" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 5: - asm volatile ("ni 0(%1),0xDF" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 6: - asm volatile ("ni 0(%1),0xBF" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 7: - asm volatile ("ni 0(%1),0x7F" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - } + *(unsigned char *) addr &= ~(1 << (nr & 7)); } #define clear_bit_simple(nr,addr) \ @@ -340,10 +313,10 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) unsigned long addr; addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); - asm volatile("xc 0(1,%1),0(%2)" - : "=m" (*(char *) addr) - : "a" (addr), "a" (_oi_bitmap + (nr & 7)), - "m" (*(char *) addr) : "cc" ); + asm volatile( + " xc 0(1,%1),0(%2)" + : "=m" (*(char *) addr) : "a" (addr), + "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" ); } static inline void @@ -352,40 +325,7 @@ __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) unsigned long addr; addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); - switch (nr&7) { - case 0: - asm volatile ("xi 0(%1),0x01" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 1: - asm volatile ("xi 0(%1),0x02" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 2: - asm volatile ("xi 0(%1),0x04" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 3: - asm volatile ("xi 0(%1),0x08" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 4: - asm volatile ("xi 0(%1),0x10" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 5: - asm volatile ("xi 0(%1),0x20" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 6: - asm volatile ("xi 0(%1),0x40" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - case 7: - asm volatile ("xi 0(%1),0x80" : "=m" (*(char *) addr) - : "a" (addr), "m" (*(char *) addr) : "cc" ); - break; - } + *(unsigned char *) addr ^= 1 << (nr & 7); } #define change_bit_simple(nr,addr) \ @@ -404,10 +344,11 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; - asm volatile("oc 0(1,%1),0(%2)" - : "=m" (*(char *) addr) - : "a" (addr), "a" (_oi_bitmap + (nr & 7)), - "m" (*(char *) addr) : "cc", "memory" ); + asm volatile( + " oc 0(1,%1),0(%2)" + : "=m" (*(char *) addr) + : "a" (addr), "a" (_oi_bitmap + (nr & 7)), + "m" (*(char *) addr) : "cc", "memory"); return (ch >> (nr & 7)) & 1; } #define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y) @@ -423,10 +364,11 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; - asm volatile("nc 0(1,%1),0(%2)" - : "=m" (*(char *) addr) - : "a" (addr), "a" (_ni_bitmap + (nr & 7)), - "m" (*(char *) addr) : "cc", "memory" ); + asm volatile( + " nc 0(1,%1),0(%2)" + : "=m" (*(char *) addr) + : "a" (addr), "a" (_ni_bitmap + (nr & 7)), + "m" (*(char *) addr) : "cc", "memory"); return (ch >> (nr & 7)) & 1; } #define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y) @@ -442,10 +384,11 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); ch = *(unsigned char *) addr; - asm volatile("xc 0(1,%1),0(%2)" - : "=m" (*(char *) addr) - : "a" (addr), "a" (_oi_bitmap + (nr & 7)), - "m" (*(char *) addr) : "cc", "memory" ); + asm volatile( + " xc 0(1,%1),0(%2)" + : "=m" (*(char *) addr) + : "a" (addr), "a" (_oi_bitmap + (nr & 7)), + "m" (*(char *) addr) : "cc", "memory"); return (ch >> (nr & 7)) & 1; } #define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y) @@ -557,35 +500,36 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size) if (!size) return 0; - __asm__(" lhi %1,-1\n" - " lr %2,%3\n" - " slr %0,%0\n" - " ahi %2,31\n" - " srl %2,5\n" - "0: c %1,0(%0,%4)\n" - " jne 1f\n" - " la %0,4(%0)\n" - " brct %2,0b\n" - " lr %0,%3\n" - " j 4f\n" - "1: l %2,0(%0,%4)\n" - " sll %0,3\n" - " lhi %1,0xff\n" - " tml %2,0xffff\n" - " jno 2f\n" - " ahi %0,16\n" - " srl %2,16\n" - "2: tml %2,0x00ff\n" - " jno 3f\n" - " ahi %0,8\n" - " srl %2,8\n" - "3: nr %2,%1\n" - " ic %2,0(%2,%5)\n" - " alr %0,%2\n" - "4:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) - : "a" (size), "a" (addr), "a" (&_zb_findmap), - "m" (*(addrtype *) addr) : "cc" ); + asm volatile( + " lhi %1,-1\n" + " lr %2,%3\n" + " slr %0,%0\n" + " ahi %2,31\n" + " srl %2,5\n" + "0: c %1,0(%0,%4)\n" + " jne 1f\n" + " la %0,4(%0)\n" + " brct %2,0b\n" + " lr %0,%3\n" + " j 4f\n" + "1: l %2,0(%0,%4)\n" + " sll %0,3\n" + " lhi %1,0xff\n" + " tml %2,0xffff\n" + " jno 2f\n" + " ahi %0,16\n" + " srl %2,16\n" + "2: tml %2,0x00ff\n" + " jno 3f\n" + " ahi %0,8\n" + " srl %2,8\n" + "3: nr %2,%1\n" + " ic %2,0(%2,%5)\n" + " alr %0,%2\n" + "4:" + : "=&a" (res), "=&d" (cmp), "=&a" (count) + : "a" (size), "a" (addr), "a" (&_zb_findmap), + "m" (*(addrtype *) addr) : "cc"); return (res < size) ? res : size; } @@ -598,35 +542,36 @@ find_first_bit(const unsigned long * addr, unsigned long size) if (!size) return 0; - __asm__(" slr %1,%1\n" - " lr %2,%3\n" - " slr %0,%0\n" - " ahi %2,31\n" - " srl %2,5\n" - "0: c %1,0(%0,%4)\n" - " jne 1f\n" - " la %0,4(%0)\n" - " brct %2,0b\n" - " lr %0,%3\n" - " j 4f\n" - "1: l %2,0(%0,%4)\n" - " sll %0,3\n" - " lhi %1,0xff\n" - " tml %2,0xffff\n" - " jnz 2f\n" - " ahi %0,16\n" - " srl %2,16\n" - "2: tml %2,0x00ff\n" - " jnz 3f\n" - " ahi %0,8\n" - " srl %2,8\n" - "3: nr %2,%1\n" - " ic %2,0(%2,%5)\n" - " alr %0,%2\n" - "4:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) - : "a" (size), "a" (addr), "a" (&_sb_findmap), - "m" (*(addrtype *) addr) : "cc" ); + asm volatile( + " slr %1,%1\n" + " lr %2,%3\n" + " slr %0,%0\n" + " ahi %2,31\n" + " srl %2,5\n" + "0: c %1,0(%0,%4)\n" + " jne 1f\n" + " la %0,4(%0)\n" + " brct %2,0b\n" + " lr %0,%3\n" + " j 4f\n" + "1: l %2,0(%0,%4)\n" + " sll %0,3\n" + " lhi %1,0xff\n" + " tml %2,0xffff\n" + " jnz 2f\n" + " ahi %0,16\n" + " srl %2,16\n" + "2: tml %2,0x00ff\n" + " jnz 3f\n" + " ahi %0,8\n" + " srl %2,8\n" + "3: nr %2,%1\n" + " ic %2,0(%2,%5)\n" + " alr %0,%2\n" + "4:" + : "=&a" (res), "=&d" (cmp), "=&a" (count) + : "a" (size), "a" (addr), "a" (&_sb_findmap), + "m" (*(addrtype *) addr) : "cc"); return (res < size) ? res : size; } @@ -640,39 +585,40 @@ find_first_zero_bit(const unsigned long * addr, unsigned long size) if (!size) return 0; - __asm__(" lghi %1,-1\n" - " lgr %2,%3\n" - " slgr %0,%0\n" - " aghi %2,63\n" - " srlg %2,%2,6\n" - "0: cg %1,0(%0,%4)\n" - " jne 1f\n" - " la %0,8(%0)\n" - " brct %2,0b\n" - " lgr %0,%3\n" - " j 5f\n" - "1: lg %2,0(%0,%4)\n" - " sllg %0,%0,3\n" - " clr %2,%1\n" - " jne 2f\n" - " aghi %0,32\n" - " srlg %2,%2,32\n" - "2: lghi %1,0xff\n" - " tmll %2,0xffff\n" - " jno 3f\n" - " aghi %0,16\n" - " srl %2,16\n" - "3: tmll %2,0x00ff\n" - " jno 4f\n" - " aghi %0,8\n" - " srl %2,8\n" - "4: ngr %2,%1\n" - " ic %2,0(%2,%5)\n" - " algr %0,%2\n" - "5:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) + asm volatile( + " lghi %1,-1\n" + " lgr %2,%3\n" + " slgr %0,%0\n" + " aghi %2,63\n" + " srlg %2,%2,6\n" + "0: cg %1,0(%0,%4)\n" + " jne 1f\n" + " la %0,8(%0)\n" + " brct %2,0b\n" + " lgr %0,%3\n" + " j 5f\n" + "1: lg %2,0(%0,%4)\n" + " sllg %0,%0,3\n" + " clr %2,%1\n" + " jne 2f\n" + " aghi %0,32\n" + " srlg %2,%2,32\n" + "2: lghi %1,0xff\n" + " tmll %2,0xffff\n" + " jno 3f\n" + " aghi %0,16\n" + " srl %2,16\n" + "3: tmll %2,0x00ff\n" + " jno 4f\n" + " aghi %0,8\n" + " srl %2,8\n" + "4: ngr %2,%1\n" + " ic %2,0(%2,%5)\n" + " algr %0,%2\n" + "5:" + : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (addr), "a" (&_zb_findmap), - "m" (*(addrtype *) addr) : "cc" ); + "m" (*(addrtype *) addr) : "cc"); return (res < size) ? res : size; } @@ -684,39 +630,40 @@ find_first_bit(const unsigned long * addr, unsigned long size) if (!size) return 0; - __asm__(" slgr %1,%1\n" - " lgr %2,%3\n" - " slgr %0,%0\n" - " aghi %2,63\n" - " srlg %2,%2,6\n" - "0: cg %1,0(%0,%4)\n" - " jne 1f\n" - " aghi %0,8\n" - " brct %2,0b\n" - " lgr %0,%3\n" - " j 5f\n" - "1: lg %2,0(%0,%4)\n" - " sllg %0,%0,3\n" - " clr %2,%1\n" - " jne 2f\n" - " aghi %0,32\n" - " srlg %2,%2,32\n" - "2: lghi %1,0xff\n" - " tmll %2,0xffff\n" - " jnz 3f\n" - " aghi %0,16\n" - " srl %2,16\n" - "3: tmll %2,0x00ff\n" - " jnz 4f\n" - " aghi %0,8\n" - " srl %2,8\n" - "4: ngr %2,%1\n" - " ic %2,0(%2,%5)\n" - " algr %0,%2\n" - "5:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) + asm volatile( + " slgr %1,%1\n" + " lgr %2,%3\n" + " slgr %0,%0\n" + " aghi %2,63\n" + " srlg %2,%2,6\n" + "0: cg %1,0(%0,%4)\n" + " jne 1f\n" + " aghi %0,8\n" + " brct %2,0b\n" + " lgr %0,%3\n" + " j 5f\n" + "1: lg %2,0(%0,%4)\n" + " sllg %0,%0,3\n" + " clr %2,%1\n" + " jne 2f\n" + " aghi %0,32\n" + " srlg %2,%2,32\n" + "2: lghi %1,0xff\n" + " tmll %2,0xffff\n" + " jnz 3f\n" + " aghi %0,16\n" + " srl %2,16\n" + "3: tmll %2,0x00ff\n" + " jnz 4f\n" + " aghi %0,8\n" + " srl %2,8\n" + "4: ngr %2,%1\n" + " ic %2,0(%2,%5)\n" + " algr %0,%2\n" + "5:" + : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (addr), "a" (&_sb_findmap), - "m" (*(addrtype *) addr) : "cc" ); + "m" (*(addrtype *) addr) : "cc"); return (res < size) ? res : size; } @@ -832,36 +779,37 @@ ext2_find_first_zero_bit(void *vaddr, unsigned int size) if (!size) return 0; - __asm__(" lhi %1,-1\n" - " lr %2,%3\n" - " ahi %2,31\n" - " srl %2,5\n" - " slr %0,%0\n" - "0: cl %1,0(%0,%4)\n" - " jne 1f\n" - " ahi %0,4\n" - " brct %2,0b\n" - " lr %0,%3\n" - " j 4f\n" - "1: l %2,0(%0,%4)\n" - " sll %0,3\n" - " ahi %0,24\n" - " lhi %1,0xff\n" - " tmh %2,0xffff\n" - " jo 2f\n" - " ahi %0,-16\n" - " srl %2,16\n" - "2: tml %2,0xff00\n" - " jo 3f\n" - " ahi %0,-8\n" - " srl %2,8\n" - "3: nr %2,%1\n" - " ic %2,0(%2,%5)\n" - " alr %0,%2\n" - "4:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) - : "a" (size), "a" (vaddr), "a" (&_zb_findmap), - "m" (*(addrtype *) vaddr) : "cc" ); + asm volatile( + " lhi %1,-1\n" + " lr %2,%3\n" + " ahi %2,31\n" + " srl %2,5\n" + " slr %0,%0\n" + "0: cl %1,0(%0,%4)\n" + " jne 1f\n" + " ahi %0,4\n" + " brct %2,0b\n" + " lr %0,%3\n" + " j 4f\n" + "1: l %2,0(%0,%4)\n" + " sll %0,3\n" + " ahi %0,24\n" + " lhi %1,0xff\n" + " tmh %2,0xffff\n" + " jo 2f\n" + " ahi %0,-16\n" + " srl %2,16\n" + "2: tml %2,0xff00\n" + " jo 3f\n" + " ahi %0,-8\n" + " srl %2,8\n" + "3: nr %2,%1\n" + " ic %2,0(%2,%5)\n" + " alr %0,%2\n" + "4:" + : "=&a" (res), "=&d" (cmp), "=&a" (count) + : "a" (size), "a" (vaddr), "a" (&_zb_findmap), + "m" (*(addrtype *) vaddr) : "cc"); return (res < size) ? res : size; } @@ -875,39 +823,40 @@ ext2_find_first_zero_bit(void *vaddr, unsigned long size) if (!size) return 0; - __asm__(" lghi %1,-1\n" - " lgr %2,%3\n" - " aghi %2,63\n" - " srlg %2,%2,6\n" - " slgr %0,%0\n" - "0: clg %1,0(%0,%4)\n" - " jne 1f\n" - " aghi %0,8\n" - " brct %2,0b\n" - " lgr %0,%3\n" - " j 5f\n" - "1: cl %1,0(%0,%4)\n" - " jne 2f\n" - " aghi %0,4\n" - "2: l %2,0(%0,%4)\n" - " sllg %0,%0,3\n" - " aghi %0,24\n" - " lghi %1,0xff\n" - " tmlh %2,0xffff\n" - " jo 3f\n" - " aghi %0,-16\n" - " srl %2,16\n" - "3: tmll %2,0xff00\n" - " jo 4f\n" - " aghi %0,-8\n" - " srl %2,8\n" - "4: ngr %2,%1\n" - " ic %2,0(%2,%5)\n" - " algr %0,%2\n" - "5:" - : "=&a" (res), "=&d" (cmp), "=&a" (count) + asm volatile( + " lghi %1,-1\n" + " lgr %2,%3\n" + " aghi %2,63\n" + " srlg %2,%2,6\n" + " slgr %0,%0\n" + "0: clg %1,0(%0,%4)\n" + " jne 1f\n" + " aghi %0,8\n" + " brct %2,0b\n" + " lgr %0,%3\n" + " j 5f\n" + "1: cl %1,0(%0,%4)\n" + " jne 2f\n" + " aghi %0,4\n" + "2: l %2,0(%0,%4)\n" + " sllg %0,%0,3\n" + " aghi %0,24\n" + " lghi %1,0xff\n" + " tmlh %2,0xffff\n" + " jo 3f\n" + " aghi %0,-16\n" + " srl %2,16\n" + "3: tmll %2,0xff00\n" + " jo 4f\n" + " aghi %0,-8\n" + " srl %2,8\n" + "4: ngr %2,%1\n" + " ic %2,0(%2,%5)\n" + " algr %0,%2\n" + "5:" + : "=&a" (res), "=&d" (cmp), "=&a" (count) : "a" (size), "a" (vaddr), "a" (&_zb_findmap), - "m" (*(addrtype *) vaddr) : "cc" ); + "m" (*(addrtype *) vaddr) : "cc"); return (res < size) ? res : size; } @@ -927,13 +876,16 @@ ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) p = addr + offset / __BITOPS_WORDSIZE; if (bit) { #ifndef __s390x__ - asm(" ic %0,0(%1)\n" - " icm %0,2,1(%1)\n" - " icm %0,4,2(%1)\n" - " icm %0,8,3(%1)" - : "=&a" (word) : "a" (p), "m" (*p) : "cc" ); + asm volatile( + " ic %0,0(%1)\n" + " icm %0,2,1(%1)\n" + " icm %0,4,2(%1)\n" + " icm %0,8,3(%1)" + : "=&a" (word) : "a" (p), "m" (*p) : "cc"); #else - asm(" lrvg %0,%1" : "=a" (word) : "m" (*p) ); + asm volatile( + " lrvg %0,%1" + : "=a" (word) : "m" (*p) ); #endif /* * s390 version of ffz returns __BITOPS_WORDSIZE diff --git a/include/asm-s390/byteorder.h b/include/asm-s390/byteorder.h index 2cc35a0e188..1fe2492baa8 100644 --- a/include/asm-s390/byteorder.h +++ b/include/asm-s390/byteorder.h @@ -14,60 +14,54 @@ #ifdef __GNUC__ #ifdef __s390x__ -static __inline__ __u64 ___arch__swab64p(const __u64 *x) +static inline __u64 ___arch__swab64p(const __u64 *x) { __u64 result; - __asm__ __volatile__ ( - " lrvg %0,%1" - : "=d" (result) : "m" (*x) ); + asm volatile("lrvg %0,%1" : "=d" (result) : "m" (*x)); return result; } -static __inline__ __u64 ___arch__swab64(__u64 x) +static inline __u64 ___arch__swab64(__u64 x) { __u64 result; - __asm__ __volatile__ ( - " lrvgr %0,%1" - : "=d" (result) : "d" (x) ); + asm volatile("lrvgr %0,%1" : "=d" (result) : "d" (x)); return result; } -static __inline__ void ___arch__swab64s(__u64 *x) +static inline void ___arch__swab64s(__u64 *x) { *x = ___arch__swab64p(x); } #endif /* __s390x__ */ -static __inline__ __u32 ___arch__swab32p(const __u32 *x) +static inline __u32 ___arch__swab32p(const __u32 *x) { __u32 result; - __asm__ __volatile__ ( + asm volatile( #ifndef __s390x__ - " icm %0,8,3(%1)\n" - " icm %0,4,2(%1)\n" - " icm %0,2,1(%1)\n" - " ic %0,0(%1)" - : "=&d" (result) : "a" (x), "m" (*x) : "cc" ); + " icm %0,8,3(%1)\n" + " icm %0,4,2(%1)\n" + " icm %0,2,1(%1)\n" + " ic %0,0(%1)" + : "=&d" (result) : "a" (x), "m" (*x) : "cc"); #else /* __s390x__ */ - " lrv %0,%1" - : "=d" (result) : "m" (*x) ); + " lrv %0,%1" + : "=d" (result) : "m" (*x)); #endif /* __s390x__ */ return result; } -static __inline__ __u32 ___arch__swab32(__u32 x) +static inline __u32 ___arch__swab32(__u32 x) { #ifndef __s390x__ return ___arch__swab32p(&x); #else /* __s390x__ */ __u32 result; - __asm__ __volatile__ ( - " lrvr %0,%1" - : "=d" (result) : "d" (x) ); + asm volatile("lrvr %0,%1" : "=d" (result) : "d" (x)); return result; #endif /* __s390x__ */ } @@ -81,14 +75,14 @@ static __inline__ __u16 ___arch__swab16p(const __u16 *x) { __u16 result; - __asm__ __volatile__ ( + asm volatile( #ifndef __s390x__ - " icm %0,2,1(%1)\n" - " ic %0,0(%1)\n" - : "=&d" (result) : "a" (x), "m" (*x) : "cc" ); + " icm %0,2,1(%1)\n" + " ic %0,0(%1)\n" + : "=&d" (result) : "a" (x), "m" (*x) : "cc"); #else /* __s390x__ */ - " lrvh %0,%1" - : "=d" (result) : "m" (*x) ); + " lrvh %0,%1" + : "=d" (result) : "m" (*x)); #endif /* __s390x__ */ return result; } diff --git a/include/asm-s390/checksum.h b/include/asm-s390/checksum.h index 471f2af2b16..37c362d89fa 100644 --- a/include/asm-s390/checksum.h +++ b/include/asm-s390/checksum.h @@ -30,57 +30,13 @@ static inline unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) { - /* - * Experiments with ethernet and slip connections show that buf - * is aligned on either a 2-byte or 4-byte boundary. - */ -#ifndef __s390x__ - register_pair rp; - - rp.subreg.even = (unsigned long) buff; - rp.subreg.odd = (unsigned long) len; - __asm__ __volatile__ ( - "0: cksm %0,%1\n" /* do checksum on longs */ - " jo 0b\n" - : "+&d" (sum), "+&a" (rp) : : "cc", "memory" ); -#else /* __s390x__ */ - __asm__ __volatile__ ( - " lgr 2,%1\n" /* address in gpr 2 */ - " lgfr 3,%2\n" /* length in gpr 3 */ - "0: cksm %0,2\n" /* do checksum on longs */ - " jo 0b\n" - : "+&d" (sum) - : "d" (buff), "d" (len) - : "cc", "memory", "2", "3" ); -#endif /* __s390x__ */ - return sum; -} - -/* - * csum_partial as an inline function - */ -static inline unsigned int -csum_partial_inline(const unsigned char * buff, int len, unsigned int sum) -{ -#ifndef __s390x__ - register_pair rp; + register unsigned long reg2 asm("2") = (unsigned long) buff; + register unsigned long reg3 asm("3") = (unsigned long) len; - rp.subreg.even = (unsigned long) buff; - rp.subreg.odd = (unsigned long) len; - __asm__ __volatile__ ( - "0: cksm %0,%1\n" /* do checksum on longs */ - " jo 0b\n" - : "+&d" (sum), "+&a" (rp) : : "cc", "memory" ); -#else /* __s390x__ */ - __asm__ __volatile__ ( - " lgr 2,%1\n" /* address in gpr 2 */ - " lgfr 3,%2\n" /* length in gpr 3 */ - "0: cksm %0,2\n" /* do checksum on longs */ - " jo 0b\n" - : "+&d" (sum) - : "d" (buff), "d" (len) - : "cc", "memory", "2", "3" ); -#endif /* __s390x__ */ + asm volatile( + "0: cksm %0,%1\n" /* do checksum on longs */ + " jo 0b\n" + : "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory"); return sum; } @@ -114,7 +70,7 @@ static inline unsigned int csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum) { memcpy(dst,src,len); - return csum_partial_inline(dst, len, sum); + return csum_partial(dst, len, sum); } /* @@ -126,22 +82,22 @@ csum_fold(unsigned int sum) #ifndef __s390x__ register_pair rp; - __asm__ __volatile__ ( - " slr %N1,%N1\n" /* %0 = H L */ - " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ - " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */ - " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */ - " alr %0,%1\n" /* %0 = H+L+C L+H */ - " srl %0,16\n" /* %0 = H+L+C */ - : "+&d" (sum), "=d" (rp) : : "cc" ); + asm volatile( + " slr %N1,%N1\n" /* %0 = H L */ + " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ + " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */ + " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */ + " alr %0,%1\n" /* %0 = H+L+C L+H */ + " srl %0,16\n" /* %0 = H+L+C */ + : "+&d" (sum), "=d" (rp) : : "cc"); #else /* __s390x__ */ - __asm__ __volatile__ ( - " sr 3,3\n" /* %0 = H*65536 + L */ - " lr 2,%0\n" /* %0 = H L, R2/R3 = H L / 0 0 */ - " srdl 2,16\n" /* %0 = H L, R2/R3 = 0 H / L 0 */ - " alr 2,3\n" /* %0 = H L, R2/R3 = L H / L 0 */ - " alr %0,2\n" /* %0 = H+L+C L+H */ - " srl %0,16\n" /* %0 = H+L+C */ + asm volatile( + " sr 3,3\n" /* %0 = H*65536 + L */ + " lr 2,%0\n" /* %0 = H L, 2/3 = H L / 0 0 */ + " srdl 2,16\n" /* %0 = H L, 2/3 = 0 H / L 0 */ + " alr 2,3\n" /* %0 = H L, 2/3 = L H / L 0 */ + " alr %0,2\n" /* %0 = H+L+C L+H */ + " srl %0,16\n" /* %0 = H+L+C */ : "+&d" (sum) : : "cc", "2", "3"); #endif /* __s390x__ */ return ((unsigned short) ~sum); @@ -155,29 +111,7 @@ csum_fold(unsigned int sum) static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) { - unsigned long sum; -#ifndef __s390x__ - register_pair rp; - - rp.subreg.even = (unsigned long) iph; - rp.subreg.odd = (unsigned long) ihl*4; - __asm__ __volatile__ ( - " sr %0,%0\n" /* set sum to zero */ - "0: cksm %0,%1\n" /* do checksum on longs */ - " jo 0b\n" - : "=&d" (sum), "+&a" (rp) : : "cc", "memory" ); -#else /* __s390x__ */ - __asm__ __volatile__ ( - " slgr %0,%0\n" /* set sum to zero */ - " lgr 2,%1\n" /* address in gpr 2 */ - " lgfr 3,%2\n" /* length in gpr 3 */ - "0: cksm %0,2\n" /* do checksum on ints */ - " jo 0b\n" - : "=&d" (sum) - : "d" (iph), "d" (ihl*4) - : "cc", "memory", "2", "3" ); -#endif /* __s390x__ */ - return csum_fold(sum); + return csum_fold(csum_partial(iph, ihl*4, 0)); } /* @@ -190,47 +124,47 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned int sum) { #ifndef __s390x__ - __asm__ __volatile__ ( - " alr %0,%1\n" /* sum += saddr */ - " brc 12,0f\n" - " ahi %0,1\n" /* add carry */ + asm volatile( + " alr %0,%1\n" /* sum += saddr */ + " brc 12,0f\n" + " ahi %0,1\n" /* add carry */ "0:" - : "+&d" (sum) : "d" (saddr) : "cc" ); - __asm__ __volatile__ ( - " alr %0,%1\n" /* sum += daddr */ - " brc 12,1f\n" - " ahi %0,1\n" /* add carry */ + : "+&d" (sum) : "d" (saddr) : "cc"); + asm volatile( + " alr %0,%1\n" /* sum += daddr */ + " brc 12,1f\n" + " ahi %0,1\n" /* add carry */ "1:" - : "+&d" (sum) : "d" (daddr) : "cc" ); - __asm__ __volatile__ ( - " alr %0,%1\n" /* sum += (len<<16) + (proto<<8) */ - " brc 12,2f\n" - " ahi %0,1\n" /* add carry */ + : "+&d" (sum) : "d" (daddr) : "cc"); + asm volatile( + " alr %0,%1\n" /* sum += (len<<16) + (proto<<8) */ + " brc 12,2f\n" + " ahi %0,1\n" /* add carry */ "2:" : "+&d" (sum) : "d" (((unsigned int) len<<16) + (unsigned int) proto) - : "cc" ); + : "cc"); #else /* __s390x__ */ - __asm__ __volatile__ ( - " lgfr %0,%0\n" - " algr %0,%1\n" /* sum += saddr */ - " brc 12,0f\n" - " aghi %0,1\n" /* add carry */ - "0: algr %0,%2\n" /* sum += daddr */ - " brc 12,1f\n" - " aghi %0,1\n" /* add carry */ - "1: algfr %0,%3\n" /* sum += (len<<16) + proto */ - " brc 12,2f\n" - " aghi %0,1\n" /* add carry */ - "2: srlg 0,%0,32\n" - " alr %0,0\n" /* fold to 32 bits */ - " brc 12,3f\n" - " ahi %0,1\n" /* add carry */ - "3: llgfr %0,%0" + asm volatile( + " lgfr %0,%0\n" + " algr %0,%1\n" /* sum += saddr */ + " brc 12,0f\n" + " aghi %0,1\n" /* add carry */ + "0: algr %0,%2\n" /* sum += daddr */ + " brc 12,1f\n" + " aghi %0,1\n" /* add carry */ + "1: algfr %0,%3\n" /* sum += (len<<16) + proto */ + " brc 12,2f\n" + " aghi %0,1\n" /* add carry */ + "2: srlg 0,%0,32\n" + " alr %0,0\n" /* fold to 32 bits */ + " brc 12,3f\n" + " ahi %0,1\n" /* add carry */ + "3: llgfr %0,%0" : "+&d" (sum) : "d" (saddr), "d" (daddr), "d" (((unsigned int) len<<16) + (unsigned int) proto) - : "cc", "0" ); + : "cc", "0"); #endif /* __s390x__ */ return sum; } diff --git a/include/asm-s390/div64.h b/include/asm-s390/div64.h index af098dc3cf5..6cd978cefb2 100644 --- a/include/asm-s390/div64.h +++ b/include/asm-s390/div64.h @@ -1,49 +1 @@ -#ifndef __S390_DIV64 -#define __S390_DIV64 - -#ifndef __s390x__ - -/* for do_div "base" needs to be smaller than 2^31-1 */ -#define do_div(n, base) ({ \ - unsigned long long __n = (n); \ - unsigned long __r; \ - \ - asm (" slr 0,0\n" \ - " l 1,%1\n" \ - " srdl 0,1\n" \ - " dr 0,%2\n" \ - " alr 1,1\n" \ - " alr 0,0\n" \ - " lhi 2,1\n" \ - " n 2,%1\n" \ - " alr 0,2\n" \ - " clr 0,%2\n" \ - " jl 0f\n" \ - " slr 0,%2\n" \ - " ahi 1,1\n" \ - "0: st 1,%1\n" \ - " l 1,4+%1\n" \ - " srdl 0,1\n" \ - " dr 0,%2\n" \ - " alr 1,1\n" \ - " alr 0,0\n" \ - " lhi 2,1\n" \ - " n 2,4+%1\n" \ - " alr 0,2\n" \ - " clr 0,%2\n" \ - " jl 1f\n" \ - " slr 0,%2\n" \ - " ahi 1,1\n" \ - "1: st 1,4+%1\n" \ - " lr %0,0" \ - : "=d" (__r), "=m" (__n) \ - : "d" (base), "m" (__n) : "0", "1", "2", "cc" ); \ - (n) = (__n); \ - __r; \ -}) - -#else /* __s390x__ */ #include <asm-generic/div64.h> -#endif /* __s390x__ */ - -#endif diff --git a/include/asm-s390/ebcdic.h b/include/asm-s390/ebcdic.h index 15fd2eda6c9..7f6f641d32f 100644 --- a/include/asm-s390/ebcdic.h +++ b/include/asm-s390/ebcdic.h @@ -26,16 +26,16 @@ codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr) { if (nr-- <= 0) return; - __asm__ __volatile__( - " bras 1,1f\n" - " tr 0(1,%0),0(%2)\n" - "0: tr 0(256,%0),0(%2)\n" - " la %0,256(%0)\n" - "1: ahi %1,-256\n" - " jnm 0b\n" - " ex %1,0(1)" - : "+&a" (addr), "+&a" (nr) - : "a" (codepage) : "cc", "memory", "1" ); + asm volatile( + " bras 1,1f\n" + " tr 0(1,%0),0(%2)\n" + "0: tr 0(256,%0),0(%2)\n" + " la %0,256(%0)\n" + "1: ahi %1,-256\n" + " jnm 0b\n" + " ex %1,0(1)" + : "+&a" (addr), "+&a" (nr) + : "a" (codepage) : "cc", "memory", "1"); } #define ASCEBC(addr,nr) codepage_convert(_ascebc, addr, nr) diff --git a/include/asm-s390/io.h b/include/asm-s390/io.h index a6cc27e7700..63c78b9399c 100644 --- a/include/asm-s390/io.h +++ b/include/asm-s390/io.h @@ -27,18 +27,16 @@ static inline unsigned long virt_to_phys(volatile void * address) { unsigned long real_address; - __asm__ ( + asm volatile( #ifndef __s390x__ - " lra %0,0(%1)\n" - " jz 0f\n" - " sr %0,%0\n" + " lra %0,0(%1)\n" #else /* __s390x__ */ - " lrag %0,0(%1)\n" - " jz 0f\n" - " slgr %0,%0\n" + " lrag %0,0(%1)\n" #endif /* __s390x__ */ + " jz 0f\n" + " la %0,0\n" "0:" - : "=a" (real_address) : "a" (address) : "cc" ); + : "=a" (real_address) : "a" (address) : "cc"); return real_address; } diff --git a/include/asm-s390/irqflags.h b/include/asm-s390/irqflags.h index 3b566a5b3cc..3f26131120b 100644 --- a/include/asm-s390/irqflags.h +++ b/include/asm-s390/irqflags.h @@ -10,43 +10,93 @@ #ifdef __KERNEL__ +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + +/* store then or system mask. */ +#define __raw_local_irq_stosm(__or) \ +({ \ + unsigned long __mask; \ + asm volatile( \ + " stosm %0,%1" \ + : "=Q" (__mask) : "i" (__or) : "memory"); \ + __mask; \ +}) + +/* store then and system mask. */ +#define __raw_local_irq_stnsm(__and) \ +({ \ + unsigned long __mask; \ + asm volatile( \ + " stnsm %0,%1" \ + : "=Q" (__mask) : "i" (__and) : "memory"); \ + __mask; \ +}) + +/* set system mask. */ +#define __raw_local_irq_ssm(__mask) \ +({ \ + asm volatile("ssm %0" : : "Q" (__mask) : "memory"); \ +}) + +#else /* __GNUC__ */ + +/* store then or system mask. */ +#define __raw_local_irq_stosm(__or) \ +({ \ + unsigned long __mask; \ + asm volatile( \ + " stosm 0(%1),%2" \ + : "=m" (__mask) \ + : "a" (&__mask), "i" (__or) : "memory"); \ + __mask; \ +}) + +/* store then and system mask. */ +#define __raw_local_irq_stnsm(__and) \ +({ \ + unsigned long __mask; \ + asm volatile( \ + " stnsm 0(%1),%2" \ + : "=m" (__mask) \ + : "a" (&__mask), "i" (__and) : "memory"); \ + __mask; \ +}) + +/* set system mask. */ +#define __raw_local_irq_ssm(__mask) \ +({ \ + asm volatile( \ + " ssm 0(%0)" \ + : : "a" (&__mask), "m" (__mask) : "memory"); \ +}) + +#endif /* __GNUC__ */ + /* interrupt control.. */ -#define raw_local_irq_enable() ({ \ - unsigned long __dummy; \ - __asm__ __volatile__ ( \ - "stosm 0(%1),0x03" \ - : "=m" (__dummy) : "a" (&__dummy) : "memory" ); \ - }) - -#define raw_local_irq_disable() ({ \ - unsigned long __flags; \ - __asm__ __volatile__ ( \ - "stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \ - __flags; \ - }) - -#define raw_local_save_flags(x) \ -do { \ - typecheck(unsigned long, x); \ - __asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) ); \ -} while (0) +static inline unsigned long raw_local_irq_enable(void) +{ + return __raw_local_irq_stosm(0x03); +} -#define raw_local_irq_restore(x) \ -do { \ - typecheck(unsigned long, x); \ - __asm__ __volatile__("ssm 0(%0)" : : "a" (&x), "m" (x) : "memory"); \ +static inline unsigned long raw_local_irq_disable(void) +{ + return __raw_local_irq_stnsm(0xfc); +} + +#define raw_local_save_flags(x) \ +do { \ + typecheck(unsigned long, x); \ + (x) = __raw_local_irq_stosm(0x00); \ } while (0) -#define raw_irqs_disabled() \ -({ \ - unsigned long flags; \ - raw_local_save_flags(flags); \ - !((flags >> __FLAG_SHIFT) & 3); \ -}) +static inline void raw_local_irq_restore(unsigned long flags) +{ + __raw_local_irq_ssm(flags); +} static inline int raw_irqs_disabled_flags(unsigned long flags) { - return !((flags >> __FLAG_SHIFT) & 3); + return !(flags & (3UL << (BITS_PER_LONG - 8))); } /* For spinlocks etc */ diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h index 18695d10ded..06583ed0bde 100644 --- a/include/asm-s390/lowcore.h +++ b/include/asm-s390/lowcore.h @@ -359,7 +359,7 @@ extern struct _lowcore *lowcore_ptr[]; static inline void set_prefix(__u32 address) { - __asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" ); + asm volatile("spx %0" : : "m" (address) : "memory"); } #define __PANIC_MAGIC 0xDEADC0DE diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index b2628dc5c49..796c400f2b7 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h @@ -22,89 +22,45 @@ #include <asm/setup.h> #ifndef __ASSEMBLY__ -#ifndef __s390x__ - -static inline void clear_page(void *page) -{ - register_pair rp; - - rp.subreg.even = (unsigned long) page; - rp.subreg.odd = (unsigned long) 4096; - asm volatile (" slr 1,1\n" - " mvcl %0,0" - : "+&a" (rp) : : "memory", "cc", "1" ); -} - -static inline void copy_page(void *to, void *from) -{ - if (MACHINE_HAS_MVPG) - asm volatile (" sr 0,0\n" - " mvpg %0,%1" - : : "a" ((void *)(to)), "a" ((void *)(from)) - : "memory", "cc", "0" ); - else - asm volatile (" mvc 0(256,%0),0(%1)\n" - " mvc 256(256,%0),256(%1)\n" - " mvc 512(256,%0),512(%1)\n" - " mvc 768(256,%0),768(%1)\n" - " mvc 1024(256,%0),1024(%1)\n" - " mvc 1280(256,%0),1280(%1)\n" - " mvc 1536(256,%0),1536(%1)\n" - " mvc 1792(256,%0),1792(%1)\n" - " mvc 2048(256,%0),2048(%1)\n" - " mvc 2304(256,%0),2304(%1)\n" - " mvc 2560(256,%0),2560(%1)\n" - " mvc 2816(256,%0),2816(%1)\n" - " mvc 3072(256,%0),3072(%1)\n" - " mvc 3328(256,%0),3328(%1)\n" - " mvc 3584(256,%0),3584(%1)\n" - " mvc 3840(256,%0),3840(%1)\n" - : : "a"((void *)(to)),"a"((void *)(from)) - : "memory" ); -} - -#else /* __s390x__ */ - static inline void clear_page(void *page) { - asm volatile (" lgr 2,%0\n" - " lghi 3,4096\n" - " slgr 1,1\n" - " mvcl 2,0" - : : "a" ((void *) (page)) - : "memory", "cc", "1", "2", "3" ); + register unsigned long reg1 asm ("1") = 0; + register void *reg2 asm ("2") = page; + register unsigned long reg3 asm ("3") = 4096; + asm volatile( + " mvcl 2,0" + : "+d" (reg2), "+d" (reg3) : "d" (reg1) : "memory", "cc"); } static inline void copy_page(void *to, void *from) { - if (MACHINE_HAS_MVPG) - asm volatile (" sgr 0,0\n" - " mvpg %0,%1" - : : "a" ((void *)(to)), "a" ((void *)(from)) - : "memory", "cc", "0" ); - else - asm volatile (" mvc 0(256,%0),0(%1)\n" - " mvc 256(256,%0),256(%1)\n" - " mvc 512(256,%0),512(%1)\n" - " mvc 768(256,%0),768(%1)\n" - " mvc 1024(256,%0),1024(%1)\n" - " mvc 1280(256,%0),1280(%1)\n" - " mvc 1536(256,%0),1536(%1)\n" - " mvc 1792(256,%0),1792(%1)\n" - " mvc 2048(256,%0),2048(%1)\n" - " mvc 2304(256,%0),2304(%1)\n" - " mvc 2560(256,%0),2560(%1)\n" - " mvc 2816(256,%0),2816(%1)\n" - " mvc 3072(256,%0),3072(%1)\n" - " mvc 3328(256,%0),3328(%1)\n" - " mvc 3584(256,%0),3584(%1)\n" - " mvc 3840(256,%0),3840(%1)\n" - : : "a"((void *)(to)),"a"((void *)(from)) - : "memory" ); + if (MACHINE_HAS_MVPG) { + register unsigned long reg0 asm ("0") = 0; + asm volatile( + " mvpg %0,%1" + : : "a" (to), "a" (from), "d" (reg0) + : "memory", "cc"); + } else + asm volatile( + " mvc 0(256,%0),0(%1)\n" + " mvc 256(256,%0),256(%1)\n" + " mvc 512(256,%0),512(%1)\n" + " mvc 768(256,%0),768(%1)\n" + " mvc 1024(256,%0),1024(%1)\n" + " mvc 1280(256,%0),1280(%1)\n" + " mvc 1536(256,%0),1536(%1)\n" + " mvc 1792(256,%0),1792(%1)\n" + " mvc 2048(256,%0),2048(%1)\n" + " mvc 2304(256,%0),2304(%1)\n" + " mvc 2560(256,%0),2560(%1)\n" + " mvc 2816(256,%0),2816(%1)\n" + " mvc 3072(256,%0),3072(%1)\n" + " mvc 3328(256,%0),3328(%1)\n" + " mvc 3584(256,%0),3584(%1)\n" + " mvc 3840(256,%0),3840(%1)\n" + : : "a" (to), "a" (from) : "memory"); } -#endif /* __s390x__ */ - #define clear_user_page(page, vaddr, pg) clear_page(page) #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) @@ -159,7 +115,7 @@ extern unsigned int default_storage_key; static inline void page_set_storage_key(unsigned long addr, unsigned int skey) { - asm volatile ( "sske %0,%1" : : "d" (skey), "a" (addr) ); + asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); } static inline unsigned int @@ -167,8 +123,7 @@ page_get_storage_key(unsigned long addr) { unsigned int skey; - asm volatile ( "iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0) ); - + asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0)); return skey; } diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index e965309feda..83425cdefc9 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -554,9 +554,10 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep) /* ipte in zarch mode can do the math */ pte_t *pto = ptep; #endif - asm volatile ("ipte %2,%3" - : "=m" (*ptep) : "m" (*ptep), - "a" (pto), "a" (address) ); + asm volatile( + " ipte %2,%3" + : "=m" (*ptep) : "m" (*ptep), + "a" (pto), "a" (address)); } pte_val(*ptep) = _PAGE_TYPE_EMPTY; } @@ -609,16 +610,17 @@ ptep_establish(struct vm_area_struct *vma, /* * Test and clear referenced bit in storage key. */ -#define page_test_and_clear_young(page) \ -({ \ - struct page *__page = (page); \ - unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \ - int __ccode; \ - asm volatile ("rrbe 0,%1\n\t" \ - "ipm %0\n\t" \ - "srl %0,28\n\t" \ - : "=d" (__ccode) : "a" (__physpage) : "cc" ); \ - (__ccode & 2); \ +#define page_test_and_clear_young(page) \ +({ \ + struct page *__page = (page); \ + unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT);\ + int __ccode; \ + asm volatile( \ + " rrbe 0,%1\n" \ + " ipm %0\n" \ + " srl %0,28\n" \ + : "=d" (__ccode) : "a" (__physpage) : "cc"); \ + (__ccode & 2); \ }) /* diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index 578c2209fa7..cbbedc63ba2 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h @@ -13,7 +13,6 @@ #ifndef __ASM_S390_PROCESSOR_H #define __ASM_S390_PROCESSOR_H -#include <asm/page.h> #include <asm/ptrace.h> #ifdef __KERNEL__ @@ -21,7 +20,7 @@ * Default implementation of macro that returns current * instruction pointer ("program counter"). */ -#define current_text_addr() ({ void *pc; __asm__("basr %0,0":"=a"(pc)); pc; }) +#define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) /* * CPU type and hardware bug flags. Kept separately for each CPU. @@ -202,7 +201,7 @@ unsigned long get_wchan(struct task_struct *p); static inline void cpu_relax(void) { if (MACHINE_HAS_DIAG44) - asm volatile ("diag 0,0,68" : : : "memory"); + asm volatile("diag 0,0,68" : : : "memory"); else barrier(); } @@ -213,9 +212,9 @@ static inline void cpu_relax(void) static inline void __load_psw(psw_t psw) { #ifndef __s390x__ - asm volatile ("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); + asm volatile("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc"); #else - asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); + asm volatile("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc"); #endif } @@ -232,20 +231,20 @@ static inline void __load_psw_mask (unsigned long mask) psw.mask = mask; #ifndef __s390x__ - asm volatile ( - " basr %0,0\n" - "0: ahi %0,1f-0b\n" - " st %0,4(%1)\n" - " lpsw 0(%1)\n" + asm volatile( + " basr %0,0\n" + "0: ahi %0,1f-0b\n" + " st %0,4(%1)\n" + " lpsw 0(%1)\n" "1:" - : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc" ); + : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc"); #else /* __s390x__ */ - asm volatile ( - " larl %0,1f\n" - " stg %0,8(%1)\n" - " lpswe 0(%1)\n" + asm volatile( + " larl %0,1f\n" + " stg %0,8(%1)\n" + " lpswe 0(%1)\n" "1:" - : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc" ); + : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc"); #endif /* __s390x__ */ } @@ -274,56 +273,57 @@ static inline void disabled_wait(unsigned long code) * the processor is dead afterwards */ #ifndef __s390x__ - asm volatile (" stctl 0,0,0(%2)\n" - " ni 0(%2),0xef\n" /* switch off protection */ - " lctl 0,0,0(%2)\n" - " stpt 0xd8\n" /* store timer */ - " stckc 0xe0\n" /* store clock comparator */ - " stpx 0x108\n" /* store prefix register */ - " stam 0,15,0x120\n" /* store access registers */ - " std 0,0x160\n" /* store f0 */ - " std 2,0x168\n" /* store f2 */ - " std 4,0x170\n" /* store f4 */ - " std 6,0x178\n" /* store f6 */ - " stm 0,15,0x180\n" /* store general registers */ - " stctl 0,15,0x1c0\n" /* store control registers */ - " oi 0x1c0,0x10\n" /* fake protection bit */ - " lpsw 0(%1)" - : "=m" (ctl_buf) - : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); + asm volatile( + " stctl 0,0,0(%2)\n" + " ni 0(%2),0xef\n" /* switch off protection */ + " lctl 0,0,0(%2)\n" + " stpt 0xd8\n" /* store timer */ + " stckc 0xe0\n" /* store clock comparator */ + " stpx 0x108\n" /* store prefix register */ + " stam 0,15,0x120\n" /* store access registers */ + " std 0,0x160\n" /* store f0 */ + " std 2,0x168\n" /* store f2 */ + " std 4,0x170\n" /* store f4 */ + " std 6,0x178\n" /* store f6 */ + " stm 0,15,0x180\n" /* store general registers */ + " stctl 0,15,0x1c0\n" /* store control registers */ + " oi 0x1c0,0x10\n" /* fake protection bit */ + " lpsw 0(%1)" + : "=m" (ctl_buf) + : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc"); #else /* __s390x__ */ - asm volatile (" stctg 0,0,0(%2)\n" - " ni 4(%2),0xef\n" /* switch off protection */ - " lctlg 0,0,0(%2)\n" - " lghi 1,0x1000\n" - " stpt 0x328(1)\n" /* store timer */ - " stckc 0x330(1)\n" /* store clock comparator */ - " stpx 0x318(1)\n" /* store prefix register */ - " stam 0,15,0x340(1)\n" /* store access registers */ - " stfpc 0x31c(1)\n" /* store fpu control */ - " std 0,0x200(1)\n" /* store f0 */ - " std 1,0x208(1)\n" /* store f1 */ - " std 2,0x210(1)\n" /* store f2 */ - " std 3,0x218(1)\n" /* store f3 */ - " std 4,0x220(1)\n" /* store f4 */ - " std 5,0x228(1)\n" /* store f5 */ - " std 6,0x230(1)\n" /* store f6 */ - " std 7,0x238(1)\n" /* store f7 */ - " std 8,0x240(1)\n" /* store f8 */ - " std 9,0x248(1)\n" /* store f9 */ - " std 10,0x250(1)\n" /* store f10 */ - " std 11,0x258(1)\n" /* store f11 */ - " std 12,0x260(1)\n" /* store f12 */ - " std 13,0x268(1)\n" /* store f13 */ - " std 14,0x270(1)\n" /* store f14 */ - " std 15,0x278(1)\n" /* store f15 */ - " stmg 0,15,0x280(1)\n" /* store general registers */ - " stctg 0,15,0x380(1)\n" /* store control registers */ - " oi 0x384(1),0x10\n" /* fake protection bit */ - " lpswe 0(%1)" - : "=m" (ctl_buf) - : "a" (&dw_psw), "a" (&ctl_buf), - "m" (dw_psw) : "cc", "0", "1"); + asm volatile( + " stctg 0,0,0(%2)\n" + " ni 4(%2),0xef\n" /* switch off protection */ + " lctlg 0,0,0(%2)\n" + " lghi 1,0x1000\n" + " stpt 0x328(1)\n" /* store timer */ + " stckc 0x330(1)\n" /* store clock comparator */ + " stpx 0x318(1)\n" /* store prefix register */ + " stam 0,15,0x340(1)\n"/* store access registers */ + " stfpc 0x31c(1)\n" /* store fpu control */ + " std 0,0x200(1)\n" /* store f0 */ + " std 1,0x208(1)\n" /* store f1 */ + " std 2,0x210(1)\n" /* store f2 */ + " std 3,0x218(1)\n" /* store f3 */ + " std 4,0x220(1)\n" /* store f4 */ + " std 5,0x228(1)\n" /* store f5 */ + " std 6,0x230(1)\n" /* store f6 */ + " std 7,0x238(1)\n" /* store f7 */ + " std 8,0x240(1)\n" /* store f8 */ + " std 9,0x248(1)\n" /* store f9 */ + " std 10,0x250(1)\n" /* store f10 */ + " std 11,0x258(1)\n" /* store f11 */ + " std 12,0x260(1)\n" /* store f12 */ + " std 13,0x268(1)\n" /* store f13 */ + " std 14,0x270(1)\n" /* store f14 */ + " std 15,0x278(1)\n" /* store f15 */ + " stmg 0,15,0x280(1)\n"/* store general registers */ + " stctg 0,15,0x380(1)\n"/* store control registers */ + " oi 0x384(1),0x10\n"/* fake protection bit */ + " lpswe 0(%1)" + : "=m" (ctl_buf) + : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0"); #endif /* __s390x__ */ } diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h index 4d75d77b0f9..8d2bf65b0b6 100644 --- a/include/asm-s390/ptrace.h +++ b/include/asm-s390/ptrace.h @@ -479,7 +479,7 @@ extern void show_regs(struct pt_regs * regs); static inline void psw_set_key(unsigned int key) { - asm volatile ( "spka 0(%0)" : : "d" (key) ); + asm volatile("spka 0(%0)" : : "d" (key)); } #endif /* __ASSEMBLY__ */ diff --git a/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h index 13ec1696515..90f4eccaa29 100644 --- a/include/asm-s390/rwsem.h +++ b/include/asm-s390/rwsem.h @@ -122,23 +122,23 @@ static inline void __down_read(struct rw_semaphore *sem) { signed long old, new; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%3)\n" - "0: lr %1,%0\n" - " ahi %1,%5\n" - " cs %0,%1,0(%3)\n" - " jl 0b" + " l %0,0(%3)\n" + "0: lr %1,%0\n" + " ahi %1,%5\n" + " cs %0,%1,0(%3)\n" + " jl 0b" #else /* __s390x__ */ - " lg %0,0(%3)\n" - "0: lgr %1,%0\n" - " aghi %1,%5\n" - " csg %0,%1,0(%3)\n" - " jl 0b" + " lg %0,0(%3)\n" + "0: lgr %1,%0\n" + " aghi %1,%5\n" + " csg %0,%1,0(%3)\n" + " jl 0b" #endif /* __s390x__ */ - : "=&d" (old), "=&d" (new), "=m" (sem->count) + : "=&d" (old), "=&d" (new), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), - "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" ); + "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); if (old < 0) rwsem_down_read_failed(sem); } @@ -150,27 +150,27 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) { signed long old, new; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%3)\n" - "0: ltr %1,%0\n" - " jm 1f\n" - " ahi %1,%5\n" - " cs %0,%1,0(%3)\n" - " jl 0b\n" + " l %0,0(%3)\n" + "0: ltr %1,%0\n" + " jm 1f\n" + " ahi %1,%5\n" + " cs %0,%1,0(%3)\n" + " jl 0b\n" "1:" #else /* __s390x__ */ - " lg %0,0(%3)\n" - "0: ltgr %1,%0\n" - " jm 1f\n" - " aghi %1,%5\n" - " csg %0,%1,0(%3)\n" - " jl 0b\n" + " lg %0,0(%3)\n" + "0: ltgr %1,%0\n" + " jm 1f\n" + " aghi %1,%5\n" + " csg %0,%1,0(%3)\n" + " jl 0b\n" "1:" #endif /* __s390x__ */ - : "=&d" (old), "=&d" (new), "=m" (sem->count) + : "=&d" (old), "=&d" (new), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), - "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" ); + "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); return old >= 0 ? 1 : 0; } @@ -182,23 +182,23 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) signed long old, new, tmp; tmp = RWSEM_ACTIVE_WRITE_BIAS; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%3)\n" - "0: lr %1,%0\n" - " a %1,%5\n" - " cs %0,%1,0(%3)\n" - " jl 0b" + " l %0,0(%3)\n" + "0: lr %1,%0\n" + " a %1,%5\n" + " cs %0,%1,0(%3)\n" + " jl 0b" #else /* __s390x__ */ - " lg %0,0(%3)\n" - "0: lgr %1,%0\n" - " ag %1,%5\n" - " csg %0,%1,0(%3)\n" - " jl 0b" + " lg %0,0(%3)\n" + "0: lgr %1,%0\n" + " ag %1,%5\n" + " csg %0,%1,0(%3)\n" + " jl 0b" #endif /* __s390x__ */ - : "=&d" (old), "=&d" (new), "=m" (sem->count) + : "=&d" (old), "=&d" (new), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), "m" (tmp) - : "cc", "memory" ); + : "cc", "memory"); if (old != 0) rwsem_down_write_failed(sem); } @@ -215,24 +215,24 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) { signed long old; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%2)\n" - "0: ltr %0,%0\n" - " jnz 1f\n" - " cs %0,%4,0(%2)\n" - " jl 0b\n" + " l %0,0(%2)\n" + "0: ltr %0,%0\n" + " jnz 1f\n" + " cs %0,%4,0(%2)\n" + " jl 0b\n" #else /* __s390x__ */ - " lg %0,0(%2)\n" - "0: ltgr %0,%0\n" - " jnz 1f\n" - " csg %0,%4,0(%2)\n" - " jl 0b\n" + " lg %0,0(%2)\n" + "0: ltgr %0,%0\n" + " jnz 1f\n" + " csg %0,%4,0(%2)\n" + " jl 0b\n" #endif /* __s390x__ */ "1:" - : "=&d" (old), "=m" (sem->count) + : "=&d" (old), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), - "d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory" ); + "d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory"); return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0; } @@ -243,24 +243,24 @@ static inline void __up_read(struct rw_semaphore *sem) { signed long old, new; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%3)\n" - "0: lr %1,%0\n" - " ahi %1,%5\n" - " cs %0,%1,0(%3)\n" - " jl 0b" + " l %0,0(%3)\n" + "0: lr %1,%0\n" + " ahi %1,%5\n" + " cs %0,%1,0(%3)\n" + " jl 0b" #else /* __s390x__ */ - " lg %0,0(%3)\n" - "0: lgr %1,%0\n" - " aghi %1,%5\n" - " csg %0,%1,0(%3)\n" - " jl 0b" + " lg %0,0(%3)\n" + "0: lgr %1,%0\n" + " aghi %1,%5\n" + " csg %0,%1,0(%3)\n" + " jl 0b" #endif /* __s390x__ */ - : "=&d" (old), "=&d" (new), "=m" (sem->count) + : "=&d" (old), "=&d" (new), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS) - : "cc", "memory" ); + : "cc", "memory"); if (new < 0) if ((new & RWSEM_ACTIVE_MASK) == 0) rwsem_wake(sem); @@ -274,23 +274,23 @@ static inline void __up_write(struct rw_semaphore *sem) signed long old, new, tmp; tmp = -RWSEM_ACTIVE_WRITE_BIAS; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%3)\n" - "0: lr %1,%0\n" - " a %1,%5\n" - " cs %0,%1,0(%3)\n" - " jl 0b" + " l %0,0(%3)\n" + "0: lr %1,%0\n" + " a %1,%5\n" + " cs %0,%1,0(%3)\n" + " jl 0b" #else /* __s390x__ */ - " lg %0,0(%3)\n" - "0: lgr %1,%0\n" - " ag %1,%5\n" - " csg %0,%1,0(%3)\n" - " jl 0b" + " lg %0,0(%3)\n" + "0: lgr %1,%0\n" + " ag %1,%5\n" + " csg %0,%1,0(%3)\n" + " jl 0b" #endif /* __s390x__ */ - : "=&d" (old), "=&d" (new), "=m" (sem->count) + : "=&d" (old), "=&d" (new), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), "m" (tmp) - : "cc", "memory" ); + : "cc", "memory"); if (new < 0) if ((new & RWSEM_ACTIVE_MASK) == 0) rwsem_wake(sem); @@ -304,23 +304,23 @@ static inline void __downgrade_write(struct rw_semaphore *sem) signed long old, new, tmp; tmp = -RWSEM_WAITING_BIAS; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%3)\n" - "0: lr %1,%0\n" - " a %1,%5\n" - " cs %0,%1,0(%3)\n" - " jl 0b" + " l %0,0(%3)\n" + "0: lr %1,%0\n" + " a %1,%5\n" + " cs %0,%1,0(%3)\n" + " jl 0b" #else /* __s390x__ */ - " lg %0,0(%3)\n" - "0: lgr %1,%0\n" - " ag %1,%5\n" - " csg %0,%1,0(%3)\n" - " jl 0b" + " lg %0,0(%3)\n" + "0: lgr %1,%0\n" + " ag %1,%5\n" + " csg %0,%1,0(%3)\n" + " jl 0b" #endif /* __s390x__ */ - : "=&d" (old), "=&d" (new), "=m" (sem->count) + : "=&d" (old), "=&d" (new), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), "m" (tmp) - : "cc", "memory" ); + : "cc", "memory"); if (new > 1) rwsem_downgrade_wake(sem); } @@ -332,23 +332,23 @@ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) { signed long old, new; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%3)\n" - "0: lr %1,%0\n" - " ar %1,%5\n" - " cs %0,%1,0(%3)\n" - " jl 0b" + " l %0,0(%3)\n" + "0: lr %1,%0\n" + " ar %1,%5\n" + " cs %0,%1,0(%3)\n" + " jl 0b" #else /* __s390x__ */ - " lg %0,0(%3)\n" - "0: lgr %1,%0\n" - " agr %1,%5\n" - " csg %0,%1,0(%3)\n" - " jl 0b" + " lg %0,0(%3)\n" + "0: lgr %1,%0\n" + " agr %1,%5\n" + " csg %0,%1,0(%3)\n" + " jl 0b" #endif /* __s390x__ */ - : "=&d" (old), "=&d" (new), "=m" (sem->count) + : "=&d" (old), "=&d" (new), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), "d" (delta) - : "cc", "memory" ); + : "cc", "memory"); } /* @@ -358,23 +358,23 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) { signed long old, new; - __asm__ __volatile__( + asm volatile( #ifndef __s390x__ - " l %0,0(%3)\n" - "0: lr %1,%0\n" - " ar %1,%5\n" - " cs %0,%1,0(%3)\n" - " jl 0b" + " l %0,0(%3)\n" + "0: lr %1,%0\n" + " ar %1,%5\n" + " cs %0,%1,0(%3)\n" + " jl 0b" #else /* __s390x__ */ - " lg %0,0(%3)\n" - "0: lgr %1,%0\n" - " agr %1,%5\n" - " csg %0,%1,0(%3)\n" - " jl 0b" + " lg %0,0(%3)\n" + "0: lgr %1,%0\n" + " agr %1,%5\n" + " csg %0,%1,0(%3)\n" + " jl 0b" #endif /* __s390x__ */ - : "=&d" (old), "=&d" (new), "=m" (sem->count) + : "=&d" (old), "=&d" (new), "=m" (sem->count) : "a" (&sem->count), "m" (sem->count), "d" (delta) - : "cc", "memory" ); + : "cc", "memory"); return new; } diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h index 32cdc69f39f..dbce058aefa 100644 --- a/include/asm-s390/semaphore.h +++ b/include/asm-s390/semaphore.h @@ -85,17 +85,17 @@ static inline int down_trylock(struct semaphore * sem) * sem->count.counter = --new_val; * In the ppc code this is called atomic_dec_if_positive. */ - __asm__ __volatile__ ( - " l %0,0(%3)\n" - "0: ltr %1,%0\n" - " jle 1f\n" - " ahi %1,-1\n" - " cs %0,%1,0(%3)\n" - " jl 0b\n" + asm volatile( + " l %0,0(%3)\n" + "0: ltr %1,%0\n" + " jle 1f\n" + " ahi %1,-1\n" + " cs %0,%1,0(%3)\n" + " jl 0b\n" "1:" : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count.counter) : "a" (&sem->count.counter), "m" (sem->count.counter) - : "cc", "memory" ); + : "cc", "memory"); return old_val <= 0; } diff --git a/include/asm-s390/sfp-machine.h b/include/asm-s390/sfp-machine.h index de69dfa46fb..8ca8c77b2d0 100644 --- a/include/asm-s390/sfp-machine.h +++ b/include/asm-s390/sfp-machine.h @@ -76,21 +76,23 @@ unsigned int __r2 = (x2) + (y2); \ unsigned int __r1 = (x1); \ unsigned int __r0 = (x0); \ - __asm__ (" alr %2,%3\n" \ - " brc 12,0f\n" \ - " lhi 0,1\n" \ - " alr %1,0\n" \ - " brc 12,0f\n" \ - " alr %0,0\n" \ - "0:" \ - : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \ - : "d" (y0), "i" (1) : "cc", "0" ); \ - __asm__ (" alr %1,%2\n" \ - " brc 12,0f\n" \ - " ahi %0,1\n" \ - "0:" \ - : "+&d" (__r2), "+&d" (__r1) \ - : "d" (y1) : "cc" ); \ + asm volatile( \ + " alr %2,%3\n" \ + " brc 12,0f\n" \ + " lhi 0,1\n" \ + " alr %1,0\n" \ + " brc 12,0f\n" \ + " alr %0,0\n" \ + "0:" \ + : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \ + : "d" (y0), "i" (1) : "cc", "0" ); \ + asm volatile( \ + " alr %1,%2\n" \ + " brc 12,0f\n" \ + " ahi %0,1\n" \ + "0:" \ + : "+&d" (__r2), "+&d" (__r1) \ + : "d" (y1) : "cc"); \ (r2) = __r2; \ (r1) = __r1; \ (r0) = __r0; \ @@ -100,21 +102,23 @@ unsigned int __r2 = (x2) - (y2); \ unsigned int __r1 = (x1); \ unsigned int __r0 = (x0); \ - __asm__ (" slr %2,%3\n" \ - " brc 3,0f\n" \ - " lhi 0,1\n" \ - " slr %1,0\n" \ - " brc 3,0f\n" \ - " slr %0,0\n" \ - "0:" \ - : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \ - : "d" (y0) : "cc", "0" ); \ - __asm__ (" slr %1,%2\n" \ - " brc 3,0f\n" \ - " ahi %0,-1\n" \ - "0:" \ - : "+&d" (__r2), "+&d" (__r1) \ - : "d" (y1) : "cc" ); \ + asm volatile( \ + " slr %2,%3\n" \ + " brc 3,0f\n" \ + " lhi 0,1\n" \ + " slr %1,0\n" \ + " brc 3,0f\n" \ + " slr %0,0\n" \ + "0:" \ + : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \ + : "d" (y0) : "cc", "0"); \ + asm volatile( \ + " slr %1,%2\n" \ + " brc 3,0f\n" \ + " ahi %0,-1\n" \ + "0:" \ + : "+&d" (__r2), "+&d" (__r1) \ + : "d" (y1) : "cc"); \ (r2) = __r2; \ (r1) = __r1; \ (r0) = __r0; \ diff --git a/include/asm-s390/sigp.h b/include/asm-s390/sigp.h index fc56458aff6..e16d56f8dfe 100644 --- a/include/asm-s390/sigp.h +++ b/include/asm-s390/sigp.h @@ -70,16 +70,16 @@ typedef enum static inline sigp_ccode signal_processor(__u16 cpu_addr, sigp_order_code order_code) { + register unsigned long reg1 asm ("1") = 0; sigp_ccode ccode; - __asm__ __volatile__( - " sr 1,1\n" /* parameter=0 in gpr 1 */ - " sigp 1,%1,0(%2)\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (ccode) - : "d" (__cpu_logical_map[cpu_addr]), "a" (order_code) - : "cc" , "memory", "1" ); + asm volatile( + " sigp %1,%2,0(%3)\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (ccode) + : "d" (reg1), "d" (__cpu_logical_map[cpu_addr]), + "a" (order_code) : "cc" , "memory"); return ccode; } @@ -87,20 +87,18 @@ signal_processor(__u16 cpu_addr, sigp_order_code order_code) * Signal processor with parameter */ static inline sigp_ccode -signal_processor_p(__u32 parameter, __u16 cpu_addr, - sigp_order_code order_code) +signal_processor_p(__u32 parameter, __u16 cpu_addr, sigp_order_code order_code) { + register unsigned int reg1 asm ("1") = parameter; sigp_ccode ccode; - - __asm__ __volatile__( - " lr 1,%1\n" /* parameter in gpr 1 */ - " sigp 1,%2,0(%3)\n" - " ipm %0\n" - " srl %0,28\n" + + asm volatile( + " sigp %1,%2,0(%3)\n" + " ipm %0\n" + " srl %0,28\n" : "=d" (ccode) - : "d" (parameter), "d" (__cpu_logical_map[cpu_addr]), - "a" (order_code) - : "cc" , "memory", "1" ); + : "d" (reg1), "d" (__cpu_logical_map[cpu_addr]), + "a" (order_code) : "cc" , "memory"); return ccode; } @@ -108,24 +106,21 @@ signal_processor_p(__u32 parameter, __u16 cpu_addr, * Signal processor with parameter and return status */ static inline sigp_ccode -signal_processor_ps(__u32 *statusptr, __u32 parameter, - __u16 cpu_addr, sigp_order_code order_code) +signal_processor_ps(__u32 *statusptr, __u32 parameter, __u16 cpu_addr, + sigp_order_code order_code) { + register unsigned int reg1 asm ("1") = parameter; sigp_ccode ccode; - - __asm__ __volatile__( - " sr 2,2\n" /* clear status */ - " lr 3,%2\n" /* parameter in gpr 3 */ - " sigp 2,%3,0(%4)\n" - " st 2,%1\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (ccode), "=m" (*statusptr) - : "d" (parameter), "d" (__cpu_logical_map[cpu_addr]), - "a" (order_code) - : "cc" , "memory", "2" , "3" - ); - return ccode; + + asm volatile( + " sigp %1,%2,0(%3)\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (ccode), "+d" (reg1) + : "d" (__cpu_logical_map[cpu_addr]), "a" (order_code) + : "cc" , "memory"); + *statusptr = reg1; + return ccode; } #endif /* __SIGP__ */ diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 9fb02e9779c..c3cf030ada4 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h @@ -56,7 +56,7 @@ static inline __u16 hard_smp_processor_id(void) { __u16 cpu_address; - __asm__ ("stap %0\n" : "=m" (cpu_address)); + asm volatile("stap %0" : "=m" (cpu_address)); return cpu_address; } diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h index 273dbecf8ac..ce3edf6d63b 100644 --- a/include/asm-s390/spinlock.h +++ b/include/asm-s390/spinlock.h @@ -11,17 +11,36 @@ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + +static inline int +_raw_compare_and_swap(volatile unsigned int *lock, + unsigned int old, unsigned int new) +{ + asm volatile( + " cs %0,%3,%1" + : "=d" (old), "=Q" (*lock) + : "0" (old), "d" (new), "Q" (*lock) + : "cc", "memory" ); + return old; +} + +#else /* __GNUC__ */ + static inline int _raw_compare_and_swap(volatile unsigned int *lock, unsigned int old, unsigned int new) { - asm volatile ("cs %0,%3,0(%4)" - : "=d" (old), "=m" (*lock) - : "0" (old), "d" (new), "a" (lock), "m" (*lock) - : "cc", "memory" ); + asm volatile( + " cs %0,%3,0(%4)" + : "=d" (old), "=m" (*lock) + : "0" (old), "d" (new), "a" (lock), "m" (*lock) + : "cc", "memory" ); return old; } +#endif /* __GNUC__ */ + /* * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. diff --git a/include/asm-s390/string.h b/include/asm-s390/string.h index 23a4c390489..d074673a6d9 100644 --- a/include/asm-s390/string.h +++ b/include/asm-s390/string.h @@ -60,12 +60,13 @@ static inline void *memchr(const void * s, int c, size_t n) register int r0 asm("0") = (char) c; const void *ret = s + n; - asm volatile ("0: srst %0,%1\n" - " jo 0b\n" - " jl 1f\n" - " la %0,0\n" - "1:" - : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); + asm volatile( + "0: srst %0,%1\n" + " jo 0b\n" + " jl 1f\n" + " la %0,0\n" + "1:" + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc"); return (void *) ret; } @@ -74,9 +75,10 @@ static inline void *memscan(void *s, int c, size_t n) register int r0 asm("0") = (char) c; const void *ret = s + n; - asm volatile ("0: srst %0,%1\n" - " jo 0b\n" - : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); + asm volatile( + "0: srst %0,%1\n" + " jo 0b\n" + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc"); return (void *) ret; } @@ -86,12 +88,13 @@ static inline char *strcat(char *dst, const char *src) unsigned long dummy; char *ret = dst; - asm volatile ("0: srst %0,%1\n" - " jo 0b\n" - "1: mvst %0,%2\n" - " jo 1b" - : "=&a" (dummy), "+a" (dst), "+a" (src) - : "d" (r0), "0" (0) : "cc", "memory" ); + asm volatile( + "0: srst %0,%1\n" + " jo 0b\n" + "1: mvst %0,%2\n" + " jo 1b" + : "=&a" (dummy), "+a" (dst), "+a" (src) + : "d" (r0), "0" (0) : "cc", "memory" ); return ret; } @@ -100,10 +103,11 @@ static inline char *strcpy(char *dst, const char *src) register int r0 asm("0") = 0; char *ret = dst; - asm volatile ("0: mvst %0,%1\n" - " jo 0b" - : "+&a" (dst), "+&a" (src) : "d" (r0) - : "cc", "memory" ); + asm volatile( + "0: mvst %0,%1\n" + " jo 0b" + : "+&a" (dst), "+&a" (src) : "d" (r0) + : "cc", "memory"); return ret; } @@ -112,9 +116,10 @@ static inline size_t strlen(const char *s) register unsigned long r0 asm("0") = 0; const char *tmp = s; - asm volatile ("0: srst %0,%1\n" - " jo 0b" - : "+d" (r0), "+a" (tmp) : : "cc" ); + asm volatile( + "0: srst %0,%1\n" + " jo 0b" + : "+d" (r0), "+a" (tmp) : : "cc"); return r0 - (unsigned long) s; } @@ -124,9 +129,10 @@ static inline size_t strnlen(const char * s, size_t n) const char *tmp = s; const char *end = s + n; - asm volatile ("0: srst %0,%1\n" - " jo 0b" - : "+a" (end), "+a" (tmp) : "d" (r0) : "cc" ); + asm volatile( + "0: srst %0,%1\n" + " jo 0b" + : "+a" (end), "+a" (tmp) : "d" (r0) : "cc"); return end - s; } diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index 16040048cd1..ccbafe4bf2c 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -23,74 +23,68 @@ struct task_struct; extern struct task_struct *__switch_to(void *, void *); -#ifdef __s390x__ -#define __FLAG_SHIFT 56 -#else /* ! __s390x__ */ -#define __FLAG_SHIFT 24 -#endif /* ! __s390x__ */ - static inline void save_fp_regs(s390_fp_regs *fpregs) { - asm volatile ( - " std 0,8(%1)\n" - " std 2,24(%1)\n" - " std 4,40(%1)\n" - " std 6,56(%1)" - : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory" ); + asm volatile( + " std 0,8(%1)\n" + " std 2,24(%1)\n" + " std 4,40(%1)\n" + " std 6,56(%1)" + : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory"); if (!MACHINE_HAS_IEEE) return; asm volatile( - " stfpc 0(%1)\n" - " std 1,16(%1)\n" - " std 3,32(%1)\n" - " std 5,48(%1)\n" - " std 7,64(%1)\n" - " std 8,72(%1)\n" - " std 9,80(%1)\n" - " std 10,88(%1)\n" - " std 11,96(%1)\n" - " std 12,104(%1)\n" - " std 13,112(%1)\n" - " std 14,120(%1)\n" - " std 15,128(%1)\n" - : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory" ); + " stfpc 0(%1)\n" + " std 1,16(%1)\n" + " std 3,32(%1)\n" + " std 5,48(%1)\n" + " std 7,64(%1)\n" + " std 8,72(%1)\n" + " std 9,80(%1)\n" + " std 10,88(%1)\n" + " std 11,96(%1)\n" + " std 12,104(%1)\n" + " std 13,112(%1)\n" + " std 14,120(%1)\n" + " std 15,128(%1)\n" + : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory"); } static inline void restore_fp_regs(s390_fp_regs *fpregs) { - asm volatile ( - " ld 0,8(%0)\n" - " ld 2,24(%0)\n" - " ld 4,40(%0)\n" - " ld 6,56(%0)" - : : "a" (fpregs), "m" (*fpregs) ); + asm volatile( + " ld 0,8(%0)\n" + " ld 2,24(%0)\n" + " ld 4,40(%0)\n" + " ld 6,56(%0)" + : : "a" (fpregs), "m" (*fpregs)); if (!MACHINE_HAS_IEEE) return; asm volatile( - " lfpc 0(%0)\n" - " ld 1,16(%0)\n" - " ld 3,32(%0)\n" - " ld 5,48(%0)\n" - " ld 7,64(%0)\n" - " ld 8,72(%0)\n" - " ld 9,80(%0)\n" - " ld 10,88(%0)\n" - " ld 11,96(%0)\n" - " ld 12,104(%0)\n" - " ld 13,112(%0)\n" - " ld 14,120(%0)\n" - " ld 15,128(%0)\n" - : : "a" (fpregs), "m" (*fpregs) ); + " lfpc 0(%0)\n" + " ld 1,16(%0)\n" + " ld 3,32(%0)\n" + " ld 5,48(%0)\n" + " ld 7,64(%0)\n" + " ld 8,72(%0)\n" + " ld 9,80(%0)\n" + " ld 10,88(%0)\n" + " ld 11,96(%0)\n" + " ld 12,104(%0)\n" + " ld 13,112(%0)\n" + " ld 14,120(%0)\n" + " ld 15,128(%0)\n" + : : "a" (fpregs), "m" (*fpregs)); } static inline void save_access_regs(unsigned int *acrs) { - asm volatile ("stam 0,15,0(%0)" : : "a" (acrs) : "memory" ); + asm volatile("stam 0,15,0(%0)" : : "a" (acrs) : "memory"); } static inline void restore_access_regs(unsigned int *acrs) { - asm volatile ("lam 0,15,0(%0)" : : "a" (acrs) ); + asm volatile("lam 0,15,0(%0)" : : "a" (acrs)); } #define switch_to(prev,next,last) do { \ @@ -126,7 +120,7 @@ extern void account_system_vtime(struct task_struct *); account_vtime(prev); \ } while (0) -#define nop() __asm__ __volatile__ ("nop") +#define nop() asm volatile("nop") #define xchg(ptr,x) \ ({ \ @@ -147,15 +141,15 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size) shift = (3 ^ (addr & 3)) << 3; addr ^= addr & 3; asm volatile( - " l %0,0(%4)\n" - "0: lr 0,%0\n" - " nr 0,%3\n" - " or 0,%2\n" - " cs %0,0,0(%4)\n" - " jl 0b\n" + " l %0,0(%4)\n" + "0: lr 0,%0\n" + " nr 0,%3\n" + " or 0,%2\n" + " cs %0,0,0(%4)\n" + " jl 0b\n" : "=&d" (old), "=m" (*(int *) addr) : "d" (x << shift), "d" (~(255 << shift)), "a" (addr), - "m" (*(int *) addr) : "memory", "cc", "0" ); + "m" (*(int *) addr) : "memory", "cc", "0"); x = old >> shift; break; case 2: @@ -163,36 +157,36 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size) shift = (2 ^ (addr & 2)) << 3; addr ^= addr & 2; asm volatile( - " l %0,0(%4)\n" - "0: lr 0,%0\n" - " nr 0,%3\n" - " or 0,%2\n" - " cs %0,0,0(%4)\n" - " jl 0b\n" + " l %0,0(%4)\n" + "0: lr 0,%0\n" + " nr 0,%3\n" + " or 0,%2\n" + " cs %0,0,0(%4)\n" + " jl 0b\n" : "=&d" (old), "=m" (*(int *) addr) : "d" (x << shift), "d" (~(65535 << shift)), "a" (addr), - "m" (*(int *) addr) : "memory", "cc", "0" ); + "m" (*(int *) addr) : "memory", "cc", "0"); x = old >> shift; break; case 4: - asm volatile ( - " l %0,0(%3)\n" - "0: cs %0,%2,0(%3)\n" - " jl 0b\n" + asm volatile( + " l %0,0(%3)\n" + "0: cs %0,%2,0(%3)\n" + " jl 0b\n" : "=&d" (old), "=m" (*(int *) ptr) : "d" (x), "a" (ptr), "m" (*(int *) ptr) - : "memory", "cc" ); + : "memory", "cc"); x = old; break; #ifdef __s390x__ case 8: - asm volatile ( - " lg %0,0(%3)\n" - "0: csg %0,%2,0(%3)\n" - " jl 0b\n" + asm volatile( + " lg %0,0(%3)\n" + "0: csg %0,%2,0(%3)\n" + " jl 0b\n" : "=&d" (old), "=m" (*(long *) ptr) : "d" (x), "a" (ptr), "m" (*(long *) ptr) - : "memory", "cc" ); + : "memory", "cc"); x = old; break; #endif /* __s390x__ */ @@ -224,55 +218,55 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) shift = (3 ^ (addr & 3)) << 3; addr ^= addr & 3; asm volatile( - " l %0,0(%4)\n" - "0: nr %0,%5\n" - " lr %1,%0\n" - " or %0,%2\n" - " or %1,%3\n" - " cs %0,%1,0(%4)\n" - " jnl 1f\n" - " xr %1,%0\n" - " nr %1,%5\n" - " jnz 0b\n" + " l %0,0(%4)\n" + "0: nr %0,%5\n" + " lr %1,%0\n" + " or %0,%2\n" + " or %1,%3\n" + " cs %0,%1,0(%4)\n" + " jnl 1f\n" + " xr %1,%0\n" + " nr %1,%5\n" + " jnz 0b\n" "1:" : "=&d" (prev), "=&d" (tmp) : "d" (old << shift), "d" (new << shift), "a" (ptr), "d" (~(255 << shift)) - : "memory", "cc" ); + : "memory", "cc"); return prev >> shift; case 2: addr = (unsigned long) ptr; shift = (2 ^ (addr & 2)) << 3; addr ^= addr & 2; asm volatile( - " l %0,0(%4)\n" - "0: nr %0,%5\n" - " lr %1,%0\n" - " or %0,%2\n" - " or %1,%3\n" - " cs %0,%1,0(%4)\n" - " jnl 1f\n" - " xr %1,%0\n" - " nr %1,%5\n" - " jnz 0b\n" + " l %0,0(%4)\n" + "0: nr %0,%5\n" + " lr %1,%0\n" + " or %0,%2\n" + " or %1,%3\n" + " cs %0,%1,0(%4)\n" + " jnl 1f\n" + " xr %1,%0\n" + " nr %1,%5\n" + " jnz 0b\n" "1:" : "=&d" (prev), "=&d" (tmp) : "d" (old << shift), "d" (new << shift), "a" (ptr), "d" (~(65535 << shift)) - : "memory", "cc" ); + : "memory", "cc"); return prev >> shift; case 4: - asm volatile ( - " cs %0,%2,0(%3)\n" + asm volatile( + " cs %0,%2,0(%3)\n" : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr) - : "memory", "cc" ); + : "memory", "cc"); return prev; #ifdef __s390x__ case 8: - asm volatile ( - " csg %0,%2,0(%3)\n" + asm volatile( + " csg %0,%2,0(%3)\n" : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr) - : "memory", "cc" ); + : "memory", "cc"); return prev; #endif /* __s390x__ */ } @@ -289,8 +283,8 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) * all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ). */ -#define eieio() __asm__ __volatile__ ( "bcr 15,0" : : : "memory" ) -# define SYNC_OTHER_CORES(x) eieio() +#define eieio() asm volatile("bcr 15,0" : : : "memory") +#define SYNC_OTHER_CORES(x) eieio() #define mb() eieio() #define rmb() eieio() #define wmb() eieio() @@ -307,117 +301,56 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) #ifdef __s390x__ -#define __ctl_load(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } addrtype; \ - __asm__ __volatile__ ( \ - " bras 1,0f\n" \ - " lctlg 0,0,0(%0)\n" \ - "0: ex %1,0(1)" \ - : : "a" (&array), "a" (((low)<<4)+(high)), \ - "m" (*(addrtype *)(array)) : "1" ); \ +#define __ctl_load(array, low, high) ({ \ + typedef struct { char _[sizeof(array)]; } addrtype; \ + asm volatile( \ + " lctlg %1,%2,0(%0)\n" \ + : : "a" (&array), "i" (low), "i" (high), \ + "m" (*(addrtype *)(array))); \ }) -#define __ctl_store(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } addrtype; \ - __asm__ __volatile__ ( \ - " bras 1,0f\n" \ - " stctg 0,0,0(%1)\n" \ - "0: ex %2,0(1)" \ - : "=m" (*(addrtype *)(array)) \ - : "a" (&array), "a" (((low)<<4)+(high)) : "1" ); \ +#define __ctl_store(array, low, high) ({ \ + typedef struct { char _[sizeof(array)]; } addrtype; \ + asm volatile( \ + " stctg %2,%3,0(%1)\n" \ + : "=m" (*(addrtype *)(array)) \ + : "a" (&array), "i" (low), "i" (high)); \ }) -#define __ctl_set_bit(cr, bit) ({ \ - __u8 __dummy[24]; \ - __asm__ __volatile__ ( \ - " bras 1,0f\n" /* skip indirect insns */ \ - " stctg 0,0,0(%1)\n" \ - " lctlg 0,0,0(%1)\n" \ - "0: ex %2,0(1)\n" /* execute stctl */ \ - " lg 0,0(%1)\n" \ - " ogr 0,%3\n" /* set the bit */ \ - " stg 0,0(%1)\n" \ - "1: ex %2,6(1)" /* execute lctl */ \ - : "=m" (__dummy) \ - : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \ - "a" (cr*17), "a" (1L<<(bit)) \ - : "cc", "0", "1" ); \ - }) - -#define __ctl_clear_bit(cr, bit) ({ \ - __u8 __dummy[16]; \ - __asm__ __volatile__ ( \ - " bras 1,0f\n" /* skip indirect insns */ \ - " stctg 0,0,0(%1)\n" \ - " lctlg 0,0,0(%1)\n" \ - "0: ex %2,0(1)\n" /* execute stctl */ \ - " lg 0,0(%1)\n" \ - " ngr 0,%3\n" /* set the bit */ \ - " stg 0,0(%1)\n" \ - "1: ex %2,6(1)" /* execute lctl */ \ - : "=m" (__dummy) \ - : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \ - "a" (cr*17), "a" (~(1L<<(bit))) \ - : "cc", "0", "1" ); \ - }) - #else /* __s390x__ */ -#define __ctl_load(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } addrtype; \ - __asm__ __volatile__ ( \ - " bras 1,0f\n" \ - " lctl 0,0,0(%0)\n" \ - "0: ex %1,0(1)" \ - : : "a" (&array), "a" (((low)<<4)+(high)), \ - "m" (*(addrtype *)(array)) : "1" ); \ - }) +#define __ctl_load(array, low, high) ({ \ + typedef struct { char _[sizeof(array)]; } addrtype; \ + asm volatile( \ + " lctl %1,%2,0(%0)\n" \ + : : "a" (&array), "i" (low), "i" (high), \ + "m" (*(addrtype *)(array))); \ +}) -#define __ctl_store(array, low, high) ({ \ - typedef struct { char _[sizeof(array)]; } addrtype; \ - __asm__ __volatile__ ( \ - " bras 1,0f\n" \ - " stctl 0,0,0(%1)\n" \ - "0: ex %2,0(1)" \ - : "=m" (*(addrtype *)(array)) \ - : "a" (&array), "a" (((low)<<4)+(high)): "1" ); \ +#define __ctl_store(array, low, high) ({ \ + typedef struct { char _[sizeof(array)]; } addrtype; \ + asm volatile( \ + " stctl %2,%3,0(%1)\n" \ + : "=m" (*(addrtype *)(array)) \ + : "a" (&array), "i" (low), "i" (high)); \ }) -#define __ctl_set_bit(cr, bit) ({ \ - __u8 __dummy[16]; \ - __asm__ __volatile__ ( \ - " bras 1,0f\n" /* skip indirect insns */ \ - " stctl 0,0,0(%1)\n" \ - " lctl 0,0,0(%1)\n" \ - "0: ex %2,0(1)\n" /* execute stctl */ \ - " l 0,0(%1)\n" \ - " or 0,%3\n" /* set the bit */ \ - " st 0,0(%1)\n" \ - "1: ex %2,4(1)" /* execute lctl */ \ - : "=m" (__dummy) \ - : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \ - "a" (cr*17), "a" (1<<(bit)) \ - : "cc", "0", "1" ); \ - }) - -#define __ctl_clear_bit(cr, bit) ({ \ - __u8 __dummy[16]; \ - __asm__ __volatile__ ( \ - " bras 1,0f\n" /* skip indirect insns */ \ - " stctl 0,0,0(%1)\n" \ - " lctl 0,0,0(%1)\n" \ - "0: ex %2,0(1)\n" /* execute stctl */ \ - " l 0,0(%1)\n" \ - " nr 0,%3\n" /* set the bit */ \ - " st 0,0(%1)\n" \ - "1: ex %2,4(1)" /* execute lctl */ \ - : "=m" (__dummy) \ - : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \ - "a" (cr*17), "a" (~(1<<(bit))) \ - : "cc", "0", "1" ); \ - }) #endif /* __s390x__ */ +#define __ctl_set_bit(cr, bit) ({ \ + unsigned long __dummy; \ + __ctl_store(__dummy, cr, cr); \ + __dummy |= 1UL << (bit); \ + __ctl_load(__dummy, cr, cr); \ +}) + +#define __ctl_clear_bit(cr, bit) ({ \ + unsigned long __dummy; \ + __ctl_store(__dummy, cr, cr); \ + __dummy &= ~(1UL << (bit)); \ + __ctl_load(__dummy, cr, cr); \ +}) + #include <linux/irqflags.h> /* @@ -427,8 +360,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) static inline void __set_psw_mask(unsigned long mask) { - local_save_flags(mask); - __load_psw_mask(mask); + __load_psw_mask(mask | (__raw_local_irq_stosm(0x00) & ~(-1UL >> 8))); } #define local_mcck_enable() __set_psw_mask(PSW_KERNEL_BITS) diff --git a/include/asm-s390/timex.h b/include/asm-s390/timex.h index 5d0332a4c2b..4df4a41029a 100644 --- a/include/asm-s390/timex.h +++ b/include/asm-s390/timex.h @@ -15,20 +15,21 @@ typedef unsigned long long cycles_t; -static inline cycles_t get_cycles(void) -{ - cycles_t cycles; - - __asm__ __volatile__ ("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc"); - return cycles >> 2; -} - static inline unsigned long long get_clock (void) { unsigned long long clk; - __asm__ __volatile__ ("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc"); +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) + asm volatile("stck %0" : "=Q" (clk) : : "cc"); +#else /* __GNUC__ */ + asm volatile("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc"); +#endif /* __GNUC__ */ return clk; } +static inline cycles_t get_cycles(void) +{ + return (cycles_t) get_clock() >> 2; +} + #endif diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h index 73cd85bebfb..fa4dc916a9b 100644 --- a/include/asm-s390/tlbflush.h +++ b/include/asm-s390/tlbflush.h @@ -25,7 +25,7 @@ */ #define local_flush_tlb() \ -do { __asm__ __volatile__("ptlb": : :"memory"); } while (0) +do { asm volatile("ptlb": : :"memory"); } while (0) #ifndef CONFIG_SMP @@ -68,24 +68,24 @@ extern void smp_ptlb_all(void); static inline void global_flush_tlb(void) { + register unsigned long reg2 asm("2"); + register unsigned long reg3 asm("3"); + register unsigned long reg4 asm("4"); + long dummy; + #ifndef __s390x__ if (!MACHINE_HAS_CSP) { smp_ptlb_all(); return; } #endif /* __s390x__ */ - { - register unsigned long addr asm("4"); - long dummy; - - dummy = 0; - addr = ((unsigned long) &dummy) + 1; - __asm__ __volatile__ ( - " slr 2,2\n" - " slr 3,3\n" - " csp 2,%0" - : : "a" (addr), "m" (dummy) : "cc", "2", "3" ); - } + + dummy = 0; + reg2 = reg3 = 0; + reg4 = ((unsigned long) &dummy) + 1; + asm volatile( + " csp %0,%2" + : : "d" (reg2), "d" (reg3), "d" (reg4), "m" (dummy) : "cc" ); } /* @@ -102,9 +102,9 @@ static inline void __flush_tlb_mm(struct mm_struct * mm) if (unlikely(cpus_empty(mm->cpu_vm_mask))) return; if (MACHINE_HAS_IDTE) { - asm volatile (".insn rrf,0xb98e0000,0,%0,%1,0" - : : "a" (2048), - "a" (__pa(mm->pgd)&PAGE_MASK) : "cc" ); + asm volatile( + " .insn rrf,0xb98e0000,0,%0,%1,0" + : : "a" (2048), "a" (__pa(mm->pgd)&PAGE_MASK) : "cc"); return; } preempt_disable(); diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h index e2047b0c909..72ae4efddb4 100644 --- a/include/asm-s390/uaccess.h +++ b/include/asm-s390/uaccess.h @@ -38,25 +38,14 @@ #define get_ds() (KERNEL_DS) #define get_fs() (current->thread.mm_segment) -#ifdef __s390x__ #define set_fs(x) \ ({ \ unsigned long __pto; \ current->thread.mm_segment = (x); \ __pto = current->thread.mm_segment.ar4 ? \ S390_lowcore.user_asce : S390_lowcore.kernel_asce; \ - asm volatile ("lctlg 7,7,%0" : : "m" (__pto) ); \ + __ctl_load(__pto, 7, 7); \ }) -#else /* __s390x__ */ -#define set_fs(x) \ -({ \ - unsigned long __pto; \ - current->thread.mm_segment = (x); \ - __pto = current->thread.mm_segment.ar4 ? \ - S390_lowcore.user_asce : S390_lowcore.kernel_asce; \ - asm volatile ("lctl 7,7,%0" : : "m" (__pto) ); \ -}) -#endif /* __s390x__ */ #define segment_eq(a,b) ((a).ar4 == (b).ar4) diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index d49c54cb550..0361ac5dcde 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h @@ -355,145 +355,145 @@ do { \ #define _svc_clobber "1", "cc", "memory" -#define _syscall0(type,name) \ -type name(void) { \ - register long __svcres asm("2"); \ - long __res; \ - __asm__ __volatile__ ( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name) \ - : _svc_clobber ); \ - __res = __svcres; \ - __syscall_return(type,__res); \ +#define _syscall0(type,name) \ +type name(void) { \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ } -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) { \ - register type1 __arg1 asm("2") = arg1; \ - register long __svcres asm("2"); \ - long __res; \ - __asm__ __volatile__ ( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1) \ - : _svc_clobber ); \ - __res = __svcres; \ - __syscall_return(type,__res); \ +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) { \ + register type1 __arg1 asm("2") = arg1; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ } -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1, type2 arg2) { \ - register type1 __arg1 asm("2") = arg1; \ - register type2 __arg2 asm("3") = arg2; \ - register long __svcres asm("2"); \ - long __res; \ - __asm__ __volatile__ ( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1), \ - "d" (__arg2) \ - : _svc_clobber ); \ - __res = __svcres; \ - __syscall_return(type,__res); \ +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1, type2 arg2) { \ + register type1 __arg1 asm("2") = arg1; \ + register type2 __arg2 asm("3") = arg2; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1), \ + "d" (__arg2) \ + : _svc_clobber ); \ + __res = __svcres; \ + __syscall_return(type,__res); \ } -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)\ -type name(type1 arg1, type2 arg2, type3 arg3) { \ - register type1 __arg1 asm("2") = arg1; \ - register type2 __arg2 asm("3") = arg2; \ - register type3 __arg3 asm("4") = arg3; \ - register long __svcres asm("2"); \ - long __res; \ - __asm__ __volatile__ ( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1), \ - "d" (__arg2), \ - "d" (__arg3) \ - : _svc_clobber ); \ - __res = __svcres; \ - __syscall_return(type,__res); \ +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1, type2 arg2, type3 arg3) { \ + register type1 __arg1 asm("2") = arg1; \ + register type2 __arg2 asm("3") = arg2; \ + register type3 __arg3 asm("4") = arg3; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1), \ + "d" (__arg2), \ + "d" (__arg3) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ } -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,\ - type4,name4) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - register type1 __arg1 asm("2") = arg1; \ - register type2 __arg2 asm("3") = arg2; \ - register type3 __arg3 asm("4") = arg3; \ - register type4 __arg4 asm("5") = arg4; \ - register long __svcres asm("2"); \ - long __res; \ - __asm__ __volatile__ ( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1), \ - "d" (__arg2), \ - "d" (__arg3), \ - "d" (__arg4) \ - : _svc_clobber ); \ - __res = __svcres; \ - __syscall_return(type,__res); \ +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3, \ + type4,name4) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ + register type1 __arg1 asm("2") = arg1; \ + register type2 __arg2 asm("3") = arg2; \ + register type3 __arg3 asm("4") = arg3; \ + register type4 __arg4 asm("5") = arg4; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1), \ + "d" (__arg2), \ + "d" (__arg3), \ + "d" (__arg4) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ } -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,\ - type4,name4,type5,name5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - register type1 __arg1 asm("2") = arg1; \ - register type2 __arg2 asm("3") = arg2; \ - register type3 __arg3 asm("4") = arg3; \ - register type4 __arg4 asm("5") = arg4; \ - register type5 __arg5 asm("6") = arg5; \ - register long __svcres asm("2"); \ - long __res; \ - __asm__ __volatile__ ( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1), \ - "d" (__arg2), \ - "d" (__arg3), \ - "d" (__arg4), \ - "d" (__arg5) \ - : _svc_clobber ); \ - __res = __svcres; \ - __syscall_return(type,__res); \ +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3, \ + type4,name4,type5,name5) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ + type5 arg5) { \ + register type1 __arg1 asm("2") = arg1; \ + register type2 __arg2 asm("3") = arg2; \ + register type3 __arg3 asm("4") = arg3; \ + register type4 __arg4 asm("5") = arg4; \ + register type5 __arg5 asm("6") = arg5; \ + register long __svcres asm("2"); \ + long __res; \ + asm volatile( \ + " .if %1 < 256\n" \ + " svc %b1\n" \ + " .else\n" \ + " la %%r1,%1\n" \ + " svc 0\n" \ + " .endif" \ + : "=d" (__svcres) \ + : "i" (__NR_##name), \ + "0" (__arg1), \ + "d" (__arg2), \ + "d" (__arg3), \ + "d" (__arg4), \ + "d" (__arg5) \ + : _svc_clobber); \ + __res = __svcres; \ + __syscall_return(type,__res); \ } #define __ARCH_WANT_IPC_PARSE_VERSION diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index ba095aebedf..587264a58d5 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -85,6 +85,8 @@ struct mmc_host { unsigned long caps; /* Host capabilities */ #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ +#define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */ +#define MMC_CAP_BYTEBLOCK (1 << 2) /* Can do non-log2 block sizes */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 627e2c08ce4..a3594dfd696 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -68,7 +68,6 @@ struct mmc_command { struct mmc_data { unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */ unsigned int timeout_clks; /* data timeout (in clocks) */ - unsigned int blksz_bits; /* data block size */ unsigned int blksz; /* data block size */ unsigned int blocks; /* number of blocks */ unsigned int error; /* data error */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab032ceafa8..61db1907f06 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -479,6 +479,7 @@ #define PCI_VENDOR_ID_AMD 0x1022 #define PCI_DEVICE_ID_AMD_K8_NB 0x1100 +#define PCI_DEVICE_ID_AMD_K8_NB_MISC 0x1103 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 #define PCI_DEVICE_ID_AMD_SCSI 0x2020 diff --git a/include/linux/usb.h b/include/linux/usb.h index 0da15b0b02b..190cc1b78fe 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -380,10 +380,10 @@ struct usb_device { int maxchild; /* Number of ports if hub */ struct usb_device *children[USB_MAXCHILDREN]; + int pm_usage_cnt; /* usage counter for autosuspend */ #ifdef CONFIG_PM struct work_struct autosuspend; /* for delayed autosuspends */ struct mutex pm_mutex; /* protects PM operations */ - int pm_usage_cnt; /* usage counter for autosuspend */ unsigned auto_pm:1; /* autosuspend/resume in progress */ unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ diff --git a/kernel/fork.c b/kernel/fork.c index a0dad84567c..802b1cf0e63 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1061,7 +1061,11 @@ static struct task_struct *copy_process(unsigned long clone_flags, #endif #ifdef CONFIG_TRACE_IRQFLAGS p->irq_events = 0; +#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW + p->hardirqs_enabled = 1; +#else p->hardirqs_enabled = 0; +#endif p->hardirq_enable_ip = 0; p->hardirq_enable_event = 0; p->hardirq_disable_ip = _THIS_IP_; |