mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge with linus
This commit is contained in:
205
Documentation/dvb/README.flexcop
Normal file
205
Documentation/dvb/README.flexcop
Normal file
@@ -0,0 +1,205 @@
|
||||
This README escorted the skystar2-driver rewriting procedure. It describes the
|
||||
state of the new flexcop-driver set and some internals are written down here
|
||||
too.
|
||||
|
||||
This document hopefully describes things about the flexcop and its
|
||||
device-offsprings. Goal was to write an easy-to-write and easy-to-read set of
|
||||
drivers based on the skystar2.c and other information.
|
||||
|
||||
Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been
|
||||
touched and rewritten.
|
||||
|
||||
History & News
|
||||
==============
|
||||
2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana)
|
||||
|
||||
|
||||
|
||||
|
||||
General coding processing
|
||||
=========================
|
||||
|
||||
We should proceed as follows (as long as no one complains):
|
||||
|
||||
0) Think before start writing code!
|
||||
|
||||
1) rewriting the skystar2.c with the help of the flexcop register descriptions
|
||||
and splitting up the files to a pci-bus-part and a flexcop-part.
|
||||
The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the
|
||||
device-specific part and b2c2-flexcop.ko for the common flexcop-functions.
|
||||
|
||||
2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c
|
||||
and other pci drivers)
|
||||
|
||||
3) make some beautification (see 'Improvements when rewriting (refactoring) is
|
||||
done')
|
||||
|
||||
4) Testing the new driver and maybe substitute the skystar2.c with it, to reach
|
||||
a wider tester audience.
|
||||
|
||||
5) creating an usb-bus-part using the already written flexcop code for the pci
|
||||
card.
|
||||
|
||||
Idea: create a kernel-object for the flexcop and export all important
|
||||
functions. This option saves kernel-memory, but maybe a lot of functions have
|
||||
to be exported to kernel namespace.
|
||||
|
||||
|
||||
Current situation
|
||||
=================
|
||||
|
||||
0) Done :)
|
||||
1) Done (some minor issues left)
|
||||
2) Done
|
||||
3) Not ready yet, more information is necessary
|
||||
4) next to be done (see the table below)
|
||||
5) USB driver is working (yes, there are some minor issues)
|
||||
|
||||
What seems to be ready?
|
||||
-----------------------
|
||||
|
||||
1) Rewriting
|
||||
1a) i2c is cut off from the flexcop-pci.c and seems to work
|
||||
1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c
|
||||
1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c
|
||||
1e) eeprom (reading MAC address)
|
||||
1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me))
|
||||
1f) misc. register accesses for reading parameters (e.g. resetting, revision)
|
||||
1g) pid/mac filter (flexcop-hw-filter.c)
|
||||
1i) dvb-stuff initialization in flexcop.c (done)
|
||||
1h) dma stuff (now just using the size-irq, instead of all-together, to be done)
|
||||
1j) remove flexcop initialization from flexcop-pci.c completely (done)
|
||||
1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO')
|
||||
1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from
|
||||
non-static where possible, moved code to proper places)
|
||||
|
||||
2) Search for errors in the leftover of flexcop-pci.c (partially done)
|
||||
5a) add MAC address reading
|
||||
5c) feeding of ISOC data to the software demux (format of the isochronous data
|
||||
and speed optimization, no real error) (thanks to Vadim Catana)
|
||||
|
||||
What to do in the near future?
|
||||
--------------------------------------
|
||||
(no special order here)
|
||||
|
||||
5) USB driver
|
||||
5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting)
|
||||
|
||||
Testing changes
|
||||
---------------
|
||||
|
||||
O = item is working
|
||||
P = item is partially working
|
||||
X = item is not working
|
||||
N = item does not apply here
|
||||
<empty field> = item need to be examined
|
||||
|
||||
| PCI | USB
|
||||
item | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312
|
||||
-------+-------+---------+---------+-------+-------+---------+---------+-------
|
||||
1a) | O | | | | N | N | N | N
|
||||
1b) | O | | | | | | O |
|
||||
1c) | N | N | | | N | N | O |
|
||||
1d) | O | O
|
||||
1e) | O | O
|
||||
1f) | P
|
||||
1g) | O
|
||||
1h) | P |
|
||||
1i) | O | N
|
||||
1j) | O | N
|
||||
1l) | O | N
|
||||
2) | O | N
|
||||
5a) | N | O
|
||||
5b)* | N |
|
||||
5c) | N | O
|
||||
|
||||
* - not done yet
|
||||
|
||||
Known bugs and problems and TODO
|
||||
--------------------------------
|
||||
|
||||
1g/h/l) when pid filtering is enabled on the pci card
|
||||
|
||||
DMA usage currently:
|
||||
The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first
|
||||
address and triggers an IRQ when it's full and starts writing to the second
|
||||
address. When the second address is full, the IRQ is triggered again, and
|
||||
the flexcop writes to first address again, and so on.
|
||||
The buffersize of each address is currently 640*188 bytes.
|
||||
|
||||
Problem is, when using hw-pid-filtering and doing some low-bandwidth
|
||||
operation (like scanning) the buffers won't be filled enough to trigger
|
||||
the IRQ. That's why:
|
||||
|
||||
When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ
|
||||
is triggered. Is the current write address of DMA1 different to the one
|
||||
during the last IRQ, then the data is passed to the demuxer.
|
||||
|
||||
There is an additional DMA-IRQ-method: packet count IRQ. This isn't
|
||||
implemented correctly yet.
|
||||
|
||||
The solution is to disable HW PID filtering, but I don't know how the DVB
|
||||
API software demux behaves on slow systems with 45MBit/s TS.
|
||||
|
||||
Solved bugs :)
|
||||
--------------
|
||||
1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't
|
||||
working)
|
||||
SOLUTION: also index 0 was affected, because net_translation is done for
|
||||
these indexes by default
|
||||
|
||||
5b) isochronous transfer does only work in the first attempt (for the Sky2PC
|
||||
USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really
|
||||
woke up again (don't know if this need fixes, see
|
||||
flexcop-fe-tuner.c:flexcop_sleep)
|
||||
|
||||
NEWS: when the driver is loaded and unloaded and loaded again (w/o doing
|
||||
anything in the while the driver is loaded the first time), no transfers take
|
||||
place anymore.
|
||||
|
||||
Improvements when rewriting (refactoring) is done
|
||||
=================================================
|
||||
|
||||
- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control
|
||||
(enable sleeping for other demods than dvb-s)
|
||||
- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA)
|
||||
|
||||
Debugging
|
||||
---------
|
||||
- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it
|
||||
with this flexcop, this is important, because i2c is now using the
|
||||
flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for
|
||||
that, please tell us so).
|
||||
|
||||
Everything which is identical in the following table, can be put into a common
|
||||
flexcop-module.
|
||||
|
||||
PCI USB
|
||||
-------------------------------------------------------------------------------
|
||||
Different:
|
||||
Register access: accessing IO memory USB control message
|
||||
I2C bus: I2C bus of the FC USB control message
|
||||
Data transfer: DMA isochronous transfer
|
||||
EEPROM transfer: through i2c bus not clear yet
|
||||
|
||||
Identical:
|
||||
Streaming: accessing registers
|
||||
PID Filtering: accessing registers
|
||||
Sram destinations: accessing registers
|
||||
Tuner/Demod: I2C bus
|
||||
DVB-stuff: can be written for common use
|
||||
|
||||
Acknowledgements (just for the rewriting part)
|
||||
================
|
||||
|
||||
Bjarne Steinsbo thought a lot in the first place of the pci part for this code
|
||||
sharing idea.
|
||||
|
||||
Andreas Oberritter for providing a recent PCI initialization template
|
||||
(pluto2.c).
|
||||
|
||||
Boleslaw Ciesielski for pointing out a problem with firmware loader.
|
||||
|
||||
Vadim Catana for correcting the USB transfer.
|
||||
|
||||
comments, critics and ideas to linux-dvb@linuxtv.org.
|
||||
@@ -17,74 +17,53 @@ Because of this, you need to enable
|
||||
"Device drivers" => "Multimedia devices"
|
||||
=> "Video For Linux" => "BT848 Video For Linux"
|
||||
|
||||
Furthermore you need to enable
|
||||
"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
|
||||
=> "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
|
||||
|
||||
2) Loading Modules
|
||||
==================
|
||||
|
||||
In general you need to load the bttv driver, which will handle the gpio and
|
||||
i2c communication for us. Next you need the common dvb-bt8xx device driver
|
||||
and one frontend driver.
|
||||
|
||||
The bttv driver will HANG YOUR SYSTEM IF YOU DO NOT SPECIFY THE CORRECT
|
||||
CARD ID!
|
||||
|
||||
(If you don't get your card running and you suspect that the card id you're
|
||||
using is wrong, have a look at "bttv-cards.c" for a list of possible card
|
||||
ids.)
|
||||
|
||||
Pay attention to failures when you load the frontend drivers
|
||||
(e.g. dmesg, /var/log/messages).
|
||||
i2c communication for us, plus the common dvb-bt8xx device driver.
|
||||
The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
|
||||
TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
|
||||
|
||||
3a) Nebula / Pinnacle PCTV
|
||||
--------------------------
|
||||
|
||||
$ modprobe bttv i2c_hw=1 card=0x68
|
||||
$ modprobe dvb-bt8xx
|
||||
|
||||
For Nebula cards use the "nxt6000" frontend driver:
|
||||
$ modprobe nxt6000
|
||||
$ modprobe bttv (normally bttv is being loaded automatically by kmod)
|
||||
$ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
|
||||
|
||||
For Pinnacle PCTV cards use the "cx24110" frontend driver:
|
||||
$ modprobe cx24110
|
||||
|
||||
3b) TwinHan
|
||||
-----------
|
||||
3b) TwinHan and Clones
|
||||
--------------------------
|
||||
|
||||
$ modprobe bttv i2c_hw=1 card=0x71
|
||||
$ modprobe dvb-bt8xx
|
||||
$ modprobe dst
|
||||
|
||||
The value 0x71 will override the PCI type detection for dvb-bt8xx, which
|
||||
is necessary for TwinHan cards.#
|
||||
The value 0x71 will override the PCI type detection for dvb-bt8xx,
|
||||
which is necessary for TwinHan cards.
|
||||
|
||||
If you're having an older card (blue color circuit) and card=0x71 locks your
|
||||
machine, try using 0x68, too. If that does not work, ask on the DVB mailing list.
|
||||
If you're having an older card (blue color circuit) and card=0x71 locks
|
||||
your machine, try using 0x68, too. If that does not work, ask on the
|
||||
mailing list.
|
||||
|
||||
The DST module takes a couple of useful parameters, in case the
|
||||
dst drivers fails to detect your type of card correctly.
|
||||
The DST module takes a couple of useful parameters.
|
||||
|
||||
dst_type takes values 0 (satellite), 1 (terrestial TV), 2 (cable).
|
||||
verbose takes values 0 to 5. These values control the verbosity level.
|
||||
|
||||
dst_type_flags takes bit combined values:
|
||||
1 = new tuner type packets. You can use this if your card is detected
|
||||
and you have debug and you continually see the tuner packets not
|
||||
working (make sure not a basic problem like dish alignment etc.)
|
||||
debug takes values 0 and 1. You can either disable or enable debugging.
|
||||
|
||||
2 = TS 204. If your card tunes OK, but the picture is terrible, seemingly
|
||||
breaking up in one half continually, and crc fails a lot, then
|
||||
this is worth a try (or trying to turn off)
|
||||
dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
|
||||
0x20 means it has a Conditional Access slot.
|
||||
|
||||
4 = has symdiv. Some cards, mostly without new tuner packets, require
|
||||
a symbol division algorithm. Doesn't apply to terrestial TV.
|
||||
|
||||
You can also specify a value to have the autodetected values turned off
|
||||
(e.g. 0). The autodected values are determined bythe cards 'response
|
||||
The autodected values are determined bythe cards 'response
|
||||
string' which you can see in your logs e.g.
|
||||
|
||||
dst_check_ci: recognize DST-MOT
|
||||
dst_get_device_id: Recognise [DSTMCI]
|
||||
|
||||
or
|
||||
|
||||
dst_check_ci: unable to recognize DSTXCI or STXCI
|
||||
|
||||
--
|
||||
Authors: Richard Walker, Jamie Honan, Michael Hunold
|
||||
Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
|
||||
|
||||
219
Documentation/dvb/ci.txt
Normal file
219
Documentation/dvb/ci.txt
Normal file
@@ -0,0 +1,219 @@
|
||||
* For the user
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
NOTE: This document describes the usage of the high level CI API as
|
||||
in accordance to the Linux DVB API. This is a not a documentation for the,
|
||||
existing low level CI API.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To utilize the High Level CI capabilities,
|
||||
|
||||
(1*) This point is valid only for the Twinhan/clones
|
||||
For the Twinhan/Twinhan clones, the dst_ca module handles the CI
|
||||
hardware handling.This module is loaded automatically if a CI
|
||||
(Common Interface, that holds the CAM (Conditional Access Module)
|
||||
is detected.
|
||||
|
||||
(2) one requires a userspace application, ca_zap. This small userland
|
||||
application is in charge of sending the descrambling related information
|
||||
to the CAM.
|
||||
|
||||
This application requires the following to function properly as of now.
|
||||
|
||||
(a) Tune to a valid channel, with szap.
|
||||
eg: $ szap -c channels.conf -r "TMC" -x
|
||||
|
||||
(b) a channels.conf containing a valid PMT PID
|
||||
|
||||
eg: TMC:11996:h:0:27500:278:512:650:321
|
||||
|
||||
here 278 is a valid PMT PID. the rest of the values are the
|
||||
same ones that szap uses.
|
||||
|
||||
(c) after running a szap, you have to run ca_zap, for the
|
||||
descrambler to function,
|
||||
|
||||
eg: $ ca_zap patched_channels.conf "TMC"
|
||||
|
||||
The patched means a patch to apply to scan, such that scan can
|
||||
generate a channels.conf_with pmt, which has this PMT PID info
|
||||
(NOTE: szap cannot use this channels.conf with the PMT_PID)
|
||||
|
||||
|
||||
(d) Hopeflly Enjoy your favourite subscribed channel as you do with
|
||||
a FTA card.
|
||||
|
||||
(3) Currently ca_zap, and dst_test, both are meant for demonstration
|
||||
purposes only, they can become full fledged applications if necessary.
|
||||
|
||||
|
||||
* Cards that fall in this category
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
At present the cards that fall in this category are the Twinhan and it's
|
||||
clones, these cards are available as VVMER, Tomato, Hercules, Orange and
|
||||
so on.
|
||||
|
||||
* CI modules that are supported
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The CI module support is largely dependant upon the firmware on the cards
|
||||
Some cards do support almost all of the available CI modules. There is
|
||||
nothing much that can be done in order to make additional CI modules
|
||||
working with these cards.
|
||||
|
||||
Modules that have been tested by this driver at present are
|
||||
|
||||
(1) Irdeto 1 and 2 from SCM
|
||||
(2) Viaccess from SCM
|
||||
(3) Dragoncam
|
||||
|
||||
* The High level CI API
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* For the programmer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
With the High Level CI approach any new card with almost any random
|
||||
architecture can be implemented with this style, the definitions
|
||||
insidethe switch statement can be easily adapted for any card, thereby
|
||||
eliminating the need for any additional ioctls.
|
||||
|
||||
The disadvantage is that the driver/hardware has to manage the rest. For
|
||||
the application programmer it would be as simple as sending/receiving an
|
||||
array to/from the CI ioctls as defined in the Linux DVB API. No changes
|
||||
have been made in the API to accomodate this feature.
|
||||
|
||||
|
||||
* Why the need for another CI interface ?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
This is one of the most commonly asked question. Well a nice question.
|
||||
Strictly speaking this is not a new interface.
|
||||
|
||||
The CI interface is defined in the DVB API in ca.h as
|
||||
|
||||
typedef struct ca_slot_info {
|
||||
int num; /* slot number */
|
||||
|
||||
int type; /* CA interface this slot supports */
|
||||
#define CA_CI 1 /* CI high level interface */
|
||||
#define CA_CI_LINK 2 /* CI link layer level interface */
|
||||
#define CA_CI_PHYS 4 /* CI physical layer level interface */
|
||||
#define CA_DESCR 8 /* built-in descrambler */
|
||||
#define CA_SC 128 /* simple smart card interface */
|
||||
|
||||
unsigned int flags;
|
||||
#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
|
||||
#define CA_CI_MODULE_READY 2
|
||||
} ca_slot_info_t;
|
||||
|
||||
|
||||
|
||||
This CI interface follows the CI high level interface, which is not
|
||||
implemented by most applications. Hence this area is revisited.
|
||||
|
||||
This CI interface is quite different in the case that it tries to
|
||||
accomodate all other CI based devices, that fall into the other categories
|
||||
|
||||
This means that this CI interface handles the EN50221 style tags in the
|
||||
Application layer only and no session management is taken care of by the
|
||||
application. The driver/hardware will take care of all that.
|
||||
|
||||
This interface is purely an EN50221 interface exchanging APDU's. This
|
||||
means that no session management, link layer or a transport layer do
|
||||
exist in this case in the application to driver communication. It is
|
||||
as simple as that. The driver/hardware has to take care of that.
|
||||
|
||||
|
||||
With this High Level CI interface, the interface can be defined with the
|
||||
regular ioctls.
|
||||
|
||||
All these ioctls are also valid for the High level CI interface
|
||||
|
||||
#define CA_RESET _IO('o', 128)
|
||||
#define CA_GET_CAP _IOR('o', 129, ca_caps_t)
|
||||
#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t)
|
||||
#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
|
||||
#define CA_GET_MSG _IOR('o', 132, ca_msg_t)
|
||||
#define CA_SEND_MSG _IOW('o', 133, ca_msg_t)
|
||||
#define CA_SET_DESCR _IOW('o', 134, ca_descr_t)
|
||||
#define CA_SET_PID _IOW('o', 135, ca_pid_t)
|
||||
|
||||
|
||||
On querying the device, the device yields information thus
|
||||
|
||||
CA_GET_SLOT_INFO
|
||||
----------------------------
|
||||
Command = [info]
|
||||
APP: Number=[1]
|
||||
APP: Type=[1]
|
||||
APP: flags=[1]
|
||||
APP: CI High level interface
|
||||
APP: CA/CI Module Present
|
||||
|
||||
CA_GET_CAP
|
||||
----------------------------
|
||||
Command = [caps]
|
||||
APP: Slots=[1]
|
||||
APP: Type=[1]
|
||||
APP: Descrambler keys=[16]
|
||||
APP: Type=[1]
|
||||
|
||||
CA_SEND_MSG
|
||||
----------------------------
|
||||
Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1]
|
||||
Found CA descriptor @ program level
|
||||
|
||||
(20) ES type=[2] ES pid=[201] ES length =[0 (0x0)]
|
||||
(25) ES type=[4] ES pid=[301] ES length =[0 (0x0)]
|
||||
ca_message length is 25 (0x19) bytes
|
||||
EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00]
|
||||
|
||||
|
||||
Not all ioctl's are implemented in the driver from the API, the other
|
||||
features of the hardware that cannot be implemented by the API are achieved
|
||||
using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is
|
||||
used to exchange the data to maintain compatibility with other hardware.
|
||||
|
||||
|
||||
/* a message to/from a CI-CAM */
|
||||
typedef struct ca_msg {
|
||||
unsigned int index;
|
||||
unsigned int type;
|
||||
unsigned int length;
|
||||
unsigned char msg[256];
|
||||
} ca_msg_t;
|
||||
|
||||
|
||||
The flow of data can be described thus,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
App (User)
|
||||
-----
|
||||
parse
|
||||
|
|
||||
|
|
||||
v
|
||||
en50221 APDU (package)
|
||||
--------------------------------------
|
||||
| | | High Level CI driver
|
||||
| | |
|
||||
| v |
|
||||
| en50221 APDU (unpackage) |
|
||||
| | |
|
||||
| | |
|
||||
| v |
|
||||
| sanity checks |
|
||||
| | |
|
||||
| | |
|
||||
| v |
|
||||
| do (H/W dep) |
|
||||
--------------------------------------
|
||||
| Hardware
|
||||
|
|
||||
v
|
||||
|
||||
|
||||
|
||||
|
||||
The High Level CI interface uses the EN50221 DVB standard, following a
|
||||
standard ensures futureproofness.
|
||||
@@ -107,7 +107,7 @@ sub tda10045 {
|
||||
sub tda10046 {
|
||||
my $sourcefile = "tt_budget_217g.zip";
|
||||
my $url = "http://www.technotrend.de/new/217g/$sourcefile";
|
||||
my $hash = "a25b579e37109af60f4a36c37893957c";
|
||||
my $hash = "6a7e1e2f2644b162ff0502367553c72d";
|
||||
my $outfile = "dvb-fe-tda10046.fw";
|
||||
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
|
||||
|
||||
@@ -115,7 +115,7 @@ sub tda10046 {
|
||||
|
||||
wgetfile($sourcefile, $url);
|
||||
unzip($sourcefile, $tmpdir);
|
||||
extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24479, "$tmpdir/fwtmp");
|
||||
extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp");
|
||||
verify("$tmpdir/fwtmp", $hash);
|
||||
copy("$tmpdir/fwtmp", $outfile);
|
||||
|
||||
|
||||
@@ -63,3 +63,23 @@ Why: Outside of Linux, the only implementations of anything even
|
||||
people, who might be using implementations that I am not aware
|
||||
of, to adjust to this upcoming change.
|
||||
Who: Paul E. McKenney <paulmck@us.ibm.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: IEEE1394 Audio and Music Data Transmission Protocol driver,
|
||||
Connection Management Procedures driver
|
||||
When: November 2005
|
||||
Files: drivers/ieee1394/{amdtp,cmp}*
|
||||
Why: These are incomplete, have never worked, and are better implemented
|
||||
in userland via raw1394 (see http://freebob.sourceforge.net/ for
|
||||
example.)
|
||||
Who: Jody McIntyre <scjody@steamballoon.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
|
||||
When: November 2005
|
||||
Why: Deprecated in favour of the new ioctl-based rawiso interface, which is
|
||||
more efficient. You should really be using libraw1394 for raw1394
|
||||
access anyway.
|
||||
Who: Jody McIntyre <scjody@steamballoon.com>
|
||||
|
||||
2
Makefile
2
Makefile
@@ -530,7 +530,7 @@ endif
|
||||
include $(srctree)/arch/$(ARCH)/Makefile
|
||||
|
||||
# arch Makefile may override CC so keep this after arch Makefile is included
|
||||
NOSTDINC_FLAGS := -nostdinc -isystem $(shell $(CC) -print-file-name=include)
|
||||
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
|
||||
CHECKFLAGS += $(NOSTDINC_FLAGS)
|
||||
|
||||
# warn about C99 declaration after statement
|
||||
|
||||
@@ -1150,16 +1150,13 @@ osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remai
|
||||
if (get_tv32(&tmp, sleep))
|
||||
goto fault;
|
||||
|
||||
ticks = tmp.tv_usec;
|
||||
ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
|
||||
ticks += tmp.tv_sec * HZ;
|
||||
ticks = timeval_to_jiffies(&tmp);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
ticks = schedule_timeout(ticks);
|
||||
|
||||
if (remain) {
|
||||
tmp.tv_sec = ticks / HZ;
|
||||
tmp.tv_usec = ticks % HZ;
|
||||
jiffies_to_timeval(ticks, &tmp);
|
||||
if (put_tv32(remain, &tmp))
|
||||
goto fault;
|
||||
}
|
||||
|
||||
@@ -478,7 +478,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
|
||||
{
|
||||
unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
|
||||
|
||||
s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2;
|
||||
s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate);
|
||||
|
||||
printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
|
||||
print_mhz(s3c2440_clk_upll.rate));
|
||||
|
||||
@@ -192,9 +192,11 @@ void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
|
||||
|
||||
iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
|
||||
iotable_init(mach_desc, size);
|
||||
|
||||
/* rename any peripherals used differing from the s3c2410 */
|
||||
|
||||
s3c_device_i2c.name = "s3c2440-i2c";
|
||||
s3c_device_i2c.name = "s3c2440-i2c";
|
||||
s3c_device_nand.name = "s3c2440-nand";
|
||||
|
||||
/* change irq for watchdog */
|
||||
|
||||
@@ -225,7 +227,7 @@ void __init s3c2440_init_clocks(int xtal)
|
||||
break;
|
||||
|
||||
case S3C2440_CLKDIVN_HDIVN_2:
|
||||
hdiv = 1;
|
||||
hdiv = 2;
|
||||
break;
|
||||
|
||||
case S3C2440_CLKDIVN_HDIVN_4_8:
|
||||
|
||||
@@ -412,21 +412,20 @@ config CPU_BPREDICT_DISABLE
|
||||
|
||||
config TLS_REG_EMUL
|
||||
bool
|
||||
default y if (SMP || CPU_32v6) && (CPU_32v5 || CPU_32v4 || CPU_32v3)
|
||||
default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
|
||||
help
|
||||
We might be running on an ARMv6+ processor which should have the TLS
|
||||
register but for some reason we can't use it, or maybe an SMP system
|
||||
using a pre-ARMv6 processor (there are apparently a few prototypes
|
||||
like that in existence) and therefore access to that register must
|
||||
be emulated.
|
||||
An SMP system using a pre-ARMv6 processor (there are apparently
|
||||
a few prototypes like that in existence) and therefore access to
|
||||
that required register must be emulated.
|
||||
|
||||
config HAS_TLS_REG
|
||||
bool
|
||||
depends on CPU_32v6
|
||||
default y if !TLS_REG_EMUL
|
||||
depends on !TLS_REG_EMUL
|
||||
default y if SMP || CPU_32v7
|
||||
help
|
||||
This selects support for the CP15 thread register.
|
||||
It is defined to be available on ARMv6 or later. If a particular
|
||||
ARMv6 or later CPU doesn't support it then it must omc;ide "select
|
||||
TLS_REG_EMUL" along with its other caracteristics.
|
||||
It is defined to be available on some ARMv6 processors (including
|
||||
all SMP capable ARMv6's) or later processors. User space may
|
||||
assume directly accessing that register and always obtain the
|
||||
expected value only on ARMv7 and above.
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* linux/arch/arm/lib/copy_page-armv4mc.S
|
||||
*
|
||||
* Copyright (C) 1995-2001 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.
|
||||
*
|
||||
* ASM optimised string functions
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/constants.h>
|
||||
|
||||
.text
|
||||
.align 5
|
||||
/*
|
||||
* ARMv4 mini-dcache optimised copy_user_page
|
||||
*
|
||||
* We flush the destination cache lines just before we write the data into the
|
||||
* corresponding address. Since the Dcache is read-allocate, this removes the
|
||||
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
|
||||
* and merged as appropriate.
|
||||
*
|
||||
* Note: We rely on all ARMv4 processors implementing the "invalidate D line"
|
||||
* instruction. If your processor does not supply this, you have to write your
|
||||
* own copy_user_page that does the right thing.
|
||||
*/
|
||||
ENTRY(v4_mc_copy_user_page)
|
||||
stmfd sp!, {r4, lr} @ 2
|
||||
mov r4, r0
|
||||
mov r0, r1
|
||||
bl map_page_minicache
|
||||
mov r1, #PAGE_SZ/64 @ 1
|
||||
ldmia r0!, {r2, r3, ip, lr} @ 4
|
||||
1: mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line
|
||||
stmia r4!, {r2, r3, ip, lr} @ 4
|
||||
ldmia r0!, {r2, r3, ip, lr} @ 4+1
|
||||
stmia r4!, {r2, r3, ip, lr} @ 4
|
||||
ldmia r0!, {r2, r3, ip, lr} @ 4
|
||||
mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line
|
||||
stmia r4!, {r2, r3, ip, lr} @ 4
|
||||
ldmia r0!, {r2, r3, ip, lr} @ 4
|
||||
subs r1, r1, #1 @ 1
|
||||
stmia r4!, {r2, r3, ip, lr} @ 4
|
||||
ldmneia r0!, {r2, r3, ip, lr} @ 4
|
||||
bne 1b @ 1
|
||||
ldmfd sp!, {r4, pc} @ 3
|
||||
|
||||
.align 5
|
||||
/*
|
||||
* ARMv4 optimised clear_user_page
|
||||
*
|
||||
* Same story as above.
|
||||
*/
|
||||
ENTRY(v4_mc_clear_user_page)
|
||||
str lr, [sp, #-4]!
|
||||
mov r1, #PAGE_SZ/64 @ 1
|
||||
mov r2, #0 @ 1
|
||||
mov r3, #0 @ 1
|
||||
mov ip, #0 @ 1
|
||||
mov lr, #0 @ 1
|
||||
1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line
|
||||
stmia r0!, {r2, r3, ip, lr} @ 4
|
||||
stmia r0!, {r2, r3, ip, lr} @ 4
|
||||
mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line
|
||||
stmia r0!, {r2, r3, ip, lr} @ 4
|
||||
stmia r0!, {r2, r3, ip, lr} @ 4
|
||||
subs r1, r1, #1 @ 1
|
||||
bne 1b @ 1
|
||||
ldr pc, [sp], #4
|
||||
|
||||
__INITDATA
|
||||
|
||||
.type v4_mc_user_fns, #object
|
||||
ENTRY(v4_mc_user_fns)
|
||||
.long v4_mc_clear_user_page
|
||||
.long v4_mc_copy_user_page
|
||||
.size v4_mc_user_fns, . - v4_mc_user_fns
|
||||
111
arch/arm/mm/copypage-v4mc.c
Normal file
111
arch/arm/mm/copypage-v4mc.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* linux/arch/arm/lib/copypage-armv4mc.S
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This handles the mini data cache, as found on SA11x0 and XScale
|
||||
* processors. When we copy a user page page, we map it in such a way
|
||||
* that accesses to this page will not touch the main data cache, but
|
||||
* will be cached in the mini data cache. This prevents us thrashing
|
||||
* the main data cache on page faults.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
/*
|
||||
* 0xffff8000 to 0xffffffff is reserved for any ARM architecture
|
||||
* specific hacks for copying pages efficiently.
|
||||
*/
|
||||
#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);
|
||||
|
||||
/*
|
||||
* ARMv4 mini-dcache optimised copy_user_page
|
||||
*
|
||||
* We flush the destination cache lines just before we write the data into the
|
||||
* corresponding address. Since the Dcache is read-allocate, this removes the
|
||||
* Dcache aliasing issue. The writes will be forwarded to the write buffer,
|
||||
* and merged as appropriate.
|
||||
*
|
||||
* Note: We rely on all ARMv4 processors implementing the "invalidate D line"
|
||||
* instruction. If your processor does not supply this, you have to write your
|
||||
* own copy_user_page that does the right thing.
|
||||
*/
|
||||
static void __attribute__((naked))
|
||||
mc_copy_user_page(void *from, void *to)
|
||||
{
|
||||
asm volatile(
|
||||
"stmfd sp!, {r4, lr} @ 2\n\
|
||||
mov r4, %2 @ 1\n\
|
||||
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||
1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||
ldmia %0!, {r2, r3, ip, lr} @ 4+1\n\
|
||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||
mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||
ldmia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||
subs r4, r4, #1 @ 1\n\
|
||||
stmia %1!, {r2, r3, ip, lr} @ 4\n\
|
||||
ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
|
||||
bne 1b @ 1\n\
|
||||
ldmfd sp!, {r4, pc} @ 3"
|
||||
:
|
||||
: "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
|
||||
}
|
||||
|
||||
void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
|
||||
{
|
||||
spin_lock(&minicache_lock);
|
||||
|
||||
set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
|
||||
flush_tlb_kernel_page(0xffff8000);
|
||||
|
||||
mc_copy_user_page((void *)0xffff8000, kto);
|
||||
|
||||
spin_unlock(&minicache_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* ARMv4 optimised clear_user_page
|
||||
*/
|
||||
void __attribute__((naked))
|
||||
v4_mc_clear_user_page(void *kaddr, unsigned long vaddr)
|
||||
{
|
||||
asm volatile(
|
||||
"str lr, [sp, #-4]!\n\
|
||||
mov r1, %0 @ 1\n\
|
||||
mov r2, #0 @ 1\n\
|
||||
mov r3, #0 @ 1\n\
|
||||
mov ip, #0 @ 1\n\
|
||||
mov lr, #0 @ 1\n\
|
||||
1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia r0!, {r2, r3, ip, lr} @ 4\n\
|
||||
stmia r0!, {r2, r3, ip, lr} @ 4\n\
|
||||
mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
|
||||
stmia r0!, {r2, r3, ip, lr} @ 4\n\
|
||||
stmia r0!, {r2, r3, ip, lr} @ 4\n\
|
||||
subs r1, r1, #1 @ 1\n\
|
||||
bne 1b @ 1\n\
|
||||
ldr pc, [sp], #4"
|
||||
:
|
||||
: "I" (PAGE_SIZE / 64));
|
||||
}
|
||||
|
||||
struct cpu_user_fns v4_mc_user_fns __initdata = {
|
||||
.cpu_clear_user_page = v4_mc_clear_user_page,
|
||||
.cpu_copy_user_page = v4_mc_copy_user_page,
|
||||
};
|
||||
@@ -26,8 +26,8 @@
|
||||
#define to_address (0xffffc000)
|
||||
#define to_pgprot PAGE_KERNEL
|
||||
|
||||
static pte_t *from_pte;
|
||||
static pte_t *to_pte;
|
||||
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
|
||||
|
||||
static DEFINE_SPINLOCK(v6_lock);
|
||||
|
||||
#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
|
||||
@@ -74,8 +74,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
|
||||
*/
|
||||
spin_lock(&v6_lock);
|
||||
|
||||
set_pte(from_pte + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
|
||||
set_pte(to_pte + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
|
||||
set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
|
||||
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
|
||||
|
||||
from = from_address + (offset << PAGE_SHIFT);
|
||||
to = to_address + (offset << PAGE_SHIFT);
|
||||
@@ -114,7 +114,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
|
||||
*/
|
||||
spin_lock(&v6_lock);
|
||||
|
||||
set_pte(to_pte + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
|
||||
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
|
||||
flush_tlb_kernel_page(to);
|
||||
clear_page((void *)to);
|
||||
|
||||
@@ -129,21 +129,6 @@ struct cpu_user_fns v6_user_fns __initdata = {
|
||||
static int __init v6_userpage_init(void)
|
||||
{
|
||||
if (cache_is_vipt_aliasing()) {
|
||||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
|
||||
pgd = pgd_offset_k(from_address);
|
||||
pmd = pmd_alloc(&init_mm, pgd, from_address);
|
||||
if (!pmd)
|
||||
BUG();
|
||||
from_pte = pte_alloc_kernel(&init_mm, pmd, from_address);
|
||||
if (!from_pte)
|
||||
BUG();
|
||||
|
||||
to_pte = pte_alloc_kernel(&init_mm, pmd, to_address);
|
||||
if (!to_pte)
|
||||
BUG();
|
||||
|
||||
cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing;
|
||||
cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing;
|
||||
}
|
||||
@@ -151,5 +136,4 @@ static int __init v6_userpage_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
__initcall(v6_userpage_init);
|
||||
|
||||
core_initcall(v6_userpage_init);
|
||||
|
||||
@@ -13,6 +13,29 @@
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/tlbflush.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);
|
||||
|
||||
set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
|
||||
flush_tlb_kernel_page(to);
|
||||
|
||||
asm( "mcrr p15, 0, %1, %0, c14\n"
|
||||
" mcrr p15, 0, %1, %0, c5\n"
|
||||
:
|
||||
: "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES)
|
||||
: "cc");
|
||||
}
|
||||
#else
|
||||
#define flush_pfn_alias(pfn,vaddr) do { } while (0)
|
||||
#endif
|
||||
|
||||
static void __flush_dcache_page(struct address_space *mapping, struct page *page)
|
||||
{
|
||||
@@ -36,6 +59,18 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
|
||||
if (!mapping)
|
||||
return;
|
||||
|
||||
/*
|
||||
* This is a page cache page. If we have a VIPT cache, we
|
||||
* only need to do one flush - which would be at the relevant
|
||||
* userspace colour, which is congruent with page->index.
|
||||
*/
|
||||
if (cache_is_vipt()) {
|
||||
if (cache_is_vipt_aliasing())
|
||||
flush_pfn_alias(page_to_pfn(page),
|
||||
page->index << PAGE_CACHE_SHIFT);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are possible user space mappings of this page:
|
||||
* - VIVT cache: we need to also write back and invalidate all user
|
||||
@@ -57,8 +92,6 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
|
||||
continue;
|
||||
offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
|
||||
flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));
|
||||
if (cache_is_vipt())
|
||||
break;
|
||||
}
|
||||
flush_dcache_mmap_unlock(mapping);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ pgprot_t pgprot_kernel;
|
||||
|
||||
EXPORT_SYMBOL(pgprot_kernel);
|
||||
|
||||
pmd_t *top_pmd;
|
||||
|
||||
struct cachepolicy {
|
||||
const char policy[16];
|
||||
unsigned int cr_mask;
|
||||
@@ -142,6 +144,16 @@ __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
|
||||
*/
|
||||
@@ -220,7 +232,7 @@ void free_pgd_slow(pgd_t *pgd)
|
||||
return;
|
||||
|
||||
/* pgd is always present and good */
|
||||
pmd = (pmd_t *)pgd;
|
||||
pmd = pmd_off(pgd, 0);
|
||||
if (pmd_none(*pmd))
|
||||
goto free;
|
||||
if (pmd_bad(*pmd)) {
|
||||
@@ -246,9 +258,8 @@ free:
|
||||
static inline void
|
||||
alloc_init_section(unsigned long virt, unsigned long phys, int prot)
|
||||
{
|
||||
pmd_t *pmdp;
|
||||
pmd_t *pmdp = pmd_off_k(virt);
|
||||
|
||||
pmdp = pmd_offset(pgd_offset_k(virt), virt);
|
||||
if (virt & (1 << 20))
|
||||
pmdp++;
|
||||
|
||||
@@ -283,11 +294,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
|
||||
static inline void
|
||||
alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
|
||||
{
|
||||
pmd_t *pmdp;
|
||||
pmd_t *pmdp = pmd_off_k(virt);
|
||||
pte_t *ptep;
|
||||
|
||||
pmdp = pmd_offset(pgd_offset_k(virt), virt);
|
||||
|
||||
if (pmd_none(*pmdp)) {
|
||||
unsigned long pmdval;
|
||||
ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
|
||||
@@ -310,7 +319,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
|
||||
*/
|
||||
static inline void clear_mapping(unsigned long virt)
|
||||
{
|
||||
pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
|
||||
pmd_clear(pmd_off_k(virt));
|
||||
}
|
||||
|
||||
struct mem_types {
|
||||
@@ -578,7 +587,7 @@ void setup_mm_for_reboot(char mode)
|
||||
PMD_TYPE_SECT;
|
||||
if (cpu_arch <= CPU_ARCH_ARMv5)
|
||||
pmdval |= PMD_BIT4;
|
||||
pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
|
||||
pmd = pmd_off(pgd, i << PGDIR_SHIFT);
|
||||
pmd[0] = __pmd(pmdval);
|
||||
pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
|
||||
flush_pmd_entry(pmd);
|
||||
@@ -675,6 +684,8 @@ void __init memtable_init(struct meminfo *mi)
|
||||
|
||||
flush_cache_all();
|
||||
flush_tlb_all();
|
||||
|
||||
top_pmd = pmd_off_k(0xffff0000);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,9 +24,6 @@ __asm__(".align 4\nvide: ret");
|
||||
|
||||
static void __init init_amd(struct cpuinfo_x86 *c)
|
||||
{
|
||||
#ifdef CONFIG_X86_SMP
|
||||
int cpu = c == &boot_cpu_data ? 0 : c - cpu_data;
|
||||
#endif
|
||||
u32 l, h;
|
||||
int mbytes = num_physpages >> (20-PAGE_SHIFT);
|
||||
int r;
|
||||
@@ -205,7 +202,9 @@ static void __init init_amd(struct cpuinfo_x86 *c)
|
||||
* of two.
|
||||
*/
|
||||
if (c->x86_num_cores > 1) {
|
||||
cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
|
||||
int cpu = smp_processor_id();
|
||||
/* Fix up the APIC ID following AMD specifications. */
|
||||
cpu_core_id[cpu] >>= hweight32(c->x86_num_cores - 1);
|
||||
printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
|
||||
cpu, c->x86_num_cores, cpu_core_id[cpu]);
|
||||
}
|
||||
|
||||
@@ -243,6 +243,13 @@ static void __init early_cpu_detect(void)
|
||||
}
|
||||
|
||||
early_intel_workaround(c);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#ifdef CONFIG_X86_HT
|
||||
phys_proc_id[smp_processor_id()] =
|
||||
#endif
|
||||
cpu_core_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
|
||||
#endif
|
||||
}
|
||||
|
||||
void __init generic_identify(struct cpuinfo_x86 * c)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#define INCLUDES
|
||||
#include "compat_ioctl.c"
|
||||
#include <asm/ioctl32.h>
|
||||
|
||||
#define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* pmu.c, Power Management Unit routines for NEC VR4100 series.
|
||||
*
|
||||
* Copyright (C) 2003-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
|
||||
* Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
|
||||
*
|
||||
* 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
|
||||
@@ -17,7 +17,9 @@
|
||||
* 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/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/types.h>
|
||||
@@ -27,20 +29,31 @@
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define PMUCNT2REG KSEG1ADDR(0x0f0000c6)
|
||||
#define PMU_TYPE1_BASE 0x0b0000a0UL
|
||||
#define PMU_TYPE1_SIZE 0x0eUL
|
||||
|
||||
#define PMU_TYPE2_BASE 0x0f0000c0UL
|
||||
#define PMU_TYPE2_SIZE 0x10UL
|
||||
|
||||
#define PMUCNT2REG 0x06
|
||||
#define SOFTRST 0x0010
|
||||
|
||||
static void __iomem *pmu_base;
|
||||
|
||||
#define pmu_read(offset) readw(pmu_base + (offset))
|
||||
#define pmu_write(offset, value) writew((value), pmu_base + (offset))
|
||||
|
||||
static inline void software_reset(void)
|
||||
{
|
||||
uint16_t val;
|
||||
uint16_t pmucnt2;
|
||||
|
||||
switch (current_cpu_data.cputype) {
|
||||
case CPU_VR4122:
|
||||
case CPU_VR4131:
|
||||
case CPU_VR4133:
|
||||
val = readw(PMUCNT2REG);
|
||||
val |= SOFTRST;
|
||||
writew(val, PMUCNT2REG);
|
||||
pmucnt2 = pmu_read(PMUCNT2REG);
|
||||
pmucnt2 |= SOFTRST;
|
||||
pmu_write(PMUCNT2REG, pmucnt2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -71,6 +84,34 @@ static void vr41xx_power_off(void)
|
||||
|
||||
static int __init vr41xx_pmu_init(void)
|
||||
{
|
||||
unsigned long start, size;
|
||||
|
||||
switch (current_cpu_data.cputype) {
|
||||
case CPU_VR4111:
|
||||
case CPU_VR4121:
|
||||
start = PMU_TYPE1_BASE;
|
||||
size = PMU_TYPE1_SIZE;
|
||||
break;
|
||||
case CPU_VR4122:
|
||||
case CPU_VR4131:
|
||||
case CPU_VR4133:
|
||||
start = PMU_TYPE2_BASE;
|
||||
size = PMU_TYPE2_SIZE;
|
||||
break;
|
||||
default:
|
||||
printk("Unexpected CPU of NEC VR4100 series\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (request_mem_region(start, size, "PMU") == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
pmu_base = ioremap(start, size);
|
||||
if (pmu_base == NULL) {
|
||||
release_mem_region(start, size);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
_machine_restart = vr41xx_restart;
|
||||
_machine_halt = vr41xx_halt;
|
||||
_machine_power_off = vr41xx_power_off;
|
||||
@@ -78,4 +119,4 @@ static int __init vr41xx_pmu_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
early_initcall(vr41xx_pmu_init);
|
||||
core_initcall(vr41xx_pmu_init);
|
||||
|
||||
@@ -236,9 +236,15 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
|
||||
(*prev)->fd, pollfds[i].fd);
|
||||
goto out;
|
||||
}
|
||||
memcpy(&pollfds[i], &pollfds[i + 1],
|
||||
(pollfds_num - i - 1) * sizeof(pollfds[0]));
|
||||
|
||||
pollfds_num--;
|
||||
|
||||
/* This moves the *whole* array after pollfds[i] (though
|
||||
* it doesn't spot as such)! */
|
||||
|
||||
memmove(&pollfds[i], &pollfds[i + 1],
|
||||
(pollfds_num - i) * sizeof(pollfds[0]));
|
||||
|
||||
if(last_irq_ptr == &old_fd->next)
|
||||
last_irq_ptr = prev;
|
||||
*prev = (*prev)->next;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user